diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 4a6b8a6375311b3e13177b76e0924b6d5a635f68..0000000000000000000000000000000000000000 --- a/.editorconfig +++ /dev/null @@ -1,26 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 2 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true - -[vcbuild.bat] -end_of_line = crlf - -[Makefile] -indent_size = 8 -indent_style = tab - -[{deps}/**] -charset = unset -end_of_line = unset -indent_size = unset -indent_style = unset -trim_trailing_whitespace = unset - -[{test/fixtures,deps,tools/node_modules,tools/gyp,tools/icu,tools/msvs}/**] -insert_final_newline = false diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index bdfdfaeab2388d2650d1b32ab44cc8abecfabc8a..0000000000000000000000000000000000000000 --- a/.eslintignore +++ /dev/null @@ -1,12 +0,0 @@ -node_modules -lib/internal/v8_prof_polyfill.js -lib/punycode.js -test/addons/??_* -test/fixtures -test/message/esm_display_syntax_error.mjs -tools/icu -tools/lint-md.js -tools/node-lint-md-cli-rollup/dist -benchmark/tmp -doc/**/*.js -!.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 2ad6cc199cedf7c74bd8f61aef18eb8d8e6b435e..0000000000000000000000000000000000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,294 +0,0 @@ -'use strict'; - -/* eslint-env node */ - -const Module = require('module'); -const path = require('path'); - -const NodePlugin = require('./tools/node_modules/eslint-plugin-node-core'); -NodePlugin.RULES_DIR = path.resolve(__dirname, 'tools', 'eslint-rules'); - -// The Module._findPath() monkeypatching is to make it so that ESLint will work -// if invoked by a globally-installed ESLint or ESLint installed elsewhere -// rather than the one we ship. This makes it possible for IDEs to lint files -// with our rules while people edit them. -const ModuleFindPath = Module._findPath; -const hacks = [ - 'eslint-plugin-node-core', - 'eslint-plugin-markdown', - 'babel-eslint', -]; -Module._findPath = (request, paths, isMain) => { - const r = ModuleFindPath(request, paths, isMain); - if (!r && hacks.includes(request)) { - try { - return require.resolve(`./tools/node_modules/${request}`); - // Keep the variable in place to ensure that ESLint started by older Node.js - // versions work as expected. - // eslint-disable-next-line no-unused-vars - } catch (e) { - return require.resolve( - `./tools/node_modules/eslint/node_modules/${request}`); - } - } - return r; -}; - -module.exports = { - root: true, - plugins: ['markdown', 'node-core'], - parser: 'babel-eslint', - parserOptions: { sourceType: 'script' }, - overrides: [ - { - files: [ - 'doc/api/esm.md', - 'doc/api/module.md', - 'doc/api/modules.md', - 'doc/api/packages.md', - 'test/es-module/test-esm-type-flag.js', - 'test/es-module/test-esm-type-flag-alias.js', - '*.mjs', - 'test/es-module/test-esm-example-loader.js', - ], - parserOptions: { sourceType: 'module' }, - }, - { - files: ['**/*.md'], - parserOptions: { ecmaFeatures: { impliedStrict: true } }, - rules: { strict: 'off' }, - }, - ], - rules: { - // ESLint built-in rules - // https://eslint.org/docs/rules/ - 'accessor-pairs': 'error', - 'array-callback-return': 'error', - 'arrow-parens': ['error', 'always'], - 'arrow-spacing': ['error', { before: true, after: true }], - 'block-scoped-var': 'error', - 'block-spacing': 'error', - 'brace-style': ['error', '1tbs', { allowSingleLine: true }], - 'capitalized-comments': ['error', 'always', { - line: { - // Ignore all lines that have less characters than 20 and all lines that - // start with something that looks like a variable name or code. - // eslint-disable-next-line max-len - ignorePattern: '.{0,20}$|[a-z]+ ?[0-9A-Z_.(/=:[#-]|std|http|ssh|ftp|(let|var|const) [a-z_A-Z0-9]+ =|[b-z] |[a-z]*[0-9].* ', - ignoreInlineComments: true, - ignoreConsecutiveComments: true, - }, - block: { - ignorePattern: '.*', - }, - }], - 'comma-dangle': ['error', 'only-multiline'], - 'comma-spacing': 'error', - 'comma-style': 'error', - 'computed-property-spacing': 'error', - 'constructor-super': 'error', - 'default-case-last': 'error', - 'dot-location': ['error', 'property'], - 'dot-notation': 'error', - 'eol-last': 'error', - 'eqeqeq': ['error', 'smart'], - 'for-direction': 'error', - 'func-call-spacing': 'error', - 'func-name-matching': 'error', - 'func-style': ['error', 'declaration', { allowArrowFunctions: true }], - 'getter-return': 'error', - 'indent': ['error', 2, { - ArrayExpression: 'first', - CallExpression: { arguments: 'first' }, - FunctionDeclaration: { parameters: 'first' }, - FunctionExpression: { parameters: 'first' }, - MemberExpression: 'off', - ObjectExpression: 'first', - SwitchCase: 1, - }], - 'key-spacing': ['error', { mode: 'strict' }], - 'keyword-spacing': 'error', - 'linebreak-style': ['error', 'unix'], - 'max-len': ['error', { - code: 80, - ignorePattern: '^// Flags:', - ignoreRegExpLiterals: true, - ignoreUrls: true, - tabWidth: 2, - }], - 'new-parens': 'error', - 'no-async-promise-executor': 'error', - 'no-class-assign': 'error', - 'no-confusing-arrow': 'error', - 'no-const-assign': 'error', - 'no-constructor-return': 'error', - 'no-control-regex': 'error', - 'no-debugger': 'error', - 'no-delete-var': 'error', - 'no-dupe-args': 'error', - 'no-dupe-class-members': 'error', - 'no-dupe-keys': 'error', - 'no-dupe-else-if': 'error', - 'no-duplicate-case': 'error', - 'no-duplicate-imports': 'error', - 'no-else-return': ['error', { allowElseIf: true }], - 'no-empty-character-class': 'error', - 'no-ex-assign': 'error', - 'no-extra-boolean-cast': 'error', - 'no-extra-parens': ['error', 'functions'], - 'no-extra-semi': 'error', - 'no-fallthrough': 'error', - 'no-func-assign': 'error', - 'no-global-assign': 'error', - 'no-invalid-regexp': 'error', - 'no-irregular-whitespace': 'error', - 'no-lonely-if': 'error', - 'no-misleading-character-class': 'error', - 'no-mixed-requires': 'error', - 'no-mixed-spaces-and-tabs': 'error', - 'no-multi-spaces': ['error', { ignoreEOLComments: true }], - 'no-multiple-empty-lines': ['error', { max: 2, maxEOF: 0, maxBOF: 0 }], - 'no-new-require': 'error', - 'no-new-symbol': 'error', - 'no-obj-calls': 'error', - 'no-octal': 'error', - 'no-path-concat': 'error', - 'no-proto': 'error', - 'no-redeclare': ['error', { 'builtinGlobals': false }], - 'no-restricted-modules': ['error', 'sys'], - /* eslint-disable max-len */ - 'no-restricted-properties': [ - 'error', - { - object: 'assert', - property: 'deepEqual', - message: 'Use `assert.deepStrictEqual()`.', - }, - { - object: 'assert', - property: 'notDeepEqual', - message: 'Use `assert.notDeepStrictEqual()`.', - }, - { - object: 'assert', - property: 'equal', - message: 'Use `assert.strictEqual()` rather than `assert.equal()`.', - }, - { - object: 'assert', - property: 'notEqual', - message: 'Use `assert.notStrictEqual()` rather than `assert.notEqual()`.', - }, - { - property: '__defineGetter__', - message: '__defineGetter__ is deprecated.', - }, - { - property: '__defineSetter__', - message: '__defineSetter__ is deprecated.', - }, - ], - // If this list is modified, please copy changes that should apply to ./lib - // as well to lib/.eslintrc.yaml. - 'no-restricted-syntax': [ - 'error', - { - selector: "CallExpression[callee.name='setTimeout'][arguments.length<2]", - message: '`setTimeout()` must be invoked with at least two arguments.', - }, - { - selector: "CallExpression[callee.name='setInterval'][arguments.length<2]", - message: '`setInterval()` must be invoked with at least two arguments.', - }, - { - selector: 'ThrowStatement > CallExpression[callee.name=/Error$/]', - message: 'Use `new` keyword when throwing an `Error`.', - }, - { - selector: "CallExpression[callee.name='isNaN']", - message: 'Use Number.isNaN() instead of the global isNaN() function.', - }, - ], - /* eslint-enable max-len */ - 'no-return-await': 'error', - 'no-self-assign': 'error', - 'no-self-compare': 'error', - 'no-setter-return': 'error', - 'no-shadow-restricted-names': 'error', - 'no-tabs': 'error', - 'no-template-curly-in-string': 'error', - 'no-this-before-super': 'error', - 'no-throw-literal': 'error', - 'no-trailing-spaces': 'error', - 'no-undef': ['error', { typeof: true }], - 'no-undef-init': 'error', - 'no-unexpected-multiline': 'error', - 'no-unreachable': 'error', - 'no-unsafe-finally': 'error', - 'no-unsafe-negation': 'error', - 'no-unused-labels': 'error', - 'no-unused-vars': ['error', { args: 'none', caughtErrors: 'all' }], - 'no-use-before-define': ['error', { - classes: true, - functions: false, - variables: false, - }], - 'no-useless-backreference': 'error', - 'no-useless-call': 'error', - 'no-useless-catch': 'error', - 'no-useless-concat': 'error', - 'no-useless-constructor': 'error', - 'no-useless-escape': 'error', - 'no-useless-return': 'error', - 'no-void': 'error', - 'no-whitespace-before-property': 'error', - 'no-with': 'error', - 'object-curly-spacing': ['error', 'always'], - 'one-var': ['error', { initialized: 'never' }], - 'one-var-declaration-per-line': 'error', - 'operator-linebreak': ['error', 'after'], - 'padding-line-between-statements': [ - 'error', - { blankLine: 'always', prev: 'function', next: 'function' }, - ], - 'prefer-const': ['error', { ignoreReadBeforeAssign: true }], - 'quotes': ['error', 'single', { avoidEscape: true }], - 'quote-props': ['error', 'consistent'], - 'rest-spread-spacing': 'error', - 'semi': 'error', - 'semi-spacing': 'error', - 'space-before-blocks': ['error', 'always'], - 'space-before-function-paren': ['error', { - anonymous: 'never', - named: 'never', - asyncArrow: 'always', - }], - 'space-in-parens': ['error', 'never'], - 'space-infix-ops': 'error', - 'space-unary-ops': 'error', - 'spaced-comment': ['error', 'always', { - 'block': { 'balanced': true }, - 'exceptions': ['-'], - }], - 'strict': ['error', 'global'], - 'symbol-description': 'error', - 'template-curly-spacing': 'error', - 'unicode-bom': 'error', - 'use-isnan': 'error', - 'valid-typeof': 'error', - - // Custom rules from eslint-plugin-node-core - 'node-core/no-unescaped-regexp-dot': 'error', - 'node-core/no-duplicate-requires': 'error', - }, - globals: { - Atomics: 'readable', - BigInt: 'readable', - BigInt64Array: 'readable', - BigUint64Array: 'readable', - TextEncoder: 'readable', - TextDecoder: 'readable', - queueMicrotask: 'readable', - globalThis: 'readable', - }, -}; diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index e5da96e405628a61f98923ebbc0fe4dd29f25413..0000000000000000000000000000000000000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,101 +0,0 @@ -# Node.js Project Codeowners - -# 1. Codeowners must always be teams, never individuals -# 2. Each codeowner team should contain at least one TSC member -# 3. PRs touching any code with a codeowner must be signed off by at least one -# person on the code owner team. - -# tsc & commcomm - -/.github/CODEOWNERS @nodejs/tsc -/GOVERNANCE.md @nodejs/tsc -/onboarding.md @nodejs/tsc -/CODE_OF_CONDUCT.md @nodejs/tsc @nodejs/community-committee -/CONTRIBUTING.md @nodejs/tsc @nodejs/community-committee -/LICENSE @nodejs/tsc @nodejs/community-committee -/doc/guides/contributing/code-of-conduct.md @nodejs/tsc @nodejs/community-committee -# TODO(mmarchini): the bot doens't have a notion of precedence, that might -# change when move the codeowners code to an Action, at which point we can -# uncomment the line below -# /doc/guides/contributing/*.md @nodejs/tsc -/doc/guides/contributing/issues.md @nodejs/tsc -/doc/guides/contributing/pull-requests.md @nodejs/tsc -/doc/guides/collaborator-guide.md @nodejs/tsc -/doc/guides/offboarding.md @nodejs/tsc -/doc/guides/onboarding-extras.md @nodejs/tsc - -# net - -/deps/cares @nodejs/net -/doc/api/dns.md @nodejs/net -/doc/api/dgram.md @nodejs/net -/doc/api/net.md @nodejs/net -/lib/dgram.js @nodejs/net -/lib/dns.js @nodejs/net -/lib/net.js @nodejs/net @nodejs/quic -/lib/internal/dgram.js @nodejs/net -/lib/internal/dns/* @nodejs/net -/lib/internal/net.js @nodejs/net -/lib/internal/socket_list.js @nodejs/net -/lib/internal/js_stream_socket.js @nodejs/net -/src/cares_wrap.h @nodejs/net -/src/connect_wrap.* @nodejs/net -/src/connection_wrap.* @nodejs/net -/src/node_sockaddr* @nodejs/net -/src/tcp_wrap.* @nodejs/net -/src/udp_wrap.* @nodejs/net - -# tls/crypto - -/lib/internal/crypto/* @nodejs/crypto -/lib/internal/tls.js @nodejs/crypto @nodejs/net -/lib/crypto.js @nodejs/crypto -/lib/tls.js @nodejs/crypto @nodejs/net -/src/node_crypto* @nodejs/crypto -/src/node_crypto_common* @nodejs/crypto @nodejs/quic - -# http - -/deps/llhttp/* @nodejs/http @nodejs/net -/doc/api/http.md @nodejs/http @nodejs/net -/doc/api/http2.md @nodejs/http @nodejs/net -/lib/_http_* @nodejs/http @nodejs/net -/lib/http.js @nodejs/http @nodejs/net -/lib/https.js @nodejs/crypto @nodejs/net @nodejs/http -/src/node_http_common* @nodejs/http @nodejs/http2 @nodejs/quic @nodejs/net -/src/node_http_parser.cc @nodejs/http @nodejs/net - -# http2 - -/deps/nghttp2/* @nodejs/http2 @nodejs/net -/doc/api/http2.md @nodejs/http2 @nodejs/net -/lib/http2.js @nodejs/http2 @nodejs/net -/lib/internal/http2/* @nodejs/http2 @nodejs/net -/src/node_http2* @nodejs/http2 @nodejs/net -/src/node_mem* @nodejs/http2 - -# modules - -/doc/api/modules.md @nodejs/modules -/doc/api/esm.md @nodejs/modules -/doc/api/module.md @nodejs/modules -/doc/api/packages.md @nodejs/modules -/lib/module.js @nodejs/modules -/lib/internal/modules/* @nodejs/modules -/lib/internal/bootstrap/loaders.js @nodejs/modules -/src/module_wrap* @nodejs/modules @nodejs/vm - -# N-API - -/src/node_api* @nodejs/n-api -/src/js_native_api* @nodejs/n-api -/doc/guides/adding-new-napi-api.md @nodejs/n-api -/doc/api/n-api.md @nodejs/n-api - -# WASI -/deps/uvwasi/ @nodejs/wasi -/doc/api/wasi.md @nodejs/wasi -/lib/wasi.js @nodejs/wasi -/src/node_wasi* @nodejs/wasi -/test/wasi/ @nodejs/wasi -/test/fixtures/wasi/ @nodejs/wasi diff --git a/.github/ISSUE_TEMPLATE/1-bug-report.md b/.github/ISSUE_TEMPLATE/1-bug-report.md deleted file mode 100644 index 2a2e94d411fe2a26488cf7d932cbb91301fa6764..0000000000000000000000000000000000000000 --- a/.github/ISSUE_TEMPLATE/1-bug-report.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -name: "\U0001F41B Bug report" -about: Create a report to help us improve - ---- - - - -* **Version**: -* **Platform**: -* **Subsystem**: - -### What steps will reproduce the bug? - - - -### How often does it reproduce? Is there a required condition? - -### What is the expected behavior? - - - -### What do you see instead? - - - -### Additional information - - diff --git a/.github/ISSUE_TEMPLATE/2-feature-request.md b/.github/ISSUE_TEMPLATE/2-feature-request.md deleted file mode 100644 index 0d40bfdd110b931bc1a60de72a8aaee2bb895a2c..0000000000000000000000000000000000000000 --- a/.github/ISSUE_TEMPLATE/2-feature-request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: "\U0001F680 Feature request" -about: Suggest an idea for this project - ---- - - - -**Is your feature request related to a problem? Please describe.** -Please describe the problem you are trying to solve. - -**Describe the solution you'd like** -Please describe the desired behavior. - -**Describe alternatives you've considered** -Please describe alternative solutions or features you have considered. diff --git a/.github/ISSUE_TEMPLATE/3-api-ref-docs-problem.md b/.github/ISSUE_TEMPLATE/3-api-ref-docs-problem.md deleted file mode 100644 index f63d540abaf4e2f62323fded5c70df48f59ac48f..0000000000000000000000000000000000000000 --- a/.github/ISSUE_TEMPLATE/3-api-ref-docs-problem.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -name: "\U0001F4D7 Open an issue regarding the Node.js API reference docs" -about: Let us know about any problematic API reference documents -title: "doc: " -labels: doc ---- - -# 📗 API Reference Docs Problem - - - - - -- **Version**: ✍️ - - - -- **Platform**: ✍️ - - - -- **Subsystem**: ✍️ - -## Location - -_Section of the site where the content exists_ - -Affected URL(s): - -- https://nodejs.org/api/✍️ - -## Description - -_Concise explanation of the problem_ - - - -✍️ - ---- - - - -- [ ] I would like to work on this issue and - submit a pull request. diff --git a/.github/ISSUE_TEMPLATE/4-report-a-flaky-test.md b/.github/ISSUE_TEMPLATE/4-report-a-flaky-test.md deleted file mode 100644 index 544c9d5f47b0f5965c7fb97161717c1bcd69dec6..0000000000000000000000000000000000000000 --- a/.github/ISSUE_TEMPLATE/4-report-a-flaky-test.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: Report a flaky test -about: Report a flaky test in our CI -labels: "CI / flaky test" - ---- - - - -* **Test**: -* **Platform**: -* **Console Output:** -``` -REPLACE ME -``` -* **Build Links**: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 428bbf678a34c3eaead4a60264bfba9814aa6903..0000000000000000000000000000000000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,8 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: ⁉️ Need help with Node.js? - url: https://github.com/nodejs/help - about: Please file an issue in our help repo. - - name: 🌐 Found a problem with nodejs.org beyond the API reference docs? - url: https://github.com/nodejs/nodejs.org/issues/new/choose - about: Please file an issue in the Node.js website repo. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 66efca5cd000e71f00e0ad3421fd16fe7364bc03..0000000000000000000000000000000000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,44 +0,0 @@ - - -##### Checklist - - -- [ ] `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes -- [ ] tests and/or benchmarks are included -- [ ] documentation is changed or added -- [ ] commit message follows [commit guidelines](https://github.com/nodejs/node/blob/master/doc/guides/contributing/pull-requests.md#commit-message-guidelines) - - diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md deleted file mode 100644 index d3af8e681917a0daadd08ebc8354e67f0e203aee..0000000000000000000000000000000000000000 --- a/.github/SUPPORT.md +++ /dev/null @@ -1,27 +0,0 @@ -# Support - -Node.js contributors have limited availability to address general support -questions. Please make sure you are using a [currently-supported version of -Node.js](https://github.com/nodejs/Release#release-schedule). - -When looking for support, please first search for your question in these venues: - -* [Node.js Website](https://nodejs.org/en/), especially the - [API docs](https://nodejs.org/api/) -* [Node.js Help](https://github.com/nodejs/help) -* [Open or closed issues in the Node.js GitHub organization](https://github.com/issues?utf8=%E2%9C%93&q=sort%3Aupdated-desc+org%3Anodejs+is%3Aissue) - -If you didn't find an answer in the resources above, try these unofficial -resources: - -* [Questions tagged 'node.js' on Stack Overflow](https://stackoverflow.com/questions/tagged/node.js) -* [#nodejs](https://openjs-foundation.slack.com/archives/CK9Q4MB53) channel on the OpenJS Foundation Slack ([join here](https://slack-invite.openjsf.org/)) -* [#node.js channel on chat.freenode.net](https://webchat.freenode.net?channels=node.js&uio=d4) -* [Node.js Slack Community](https://node-js.slack.com/) - * To register: [nodeslackers.com](https://www.nodeslackers.com/) - -GitHub issues are for tracking enhancements and bugs, not general support. - -The open source license grants you the freedom to use Node.js. It does not -guarantee commitments of other people's time. Please be respectful and manage -your expectations. diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml deleted file mode 100644 index cb9318ab4ade9f7bdd5c5d920c565280749093d6..0000000000000000000000000000000000000000 --- a/.github/workflows/auto-start-ci.yml +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: Auto Start CI - -on: - schedule: - # Runs every five minutes (fastest the scheduler can run). Five minutes is - # optimistic, it can take longer to run. - # To understand why `schedule` is used instead of other events, refer to - # ./doc/guides/commit-queue.md - - cron: "*/5 * * * *" - -jobs: - startCI: - if: github.repository == 'nodejs/node' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - # Install dependencies - - name: Install jq - run: sudo apt-get install jq -y - - name: Install Node.js - uses: actions/setup-node@v2-beta - with: - node-version: '12' - - name: Install node-core-utils - run: npm install -g node-core-utils - - - name: Set variables - run: | - echo "::set-env name=REPOSITORY::$(echo ${{ github.repository }} | cut -d/ -f2)" - echo "::set-env name=OWNER::${{ github.repository_owner }}" - - # Get Pull Requests - - name: Get Pull Requests - uses: octokit/graphql-action@v2.x - id: get_prs_for_ci - with: - query: | - query prs($owner:String!, $repo:String!) { - repository(owner:$owner, name:$repo) { - pullRequests(labels: ["request-ci"], states: OPEN, last: 100) { - nodes { - number - } - } - } - } - owner: ${{ env.OWNER }} - repo: ${{ env.REPOSITORY }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Setup node-core-utils - run: | - ncu-config set username ${{ secrets.JENKINS_USER }} - ncu-config set token none - ncu-config set jenkins_token ${{ secrets.JENKINS_TOKEN }} - ncu-config set owner ${{ env.OWNER }} - ncu-config set repo ${{ env.REPOSITORY }} - - - name: Start CI - run: ./tools/actions/start-ci.sh ${{ secrets.GITHUB_TOKEN }} ${{ env.OWNER }} ${{ env.REPOSITORY }} $(echo '${{ steps.get_prs_for_ci.outputs.data }}' | jq '.repository.pullRequests.nodes | map(.number) | .[]') diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml deleted file mode 100644 index 7d7a8167308960a87efb054f326c57350837b96b..0000000000000000000000000000000000000000 --- a/.github/workflows/build-windows.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: build-windows - -on: [push, pull_request] - -env: - PYTHON_VERSION: 2.7 - FLAKY_TESTS: dontcare - -jobs: - build-windows: - runs-on: windows-2016 - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@v1 - with: - python-version: ${{ env.PYTHON_VERSION }} - - name: Install deps - run: choco install nasm - - name: Environment Information - run: npx envinfo - - name: Build - run: ./vcbuild.bat diff --git a/.github/workflows/close-stalled.yml b/.github/workflows/close-stalled.yml deleted file mode 100644 index 1834d3ac2e681536750e2bf7fefcb05333860c47..0000000000000000000000000000000000000000 --- a/.github/workflows/close-stalled.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Close stalled issues and PRs -on: - schedule: - - cron: "0 0 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - days-before-close: 30 - stale-pr-label: stalled - stale-issue-label: stalled - close-issue-message: Closing this because it has stalled. Feel free to reopen if this issue is still relevant, or to ping the collaborator who labelled it stalled if you have any questions. - close-pr-message: Closing this because it has stalled. Feel free to reopen if this PR is still relevant, or to ping the collaborator who labelled it stalled if you have any questions. - # used to filter issues to check whether or not should be closed, avoids hitting maximum operations allowed if needing to paginate through all open issues - only-labels: stalled - # max requests it will send per run to the GitHub API before it deliberately exits to avoid hitting API rate limits - operations-per-run: 500 - # deactivates automatic removal of stalled label if issue gets any activity - remove-stale-when-updated: false - # deactivates automatic stale labelling as we prefer to do that manually - days-before-stale: -1 diff --git a/.github/workflows/comment-stalled.yml b/.github/workflows/comment-stalled.yml deleted file mode 100644 index 62bd26f39eb72d9497f399fc19f8db4383afad11..0000000000000000000000000000000000000000 --- a/.github/workflows/comment-stalled.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Comment on issues and PRs when labelled stalled -on: - issues: - types: [labeled] - pull_request_target: - types: [labeled] - -jobs: - staleComment: - runs-on: ubuntu-latest - steps: - - name: Post comment - if: github.event.label.name == 'stalled' - env: - COMMENTS_URL: ${{ github.event.issue.comments_url || github.event.pull_request.comments_url }} - run: | - curl -X POST $COMMENTS_URL \ - -H "Content-Type: application/json" \ - -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - --data '{ "body": "This issue/PR was marked as stalled, it will be automatically closed in 30 days. If it should remain open, please leave a comment explaining why it should remain open." }' diff --git a/.github/workflows/commit-queue.yml b/.github/workflows/commit-queue.yml deleted file mode 100644 index 6f4affe656c9a179ba08c3ba20ceee1f88b175c8..0000000000000000000000000000000000000000 --- a/.github/workflows/commit-queue.yml +++ /dev/null @@ -1,79 +0,0 @@ ---- -# This action requires the following secrets to be set on the repository: -# GH_USER_NAME: GitHub user whose Jenkins and GitHub token are defined below -# GH_USER_TOKEN: GitHub user token, to be used by ncu and to push changes -# JENKINS_TOKEN: Jenkins token, to be used to check CI status - -name: Commit Queue - -on: - # `schedule` event is used instead of `pull_request` because when a - # `pull_request` event is triggered on a PR from a fork, GITHUB_TOKEN will - # be read-only, and the Action won't have access to any other repository - # secrets, which it needs to access Jenkins API. - schedule: - - cron: "*/5 * * * *" - -jobs: - commitQueue: - if: github.repository == 'nodejs/node' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - # A personal token is required because pushing with GITHUB_TOKEN will - # prevent commits from running CI after they land on master. It needs - # to be set here because `checkout` configures GitHub authentication - # for push as well. - token: ${{ secrets.GH_USER_TOKEN }} - - # Install dependencies - - name: Install Node.js - uses: actions/setup-node@v2-beta - with: - node-version: '12' - - name: Install dependencies - run: | - sudo apt-get install jq -y - npm install -g node-core-utils@latest - - - name: Set variables - run: | - echo "::set-env name=REPOSITORY::$(echo ${{ github.repository }} | cut -d/ -f2)" - echo "::set-env name=OWNER::${{ github.repository_owner }}" - - - name: Get Pull Requests - uses: octokit/graphql-action@v2.x - id: get_mergable_pull_requests - with: - query: | - query release($owner:String!,$repo:String!, $base_ref:String!) { - repository(owner:$owner, name:$repo) { - pullRequests(baseRefName: $base_ref, labels: ["commit-queue"], states: OPEN, last: 100) { - nodes { - number - } - } - } - } - owner: ${{ env.OWNER }} - repo: ${{ env.REPOSITORY }} - # Commit queue is only enabled for the default branch on the repository - # TODO(mmarchini): get the default branch programmatically instead of - # assuming `master` - base_ref: "master" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Configure node-core-utils - run: | - ncu-config set branch master - ncu-config set upstream origin - ncu-config set username "${{ secrets.GH_USER_NAME }}" - ncu-config set token "${{ secrets.GH_USER_TOKEN }}" - ncu-config set jenkins_token "${{ secrets.JENKINS_TOKEN }}" - ncu-config set repo "${{ env.REPOSITORY }}" - ncu-config set owner "${{ env.OWNER }}" - - - name: Start the commit queue - run: ./tools/actions/commit-queue.sh ${{ env.OWNER }} ${{ env.REPOSITORY }} ${{ secrets.GITHUB_TOKEN }} $(echo '${{ steps.get_mergable_pull_requests.outputs.data }}' | jq '.repository.pullRequests.nodes | map(.number) | .[]') diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml deleted file mode 100644 index 4453db5c751c7fc257aaf1645c6690115ee71c40..0000000000000000000000000000000000000000 --- a/.github/workflows/linters.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: linters - -on: [push, pull_request] - -env: - PYTHON_VERSION: 3.8 - NODE_VERSION: 10.x - -jobs: - lint-addon-docs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v1 - with: - node-version: ${{ env.NODE_VERSION }} - - name: Environment Information - run: npx envinfo - - name: Lint addon docs - run: NODE=$(which node) make lint-addon-docs - lint-cpp: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@v1 - with: - python-version: ${{ env.PYTHON_VERSION }} - - name: Environment Information - run: npx envinfo - - name: Lint C/C++ files - run: make lint-cpp - lint-md: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v1 - with: - node-version: ${{ env.NODE_VERSION }} - - name: Environment Information - run: npx envinfo - - name: Lint docs - run: | - echo "::add-matcher::.github/workflows/remark-lint-problem-matcher.json" - NODE=$(which node) make lint-md - lint-js: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v1 - with: - node-version: ${{ env.NODE_VERSION }} - - name: Environment Information - run: npx envinfo - - name: Lint JavaScript files - run: NODE=$(which node) make lint-js - lint-py: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@v1 - with: - python-version: ${{ env.PYTHON_VERSION }} - - name: Environment Information - run: npx envinfo - - name: Lint Python - run: | - make lint-py-build || true - NODE=$(which node) make lint-py diff --git a/.github/workflows/misc.yml b/.github/workflows/misc.yml deleted file mode 100644 index 6161326b93865a702694ba569164dd63f634804e..0000000000000000000000000000000000000000 --- a/.github/workflows/misc.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: misc - -on: [push, pull_request] - -env: - NODE_VERSION: 12.x - -jobs: - build-docs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v1 - with: - node-version: ${{ env.NODE_VERSION }} - - name: Environment Information - run: npx envinfo - - name: Build - run: NODE=$(which node) make doc-only - - uses: actions/upload-artifact@v1 - with: - name: docs - path: out/doc - - name: Check links - run: node tools/doc/checkLinks.js . diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml deleted file mode 100644 index 9ff5e9a39d81fac26564094065a3aef7ba190ddf..0000000000000000000000000000000000000000 --- a/.github/workflows/pythonpackage.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Python 3 testing - -on: [push, pull_request] - -jobs: - build: - runs-on: ubuntu-latest - strategy: - fail-fast: false - max-parallel: 1 - matrix: - python-version: [3.8] # [2.7, 3.5, 3.6, 3.7] - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - name: Compile Node.js - run: | - python ./configure.py - make -j2 V=1 - - name: Test JS Suites - run: | - python tools/test.py -j 2 -p dots --report --mode=release --flaky-tests=dontcare default - - name: Test C++ Suites - run: | - make -j1 V=1 test/addons/.buildstamp test/js-native-api/.buildstamp test/node-api/.buildstamp - python tools/test.py -j 2 -p dots --report --mode=release --flaky-tests=dontcare addons js-native-api node-api - - name: Make lint - run: | - make lint-py-build || true - NODE=$(which node) make lint lint-py diff --git a/.github/workflows/remark-lint-problem-matcher.json b/.github/workflows/remark-lint-problem-matcher.json deleted file mode 100644 index cfb281310a9a0f14ebcf6e1c150cf3fbe71f80b0..0000000000000000000000000000000000000000 --- a/.github/workflows/remark-lint-problem-matcher.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "problemMatcher": [ - { - "owner": "remark-lint", - "pattern": [ - { - "regexp": "^(?:\\x1b\\[\\d+m)*(.+?)(?:\\x1b\\[\\d+m)*$", - "file": 1 - }, - { - "regexp": "^\\s+(?:\\d+:\\d+-)?(\\d+):(\\d+)\\s+\\S*(error|warning|info)\\S*\\s+(.+)\\s+(\\S+)\\s+(?:\\S+)$", - "line": 1, - "column": 2, - "severity": 3, - "message": 4, - "code": 5, - "loop": true - } - ] - } - ] -} diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml deleted file mode 100644 index bec9884f6c837c5ff9eeb96f2d1fba92abca2e97..0000000000000000000000000000000000000000 --- a/.github/workflows/test-linux.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: test-linux - -on: [push, pull_request] - -env: - PYTHON_VERSION: 2.7 - FLAKY_TESTS: dontcare - -jobs: - test-linux: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@v1 - with: - python-version: ${{ env.PYTHON_VERSION }} - - name: Environment Information - run: npx envinfo - - name: Build - run: make build-ci -j2 V=1 - - name: Test - run: make run-ci -j2 V=1 TEST_CI_ARGS="-p dots" diff --git a/.github/workflows/test-macos.yml b/.github/workflows/test-macos.yml deleted file mode 100644 index b9794bde31b45a4d13d98f4eb648a4936999f5ba..0000000000000000000000000000000000000000 --- a/.github/workflows/test-macos.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: test-macOS - -on: [push, pull_request] - -env: - PYTHON_VERSION: 2.7 - FLAKY_TESTS: dontcare - -jobs: - test-macOS: - runs-on: macos-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@v1 - with: - python-version: ${{ env.PYTHON_VERSION }} - - name: Environment Information - run: npx envinfo - - name: Build - run: make build-ci -j8 V=1 - - name: Test - run: make run-ci -j8 V=1 TEST_CI_ARGS="-p dots" diff --git a/.mailmap b/.mailmap deleted file mode 100644 index 4597ae9e47f61ddd4977b1518cddc22cbf2d7538..0000000000000000000000000000000000000000 --- a/.mailmap +++ /dev/null @@ -1,471 +0,0 @@ -Aaron Bieber -Aaron Heckmann -Aayush Ahuja aayush.a -Abe Fettig -Abhimanyu Vashisht -Akito Ito -Alejandro Estrada -Alejandro Estrada -Alejandro Oviedo Garcia Alejandro Oviedo -Alex Gilbert agilbert -Alex Hultman -Alex Jordan AJ Jordan -Alex Kocharin -Alex Kocharin -Alexander Marchenko axvm -Alexey Kupershtokh -Alexis Campailla -Alexis Sellier -Alexis Sellier -Alfred Cepeda ALJCepeda -Allen Yonghuang Wang -Amery 子丶言 -Amit Bendor -Anatoli Papirovski -Andreas Offenhaeuser anoff -Andrew Hughes -Andy Bettisworth -Angel Stoyanov atstojanov -Anna Henningsen -Anna Henningsen -Anna Magdalena Kedzierska AnnaMag -Antoine Amara Antoine AMARA -Aria Stewart -Arlo Breault -Arnaud Lefebvre BlackYoup -Artem Zaytsev -Artur G Vieira Artur Vieira -Arnout Kazemier <3rd-Eden@users.noreply.github.com> -Asaf David asafdav2 -Ash Cripps -Ash Cripps -Ash Cripps -Ashley Maceli ashleyraymaceli -Ashok Suthar -Ashutosh Kumar Singh -Atsuo Fukaya -Ben Lugavere blugavere -Ben Noordhuis -Ben Noordhuis -Ben Taber -Benjamin Coe -Benjamin Coe -Benjamin Fleischer Benjamin Fleischer -Benjamin Gruenbaum -Benjamin Gruenbaum -Benjamin Gruenbaum -Benjamin Waters -Bert Belder -Bert Belder -Bert Belder -Beth Griggs Beth Griggs -Beth Griggs Bethany Griggs -Beth Griggs Bethany N Griggs -Beth Griggs BethGriggs -Bidisha Pyne -Brad Decker brad-decker -Brad Larson BradLarson -Bradley Meck Bradley Farias -Brandon Benvie -Brandon Kobel kobelb -Brendan Ashworth -Brent Pendergraft penDerGraft -Brian White -Brian White -Caleb Boyd -Calvin Metcalf -Calvin Metcalf -Caralyn Reisle creisle -Charles -Charles Rudolph -Chen Gang -Chew Choon Keat -Chris Andrews cpandrews8 -Chris Johnson -Chris Young -Christian Clauss -Christian Clauss -Christophe Naud-Dulude Chris911 -Christopher Lenz -Claudio Rodriguez -Colin Ihrig -Corey Martin -Damien Simonin Feugas -Dan Kaplun -Dan Williams Dan.Williams -Daniel Abrão Daniel Abrão -Daniel Bevenius daniel.bevenius -Daniel Berger -Daniel Chcouri <333222@gmail.com> -Daniel Gröber -Daniel Gröber -Daniel Paulino dpaulino -Daniel Pihlström -Daniel Wang firedfox -Daniel Wang firedfox -Danny Nemer -Danny Nemer -Dave Pacheco -David Cai DavidCai -David Mark Clements -David Mark Clements -David Mark Clements -David Siegel -DC dcposch@dcpos.ch -Deepjyoti Mondal -Domenic Denicola -Domenic Denicola -Doug Wade doug.wade -Eduard Burtescu -Einar Otto Stangvik -Elliott Cable -Eric Phetteplace -Ernesto Salazar -Erwin W. Ramadhan erwinwahyura -Eugene Obrezkov ghaiklor -EungJun Yi -Evan Larkin -Evan Lucas -Evan Lucas -FangDun Cai Fangdun Cai (Fundon) -Fangshi He hefangshi -Farid Neshat -Fatah N fatahn -Fedor Indutny -Felix Böhm -Felix Geisendörfer -Felix Geisendörfer -Flandre Scarlet Flandre -Florian Margaine Florian MARGAINE -Forrest L Norvell -Franziska Hinkelmann F. Hinkelmann -Friedemann Altrock -Fuji Goro -Gabriel de Perthuis -Gareth Ellis -Garwah Lam -Geoffrey Bugaisky gbugaisky -Gerhard Stoebich -Gibson Fahnestock -Gil Pedersen -Graham Fairweather Xotic750 -Greg Sabia Tucker -Gregor Martynus Gregor -Guy Bedford guybedford -Halil İbrahim Şener hisener -Hannah Kim heeeunkimmm -Hannes Magnusson -Hendrik Schwalm hschwalm -Hitesh Kanwathirtha -Henry Chin -Herbert Vojčík -Icer Liang -Igor Savin kibertoad -Igor Soarez -Igor Zinkovsky -Imran Iqbal -Ionică Bizău -Isaac Z. Schlueter -Isaac Z. Schlueter -Isaac Z. Schlueter isaacs -Isuru Siriwardana isurusiri -Italo A. Casas -Jackson Tian -Jake Verbaten -Jamen Marzonie Jamen Marz -James Beavers Druotic -James Hartig -James M Snell -James Nimlos JamesNimlos -Jan Krems -Jenna Vuong -JeongHoon Byun Outsider -Jered Schmidt -Jeremiah Senkpiel -Jerry Chin -Jessica Quynh Tran jessicaquynh -Jesús Leganés-Combarro 'piranna Jesús Leganés Combarro "piranna -Joe Shaw -Johan Bergström -Johan Dahlberg -Johann Hofmann -John Barboza jBarz -John Barboza jBarz -John Gardner Alhadis -John McGuirk jmcgui05 -John Musgrave musgravejw -Johnny Ray Austin Johnny Ray -Jon Tippens legalcodes -Jonas Pfenniger -Jonathan Gourlay mrgorbo -Jonathan Ong -Jonathan Persson -Jonathan Rentzsch -Joseph Leon -Jose Luis Vivero jlvivero -Josh Erickson -Josh Hunter jopann -Joshua S. Weinstein -Joyee Cheung joyeecheung -Juan Soto -Julien Klepatch jklepatch -Julien Waechter julien.waechter -Junliang Yan -Junliang Yan -Junshu Okamoto jun-oka -Justin Beckwith -Justin Lee -Jérémy Lal -Jérémy Lal -Juan Sebastian Velez Posada -Kai Sasaki Lewuathe -Karl Skomski -Kat Marchán -Kathy Truong k3kathy -Kazuyuki Yamada -Keith M Wesolowski -Kelsey Breseman -Ke Ding -Khaidi Chu XadillaX -Khaidi Chu -Kimberly Wilber -Kimberly Wilber -Kiyoshi Nomo kysnm -Koichi Kobayashi -Kostiantyn Wandalen -Kris Kowal -Kyle Robinson Young -Lakshmi Swetha Gopireddy LAKSHMI SWETHA GOPIREDDY -Leeseean Chiu -Luke Bayes -Lydia Kats Lydia Katsamberis -Maciej Małecki -MaleDong -Malte-Thorben Bruns -Malte-Thorben Bruns skenqbx -Mandeep Singh -Manil Chowdhurian Chowdhurian -Marcelo Gobelli decareano -Marcin Cieślak -Marcin Cieślak -Marcin Zielinski marzelin -Marti Martz -Martial James Jefferson -Martijn Schrage Oblosys -Masato Ohba -Mary Marchini -Mary Marchini -Mary Marchini -Mary Marchini -Mary Marchini -Matt Lang matt-in-a-hat -Matt Reed matthewreed26 -Matteo Collina -Matthias Bastian piepmatz -Mathias Buus -Mathias Pettersson -Matthew Lye -Matthew Turner -Maurice Hayward maurice_hayward -Michael Bernstein -Michael Dawson -Michaël Zasso -Michael-Rainabba Richardson rainabba -Michał Gołębiowski-Owczarek -Micheil Smith -Micleusanu Nicu -Miguel Angel Asencio Hurtado maasencioh -Mikael Bourges-Sevenier -Mike Kaufman -Minqi Pan P.S.V.R -Minuk Park -Minwoo Jung JungMinu -Minwoo Jung -Minwoo Jung -Miroslav Bajtoš -Mitar Milutinovic -Myles Borins -Myles Borins -Myles Borins -Nam Nguyen -Nebu Pookins -Netto Farah nettofarah -Nicholas Kinsey -Nick Soggin -Nikolai Vavilov -Nils Kuhnhenn -Noah Rose Ledesma Noah Rose -Noah Rose Ledesma -Oluwaseun Omoyajowo -Onne Gorter -Paul Querna -Pedro Lima Pedro Victor -Pedro Lima Pedro lima -Peng Lyu rebornix -Peter Flannery -Peter Marton -Peter Paugh Peter -Phillip Johnsen -Prateek Singh -Rachel White rachelnicole -Ratikesh Misra -Ravindra Barthwal Ravindra barthwal -Ray Morgan -Ray Solomon -Raymond Feng -Rebecca Turner -Refael Ackermann -Reza Akhavan jedireza -Ricardo Sánchez Gregorio richnologies -Richard Lau -Rick Olson -Rob Adelmann -Rob Adelmann adelmann -Robert Nagy Robert Nagy -Rod Machen -Roman Klauke -Roman Reiss -Ron Korving -Ron Korving ronkorving -Ruben Bridgewater -Ruben Bridgewater -Russell Dempsey -Ryan Dahl -Ryan Emery -Ryan Mahan -Ryan Scheel Ryan Scheel -Ryan Scheel Ryan Scheel (Havvy) -Saad Quadri saadq -Sagir Khan -Sakthipriyan Vairamani -Sam Mikes -Sam P Gallagher-Bishop -Sam Shull -Sam Shull -Sam Roberts -Samantha Sample = <=> -Sambasiva Suda -San-Tai Hsu -Santiago Gimeno -Sarah Meyer sarahmeyer -Sartrey Lee sartrey -Saúl Ibarra Corretgé -Shobhit Chittora -Scott Blomquist -Segu Riluvan -Sergey Kryzhanovsky -Shannen Saez -Shaopeng Zhang szhang351 -Shigeki Ohtsu -Shigeki Ohtsu -Shivang Saxena -Shiya Luo shiya -Siddharth Mahendraker -Simon Willison -Siobhan O'Donovan justshiv -Siyuan Gao r1cebank -solebox solebox <5013box@gmail.com> -Sreepurna Jasti -Sreepurna Jasti sreepurnajasti -Sreepurna Jasti sreepurnajasti -Stanislav Opichal -Stefan Budeanu -Stefan Bühler -Stephen Belanger -Steve Mao -Steven R. Loomis -Stewart X Addison Stewart Addison -Stewart X Addison sxa555 -Stewart X Addison Stewart X Addison -Suraiya Hameed suraiyah -Suramya shah ss22ever -Surya Panikkal surya panikkal -Surya Panikkal suryagh -Taehee Kang hugnosis -Tanuja-Sawant -Taylor Woll taylor.woll -Thomas Watson Steen Thomas Watson -Timothy O. Peters -Timur Shemsedinov tshemsedinov -Ting Shao -Toby Farley tobyfarley -Toby Stableford toboid -Todd Kennedy -TJ Holowaychuk -TJ Holowaychuk -Tadashi SAWADA -Takahiro ANDO -Tarun Batra Tarun -Ted Young -Teppei Sato -Theotime Poisseau -Thomas Hunter II -Thomas Lee -Thomas Reggi -Tierney Cyren &! (bitandbang) -Tierney Cyren bitandbang -Tim Caswell -Tim Price -Tim Smart -Tim Smart -Timothy Leverett Timothy -Tobias Nießen -Tom Atkinson -Tom Atkinson -Tom Hughes -Tom Hughes-Croucher -Tom Purcell tpurcell -Tom White -Tomoki Okahana umatoma -Tracy Hinds Tracy -Travis Meisenheimer -Trevor Burnham -Trivikram Kamat <16024985+trivikr@users.noreply.github.com> -Tyler Larson -Ujjwal Sharma -Viktor Karpov vitkarpov -Vincent Voyer -Vladimir de Turckheim -vsemozhetbyt Vse Mozhet Byt -Wang Xinyong -Weijia Wang <381152119@qq.com> -Weijia Wang <381152119@qq.com> -Weijia Wang <381152119@qq.com> -Wei-Wei Wu -Willi Eggeling -Will Hayslett -Wilson Lin -Wyatt Preul geek -Xavier J Ortiz -xiaoyu <306766053@qq.com> Poker <306766053@qq.com> -Yael Hermon -Yazhong Liu Yazhong Liu -Yazhong Liu Yorkie -Yazhong Liu Yorkie -Yazhong Liu Yorkie Liu -Yingchen Xue -Yongsheng Zhang -Yongsheng Zhang <17367077526@163.com> -Yongsheng Zhang -Yoshihiro KIKUCHI -Yosuke Furukawa -Yuichiro MASUI -Yuta Hiroto abouthiroppy -Zach Bjornson -Zachary Scott -Zachary Vacura -Zoran Tomicic -Сковорода Никита Андреевич ChALkeR -隋鑫磊 - -# These people didn't contribute patches to node directly, -# but we've landed their v8 patches in the node repository: -Daniel Clifford -Erik Corry -Jakob Kummerow -Kevin Millikin -Lasse R.H. Nielsen -Michael Starzinger -Toon Verwaest -Vyacheslav Egorov -Yang Guo diff --git a/AUTHORS b/AUTHORS index a61c4010be5d3c3904bb058067fdc10732a21932..213c03ba9f32a8120b581885ab55187ea4a79445 100644 --- a/AUTHORS +++ b/AUTHORS @@ -504,7 +504,7 @@ David Chan Alexis Campailla Nikolai Vavilov Michael Ridgway -Yazhong Liu +Yorkie Liu Gabriel Falkenberg Kai Groner Lalit Kapoor @@ -587,7 +587,7 @@ Ed Umansky Maurice Butler John Albietz Andrew Oppenlander -Julien Gilli +Julien Gilli Gabriel Wicke Jakob Gillich Lucio M. Tato @@ -652,7 +652,7 @@ Ben Burns Julian Duque Teppei Sato Rudi Cilibrasi -Tim Ruffles +Tim Ruffles CGavrila Aleksey Smolenchuk Caitlin Potter @@ -784,7 +784,7 @@ Sven Slootweg Dmitry Vasilyev Malcolm Ahoy Imran Iqbal -Stewart X Addison +Stewart X Addison Matt Harrison Christopher J. Brody Salman Aljammaz @@ -808,7 +808,7 @@ David Boivin Liang-Chi Hsieh Timothy Gu Fábio Santos -Myles Borins +Myles Borins Jonas Dohse Коренберг Марк Caleb Boyd @@ -995,6 +995,7 @@ Doug Wade Mohsen Marian Justin Sprigg +Eugene Ostroukhov Bryan Hughes Ehsan Akhgari Ingvar Stepanyan @@ -1168,7 +1169,7 @@ Yoshiya Hinosawa Syuhei Kobayashi YutamaKotaro MURAKAMI Masahiko -Thomas Watson Steen +Thomas Watson Daijiro Yamada Kelvin Jin Mitsuo Utano @@ -1204,7 +1205,7 @@ Daniel Pittman Ian White Chris Bystrek Christine Hong -Oscar Martinez +Oscar Martinez Aileen David Bradford stokingerl @@ -1254,7 +1255,7 @@ J Scott Chapman Erez Weiss Scott Smereka Fabrice Tatieze -Uttam Pawar +Uttam Pawar Ben Lugavere Punit Buch mark hughes @@ -1270,12 +1271,11 @@ amrios Chris Henney Yojan Shrestha Rodrigo Palma -Sam Shull Michael-Bryant Choa CodeVana Daniel Sims Diego Paez -Paul Graham +Paul Graham Jared Young vazina robertson Bruce Lai @@ -1324,7 +1324,6 @@ malen Kailean Courtney Fumiya KARASAWA John Barboza -Paul Graham Nate Chris Story Matthew Garrett @@ -1481,7 +1480,6 @@ Tony Rice Olivier Martin jeyanthinath Aditya Anand -Oscar Martinez cool88 Steven Lehn Łukasz Szewczak @@ -1489,12 +1487,12 @@ Madara Uchiha Gil Tayar Glenn Schlereth Artur G Vieira -Gerhard Stoebich +Gerhard Stöbich Sreepurna Jasti Rafael Fragoso Andrei Cioromila Frank Lanitz -Khaidi Chu +Khaidi Chu Akshay Iyer Rick Bullotta Rajaram Gaunker @@ -1543,7 +1541,7 @@ lena Azard <330815461@qq.com> Ezequiel Garcia Kyle Farnung -Weijia Wang <381152119@qq.com> +Weijia Wang Nataly Shrits Jaime Bernardo Natanael Log @@ -1620,7 +1618,6 @@ Mandeep Singh Prakash Palaniappan Keita Akutsu Michael Albert -Eugene Ostroukhov Vishal Bisht Griffith Tchenpan Oky Antoro @@ -1664,7 +1661,7 @@ Miguel Martins Yury Popov George Bezerra Benjamin Coe -Tim Costa +Tim Costa Rahul Mishra Damien O'Reilly Tuan Anh Tran @@ -2116,7 +2113,7 @@ dustinnewman98 Oluwaseun Omoyajowo Wilson Lin Eric Bickle -Ujjwal Sharma +Ujjwal Sharma Wei-Wei Wu Prateek Singh Ken Lin @@ -2270,7 +2267,6 @@ prayag21 <10997858+prayag21@users.noreply.github.com> Bruno Pinho Anto Aravinth Helio Frota <00hf11@gmail.com> -Tim Ruffles Jacob Page sagulati conectado @@ -2335,7 +2331,6 @@ Sintendo Nitish Sakhawalkar André Cruz Josh Broomfield -Julien Gilli Umang Raghuvanshi Duarte David Aleksey Chemakin @@ -2499,14 +2494,14 @@ Jerome Covington Rob Reynolds warnerp18 chux0519 -Tadhg Creedon +Tadhg Creedon Petar Dodev mzucker Morgan Roderick Remy Parzinski Roland Broekema Florin-Daniel BÎLBÎE -Robin Drexler +Robin Drexler ZauberNerd G. Carcaci Jackson Chui <14085209+haiXchuus@users.noreply.github.com> @@ -2583,7 +2578,6 @@ rahulshuklab4u gengjiawen Maya Anilson Mrityunjoy Saha -Robin Drexler Prabu Subra Abhishek Dixit Sarath Govind K K @@ -2621,7 +2615,6 @@ grimrose timothy searcy nakashima /Jesse -Tadhg Creedon exoego sigwyg pastak @@ -2673,7 +2666,6 @@ Amit Zur Thang Tran Kai Abhishek Agarwal -Uttam Pawar Jon Kunkee Mukul Khanna Jarrod Connolly @@ -2682,7 +2674,7 @@ Alexander Sattelmaier Avi ד Thomas Aymen Naghmouchi -himself65 +himself65 Geir Hauge Patrick Gansterer Nicolas Moteau @@ -2732,7 +2724,6 @@ imhype <543717080@qq.com> ptaylor Boxuan Li Aditya Pratap Singh -Eugene Ostroukhov Preveen Padmanabhan Benjamin Ki Daniel Nalborczyk @@ -2740,7 +2731,6 @@ Alba Mendez zero1five Gaelan Jacob -himself65 Dan Beglin Anish Asrani teams2ua @@ -2792,13 +2782,11 @@ Juan Roa Ivan Villa Caleb ツ Everett Miken -Eugene Ostroukhov Gabriela Niño Mike MacCana Tim Baverstock Walle Cyril -Xu Meng -Samuel Attard +Xu Meng Ben L. Titzer Ojasvi Monga Shajan Jacob @@ -2848,7 +2836,7 @@ Javier Ledezma Marian Rusnak <4215517+marian-r@users.noreply.github.com> Jenia Anton Gerasimov -rickyes +rickyes <0x19951125@gmail.com> Simon A. Eugster TATSUNO Yasuhiro Robert Jensen @@ -2894,7 +2882,6 @@ Albert Wang Kenza Houmani mkdorff xefimx -garygsc Susana Ferreira Xavier Redondo Duncan Healy @@ -2964,7 +2951,6 @@ Rosen Penev Jeremy Albright Giovanni Campagna Donggeon Lim -Tim Costa rene.herrmann Derek Lewis Kirill Ponomarev @@ -3003,7 +2989,7 @@ Conor ONeill tsabolov Swagat Konchada Yuhanun Citgez -Danielle Adams +Danielle Adams Andrey Pechkurov Jeff simon @@ -3017,13 +3003,11 @@ Andrew Neitsch RamanandPatil forfun414 David Gilbertson -Sergey Zelenov Eric Bickle Joe Pea ExE Boss <3889017+ExE-Boss@users.noreply.github.com> Mateusz Krawczuk Jonathan MERCIER -Ujjwal Sharma Jichan Hassaan Pasha Eric Dobbertin @@ -3036,7 +3020,6 @@ Sk Sajidul Kadir Bartlomiej Brzozowski Saajan Yash Ladha -Xu Meng Alex R Hachimi Aa (Sfeir) Daniel Estiven Rico Posada @@ -3085,7 +3068,6 @@ Ben Bucksch Eli Schwartz Maciej Kacper Jagiełło Tom Nagle -rickyes sapics Sagar Jadhav Dennis Ameling @@ -3139,5 +3121,196 @@ Shigma <33423008+Shigma@users.noreply.github.com> atian25@qq.com Amila Welihinda schamberg97 <50446906+schamberg97@users.noreply.github.com> +DrunkenPoney +Christoph Tavan +Clark Kozak +Michael Auderer +Linn Dahlgren +Ikko Ashimine +Anatoly Korniltsev +Victor Antonio Barzana Crespo +Matthieu Larcher +anlex N <1293006794@qq.com> +ThakurKarthik +Aastha Gupta +Yohanan Baruchel +Dmitry Gozman +Daniil Demidovich +Hussaina Begum Nandyala +Danny Sonnenschein +Sourav Shaw +H Adinarayana +lucasg +Brian 'bdougie' Douglas +Lee, Bonggi +Momtchil Momtchev +Josh Dague +Vincent Boivin +ax1 <16510021+ax1@users.noreply.github.com> +Shubham Parihar <51517103+iShibi@users.noreply.github.com> +Darshan Sen +Matthew Francis Brunetti +Chris Opperwall +Takuya Noguchi +tyankatsu +Ben Turner <7623873+ben-turner@users.noreply.github.com> +Bryan Field +krank2me +masx200 <34191203+masx200@users.noreply.github.com> +Baruch Odem (Rothkoff) +Mattias Runge-Broberg +Dmitry Semigradsky +Ole André Vadla Ravnås +Aleksandr Krutko +Brian Ingenito <28159742+bingenito@users.noreply.github.com> +FeelyChau +Darcy Clarke +mayank agarwal +woodfairy +Nikola Glavina +Rishabh Mehan +Anna Henningsen +Andrew Casey +Anders Kaseorg +Hollow Man +nlf +naortedgi +Narasimha Prasanna HN +Zijian Liu +inokawa <48897392+inokawa@users.noreply.github.com> +Michael Bashurov +Moshe vilner +Nicolai Stange +kai zhu +FrankQiu +Rock +Chinmoy Chakraborty +Maksym Baranovskyi +Michael Chen <4326639+mcgitty@users.noreply.github.com> +François-Denis Gonthier +Dr +Nitzan Uziely +Adrien Maret +Thiago Padilha +Joseph Hackman +Pranshu Jethmalani +Rohan Chougule +Mohamed Kamagate +Ajay Poshak +Isaac Levy +ugultopu +Nicholas Schamberg +Dimitris Halatsis +Mattia Pontonio <44380480+mattiapontonio@users.noreply.github.com> +Milad Fa +Emil Sivervik +alexbs +Ian Storm Taylor +Carlos Fuentes +Tyler Ang-Wanek +Matthew Mario Di Pasquale +ttzztztz +Romuald Brillout +Dave Cardwell +Akash Negi <55234838+NegiAkash890@users.noreply.github.com> +James Addison +Fabian Cook +Kalvin Vasconcellos +marsonya +Qingyu Deng +Matin Zadehdolatabad +Daniel Clark +Sajal Khandelwal +Cheng Liu +Utku Gultopu +Jay Tailor <60511316+JayvaScript@users.noreply.github.com> +Greg Ziskind +Dan Čermák +Vít Ondruch +humanwebpl <58517331+humanwebpl@users.noreply.github.com> +Dawid Rusnak +obi-el +Merlin Luntke <22600241+Luntke@users.noreply.github.com> +Marko Kaznovac +Gabriel Schulhof +Ian Kerins +dbachko +Mattias Buelens +Dylan Elliott +Wassim Chegham +simov +wwwzbwcom +David Glasser +pezhmanparsaee +Hassaan Pasha +Darkripper214 +Anu Pasumarthy +HiroyukiYagihashi +Arkerone +Voltrex +ycjcl868 <45808948@qq.com> +Serkan Özel +Ferdi +eladkeyshawn +luyahan +Simon Knott +Siddharth +Cactysman +David Brownman +Michael Rommel +Chengzhong Wu +Andres +Jayden Seric +divlo +Rohit Gohri +Giora Guttsait +takayama +Rafael Gonzaga +Arnold Zokas +Nils Dralle +Jesse Chan +helloyou2012 +MrJithil +Rodolfo Carvalho +Jordan Baczuk +moander +Hitesh Sharma +Andreas Schwab +Moritz Kneilmann +fisker Cheung +Issam E. Maghni +TodorTotev <51530311+TodorTotev@users.noreply.github.com> +Wael Almattar +yotamselementor <83912471+yotamselementor@users.noreply.github.com> +pengjie <37610029@qq.com> +Philip +julianjany <54538266+julianjany@users.noreply.github.com> +bl-ue +npm-robot +Shaun Keys +Simone Busoli +Derevianchenko Maksym <32910350+maks-white@users.noreply.github.com> +RA80533 <32469082+RA80533@users.noreply.github.com> +Mao Wtm +Houssem Chebab +Davidson Francis +Rohan Sharma +AkshayK +FrankEntriken <42781627+FrankEntriken@users.noreply.github.com> +Cyrille Bourgois +Jacob <3012099+JakobJingleheimer@users.noreply.github.com> +ejose19 <8742215+ejose19@users.noreply.github.com> +Tobias Koppers +Makoto Kato +foxxyz +LitoMore +nerdthatnoonelikes +Nikita Rykov <40735471+angrymouse@users.noreply.github.com> +Benjamin Mayr +Lew Gordon +Mestery +Himadri Ganguly +Howie Zhao +Luan Devecchi # Generated by tools/update-authors.js diff --git a/BSDmakefile b/BSDmakefile index b2f36fa28720f182692f6670bb24fbcc7ebf7a0d..3994ab9efd9a4d2f8c3544ab84c93fedafe75258 100644 --- a/BSDmakefile +++ b/BSDmakefile @@ -3,7 +3,7 @@ FLAGS=${.MAKEFLAGS:C/\-J ([0-9]+,?)+//W} all: .DEFAULT .DEFAULT: - @which gmake > /dev/null 2>&1 ||\ + @command -v gmake > /dev/null 2>&1 ||\ (echo "GMake is required for node.js to build.\ Install and try again" && exit 1) @gmake ${.FLAGS} ${.TARGETS} diff --git a/BUILDING.md b/BUILDING.md index 85d8d1ffa159ecb2df93d3b45246ec911ae6fe8c..5d2459eb76548fb4b7ea481ef913d652bcfb13fa 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -8,7 +8,7 @@ If you can reproduce a test failure, search for it in the [Node.js issue tracker](https://github.com/nodejs/node/issues) or file a new issue. -## Table of Contents +## Table of contents * [Supported platforms](#supported-platforms) * [Input](#input) @@ -24,11 +24,13 @@ file a new issue. * [Unix prerequisites](#unix-prerequisites) * [macOS prerequisites](#macos-prerequisites) * [Building Node.js](#building-nodejs-1) + * [Installing Node.js](#installing-nodejs) * [Running Tests](#running-tests) * [Running Coverage](#running-coverage) * [Building the documentation](#building-the-documentation) * [Building a debug build](#building-a-debug-build) * [Building an ASAN build](#building-an-asan-build) + * [Speeding up frequent rebuilds when developing](#speeding-up-frequent-rebuilds-when-developing) * [Troubleshooting Unix and macOS builds](#troubleshooting-unix-and-macos-builds) * [Windows](#windows) * [Prerequisites](#prerequisites) @@ -37,21 +39,23 @@ file a new issue. * [Building Node.js](#building-nodejs-2) * [Android/Android-based devices (e.g. Firefox OS)](#androidandroid-based-devices-eg-firefox-os) * [`Intl` (ECMA-402) support](#intl-ecma-402-support) - * [Default: `small-icu` (English only) support](#default-small-icu-english-only-support) * [Build with full ICU support (all locales supported by ICU)](#build-with-full-icu-support-all-locales-supported-by-icu) * [Unix/macOS](#unixmacos) * [Windows](#windows-1) - * [Building without Intl support](#building-without-intl-support) + * [Trimmed: `small-icu` (English only) support](#trimmed-small-icu-english-only-support) * [Unix/macOS](#unixmacos-1) * [Windows](#windows-2) - * [Use existing installed ICU (Unix/macOS only)](#use-existing-installed-icu-unixmacos-only) - * [Build with a specific ICU](#build-with-a-specific-icu) + * [Building without Intl support](#building-without-intl-support) * [Unix/macOS](#unixmacos-2) * [Windows](#windows-3) + * [Use existing installed ICU (Unix/macOS only)](#use-existing-installed-icu-unixmacos-only) + * [Build with a specific ICU](#build-with-a-specific-icu) + * [Unix/macOS](#unixmacos-3) + * [Windows](#windows-4) * [Building Node.js with FIPS-compliant OpenSSL](#building-nodejs-with-fips-compliant-openssl) * [Building Node.js with external core modules](#building-nodejs-with-external-core-modules) - * [Unix/macOS](#unixmacos-3) - * [Windows](#windows-4) + * [Unix/macOS](#unixmacos-4) + * [Windows](#windows-5) * [Note for downstream distributors of Node.js](#note-for-downstream-distributors-of-nodejs) ## Supported platforms @@ -105,10 +109,12 @@ platforms. This is true regardless of entries in the table below. | GNU/Linux | armv6 | kernel >= 4.14, glibc >= 2.24 | Experimental | Downgraded as of Node.js 12 | | GNU/Linux | ppc64le >=power8 | kernel >= 3.10.0, glibc >= 2.17 | Tier 2 | e.g. Ubuntu 16.04 [1](#fn1), EL 7 [2](#fn2) | | GNU/Linux | s390x | kernel >= 3.10.0, glibc >= 2.17 | Tier 2 | e.g. EL 7 [2](#fn2) | -| Windows | x64, x86 (WoW64) | >= Windows 7/2008 R2/2012 R2 | Tier 1 | [4](#fn4),[5](#fn5) | -| Windows | x86 (native) | >= Windows 7/2008 R2/2012 R2 | Tier 1 (running) / Experimental (compiling) [6](#fn6) | | -| Windows | arm64 | >= Windows 10 | Experimental | | +| Windows | x64, x86 (WoW64) | >= Windows 8.1/2012 R2 | Tier 1 | [4](#fn4),[5](#fn5) | +| Windows | x86 (native) | >= Windows 8.1/2012 R2 | Tier 1 (running) / Experimental (compiling) [6](#fn6) | | +| Windows | x64, x86 | Windows Server 2012 (not R2) | Experimental | | +| Windows | arm64 | >= Windows 10 | Tier 2 (compiling) / Experimental (running) | | | macOS | x64 | >= 10.11 | Tier 1 | | +| macOS | arm64 | >= 11 | Experimental | | | SmartOS | x64 | >= 18 | Tier 2 | | | AIX | ppc64be >=power7 | >= 7.2 TL02 | Tier 2 | | | FreeBSD | x64 | >= 11 | Experimental | Downgraded as of Node.js 12 [7](#fn7) | @@ -157,26 +163,25 @@ Depending on the host platform, the selection of toolchains may vary. | ---------------- | -------------------------------------------------------------- | | Linux | GCC >= 6.3 | | Windows | Visual Studio >= 2017 with the Windows 10 SDK on a 64-bit host | -| macOS | Xcode >= 8 (Apple LLVM >= 8) | +| macOS | Xcode >= 10 (Apple LLVM >= 10) | ### Official binary platforms and toolchains Binaries at are produced on: -| Binary package | Platform and Toolchain | -| --------------------- | ------------------------------------------------------------------------ | -| aix-ppc64 | AIX 7.1 TL05 on PPC64BE with GCC 6 | -| darwin-x64 (and .pkg) | macOS 10.15, Xcode Command Line Tools 11 with -mmacosx-version-min=10.10 | -| linux-arm64 | CentOS 7 with devtoolset-6 / GCC 6 | -| linux-armv7l | Cross-compiled on Ubuntu 16.04 x64 with [custom GCC toolchain](https://github.com/rvagg/rpi-newer-crosstools) | -| linux-ppc64le | CentOS 7 with devtoolset-6 / GCC 6 [7](#fn7) | -| linux-s390x | RHEL 7 with devtoolset-6 / GCC 6 [7](#fn7) | -| linux-x64 | CentOS 7 with devtoolset-6 / GCC 6 [7](#fn7) | -| sunos-x64 | SmartOS 18 with GCC 7 | -| win-x64 and win-x86 | Windows 2012 R2 (x64) with Visual Studio 2017 | - -7: The Enterprise Linux devtoolset-6 allows us to compile -binaries with GCC 6 but linked to the glibc and libstdc++ versions of the host +| Binary package | Platform and Toolchain | +| --------------------- | ------------------------------------------------------------------------------------------------------------- | +| aix-ppc64 | AIX 7.1 TL05 on PPC64BE with GCC 6 | +| darwin-x64 (and .pkg) | macOS 10.15, Xcode Command Line Tools 11 with -mmacosx-version-min=10.13 | +| linux-arm64 | CentOS 7 with devtoolset-8 / GCC 8 [8](#fn8) | +| linux-armv7l | Cross-compiled on Ubuntu 18.04 x64 with [custom GCC toolchain](https://github.com/rvagg/rpi-newer-crosstools) | +| linux-ppc64le | CentOS 7 with devtoolset-8 / GCC 8 [8](#fn8) | +| linux-s390x | RHEL 7 with devtoolset-8 / GCC 8 [8](#fn8) | +| linux-x64 | CentOS 7 with devtoolset-8 / GCC 8 [8](#fn8) | +| win-x64 and win-x86 | Windows 2012 R2 (x64) with Visual Studio 2019 | + +8: The Enterprise Linux devtoolset-8 allows us to compile +binaries with GCC 8 but linked to the glibc and libstdc++ versions of the host platforms (CentOS 7 / RHEL 7). Therefore, binaries produced on these systems are compatible with glibc >= 2.17 and libstdc++ >= 6.0.20 (`GLIBCXX_3.4.20`). These are available on distributions natively supporting GCC 4.9, such as @@ -213,27 +218,18 @@ Supported platforms and toolchains change with each major version of Node.js. This document is only valid for the current major version of Node.js. Consult previous versions of this document for older versions of Node.js: -* [Node.js 13](https://github.com/nodejs/node/blob/v13.x/BUILDING.md) +* [Node.js 14](https://github.com/nodejs/node/blob/v14.x/BUILDING.md) * [Node.js 12](https://github.com/nodejs/node/blob/v12.x/BUILDING.md) * [Node.js 10](https://github.com/nodejs/node/blob/v10.x/BUILDING.md) -* [Node.js 8](https://github.com/nodejs/node/blob/v8.x/BUILDING.md) ## Building Node.js on supported platforms ### Note about Python 2 and Python 3 -The Node.js project uses Python as part of its build process and has -historically only been Python 2 compatible. - -Python 2 will reach its _End-of-Life_ at the end of 2019 at which point the -interpreter will cease receiving updates. See -for more information. - -The Node.js project is in the process of transitioning its Python code to -Python 3 compatibility. Installing both versions of Python while building -and testing Node.js allows developers and end users to test, benchmark, -and debug Node.js running on both versions to ensure a smooth and complete -transition before the year-end deadline. +The Node.js project supports both Python 3 and Python 2 for building. +If both are installed Python 3 will be used. If only Python 2 is available +it will be used instead. When possible we recommend that you build and +test with Python 3. ### Unix and macOS @@ -243,7 +239,7 @@ transition before the year-end deadline. * GNU Make 3.81 or newer * Python (see note above) * Python 2.7 - * Python 3.5, 3.6, and 3.7 are experimental. + * Python 3.5, 3.6, 3.7, 3.8, 3.9 or 3.10 (see note above) Installation via Linux package manager can be achieved with: @@ -255,14 +251,12 @@ Installation via Linux package manager can be achieved with: FreeBSD and OpenBSD users may also need to install `libexecinfo`. -Python 3 users may also need to install `python3-distutils`. - #### macOS prerequisites -* Xcode Command Line Tools >= 8 for macOS +* Xcode Command Line Tools >= 10 for macOS * Python (see note above) * Python 2.7 - * Python 3.5, 3.6, and 3.7 are experimental. + * Python 3.6, 3.7, 3.8, 3.9, or 3.10 (see note above) macOS users can install the `Xcode Command Line Tools` by running `xcode-select --install`. Alternatively, if you already have the full Xcode @@ -282,11 +276,6 @@ $ ./configure $ make -j4 ``` -If you run into a `No module named 'distutils.spawn'` error when executing -`./configure`, please try `python3 -m pip install --upgrade setuptools` or -`sudo apt install python3-distutils -y`. -For more information, see . - The `-j4` option will cause `make` to run 4 simultaneous compilation jobs which may reduce build time. For more information, see the [GNU Make Documentation](https://www.gnu.org/software/make/manual/html_node/Parallel.html). @@ -305,7 +294,15 @@ project's root directory. $ sudo ./tools/macos-firewall.sh ``` -#### Running Tests +#### Installing Node.js + +To install this version of Node.js into a system directory: + +```bash +[sudo] make install +``` + +#### Running tests To verify the build: @@ -315,7 +312,7 @@ $ make test-only At this point, you are ready to make code changes and re-run the tests. -If you are running tests before submitting a Pull Request, the recommended +If you are running tests before submitting a pull request, the recommended command is: ```console @@ -375,7 +372,7 @@ You can use [node-code-ide-configs](https://github.com/nodejs/node-code-ide-configs) to run/debug tests, if your IDE configs are present. -#### Running Coverage +#### Running coverage It's good practice to ensure any code you add or change is covered by tests. You can do so by running the test suite with coverage enabled: @@ -386,28 +383,32 @@ $ make coverage ``` A detailed coverage report will be written to `coverage/index.html` for -JavaScript coverage and to `coverage/cxxcoverage.html` for C++ coverage -(if you only want to run the JavaScript tests then you do not need to run -the first command `./configure --coverage`). - -_Generating a test coverage report can take several minutes._ +JavaScript coverage and to `coverage/cxxcoverage.html` for C++ coverage. -To collect coverage for a subset of tests you can set the `CI_JS_SUITES` and -`CI_NATIVE_SUITES` variables (to run specific suites, e.g., `child-process`, in -isolation, unset the opposing `_SUITES` variable): +If you only want to run the JavaScript tests then you do not need to run +the first command (`./configure --coverage`). Run `make coverage-run-js`, +to execute JavaScript tests independently of the C++ test suite: ```text -$ CI_JS_SUITES=child-process CI_NATIVE_SUITES= make coverage +$ make coverage-run-js ``` -The above command executes tests for the `child-process` subsystem and -outputs the resulting coverage report. +If you are updating tests and want to collect coverage for a single test file +(e.g. `test/parallel/test-stream2-transform.js`): -Alternatively, you can run `make coverage-run-js`, to execute JavaScript tests -independently of the C++ test suite: +```text +$ make coverage-clean +$ NODE_V8_COVERAGE=coverage/tmp python tools/test.py test/parallel/test-stream2-transform.js +$ make coverage-report-js +``` + +You can collect coverage for the entire suite of tests for a given subsystem +by providing the name of a subsystem: ```text -$ CI_JS_SUITES=fs CI_NATIVE_SUITES= make coverage-run-js +$ make coverage-clean +$ NODE_V8_COVERAGE=coverage/tmp python tools/test.py -J --mode=release child-process +$ make coverage-report-js ``` The `make coverage` command downloads some tools to the project root directory. @@ -464,12 +465,6 @@ To test if Node.js was built correctly: ./node -e "console.log('Hello from Node.js ' + process.version)" ``` -To install this version of Node.js into a system directory: - -```bash -[sudo] make install -``` - #### Building a debug build If you run into an issue where the information provided by the JS stack trace @@ -525,6 +520,29 @@ $ ./configure --debug --enable-asan && make -j4 $ make test-only ``` +#### Speeding up frequent rebuilds when developing + +If you plan to frequently rebuild Node.js, especially if using several branches, +installing `ccache` can help to greatly reduce build times. Set up with: +```console +$ sudo apt install ccache # for Debian/Ubuntu, included in most Linux distros +$ ccache -o cache_dir= +$ ccache -o max_size=5.0G +$ export CC="ccache gcc" # add to your .profile +$ export CXX="ccache g++" # add to your .profile +``` +This will allow for near-instantaneous rebuilds even when switching branches. + +When modifying only the JS layer in `lib`, it is possible to externally load it +without modifying the executable: +```console +$ ./configure --node-builtin-modules-path $(pwd) +``` +The resulting binary won't include any JS files and will try to load them from +the specified directory. The JS debugger of Visual Studio Code supports this +configuration since the November 2020 version and allows for setting +breakpoints. + #### Troubleshooting Unix and macOS builds Stale builds can sometimes result in `file not found` errors while building. @@ -542,12 +560,12 @@ to run it again before invoking `make -j4`. ##### Option 1: Manual install -* [Python 2.7](https://www.python.org/downloads/) +* [Python 3.8](https://www.python.org/downloads/) * The "Desktop development with C++" workload from - [Visual Studio 2017](https://www.visualstudio.com/downloads/) or the - "Visual C++ build tools" workload from the - [Build Tools](https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2017), - with the default optional components. + [Visual Studio 2017 or 2019](https://visualstudio.microsoft.com/downloads/) or + the "Visual C++ build tools" workload from the + [Build Tools](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019), + with the default optional components * Basic Unix tools required for some tests, [Git for Windows](https://git-scm.com/download/win) includes Git Bash and tools which can be included in the global `PATH`. @@ -559,13 +577,13 @@ to run it again before invoking `make -j4`. Optional requirements to build the MSI installer package: * The [WiX Toolset v3.11](https://wixtoolset.org/releases/) and the - [Wix Toolset Visual Studio 2017 Extension](https://marketplace.visualstudio.com/items?itemName=RobMensching.WixToolsetVisualStudio2017Extension). + [Wix Toolset Visual Studio 2017 Extension](https://marketplace.visualstudio.com/items?itemName=RobMensching.WixToolsetVisualStudio2017Extension) + or the [Wix Toolset Visual Studio 2019 Extension](https://marketplace.visualstudio.com/items?itemName=WixToolset.WixToolsetVisualStudio2019Extension). +* The [WiX Toolset v3.14](https://wixtoolset.org/releases/) if + building for Windows 10 on ARM (ARM64) Optional requirements for compiling for Windows 10 on ARM (ARM64): -* ARM64 Windows build machine - * Due to a GYP limitation, this is required to run compiled code - generation tools (like V8's builtins and mksnapshot tools) * Visual Studio 15.9.0 or newer * Visual Studio optional components * Visual C++ compilers and libraries for ARM64 @@ -580,7 +598,7 @@ This script will install the following [Chocolatey](https://chocolatey.org/) packages: * [Git for Windows](https://chocolatey.org/packages/git) with the `git` and - Unix tools added to the `PATH`. + Unix tools added to the `PATH` * [Python 3.x](https://chocolatey.org/packages/python) and [legacy Python](https://chocolatey.org/packages/python2) * [Visual Studio 2019 Build Tools](https://chocolatey.org/packages/visualstudio2019buildtools) @@ -589,7 +607,7 @@ packages: To install Node.js prerequisites using [Boxstarter WebLauncher](https://boxstarter.org/WebLauncher), open - + with Internet Explorer or Edge browser on the target machine. Alternatively, you can use PowerShell. Run those commands from an elevated @@ -599,7 +617,7 @@ PowerShell terminal: Set-ExecutionPolicy Unrestricted -Force iex ((New-Object System.Net.WebClient).DownloadString('https://boxstarter.org/bootstrapper.ps1')) get-boxstarter -Force -Install-BoxstarterPackage https://raw.githubusercontent.com/nodejs/node/master/tools/bootstrap/windows_boxstarter -DisableReboots +Install-BoxstarterPackage https://raw.githubusercontent.com/nodejs/node/HEAD/tools/bootstrap/windows_boxstarter -DisableReboots ``` The entire installation using Boxstarter will take up approximately 10 GB of @@ -644,32 +662,41 @@ $ make ## `Intl` (ECMA-402) support -[Intl](https://github.com/nodejs/node/blob/master/doc/api/intl.md) support is -enabled by default, with English data only. +[Intl](https://github.com/nodejs/node/blob/HEAD/doc/api/intl.md) support is +enabled by default. -### Default: `small-icu` (English only) support +### Build with full ICU support (all locales supported by ICU) -By default, only English data is included, but -the full `Intl` (ECMA-402) APIs. It does not need to download -any dependencies to function. You can add full -data at runtime. +This is the default option. -### Build with full ICU support (all locales supported by ICU) +#### Unix/macOS + +```console +$ ./configure --with-intl=full-icu +``` + +#### Windows -With the `--download=all`, this may download ICU if you don't have an -ICU in `deps/icu`. (The embedded `small-icu` included in the default -Node.js source does not include all locales.) +```console +> .\vcbuild full-icu +``` + +### Trimmed: `small-icu` (English only) support + + In this configuration, only English data is included, but +the full `Intl` (ECMA-402) APIs. It does not need to download +any dependencies to function. You can add full data at runtime. #### Unix/macOS ```console -$ ./configure --with-intl=full-icu --download=all +$ ./configure --with-intl=small-icu ``` #### Windows ```console -> .\vcbuild full-icu download-all +> .\vcbuild small-icu ``` ### Building without Intl support @@ -779,4 +806,4 @@ When Node.js is built (with an intention to distribute) with an ABI incompatible with the official Node.js builds (e.g. using a ABI incompatible version of a dependency), please reserve and use a custom `NODE_MODULE_VERSION` by opening a pull request against the registry available at -. +. diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb8c234c20cc85b23020a6bacc5a435044fbeba..946430073dfa2d98f22b51c42c37891a4c8d05c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,11 @@ Select a Node.js version below to view the changelog history: -* [Node.js 12](doc/changelogs/CHANGELOG_V12.md) **Long Term Support** +* [Node.js 14](doc/changelogs/CHANGELOG_V14.md) **Long Term Support** +* [Node.js 13](doc/changelogs/CHANGELOG_V13.md) End-of-Life +* [Node.js 12](doc/changelogs/CHANGELOG_V12.md) Long Term Support * [Node.js 11](doc/changelogs/CHANGELOG_V11.md) End-of-Life -* [Node.js 10](doc/changelogs/CHANGELOG_V10.md) Long Term Support +* [Node.js 10](doc/changelogs/CHANGELOG_V10.md) End-of-Life * [Node.js 9](doc/changelogs/CHANGELOG_V9.md) End-of-Life * [Node.js 8](doc/changelogs/CHANGELOG_V8.md) End-of-Life * [Node.js 7](doc/changelogs/CHANGELOG_V7.md) End-of-Life @@ -22,34 +24,50 @@ release. + - - + - -
14LTS 12LTS10LTS8LTS
-12.22.7
-12.22.6
-12.22.5
-12.22.4
-12.22.3
-12.22.2
-12.22.1
-12.22.0
-12.21.0
-12.20.2
-12.20.1
-12.20.0
-12.19.1
-12.19.0
-12.18.4
-12.18.3
-12.18.2
-12.18.1
-12.18.0
-12.17.0
-12.16.3
-12.16.2
+14.18.3
+14.18.2
+14.18.1
+14.18.0
+14.17.6
+14.17.5
+14.17.4
+14.17.3
+14.17.2
+14.17.1
+14.17.0
+14.16.1
+14.16.0
+14.15.5
+14.15.4
+14.15.3
+14.15.2
+14.15.1
+14.15.0
+14.14.0
+14.13.1
+14.13.0
+14.12.0
+14.11.0
+14.10.1
+14.10.0
+14.9.0
+14.8.0
+14.7.0
+14.6.0
+14.5.0
+14.4.0
+14.3.0
+14.2.0
+14.1.0
+14.0.0
+
+12.16.2
12.16.1
12.16.0
12.15.0
@@ -75,66 +93,6 @@ release. 12.1.0
12.0.0
-10.15.3
-10.15.2
-10.15.1
-10.15.0
-10.14.2
-10.14.1
-10.14.0
-10.13.0
-10.12.0
-10.11.0
-10.10.0
-10.9.0
-10.8.0
-10.7.0
-10.6.0
-10.5.0
-10.4.1
-10.4.0
-10.3.0
-10.2.1
-10.2.0
-10.1.0
-10.0.0
-
-8.16.0
-8.15.1
-8.15.0
-8.14.1
-8.14.0
-8.13.0
-8.12.0
-8.11.4
-8.11.3
-8.11.2
-8.11.1
-8.11.0
-8.10.0
-8.9.4
-8.9.3
-8.9.2
-8.9.1
-8.9.0
-8.8.1
-8.8.0
-8.7.0
-8.6.0
-8.5.0
-8.4.0
-8.3.0
-8.2.1
-8.2.0
-8.1.4
-8.1.3
-8.1.2
-8.1.1
-8.1.0
-8.0.0
-
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 4c211405596cb42eac87cbf2c90c2764766fbb18..d724027fd9aadb9987b8213c66e78de32c31e042 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,4 +1,4 @@ # Code of Conduct -* [Node.js Code of Conduct](https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md) -* [Node.js Moderation Policy](https://github.com/nodejs/admin/blob/master/Moderation-Policy.md) +* [Node.js Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md) +* [Node.js Moderation Policy](https://github.com/nodejs/admin/blob/HEAD/Moderation-Policy.md) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 29700978fb78bff41183f67d80d596279f1167b3..30db8cf9b12524a4340167b352fb7f69493a94c2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,19 +8,17 @@ ## [Code of Conduct](./doc/guides/contributing/code-of-conduct.md) The Node.js project has a -[Code of Conduct](https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md) +[Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md) to which all contributors must adhere. See [details on our policy on Code of Conduct](./doc/guides/contributing/code-of-conduct.md). ## [Issues](./doc/guides/contributing/issues.md) -* [How to Contribute in Issues](./doc/guides/contributing/issues.md#how-to-contribute-in-issues) * [Asking for General Help](./doc/guides/contributing/issues.md#asking-for-general-help) * [Discussing non-technical topics](./doc/guides/contributing/issues.md#discussing-non-technical-topics) * [Submitting a Bug Report](./doc/guides/contributing/issues.md#submitting-a-bug-report) * [Triaging a Bug Report](./doc/guides/contributing/issues.md#triaging-a-bug-report) -* [Resolving a Bug Report](./doc/guides/contributing/issues.md#resolving-a-bug-report) ## [Pull Requests](./doc/guides/contributing/pull-requests.md) @@ -35,24 +33,24 @@ See [details on our policy on Code of Conduct](./doc/guides/contributing/code-of By making a contribution to this project, I certify that: -* (a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -* (b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -* (c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -* (d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. diff --git a/GOVERNANCE.md b/GOVERNANCE.md index aeb1d9c65e1f110589b4ce16a0c88e7cd07e5de4..aa73e4b3ee7519d3f4334887e85315aaba5b02d7 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -15,45 +15,46 @@ ## Triagers -Triagers assess newly-opened issues in the nodejs/node and nodejs/help -repositories. There is no GitHub team for triagers at the moment. +Triagers assess newly-opened issues in the [nodejs/node][] and [nodejs/help][] +repositories. The GitHub team for Node.js triagers is @nodejs/issue-triage. +Triagers are given the "Triage" GitHub role and have: -Triagers have: -* ability to label issues -* ability to comment, close, and reopen issues +* Ability to label issues and pull requests +* Ability to comment, close, and reopen issues and pull requests See: +* [List of triagers](./README.md#triagers) * [A guide for triagers](./doc/guides/contributing/issues.md#triaging-a-bug-report) ## Collaborators -Node.js Core Collaborators maintain the [nodejs/node][] GitHub repository. -The GitHub team for Node.js Core Collaborators is @nodejs/collaborators. +Node.js core collaborators maintain the [nodejs/node][] GitHub repository. +The GitHub team for Node.js core collaborators is @nodejs/collaborators. Collaborators have: * Commit access to the [nodejs/node][] repository * Access to the Node.js continuous integration (CI) jobs -Both Collaborators and non-Collaborators may propose changes to the Node.js +Both collaborators and non-collaborators may propose changes to the Node.js source code. The mechanism to propose such a change is a GitHub pull request. Collaborators review and merge (_land_) pull requests. -Two Collaborators must approve a pull request before the pull request can land. -(One Collaborator approval is enough if the pull request has been open for more -than 7 days.) Approving a pull request indicates that the Collaborator accepts -responsibility for the change. Approval must be from Collaborators who are not +Two collaborators must approve a pull request before the pull request can land. +(One collaborator approval is enough if the pull request has been open for more +than 7 days.) Approving a pull request indicates that the collaborator accepts +responsibility for the change. Approval must be from collaborators who are not authors of the change. -If a Collaborator opposes a proposed change, then the change cannot land. The +If a collaborator opposes a proposed change, then the change cannot land. The exception is if the TSC votes to approve the change despite the opposition. Usually, involving the TSC is unnecessary. Often, discussions or further changes -result in Collaborators removing their opposition. +result in collaborators removing their opposition. See: -* [List of Collaborators](./README.md#current-project-team-members) -* [A guide for Collaborators](./doc/guides/collaborator-guide.md) +* [List of collaborators](./README.md#current-project-team-members) +* [A guide for collaborators](./doc/guides/collaborator-guide.md) ### Collaborator activities @@ -63,12 +64,12 @@ See: * Participation in working groups * Merging pull requests -The TSC can remove inactive Collaborators or provide them with _Emeritus_ +The TSC can remove inactive collaborators or provide them with _Emeritus_ status. Emeriti may request that the TSC restore them to active status. ## Technical Steering Committee -A subset of the Collaborators forms the Technical Steering Committee (TSC). +A subset of the collaborators forms the Technical Steering Committee (TSC). The TSC has final authority over this project, including: * Technical direction @@ -76,13 +77,13 @@ The TSC has final authority over this project, including: * Contribution policy * GitHub repository hosting * Conduct guidelines -* Maintaining the list of Collaborators +* Maintaining the list of collaborators The current list of TSC members is in [the project README](./README.md#current-project-team-members). The [TSC Charter][] governs the operations of the TSC. All changes to the -Charter need approval by the OpenJS Foundation Board of Directors. +Charter need approval by the OpenJS Foundation Cross-Project Council (CPC). ### TSC meetings @@ -95,7 +96,7 @@ agenda is not to review or approve all patches. Collaborators review and approve patches on GitHub. Any community member can create a GitHub issue asking that the TSC review -something. If consensus-seeking fails for an issue, a Collaborator may apply the +something. If consensus-seeking fails for an issue, a collaborator may apply the `tsc-agenda` label. That will add it to the TSC meeting agenda. Before each TSC meeting, the meeting chair will share the agenda with members of @@ -120,11 +121,11 @@ the issue tracker is: ## Collaborator nominations -Existing Collaborators can nominate someone to become a Collaborator. Nominees +Existing collaborators can nominate someone to become a collaborator. Nominees should have significant and valuable contributions across the Node.js organization. -To nominate a new Collaborator, open an issue in the [nodejs/node][] repository. +To nominate a new collaborator, open an issue in the [nodejs/node][] repository. Provide a summary of the nominee's contributions. For example: * Commits in the [nodejs/node][] repository. @@ -144,24 +145,25 @@ Provide a summary of the nominee's contributions. For example: organization * Other participation in the wider Node.js community -Mention @nodejs/collaborators in the issue to notify other Collaborators about +Mention @nodejs/collaborators in the issue to notify other collaborators about the nomination. -The nomination passes if no Collaborators oppose it after one week. Otherwise, +The nomination passes if no collaborators oppose it after one week. Otherwise, the nomination fails. There are steps a nominator can take in advance to make a nomination as -frictionless as possible. Use the [Collaborators discussion page][] to request -feedback from other Collaborators in private. A nominator may also work with the +frictionless as possible. To request feedback from other collaborators in + private, use the [collaborators discussion page][] + (which only collaborators may view). A nominator may also work with the nominee to improve their contribution profile. Collaborators might overlook someone with valuable contributions. In that case, -the contributor may open an issue or contact a Collaborator to request a +the contributor may open an issue or contact a collaborator to request a nomination. ### Onboarding -After the nomination passes, a TSC member onboards the new Collaborator. See +After the nomination passes, a TSC member onboards the new collaborator. See [the onboarding guide](./onboarding.md) for details of the onboarding process. @@ -170,7 +172,8 @@ process. The TSC follows a [Consensus Seeking][] decision-making model per the [TSC Charter][]. -[Collaborators discussion page]: https://github.com/orgs/nodejs/teams/collaborators/discussions [Consensus Seeking]: https://en.wikipedia.org/wiki/Consensus-seeking_decision-making -[TSC Charter]: https://github.com/nodejs/TSC/blob/master/TSC-Charter.md +[TSC Charter]: https://github.com/nodejs/TSC/blob/HEAD/TSC-Charter.md +[collaborators discussion page]: https://github.com/orgs/nodejs/teams/collaborators/discussions +[nodejs/help]: https://github.com/nodejs/help [nodejs/node]: https://github.com/nodejs/node diff --git a/LICENSE b/LICENSE index 298631ee09e2dde64cab9514fb683528203f1774..1cc18f12bf8b0b0704b152ba99f477b09ee8b58a 100644 --- a/LICENSE +++ b/LICENSE @@ -53,30 +53,9 @@ The externally maintained libraries used by Node.js are: - Acorn, located at deps/acorn, is licensed as follows: """ - Copyright (C) 2012-2018 by various contributors (see AUTHORS) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS 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. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - """ + MIT License -- Acorn plugins, located at deps/acorn-plugins, is licensed as follows: - """ - Copyright (C) 2017-2018 by Adrian Heine + Copyright (C) 2012-2020 by various contributors (see AUTHORS) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -114,29 +93,6 @@ The externally maintained libraries used by Node.js are: purpose. It is provided "as is" without express or implied warranty. """ -- HTTP Parser, located at deps/http_parser, is licensed as follows: - """ - Copyright Joyent, Inc. and other Node contributors. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS 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. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - """ - - cjs-module-lexer, located at deps/cjs-module-lexer, is licensed as follows: """ MIT License @@ -439,9 +395,9 @@ The externally maintained libraries used by Node.js are: # Copyright (c) 2013 International Business Machines Corporation # and others. All Rights Reserved. # - # Project: http://code.google.com/p/lao-dictionary/ - # Dictionary: http://lao-dictionary.googlecode.com/git/Lao-Dictionary.txt - # License: http://lao-dictionary.googlecode.com/git/Lao-Dictionary-LICENSE.txt + # Project: https://github.com/veer66/lao-dictionary + # Dictionary: https://github.com/veer66/lao-dictionary/blob/master/Lao-Dictionary.txt + # License: https://github.com/veer66/lao-dictionary/blob/master/Lao-Dictionary-LICENSE.txt # (copied below) # # This file is derived from the above dictionary, with slight @@ -1082,6 +1038,7 @@ The externally maintained libraries used by Node.js are: - GYP, located at tools/gyp, is licensed as follows: """ + Copyright (c) 2020 Node.js contributors. All rights reserved. Copyright (c) 2009 Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -1268,12 +1225,12 @@ The externally maintained libraries used by Node.js are: THE SOFTWARE. """ -- babel-eslint, located at tools/node_modules/babel-eslint, is licensed as follows: +- Babel, located at tools/node_modules/@babel, is licensed as follows: """ - Copyright (c) 2014-2016 Sebastian McKenzie - MIT License + Copyright (c) 2014-present Sebastian McKenzie and other contributors + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including @@ -1294,7 +1251,7 @@ The externally maintained libraries used by Node.js are: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -- gtest, located at test/cctest/gtest, is licensed as follows: +- gtest, located at deps/googletest, is licensed as follows: """ Copyright 2008, Google Inc. All rights reserved. @@ -1353,29 +1310,6 @@ The externally maintained libraries used by Node.js are: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -- node-inspect, located at deps/node-inspect, is licensed as follows: - """ - Copyright Node.js contributors. All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS 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. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - """ - - large_pages, located at src/large_pages, is licensed as follows: """ Copyright (C) 2018 Intel Corporation diff --git a/Makefile b/Makefile index b8986e9a3c1a978bc3dfd11442a103a25a0201b8..c25a97750faccf228c4f6b4e8905d5471699e2d7 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ FLAKY_TESTS ?= run TEST_CI_ARGS ?= STAGINGSERVER ?= node-www LOGLEVEL ?= silent -OSTYPE := $(shell uname -s | tr '[A-Z]' '[a-z]') +OSTYPE := $(shell uname -s | tr '[:upper:]' '[:lower:]') COVTESTS ?= test-cov COV_SKIP_TESTS ?= core_line_numbers.js,testFinalizer.js,test_function/test.js GTEST_FILTER ?= "*" @@ -35,12 +35,17 @@ V8_TEST_OPTIONS = $(V8_EXTRA_TEST_OPTIONS) ifdef DISABLE_V8_I18N V8_BUILD_OPTIONS += i18nsupport=off endif +# V8 build and test toolchains are not currently compatible with Python 3. +# config.mk may have prepended a symlink for `python` to PATH which we need +# to undo before calling V8's tools. +OVERRIDE_BIN_DIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))out/tools/bin +NO_BIN_OVERRIDE_PATH=$(subst $() $(),:,$(filter-out $(OVERRIDE_BIN_DIR),$(subst :, ,$(PATH)))) ifeq ($(OSTYPE), darwin) GCOV = xcrun llvm-cov gcov endif -BUILDTYPE_LOWER := $(shell echo $(BUILDTYPE) | tr '[A-Z]' '[a-z]') +BUILDTYPE_LOWER := $(shell echo $(BUILDTYPE) | tr '[:upper:]' '[:lower:]') # Determine EXEEXT EXEEXT := $(shell $(PYTHON) -c \ @@ -53,7 +58,7 @@ NPM ?= ./deps/npm/bin/npm-cli.js # Flags for packaging. BUILD_DOWNLOAD_FLAGS ?= --download=all -BUILD_INTL_FLAGS ?= --with-intl=small-icu +BUILD_INTL_FLAGS ?= --with-intl=full-icu BUILD_RELEASE_FLAGS ?= $(BUILD_DOWNLOAD_FLAGS) $(BUILD_INTL_FLAGS) # Default to quiet/pretty builds. @@ -65,8 +70,8 @@ V ?= 0 available-node = \ if [ -x $(PWD)/$(NODE) ] && [ -e $(PWD)/$(NODE) ]; then \ $(PWD)/$(NODE) $(1); \ - elif [ -x `which node` ] && [ -e `which node` ] && [ `which node` ]; then \ - `which node` $(1); \ + elif [ -x `command -v node` ] && [ -e `command -v node` ] && [ `command -v node` ]; then \ + `command -v node` $(1); \ else \ echo "No available node, cannot run \"node $(1)\""; \ exit 1; \ @@ -85,7 +90,7 @@ endif # To add a target to the help, add a double comment (##) on the target line. help: ## Print help for targets with comments. @printf "For more targets and info see the comments in the Makefile.\n\n" - @grep -E '^[a-zA-Z0-9._-]+:.*?## .*$$' Makefile | sort | \ + @grep -E '^[[:alnum:]._-]+:.*?## .*$$' Makefile | sort | \ awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}' # The .PHONY is needed to ensure that we recursively use the out/Makefile @@ -102,7 +107,7 @@ $(NODE_EXE): build_type:=Release $(NODE_G_EXE): build_type:=Debug $(NODE_EXE) $(NODE_G_EXE): config.gypi out/Makefile $(MAKE) -C out BUILDTYPE=${build_type} V=$(V) - if [ ! -r $@ -o ! -L $@ ]; then \ + if [ ! -r $@ ] || [ ! -L $@ ]; then \ ln -fs out/${build_type}/$(NODE_EXE) $@; fi else ifeq ($(BUILD_WITH), ninja) @@ -116,14 +121,14 @@ else endif $(NODE_EXE): config.gypi out/Release/build.ninja ninja -C out/Release $(NINJA_ARGS) - if [ ! -r $@ -o ! -L $@ ]; then ln -fs out/Release/$(NODE_EXE) $@; fi + if [ ! -r $@ ] || [ ! -L $@ ]; then ln -fs out/Release/$(NODE_EXE) $@; fi $(NODE_G_EXE): config.gypi out/Debug/build.ninja ninja -C out/Debug $(NINJA_ARGS) - if [ ! -r $@ -o ! -L $@ ]; then ln -fs out/Debug/$(NODE_EXE) $@; fi + if [ ! -r $@ ] || [ ! -L $@ ]; then ln -fs out/Debug/$(NODE_EXE) $@; fi else $(NODE_EXE) $(NODE_G_EXE): - echo This Makefile currently only supports building with 'make' or 'ninja' + $(warning This Makefile currently only supports building with 'make' or 'ninja') endif endif @@ -133,15 +138,12 @@ CONFIG_FLAGS += --debug endif .PHONY: with-code-cache -with-code-cache: - echo "'with-code-cache' target is a noop" - .PHONY: test-code-cache -test-code-cache: with-code-cache - echo "'test-code-cache' target is a noop" +with-code-cache test-code-cache: + $(warning '$@' target is a noop) out/Makefile: config.gypi common.gypi node.gyp \ - deps/uv/uv.gyp deps/http_parser/http_parser.gyp deps/zlib/zlib.gyp \ + deps/uv/uv.gyp deps/llhttp/llhttp.gyp deps/zlib/zlib.gyp \ tools/v8_gypfiles/toolchain.gypi tools/v8_gypfiles/features.gypi \ tools/v8_gypfiles/inspector.gypi tools/v8_gypfiles/v8.gyp $(PYTHON) tools/gyp_node.py -f make @@ -150,7 +152,7 @@ out/Makefile: config.gypi common.gypi node.gyp \ # and included in config.gypi config.gypi: configure configure.py src/node_version.h @if [ -x config.status ]; then \ - ./config.status; \ + export PATH="$(NO_BIN_OVERRIDE_PATH)" && ./config.status; \ else \ echo Missing or stale $@, please run ./$<; \ exit 1; \ @@ -200,39 +202,23 @@ check: test # Remove files generated by running coverage, put the non-instrumented lib back # in place coverage-clean: - if [ -d lib_ ]; then $(RM) -r lib; mv lib_ lib; fi $(RM) -r node_modules - $(RM) -r gcovr build - $(RM) -r out/$(BUILDTYPE)/.coverage - $(RM) out/$(BUILDTYPE)/obj.target/node/gen/*.gcda - $(RM) out/$(BUILDTYPE)/obj.target/node/src/*.gcda - $(RM) out/$(BUILDTYPE)/obj.target/node/src/tracing/*.gcda - $(RM) out/$(BUILDTYPE)/obj.target/node/gen/*.gcno - $(RM) out/$(BUILDTYPE)/obj.target/node/src/*.gcno - $(RM) out/$(BUILDTYPE)/obj.target/node/src/tracing/*.gcno - $(RM) out/$(BUILDTYPE)/obj.target/cctest/src/*.gcno - $(RM) out/$(BUILDTYPE)/obj.target/cctest/test/cctest/*.gcno - $(RM) out/$(BUILDTYPE)/obj.target/embedtest/src/*.gcno - $(RM) out/$(BUILDTYPE)/obj.target/embedtest/test/embedding/*.gcno + $(RM) -r gcovr + $(RM) -r coverage/tmp + $(FIND) out/$(BUILDTYPE)/obj.target \( -name "*.gcda" -o -name "*.gcno" \) \ + -type f -exec $(RM) {} \; .PHONY: coverage -# Build and test with code coverage reporting. Leave the lib directory -# instrumented for any additional runs the user may want to make. -# For C++ coverage reporting, this needs to be run in conjunction with configure -# --coverage. html coverage reports will be created under coverage/ -# Related CI job: node-test-commit-linux-coverage +# Build and test with code coverage reporting. HTML coverage reports will be +# created under coverage/. For C++ coverage reporting, this needs to be run +# in conjunction with configure --coverage. +# Related CI job: node-test-commit-linux-coverage-daily coverage: coverage-test ## Run the tests and generate a coverage report. .PHONY: coverage-build coverage-build: all -$(MAKE) coverage-build-js - if [ ! -d gcovr ]; then git clone -b 3.4 --depth=1 \ - --single-branch https://github.com/gcovr/gcovr.git; fi - if [ ! -d build ]; then git clone --depth=1 \ - --single-branch https://github.com/nodejs/build.git; fi - if [ ! -f gcovr/scripts/gcovr.orig ]; then \ - (cd gcovr && patch -N -p1 < \ - "$(CURDIR)/build/jenkins/scripts/coverage/gcovr-patches-3.4.diff"); fi + if [ ! -d gcovr ]; then $(PYTHON) -m pip install -t gcovr gcovr==4.2; fi $(MAKE) .PHONY: coverage-build-js @@ -244,35 +230,26 @@ coverage-build-js: .PHONY: coverage-test coverage-test: coverage-build - $(RM) out/$(BUILDTYPE)/obj.target/node/src/*.gcda - $(RM) out/$(BUILDTYPE)/obj.target/node/src/*/*.gcda - $(RM) out/$(BUILDTYPE)/obj.target/node_lib/src/*.gcda - $(RM) out/$(BUILDTYPE)/obj.target/node_lib/src/*/*.gcda - -NODE_V8_COVERAGE=out/$(BUILDTYPE)/.coverage \ - TEST_CI_ARGS="$(TEST_CI_ARGS) --type=coverage" $(MAKE) $(COVTESTS) + $(FIND) out/$(BUILDTYPE)/obj.target -name "*.gcda" -type f -exec $(RM) {} \; + -NODE_V8_COVERAGE=coverage/tmp \ + TEST_CI_ARGS="$(TEST_CI_ARGS) --type=coverage" $(MAKE) $(COVTESTS) $(MAKE) coverage-report-js - -(cd out && "../gcovr/scripts/gcovr" \ + -(cd out && PYTHONPATH=../gcovr $(PYTHON) -m gcovr \ --gcov-exclude='.*\b(deps|usr|out|cctest|embedding)\b' -v \ - -r Release/obj.target --html --html-detail -o ../coverage/cxxcoverage.html \ + -r ../src/ --object-directory Release/obj.target \ + --html --html-details -o ../coverage/cxxcoverage.html \ --gcov-executable="$(GCOV)") - @echo -n "Javascript coverage %: " + @printf "Javascript coverage %%: " @grep -B1 Lines coverage/index.html | head -n1 \ | sed 's/<[^>]*>//g'| sed 's/ //g' - @echo -n "C++ coverage %: " + @printf "C++ coverage %%: " @grep -A3 Lines coverage/cxxcoverage.html | grep style \ | sed 's/<[^>]*>//g'| sed 's/ //g' -COV_REPORT_OPTIONS = --reporter=html \ - --temp-directory=out/$(BUILDTYPE)/.coverage --omit-relative=false \ - --resolve=./lib --exclude="benchmark/" --exclude="deps/" --exclude="test/" --exclude="tools/" \ - --wrapper-length=0 -ifdef COV_ENFORCE_THRESHOLD - COV_REPORT_OPTIONS += --check-coverage --lines=$(COV_ENFORCE_THRESHOLD) -endif - .PHONY: coverage-report-js coverage-report-js: - $(NODE) ./node_modules/.bin/c8 report $(COV_REPORT_OPTIONS) + -$(MAKE) coverage-build-js + $(NODE) ./node_modules/.bin/c8 report .PHONY: cctest # Runs the C++ tests using the built `cctest` executable. @@ -292,7 +269,8 @@ endif # Rebuilds deps/v8 as a git tree, pulls its third-party dependencies, and # builds it. v8: - tools/make-v8.sh $(V8_ARCH).$(BUILDTYPE_LOWER) $(V8_BUILD_OPTIONS) + export PATH="$(NO_BIN_OVERRIDE_PATH)" && \ + tools/make-v8.sh $(V8_ARCH).$(BUILDTYPE_LOWER) $(V8_BUILD_OPTIONS) .PHONY: jstest jstest: build-addons build-js-native-api-tests build-node-api-tests ## Runs addon tests and JS tests @@ -307,9 +285,8 @@ tooltest: .PHONY: coverage-run-js coverage-run-js: - $(RM) -r out/$(BUILDTYPE)/.coverage - $(MAKE) coverage-build-js - -NODE_V8_COVERAGE=out/$(BUILDTYPE)/.coverage CI_SKIP_TESTS=$(COV_SKIP_TESTS) \ + $(RM) -r coverage/tmp + -NODE_V8_COVERAGE=coverage/tmp CI_SKIP_TESTS=$(COV_SKIP_TESTS) \ TEST_CI_ARGS="$(TEST_CI_ARGS) --type=coverage" $(MAKE) jstest $(MAKE) coverage-report-js @@ -350,7 +327,7 @@ test-valgrind: all test-check-deopts: all $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) --check-deopts parallel sequential -DOCBUILDSTAMP_PREREQS = tools/doc/addon-verify.js doc/api/addons.md +DOCBUILDSTAMP_PREREQS = tools/doc/addon-verify.mjs doc/api/addons.md ifeq ($(OSTYPE),aix) DOCBUILDSTAMP_PREREQS := $(DOCBUILDSTAMP_PREREQS) out/$(BUILDTYPE)/node.exp @@ -364,7 +341,7 @@ test/addons/.docbuildstamp: $(DOCBUILDSTAMP_PREREQS) tools/doc/node_modules else \ $(RM) -r test/addons/??_*/; \ [ -x $(NODE) ] && $(NODE) $< || node $< ; \ - touch $@; \ + [ $$? -eq 0 ] && touch $@; \ fi ADDONS_BINDING_GYPS := \ @@ -468,7 +445,7 @@ benchmark/napi/.buildstamp: $(ADDONS_PREREQS) \ .PHONY: clear-stalled clear-stalled: - @echo "Clean up any leftover processes but don't error if found." + $(info Clean up any leftover processes but don't error if found.) ps awwx | grep Release/node | grep -v grep | cat @PS_OUT=`ps awwx | grep Release/node | grep -v grep | awk '{print $$1}'`; \ if [ "$${PS_OUT}" ]; then \ @@ -519,7 +496,7 @@ test-ci-js: | clear-stalled $(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \ --mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \ $(TEST_CI_ARGS) $(CI_JS_SUITES) - @echo "Clean up any leftover processes, error if found." + $(info Clean up any leftover processes, error if found.) ps awwx | grep Release/node | grep -v grep | cat @PS_OUT=`ps awwx | grep Release/node | grep -v grep | awk '{print $$1}'`; \ if [ "$${PS_OUT}" ]; then \ @@ -535,7 +512,7 @@ test-ci: | clear-stalled bench-addons-build build-addons build-js-native-api-tes --mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \ $(TEST_CI_ARGS) $(CI_JS_SUITES) $(CI_NATIVE_SUITES) $(CI_DOC) out/Release/embedtest 'require("./test/embedding/test-embedding.js")' - @echo "Clean up any leftover processes, error if found." + $(info Clean up any leftover processes, error if found.) ps awwx | grep Release/node | grep -v grep | cat @PS_OUT=`ps awwx | grep Release/node | grep -v grep | awk '{print $$1}'`; \ if [ "$${PS_OUT}" ]; then \ @@ -583,10 +560,6 @@ test-pummel: all test-internet: all $(PYTHON) tools/test.py $(PARALLEL_ARGS) internet -test-node-inspect: $(NODE_EXE) - USE_EMBEDDED_NODE_INSPECT=1 $(NODE) tools/test-npm-package \ - --install deps/node-inspect test - test-benchmark: | bench-addons-build $(PYTHON) tools/test.py $(PARALLEL_ARGS) benchmark @@ -599,20 +572,23 @@ test-hash-seed: all $(NODE) test/pummel/test-hash-seed.js .PHONY: test-doc -test-doc: doc-only lint ## Builds, lints, and verifies the docs. +test-doc: doc-only lint-md ## Builds, lints, and verifies the docs. @if [ "$(shell $(node_use_openssl))" != "true" ]; then \ echo "Skipping test-doc (no crypto)"; \ else \ $(PYTHON) tools/test.py $(PARALLEL_ARGS) doctool; \ fi - $(NODE) tools/doc/checkLinks.js . + +.PHONY: test-doc-ci +test-doc-ci: doc-only + $(PYTHON) tools/test.py --shell $(NODE) $(TEST_CI_ARGS) $(PARALLEL_ARGS) doctool test-known-issues: all $(PYTHON) tools/test.py $(PARALLEL_ARGS) known_issues # Related CI job: node-test-npm test-npm: $(NODE_EXE) ## Run the npm test suite on deps/npm. - $(NODE) tools/test-npm-package --install --logfile=test-npm.tap deps/npm test-node + $(NODE) tools/test-npm-package --install --logfile=test-npm.tap deps/npm test test-npm-publish: $(NODE_EXE) npm_package_config_publishtest=true $(NODE) deps/npm/test/run.js @@ -668,20 +644,22 @@ test-with-async-hooks: ifneq ("","$(wildcard deps/v8/tools/run-tests.py)") # Related CI job: node-test-commit-v8-linux test-v8: v8 ## Runs the V8 test suite on deps/v8. - deps/v8/tools/run-tests.py --gn --arch=$(V8_ARCH) \ - --mode=$(BUILDTYPE_LOWER) $(V8_TEST_OPTIONS) \ + export PATH="$(NO_BIN_OVERRIDE_PATH)" && \ + deps/v8/tools/run-tests.py --gn --arch=$(V8_ARCH) $(V8_TEST_OPTIONS) \ mjsunit cctest debugger inspector message preparser \ $(TAP_V8) - @echo Testing hash seed + $(info Testing hash seed) $(MAKE) test-hash-seed test-v8-intl: v8 - deps/v8/tools/run-tests.py --gn --arch=$(V8_ARCH) \ - --mode=$(BUILDTYPE_LOWER) intl \ + export PATH="$(NO_BIN_OVERRIDE_PATH)" && \ + deps/v8/tools/run-tests.py --gn --arch=$(V8_ARCH) \ + intl \ $(TAP_V8_INTL) test-v8-benchmarks: v8 - deps/v8/tools/run-tests.py --gn --arch=$(V8_ARCH) --mode=$(BUILDTYPE_LOWER) \ + export PATH="$(NO_BIN_OVERRIDE_PATH)" && \ + deps/v8/tools/run-tests.py --gn --arch=$(V8_ARCH) \ benchmarks \ $(TAP_V8_BENCHMARKS) @@ -692,9 +670,8 @@ test-v8-all: test-v8 test-v8-intl test-v8-benchmarks test-v8-updates # runs all v8 tests else test-v8 test-v8-intl test-v8-benchmarks test-v8-all: - @echo "Testing v8 is not available through the source tarball." - @echo "Use the git repo instead:" \ - "$ git clone https://github.com/nodejs/node.git" + $(warning Testing V8 is not available through the source tarball.) + $(warning Use the git repo instead: $$ git clone https://github.com/nodejs/node.git) endif apidoc_dirs = out/doc out/doc/api out/doc/api/assets @@ -717,7 +694,7 @@ doc-only: tools/doc/node_modules \ @if [ "$(shell $(node_use_openssl))" != "true" ]; then \ echo "Skipping doc-only (no crypto)"; \ else \ - $(MAKE) out/doc/api/all.html out/doc/api/all.json; \ + $(MAKE) out/doc/api/all.html out/doc/api/all.json out/doc/api/stability; \ fi .PHONY: doc @@ -746,29 +723,33 @@ run-npm-ci = $(PWD)/$(NPM) ci LINK_DATA = out/doc/apilinks.json VERSIONS_DATA = out/previous-doc-versions.json -gen-api = tools/doc/generate.js --node-version=$(FULLVERSION) \ +gen-api = tools/doc/generate.mjs --node-version=$(FULLVERSION) \ --apilinks=$(LINK_DATA) $< --output-directory=out/doc/api \ --versions-file=$(VERSIONS_DATA) -gen-apilink = tools/doc/apilinks.js $(LINK_DATA) $(wildcard lib/*.js) +gen-apilink = tools/doc/apilinks.mjs $(LINK_DATA) $(wildcard lib/*.js) -$(LINK_DATA): $(wildcard lib/*.js) tools/doc/apilinks.js | out/doc +$(LINK_DATA): $(wildcard lib/*.js) tools/doc/apilinks.mjs | out/doc $(call available-node, $(gen-apilink)) # Regenerate previous versions data if the current version changes -$(VERSIONS_DATA): CHANGELOG.md src/node_version.h tools/doc/versions.js - $(call available-node, tools/doc/versions.js $@) +$(VERSIONS_DATA): CHANGELOG.md src/node_version.h tools/doc/versions.mjs + $(call available-node, tools/doc/versions.mjs $@) -out/doc/api/%.json out/doc/api/%.html: doc/api/%.md tools/doc/generate.js \ - tools/doc/markdown.js tools/doc/html.js tools/doc/json.js \ - tools/doc/apilinks.js $(VERSIONS_DATA) | $(LINK_DATA) out/doc/api +out/doc/api/%.json out/doc/api/%.html: doc/api/%.md tools/doc/generate.mjs \ + tools/doc/markdown.mjs tools/doc/html.mjs tools/doc/json.mjs \ + tools/doc/apilinks.mjs $(VERSIONS_DATA) | $(LINK_DATA) out/doc/api $(call available-node, $(gen-api)) -out/doc/api/all.html: $(apidocs_html) tools/doc/allhtml.js \ - tools/doc/apilinks.js | out/doc/api - $(call available-node, tools/doc/allhtml.js) +out/doc/api/all.html: $(apidocs_html) tools/doc/allhtml.mjs \ + tools/doc/apilinks.mjs | out/doc/api + $(call available-node, tools/doc/allhtml.mjs) + +out/doc/api/all.json: $(apidocs_json) tools/doc/alljson.mjs | out/doc/api + $(call available-node, tools/doc/alljson.mjs) -out/doc/api/all.json: $(apidocs_json) tools/doc/alljson.js | out/doc/api - $(call available-node, tools/doc/alljson.js) +.PHONY: out/doc/api/stability +out/doc/api/stability: out/doc/api/all.json tools/doc/stability.mjs | out/doc/api + $(call available-node, tools/doc/stability.mjs) .PHONY: docopen docopen: out/doc/api/all.html @@ -785,6 +766,7 @@ docclean: RAWVER=$(shell $(PYTHON) tools/getnodeversion.py) VERSION=v$(RAWVER) +CHANGELOG=doc/changelogs/CHANGELOG_V$(firstword $(subst ., ,$(RAWVER))).md # For nightly builds, you must set DISTTYPE to "nightly", "next-nightly" or # "custom". For the nightly and next-nightly case, you need to set DATESTRING @@ -919,24 +901,23 @@ BINARYNAME=$(TARNAME)-$(PLATFORM)-$(ARCH) endif BINARYTAR=$(BINARYNAME).tar # OSX doesn't have xz installed by default, http://macpkg.sourceforge.net/ -HAS_XZ ?= $(shell which xz > /dev/null 2>&1; [ $$? -eq 0 ] && echo 1 || echo 0) +HAS_XZ ?= $(shell command -v xz > /dev/null 2>&1; [ $$? -eq 0 ] && echo 1 || echo 0) # Supply SKIP_XZ=1 to explicitly skip .tar.xz creation SKIP_XZ ?= 0 -XZ = $(shell [ $(HAS_XZ) -eq 1 -a $(SKIP_XZ) -eq 0 ] && echo 1 || echo 0) +XZ = $(shell [ $(HAS_XZ) -eq 1 ] && [ $(SKIP_XZ) -eq 0 ] && echo 1 || echo 0) XZ_COMPRESSION ?= 9e PKG=$(TARNAME).pkg MACOSOUTDIR=out/macos ifeq ($(SKIP_XZ), 1) check-xz: - @echo "SKIP_XZ=1 supplied, skipping .tar.xz creation" + $(info SKIP_XZ=1 supplied, skipping .tar.xz creation) else ifeq ($(HAS_XZ), 1) check-xz: else check-xz: - @echo "No xz command, cannot continue" - @exit 1 + $(error No xz command, cannot continue) endif endif @@ -964,7 +945,7 @@ release-only: check-xz echo "" >&2 ; \ exit 1 ; \ fi - @if [ "$(DISTTYPE)" != "release" -o "$(RELEASE)" = "1" ]; then \ + @if [ "$(DISTTYPE)" != "release" ] || [ "$(RELEASE)" = "1" ]; then \ exit 0; \ else \ echo "" >&2 ; \ @@ -973,6 +954,15 @@ release-only: check-xz echo "" >&2 ; \ exit 1 ; \ fi + @if [ "$(RELEASE)" = "0" ] || [ -f "$(CHANGELOG)" ]; then \ + exit 0; \ + else \ + echo "" >&2 ; \ + echo "#NODE_VERSION_IS_RELEASE is set to $(RELEASE) but " >&2 ; \ + echo "$(CHANGELOG) does not exist." >&2 ; \ + echo "" >&2 ; \ + exit 1 ; \ + fi $(PKG): release-only $(RM) -r $(MACOSOUTDIR) @@ -1001,7 +991,7 @@ $(PKG): release-only --release-urlbase=$(RELEASE_URLBASE) \ $(CONFIG_FLAGS) $(BUILD_RELEASE_FLAGS) $(MAKE) install V=$(V) DESTDIR=$(MACOSOUTDIR)/dist/node - SIGN="$(CODESIGN_CERT)" PKGDIR="$(MACOSOUTDIR)/dist/node/usr/local" bash \ + SIGN="$(CODESIGN_CERT)" PKGDIR="$(MACOSOUTDIR)/dist/node/usr/local" sh \ tools/osx-codesign.sh mkdir -p $(MACOSOUTDIR)/dist/npm/usr/local/lib/node_modules mkdir -p $(MACOSOUTDIR)/pkgs @@ -1023,8 +1013,8 @@ $(PKG): release-only productbuild --distribution $(MACOSOUTDIR)/installer/productbuild/distribution.xml \ --resources $(MACOSOUTDIR)/installer/productbuild/Resources \ --package-path $(MACOSOUTDIR)/pkgs ./$(PKG) - SIGN="$(PRODUCTSIGN_CERT)" PKG="$(PKG)" bash tools/osx-productsign.sh - bash tools/osx-notarize.sh $(FULLVERSION) + SIGN="$(PRODUCTSIGN_CERT)" PKG="$(PKG)" sh tools/osx-productsign.sh + sh tools/osx-notarize.sh $(FULLVERSION) .PHONY: pkg # Builds the macOS installer for releases. @@ -1037,7 +1027,7 @@ pkg-upload: pkg scp -p $(TARNAME).pkg $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg.done" -$(TARBALL): release-only $(NODE_EXE) doc +$(TARBALL): release-only doc-only git checkout-index -a -f --prefix=$(TARNAME)/ mkdir -p $(TARNAME)/doc/api cp doc/node.1 $(TARNAME)/doc/node.1 @@ -1066,7 +1056,7 @@ $(TARBALL): release-only $(NODE_EXE) doc find $(TARNAME)/deps/v8/test -type f ! -regex '.*/test/torque/.*' | xargs $(RM) find $(TARNAME)/deps/zlib/contrib/* -type d ! -regex '.*/contrib/optimizations$$' | xargs $(RM) -r find $(TARNAME)/ -name ".eslint*" -maxdepth 2 | xargs $(RM) - find $(TARNAME)/ -type l | xargs $(RM) # annoying on windows + find $(TARNAME)/ -type l | xargs $(RM) tar -cf $(TARNAME).tar $(TARNAME) $(RM) -r $(TARNAME) gzip -c -f -9 $(TARNAME).tar > $(TARNAME).tar.gz @@ -1140,9 +1130,13 @@ $(BINARYTAR): release-only $(MAKE) install DESTDIR=$(BINARYNAME) V=$(V) PORTABLE=1 cp README.md $(BINARYNAME) cp LICENSE $(BINARYNAME) +ifeq ("$(wildcard $(CHANGELOG))","") cp CHANGELOG.md $(BINARYNAME) +else + cp $(CHANGELOG) $(BINARYNAME)/CHANGELOG.md +endif ifeq ($(OSTYPE),darwin) - SIGN="$(CODESIGN_CERT)" PKGDIR="$(BINARYNAME)" bash tools/osx-codesign.sh + SIGN="$(CODESIGN_CERT)" PKGDIR="$(BINARYNAME)" sh tools/osx-codesign.sh endif tar -cf $(BINARYNAME).tar $(BINARYNAME) $(RM) -r $(BINARYNAME) @@ -1169,12 +1163,9 @@ ifeq ($(XZ), 1) endif .PHONY: bench-all -bench-all: bench-addons-build - @echo "Please use benchmark/run.js or benchmark/compare.js to run the benchmarks." - .PHONY: bench -bench: bench-addons-build - @echo "Please use benchmark/run.js or benchmark/compare.js to run the benchmarks." +bench bench-all: bench-addons-build + $(warning Please use benchmark/run.js or benchmark/compare.js to run the benchmarks.) # Build required addons for benchmark before running it. .PHONY: bench-addons-build @@ -1198,7 +1189,7 @@ lint-md-clean: .PHONY: lint-md-build lint-md-build: - $(warning "Deprecated no-op target 'lint-md-build'") + $(warning Deprecated no-op target 'lint-md-build') ifeq ("$(wildcard tools/.mdlintstamp)","") LINT_MD_NEWER = @@ -1210,22 +1201,22 @@ LINT_MD_TARGETS = doc src lib benchmark test tools/doc tools/icu $(wildcard *.md LINT_MD_FILES = $(shell $(FIND) $(LINT_MD_TARGETS) -type f \ ! -path '*node_modules*' ! -path 'test/fixtures/*' -name '*.md' \ $(LINT_MD_NEWER)) -run-lint-md = tools/lint-md.js -q -f --no-stdout $(LINT_MD_FILES) +run-lint-md = tools/lint-md.mjs -q -f --no-stdout $(LINT_MD_FILES) # Lint all changed markdown files maintained by us tools/.mdlintstamp: $(LINT_MD_FILES) - @echo "Running Markdown linter..." + $(info Running Markdown linter...) @$(call available-node,$(run-lint-md)) @touch $@ .PHONY: lint-md # Lints the markdown documents maintained by us in the codebase. -lint-md: | tools/.mdlintstamp +lint-md: lint-js-doc | tools/.mdlintstamp LINT_JS_TARGETS = .eslintrc.js benchmark doc lib test tools run-lint-js = tools/node_modules/eslint/bin/eslint.js --cache \ - --report-unused-disable-directives --ext=.js,.mjs,.md $(LINT_JS_TARGETS) + --report-unused-disable-directives $(LINT_JS_TARGETS) run-lint-js-fix = $(run-lint-js) --fix .PHONY: lint-js-fix @@ -1233,9 +1224,11 @@ lint-js-fix: @$(call available-node,$(run-lint-js-fix)) .PHONY: lint-js +.PHONY: lint-js-doc # Note that on the CI `lint-js-ci` is run instead. # Lints the JavaScript code with eslint. -lint-js: +lint-js-doc: LINT_JS_TARGETS=doc +lint-js lint-js-doc: @if [ "$(shell $(node_use_openssl))" != "true" ]; then \ echo "Skipping $@ (no crypto)"; \ else \ @@ -1244,20 +1237,20 @@ lint-js: fi jslint: lint-js - @echo "Please use lint-js instead of jslint" + $(warning Please use lint-js instead of jslint) run-lint-js-ci = tools/node_modules/eslint/bin/eslint.js \ - --report-unused-disable-directives --ext=.js,.mjs,.md -f tap \ + --report-unused-disable-directives -f tap \ -o test-eslint.tap $(LINT_JS_TARGETS) .PHONY: lint-js-ci # On the CI the output is emitted in the TAP format. lint-js-ci: - @echo "Running JS linter..." + $(info Running JS linter...) @$(call available-node,$(run-lint-js-ci)) jslint-ci: lint-js-ci - @echo "Please use lint-js-ci instead of jslint-ci" + $(warning Please use lint-js-ci instead of jslint-ci) LINT_CPP_ADDON_DOC_FILES_GLOB = test/addons/??_*/*.cc test/addons/??_*/*.h LINT_CPP_ADDON_DOC_FILES = $(wildcard $(LINT_CPP_ADDON_DOC_FILES_GLOB)) @@ -1269,7 +1262,7 @@ LINT_CPP_EXCLUDE += $(wildcard test/js-native-api/??_*/*.cc test/js-native-api/? LINT_CPP_EXCLUDE += src/tracing/trace_event.h src/tracing/trace_event_common.h LINT_CPP_FILES = $(filter-out $(LINT_CPP_EXCLUDE), $(wildcard \ - benchmark/napi/function_call/binding.cc \ + benchmark/napi/*/*.cc \ src/*.c \ src/*.cc \ src/*.h \ @@ -1314,15 +1307,15 @@ CLANG_FORMAT_START ?= HEAD # $ CLANG_FORMAT_START=master make format-cpp format-cpp: ## Format C++ diff from $CLANG_FORMAT_START to current changes ifneq ("","$(wildcard tools/clang-format/node_modules/)") - @echo "Formatting C++ diff from $(CLANG_FORMAT_START).." + $(info Formatting C++ diff from $(CLANG_FORMAT_START)..) @$(PYTHON) tools/clang-format/node_modules/.bin/git-clang-format \ --binary=tools/clang-format/node_modules/.bin/clang-format \ --style=file \ $(CLANG_FORMAT_START) -- \ $(LINT_CPP_FILES) else - @echo "clang-format is not installed." - @echo "To install (requires internet access) run: $ make format-cpp-build" + $(info clang-format is not installed.) + $(info To install (requires internet access) run: $$ make format-cpp-build) endif ifeq ($(V),1) @@ -1335,7 +1328,7 @@ endif lint-cpp: tools/.cpplintstamp tools/.cpplintstamp: $(LINT_CPP_FILES) - @echo "Running C++ linter..." + $(info Running C++ linter...) @$(PYTHON) tools/cpplint.py $(CPPLINT_QUIET) $? @$(PYTHON) tools/checkimports.py $? @touch $@ @@ -1344,19 +1337,19 @@ tools/.cpplintstamp: $(LINT_CPP_FILES) lint-addon-docs: tools/.doclintstamp tools/.doclintstamp: test/addons/.docbuildstamp - @echo "Running C++ linter on addon docs..." + $(info Running C++ linter on addon docs...) @$(PYTHON) tools/cpplint.py $(CPPLINT_QUIET) --filter=$(ADDON_DOC_LINT_FLAGS) \ $(LINT_CPP_ADDON_DOC_FILES_GLOB) @touch $@ cpplint: lint-cpp - @echo "Please use lint-cpp instead of cpplint" + $(warning Please use lint-cpp instead of cpplint) .PHONY: lint-py-build # python -m pip install flake8 # Try with '--system' is to overcome systems that blindly set '--user' lint-py-build: - @echo "Pip installing flake8 linter on $(shell $(PYTHON) --version)..." + $(info Pip installing flake8 linter on $(shell $(PYTHON) --version)...) $(PYTHON) -m pip install --upgrade -t tools/pip/site-packages flake8 || \ $(PYTHON) -m pip install --upgrade --system -t tools/pip/site-packages flake8 @@ -1368,8 +1361,8 @@ lint-py: PYTHONPATH=tools/pip $(PYTHON) -m flake8 --count --show-source --statistics . else lint-py: - @echo "Python linting with flake8 is not avalible" - @echo "Run 'make lint-py-build'" + $(warning Python linting with flake8 is not available) + $(warning Run 'make lint-py-build') endif .PHONY: lint @@ -1382,7 +1375,7 @@ lint: ## Run JS, C++, MD and doc linters. $(MAKE) lint-addon-docs || EXIT_STATUS=$$? ; \ $(MAKE) lint-md || EXIT_STATUS=$$? ; \ exit $$EXIT_STATUS -CONFLICT_RE=^>>>>>>> [0-9A-Fa-f]+|^<<<<<<< [A-Za-z]+ +CONFLICT_RE=^>>>>>>> [[:xdigit:]]+|^<<<<<<< [[:alpha:]]+ # Related CI job: node-test-linter lint-ci: lint-js-ci lint-cpp lint-py lint-md lint-addon-docs @@ -1395,12 +1388,9 @@ lint-ci: lint-js-ci lint-cpp lint-py lint-md lint-addon-docs exit 1 ; \ fi else -lint: - @echo "Linting is not available through the source tarball." - @echo "Use the git repo instead:" \ - "$ git clone https://github.com/nodejs/node.git" - -lint-ci: lint +lint lint-ci: + $(info Linting is not available through the source tarball.) + $(info Use the git repo instead: $$ git clone https://github.com/nodejs/node.git) endif .PHONY: lint-clean @@ -1408,7 +1398,7 @@ lint-clean: $(RM) tools/.*lintstamp $(RM) .eslintcache -HAS_DOCKER ?= $(shell which docker > /dev/null 2>&1; [ $$? -eq 0 ] && echo 1 || echo 0) +HAS_DOCKER ?= $(shell command -v docker > /dev/null 2>&1; [ $$? -eq 0 ] && echo 1 || echo 0) ifeq ($(HAS_DOCKER), 1) DOCKER_COMMAND ?= docker run -it -v $(PWD):/node @@ -1420,6 +1410,5 @@ gen-openssl: ## Generate platform dependent openssl files (requires docker) $(DOCKER_COMMAND) node-openssl-builder make -C deps/openssl/config else gen-openssl: - @echo "No docker command, cannot continue" - @exit 1 + $(error No docker command, cannot continue) endif diff --git a/OAT.xml b/OAT.xml index 5fc56ae96d13eec912546b329ff4739fcf3e6967..f07abd715fd5188dee3b623f15d84d576c747b1a 100644 --- a/OAT.xml +++ b/OAT.xml @@ -149,6 +149,14 @@ Note:If the text contains special characters, please escape them according to th + + + + + + + + @@ -188,7 +196,15 @@ Note:If the text contains special characters, please escape them according to th + + + + + + + + diff --git a/README.OpenSource b/README.OpenSource index 996e2e689dc1d0d6c2dc8fbd64191c7121dd3209..a6fe01b7c25cb699092ce4a77ff76fe918bb9d24 100644 --- a/README.OpenSource +++ b/README.OpenSource @@ -3,7 +3,7 @@ "Name": "node", "License": "ISC License,Public Domain,MIT License,Free Software Foundation - MIT License,Apache License V2.0,ICU License,zlib/libpng License,BSD 2-Clause License,BSD 3-Clause License", "License File": "LICENSE", - "Version Number": "12.22.7", + "Version Number": "14.18.3", "Owner": "sunbingxin@huawei.com", "Upstream URL": "http://www.nodejs.org/", "Description": "Node.js is an open-source, cross-platform, JavaScript runtime environment. It executes JavaScript code outside of a browser." diff --git a/README.md b/README.md index a5066a675f0a8e8c72091eb0a85d199089738b3a..74a31d75d60f02d157b3074de4b293c630d56798 100644 --- a/README.md +++ b/README.md @@ -18,29 +18,30 @@ The Node.js project uses an [open governance model](./GOVERNANCE.md). The **This project is bound by a [Code of Conduct][].** -# Table of Contents +# Table of contents * [Support](#support) -* [Release Types](#release-types) +* [Release types](#release-types) * [Download](#download) - * [Current and LTS Releases](#current-and-lts-releases) - * [Nightly Releases](#nightly-releases) - * [API Documentation](#api-documentation) - * [Verifying Binaries](#verifying-binaries) + * [Current and LTS releases](#current-and-lts-releases) + * [Nightly releases](#nightly-releases) + * [API documentation](#api-documentation) + * [Verifying binaries](#verifying-binaries) * [Building Node.js](#building-nodejs) * [Security](#security) * [Contributing to Node.js](#contributing-to-nodejs) -* [Current Project Team Members](#current-project-team-members) +* [Current project team members](#current-project-team-members) * [TSC (Technical Steering Committee)](#tsc-technical-steering-committee) * [Collaborators](#collaborators) - * [Release Keys](#release-keys) + * [Release keys](#release-keys) +* [License](#license) ## Support Looking for help? Check out the [instructions for getting support](.github/SUPPORT.md). -## Release Types +## Release types * **Current**: Under active development. Code for the Current release is in the branch for its major version number (for example, @@ -49,10 +50,10 @@ Looking for help? Check out the April and October every year. Releases appearing each October have a support life of 8 months. Releases appearing each April convert to LTS (see below) each October. -* **LTS**: Releases that receive Long-term Support, with a focus on stability +* **LTS**: Releases that receive Long Term Support, with a focus on stability and security. Every even-numbered major version will become an LTS release. LTS releases receive 12 months of _Active LTS_ support and a further 18 months - of _Maintenance_. LTS release lines have alphabetically-ordered codenames, + of _Maintenance_. LTS release lines have alphabetically-ordered code names, beginning with v4 Argon. There are no breaking changes or feature additions, except in some special circumstances. * **Nightly**: Code from the Current branch built every 24-hours when there are @@ -68,7 +69,7 @@ For more information, see the Binaries, installers, and source tarballs are available at . -#### Current and LTS Releases +#### Current and LTS releases The [latest](https://nodejs.org/download/release/latest/) directory is an @@ -77,20 +78,20 @@ alias for the latest release from an LTS line. For example, the [latest-carbon](https://nodejs.org/download/release/latest-carbon/) directory contains the latest Carbon (Node.js 8) release. -#### Nightly Releases +#### Nightly releases Each directory name and filename contains a date (in UTC) and the commit SHA at the HEAD of the release. -#### API Documentation +#### API documentation Documentation for the latest Current release is at . Version-specific documentation is available in each release directory in the _docs_ subdirectory. Version-specific documentation is also at . -### Verifying Binaries +### Verifying binaries Download directories contain a `SHASUMS256.txt` file with SHA checksums for the files. @@ -110,7 +111,7 @@ $ grep node-vx.y.z.tar.gz SHASUMS256.txt | sha256sum -c - For Current and LTS, the GPG detached signature of `SHASUMS256.txt` is in `SHASUMS256.txt.sig`. You can use it with `gpg` to verify the integrity of -`SHASUM256.txt`. You will first need to import +`SHASUMS256.txt`. You will first need to import [the GPG keys of individuals authorized to create releases](#release-keys). To import the keys: @@ -143,17 +144,21 @@ For information on reporting security vulnerabilities in Node.js, see * [Contributing to the project][] * [Working Groups][] -* [Strategic Initiatives][] +* [Strategic initiatives][] * [Technical values and prioritization][] -## Current Project Team Members +## Current project team members For information about the governance of the Node.js project, see [GOVERNANCE.md](./GOVERNANCE.md). + ### TSC (Technical Steering Committee) +* [aduh95](https://github.com/aduh95) - +**Antoine du Hamel** <duhamelantoine1995@gmail.com> (he/him) * [apapirovski](https://github.com/apapirovski) - **Anatoli Papirovski** <apapirovski@mac.com> (he/him) * [BethGriggs](https://github.com/BethGriggs) - @@ -165,13 +170,15 @@ For information about the governance of the Node.js project, see * [cjihrig](https://github.com/cjihrig) - **Colin Ihrig** <cjihrig@gmail.com> (he/him) * [codebytere](https://github.com/codebytere) - -**Shelley Vohr** <codebytere@gmail.com> (she/her) +**Shelley Vohr** <shelley.vohr@gmail.com> (she/her) * [danbev](https://github.com/danbev) - **Daniel Bevenius** <daniel.bevenius@gmail.com> (he/him) +* [danielleadams](https://github.com/danielleadams) - +**Danielle Adams** <adamzdanielle@gmail.com> (she/her) * [fhinkel](https://github.com/fhinkel) - **Franziska Hinkelmann** <franziska.hinkelmann@gmail.com> (she/her) * [gabrielschulhof](https://github.com/gabrielschulhof) - -**Gabriel Schulhof** <gabriel.schulhof@intel.com> +**Gabriel Schulhof** <gabrielschulhof@gmail.com> * [gireeshpunathil](https://github.com/gireeshpunathil) - **Gireesh Punathil** <gpunathi@in.ibm.com> (he/him) * [jasnell](https://github.com/jasnell) - @@ -186,6 +193,8 @@ For information about the governance of the Node.js project, see **Mary Marchini** <oss@mmarchini.me> (she/her) * [MylesBorins](https://github.com/MylesBorins) - **Myles Borins** <myles.borins@gmail.com> (he/him) +* [ronag](https://github.com/ronag) - +**Robert Nagy** <ronagy@icloud.com> * [targos](https://github.com/targos) - **Michaël Zasso** <targos@protonmail.com> (he/him) * [tniessen](https://github.com/tniessen) - @@ -193,7 +202,11 @@ For information about the governance of the Node.js project, see * [Trott](https://github.com/Trott) - **Rich Trott** <rtrott@gmail.com> (he/him) -### TSC Emeriti +
+ +Emeriti + +### TSC emeriti * [addaleax](https://github.com/addaleax) - **Anna Henningsen** <anna@addaleax.net> (she/her) @@ -208,7 +221,7 @@ For information about the governance of the Node.js project, see * [gibfahn](https://github.com/gibfahn) - **Gibson Fahnestock** <gibfahn@gmail.com> (he/him) * [indutny](https://github.com/indutny) - -**Fedor Indutny** <fedor.indutny@gmail.com> +**Fedor Indutny** <fedor@indutny.com> * [isaacs](https://github.com/isaacs) - **Isaac Z. Schlueter** <i@izs.me> * [joshgav](https://github.com/joshgav) - @@ -236,6 +249,11 @@ For information about the governance of the Node.js project, see * [trevnorris](https://github.com/trevnorris) - **Trevor Norris** <trev.norris@gmail.com> +
+ + ### Collaborators * [addaleax](https://github.com/addaleax) - @@ -244,8 +262,6 @@ For information about the governance of the Node.js project, see **Antoine du Hamel** <duhamelantoine1995@gmail.com> (he/him) * [ak239](https://github.com/ak239) - **Aleksei Koziatinskii** <ak239spb@gmail.com> -* [AndreasMadsen](https://github.com/AndreasMadsen) - -**Andreas Madsen** <amwebdk@gmail.com> (he/him) * [antsmartian](https://github.com/antsmartian) - **Anto Aravinth** <anto.aravinth.cse@gmail.com> (he/him) * [apapirovski](https://github.com/apapirovski) - @@ -264,8 +280,6 @@ For information about the governance of the Node.js project, see **Bradley Farias** <bradley.meck@gmail.com> * [bmeurer](https://github.com/bmeurer) - **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) * [BridgeAR](https://github.com/BridgeAR) - @@ -279,7 +293,7 @@ For information about the governance of the Node.js project, see * [cjihrig](https://github.com/cjihrig) - **Colin Ihrig** <cjihrig@gmail.com> (he/him) * [codebytere](https://github.com/codebytere) - -**Shelley Vohr** <codebytere@gmail.com> (she/her) +**Shelley Vohr** <shelley.vohr@gmail.com> (she/her) * [danbev](https://github.com/danbev) - **Daniel Bevenius** <daniel.bevenius@gmail.com> (he/him) * [danielleadams](https://github.com/danielleadams) - @@ -292,6 +306,10 @@ For information about the governance of the Node.js project, see **David Carlier** <devnexen@gmail.com> * [devsnek](https://github.com/devsnek) - **Gus Caplan** <me@gus.host> (they/them) +* [dmabupt](https://github.com/dmabupt) - +**Xu Meng** <dmabupt@gmail.com> (he/him) +* [dnlup](https://github.com/dnlup) +**Daniele Belardi** <dwon.dnl@gmail.com> (he/him) * [edsadr](https://github.com/edsadr) - **Adrian Estrada** <edsadr@gmail.com> (he/him) * [eugeneo](https://github.com/eugeneo) - @@ -305,9 +323,7 @@ For information about the governance of the Node.js project, see * [Flarna](https://github.com/Flarna) - **Gerhard Stöbich** <deb2001-github@yahoo.de> (he/they) * [gabrielschulhof](https://github.com/gabrielschulhof) - -**Gabriel Schulhof** <gabriel.schulhof@intel.com> -* [gdams](https://github.com/gdams) - -**George Adams** <george.adams@uk.ibm.com> (he/him) +**Gabriel Schulhof** <gabrielschulhof@gmail.com> * [geek](https://github.com/geek) - **Wyatt Preul** <wpreul@gmail.com> * [gengjiawen](https://github.com/gengjiawen) - @@ -326,14 +342,14 @@ For information about the governance of the Node.js project, see **Zeyu Yang** <himself65@outlook.com> (he/him) * [hiroppy](https://github.com/hiroppy) - **Yuta Hiroto** <hello@hiroppy.me> (he/him) +* [iansu](https://github.com/iansu) - +**Ian Sutherland** <ian@iansutherland.ca> * [indutny](https://github.com/indutny) - -**Fedor Indutny** <fedor.indutny@gmail.com> +**Fedor Indutny** <fedor@indutny.com> * [JacksonTian](https://github.com/JacksonTian) - **Jackson Tian** <shyvo1987@gmail.com> * [jasnell](https://github.com/jasnell) - **James M Snell** <jasnell@gmail.com> (he/him) -* [jdalton](https://github.com/jdalton) - -**John-David Dalton** <john.david.dalton@gmail.com> * [jkrems](https://github.com/jkrems) - **Jan Krems** <jan.krems@gmail.com> (he/him) * [joaocgreis](https://github.com/joaocgreis) - @@ -344,42 +360,48 @@ For information about the governance of the Node.js project, see **Juan José Arboleda** <soyjuanarbol@gmail.com> (he/him) * [JungMinu](https://github.com/JungMinu) - **Minwoo Jung** <nodecorelab@gmail.com> (he/him) -* [lance](https://github.com/lance) - -**Lance Ball** <lball@redhat.com> (he/him) * [legendecas](https://github.com/legendecas) - **Chengzhong Wu** <legendecas@gmail.com> (he/him) * [Leko](https://github.com/Leko) - **Shingo Inoue** <leko.noor@gmail.com> (he/him) +* [linkgoron](https://github.com/linkgoron) - +**Nitzan Uziely** <linkgoron@gmail.com> * [lpinca](https://github.com/lpinca) - **Luigi Pinca** <luigipinca@gmail.com> (he/him) * [lundibundi](https://github.com/lundibundi) - **Denys Otrishko** <shishugi@gmail.com> (he/him) +* [Lxxyx](https://github.com/Lxxyx) - +**Zijian Liu** <lxxyxzj@gmail.com> (he/him) * [mafintosh](https://github.com/mafintosh) - **Mathias Buus** <mathiasbuus@gmail.com> (he/him) * [mcollina](https://github.com/mcollina) - **Matteo Collina** <matteo.collina@gmail.com> (he/him) * [mhdawson](https://github.com/mhdawson) - **Michael Dawson** <midawson@redhat.com> (he/him) +* [miladfarca](https://github.com/miladfarca) - +**Milad Fa** <mfarazma@redhat.com> (he/him) * [mildsunrise](https://github.com/mildsunrise) - **Alba Mendez** <me@alba.sh> (she/her) * [misterdjules](https://github.com/misterdjules) - -**Julien Gilli** <jgilli@nodejs.org> +**Julien Gilli** <jgilli@netflix.com> * [mmarchini](https://github.com/mmarchini) - **Mary Marchini** <oss@mmarchini.me> (she/her) * [mscdex](https://github.com/mscdex) - **Brian White** <mscdex@mscdex.net> * [MylesBorins](https://github.com/MylesBorins) - **Myles Borins** <myles.borins@gmail.com> (he/him) -* [ofrobots](https://github.com/ofrobots) - -**Ali Ijaz Sheikh** <ofrobots@google.com> (he/him) * [oyyd](https://github.com/oyyd) - **Ouyang Yadong** <oyydoibh@gmail.com> (he/him) -* [psmarshall](https://github.com/psmarshall) - -**Peter Marshall** <petermarshall@chromium.org> (he/him) +* [panva](https://github.com/panva) - +**Filip Skokan** <panva.ip@gmail.com> +* [PoojaDurgad](https://github.com/PoojaDurgad) - +**Pooja D P** <Pooja.D.P@ibm.com> (she/her) * [puzpuzpuz](https://github.com/puzpuzpuz) - **Andrey Pechkurov** <apechkurov@gmail.com> (he/him) * [Qard](https://github.com/Qard) - **Stephen Belanger** <admin@stephenbelanger.com> (he/him) +* [RaisinTen](https://github.com/RaisinTen) - +**Darshan Sen** <raisinten@gmail.com> (he/him) * [refack](https://github.com/refack) - **Refael Ackermann (רפאל פלחי)** <refack@gmail.com> (he/him/הוא/אתה) * [rexagod](https://github.com/rexagod) - @@ -390,10 +412,6 @@ For information about the governance of the Node.js project, see **Ricky Zhou** <0x19951125@gmail.com> (he/him) * [ronag](https://github.com/ronag) - **Robert Nagy** <ronagy@icloud.com> -* [ronkorving](https://github.com/ronkorving) - -**Ron Korving** <ron@ronkorving.nl> -* [rubys](https://github.com/rubys) - -**Sam Ruby** <rubys@intertwingly.net> * [ruyadorno](https://github.com/ruyadorno) - **Ruy Adorno** <ruyadorno@github.com> (he/him) * [rvagg](https://github.com/rvagg) - @@ -401,13 +419,11 @@ For information about the governance of the Node.js project, see * [ryzokuken](https://github.com/ryzokuken) - **Ujjwal Sharma** <ryzokuken@disroot.org> (he/him) * [saghul](https://github.com/saghul) - -**Saúl Ibarra Corretgé** <saghul@gmail.com> +**Saúl Ibarra Corretgé** <s@saghul.net> * [santigimeno](https://github.com/santigimeno) - **Santiago Gimeno** <santiago.gimeno@gmail.com> * [seishun](https://github.com/seishun) - **Nikolai Vavilov** <vvnicholas@gmail.com> -* [shigeki](https://github.com/shigeki) - -**Shigeki Ohtsu** <ohtsu@ohtsu.org> (he/him) * [shisama](https://github.com/shisama) - **Masashi Hirano** <shisama07@gmail.com> (he/him) * [silverwind](https://github.com/silverwind) - @@ -436,6 +452,8 @@ For information about the governance of the Node.js project, see **Thomas Watson** <w@tson.dk> * [XadillaX](https://github.com/XadillaX) - **Khaidi Chu** <i@2333.moe> (he/him) +* [yashLadha](https://github.com/yashLadha) - +**Yash Ladha** <yash@yashladha.in> (he/him) * [yhwang](https://github.com/yhwang) - **Yihong Wang** <yh.wang@ibm.com> * [yorkie](https://github.com/yorkie) - @@ -445,14 +463,24 @@ For information about the governance of the Node.js project, see * [ZYSzys](https://github.com/ZYSzys) - **Yongsheng Zhang** <zyszys98@gmail.com> (he/him) -### Collaborator Emeriti +
+ +Emeriti + + +### Collaborator emeriti * [andrasq](https://github.com/andrasq) - **Andras** <andras@kinvey.com> * [AnnaMag](https://github.com/AnnaMag) - **Anna M. Kedzierska** <anna.m.kedzierska@gmail.com> +* [AndreasMadsen](https://github.com/AndreasMadsen) - +**Andreas Madsen** <amwebdk@gmail.com> (he/him) * [aqrln](https://github.com/aqrln) - **Alexey Orlenko** <eaglexrlnk@gmail.com> (he/him) +* [bnoordhuis](https://github.com/bnoordhuis) - +**Ben Noordhuis** <info@bnoordhuis.nl> * [brendanashworth](https://github.com/brendanashworth) - **Brendan Ashworth** <brendan.ashworth@me.com> * [calvinmetcalf](https://github.com/calvinmetcalf) - @@ -471,6 +499,8 @@ For information about the governance of the Node.js project, see **Alexander Makarenko** <estliberitas@gmail.com> * [firedfox](https://github.com/firedfox) - **Daniel Wang** <wangyang0123@gmail.com> +* [gdams](https://github.com/gdams) - +**George Adams** <george.adams@microsoft.com> (he/him) * [gibfahn](https://github.com/gibfahn) - **Gibson Fahnestock** <gibfahn@gmail.com> (he/him) * [glentiki](https://github.com/glentiki) - @@ -489,6 +519,8 @@ For information about the governance of the Node.js project, see **Jason Ginchereau** <jasongin@microsoft.com> * [jbergstroem](https://github.com/jbergstroem) - **Johan Bergström** <bugs@bergstroem.nu> +* [jdalton](https://github.com/jdalton) - +**John-David Dalton** <john.david.dalton@gmail.com> * [jhamhader](https://github.com/jhamhader) - **Yuval Brik** <yuval@brik.org.il> * [joshgav](https://github.com/joshgav) - @@ -499,6 +531,8 @@ For information about the governance of the Node.js project, see **Kyle Farnung** <kfarnung@microsoft.com> (he/him) * [kunalspathak](https://github.com/kunalspathak) - **Kunal Pathak** <kunal.pathak@microsoft.com> +* [lance](https://github.com/lance) - +**Lance Ball** <lball@redhat.com> (he/him) * [lucamaraschi](https://github.com/lucamaraschi) - **Luca Maraschi** <luca.maraschi@gmail.com> (he/him) * [lxe](https://github.com/lxe) - @@ -517,6 +551,8 @@ For information about the governance of the Node.js project, see **Chen Gang** <gangc.cxy@foxmail.com> * [not-an-aardvark](https://github.com/not-an-aardvark) - **Teddy Katz** <teddy.katz@gmail.com> (he/him) +* [ofrobots](https://github.com/ofrobots) - +**Ali Ijaz Sheikh** <ofrobots@google.com> (he/him) * [Olegas](https://github.com/Olegas) - **Oleg Elifantiev** <oleg@elifantiev.ru> * [orangemocha](https://github.com/orangemocha) - @@ -533,6 +569,8 @@ For information about the governance of the Node.js project, see **Minqi Pan** <pmq2001@gmail.com> * [princejwesley](https://github.com/princejwesley) - **Prince John Wesley** <princejohnwesley@gmail.com> +* [psmarshall](https://github.com/psmarshall) - +**Peter Marshall** <petermarshall@chromium.org> (he/him) * [rlidwka](https://github.com/rlidwka) - **Alex Kocharin** <alex@kocharin.ru> * [rmg](https://github.com/rmg) - @@ -541,12 +579,18 @@ For information about the governance of the Node.js project, see **Robert Kowalski** <rok@kowalski.gd> * [romankl](https://github.com/romankl) - **Roman Klauke** <romaaan.git@gmail.com> +* [ronkorving](https://github.com/ronkorving) - +**Ron Korving** <ron@ronkorving.nl> * [RReverser](https://github.com/RReverser) - **Ingvar Stepanyan** <me@rreverser.com> +* [rubys](https://github.com/rubys) - +**Sam Ruby** <rubys@intertwingly.net> * [sam-github](https://github.com/sam-github) - **Sam Roberts** <vieuxtech@gmail.com> * [sebdeckers](https://github.com/sebdeckers) - **Sebastiaan Deckers** <sebdeckers83@gmail.com> +* [shigeki](https://github.com/shigeki) - +**Shigeki Ohtsu** <ohtsu@ohtsu.org> (he/him) * [stefanmb](https://github.com/stefanmb) - **Stefan Budeanu** <stefan@budeanu.com> * [tellnes](https://github.com/tellnes) - @@ -565,6 +609,8 @@ For information about the governance of the Node.js project, see **Vse Mozhet Byt** <vsemozhetbyt@gmail.com> (he/him) * [whitlockjc](https://github.com/whitlockjc) - **Jeremy Whitlock** <jwhitlock@apache.org> + +
Collaborators follow the [Collaborator Guide](./doc/guides/collaborator-guide.md) in @@ -572,10 +618,18 @@ maintaining the Node.js project. ### Triagers +* [Ayase-252](https://github.com/Ayase-252) - +**Qingyu Deng** <i@ayase-lab.com> +* [himadriganguly](https://github.com/himadriganguly) - +**Himadri Ganguly** <himadri.tech@gmail.com> (he/him) +* [marsonya](https://github.com/marsonya) - +**Akhil Marsonya** <akhil.marsonya27@gmail.com> (he/him) * [PoojaDurgad](https://github.com/PoojaDurgad) - **Pooja Durgad** <Pooja.D.P@ibm.com> +* [RaisinTen](https://github.com/RaisinTen) - +**Darshan Sen** <raisinten@gmail.com> -### Release Keys +### Release keys Primary GPG keys for Node.js Releasers (some Releasers sign with subkeys): @@ -583,6 +637,8 @@ Primary GPG keys for Node.js Releasers (some Releasers sign with subkeys): `4ED778F539E3634C779C87C6D7062848A1AB005C` * **Colin Ihrig** <cjihrig@gmail.com> `94AE36675C464D64BAFA68DD7434390BDBE9B9C5` +* **Danielle Adams** <adamzdanielle@gmail.com> +`74F12602B6F1C4E913FAA37AD3A89613643B6201` * **James M Snell** <jasnell@keybase.io> `71DCFD284A79C3B38668286BC97EC7A07EDE3FC1` * **Michaël Zasso** <targos@protonmail.com> @@ -600,11 +656,13 @@ Primary GPG keys for Node.js Releasers (some Releasers sign with subkeys): * **Shelley Vohr** <shelley.vohr@gmail.com> `B9E2F5981AA6E0CD28160D9FF13993A75599653C` -To import the full set of trusted release keys: +To import the full set of trusted release keys (including subkeys possibly used +to sign releases): ```bash gpg --keyserver pool.sks-keyservers.net --recv-keys 4ED778F539E3634C779C87C6D7062848A1AB005C gpg --keyserver pool.sks-keyservers.net --recv-keys 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 +gpg --keyserver pool.sks-keyservers.net --recv-keys 74F12602B6F1C4E913FAA37AD3A89613643B6201 gpg --keyserver pool.sks-keyservers.net --recv-keys 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 gpg --keyserver pool.sks-keyservers.net --recv-keys 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 gpg --keyserver pool.sks-keyservers.net --recv-keys C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 @@ -618,10 +676,14 @@ gpg --keyserver pool.sks-keyservers.net --recv-keys B9E2F5981AA6E0CD28160D9FF139 See the section above on [Verifying Binaries](#verifying-binaries) for how to use these keys to verify a downloaded file. -Other keys used to sign some previous releases: +
+ +Other keys used to sign some previous releases * **Chris Dickinson** <christopher.s.dickinson@gmail.com> `9554F04D7259F04124DE6B476D5A82AC7E37093B` +* **Danielle Adams** <adamzdanielle@gmail.com> +`1C050899334244A8AF75E53792EF661D867B9DFA` * **Evan Lucas** <evanlucas@me.com> `B9AE9905FFD7803F25714661B63B535A4C206CA9` * **Gibson Fahnestock** <gibfahn@gmail.com> @@ -637,10 +699,20 @@ Other keys used to sign some previous releases: * **Timothy J Fontaine** <tjfontaine@gmail.com> `7937DFD2AB06298B2293C3187D33FF9D0246406D` -[Code of Conduct]: https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md +
+ +## License + +Node.js is available under the +[MIT license](https://opensource.org/licenses/MIT). Node.js also includes +external libraries that are available under a variety of licenses. See +[LICENSE](https://github.com/nodejs/node/blob/HEAD/LICENSE) for the full +license text. + +[Code of Conduct]: https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md [Contributing to the project]: CONTRIBUTING.md [Node.js Website]: https://nodejs.org/ [OpenJS Foundation]: https://openjsf.org/ -[Strategic Initiatives]: https://github.com/nodejs/TSC/blob/master/Strategic-Initiatives.md +[Strategic initiatives]: doc/guides/strategic-initiatives.md [Technical values and prioritization]: doc/guides/technical-values.md -[Working Groups]: https://github.com/nodejs/TSC/blob/master/WORKING_GROUPS.md +[Working Groups]: https://github.com/nodejs/TSC/blob/HEAD/WORKING_GROUPS.md diff --git a/SECURITY.md b/SECURITY.md index e121072ffe43812e70e6c836f1cfda9cc756fcd0..859b88e8a175a976db4d1cb326bae33b780be43e 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -26,7 +26,7 @@ maintainers and should also be coordinated through the Node.js Ecosystem Security Team via [HackerOne](https://hackerone.com/nodejs-ecosystem). Details regarding this process can be found in the -[Security Working Group repository](https://github.com/nodejs/security-wg/blob/master/processes/third_party_vuln_process.md). +[Security Working Group repository](https://github.com/nodejs/security-wg/blob/HEAD/processes/third_party_vuln_process.md). Thank you for improving the security of Node.js and its ecosystem. Your efforts and responsible disclosure are greatly appreciated and will be acknowledged. diff --git a/android-configure b/android-configure index a7cb2b9c8b4a7833a195d133d370f36fa483b8d9..43341d1abea765bbd08c80b384511874395bf09a 100644 --- a/android-configure +++ b/android-configure @@ -10,7 +10,7 @@ if [ $# -ne 3 ]; then echo "$0 should have 3 parameters: ndk_path, target_arch and sdk_version" - exit 1 + return 1 fi NDK_PATH=$1 @@ -44,21 +44,21 @@ case $ARCH in ;; *) echo "Unsupported architecture provided: $ARCH" - exit 1 + return 1 ;; esac HOST_OS="linux" HOST_ARCH="x86_64" -export CC_host=$(which gcc) -export CXX_host=$(which g++) +export CC_host=$(command -v gcc) +export CXX_host=$(command -v g++) host_gcc_version=$($CC_host --version | grep gcc | awk '{print $NF}') major=$(echo $host_gcc_version | awk -F . '{print $1}') minor=$(echo $host_gcc_version | awk -F . '{print $2}') -if [ -z $major ] || [ -z $minor ] || [ $major -lt 6 ] || [ $major -eq 6 -a $minor -lt 3 ]; then +if [ -z $major ] || [ -z $minor ] || [ $major -lt 6 ] || ( [ $major -eq 6 ] && [ $minor -lt 3 ] ); then echo "host gcc $host_gcc_version is too old, need gcc 6.3.0" - exit 1 + return 1 fi SUFFIX="$TOOLCHAIN_NAME$ANDROID_SDK_VERSION" diff --git a/benchmark/_benchmark_progress.js b/benchmark/_benchmark_progress.js index 1b7ac738f6de0d9e74de96f38de6d0f1e538a963..6c925f34e682025d707ac4bd295cf45796041b81 100644 --- a/benchmark/_benchmark_progress.js +++ b/benchmark/_benchmark_progress.js @@ -39,7 +39,6 @@ class BenchmarkProgress { this.completedConfig = 0; // Total number of configurations for the current file this.scheduledConfig = 0; - this.interval; // Updates the elapsed time. } startQueue(index) { diff --git a/benchmark/_http-benchmarkers.js b/benchmark/_http-benchmarkers.js index d0f192e75948b68e8b442b2230704d9ed1e22828..615579cba52416619859b0420f0436cd10acec98 100644 --- a/benchmark/_http-benchmarkers.js +++ b/benchmark/_http-benchmarkers.js @@ -5,7 +5,7 @@ const path = require('path'); const fs = require('fs'); const requirementsURL = - 'https://github.com/nodejs/node/blob/master/benchmark/writing-and-running-benchmarks.md#http-benchmark-requirements'; + 'https://github.com/nodejs/node/blob/HEAD/benchmark/writing-and-running-benchmarks.md#http-benchmark-requirements'; // The port used by servers and wrk exports.PORT = Number(process.env.PORT) || 12346; @@ -29,7 +29,8 @@ class AutocannonBenchmarker { for (const field in options.headers) { args.push('-H', `${field}=${options.headers[field]}`); } - args.push(`http://127.0.0.1:${options.port}${options.path}`); + const scheme = options.scheme || 'http'; + args.push(`${scheme}://127.0.0.1:${options.port}${options.path}`); const child = child_process.spawn(this.executable, args); return child; } @@ -60,11 +61,12 @@ class WrkBenchmarker { const duration = typeof options.duration === 'number' ? Math.max(options.duration, 1) : options.duration; + const scheme = options.scheme || 'http'; const args = [ '-d', duration, '-c', options.connections, '-t', Math.min(options.connections, require('os').cpus().length || 8), - `http://127.0.0.1:${options.port}${options.path}`, + `${scheme}://127.0.0.1:${options.port}${options.path}`, ]; for (const field in options.headers) { args.push('-H', `${field}: ${options.headers[field]}`); @@ -90,8 +92,8 @@ class WrkBenchmarker { */ class TestDoubleBenchmarker { constructor(type) { - // `type` is the type of benchmarker. Possible values are 'http' and - // 'http2'. + // `type` is the type of benchmarker. Possible values are 'http', 'https', + // and 'http2'. this.name = `test-double-${type}`; this.executable = path.resolve(__dirname, '_test-double-benchmarker.js'); this.present = fs.existsSync(this.executable); @@ -101,8 +103,9 @@ class TestDoubleBenchmarker { create(options) { process.env.duration = process.env.duration || options.duration || 5; + const scheme = options.scheme || 'http'; const env = { - test_url: `http://127.0.0.1:${options.port}${options.path}`, + test_url: `${scheme}://127.0.0.1:${options.port}${options.path}`, ...process.env }; @@ -179,6 +182,7 @@ const http_benchmarkers = [ new WrkBenchmarker(), new AutocannonBenchmarker(), new TestDoubleBenchmarker('http'), + new TestDoubleBenchmarker('https'), new TestDoubleBenchmarker('http2'), new H2LoadBenchmarker(), ]; @@ -218,7 +222,7 @@ exports.run = function(options, callback) { return; } - const benchmarker_start = process.hrtime(); + const benchmarker_start = process.hrtime.bigint(); const child = benchmarker.create(options); @@ -229,7 +233,7 @@ exports.run = function(options, callback) { child.stdout.on('data', (chunk) => stdout += chunk); child.once('close', (code) => { - const elapsed = process.hrtime(benchmarker_start); + const benchmark_end = process.hrtime.bigint(); if (code) { let error_message = `${options.benchmarker} failed with ${code}.`; if (stdout !== '') { @@ -246,6 +250,7 @@ exports.run = function(options, callback) { return; } + const elapsed = benchmark_end - benchmarker_start; callback(null, code, options.benchmarker, result, elapsed); }); diff --git a/benchmark/_test-double-benchmarker.js b/benchmark/_test-double-benchmarker.js index 60264dfd46a60696d1d4e18f9c65c3debbac7d79..2d05f9fd92be2bfd9dd5f953e7357ecb8cdc3aa7 100644 --- a/benchmark/_test-double-benchmarker.js +++ b/benchmark/_test-double-benchmarker.js @@ -1,10 +1,15 @@ 'use strict'; const myModule = process.argv[2]; -if (!['http', 'http2'].includes(myModule)) { +if (!['http', 'https', 'http2'].includes(myModule)) { throw new Error(`Invalid module for benchmark test double: ${myModule}`); } +let options; +if (myModule === 'https') { + options = { rejectUnauthorized: false }; +} + const http = require(myModule); const duration = +process.env.duration; @@ -33,11 +38,15 @@ function request(res, client) { } function run() { - if (http.get) { // HTTP - http.get(url, request); + if (http.get) { // HTTP or HTTPS + if (options) { + http.get(url, options, request); + } else { + http.get(url, request); + } } else { // HTTP/2 const client = http.connect(url); - client.on('error', (e) => { throw e; }); + client.on('error', () => {}); request(client.request(), client); } } diff --git a/benchmark/async_hooks/async-local-storage-run.js b/benchmark/async_hooks/async-local-storage-run.js new file mode 100644 index 0000000000000000000000000000000000000000..d65abb7047b2e4a8add11872d179501a22604057 --- /dev/null +++ b/benchmark/async_hooks/async-local-storage-run.js @@ -0,0 +1,21 @@ +'use strict'; +const common = require('../common.js'); +const { AsyncLocalStorage } = require('async_hooks'); + +const bench = common.createBenchmark(main, { + n: [1e7] +}); + +async function run(store, n) { + for (let i = 0; i < n; i++) { + await new Promise((resolve) => store.run(i, resolve)); + } +} + +function main({ n }) { + const store = new AsyncLocalStorage(); + bench.start(); + run(store, n).then(() => { + bench.end(n); + }); +} diff --git a/benchmark/async_hooks/promises.js b/benchmark/async_hooks/promises.js index e74e3d37af11fc1762477caf25231bf53922f51f..d60ae70192c8cb101cfad92895839f30586e70c3 100644 --- a/benchmark/async_hooks/promises.js +++ b/benchmark/async_hooks/promises.js @@ -2,10 +2,37 @@ const common = require('../common.js'); const { createHook } = require('async_hooks'); +let hook; +const tests = { + disabled() { + hook = createHook({ + promiseResolve() {} + }); + }, + enabled() { + hook = createHook({ + promiseResolve() {} + }).enable(); + }, + enabledWithDestroy() { + hook = createHook({ + promiseResolve() {}, + destroy() {} + }).enable(); + }, + enabledWithInitOnly() { + hook = createHook({ + init() {} + }).enable(); + } +}; + const bench = common.createBenchmark(main, { n: [1e6], asyncHooks: [ 'enabled', + 'enabledWithDestroy', + 'enabledWithInitOnly', 'disabled', ] }); @@ -20,10 +47,8 @@ async function run(n) { } function main({ n, asyncHooks }) { - const hook = createHook({ promiseResolve() {} }); - if (asyncHooks !== 'disabled') { - hook.enable(); - } + if (hook) hook.disable(); + tests[asyncHooks](); bench.start(); run(n).then(() => { bench.end(n); diff --git a/benchmark/child_process/child-process-params.js b/benchmark/child_process/child-process-params.js index df930395b2a0159721434508ee5a227e6247a86d..8db8d3ace20c538506de3e873c4dccd36e37aeca 100644 --- a/benchmark/child_process/child-process-params.js +++ b/benchmark/child_process/child-process-params.js @@ -82,6 +82,7 @@ function main({ n, methodName, params }) { } break; case 'execFileSync': + case 'spawnSync': switch (params) { case 1: bench.start(); @@ -119,24 +120,5 @@ function main({ n, methodName, params }) { break; } break; - case 'spawnSync': - switch (params) { - case 1: - bench.start(); - for (let i = 0; i < n; i++) method(command); - bench.end(n); - break; - case 2: - bench.start(); - for (let i = 0; i < n; i++) method(command, args); - bench.end(n); - break; - case 3: - bench.start(); - for (let i = 0; i < n; i++) method(command, args, options); - bench.end(n); - break; - } - break; } } diff --git a/benchmark/child_process/child-process-read-ipc.js b/benchmark/child_process/child-process-read-ipc.js index 827f75b1e54bd1512b63b9de95de75f0a384bf48..280505026cd02ecb6b869041357280cbcbf370b6 100644 --- a/benchmark/child_process/child-process-read-ipc.js +++ b/benchmark/child_process/child-process-read-ipc.js @@ -13,7 +13,7 @@ if (process.argv[2] === 'child') { const bench = common.createBenchmark(main, { len: [ 64, 256, 1024, 4096, 16384, 65536, - 65536 << 4, 65536 << 8, + 65536 << 4, 65536 << 6 - 1, ], dur: [5] }); diff --git a/benchmark/common.js b/benchmark/common.js index 701a8d6c34f07f74acde23af0957ea18ca3927d5..28a317b9a1d7a4bd23c4ccb627b87f657015ca0d 100644 --- a/benchmark/common.js +++ b/benchmark/common.js @@ -4,24 +4,24 @@ const child_process = require('child_process'); const http_benchmarkers = require('./_http-benchmarkers.js'); class Benchmark { - // Used to make sure a benchmark only start a timer once - #started = false; + constructor(fn, configs, options = {}) { + // Used to make sure a benchmark only start a timer once + this._started = false; - // Indicate that the benchmark ended - #ended = false; + // Indicate that the benchmark ended + this._ended = false; - // Holds process.hrtime value - #time = [0, 0]; + // Holds process.hrtime value + this._time = 0n; - // Use the file name as the name of the benchmark - name = require.main.filename.slice(__dirname.length + 1); + // Use the file name as the name of the benchmark + this.name = require.main.filename.slice(__dirname.length + 1); - // Execution arguments i.e. flags used to run the jobs - flags = process.env.NODE_BENCHMARK_FLAGS ? - process.env.NODE_BENCHMARK_FLAGS.split(/\s+/) : - []; + // Execution arguments i.e. flags used to run the jobs + this.flags = process.env.NODE_BENCHMARK_FLAGS ? + process.env.NODE_BENCHMARK_FLAGS.split(/\s+/) : + []; - constructor(fn, configs, options = {}) { // Parse job-specific configuration from the command line arguments const argv = process.argv.slice(2); const parsed_args = this._parseArgs(argv, configs, options); @@ -214,21 +214,21 @@ class Benchmark { } start() { - if (this.#started) { + if (this._started) { throw new Error('Called start more than once in a single benchmark'); } - this.#started = true; - this.#time = process.hrtime(); + this._started = true; + this._time = process.hrtime.bigint(); } end(operations) { // Get elapsed time now and do error checking later for accuracy. - const elapsed = process.hrtime(this.#time); + const time = process.hrtime.bigint(); - if (!this.#started) { + if (!this._started) { throw new Error('called end without start'); } - if (this.#ended) { + if (this._ended) { throw new Error('called end multiple times'); } if (typeof operations !== 'number') { @@ -237,16 +237,19 @@ class Benchmark { if (!process.env.NODEJS_BENCHMARK_ZERO_ALLOWED && operations <= 0) { throw new Error('called end() with operation count <= 0'); } - if (elapsed[0] === 0 && elapsed[1] === 0) { + + this._ended = true; + + if (time === this._time) { if (!process.env.NODEJS_BENCHMARK_ZERO_ALLOWED) throw new Error('insufficient clock precision for short benchmark'); // Avoid dividing by zero - elapsed[1] = 1; + this.report(operations && Number.MAX_VALUE, 0n); + return; } - this.#ended = true; - const time = elapsed[0] + elapsed[1] / 1e9; - const rate = operations / time; + const elapsed = time - this._time; + const rate = operations / (Number(elapsed) / 1e9); this.report(rate, elapsed); } @@ -255,12 +258,21 @@ class Benchmark { name: this.name, conf: this.config, rate, - time: elapsed[0] + elapsed[1] / 1e9, + time: nanoSecondsToString(elapsed), type: 'report', }); } } +function nanoSecondsToString(bigint) { + const str = bigint.toString(); + const decimalPointIndex = str.length - 9; + if (decimalPointIndex <= 0) { + return `0.${'0'.repeat(-decimalPointIndex)}${str}`; + } + return `${str.slice(0, decimalPointIndex)}.${str.slice(decimalPointIndex)}`; +} + function formatResult(data) { // Construct configuration string, " A=a, B=b, ..." let conf = ''; @@ -271,7 +283,7 @@ function formatResult(data) { let rate = data.rate.toString().split('.'); rate[0] = rate[0].replace(/(\d)(?=(?:\d\d\d)+(?!\d))/g, '$1,'); rate = (rate[1] ? rate.join('.') : rate[0]); - return `${data.name}${conf}: ${rate}`; + return `${data.name}${conf}: ${rate}\n`; } function sendResult(data) { @@ -280,7 +292,7 @@ function sendResult(data) { process.send(data); } else { // Otherwise report by stdout - console.log(formatResult(data)); + process.stdout.write(formatResult(data)); } } diff --git a/benchmark/compare.R b/benchmark/compare.R index 7a0c89af3de4c5e46c1fbf1d923c8a335ce3e93a..21e35b7e8f1b9fb0753e4230c9085afda15e378c 100644 --- a/benchmark/compare.R +++ b/benchmark/compare.R @@ -23,7 +23,7 @@ dat = read.csv( dat = data.frame(dat); dat$nameTwoLines = paste0(dat$filename, '\n', dat$configuration); -dat$name = paste0(dat$filename, dat$configuration); +dat$name = paste0(dat$filename, ' ', dat$configuration); # Create a box plot if (!is.null(plot.filename)) { @@ -35,14 +35,14 @@ if (!is.null(plot.filename)) { ggsave(plot.filename, p); } -# computes the shared standard error, as used in the welch t-test +# Computes the shared standard error, as used in Welch's t-test. welch.sd = function (old.rate, new.rate) { old.se.squared = var(old.rate) / length(old.rate) new.se.squared = var(new.rate) / length(new.rate) return(sqrt(old.se.squared + new.se.squared)) } -# calculate the improvement confidence interval. The improvement is calculated +# Calculate the improvement confidence interval. The improvement is calculated # by dividing by old.mu and not new.mu, because old.mu is what the mean # improvement is calculated relative to. confidence.interval = function (shared.se, old.mu, w, risk) { @@ -50,7 +50,7 @@ confidence.interval = function (shared.se, old.mu, w, risk) { return(sprintf("±%.2f%%", (interval / old.mu) * 100)) } -# Print a table with results +# Calculate the statistics table. statistics = ddply(dat, "name", function(subdat) { old.rate = subset(subdat, binary == "old")$rate; new.rate = subset(subdat, binary == "new")$rate; @@ -68,14 +68,14 @@ statistics = ddply(dat, "name", function(subdat) { "(***)" = "NA" ); - # Check if there is enough data to calculate the calculate the p-value + # Check if there is enough data to calculate the p-value. if (length(old.rate) > 1 && length(new.rate) > 1) { - # Perform a statistics test to see of there actually is a difference in + # Perform a statistical test to see if there actually is a difference in # performance. w = t.test(rate ~ binary, data=subdat); shared.se = welch.sd(old.rate, new.rate) - # Add user friendly stars to the table. There should be at least one star + # Add user-friendly stars to the table. There should be at least one star # before you can say that there is an improvement. confidence = ''; if (w$p.value < 0.001) { @@ -99,7 +99,7 @@ statistics = ddply(dat, "name", function(subdat) { }); -# Set the benchmark names as the row.names to left align them in the print +# Set the benchmark names as the row.names to left align them in the print. row.names(statistics) = statistics$name; statistics$name = NULL; @@ -108,7 +108,7 @@ print(statistics); cat("\n") cat(sprintf( "Be aware that when doing many comparisons the risk of a false-positive -result increases. In this case there are %d comparisons, you can thus +result increases. In this case, there are %d comparisons, you can thus expect the following amount of false-positive results: %.2f false positives, when considering a 5%% risk acceptance (*, **, ***), %.2f false positives, when considering a 1%% risk acceptance (**, ***), diff --git a/benchmark/compare.js b/benchmark/compare.js index 5c9cd03be3fdee5e8437c6ebd8fcd7176acd9e04..169948e006d660651a40a4c4b4a3e1fc4c7fd270 100644 --- a/benchmark/compare.js +++ b/benchmark/compare.js @@ -56,7 +56,7 @@ for (const filename of benchmarks) { // queue.length = binary.length * runs * benchmarks.length // Print csv header -console.log('"binary", "filename", "configuration", "rate", "time"'); +console.log('"binary","filename","configuration","rate","time"'); const kStartOfQueue = 0; @@ -85,8 +85,8 @@ if (showProgress) { // Escape quotes (") for correct csv formatting conf = conf.replace(/"/g, '""'); - console.log(`"${job.binary}", "${job.filename}", "${conf}", ` + - `${data.rate}, ${data.time}`); + console.log(`"${job.binary}","${job.filename}","${conf}",` + + `${data.rate},${data.time}`); if (showProgress) { // One item in the subqueue has been completed. progress.completeConfig(data); diff --git a/benchmark/crypto/randomUUID.js b/benchmark/crypto/randomUUID.js new file mode 100644 index 0000000000000000000000000000000000000000..cca05242874738e577893725d5393c06dfca4d04 --- /dev/null +++ b/benchmark/crypto/randomUUID.js @@ -0,0 +1,17 @@ +'use strict'; + +const common = require('../common.js'); +const { randomUUID } = require('crypto'); + +const bench = common.createBenchmark(main, { + n: [1e7], + disableEntropyCache: [0, 1], +}); + +function main({ n, disableEntropyCache }) { + disableEntropyCache = !!disableEntropyCache; + bench.start(); + for (let i = 0; i < n; ++i) + randomUUID({ disableEntropyCache }); + bench.end(n); +} diff --git a/benchmark/diagnostics_channel/http.js b/benchmark/diagnostics_channel/http.js new file mode 100644 index 0000000000000000000000000000000000000000..55fac8a706df15a12f6b3d8568b2be1f87fdba63 --- /dev/null +++ b/benchmark/diagnostics_channel/http.js @@ -0,0 +1,96 @@ +'use strict'; +const common = require('../common.js'); +const dc = require('diagnostics_channel'); +const { AsyncLocalStorage } = require('async_hooks'); +const http = require('http'); + +const bench = common.createBenchmark(main, { + apm: ['none', 'diagnostics_channel', 'patch'], + type: 'buffer', + len: 1024, + chunks: 4, + connections: [50, 500], + chunkedEnc: 1, + duration: 5 +}); + +function main({ apm, connections, duration, type, len, chunks, chunkedEnc }) { + const done = { none, patch, diagnostics_channel }[apm](); + + const server = require('../fixtures/simple-http-server.js') + .listen(common.PORT) + .on('listening', () => { + const path = `/${type}/${len}/${chunks}/normal/${chunkedEnc}`; + bench.http({ + path, + connections, + duration + }, () => { + server.close(); + if (done) done(); + }); + }); +} + +function none() {} + +function patch() { + const als = new AsyncLocalStorage(); + const times = []; + + const { emit } = http.Server.prototype; + function wrappedEmit(...args) { + const [name, req, res] = args; + if (name === 'request') { + als.enterWith({ + url: req.url, + start: process.hrtime.bigint() + }); + + res.on('finish', () => { + times.push({ + ...als.getStore(), + statusCode: res.statusCode, + end: process.hrtime.bigint() + }); + }); + } + return emit.apply(this, args); + } + http.Server.prototype.emit = wrappedEmit; + + return () => { + http.Server.prototype.emit = emit; + }; +} + +function diagnostics_channel() { + const als = new AsyncLocalStorage(); + const times = []; + + const start = dc.channel('http.server.request.start'); + const finish = dc.channel('http.server.response.finish'); + + function onStart(req) { + als.enterWith({ + url: req.url, + start: process.hrtime.bigint() + }); + } + + function onFinish(res) { + times.push({ + ...als.getStore(), + statusCode: res.statusCode, + end: process.hrtime.bigint() + }); + } + + start.subscribe(onStart); + finish.subscribe(onFinish); + + return () => { + start.unsubscribe(onStart); + finish.unsubscribe(onFinish); + }; +} diff --git a/benchmark/diagnostics_channel/publish.js b/benchmark/diagnostics_channel/publish.js new file mode 100644 index 0000000000000000000000000000000000000000..31a770c862791955337ca3d0e1866f1afd6b90b5 --- /dev/null +++ b/benchmark/diagnostics_channel/publish.js @@ -0,0 +1,29 @@ +'use strict'; +const common = require('../common.js'); +const dc = require('diagnostics_channel'); + +const bench = common.createBenchmark(main, { + n: [1e8], + subscribers: [0, 1, 10], +}); + +function noop() {} + +function main({ n, subscribers }) { + const channel = dc.channel('test'); + for (let i = 0; i < subscribers; i++) { + channel.subscribe(noop); + } + + const data = { + foo: 'bar' + }; + + bench.start(); + for (let i = 0; i < n; i++) { + if (channel.hasSubscribers) { + channel.publish(data); + } + } + bench.end(n); +} diff --git a/benchmark/diagnostics_channel/subscribe.js b/benchmark/diagnostics_channel/subscribe.js new file mode 100644 index 0000000000000000000000000000000000000000..1415054588c4b1141f1571eed7dd00bc67ecafec --- /dev/null +++ b/benchmark/diagnostics_channel/subscribe.js @@ -0,0 +1,19 @@ +'use strict'; +const common = require('../common.js'); +const dc = require('diagnostics_channel'); + +const bench = common.createBenchmark(main, { + n: [1e8], +}); + +function noop() {} + +function main({ n }) { + const channel = dc.channel('channel.0'); + + bench.start(); + for (let i = 0; i < n; i++) { + channel.subscribe(noop); + } + bench.end(n); +} diff --git a/benchmark/es/destructuring-bench.js b/benchmark/es/destructuring-bench.js index c07c0383da91acb205cb627f9e74df3a0b5147d4..d412b82757f0836b8da1f5a47e7ce2b75cb364ec 100644 --- a/benchmark/es/destructuring-bench.js +++ b/benchmark/es/destructuring-bench.js @@ -12,7 +12,8 @@ function runSwapManual(n) { let x, y, r; bench.start(); for (let i = 0; i < n; i++) { - x = 1, y = 2; + x = 1; + y = 2; r = x; x = y; y = r; @@ -26,7 +27,8 @@ function runSwapDestructured(n) { let x, y; bench.start(); for (let i = 0; i < n; i++) { - x = 1, y = 2; + x = 1; + y = 2; [x, y] = [y, x]; assert.strictEqual(x, 2); assert.strictEqual(y, 1); diff --git a/benchmark/events/eventtarget.js b/benchmark/events/eventtarget.js new file mode 100644 index 0000000000000000000000000000000000000000..d2c3ad034ff9b4471962149e0cd1ef905256c09c --- /dev/null +++ b/benchmark/events/eventtarget.js @@ -0,0 +1,22 @@ +'use strict'; +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + n: [1e6], + listeners: [1, 5, 10] +}, { flags: ['--expose-internals'] }); + +function main({ n, listeners }) { + const { EventTarget, Event } = require('internal/event_target'); + const target = new EventTarget(); + + for (let n = 0; n < listeners; n++) + target.addEventListener('foo', () => {}); + + bench.start(); + for (let i = 0; i < n; i++) { + target.dispatchEvent(new Event('foo')); + } + bench.end(n); + +} diff --git a/benchmark/fixtures/coverage-many-branches.js b/benchmark/fixtures/coverage-many-branches.js new file mode 100644 index 0000000000000000000000000000000000000000..9cb6360336e019a7d1a09cb82161c4f66b3aab60 --- /dev/null +++ b/benchmark/fixtures/coverage-many-branches.js @@ -0,0 +1,115 @@ +'use strict'; + +// Exercise coverage of a class. Note, this logic is silly and exists solely +// to generate branch coverage code paths: +class CoveredClass { + constructor(x, y, opts) { + this.x = x; + this.y = y; + // Exercise coverage of nullish coalescing: + this.opts = opts ?? (Math.random() > 0.5 ? {} : undefined); + } + add() { + return this.x + this.y; + } + addSpecial() { + // Exercise coverage of optional chains: + if (this.opts?.special && this.opts?.special?.x && this.opts?.special?.y) { + return this.opts.special.x + this.opts.special.y; + } + return add(); + } + mult() { + return this.x * this.y; + } + multSpecial() { + if (this.opts?.special && this.opts?.special?.x && this.opts?.special?.y) { + return this.opts.special.x * this.opts.special.y; + } + return mult(); + } +} + +// Excercise coverage of functions: +function add(x, y) { + const mt = new CoveredClass(x, y); + return mt.add(); +} + +function addSpecial(x, y) { + let mt; + if (Math.random() > 0.5) { + mt = new CoveredClass(x, y); + } else { + mt = new CoveredClass(x, y, { + special: { + x: Math.random() * x, + y: Math.random() * y + } + }); + } + return mt.addSpecial(); +} + +function mult(x, y) { + const mt = new CoveredClass(x, y); + return mt.mult(); +} + +function multSpecial(x, y) { + let mt; + if (Math.random() > 0.5) { + mt = new CoveredClass(x, y); + } else { + mt = new CoveredClass(x, y, { + special: { + x: Math.random() * x, + y: Math.random() * y + } + }); + } + return mt.multSpecial(); +} + +for (let i = 0; i < parseInt(process.env.N); i++) { + const operations = ['add', 'addSpecial', 'mult', 'multSpecial']; + for (const operation of operations) { + // Exercise coverage of switch statements: + switch (operation) { + case 'add': + if (add(Math.random() * 10, Math.random() * 10) > 10) { + // Exercise coverage of ternary operations: + let r = addSpecial(Math.random() * 10, Math.random() * 10) > 10 ? + mult(Math.random() * 10, Math.random() * 10) : + add(Math.random() * 10, Math.random() * 10); + // Exercise && and || + if (r && Math.random() > 0.5 || Math.random() < 0.5) r++; + } + break; + case 'addSpecial': + if (addSpecial(Math.random() * 10, Math.random() * 10) > 10 && + add(Math.random() * 10, Math.random() * 10) > 10) { + let r = mult(Math.random() * 10, Math.random() * 10) > 10 ? + add(Math.random() * 10, Math.random() * 10) > 10 : + mult(Math.random() * 10, Math.random() * 10); + if (r && Math.random() > 0.5 || Math.random() < 0.5) r++; + } + break; + case 'mult': + if (mult(Math.random() * 10, Math.random() * 10) > 10) { + let r = multSpecial(Math.random() * 10, Math.random() * 10) > 10 ? + add(Math.random() * 10, Math.random() * 10) : + mult(Math.random() * 10, Math.random() * 10); + if (r && Math.random() > 0.5 || Math.random() < 0.5) r++; + } + break; + case 'multSpecial': + while (multSpecial(Math.random() * 10, Math.random() * 10) < 10) { + mult(Math.random() * 10, Math.random() * 10); + } + break; + default: + break; + } + } +} diff --git a/benchmark/fixtures/require-builtins.js b/benchmark/fixtures/require-builtins.js new file mode 100644 index 0000000000000000000000000000000000000000..685eef1875b301a96e40e9be8cb9bb57efada158 --- /dev/null +++ b/benchmark/fixtures/require-builtins.js @@ -0,0 +1,44 @@ +'use strict'; + +const list = [ + 'async_hooks', + 'assert', + 'buffer', + 'child_process', + 'console', + 'constants', + 'crypto', + 'cluster', + 'dgram', + 'dns', + 'domain', + 'events', + 'fs', + 'http', + 'http2', + 'https', + 'module', + 'net', + 'os', + 'path', + 'perf_hooks', + 'process', + 'punycode', + 'querystring', + 'readline', + 'repl', + 'stream', + 'string_decoder', + 'timers', + 'tls', + 'tty', + 'url', + 'util', + 'vm', + 'zlib', +]; + +for (let i = 0; i < list.length; ++i) { + const item = list[i]; + require(item); +} diff --git a/benchmark/fixtures/simple-https-server.js b/benchmark/fixtures/simple-https-server.js new file mode 100644 index 0000000000000000000000000000000000000000..d3b07a110113d715961897642c2631119c2fd9a6 --- /dev/null +++ b/benchmark/fixtures/simple-https-server.js @@ -0,0 +1,72 @@ +'use strict'; + +const fixtures = require('../../test/common/fixtures'); +const https = require('https'); + +const options = { + key: fixtures.readKey('rsa_private.pem'), + cert: fixtures.readKey('rsa_cert.crt') +}; + +const storedBytes = Object.create(null); +const storedBuffer = Object.create(null); + +module.exports = https.createServer(options, (req, res) => { + // URL format: ////chunkedEnc + const params = req.url.split('/'); + const command = params[1]; + let body = ''; + const arg = params[2]; + const n_chunks = parseInt(params[3], 10); + const chunkedEnc = params.length >= 5 && params[4] === '0' ? false : true; + let status = 200; + + let n, i; + if (command === 'bytes') { + n = ~~arg; + if (n <= 0) + throw new Error('bytes called with n <= 0'); + if (storedBytes[n] === undefined) { + storedBytes[n] = 'C'.repeat(n); + } + body = storedBytes[n]; + } else if (command === 'buffer') { + n = ~~arg; + if (n <= 0) + throw new Error('buffer called with n <= 0'); + if (storedBuffer[n] === undefined) { + storedBuffer[n] = Buffer.allocUnsafe(n); + for (i = 0; i < n; i++) { + storedBuffer[n][i] = 'C'.charCodeAt(0); + } + } + body = storedBuffer[n]; + } else { + status = 404; + body = 'not found\n'; + } + + // example: https://localhost:port/bytes/512/4 + // sends a 512 byte body in 4 chunks of 128 bytes + const len = body.length; + if (chunkedEnc) { + res.writeHead(status, { + 'Content-Type': 'text/plain', + 'Transfer-Encoding': 'chunked' + }); + } else { + res.writeHead(status, { + 'Content-Type': 'text/plain', + 'Content-Length': len.toString() + }); + } + // send body in chunks + if (n_chunks > 1) { + const step = Math.floor(len / n_chunks) || 1; + for (i = 0, n = (n_chunks - 1); i < n; ++i) + res.write(body.slice(i * step, i * step + step)); + res.end(body.slice((n_chunks - 1) * step)); + } else { + res.end(body); + } +}); diff --git a/benchmark/fs/bench-statSync-failure.js b/benchmark/fs/bench-statSync-failure.js new file mode 100644 index 0000000000000000000000000000000000000000..82cb24c09f4af224a414fba9e638e99636c96139 --- /dev/null +++ b/benchmark/fs/bench-statSync-failure.js @@ -0,0 +1,28 @@ +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const path = require('path'); + +const bench = common.createBenchmark(main, { + n: [1e6], + statSyncType: ['throw', 'noThrow'] +}); + + +function main({ n, statSyncType }) { + const arg = path.join(__dirname, 'non.existent'); + + bench.start(); + for (let i = 0; i < n; i++) { + if (statSyncType === 'noThrow') { + fs.statSync(arg, { throwIfNoEntry: false }); + } else { + try { + fs.statSync(arg); + } catch { + } + } + } + bench.end(n); +} diff --git a/benchmark/fs/bench-statSync.js b/benchmark/fs/bench-statSync.js index 0c9366a402cb71763e3fa96843de056084b7ed7f..e75d6603fcfc644ad4f9db861a084e8b2476b4ae 100644 --- a/benchmark/fs/bench-statSync.js +++ b/benchmark/fs/bench-statSync.js @@ -21,6 +21,6 @@ function main({ n, statSyncType }) { } bench.end(n); - if (statSyncType === 'fstat') + if (statSyncType === 'fstatSync') fs.closeSync(arg); } diff --git a/benchmark/fs/read-stream-throughput.js b/benchmark/fs/read-stream-throughput.js index c6b4ecb166ac65af20fe272f8854c2d5d86d1d57..5984317ff91743496d0693c2f89d71bb72da3178 100644 --- a/benchmark/fs/read-stream-throughput.js +++ b/benchmark/fs/read-stream-throughput.js @@ -3,11 +3,14 @@ const path = require('path'); const common = require('../common.js'); -const filename = path.resolve(process.env.NODE_TMPDIR || __dirname, - `.removeme-benchmark-garbage-${process.pid}`); const fs = require('fs'); const assert = require('assert'); +const tmpdir = require('../../test/common/tmpdir'); +tmpdir.refresh(); +const filename = path.resolve(tmpdir.path, + `.removeme-benchmark-garbage-${process.pid}`); + const bench = common.createBenchmark(main, { encodingType: ['buf', 'asc', 'utf'], filesize: [1000 * 1024], diff --git a/benchmark/fs/readfile-promises.js b/benchmark/fs/readfile-promises.js new file mode 100644 index 0000000000000000000000000000000000000000..28633c3f06427be3aaa0478da00d4fb69ab55343 --- /dev/null +++ b/benchmark/fs/readfile-promises.js @@ -0,0 +1,63 @@ +// Call fs.promises.readFile over and over again really fast. +// Then see how many times it got called. +// Yes, this is a silly benchmark. Most benchmarks are silly. +'use strict'; + +const path = require('path'); +const common = require('../common.js'); +const fs = require('fs'); +const assert = require('assert'); + +const tmpdir = require('../../test/common/tmpdir'); +tmpdir.refresh(); +const filename = path.resolve(tmpdir.path, + `.removeme-benchmark-garbage-${process.pid}`); + +const bench = common.createBenchmark(main, { + duration: [5], + len: [1024, 16 * 1024 * 1024], + concurrent: [1, 10] +}); + +function main({ len, duration, concurrent }) { + try { fs.unlinkSync(filename); } catch { } + let data = Buffer.alloc(len, 'x'); + fs.writeFileSync(filename, data); + data = null; + + let writes = 0; + let benchEnded = false; + bench.start(); + setTimeout(() => { + benchEnded = true; + bench.end(writes); + try { fs.unlinkSync(filename); } catch { } + process.exit(0); + }, duration * 1000); + + function read() { + fs.promises.readFile(filename) + .then((res) => afterRead(undefined, res)) + .catch((err) => afterRead(err)); + } + + function afterRead(er, data) { + if (er) { + if (er.code === 'ENOENT') { + // Only OK if unlinked by the timer from main. + assert.ok(benchEnded); + return; + } + throw er; + } + + if (data.length !== len) + throw new Error('wrong number of bytes returned'); + + writes++; + if (!benchEnded) + read(); + } + + while (concurrent--) read(); +} diff --git a/benchmark/fs/readfile.js b/benchmark/fs/readfile.js index 25d87622bcba029ae0a3502a70333ce62075af83..3f996e02ede876574cd48db923cdcd80e9639d83 100644 --- a/benchmark/fs/readfile.js +++ b/benchmark/fs/readfile.js @@ -5,11 +5,14 @@ const path = require('path'); const common = require('../common.js'); -const filename = path.resolve(process.env.NODE_TMPDIR || __dirname, - `.removeme-benchmark-garbage-${process.pid}`); const fs = require('fs'); const assert = require('assert'); +const tmpdir = require('../../test/common/tmpdir'); +tmpdir.refresh(); +const filename = path.resolve(tmpdir.path, + `.removeme-benchmark-garbage-${process.pid}`); + const bench = common.createBenchmark(main, { duration: [5], len: [1024, 16 * 1024 * 1024], diff --git a/benchmark/fs/write-stream-throughput.js b/benchmark/fs/write-stream-throughput.js index f715dfb96d8679cdf101d0b355377afe9d4c5213..44a3bb23b041d1a61f18a2373d1e19ccd552c3f6 100644 --- a/benchmark/fs/write-stream-throughput.js +++ b/benchmark/fs/write-stream-throughput.js @@ -3,10 +3,13 @@ const path = require('path'); const common = require('../common.js'); -const filename = path.resolve(process.env.NODE_TMPDIR || __dirname, - `.removeme-benchmark-garbage-${process.pid}`); const fs = require('fs'); +const tmpdir = require('../../test/common/tmpdir'); +tmpdir.refresh(); +const filename = path.resolve(tmpdir.path, + `.removeme-benchmark-garbage-${process.pid}`); + const bench = common.createBenchmark(main, { dur: [5], encodingType: ['buf', 'asc', 'utf'], diff --git a/benchmark/fs/writefile-promises.js b/benchmark/fs/writefile-promises.js new file mode 100644 index 0000000000000000000000000000000000000000..2ba25184ff3132abac3ffd9ebd69725729f2349c --- /dev/null +++ b/benchmark/fs/writefile-promises.js @@ -0,0 +1,76 @@ +// Call fs.promises.writeFile over and over again really fast. +// Then see how many times it got called. +// Yes, this is a silly benchmark. Most benchmarks are silly. +'use strict'; + +const path = require('path'); +const common = require('../common.js'); +const fs = require('fs'); +const assert = require('assert'); +const tmpdir = require('../../test/common/tmpdir'); + +tmpdir.refresh(); +const filename = path.resolve(tmpdir.path, + `.removeme-benchmark-garbage-${process.pid}`); +let filesWritten = 0; +const bench = common.createBenchmark(main, { + duration: [5], + encodingType: ['buf', 'asc', 'utf'], + size: [2, 1024, 65535, 1024 * 1024], + concurrent: [1, 10] +}); + +function main({ encodingType, duration, concurrent, size }) { + let encoding; + let chunk; + switch (encodingType) { + case 'buf': + chunk = Buffer.alloc(size, 'b'); + break; + case 'asc': + chunk = 'a'.repeat(size); + encoding = 'ascii'; + break; + case 'utf': + chunk = 'ü'.repeat(Math.ceil(size / 2)); + encoding = 'utf8'; + break; + default: + throw new Error(`invalid encodingType: ${encodingType}`); + } + + let writes = 0; + let benchEnded = false; + bench.start(); + setTimeout(() => { + benchEnded = true; + bench.end(writes); + for (let i = 0; i < filesWritten; i++) { + try { fs.unlinkSync(`${filename}-${i}`); } catch { } + } + process.exit(0); + }, duration * 1000); + + function write() { + fs.promises.writeFile(`${filename}-${filesWritten++}`, chunk, encoding) + .then(() => afterWrite()) + .catch((err) => afterWrite(err)); + } + + function afterWrite(er) { + if (er) { + if (er.code === 'ENOENT') { + // Only OK if unlinked by the timer from main. + assert.ok(benchEnded); + return; + } + throw er; + } + + writes++; + if (!benchEnded) + write(); + } + + while (concurrent--) write(); +} diff --git a/benchmark/http/headers.js b/benchmark/http/headers.js index b83ac17e742a2ef2fbce501c3750740839b7d5b2..a3d2b7810be67625869b237ab8dca0ec83709056 100644 --- a/benchmark/http/headers.js +++ b/benchmark/http/headers.js @@ -4,7 +4,7 @@ const common = require('../common.js'); const http = require('http'); const bench = common.createBenchmark(main, { - n: [10, 1000], + n: [10, 600], len: [1, 100], duration: 5 }); diff --git a/benchmark/http2/compat.js b/benchmark/http2/compat.js index 2c7e732b07f0a5ad84d3d801e0b3bb0139716153..9ca7ab1ba08ef78ba912fde2c3f5421f1bd8768a 100644 --- a/benchmark/http2/compat.js +++ b/benchmark/http2/compat.js @@ -24,9 +24,10 @@ function main({ requests, streams, clients, duration }) { res.destroy(); }); }); - server.listen(common.PORT, () => { + server.listen(0, () => { bench.http({ path: '/', + port: server.address().port, requests, maxConcurrentStreams: streams, clients, diff --git a/benchmark/http2/headers.js b/benchmark/http2/headers.js index 56799da1987e5343c7f8406db9b50ba24a159df7..886f64be1c8b7ba35e2d9af092e58b497d2874e4 100644 --- a/benchmark/http2/headers.js +++ b/benchmark/http2/headers.js @@ -1,7 +1,6 @@ 'use strict'; const common = require('../common.js'); -const PORT = common.PORT; const bench = common.createBenchmark(main, { n: [1e3], @@ -32,8 +31,8 @@ function main({ n, nheaders }) { stream.respond(); stream.end('Hi!'); }); - server.listen(PORT, () => { - const client = http2.connect(`http://localhost:${PORT}/`, { + server.listen(0, () => { + const client = http2.connect(`http://localhost:${server.address().port}/`, { maxHeaderListPairs: 20000 }); diff --git a/benchmark/http2/respond-with-fd.js b/benchmark/http2/respond-with-fd.js index 5bf5988d16a64c43d2d74be1da3b83cca320e11c..547b6900b61f48251ec5a460d44c4d896bc4b8db 100644 --- a/benchmark/http2/respond-with-fd.js +++ b/benchmark/http2/respond-with-fd.js @@ -25,10 +25,11 @@ function main({ requests, streams, clients, duration }) { stream.respondWithFD(fd); stream.on('error', (err) => {}); }); - server.listen(common.PORT, () => { + server.listen(0, () => { bench.http({ path: '/', requests, + port: server.address().port, maxConcurrentStreams: streams, clients, duration, diff --git a/benchmark/http2/simple.js b/benchmark/http2/simple.js index 929c4c655e12955ad3eb391cb837aefb10124386..d9ac513d3c3e68b266d1195a25a06c47e53a66e3 100644 --- a/benchmark/http2/simple.js +++ b/benchmark/http2/simple.js @@ -22,9 +22,10 @@ function main({ requests, streams, clients, duration }) { out.pipe(stream); stream.on('error', (err) => {}); }); - server.listen(common.PORT, () => { + server.listen(0, () => { bench.http({ path: '/', + port: server.address().port, requests, maxConcurrentStreams: streams, clients, diff --git a/benchmark/http2/write.js b/benchmark/http2/write.js index 7ea8b2c02da65022515cae1dc2cac20cc5bb595c..caf93e2f2b62d55c9bbbcc0896e9b584fa424242 100644 --- a/benchmark/http2/write.js +++ b/benchmark/http2/write.js @@ -26,9 +26,10 @@ function main({ streams, length, size, duration }) { } write(); }); - server.listen(common.PORT, () => { + server.listen(0, () => { bench.http({ path: '/', + port: server.address().port, requests: 10000, duration, maxConcurrentStreams: streams, diff --git a/benchmark/https/simple.js b/benchmark/https/simple.js new file mode 100644 index 0000000000000000000000000000000000000000..243546c346f484ebd48971c383d725abfdc13d62 --- /dev/null +++ b/benchmark/https/simple.js @@ -0,0 +1,29 @@ +'use strict'; +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + type: ['bytes', 'buffer'], + len: [4, 1024, 102400], + chunks: [1, 4], + c: [50, 500], + chunkedEnc: [1, 0], + benchmarker: ['test-double-https'], + duration: 5 +}); + +function main({ type, len, chunks, c, chunkedEnc, duration }) { + const server = require('../fixtures/simple-https-server.js') + .listen(common.PORT) + .on('listening', () => { + const path = `/${type}/${len}/${chunks}/${chunkedEnc}`; + + bench.http({ + path, + connections: c, + scheme: 'https', + duration + }, () => { + server.close(); + }); + }); +} diff --git a/benchmark/misc/hidestackframes.js b/benchmark/misc/hidestackframes.js new file mode 100644 index 0000000000000000000000000000000000000000..5b14f2d95b22e2caf76b5a5f9fdc2c872d80b257 --- /dev/null +++ b/benchmark/misc/hidestackframes.js @@ -0,0 +1,45 @@ +'use strict'; + +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + type: ['hide-stackframes-throw', 'direct-call-throw', + 'hide-stackframes-noerr', 'direct-call-noerr'], + n: [10e4] +}, { + flags: ['--expose-internals'] +}); + +function main({ n, type }) { + const { + hideStackFrames, + codes: { + ERR_INVALID_ARG_TYPE, + }, + } = require('internal/errors'); + + const testfn = (value) => { + if (typeof value !== 'number') { + throw new ERR_INVALID_ARG_TYPE('Benchmark', 'number', value); + } + }; + + let fn = testfn; + if (type.startsWith('hide-stackframe')) + fn = hideStackFrames(testfn); + let value = 42; + if (type.endsWith('-throw')) + value = 'err'; + + bench.start(); + + for (let i = 0; i < n; i++) { + try { + fn(value); + } catch { + // No-op + } + } + + bench.end(n); +} diff --git a/benchmark/misc/startup.js b/benchmark/misc/startup.js index da24ee65199077999d1cd3dd97a348f987822323..dea5a31753f8fe927d785e9dd9e24da59e31b3ca 100644 --- a/benchmark/misc/startup.js +++ b/benchmark/misc/startup.js @@ -7,7 +7,11 @@ let Worker; // Lazy loaded in main const bench = common.createBenchmark(main, { dur: [1], - script: ['benchmark/fixtures/require-cachable', 'test/fixtures/semicolon'], + script: [ + 'benchmark/fixtures/require-builtins', + 'benchmark/fixtures/require-cachable', + 'test/fixtures/semicolon', + ], mode: ['process', 'worker'] }, { flags: ['--expose-internals'] diff --git a/benchmark/module/module-loader-circular.js b/benchmark/module/module-loader-circular.js new file mode 100644 index 0000000000000000000000000000000000000000..6d392e0e1908db1900ad095ada5ff7d3c773f69a --- /dev/null +++ b/benchmark/module/module-loader-circular.js @@ -0,0 +1,34 @@ +'use strict'; +const fs = require('fs'); +const path = require('path'); +const common = require('../common.js'); + +const tmpdir = require('../../test/common/tmpdir'); +const benchmarkDirectory = + path.resolve(tmpdir.path, 'benchmark-module-circular'); + +const bench = common.createBenchmark(main, { + n: [1e4] +}); + +function main({ n }) { + tmpdir.refresh(); + + const aDotJS = path.join(benchmarkDirectory, 'a.js'); + const bDotJS = path.join(benchmarkDirectory, 'b.js'); + + fs.mkdirSync(benchmarkDirectory); + fs.writeFileSync(aDotJS, 'require("./b.js");'); + fs.writeFileSync(bDotJS, 'require("./a.js");'); + + bench.start(); + for (let i = 0; i < n; i++) { + require(aDotJS); + require(bDotJS); + delete require.cache[aDotJS]; + delete require.cache[bDotJS]; + } + bench.end(n); + + tmpdir.refresh(); +} diff --git a/benchmark/napi/function_args/binding.cc b/benchmark/napi/function_args/binding.cc index 9f250aaa83db50b745b210bced34bbb8b88c04e3..078fe0ee3ea767616e7b938fe4a2fb8d6a2b8d6e 100644 --- a/benchmark/napi/function_args/binding.cc +++ b/benchmark/napi/function_args/binding.cc @@ -2,18 +2,20 @@ #include #include -using v8::Isolate; +using v8::Array; +using v8::ArrayBuffer; +using v8::ArrayBufferView; +using v8::BackingStore; using v8::Context; +using v8::FunctionCallbackInfo; +using v8::Isolate; using v8::Local; using v8::MaybeLocal; -using v8::Value; using v8::Number; -using v8::String; using v8::Object; -using v8::Array; -using v8::ArrayBufferView; -using v8::ArrayBuffer; -using v8::FunctionCallbackInfo; +using v8::String; +using v8::Uint32; +using v8::Value; void CallWithString(const FunctionCallbackInfo& args) { assert(args.Length() == 1 && args[0]->IsString()); @@ -22,7 +24,7 @@ void CallWithString(const FunctionCallbackInfo& args) { const int32_t length = str->Utf8Length(args.GetIsolate()) + 1; char* buf = new char[length]; str->WriteUtf8(args.GetIsolate(), buf, length); - delete [] buf; + delete[] buf; } } @@ -31,7 +33,7 @@ void CallWithArray(const FunctionCallbackInfo& args) { if (args.Length() == 1 && args[0]->IsArray()) { const Local array = args[0].As(); uint32_t length = array->Length(); - for (uint32_t i = 0; i < length; ++ i) { + for (uint32_t i = 0; i < length; i++) { Local v; v = array->Get(args.GetIsolate()->GetCurrentContext(), i).ToLocalChecked(); @@ -101,12 +103,10 @@ void CallWithTypedarray(const FunctionCallbackInfo& args) { const size_t byte_length = view->ByteLength(); assert(byte_length > 0); assert(view->HasBuffer()); - Local buffer; - buffer = view->Buffer(); - ArrayBuffer::Contents contents; - contents = buffer->GetContents(); + Local buffer = view->Buffer(); + std::shared_ptr bs = buffer->GetBackingStore(); const uint32_t* data = reinterpret_cast( - static_cast(contents.Data()) + byte_offset); + static_cast(bs->Data()) + byte_offset); assert(data); } } @@ -114,16 +114,18 @@ void CallWithTypedarray(const FunctionCallbackInfo& args) { void CallWithArguments(const FunctionCallbackInfo& args) { assert(args.Length() > 1 && args[0]->IsNumber()); if (args.Length() > 1 && args[0]->IsNumber()) { - int32_t loop = args[0].As()->Value(); + int32_t loop = args[0].As()->Value(); for (int32_t i = 1; i < loop; ++i) { assert(i < args.Length()); assert(args[i]->IsUint32()); - args[i].As()->Value(); + args[i].As()->Value(); } } } -void Initialize(Local target) { +void Initialize(Local target, + Local module, + void* data) { NODE_SET_METHOD(target, "callWithString", CallWithString); NODE_SET_METHOD(target, "callWithLongString", CallWithString); diff --git a/benchmark/napi/function_call/binding.cc b/benchmark/napi/function_call/binding.cc index 289a94ac3ecc88b2070a94fcba4b61e6263c55a3..570f96f41ec458c59396be0ddb9152b92db4c97d 100644 --- a/benchmark/napi/function_call/binding.cc +++ b/benchmark/napi/function_call/binding.cc @@ -7,7 +7,9 @@ void Hello(const v8::FunctionCallbackInfo& args) { args.GetReturnValue().Set(c++); } -void Initialize(v8::Local target) { +void Initialize(v8::Local target, + v8::Local module, + void* data) { NODE_SET_METHOD(target, "hello", Hello); } diff --git a/benchmark/perf_hooks/bench-eventlooputil.js b/benchmark/perf_hooks/bench-eventlooputil.js index 984b2b66aecbcf04beaef849eb09f4d61da1f69f..1fd452afa91300212d07998bd95cf9fe446ffdc2 100644 --- a/benchmark/perf_hooks/bench-eventlooputil.js +++ b/benchmark/perf_hooks/bench-eventlooputil.js @@ -33,7 +33,7 @@ function main({ method, n }) { function benchIdleTime(n) { bench.start(); for (let i = 0; i < n; i++) - nodeTiming.idleTime; + nodeTiming.idleTime; // eslint-disable-line no-unused-expressions bench.end(n); } diff --git a/benchmark/process/bench-env.js b/benchmark/process/bench-env.js index 5df521cc9583898b51a895cea2476e732a0f5fa0..e96c1d025072144b509c51b5d64fd00a4d558250 100644 --- a/benchmark/process/bench-env.js +++ b/benchmark/process/bench-env.js @@ -13,7 +13,7 @@ function main({ n, operation }) { case 'get': bench.start(); for (let i = 0; i < n; i++) { - process.env.PATH; + process.env.PATH; // eslint-disable-line no-unused-expressions } bench.end(n); break; @@ -42,7 +42,7 @@ function main({ n, operation }) { case 'query': bench.start(); for (let i = 0; i < n; i++) { - 'PATH' in process.env; + 'PATH' in process.env; // eslint-disable-line no-unused-expressions } bench.end(n); break; diff --git a/benchmark/process/coverage.js b/benchmark/process/coverage.js new file mode 100644 index 0000000000000000000000000000000000000000..3dc0cbe52b4c0d507733ca3dae3fa37079f4ac5a --- /dev/null +++ b/benchmark/process/coverage.js @@ -0,0 +1,32 @@ +// This benchmark is meant to exercise a grab bag of code paths that would +// be expected to run slower under coverage. +'use strict'; + +const common = require('../common.js'); +const bench = common.createBenchmark(main, { + n: [1e5] +}); +const path = require('path'); +const { rmSync } = require('fs'); +const { spawnSync } = require('child_process'); +const tmpdir = require('../../test/common/tmpdir'); + +const coverageDir = path.join(tmpdir.path, `./cov-${Date.now()}`); + +function main({ n }) { + bench.start(); + const result = spawnSync(process.execPath, [ + require.resolve('../fixtures/coverage-many-branches'), + ], { + env: { + NODE_V8_COVERAGE: coverageDir, + N: n, + ...process.env + } + }); + bench.end(n); + rmSync(coverageDir, { recursive: true, force: true }); + if (result.status !== 0) { + throw new Error(result.stderr.toString('utf8')); + } +} diff --git a/benchmark/streams/writable-manywrites.js b/benchmark/streams/writable-manywrites.js index e4ae9ab91e5f4a35c6f83fa1667c7530a9a8c8f5..025a5017ee64462da61c30f949ca74da479b892e 100644 --- a/benchmark/streams/writable-manywrites.js +++ b/benchmark/streams/writable-manywrites.js @@ -7,11 +7,12 @@ const bench = common.createBenchmark(main, { n: [2e6], sync: ['yes', 'no'], writev: ['yes', 'no'], - callback: ['yes', 'no'] + callback: ['yes', 'no'], + len: [1024, 32 * 1024] }); -function main({ n, sync, writev, callback }) { - const b = Buffer.allocUnsafe(1024); +function main({ n, sync, writev, callback, len }) { + const b = Buffer.allocUnsafe(len); const s = new Writable(); sync = sync === 'yes'; diff --git a/benchmark/string_decoder/string-decoder-create.js b/benchmark/string_decoder/string-decoder-create.js index f7fa5e0246b8601dde379e8bdc41ed753390b60f..641e562fdeab3d920df98daca1326c24f73305f3 100644 --- a/benchmark/string_decoder/string-decoder-create.js +++ b/benchmark/string_decoder/string-decoder-create.js @@ -12,8 +12,7 @@ const bench = common.createBenchmark(main, { function main({ encoding, n }) { bench.start(); for (let i = 0; i < n; ++i) { - const sd = new StringDecoder(encoding); - !!sd.encoding; + new StringDecoder(encoding); } bench.end(n); } diff --git a/benchmark/tls/throughput.js b/benchmark/tls/throughput-c2s.js similarity index 100% rename from benchmark/tls/throughput.js rename to benchmark/tls/throughput-c2s.js diff --git a/benchmark/tls/throughput-s2c.js b/benchmark/tls/throughput-s2c.js new file mode 100644 index 0000000000000000000000000000000000000000..a505a719d3088455bf0747586a3f2da1ab8f022a --- /dev/null +++ b/benchmark/tls/throughput-s2c.js @@ -0,0 +1,104 @@ +'use strict'; +const common = require('../common.js'); +const bench = common.createBenchmark(main, { + dur: [5], + type: ['buf', 'asc', 'utf'], + sendchunklen: [256, 32 * 1024, 128 * 1024, 16 * 1024 * 1024], + recvbuflen: [0, 64 * 1024, 1024 * 1024], + recvbufgenfn: ['true', 'false'] +}); + +const fixtures = require('../../test/common/fixtures'); +let options; +let recvbuf; +let received = 0; +const tls = require('tls'); + +function main({ dur, type, sendchunklen, recvbuflen, recvbufgenfn }) { + if (isFinite(recvbuflen) && recvbuflen > 0) + recvbuf = Buffer.alloc(recvbuflen); + + let encoding; + let chunk; + switch (type) { + case 'buf': + chunk = Buffer.alloc(sendchunklen, 'b'); + break; + case 'asc': + chunk = 'a'.repeat(sendchunklen); + encoding = 'ascii'; + break; + case 'utf': + chunk = 'ü'.repeat(sendchunklen / 2); + encoding = 'utf8'; + break; + default: + throw new Error('invalid type'); + } + + options = { + key: fixtures.readKey('rsa_private.pem'), + cert: fixtures.readKey('rsa_cert.crt'), + ca: fixtures.readKey('rsa_ca.crt'), + ciphers: 'AES256-GCM-SHA384' + }; + + let socketOpts; + if (recvbuf === undefined) { + socketOpts = { port: common.PORT, rejectUnauthorized: false }; + } else { + let buffer = recvbuf; + if (recvbufgenfn === 'true') { + let bufidx = -1; + const bufpool = [ + recvbuf, + Buffer.from(recvbuf), + Buffer.from(recvbuf), + ]; + buffer = () => { + bufidx = (bufidx + 1) % bufpool.length; + return bufpool[bufidx]; + }; + } + socketOpts = { + port: common.PORT, + rejectUnauthorized: false, + onread: { + buffer, + callback: function(nread, buf) { + received += nread; + } + } + }; + } + + const server = tls.createServer(options, (socket) => { + socket.on('data', (buf) => { + socket.on('drain', write); + write(); + }); + + function write() { + while (false !== socket.write(chunk, encoding)); + } + }); + + let conn; + server.listen(common.PORT, () => { + conn = tls.connect(socketOpts, () => { + setTimeout(done, dur * 1000); + bench.start(); + conn.write('hello'); + }); + + conn.on('data', (chunk) => { + received += chunk.length; + }); + }); + + function done() { + const mbits = (received * 8) / (1024 * 1024); + bench.end(mbits); + process.exit(0); + } +} diff --git a/benchmark/url/legacy-vs-whatwg-url-searchparams-parse.js b/benchmark/url/legacy-vs-whatwg-url-searchparams-parse.js index f6037d332d069211cc36a2d163cda7242cbf8579..fc21ea7c85d14b0c743746da6490bf07a3c2c892 100644 --- a/benchmark/url/legacy-vs-whatwg-url-searchparams-parse.js +++ b/benchmark/url/legacy-vs-whatwg-url-searchparams-parse.js @@ -1,6 +1,5 @@ 'use strict'; const common = require('../common.js'); -const { URLSearchParams } = require('url'); const querystring = require('querystring'); const searchParams = common.searchParams; diff --git a/benchmark/url/legacy-vs-whatwg-url-searchparams-serialize.js b/benchmark/url/legacy-vs-whatwg-url-searchparams-serialize.js index cb2301e94036daad17d6e581655a3ad027396146..b9c2861719bc0f4338b01f40007c25a7845728b0 100644 --- a/benchmark/url/legacy-vs-whatwg-url-searchparams-serialize.js +++ b/benchmark/url/legacy-vs-whatwg-url-searchparams-serialize.js @@ -1,6 +1,5 @@ 'use strict'; const common = require('../common.js'); -const { URLSearchParams } = require('url'); const querystring = require('querystring'); const searchParams = common.searchParams; diff --git a/benchmark/url/url-searchparams-iteration.js b/benchmark/url/url-searchparams-iteration.js index b628908d62c708412cac8220509c93c9ef842693..ce530c5227fab34d473d474c9e3c27fac72c98f2 100644 --- a/benchmark/url/url-searchparams-iteration.js +++ b/benchmark/url/url-searchparams-iteration.js @@ -1,7 +1,6 @@ 'use strict'; const common = require('../common.js'); const assert = require('assert'); -const { URLSearchParams } = require('url'); const bench = common.createBenchmark(main, { loopMethod: ['forEach', 'iterator'], diff --git a/benchmark/url/url-searchparams-read.js b/benchmark/url/url-searchparams-read.js index cdaaa7ad11a8c3feec205bec156a9dd931a9a10e..e1cb39fbe71cd8cc5a6927f7b055d437f1e866cf 100644 --- a/benchmark/url/url-searchparams-read.js +++ b/benchmark/url/url-searchparams-read.js @@ -1,6 +1,5 @@ 'use strict'; const common = require('../common.js'); -const { URLSearchParams } = require('url'); const bench = common.createBenchmark(main, { accessMethod: ['get', 'getAll', 'has'], diff --git a/benchmark/url/url-searchparams-sort.js b/benchmark/url/url-searchparams-sort.js index 5beb98cf2d2e254fa1802ef364d6fff1aad8abdf..a1873fd612f873da506bdfd0df1f41b997119256 100644 --- a/benchmark/url/url-searchparams-sort.js +++ b/benchmark/url/url-searchparams-sort.js @@ -1,6 +1,5 @@ 'use strict'; const common = require('../common.js'); -const URLSearchParams = require('url').URLSearchParams; const inputs = { wpt: 'wpt', // To work around tests diff --git a/benchmark/worker/atomics-wait.js b/benchmark/worker/atomics-wait.js new file mode 100644 index 0000000000000000000000000000000000000000..a771b1813731edf4f0dd60f3505799e389f1d876 --- /dev/null +++ b/benchmark/worker/atomics-wait.js @@ -0,0 +1,15 @@ +'use strict'; +/* global SharedArrayBuffer */ + +const common = require('../common.js'); +const bench = common.createBenchmark(main, { + n: [1e7] +}); + +function main({ n }) { + const i32arr = new Int32Array(new SharedArrayBuffer(4)); + bench.start(); + for (let i = 0; i < n; i++) + Atomics.wait(i32arr, 0, 1); // Will return immediately. + bench.end(n); +} diff --git a/benchmark/worker/messageport.js b/benchmark/worker/messageport.js index 8e2ddae73ff3abe0d1a905db2e39a1fe2b9d0f86..2f0d6f0621e8c8532d3001646efb748e322c0a3d 100644 --- a/benchmark/worker/messageport.js +++ b/benchmark/worker/messageport.js @@ -4,6 +4,7 @@ const common = require('../common.js'); const { MessageChannel } = require('worker_threads'); const bench = common.createBenchmark(main, { payload: ['string', 'object'], + style: ['eventtarget', 'eventemitter'], n: [1e6] }); @@ -25,14 +26,26 @@ function main(conf) { const { port1, port2 } = new MessageChannel(); let messages = 0; - port2.onmessage = () => { + function listener() { if (messages++ === n) { bench.end(n); port1.close(); } else { write(); } - }; + } + + switch (conf.style) { + case 'eventtarget': + port2.onmessage = listener; + break; + case 'eventemitter': + port2.on('message', listener); + break; + default: + throw new Error('Unsupported listener type'); + } + bench.start(); write(); diff --git a/common.gypi b/common.gypi index 102f09077455072fb5f73fa990808a0d21729463..f3a4aad62abef659e6b5aecbb01c382c75339349 100644 --- a/common.gypi +++ b/common.gypi @@ -26,21 +26,20 @@ 'uv_library%': 'static_library', 'clang%': 0, + 'error_on_warn%': 'false', 'openssl_fips%': '', + 'openssl_no_asm%': 0, # Don't use ICU data file (icudtl.dat) from V8, we use our own. 'icu_use_data_file_flag%': 0, # 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.45', + 'v8_embedder_string': '-node.85', ##### V8 defaults for Node.js ##### - # Old time default, now explicitly stated. - 'v8_use_snapshot': 1, - # Turn on SipHash for hash seed generation, addresses HashWick 'v8_use_siphash': 'true', @@ -61,6 +60,12 @@ # https://github.com/nodejs/node/pull/22920/files#r222779926 'v8_enable_handle_zapping': 0, + # Disable pointer compression. Can be enabled at build time via configure + # options but default values are required here as this file is also used by + # node-gyp to build addons. + 'v8_enable_pointer_compression%': 0, + 'v8_enable_31bit_smis_on_64bit_arch%': 0, + # Disable V8 untrusted code mitigations. # See https://github.com/v8/v8/wiki/Untrusted-code-mitigations 'v8_untrusted_code_mitigations': 0, @@ -77,55 +82,21 @@ ##### end V8 defaults ##### 'conditions': [ - ['target_arch=="arm64"', { - # Disabled pending https://github.com/nodejs/node/issues/23913. - 'openssl_no_asm%': 1, - }, { - 'openssl_no_asm%': 0, - }], ['OS == "win"', { 'os_posix': 0, 'v8_postmortem_support%': 0, + 'obj_dir': '<(PRODUCT_DIR)/obj', + 'v8_base': '<(PRODUCT_DIR)/lib/libv8_snapshot.a', }, { 'os_posix': 1, 'v8_postmortem_support%': 1, }], - ['v8_use_snapshot==1', { - 'conditions': [ - ['GENERATOR == "ninja"', { - 'obj_dir': '<(PRODUCT_DIR)/obj', - 'v8_base': '<(PRODUCT_DIR)/obj/tools/v8_gypfiles/libv8_snapshot.a', - }, { - 'obj_dir%': '<(PRODUCT_DIR)/obj.target', - 'v8_base': '<(PRODUCT_DIR)/obj.target/tools/v8_gypfiles/libv8_snapshot.a', - }], - ['OS == "win"', { - 'obj_dir': '<(PRODUCT_DIR)/obj', - 'v8_base': '<(PRODUCT_DIR)/lib/libv8_snapshot.a', - }], - ['OS == "mac"', { - 'obj_dir%': '<(PRODUCT_DIR)/obj.target', - 'v8_base': '<(PRODUCT_DIR)/libv8_snapshot.a', - }], - ], + ['GENERATOR == "ninja"', { + 'obj_dir': '<(PRODUCT_DIR)/obj', + 'v8_base': '<(PRODUCT_DIR)/obj/tools/v8_gypfiles/libv8_snapshot.a', }, { - 'conditions': [ - ['GENERATOR == "ninja"', { - 'obj_dir': '<(PRODUCT_DIR)/obj', - 'v8_base': '<(PRODUCT_DIR)/obj/tools/v8_gypfiles/libv8_nosnapshot.a', - }, { - 'obj_dir%': '<(PRODUCT_DIR)/obj.target', - 'v8_base': '<(PRODUCT_DIR)/obj.target/tools/v8_gypfiles/libv8_nosnapshot.a', - }], - ['OS == "win"', { - 'obj_dir': '<(PRODUCT_DIR)/obj', - 'v8_base': '<(PRODUCT_DIR)/lib/libv8_nosnapshot.a', - }], - ['OS == "mac"', { - 'obj_dir%': '<(PRODUCT_DIR)/obj.target', - 'v8_base': '<(PRODUCT_DIR)/libv8_nosnapshot.a', - }], - ], + 'obj_dir%': '<(PRODUCT_DIR)/obj.target', + 'v8_base': '<(PRODUCT_DIR)/obj.target/tools/v8_gypfiles/libv8_snapshot.a', }], ['openssl_fips != ""', { 'openssl_product': '<(STATIC_LIB_PREFIX)crypto<(STATIC_LIB_SUFFIX)', @@ -134,10 +105,15 @@ }], ['OS=="mac"', { 'clang%': 1, + 'obj_dir%': '<(PRODUCT_DIR)/obj.target', + 'v8_base': '<(PRODUCT_DIR)/libv8_snapshot.a', }], ['target_arch in "ppc64 s390x"', { 'v8_enable_backtrace': 1, }], + ['OS=="linux"', { + 'node_section_ordering_info%': '' + }] ], }, @@ -188,17 +164,42 @@ 'v8_enable_handle_zapping': 0, 'pgo_generate': ' -fprofile-generate ', 'pgo_use': ' -fprofile-use -fprofile-correction ', - 'lto': ' -flto=4 -fuse-linker-plugin -ffat-lto-objects ', 'conditions': [ ['node_shared != "true"', { 'MSVC_runtimeType': 0 # MultiThreaded (/MT) }, { 'MSVC_runtimeType': 2 # MultiThreadedDLL (/MD) }], + ['llvm_version=="0.0"', { + 'lto': ' -flto=4 -fuse-linker-plugin -ffat-lto-objects ', # GCC + }, { + 'lto': ' -flto ', # Clang + }], ], }, 'cflags': [ '-O3' ], 'conditions': [ + ['enable_lto=="true"', { + 'cflags': ['<(lto)'], + 'ldflags': ['<(lto)'], + 'xcode_settings': { + 'LLVM_LTO': 'YES', + }, + }], + ['OS=="linux"', { + 'conditions': [ + ['node_section_ordering_info!=""', { + 'cflags': [ + '-fuse-ld=gold', + '-ffunction-sections', + ], + 'ldflags': [ + '-fuse-ld=gold', + '-Wl,--section-ordering-file=<(node_section_ordering_info)', + ], + }], + ], + }], ['OS=="solaris"', { # pull in V8's postmortem metadata 'ldflags': [ '-Wl,-z,allextract' ] @@ -216,10 +217,6 @@ 'cflags': ['<(pgo_use)'], 'ldflags': ['<(pgo_use)'], },], - ['enable_lto=="true"', { - 'cflags': ['<(lto)'], - 'ldflags': ['<(lto)'], - },], ], },], ['OS == "android"', { @@ -229,6 +226,11 @@ ], 'msvs_settings': { 'VCCLCompilerTool': { + 'conditions': [ + ['target_arch=="arm64"', { + 'FloatingPointModel': 1 # /fp:strict + }] + ], 'EnableFunctionLevelLinking': 'true', 'EnableIntrinsicFunctions': 'true', 'FavorSizeOrSpeed': 1, # /Ot, favor speed over size @@ -255,7 +257,14 @@ # Forcibly disable -Werror. We support a wide range of compilers, it's # simply not feasible to squelch all warnings, never mind that the # libraries in deps/ are not under our control. - 'cflags!': ['-Werror'], + 'conditions': [ + [ 'error_on_warn=="false"', { + 'cflags!': ['-Werror'], + }, '(_target_name!="<(node_lib_target_name)" or ' + '_target_name!="<(node_core_target_name)")', { + 'cflags!': ['-Werror'], + }], + ], 'msvs_settings': { 'VCCLCompilerTool': { 'BufferSecurityCheck': 'true', @@ -345,6 +354,12 @@ }], ], }], + ['v8_enable_pointer_compression == 1', { + 'defines': ['V8_COMPRESS_POINTERS'], + }], + ['v8_enable_pointer_compression == 1 or v8_enable_31bit_smis_on_64bit_arch == 1', { + 'defines': ['V8_31BIT_SMIS_ON_64BIT_ARCH'], + }], ['OS == "win"', { 'defines': [ 'WIN32', @@ -471,7 +486,7 @@ 'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti 'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings 'PREBINDING': 'NO', # No -Wl,-prebind - 'MACOSX_DEPLOYMENT_TARGET': '10.10', # -mmacosx-version-min=10.10 + 'MACOSX_DEPLOYMENT_TARGET': '10.13', # -mmacosx-version-min=10.13 'USE_HEADERMAP': 'NO', 'OTHER_CFLAGS': [ '-fno-strict-aliasing', diff --git a/configure b/configure index 9156e13f7aed0dad68fc3f89a94f12a33d4525c8..debd3cc3d452d0f1c66ad8502c5e493d29228cfa 100644 --- a/configure +++ b/configure @@ -1,28 +1,39 @@ #!/bin/sh -# Locate python2 interpreter and re-execute the script. Note that the -# mix of single and double quotes is intentional, as is the fact that -# the ] goes on a new line. +# Locate an acceptable python interpreter and then re-execute the script. +# Note that the mix of single and double quotes is intentional, +# as is the fact that the ] goes on a new line. _=[ 'exec' '/bin/sh' '-c' ''' -which python2.7 >/dev/null && exec python2.7 "$0" "$@" -which python2 >/dev/null && exec python2 "$0" "$@" +test ${FORCE_PYTHON2} && exec python2 "$0" "$@" # workaround for gclient +command -v python3.10 >/dev/null && exec python3.10 "$0" "$@" +command -v python3.9 >/dev/null && exec python3.9 "$0" "$@" +command -v python3.8 >/dev/null && exec python3.8 "$0" "$@" +command -v python3.7 >/dev/null && exec python3.7 "$0" "$@" +command -v python3.6 >/dev/null && exec python3.6 "$0" "$@" +command -v python3.5 >/dev/null && exec python3.5 "$0" "$@" +command -v python3 >/dev/null && exec python3 "$0" "$@" +command -v python2.7 >/dev/null && exec python2.7 "$0" "$@" exec python "$0" "$@" ''' "$0" "$@" ] del _ import sys -from distutils.spawn import find_executable as which -if sys.version_info[:2] != (2, 7): - sys.stderr.write('Please use Python 2.7') +try: + from shutil import which +except ImportError: + from distutils.spawn import find_executable as which - python2 = which('python2') or which('python2.7') - - if python2: - sys.stderr.write(':\n\n') - sys.stderr.write(' ' + python2 + ' ' + ' '.join(sys.argv)) - - sys.stderr.write('\n') +print('Node.js configure: Found Python {0}.{1}.{2}...'.format(*sys.version_info)) +acceptable_pythons = ((3,10), (3, 9), (3, 8), (3, 7), (3, 6), (3, 5), (2, 7)) +if sys.version_info[:2] in acceptable_pythons: + import configure +else: + python_cmds = ['python{0}.{1}'.format(*vers) for vers in acceptable_pythons] + sys.stderr.write('Please use {0}.\n'.format(' or '.join(python_cmds))) + for python_cmd in python_cmds: + python_cmd_path = which(python_cmd) + if python_cmd_path and 'pyenv/shims' not in python_cmd_path: + sys.stderr.write('\t{0} {1}\n'.format(python_cmd_path, + ' '.join(sys.argv[:1]))) sys.exit(1) - -import configure diff --git a/configure.py b/configure.py index e6485a7b38372a14a480fd7d0fa365044a87e256..30cf6726ae891604da65e990409c22209d632b22 100644 --- a/configure.py +++ b/configure.py @@ -11,9 +11,15 @@ import re import shlex import subprocess import shutil +import bz2 import io -from distutils.spawn import find_executable as which +# Fallback to find_executable from distutils.spawn is a stopgap for +# supporting V8 builds, which do not yet support Python 3. +try: + from shutil import which +except ImportError: + from distutils.spawn import find_executable as which from distutils.version import StrictVersion # If not run from node/, cd to node/. @@ -38,6 +44,7 @@ sys.path.insert(0, 'tools') import getmoduleversion import getnapibuildversion from gyp_node import run_gyp +from utils import SearchFiles # imports in deps/v8/tools/node sys.path.insert(0, os.path.join('deps', 'v8', 'tools', 'node')) @@ -116,6 +123,11 @@ parser.add_option('--dest-os', choices=valid_os, help='operating system to build for ({0})'.format(', '.join(valid_os))) +parser.add_option('--error-on-warn', + action='store_true', + dest='error_on_warn', + help='Turn compiler warnings into errors for node core sources.') + parser.add_option('--gdb', action='store_true', dest='gdb', @@ -154,7 +166,7 @@ parser.add_option("--enable-lto", action="store_true", dest="enable_lto", help="Enable compiling with lto of a binary. This feature is only available " - "on linux with gcc and g++ 5.4.1 or newer.") + "with gcc 5.4.1+ or clang 3.9.1+.") parser.add_option("--link-module", action="append", @@ -376,6 +388,11 @@ parser.add_option('--enable-trace-maps', dest='trace_maps', help='Enable the --trace-maps flag in V8 (use at your own risk)') +parser.add_option('--experimental-enable-pointer-compression', + action='store_true', + dest='enable_pointer_compression', + help='[Experimental] Enable V8 pointer compression (limits max heap to 4GB and breaks ABI compatibility)') + parser.add_option('--v8-options', action='store', dest='v8_options', @@ -444,10 +461,18 @@ parser.add_option('--use-largepages-script-lld', dest='node_use_large_pages_script_lld', help='This option has no effect. --use-largepages is now a runtime option.') +parser.add_option('--use-section-ordering-file', + action='store', + dest='node_section_ordering_info', + default='', + help='Pass a section ordering file to the linker. This requires that ' + + 'Node.js be linked using the gold linker. The gold linker must have ' + + 'version 1.2 or greater.') + intl_optgroup.add_option('--with-intl', action='store', dest='with_intl', - default='small-icu', + default='full-icu', choices=valid_intl_modes, help='Intl mode (valid choices: {0}) [default: %default]'.format( ', '.join(valid_intl_modes))) @@ -555,7 +580,7 @@ parser.add_option('--with-snapshot', parser.add_option('--without-snapshot', action='store_true', - dest='without_snapshot', + dest='unused_without_snapshot', help=optparse.SUPPRESS_HELP) parser.add_option('--without-siphash', @@ -838,10 +863,11 @@ def get_gas_version(cc): # Note: Apple clang self-reports as clang 4.2.0 and gcc 4.2.1. It passes # the version check more by accident than anything else but a more rigorous -# check involves checking the build number against a whitelist. I'm not +# check involves checking the build number against an allowlist. I'm not # quite prepared to go that far yet. def check_compiler(o): if sys.platform == 'win32': + o['variables']['llvm_version'] = '0.0' if not options.openssl_no_asm and options.dest_cpu in ('x86', 'x64'): nasm_version = get_nasm_version('nasm') o['variables']['nasm_version'] = nasm_version @@ -938,12 +964,7 @@ def is_arm_hard_float_abi(): def host_arch_cc(): """Host architecture check using the CC command.""" - if sys.platform.startswith('aix'): - # we only support gcc at this point and the default on AIX - # would be xlc so hard code gcc - k = cc_macros('gcc') - else: - k = cc_macros(os.environ.get('CC_host')) + k = cc_macros(os.environ.get('CC_host')) matchup = { '__aarch64__' : 'arm64', @@ -1021,15 +1042,24 @@ def configure_mips(o, target_arch): host_byteorder = 'little' if target_arch in ('mipsel', 'mips64el') else 'big' o['variables']['v8_host_byteorder'] = host_byteorder +def clang_version_ge(version_checked): + for compiler in [(CC, 'c'), (CXX, 'c++')]: + ok, is_clang, clang_version, gcc_version = \ + try_check_compiler(compiler[0], compiler[1]) + if is_clang and clang_version >= version_checked: + return True + return False def gcc_version_ge(version_checked): for compiler in [(CC, 'c'), (CXX, 'c++')]: - ok, is_clang, clang_version, compiler_version = \ + ok, is_clang, clang_version, gcc_version = \ try_check_compiler(compiler[0], compiler[1]) - if is_clang or compiler_version < version_checked: + if is_clang or gcc_version < version_checked: return False return True +def configure_node_lib_files(o): + o['variables']['node_library_files'] = SearchFiles('lib', 'js') def configure_node(o): if options.dest_os == 'android': @@ -1038,6 +1068,7 @@ def configure_node(o): o['variables']['node_install_npm'] = b(not options.without_npm) o['variables']['debug_node'] = b(options.debug_node) o['default_configuration'] = 'Debug' if options.debug else 'Release' + o['variables']['error_on_warn'] = b(options.error_on_warn) host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc() target_arch = options.dest_cpu or host_arch @@ -1055,15 +1086,18 @@ def configure_node(o): cross_compiling = (options.cross_compiling if options.cross_compiling is not None else target_arch != host_arch) - want_snapshots = not options.without_snapshot - o['variables']['want_separate_host_toolset'] = int( - cross_compiling and want_snapshots) + if cross_compiling: + os.environ['GYP_CROSSCOMPILE'] = "1" + if options.unused_without_snapshot: + warn('building --without-snapshot is no longer possible') + + o['variables']['want_separate_host_toolset'] = int(cross_compiling) if options.without_node_snapshot or options.node_builtin_modules_path: o['variables']['node_use_node_snapshot'] = 'false' else: o['variables']['node_use_node_snapshot'] = b( - not cross_compiling and want_snapshots and not options.shared) + not cross_compiling and not options.shared) if options.without_node_code_cache or options.node_builtin_modules_path: o['variables']['node_use_node_code_cache'] = 'false' @@ -1103,18 +1137,19 @@ def configure_node(o): o['variables']['enable_pgo_generate'] = b(options.enable_pgo_generate) o['variables']['enable_pgo_use'] = b(options.enable_pgo_use) - if flavor != 'linux' and (options.enable_lto): + if flavor == 'win' and (options.enable_lto): raise Exception( - 'The lto option is supported only on linux.') - - if flavor == 'linux': - if options.enable_lto: - version_checked = (5, 4, 1) - if not gcc_version_ge(version_checked): - version_checked_str = ".".join(map(str, version_checked)) - raise Exception( - 'The option --enable-lto is supported for gcc and gxx %s' - ' or newer only.' % (version_checked_str)) + 'Use Link Time Code Generation instead.') + + if options.enable_lto: + gcc_version_checked = (5, 4, 1) + clang_version_checked = (3, 9, 1) + if not gcc_version_ge(gcc_version_checked) and not clang_version_ge(clang_version_checked): + gcc_version_checked_str = ".".join(map(str, gcc_version_checked)) + clang_version_checked_str = ".".join(map(str, clang_version_checked)) + raise Exception( + 'The option --enable-lto is supported for gcc %s+' + 'or clang %s+ only.' % (gcc_version_checked_str, clang_version_checked_str)) o['variables']['enable_lto'] = b(options.enable_lto) @@ -1225,8 +1260,7 @@ def configure_library(lib, output, pkgname=None): output['variables']['node_' + shared_lib] = b(getattr(options, shared_lib)) if getattr(options, shared_lib): - (pkg_libs, pkg_cflags, pkg_libpath, pkg_modversion) = ( - pkg_config(pkgname or lib)) + (pkg_libs, pkg_cflags, pkg_libpath, _) = pkg_config(pkgname or lib) if options.__dict__[shared_lib + '_includes']: output['include_dirs'] += [options.__dict__[shared_lib + '_includes']] @@ -1266,7 +1300,8 @@ def configure_v8(o): o['variables']['v8_random_seed'] = 0 # Use a random seed for hash tables. o['variables']['v8_promise_internal_field_count'] = 1 # Add internal field to promises for async hooks. o['variables']['v8_use_siphash'] = 0 if options.without_siphash else 1 - o['variables']['v8_use_snapshot'] = 0 if options.without_snapshot else 1 + o['variables']['v8_enable_pointer_compression'] = 1 if options.enable_pointer_compression else 0 + o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0 o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0 o['variables']['node_use_v8_platform'] = b(not options.without_v8_platform) o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8) @@ -1430,8 +1465,6 @@ def configure_intl(o): 'variables': {} } icu_config_name = 'icu_config.gypi' - def write_config(data, name): - return # write an empty file to start with write(icu_config_name, do_not_edit + @@ -1497,7 +1530,8 @@ def configure_intl(o): icu_parent_path = 'deps' # The full path to the ICU source directory. Should not include './'. - icu_full_path = 'deps/icu' + icu_deps_path = 'deps/icu' + icu_full_path = icu_deps_path # icu-tmp is used to download and unpack the ICU tarball. icu_tmp_path = os.path.join(icu_parent_path, 'icu-tmp') @@ -1505,30 +1539,26 @@ def configure_intl(o): # canned ICU. see tools/icu/README.md to update. canned_icu_dir = 'deps/icu-small' + # use the README to verify what the canned ICU is + canned_is_full = os.path.isfile(os.path.join(canned_icu_dir, 'README-FULL-ICU.txt')) + canned_is_small = os.path.isfile(os.path.join(canned_icu_dir, 'README-SMALL-ICU.txt')) + if canned_is_small: + warn('Ignoring %s - in-repo small icu is no longer supported.' % canned_icu_dir) + # We can use 'deps/icu-small' - pre-canned ICU *iff* - # - with_intl == small-icu (the default!) - # - with_icu_locales == 'root,en' (the default!) - # - deps/icu-small exists! + # - canned_is_full AND # - with_icu_source is unset (i.e. no other ICU was specified) - # (Note that this is the *DEFAULT CASE*.) # # This is *roughly* equivalent to - # $ configure --with-intl=small-icu --with-icu-source=deps/icu-small + # $ configure --with-intl=full-icu --with-icu-source=deps/icu-small # .. Except that we avoid copying icu-small over to deps/icu. # In this default case, deps/icu is ignored, although make clean will # still harmlessly remove deps/icu. - # are we using default locales? - using_default_locales = ( options.with_icu_locales == icu_default_locales ) - - # make sure the canned ICU really exists - canned_icu_available = os.path.isdir(canned_icu_dir) - - if (o['variables']['icu_small'] == b(True)) and using_default_locales and (not with_icu_source) and canned_icu_available: + if (not with_icu_source) and canned_is_full: # OK- we can use the canned ICU. - icu_config['variables']['icu_small_canned'] = 1 icu_full_path = canned_icu_dir - + icu_config['variables']['icu_full_canned'] = 1 # --with-icu-source processing # now, check that they didn't pass --with-icu-source=deps/icu elif with_icu_source and os.path.abspath(icu_full_path) == os.path.abspath(with_icu_source): @@ -1607,29 +1637,43 @@ def configure_intl(o): icu_endianness = sys.byteorder[0] o['variables']['icu_ver_major'] = icu_ver_major o['variables']['icu_endianness'] = icu_endianness - icu_data_file_l = 'icudt%s%s.dat' % (icu_ver_major, 'l') + icu_data_file_l = 'icudt%s%s.dat' % (icu_ver_major, 'l') # LE filename icu_data_file = 'icudt%s%s.dat' % (icu_ver_major, icu_endianness) # relative to configure icu_data_path = os.path.join(icu_full_path, 'source/data/in', - icu_data_file_l) + icu_data_file_l) # LE + compressed_data = '%s.bz2' % (icu_data_path) + if not os.path.isfile(icu_data_path) and os.path.isfile(compressed_data): + # unpack. deps/icu is a temporary path + if os.path.isdir(icu_tmp_path): + shutil.rmtree(icu_tmp_path) + os.mkdir(icu_tmp_path) + icu_data_path = os.path.join(icu_tmp_path, icu_data_file_l) + with open(icu_data_path, 'wb') as outf: + inf = bz2.BZ2File(compressed_data, 'rb') + try: + shutil.copyfileobj(inf, outf) + finally: + inf.close() + # Now, proceed.. + # relative to dep.. - icu_data_in = os.path.join('..','..', icu_full_path, 'source/data/in', icu_data_file_l) + icu_data_in = os.path.join('..','..', icu_data_path) if not os.path.isfile(icu_data_path) and icu_endianness != 'l': # use host endianness icu_data_path = os.path.join(icu_full_path, 'source/data/in', - icu_data_file) - # relative to dep.. - icu_data_in = os.path.join('..', icu_full_path, 'source/data/in', - icu_data_file) - # this is the input '.dat' file to use .. icudt*.dat - # may be little-endian if from a icu-project.org tarball - o['variables']['icu_data_in'] = icu_data_in + icu_data_file) # will be generated if not os.path.isfile(icu_data_path): # .. and we're not about to build it from .gyp! error('''ICU prebuilt data file %s does not exist. See the README.md.''' % icu_data_path) + + # this is the input '.dat' file to use .. icudt*.dat + # may be little-endian if from a icu-project.org tarball + o['variables']['icu_data_in'] = icu_data_in + # map from variable name to subdirs icu_src = { 'stubdata': 'stubdata', @@ -1646,6 +1690,31 @@ def configure_intl(o): var = 'icu_src_%s' % i path = '../../%s/source/%s' % (icu_full_path, icu_src[i]) icu_config['variables'][var] = glob_to_var('tools/icu', path, 'patches/%s/source/%s' % (icu_ver_major, icu_src[i]) ) + # calculate platform-specific genccode args + # print("platform %s, flavor %s" % (sys.platform, flavor)) + # if sys.platform == 'darwin': + # shlib_suffix = '%s.dylib' + # elif sys.platform.startswith('aix'): + # shlib_suffix = '%s.a' + # else: + # shlib_suffix = 'so.%s' + if flavor == 'win': + icu_config['variables']['icu_asm_ext'] = 'obj' + icu_config['variables']['icu_asm_opts'] = [ '-o ' ] + elif with_intl == 'small-icu' or options.cross_compiling: + icu_config['variables']['icu_asm_ext'] = 'c' + icu_config['variables']['icu_asm_opts'] = [] + elif flavor == 'mac': + icu_config['variables']['icu_asm_ext'] = 'S' + icu_config['variables']['icu_asm_opts'] = [ '-a', 'gcc-darwin' ] + elif sys.platform.startswith('aix'): + icu_config['variables']['icu_asm_ext'] = 'S' + icu_config['variables']['icu_asm_opts'] = [ '-a', 'xlc' ] + else: + # assume GCC-compatible asm is OK + icu_config['variables']['icu_asm_ext'] = 'S' + icu_config['variables']['icu_asm_opts'] = [ '-a', 'gcc' ] + # write updated icu_config.gypi with a bunch of paths write(icu_config_name, do_not_edit + pprint.pformat(icu_config, indent=2) + '\n') @@ -1657,6 +1726,30 @@ def configure_inspector(o): options.without_ssl) o['variables']['v8_enable_inspector'] = 0 if disable_inspector else 1 +def configure_section_file(o): + try: + proc = subprocess.Popen(['ld.gold'] + ['-v'], stdin = subprocess.PIPE, + stdout = subprocess.PIPE, stderr = subprocess.PIPE) + except OSError: + if options.node_section_ordering_info != "": + warn('''No acceptable ld.gold linker found!''') + return 0 + + match = re.match(r"^GNU gold.*([0-9]+)\.([0-9]+)$", + proc.communicate()[0].decode("utf-8")) + + if match: + gold_major_version = match.group(1) + gold_minor_version = match.group(2) + if int(gold_major_version) == 1 and int(gold_minor_version) <= 1: + error('''GNU gold version must be greater than 1.2 in order to use section + reordering''') + + if options.node_section_ordering_info != "": + o['variables']['node_section_ordering_info'] = os.path.realpath( + str(options.node_section_ordering_info)) + else: + o['variables']['node_section_ordering_info'] = "" def make_bin_override(): if sys.platform == 'win32': @@ -1710,6 +1803,7 @@ if (options.dest_os): flavor = GetFlavor(flavor_params) configure_node(output) +configure_node_lib_files(output) configure_napi(output) configure_library('zlib', output) configure_library('http_parser', output) @@ -1722,6 +1816,7 @@ configure_openssl(output) configure_intl(output) configure_static(output) configure_inspector(output) +configure_section_file(output) # Forward OSS-Fuzz settings output['variables']['ossfuzz'] = b(options.ossfuzz) @@ -1810,6 +1905,10 @@ else: if options.compile_commands_json: gyp_args += ['-f', 'compile_commands_json'] +# override the variable `python` defined in common.gypi +if bin_override is not None: + gyp_args += ['-Dpython=' + sys.executable] + # pass the leftover positional arguments to GYP gyp_args += args diff --git a/deps/acorn-plugins/acorn-class-fields/CHANGELOG.md b/deps/acorn-plugins/acorn-class-fields/CHANGELOG.md deleted file mode 100644 index de2c66b0c3bc65c00f88f57d8cc4a1d0ca4af32f..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-class-fields/CHANGELOG.md +++ /dev/null @@ -1,28 +0,0 @@ -## 0.3.1 (2019-02-09) - -* Restore compatibility with acorn-private-methods - -## 0.3.0 (2019-02-09) - -* Require acorn >= 6.1.0 - -## 0.2.1 (2018-11-06) - -* Adapt to changes in acorn 6.0.3 - -## 0.2.0 (2018-09-14) - -* Update to new acorn 6 interface -* Change license to MIT - -## 0.1.2 (2018-01-26) - -* Don't accept whitespace between hash and private name - -## 0.1.1 (2018-01-17) - -* Correctly parse all fields named `async` - -## 0.1.0 (2018-01-13) - -Initial release diff --git a/deps/acorn-plugins/acorn-class-fields/LICENSE b/deps/acorn-plugins/acorn-class-fields/LICENSE deleted file mode 100644 index 7c2b27a19c033cbdfa39082bf03715fa874a646e..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-class-fields/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2017-2018 by Adrian Heine - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS 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. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/deps/acorn-plugins/acorn-class-fields/README.md b/deps/acorn-plugins/acorn-class-fields/README.md deleted file mode 100644 index 60f3463e94d315c260bff7f99366574f6e71c2a7..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-class-fields/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Class fields support for Acorn - -[![NPM version](https://img.shields.io/npm/v/acorn-class-fields.svg)](https://www.npmjs.org/package/acorn-class-fields) - -This is a plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript. - -It implements support for class fields as defined in the stage 3 proposal [Class field declarations for JavaScript](https://github.com/tc39/proposal-class-fields). The emitted AST follows [an ESTree proposal](https://github.com/estree/estree/pull/180). - -## Usage - -This module provides a plugin that can be used to extend the Acorn `Parser` class: - -```javascript -const {Parser} = require('acorn'); -const classFields = require('acorn-class-fields'); -Parser.extend(classFields).parse('class X { x = 0 }'); -``` - -## License - -This plugin is released under an [MIT License](./LICENSE). diff --git a/deps/acorn-plugins/acorn-class-fields/index.js b/deps/acorn-plugins/acorn-class-fields/index.js deleted file mode 100644 index 20348c80c6bcbf24db63081cfcbd50e130ae3470..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-class-fields/index.js +++ /dev/null @@ -1,59 +0,0 @@ -"use strict" - -const acorn = require('internal/deps/acorn/acorn/dist/acorn') -const tt = acorn.tokTypes -const privateClassElements = require('internal/deps/acorn-plugins/acorn-private-class-elements/index') - -function maybeParseFieldValue(field) { - if (this.eat(tt.eq)) { - const oldInFieldValue = this._inFieldValue - this._inFieldValue = true - field.value = this.parseExpression() - this._inFieldValue = oldInFieldValue - } else field.value = null -} - -module.exports = function(Parser) { - Parser = privateClassElements(Parser) - return class extends Parser { - // Parse fields - parseClassElement(_constructorAllowsSuper) { - if (this.options.ecmaVersion >= 8 && (this.type == tt.name || this.type == this.privateNameToken || this.type == tt.bracketL || this.type == tt.string)) { - const branch = this._branch() - if (branch.type == tt.bracketL) { - let count = 0 - do { - if (branch.eat(tt.bracketL)) ++count - else if (branch.eat(tt.bracketR)) --count - else branch.next() - } while (count > 0) - } else branch.next() - if (branch.type == tt.eq || branch.canInsertSemicolon() || branch.type == tt.semi) { - const node = this.startNode() - if (this.type == this.privateNameToken) { - this.parsePrivateClassElementName(node) - } else { - this.parsePropertyName(node) - } - if ((node.key.type === "Identifier" && node.key.name === "constructor") || - (node.key.type === "Literal" && node.key.value === "constructor")) { - this.raise(node.key.start, "Classes may not have a field called constructor") - } - maybeParseFieldValue.call(this, node) - this.finishNode(node, "FieldDefinition") - this.semicolon() - return node - } - } - - return super.parseClassElement.apply(this, arguments) - } - - // Prohibit arguments in class field initializers - parseIdent(liberal, isBinding) { - const ident = super.parseIdent(liberal, isBinding) - if (this._inFieldValue && ident.name == "arguments") this.raise(ident.start, "A class field initializer may not contain arguments") - return ident - } - } -} diff --git a/deps/acorn-plugins/acorn-class-fields/package.json b/deps/acorn-plugins/acorn-class-fields/package.json deleted file mode 100644 index 550511399f248da8bb9076133f3dbeade104251b..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-class-fields/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "acorn-class-fields", - "description": "Support for class fields in acorn", - "homepage": "https://github.com/acornjs/acorn-class-fields", - "contributors": [ - "Adrian Heine " - ], - "engines": { - "node": ">=4.8.2" - }, - "repository": { - "type": "git", - "url": "https://github.com/acornjs/acorn-class-fields" - }, - "license": "MIT", - "scripts": { - "test": "mocha", - "test:test262": "node run_test262.js", - "lint": "eslint -c .eslintrc.json ." - }, - "peerDependencies": { - "acorn": "^6.0.0" - }, - "version": "0.3.1", - "devDependencies": { - "acorn": "^6.1.0", - "eslint": "^5.13.0", - "eslint-plugin-node": "^8.0.1", - "mocha": "^5.2.0", - "test262": "git+https://github.com/tc39/test262.git#33a306d1026b72227eb50a918db19ada16f12b3d", - "test262-parser-runner": "^0.5.0" - }, - "dependencies": { - "acorn-private-class-elements": "^0.1.1" - } -} \ No newline at end of file diff --git a/deps/acorn-plugins/acorn-numeric-separator/CHANGELOG.md b/deps/acorn-plugins/acorn-numeric-separator/CHANGELOG.md deleted file mode 100644 index dfe8e3ea9dedb8b68d67f21e3c2a45b0b055e576..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-numeric-separator/CHANGELOG.md +++ /dev/null @@ -1,16 +0,0 @@ -## 0.3.0 (2019-04-04) - -* Make compatible with acorn-bigint - -## 0.2.0 (2018-09-14) - -* Update to new acorn 6 interface -* Change license to MIT - -## 0.1.1 (2018-01-16) - -* Don't bail on empty integers as in `1.` - -## 0.1.0 (2017-12-19) - -Initial release diff --git a/deps/acorn-plugins/acorn-numeric-separator/LICENSE b/deps/acorn-plugins/acorn-numeric-separator/LICENSE deleted file mode 100644 index 7c2b27a19c033cbdfa39082bf03715fa874a646e..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-numeric-separator/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2017-2018 by Adrian Heine - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS 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. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/deps/acorn-plugins/acorn-numeric-separator/README.md b/deps/acorn-plugins/acorn-numeric-separator/README.md deleted file mode 100644 index 27188572d1bf4048b2053a6aaf770a8b3459e854..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-numeric-separator/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Numeric separator support for Acorn - -[![NPM version](https://img.shields.io/npm/v/acorn-numeric-separator.svg)](https://www.npmjs.org/package/acorn-numeric-separator) - -This is a plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript. - -It implements support for numeric separators as defined in the stage 3 proposal [Numeric Separators](https://github.com/tc39/proposal-numeric-separator). - -## Usage - -This module provides a plugin that can be used to extend the Acorn `Parser` class to parse numeric separators: - -```javascript -var acorn = require('acorn'); -var numericSeparator = require('acorn-numeric-separator'); -acorn.Parser.extend(numericSeparator).parse('100_000'); -``` - -## License - -This plugin is released under an [MIT License](./LICENSE). diff --git a/deps/acorn-plugins/acorn-numeric-separator/index.js b/deps/acorn-plugins/acorn-numeric-separator/index.js deleted file mode 100644 index 52f207cfd8d454d30e6e43f3da2b51ed14644004..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-numeric-separator/index.js +++ /dev/null @@ -1,49 +0,0 @@ -"use strict" - -module.exports = function(Parser) { - return class extends Parser { - readInt(radix, len) { - // Hack: len is only != null for unicode escape sequences, - // where numeric separators are not allowed - if (len != null) return super.readInt(radix, len) - - let start = this.pos, total = 0, acceptUnderscore = false - for (;;) { - let code = this.input.charCodeAt(this.pos), val - if (code >= 97) val = code - 97 + 10 // a - else if (code == 95) { - if (!acceptUnderscore) this.raise(this.pos, "Invalid numeric separator") - ++this.pos - acceptUnderscore = false - continue - } else if (code >= 65) val = code - 65 + 10 // A - else if (code >= 48 && code <= 57) val = code - 48 // 0-9 - else val = Infinity - if (val >= radix) break - ++this.pos - total = total * radix + val - acceptUnderscore = true - } - if (this.pos === start) return null - if (!acceptUnderscore) this.raise(this.pos - 1, "Invalid numeric separator") - - return total - } - - readNumber(startsWithDot) { - const token = super.readNumber(startsWithDot) - let octal = this.end - this.start >= 2 && this.input.charCodeAt(this.start) === 48 - const stripped = this.getNumberInput(this.start, this.end) - if (stripped.length < this.end - this.start) { - if (octal) this.raise(this.start, "Invalid number") - this.value = parseFloat(stripped) - } - return token - } - - // This is used by acorn-bigint - getNumberInput(start, end) { - return this.input.slice(start, end).replace(/_/g, "") - } - } -} diff --git a/deps/acorn-plugins/acorn-numeric-separator/package.json b/deps/acorn-plugins/acorn-numeric-separator/package.json deleted file mode 100644 index cc0c52a65d2dfe3be80c39b880d84807a39466a2..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-numeric-separator/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "acorn-numeric-separator", - "description": "Support for numeric separators in acorn", - "homepage": "https://github.com/acornjs/acorn-numeric-separator", - "contributors": [ - "Adrian Heine " - ], - "engines": { - "node": ">=4.8.2" - }, - "repository": { - "type": "git", - "url": "https://github.com/acornjs/acorn-numeric-separator" - }, - "license": "MIT", - "scripts": { - "test": "mocha", - "test:test262": "node run_test262.js", - "lint": "eslint -c .eslintrc.json ." - }, - "peerDependencies": { - "acorn": "^6.0.0" - }, - "version": "0.3.0", - "devDependencies": { - "acorn": "^6.0.0", - "eslint": "^5.5.0", - "eslint-plugin-node": "^8.0.1", - "mocha": "^6.0.2", - "test262": "git+https://github.com/tc39/test262.git#de567d3aa5de4eaa11e00131d26b9fe77997dfb0", - "test262-parser-runner": "^0.5.0" - } -} \ No newline at end of file diff --git a/deps/acorn-plugins/acorn-private-class-elements/CHANGELOG.md b/deps/acorn-plugins/acorn-private-class-elements/CHANGELOG.md deleted file mode 100644 index 6d4854429aacfa8129c39bafe98199e935f5e8e9..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-private-class-elements/CHANGELOG.md +++ /dev/null @@ -1,11 +0,0 @@ -## 0.2.0 (2020-03-07) - -* Mark as compatible with acorn v7 - -## 0.1.1 (2019-02-09) - -* Add \_branch() method - -## 0.1.0 (2019-02-09) - -Initial release diff --git a/deps/acorn-plugins/acorn-private-class-elements/LICENSE b/deps/acorn-plugins/acorn-private-class-elements/LICENSE deleted file mode 100644 index 7c2b27a19c033cbdfa39082bf03715fa874a646e..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-private-class-elements/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2017-2018 by Adrian Heine - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS 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. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/deps/acorn-plugins/acorn-private-class-elements/README.md b/deps/acorn-plugins/acorn-private-class-elements/README.md deleted file mode 100644 index 0d228820cd1d0146dff282c6b405dd3a7797574c..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-private-class-elements/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Helpers for supporting private class methods and fields for Acorn - -[![NPM version](https://img.shields.io/npm/v/acorn-private-class-elements.svg)](https://www.npmjs.org/package/acorn-private-class-elements) - -This is a plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript. - -It provides helpers for implementing support for private class elements. The emitted AST follows [an ESTree proposal](https://github.com/estree/estree/pull/180). - -## License - -This plugin is released under an [MIT License](./LICENSE). diff --git a/deps/acorn-plugins/acorn-private-class-elements/index.js b/deps/acorn-plugins/acorn-private-class-elements/index.js deleted file mode 100644 index 1f40bda9baa2eb30e335f0a1d38f2cc2b4f89099..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-private-class-elements/index.js +++ /dev/null @@ -1,123 +0,0 @@ -"use strict" - -const acorn = require('internal/deps/acorn/acorn/dist/acorn') -if (acorn.version.indexOf("6.") != 0 && acorn.version.indexOf("6.0.") == 0 && acorn.version.indexOf("7.") != 0) { - throw new Error(`acorn-private-class-elements requires acorn@^6.1.0 or acorn@7.0.0, not ${acorn.version}`) -} -const tt = acorn.tokTypes -const TokenType = acorn.TokenType - -module.exports = function(Parser) { - // Only load this plugin once. - if (Parser.prototype.parsePrivateName) { - return Parser - } - - // Make sure `Parser` comes from the same acorn as our `tt`, - // otherwise the comparisons fail. - let cur = Parser - while (cur && cur !== acorn.Parser) { - cur = cur.__proto__ - } - if (cur !== acorn.Parser) { - throw new Error("acorn-private-class-elements does not support mixing different acorn copies") - } - - Parser = class extends Parser { - _branch() { - this.__branch = this.__branch || new Parser({ecmaVersion: this.options.ecmaVersion}, this.input) - this.__branch.end = this.end - this.__branch.pos = this.pos - this.__branch.type = this.type - this.__branch.value = this.value - this.__branch.containsEsc = this.containsEsc - return this.__branch - } - - parsePrivateClassElementName(element) { - element.computed = false - element.key = this.parsePrivateName() - if (element.key.name == "constructor") this.raise(element.key.start, "Classes may not have a private element named constructor") - const accept = {get: "set", set: "get"}[element.kind] - const privateBoundNames = this._privateBoundNamesStack[this._privateBoundNamesStack.length - 1] - if (Object.prototype.hasOwnProperty.call(privateBoundNames, element.key.name) && privateBoundNames[element.key.name] !== accept) { - this.raise(element.start, "Duplicate private element") - } - privateBoundNames[element.key.name] = element.kind || true - delete this._unresolvedPrivateNamesStack[this._unresolvedPrivateNamesStack.length - 1][element.key.name] - return element.key - } - - parsePrivateName() { - const node = this.startNode() - node.name = this.value - this.next() - this.finishNode(node, "PrivateName") - if (this.options.allowReserved == "never") this.checkUnreserved(node) - return node - } - - // Parse # token - getTokenFromCode(code) { - if (code === 35) { - ++this.pos - const word = this.readWord1() - return this.finishToken(this.privateNameToken, word) - } - return super.getTokenFromCode(code) - } - - // Manage stacks and check for undeclared private names - parseClass(node, isStatement) { - this._privateBoundNamesStack = this._privateBoundNamesStack || [] - const privateBoundNames = Object.create(this._privateBoundNamesStack[this._privateBoundNamesStack.length - 1] || null) - this._privateBoundNamesStack.push(privateBoundNames) - this._unresolvedPrivateNamesStack = this._unresolvedPrivateNamesStack || [] - const unresolvedPrivateNames = Object.create(null) - this._unresolvedPrivateNamesStack.push(unresolvedPrivateNames) - const _return = super.parseClass(node, isStatement) - this._privateBoundNamesStack.pop() - this._unresolvedPrivateNamesStack.pop() - if (!this._unresolvedPrivateNamesStack.length) { - const names = Object.keys(unresolvedPrivateNames) - if (names.length) { - names.sort((n1, n2) => unresolvedPrivateNames[n1] - unresolvedPrivateNames[n2]) - this.raise(unresolvedPrivateNames[names[0]], "Usage of undeclared private name") - } - } else Object.assign(this._unresolvedPrivateNamesStack[this._unresolvedPrivateNamesStack.length - 1], unresolvedPrivateNames) - return _return - } - - // Parse private element access - parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow) { - if (!this.eat(tt.dot)) { - return super.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow) - } - let node = this.startNodeAt(startPos, startLoc) - node.object = base - node.computed = false - if (this.type == this.privateNameToken) { - node.property = this.parsePrivateName() - if (!this._privateBoundNamesStack.length || !this._privateBoundNamesStack[this._privateBoundNamesStack.length - 1][node.property.name]) { - this._unresolvedPrivateNamesStack[this._unresolvedPrivateNamesStack.length - 1][node.property.name] = node.property.start - } - } else { - node.property = this.parseIdent(true) - } - return this.finishNode(node, "MemberExpression") - } - - // Prohibit delete of private class elements - parseMaybeUnary(refDestructuringErrors, sawUnary) { - const _return = super.parseMaybeUnary(refDestructuringErrors, sawUnary) - if (_return.operator == "delete") { - if (_return.argument.type == "MemberExpression" && _return.argument.property.type == "PrivateName") { - this.raise(_return.start, "Private elements may not be deleted") - } - } - return _return - } - } - Parser.prototype.privateNameToken = new TokenType("privateName") - return Parser -} diff --git a/deps/acorn-plugins/acorn-private-class-elements/package.json b/deps/acorn-plugins/acorn-private-class-elements/package.json deleted file mode 100644 index b8b652a1e9e2f3c72b11bac54ebe4522f87370b0..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-private-class-elements/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "acorn-private-class-elements", - "description": "Helpers for supporting private class methods and fields in acorn", - "homepage": "https://github.com/acornjs/acorn-private-class-elements", - "contributors": [ - "Adrian Heine " - ], - "engines": { - "node": ">=4.8.2" - }, - "repository": { - "type": "git", - "url": "https://github.com/acornjs/acorn-private-class-elements" - }, - "license": "MIT", - "scripts": { - "test": "mocha", - "lint": "eslint -c .eslintrc.json ." - }, - "peerDependencies": { - "acorn": "^6.1.0 || ^7.0.0" - }, - "version": "0.2.0", - "devDependencies": { - "acorn": "^7.0.0", - "eslint": "^6.8.0", - "eslint-plugin-node": "^11.0.0", - "mocha": "^7.1.0" - } -} \ No newline at end of file diff --git a/deps/acorn-plugins/acorn-private-methods/CHANGELOG.md b/deps/acorn-plugins/acorn-private-methods/CHANGELOG.md deleted file mode 100644 index 5de4b97b8111b03187e5c7c87a74b705ec1461d5..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-private-methods/CHANGELOG.md +++ /dev/null @@ -1,29 +0,0 @@ -## 0.3.0 (2019-02-09) - -* Require acorn >= 6.1.0 - -## 0.2.3 (2019-02-09) - -* Forbid binding await in async arrow function's parameter list - -## 0.2.2 (2019-01-30) - -* Fix parsing of chained subscripts - -## 0.2.1 (2018-11-06) - -* Adapt to changes in acorn 6.0.3 - -## 0.2.0 (2018-09-14) - -* Update to new acorn 6 interface -* Change license to MIT -* Don't allow direct super() calls in private methods - -## 0.1.1 (2018-02-09) - -* Don't accept whitespace between hash and private name - -## 0.1.0 (2018-01-13) - -Initial release diff --git a/deps/acorn-plugins/acorn-private-methods/LICENSE b/deps/acorn-plugins/acorn-private-methods/LICENSE deleted file mode 100644 index 7c2b27a19c033cbdfa39082bf03715fa874a646e..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-private-methods/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2017-2018 by Adrian Heine - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS 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. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/deps/acorn-plugins/acorn-private-methods/README.md b/deps/acorn-plugins/acorn-private-methods/README.md deleted file mode 100644 index 6929e84ba620a80d010e7f93e9cf58a83d9d1c46..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-private-methods/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Private methods and getter/setters support for Acorn - -[![NPM version](https://img.shields.io/npm/v/acorn-private-methods.svg)](https://www.npmjs.org/package/acorn-private-methods) - -This is a plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript. - -It implements support for private methods, getters and setters as defined in the stage 3 proposal [Private methods and getter/setters for JavaScript classes](https://github.com/tc39/proposal-private-methods). The emitted AST follows [an ESTree proposal](https://github.com/estree/estree/pull/180). - -## Usage - -This module provides a plugin that can be used to extend the Acorn `Parser` class: - -```javascript -const {Parser} = require('acorn'); -const privateMethods = require('acorn-private-methods'); -Parser.extend(privateMethods).parse('class X { #a() {} }'); -``` - -## License - -This plugin is released under an [MIT License](./LICENSE). diff --git a/deps/acorn-plugins/acorn-private-methods/index.js b/deps/acorn-plugins/acorn-private-methods/index.js deleted file mode 100644 index a2964251680565b09a332c415c18e6ba22baebd5..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-private-methods/index.js +++ /dev/null @@ -1,25 +0,0 @@ -"use strict" - -const privateClassElements = require('internal/deps/acorn-plugins/acorn-private-class-elements/index') - -module.exports = function(Parser) { - const ExtendedParser = privateClassElements(Parser) - - return class extends ExtendedParser { - // Parse private methods - parseClassElement(_constructorAllowsSuper) { - const oldInClassMemberName = this._inClassMemberName - this._inClassMemberName = true - const result = super.parseClassElement.apply(this, arguments) - this._inClassMemberName = oldInClassMemberName - return result - } - - parsePropertyName(prop) { - const isPrivate = this.options.ecmaVersion >= 8 && this._inClassMemberName && this.type == this.privateNameToken - this._inClassMemberName = false - if (!isPrivate) return super.parsePropertyName(prop) - return this.parsePrivateClassElementName(prop) - } - } -} diff --git a/deps/acorn-plugins/acorn-private-methods/package.json b/deps/acorn-plugins/acorn-private-methods/package.json deleted file mode 100644 index e7b91592aaa9b90ff7a612ec8e64e4024c7a6086..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-private-methods/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "acorn-private-methods", - "description": "Support for private methods in acorn", - "homepage": "https://github.com/acornjs/acorn-private-methods", - "contributors": [ - "Adrian Heine " - ], - "engines": { - "node": ">=4.8.2" - }, - "repository": { - "type": "git", - "url": "https://github.com/acornjs/acorn-private-methods" - }, - "license": "MIT", - "scripts": { - "test": "mocha", - "test:test262": "node run_test262.js", - "lint": "eslint -c .eslintrc.json ." - }, - "peerDependencies": { - "acorn": "^6.1.0" - }, - "dependencies": { - "acorn-private-class-elements": "^0.1.0" - }, - "version": "0.3.0", - "devDependencies": { - "acorn": "^6.1.0", - "eslint": "^5.13.0", - "eslint-plugin-node": "^8.0.1", - "mocha": "^5.2.0", - "test262": "git+https://github.com/tc39/test262.git#33a306d1026b72227eb50a918db19ada16f12b3d", - "test262-parser-runner": "^0.5.0" - } -} \ No newline at end of file diff --git a/deps/acorn-plugins/acorn-static-class-features/CHANGELOG.md b/deps/acorn-plugins/acorn-static-class-features/CHANGELOG.md deleted file mode 100644 index b9896a4bc5a45e647d37744e7c3ebf18cb1f8662..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-static-class-features/CHANGELOG.md +++ /dev/null @@ -1,11 +0,0 @@ -## 0.2.0 (2019-02-09) - -* Require acorn >= 6.1.0 - -## 0.1.1 (2018-11-06) - -* Adapt to changes in acorn 6.0.3 - -## 0.1.0 (2018-09-14) - -Initial release diff --git a/deps/acorn-plugins/acorn-static-class-features/LICENSE b/deps/acorn-plugins/acorn-static-class-features/LICENSE deleted file mode 100644 index 7c2b27a19c033cbdfa39082bf03715fa874a646e..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-static-class-features/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2017-2018 by Adrian Heine - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS 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. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/deps/acorn-plugins/acorn-static-class-features/README.md b/deps/acorn-plugins/acorn-static-class-features/README.md deleted file mode 100644 index bb214fce164a1a0c3d9eb8d38998b82a5b6ec81d..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-static-class-features/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Static class features support for Acorn - -[![NPM version](https://img.shields.io/npm/v/acorn-class-fields.svg)](https://www.npmjs.org/package/acorn-static-class-features) - -This is a plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript. - -It implements support for static class features as defined in the stage 3 proposal [Static class features](https://github.com/tc39/proposal-static-class-features). The emitted AST follows [an ESTree proposal](https://github.com/estree/estree/pull/180). - -## Usage - -This module provides a plugin that can be used to extend the Acorn `Parser` class: - -```javascript -const {Parser} = require('acorn'); -const staticClassFeatures = require('acorn-static-class-features'); -Parser.extend(staticClassFeatures).parse('class X { static x = 0 }'); -``` - -## License - -This plugin is released under an [MIT License](./LICENSE). diff --git a/deps/acorn-plugins/acorn-static-class-features/index.js b/deps/acorn-plugins/acorn-static-class-features/index.js deleted file mode 100644 index d8954bf3275e0e4ffc03bd483f5a00138c17c2c0..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-static-class-features/index.js +++ /dev/null @@ -1,126 +0,0 @@ -"use strict" - -const skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g - -const acorn = require('internal/deps/acorn/acorn/dist/acorn') -const tt = acorn.tokTypes - -function maybeParseFieldValue(field) { - if (this.eat(tt.eq)) { - const oldInFieldValue = this._inStaticFieldValue - this._inStaticFieldValue = true - field.value = this.parseExpression() - this._inStaticFieldValue = oldInFieldValue - } else field.value = null -} - -const privateClassElements = require("internal/deps/acorn-plugins/acorn-private-class-elements/index") - -module.exports = function(Parser) { - const ExtendedParser = privateClassElements(Parser) - - return class extends ExtendedParser { - // Parse private fields - parseClassElement(_constructorAllowsSuper) { - if (this.eat(tt.semi)) return null - - const node = this.startNode() - - const tryContextual = (k, noLineBreak) => { - if (typeof noLineBreak == "undefined") noLineBreak = false - const start = this.start, startLoc = this.startLoc - if (!this.eatContextual(k)) return false - if (this.type !== tt.parenL && (!noLineBreak || !this.canInsertSemicolon())) return true - if (node.key) this.unexpected() - node.computed = false - node.key = this.startNodeAt(start, startLoc) - node.key.name = k - this.finishNode(node.key, "Identifier") - return false - } - - node.static = tryContextual("static") - if (!node.static) return super.parseClassElement.apply(this, arguments) - - let isGenerator = this.eat(tt.star) - let isAsync = false - if (!isGenerator) { - // Special-case for `async`, since `parseClassMember` currently looks - // for `(` to determine whether `async` is a method name - if (this.options.ecmaVersion >= 8 && this.isContextual("async")) { - skipWhiteSpace.lastIndex = this.pos - let skip = skipWhiteSpace.exec(this.input) - let next = this.input.charAt(this.pos + skip[0].length) - if (next === ";" || next === "=") { - node.key = this.parseIdent(true) - node.computed = false - maybeParseFieldValue.call(this, node) - this.finishNode(node, "FieldDefinition") - this.semicolon() - return node - } else if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { - isAsync = true - isGenerator = this.options.ecmaVersion >= 9 && this.eat(tt.star) - } - } else if (tryContextual("get")) { - node.kind = "get" - } else if (tryContextual("set")) { - node.kind = "set" - } - } - if (this.type === this.privateNameToken) { - this.parsePrivateClassElementName(node) - if (this.type !== tt.parenL) { - if (node.key.name === "prototype") { - this.raise(node.key.start, "Classes may not have a private static property named prototype") - } - maybeParseFieldValue.call(this, node) - this.finishNode(node, "FieldDefinition") - this.semicolon() - return node - } - } else if (!node.key) { - this.parsePropertyName(node) - if ((node.key.name || node.key.value) === "prototype" && !node.computed) { - this.raise(node.key.start, "Classes may not have a static property named prototype") - } - } - if (!node.kind) node.kind = "method" - this.parseClassMethod(node, isGenerator, isAsync) - if (!node.kind && (node.key.name || node.key.value) === "constructor" && !node.computed) { - this.raise(node.key.start, "Classes may not have a static field named constructor") - } - if (node.kind === "get" && node.value.params.length !== 0) { - this.raiseRecoverable(node.value.start, "getter should have no params") - } - if (node.kind === "set" && node.value.params.length !== 1) { - this.raiseRecoverable(node.value.start, "setter should have exactly one param") - } - if (node.kind === "set" && node.value.params[0].type === "RestElement") { - this.raiseRecoverable(node.value.params[0].start, "Setter cannot use rest params") - } - - return node - - } - - // Parse public static fields - parseClassMethod(method, isGenerator, isAsync, _allowsDirectSuper) { - if (isGenerator || isAsync || method.kind != "method" || !method.static || this.options.ecmaVersion < 8 || this.type == tt.parenL) { - return super.parseClassMethod.apply(this, arguments) - } - maybeParseFieldValue.call(this, method) - delete method.kind - method = this.finishNode(method, "FieldDefinition") - this.semicolon() - return method - } - - // Prohibit arguments in class field initializers - parseIdent(liberal, isBinding) { - const ident = super.parseIdent(liberal, isBinding) - if (this._inStaticFieldValue && ident.name == "arguments") this.raise(ident.start, "A static class field initializer may not contain arguments") - return ident - } - } -} diff --git a/deps/acorn-plugins/acorn-static-class-features/package.json b/deps/acorn-plugins/acorn-static-class-features/package.json deleted file mode 100644 index 066223d9965df563649f6b55ec3e0623d1d45e82..0000000000000000000000000000000000000000 --- a/deps/acorn-plugins/acorn-static-class-features/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "acorn-static-class-features", - "description": "Support for static class features in acorn", - "homepage": "https://github.com/acornjs/acorn-static-class-features", - "contributors": [ - "Adrian Heine " - ], - "engines": { - "node": ">=4.8.2" - }, - "repository": { - "type": "git", - "url": "https://github.com/acornjs/acorn-static-class-features" - }, - "license": "MIT", - "scripts": { - "test": "mocha", - "test:test262": "node run_test262.js", - "lint": "eslint -c .eslintrc.json ." - }, - "peerDependencies": { - "acorn": "^6.1.0" - }, - "version": "0.2.0", - "devDependencies": { - "acorn": "^6.1.0", - "eslint": "^5.13.0", - "eslint-plugin-node": "^8.0.1", - "mocha": "^5.2.0", - "test262": "git+https://github.com/tc39/test262.git#33a306d1026b72227eb50a918db19ada16f12b3d", - "test262-parser-runner": "^0.5.0" - }, - "dependencies": { - "acorn-private-class-elements": "^0.1.1" - } -} \ No newline at end of file diff --git a/deps/acorn/acorn-walk/CHANGELOG.md b/deps/acorn/acorn-walk/CHANGELOG.md index 89114970bbeae47f7ec3c6e7e0380ad9afb2b1b5..a9382d0db9abefa141b9fbc534ea3d817a6df797 100644 --- a/deps/acorn/acorn-walk/CHANGELOG.md +++ b/deps/acorn/acorn-walk/CHANGELOG.md @@ -1,3 +1,37 @@ +## 8.1.0 (2021-04-24) + +### New features + +Support node types for class fields and private methods. + +## 8.0.2 (2021-01-25) + +### Bug fixes + +Adjust package.json to work with Node 12.16.0 and 13.0-13.6. + +## 8.0.0 (2021-01-05) + +### Bug fixes + +Fix a bug where `full` and `fullAncestor` would skip nodes with overridden types. + +## 8.0.0 (2020-08-12) + +### New features + +The package can now be loaded directly as an ECMAScript module in node 13+. + +## 7.2.0 (2020-06-17) + +### New features + +Support optional chaining and nullish coalescing. + +Support `import.meta`. + +Add support for `export * as ns from "source"`. + ## 7.1.1 (2020-02-13) ### Bug fixes diff --git a/deps/acorn/acorn-walk/LICENSE b/deps/acorn/acorn-walk/LICENSE index 2c0632b6a7c63bd701c60f1daa8b8fa9bea56a81..d6be6db2cfff576dd96f97180707581bfb6b726c 100644 --- a/deps/acorn/acorn-walk/LICENSE +++ b/deps/acorn/acorn-walk/LICENSE @@ -1,4 +1,6 @@ -Copyright (C) 2012-2018 by various contributors (see AUTHORS) +MIT License + +Copyright (C) 2012-2020 by various contributors (see AUTHORS) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/deps/acorn/acorn-walk/dist/walk.d.ts b/deps/acorn/acorn-walk/dist/walk.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..00cc005f1245c5d445a518a50838445652e550a1 --- /dev/null +++ b/deps/acorn/acorn-walk/dist/walk.d.ts @@ -0,0 +1,112 @@ +import {Node} from 'acorn'; + +declare module "acorn-walk" { + type FullWalkerCallback = ( + node: Node, + state: TState, + type: string + ) => void; + + type FullAncestorWalkerCallback = ( + node: Node, + state: TState | Node[], + ancestors: Node[], + type: string + ) => void; + type WalkerCallback = (node: Node, state: TState) => void; + + type SimpleWalkerFn = ( + node: Node, + state: TState + ) => void; + + type AncestorWalkerFn = ( + node: Node, + state: TState| Node[], + ancestors: Node[] + ) => void; + + type RecursiveWalkerFn = ( + node: Node, + state: TState, + callback: WalkerCallback + ) => void; + + type SimpleVisitors = { + [type: string]: SimpleWalkerFn + }; + + type AncestorVisitors = { + [type: string]: AncestorWalkerFn + }; + + type RecursiveVisitors = { + [type: string]: RecursiveWalkerFn + }; + + type FindPredicate = (type: string, node: Node) => boolean; + + interface Found { + node: Node, + state: TState + } + + export function simple( + node: Node, + visitors: SimpleVisitors, + base?: RecursiveVisitors, + state?: TState + ): void; + + export function ancestor( + node: Node, + visitors: AncestorVisitors, + base?: RecursiveVisitors, + state?: TState + ): void; + + export function recursive( + node: Node, + state: TState, + functions: RecursiveVisitors, + base?: RecursiveVisitors + ): void; + + export function full( + node: Node, + callback: FullWalkerCallback, + base?: RecursiveVisitors, + state?: TState + ): void; + + export function fullAncestor( + node: Node, + callback: FullAncestorWalkerCallback, + base?: RecursiveVisitors, + state?: TState + ): void; + + export function make( + functions: RecursiveVisitors, + base?: RecursiveVisitors + ): RecursiveVisitors; + + export function findNodeAt( + node: Node, + start: number | undefined, + end?: number | undefined, + type?: FindPredicate | string, + base?: RecursiveVisitors, + state?: TState + ): Found | undefined; + + export function findNodeAround( + node: Node, + start: number | undefined, + type?: FindPredicate | string, + base?: RecursiveVisitors, + state?: TState + ): Found | undefined; + + export const findNodeAfter: typeof findNodeAround; +} diff --git a/deps/acorn/acorn-walk/dist/walk.js b/deps/acorn/acorn-walk/dist/walk.js index 7aaab9ce824f60dd7ac8edc1021b6ace6fd597be..5582c907595e11039c58a1d956592eb6138beba1 100644 --- a/deps/acorn/acorn-walk/dist/walk.js +++ b/deps/acorn/acorn-walk/dist/walk.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory((global.acorn = global.acorn || {}, global.acorn.walk = {}))); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; // AST walker module for Mozilla Parser API compatible trees @@ -72,11 +72,15 @@ // A full walk triggers the callback on each node function full(node, callback, baseVisitor, state, override) { - if (!baseVisitor) { baseVisitor = base - ; }(function c(node, st, override) { + if (!baseVisitor) { baseVisitor = base; } + var last + ;(function c(node, st, override) { var type = override || node.type; baseVisitor[type](node, st, c); - if (!override) { callback(node, st, type); } + if (last !== node) { + callback(node, st, type); + last = node; + } })(node, state, override); } @@ -84,13 +88,16 @@ // the callback on each node function fullAncestor(node, callback, baseVisitor, state) { if (!baseVisitor) { baseVisitor = base; } - var ancestors = [] + var ancestors = [], last ;(function c(node, st, override) { var type = override || node.type; var isNew = node !== ancestors[ancestors.length - 1]; if (isNew) { ancestors.push(node); } baseVisitor[type](node, st, c); - if (!override) { callback(node, st || ancestors, ancestors, type); } + if (last !== node) { + callback(node, st || ancestors, ancestors, type); + last = node; + } if (isNew) { ancestors.pop(); } })(node, state); } @@ -168,17 +175,10 @@ return max } - // Fallback to an Object.create polyfill for older environments. - var create = Object.create || function(proto) { - function Ctor() {} - Ctor.prototype = proto; - return new Ctor - }; - // Used to create a custom walker. Will fill in all missing node // type properties with the defaults. function make(funcs, baseVisitor) { - var visitor = create(baseVisitor || base); + var visitor = Object.create(baseVisitor || base); for (var type in funcs) { visitor[type] = funcs[type]; } return visitor } @@ -200,7 +200,7 @@ }; base.Statement = skipThrough; base.EmptyStatement = ignore; - base.ExpressionStatement = base.ParenthesizedExpression = + base.ExpressionStatement = base.ParenthesizedExpression = base.ChainExpression = function (node, st, c) { return c(node.expression, st, "Expression"); }; base.IfStatement = function (node, st, c) { c(node.test, st, "Expression"); @@ -405,6 +405,8 @@ if (node.source) { c(node.source, st, "Expression"); } }; base.ExportAllDeclaration = function (node, st, c) { + if (node.exported) + { c(node.exported, st); } c(node.source, st, "Expression"); }; base.ImportDeclaration = function (node, st, c) { @@ -419,7 +421,7 @@ base.ImportExpression = function (node, st, c) { c(node.source, st, "Expression"); }; - base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore; + base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore; base.TaggedTemplateExpression = function (node, st, c) { c(node.tag, st, "Expression"); @@ -439,9 +441,9 @@ c(elt, st); } }; - base.MethodDefinition = base.Property = function (node, st, c) { + base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) { if (node.computed) { c(node.key, st, "Expression"); } - c(node.value, st, "Expression"); + if (node.value) { c(node.value, st, "Expression"); } }; exports.ancestor = ancestor; @@ -458,4 +460,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/deps/acorn/acorn-walk/dist/walk.mjs b/deps/acorn/acorn-walk/dist/walk.mjs new file mode 100644 index 0000000000000000000000000000000000000000..ea5d4b0bc2041ff30c6857af088ec247ebdcd58d --- /dev/null +++ b/deps/acorn/acorn-walk/dist/walk.mjs @@ -0,0 +1,443 @@ +// AST walker module for Mozilla Parser API compatible trees + +// A simple walk is one where you simply specify callbacks to be +// called on specific nodes. The last two arguments are optional. A +// simple use would be +// +// walk.simple(myTree, { +// Expression: function(node) { ... } +// }); +// +// to do something with all expressions. All Parser API node types +// can be used to identify node types, as well as Expression and +// Statement, which denote categories of nodes. +// +// The base argument can be used to pass a custom (recursive) +// walker, and state can be used to give this walked an initial +// state. + +function simple(node, visitors, baseVisitor, state, override) { + if (!baseVisitor) { baseVisitor = base + ; }(function c(node, st, override) { + var type = override || node.type, found = visitors[type]; + baseVisitor[type](node, st, c); + if (found) { found(node, st); } + })(node, state, override); +} + +// An ancestor walk keeps an array of ancestor nodes (including the +// current node) and passes them to the callback as third parameter +// (and also as state parameter when no other state is present). +function ancestor(node, visitors, baseVisitor, state, override) { + var ancestors = []; + if (!baseVisitor) { baseVisitor = base + ; }(function c(node, st, override) { + var type = override || node.type, found = visitors[type]; + var isNew = node !== ancestors[ancestors.length - 1]; + if (isNew) { ancestors.push(node); } + baseVisitor[type](node, st, c); + if (found) { found(node, st || ancestors, ancestors); } + if (isNew) { ancestors.pop(); } + })(node, state, override); +} + +// A recursive walk is one where your functions override the default +// walkers. They can modify and replace the state parameter that's +// threaded through the walk, and can opt how and whether to walk +// their child nodes (by calling their third argument on these +// nodes). +function recursive(node, state, funcs, baseVisitor, override) { + var visitor = funcs ? make(funcs, baseVisitor || undefined) : baseVisitor + ;(function c(node, st, override) { + visitor[override || node.type](node, st, c); + })(node, state, override); +} + +function makeTest(test) { + if (typeof test === "string") + { return function (type) { return type === test; } } + else if (!test) + { return function () { return true; } } + else + { return test } +} + +var Found = function Found(node, state) { this.node = node; this.state = state; }; + +// A full walk triggers the callback on each node +function full(node, callback, baseVisitor, state, override) { + if (!baseVisitor) { baseVisitor = base; } + var last + ;(function c(node, st, override) { + var type = override || node.type; + baseVisitor[type](node, st, c); + if (last !== node) { + callback(node, st, type); + last = node; + } + })(node, state, override); +} + +// An fullAncestor walk is like an ancestor walk, but triggers +// the callback on each node +function fullAncestor(node, callback, baseVisitor, state) { + if (!baseVisitor) { baseVisitor = base; } + var ancestors = [], last + ;(function c(node, st, override) { + var type = override || node.type; + var isNew = node !== ancestors[ancestors.length - 1]; + if (isNew) { ancestors.push(node); } + baseVisitor[type](node, st, c); + if (last !== node) { + callback(node, st || ancestors, ancestors, type); + last = node; + } + if (isNew) { ancestors.pop(); } + })(node, state); +} + +// Find a node with a given start, end, and type (all are optional, +// null can be used as wildcard). Returns a {node, state} object, or +// undefined when it doesn't find a matching node. +function findNodeAt(node, start, end, test, baseVisitor, state) { + if (!baseVisitor) { baseVisitor = base; } + test = makeTest(test); + try { + (function c(node, st, override) { + var type = override || node.type; + if ((start == null || node.start <= start) && + (end == null || node.end >= end)) + { baseVisitor[type](node, st, c); } + if ((start == null || node.start === start) && + (end == null || node.end === end) && + test(type, node)) + { throw new Found(node, st) } + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } +} + +// Find the innermost node of a given type that contains the given +// position. Interface similar to findNodeAt. +function findNodeAround(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + try { + (function c(node, st, override) { + var type = override || node.type; + if (node.start > pos || node.end < pos) { return } + baseVisitor[type](node, st, c); + if (test(type, node)) { throw new Found(node, st) } + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } +} + +// Find the outermost matching node after a given position. +function findNodeAfter(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + try { + (function c(node, st, override) { + if (node.end < pos) { return } + var type = override || node.type; + if (node.start >= pos && test(type, node)) { throw new Found(node, st) } + baseVisitor[type](node, st, c); + })(node, state); + } catch (e) { + if (e instanceof Found) { return e } + throw e + } +} + +// Find the outermost matching node before a given position. +function findNodeBefore(node, pos, test, baseVisitor, state) { + test = makeTest(test); + if (!baseVisitor) { baseVisitor = base; } + var max + ;(function c(node, st, override) { + if (node.start > pos) { return } + var type = override || node.type; + if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node)) + { max = new Found(node, st); } + baseVisitor[type](node, st, c); + })(node, state); + return max +} + +// Used to create a custom walker. Will fill in all missing node +// type properties with the defaults. +function make(funcs, baseVisitor) { + var visitor = Object.create(baseVisitor || base); + for (var type in funcs) { visitor[type] = funcs[type]; } + return visitor +} + +function skipThrough(node, st, c) { c(node, st); } +function ignore(_node, _st, _c) {} + +// Node walkers. + +var base = {}; + +base.Program = base.BlockStatement = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var stmt = list[i]; + + c(stmt, st, "Statement"); + } +}; +base.Statement = skipThrough; +base.EmptyStatement = ignore; +base.ExpressionStatement = base.ParenthesizedExpression = base.ChainExpression = + function (node, st, c) { return c(node.expression, st, "Expression"); }; +base.IfStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Statement"); + if (node.alternate) { c(node.alternate, st, "Statement"); } +}; +base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); }; +base.BreakStatement = base.ContinueStatement = ignore; +base.WithStatement = function (node, st, c) { + c(node.object, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.SwitchStatement = function (node, st, c) { + c(node.discriminant, st, "Expression"); + for (var i$1 = 0, list$1 = node.cases; i$1 < list$1.length; i$1 += 1) { + var cs = list$1[i$1]; + + if (cs.test) { c(cs.test, st, "Expression"); } + for (var i = 0, list = cs.consequent; i < list.length; i += 1) + { + var cons = list[i]; + + c(cons, st, "Statement"); + } + } +}; +base.SwitchCase = function (node, st, c) { + if (node.test) { c(node.test, st, "Expression"); } + for (var i = 0, list = node.consequent; i < list.length; i += 1) + { + var cons = list[i]; + + c(cons, st, "Statement"); + } +}; +base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) { + if (node.argument) { c(node.argument, st, "Expression"); } +}; +base.ThrowStatement = base.SpreadElement = + function (node, st, c) { return c(node.argument, st, "Expression"); }; +base.TryStatement = function (node, st, c) { + c(node.block, st, "Statement"); + if (node.handler) { c(node.handler, st); } + if (node.finalizer) { c(node.finalizer, st, "Statement"); } +}; +base.CatchClause = function (node, st, c) { + if (node.param) { c(node.param, st, "Pattern"); } + c(node.body, st, "Statement"); +}; +base.WhileStatement = base.DoWhileStatement = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.ForStatement = function (node, st, c) { + if (node.init) { c(node.init, st, "ForInit"); } + if (node.test) { c(node.test, st, "Expression"); } + if (node.update) { c(node.update, st, "Expression"); } + c(node.body, st, "Statement"); +}; +base.ForInStatement = base.ForOfStatement = function (node, st, c) { + c(node.left, st, "ForInit"); + c(node.right, st, "Expression"); + c(node.body, st, "Statement"); +}; +base.ForInit = function (node, st, c) { + if (node.type === "VariableDeclaration") { c(node, st); } + else { c(node, st, "Expression"); } +}; +base.DebuggerStatement = ignore; + +base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); }; +base.VariableDeclaration = function (node, st, c) { + for (var i = 0, list = node.declarations; i < list.length; i += 1) + { + var decl = list[i]; + + c(decl, st); + } +}; +base.VariableDeclarator = function (node, st, c) { + c(node.id, st, "Pattern"); + if (node.init) { c(node.init, st, "Expression"); } +}; + +base.Function = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + c(param, st, "Pattern"); + } + c(node.body, st, node.expression ? "Expression" : "Statement"); +}; + +base.Pattern = function (node, st, c) { + if (node.type === "Identifier") + { c(node, st, "VariablePattern"); } + else if (node.type === "MemberExpression") + { c(node, st, "MemberPattern"); } + else + { c(node, st); } +}; +base.VariablePattern = ignore; +base.MemberPattern = skipThrough; +base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); }; +base.ArrayPattern = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Pattern"); } + } +}; +base.ObjectPattern = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + if (prop.type === "Property") { + if (prop.computed) { c(prop.key, st, "Expression"); } + c(prop.value, st, "Pattern"); + } else if (prop.type === "RestElement") { + c(prop.argument, st, "Pattern"); + } + } +}; + +base.Expression = skipThrough; +base.ThisExpression = base.Super = base.MetaProperty = ignore; +base.ArrayExpression = function (node, st, c) { + for (var i = 0, list = node.elements; i < list.length; i += 1) { + var elt = list[i]; + + if (elt) { c(elt, st, "Expression"); } + } +}; +base.ObjectExpression = function (node, st, c) { + for (var i = 0, list = node.properties; i < list.length; i += 1) + { + var prop = list[i]; + + c(prop, st); + } +}; +base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration; +base.SequenceExpression = function (node, st, c) { + for (var i = 0, list = node.expressions; i < list.length; i += 1) + { + var expr = list[i]; + + c(expr, st, "Expression"); + } +}; +base.TemplateLiteral = function (node, st, c) { + for (var i = 0, list = node.quasis; i < list.length; i += 1) + { + var quasi = list[i]; + + c(quasi, st); + } + + for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1) + { + var expr = list$1[i$1]; + + c(expr, st, "Expression"); + } +}; +base.TemplateElement = ignore; +base.UnaryExpression = base.UpdateExpression = function (node, st, c) { + c(node.argument, st, "Expression"); +}; +base.BinaryExpression = base.LogicalExpression = function (node, st, c) { + c(node.left, st, "Expression"); + c(node.right, st, "Expression"); +}; +base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) { + c(node.left, st, "Pattern"); + c(node.right, st, "Expression"); +}; +base.ConditionalExpression = function (node, st, c) { + c(node.test, st, "Expression"); + c(node.consequent, st, "Expression"); + c(node.alternate, st, "Expression"); +}; +base.NewExpression = base.CallExpression = function (node, st, c) { + c(node.callee, st, "Expression"); + if (node.arguments) + { for (var i = 0, list = node.arguments; i < list.length; i += 1) + { + var arg = list[i]; + + c(arg, st, "Expression"); + } } +}; +base.MemberExpression = function (node, st, c) { + c(node.object, st, "Expression"); + if (node.computed) { c(node.property, st, "Expression"); } +}; +base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) { + if (node.declaration) + { c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); } + if (node.source) { c(node.source, st, "Expression"); } +}; +base.ExportAllDeclaration = function (node, st, c) { + if (node.exported) + { c(node.exported, st); } + c(node.source, st, "Expression"); +}; +base.ImportDeclaration = function (node, st, c) { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) + { + var spec = list[i]; + + c(spec, st); + } + c(node.source, st, "Expression"); +}; +base.ImportExpression = function (node, st, c) { + c(node.source, st, "Expression"); +}; +base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore; + +base.TaggedTemplateExpression = function (node, st, c) { + c(node.tag, st, "Expression"); + c(node.quasi, st, "Expression"); +}; +base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); }; +base.Class = function (node, st, c) { + if (node.id) { c(node.id, st, "Pattern"); } + if (node.superClass) { c(node.superClass, st, "Expression"); } + c(node.body, st); +}; +base.ClassBody = function (node, st, c) { + for (var i = 0, list = node.body; i < list.length; i += 1) + { + var elt = list[i]; + + c(elt, st); + } +}; +base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) { + if (node.computed) { c(node.key, st, "Expression"); } + if (node.value) { c(node.value, st, "Expression"); } +}; + +export { ancestor, base, findNodeAfter, findNodeAround, findNodeAt, findNodeBefore, full, fullAncestor, make, recursive, simple }; diff --git a/deps/acorn/acorn-walk/package.json b/deps/acorn/acorn-walk/package.json index a66ca892ced57738a724b93d3d2f96978925dc8b..118bb0be2c72f51dbdf6fe8e3374eb80b83b64a6 100644 --- a/deps/acorn/acorn-walk/package.json +++ b/deps/acorn/acorn-walk/package.json @@ -5,7 +5,18 @@ "main": "dist/walk.js", "types": "dist/walk.d.ts", "module": "dist/walk.mjs", - "version": "7.1.1", + "exports": { + ".": [ + { + "import": "./dist/walk.mjs", + "require": "./dist/walk.js", + "default": "./dist/walk.js" + }, + "./dist/walk.js" + ], + "./package.json": "./package.json" + }, + "version": "8.1.0", "engines": {"node": ">=0.4.0"}, "maintainers": [ { diff --git a/deps/acorn/acorn/CHANGELOG.md b/deps/acorn/acorn/CHANGELOG.md index 32f5ce8f3bb4bf66d564c04847377edc14b3705a..d69ad88125311826f7f62ead731debfd51ebe610 100644 --- a/deps/acorn/acorn/CHANGELOG.md +++ b/deps/acorn/acorn/CHANGELOG.md @@ -1,3 +1,173 @@ +## 8.4.1 (2021-06-24) + +### Bug fixes + +Fix a bug where `allowAwaitOutsideFunction` would allow `await` in class field initializers, and setting `ecmaVersion` to 13 or higher would allow top-level await in non-module sources. + +## 8.4.0 (2021-06-11) + +### New features + +A new option, `allowSuperOutsideMethod`, can be used to suppress the error when `super` is used in the wrong context. + +## 8.3.0 (2021-05-31) + +### New features + +Default `allowAwaitOutsideFunction` to true for ECMAScript 2022 an higher. + +Add support for the `p` ([indices](https://github.com/tc39/proposal-regexp-match-indices)) regexp flag. + +## 8.2.4 (2021-05-04) + +### Bug fixes + +Fix spec conformity in corner case 'for await (async of ...)'. + +## 8.2.3 (2021-05-04) + +### Bug fixes + +Fix an issue where the library couldn't parse 'for (async of ...)'. + +Fix a bug in UTF-16 decoding that would read characters incorrectly in some circumstances. + +## 8.2.2 (2021-04-29) + +### Bug fixes + +Fix a bug where a class field initialized to an async arrow function wouldn't allow await inside it. Same issue existed for generator arrow functions with yield. + +## 8.2.1 (2021-04-24) + +### Bug fixes + +Fix a regression introduced in 8.2.0 where static or async class methods with keyword names fail to parse. + +## 8.2.0 (2021-04-24) + +### New features + +Add support for ES2022 class fields and private methods. + +## 8.1.1 (2021-04-12) + +### Various + +Stop shipping source maps in the NPM package. + +## 8.1.0 (2021-03-09) + +### Bug fixes + +Fix a spurious error in nested destructuring arrays. + +### New features + +Expose `allowAwaitOutsideFunction` in CLI interface. + +Make `allowImportExportAnywhere` also apply to `import.meta`. + +## 8.0.5 (2021-01-25) + +### Bug fixes + +Adjust package.json to work with Node 12.16.0 and 13.0-13.6. + +## 8.0.4 (2020-10-05) + +### Bug fixes + +Make `await x ** y` an error, following the spec. + +Fix potentially exponential regular expression. + +## 8.0.3 (2020-10-02) + +### Bug fixes + +Fix a wasteful loop during `Parser` creation when setting `ecmaVersion` to `"latest"`. + +## 8.0.2 (2020-09-30) + +### Bug fixes + +Make the TypeScript types reflect the current allowed values for `ecmaVersion`. + +Fix another regexp/division tokenizer issue. + +## 8.0.1 (2020-08-12) + +### Bug fixes + +Provide the correct value in the `version` export. + +## 8.0.0 (2020-08-12) + +### Bug fixes + +Disallow expressions like `(a = b) = c`. + +Make non-octal escape sequences a syntax error in strict mode. + +### New features + +The package can now be loaded directly as an ECMAScript module in node 13+. + +Update to the set of Unicode properties from ES2021. + +### Breaking changes + +The `ecmaVersion` option is now required. For the moment, omitting it will still work with a warning, but that will change in a future release. + +Some changes to method signatures that may be used by plugins. + +## 7.4.0 (2020-08-03) + +### New features + +Add support for logical assignment operators. + +Add support for numeric separators. + +## 7.3.1 (2020-06-11) + +### Bug fixes + +Make the string in the `version` export match the actual library version. + +## 7.3.0 (2020-06-11) + +### Bug fixes + +Fix a bug that caused parsing of object patterns with a property named `set` that had a default value to fail. + +### New features + +Add support for optional chaining (`?.`). + +## 7.2.0 (2020-05-09) + +### Bug fixes + +Fix precedence issue in parsing of async arrow functions. + +### New features + +Add support for nullish coalescing. + +Add support for `import.meta`. + +Support `export * as ...` syntax. + +Upgrade to Unicode 13. + +## 6.4.1 (2020-03-09) + +### Bug fixes + +More carefully check for valid UTF16 surrogate pairs in regexp validator. + ## 7.1.1 (2020-03-01) ### Bug fixes diff --git a/deps/acorn/acorn/LICENSE b/deps/acorn/acorn/LICENSE index 2c0632b6a7c63bd701c60f1daa8b8fa9bea56a81..d6be6db2cfff576dd96f97180707581bfb6b726c 100644 --- a/deps/acorn/acorn/LICENSE +++ b/deps/acorn/acorn/LICENSE @@ -1,4 +1,6 @@ -Copyright (C) 2012-2018 by various contributors (see AUTHORS) +MIT License + +Copyright (C) 2012-2020 by various contributors (see AUTHORS) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/deps/acorn/acorn/README.md b/deps/acorn/acorn/README.md index 585f2736fc05b5e36766149c089b922c449d9998..f27a99444b6f3f02a6b83ec98af012be68242d38 100644 --- a/deps/acorn/acorn/README.md +++ b/deps/acorn/acorn/README.md @@ -32,14 +32,14 @@ npm install ## Interface **parse**`(input, options)` is the main interface to the library. The -`input` parameter is a string, `options` can be undefined or an object -setting some of the options listed below. The return value will be an -abstract syntax tree object as specified by the [ESTree +`input` parameter is a string, `options` must be an object setting +some of the options listed below. The return value will be an abstract +syntax tree object as specified by the [ESTree spec](https://github.com/estree/estree). ```javascript let acorn = require("acorn"); -console.log(acorn.parse("1 + 1")); +console.log(acorn.parse("1 + 1", {ecmaVersion: 2020})); ``` When encountering a syntax error, the parser will raise a @@ -48,18 +48,20 @@ have a `pos` property that indicates the string offset at which the error occurred, and a `loc` object that contains a `{line, column}` object referring to that same position. -Options can be provided by passing a second argument, which should be -an object containing any of these fields: +Options are provided by in a second argument, which should be an +object containing any of these fields (only `ecmaVersion` is +required): - **ecmaVersion**: Indicates the ECMAScript version to parse. Must be - either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), 10 (2019) or 11 - (2020, partial support). This influences support for strict mode, - the set of reserved words, and support for new syntax features. - Default is 10. + either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 (2019), + 11 (2020), 12 (2021, partial support), 13 (2022, partial support) + or `"latest"` (the latest the library supports). This influences + support for strict mode, the set of reserved words, and support + for new syntax features. **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being - implemented by Acorn. Other proposed new features can be implemented - through plugins. + implemented by Acorn. Other proposed new features must be + implemented through plugins. - **sourceType**: Indicate the mode the code should be parsed in. Can be either `"script"` or `"module"`. This influences global strict mode @@ -89,13 +91,19 @@ an object containing any of these fields: - **allowImportExportEverywhere**: By default, `import` and `export` declarations can only appear at a program's top level. Setting this - option to `true` allows them anywhere where a statement is allowed. - -- **allowAwaitOutsideFunction**: By default, `await` expressions can - only appear inside `async` functions. Setting this option to + option to `true` allows them anywhere where a statement is allowed, + and also allows `import.meta` expressions to appear in scripts + (when `sourceType` is not `"module"`). + +- **allowAwaitOutsideFunction**: If `false`, `await` expressions can + only appear inside `async` functions. Defaults to `true` for + `ecmaVersion` 2022 and later, `false` for lower versions. Setting this option to `true` allows to have top-level `await` expressions. They are still not allowed in non-`async` functions, though. +- **allowSuperOutsideMethod**: By default, `super` outside a method + raises an error. Set this to `true` to accept such code. + - **allowHashBang**: When this is enabled (off by default), if the code starts with the characters `#!` (as in a shellscript), the first line will be treated as a comment. @@ -224,7 +232,7 @@ you can use its static `extend` method. var acorn = require("acorn"); var jsx = require("acorn-jsx"); var JSXParser = acorn.Parser.extend(jsx()); -JSXParser.parse("foo()"); +JSXParser.parse("foo()", {ecmaVersion: 2020}); ``` The `extend` method takes any number of plugin values, and returns a @@ -249,6 +257,9 @@ options: - `--allow-hash-bang`: If the code starts with the characters #! (as in a shellscript), the first line will be treated as a comment. +- `--allow-await-outside-function`: Allows top-level `await` expressions. + See the `allowAwaitOutsideFunction` option for more information. + - `--compact`: No whitespace is used in the AST output. - `--silent`: Do not output the AST, just return the exit status. @@ -266,5 +277,4 @@ Plugins for ECMAScript proposals: - [`acorn-stage3`](https://github.com/acornjs/acorn-stage3): Parse most stage 3 proposals, bundling: - [`acorn-class-fields`](https://github.com/acornjs/acorn-class-fields): Parse [class fields proposal](https://github.com/tc39/proposal-class-fields) - [`acorn-import-meta`](https://github.com/acornjs/acorn-import-meta): Parse [import.meta proposal](https://github.com/tc39/proposal-import-meta) - - [`acorn-numeric-separator`](https://github.com/acornjs/acorn-numeric-separator): Parse [numeric separator proposal](https://github.com/tc39/proposal-numeric-separator) - [`acorn-private-methods`](https://github.com/acornjs/acorn-private-methods): parse [private methods, getters and setters proposal](https://github.com/tc39/proposal-private-methods)n diff --git a/deps/node-inspect/cli.js b/deps/acorn/acorn/bin/acorn similarity index 32% rename from deps/node-inspect/cli.js rename to deps/acorn/acorn/bin/acorn index 4856fd706c45c2fbdae2d02e7dd5fd1b3dc5a2df..cf7df46890fdd48bbaa57fb0478c142bc4409f21 100755 --- a/deps/node-inspect/cli.js +++ b/deps/acorn/acorn/bin/acorn @@ -1,2 +1,4 @@ #!/usr/bin/env node -require('./lib/cli.js'); +'use strict'; + +require('../dist/bin.js'); diff --git a/deps/acorn/acorn/dist/acorn.d.ts b/deps/acorn/acorn/dist/acorn.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..8e8fbbcb426c3cc4db15802f44a231732ccc05be --- /dev/null +++ b/deps/acorn/acorn/dist/acorn.d.ts @@ -0,0 +1,211 @@ +export as namespace acorn +export = acorn + +declare namespace acorn { + function parse(input: string, options: Options): Node + + function parseExpressionAt(input: string, pos: number, options: Options): Node + + function tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator + } + + interface Options { + ecmaVersion: 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 'latest' + sourceType?: 'script' | 'module' + onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + allowReserved?: boolean | 'never' + allowReturnOutsideFunction?: boolean + allowImportExportEverywhere?: boolean + allowAwaitOutsideFunction?: boolean + allowSuperOutsideMethod?: boolean + allowHashBang?: boolean + locations?: boolean + onToken?: ((token: Token) => any) | Token[] + onComment?: (( + isBlock: boolean, text: string, start: number, end: number, startLoc?: Position, + endLoc?: Position + ) => void) | Comment[] + ranges?: boolean + program?: Node + sourceFile?: string + directSourceFile?: string + preserveParens?: boolean + } + + class Parser { + constructor(options: Options, input: string, startPos?: number) + parse(this: Parser): Node + static parse(this: typeof Parser, input: string, options: Options): Node + static parseExpressionAt(this: typeof Parser, input: string, pos: number, options: Options): Node + static tokenizer(this: typeof Parser, input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator + } + static extend(this: typeof Parser, ...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser + } + + interface Position { line: number; column: number; offset: number } + + const defaultOptions: Options + + function getLineInfo(input: string, offset: number): Position + + class SourceLocation { + start: Position + end: Position + source?: string | null + constructor(p: Parser, start: Position, end: Position) + } + + class Node { + type: string + start: number + end: number + loc?: SourceLocation + sourceFile?: string + range?: [number, number] + constructor(parser: Parser, pos: number, loc?: SourceLocation) + } + + class TokenType { + label: string + keyword: string + beforeExpr: boolean + startsExpr: boolean + isLoop: boolean + isAssign: boolean + prefix: boolean + postfix: boolean + binop: number + updateContext?: (prevType: TokenType) => void + constructor(label: string, conf?: any) + } + + const tokTypes: { + num: TokenType + regexp: TokenType + string: TokenType + name: TokenType + privateId: TokenType + eof: TokenType + bracketL: TokenType + bracketR: TokenType + braceL: TokenType + braceR: TokenType + parenL: TokenType + parenR: TokenType + comma: TokenType + semi: TokenType + colon: TokenType + dot: TokenType + question: TokenType + arrow: TokenType + template: TokenType + ellipsis: TokenType + backQuote: TokenType + dollarBraceL: TokenType + eq: TokenType + assign: TokenType + incDec: TokenType + prefix: TokenType + logicalOR: TokenType + logicalAND: TokenType + bitwiseOR: TokenType + bitwiseXOR: TokenType + bitwiseAND: TokenType + equality: TokenType + relational: TokenType + bitShift: TokenType + plusMin: TokenType + modulo: TokenType + star: TokenType + slash: TokenType + starstar: TokenType + _break: TokenType + _case: TokenType + _catch: TokenType + _continue: TokenType + _debugger: TokenType + _default: TokenType + _do: TokenType + _else: TokenType + _finally: TokenType + _for: TokenType + _function: TokenType + _if: TokenType + _return: TokenType + _switch: TokenType + _throw: TokenType + _try: TokenType + _var: TokenType + _const: TokenType + _while: TokenType + _with: TokenType + _new: TokenType + _this: TokenType + _super: TokenType + _class: TokenType + _extends: TokenType + _export: TokenType + _import: TokenType + _null: TokenType + _true: TokenType + _false: TokenType + _in: TokenType + _instanceof: TokenType + _typeof: TokenType + _void: TokenType + _delete: TokenType + } + + class TokContext { + constructor(token: string, isExpr: boolean, preserveSpace: boolean, override?: (p: Parser) => void) + } + + const tokContexts: { + b_stat: TokContext + b_expr: TokContext + b_tmpl: TokContext + p_stat: TokContext + p_expr: TokContext + q_tmpl: TokContext + f_expr: TokContext + } + + function isIdentifierStart(code: number, astral?: boolean): boolean + + function isIdentifierChar(code: number, astral?: boolean): boolean + + interface AbstractToken { + } + + interface Comment extends AbstractToken { + type: string + value: string + start: number + end: number + loc?: SourceLocation + range?: [number, number] + } + + class Token { + type: TokenType + value: any + start: number + end: number + loc?: SourceLocation + range?: [number, number] + constructor(p: Parser) + } + + function isNewLine(code: number): boolean + + const lineBreak: RegExp + + const lineBreakG: RegExp + + const version: string +} diff --git a/deps/acorn/acorn/dist/acorn.js b/deps/acorn/acorn/dist/acorn.js index e2b33179c789c729fc27059ff73884e962953114..af24e36cf16d2edc85aa57a07f15ce5dd89d33f3 100644 --- a/deps/acorn/acorn/dist/acorn.js +++ b/deps/acorn/acorn/dist/acorn.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.acorn = {})); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; // Reserved word lists for various dialects of the language @@ -33,8 +33,8 @@ // are only applied when a character is found to actually have a // code point above 128. // Generated by `bin/generate-identifier-regex.js`. - var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7c6\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab67\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; - var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; + var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08c7\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf\u1ac0\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); @@ -48,10 +48,10 @@ // generated by bin/generate-identifier-regex.js // eslint-disable-next-line comma-spacing - var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,477,28,11,0,9,21,155,22,13,52,76,44,33,24,27,35,30,0,12,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,21,0,33,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,230,43,117,63,32,0,161,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,270,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,74,6,0,67,12,65,1,2,0,29,6135,9,754,9486,286,50,2,18,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,2357,44,11,6,17,0,370,43,1301,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,15,7472,3104,541]; + var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,349,41,7,1,79,28,11,0,9,21,107,20,28,22,13,52,76,44,33,24,27,35,30,0,3,0,9,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,230,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,190,0,80,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,74,6,0,67,12,65,1,2,0,29,6135,9,1237,43,8,8952,286,50,2,18,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,2357,44,11,6,17,0,370,43,1301,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42717,35,4148,12,221,3,5761,15,7472,3104,541,1507,4938]; // eslint-disable-next-line comma-spacing - var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,232,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1014,0,2,54,8,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,262,6,10,9,419,13,1495,6,110,6,6,9,792487,239]; + var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,370,1,154,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,2,11,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1014,0,2,54,8,3,82,0,12,1,19628,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,262,6,10,9,419,13,1495,6,110,6,6,9,4759,9,787719,239]; // This has a complexity linear to the value of the code. The // assumption is that looking up astral identifier characters is @@ -152,6 +152,7 @@ regexp: new TokenType("regexp", startsExpr), string: new TokenType("string", startsExpr), name: new TokenType("name", startsExpr), + privateId: new TokenType("privateId", startsExpr), eof: new TokenType("eof"), // Punctuation token types. @@ -166,6 +167,7 @@ colon: new TokenType(":", beforeExpr), dot: new TokenType("."), question: new TokenType("?", beforeExpr), + questionDot: new TokenType("?."), arrow: new TokenType("=>", beforeExpr), template: new TokenType("template"), invalidTemplate: new TokenType("invalidTemplate"), @@ -204,6 +206,7 @@ star: binop("*", 10), slash: binop("/", 10), starstar: new TokenType("**", {beforeExpr: true}), + coalesce: binop("??", 1), // Keyword token types. _break: kw("break"), @@ -312,16 +315,17 @@ } } - // A second optional argument can be given to further configure - // the parser process. These options are recognized: + // A second argument must be given to configure the parser process. + // These options are recognized (only `ecmaVersion` is required): var defaultOptions = { // `ecmaVersion` indicates the ECMAScript version to parse. Must be - // either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), or 10 - // (2019). This influences support for strict mode, the set of - // reserved words, and support for new syntax features. The default - // is 10. - ecmaVersion: 10, + // either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 + // (2019), 11 (2020), 12 (2021), 13 (2022), or `"latest"` (the + // latest version the library supports). This influences support + // for strict mode, the set of reserved words, and support for + // new syntax features. + ecmaVersion: null, // `sourceType` indicates the mode the code should be parsed in. // Can be either `"script"` or `"module"`. This influences global // strict mode and parsing of `import` and `export` declarations. @@ -344,11 +348,16 @@ // error. allowReturnOutsideFunction: false, // When enabled, import/export statements are not constrained to - // appearing at the top of the program. + // appearing at the top of the program, and an import.meta expression + // in a script isn't considered an error. allowImportExportEverywhere: false, + // By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022. // When enabled, await identifiers are allowed to appear at the top-level scope, // but they are still not allowed in non-async functions. - allowAwaitOutsideFunction: false, + allowAwaitOutsideFunction: null, + // When enabled, super identifiers are not constrained to + // appearing in methods and do not raise an error when they appear elsewhere. + allowSuperOutsideMethod: null, // When enabled, hashbang directive in the beginning of file // is allowed and treated as a line comment. allowHashBang: false, @@ -402,14 +411,25 @@ // Interpret and default an options object + var warnedAboutEcmaVersion = false; + function getOptions(opts) { var options = {}; for (var opt in defaultOptions) { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; } - if (options.ecmaVersion >= 2015) - { options.ecmaVersion -= 2009; } + if (options.ecmaVersion === "latest") { + options.ecmaVersion = 1e8; + } else if (options.ecmaVersion == null) { + if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) { + warnedAboutEcmaVersion = true; + console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future."); + } + options.ecmaVersion = 11; + } else if (options.ecmaVersion >= 2015) { + options.ecmaVersion -= 2009; + } if (options.allowReserved == null) { options.allowReserved = options.ecmaVersion < 5; } @@ -456,7 +476,7 @@ return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0) } - // Used in checkLVal and declareName to determine the type of a binding + // Used in checkLVal* and declareName to determine the type of a binding var BIND_NONE = 0, // Not a binding BIND_VAR = 1, // Var-style binding @@ -471,8 +491,7 @@ this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]); var reserved = ""; if (options.allowReserved !== true) { - for (var v = options.ecmaVersion;; v--) - { if (reserved = reservedWords[v]) { break } } + reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3]; if (options.sourceType === "module") { reserved += " await"; } } this.reservedWords = wordsRegexp(reserved); @@ -525,13 +544,14 @@ // Used to signify the start of a potential arrow function this.potentialArrowAt = -1; + this.potentialArrowInForAwait = false; // Positions to delayed-check that yield/await does not exist in default parameters. this.yieldPos = this.awaitPos = this.awaitIdentPos = 0; // Labels in scope. this.labels = []; // Thus-far undefined exports. - this.undefinedExports = {}; + this.undefinedExports = Object.create(null); // If enabled, skip leading hashbang line. if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") @@ -543,9 +563,14 @@ // For RegExp validation this.regexpState = null; + + // The stack of private names. + // Each element has two properties: 'declared' and 'used'. + // When it exited from the outermost class definition, all used private names must be declared. + this.privateNameStack = []; }; - var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true } }; + var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },inNonArrowFunction: { configurable: true } }; Parser.prototype.parse = function parse () { var node = this.options.program || this.startNode(); @@ -554,14 +579,30 @@ }; prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 }; - prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 }; - prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 }; - prototypeAccessors.allowSuper.get = function () { return (this.currentThisScope().flags & SCOPE_SUPER) > 0 }; + prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 && !this.currentVarScope().inClassFieldInit }; + prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 && !this.currentVarScope().inClassFieldInit }; + prototypeAccessors.canAwait.get = function () { + for (var i = this.scopeStack.length - 1; i >= 0; i--) { + var scope = this.scopeStack[i]; + if (scope.inClassFieldInit) { return false } + if (scope.flags & SCOPE_FUNCTION) { return (scope.flags & SCOPE_ASYNC) > 0 } + } + return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction + }; + prototypeAccessors.allowSuper.get = function () { + var ref = this.currentThisScope(); + var flags = ref.flags; + var inClassFieldInit = ref.inClassFieldInit; + return (flags & SCOPE_SUPER) > 0 || inClassFieldInit || this.options.allowSuperOutsideMethod + }; prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 }; prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) }; - - // Switch to a getter for 7.0.0. - Parser.prototype.inNonArrowFunction = function inNonArrowFunction () { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0 }; + prototypeAccessors.inNonArrowFunction.get = function () { + var ref = this.currentThisScope(); + var flags = ref.flags; + var inClassFieldInit = ref.inClassFieldInit; + return (flags & SCOPE_FUNCTION) > 0 || inClassFieldInit + }; Parser.extend = function extend () { var plugins = [], len = arguments.length; @@ -592,7 +633,7 @@ // ## Parser utilities - var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)")/; + var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/; pp.strictDirective = function(start) { for (;;) { // Try to find string literal. @@ -600,7 +641,14 @@ start += skipWhiteSpace.exec(this.input)[0].length; var match = literal.exec(this.input.slice(start)); if (!match) { return false } - if ((match[1] || match[2]) === "use strict") { return true } + if ((match[1] || match[2]) === "use strict") { + skipWhiteSpace.lastIndex = start + match[0].length; + var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length; + var next = this.input.charAt(end); + return next === ";" || next === "}" || + (lineBreak.test(spaceAfter[0]) && + !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "=")) + } start += match[0].length; // Skip semicolon, if any. @@ -740,7 +788,7 @@ // to its body instead of creating a new node. pp$1.parseTopLevel = function(node) { - var exports = {}; + var exports = Object.create(null); if (!node.body) { node.body = []; } while (this.type !== types.eof) { var stmt = this.parseStatement(null, true, exports); @@ -770,13 +818,14 @@ // Statement) is allowed here. If context is not empty then only a Statement // is allowed. However, `let [` is an explicit negative lookahead for // ExpressionStatement, so special-case it first. - if (nextCh === 91) { return true } // '[' + if (nextCh === 91 || nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '[', '/', astral if (context) { return false } if (nextCh === 123) { return true } // '{' if (isIdentifierStart(nextCh, true)) { var pos = next + 1; - while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; } + while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; } + if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } var ident = this.input.slice(next, pos); if (!keywordRelationalOperator.test(ident)) { return true } } @@ -792,10 +841,11 @@ skipWhiteSpace.lastIndex = this.pos; var skip = skipWhiteSpace.exec(this.input); - var next = this.pos + skip[0].length; + var next = this.pos + skip[0].length, after; return !lineBreak.test(this.input.slice(this.pos, next)) && this.input.slice(next, next + 8) === "function" && - (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) + (next + 8 === this.input.length || + !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00)) }; // Parse a single statement. @@ -850,7 +900,7 @@ skipWhiteSpace.lastIndex = this.pos; var skip = skipWhiteSpace.exec(this.input); var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); - if (nextCh === 40) // '(' + if (nextCh === 40 || nextCh === 46) // '(' or '.' { return this.parseExpressionStatement(node, this.parseExpression()) } } @@ -935,7 +985,7 @@ pp$1.parseForStatement = function(node) { this.next(); - var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1; + var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1; this.labels.push(loopLabel); this.enterScope(0); this.expect(types.parenL); @@ -961,7 +1011,7 @@ return this.parseFor(node, init$1) } var refDestructuringErrors = new DestructuringErrors; - var init = this.parseExpression(true, refDestructuringErrors); + var init = this.parseExpression(awaitAt > -1 ? "await" : true, refDestructuringErrors); if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { if (this.options.ecmaVersion >= 9) { if (this.type === types._in) { @@ -969,7 +1019,7 @@ } else { node.await = awaitAt > -1; } } this.toAssignable(init, false, refDestructuringErrors); - this.checkLVal(init); + this.checkLValPattern(init); return this.parseForIn(node, init) } else { this.checkExpressionErrors(refDestructuringErrors, true); @@ -1070,7 +1120,7 @@ clause.param = this.parseBindingAtom(); var simple = clause.param.type === "Identifier"; this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0); - this.checkLVal(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); + this.checkLValPattern(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); this.expect(types.parenR); } else { if (this.options.ecmaVersion < 10) { this.unexpected(); } @@ -1150,17 +1200,19 @@ // strict"` declarations when `allowStrict` is true (used for // function bodies). - pp$1.parseBlock = function(createNewLexicalScope, node) { + pp$1.parseBlock = function(createNewLexicalScope, node, exitStrict) { if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; if ( node === void 0 ) node = this.startNode(); node.body = []; this.expect(types.braceL); if (createNewLexicalScope) { this.enterScope(0); } - while (!this.eat(types.braceR)) { + while (this.type !== types.braceR) { var stmt = this.parseStatement(null); node.body.push(stmt); } + if (exitStrict) { this.strict = false; } + this.next(); if (createNewLexicalScope) { this.exitScope(); } return this.finishNode(node, "BlockStatement") }; @@ -1204,8 +1256,6 @@ init.start, ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer") ); - } else if (init.type === "AssignmentPattern") { - this.raise(init.start, "Invalid left-hand side in for-loop"); } node.left = init; node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); @@ -1241,7 +1291,7 @@ pp$1.parseVarId = function(decl, kind) { decl.id = this.parseBindingAtom(); - this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); + this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); }; var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4; @@ -1267,7 +1317,7 @@ // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding // mode depends on properties of the current scope (see // treatFunctionsAsVar). - { this.checkLVal(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); } + { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); } } var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; @@ -1307,92 +1357,171 @@ this.parseClassId(node, isStatement); this.parseClassSuper(node); + var privateNameMap = this.enterClassBody(); var classBody = this.startNode(); var hadConstructor = false; classBody.body = []; this.expect(types.braceL); - while (!this.eat(types.braceR)) { + while (this.type !== types.braceR) { var element = this.parseClassElement(node.superClass !== null); if (element) { classBody.body.push(element); if (element.type === "MethodDefinition" && element.kind === "constructor") { if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); } hadConstructor = true; + } else if (element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) { + this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared")); } } } - node.body = this.finishNode(classBody, "ClassBody"); this.strict = oldStrict; + this.next(); + node.body = this.finishNode(classBody, "ClassBody"); + this.exitClassBody(); return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") }; pp$1.parseClassElement = function(constructorAllowsSuper) { - var this$1 = this; - if (this.eat(types.semi)) { return null } - var method = this.startNode(); - var tryContextual = function (k, noLineBreak) { - if ( noLineBreak === void 0 ) noLineBreak = false; - - var start = this$1.start, startLoc = this$1.startLoc; - if (!this$1.eatContextual(k)) { return false } - if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true } - if (method.key) { this$1.unexpected(); } - method.computed = false; - method.key = this$1.startNodeAt(start, startLoc); - method.key.name = k; - this$1.finishNode(method.key, "Identifier"); - return false - }; - - method.kind = "method"; - method.static = tryContextual("static"); - var isGenerator = this.eat(types.star); + var ecmaVersion = this.options.ecmaVersion; + var node = this.startNode(); + var keyName = ""; + var isGenerator = false; var isAsync = false; - if (!isGenerator) { - if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { + var kind = "method"; + + // Parse modifiers + node.static = false; + if (this.eatContextual("static")) { + if (this.isClassElementNameStart() || this.type === types.star) { + node.static = true; + } else { + keyName = "static"; + } + } + if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) { + if ((this.isClassElementNameStart() || this.type === types.star) && !this.canInsertSemicolon()) { isAsync = true; - isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); - } else if (tryContextual("get")) { - method.kind = "get"; - } else if (tryContextual("set")) { - method.kind = "set"; + } else { + keyName = "async"; } } - if (!method.key) { this.parsePropertyName(method); } + if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types.star)) { + isGenerator = true; + } + if (!keyName && !isAsync && !isGenerator) { + var lastValue = this.value; + if (this.eatContextual("get") || this.eatContextual("set")) { + if (this.isClassElementNameStart()) { + kind = lastValue; + } else { + keyName = lastValue; + } + } + } + + // Parse element name + if (keyName) { + // 'async', 'get', 'set', or 'static' were not a keyword contextually. + // The last token is any of those. Make it the element name. + node.computed = false; + node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc); + node.key.name = keyName; + this.finishNode(node.key, "Identifier"); + } else { + this.parseClassElementName(node); + } + + // Parse element value + if (ecmaVersion < 13 || this.type === types.parenL || kind !== "method" || isGenerator || isAsync) { + var isConstructor = !node.static && checkKeyName(node, "constructor"); + var allowsDirectSuper = isConstructor && constructorAllowsSuper; + // Couldn't move this check into the 'parseClassMethod' method for backward compatibility. + if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); } + node.kind = isConstructor ? "constructor" : kind; + this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper); + } else { + this.parseClassField(node); + } + + return node + }; + + pp$1.isClassElementNameStart = function() { + return ( + this.type === types.name || + this.type === types.privateId || + this.type === types.num || + this.type === types.string || + this.type === types.bracketL || + this.type.keyword + ) + }; + + pp$1.parseClassElementName = function(element) { + if (this.type === types.privateId) { + if (this.value === "constructor") { + this.raise(this.start, "Classes can't have an element named '#constructor'"); + } + element.computed = false; + element.key = this.parsePrivateIdent(); + } else { + this.parsePropertyName(element); + } + }; + + pp$1.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) { + // Check key and flags var key = method.key; - var allowsDirectSuper = false; - if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" || - key.type === "Literal" && key.value === "constructor")) { - if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); } + if (method.kind === "constructor") { if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } - method.kind = "constructor"; - allowsDirectSuper = constructorAllowsSuper; - } else if (method.static && key.type === "Identifier" && key.name === "prototype") { + } else if (method.static && checkKeyName(method, "prototype")) { this.raise(key.start, "Classes may not have a static property named prototype"); } - this.parseClassMethod(method, isGenerator, isAsync, allowsDirectSuper); - if (method.kind === "get" && method.value.params.length !== 0) - { this.raiseRecoverable(method.value.start, "getter should have no params"); } - if (method.kind === "set" && method.value.params.length !== 1) - { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); } - if (method.kind === "set" && method.value.params[0].type === "RestElement") - { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); } - return method - }; - pp$1.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) { - method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); + // Parse value + var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); + + // Check value + if (method.kind === "get" && value.params.length !== 0) + { this.raiseRecoverable(value.start, "getter should have no params"); } + if (method.kind === "set" && value.params.length !== 1) + { this.raiseRecoverable(value.start, "setter should have exactly one param"); } + if (method.kind === "set" && value.params[0].type === "RestElement") + { this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); } + return this.finishNode(method, "MethodDefinition") }; + pp$1.parseClassField = function(field) { + if (checkKeyName(field, "constructor")) { + this.raise(field.key.start, "Classes can't have a field named 'constructor'"); + } else if (field.static && checkKeyName(field, "prototype")) { + this.raise(field.key.start, "Classes can't have a static field named 'prototype'"); + } + + if (this.eat(types.eq)) { + // To raise SyntaxError if 'arguments' exists in the initializer. + var scope = this.currentThisScope(); + var inClassFieldInit = scope.inClassFieldInit; + scope.inClassFieldInit = true; + field.value = this.parseMaybeAssign(); + scope.inClassFieldInit = inClassFieldInit; + } else { + field.value = null; + } + this.semicolon(); + + return this.finishNode(field, "PropertyDefinition") + }; + pp$1.parseClassId = function(node, isStatement) { if (this.type === types.name) { node.id = this.parseIdent(); if (isStatement) - { this.checkLVal(node.id, BIND_LEXICAL, false); } + { this.checkLValSimple(node.id, BIND_LEXICAL, false); } } else { if (isStatement === true) { this.unexpected(); } @@ -1404,12 +1533,79 @@ node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; }; + pp$1.enterClassBody = function() { + var element = {declared: Object.create(null), used: []}; + this.privateNameStack.push(element); + return element.declared + }; + + pp$1.exitClassBody = function() { + var ref = this.privateNameStack.pop(); + var declared = ref.declared; + var used = ref.used; + var len = this.privateNameStack.length; + var parent = len === 0 ? null : this.privateNameStack[len - 1]; + for (var i = 0; i < used.length; ++i) { + var id = used[i]; + if (!has(declared, id.name)) { + if (parent) { + parent.used.push(id); + } else { + this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class")); + } + } + } + }; + + function isPrivateNameConflicted(privateNameMap, element) { + var name = element.key.name; + var curr = privateNameMap[name]; + + var next = "true"; + if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) { + next = (element.static ? "s" : "i") + element.kind; + } + + // `class { get #a(){}; static set #a(_){} }` is also conflict. + if ( + curr === "iget" && next === "iset" || + curr === "iset" && next === "iget" || + curr === "sget" && next === "sset" || + curr === "sset" && next === "sget" + ) { + privateNameMap[name] = "true"; + return false + } else if (!curr) { + privateNameMap[name] = next; + return false + } else { + return true + } + } + + function checkKeyName(node, name) { + var computed = node.computed; + var key = node.key; + return !computed && ( + key.type === "Identifier" && key.name === name || + key.type === "Literal" && key.value === name + ) + } + // Parses module export declaration. pp$1.parseExport = function(node, exports) { this.next(); // export * from '...' if (this.eat(types.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseIdent(true); + this.checkExport(exports, node.exported.name, this.lastTokStart); + } else { + node.exported = null; + } + } this.expectContextual("from"); if (this.type !== types.string) { this.unexpected(); } node.source = this.parseExprAtom(); @@ -1564,7 +1760,7 @@ // import defaultObj, { x, y as z } from '...' var node = this.startNode(); node.local = this.parseIdent(); - this.checkLVal(node.local, BIND_LEXICAL); + this.checkLValSimple(node.local, BIND_LEXICAL); nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); if (!this.eat(types.comma)) { return nodes } } @@ -1573,7 +1769,7 @@ this.next(); this.expectContextual("as"); node$1.local = this.parseIdent(); - this.checkLVal(node$1.local, BIND_LEXICAL); + this.checkLValSimple(node$1.local, BIND_LEXICAL); nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); return nodes } @@ -1592,7 +1788,7 @@ this.checkUnreserved(node$2.imported); node$2.local = node$2.imported; } - this.checkLVal(node$2.local, BIND_LEXICAL); + this.checkLValSimple(node$2.local, BIND_LEXICAL); nodes.push(this.finishNode(node$2, "ImportSpecifier")); } return nodes @@ -1629,6 +1825,7 @@ case "ObjectPattern": case "ArrayPattern": + case "AssignmentPattern": case "RestElement": break @@ -1677,15 +1874,16 @@ node.type = "AssignmentPattern"; delete node.operator; this.toAssignable(node.left, isBinding); - // falls through to AssignmentPattern - - case "AssignmentPattern": break case "ParenthesizedExpression": this.toAssignable(node.expression, isBinding, refDestructuringErrors); break + case "ChainExpression": + this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side"); + break + case "MemberExpression": if (!isBinding) { break } @@ -1792,70 +1990,152 @@ return this.finishNode(node, "AssignmentPattern") }; - // Verify that a node is an lval — something that can be assigned - // to. - // bindingType can be either: - // 'var' indicating that the lval creates a 'var' binding - // 'let' indicating that the lval creates a lexical ('let' or 'const') binding - // 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references + // The following three functions all verify that a node is an lvalue — + // something that can be bound, or assigned to. In order to do so, they perform + // a variety of checks: + // + // - Check that none of the bound/assigned-to identifiers are reserved words. + // - Record name declarations for bindings in the appropriate scope. + // - Check duplicate argument names, if checkClashes is set. + // + // If a complex binding pattern is encountered (e.g., object and array + // destructuring), the entire pattern is recursively checked. + // + // There are three versions of checkLVal*() appropriate for different + // circumstances: + // + // - checkLValSimple() shall be used if the syntactic construct supports + // nothing other than identifiers and member expressions. Parenthesized + // expressions are also correctly handled. This is generally appropriate for + // constructs for which the spec says + // + // > It is a Syntax Error if AssignmentTargetType of [the production] is not + // > simple. + // + // It is also appropriate for checking if an identifier is valid and not + // defined elsewhere, like import declarations or function/class identifiers. + // + // Examples where this is used include: + // a += …; + // import a from '…'; + // where a is the node to be checked. + // + // - checkLValPattern() shall be used if the syntactic construct supports + // anything checkLValSimple() supports, as well as object and array + // destructuring patterns. This is generally appropriate for constructs for + // which the spec says + // + // > It is a Syntax Error if [the production] is neither an ObjectLiteral nor + // > an ArrayLiteral and AssignmentTargetType of [the production] is not + // > simple. + // + // Examples where this is used include: + // (a = …); + // const a = …; + // try { … } catch (a) { … } + // where a is the node to be checked. + // + // - checkLValInnerPattern() shall be used if the syntactic construct supports + // anything checkLValPattern() supports, as well as default assignment + // patterns, rest elements, and other constructs that may appear within an + // object or array destructuring pattern. + // + // As a special case, function parameters also use checkLValInnerPattern(), + // as they also support defaults and rest constructs. + // + // These functions deliberately support both assignment and binding constructs, + // as the logic for both is exceedingly similar. If the node is the target of + // an assignment, then bindingType should be set to BIND_NONE. Otherwise, it + // should be set to the appropriate BIND_* constant, like BIND_VAR or + // BIND_LEXICAL. + // + // If the function is called with a non-BIND_NONE bindingType, then + // additionally a checkClashes object may be specified to allow checking for + // duplicate argument names. checkClashes is ignored if the provided construct + // is an assignment (i.e., bindingType is BIND_NONE). - pp$2.checkLVal = function(expr, bindingType, checkClashes) { + pp$2.checkLValSimple = function(expr, bindingType, checkClashes) { if ( bindingType === void 0 ) bindingType = BIND_NONE; + var isBind = bindingType !== BIND_NONE; + switch (expr.type) { case "Identifier": - if (bindingType === BIND_LEXICAL && expr.name === "let") - { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); } if (this.strict && this.reservedWordsStrictBind.test(expr.name)) - { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } - if (checkClashes) { - if (has(checkClashes, expr.name)) - { this.raiseRecoverable(expr.start, "Argument name clash"); } - checkClashes[expr.name] = true; + { this.raiseRecoverable(expr.start, (isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } + if (isBind) { + if (bindingType === BIND_LEXICAL && expr.name === "let") + { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); } + if (checkClashes) { + if (has(checkClashes, expr.name)) + { this.raiseRecoverable(expr.start, "Argument name clash"); } + checkClashes[expr.name] = true; + } + if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } } - if (bindingType !== BIND_NONE && bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } + break + + case "ChainExpression": + this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side"); break case "MemberExpression": - if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); } + if (isBind) { this.raiseRecoverable(expr.start, "Binding member expression"); } break - case "ObjectPattern": - for (var i = 0, list = expr.properties; i < list.length; i += 1) - { - var prop = list[i]; + case "ParenthesizedExpression": + if (isBind) { this.raiseRecoverable(expr.start, "Binding parenthesized expression"); } + return this.checkLValSimple(expr.expression, bindingType, checkClashes) - this.checkLVal(prop, bindingType, checkClashes); + default: + this.raise(expr.start, (isBind ? "Binding" : "Assigning to") + " rvalue"); } - break + }; - case "Property": - // AssignmentProperty has type === "Property" - this.checkLVal(expr.value, bindingType, checkClashes); + pp$2.checkLValPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "ObjectPattern": + for (var i = 0, list = expr.properties; i < list.length; i += 1) { + var prop = list[i]; + + this.checkLValInnerPattern(prop, bindingType, checkClashes); + } break case "ArrayPattern": for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { var elem = list$1[i$1]; - if (elem) { this.checkLVal(elem, bindingType, checkClashes); } + if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); } } break - case "AssignmentPattern": - this.checkLVal(expr.left, bindingType, checkClashes); + default: + this.checkLValSimple(expr, bindingType, checkClashes); + } + }; + + pp$2.checkLValInnerPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "Property": + // AssignmentProperty has type === "Property" + this.checkLValInnerPattern(expr.value, bindingType, checkClashes); break - case "RestElement": - this.checkLVal(expr.argument, bindingType, checkClashes); + case "AssignmentPattern": + this.checkLValPattern(expr.left, bindingType, checkClashes); break - case "ParenthesizedExpression": - this.checkLVal(expr.expression, bindingType, checkClashes); + case "RestElement": + this.checkLValPattern(expr.argument, bindingType, checkClashes); break default: - this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue"); + this.checkLValPattern(expr, bindingType, checkClashes); } }; @@ -1930,13 +2210,13 @@ // and object pattern might appear (so it's possible to raise // delayed syntax error at correct position). - pp$3.parseExpression = function(noIn, refDestructuringErrors) { + pp$3.parseExpression = function(forInit, refDestructuringErrors) { var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseMaybeAssign(noIn, refDestructuringErrors); + var expr = this.parseMaybeAssign(forInit, refDestructuringErrors); if (this.type === types.comma) { var node = this.startNodeAt(startPos, startLoc); node.expressions = [expr]; - while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors)); } + while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); } return this.finishNode(node, "SequenceExpression") } return expr @@ -1945,9 +2225,9 @@ // Parse an assignment expression. This includes applications of // operators like `+=`. - pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + pp$3.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) { if (this.isContextual("yield")) { - if (this.inGenerator) { return this.parseYield(noIn) } + if (this.inGenerator) { return this.parseYield(forInit) } // The tokenizer will assume an expression is allowed after // `yield`, but this isn't that kind of yield else { this.exprAllowed = false; } @@ -1964,22 +2244,29 @@ } var startPos = this.start, startLoc = this.startLoc; - if (this.type === types.parenL || this.type === types.name) - { this.potentialArrowAt = this.start; } - var left = this.parseMaybeConditional(noIn, refDestructuringErrors); + if (this.type === types.parenL || this.type === types.name) { + this.potentialArrowAt = this.start; + this.potentialArrowInForAwait = forInit === "await"; + } + var left = this.parseMaybeConditional(forInit, refDestructuringErrors); if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } if (this.type.isAssign) { var node = this.startNodeAt(startPos, startLoc); node.operator = this.value; - node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left; + if (this.type === types.eq) + { left = this.toAssignable(left, false, refDestructuringErrors); } if (!ownDestructuringErrors) { refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1; } - if (refDestructuringErrors.shorthandAssign >= node.left.start) + if (refDestructuringErrors.shorthandAssign >= left.start) { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly - this.checkLVal(left); + if (this.type === types.eq) + { this.checkLValPattern(left); } + else + { this.checkLValSimple(left); } + node.left = left; this.next(); - node.right = this.parseMaybeAssign(noIn); + node.right = this.parseMaybeAssign(forInit); return this.finishNode(node, "AssignmentExpression") } else { if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } @@ -1991,16 +2278,16 @@ // Parse a ternary conditional (`?:`) operator. - pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { + pp$3.parseMaybeConditional = function(forInit, refDestructuringErrors) { var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseExprOps(noIn, refDestructuringErrors); + var expr = this.parseExprOps(forInit, refDestructuringErrors); if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } if (this.eat(types.question)) { var node = this.startNodeAt(startPos, startLoc); node.test = expr; node.consequent = this.parseMaybeAssign(); this.expect(types.colon); - node.alternate = this.parseMaybeAssign(noIn); + node.alternate = this.parseMaybeAssign(forInit); return this.finishNode(node, "ConditionalExpression") } return expr @@ -2008,11 +2295,11 @@ // Start the precedence parser. - pp$3.parseExprOps = function(noIn, refDestructuringErrors) { + pp$3.parseExprOps = function(forInit, refDestructuringErrors) { var startPos = this.start, startLoc = this.startLoc; var expr = this.parseMaybeUnary(refDestructuringErrors, false); if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } - return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn) + return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit) }; // Parse binary operators with the operator precedence parsing @@ -2021,17 +2308,26 @@ // defer further parser to one of its callers when it encounters an // operator that has a lower precedence than the set it is parsing. - pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { + pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) { var prec = this.type.binop; - if (prec != null && (!noIn || this.type !== types._in)) { + if (prec != null && (!forInit || this.type !== types._in)) { if (prec > minPrec) { var logical = this.type === types.logicalOR || this.type === types.logicalAND; + var coalesce = this.type === types.coalesce; + if (coalesce) { + // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions. + // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error. + prec = types.logicalAND.binop; + } var op = this.value; this.next(); var startPos = this.start, startLoc = this.startLoc; - var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn); - var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical); - return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) + var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, forInit); + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce); + if ((logical && this.type === types.coalesce) || (coalesce && (this.type === types.logicalOR || this.type === types.logicalAND))) { + this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"); + } + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit) } } return left @@ -2047,9 +2343,9 @@ // Parse unary operators, both prefix and postfix. - pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec) { var startPos = this.start, startLoc = this.startLoc, expr; - if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) { + if (this.isContextual("await") && this.canAwait) { expr = this.parseAwait(); sawUnary = true; } else if (this.type.prefix) { @@ -2057,12 +2353,14 @@ node.operator = this.value; node.prefix = true; this.next(); - node.argument = this.parseMaybeUnary(null, true); + node.argument = this.parseMaybeUnary(null, true, update); this.checkExpressionErrors(refDestructuringErrors, true); - if (update) { this.checkLVal(node.argument); } + if (update) { this.checkLValSimple(node.argument); } else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } + else if (node.operator === "delete" && isPrivateFieldAccess(node.argument)) + { this.raiseRecoverable(node.start, "Private fields can not be deleted"); } else { sawUnary = true; } expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); } else { @@ -2073,18 +2371,29 @@ node$1.operator = this.value; node$1.prefix = false; node$1.argument = expr; - this.checkLVal(expr); + this.checkLValSimple(expr); this.next(); expr = this.finishNode(node$1, "UpdateExpression"); } } - if (!sawUnary && this.eat(types.starstar)) - { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) } - else - { return expr } + if (!incDec && this.eat(types.starstar)) { + if (sawUnary) + { this.unexpected(this.lastTokStart); } + else + { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) } + } else { + return expr + } }; + function isPrivateFieldAccess(node) { + return ( + node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" || + node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) + ) + } + // Parse call, dot, and `[]`-subscript expressions. pp$3.parseExprSubscripts = function(refDestructuringErrors) { @@ -2096,28 +2405,55 @@ if (refDestructuringErrors && result.type === "MemberExpression") { if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } + if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; } } return result }; pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && - this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async"; + this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && + this.potentialArrowAt === base.start; + var optionalChained = false; + while (true) { - var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow); - if (element === base || element.type === "ArrowFunctionExpression") { return element } + var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained); + + if (element.optional) { optionalChained = true; } + if (element === base || element.type === "ArrowFunctionExpression") { + if (optionalChained) { + var chainNode = this.startNodeAt(startPos, startLoc); + chainNode.expression = element; + element = this.finishNode(chainNode, "ChainExpression"); + } + return element + } + base = element; } }; - pp$3.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow) { + pp$3.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained) { + var optionalSupported = this.options.ecmaVersion >= 11; + var optional = optionalSupported && this.eat(types.questionDot); + if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); } + var computed = this.eat(types.bracketL); - if (computed || this.eat(types.dot)) { + if (computed || (optional && this.type !== types.parenL && this.type !== types.backQuote) || this.eat(types.dot)) { var node = this.startNodeAt(startPos, startLoc); node.object = base; - node.property = computed ? this.parseExpression() : this.parseIdent(this.options.allowReserved !== "never"); + if (computed) { + node.property = this.parseExpression(); + this.expect(types.bracketR); + } else if (this.type === types.privateId && base.type !== "Super") { + node.property = this.parsePrivateIdent(); + } else { + node.property = this.parseIdent(this.options.allowReserved !== "never"); + } node.computed = !!computed; - if (computed) { this.expect(types.bracketR); } + if (optionalSupported) { + node.optional = optional; + } base = this.finishNode(node, "MemberExpression"); } else if (!noCalls && this.eat(types.parenL)) { var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; @@ -2125,7 +2461,7 @@ this.awaitPos = 0; this.awaitIdentPos = 0; var exprList = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); - if (maybeAsyncArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) { + if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types.arrow)) { this.checkPatternErrors(refDestructuringErrors, false); this.checkYieldAwaitInDefaultParams(); if (this.awaitIdentPos > 0) @@ -2142,8 +2478,14 @@ var node$1 = this.startNodeAt(startPos, startLoc); node$1.callee = base; node$1.arguments = exprList; + if (optionalSupported) { + node$1.optional = optional; + } base = this.finishNode(node$1, "CallExpression"); } else if (this.type === types.backQuote) { + if (optional || optionalChained) { + this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions"); + } var node$2 = this.startNodeAt(startPos, startLoc); node$2.tag = base; node$2.quasi = this.parseTemplate({isTagged: true}); @@ -2194,7 +2536,8 @@ if (canBeArrow && !this.canInsertSemicolon()) { if (this.eat(types.arrow)) { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) } - if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) { + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc && + (!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) { id = this.parseIdent(false); if (this.canInsertSemicolon() || !this.eat(types.arrow)) { this.unexpected(); } @@ -2266,10 +2609,18 @@ pp$3.parseExprImport = function() { var node = this.startNode(); - this.next(); // skip `import` + + // Consume `import` as an identifier for `import.meta`. + // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`. + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); } + var meta = this.parseIdent(true); + switch (this.type) { case types.parenL: return this.parseDynamicImport(node) + case types.dot: + node.meta = meta; + return this.parseImportMeta(node) default: this.unexpected(); } @@ -2294,11 +2645,27 @@ return this.finishNode(node, "ImportExpression") }; + pp$3.parseImportMeta = function(node) { + this.next(); // skip `.` + + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + + if (node.property.name !== "meta") + { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); } + if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere) + { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); } + + return this.finishNode(node, "MetaProperty") + }; + pp$3.parseLiteral = function(value) { var node = this.startNode(); node.value = value; node.raw = this.input.slice(this.start, this.end); - if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1); } + if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, ""); } this.next(); return this.finishNode(node, "Literal") }; @@ -2396,10 +2763,12 @@ node.meta = meta; var containsEsc = this.containsEsc; node.property = this.parseIdent(true); - if (node.property.name !== "target" || containsEsc) - { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); } - if (!this.inNonArrowFunction()) - { this.raiseRecoverable(node.start, "new.target can only be used in functions"); } + if (node.property.name !== "target") + { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); } + if (!this.inNonArrowFunction) + { this.raiseRecoverable(node.start, "'new.target' can only be used in functions"); } return this.finishNode(node, "MetaProperty") } var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types._import; @@ -2548,7 +2917,7 @@ } else if (!isPattern && !containsEsc && this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && - (this.type !== types.comma && this.type !== types.braceR)) { + (this.type !== types.comma && this.type !== types.braceR && this.type !== types.eq)) { if (isGenerator || isAsync) { this.unexpected(); } prop.kind = prop.key.name; this.parsePropertyName(prop); @@ -2571,13 +2940,13 @@ { this.awaitIdentPos = startPos; } prop.kind = "init"; if (isPattern) { - prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); } else if (this.type === types.eq && refDestructuringErrors) { if (refDestructuringErrors.shorthandAssign < 0) { refDestructuringErrors.shorthandAssign = this.start; } - prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); } else { - prop.value = prop.key; + prop.value = this.copyNode(prop.key); } prop.shorthand = true; } else { this.unexpected(); } @@ -2683,16 +3052,14 @@ // Add the params to varDeclaredNames to ensure that an error is thrown // if a let/const declaration in the function clashes with one of the params. this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)); - node.body = this.parseBlock(false); + // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' + if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); } + node.body = this.parseBlock(false, undefined, useStrict && !oldStrict); node.expression = false; this.adaptDirectivePrologue(node.body.body); this.labels = oldLabels; } this.exitScope(); - - // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' - if (this.strict && node.id) { this.checkLVal(node.id, BIND_OUTSIDE); } - this.strict = oldStrict; }; pp$3.isSimpleParamList = function(params) { @@ -2709,12 +3076,12 @@ // or "arguments" and duplicate parameters. pp$3.checkParams = function(node, allowDuplicates) { - var nameHash = {}; + var nameHash = Object.create(null); for (var i = 0, list = node.params; i < list.length; i += 1) { var param = list[i]; - this.checkLVal(param, BIND_VAR, allowDuplicates ? null : nameHash); + this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash); } }; @@ -2756,6 +3123,8 @@ { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); } if (this.inAsync && name === "await") { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); } + if (this.currentThisScope().inClassFieldInit && name === "arguments") + { this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); } if (this.keywords.test(name)) { this.raise(start, ("Unexpected keyword '" + name + "'")); } if (this.options.ecmaVersion < 6 && @@ -2800,9 +3169,29 @@ return node }; + pp$3.parsePrivateIdent = function() { + var node = this.startNode(); + if (this.type === types.privateId) { + node.name = this.value; + } else { + this.unexpected(); + } + this.next(); + this.finishNode(node, "PrivateIdentifier"); + + // For validating existence + if (this.privateNameStack.length === 0) { + this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class")); + } else { + this.privateNameStack[this.privateNameStack.length - 1].used.push(node); + } + + return node + }; + // Parses yield expression inside generator. - pp$3.parseYield = function(noIn) { + pp$3.parseYield = function(forInit) { if (!this.yieldPos) { this.yieldPos = this.start; } var node = this.startNode(); @@ -2812,7 +3201,7 @@ node.argument = null; } else { node.delegate = this.eat(types.star); - node.argument = this.parseMaybeAssign(noIn); + node.argument = this.parseMaybeAssign(forInit); } return this.finishNode(node, "YieldExpression") }; @@ -2822,7 +3211,7 @@ var node = this.startNode(); this.next(); - node.argument = this.parseMaybeUnary(null, false); + node.argument = this.parseMaybeUnary(null, true); return this.finishNode(node, "AwaitExpression") }; @@ -2860,6 +3249,8 @@ this.lexical = []; // A list of lexically-declared FunctionDeclaration names in the current lexical scope this.functions = []; + // A switch to disallow the identifier reference 'arguments' + this.inClassFieldInit = false; }; // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. @@ -2987,6 +3378,12 @@ return finishNodeAt.call(this, node, type, pos, loc) }; + pp$6.copyNode = function(node) { + var newNode = new Node(this, node.start, this.startLoc); + for (var prop in node) { newNode[prop] = node[prop]; } + return newNode + }; + // The algorithm used to determine whether a regexp can appear at a var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { @@ -3091,7 +3488,8 @@ }; types._function.updateContext = types._class.updateContext = function(prevType) { - if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && + if (prevType.beforeExpr && prevType !== types._else && + !(prevType === types.semi && this.curContext() !== types$1.p_stat) && !(prevType === types._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat)) { this.context.push(types$1.f_expr); } @@ -3137,10 +3535,12 @@ var ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS"; var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic"; var ecma11BinaryProperties = ecma10BinaryProperties; + var ecma12BinaryProperties = ecma11BinaryProperties + " EBase EComp EMod EPres ExtPict"; var unicodeBinaryProperties = { 9: ecma9BinaryProperties, 10: ecma10BinaryProperties, - 11: ecma11BinaryProperties + 11: ecma11BinaryProperties, + 12: ecma12BinaryProperties }; // #table-unicode-general-category-values @@ -3150,10 +3550,12 @@ var ecma9ScriptValues = "Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb"; var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd"; var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; + var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi"; var unicodeScriptValues = { 9: ecma9ScriptValues, 10: ecma10ScriptValues, - 11: ecma11ScriptValues + 11: ecma11ScriptValues, + 12: ecma12ScriptValues }; var data = {}; @@ -3174,13 +3576,14 @@ buildUnicodeData(9); buildUnicodeData(10); buildUnicodeData(11); + buildUnicodeData(12); var pp$8 = Parser.prototype; var RegExpValidationState = function RegExpValidationState(parser) { this.parser = parser; - this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : ""); - this.unicodeProperties = data[parser.options.ecmaVersion >= 11 ? 11 : parser.options.ecmaVersion]; + this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : ""); + this.unicodeProperties = data[parser.options.ecmaVersion >= 12 ? 12 : parser.options.ecmaVersion]; this.source = ""; this.flags = ""; this.start = 0; @@ -3211,49 +3614,61 @@ // If u flag is given, this returns the code point at the index (it combines a surrogate pair). // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). - RegExpValidationState.prototype.at = function at (i) { + RegExpValidationState.prototype.at = function at (i, forceU) { + if ( forceU === void 0 ) forceU = false; + var s = this.source; var l = s.length; if (i >= l) { return -1 } var c = s.charCodeAt(i); - if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { return c } var next = s.charCodeAt(i + 1); return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c }; - RegExpValidationState.prototype.nextIndex = function nextIndex (i) { + RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) { + if ( forceU === void 0 ) forceU = false; + var s = this.source; var l = s.length; if (i >= l) { return l } var c = s.charCodeAt(i), next; - if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) { return i + 1 } return i + 2 }; - RegExpValidationState.prototype.current = function current () { - return this.at(this.pos) + RegExpValidationState.prototype.current = function current (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.pos, forceU) }; - RegExpValidationState.prototype.lookahead = function lookahead () { - return this.at(this.nextIndex(this.pos)) + RegExpValidationState.prototype.lookahead = function lookahead (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.nextIndex(this.pos, forceU), forceU) }; - RegExpValidationState.prototype.advance = function advance () { - this.pos = this.nextIndex(this.pos); + RegExpValidationState.prototype.advance = function advance (forceU) { + if ( forceU === void 0 ) forceU = false; + + this.pos = this.nextIndex(this.pos, forceU); }; - RegExpValidationState.prototype.eat = function eat (ch) { - if (this.current() === ch) { - this.advance(); + RegExpValidationState.prototype.eat = function eat (ch, forceU) { + if ( forceU === void 0 ) forceU = false; + + if (this.current(forceU) === ch) { + this.advance(forceU); return true } return false @@ -3592,9 +4007,9 @@ return false }; - // GroupSpecifier[U] :: + // GroupSpecifier :: // [empty] - // `?` GroupName[?U] + // `?` GroupName pp$8.regexp_groupSpecifier = function(state) { if (state.eat(0x3F /* ? */)) { if (this.regexp_eatGroupName(state)) { @@ -3608,8 +4023,8 @@ } }; - // GroupName[U] :: - // `<` RegExpIdentifierName[?U] `>` + // GroupName :: + // `<` RegExpIdentifierName `>` // Note: this updates `state.lastStringValue` property with the eaten name. pp$8.regexp_eatGroupName = function(state) { state.lastStringValue = ""; @@ -3622,9 +4037,9 @@ return false }; - // RegExpIdentifierName[U] :: - // RegExpIdentifierStart[?U] - // RegExpIdentifierName[?U] RegExpIdentifierPart[?U] + // RegExpIdentifierName :: + // RegExpIdentifierStart + // RegExpIdentifierName RegExpIdentifierPart // Note: this updates `state.lastStringValue` property with the eaten name. pp$8.regexp_eatRegExpIdentifierName = function(state) { state.lastStringValue = ""; @@ -3638,17 +4053,18 @@ return false }; - // RegExpIdentifierStart[U] :: + // RegExpIdentifierStart :: // UnicodeIDStart // `$` // `_` - // `\` RegExpUnicodeEscapeSequence[?U] + // `\` RegExpUnicodeEscapeSequence[+U] pp$8.regexp_eatRegExpIdentifierStart = function(state) { var start = state.pos; - var ch = state.current(); - state.advance(); + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); - if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { ch = state.lastIntValue; } if (isRegExpIdentifierStart(ch)) { @@ -3663,19 +4079,20 @@ return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ } - // RegExpIdentifierPart[U] :: + // RegExpIdentifierPart :: // UnicodeIDContinue // `$` // `_` - // `\` RegExpUnicodeEscapeSequence[?U] + // `\` RegExpUnicodeEscapeSequence[+U] // // pp$8.regexp_eatRegExpIdentifierPart = function(state) { var start = state.pos; - var ch = state.current(); - state.advance(); + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); - if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { ch = state.lastIntValue; } if (isRegExpIdentifierPart(ch)) { @@ -3745,7 +4162,7 @@ this.regexp_eatCControlLetter(state) || this.regexp_eatZero(state) || this.regexp_eatHexEscapeSequence(state) || - this.regexp_eatRegExpUnicodeEscapeSequence(state) || + this.regexp_eatRegExpUnicodeEscapeSequence(state, false) || (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || this.regexp_eatIdentityEscape(state) ) @@ -3818,13 +4235,16 @@ } // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence - pp$8.regexp_eatRegExpUnicodeEscapeSequence = function(state) { + pp$8.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) { + if ( forceU === void 0 ) forceU = false; + var start = state.pos; + var switchU = forceU || state.switchU; if (state.eat(0x75 /* u */)) { if (this.regexp_eatFixedHexDigits(state, 4)) { var lead = state.lastIntValue; - if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) { + if (switchU && lead >= 0xD800 && lead <= 0xDBFF) { var leadSurrogateEnd = state.pos; if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) { var trail = state.lastIntValue; @@ -3839,7 +4259,7 @@ return true } if ( - state.switchU && + switchU && state.eat(0x7B /* { */) && this.regexp_eatHexDigits(state) && state.eat(0x7D /* } */) && @@ -3847,7 +4267,7 @@ ) { return true } - if (state.switchU) { + if (switchU) { state.raise("Invalid unicode escape"); } state.pos = start; @@ -4307,9 +4727,9 @@ pp$9.fullCharCodeAtPos = function() { var code = this.input.charCodeAt(this.pos); - if (code <= 0xd7ff || code >= 0xe000) { return code } + if (code <= 0xd7ff || code >= 0xdc00) { return code } var next = this.input.charCodeAt(this.pos + 1); - return (code << 10) + next - 0x35fdc00 + return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00 }; pp$9.skipBlockComment = function() { @@ -4447,7 +4867,13 @@ pp$9.readToken_pipe_amp = function(code) { // '|&' var next = this.input.charCodeAt(this.pos + 1); - if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) } + if (next === code) { + if (this.options.ecmaVersion >= 12) { + var next2 = this.input.charCodeAt(this.pos + 2); + if (next2 === 61) { return this.finishOp(types.assign, 3) } + } + return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) + } if (next === 61) { return this.finishOp(types.assign, 2) } return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1) }; @@ -4503,6 +4929,39 @@ return this.finishOp(code === 61 ? types.eq : types.prefix, 1) }; + pp$9.readToken_question = function() { // '?' + var ecmaVersion = this.options.ecmaVersion; + if (ecmaVersion >= 11) { + var next = this.input.charCodeAt(this.pos + 1); + if (next === 46) { + var next2 = this.input.charCodeAt(this.pos + 2); + if (next2 < 48 || next2 > 57) { return this.finishOp(types.questionDot, 2) } + } + if (next === 63) { + if (ecmaVersion >= 12) { + var next2$1 = this.input.charCodeAt(this.pos + 2); + if (next2$1 === 61) { return this.finishOp(types.assign, 3) } + } + return this.finishOp(types.coalesce, 2) + } + } + return this.finishOp(types.question, 1) + }; + + pp$9.readToken_numberSign = function() { // '#' + var ecmaVersion = this.options.ecmaVersion; + var code = 35; // '#' + if (ecmaVersion >= 13) { + ++this.pos; + code = this.fullCharCodeAtPos(); + if (isIdentifierStart(code, true) || code === 92 /* '\' */) { + return this.finishToken(types.privateId, this.readWord1()) + } + } + + this.raise(this.pos, "Unexpected character '" + codePointToString$1(code) + "'"); + }; + pp$9.getTokenFromCode = function(code) { switch (code) { // The interpretation of a dot depends on whether it is followed @@ -4520,7 +4979,6 @@ case 123: ++this.pos; return this.finishToken(types.braceL) case 125: ++this.pos; return this.finishToken(types.braceR) case 58: ++this.pos; return this.finishToken(types.colon) - case 63: ++this.pos; return this.finishToken(types.question) case 96: // '`' if (this.options.ecmaVersion < 6) { break } @@ -4570,8 +5028,14 @@ case 61: case 33: // '=!' return this.readToken_eq_excl(code) + case 63: // '?' + return this.readToken_question() + case 126: // '~' return this.finishOp(types.prefix, 1) + + case 35: // '#' + return this.readToken_numberSign() } this.raise(this.pos, "Unexpected character '" + codePointToString$1(code) + "'"); @@ -4625,30 +5089,67 @@ // were read, the integer value otherwise. When `len` is given, this // will return `null` unless the integer has exactly `len` digits. - pp$9.readInt = function(radix, len) { - var start = this.pos, total = 0; - for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) { + pp$9.readInt = function(radix, len, maybeLegacyOctalNumericLiteral) { + // `len` is used for character escape sequences. In that case, disallow separators. + var allowSeparators = this.options.ecmaVersion >= 12 && len === undefined; + + // `maybeLegacyOctalNumericLiteral` is true if it doesn't have prefix (0x,0o,0b) + // and isn't fraction part nor exponent part. In that case, if the first digit + // is zero then disallow separators. + var isLegacyOctalNumericLiteral = maybeLegacyOctalNumericLiteral && this.input.charCodeAt(this.pos) === 48; + + var start = this.pos, total = 0, lastCode = 0; + for (var i = 0, e = len == null ? Infinity : len; i < e; ++i, ++this.pos) { var code = this.input.charCodeAt(this.pos), val = (void 0); + + if (allowSeparators && code === 95) { + if (isLegacyOctalNumericLiteral) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed in legacy octal numeric literals"); } + if (lastCode === 95) { this.raiseRecoverable(this.pos, "Numeric separator must be exactly one underscore"); } + if (i === 0) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed at the first of digits"); } + lastCode = code; + continue + } + if (code >= 97) { val = code - 97 + 10; } // a else if (code >= 65) { val = code - 65 + 10; } // A else if (code >= 48 && code <= 57) { val = code - 48; } // 0-9 else { val = Infinity; } if (val >= radix) { break } - ++this.pos; + lastCode = code; total = total * radix + val; } + + if (allowSeparators && lastCode === 95) { this.raiseRecoverable(this.pos - 1, "Numeric separator is not allowed at the last of digits"); } if (this.pos === start || len != null && this.pos - start !== len) { return null } return total }; + function stringToNumber(str, isLegacyOctalNumericLiteral) { + if (isLegacyOctalNumericLiteral) { + return parseInt(str, 8) + } + + // `parseFloat(value)` stops parsing at the first numeric separator then returns a wrong value. + return parseFloat(str.replace(/_/g, "")) + } + + function stringToBigInt(str) { + if (typeof BigInt !== "function") { + return null + } + + // `BigInt(value)` throws syntax error if the string contains numeric separators. + return BigInt(str.replace(/_/g, "")) + } + pp$9.readRadixNumber = function(radix) { var start = this.pos; this.pos += 2; // 0x var val = this.readInt(radix); if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); } if (this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110) { - val = typeof BigInt !== "undefined" ? BigInt(this.input.slice(start, this.pos)) : null; + val = stringToBigInt(this.input.slice(start, this.pos)); ++this.pos; } else if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); } return this.finishToken(types.num, val) @@ -4658,13 +5159,12 @@ pp$9.readNumber = function(startsWithDot) { var start = this.pos; - if (!startsWithDot && this.readInt(10) === null) { this.raise(start, "Invalid number"); } + if (!startsWithDot && this.readInt(10, undefined, true) === null) { this.raise(start, "Invalid number"); } var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48; if (octal && this.strict) { this.raise(start, "Invalid number"); } var next = this.input.charCodeAt(this.pos); if (!octal && !startsWithDot && this.options.ecmaVersion >= 11 && next === 110) { - var str$1 = this.input.slice(start, this.pos); - var val$1 = typeof BigInt !== "undefined" ? BigInt(str$1) : null; + var val$1 = stringToBigInt(this.input.slice(start, this.pos)); ++this.pos; if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); } return this.finishToken(types.num, val$1) @@ -4682,8 +5182,7 @@ } if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); } - var str = this.input.slice(start, this.pos); - var val = octal ? parseInt(str, 8) : parseFloat(str); + var val = stringToNumber(this.input.slice(start, this.pos), octal); return this.finishToken(types.num, val) }; @@ -4846,6 +5345,12 @@ return "" case 56: case 57: + if (this.strict) { + this.invalidStringToken( + this.pos - 1, + "Invalid escape sequence" + ); + } if (inTemplate) { var codePos = this.pos - 1; @@ -4942,7 +5447,7 @@ // Acorn is a tiny, fast JavaScript parser written in JavaScript. - var version = "7.1.0"; + var version = "8.4.1"; Parser.acorn = { Parser: Parser, @@ -5017,4 +5522,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/deps/acorn/acorn/dist/acorn.mjs b/deps/acorn/acorn/dist/acorn.mjs new file mode 100644 index 0000000000000000000000000000000000000000..30833d4fdf9f75e238f2e037439163faaffaa459 --- /dev/null +++ b/deps/acorn/acorn/dist/acorn.mjs @@ -0,0 +1,5494 @@ +// Reserved word lists for various dialects of the language + +var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" +}; + +// And the keywords + +var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"; + +var keywords = { + 5: ecma5AndLessKeywords, + "5module": ecma5AndLessKeywords + " export import", + 6: ecma5AndLessKeywords + " const class extends export import super" +}; + +var keywordRelationalOperator = /^in(stanceof)?$/; + +// ## Character categories + +// Big ugly regular expressions that match characters in the +// whitespace, identifier, and identifier-start categories. These +// are only applied when a character is found to actually have a +// code point above 128. +// Generated by `bin/generate-identifier-regex.js`. +var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08c7\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; +var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf\u1ac0\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; + +var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); +var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + +nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; + +// These are a run-length and offset encoded representation of the +// >0xffff code points that are a valid part of identifiers. The +// offset starts at 0x10000, and each pair of numbers represents an +// offset to the next range, and then a size of the range. They were +// generated by bin/generate-identifier-regex.js + +// eslint-disable-next-line comma-spacing +var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,349,41,7,1,79,28,11,0,9,21,107,20,28,22,13,52,76,44,33,24,27,35,30,0,3,0,9,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,230,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,190,0,80,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,74,6,0,67,12,65,1,2,0,29,6135,9,1237,43,8,8952,286,50,2,18,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,2357,44,11,6,17,0,370,43,1301,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42717,35,4148,12,221,3,5761,15,7472,3104,541,1507,4938]; + +// eslint-disable-next-line comma-spacing +var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,370,1,154,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,2,11,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1014,0,2,54,8,3,82,0,12,1,19628,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,262,6,10,9,419,13,1495,6,110,6,6,9,4759,9,787719,239]; + +// This has a complexity linear to the value of the code. The +// assumption is that looking up astral identifier characters is +// rare. +function isInAstralSet(code, set) { + var pos = 0x10000; + for (var i = 0; i < set.length; i += 2) { + pos += set[i]; + if (pos > code) { return false } + pos += set[i + 1]; + if (pos >= code) { return true } + } +} + +// Test whether a given character code starts an identifier. + +function isIdentifierStart(code, astral) { + if (code < 65) { return code === 36 } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) +} + +// Test whether a given character is part of an identifier. + +function isIdentifierChar(code, astral) { + if (code < 48) { return code === 36 } + if (code < 58) { return true } + if (code < 65) { return false } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) +} + +// ## Token types + +// The assignment of fine-grained, information-carrying type objects +// allows the tokenizer to store the information it has about a +// token in a way that is very cheap for the parser to look up. + +// All token type variables start with an underscore, to make them +// easy to recognize. + +// The `beforeExpr` property is used to disambiguate between regular +// expressions and divisions. It is set on all token types that can +// be followed by an expression (thus, a slash after them would be a +// regular expression). +// +// The `startsExpr` property is used to check if the token ends a +// `yield` expression. It is set on all token types that either can +// directly start an expression (like a quotation mark) or can +// continue an expression (like the body of a string). +// +// `isLoop` marks a keyword as starting a loop, which is important +// to know when parsing a label, in order to allow or disallow +// continue jumps to that label. + +var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; + + this.label = label; + this.keyword = conf.keyword; + this.beforeExpr = !!conf.beforeExpr; + this.startsExpr = !!conf.startsExpr; + this.isLoop = !!conf.isLoop; + this.isAssign = !!conf.isAssign; + this.prefix = !!conf.prefix; + this.postfix = !!conf.postfix; + this.binop = conf.binop || null; + this.updateContext = null; +}; + +function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) +} +var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true}; + +// Map keyword names to token types. + +var keywords$1 = {}; + +// Succinct definitions of keyword token types +function kw(name, options) { + if ( options === void 0 ) options = {}; + + options.keyword = name; + return keywords$1[name] = new TokenType(name, options) +} + +var types = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + privateId: new TokenType("privateId", startsExpr), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + questionDot: new TokenType("?."), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + invalidTemplate: new TokenType("invalidTemplate"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=/===/!==", 6), + relational: binop("/<=/>=", 7), + bitShift: binop("<>/>>>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + coalesce: binop("??", 1), + + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class", startsExpr), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import", startsExpr), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) +}; + +// Matches a whole line break (where CRLF is considered a single +// line break). Used to count lines. + +var lineBreak = /\r\n?|\n|\u2028|\u2029/; +var lineBreakG = new RegExp(lineBreak.source, "g"); + +function isNewLine(code, ecma2019String) { + return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029)) +} + +var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/; + +var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; + +var ref = Object.prototype; +var hasOwnProperty = ref.hasOwnProperty; +var toString = ref.toString; + +// Checks if an object has a property. + +function has(obj, propName) { + return hasOwnProperty.call(obj, propName) +} + +var isArray = Array.isArray || (function (obj) { return ( + toString.call(obj) === "[object Array]" +); }); + +function wordsRegexp(words) { + return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$") +} + +// These are used when `options.locations` is on, for the +// `startLoc` and `endLoc` properties. + +var Position = function Position(line, col) { + this.line = line; + this.column = col; +}; + +Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) +}; + +var SourceLocation = function SourceLocation(p, start, end) { + this.start = start; + this.end = end; + if (p.sourceFile !== null) { this.source = p.sourceFile; } +}; + +// The `getLineInfo` function is mostly useful when the +// `locations` option is off (for performance reasons) and you +// want to find the line/column position for a given character +// offset. `input` should be the code string that the offset refers +// into. + +function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + lineBreakG.lastIndex = cur; + var match = lineBreakG.exec(input); + if (match && match.index < offset) { + ++line; + cur = match.index + match[0].length; + } else { + return new Position(line, offset - cur) + } + } +} + +// A second argument must be given to configure the parser process. +// These options are recognized (only `ecmaVersion` is required): + +var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must be + // either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 + // (2019), 11 (2020), 12 (2021), 13 (2022), or `"latest"` (the + // latest version the library supports). This influences support + // for strict mode, the set of reserved words, and support for + // new syntax features. + ecmaVersion: null, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"` or `"module"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // the position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program, and an import.meta expression + // in a script isn't considered an error. + allowImportExportEverywhere: false, + // By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022. + // When enabled, await identifiers are allowed to appear at the top-level scope, + // but they are still not allowed in non-async functions. + allowAwaitOutsideFunction: null, + // When enabled, super identifiers are not constrained to + // appearing in methods and do not raise an error when they appear elsewhere. + allowSuperOutsideMethod: null, + // When enabled, hashbang directive in the beginning of file + // is allowed and treated as a line comment. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false +}; + +// Interpret and default an options object + +var warnedAboutEcmaVersion = false; + +function getOptions(opts) { + var options = {}; + + for (var opt in defaultOptions) + { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; } + + if (options.ecmaVersion === "latest") { + options.ecmaVersion = 1e8; + } else if (options.ecmaVersion == null) { + if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) { + warnedAboutEcmaVersion = true; + console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future."); + } + options.ecmaVersion = 11; + } else if (options.ecmaVersion >= 2015) { + options.ecmaVersion -= 2009; + } + + if (options.allowReserved == null) + { options.allowReserved = options.ecmaVersion < 5; } + + if (isArray(options.onToken)) { + var tokens = options.onToken; + options.onToken = function (token) { return tokens.push(token); }; + } + if (isArray(options.onComment)) + { options.onComment = pushComment(options, options.onComment); } + + return options +} + +function pushComment(options, array) { + return function(block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? "Block" : "Line", + value: text, + start: start, + end: end + }; + if (options.locations) + { comment.loc = new SourceLocation(this, startLoc, endLoc); } + if (options.ranges) + { comment.range = [start, end]; } + array.push(comment); + } +} + +// Each scope gets a bitset that may contain these flags +var + SCOPE_TOP = 1, + SCOPE_FUNCTION = 2, + SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION, + SCOPE_ASYNC = 4, + SCOPE_GENERATOR = 8, + SCOPE_ARROW = 16, + SCOPE_SIMPLE_CATCH = 32, + SCOPE_SUPER = 64, + SCOPE_DIRECT_SUPER = 128; + +function functionFlags(async, generator) { + return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0) +} + +// Used in checkLVal* and declareName to determine the type of a binding +var + BIND_NONE = 0, // Not a binding + BIND_VAR = 1, // Var-style binding + BIND_LEXICAL = 2, // Let- or const-style binding + BIND_FUNCTION = 3, // Function declaration + BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding + BIND_OUTSIDE = 5; // Special case for function names as bound inside the function + +var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options); + this.sourceFile = options.sourceFile; + this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]); + var reserved = ""; + if (options.allowReserved !== true) { + reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3]; + if (options.sourceType === "module") { reserved += " await"; } + } + this.reservedWords = wordsRegexp(reserved); + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; + this.reservedWordsStrict = wordsRegexp(reservedStrict); + this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind); + this.input = String(input); + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false; + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos; + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; + } else { + this.pos = this.lineStart = 0; + this.curLine = 1; + } + + // Properties of the current token: + // Its type + this.type = types.eof; + // For tokens that include more information than their type, the value + this.value = null; + // Its start and end offset + this.start = this.end = this.pos; + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition(); + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null; + this.lastTokStart = this.lastTokEnd = this.pos; + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext(); + this.exprAllowed = true; + + // Figure out if it's a module code. + this.inModule = options.sourceType === "module"; + this.strict = this.inModule || this.strictDirective(this.pos); + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1; + this.potentialArrowInForAwait = false; + + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = this.awaitIdentPos = 0; + // Labels in scope. + this.labels = []; + // Thus-far undefined exports. + this.undefinedExports = Object.create(null); + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") + { this.skipLineComment(2); } + + // Scope tracking for duplicate variable names (see scope.js) + this.scopeStack = []; + this.enterScope(SCOPE_TOP); + + // For RegExp validation + this.regexpState = null; + + // The stack of private names. + // Each element has two properties: 'declared' and 'used'. + // When it exited from the outermost class definition, all used private names must be declared. + this.privateNameStack = []; +}; + +var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },inNonArrowFunction: { configurable: true } }; + +Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode(); + this.nextToken(); + return this.parseTopLevel(node) +}; + +prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 }; +prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 && !this.currentVarScope().inClassFieldInit }; +prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 && !this.currentVarScope().inClassFieldInit }; +prototypeAccessors.canAwait.get = function () { + for (var i = this.scopeStack.length - 1; i >= 0; i--) { + var scope = this.scopeStack[i]; + if (scope.inClassFieldInit) { return false } + if (scope.flags & SCOPE_FUNCTION) { return (scope.flags & SCOPE_ASYNC) > 0 } + } + return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction +}; +prototypeAccessors.allowSuper.get = function () { + var ref = this.currentThisScope(); + var flags = ref.flags; + var inClassFieldInit = ref.inClassFieldInit; + return (flags & SCOPE_SUPER) > 0 || inClassFieldInit || this.options.allowSuperOutsideMethod +}; +prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 }; +prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) }; +prototypeAccessors.inNonArrowFunction.get = function () { + var ref = this.currentThisScope(); + var flags = ref.flags; + var inClassFieldInit = ref.inClassFieldInit; + return (flags & SCOPE_FUNCTION) > 0 || inClassFieldInit +}; + +Parser.extend = function extend () { + var plugins = [], len = arguments.length; + while ( len-- ) plugins[ len ] = arguments[ len ]; + + var cls = this; + for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } + return cls +}; + +Parser.parse = function parse (input, options) { + return new this(options, input).parse() +}; + +Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) { + var parser = new this(options, input, pos); + parser.nextToken(); + return parser.parseExpression() +}; + +Parser.tokenizer = function tokenizer (input, options) { + return new this(options, input) +}; + +Object.defineProperties( Parser.prototype, prototypeAccessors ); + +var pp = Parser.prototype; + +// ## Parser utilities + +var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/; +pp.strictDirective = function(start) { + for (;;) { + // Try to find string literal. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + var match = literal.exec(this.input.slice(start)); + if (!match) { return false } + if ((match[1] || match[2]) === "use strict") { + skipWhiteSpace.lastIndex = start + match[0].length; + var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length; + var next = this.input.charAt(end); + return next === ";" || next === "}" || + (lineBreak.test(spaceAfter[0]) && + !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "=")) + } + start += match[0].length; + + // Skip semicolon, if any. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + if (this.input[start] === ";") + { start++; } + } +}; + +// Predicate that tests whether the next token is of the given +// type, and if yes, consumes it as a side effect. + +pp.eat = function(type) { + if (this.type === type) { + this.next(); + return true + } else { + return false + } +}; + +// Tests whether parsed token is a contextual keyword. + +pp.isContextual = function(name) { + return this.type === types.name && this.value === name && !this.containsEsc +}; + +// Consumes contextual keyword if possible. + +pp.eatContextual = function(name) { + if (!this.isContextual(name)) { return false } + this.next(); + return true +}; + +// Asserts that following token is given contextual keyword. + +pp.expectContextual = function(name) { + if (!this.eatContextual(name)) { this.unexpected(); } +}; + +// Test whether a semicolon can be inserted at the current position. + +pp.canInsertSemicolon = function() { + return this.type === types.eof || + this.type === types.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +}; + +pp.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } + return true + } +}; + +// Consume a semicolon, or, failing that, see if we are allowed to +// pretend that there is a semicolon at this position. + +pp.semicolon = function() { + if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); } +}; + +pp.afterTrailingComma = function(tokType, notNext) { + if (this.type === tokType) { + if (this.options.onTrailingComma) + { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } + if (!notNext) + { this.next(); } + return true + } +}; + +// Expect a token of a given type. If found, consume it, otherwise, +// raise an unexpected token error. + +pp.expect = function(type) { + this.eat(type) || this.unexpected(); +}; + +// Raise an unexpected token error. + +pp.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token"); +}; + +function DestructuringErrors() { + this.shorthandAssign = + this.trailingComma = + this.parenthesizedAssign = + this.parenthesizedBind = + this.doubleProto = + -1; +} + +pp.checkPatternErrors = function(refDestructuringErrors, isAssign) { + if (!refDestructuringErrors) { return } + if (refDestructuringErrors.trailingComma > -1) + { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } + var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; + if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); } +}; + +pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + if (!refDestructuringErrors) { return false } + var shorthandAssign = refDestructuringErrors.shorthandAssign; + var doubleProto = refDestructuringErrors.doubleProto; + if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } + if (shorthandAssign >= 0) + { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } + if (doubleProto >= 0) + { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } +}; + +pp.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } + if (this.awaitPos) + { this.raise(this.awaitPos, "Await expression cannot be a default value"); } +}; + +pp.isSimpleAssignTarget = function(expr) { + if (expr.type === "ParenthesizedExpression") + { return this.isSimpleAssignTarget(expr.expression) } + return expr.type === "Identifier" || expr.type === "MemberExpression" +}; + +var pp$1 = Parser.prototype; + +// ### Statement parsing + +// Parse a program. Initializes the parser, reads any number of +// statements, and wraps them in a Program node. Optionally takes a +// `program` argument. If present, the statements will be appended +// to its body instead of creating a new node. + +pp$1.parseTopLevel = function(node) { + var exports = Object.create(null); + if (!node.body) { node.body = []; } + while (this.type !== types.eof) { + var stmt = this.parseStatement(null, true, exports); + node.body.push(stmt); + } + if (this.inModule) + { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1) + { + var name = list[i]; + + this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined")); + } } + this.adaptDirectivePrologue(node.body); + this.next(); + node.sourceType = this.options.sourceType; + return this.finishNode(node, "Program") +}; + +var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; + +pp$1.isLet = function(context) { + if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + // For ambiguous cases, determine if a LexicalDeclaration (or only a + // Statement) is allowed here. If context is not empty then only a Statement + // is allowed. However, `let [` is an explicit negative lookahead for + // ExpressionStatement, so special-case it first. + if (nextCh === 91 || nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '[', '/', astral + if (context) { return false } + + if (nextCh === 123) { return true } // '{' + if (isIdentifierStart(nextCh, true)) { + var pos = next + 1; + while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; } + if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } + var ident = this.input.slice(next, pos); + if (!keywordRelationalOperator.test(ident)) { return true } + } + return false +}; + +// check 'async [no LineTerminator here] function' +// - 'async /*foo*/ function' is OK. +// - 'async /*\n*/ function' is invalid. +pp$1.isAsyncFunction = function() { + if (this.options.ecmaVersion < 8 || !this.isContextual("async")) + { return false } + + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, after; + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 === this.input.length || + !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00)) +}; + +// Parse a single statement. +// +// If expecting a statement and finding a slash operator, parse a +// regular expression literal. This is to handle cases like +// `if (foo) /blah/.exec(foo)`, where looking at the previous token +// does not help. + +pp$1.parseStatement = function(context, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind; + + if (this.isLet(context)) { + starttype = types._var; + kind = "let"; + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case types._debugger: return this.parseDebuggerStatement(node) + case types._do: return this.parseDoStatement(node) + case types._for: return this.parseForStatement(node) + case types._function: + // Function as sole body of either an if statement or a labeled statement + // works, but not when it is part of a labeled statement that is the sole + // body of an if statement. + if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); } + return this.parseFunctionStatement(node, false, !context) + case types._class: + if (context) { this.unexpected(); } + return this.parseClass(node, true) + case types._if: return this.parseIfStatement(node) + case types._return: return this.parseReturnStatement(node) + case types._switch: return this.parseSwitchStatement(node) + case types._throw: return this.parseThrowStatement(node) + case types._try: return this.parseTryStatement(node) + case types._const: case types._var: + kind = kind || this.value; + if (context && kind !== "var") { this.unexpected(); } + return this.parseVarStatement(node, kind) + case types._while: return this.parseWhileStatement(node) + case types._with: return this.parseWithStatement(node) + case types.braceL: return this.parseBlock(true, node) + case types.semi: return this.parseEmptyStatement(node) + case types._export: + case types._import: + if (this.options.ecmaVersion > 10 && starttype === types._import) { + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + if (nextCh === 40 || nextCh === 46) // '(' or '.' + { return this.parseExpressionStatement(node, this.parseExpression()) } + } + + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } + if (!this.inModule) + { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } + } + return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction()) { + if (context) { this.unexpected(); } + this.next(); + return this.parseFunctionStatement(node, true, !context) + } + + var maybeName = this.value, expr = this.parseExpression(); + if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) + { return this.parseLabeledStatement(node, maybeName, expr, context) } + else { return this.parseExpressionStatement(node, expr) } + } +}; + +pp$1.parseBreakContinueStatement = function(node, keyword) { + var isBreak = keyword === "break"; + this.next(); + if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; } + else if (this.type !== types.name) { this.unexpected(); } + else { + node.label = this.parseIdent(); + this.semicolon(); + } + + // Verify that there is an actual destination to break or + // continue to. + var i = 0; + for (; i < this.labels.length; ++i) { + var lab = this.labels[i]; + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } + if (node.label && isBreak) { break } + } + } + if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") +}; + +pp$1.parseDebuggerStatement = function(node) { + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement") +}; + +pp$1.parseDoStatement = function(node) { + this.next(); + this.labels.push(loopLabel); + node.body = this.parseStatement("do"); + this.labels.pop(); + this.expect(types._while); + node.test = this.parseParenExpression(); + if (this.options.ecmaVersion >= 6) + { this.eat(types.semi); } + else + { this.semicolon(); } + return this.finishNode(node, "DoWhileStatement") +}; + +// Disambiguating between a `for` and a `for`/`in` or `for`/`of` +// loop is non-trivial. Basically, we have to parse the init `var` +// statement or expression, disallowing the `in` operator (see +// the second parameter to `parseExpression`), and then check +// whether the next token is `in` or `of`. When there is no init +// part (semicolon immediately after the opening parenthesis), it +// is a regular `for` loop. + +pp$1.parseForStatement = function(node) { + this.next(); + var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1; + this.labels.push(loopLabel); + this.enterScope(0); + this.expect(types.parenL); + if (this.type === types.semi) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, null) + } + var isLet = this.isLet(); + if (this.type === types._var || this.type === types._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value; + this.next(); + this.parseVar(init$1, true, kind); + this.finishNode(init$1, "VariableDeclaration"); + if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + return this.parseForIn(node, init$1) + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init$1) + } + var refDestructuringErrors = new DestructuringErrors; + var init = this.parseExpression(awaitAt > -1 ? "await" : true, refDestructuringErrors); + if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + this.toAssignable(init, false, refDestructuringErrors); + this.checkLValPattern(init); + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true); + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) +}; + +pp$1.parseFunctionStatement = function(node, isAsync, declarationPosition) { + this.next(); + return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) +}; + +pp$1.parseIfStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement("if"); + node.alternate = this.eat(types._else) ? this.parseStatement("if") : null; + return this.finishNode(node, "IfStatement") +}; + +pp$1.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + { this.raise(this.start, "'return' outside of function"); } + this.next(); + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; } + else { node.argument = this.parseExpression(); this.semicolon(); } + return this.finishNode(node, "ReturnStatement") +}; + +pp$1.parseSwitchStatement = function(node) { + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.expect(types.braceL); + this.labels.push(switchLabel); + this.enterScope(0); + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + var cur; + for (var sawDefault = false; this.type !== types.braceR;) { + if (this.type === types._case || this.type === types._default) { + var isCase = this.type === types._case; + if (cur) { this.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + if (isCase) { + cur.test = this.parseExpression(); + } else { + if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); } + sawDefault = true; + cur.test = null; + } + this.expect(types.colon); + } else { + if (!cur) { this.unexpected(); } + cur.consequent.push(this.parseStatement(null)); + } + } + this.exitScope(); + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.next(); // Closing brace + this.labels.pop(); + return this.finishNode(node, "SwitchStatement") +}; + +pp$1.parseThrowStatement = function(node) { + this.next(); + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + { this.raise(this.lastTokEnd, "Illegal newline after throw"); } + node.argument = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ThrowStatement") +}; + +// Reused empty array added for node fields that are always empty. + +var empty = []; + +pp$1.parseTryStatement = function(node) { + this.next(); + node.block = this.parseBlock(); + node.handler = null; + if (this.type === types._catch) { + var clause = this.startNode(); + this.next(); + if (this.eat(types.parenL)) { + clause.param = this.parseBindingAtom(); + var simple = clause.param.type === "Identifier"; + this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0); + this.checkLValPattern(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); + this.expect(types.parenR); + } else { + if (this.options.ecmaVersion < 10) { this.unexpected(); } + clause.param = null; + this.enterScope(0); + } + clause.body = this.parseBlock(false); + this.exitScope(); + node.handler = this.finishNode(clause, "CatchClause"); + } + node.finalizer = this.eat(types._finally) ? this.parseBlock() : null; + if (!node.handler && !node.finalizer) + { this.raise(node.start, "Missing catch or finally clause"); } + return this.finishNode(node, "TryStatement") +}; + +pp$1.parseVarStatement = function(node, kind) { + this.next(); + this.parseVar(node, false, kind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") +}; + +pp$1.parseWhileStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + this.labels.push(loopLabel); + node.body = this.parseStatement("while"); + this.labels.pop(); + return this.finishNode(node, "WhileStatement") +}; + +pp$1.parseWithStatement = function(node) { + if (this.strict) { this.raise(this.start, "'with' in strict mode"); } + this.next(); + node.object = this.parseParenExpression(); + node.body = this.parseStatement("with"); + return this.finishNode(node, "WithStatement") +}; + +pp$1.parseEmptyStatement = function(node) { + this.next(); + return this.finishNode(node, "EmptyStatement") +}; + +pp$1.parseLabeledStatement = function(node, maybeName, expr, context) { + for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1) + { + var label = list[i$1]; + + if (label.name === maybeName) + { this.raise(expr.start, "Label '" + maybeName + "' is already declared"); + } } + var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null; + for (var i = this.labels.length - 1; i >= 0; i--) { + var label$1 = this.labels[i]; + if (label$1.statementStart === node.start) { + // Update information about previous labels on this node + label$1.statementStart = this.start; + label$1.kind = kind; + } else { break } + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); + node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); + this.labels.pop(); + node.label = expr; + return this.finishNode(node, "LabeledStatement") +}; + +pp$1.parseExpressionStatement = function(node, expr) { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") +}; + +// Parse a semicolon-enclosed block of statements, handling `"use +// strict"` declarations when `allowStrict` is true (used for +// function bodies). + +pp$1.parseBlock = function(createNewLexicalScope, node, exitStrict) { + if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; + if ( node === void 0 ) node = this.startNode(); + + node.body = []; + this.expect(types.braceL); + if (createNewLexicalScope) { this.enterScope(0); } + while (this.type !== types.braceR) { + var stmt = this.parseStatement(null); + node.body.push(stmt); + } + if (exitStrict) { this.strict = false; } + this.next(); + if (createNewLexicalScope) { this.exitScope(); } + return this.finishNode(node, "BlockStatement") +}; + +// Parse a regular `for` loop. The disambiguation code in +// `parseStatement` will already have parsed the init statement or +// expression. + +pp$1.parseFor = function(node, init) { + node.init = init; + this.expect(types.semi); + node.test = this.type === types.semi ? null : this.parseExpression(); + this.expect(types.semi); + node.update = this.type === types.parenR ? null : this.parseExpression(); + this.expect(types.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, "ForStatement") +}; + +// Parse a `for`/`in` and `for`/`of` loop, which are almost +// same from parser's perspective. + +pp$1.parseForIn = function(node, init) { + var isForIn = this.type === types._in; + this.next(); + + if ( + init.type === "VariableDeclaration" && + init.declarations[0].init != null && + ( + !isForIn || + this.options.ecmaVersion < 8 || + this.strict || + init.kind !== "var" || + init.declarations[0].id.type !== "Identifier" + ) + ) { + this.raise( + init.start, + ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer") + ); + } + node.left = init; + node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); + this.expect(types.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement") +}; + +// Parse a list of variable declarations. + +pp$1.parseVar = function(node, isFor, kind) { + node.declarations = []; + node.kind = kind; + for (;;) { + var decl = this.startNode(); + this.parseVarId(decl, kind); + if (this.eat(types.eq)) { + decl.init = this.parseMaybeAssign(isFor); + } else if (kind === "const" && !(this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { + this.unexpected(); + } else if (decl.id.type !== "Identifier" && !(isFor && (this.type === types._in || this.isContextual("of")))) { + this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); + } else { + decl.init = null; + } + node.declarations.push(this.finishNode(decl, "VariableDeclarator")); + if (!this.eat(types.comma)) { break } + } + return node +}; + +pp$1.parseVarId = function(decl, kind) { + decl.id = this.parseBindingAtom(); + this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); +}; + +var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4; + +// Parse a function declaration or literal (depending on the +// `statement & FUNC_STATEMENT`). + +// Remove `allowExpressionBody` for 7.0.0, as it is only called with false +pp$1.parseFunction = function(node, statement, allowExpressionBody, isAsync) { + this.initFunction(node); + if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) { + if (this.type === types.star && (statement & FUNC_HANGING_STATEMENT)) + { this.unexpected(); } + node.generator = this.eat(types.star); + } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + if (statement & FUNC_STATEMENT) { + node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types.name ? null : this.parseIdent(); + if (node.id && !(statement & FUNC_HANGING_STATEMENT)) + // If it is a regular function declaration in sloppy mode, then it is + // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding + // mode depends on properties of the current scope (see + // treatFunctionsAsVar). + { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); } + } + + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(node.async, node.generator)); + + if (!(statement & FUNC_STATEMENT)) + { node.id = this.type === types.name ? this.parseIdent() : null; } + + this.parseFunctionParams(node); + this.parseFunctionBody(node, allowExpressionBody, false); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression") +}; + +pp$1.parseFunctionParams = function(node) { + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); +}; + +// Parse a class declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseClass = function(node, isStatement) { + this.next(); + + // ecma-262 14.6 Class Definitions + // A class definition is always strict mode code. + var oldStrict = this.strict; + this.strict = true; + + this.parseClassId(node, isStatement); + this.parseClassSuper(node); + var privateNameMap = this.enterClassBody(); + var classBody = this.startNode(); + var hadConstructor = false; + classBody.body = []; + this.expect(types.braceL); + while (this.type !== types.braceR) { + var element = this.parseClassElement(node.superClass !== null); + if (element) { + classBody.body.push(element); + if (element.type === "MethodDefinition" && element.kind === "constructor") { + if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); } + hadConstructor = true; + } else if (element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) { + this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared")); + } + } + } + this.strict = oldStrict; + this.next(); + node.body = this.finishNode(classBody, "ClassBody"); + this.exitClassBody(); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +}; + +pp$1.parseClassElement = function(constructorAllowsSuper) { + if (this.eat(types.semi)) { return null } + + var ecmaVersion = this.options.ecmaVersion; + var node = this.startNode(); + var keyName = ""; + var isGenerator = false; + var isAsync = false; + var kind = "method"; + + // Parse modifiers + node.static = false; + if (this.eatContextual("static")) { + if (this.isClassElementNameStart() || this.type === types.star) { + node.static = true; + } else { + keyName = "static"; + } + } + if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) { + if ((this.isClassElementNameStart() || this.type === types.star) && !this.canInsertSemicolon()) { + isAsync = true; + } else { + keyName = "async"; + } + } + if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types.star)) { + isGenerator = true; + } + if (!keyName && !isAsync && !isGenerator) { + var lastValue = this.value; + if (this.eatContextual("get") || this.eatContextual("set")) { + if (this.isClassElementNameStart()) { + kind = lastValue; + } else { + keyName = lastValue; + } + } + } + + // Parse element name + if (keyName) { + // 'async', 'get', 'set', or 'static' were not a keyword contextually. + // The last token is any of those. Make it the element name. + node.computed = false; + node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc); + node.key.name = keyName; + this.finishNode(node.key, "Identifier"); + } else { + this.parseClassElementName(node); + } + + // Parse element value + if (ecmaVersion < 13 || this.type === types.parenL || kind !== "method" || isGenerator || isAsync) { + var isConstructor = !node.static && checkKeyName(node, "constructor"); + var allowsDirectSuper = isConstructor && constructorAllowsSuper; + // Couldn't move this check into the 'parseClassMethod' method for backward compatibility. + if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); } + node.kind = isConstructor ? "constructor" : kind; + this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper); + } else { + this.parseClassField(node); + } + + return node +}; + +pp$1.isClassElementNameStart = function() { + return ( + this.type === types.name || + this.type === types.privateId || + this.type === types.num || + this.type === types.string || + this.type === types.bracketL || + this.type.keyword + ) +}; + +pp$1.parseClassElementName = function(element) { + if (this.type === types.privateId) { + if (this.value === "constructor") { + this.raise(this.start, "Classes can't have an element named '#constructor'"); + } + element.computed = false; + element.key = this.parsePrivateIdent(); + } else { + this.parsePropertyName(element); + } +}; + +pp$1.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) { + // Check key and flags + var key = method.key; + if (method.kind === "constructor") { + if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } + if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } + } else if (method.static && checkKeyName(method, "prototype")) { + this.raise(key.start, "Classes may not have a static property named prototype"); + } + + // Parse value + var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); + + // Check value + if (method.kind === "get" && value.params.length !== 0) + { this.raiseRecoverable(value.start, "getter should have no params"); } + if (method.kind === "set" && value.params.length !== 1) + { this.raiseRecoverable(value.start, "setter should have exactly one param"); } + if (method.kind === "set" && value.params[0].type === "RestElement") + { this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); } + + return this.finishNode(method, "MethodDefinition") +}; + +pp$1.parseClassField = function(field) { + if (checkKeyName(field, "constructor")) { + this.raise(field.key.start, "Classes can't have a field named 'constructor'"); + } else if (field.static && checkKeyName(field, "prototype")) { + this.raise(field.key.start, "Classes can't have a static field named 'prototype'"); + } + + if (this.eat(types.eq)) { + // To raise SyntaxError if 'arguments' exists in the initializer. + var scope = this.currentThisScope(); + var inClassFieldInit = scope.inClassFieldInit; + scope.inClassFieldInit = true; + field.value = this.parseMaybeAssign(); + scope.inClassFieldInit = inClassFieldInit; + } else { + field.value = null; + } + this.semicolon(); + + return this.finishNode(field, "PropertyDefinition") +}; + +pp$1.parseClassId = function(node, isStatement) { + if (this.type === types.name) { + node.id = this.parseIdent(); + if (isStatement) + { this.checkLValSimple(node.id, BIND_LEXICAL, false); } + } else { + if (isStatement === true) + { this.unexpected(); } + node.id = null; + } +}; + +pp$1.parseClassSuper = function(node) { + node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; +}; + +pp$1.enterClassBody = function() { + var element = {declared: Object.create(null), used: []}; + this.privateNameStack.push(element); + return element.declared +}; + +pp$1.exitClassBody = function() { + var ref = this.privateNameStack.pop(); + var declared = ref.declared; + var used = ref.used; + var len = this.privateNameStack.length; + var parent = len === 0 ? null : this.privateNameStack[len - 1]; + for (var i = 0; i < used.length; ++i) { + var id = used[i]; + if (!has(declared, id.name)) { + if (parent) { + parent.used.push(id); + } else { + this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class")); + } + } + } +}; + +function isPrivateNameConflicted(privateNameMap, element) { + var name = element.key.name; + var curr = privateNameMap[name]; + + var next = "true"; + if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) { + next = (element.static ? "s" : "i") + element.kind; + } + + // `class { get #a(){}; static set #a(_){} }` is also conflict. + if ( + curr === "iget" && next === "iset" || + curr === "iset" && next === "iget" || + curr === "sget" && next === "sset" || + curr === "sset" && next === "sget" + ) { + privateNameMap[name] = "true"; + return false + } else if (!curr) { + privateNameMap[name] = next; + return false + } else { + return true + } +} + +function checkKeyName(node, name) { + var computed = node.computed; + var key = node.key; + return !computed && ( + key.type === "Identifier" && key.name === name || + key.type === "Literal" && key.value === name + ) +} + +// Parses module export declaration. + +pp$1.parseExport = function(node, exports) { + this.next(); + // export * from '...' + if (this.eat(types.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseIdent(true); + this.checkExport(exports, node.exported.name, this.lastTokStart); + } else { + node.exported = null; + } + } + this.expectContextual("from"); + if (this.type !== types.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(types._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart); + var isAsync; + if (this.type === types._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync); + } else if (this.type === types._class) { + var cNode = this.startNode(); + node.declaration = this.parseClass(cNode, "nullableID"); + } else { + node.declaration = this.parseMaybeAssign(); + this.semicolon(); + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(null); + if (node.declaration.type === "VariableDeclaration") + { this.checkVariableExport(exports, node.declaration.declarations); } + else + { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); } + node.specifiers = []; + node.source = null; + } else { // export { x, y as z } [from '...'] + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(exports); + if (this.eatContextual("from")) { + if (this.type !== types.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + } else { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) { + // check for keywords used as local names + var spec = list[i]; + + this.checkUnreserved(spec.local); + // check if export is defined + this.checkLocalExport(spec.local); + } + + node.source = null; + } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") +}; + +pp$1.checkExport = function(exports, name, pos) { + if (!exports) { return } + if (has(exports, name)) + { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } + exports[name] = true; +}; + +pp$1.checkPatternExport = function(exports, pat) { + var type = pat.type; + if (type === "Identifier") + { this.checkExport(exports, pat.name, pat.start); } + else if (type === "ObjectPattern") + { for (var i = 0, list = pat.properties; i < list.length; i += 1) + { + var prop = list[i]; + + this.checkPatternExport(exports, prop); + } } + else if (type === "ArrayPattern") + { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { + var elt = list$1[i$1]; + + if (elt) { this.checkPatternExport(exports, elt); } + } } + else if (type === "Property") + { this.checkPatternExport(exports, pat.value); } + else if (type === "AssignmentPattern") + { this.checkPatternExport(exports, pat.left); } + else if (type === "RestElement") + { this.checkPatternExport(exports, pat.argument); } + else if (type === "ParenthesizedExpression") + { this.checkPatternExport(exports, pat.expression); } +}; + +pp$1.checkVariableExport = function(exports, decls) { + if (!exports) { return } + for (var i = 0, list = decls; i < list.length; i += 1) + { + var decl = list[i]; + + this.checkPatternExport(exports, decl.id); + } +}; + +pp$1.shouldParseExportStatement = function() { + return this.type.keyword === "var" || + this.type.keyword === "const" || + this.type.keyword === "class" || + this.type.keyword === "function" || + this.isLet() || + this.isAsyncFunction() +}; + +// Parses a comma-separated list of module exports. + +pp$1.parseExportSpecifiers = function(exports) { + var nodes = [], first = true; + // export { x, y as z } [from '...'] + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this.expect(types.comma); + if (this.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var node = this.startNode(); + node.local = this.parseIdent(true); + node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local; + this.checkExport(exports, node.exported.name, node.exported.start); + nodes.push(this.finishNode(node, "ExportSpecifier")); + } + return nodes +}; + +// Parses import declaration. + +pp$1.parseImport = function(node) { + this.next(); + // import '...' + if (this.type === types.string) { + node.specifiers = empty; + node.source = this.parseExprAtom(); + } else { + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected(); + } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration") +}; + +// Parses a comma-separated list of module imports. + +pp$1.parseImportSpecifiers = function() { + var nodes = [], first = true; + if (this.type === types.name) { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode(); + node.local = this.parseIdent(); + this.checkLValSimple(node.local, BIND_LEXICAL); + nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); + if (!this.eat(types.comma)) { return nodes } + } + if (this.type === types.star) { + var node$1 = this.startNode(); + this.next(); + this.expectContextual("as"); + node$1.local = this.parseIdent(); + this.checkLValSimple(node$1.local, BIND_LEXICAL); + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); + return nodes + } + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this.expect(types.comma); + if (this.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var node$2 = this.startNode(); + node$2.imported = this.parseIdent(true); + if (this.eatContextual("as")) { + node$2.local = this.parseIdent(); + } else { + this.checkUnreserved(node$2.imported); + node$2.local = node$2.imported; + } + this.checkLValSimple(node$2.local, BIND_LEXICAL); + nodes.push(this.finishNode(node$2, "ImportSpecifier")); + } + return nodes +}; + +// Set `ExpressionStatement#directive` property for directive prologues. +pp$1.adaptDirectivePrologue = function(statements) { + for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { + statements[i].directive = statements[i].expression.raw.slice(1, -1); + } +}; +pp$1.isDirectiveCandidate = function(statement) { + return ( + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" && + typeof statement.expression.value === "string" && + // Reject parenthesized strings. + (this.input[statement.start] === "\"" || this.input[statement.start] === "'") + ) +}; + +var pp$2 = Parser.prototype; + +// Convert existing expression atom to assignable pattern +// if possible. + +pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) { + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); } + break + + case "ObjectPattern": + case "ArrayPattern": + case "AssignmentPattern": + case "RestElement": + break + + case "ObjectExpression": + node.type = "ObjectPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + this.toAssignable(prop, isBinding); + // Early error: + // AssignmentRestProperty[Yield, Await] : + // `...` DestructuringAssignmentTarget[Yield, Await] + // + // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. + if ( + prop.type === "RestElement" && + (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + ) { + this.raise(prop.argument.start, "Unexpected token"); + } + } + break + + case "Property": + // AssignmentProperty has type === "Property" + if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } + this.toAssignable(node.value, isBinding); + break + + case "ArrayExpression": + node.type = "ArrayPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + this.toAssignableList(node.elements, isBinding); + break + + case "SpreadElement": + node.type = "RestElement"; + this.toAssignable(node.argument, isBinding); + if (node.argument.type === "AssignmentPattern") + { this.raise(node.argument.start, "Rest elements cannot have a default value"); } + break + + case "AssignmentExpression": + if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } + node.type = "AssignmentPattern"; + delete node.operator; + this.toAssignable(node.left, isBinding); + break + + case "ParenthesizedExpression": + this.toAssignable(node.expression, isBinding, refDestructuringErrors); + break + + case "ChainExpression": + this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side"); + break + + case "MemberExpression": + if (!isBinding) { break } + + default: + this.raise(node.start, "Assigning to rvalue"); + } + } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + return node +}; + +// Convert list of expression atoms to binding list. + +pp$2.toAssignableList = function(exprList, isBinding) { + var end = exprList.length; + for (var i = 0; i < end; i++) { + var elt = exprList[i]; + if (elt) { this.toAssignable(elt, isBinding); } + } + if (end) { + var last = exprList[end - 1]; + if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + { this.unexpected(last.argument.start); } + } + return exprList +}; + +// Parses spread element. + +pp$2.parseSpread = function(refDestructuringErrors) { + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeAssign(false, refDestructuringErrors); + return this.finishNode(node, "SpreadElement") +}; + +pp$2.parseRestBinding = function() { + var node = this.startNode(); + this.next(); + + // RestElement inside of a function parameter must be an identifier + if (this.options.ecmaVersion === 6 && this.type !== types.name) + { this.unexpected(); } + + node.argument = this.parseBindingAtom(); + + return this.finishNode(node, "RestElement") +}; + +// Parses lvalue (assignable) atom. + +pp$2.parseBindingAtom = function() { + if (this.options.ecmaVersion >= 6) { + switch (this.type) { + case types.bracketL: + var node = this.startNode(); + this.next(); + node.elements = this.parseBindingList(types.bracketR, true, true); + return this.finishNode(node, "ArrayPattern") + + case types.braceL: + return this.parseObj(true) + } + } + return this.parseIdent() +}; + +pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) { + var elts = [], first = true; + while (!this.eat(close)) { + if (first) { first = false; } + else { this.expect(types.comma); } + if (allowEmpty && this.type === types.comma) { + elts.push(null); + } else if (allowTrailingComma && this.afterTrailingComma(close)) { + break + } else if (this.type === types.ellipsis) { + var rest = this.parseRestBinding(); + this.parseBindingListItem(rest); + elts.push(rest); + if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } + this.expect(close); + break + } else { + var elem = this.parseMaybeDefault(this.start, this.startLoc); + this.parseBindingListItem(elem); + elts.push(elem); + } + } + return elts +}; + +pp$2.parseBindingListItem = function(param) { + return param +}; + +// Parses assignment pattern around given atom if possible. + +pp$2.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom(); + if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.right = this.parseMaybeAssign(); + return this.finishNode(node, "AssignmentPattern") +}; + +// The following three functions all verify that a node is an lvalue — +// something that can be bound, or assigned to. In order to do so, they perform +// a variety of checks: +// +// - Check that none of the bound/assigned-to identifiers are reserved words. +// - Record name declarations for bindings in the appropriate scope. +// - Check duplicate argument names, if checkClashes is set. +// +// If a complex binding pattern is encountered (e.g., object and array +// destructuring), the entire pattern is recursively checked. +// +// There are three versions of checkLVal*() appropriate for different +// circumstances: +// +// - checkLValSimple() shall be used if the syntactic construct supports +// nothing other than identifiers and member expressions. Parenthesized +// expressions are also correctly handled. This is generally appropriate for +// constructs for which the spec says +// +// > It is a Syntax Error if AssignmentTargetType of [the production] is not +// > simple. +// +// It is also appropriate for checking if an identifier is valid and not +// defined elsewhere, like import declarations or function/class identifiers. +// +// Examples where this is used include: +// a += …; +// import a from '…'; +// where a is the node to be checked. +// +// - checkLValPattern() shall be used if the syntactic construct supports +// anything checkLValSimple() supports, as well as object and array +// destructuring patterns. This is generally appropriate for constructs for +// which the spec says +// +// > It is a Syntax Error if [the production] is neither an ObjectLiteral nor +// > an ArrayLiteral and AssignmentTargetType of [the production] is not +// > simple. +// +// Examples where this is used include: +// (a = …); +// const a = …; +// try { … } catch (a) { … } +// where a is the node to be checked. +// +// - checkLValInnerPattern() shall be used if the syntactic construct supports +// anything checkLValPattern() supports, as well as default assignment +// patterns, rest elements, and other constructs that may appear within an +// object or array destructuring pattern. +// +// As a special case, function parameters also use checkLValInnerPattern(), +// as they also support defaults and rest constructs. +// +// These functions deliberately support both assignment and binding constructs, +// as the logic for both is exceedingly similar. If the node is the target of +// an assignment, then bindingType should be set to BIND_NONE. Otherwise, it +// should be set to the appropriate BIND_* constant, like BIND_VAR or +// BIND_LEXICAL. +// +// If the function is called with a non-BIND_NONE bindingType, then +// additionally a checkClashes object may be specified to allow checking for +// duplicate argument names. checkClashes is ignored if the provided construct +// is an assignment (i.e., bindingType is BIND_NONE). + +pp$2.checkLValSimple = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + var isBind = bindingType !== BIND_NONE; + + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + { this.raiseRecoverable(expr.start, (isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } + if (isBind) { + if (bindingType === BIND_LEXICAL && expr.name === "let") + { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); } + if (checkClashes) { + if (has(checkClashes, expr.name)) + { this.raiseRecoverable(expr.start, "Argument name clash"); } + checkClashes[expr.name] = true; + } + if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } + } + break + + case "ChainExpression": + this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side"); + break + + case "MemberExpression": + if (isBind) { this.raiseRecoverable(expr.start, "Binding member expression"); } + break + + case "ParenthesizedExpression": + if (isBind) { this.raiseRecoverable(expr.start, "Binding parenthesized expression"); } + return this.checkLValSimple(expr.expression, bindingType, checkClashes) + + default: + this.raise(expr.start, (isBind ? "Binding" : "Assigning to") + " rvalue"); + } +}; + +pp$2.checkLValPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "ObjectPattern": + for (var i = 0, list = expr.properties; i < list.length; i += 1) { + var prop = list[i]; + + this.checkLValInnerPattern(prop, bindingType, checkClashes); + } + break + + case "ArrayPattern": + for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { + var elem = list$1[i$1]; + + if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); } + } + break + + default: + this.checkLValSimple(expr, bindingType, checkClashes); + } +}; + +pp$2.checkLValInnerPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "Property": + // AssignmentProperty has type === "Property" + this.checkLValInnerPattern(expr.value, bindingType, checkClashes); + break + + case "AssignmentPattern": + this.checkLValPattern(expr.left, bindingType, checkClashes); + break + + case "RestElement": + this.checkLValPattern(expr.argument, bindingType, checkClashes); + break + + default: + this.checkLValPattern(expr, bindingType, checkClashes); + } +}; + +// A recursive descent parser operates by defining functions for all + +var pp$3 = Parser.prototype; + +// Check if property name clashes with already added. +// Object/class getters and setters are not allowed to clash — +// either with each other or with an init property — and in +// strict mode, init properties are also not allowed to be repeated. + +pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) { + if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") + { return } + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + { return } + var key = prop.key; + var name; + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) { + if (refDestructuringErrors) { + if (refDestructuringErrors.doubleProto < 0) + { refDestructuringErrors.doubleProto = key.start; } + // Backwards-compat kludge. Can be removed in version 6.0 + } else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } + } + propHash.proto = true; + } + return + } + name = "$" + name; + var other = propHash[name]; + if (other) { + var redefinition; + if (kind === "init") { + redefinition = this.strict && other.init || other.get || other.set; + } else { + redefinition = other.init || other[kind]; + } + if (redefinition) + { this.raiseRecoverable(key.start, "Redefinition of property"); } + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + }; + } + other[kind] = true; +}; + +// ### Expression parsing + +// These nest, from the most general expression type at the top to +// 'atomic', nondivisible expression types at the bottom. Most of +// the functions will simply let the function(s) below them parse, +// and, *if* the syntactic construct they handle is present, wrap +// the AST node that the inner parser gave them in another node. + +// Parse a full expression. The optional arguments are used to +// forbid the `in` operator (in for loops initalization expressions) +// and provide reference for storing '=' operator inside shorthand +// property assignment in contexts where both object expression +// and object pattern might appear (so it's possible to raise +// delayed syntax error at correct position). + +pp$3.parseExpression = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeAssign(forInit, refDestructuringErrors); + if (this.type === types.comma) { + var node = this.startNodeAt(startPos, startLoc); + node.expressions = [expr]; + while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); } + return this.finishNode(node, "SequenceExpression") + } + return expr +}; + +// Parse an assignment expression. This includes applications of +// operators like `+=`. + +pp$3.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) { + if (this.isContextual("yield")) { + if (this.inGenerator) { return this.parseYield(forInit) } + // The tokenizer will assume an expression is allowed after + // `yield`, but this isn't that kind of yield + else { this.exprAllowed = false; } + } + + var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1; + if (refDestructuringErrors) { + oldParenAssign = refDestructuringErrors.parenthesizedAssign; + oldTrailingComma = refDestructuringErrors.trailingComma; + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; + } else { + refDestructuringErrors = new DestructuringErrors; + ownDestructuringErrors = true; + } + + var startPos = this.start, startLoc = this.startLoc; + if (this.type === types.parenL || this.type === types.name) { + this.potentialArrowAt = this.start; + this.potentialArrowInForAwait = forInit === "await"; + } + var left = this.parseMaybeConditional(forInit, refDestructuringErrors); + if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } + if (this.type.isAssign) { + var node = this.startNodeAt(startPos, startLoc); + node.operator = this.value; + if (this.type === types.eq) + { left = this.toAssignable(left, false, refDestructuringErrors); } + if (!ownDestructuringErrors) { + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1; + } + if (refDestructuringErrors.shorthandAssign >= left.start) + { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly + if (this.type === types.eq) + { this.checkLValPattern(left); } + else + { this.checkLValSimple(left); } + node.left = left; + this.next(); + node.right = this.parseMaybeAssign(forInit); + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } + } + if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } + if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } + return left +}; + +// Parse a ternary conditional (`?:`) operator. + +pp$3.parseMaybeConditional = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprOps(forInit, refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + if (this.eat(types.question)) { + var node = this.startNodeAt(startPos, startLoc); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + this.expect(types.colon); + node.alternate = this.parseMaybeAssign(forInit); + return this.finishNode(node, "ConditionalExpression") + } + return expr +}; + +// Start the precedence parser. + +pp$3.parseExprOps = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeUnary(refDestructuringErrors, false); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit) +}; + +// Parse binary operators with the operator precedence parsing +// algorithm. `left` is the left-hand side of the operator. +// `minPrec` provides context that allows the function to stop and +// defer further parser to one of its callers when it encounters an +// operator that has a lower precedence than the set it is parsing. + +pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) { + var prec = this.type.binop; + if (prec != null && (!forInit || this.type !== types._in)) { + if (prec > minPrec) { + var logical = this.type === types.logicalOR || this.type === types.logicalAND; + var coalesce = this.type === types.coalesce; + if (coalesce) { + // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions. + // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error. + prec = types.logicalAND.binop; + } + var op = this.value; + this.next(); + var startPos = this.start, startLoc = this.startLoc; + var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, forInit); + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce); + if ((logical && this.type === types.coalesce) || (coalesce && (this.type === types.logicalOR || this.type === types.logicalAND))) { + this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"); + } + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit) + } + } + return left +}; + +pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.operator = op; + node.right = right; + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") +}; + +// Parse unary operators, both prefix and postfix. + +pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec) { + var startPos = this.start, startLoc = this.startLoc, expr; + if (this.isContextual("await") && this.canAwait) { + expr = this.parseAwait(); + sawUnary = true; + } else if (this.type.prefix) { + var node = this.startNode(), update = this.type === types.incDec; + node.operator = this.value; + node.prefix = true; + this.next(); + node.argument = this.parseMaybeUnary(null, true, update); + this.checkExpressionErrors(refDestructuringErrors, true); + if (update) { this.checkLValSimple(node.argument); } + else if (this.strict && node.operator === "delete" && + node.argument.type === "Identifier") + { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } + else if (node.operator === "delete" && isPrivateFieldAccess(node.argument)) + { this.raiseRecoverable(node.start, "Private fields can not be deleted"); } + else { sawUnary = true; } + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); + } else { + expr = this.parseExprSubscripts(refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.operator = this.value; + node$1.prefix = false; + node$1.argument = expr; + this.checkLValSimple(expr); + this.next(); + expr = this.finishNode(node$1, "UpdateExpression"); + } + } + + if (!incDec && this.eat(types.starstar)) { + if (sawUnary) + { this.unexpected(this.lastTokStart); } + else + { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) } + } else { + return expr + } +}; + +function isPrivateFieldAccess(node) { + return ( + node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" || + node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) + ) +} + +// Parse call, dot, and `[]`-subscript expressions. + +pp$3.parseExprSubscripts = function(refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprAtom(refDestructuringErrors); + if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")") + { return expr } + var result = this.parseSubscripts(expr, startPos, startLoc); + if (refDestructuringErrors && result.type === "MemberExpression") { + if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } + if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } + if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; } + } + return result +}; + +pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { + var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && + this.potentialArrowAt === base.start; + var optionalChained = false; + + while (true) { + var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained); + + if (element.optional) { optionalChained = true; } + if (element === base || element.type === "ArrowFunctionExpression") { + if (optionalChained) { + var chainNode = this.startNodeAt(startPos, startLoc); + chainNode.expression = element; + element = this.finishNode(chainNode, "ChainExpression"); + } + return element + } + + base = element; + } +}; + +pp$3.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained) { + var optionalSupported = this.options.ecmaVersion >= 11; + var optional = optionalSupported && this.eat(types.questionDot); + if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); } + + var computed = this.eat(types.bracketL); + if (computed || (optional && this.type !== types.parenL && this.type !== types.backQuote) || this.eat(types.dot)) { + var node = this.startNodeAt(startPos, startLoc); + node.object = base; + if (computed) { + node.property = this.parseExpression(); + this.expect(types.bracketR); + } else if (this.type === types.privateId && base.type !== "Super") { + node.property = this.parsePrivateIdent(); + } else { + node.property = this.parseIdent(this.options.allowReserved !== "never"); + } + node.computed = !!computed; + if (optionalSupported) { + node.optional = optional; + } + base = this.finishNode(node, "MemberExpression"); + } else if (!noCalls && this.eat(types.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + var exprList = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); + if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + if (this.awaitIdentPos > 0) + { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); } + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true) + } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos; + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.callee = base; + node$1.arguments = exprList; + if (optionalSupported) { + node$1.optional = optional; + } + base = this.finishNode(node$1, "CallExpression"); + } else if (this.type === types.backQuote) { + if (optional || optionalChained) { + this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions"); + } + var node$2 = this.startNodeAt(startPos, startLoc); + node$2.tag = base; + node$2.quasi = this.parseTemplate({isTagged: true}); + base = this.finishNode(node$2, "TaggedTemplateExpression"); + } + return base +}; + +// Parse an atomic expression — either a single token that is an +// expression, an expression started by a keyword like `function` or +// `new`, or an expression wrapped in punctuation like `()`, `[]`, +// or `{}`. + +pp$3.parseExprAtom = function(refDestructuringErrors) { + // If a division operator appears in an expression position, the + // tokenizer got confused, and we force it to read a regexp instead. + if (this.type === types.slash) { this.readRegexp(); } + + var node, canBeArrow = this.potentialArrowAt === this.start; + switch (this.type) { + case types._super: + if (!this.allowSuper) + { this.raise(this.start, "'super' keyword outside a method"); } + node = this.startNode(); + this.next(); + if (this.type === types.parenL && !this.allowDirectSuper) + { this.raise(node.start, "super() call outside constructor of a subclass"); } + // The `super` keyword can appear at below: + // SuperProperty: + // super [ Expression ] + // super . IdentifierName + // SuperCall: + // super ( Arguments ) + if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL) + { this.unexpected(); } + return this.finishNode(node, "Super") + + case types._this: + node = this.startNode(); + this.next(); + return this.finishNode(node, "ThisExpression") + + case types.name: + var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; + var id = this.parseIdent(false); + if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function)) + { return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true) } + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(types.arrow)) + { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) } + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc && + (!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) { + id = this.parseIdent(false); + if (this.canInsertSemicolon() || !this.eat(types.arrow)) + { this.unexpected(); } + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) + } + } + return id + + case types.regexp: + var value = this.value; + node = this.parseLiteral(value.value); + node.regex = {pattern: value.pattern, flags: value.flags}; + return node + + case types.num: case types.string: + return this.parseLiteral(this.value) + + case types._null: case types._true: case types._false: + node = this.startNode(); + node.value = this.type === types._null ? null : this.type === types._true; + node.raw = this.type.keyword; + this.next(); + return this.finishNode(node, "Literal") + + case types.parenL: + var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow); + if (refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) + { refDestructuringErrors.parenthesizedAssign = start; } + if (refDestructuringErrors.parenthesizedBind < 0) + { refDestructuringErrors.parenthesizedBind = start; } + } + return expr + + case types.bracketL: + node = this.startNode(); + this.next(); + node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors); + return this.finishNode(node, "ArrayExpression") + + case types.braceL: + return this.parseObj(false, refDestructuringErrors) + + case types._function: + node = this.startNode(); + this.next(); + return this.parseFunction(node, 0) + + case types._class: + return this.parseClass(this.startNode(), false) + + case types._new: + return this.parseNew() + + case types.backQuote: + return this.parseTemplate() + + case types._import: + if (this.options.ecmaVersion >= 11) { + return this.parseExprImport() + } else { + return this.unexpected() + } + + default: + this.unexpected(); + } +}; + +pp$3.parseExprImport = function() { + var node = this.startNode(); + + // Consume `import` as an identifier for `import.meta`. + // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`. + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); } + var meta = this.parseIdent(true); + + switch (this.type) { + case types.parenL: + return this.parseDynamicImport(node) + case types.dot: + node.meta = meta; + return this.parseImportMeta(node) + default: + this.unexpected(); + } +}; + +pp$3.parseDynamicImport = function(node) { + this.next(); // skip `(` + + // Parse node.source. + node.source = this.parseMaybeAssign(); + + // Verify ending. + if (!this.eat(types.parenR)) { + var errorPos = this.start; + if (this.eat(types.comma) && this.eat(types.parenR)) { + this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); + } else { + this.unexpected(errorPos); + } + } + + return this.finishNode(node, "ImportExpression") +}; + +pp$3.parseImportMeta = function(node) { + this.next(); // skip `.` + + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + + if (node.property.name !== "meta") + { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); } + if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere) + { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); } + + return this.finishNode(node, "MetaProperty") +}; + +pp$3.parseLiteral = function(value) { + var node = this.startNode(); + node.value = value; + node.raw = this.input.slice(this.start, this.end); + if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, ""); } + this.next(); + return this.finishNode(node, "Literal") +}; + +pp$3.parseParenExpression = function() { + this.expect(types.parenL); + var val = this.parseExpression(); + this.expect(types.parenR); + return val +}; + +pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { + var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; + if (this.options.ecmaVersion >= 6) { + this.next(); + + var innerStartPos = this.start, innerStartLoc = this.startLoc; + var exprList = [], first = true, lastIsComma = false; + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; + this.yieldPos = 0; + this.awaitPos = 0; + // Do not save awaitIdentPos to allow checking awaits nested in parameters + while (this.type !== types.parenR) { + first ? first = false : this.expect(types.comma); + if (allowTrailingComma && this.afterTrailingComma(types.parenR, true)) { + lastIsComma = true; + break + } else if (this.type === types.ellipsis) { + spreadStart = this.start; + exprList.push(this.parseParenItem(this.parseRestBinding())); + if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } + break + } else { + exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem)); + } + } + var innerEndPos = this.start, innerEndLoc = this.startLoc; + this.expect(types.parenR); + + if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + return this.parseParenArrowList(startPos, startLoc, exprList) + } + + if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } + if (spreadStart) { this.unexpected(spreadStart); } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc); + val.expressions = exprList; + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); + } else { + val = exprList[0]; + } + } else { + val = this.parseParenExpression(); + } + + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc); + par.expression = val; + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val + } +}; + +pp$3.parseParenItem = function(item) { + return item +}; + +pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) +}; + +// New's precedence is slightly tricky. It must allow its argument to +// be a `[]` or dot subscript expression, but not a call — at least, +// not without wrapping it in parentheses. Thus, it uses the noCalls +// argument to parseSubscripts to prevent it from consuming the +// argument list. + +var empty$1 = []; + +pp$3.parseNew = function() { + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); } + var node = this.startNode(); + var meta = this.parseIdent(true); + if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) { + node.meta = meta; + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + if (node.property.name !== "target") + { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); } + if (!this.inNonArrowFunction) + { this.raiseRecoverable(node.start, "'new.target' can only be used in functions"); } + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types._import; + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); + if (isImport && node.callee.type === "ImportExpression") { + this.raise(startPos, "Cannot use new with import()"); + } + if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); } + else { node.arguments = empty$1; } + return this.finishNode(node, "NewExpression") +}; + +// Parse template expression. + +pp$3.parseTemplateElement = function(ref) { + var isTagged = ref.isTagged; + + var elem = this.startNode(); + if (this.type === types.invalidTemplate) { + if (!isTagged) { + this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); + } + elem.value = { + raw: this.value, + cooked: null + }; + } else { + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), + cooked: this.value + }; + } + this.next(); + elem.tail = this.type === types.backQuote; + return this.finishNode(elem, "TemplateElement") +}; + +pp$3.parseTemplate = function(ref) { + if ( ref === void 0 ) ref = {}; + var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; + + var node = this.startNode(); + this.next(); + node.expressions = []; + var curElt = this.parseTemplateElement({isTagged: isTagged}); + node.quasis = [curElt]; + while (!curElt.tail) { + if (this.type === types.eof) { this.raise(this.pos, "Unterminated template literal"); } + this.expect(types.dollarBraceL); + node.expressions.push(this.parseExpression()); + this.expect(types.braceR); + node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged})); + } + this.next(); + return this.finishNode(node, "TemplateLiteral") +}; + +pp$3.isAsyncProp = function(prop) { + return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && + (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) && + !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +}; + +// Parse an object literal or binding pattern. + +pp$3.parseObj = function(isPattern, refDestructuringErrors) { + var node = this.startNode(), first = true, propHash = {}; + node.properties = []; + this.next(); + while (!this.eat(types.braceR)) { + if (!first) { + this.expect(types.comma); + if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var prop = this.parseProperty(isPattern, refDestructuringErrors); + if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); } + node.properties.push(prop); + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") +}; + +pp$3.parseProperty = function(isPattern, refDestructuringErrors) { + var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; + if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) { + if (isPattern) { + prop.argument = this.parseIdent(false); + if (this.type === types.comma) { + this.raise(this.start, "Comma is not permitted after the rest element"); + } + return this.finishNode(prop, "RestElement") + } + // To disallow parenthesized identifier via `this.toAssignable()`. + if (this.type === types.parenL && refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0) { + refDestructuringErrors.parenthesizedAssign = this.start; + } + if (refDestructuringErrors.parenthesizedBind < 0) { + refDestructuringErrors.parenthesizedBind = this.start; + } + } + // Parse argument. + prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); + // To disallow trailing comma via `this.toAssignable()`. + if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { + refDestructuringErrors.trailingComma = this.start; + } + // Finish + return this.finishNode(prop, "SpreadElement") + } + if (this.options.ecmaVersion >= 6) { + prop.method = false; + prop.shorthand = false; + if (isPattern || refDestructuringErrors) { + startPos = this.start; + startLoc = this.startLoc; + } + if (!isPattern) + { isGenerator = this.eat(types.star); } + } + var containsEsc = this.containsEsc; + this.parsePropertyName(prop); + if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); + this.parsePropertyName(prop, refDestructuringErrors); + } else { + isAsync = false; + } + this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); + return this.finishNode(prop, "Property") +}; + +pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { + if ((isGenerator || isAsync) && this.type === types.colon) + { this.unexpected(); } + + if (this.eat(types.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); + prop.kind = "init"; + } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) { + if (isPattern) { this.unexpected(); } + prop.kind = "init"; + prop.method = true; + prop.value = this.parseMethod(isGenerator, isAsync); + } else if (!isPattern && !containsEsc && + this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type !== types.comma && this.type !== types.braceR && this.type !== types.eq)) { + if (isGenerator || isAsync) { this.unexpected(); } + prop.kind = prop.key.name; + this.parsePropertyName(prop); + prop.value = this.parseMethod(false); + var paramCount = prop.kind === "get" ? 0 : 1; + if (prop.value.params.length !== paramCount) { + var start = prop.value.start; + if (prop.kind === "get") + { this.raiseRecoverable(start, "getter should have no params"); } + else + { this.raiseRecoverable(start, "setter should have exactly one param"); } + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } + } + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + if (isGenerator || isAsync) { this.unexpected(); } + this.checkUnreserved(prop.key); + if (prop.key.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = startPos; } + prop.kind = "init"; + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); + } else if (this.type === types.eq && refDestructuringErrors) { + if (refDestructuringErrors.shorthandAssign < 0) + { refDestructuringErrors.shorthandAssign = this.start; } + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); + } else { + prop.value = this.copyNode(prop.key); + } + prop.shorthand = true; + } else { this.unexpected(); } +}; + +pp$3.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(types.bracketL)) { + prop.computed = true; + prop.key = this.parseMaybeAssign(); + this.expect(types.bracketR); + return prop.key + } else { + prop.computed = false; + } + } + return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never") +}; + +// Initialize empty function node. + +pp$3.initFunction = function(node) { + node.id = null; + if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; } + if (this.options.ecmaVersion >= 8) { node.async = false; } +}; + +// Parse object or class method. + +pp$3.parseMethod = function(isGenerator, isAsync, allowDirectSuper) { + var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); + + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + this.parseFunctionBody(node, false, true); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "FunctionExpression") +}; + +// Parse arrow function expression with given parameters. + +pp$3.parseArrowExpression = function(node, params, isAsync) { + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW); + this.initFunction(node); + if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + + node.params = this.toAssignableList(params, true); + this.parseFunctionBody(node, true, false); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "ArrowFunctionExpression") +}; + +// Parse function body and check parameters. + +pp$3.parseFunctionBody = function(node, isArrowFunction, isMethod) { + var isExpression = isArrowFunction && this.type !== types.braceL; + var oldStrict = this.strict, useStrict = false; + + if (isExpression) { + node.body = this.parseMaybeAssign(); + node.expression = true; + this.checkParams(node, false); + } else { + var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); + if (!oldStrict || nonSimple) { + useStrict = this.strictDirective(this.end); + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldLabels = this.labels; + this.labels = []; + if (useStrict) { this.strict = true; } + + // Add the params to varDeclaredNames to ensure that an error is thrown + // if a let/const declaration in the function clashes with one of the params. + this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)); + // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' + if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); } + node.body = this.parseBlock(false, undefined, useStrict && !oldStrict); + node.expression = false; + this.adaptDirectivePrologue(node.body.body); + this.labels = oldLabels; + } + this.exitScope(); +}; + +pp$3.isSimpleParamList = function(params) { + for (var i = 0, list = params; i < list.length; i += 1) + { + var param = list[i]; + + if (param.type !== "Identifier") { return false + } } + return true +}; + +// Checks function params for various disallowed patterns such as using "eval" +// or "arguments" and duplicate parameters. + +pp$3.checkParams = function(node, allowDuplicates) { + var nameHash = Object.create(null); + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash); + } +}; + +// Parses a comma-separated list of expressions, and returns them as +// an array. `close` is the token type that ends the list, and +// `allowEmpty` can be turned on to allow subsequent commas with +// nothing in between them to be parsed as `null` (which is needed +// for array literals). + +pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var elts = [], first = true; + while (!this.eat(close)) { + if (!first) { + this.expect(types.comma); + if (allowTrailingComma && this.afterTrailingComma(close)) { break } + } else { first = false; } + + var elt = (void 0); + if (allowEmpty && this.type === types.comma) + { elt = null; } + else if (this.type === types.ellipsis) { + elt = this.parseSpread(refDestructuringErrors); + if (refDestructuringErrors && this.type === types.comma && refDestructuringErrors.trailingComma < 0) + { refDestructuringErrors.trailingComma = this.start; } + } else { + elt = this.parseMaybeAssign(false, refDestructuringErrors); + } + elts.push(elt); + } + return elts +}; + +pp$3.checkUnreserved = function(ref) { + var start = ref.start; + var end = ref.end; + var name = ref.name; + + if (this.inGenerator && name === "yield") + { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); } + if (this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); } + if (this.currentThisScope().inClassFieldInit && name === "arguments") + { this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); } + if (this.keywords.test(name)) + { this.raise(start, ("Unexpected keyword '" + name + "'")); } + if (this.options.ecmaVersion < 6 && + this.input.slice(start, end).indexOf("\\") !== -1) { return } + var re = this.strict ? this.reservedWordsStrict : this.reservedWords; + if (re.test(name)) { + if (!this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); } + this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); + } +}; + +// Parse the next token as an identifier. If `liberal` is true (used +// when parsing properties), it will also convert keywords into +// identifiers. + +pp$3.parseIdent = function(liberal, isBinding) { + var node = this.startNode(); + if (this.type === types.name) { + node.name = this.value; + } else if (this.type.keyword) { + node.name = this.type.keyword; + + // To fix https://github.com/acornjs/acorn/issues/575 + // `class` and `function` keywords push new context into this.context. + // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. + // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword + if ((node.name === "class" || node.name === "function") && + (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { + this.context.pop(); + } + } else { + this.unexpected(); + } + this.next(!!liberal); + this.finishNode(node, "Identifier"); + if (!liberal) { + this.checkUnreserved(node); + if (node.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = node.start; } + } + return node +}; + +pp$3.parsePrivateIdent = function() { + var node = this.startNode(); + if (this.type === types.privateId) { + node.name = this.value; + } else { + this.unexpected(); + } + this.next(); + this.finishNode(node, "PrivateIdentifier"); + + // For validating existence + if (this.privateNameStack.length === 0) { + this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class")); + } else { + this.privateNameStack[this.privateNameStack.length - 1].used.push(node); + } + + return node +}; + +// Parses yield expression inside generator. + +pp$3.parseYield = function(forInit) { + if (!this.yieldPos) { this.yieldPos = this.start; } + + var node = this.startNode(); + this.next(); + if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(types.star); + node.argument = this.parseMaybeAssign(forInit); + } + return this.finishNode(node, "YieldExpression") +}; + +pp$3.parseAwait = function() { + if (!this.awaitPos) { this.awaitPos = this.start; } + + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeUnary(null, true); + return this.finishNode(node, "AwaitExpression") +}; + +var pp$4 = Parser.prototype; + +// This function is used to raise exceptions on parse errors. It +// takes an offset integer (into the current `input`) to indicate +// the location of the error, attaches the position to the end +// of the error message, and then raises a `SyntaxError` with that +// message. + +pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos); + message += " (" + loc.line + ":" + loc.column + ")"; + var err = new SyntaxError(message); + err.pos = pos; err.loc = loc; err.raisedAt = this.pos; + throw err +}; + +pp$4.raiseRecoverable = pp$4.raise; + +pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } +}; + +var pp$5 = Parser.prototype; + +var Scope = function Scope(flags) { + this.flags = flags; + // A list of var-declared names in the current lexical scope + this.var = []; + // A list of lexically-declared names in the current lexical scope + this.lexical = []; + // A list of lexically-declared FunctionDeclaration names in the current lexical scope + this.functions = []; + // A switch to disallow the identifier reference 'arguments' + this.inClassFieldInit = false; +}; + +// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. + +pp$5.enterScope = function(flags) { + this.scopeStack.push(new Scope(flags)); +}; + +pp$5.exitScope = function() { + this.scopeStack.pop(); +}; + +// The spec says: +// > At the top level of a function, or script, function declarations are +// > treated like var declarations rather than like lexical declarations. +pp$5.treatFunctionsAsVarInScope = function(scope) { + return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP) +}; + +pp$5.declareName = function(name, bindingType, pos) { + var redeclared = false; + if (bindingType === BIND_LEXICAL) { + var scope = this.currentScope(); + redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; + scope.lexical.push(name); + if (this.inModule && (scope.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + } else if (bindingType === BIND_SIMPLE_CATCH) { + var scope$1 = this.currentScope(); + scope$1.lexical.push(name); + } else if (bindingType === BIND_FUNCTION) { + var scope$2 = this.currentScope(); + if (this.treatFunctionsAsVar) + { redeclared = scope$2.lexical.indexOf(name) > -1; } + else + { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; } + scope$2.functions.push(name); + } else { + for (var i = this.scopeStack.length - 1; i >= 0; --i) { + var scope$3 = this.scopeStack[i]; + if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) || + !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) { + redeclared = true; + break + } + scope$3.var.push(name); + if (this.inModule && (scope$3.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + if (scope$3.flags & SCOPE_VAR) { break } + } + } + if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); } +}; + +pp$5.checkLocalExport = function(id) { + // scope.functions must be empty as Module code is always strict. + if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && + this.scopeStack[0].var.indexOf(id.name) === -1) { + this.undefinedExports[id.name] = id; + } +}; + +pp$5.currentScope = function() { + return this.scopeStack[this.scopeStack.length - 1] +}; + +pp$5.currentVarScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & SCOPE_VAR) { return scope } + } +}; + +// Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. +pp$5.currentThisScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope } + } +}; + +var Node = function Node(parser, pos, loc) { + this.type = ""; + this.start = pos; + this.end = 0; + if (parser.options.locations) + { this.loc = new SourceLocation(parser, loc); } + if (parser.options.directSourceFile) + { this.sourceFile = parser.options.directSourceFile; } + if (parser.options.ranges) + { this.range = [pos, 0]; } +}; + +// Start an AST node, attaching a start offset. + +var pp$6 = Parser.prototype; + +pp$6.startNode = function() { + return new Node(this, this.start, this.startLoc) +}; + +pp$6.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) +}; + +// Finish an AST node, adding `type` and `end` properties. + +function finishNodeAt(node, type, pos, loc) { + node.type = type; + node.end = pos; + if (this.options.locations) + { node.loc.end = loc; } + if (this.options.ranges) + { node.range[1] = pos; } + return node +} + +pp$6.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) +}; + +// Finish node at given position + +pp$6.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) +}; + +pp$6.copyNode = function(node) { + var newNode = new Node(this, node.start, this.startLoc); + for (var prop in node) { newNode[prop] = node[prop]; } + return newNode +}; + +// The algorithm used to determine whether a regexp can appear at a + +var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { + this.token = token; + this.isExpr = !!isExpr; + this.preserveSpace = !!preserveSpace; + this.override = override; + this.generator = !!generator; +}; + +var types$1 = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", false), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), + f_stat: new TokContext("function", false), + f_expr: new TokContext("function", true), + f_expr_gen: new TokContext("function", true, false, null, true), + f_gen: new TokContext("function", false, false, null, true) +}; + +var pp$7 = Parser.prototype; + +pp$7.initialContext = function() { + return [types$1.b_stat] +}; + +pp$7.braceIsBlock = function(prevType) { + var parent = this.curContext(); + if (parent === types$1.f_expr || parent === types$1.f_stat) + { return true } + if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr)) + { return !parent.isExpr } + + // The check for `tt.name && exprAllowed` detects whether we are + // after a `yield` or `of` construct. See the `updateContext` for + // `tt.name`. + if (prevType === types._return || prevType === types.name && this.exprAllowed) + { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } + if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow) + { return true } + if (prevType === types.braceL) + { return parent === types$1.b_stat } + if (prevType === types._var || prevType === types._const || prevType === types.name) + { return false } + return !this.exprAllowed +}; + +pp$7.inGeneratorContext = function() { + for (var i = this.context.length - 1; i >= 1; i--) { + var context = this.context[i]; + if (context.token === "function") + { return context.generator } + } + return false +}; + +pp$7.updateContext = function(prevType) { + var update, type = this.type; + if (type.keyword && prevType === types.dot) + { this.exprAllowed = false; } + else if (update = type.updateContext) + { update.call(this, prevType); } + else + { this.exprAllowed = type.beforeExpr; } +}; + +// Token-specific context update code + +types.parenR.updateContext = types.braceR.updateContext = function() { + if (this.context.length === 1) { + this.exprAllowed = true; + return + } + var out = this.context.pop(); + if (out === types$1.b_stat && this.curContext().token === "function") { + out = this.context.pop(); + } + this.exprAllowed = !out.isExpr; +}; + +types.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr); + this.exprAllowed = true; +}; + +types.dollarBraceL.updateContext = function() { + this.context.push(types$1.b_tmpl); + this.exprAllowed = true; +}; + +types.parenL.updateContext = function(prevType) { + var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while; + this.context.push(statementParens ? types$1.p_stat : types$1.p_expr); + this.exprAllowed = true; +}; + +types.incDec.updateContext = function() { + // tokExprAllowed stays unchanged +}; + +types._function.updateContext = types._class.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== types._else && + !(prevType === types.semi && this.curContext() !== types$1.p_stat) && + !(prevType === types._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && + !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat)) + { this.context.push(types$1.f_expr); } + else + { this.context.push(types$1.f_stat); } + this.exprAllowed = false; +}; + +types.backQuote.updateContext = function() { + if (this.curContext() === types$1.q_tmpl) + { this.context.pop(); } + else + { this.context.push(types$1.q_tmpl); } + this.exprAllowed = false; +}; + +types.star.updateContext = function(prevType) { + if (prevType === types._function) { + var index = this.context.length - 1; + if (this.context[index] === types$1.f_expr) + { this.context[index] = types$1.f_expr_gen; } + else + { this.context[index] = types$1.f_gen; } + } + this.exprAllowed = true; +}; + +types.name.updateContext = function(prevType) { + var allowed = false; + if (this.options.ecmaVersion >= 6 && prevType !== types.dot) { + if (this.value === "of" && !this.exprAllowed || + this.value === "yield" && this.inGeneratorContext()) + { allowed = true; } + } + this.exprAllowed = allowed; +}; + +// This file contains Unicode properties extracted from the ECMAScript +// specification. The lists are extracted like so: +// $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText) + +// #table-binary-unicode-properties +var ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS"; +var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic"; +var ecma11BinaryProperties = ecma10BinaryProperties; +var ecma12BinaryProperties = ecma11BinaryProperties + " EBase EComp EMod EPres ExtPict"; +var unicodeBinaryProperties = { + 9: ecma9BinaryProperties, + 10: ecma10BinaryProperties, + 11: ecma11BinaryProperties, + 12: ecma12BinaryProperties +}; + +// #table-unicode-general-category-values +var unicodeGeneralCategoryValues = "Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu"; + +// #table-unicode-script-values +var ecma9ScriptValues = "Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb"; +var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd"; +var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; +var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi"; +var unicodeScriptValues = { + 9: ecma9ScriptValues, + 10: ecma10ScriptValues, + 11: ecma11ScriptValues, + 12: ecma12ScriptValues +}; + +var data = {}; +function buildUnicodeData(ecmaVersion) { + var d = data[ecmaVersion] = { + binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues), + nonBinary: { + General_Category: wordsRegexp(unicodeGeneralCategoryValues), + Script: wordsRegexp(unicodeScriptValues[ecmaVersion]) + } + }; + d.nonBinary.Script_Extensions = d.nonBinary.Script; + + d.nonBinary.gc = d.nonBinary.General_Category; + d.nonBinary.sc = d.nonBinary.Script; + d.nonBinary.scx = d.nonBinary.Script_Extensions; +} +buildUnicodeData(9); +buildUnicodeData(10); +buildUnicodeData(11); +buildUnicodeData(12); + +var pp$8 = Parser.prototype; + +var RegExpValidationState = function RegExpValidationState(parser) { + this.parser = parser; + this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : ""); + this.unicodeProperties = data[parser.options.ecmaVersion >= 12 ? 12 : parser.options.ecmaVersion]; + this.source = ""; + this.flags = ""; + this.start = 0; + this.switchU = false; + this.switchN = false; + this.pos = 0; + this.lastIntValue = 0; + this.lastStringValue = ""; + this.lastAssertionIsQuantifiable = false; + this.numCapturingParens = 0; + this.maxBackReference = 0; + this.groupNames = []; + this.backReferenceNames = []; +}; + +RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { + var unicode = flags.indexOf("u") !== -1; + this.start = start | 0; + this.source = pattern + ""; + this.flags = flags; + this.switchU = unicode && this.parser.options.ecmaVersion >= 6; + this.switchN = unicode && this.parser.options.ecmaVersion >= 9; +}; + +RegExpValidationState.prototype.raise = function raise (message) { + this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message)); +}; + +// If u flag is given, this returns the code point at the index (it combines a surrogate pair). +// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). +RegExpValidationState.prototype.at = function at (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return -1 + } + var c = s.charCodeAt(i); + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return c + } + var next = s.charCodeAt(i + 1); + return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c +}; + +RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return l + } + var c = s.charCodeAt(i), next; + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || + (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) { + return i + 1 + } + return i + 2 +}; + +RegExpValidationState.prototype.current = function current (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.pos, forceU) +}; + +RegExpValidationState.prototype.lookahead = function lookahead (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.nextIndex(this.pos, forceU), forceU) +}; + +RegExpValidationState.prototype.advance = function advance (forceU) { + if ( forceU === void 0 ) forceU = false; + + this.pos = this.nextIndex(this.pos, forceU); +}; + +RegExpValidationState.prototype.eat = function eat (ch, forceU) { + if ( forceU === void 0 ) forceU = false; + + if (this.current(forceU) === ch) { + this.advance(forceU); + return true + } + return false +}; + +function codePointToString(ch) { + if (ch <= 0xFFFF) { return String.fromCharCode(ch) } + ch -= 0x10000; + return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00) +} + +/** + * Validate the flags part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ +pp$8.validateRegExpFlags = function(state) { + var validFlags = state.validFlags; + var flags = state.flags; + + for (var i = 0; i < flags.length; i++) { + var flag = flags.charAt(i); + if (validFlags.indexOf(flag) === -1) { + this.raise(state.start, "Invalid regular expression flag"); + } + if (flags.indexOf(flag, i + 1) > -1) { + this.raise(state.start, "Duplicate regular expression flag"); + } + } +}; + +/** + * Validate the pattern part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ +pp$8.validateRegExpPattern = function(state) { + this.regexp_pattern(state); + + // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of + // parsing contains a |GroupName|, reparse with the goal symbol + // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* + // exception if _P_ did not conform to the grammar, if any elements of _P_ + // were not matched by the parse, or if any Early Error conditions exist. + if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { + state.switchN = true; + this.regexp_pattern(state); + } +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern +pp$8.regexp_pattern = function(state) { + state.pos = 0; + state.lastIntValue = 0; + state.lastStringValue = ""; + state.lastAssertionIsQuantifiable = false; + state.numCapturingParens = 0; + state.maxBackReference = 0; + state.groupNames.length = 0; + state.backReferenceNames.length = 0; + + this.regexp_disjunction(state); + + if (state.pos !== state.source.length) { + // Make the same messages as V8. + if (state.eat(0x29 /* ) */)) { + state.raise("Unmatched ')'"); + } + if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) { + state.raise("Lone quantifier brackets"); + } + } + if (state.maxBackReference > state.numCapturingParens) { + state.raise("Invalid escape"); + } + for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { + var name = list[i]; + + if (state.groupNames.indexOf(name) === -1) { + state.raise("Invalid named capture referenced"); + } + } +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction +pp$8.regexp_disjunction = function(state) { + this.regexp_alternative(state); + while (state.eat(0x7C /* | */)) { + this.regexp_alternative(state); + } + + // Make the same message as V8. + if (this.regexp_eatQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + if (state.eat(0x7B /* { */)) { + state.raise("Lone quantifier brackets"); + } +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative +pp$8.regexp_alternative = function(state) { + while (state.pos < state.source.length && this.regexp_eatTerm(state)) + { } +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term +pp$8.regexp_eatTerm = function(state) { + if (this.regexp_eatAssertion(state)) { + // Handle `QuantifiableAssertion Quantifier` alternative. + // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion + // is a QuantifiableAssertion. + if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { + // Make the same message as V8. + if (state.switchU) { + state.raise("Invalid quantifier"); + } + } + return true + } + + if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { + this.regexp_eatQuantifier(state); + return true + } + + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion +pp$8.regexp_eatAssertion = function(state) { + var start = state.pos; + state.lastAssertionIsQuantifiable = false; + + // ^, $ + if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) { + return true + } + + // \b \B + if (state.eat(0x5C /* \ */)) { + if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) { + return true + } + state.pos = start; + } + + // Lookahead / Lookbehind + if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) { + var lookbehind = false; + if (this.options.ecmaVersion >= 9) { + lookbehind = state.eat(0x3C /* < */); + } + if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) { + this.regexp_disjunction(state); + if (!state.eat(0x29 /* ) */)) { + state.raise("Unterminated group"); + } + state.lastAssertionIsQuantifiable = !lookbehind; + return true + } + } + + state.pos = start; + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier +pp$8.regexp_eatQuantifier = function(state, noError) { + if ( noError === void 0 ) noError = false; + + if (this.regexp_eatQuantifierPrefix(state, noError)) { + state.eat(0x3F /* ? */); + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix +pp$8.regexp_eatQuantifierPrefix = function(state, noError) { + return ( + state.eat(0x2A /* * */) || + state.eat(0x2B /* + */) || + state.eat(0x3F /* ? */) || + this.regexp_eatBracedQuantifier(state, noError) + ) +}; +pp$8.regexp_eatBracedQuantifier = function(state, noError) { + var start = state.pos; + if (state.eat(0x7B /* { */)) { + var min = 0, max = -1; + if (this.regexp_eatDecimalDigits(state)) { + min = state.lastIntValue; + if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) { + max = state.lastIntValue; + } + if (state.eat(0x7D /* } */)) { + // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term + if (max !== -1 && max < min && !noError) { + state.raise("numbers out of order in {} quantifier"); + } + return true + } + } + if (state.switchU && !noError) { + state.raise("Incomplete quantifier"); + } + state.pos = start; + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom +pp$8.regexp_eatAtom = function(state) { + return ( + this.regexp_eatPatternCharacters(state) || + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) + ) +}; +pp$8.regexp_eatReverseSolidusAtomEscape = function(state) { + var start = state.pos; + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatAtomEscape(state)) { + return true + } + state.pos = start; + } + return false +}; +pp$8.regexp_eatUncapturingGroup = function(state) { + var start = state.pos; + if (state.eat(0x28 /* ( */)) { + if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) { + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + return true + } + state.raise("Unterminated group"); + } + state.pos = start; + } + return false +}; +pp$8.regexp_eatCapturingGroup = function(state) { + if (state.eat(0x28 /* ( */)) { + if (this.options.ecmaVersion >= 9) { + this.regexp_groupSpecifier(state); + } else if (state.current() === 0x3F /* ? */) { + state.raise("Invalid group"); + } + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + state.numCapturingParens += 1; + return true + } + state.raise("Unterminated group"); + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom +pp$8.regexp_eatExtendedAtom = function(state) { + return ( + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) || + this.regexp_eatInvalidBracedQuantifier(state) || + this.regexp_eatExtendedPatternCharacter(state) + ) +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier +pp$8.regexp_eatInvalidBracedQuantifier = function(state) { + if (this.regexp_eatBracedQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter +pp$8.regexp_eatSyntaxCharacter = function(state) { + var ch = state.current(); + if (isSyntaxCharacter(ch)) { + state.lastIntValue = ch; + state.advance(); + return true + } + return false +}; +function isSyntaxCharacter(ch) { + return ( + ch === 0x24 /* $ */ || + ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ || + ch === 0x2E /* . */ || + ch === 0x3F /* ? */ || + ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ || + ch >= 0x7B /* { */ && ch <= 0x7D /* } */ + ) +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter +// But eat eager. +pp$8.regexp_eatPatternCharacters = function(state) { + var start = state.pos; + var ch = 0; + while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { + state.advance(); + } + return state.pos !== start +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter +pp$8.regexp_eatExtendedPatternCharacter = function(state) { + var ch = state.current(); + if ( + ch !== -1 && + ch !== 0x24 /* $ */ && + !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) && + ch !== 0x2E /* . */ && + ch !== 0x3F /* ? */ && + ch !== 0x5B /* [ */ && + ch !== 0x5E /* ^ */ && + ch !== 0x7C /* | */ + ) { + state.advance(); + return true + } + return false +}; + +// GroupSpecifier :: +// [empty] +// `?` GroupName +pp$8.regexp_groupSpecifier = function(state) { + if (state.eat(0x3F /* ? */)) { + if (this.regexp_eatGroupName(state)) { + if (state.groupNames.indexOf(state.lastStringValue) !== -1) { + state.raise("Duplicate capture group name"); + } + state.groupNames.push(state.lastStringValue); + return + } + state.raise("Invalid group"); + } +}; + +// GroupName :: +// `<` RegExpIdentifierName `>` +// Note: this updates `state.lastStringValue` property with the eaten name. +pp$8.regexp_eatGroupName = function(state) { + state.lastStringValue = ""; + if (state.eat(0x3C /* < */)) { + if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) { + return true + } + state.raise("Invalid capture group name"); + } + return false +}; + +// RegExpIdentifierName :: +// RegExpIdentifierStart +// RegExpIdentifierName RegExpIdentifierPart +// Note: this updates `state.lastStringValue` property with the eaten name. +pp$8.regexp_eatRegExpIdentifierName = function(state) { + state.lastStringValue = ""; + if (this.regexp_eatRegExpIdentifierStart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + while (this.regexp_eatRegExpIdentifierPart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + } + return true + } + return false +}; + +// RegExpIdentifierStart :: +// UnicodeIDStart +// `$` +// `_` +// `\` RegExpUnicodeEscapeSequence[+U] +pp$8.regexp_eatRegExpIdentifierStart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierStart(ch)) { + state.lastIntValue = ch; + return true + } + + state.pos = start; + return false +}; +function isRegExpIdentifierStart(ch) { + return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ +} + +// RegExpIdentifierPart :: +// UnicodeIDContinue +// `$` +// `_` +// `\` RegExpUnicodeEscapeSequence[+U] +// +// +pp$8.regexp_eatRegExpIdentifierPart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierPart(ch)) { + state.lastIntValue = ch; + return true + } + + state.pos = start; + return false +}; +function isRegExpIdentifierPart(ch) { + return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D /* */ +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape +pp$8.regexp_eatAtomEscape = function(state) { + if ( + this.regexp_eatBackReference(state) || + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) || + (state.switchN && this.regexp_eatKGroupName(state)) + ) { + return true + } + if (state.switchU) { + // Make the same message as V8. + if (state.current() === 0x63 /* c */) { + state.raise("Invalid unicode escape"); + } + state.raise("Invalid escape"); + } + return false +}; +pp$8.regexp_eatBackReference = function(state) { + var start = state.pos; + if (this.regexp_eatDecimalEscape(state)) { + var n = state.lastIntValue; + if (state.switchU) { + // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape + if (n > state.maxBackReference) { + state.maxBackReference = n; + } + return true + } + if (n <= state.numCapturingParens) { + return true + } + state.pos = start; + } + return false +}; +pp$8.regexp_eatKGroupName = function(state) { + if (state.eat(0x6B /* k */)) { + if (this.regexp_eatGroupName(state)) { + state.backReferenceNames.push(state.lastStringValue); + return true + } + state.raise("Invalid named reference"); + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape +pp$8.regexp_eatCharacterEscape = function(state) { + return ( + this.regexp_eatControlEscape(state) || + this.regexp_eatCControlLetter(state) || + this.regexp_eatZero(state) || + this.regexp_eatHexEscapeSequence(state) || + this.regexp_eatRegExpUnicodeEscapeSequence(state, false) || + (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || + this.regexp_eatIdentityEscape(state) + ) +}; +pp$8.regexp_eatCControlLetter = function(state) { + var start = state.pos; + if (state.eat(0x63 /* c */)) { + if (this.regexp_eatControlLetter(state)) { + return true + } + state.pos = start; + } + return false +}; +pp$8.regexp_eatZero = function(state) { + if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) { + state.lastIntValue = 0; + state.advance(); + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape +pp$8.regexp_eatControlEscape = function(state) { + var ch = state.current(); + if (ch === 0x74 /* t */) { + state.lastIntValue = 0x09; /* \t */ + state.advance(); + return true + } + if (ch === 0x6E /* n */) { + state.lastIntValue = 0x0A; /* \n */ + state.advance(); + return true + } + if (ch === 0x76 /* v */) { + state.lastIntValue = 0x0B; /* \v */ + state.advance(); + return true + } + if (ch === 0x66 /* f */) { + state.lastIntValue = 0x0C; /* \f */ + state.advance(); + return true + } + if (ch === 0x72 /* r */) { + state.lastIntValue = 0x0D; /* \r */ + state.advance(); + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter +pp$8.regexp_eatControlLetter = function(state) { + var ch = state.current(); + if (isControlLetter(ch)) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false +}; +function isControlLetter(ch) { + return ( + (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) || + (ch >= 0x61 /* a */ && ch <= 0x7A /* z */) + ) +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence +pp$8.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) { + if ( forceU === void 0 ) forceU = false; + + var start = state.pos; + var switchU = forceU || state.switchU; + + if (state.eat(0x75 /* u */)) { + if (this.regexp_eatFixedHexDigits(state, 4)) { + var lead = state.lastIntValue; + if (switchU && lead >= 0xD800 && lead <= 0xDBFF) { + var leadSurrogateEnd = state.pos; + if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) { + var trail = state.lastIntValue; + if (trail >= 0xDC00 && trail <= 0xDFFF) { + state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; + return true + } + } + state.pos = leadSurrogateEnd; + state.lastIntValue = lead; + } + return true + } + if ( + switchU && + state.eat(0x7B /* { */) && + this.regexp_eatHexDigits(state) && + state.eat(0x7D /* } */) && + isValidUnicode(state.lastIntValue) + ) { + return true + } + if (switchU) { + state.raise("Invalid unicode escape"); + } + state.pos = start; + } + + return false +}; +function isValidUnicode(ch) { + return ch >= 0 && ch <= 0x10FFFF +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape +pp$8.regexp_eatIdentityEscape = function(state) { + if (state.switchU) { + if (this.regexp_eatSyntaxCharacter(state)) { + return true + } + if (state.eat(0x2F /* / */)) { + state.lastIntValue = 0x2F; /* / */ + return true + } + return false + } + + var ch = state.current(); + if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape +pp$8.regexp_eatDecimalEscape = function(state) { + state.lastIntValue = 0; + var ch = state.current(); + if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) { + do { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape +pp$8.regexp_eatCharacterClassEscape = function(state) { + var ch = state.current(); + + if (isCharacterClassEscape(ch)) { + state.lastIntValue = -1; + state.advance(); + return true + } + + if ( + state.switchU && + this.options.ecmaVersion >= 9 && + (ch === 0x50 /* P */ || ch === 0x70 /* p */) + ) { + state.lastIntValue = -1; + state.advance(); + if ( + state.eat(0x7B /* { */) && + this.regexp_eatUnicodePropertyValueExpression(state) && + state.eat(0x7D /* } */) + ) { + return true + } + state.raise("Invalid property name"); + } + + return false +}; +function isCharacterClassEscape(ch) { + return ( + ch === 0x64 /* d */ || + ch === 0x44 /* D */ || + ch === 0x73 /* s */ || + ch === 0x53 /* S */ || + ch === 0x77 /* w */ || + ch === 0x57 /* W */ + ) +} + +// UnicodePropertyValueExpression :: +// UnicodePropertyName `=` UnicodePropertyValue +// LoneUnicodePropertyNameOrValue +pp$8.regexp_eatUnicodePropertyValueExpression = function(state) { + var start = state.pos; + + // UnicodePropertyName `=` UnicodePropertyValue + if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) { + var name = state.lastStringValue; + if (this.regexp_eatUnicodePropertyValue(state)) { + var value = state.lastStringValue; + this.regexp_validateUnicodePropertyNameAndValue(state, name, value); + return true + } + } + state.pos = start; + + // LoneUnicodePropertyNameOrValue + if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { + var nameOrValue = state.lastStringValue; + this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue); + return true + } + return false +}; +pp$8.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { + if (!has(state.unicodeProperties.nonBinary, name)) + { state.raise("Invalid property name"); } + if (!state.unicodeProperties.nonBinary[name].test(value)) + { state.raise("Invalid property value"); } +}; +pp$8.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { + if (!state.unicodeProperties.binary.test(nameOrValue)) + { state.raise("Invalid property name"); } +}; + +// UnicodePropertyName :: +// UnicodePropertyNameCharacters +pp$8.regexp_eatUnicodePropertyName = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyNameCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" +}; +function isUnicodePropertyNameCharacter(ch) { + return isControlLetter(ch) || ch === 0x5F /* _ */ +} + +// UnicodePropertyValue :: +// UnicodePropertyValueCharacters +pp$8.regexp_eatUnicodePropertyValue = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyValueCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" +}; +function isUnicodePropertyValueCharacter(ch) { + return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) +} + +// LoneUnicodePropertyNameOrValue :: +// UnicodePropertyValueCharacters +pp$8.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { + return this.regexp_eatUnicodePropertyValue(state) +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass +pp$8.regexp_eatCharacterClass = function(state) { + if (state.eat(0x5B /* [ */)) { + state.eat(0x5E /* ^ */); + this.regexp_classRanges(state); + if (state.eat(0x5D /* ] */)) { + return true + } + // Unreachable since it threw "unterminated regular expression" error before. + state.raise("Unterminated character class"); + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges +// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges +// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash +pp$8.regexp_classRanges = function(state) { + while (this.regexp_eatClassAtom(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) { + var right = state.lastIntValue; + if (state.switchU && (left === -1 || right === -1)) { + state.raise("Invalid character class"); + } + if (left !== -1 && right !== -1 && left > right) { + state.raise("Range out of order in character class"); + } + } + } +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom +// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash +pp$8.regexp_eatClassAtom = function(state) { + var start = state.pos; + + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatClassEscape(state)) { + return true + } + if (state.switchU) { + // Make the same message as V8. + var ch$1 = state.current(); + if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) { + state.raise("Invalid class escape"); + } + state.raise("Invalid escape"); + } + state.pos = start; + } + + var ch = state.current(); + if (ch !== 0x5D /* ] */) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape +pp$8.regexp_eatClassEscape = function(state) { + var start = state.pos; + + if (state.eat(0x62 /* b */)) { + state.lastIntValue = 0x08; /* */ + return true + } + + if (state.switchU && state.eat(0x2D /* - */)) { + state.lastIntValue = 0x2D; /* - */ + return true + } + + if (!state.switchU && state.eat(0x63 /* c */)) { + if (this.regexp_eatClassControlLetter(state)) { + return true + } + state.pos = start; + } + + return ( + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) + ) +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter +pp$8.regexp_eatClassControlLetter = function(state) { + var ch = state.current(); + if (isDecimalDigit(ch) || ch === 0x5F /* _ */) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence +pp$8.regexp_eatHexEscapeSequence = function(state) { + var start = state.pos; + if (state.eat(0x78 /* x */)) { + if (this.regexp_eatFixedHexDigits(state, 2)) { + return true + } + if (state.switchU) { + state.raise("Invalid escape"); + } + state.pos = start; + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits +pp$8.regexp_eatDecimalDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isDecimalDigit(ch = state.current())) { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } + return state.pos !== start +}; +function isDecimalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */ +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits +pp$8.regexp_eatHexDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isHexDigit(ch = state.current())) { + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return state.pos !== start +}; +function isHexDigit(ch) { + return ( + (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) || + (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) || + (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) + ) +} +function hexToInt(ch) { + if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) { + return 10 + (ch - 0x41 /* A */) + } + if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) { + return 10 + (ch - 0x61 /* a */) + } + return ch - 0x30 /* 0 */ +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence +// Allows only 0-377(octal) i.e. 0-255(decimal). +pp$8.regexp_eatLegacyOctalEscapeSequence = function(state) { + if (this.regexp_eatOctalDigit(state)) { + var n1 = state.lastIntValue; + if (this.regexp_eatOctalDigit(state)) { + var n2 = state.lastIntValue; + if (n1 <= 3 && this.regexp_eatOctalDigit(state)) { + state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue; + } else { + state.lastIntValue = n1 * 8 + n2; + } + } else { + state.lastIntValue = n1; + } + return true + } + return false +}; + +// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit +pp$8.regexp_eatOctalDigit = function(state) { + var ch = state.current(); + if (isOctalDigit(ch)) { + state.lastIntValue = ch - 0x30; /* 0 */ + state.advance(); + return true + } + state.lastIntValue = 0; + return false +}; +function isOctalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */ +} + +// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits +// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit +// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence +pp$8.regexp_eatFixedHexDigits = function(state, length) { + var start = state.pos; + state.lastIntValue = 0; + for (var i = 0; i < length; ++i) { + var ch = state.current(); + if (!isHexDigit(ch)) { + state.pos = start; + return false + } + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return true +}; + +// Object type used to represent tokens. Note that normally, tokens +// simply exist as properties on the parser object. This is only +// used for the onToken callback and the external tokenizer. + +var Token = function Token(p) { + this.type = p.type; + this.value = p.value; + this.start = p.start; + this.end = p.end; + if (p.options.locations) + { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); } + if (p.options.ranges) + { this.range = [p.start, p.end]; } +}; + +// ## Tokenizer + +var pp$9 = Parser.prototype; + +// Move to the next token + +pp$9.next = function(ignoreEscapeSequenceInKeyword) { + if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc) + { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); } + if (this.options.onToken) + { this.options.onToken(new Token(this)); } + + this.lastTokEnd = this.end; + this.lastTokStart = this.start; + this.lastTokEndLoc = this.endLoc; + this.lastTokStartLoc = this.startLoc; + this.nextToken(); +}; + +pp$9.getToken = function() { + this.next(); + return new Token(this) +}; + +// If we're in an ES6 environment, make parsers iterable +if (typeof Symbol !== "undefined") + { pp$9[Symbol.iterator] = function() { + var this$1 = this; + + return { + next: function () { + var token = this$1.getToken(); + return { + done: token.type === types.eof, + value: token + } + } + } + }; } + +// Toggle strict mode. Re-reads the next number or string to please +// pedantic tests (`"use strict"; 010;` should fail). + +pp$9.curContext = function() { + return this.context[this.context.length - 1] +}; + +// Read a single token, updating the parser object's token-related +// properties. + +pp$9.nextToken = function() { + var curContext = this.curContext(); + if (!curContext || !curContext.preserveSpace) { this.skipSpace(); } + + this.start = this.pos; + if (this.options.locations) { this.startLoc = this.curPosition(); } + if (this.pos >= this.input.length) { return this.finishToken(types.eof) } + + if (curContext.override) { return curContext.override(this) } + else { this.readToken(this.fullCharCodeAtPos()); } +}; + +pp$9.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + { return this.readWord() } + + return this.getTokenFromCode(code) +}; + +pp$9.fullCharCodeAtPos = function() { + var code = this.input.charCodeAt(this.pos); + if (code <= 0xd7ff || code >= 0xdc00) { return code } + var next = this.input.charCodeAt(this.pos + 1); + return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00 +}; + +pp$9.skipBlockComment = function() { + var startLoc = this.options.onComment && this.curPosition(); + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2); + if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); } + this.pos = end + 2; + if (this.options.locations) { + lineBreakG.lastIndex = start; + var match; + while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { + ++this.curLine; + this.lineStart = match.index + match[0].length; + } + } + if (this.options.onComment) + { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()); } +}; + +pp$9.skipLineComment = function(startSkip) { + var start = this.pos; + var startLoc = this.options.onComment && this.curPosition(); + var ch = this.input.charCodeAt(this.pos += startSkip); + while (this.pos < this.input.length && !isNewLine(ch)) { + ch = this.input.charCodeAt(++this.pos); + } + if (this.options.onComment) + { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()); } +}; + +// Called at the start of the parse and after every token. Skips +// whitespace and comments, and. + +pp$9.skipSpace = function() { + loop: while (this.pos < this.input.length) { + var ch = this.input.charCodeAt(this.pos); + switch (ch) { + case 32: case 160: // ' ' + ++this.pos; + break + case 13: + if (this.input.charCodeAt(this.pos + 1) === 10) { + ++this.pos; + } + case 10: case 8232: case 8233: + ++this.pos; + if (this.options.locations) { + ++this.curLine; + this.lineStart = this.pos; + } + break + case 47: // '/' + switch (this.input.charCodeAt(this.pos + 1)) { + case 42: // '*' + this.skipBlockComment(); + break + case 47: + this.skipLineComment(2); + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this.pos; + } else { + break loop + } + } + } +}; + +// Called at the end of every token. Sets `end`, `val`, and +// maintains `context` and `exprAllowed`, and skips the space after +// the token, so that the next one's `start` will point at the +// right position. + +pp$9.finishToken = function(type, val) { + this.end = this.pos; + if (this.options.locations) { this.endLoc = this.curPosition(); } + var prevType = this.type; + this.type = type; + this.value = val; + + this.updateContext(prevType); +}; + +// ### Token reading + +// This is the function that is called to fetch the next token. It +// is somewhat obscure, because it works in character codes rather +// than characters, and because operator parsing has been inlined +// into it. +// +// All in the name of speed. +// +pp$9.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1); + if (next >= 48 && next <= 57) { return this.readNumber(true) } + var next2 = this.input.charCodeAt(this.pos + 2); + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3; + return this.finishToken(types.ellipsis) + } else { + ++this.pos; + return this.finishToken(types.dot) + } +}; + +pp$9.readToken_slash = function() { // '/' + var next = this.input.charCodeAt(this.pos + 1); + if (this.exprAllowed) { ++this.pos; return this.readRegexp() } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.slash, 1) +}; + +pp$9.readToken_mult_modulo_exp = function(code) { // '%*' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + var tokentype = code === 42 ? types.star : types.modulo; + + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) { + ++size; + tokentype = types.starstar; + next = this.input.charCodeAt(this.pos + 2); + } + + if (next === 61) { return this.finishOp(types.assign, size + 1) } + return this.finishOp(tokentype, size) +}; + +pp$9.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (this.options.ecmaVersion >= 12) { + var next2 = this.input.charCodeAt(this.pos + 2); + if (next2 === 61) { return this.finishOp(types.assign, 3) } + } + return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) + } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1) +}; + +pp$9.readToken_caret = function() { // '^' + var next = this.input.charCodeAt(this.pos + 1); + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.bitwiseXOR, 1) +}; + +pp$9.readToken_plus_min = function(code) { // '+-' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && + (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { + // A `-->` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types.incDec, 2) + } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.plusMin, 1) +}; + +pp$9.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) } + return this.finishOp(types.bitShift, size) + } + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + // ` + fillIn->gender = getGenderString( + getDerivedGender(loc, "per", numeratorUnitData, denominatorUnitData, status), status); +} + +void LongNameHandler::processPatternTimes(MeasureUnitImpl &&productUnit, + Locale loc, + const UNumberUnitWidth &width, + const char *caseVariant, + UnicodeString *outArray, + UErrorCode &status) { + if (U_FAILURE(status)) { + return; + } + if (productUnit.complexity == UMEASURE_UNIT_MIXED) { + // These are handled by MixedUnitLongNameHandler + status = U_UNSUPPORTED_ERROR; + return; + } + +#if U_DEBUG + for (int32_t pluralIndex = 0; pluralIndex < ARRAY_LENGTH; pluralIndex++) { + U_ASSERT(outArray[pluralIndex].length() == 0); + U_ASSERT(!outArray[pluralIndex].isBogus()); + } +#endif + + if (productUnit.identifier.isEmpty()) { + // TODO(icu-units#28): consider when serialize should be called. + // identifier might also be empty for MeasureUnit(). + productUnit.serialize(status); + } + if (U_FAILURE(status)) { + return; + } + if (productUnit.identifier.length() == 0) { + // MeasureUnit(): no units: return empty strings. + return; + } + + MeasureUnit builtinUnit; + if (MeasureUnit::findBySubType(productUnit.identifier.toStringPiece(), &builtinUnit)) { + // TODO(icu-units#145): spec doesn't cover builtin-per-builtin, it + // breaks them all down. Do we want to drop this? + // - findBySubType isn't super efficient, if we skip it and go to basic + // singles, we don't have to construct MeasureUnit's anymore. + // - Check all the existing unit tests that fail without this: is it due + // to incorrect fallback via getMeasureData? + // - Do those unit tests cover this code path representatively? + if (builtinUnit != MeasureUnit()) { + getMeasureData(loc, builtinUnit, width, caseVariant, outArray, status); + maybeCalculateGender(loc, builtinUnit, outArray, status); + } + return; + } + + // 2. Set timesPattern to be getValue(times, locale, length) + UnicodeString timesPattern = getCompoundValue("times", loc, width, status); + SimpleFormatter timesPatternFormatter(timesPattern, 2, 2, status); + if (U_FAILURE(status)) { + return; + } + + PlaceholderPosition globalPlaceholder[ARRAY_LENGTH]; + UChar globalJoinerChar = 0; + // Numbered list items are from the algorithms at + // https://unicode.org/reports/tr35/tr35-general.html#compound-units: + // + // pattern(...) point 5: + // - Set both globalPlaceholder and globalPlaceholderPosition to be empty + // + // 3. Set result to be empty + for (int32_t pluralIndex = 0; pluralIndex < ARRAY_LENGTH; pluralIndex++) { + // Initial state: empty string pattern, via all falling back to OTHER: + if (pluralIndex == StandardPlural::Form::OTHER) { + outArray[pluralIndex].remove(); + } else { + outArray[pluralIndex].setToBogus(); + } + globalPlaceholder[pluralIndex] = PH_EMPTY; + } + + // Empty string represents "compound" (propagate the plural form). + const char *pluralCategory = ""; + DerivedComponents derivedTimesPlurals(loc, "plural", "times"); + DerivedComponents derivedTimesCases(loc, "case", "times"); + DerivedComponents derivedPowerCases(loc, "case", "power"); + + // 4. For each single_unit in product_unit + for (int32_t singleUnitIndex = 0; singleUnitIndex < productUnit.singleUnits.length(); + singleUnitIndex++) { + SingleUnitImpl *singleUnit = productUnit.singleUnits[singleUnitIndex]; + const char *singlePluralCategory; + const char *singleCaseVariant; + // TODO(icu-units#28): ensure we have unit tests that change/fail if we + // assign incorrect case variants here: + if (singleUnitIndex < productUnit.singleUnits.length() - 1) { + // 4.1. If hasMultiple + singlePluralCategory = derivedTimesPlurals.value0(pluralCategory); + singleCaseVariant = derivedTimesCases.value0(caseVariant); + pluralCategory = derivedTimesPlurals.value1(pluralCategory); + caseVariant = derivedTimesCases.value1(caseVariant); + } else { + singlePluralCategory = derivedTimesPlurals.value1(pluralCategory); + singleCaseVariant = derivedTimesCases.value1(caseVariant); + } + + // 4.2. Get the gender of that single_unit + MeasureUnit simpleUnit; + if (!MeasureUnit::findBySubType(singleUnit->getSimpleUnitID(), &simpleUnit)) { + // Ideally all simple units should be known, but they're not: + // 100-kilometer is internally treated as a simple unit, but it is + // not a built-in unit and does not have formatting data in CLDR 39. + // + // TODO(icu-units#28): test (desirable) invariants in unit tests. + status = U_UNSUPPORTED_ERROR; + return; + } + const char *gender = getGenderString(getGenderForBuiltin(loc, simpleUnit, status), status); + + // 4.3. If singleUnit starts with a dimensionality_prefix, such as 'square-' + U_ASSERT(singleUnit->dimensionality > 0); + int32_t dimensionality = singleUnit->dimensionality; + UnicodeString dimensionalityPrefixPatterns[ARRAY_LENGTH]; + if (dimensionality != 1) { + // 4.3.1. set dimensionalityPrefixPattern to be + // getValue(that dimensionality_prefix, locale, length, singlePluralCategory, singleCaseVariant, gender), + // such as "{0} kwadratowym" + CharString dimensionalityKey("compound/power", status); + dimensionalityKey.appendNumber(dimensionality, status); + getInflectedMeasureData(dimensionalityKey.toStringPiece(), loc, width, gender, + singleCaseVariant, dimensionalityPrefixPatterns, status); + if (U_FAILURE(status)) { + // At the time of writing, only pow2 and pow3 are supported. + // Attempting to format other powers results in a + // U_RESOURCE_TYPE_MISMATCH. We convert the error if we + // understand it: + if (status == U_RESOURCE_TYPE_MISMATCH && dimensionality > 3) { + status = U_UNSUPPORTED_ERROR; + } + return; + } + + // TODO(icu-units#139): + // 4.3.2. set singlePluralCategory to be power0(singlePluralCategory) + + // 4.3.3. set singleCaseVariant to be power0(singleCaseVariant) + singleCaseVariant = derivedPowerCases.value0(singleCaseVariant); + // 4.3.4. remove the dimensionality_prefix from singleUnit + singleUnit->dimensionality = 1; + } + + // 4.4. if singleUnit starts with an si_prefix, such as 'centi' + UMeasurePrefix prefix = singleUnit->unitPrefix; + UnicodeString prefixPattern; + if (prefix != UMEASURE_PREFIX_ONE) { + // 4.4.1. set siPrefixPattern to be getValue(that si_prefix, locale, + // length), such as "centy{0}" + CharString prefixKey; + // prefixKey looks like "1024p3" or "10p-2": + prefixKey.appendNumber(umeas_getPrefixBase(prefix), status); + prefixKey.append('p', status); + prefixKey.appendNumber(umeas_getPrefixPower(prefix), status); + // Contains a pattern like "centy{0}". + prefixPattern = getCompoundValue(prefixKey.toStringPiece(), loc, width, status); + + // 4.4.2. set singlePluralCategory to be prefix0(singlePluralCategory) + // + // TODO(icu-units#139): that refers to these rules: + // + // though I'm not sure what other value they might end up having. + // + // 4.4.3. set singleCaseVariant to be prefix0(singleCaseVariant) + // + // TODO(icu-units#139): that refers to: + // but the prefix (value0) doesn't have case, the rest simply + // propagates. + + // 4.4.4. remove the si_prefix from singleUnit + singleUnit->unitPrefix = UMEASURE_PREFIX_ONE; + } + + // 4.5. Set corePattern to be the getValue(singleUnit, locale, length, + // singlePluralCategory, singleCaseVariant), such as "{0} metrem" + UnicodeString singleUnitArray[ARRAY_LENGTH]; + // At this point we are left with a Simple Unit: + U_ASSERT(uprv_strcmp(singleUnit->build(status).getIdentifier(), singleUnit->getSimpleUnitID()) == + 0); + getMeasureData(loc, singleUnit->build(status), width, singleCaseVariant, singleUnitArray, + status); + if (U_FAILURE(status)) { + // Shouldn't happen if we have data for all single units + return; + } + + // Calculate output gender + if (!singleUnitArray[GENDER_INDEX].isBogus()) { + U_ASSERT(!singleUnitArray[GENDER_INDEX].isEmpty()); + UnicodeString uVal; + + if (prefix != UMEASURE_PREFIX_ONE) { + singleUnitArray[GENDER_INDEX] = + getDerivedGender(loc, "prefix", singleUnitArray, nullptr, status); + } + + if (dimensionality != 1) { + singleUnitArray[GENDER_INDEX] = + getDerivedGender(loc, "power", singleUnitArray, nullptr, status); + } + + UnicodeString timesGenderRule = getDeriveCompoundRule(loc, "gender", "times", status); + if (timesGenderRule.length() == 1) { + switch (timesGenderRule[0]) { + case u'0': + if (singleUnitIndex == 0) { + U_ASSERT(outArray[GENDER_INDEX].isBogus()); + outArray[GENDER_INDEX] = singleUnitArray[GENDER_INDEX]; + } + break; + case u'1': + if (singleUnitIndex == productUnit.singleUnits.length() - 1) { + U_ASSERT(outArray[GENDER_INDEX].isBogus()); + outArray[GENDER_INDEX] = singleUnitArray[GENDER_INDEX]; + } + } + } else { + if (outArray[GENDER_INDEX].isBogus()) { + outArray[GENDER_INDEX] = timesGenderRule; + } + } + } + + // Calculate resulting patterns for each plural form + for (int32_t pluralIndex = 0; pluralIndex < StandardPlural::Form::COUNT; pluralIndex++) { + StandardPlural::Form plural = static_cast(pluralIndex); + + // singleUnitArray[pluralIndex] looks something like "{0} Meter" + if (outArray[pluralIndex].isBogus()) { + if (singleUnitArray[pluralIndex].isBogus()) { + // Let the usual plural fallback mechanism take care of this + // plural form + continue; + } else { + // Since our singleUnit can have a plural form that outArray + // doesn't yet have (relying on fallback to OTHER), we start + // by grabbing it with the normal plural fallback mechanism + outArray[pluralIndex] = getWithPlural(outArray, plural, status); + if (U_FAILURE(status)) { + return; + } + } + } + + if (uprv_strcmp(singlePluralCategory, "") != 0) { + plural = static_cast(getIndex(singlePluralCategory, status)); + } + + // 4.6. Extract(corePattern, coreUnit, placeholder, placeholderPosition) from that pattern. + UnicodeString coreUnit; + PlaceholderPosition placeholderPosition; + UChar joinerChar; + extractCorePattern(getWithPlural(singleUnitArray, plural, status), coreUnit, + placeholderPosition, joinerChar); + + // 4.7 If the position is middle, then fail + if (placeholderPosition == PH_MIDDLE) { + status = U_UNSUPPORTED_ERROR; + return; + } + + // 4.8. If globalPlaceholder is empty + if (globalPlaceholder[pluralIndex] == PH_EMPTY) { + globalPlaceholder[pluralIndex] = placeholderPosition; + globalJoinerChar = joinerChar; + } else { + // Expect all units involved to have the same placeholder position + U_ASSERT(globalPlaceholder[pluralIndex] == placeholderPosition); + // TODO(icu-units#28): Do we want to add a unit test that checks + // for consistent joiner chars? Probably not, given how + // inconsistent they are. File a CLDR ticket with examples? + } + // Now coreUnit would be just "Meter" + + // 4.9. If siPrefixPattern is not empty + if (prefix != UMEASURE_PREFIX_ONE) { + SimpleFormatter prefixCompiled(prefixPattern, 1, 1, status); + if (U_FAILURE(status)) { + return; + } + + // 4.9.1. Set coreUnit to be the combineLowercasing(locale, length, siPrefixPattern, + // coreUnit) + UnicodeString tmp; + // combineLowercasing(locale, length, prefixPattern, coreUnit) + // + // TODO(icu-units#28): run this only if prefixPattern does not + // contain space characters - do languages "as", "bn", "hi", + // "kk", etc have concepts of upper and lower case?: + if (width == UNUM_UNIT_WIDTH_FULL_NAME) { + coreUnit.toLower(loc); + } + prefixCompiled.format(coreUnit, tmp, status); + if (U_FAILURE(status)) { + return; + } + coreUnit = tmp; + } + + // 4.10. If dimensionalityPrefixPattern is not empty + if (dimensionality != 1) { + SimpleFormatter dimensionalityCompiled( + getWithPlural(dimensionalityPrefixPatterns, plural, status), 1, 1, status); + if (U_FAILURE(status)) { + return; + } + + // 4.10.1. Set coreUnit to be the combineLowercasing(locale, length, + // dimensionalityPrefixPattern, coreUnit) + UnicodeString tmp; + // combineLowercasing(locale, length, prefixPattern, coreUnit) + // + // TODO(icu-units#28): run this only if prefixPattern does not + // contain space characters - do languages "as", "bn", "hi", + // "kk", etc have concepts of upper and lower case?: + if (width == UNUM_UNIT_WIDTH_FULL_NAME) { + coreUnit.toLower(loc); + } + dimensionalityCompiled.format(coreUnit, tmp, status); + if (U_FAILURE(status)) { + return; + } + coreUnit = tmp; + } + + if (outArray[pluralIndex].length() == 0) { + // 4.11. If the result is empty, set result to be coreUnit + outArray[pluralIndex] = coreUnit; + } else { + // 4.12. Otherwise set result to be format(timesPattern, result, coreUnit) + UnicodeString tmp; + timesPatternFormatter.format(outArray[pluralIndex], coreUnit, tmp, status); + outArray[pluralIndex] = tmp; + } + } + } + for (int32_t pluralIndex = 0; pluralIndex < StandardPlural::Form::COUNT; pluralIndex++) { + if (globalPlaceholder[pluralIndex] == PH_BEGINNING) { + UnicodeString tmp; + tmp.append(u"{0}", 3); + if (globalJoinerChar != 0) { + tmp.append(globalJoinerChar); + } + tmp.append(outArray[pluralIndex]); + outArray[pluralIndex] = tmp; + } else if (globalPlaceholder[pluralIndex] == PH_END) { + if (globalJoinerChar != 0) { + outArray[pluralIndex].append(globalJoinerChar); + } + outArray[pluralIndex].append(u"{0}", 3); + } + } } UnicodeString LongNameHandler::getUnitDisplayName( @@ -267,7 +1455,7 @@ UnicodeString LongNameHandler::getUnitDisplayName( return ICU_Utility::makeBogusString(); } UnicodeString simpleFormats[ARRAY_LENGTH]; - getMeasureData(loc, unit, width, simpleFormats, status); + getMeasureData(loc, unit, width, "", simpleFormats, status); return simpleFormats[DNAM_INDEX]; } @@ -281,7 +1469,7 @@ UnicodeString LongNameHandler::getUnitPattern( return ICU_Utility::makeBogusString(); } UnicodeString simpleFormats[ARRAY_LENGTH]; - getMeasureData(loc, unit, width, simpleFormats, status); + getMeasureData(loc, unit, width, "", simpleFormats, status); // The above already handles fallback from other widths to short if (U_FAILURE(status)) { return ICU_Utility::makeBogusString(); @@ -304,6 +1492,7 @@ LongNameHandler* LongNameHandler::forCurrencyLongNames(const Locale &loc, const getCurrencyLongNameData(loc, currency, simpleFormats, status); if (U_FAILURE(status)) { return nullptr; } result->simpleFormatsToModifiers(simpleFormats, {UFIELD_CATEGORY_NUMBER, UNUM_CURRENCY_FIELD}, status); + // TODO(icu-units#28): currency gender? return result; } @@ -328,8 +1517,12 @@ void LongNameHandler::multiSimpleFormatsToModifiers(const UnicodeString *leadFor UnicodeString leadFormat = getWithPlural(leadFormats, plural, status); if (U_FAILURE(status)) { return; } UnicodeString compoundFormat; - trailCompiled.format(leadFormat, compoundFormat, status); - if (U_FAILURE(status)) { return; } + if (leadFormat.length() == 0) { + compoundFormat = trailFormat; + } else { + trailCompiled.format(leadFormat, compoundFormat, status); + if (U_FAILURE(status)) { return; } + } SimpleFormatter compoundCompiled(compoundFormat, 0, 1, status); if (U_FAILURE(status)) { return; } fModifiers[i] = SimpleModifier(compoundCompiled, field, false, {this, SIGNUM_POS_ZERO, plural}); @@ -338,13 +1531,238 @@ void LongNameHandler::multiSimpleFormatsToModifiers(const UnicodeString *leadFor void LongNameHandler::processQuantity(DecimalQuantity &quantity, MicroProps µs, UErrorCode &status) const { - parent->processQuantity(quantity, micros, status); + if (parent != NULL) { + parent->processQuantity(quantity, micros, status); + } StandardPlural::Form pluralForm = utils::getPluralSafe(micros.rounder, rules, quantity, status); micros.modOuter = &fModifiers[pluralForm]; + micros.gender = gender; } const Modifier* LongNameHandler::getModifier(Signum /*signum*/, StandardPlural::Form plural) const { return &fModifiers[plural]; } +void MixedUnitLongNameHandler::forMeasureUnit(const Locale &loc, + const MeasureUnit &mixedUnit, + const UNumberUnitWidth &width, + const char *unitDisplayCase, + const PluralRules *rules, + const MicroPropsGenerator *parent, + MixedUnitLongNameHandler *fillIn, + UErrorCode &status) { + U_ASSERT(mixedUnit.getComplexity(status) == UMEASURE_UNIT_MIXED); + U_ASSERT(fillIn != nullptr); + if (U_FAILURE(status)) { + return; + } + + MeasureUnitImpl temp; + const MeasureUnitImpl &impl = MeasureUnitImpl::forMeasureUnit(mixedUnit, temp, status); + // Defensive, for production code: + if (impl.complexity != UMEASURE_UNIT_MIXED) { + // Should be using the normal LongNameHandler + status = U_UNSUPPORTED_ERROR; + return; + } + + fillIn->fMixedUnitCount = impl.singleUnits.length(); + fillIn->fMixedUnitData.adoptInstead(new UnicodeString[fillIn->fMixedUnitCount * ARRAY_LENGTH]); + for (int32_t i = 0; i < fillIn->fMixedUnitCount; i++) { + // Grab data for each of the components. + UnicodeString *unitData = &fillIn->fMixedUnitData[i * ARRAY_LENGTH]; + // TODO(CLDR-14502): check from the CLDR-14502 ticket whether this + // propagation of unitDisplayCase is correct: + getMeasureData(loc, impl.singleUnits[i]->build(status), width, unitDisplayCase, unitData, + status); + // TODO(ICU-21494): if we add support for gender for mixed units, we may + // need maybeCalculateGender() here. + } + + // TODO(icu-units#120): Make sure ICU doesn't output zero-valued + // high-magnitude fields + // * for mixed units count N, produce N listFormatters, one for each subset + // that might be formatted. + UListFormatterWidth listWidth = ULISTFMT_WIDTH_SHORT; + if (width == UNUM_UNIT_WIDTH_NARROW) { + listWidth = ULISTFMT_WIDTH_NARROW; + } else if (width == UNUM_UNIT_WIDTH_FULL_NAME) { + // This might be the same as SHORT in most languages: + listWidth = ULISTFMT_WIDTH_WIDE; + } + fillIn->fListFormatter.adoptInsteadAndCheckErrorCode( + ListFormatter::createInstance(loc, ULISTFMT_TYPE_UNITS, listWidth, status), status); + // TODO(ICU-21494): grab gender of each unit, calculate the gender + // associated with this list formatter, save it for later. + fillIn->rules = rules; + fillIn->parent = parent; + + // We need a localised NumberFormatter for the numbers of the bigger units + // (providing Arabic numerals, for example). + fillIn->fNumberFormatter = NumberFormatter::withLocale(loc); +} + +void MixedUnitLongNameHandler::processQuantity(DecimalQuantity &quantity, MicroProps µs, + UErrorCode &status) const { + U_ASSERT(fMixedUnitCount > 1); + if (parent != nullptr) { + parent->processQuantity(quantity, micros, status); + } + micros.modOuter = getMixedUnitModifier(quantity, micros, status); +} + +const Modifier *MixedUnitLongNameHandler::getMixedUnitModifier(DecimalQuantity &quantity, + MicroProps µs, + UErrorCode &status) const { + if (micros.mixedMeasuresCount == 0) { + U_ASSERT(micros.mixedMeasuresCount > 0); // Mixed unit: we must have more than one unit value + status = U_UNSUPPORTED_ERROR; + return µs.helpers.emptyWeakModifier; + } + + // Algorithm: + // + // For the mixed-units measurement of: "3 yard, 1 foot, 2.6 inch", we should + // find "3 yard" and "1 foot" in micros.mixedMeasures. + // + // Obtain long-names with plural forms corresponding to measure values: + // * {0} yards, {0} foot, {0} inches + // + // Format the integer values appropriately and modify with the format + // strings: + // - 3 yards, 1 foot + // + // Use ListFormatter to combine, with one placeholder: + // - 3 yards, 1 foot and {0} inches + // + // Return a SimpleModifier for this pattern, letting the rest of the + // pipeline take care of the remaining inches. + + LocalArray outputMeasuresList(new UnicodeString[fMixedUnitCount], status); + if (U_FAILURE(status)) { + return µs.helpers.emptyWeakModifier; + } + + StandardPlural::Form quantityPlural = StandardPlural::Form::OTHER; + for (int32_t i = 0; i < micros.mixedMeasuresCount; i++) { + DecimalQuantity fdec; + + // If numbers are negative, only the first number needs to have its + // negative sign formatted. + int64_t number = i > 0 ? std::abs(micros.mixedMeasures[i]) : micros.mixedMeasures[i]; + + if (micros.indexOfQuantity == i) { // Insert placeholder for `quantity` + // If quantity is not the first value and quantity is negative + if (micros.indexOfQuantity > 0 && quantity.isNegative()) { + quantity.negate(); + } + + StandardPlural::Form quantityPlural = + utils::getPluralSafe(micros.rounder, rules, quantity, status); + UnicodeString quantityFormatWithPlural = + getWithPlural(&fMixedUnitData[i * ARRAY_LENGTH], quantityPlural, status); + SimpleFormatter quantityFormatter(quantityFormatWithPlural, 0, 1, status); + quantityFormatter.format(UnicodeString(u"{0}"), outputMeasuresList[i], status); + } else { + fdec.setToLong(number); + StandardPlural::Form pluralForm = utils::getStandardPlural(rules, fdec); + UnicodeString simpleFormat = + getWithPlural(&fMixedUnitData[i * ARRAY_LENGTH], pluralForm, status); + SimpleFormatter compiledFormatter(simpleFormat, 0, 1, status); + UnicodeString num; + auto appendable = UnicodeStringAppendable(num); + + fNumberFormatter.formatDecimalQuantity(fdec, status).appendTo(appendable, status); + compiledFormatter.format(num, outputMeasuresList[i], status); + } + } + + // TODO(ICU-21494): implement gender for lists of mixed units. Presumably we + // can set micros.gender to the gender associated with the list formatter in + // use below (once we have correct support for that). And then document this + // appropriately? "getMixedUnitModifier" doesn't sound like it would do + // something like this. + + // Combine list into a "premixed" pattern + UnicodeString premixedFormatPattern; + fListFormatter->format(outputMeasuresList.getAlias(), fMixedUnitCount, premixedFormatPattern, + status); + SimpleFormatter premixedCompiled(premixedFormatPattern, 0, 1, status); + if (U_FAILURE(status)) { + return µs.helpers.emptyWeakModifier; + } + + micros.helpers.mixedUnitModifier = + SimpleModifier(premixedCompiled, kUndefinedField, false, {this, SIGNUM_POS_ZERO, quantityPlural}); + return µs.helpers.mixedUnitModifier; +} + +const Modifier *MixedUnitLongNameHandler::getModifier(Signum /*signum*/, + StandardPlural::Form /*plural*/) const { + // TODO(icu-units#28): investigate this method when investigating where + // ModifierStore::getModifier() gets used. To be sure it remains + // unreachable: + UPRV_UNREACHABLE; + return nullptr; +} + +LongNameMultiplexer *LongNameMultiplexer::forMeasureUnits(const Locale &loc, + const MaybeStackVector &units, + const UNumberUnitWidth &width, + const char *unitDisplayCase, + const PluralRules *rules, + const MicroPropsGenerator *parent, + UErrorCode &status) { + LocalPointer result(new LongNameMultiplexer(parent), status); + if (U_FAILURE(status)) { + return nullptr; + } + U_ASSERT(units.length() > 0); + if (result->fHandlers.resize(units.length()) == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } + result->fMeasureUnits.adoptInstead(new MeasureUnit[units.length()]); + for (int32_t i = 0, length = units.length(); i < length; i++) { + const MeasureUnit &unit = *units[i]; + result->fMeasureUnits[i] = unit; + if (unit.getComplexity(status) == UMEASURE_UNIT_MIXED) { + MixedUnitLongNameHandler *mlnh = result->fMixedUnitHandlers.createAndCheckErrorCode(status); + MixedUnitLongNameHandler::forMeasureUnit(loc, unit, width, unitDisplayCase, rules, NULL, + mlnh, status); + result->fHandlers[i] = mlnh; + } else { + LongNameHandler *lnh = result->fLongNameHandlers.createAndCheckErrorCode(status); + LongNameHandler::forMeasureUnit(loc, unit, width, unitDisplayCase, rules, NULL, lnh, status); + result->fHandlers[i] = lnh; + } + if (U_FAILURE(status)) { + return nullptr; + } + } + return result.orphan(); +} + +void LongNameMultiplexer::processQuantity(DecimalQuantity &quantity, MicroProps µs, + UErrorCode &status) const { + // We call parent->processQuantity() from the Multiplexer, instead of + // letting LongNameHandler handle it: we don't know which LongNameHandler to + // call until we've called the parent! + fParent->processQuantity(quantity, micros, status); + + // Call the correct LongNameHandler based on outputUnit + for (int i = 0; i < fHandlers.getCapacity(); i++) { + if (fMeasureUnits[i] == micros.outputUnit) { + fHandlers[i]->processQuantity(quantity, micros, status); + return; + } + } + if (U_FAILURE(status)) { + return; + } + // We shouldn't receive any outputUnit for which we haven't already got a + // LongNameHandler: + status = U_INTERNAL_PROGRAM_ERROR; +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/number_longnames.h b/deps/icu-small/source/i18n/number_longnames.h index a19425aa268af62ef19c6498b2321b4599ad2b48..bca55e010317dc8e89a4ece75f40a32edd7b7e51 100644 --- a/deps/icu-small/source/i18n/number_longnames.h +++ b/deps/icu-small/source/i18n/number_longnames.h @@ -7,6 +7,8 @@ #ifndef __NUMBER_LONGNAMES_H__ #define __NUMBER_LONGNAMES_H__ +#include "cmemory.h" +#include "unicode/listformatter.h" #include "unicode/uversion.h" #include "number_utils.h" #include "number_modifiers.h" @@ -14,6 +16,8 @@ U_NAMESPACE_BEGIN namespace number { namespace impl { +// LongNameHandler takes care of formatting currency and measurement unit names, +// as well as populating the gender of measure units. class LongNameHandler : public MicroPropsGenerator, public ModifierStore, public UMemory { public: static UnicodeString getUnitDisplayName( @@ -22,6 +26,8 @@ class LongNameHandler : public MicroPropsGenerator, public ModifierStore, public UNumberUnitWidth width, UErrorCode& status); + // This function does not support inflections or other newer NumberFormatter + // features: it exists to support the older not-recommended MeasureFormat. static UnicodeString getUnitPattern( const Locale& loc, const MeasureUnit& unit, @@ -33,34 +39,230 @@ class LongNameHandler : public MicroPropsGenerator, public ModifierStore, public forCurrencyLongNames(const Locale &loc, const CurrencyUnit ¤cy, const PluralRules *rules, const MicroPropsGenerator *parent, UErrorCode &status); - static LongNameHandler* - forMeasureUnit(const Locale &loc, const MeasureUnit &unit, const MeasureUnit &perUnit, - const UNumberUnitWidth &width, const PluralRules *rules, - const MicroPropsGenerator *parent, UErrorCode &status); + /** + * Construct a localized LongNameHandler for the specified MeasureUnit. + * + * Mixed units are not supported, use MixedUnitLongNameHandler::forMeasureUnit. + * + * This function uses a fillIn intead of returning a pointer, because we + * want to fill in instances in a MemoryPool (which cannot adopt pointers it + * didn't create itself). + * + * @param loc The desired locale. + * @param unitRef The measure unit to construct a LongNameHandler for. + * @param width Specifies the desired unit rendering. + * @param unitDisplayCase Specifies the desired grammatical case. If the + * specified case is not found, we fall back to nominative or no-case. + * @param rules Does not take ownership. + * @param parent Does not take ownership. + * @param fillIn Required. + */ + static void forMeasureUnit(const Locale &loc, + const MeasureUnit &unitRef, + const UNumberUnitWidth &width, + const char *unitDisplayCase, + const PluralRules *rules, + const MicroPropsGenerator *parent, + LongNameHandler *fillIn, + UErrorCode &status); + /** + * Selects the plural-appropriate Modifier from the set of fModifiers based + * on the plural form. + */ void processQuantity(DecimalQuantity &quantity, MicroProps µs, UErrorCode &status) const U_OVERRIDE; const Modifier* getModifier(Signum signum, StandardPlural::Form plural) const U_OVERRIDE; private: + // A set of pre-computed modifiers, one for each plural form. SimpleModifier fModifiers[StandardPlural::Form::COUNT]; + // Not owned const PluralRules *rules; + // Not owned const MicroPropsGenerator *parent; + // Grammatical gender of the formatted result. Not owned: must point at + // static or global strings. + const char *gender = ""; LongNameHandler(const PluralRules *rules, const MicroPropsGenerator *parent) - : rules(rules), parent(parent) {} + : rules(rules), parent(parent) { + } - static LongNameHandler* - forCompoundUnit(const Locale &loc, const MeasureUnit &unit, const MeasureUnit &perUnit, - const UNumberUnitWidth &width, const PluralRules *rules, - const MicroPropsGenerator *parent, UErrorCode &status); + LongNameHandler() : rules(nullptr), parent(nullptr) { + } + + // Enables MemoryPool::emplaceBack(): requires access to + // the private constructors. + friend class MemoryPool; + + // Allow macrosToMicroGenerator to call the private default constructor. + friend class NumberFormatterImpl; + + // Fills in LongNameHandler fields for formatting units identified `unit`. + static void forArbitraryUnit(const Locale &loc, + const MeasureUnit &unit, + const UNumberUnitWidth &width, + const char *unitDisplayCase, + LongNameHandler *fillIn, + UErrorCode &status); + // Roughly corresponds to patternTimes(...) in the spec: + // https://unicode.org/reports/tr35/tr35-general.html#compound-units + // + // productUnit is an rvalue reference to indicate this function consumes it, + // leaving it in a not-useful / undefined state. + static void processPatternTimes(MeasureUnitImpl &&productUnit, + Locale loc, + const UNumberUnitWidth &width, + const char *caseVariant, + UnicodeString *outArray, + UErrorCode &status); + + // Sets fModifiers to use the patterns from `simpleFormats`. void simpleFormatsToModifiers(const UnicodeString *simpleFormats, Field field, UErrorCode &status); + + // Sets fModifiers to a combination of `leadFormats` (one per plural form) + // and `trailFormat` appended to each. + // + // With a leadFormat of "{0}m" and a trailFormat of "{0}/s", it produces a + // pattern of "{0}m/s" by inserting each leadFormat pattern into trailFormat. void multiSimpleFormatsToModifiers(const UnicodeString *leadFormats, UnicodeString trailFormat, Field field, UErrorCode &status); }; +// Similar to LongNameHandler, but only for MIXED units. +class MixedUnitLongNameHandler : public MicroPropsGenerator, public ModifierStore, public UMemory { + public: + /** + * Construct a localized MixedUnitLongNameHandler for the specified + * MeasureUnit. It must be a MIXED unit. + * + * This function uses a fillIn intead of returning a pointer, because we + * want to fill in instances in a MemoryPool (which cannot adopt pointers it + * didn't create itself). + * + * @param loc The desired locale. + * @param mixedUnit The mixed measure unit to construct a + * MixedUnitLongNameHandler for. + * @param width Specifies the desired unit rendering. + * @param unitDisplayCase Specifies the desired grammatical case. If the + * specified case is not found, we fall back to nominative or no-case. + * @param rules Does not take ownership. + * @param parent Does not take ownership. + * @param fillIn Required. + */ + static void forMeasureUnit(const Locale &loc, + const MeasureUnit &mixedUnit, + const UNumberUnitWidth &width, + const char *unitDisplayCase, + const PluralRules *rules, + const MicroPropsGenerator *parent, + MixedUnitLongNameHandler *fillIn, + UErrorCode &status); + + /** + * Produces a plural-appropriate Modifier for a mixed unit: `quantity` is + * taken as the final smallest unit, while the larger unit values must be + * provided via `micros.mixedMeasures`. + */ + void processQuantity(DecimalQuantity &quantity, MicroProps µs, + UErrorCode &status) const U_OVERRIDE; + + // Required for ModifierStore. And ModifierStore is required by + // SimpleModifier constructor's last parameter. We assert his will never get + // called though. + const Modifier *getModifier(Signum signum, StandardPlural::Form plural) const U_OVERRIDE; + + private: + // Not owned + const PluralRules *rules; + + // Not owned + const MicroPropsGenerator *parent; + + // Total number of units in the MeasureUnit this handler was configured for: + // for "foot-and-inch", this will be 2. + int32_t fMixedUnitCount = 1; + + // Stores unit data for each of the individual units. For each unit, it + // stores ARRAY_LENGTH strings, as returned by getMeasureData. (Each unit + // with index `i` has ARRAY_LENGTH strings starting at index + // `i*ARRAY_LENGTH` in this array.) + LocalArray fMixedUnitData; + + // Formats the larger units of Mixed Unit measurements. + LocalizedNumberFormatter fNumberFormatter; + + // Joins mixed units together. + LocalPointer fListFormatter; + + MixedUnitLongNameHandler(const PluralRules *rules, const MicroPropsGenerator *parent) + : rules(rules), parent(parent) { + } + + MixedUnitLongNameHandler() : rules(nullptr), parent(nullptr) { + } + + // Allow macrosToMicroGenerator to call the private default constructor. + friend class NumberFormatterImpl; + + // Enables MemoryPool::emplaceBack(): requires access to + // the private constructors. + friend class MemoryPool; + + // For a mixed unit, returns a Modifier that takes only one parameter: the + // smallest and final unit of the set. The bigger units' values and labels + // get baked into this Modifier, together with the unit label of the final + // unit. + const Modifier *getMixedUnitModifier(DecimalQuantity &quantity, MicroProps µs, + UErrorCode &status) const; +}; + +/** + * A MicroPropsGenerator that multiplexes between different LongNameHandlers, + * depending on the outputUnit. + * + * See processQuantity() for the input requirements. + */ +class LongNameMultiplexer : public MicroPropsGenerator, public UMemory { + public: + // Produces a multiplexer for LongNameHandlers, one for each unit in + // `units`. An individual unit might be a mixed unit. + static LongNameMultiplexer *forMeasureUnits(const Locale &loc, + const MaybeStackVector &units, + const UNumberUnitWidth &width, + const char *unitDisplayCase, + const PluralRules *rules, + const MicroPropsGenerator *parent, + UErrorCode &status); + + // The output unit must be provided via `micros.outputUnit`, it must match + // one of the units provided to the factory function. + void processQuantity(DecimalQuantity &quantity, MicroProps µs, + UErrorCode &status) const U_OVERRIDE; + + private: + /** + * Because we only know which LongNameHandler we wish to call after calling + * earlier MicroPropsGenerators in the chain, LongNameMultiplexer keeps the + * parent link, while the LongNameHandlers are given no parents. + */ + MemoryPool fLongNameHandlers; + MemoryPool fMixedUnitHandlers; + // Unowned pointers to instances owned by MaybeStackVectors. + MaybeStackArray fHandlers; + // Each MeasureUnit corresponds to the same-index MicroPropsGenerator + // pointed to in fHandlers. + LocalArray fMeasureUnits; + + const MicroPropsGenerator *fParent; + + LongNameMultiplexer(const MicroPropsGenerator *parent) : fParent(parent) { + } +}; + } // namespace impl } // namespace number U_NAMESPACE_END diff --git a/deps/icu-small/source/i18n/number_mapper.cpp b/deps/icu-small/source/i18n/number_mapper.cpp index ec617438c9a9e3a5adedb2a05f8edce808e61925..e2a0d284b7cf5d4c50a494267fb7ff4533c25c66 100644 --- a/deps/icu-small/source/i18n/number_mapper.cpp +++ b/deps/icu-small/source/i18n/number_mapper.cpp @@ -92,6 +92,8 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert int32_t minSig = properties.minimumSignificantDigits; int32_t maxSig = properties.maximumSignificantDigits; double roundingIncrement = properties.roundingIncrement; + // Not assigning directly to macros.roundingMode here: we change + // roundingMode if and when we also change macros.precision. RoundingMode roundingMode = properties.roundingMode.getOrDefault(UNUM_ROUND_HALFEVEN); bool explicitMinMaxFrac = minFrac != -1 || maxFrac != -1; bool explicitMinMaxSig = minSig != -1 || maxSig != -1; @@ -145,7 +147,7 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert precision = Precision::constructCurrency(currencyUsage); } if (!precision.isBogus()) { - precision.fRoundingMode = roundingMode; + macros.roundingMode = roundingMode; macros.precision = precision; } @@ -239,7 +241,7 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert // TODO: Reset maxSig_ = 1 + minFrac_ to follow the spec. macros.precision = Precision::constructSignificant(minSig_, maxSig_); } - macros.precision.fRoundingMode = roundingMode; + macros.roundingMode = roundingMode; } } diff --git a/deps/icu-small/source/i18n/number_mapper.h b/deps/icu-small/source/i18n/number_mapper.h index d18b8b3c438cf42c48a288337ec51c57cbd6c49d..9ecd776b3b4795512159c3e60c3b2c32cbb81c50 100644 --- a/deps/icu-small/source/i18n/number_mapper.h +++ b/deps/icu-small/source/i18n/number_mapper.h @@ -136,6 +136,16 @@ class AutoAffixPatternProvider { } } + inline void setTo(const AffixPatternProvider* provider, UErrorCode& status) { + if (auto ptr = dynamic_cast(provider)) { + propertiesAPP = *ptr; + } else if (auto ptr = dynamic_cast(provider)) { + currencyPluralInfoAPP = *ptr; + } else { + status = U_INTERNAL_PROGRAM_ERROR; + } + } + inline const AffixPatternProvider& get() const { if (!currencyPluralInfoAPP.isBogus()) { return currencyPluralInfoAPP; @@ -153,9 +163,9 @@ class AutoAffixPatternProvider { /** * A struct for ownership of a few objects needed for formatting. */ -struct DecimalFormatWarehouse { +struct DecimalFormatWarehouse : public UMemory { AutoAffixPatternProvider affixProvider; - + LocalPointer rules; }; diff --git a/deps/icu-small/source/i18n/number_microprops.h b/deps/icu-small/source/i18n/number_microprops.h index 56512f5e6f94ac8c239b4c6cb4bd91c34db9e666..a18d5fc470eda1559bfd12f8bbd84a92b2e73590 100644 --- a/deps/icu-small/source/i18n/number_microprops.h +++ b/deps/icu-small/source/i18n/number_microprops.h @@ -22,6 +22,55 @@ U_NAMESPACE_BEGIN namespace number { namespace impl { +/** + * A copyable container for the integer values of mixed unit measurements. + * + * If memory allocation fails during copying, no values are copied and status is + * set to U_MEMORY_ALLOCATION_ERROR. + */ +class IntMeasures : public MaybeStackArray { + public: + /** + * Default constructor initializes with internal T[stackCapacity] buffer. + * + * Stack Capacity: most mixed units are expected to consist of two or three + * subunits, so one or two integer measures should be enough. + */ + IntMeasures() : MaybeStackArray() {} + + /** + * Copy constructor. + * + * If memory allocation fails during copying, no values are copied and + * status is set to U_MEMORY_ALLOCATION_ERROR. + */ + IntMeasures(const IntMeasures &other) : MaybeStackArray() { + this->operator=(other); + } + + // Assignment operator + IntMeasures &operator=(const IntMeasures &rhs) { + if (this == &rhs) { + return *this; + } + copyFrom(rhs, status); + return *this; + } + + /** Move constructor */ + IntMeasures(IntMeasures &&src) = default; + + /** Move assignment */ + IntMeasures &operator=(IntMeasures &&src) = default; + + UErrorCode status = U_ZERO_ERROR; +}; + +/** + * MicroProps is the first MicroPropsGenerator that should be should be called, + * producing an initialized MicroProps instance that will be passed on and + * modified throughout the rest of the chain of MicroPropsGenerator instances. + */ struct MicroProps : public MicroPropsGenerator { // NOTE: All of these fields are properly initialized in NumberFormatterImpl. @@ -34,21 +83,59 @@ struct MicroProps : public MicroPropsGenerator { bool useCurrency; char nsName[9]; + // No ownership: must point at a string which will outlive MicroProps + // instances, e.g. a string with static storage duration, or just a string + // that will never be deallocated or modified. + const char *gender; + // Note: This struct has no direct ownership of the following pointers. const DecimalFormatSymbols* symbols; + + // Pointers to Modifiers provided by the number formatting pipeline (when + // the value is known): + + // A Modifier provided by LongNameHandler, used for currency long names and + // units. If there is no LongNameHandler needed, this should be an + // EmptyModifier. (This is typically the third modifier applied.) const Modifier* modOuter; + // A Modifier for short currencies and compact notation. (This is typically + // the second modifier applied.) const Modifier* modMiddle = nullptr; + // A Modifier provided by ScientificHandler, used for scientific notation. + // This is typically the first modifier applied. const Modifier* modInner; // The following "helper" fields may optionally be used during the MicroPropsGenerator. // They live here to retain memory. struct { + // The ScientificModifier for which ScientificHandler is responsible. + // ScientificHandler::processQuantity() modifies this Modifier. ScientificModifier scientificModifier; + // EmptyModifier used for modOuter EmptyModifier emptyWeakModifier{false}; + // EmptyModifier used for modInner EmptyModifier emptyStrongModifier{true}; MultiplierFormatHandler multiplier; + // A Modifier used for Mixed Units. When formatting mixed units, + // LongNameHandler assigns this Modifier. + SimpleModifier mixedUnitModifier; } helpers; + // The MeasureUnit with which the output is represented. May also have + // UMEASURE_UNIT_MIXED complexity, in which case mixedMeasures comes into + // play. + MeasureUnit outputUnit; + + // Contains all the values of each unit in mixed units. For quantity (which is the floating value of + // the smallest unit in the mixed unit), the value stores in `quantity`. + // NOTE: the value of quantity in `mixedMeasures` will be left unset. + IntMeasures mixedMeasures; + + // Points to quantity position, -1 if the position is not set yet. + int32_t indexOfQuantity = -1; + + // Number of mixedMeasures that have been populated + int32_t mixedMeasuresCount = 0; MicroProps() = default; @@ -56,7 +143,23 @@ struct MicroProps : public MicroPropsGenerator { MicroProps& operator=(const MicroProps& other) = default; - void processQuantity(DecimalQuantity&, MicroProps& micros, UErrorCode& status) const U_OVERRIDE { + /** + * As MicroProps is the "base instance", this implementation of + * MicroPropsGenerator::processQuantity() just ensures that the output + * `micros` is correctly initialized. + * + * For the "safe" invocation of this function, micros must not be *this, + * such that a copy of the base instance is made. For the "unsafe" path, + * this function can be used only once, because the base MicroProps instance + * will be modified and thus not be available for re-use. + * + * @param quantity The quantity for consideration and optional mutation. + * @param micros The MicroProps instance to populate. If this parameter is + * not already `*this`, it will be overwritten with a copy of `*this`. + */ + void processQuantity(DecimalQuantity &quantity, MicroProps µs, + UErrorCode &status) const U_OVERRIDE { + (void) quantity; (void) status; if (this == µs) { // Unsafe path: no need to perform a copy. @@ -65,6 +168,7 @@ struct MicroProps : public MicroPropsGenerator { U_ASSERT(exhausted); } else { // Safe path: copy self into the output micros. + U_ASSERT(!exhausted); micros = *this; } } diff --git a/deps/icu-small/source/i18n/number_modifiers.cpp b/deps/icu-small/source/i18n/number_modifiers.cpp index 3becb7ba852336a05d324d97a6288d76ac21ae00..b7d825f499e4d2bf2f3ffa4f10bb716f254aa11d 100644 --- a/deps/icu-small/source/i18n/number_modifiers.cpp +++ b/deps/icu-small/source/i18n/number_modifiers.cpp @@ -25,13 +25,13 @@ const int32_t ARG_NUM_LIMIT = 0x100; icu::UInitOnce gDefaultCurrencySpacingInitOnce = U_INITONCE_INITIALIZER; UnicodeSet *UNISET_DIGIT = nullptr; -UnicodeSet *UNISET_NOTS = nullptr; +UnicodeSet *UNISET_NOTSZ = nullptr; UBool U_CALLCONV cleanupDefaultCurrencySpacing() { delete UNISET_DIGIT; UNISET_DIGIT = nullptr; - delete UNISET_NOTS; - UNISET_NOTS = nullptr; + delete UNISET_NOTSZ; + UNISET_NOTSZ = nullptr; gDefaultCurrencySpacingInitOnce.reset(); return TRUE; } @@ -39,13 +39,13 @@ UBool U_CALLCONV cleanupDefaultCurrencySpacing() { void U_CALLCONV initDefaultCurrencySpacing(UErrorCode &status) { ucln_i18n_registerCleanup(UCLN_I18N_CURRENCY_SPACING, cleanupDefaultCurrencySpacing); UNISET_DIGIT = new UnicodeSet(UnicodeString(u"[:digit:]"), status); - UNISET_NOTS = new UnicodeSet(UnicodeString(u"[:^S:]"), status); - if (UNISET_DIGIT == nullptr || UNISET_NOTS == nullptr) { + UNISET_NOTSZ = new UnicodeSet(UnicodeString(u"[[:^S:]&[:^Z:]]"), status); + if (UNISET_DIGIT == nullptr || UNISET_NOTSZ == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; return; } UNISET_DIGIT->freeze(); - UNISET_NOTS->freeze(); + UNISET_NOTSZ->freeze(); } } // namespace @@ -469,8 +469,8 @@ CurrencySpacingEnabledModifier::getUnicodeSet(const DecimalFormatSymbols &symbol status); if (pattern.compare(u"[:digit:]", -1) == 0) { return *UNISET_DIGIT; - } else if (pattern.compare(u"[:^S:]", -1) == 0) { - return *UNISET_NOTS; + } else if (pattern.compare(u"[[:^S:]&[:^Z:]]", -1) == 0) { + return *UNISET_NOTSZ; } else { return UnicodeSet(pattern, status); } diff --git a/deps/icu-small/source/i18n/number_multiplier.cpp b/deps/icu-small/source/i18n/number_multiplier.cpp index 8f07e548de121b57b31a0d06badd2086e4736f8e..58e1e441bd28c55096c8459ceaa0af8b9dceb5cd 100644 --- a/deps/icu-small/source/i18n/number_multiplier.cpp +++ b/deps/icu-small/source/i18n/number_multiplier.cpp @@ -46,6 +46,7 @@ Scale::Scale(const Scale& other) } Scale& Scale::operator=(const Scale& other) { + if (this == &other) { return *this; } // self-assignment: no-op fMagnitude = other.fMagnitude; if (other.fArbitrary != nullptr) { UErrorCode localStatus = U_ZERO_ERROR; diff --git a/deps/icu-small/source/i18n/number_output.cpp b/deps/icu-small/source/i18n/number_output.cpp index 40192a9225b9de98635d991b5f55457999ef4108..2c2c25eaedb4270a91211824e5df7811217d1c63 100644 --- a/deps/icu-small/source/i18n/number_output.cpp +++ b/deps/icu-small/source/i18n/number_output.cpp @@ -5,11 +5,13 @@ #if !UCONFIG_NO_FORMATTING +#include "unicode/measunit.h" #include "unicode/numberformatter.h" #include "number_utypes.h" #include "util.h" #include "number_decimalquantity.h" #include "number_decnum.h" +#include "numrange_impl.h" U_NAMESPACE_BEGIN namespace number { @@ -32,6 +34,16 @@ void FormattedNumber::getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpi fData->getAllFieldPositions(fpih, status); } +MeasureUnit FormattedNumber::getOutputUnit(UErrorCode& status) const { + UPRV_FORMATTED_VALUE_METHOD_GUARD(MeasureUnit()) + return fData->outputUnit; +} + +const char *FormattedNumber::getGender(UErrorCode &status) const { + UPRV_FORMATTED_VALUE_METHOD_GUARD("") + return fData->gender; +} + void FormattedNumber::getDecimalQuantity(impl::DecimalQuantity& output, UErrorCode& status) const { UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG) output = fData->quantity; @@ -41,6 +53,32 @@ void FormattedNumber::getDecimalQuantity(impl::DecimalQuantity& output, UErrorCo impl::UFormattedNumberData::~UFormattedNumberData() = default; +UPRV_FORMATTED_VALUE_SUBCLASS_AUTO_IMPL(FormattedNumberRange) + +#define UPRV_NOARG + +void FormattedNumberRange::getDecimalNumbers(ByteSink& sink1, ByteSink& sink2, UErrorCode& status) const { + UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG) + impl::DecNum decnum1; + impl::DecNum decnum2; + fData->quantity1.toDecNum(decnum1, status).toString(sink1, status); + fData->quantity2.toDecNum(decnum2, status).toString(sink2, status); +} + +UNumberRangeIdentityResult FormattedNumberRange::getIdentityResult(UErrorCode& status) const { + UPRV_FORMATTED_VALUE_METHOD_GUARD(UNUM_IDENTITY_RESULT_NOT_EQUAL) + return fData->identityResult; +} + +const impl::UFormattedNumberRangeData* FormattedNumberRange::getData(UErrorCode& status) const { + UPRV_FORMATTED_VALUE_METHOD_GUARD(nullptr) + return fData; +} + + +impl::UFormattedNumberRangeData::~UFormattedNumberRangeData() = default; + + } // namespace number U_NAMESPACE_END diff --git a/deps/icu-small/source/i18n/number_patternmodifier.cpp b/deps/icu-small/source/i18n/number_patternmodifier.cpp index 45602942aefe8e7acc3e74e16339f9554e761771..314e7cb75ee169c86e13161d8045f9fe255b6ad0 100644 --- a/deps/icu-small/source/i18n/number_patternmodifier.cpp +++ b/deps/icu-small/source/i18n/number_patternmodifier.cpp @@ -294,14 +294,20 @@ UnicodeString MutablePatternModifier::getSymbol(AffixPatternType type) const { case AffixPatternType::TYPE_PERMILLE: return fSymbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPerMillSymbol); case AffixPatternType::TYPE_CURRENCY_SINGLE: { - // UnitWidth ISO and HIDDEN overrides the singular currency symbol. - if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE) { + switch (fUnitWidth) { + case UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW: + return fCurrencySymbols.getNarrowCurrencySymbol(localStatus); + case UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT: + return fCurrencySymbols.getCurrencySymbol(localStatus); + case UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE: return fCurrencySymbols.getIntlCurrencySymbol(localStatus); - } else if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_HIDDEN) { + case UNumberUnitWidth::UNUM_UNIT_WIDTH_FORMAL: + return fCurrencySymbols.getFormalCurrencySymbol(localStatus); + case UNumberUnitWidth::UNUM_UNIT_WIDTH_VARIANT: + return fCurrencySymbols.getVariantCurrencySymbol(localStatus); + case UNumberUnitWidth::UNUM_UNIT_WIDTH_HIDDEN: return UnicodeString(); - } else if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW) { - return fCurrencySymbols.getNarrowCurrencySymbol(localStatus); - } else { + default: return fCurrencySymbols.getCurrencySymbol(localStatus); } } diff --git a/deps/icu-small/source/i18n/number_patternstring.cpp b/deps/icu-small/source/i18n/number_patternstring.cpp index 9d845056069b800f78f283102a54519f199505dd..ac9e8b7e8e4d7521841a2f8f01acc04e1467b8c8 100644 --- a/deps/icu-small/source/i18n/number_patternstring.cpp +++ b/deps/icu-small/source/i18n/number_patternstring.cpp @@ -1106,6 +1106,20 @@ PatternSignType PatternStringUtils::resolveSignDisplay(UNumberSignDisplay signDi } break; + case UNUM_SIGN_NEGATIVE: + case UNUM_SIGN_ACCOUNTING_NEGATIVE: + switch (signum) { + case SIGNUM_NEG: + return PATTERN_SIGN_TYPE_NEG; + case SIGNUM_NEG_ZERO: + case SIGNUM_POS_ZERO: + case SIGNUM_POS: + return PATTERN_SIGN_TYPE_POS; + default: + break; + } + break; + case UNUM_SIGN_NEVER: return PATTERN_SIGN_TYPE_POS; diff --git a/deps/icu-small/source/i18n/number_rounding.cpp b/deps/icu-small/source/i18n/number_rounding.cpp index 3ffce673ad08856de61e26297044f518a5e84f2d..40392ee857e493dd3ff3bc4fa7afff437eba7b89 100644 --- a/deps/icu-small/source/i18n/number_rounding.cpp +++ b/deps/icu-small/source/i18n/number_rounding.cpp @@ -5,13 +5,16 @@ #if !UCONFIG_NO_FORMATTING +#include "charstr.h" #include "uassert.h" #include "unicode/numberformatter.h" #include "number_types.h" #include "number_decimalquantity.h" #include "double-conversion.h" #include "number_roundingutils.h" +#include "number_skeletons.h" #include "putilimp.h" +#include "string_segment.h" using namespace icu; using namespace icu::number; @@ -19,6 +22,39 @@ using namespace icu::number::impl; using double_conversion::DoubleToStringConverter; +using icu::StringSegment; + +void number::impl::parseIncrementOption(const StringSegment &segment, + Precision &outPrecision, + UErrorCode &status) { + // Need to do char <-> UChar conversion... + U_ASSERT(U_SUCCESS(status)); + CharString buffer; + SKELETON_UCHAR_TO_CHAR(buffer, segment.toTempUnicodeString(), 0, segment.length(), status); + + // Utilize DecimalQuantity/decNumber to parse this for us. + DecimalQuantity dq; + UErrorCode localStatus = U_ZERO_ERROR; + dq.setToDecNumber({buffer.data(), buffer.length()}, localStatus); + if (U_FAILURE(localStatus)) { + // throw new SkeletonSyntaxException("Invalid rounding increment", segment, e); + status = U_NUMBER_SKELETON_SYNTAX_ERROR; + return; + } + double increment = dq.toDouble(); + + // We also need to figure out how many digits. Do a brute force string operation. + int decimalOffset = 0; + while (decimalOffset < segment.length() && segment.charAt(decimalOffset) != '.') { + decimalOffset++; + } + if (decimalOffset == segment.length()) { + outPrecision = Precision::increment(increment); + } else { + int32_t fractionLength = segment.length() - decimalOffset - 1; + outPrecision = Precision::increment(increment).withMinFraction(fractionLength); + } +} namespace { @@ -84,7 +120,7 @@ digits_t roundingutils::doubleFractionLength(double input, int8_t* singleDigit) Precision Precision::unlimited() { - return Precision(RND_NONE, {}, kDefaultMode); + return Precision(RND_NONE, {}); } FractionPrecision Precision::integer() { @@ -157,6 +193,12 @@ Precision Precision::minMaxSignificantDigits(int32_t minSignificantDigits, int32 } } +Precision Precision::trailingZeroDisplay(UNumberTrailingZeroDisplay trailingZeroDisplay) const { + Precision result(*this); // copy constructor + result.fTrailingZeroDisplay = trailingZeroDisplay; + return result; +} + IncrementPrecision Precision::increment(double roundingIncrement) { if (roundingIncrement > 0.0) { return constructIncrement(roundingIncrement, 0); @@ -169,10 +211,32 @@ CurrencyPrecision Precision::currency(UCurrencyUsage currencyUsage) { return constructCurrency(currencyUsage); } +Precision FractionPrecision::withSignificantDigits( + int32_t minSignificantDigits, + int32_t maxSignificantDigits, + UNumberRoundingPriority priority) const { + if (fType == RND_ERROR) { return *this; } // no-op in error state + if (minSignificantDigits >= 1 && + maxSignificantDigits >= minSignificantDigits && + maxSignificantDigits <= kMaxIntFracSig) { + return constructFractionSignificant( + *this, + minSignificantDigits, + maxSignificantDigits, + priority); + } else { + return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR}; + } +} + Precision FractionPrecision::withMinDigits(int32_t minSignificantDigits) const { if (fType == RND_ERROR) { return *this; } // no-op in error state if (minSignificantDigits >= 1 && minSignificantDigits <= kMaxIntFracSig) { - return constructFractionSignificant(*this, minSignificantDigits, -1); + return constructFractionSignificant( + *this, + 1, + minSignificantDigits, + UNUM_ROUNDING_PRIORITY_RELAXED); } else { return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR}; } @@ -181,7 +245,10 @@ Precision FractionPrecision::withMinDigits(int32_t minSignificantDigits) const { Precision FractionPrecision::withMaxDigits(int32_t maxSignificantDigits) const { if (fType == RND_ERROR) { return *this; } // no-op in error state if (maxSignificantDigits >= 1 && maxSignificantDigits <= kMaxIntFracSig) { - return constructFractionSignificant(*this, -1, maxSignificantDigits); + return constructFractionSignificant(*this, + 1, + maxSignificantDigits, + UNUM_ROUNDING_PRIORITY_STRICT); } else { return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR}; } @@ -195,11 +262,11 @@ Precision Precision::withCurrency(const CurrencyUnit ¤cy, UErrorCode &stat double increment = ucurr_getRoundingIncrementForUsage(isoCode, fUnion.currencyUsage, &status); int32_t minMaxFrac = ucurr_getDefaultFractionDigitsForUsage( isoCode, fUnion.currencyUsage, &status); - if (increment != 0.0) { - return constructIncrement(increment, minMaxFrac); - } else { - return constructFraction(minMaxFrac, minMaxFrac); - } + Precision retval = (increment != 0.0) + ? static_cast(constructIncrement(increment, minMaxFrac)) + : static_cast(constructFraction(minMaxFrac, minMaxFrac)); + retval.fTrailingZeroDisplay = fTrailingZeroDisplay; + return retval; } // Public method on CurrencyPrecision subclass @@ -229,7 +296,7 @@ FractionPrecision Precision::constructFraction(int32_t minFrac, int32_t maxFrac) settings.fMaxSig = -1; PrecisionUnion union_; union_.fracSig = settings; - return {RND_FRACTION, union_, kDefaultMode}; + return {RND_FRACTION, union_}; } Precision Precision::constructSignificant(int32_t minSig, int32_t maxSig) { @@ -240,17 +307,22 @@ Precision Precision::constructSignificant(int32_t minSig, int32_t maxSig) { settings.fMaxSig = static_cast(maxSig); PrecisionUnion union_; union_.fracSig = settings; - return {RND_SIGNIFICANT, union_, kDefaultMode}; + return {RND_SIGNIFICANT, union_}; } Precision -Precision::constructFractionSignificant(const FractionPrecision &base, int32_t minSig, int32_t maxSig) { +Precision::constructFractionSignificant( + const FractionPrecision &base, + int32_t minSig, + int32_t maxSig, + UNumberRoundingPriority priority) { FractionSignificantSettings settings = base.fUnion.fracSig; settings.fMinSig = static_cast(minSig); settings.fMaxSig = static_cast(maxSig); + settings.fPriority = priority; PrecisionUnion union_; union_.fracSig = settings; - return {RND_FRACTION_SIGNIFICANT, union_, kDefaultMode}; + return {RND_FRACTION_SIGNIFICANT, union_}; } IncrementPrecision Precision::constructIncrement(double increment, int32_t minFrac) { @@ -270,18 +342,18 @@ IncrementPrecision Precision::constructIncrement(double increment, int32_t minFr // NOTE: In C++, we must return the correct value type with the correct union. // It would be invalid to return a RND_FRACTION here because the methods on the // IncrementPrecision type assume that the union is backed by increment data. - return {RND_INCREMENT_ONE, union_, kDefaultMode}; + return {RND_INCREMENT_ONE, union_}; } else if (singleDigit == 5) { - return {RND_INCREMENT_FIVE, union_, kDefaultMode}; + return {RND_INCREMENT_FIVE, union_}; } else { - return {RND_INCREMENT, union_, kDefaultMode}; + return {RND_INCREMENT, union_}; } } CurrencyPrecision Precision::constructCurrency(UCurrencyUsage usage) { PrecisionUnion union_; union_.currencyUsage = usage; - return {RND_CURRENCY, union_, kDefaultMode}; + return {RND_CURRENCY, union_}; } @@ -341,9 +413,13 @@ RoundingImpl::chooseMultiplierAndApply(impl::DecimalQuantity &input, const impl: /** This is the method that contains the actual rounding logic. */ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const { + if (U_FAILURE(status)) { + return; + } if (fPassThrough) { return; } + int32_t resolvedMinFraction = 0; switch (fPrecision.fType) { case Precision::RND_BOGUS: case Precision::RND_ERROR: @@ -360,8 +436,8 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const getRoundingMagnitudeFraction(fPrecision.fUnion.fracSig.fMaxFrac), fRoundingMode, status); - value.setMinFraction( - uprv_max(0, -getDisplayMagnitudeFraction(fPrecision.fUnion.fracSig.fMinFrac))); + resolvedMinFraction = + uprv_max(0, -getDisplayMagnitudeFraction(fPrecision.fUnion.fracSig.fMinFrac)); break; case Precision::RND_SIGNIFICANT: @@ -369,8 +445,8 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const getRoundingMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMaxSig), fRoundingMode, status); - value.setMinFraction( - uprv_max(0, -getDisplayMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMinSig))); + resolvedMinFraction = + uprv_max(0, -getDisplayMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMinSig)); // Make sure that digits are displayed on zero. if (value.isZeroish() && fPrecision.fUnion.fracSig.fMinSig > 0) { value.setMinInteger(1); @@ -378,23 +454,21 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const break; case Precision::RND_FRACTION_SIGNIFICANT: { - int32_t displayMag = getDisplayMagnitudeFraction(fPrecision.fUnion.fracSig.fMinFrac); - int32_t roundingMag = getRoundingMagnitudeFraction(fPrecision.fUnion.fracSig.fMaxFrac); - if (fPrecision.fUnion.fracSig.fMinSig == -1) { - // Max Sig override - int32_t candidate = getRoundingMagnitudeSignificant( - value, - fPrecision.fUnion.fracSig.fMaxSig); - roundingMag = uprv_max(roundingMag, candidate); + int32_t roundingMag1 = getRoundingMagnitudeFraction(fPrecision.fUnion.fracSig.fMaxFrac); + int32_t roundingMag2 = getRoundingMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMaxSig); + int32_t roundingMag; + if (fPrecision.fUnion.fracSig.fPriority == UNUM_ROUNDING_PRIORITY_RELAXED) { + roundingMag = uprv_min(roundingMag1, roundingMag2); } else { - // Min Sig override - int32_t candidate = getDisplayMagnitudeSignificant( - value, - fPrecision.fUnion.fracSig.fMinSig); - roundingMag = uprv_min(roundingMag, candidate); + roundingMag = uprv_max(roundingMag1, roundingMag2); } value.roundToMagnitude(roundingMag, fRoundingMode, status); - value.setMinFraction(uprv_max(0, -displayMag)); + + int32_t displayMag1 = getDisplayMagnitudeFraction(fPrecision.fUnion.fracSig.fMinFrac); + int32_t displayMag2 = getDisplayMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMinSig); + int32_t displayMag = uprv_min(displayMag1, displayMag2); + resolvedMinFraction = uprv_max(0, -displayMag); + break; } @@ -403,7 +477,7 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const fPrecision.fUnion.increment.fIncrement, fRoundingMode, status); - value.setMinFraction(fPrecision.fUnion.increment.fMinFrac); + resolvedMinFraction = fPrecision.fUnion.increment.fMinFrac; break; case Precision::RND_INCREMENT_ONE: @@ -411,7 +485,7 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const -fPrecision.fUnion.increment.fMaxFrac, fRoundingMode, status); - value.setMinFraction(fPrecision.fUnion.increment.fMinFrac); + resolvedMinFraction = fPrecision.fUnion.increment.fMinFrac; break; case Precision::RND_INCREMENT_FIVE: @@ -419,7 +493,7 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const -fPrecision.fUnion.increment.fMaxFrac, fRoundingMode, status); - value.setMinFraction(fPrecision.fUnion.increment.fMinFrac); + resolvedMinFraction = fPrecision.fUnion.increment.fMinFrac; break; case Precision::RND_CURRENCY: @@ -429,10 +503,17 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const default: UPRV_UNREACHABLE; } + + if (fPrecision.fTrailingZeroDisplay == UNUM_TRAILING_ZERO_AUTO || + // PLURAL_OPERAND_T returns fraction digits as an integer + value.getPluralOperand(PLURAL_OPERAND_T) != 0) { + value.setMinFraction(resolvedMinFraction); + } } void RoundingImpl::apply(impl::DecimalQuantity &value, int32_t minInt, UErrorCode /*status*/) { // This method is intended for the one specific purpose of helping print "00.000E0". + // Question: Is it useful to look at trailingZeroDisplay here? U_ASSERT(isSignificantDigits()); U_ASSERT(value.isZeroish()); value.setMinFraction(fPrecision.fUnion.fracSig.fMinSig - minInt); diff --git a/deps/icu-small/source/i18n/number_roundingutils.h b/deps/icu-small/source/i18n/number_roundingutils.h index 3e37f3195408fe8b3d90560fca64fc5f2a7ba29d..06fadd29fd544e032d367720052b56f4fd47d431 100644 --- a/deps/icu-small/source/i18n/number_roundingutils.h +++ b/deps/icu-small/source/i18n/number_roundingutils.h @@ -8,6 +8,7 @@ #define __NUMBER_ROUNDINGUTILS_H__ #include "number_types.h" +#include "string_segment.h" U_NAMESPACE_BEGIN namespace number { @@ -44,6 +45,9 @@ enum Section { inline bool getRoundingDirection(bool isEven, bool isNegative, Section section, RoundingMode roundingMode, UErrorCode &status) { + if (U_FAILURE(status)) { + return false; + } switch (roundingMode) { case RoundingMode::UNUM_ROUND_UP: // round away from zero @@ -100,6 +104,45 @@ getRoundingDirection(bool isEven, bool isNegative, Section section, RoundingMode } break; + case RoundingMode::UNUM_ROUND_HALF_ODD: + switch (section) { + case SECTION_MIDPOINT: + return !isEven; + case SECTION_LOWER: + return true; + case SECTION_UPPER: + return false; + default: + break; + } + break; + + case RoundingMode::UNUM_ROUND_HALF_CEILING: + switch (section) { + case SECTION_MIDPOINT: + return isNegative; + case SECTION_LOWER: + return true; + case SECTION_UPPER: + return false; + default: + break; + } + break; + + case RoundingMode::UNUM_ROUND_HALF_FLOOR: + switch (section) { + case SECTION_MIDPOINT: + return !isNegative; + case SECTION_LOWER: + return true; + case SECTION_UPPER: + return false; + default: + break; + } + break; + default: break; } @@ -187,8 +230,22 @@ class RoundingImpl { Precision fPrecision; UNumberFormatRoundingMode fRoundingMode; bool fPassThrough = true; // default value + + // Permits access to fPrecision. + friend class units::UnitsRouter; + + // Permits access to fPrecision. + friend class UnitConversionHandler; }; +/** + * Parses Precision-related skeleton strings without knowledge of MacroProps + * - see blueprint_helpers::parseIncrementOption(). + * + * Referencing MacroProps means needing to pull in the .o files that have the + * destructors for the SymbolsWrapper, StringProp, and Scale classes. + */ +void parseIncrementOption(const StringSegment &segment, Precision &outPrecision, UErrorCode &status); } // namespace impl } // namespace number diff --git a/deps/icu-small/source/i18n/number_skeletons.cpp b/deps/icu-small/source/i18n/number_skeletons.cpp index 4ba2647986c755ab7e1cde837cc3ca6732ff7c83..97d74303a4358e33928d6eaf80a13ae66ca153b4 100644 --- a/deps/icu-small/source/i18n/number_skeletons.cpp +++ b/deps/icu-small/source/i18n/number_skeletons.cpp @@ -10,6 +10,7 @@ #define UNISTR_FROM_STRING_EXPLICIT #include "number_decnum.h" +#include "number_roundingutils.h" #include "number_skeletons.h" #include "umutex.h" #include "ucln_in.h" @@ -67,6 +68,9 @@ void U_CALLCONV initNumberSkeletons(UErrorCode& status) { b.add(u"rounding-mode-down", STEM_ROUNDING_MODE_DOWN, status); b.add(u"rounding-mode-up", STEM_ROUNDING_MODE_UP, status); b.add(u"rounding-mode-half-even", STEM_ROUNDING_MODE_HALF_EVEN, status); + b.add(u"rounding-mode-half-odd", STEM_ROUNDING_MODE_HALF_ODD, status); + b.add(u"rounding-mode-half-ceiling", STEM_ROUNDING_MODE_HALF_CEILING, status); + b.add(u"rounding-mode-half-floor", STEM_ROUNDING_MODE_HALF_FLOOR, status); b.add(u"rounding-mode-half-down", STEM_ROUNDING_MODE_HALF_DOWN, status); b.add(u"rounding-mode-half-up", STEM_ROUNDING_MODE_HALF_UP, status); b.add(u"rounding-mode-unnecessary", STEM_ROUNDING_MODE_UNNECESSARY, status); @@ -80,6 +84,8 @@ void U_CALLCONV initNumberSkeletons(UErrorCode& status) { b.add(u"unit-width-short", STEM_UNIT_WIDTH_SHORT, status); b.add(u"unit-width-full-name", STEM_UNIT_WIDTH_FULL_NAME, status); b.add(u"unit-width-iso-code", STEM_UNIT_WIDTH_ISO_CODE, status); + b.add(u"unit-width-formal", STEM_UNIT_WIDTH_FORMAL, status); + b.add(u"unit-width-variant", STEM_UNIT_WIDTH_VARIANT, status); b.add(u"unit-width-hidden", STEM_UNIT_WIDTH_HIDDEN, status); b.add(u"sign-auto", STEM_SIGN_AUTO, status); b.add(u"sign-always", STEM_SIGN_ALWAYS, status); @@ -88,6 +94,8 @@ void U_CALLCONV initNumberSkeletons(UErrorCode& status) { b.add(u"sign-accounting-always", STEM_SIGN_ACCOUNTING_ALWAYS, status); b.add(u"sign-except-zero", STEM_SIGN_EXCEPT_ZERO, status); b.add(u"sign-accounting-except-zero", STEM_SIGN_ACCOUNTING_EXCEPT_ZERO, status); + b.add(u"sign-negative", STEM_SIGN_NEGATIVE, status); + b.add(u"sign-accounting-negative", STEM_SIGN_ACCOUNTING_NEGATIVE, status); b.add(u"decimal-auto", STEM_DECIMAL_AUTO, status); b.add(u"decimal-always", STEM_DECIMAL_ALWAYS, status); if (U_FAILURE(status)) { return; } @@ -97,6 +105,7 @@ void U_CALLCONV initNumberSkeletons(UErrorCode& status) { b.add(u"measure-unit", STEM_MEASURE_UNIT, status); b.add(u"per-measure-unit", STEM_PER_MEASURE_UNIT, status); b.add(u"unit", STEM_UNIT, status); + b.add(u"usage", STEM_UNIT_USAGE, status); b.add(u"currency", STEM_CURRENCY, status); b.add(u"integer-width", STEM_INTEGER_WIDTH, status); b.add(u"numbering-system", STEM_NUMBERING_SYSTEM, status); @@ -117,6 +126,8 @@ void U_CALLCONV initNumberSkeletons(UErrorCode& status) { b.add(u"()!", STEM_SIGN_ACCOUNTING_ALWAYS, status); b.add(u"+?", STEM_SIGN_EXCEPT_ZERO, status); b.add(u"()?", STEM_SIGN_ACCOUNTING_EXCEPT_ZERO, status); + b.add(u"+-", STEM_SIGN_NEGATIVE, status); + b.add(u"()-", STEM_SIGN_ACCOUNTING_NEGATIVE, status); if (U_FAILURE(status)) { return; } // Build the CharsTrie @@ -149,21 +160,6 @@ UPRV_BLOCK_MACRO_BEGIN { \ } UPRV_BLOCK_MACRO_END -#define SKELETON_UCHAR_TO_CHAR(dest, src, start, end, status) (void)(dest); \ -UPRV_BLOCK_MACRO_BEGIN { \ - UErrorCode conversionStatus = U_ZERO_ERROR; \ - (dest).appendInvariantChars({FALSE, (src).getBuffer() + (start), (end) - (start)}, conversionStatus); \ - if (conversionStatus == U_INVARIANT_CONVERSION_ERROR) { \ - /* Don't propagate the invariant conversion error; it is a skeleton syntax error */ \ - (status) = U_NUMBER_SKELETON_SYNTAX_ERROR; \ - return; \ - } else if (U_FAILURE(conversionStatus)) { \ - (status) = conversionStatus; \ - return; \ - } \ -} UPRV_BLOCK_MACRO_END - - } // anonymous namespace @@ -187,14 +183,11 @@ Notation stem_to_object::notation(skeleton::StemEnum stem) { MeasureUnit stem_to_object::unit(skeleton::StemEnum stem) { switch (stem) { case STEM_BASE_UNIT: - // Slicing is okay - return NoUnit::base(); // NOLINT + return MeasureUnit(); case STEM_PERCENT: - // Slicing is okay - return NoUnit::percent(); // NOLINT + return MeasureUnit::getPercent(); case STEM_PERMILLE: - // Slicing is okay - return NoUnit::permille(); // NOLINT + return MeasureUnit::getPermille(); default: UPRV_UNREACHABLE; } @@ -227,6 +220,12 @@ UNumberFormatRoundingMode stem_to_object::roundingMode(skeleton::StemEnum stem) return UNUM_ROUND_UP; case STEM_ROUNDING_MODE_HALF_EVEN: return UNUM_ROUND_HALFEVEN; + case STEM_ROUNDING_MODE_HALF_ODD: + return UNUM_ROUND_HALF_ODD; + case STEM_ROUNDING_MODE_HALF_CEILING: + return UNUM_ROUND_HALF_CEILING; + case STEM_ROUNDING_MODE_HALF_FLOOR: + return UNUM_ROUND_HALF_FLOOR; case STEM_ROUNDING_MODE_HALF_DOWN: return UNUM_ROUND_HALFDOWN; case STEM_ROUNDING_MODE_HALF_UP: @@ -265,6 +264,10 @@ UNumberUnitWidth stem_to_object::unitWidth(skeleton::StemEnum stem) { return UNUM_UNIT_WIDTH_FULL_NAME; case STEM_UNIT_WIDTH_ISO_CODE: return UNUM_UNIT_WIDTH_ISO_CODE; + case STEM_UNIT_WIDTH_FORMAL: + return UNUM_UNIT_WIDTH_FORMAL; + case STEM_UNIT_WIDTH_VARIANT: + return UNUM_UNIT_WIDTH_VARIANT; case STEM_UNIT_WIDTH_HIDDEN: return UNUM_UNIT_WIDTH_HIDDEN; default: @@ -288,6 +291,10 @@ UNumberSignDisplay stem_to_object::signDisplay(skeleton::StemEnum stem) { return UNUM_SIGN_EXCEPT_ZERO; case STEM_SIGN_ACCOUNTING_EXCEPT_ZERO: return UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO; + case STEM_SIGN_NEGATIVE: + return UNUM_SIGN_NEGATIVE; + case STEM_SIGN_ACCOUNTING_NEGATIVE: + return UNUM_SIGN_ACCOUNTING_NEGATIVE; default: return UNUM_SIGN_COUNT; // for objects, throw; for enums, return COUNT } @@ -322,6 +329,15 @@ void enum_to_stem_string::roundingMode(UNumberFormatRoundingMode value, UnicodeS case UNUM_ROUND_HALFEVEN: sb.append(u"rounding-mode-half-even", -1); break; + case UNUM_ROUND_HALF_ODD: + sb.append(u"rounding-mode-half-odd", -1); + break; + case UNUM_ROUND_HALF_CEILING: + sb.append(u"rounding-mode-half-ceiling", -1); + break; + case UNUM_ROUND_HALF_FLOOR: + sb.append(u"rounding-mode-half-floor", -1); + break; case UNUM_ROUND_HALFDOWN: sb.append(u"rounding-mode-half-down", -1); break; @@ -372,6 +388,12 @@ void enum_to_stem_string::unitWidth(UNumberUnitWidth value, UnicodeString& sb) { case UNUM_UNIT_WIDTH_ISO_CODE: sb.append(u"unit-width-iso-code", -1); break; + case UNUM_UNIT_WIDTH_FORMAL: + sb.append(u"unit-width-formal", -1); + break; + case UNUM_UNIT_WIDTH_VARIANT: + sb.append(u"unit-width-variant", -1); + break; case UNUM_UNIT_WIDTH_HIDDEN: sb.append(u"unit-width-hidden", -1); break; @@ -403,6 +425,12 @@ void enum_to_stem_string::signDisplay(UNumberSignDisplay value, UnicodeString& s case UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO: sb.append(u"sign-accounting-except-zero", -1); break; + case UNUM_SIGN_NEGATIVE: + sb.append(u"sign-negative", -1); + break; + case UNUM_SIGN_ACCOUNTING_NEGATIVE: + sb.append(u"sign-accounting-negative", -1); + break; default: UPRV_UNREACHABLE; } @@ -470,6 +498,7 @@ UnicodeString skeleton::generate(const MacroProps& macros, UErrorCode& status) { MacroProps skeleton::parseSkeleton( const UnicodeString& skeletonString, int32_t& errOffset, UErrorCode& status) { U_ASSERT(U_SUCCESS(status)); + U_ASSERT(kSerializedStemTrie != nullptr); // Add a trailing whitespace to the end of the skeleton string to make code cleaner. UnicodeString tempSkeletonString(skeletonString); @@ -550,6 +579,7 @@ MacroProps skeleton::parseSkeleton( case STATE_MEASURE_UNIT: case STATE_PER_MEASURE_UNIT: case STATE_IDENTIFIER_UNIT: + case STATE_UNIT_USAGE: case STATE_CURRENCY_UNIT: case STATE_INTEGER_WIDTH: case STATE_NUMBERING_SYSTEM: @@ -575,6 +605,8 @@ MacroProps skeleton::parseSkeleton( ParseState skeleton::parseStem(const StringSegment& segment, const UCharsTrie& stemTrie, SeenMacroProps& seen, MacroProps& macros, UErrorCode& status) { + U_ASSERT(U_SUCCESS(status)); + // First check for "blueprint" stems, which start with a "signal char" switch (segment.charAt(0)) { case u'.': @@ -584,7 +616,7 @@ skeleton::parseStem(const StringSegment& segment, const UCharsTrie& stemTrie, Se case u'@': CHECK_NULL(seen, precision, status); blueprint_helpers::parseDigitsStem(segment, macros, status); - return STATE_NULL; + return STATE_PRECISION; case u'E': CHECK_NULL(seen, notation, status); blueprint_helpers::parseScientificStem(segment, macros, status); @@ -650,7 +682,7 @@ skeleton::parseStem(const StringSegment& segment, const UCharsTrie& stemTrie, Se case STEM_PRECISION_INTEGER: return STATE_FRACTION_PRECISION; // allows for "precision-integer/@##" default: - return STATE_NULL; + return STATE_PRECISION; } case STEM_ROUNDING_MODE_CEILING: @@ -658,6 +690,9 @@ skeleton::parseStem(const StringSegment& segment, const UCharsTrie& stemTrie, Se case STEM_ROUNDING_MODE_DOWN: case STEM_ROUNDING_MODE_UP: case STEM_ROUNDING_MODE_HALF_EVEN: + case STEM_ROUNDING_MODE_HALF_ODD: + case STEM_ROUNDING_MODE_HALF_CEILING: + case STEM_ROUNDING_MODE_HALF_FLOOR: case STEM_ROUNDING_MODE_HALF_DOWN: case STEM_ROUNDING_MODE_HALF_UP: case STEM_ROUNDING_MODE_UNNECESSARY: @@ -683,6 +718,8 @@ skeleton::parseStem(const StringSegment& segment, const UCharsTrie& stemTrie, Se case STEM_UNIT_WIDTH_SHORT: case STEM_UNIT_WIDTH_FULL_NAME: case STEM_UNIT_WIDTH_ISO_CODE: + case STEM_UNIT_WIDTH_FORMAL: + case STEM_UNIT_WIDTH_VARIANT: case STEM_UNIT_WIDTH_HIDDEN: CHECK_NULL(seen, unitWidth, status); macros.unitWidth = stem_to_object::unitWidth(stem); @@ -695,6 +732,8 @@ skeleton::parseStem(const StringSegment& segment, const UCharsTrie& stemTrie, Se case STEM_SIGN_ACCOUNTING_ALWAYS: case STEM_SIGN_EXCEPT_ZERO: case STEM_SIGN_ACCOUNTING_EXCEPT_ZERO: + case STEM_SIGN_NEGATIVE: + case STEM_SIGN_ACCOUNTING_NEGATIVE: CHECK_NULL(seen, sign, status); macros.sign = stem_to_object::signDisplay(stem); return STATE_NULL; @@ -705,7 +744,7 @@ skeleton::parseStem(const StringSegment& segment, const UCharsTrie& stemTrie, Se macros.decimal = stem_to_object::decimalSeparatorDisplay(stem); return STATE_NULL; - // Stems requiring an option: + // Stems requiring an option: case STEM_PRECISION_INCREMENT: CHECK_NULL(seen, precision, status); @@ -724,8 +763,13 @@ skeleton::parseStem(const StringSegment& segment, const UCharsTrie& stemTrie, Se CHECK_NULL(seen, perUnit, status); return STATE_IDENTIFIER_UNIT; + case STEM_UNIT_USAGE: + CHECK_NULL(seen, usage, status); + return STATE_UNIT_USAGE; + case STEM_CURRENCY: CHECK_NULL(seen, unit, status); + CHECK_NULL(seen, perUnit, status); return STATE_CURRENCY_UNIT; case STEM_INTEGER_WIDTH: @@ -747,6 +791,7 @@ skeleton::parseStem(const StringSegment& segment, const UCharsTrie& stemTrie, Se ParseState skeleton::parseOption(ParseState stem, const StringSegment& segment, MacroProps& macros, UErrorCode& status) { + U_ASSERT(U_SUCCESS(status)); ///// Required options: ///// @@ -763,9 +808,12 @@ ParseState skeleton::parseOption(ParseState stem, const StringSegment& segment, case STATE_IDENTIFIER_UNIT: blueprint_helpers::parseIdentifierUnitOption(segment, macros, status); return STATE_NULL; + case STATE_UNIT_USAGE: + blueprint_helpers::parseUnitUsageOption(segment, macros, status); + return STATE_NULL; case STATE_INCREMENT_PRECISION: blueprint_helpers::parseIncrementOption(segment, macros, status); - return STATE_NULL; + return STATE_PRECISION; case STATE_INTEGER_WIDTH: blueprint_helpers::parseIntegerWidthOption(segment, macros, status); return STATE_NULL; @@ -805,6 +853,22 @@ ParseState skeleton::parseOption(ParseState stem, const StringSegment& segment, switch (stem) { case STATE_FRACTION_PRECISION: if (blueprint_helpers::parseFracSigOption(segment, macros, status)) { + return STATE_PRECISION; + } + if (U_FAILURE(status)) { + return {}; + } + // If the fracSig option was not found, try normal precision options. + stem = STATE_PRECISION; + break; + default: + break; + } + + // Trailing zeros option + switch (stem) { + case STATE_PRECISION: + if (blueprint_helpers::parseTrailingZeroOption(segment, macros, status)) { return STATE_NULL; } if (U_FAILURE(status)) { @@ -833,7 +897,7 @@ void GeneratorHelpers::generateSkeleton(const MacroProps& macros, UnicodeString& sb.append(u' '); } if (U_FAILURE(status)) { return; } - if (GeneratorHelpers::perUnit(macros, sb, status)) { + if (GeneratorHelpers::usage(macros, sb, status)) { sb.append(u' '); } if (U_FAILURE(status)) { return; } @@ -879,6 +943,10 @@ void GeneratorHelpers::generateSkeleton(const MacroProps& macros, UnicodeString& status = U_UNSUPPORTED_ERROR; return; } + if (macros.unitDisplayCase.isSet()) { + status = U_UNSUPPORTED_ERROR; + return; + } if (macros.affixProvider != nullptr) { status = U_UNSUPPORTED_ERROR; return; @@ -968,6 +1036,7 @@ blueprint_helpers::generateCurrencyOption(const CurrencyUnit& currency, UnicodeS void blueprint_helpers::parseMeasureUnitOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status) { + U_ASSERT(U_SUCCESS(status)); const UnicodeString stemString = segment.toTempUnicodeString(); // NOTE: The category (type) of the unit is guaranteed to be a valid subtag (alphanumeric) @@ -983,14 +1052,13 @@ void blueprint_helpers::parseMeasureUnitOption(const StringSegment& segment, Mac } // Need to do char <-> UChar conversion... - U_ASSERT(U_SUCCESS(status)); CharString type; SKELETON_UCHAR_TO_CHAR(type, stemString, 0, firstHyphen, status); CharString subType; SKELETON_UCHAR_TO_CHAR(subType, stemString, firstHyphen + 1, stemString.length(), status); - // Note: the largest type as of this writing (March 2018) is "volume", which has 24 units. - static constexpr int32_t CAPACITY = 30; + // Note: the largest type as of this writing (Aug 2020) is "volume", which has 33 units. + static constexpr int32_t CAPACITY = 40; MeasureUnit units[CAPACITY]; UErrorCode localStatus = U_ZERO_ERROR; int32_t numUnits = MeasureUnit::getAvailable(type.data(), units, CAPACITY, localStatus); @@ -1011,14 +1079,6 @@ void blueprint_helpers::parseMeasureUnitOption(const StringSegment& segment, Mac status = U_NUMBER_SKELETON_SYNTAX_ERROR; } -void blueprint_helpers::generateMeasureUnitOption(const MeasureUnit& measureUnit, UnicodeString& sb, - UErrorCode&) { - // Need to do char <-> UChar conversion... - sb.append(UnicodeString(measureUnit.getType(), -1, US_INV)); - sb.append(u'-'); - sb.append(UnicodeString(measureUnit.getSubtype(), -1, US_INV)); -} - void blueprint_helpers::parseMeasurePerUnitOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status) { // A little bit of a hack: save the current unit (numerator), call the main measure unit @@ -1038,23 +1098,23 @@ void blueprint_helpers::parseIdentifierUnitOption(const StringSegment& segment, SKELETON_UCHAR_TO_CHAR(buffer, segment.toTempUnicodeString(), 0, segment.length(), status); ErrorCode internalStatus; - auto fullUnit = MeasureUnitImpl::forIdentifier(buffer.toStringPiece(), internalStatus); + macros.unit = MeasureUnit::forIdentifier(buffer.toStringPiece(), internalStatus); if (internalStatus.isFailure()) { // throw new SkeletonSyntaxException("Invalid core unit identifier", segment, e); status = U_NUMBER_SKELETON_SYNTAX_ERROR; return; } +} - // TODO(ICU-20941): Clean this up. - for (int32_t i = 0; i < fullUnit.units.length(); i++) { - SingleUnitImpl* subUnit = fullUnit.units[i]; - if (subUnit->dimensionality > 0) { - macros.unit = macros.unit.product(subUnit->build(status), status); - } else { - subUnit->dimensionality *= -1; - macros.perUnit = macros.perUnit.product(subUnit->build(status), status); - } - } +void blueprint_helpers::parseUnitUsageOption(const StringSegment &segment, MacroProps ¯os, + UErrorCode &status) { + // Need to do char <-> UChar conversion... + U_ASSERT(U_SUCCESS(status)); + CharString buffer; + SKELETON_UCHAR_TO_CHAR(buffer, segment.toTempUnicodeString(), 0, segment.length(), status); + macros.usage.set(buffer.toStringPiece()); + // We do not do any validation of the usage string: it depends on the + // unitPreferenceData in the units resources. } void blueprint_helpers::parseFractionStem(const StringSegment& segment, MacroProps& macros, @@ -1198,6 +1258,7 @@ void blueprint_helpers::parseScientificStem(const StringSegment& segment, MacroP } else if (segment.charAt(offset) == u'?') { signDisplay = UNUM_SIGN_EXCEPT_ZERO; } else { + // NOTE: Other sign displays are not included because they aren't useful in this context goto fail; } offset++; @@ -1256,21 +1317,14 @@ bool blueprint_helpers::parseFracSigOption(const StringSegment& segment, MacroPr break; } } - // For the frac-sig option, there must be minSig or maxSig but not both. - // Valid: @+, @@+, @@@+ - // Valid: @#, @##, @### - // Invalid: @, @@, @@@ - // Invalid: @@#, @@##, @@@# if (offset < segment.length()) { if (isWildcardChar(segment.charAt(offset))) { + // @+, @@+, @@@+ maxSig = -1; offset++; - } else if (minSig > 1) { - // @@#, @@##, @@@# - // throw new SkeletonSyntaxException("Invalid digits option for fraction rounder", segment); - status = U_NUMBER_SKELETON_SYNTAX_ERROR; - return false; } else { + // @#, @##, @### + // @@#, @@##, @@@# maxSig = minSig; for (; offset < segment.length(); offset++) { if (segment.charAt(offset) == u'#') { @@ -1282,54 +1336,59 @@ bool blueprint_helpers::parseFracSigOption(const StringSegment& segment, MacroPr } } else { // @, @@, @@@ - // throw new SkeletonSyntaxException("Invalid digits option for fraction rounder", segment); - status = U_NUMBER_SKELETON_SYNTAX_ERROR; - return false; + maxSig = minSig; } + UNumberRoundingPriority priority; if (offset < segment.length()) { - // throw new SkeletonSyntaxException("Invalid digits option for fraction rounder", segment); + if (maxSig == -1) { + // The wildcard character is not allowed with the priority annotation + status = U_NUMBER_SKELETON_SYNTAX_ERROR; + return false; + } + if (segment.codePointAt(offset) == u'r') { + priority = UNUM_ROUNDING_PRIORITY_RELAXED; + offset++; + } else if (segment.codePointAt(offset) == u's') { + priority = UNUM_ROUNDING_PRIORITY_STRICT; + offset++; + } else { + U_ASSERT(offset < segment.length()); + } + if (offset < segment.length()) { + // Invalid digits option for fraction rounder + status = U_NUMBER_SKELETON_SYNTAX_ERROR; + return false; + } + } else if (maxSig == -1) { + // withMinDigits + maxSig = minSig; + minSig = 1; + priority = UNUM_ROUNDING_PRIORITY_RELAXED; + } else if (minSig == 1) { + // withMaxDigits + priority = UNUM_ROUNDING_PRIORITY_STRICT; + } else { + // Digits options with both min and max sig require the priority option status = U_NUMBER_SKELETON_SYNTAX_ERROR; return false; } auto& oldPrecision = static_cast(macros.precision); - if (maxSig == -1) { - macros.precision = oldPrecision.withMinDigits(minSig); - } else { - macros.precision = oldPrecision.withMaxDigits(maxSig); - } + macros.precision = oldPrecision.withSignificantDigits(minSig, maxSig, priority); return true; } -void blueprint_helpers::parseIncrementOption(const StringSegment& segment, MacroProps& macros, - UErrorCode& status) { - // Need to do char <-> UChar conversion... - U_ASSERT(U_SUCCESS(status)); - CharString buffer; - SKELETON_UCHAR_TO_CHAR(buffer, segment.toTempUnicodeString(), 0, segment.length(), status); - - // Utilize DecimalQuantity/decNumber to parse this for us. - DecimalQuantity dq; - UErrorCode localStatus = U_ZERO_ERROR; - dq.setToDecNumber({buffer.data(), buffer.length()}, localStatus); - if (U_FAILURE(localStatus)) { - // throw new SkeletonSyntaxException("Invalid rounding increment", segment, e); - status = U_NUMBER_SKELETON_SYNTAX_ERROR; - return; +bool blueprint_helpers::parseTrailingZeroOption(const StringSegment& segment, MacroProps& macros, UErrorCode&) { + if (segment == u"w") { + macros.precision = macros.precision.trailingZeroDisplay(UNUM_TRAILING_ZERO_HIDE_IF_WHOLE); + return true; } - double increment = dq.toDouble(); + return false; +} - // We also need to figure out how many digits. Do a brute force string operation. - int decimalOffset = 0; - while (decimalOffset < segment.length() && segment.charAt(decimalOffset) != '.') { - decimalOffset++; - } - if (decimalOffset == segment.length()) { - macros.precision = Precision::increment(increment); - } else { - int32_t fractionLength = segment.length() - decimalOffset - 1; - macros.precision = Precision::increment(increment).withMinFraction(fractionLength); - } +void blueprint_helpers::parseIncrementOption(const StringSegment &segment, MacroProps ¯os, + UErrorCode &status) { + number::impl::parseIncrementOption(segment, macros.precision, status); } void blueprint_helpers::generateIncrementOption(double increment, int32_t trailingZeros, UnicodeString& sb, @@ -1499,50 +1558,46 @@ bool GeneratorHelpers::notation(const MacroProps& macros, UnicodeString& sb, UEr } bool GeneratorHelpers::unit(const MacroProps& macros, UnicodeString& sb, UErrorCode& status) { - if (utils::unitIsCurrency(macros.unit)) { + MeasureUnit unit = macros.unit; + if (!utils::unitIsBaseUnit(macros.perUnit)) { + if (utils::unitIsCurrency(macros.unit) || utils::unitIsCurrency(macros.perUnit)) { + status = U_UNSUPPORTED_ERROR; + return false; + } + unit = unit.product(macros.perUnit.reciprocal(status), status); + } + + if (utils::unitIsCurrency(unit)) { sb.append(u"currency/", -1); - CurrencyUnit currency(macros.unit, status); + CurrencyUnit currency(unit, status); if (U_FAILURE(status)) { return false; } blueprint_helpers::generateCurrencyOption(currency, sb, status); return true; - } else if (utils::unitIsNoUnit(macros.unit)) { - if (utils::unitIsPercent(macros.unit)) { - sb.append(u"percent", -1); - return true; - } else if (utils::unitIsPermille(macros.unit)) { - sb.append(u"permille", -1); - return true; - } else { - // Default value is not shown in normalized form - return false; - } + } else if (utils::unitIsBaseUnit(unit)) { + // Default value is not shown in normalized form + return false; + } else if (utils::unitIsPercent(unit)) { + sb.append(u"percent", -1); + return true; + } else if (utils::unitIsPermille(unit)) { + sb.append(u"permille", -1); + return true; } else { - sb.append(u"measure-unit/", -1); - blueprint_helpers::generateMeasureUnitOption(macros.unit, sb, status); + sb.append(u"unit/", -1); + sb.append(unit.getIdentifier()); return true; } } -bool GeneratorHelpers::perUnit(const MacroProps& macros, UnicodeString& sb, UErrorCode& status) { - // Per-units are currently expected to be only MeasureUnits. - if (utils::unitIsNoUnit(macros.perUnit)) { - if (utils::unitIsPercent(macros.perUnit) || utils::unitIsPermille(macros.perUnit)) { - status = U_UNSUPPORTED_ERROR; - return false; - } else { - // Default value: ok to ignore - return false; - } - } else if (utils::unitIsCurrency(macros.perUnit)) { - status = U_UNSUPPORTED_ERROR; - return false; - } else { - sb.append(u"per-measure-unit/", -1); - blueprint_helpers::generateMeasureUnitOption(macros.perUnit, sb, status); +bool GeneratorHelpers::usage(const MacroProps& macros, UnicodeString& sb, UErrorCode& /* status */) { + if (macros.usage.isSet()) { + sb.append(u"usage/", -1); + sb.append(UnicodeString(macros.usage.fValue, -1, US_INV)); return true; } + return false; } bool GeneratorHelpers::precision(const MacroProps& macros, UnicodeString& sb, UErrorCode& status) { @@ -1558,10 +1613,11 @@ bool GeneratorHelpers::precision(const MacroProps& macros, UnicodeString& sb, UE const Precision::FractionSignificantSettings& impl = macros.precision.fUnion.fracSig; blueprint_helpers::generateFractionStem(impl.fMinFrac, impl.fMaxFrac, sb, status); sb.append(u'/'); - if (impl.fMinSig == -1) { - blueprint_helpers::generateDigitsStem(1, impl.fMaxSig, sb, status); + blueprint_helpers::generateDigitsStem(impl.fMinSig, impl.fMaxSig, sb, status); + if (impl.fPriority == UNUM_ROUNDING_PRIORITY_RELAXED) { + sb.append(u'r'); } else { - blueprint_helpers::generateDigitsStem(impl.fMinSig, -1, sb, status); + sb.append(u's'); } } else if (macros.precision.fType == Precision::RND_INCREMENT || macros.precision.fType == Precision::RND_INCREMENT_ONE @@ -1585,6 +1641,10 @@ bool GeneratorHelpers::precision(const MacroProps& macros, UnicodeString& sb, UE return false; } + if (macros.precision.fTrailingZeroDisplay == UNUM_TRAILING_ZERO_HIDE_IF_WHOLE) { + sb.append(u"/w", -1); + } + // NOTE: Always return true for rounding because the default value depends on other options. return true; } diff --git a/deps/icu-small/source/i18n/number_skeletons.h b/deps/icu-small/source/i18n/number_skeletons.h index d9b2c0ee0b19abc88cc8bab11fa190a778378878..af6365042830595e8c79bb4d50fbb730a8d6bde9 100644 --- a/deps/icu-small/source/i18n/number_skeletons.h +++ b/deps/icu-small/source/i18n/number_skeletons.h @@ -22,10 +22,12 @@ struct SeenMacroProps; // namespace for enums and entrypoint functions namespace skeleton { -/////////////////////////////////////////////////////////////////////////////////////// -// NOTE: For an example of how to add a new stem to the number skeleton parser, see: // -// http://bugs.icu-project.org/trac/changeset/41193 // -/////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +// NOTE: For examples of how to add a new stem to the number skeleton parser, see: // +// https://github.com/unicode-org/icu/commit/a2a7982216b2348070dc71093775ac7195793d73 // +// and // +// https://github.com/unicode-org/icu/commit/6fe86f3934a8a5701034f648a8f7c5087e84aa28 // +//////////////////////////////////////////////////////////////////////////////////////// /** * While parsing a skeleton, this enum records what type of option we expect to find next. @@ -40,6 +42,7 @@ enum ParseState { STATE_SCIENTIFIC, STATE_FRACTION_PRECISION, + STATE_PRECISION, // Section 2: An option is required: @@ -47,6 +50,7 @@ enum ParseState { STATE_MEASURE_UNIT, STATE_PER_MEASURE_UNIT, STATE_IDENTIFIER_UNIT, + STATE_UNIT_USAGE, STATE_CURRENCY_UNIT, STATE_INTEGER_WIDTH, STATE_NUMBERING_SYSTEM, @@ -82,6 +86,9 @@ enum StemEnum { STEM_ROUNDING_MODE_DOWN, STEM_ROUNDING_MODE_UP, STEM_ROUNDING_MODE_HALF_EVEN, + STEM_ROUNDING_MODE_HALF_ODD, + STEM_ROUNDING_MODE_HALF_CEILING, + STEM_ROUNDING_MODE_HALF_FLOOR, STEM_ROUNDING_MODE_HALF_DOWN, STEM_ROUNDING_MODE_HALF_UP, STEM_ROUNDING_MODE_UNNECESSARY, @@ -95,6 +102,8 @@ enum StemEnum { STEM_UNIT_WIDTH_SHORT, STEM_UNIT_WIDTH_FULL_NAME, STEM_UNIT_WIDTH_ISO_CODE, + STEM_UNIT_WIDTH_FORMAL, + STEM_UNIT_WIDTH_VARIANT, STEM_UNIT_WIDTH_HIDDEN, STEM_SIGN_AUTO, STEM_SIGN_ALWAYS, @@ -103,6 +112,8 @@ enum StemEnum { STEM_SIGN_ACCOUNTING_ALWAYS, STEM_SIGN_EXCEPT_ZERO, STEM_SIGN_ACCOUNTING_EXCEPT_ZERO, + STEM_SIGN_NEGATIVE, + STEM_SIGN_ACCOUNTING_NEGATIVE, STEM_DECIMAL_AUTO, STEM_DECIMAL_ALWAYS, @@ -112,6 +123,7 @@ enum StemEnum { STEM_MEASURE_UNIT, STEM_PER_MEASURE_UNIT, STEM_UNIT, + STEM_UNIT_USAGE, STEM_CURRENCY, STEM_INTEGER_WIDTH, STEM_NUMBERING_SYSTEM, @@ -234,14 +246,20 @@ void parseCurrencyOption(const StringSegment& segment, MacroProps& macros, UErro void generateCurrencyOption(const CurrencyUnit& currency, UnicodeString& sb, UErrorCode& status); +// "measure-unit/" is deprecated in favour of "unit/". void parseMeasureUnitOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status); -void generateMeasureUnitOption(const MeasureUnit& measureUnit, UnicodeString& sb, UErrorCode& status); - +// "per-measure-unit/" is deprecated in favour of "unit/". void parseMeasurePerUnitOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status); +/** + * Parses unit identifiers like "meter-per-second" and "foot-and-inch", as + * specified via a "unit/" concise skeleton. + */ void parseIdentifierUnitOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status); +void parseUnitUsageOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status); + void parseFractionStem(const StringSegment& segment, MacroProps& macros, UErrorCode& status); void generateFractionStem(int32_t minFrac, int32_t maxFrac, UnicodeString& sb, UErrorCode& status); @@ -261,6 +279,9 @@ void parseIntegerStem(const StringSegment& segment, MacroProps& macros, UErrorCo /** @return Whether we successfully found and parsed a frac-sig option. */ bool parseFracSigOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status); +/** @return Whether we successfully found and parsed a trailing zero option. */ +bool parseTrailingZeroOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status); + void parseIncrementOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status); void @@ -302,7 +323,7 @@ class GeneratorHelpers { static bool unit(const MacroProps& macros, UnicodeString& sb, UErrorCode& status); - static bool perUnit(const MacroProps& macros, UnicodeString& sb, UErrorCode& status); + static bool usage(const MacroProps& macros, UnicodeString& sb, UErrorCode& status); static bool precision(const MacroProps& macros, UnicodeString& sb, UErrorCode& status); @@ -332,6 +353,7 @@ struct SeenMacroProps { bool notation = false; bool unit = false; bool perUnit = false; + bool usage = false; bool precision = false; bool roundingMode = false; bool grouper = false; @@ -344,6 +366,24 @@ struct SeenMacroProps { bool scale = false; }; +namespace { + +#define SKELETON_UCHAR_TO_CHAR(dest, src, start, end, status) (void)(dest); \ +UPRV_BLOCK_MACRO_BEGIN { \ + UErrorCode conversionStatus = U_ZERO_ERROR; \ + (dest).appendInvariantChars({false, (src).getBuffer() + (start), (end) - (start)}, conversionStatus); \ + if (conversionStatus == U_INVARIANT_CONVERSION_ERROR) { \ + /* Don't propagate the invariant conversion error; it is a skeleton syntax error */ \ + (status) = U_NUMBER_SKELETON_SYNTAX_ERROR; \ + return; \ + } else if (U_FAILURE(conversionStatus)) { \ + (status) = conversionStatus; \ + return; \ + } \ +} UPRV_BLOCK_MACRO_END + +} // namespace + } // namespace impl } // namespace number U_NAMESPACE_END diff --git a/deps/icu-small/source/i18n/number_symbolswrapper.cpp b/deps/icu-small/source/i18n/number_symbolswrapper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac3043d1ca11c2f332fca9d53013c99ddd71c873 --- /dev/null +++ b/deps/icu-small/source/i18n/number_symbolswrapper.cpp @@ -0,0 +1,131 @@ +// © 2020 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING + +#include "number_microprops.h" +#include "unicode/numberformatter.h" + +using namespace icu; +using namespace icu::number; +using namespace icu::number::impl; + +SymbolsWrapper::SymbolsWrapper(const SymbolsWrapper &other) { + doCopyFrom(other); +} + +SymbolsWrapper::SymbolsWrapper(SymbolsWrapper &&src) U_NOEXCEPT { + doMoveFrom(std::move(src)); +} + +SymbolsWrapper &SymbolsWrapper::operator=(const SymbolsWrapper &other) { + if (this == &other) { + return *this; + } + doCleanup(); + doCopyFrom(other); + return *this; +} + +SymbolsWrapper &SymbolsWrapper::operator=(SymbolsWrapper &&src) U_NOEXCEPT { + if (this == &src) { + return *this; + } + doCleanup(); + doMoveFrom(std::move(src)); + return *this; +} + +SymbolsWrapper::~SymbolsWrapper() { + doCleanup(); +} + +void SymbolsWrapper::setTo(const DecimalFormatSymbols &dfs) { + doCleanup(); + fType = SYMPTR_DFS; + fPtr.dfs = new DecimalFormatSymbols(dfs); +} + +void SymbolsWrapper::setTo(const NumberingSystem *ns) { + doCleanup(); + fType = SYMPTR_NS; + fPtr.ns = ns; +} + +void SymbolsWrapper::doCopyFrom(const SymbolsWrapper &other) { + fType = other.fType; + switch (fType) { + case SYMPTR_NONE: + // No action necessary + break; + case SYMPTR_DFS: + // Memory allocation failures are exposed in copyErrorTo() + if (other.fPtr.dfs != nullptr) { + fPtr.dfs = new DecimalFormatSymbols(*other.fPtr.dfs); + } else { + fPtr.dfs = nullptr; + } + break; + case SYMPTR_NS: + // Memory allocation failures are exposed in copyErrorTo() + if (other.fPtr.ns != nullptr) { + fPtr.ns = new NumberingSystem(*other.fPtr.ns); + } else { + fPtr.ns = nullptr; + } + break; + } +} + +void SymbolsWrapper::doMoveFrom(SymbolsWrapper &&src) { + fType = src.fType; + switch (fType) { + case SYMPTR_NONE: + // No action necessary + break; + case SYMPTR_DFS: + fPtr.dfs = src.fPtr.dfs; + src.fPtr.dfs = nullptr; + break; + case SYMPTR_NS: + fPtr.ns = src.fPtr.ns; + src.fPtr.ns = nullptr; + break; + } +} + +void SymbolsWrapper::doCleanup() { + switch (fType) { + case SYMPTR_NONE: + // No action necessary + break; + case SYMPTR_DFS: + delete fPtr.dfs; + break; + case SYMPTR_NS: + delete fPtr.ns; + break; + } +} + +bool SymbolsWrapper::isDecimalFormatSymbols() const { + return fType == SYMPTR_DFS; +} + +bool SymbolsWrapper::isNumberingSystem() const { + return fType == SYMPTR_NS; +} + +const DecimalFormatSymbols *SymbolsWrapper::getDecimalFormatSymbols() const { + U_ASSERT(fType == SYMPTR_DFS); + return fPtr.dfs; +} + +const NumberingSystem *SymbolsWrapper::getNumberingSystem() const { + U_ASSERT(fType == SYMPTR_NS); + return fPtr.ns; +} + +#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/number_types.h b/deps/icu-small/source/i18n/number_types.h index 5c2b8cf8b5d19c5deb9d61ab21175b6840216852..8078851ba3fdb35723547ef62e2380978d2545d7 100644 --- a/deps/icu-small/source/i18n/number_types.h +++ b/deps/icu-small/source/i18n/number_types.h @@ -246,31 +246,31 @@ class U_I18N_API ModifierStore { * itself. The {@link #processQuantity} method performs the final step in the number processing pipeline: it uses the * quantity to generate a finalized {@link MicroProps}, which can be used to render the number to output. * - *

* In other words, this interface is used for the parts of number processing that are quantity-dependent. * - *

* In order to allow for multiple different objects to all mutate the same MicroProps, a "chain" of MicroPropsGenerators * are linked together, and each one is responsible for manipulating a certain quantity-dependent part of the * MicroProps. At the tail of the linked list is a base instance of {@link MicroProps} with properties that are not * quantity-dependent. Each element in the linked list calls {@link #processQuantity} on its "parent", then does its * work, and then returns the result. * + * This chain of MicroPropsGenerators is typically constructed by NumberFormatterImpl::macrosToMicroGenerator() when + * constructing a NumberFormatter. + * * Exported as U_I18N_API because it is a base class for other exported types * */ class U_I18N_API MicroPropsGenerator { public: - virtual ~MicroPropsGenerator(); + virtual ~MicroPropsGenerator() = default; /** - * Considers the given {@link DecimalQuantity}, optionally mutates it, and returns a {@link MicroProps}. + * Considers the given {@link DecimalQuantity}, optionally mutates it, and + * populates a {@link MicroProps} instance. * - * @param quantity - * The quantity for consideration and optional mutation. - * @param micros - * The MicroProps instance to populate. - * @return A MicroProps instance resolved for the quantity. + * @param quantity The quantity for consideration and optional mutation. + * @param micros The MicroProps instance to populate. It will be modified as + * needed for the given quantity. */ virtual void processQuantity(DecimalQuantity& quantity, MicroProps& micros, UErrorCode& status) const = 0; diff --git a/deps/icu-small/source/i18n/number_usageprefs.cpp b/deps/icu-small/source/i18n/number_usageprefs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ed426da086e32727709b5e7222e992edc395ba65 --- /dev/null +++ b/deps/icu-small/source/i18n/number_usageprefs.cpp @@ -0,0 +1,214 @@ +// © 2020 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING + +#include "number_usageprefs.h" +#include "cstring.h" +#include "number_decimalquantity.h" +#include "number_microprops.h" +#include "number_roundingutils.h" +#include "number_skeletons.h" +#include "unicode/char16ptr.h" +#include "unicode/currunit.h" +#include "unicode/fmtable.h" +#include "unicode/measure.h" +#include "unicode/numberformatter.h" +#include "unicode/platform.h" +#include "unicode/unum.h" +#include "unicode/urename.h" +#include "units_data.h" + +using namespace icu; +using namespace icu::number; +using namespace icu::number::impl; +using icu::StringSegment; +using icu::units::ConversionRates; + +// Copy constructor +StringProp::StringProp(const StringProp &other) : StringProp() { + this->operator=(other); +} + +// Copy assignment operator +StringProp &StringProp::operator=(const StringProp &other) { + if (this == &other) { return *this; } // self-assignment: no-op + fLength = 0; + fError = other.fError; + if (fValue != nullptr) { + uprv_free(fValue); + fValue = nullptr; + } + if (other.fValue == nullptr) { + return *this; + } + if (U_FAILURE(other.fError)) { + // We don't bother trying to allocating memory if we're in any case busy + // copying an errored StringProp. + return *this; + } + fValue = (char *)uprv_malloc(other.fLength + 1); + if (fValue == nullptr) { + fError = U_MEMORY_ALLOCATION_ERROR; + return *this; + } + fLength = other.fLength; + uprv_strncpy(fValue, other.fValue, fLength + 1); + return *this; +} + +// Move constructor +StringProp::StringProp(StringProp &&src) U_NOEXCEPT : fValue(src.fValue), + fLength(src.fLength), + fError(src.fError) { + // Take ownership away from src if necessary + src.fValue = nullptr; +} + +// Move assignment operator +StringProp &StringProp::operator=(StringProp &&src) U_NOEXCEPT { + if (this == &src) { + return *this; + } + if (fValue != nullptr) { + uprv_free(fValue); + } + fValue = src.fValue; + fLength = src.fLength; + fError = src.fError; + // Take ownership away from src if necessary + src.fValue = nullptr; + return *this; +} + +StringProp::~StringProp() { + if (fValue != nullptr) { + uprv_free(fValue); + fValue = nullptr; + } +} + +void StringProp::set(StringPiece value) { + if (fValue != nullptr) { + uprv_free(fValue); + fValue = nullptr; + } + fLength = value.length(); + fValue = (char *)uprv_malloc(fLength + 1); + if (fValue == nullptr) { + fLength = 0; + fError = U_MEMORY_ALLOCATION_ERROR; + return; + } + uprv_strncpy(fValue, value.data(), fLength); + fValue[fLength] = 0; +} + +// Populates micros.mixedMeasures and modifies quantity, based on the values in +// measures. +void mixedMeasuresToMicros(const MaybeStackVector &measures, DecimalQuantity *quantity, + MicroProps *micros, UErrorCode status) { + micros->mixedMeasuresCount = measures.length(); + + if (micros->mixedMeasures.getCapacity() < micros->mixedMeasuresCount) { + if (micros->mixedMeasures.resize(micros->mixedMeasuresCount) == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + } + + for (int32_t i = 0; i < micros->mixedMeasuresCount; i++) { + switch (measures[i]->getNumber().getType()) { + case Formattable::kInt64: + micros->mixedMeasures[i] = measures[i]->getNumber().getInt64(); + break; + + case Formattable::kDouble: + U_ASSERT(micros->indexOfQuantity < 0); + quantity->setToDouble(measures[i]->getNumber().getDouble()); + micros->indexOfQuantity = i; + break; + + default: + U_ASSERT(0 == "Found a Measure Number which is neither a double nor an int"); + UPRV_UNREACHABLE; + break; + } + + if (U_FAILURE(status)) { + return; + } + } + + if (micros->indexOfQuantity < 0) { + // There is no quantity. + status = U_INTERNAL_PROGRAM_ERROR; + } +} + +UsagePrefsHandler::UsagePrefsHandler(const Locale &locale, + const MeasureUnit &inputUnit, + const StringPiece usage, + const MicroPropsGenerator *parent, + UErrorCode &status) + : fUnitsRouter(inputUnit, StringPiece(locale.getCountry()), usage, status), + fParent(parent) { +} + +void UsagePrefsHandler::processQuantity(DecimalQuantity &quantity, MicroProps µs, + UErrorCode &status) const { + fParent->processQuantity(quantity, micros, status); + if (U_FAILURE(status)) { + return; + } + + quantity.roundToInfinity(); // Enables toDouble + const units::RouteResult routed = fUnitsRouter.route(quantity.toDouble(), µs.rounder, status); + if (U_FAILURE(status)) { + return; + } + const MaybeStackVector& routedMeasures = routed.measures; + micros.outputUnit = routed.outputUnit.copy(status).build(status); + if (U_FAILURE(status)) { + return; + } + + mixedMeasuresToMicros(routedMeasures, &quantity, µs, status); +} + +UnitConversionHandler::UnitConversionHandler(const MeasureUnit &targetUnit, + const MicroPropsGenerator *parent, UErrorCode &status) + : fOutputUnit(targetUnit), fParent(parent) { + MeasureUnitImpl tempInput, tempOutput; + + ConversionRates conversionRates(status); + if (U_FAILURE(status)) { + return; + } + + const MeasureUnitImpl &targetUnitImpl = + MeasureUnitImpl::forMeasureUnit(targetUnit, tempOutput, status); + fUnitConverter.adoptInsteadAndCheckErrorCode( + new ComplexUnitsConverter(targetUnitImpl, conversionRates, status), status); +} + +void UnitConversionHandler::processQuantity(DecimalQuantity &quantity, MicroProps µs, + UErrorCode &status) const { + fParent->processQuantity(quantity, micros, status); + if (U_FAILURE(status)) { + return; + } + quantity.roundToInfinity(); // Enables toDouble + MaybeStackVector measures = + fUnitConverter->convert(quantity.toDouble(), µs.rounder, status); + micros.outputUnit = fOutputUnit; + if (U_FAILURE(status)) { + return; + } + + mixedMeasuresToMicros(measures, &quantity, µs, status); +} + +#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/number_usageprefs.h b/deps/icu-small/source/i18n/number_usageprefs.h new file mode 100644 index 0000000000000000000000000000000000000000..70547225a00761b84027aa11b6e7fabdebb4a7ae --- /dev/null +++ b/deps/icu-small/source/i18n/number_usageprefs.h @@ -0,0 +1,126 @@ +// © 2020 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING +#ifndef __NUMBER_USAGEPREFS_H__ +#define __NUMBER_USAGEPREFS_H__ + +#include "cmemory.h" +#include "number_types.h" +#include "unicode/listformatter.h" +#include "unicode/localpointer.h" +#include "unicode/locid.h" +#include "unicode/measunit.h" +#include "unicode/stringpiece.h" +#include "unicode/uobject.h" +#include "units_converter.h" +#include "units_router.h" + +U_NAMESPACE_BEGIN + +using ::icu::units::ComplexUnitsConverter; +using ::icu::units::UnitsRouter; + +namespace number { +namespace impl { + +/** + * A MicroPropsGenerator which uses UnitsRouter to produce output converted to a + * MeasureUnit appropriate for a particular localized usage: see + * NumberFormatterSettings::usage(). + */ +class U_I18N_API UsagePrefsHandler : public MicroPropsGenerator, public UMemory { + public: + UsagePrefsHandler(const Locale &locale, const MeasureUnit &inputUnit, const StringPiece usage, + const MicroPropsGenerator *parent, UErrorCode &status); + + /** + * Obtains the appropriate output value, MeasureUnit and + * rounding/precision behaviour from the UnitsRouter. + * + * The output unit is passed on to the LongNameHandler via + * micros.outputUnit. + */ + void processQuantity(DecimalQuantity &quantity, MicroProps µs, + UErrorCode &status) const U_OVERRIDE; + + /** + * Returns the list of possible output units, i.e. the full set of + * preferences, for the localized, usage-specific unit preferences. + * + * The returned pointer should be valid for the lifetime of the + * UsagePrefsHandler instance. + */ + const MaybeStackVector *getOutputUnits() const { + return fUnitsRouter.getOutputUnits(); + } + + private: + UnitsRouter fUnitsRouter; + const MicroPropsGenerator *fParent; +}; + +} // namespace impl +} // namespace number + +// Export explicit template instantiations of LocalPointerBase and LocalPointer. +// This is required when building DLLs for Windows. (See datefmt.h, +// collationiterator.h, erarules.h and others for similar examples.) +// +// Note: These need to be outside of the number::impl namespace, or Clang will +// generate a compile error. +#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN +#if defined(_MSC_VER) +// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!= +#pragma warning(push) +#pragma warning(disable: 4661) +#endif +template class U_I18N_API LocalPointerBase; +template class U_I18N_API LocalPointer; +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +#endif + +namespace number { +namespace impl { + +/** + * A MicroPropsGenerator which converts a measurement from one MeasureUnit to + * another. In particular, the output MeasureUnit may be a mixed unit. (The + * input unit may not be a mixed unit.) + */ +class U_I18N_API UnitConversionHandler : public MicroPropsGenerator, public UMemory { + public: + /** + * Constructor. + * + * @param targetUnit Specifies the output MeasureUnit. The input MeasureUnit + * is derived from it: in case of a mixed unit, the biggest unit is + * taken as the input unit. If not a mixed unit, the input unit will be + * the same as the output unit and no unit conversion takes place. + * @param parent The parent MicroPropsGenerator. + * @param status Receives status. + */ + UnitConversionHandler(const MeasureUnit &targetUnit, const MicroPropsGenerator *parent, + UErrorCode &status); + + /** + * Obtains the appropriate output values from the Unit Converter. + */ + void processQuantity(DecimalQuantity &quantity, MicroProps µs, + UErrorCode &status) const U_OVERRIDE; + private: + MeasureUnit fOutputUnit; + LocalPointer fUnitConverter; + const MicroPropsGenerator *fParent; +}; + +} // namespace impl +} // namespace number +U_NAMESPACE_END + +#endif // __NUMBER_USAGEPREFS_H__ +#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/number_utils.cpp b/deps/icu-small/source/i18n/number_utils.cpp index 91d7f335cd82d3daa91b4abddffdd115e486b7fc..bef7ea6c61f30b48d8544febc0ed1e78c7066696 100644 --- a/deps/icu-small/source/i18n/number_utils.cpp +++ b/deps/icu-small/source/i18n/number_utils.cpp @@ -258,7 +258,10 @@ void DecNum::toString(ByteSink& output, UErrorCode& status) const { } // "string must be at least dn->digits+14 characters long" int32_t minCapacity = fData.getAlias()->digits + 14; - MaybeStackArray buffer(minCapacity); + MaybeStackArray buffer(minCapacity, status); + if (U_FAILURE(status)) { + return; + } uprv_decNumberToString(fData, buffer.getAlias()); output.Append(buffer.getAlias(), static_cast(uprv_strlen(buffer.getAlias()))); } diff --git a/deps/icu-small/source/i18n/number_utils.h b/deps/icu-small/source/i18n/number_utils.h index 93195f080b2787bde8b8058f2e11f4a2adfe2ba1..bc369c940f7962d1bc427454191d124e9d5d448e 100644 --- a/deps/icu-small/source/i18n/number_utils.h +++ b/deps/icu-small/source/i18n/number_utils.h @@ -49,8 +49,8 @@ inline bool unitIsCurrency(const MeasureUnit& unit) { return uprv_strcmp("currency", unit.getType()) == 0; } -inline bool unitIsNoUnit(const MeasureUnit& unit) { - return uprv_strcmp("none", unit.getType()) == 0; +inline bool unitIsBaseUnit(const MeasureUnit& unit) { + return unit == MeasureUnit(); } inline bool unitIsPercent(const MeasureUnit& unit) { diff --git a/deps/icu-small/source/i18n/number_utypes.h b/deps/icu-small/source/i18n/number_utypes.h index 7a1b7a4e80ac3150c9b5844ae6e8e0d273d6c724..50c861787f4ed9c2b6300fb2a87aacbea624c191 100644 --- a/deps/icu-small/source/i18n/number_utypes.h +++ b/deps/icu-small/source/i18n/number_utypes.h @@ -28,9 +28,6 @@ const DecimalQuantity* validateUFormattedNumberToDecimalQuantity( * This struct is held internally by the C++ version FormattedNumber since the member types are not * declared in the public header file. * - * The DecimalQuantity is not currently being used by FormattedNumber, but at some point it could be used - * to add a toDecNumber() or similar method. - * * Exported as U_I18N_API for tests */ class U_I18N_API UFormattedNumberData : public FormattedValueStringBuilderImpl { @@ -38,7 +35,16 @@ public: UFormattedNumberData() : FormattedValueStringBuilderImpl(kUndefinedField) {} virtual ~UFormattedNumberData(); + // The formatted quantity. DecimalQuantity quantity; + + // The output unit for the formatted quantity. + // TODO(units,hugovdm): populate this correctly for the general case - it's + // currently only implemented for the .usage() use case. + MeasureUnit outputUnit; + + // The gender of the formatted output. + const char *gender = ""; }; diff --git a/deps/icu-small/source/i18n/numfmt.cpp b/deps/icu-small/source/i18n/numfmt.cpp index bf78179bcddefef462dc389eb7a44bef5bba1d17..bffefa5e3998b8ba71644fdff214e39046e99bc5 100644 --- a/deps/icu-small/source/i18n/numfmt.cpp +++ b/deps/icu-small/source/i18n/numfmt.cpp @@ -13,7 +13,7 @@ * Date Name Description * 02/19/97 aliu Converted from java. * 03/18/97 clhuang Implemented with C++ APIs. -* 04/17/97 aliu Enlarged MAX_INTEGER_DIGITS to fully accomodate the +* 04/17/97 aliu Enlarged MAX_INTEGER_DIGITS to fully accommodate the * largest double, by default. * Changed DigitCount to int per code review. * 07/20/98 stephen Changed operator== to check for grouping diff --git a/deps/icu-small/source/i18n/numparse_affixes.cpp b/deps/icu-small/source/i18n/numparse_affixes.cpp index 187830fb6fc0dff8669bb383a4a7cd7a78678736..cef1685d03cd852d823770f20eda137d8fc14b3c 100644 --- a/deps/icu-small/source/i18n/numparse_affixes.cpp +++ b/deps/icu-small/source/i18n/numparse_affixes.cpp @@ -127,8 +127,8 @@ void AffixPatternMatcherBuilder::addMatcher(NumberParseMatcher& matcher) { fMatchers[fMatchersLen++] = &matcher; } -AffixPatternMatcher AffixPatternMatcherBuilder::build() { - return AffixPatternMatcher(fMatchers, fMatchersLen, fPattern); +AffixPatternMatcher AffixPatternMatcherBuilder::build(UErrorCode& status) { + return AffixPatternMatcher(fMatchers, fMatchersLen, fPattern, status); } AffixTokenMatcherWarehouse::AffixTokenMatcherWarehouse(const AffixTokenMatcherSetupData* setupData) @@ -209,12 +209,13 @@ AffixPatternMatcher AffixPatternMatcher::fromAffixPattern(const UnicodeString& a AffixPatternMatcherBuilder builder(affixPattern, tokenWarehouse, ignorables); AffixUtils::iterateWithConsumer(affixPattern, builder, status); - return builder.build(); + return builder.build(status); } AffixPatternMatcher::AffixPatternMatcher(MatcherArray& matchers, int32_t matchersLen, - const UnicodeString& pattern) - : ArraySeriesMatcher(matchers, matchersLen), fPattern(pattern) {} + const UnicodeString& pattern, UErrorCode& status) + : ArraySeriesMatcher(matchers, matchersLen), fPattern(pattern, status) { +} UnicodeString AffixPatternMatcher::getPattern() const { return fPattern.toAliasedUnicodeString(); diff --git a/deps/icu-small/source/i18n/numparse_affixes.h b/deps/icu-small/source/i18n/numparse_affixes.h index 2ac69df109519edd3786580aafe57fbcfc31079b..511c73c745380d7e4e1f4cb7e56241e1cb1c0ab9 100644 --- a/deps/icu-small/source/i18n/numparse_affixes.h +++ b/deps/icu-small/source/i18n/numparse_affixes.h @@ -128,7 +128,7 @@ class AffixPatternMatcherBuilder : public TokenConsumer, public MutableMatcherCo void consumeToken(::icu::number::impl::AffixPatternType type, UChar32 cp, UErrorCode& status) override; /** NOTE: You can build only once! */ - AffixPatternMatcher build(); + AffixPatternMatcher build(UErrorCode& status); private: ArraySeriesMatcher::MatcherArray fMatchers; @@ -160,7 +160,8 @@ class U_I18N_API AffixPatternMatcher : public ArraySeriesMatcher { private: CompactUnicodeString<4> fPattern; - AffixPatternMatcher(MatcherArray& matchers, int32_t matchersLen, const UnicodeString& pattern); + AffixPatternMatcher(MatcherArray& matchers, int32_t matchersLen, const UnicodeString& pattern, + UErrorCode& status); friend class AffixPatternMatcherBuilder; }; diff --git a/deps/icu-small/source/i18n/numparse_types.h b/deps/icu-small/source/i18n/numparse_types.h index b4007c2ff5b52ceb28d330e477f4a761c48f029d..623f0e80f1668a574f1657a7e09da55d511ec944 100644 --- a/deps/icu-small/source/i18n/numparse_types.h +++ b/deps/icu-small/source/i18n/numparse_types.h @@ -64,14 +64,15 @@ class CompactUnicodeString { fBuffer[0] = 0; } - CompactUnicodeString(const UnicodeString& text) - : fBuffer(text.length() + 1) { + CompactUnicodeString(const UnicodeString& text, UErrorCode& status) + : fBuffer(text.length() + 1, status) { + if (U_FAILURE(status)) { return; } uprv_memcpy(fBuffer.getAlias(), text.getBuffer(), sizeof(UChar) * text.length()); fBuffer[text.length()] = 0; } inline UnicodeString toAliasedUnicodeString() const { - return UnicodeString(TRUE, fBuffer.getAlias(), -1); + return UnicodeString(true, fBuffer.getAlias(), -1); } bool operator==(const CompactUnicodeString& other) const { diff --git a/deps/icu-small/source/i18n/numrange_capi.cpp b/deps/icu-small/source/i18n/numrange_capi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a440a53fe6b173e0456773b381b207956c219071 --- /dev/null +++ b/deps/icu-small/source/i18n/numrange_capi.cpp @@ -0,0 +1,193 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING + +// Allow implicit conversion from char16_t* to UnicodeString for this file: +// Helpful in toString methods and elsewhere. +#define UNISTR_FROM_STRING_EXPLICIT + +#include "fphdlimp.h" +#include "number_utypes.h" +#include "numparse_types.h" +#include "formattedval_impl.h" +#include "numrange_impl.h" +#include "number_decnum.h" +#include "unicode/numberrangeformatter.h" +#include "unicode/unumberrangeformatter.h" + +using namespace icu; +using namespace icu::number; +using namespace icu::number::impl; + + +U_NAMESPACE_BEGIN +namespace number { +namespace impl { + +/** + * Implementation class for UNumberRangeFormatter. Wraps a LocalizedRangeNumberFormatter. + */ +struct UNumberRangeFormatterData : public UMemory, + // Magic number as ASCII == "NRF" (NumberRangeFormatter) + public IcuCApiHelper { + LocalizedNumberRangeFormatter fFormatter; +}; + +struct UFormattedNumberRangeImpl; + +// Magic number as ASCII == "FDN" (FormatteDNumber) +typedef IcuCApiHelper UFormattedNumberRangeApiHelper; + +struct UFormattedNumberRangeImpl : public UFormattedValueImpl, public UFormattedNumberRangeApiHelper { + UFormattedNumberRangeImpl(); + ~UFormattedNumberRangeImpl(); + + FormattedNumberRange fImpl; + UFormattedNumberRangeData fData; +}; + +UFormattedNumberRangeImpl::UFormattedNumberRangeImpl() + : fImpl(&fData) { + fFormattedValue = &fImpl; +} + +UFormattedNumberRangeImpl::~UFormattedNumberRangeImpl() { + // Disown the data from fImpl so it doesn't get deleted twice + fImpl.fData = nullptr; +} + +} // namespace impl +} // namespace number +U_NAMESPACE_END + + +UPRV_FORMATTED_VALUE_CAPI_NO_IMPLTYPE_AUTO_IMPL( + UFormattedNumberRange, + UFormattedNumberRangeImpl, + UFormattedNumberRangeApiHelper, + unumrf) + + +const UFormattedNumberRangeData* number::impl::validateUFormattedNumberRange( + const UFormattedNumberRange* uresult, UErrorCode& status) { + auto* result = UFormattedNumberRangeApiHelper::validate(uresult, status); + if (U_FAILURE(status)) { + return nullptr; + } + return &result->fData; +} + + +U_CAPI UNumberRangeFormatter* U_EXPORT2 +unumrf_openForSkeletonWithCollapseAndIdentityFallback( + const UChar* skeleton, + int32_t skeletonLen, + UNumberRangeCollapse collapse, + UNumberRangeIdentityFallback identityFallback, + const char* locale, + UParseError* perror, + UErrorCode* ec) { + auto* impl = new UNumberRangeFormatterData(); + if (impl == nullptr) { + *ec = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } + // Readonly-alias constructor (first argument is whether we are NUL-terminated) + UnicodeString skeletonString(skeletonLen == -1, skeleton, skeletonLen); + impl->fFormatter = NumberRangeFormatter::withLocale(locale) + .numberFormatterBoth(NumberFormatter::forSkeleton(skeletonString, *perror, *ec)) + .collapse(collapse) + .identityFallback(identityFallback); + return impl->exportForC(); +} + +U_CAPI void U_EXPORT2 +unumrf_formatDoubleRange( + const UNumberRangeFormatter* uformatter, + double first, + double second, + UFormattedNumberRange* uresult, + UErrorCode* ec) { + const UNumberRangeFormatterData* formatter = UNumberRangeFormatterData::validate(uformatter, *ec); + auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec); + if (U_FAILURE(*ec)) { return; } + + result->fData.getStringRef().clear(); + result->fData.quantity1.setToDouble(first); + result->fData.quantity2.setToDouble(second); + formatter->fFormatter.formatImpl(result->fData, first == second, *ec); +} + +U_CAPI void U_EXPORT2 +unumrf_formatDecimalRange( + const UNumberRangeFormatter* uformatter, + const char* first, int32_t firstLen, + const char* second, int32_t secondLen, + UFormattedNumberRange* uresult, + UErrorCode* ec) { + const UNumberRangeFormatterData* formatter = UNumberRangeFormatterData::validate(uformatter, *ec); + auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec); + if (U_FAILURE(*ec)) { return; } + + result->fData.getStringRef().clear(); + result->fData.quantity1.setToDecNumber({first, firstLen}, *ec); + result->fData.quantity2.setToDecNumber({second, secondLen}, *ec); + formatter->fFormatter.formatImpl(result->fData, first == second, *ec); +} + +U_CAPI UNumberRangeIdentityResult U_EXPORT2 +unumrf_resultGetIdentityResult( + const UFormattedNumberRange* uresult, + UErrorCode* ec) { + auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec); + if (U_FAILURE(*ec)) { + return UNUM_IDENTITY_RESULT_COUNT; + } + return result->fData.identityResult; +} + +U_CAPI int32_t U_EXPORT2 +unumrf_resultGetFirstDecimalNumber( + const UFormattedNumberRange* uresult, + char* dest, + int32_t destCapacity, + UErrorCode* ec) { + const auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec); + if (U_FAILURE(*ec)) { + return 0; + } + DecNum decnum; + return result->fData.quantity1.toDecNum(decnum, *ec) + .toCharString(*ec) + .extract(dest, destCapacity, *ec); +} + +U_CAPI int32_t U_EXPORT2 +unumrf_resultGetSecondDecimalNumber( + const UFormattedNumberRange* uresult, + char* dest, + int32_t destCapacity, + UErrorCode* ec) { + const auto* result = UFormattedNumberRangeApiHelper::validate(uresult, *ec); + if (U_FAILURE(*ec)) { + return 0; + } + DecNum decnum; + return result->fData.quantity2 + .toDecNum(decnum, *ec) + .toCharString(*ec) + .extract(dest, destCapacity, *ec); +} + +U_CAPI void U_EXPORT2 +unumrf_close(UNumberRangeFormatter* f) { + UErrorCode localStatus = U_ZERO_ERROR; + const UNumberRangeFormatterData* impl = UNumberRangeFormatterData::validate(f, localStatus); + delete impl; +} + + +#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/numrange_fluent.cpp b/deps/icu-small/source/i18n/numrange_fluent.cpp index 33179026f8d2b53f3cbbb18eaf2fbf82bdc51167..f1060b3c21d45ea9239690daaf5a42ca5f11e86b 100644 --- a/deps/icu-small/source/i18n/numrange_fluent.cpp +++ b/deps/icu-small/source/i18n/numrange_fluent.cpp @@ -12,6 +12,7 @@ #include "numrange_impl.h" #include "util.h" #include "number_utypes.h" +#include "number_decnum.h" using namespace icu; using namespace icu::number; @@ -244,6 +245,7 @@ LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(NFS&& src) U_N } LocalizedNumberRangeFormatter& LocalizedNumberRangeFormatter::operator=(const LNF& other) { + if (this == &other) { return *this; } // self-assignment: no-op NFS::operator=(static_cast&>(other)); // Do not steal; just clear delete fAtomicFormatter.exchange(nullptr); @@ -375,28 +377,4 @@ LocalizedNumberRangeFormatter::getFormatter(UErrorCode& status) const { } -UPRV_FORMATTED_VALUE_SUBCLASS_AUTO_IMPL(FormattedNumberRange) - -#define UPRV_NOARG - -UnicodeString FormattedNumberRange::getFirstDecimal(UErrorCode& status) const { - UPRV_FORMATTED_VALUE_METHOD_GUARD(ICU_Utility::makeBogusString()) - return fData->quantity1.toScientificString(); -} - -UnicodeString FormattedNumberRange::getSecondDecimal(UErrorCode& status) const { - UPRV_FORMATTED_VALUE_METHOD_GUARD(ICU_Utility::makeBogusString()) - return fData->quantity2.toScientificString(); -} - -UNumberRangeIdentityResult FormattedNumberRange::getIdentityResult(UErrorCode& status) const { - UPRV_FORMATTED_VALUE_METHOD_GUARD(UNUM_IDENTITY_RESULT_NOT_EQUAL) - return fData->identityResult; -} - - -UFormattedNumberRangeData::~UFormattedNumberRangeData() = default; - - - #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/numrange_impl.cpp b/deps/icu-small/source/i18n/numrange_impl.cpp index 9fb3dee861f1f611546ea936deb89db0c4262afd..aa713f1398b5027bd24e4e20038f40c62a18590a 100644 --- a/deps/icu-small/source/i18n/numrange_impl.cpp +++ b/deps/icu-small/source/i18n/numrange_impl.cpp @@ -12,6 +12,7 @@ #include "unicode/numberrangeformatter.h" #include "numrange_impl.h" #include "patternprops.h" +#include "pluralranges.h" #include "uresimp.h" #include "util.h" @@ -106,92 +107,9 @@ void getNumberRangeData(const char* localeName, const char* nsName, NumberRangeD sink.fillInDefaults(status); } -class PluralRangesDataSink : public ResourceSink { - public: - PluralRangesDataSink(StandardPluralRanges& output) : fOutput(output) {} - - void put(const char* /*key*/, ResourceValue& value, UBool /*noFallback*/, UErrorCode& status) U_OVERRIDE { - ResourceArray entriesArray = value.getArray(status); - if (U_FAILURE(status)) { return; } - fOutput.setCapacity(entriesArray.getSize()); - for (int i = 0; entriesArray.getValue(i, value); i++) { - ResourceArray pluralFormsArray = value.getArray(status); - if (U_FAILURE(status)) { return; } - pluralFormsArray.getValue(0, value); - StandardPlural::Form first = StandardPlural::fromString(value.getUnicodeString(status), status); - if (U_FAILURE(status)) { return; } - pluralFormsArray.getValue(1, value); - StandardPlural::Form second = StandardPlural::fromString(value.getUnicodeString(status), status); - if (U_FAILURE(status)) { return; } - pluralFormsArray.getValue(2, value); - StandardPlural::Form result = StandardPlural::fromString(value.getUnicodeString(status), status); - if (U_FAILURE(status)) { return; } - fOutput.addPluralRange(first, second, result); - } - } - - private: - StandardPluralRanges& fOutput; -}; - -void getPluralRangesData(const Locale& locale, StandardPluralRanges& output, UErrorCode& status) { - if (U_FAILURE(status)) { return; } - LocalUResourceBundlePointer rb(ures_openDirect(nullptr, "pluralRanges", &status)); - if (U_FAILURE(status)) { return; } - - CharString dataPath; - dataPath.append("locales/", -1, status); - dataPath.append(locale.getLanguage(), -1, status); - if (U_FAILURE(status)) { return; } - int32_t setLen; - // Not all languages are covered: fail gracefully - UErrorCode internalStatus = U_ZERO_ERROR; - const UChar* set = ures_getStringByKeyWithFallback(rb.getAlias(), dataPath.data(), &setLen, &internalStatus); - if (U_FAILURE(internalStatus)) { return; } - - dataPath.clear(); - dataPath.append("rules/", -1, status); - dataPath.appendInvariantChars(set, setLen, status); - if (U_FAILURE(status)) { return; } - PluralRangesDataSink sink(output); - ures_getAllItemsWithFallback(rb.getAlias(), dataPath.data(), sink, status); - if (U_FAILURE(status)) { return; } -} - } // namespace -void StandardPluralRanges::initialize(const Locale& locale, UErrorCode& status) { - getPluralRangesData(locale, *this, status); -} - -void StandardPluralRanges::addPluralRange( - StandardPlural::Form first, - StandardPlural::Form second, - StandardPlural::Form result) { - U_ASSERT(fTriplesLen < fTriples.getCapacity()); - fTriples[fTriplesLen] = {first, second, result}; - fTriplesLen++; -} - -void StandardPluralRanges::setCapacity(int32_t length) { - if (length > fTriples.getCapacity()) { - fTriples.resize(length, 0); - } -} - -StandardPlural::Form -StandardPluralRanges::resolve(StandardPlural::Form first, StandardPlural::Form second) const { - for (int32_t i=0; isemanticallyEquivalent(*micros2.modInner); - // All done checking for collapsability. + // All done checking for collapsibility. break; } @@ -410,6 +328,7 @@ void NumberRangeFormatterImpl::formatRange(UFormattedNumberRangeData& data, #define UPRV_INDEX_1 (lengthPrefix + length1) #define UPRV_INDEX_2 (lengthPrefix + length1 + lengthInfix) #define UPRV_INDEX_3 (lengthPrefix + length1 + lengthInfix + length2) + #define UPRV_INDEX_4 (lengthPrefix + length1 + lengthInfix + length2 + lengthSuffix) int32_t lengthRange = SimpleModifier::formatTwoArgPattern( fRangeFormatter, @@ -449,31 +368,38 @@ void NumberRangeFormatterImpl::formatRange(UFormattedNumberRangeData& data, // TODO: Support padding? if (collapseInner) { - // Note: this is actually a mix of prefix and suffix, but adding to infix length works const Modifier& mod = resolveModifierPlurals(*micros1.modInner, *micros2.modInner); - lengthInfix += mod.apply(string, UPRV_INDEX_0, UPRV_INDEX_3, status); + lengthSuffix += mod.apply(string, UPRV_INDEX_0, UPRV_INDEX_4, status); + lengthPrefix += mod.getPrefixLength(); + lengthSuffix -= mod.getPrefixLength(); } else { length1 += micros1.modInner->apply(string, UPRV_INDEX_0, UPRV_INDEX_1, status); - length2 += micros2.modInner->apply(string, UPRV_INDEX_2, UPRV_INDEX_3, status); + length2 += micros2.modInner->apply(string, UPRV_INDEX_2, UPRV_INDEX_4, status); } if (collapseMiddle) { - // Note: this is actually a mix of prefix and suffix, but adding to infix length works const Modifier& mod = resolveModifierPlurals(*micros1.modMiddle, *micros2.modMiddle); - lengthInfix += mod.apply(string, UPRV_INDEX_0, UPRV_INDEX_3, status); + lengthSuffix += mod.apply(string, UPRV_INDEX_0, UPRV_INDEX_4, status); + lengthPrefix += mod.getPrefixLength(); + lengthSuffix -= mod.getPrefixLength(); } else { length1 += micros1.modMiddle->apply(string, UPRV_INDEX_0, UPRV_INDEX_1, status); - length2 += micros2.modMiddle->apply(string, UPRV_INDEX_2, UPRV_INDEX_3, status); + length2 += micros2.modMiddle->apply(string, UPRV_INDEX_2, UPRV_INDEX_4, status); } if (collapseOuter) { - // Note: this is actually a mix of prefix and suffix, but adding to infix length works const Modifier& mod = resolveModifierPlurals(*micros1.modOuter, *micros2.modOuter); - lengthInfix += mod.apply(string, UPRV_INDEX_0, UPRV_INDEX_3, status); + lengthSuffix += mod.apply(string, UPRV_INDEX_0, UPRV_INDEX_4, status); + lengthPrefix += mod.getPrefixLength(); + lengthSuffix -= mod.getPrefixLength(); } else { length1 += micros1.modOuter->apply(string, UPRV_INDEX_0, UPRV_INDEX_1, status); - length2 += micros2.modOuter->apply(string, UPRV_INDEX_2, UPRV_INDEX_3, status); + length2 += micros2.modOuter->apply(string, UPRV_INDEX_2, UPRV_INDEX_4, status); } + + // Now that all pieces are added, save the span info. + data.appendSpanInfo(UFIELD_CATEGORY_NUMBER_RANGE_SPAN, 0, UPRV_INDEX_0, length1, status); + data.appendSpanInfo(UFIELD_CATEGORY_NUMBER_RANGE_SPAN, 1, UPRV_INDEX_2, length2, status); } diff --git a/deps/icu-small/source/i18n/numrange_impl.h b/deps/icu-small/source/i18n/numrange_impl.h index 8f4c8a40ba2fdc7e7ece251d2cb618d73f187ed5..b81a311a5f393d300729d6334d9b6973ffea05ad 100644 --- a/deps/icu-small/source/i18n/numrange_impl.h +++ b/deps/icu-small/source/i18n/numrange_impl.h @@ -15,6 +15,7 @@ #include "number_formatimpl.h" #include "formatted_string_builder.h" #include "formattedval_impl.h" +#include "pluralranges.h" U_NAMESPACE_BEGIN namespace number { namespace impl { @@ -40,36 +41,6 @@ public: }; -class StandardPluralRanges : public UMemory { - public: - void initialize(const Locale& locale, UErrorCode& status); - StandardPlural::Form resolve(StandardPlural::Form first, StandardPlural::Form second) const; - - /** Used for data loading. */ - void addPluralRange( - StandardPlural::Form first, - StandardPlural::Form second, - StandardPlural::Form result); - - /** Used for data loading. */ - void setCapacity(int32_t length); - - private: - struct StandardPluralRangeTriple { - StandardPlural::Form first; - StandardPlural::Form second; - StandardPlural::Form result; - }; - - // TODO: An array is simple here, but it results in linear lookup time. - // Certain locales have 20-30 entries in this list. - // Consider changing to a smarter data structure. - typedef MaybeStackArray PluralRangeTriples; - PluralRangeTriples fTriples; - int32_t fTriplesLen = 0; -}; - - class NumberRangeFormatterImpl : public UMemory { public: NumberRangeFormatterImpl(const RangeMacroProps& macros, UErrorCode& status); @@ -105,6 +76,11 @@ class NumberRangeFormatterImpl : public UMemory { }; +/** Helper function used in upluralrules.cpp */ +const UFormattedNumberRangeData* validateUFormattedNumberRange( + const UFormattedNumberRange* uresult, UErrorCode& status); + + } // namespace impl } // namespace number U_NAMESPACE_END diff --git a/deps/icu-small/source/i18n/olsontz.cpp b/deps/icu-small/source/i18n/olsontz.cpp index dd01180f8cc078195fbdcf87e63ee047ee018030..67aa1f7af81d680bd1677c76574b8d9b315f7c3b 100644 --- a/deps/icu-small/source/i18n/olsontz.cpp +++ b/deps/icu-small/source/i18n/olsontz.cpp @@ -197,58 +197,60 @@ OlsonTimeZone::OlsonTimeZone(const UResourceBundle* top, } // Process final rule and data, if any - const UChar *ruleIdUStr = ures_getStringByKey(res, kFINALRULE, &len, &ec); - ures_getByKey(res, kFINALRAW, r.getAlias(), &ec); - int32_t ruleRaw = ures_getInt(r.getAlias(), &ec); - ures_getByKey(res, kFINALYEAR, r.getAlias(), &ec); - int32_t ruleYear = ures_getInt(r.getAlias(), &ec); if (U_SUCCESS(ec)) { - UnicodeString ruleID(TRUE, ruleIdUStr, len); - UResourceBundle *rule = TimeZone::loadRule(top, ruleID, NULL, ec); - const int32_t *ruleData = ures_getIntVector(rule, &len, &ec); - if (U_SUCCESS(ec) && len == 11) { - UnicodeString emptyStr; - finalZone = new SimpleTimeZone( - ruleRaw * U_MILLIS_PER_SECOND, - emptyStr, - (int8_t)ruleData[0], (int8_t)ruleData[1], (int8_t)ruleData[2], - ruleData[3] * U_MILLIS_PER_SECOND, - (SimpleTimeZone::TimeMode) ruleData[4], - (int8_t)ruleData[5], (int8_t)ruleData[6], (int8_t)ruleData[7], - ruleData[8] * U_MILLIS_PER_SECOND, - (SimpleTimeZone::TimeMode) ruleData[9], - ruleData[10] * U_MILLIS_PER_SECOND, ec); - if (finalZone == NULL) { - ec = U_MEMORY_ALLOCATION_ERROR; - } else { - finalStartYear = ruleYear; + const UChar *ruleIdUStr = ures_getStringByKey(res, kFINALRULE, &len, &ec); + ures_getByKey(res, kFINALRAW, r.getAlias(), &ec); + int32_t ruleRaw = ures_getInt(r.getAlias(), &ec); + ures_getByKey(res, kFINALYEAR, r.getAlias(), &ec); + int32_t ruleYear = ures_getInt(r.getAlias(), &ec); + if (U_SUCCESS(ec)) { + UnicodeString ruleID(TRUE, ruleIdUStr, len); + UResourceBundle *rule = TimeZone::loadRule(top, ruleID, NULL, ec); + const int32_t *ruleData = ures_getIntVector(rule, &len, &ec); + if (U_SUCCESS(ec) && len == 11) { + UnicodeString emptyStr; + finalZone = new SimpleTimeZone( + ruleRaw * U_MILLIS_PER_SECOND, + emptyStr, + (int8_t)ruleData[0], (int8_t)ruleData[1], (int8_t)ruleData[2], + ruleData[3] * U_MILLIS_PER_SECOND, + (SimpleTimeZone::TimeMode) ruleData[4], + (int8_t)ruleData[5], (int8_t)ruleData[6], (int8_t)ruleData[7], + ruleData[8] * U_MILLIS_PER_SECOND, + (SimpleTimeZone::TimeMode) ruleData[9], + ruleData[10] * U_MILLIS_PER_SECOND, ec); + if (finalZone == NULL) { + ec = U_MEMORY_ALLOCATION_ERROR; + } else { + finalStartYear = ruleYear; - // Note: Setting finalStartYear to the finalZone is problematic. When a date is around - // year boundary, SimpleTimeZone may return false result when DST is observed at the - // beginning of year. We could apply safe margin (day or two), but when one of recurrent - // rules falls around year boundary, it could return false result. Without setting the - // start year, finalZone works fine around the year boundary of the start year. + // Note: Setting finalStartYear to the finalZone is problematic. When a date is around + // year boundary, SimpleTimeZone may return false result when DST is observed at the + // beginning of year. We could apply safe margin (day or two), but when one of recurrent + // rules falls around year boundary, it could return false result. Without setting the + // start year, finalZone works fine around the year boundary of the start year. - // finalZone->setStartYear(finalStartYear); + // finalZone->setStartYear(finalStartYear); - // Compute the millis for Jan 1, 0:00 GMT of the finalYear + // Compute the millis for Jan 1, 0:00 GMT of the finalYear - // Note: finalStartMillis is used for detecting either if - // historic transition data or finalZone to be used. In an - // extreme edge case - for example, two transitions fall into - // small windows of time around the year boundary, this may - // result incorrect offset computation. But I think it will - // never happen practically. Yoshito - Feb 20, 2010 - finalStartMillis = Grego::fieldsToDay(finalStartYear, 0, 1) * U_MILLIS_PER_DAY; + // Note: finalStartMillis is used for detecting either if + // historic transition data or finalZone to be used. In an + // extreme edge case - for example, two transitions fall into + // small windows of time around the year boundary, this may + // result incorrect offset computation. But I think it will + // never happen practically. Yoshito - Feb 20, 2010 + finalStartMillis = Grego::fieldsToDay(finalStartYear, 0, 1) * U_MILLIS_PER_DAY; + } + } else { + ec = U_INVALID_FORMAT_ERROR; } - } else { - ec = U_INVALID_FORMAT_ERROR; + ures_close(rule); + } else if (ec == U_MISSING_RESOURCE_ERROR) { + // No final zone + ec = U_ZERO_ERROR; } - ures_close(rule); - } else if (ec == U_MISSING_RESOURCE_ERROR) { - // No final zone - ec = U_ZERO_ERROR; } // initialize canonical ID @@ -272,6 +274,7 @@ OlsonTimeZone::OlsonTimeZone(const OlsonTimeZone& other) : * Assignment operator */ OlsonTimeZone& OlsonTimeZone::operator=(const OlsonTimeZone& other) { + if (this == &other) { return *this; } // self-assignment: no-op canonicalID = other.canonicalID; transitionTimesPre32 = other.transitionTimesPre32; @@ -397,9 +400,9 @@ void OlsonTimeZone::getOffset(UDate date, UBool local, int32_t& rawoff, } } -void -OlsonTimeZone::getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt, - int32_t& rawoff, int32_t& dstoff, UErrorCode& ec) const { +void OlsonTimeZone::getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt, + UTimeZoneLocalOption duplicatedTimeOpt, + int32_t& rawoff, int32_t& dstoff, UErrorCode& ec) const { if (U_FAILURE(ec)) { return; } @@ -810,7 +813,7 @@ OlsonTimeZone::initTransitionRules(UErrorCode& status) { if (finalZone->useDaylightTime()) { /* * Note: When an OlsonTimeZone is constructed, we should set the final year - * as the start year of finalZone. However, the bounday condition used for + * as the start year of finalZone. However, the boundary condition used for * getting offset from finalZone has some problems. * For now, we do not set the valid start year when the construction time * and create a clone and set the start year when extracting rules. diff --git a/deps/icu-small/source/i18n/olsontz.h b/deps/icu-small/source/i18n/olsontz.h index 79601546984a23843dc575bb9ebc4229fe98aa31..6bedb8792b0cd4dde35a0d3a5be764b5f258f9a8 100644 --- a/deps/icu-small/source/i18n/olsontz.h +++ b/deps/icu-small/source/i18n/olsontz.h @@ -187,8 +187,10 @@ class U_I18N_API OlsonTimeZone: public BasicTimeZone { /** * BasicTimeZone API. */ - virtual void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt, - int32_t& rawoff, int32_t& dstoff, UErrorCode& ec) const; + virtual void getOffsetFromLocal( + UDate date, UTimeZoneLocalOption nonExistingTimeOpt, + UTimeZoneLocalOption duplicatedTimeOpt, + int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const; /** * TimeZone API. This method has no effect since objects of this @@ -208,7 +210,7 @@ class U_I18N_API OlsonTimeZone: public BasicTimeZone { /** * TimeZone API. For a historical zone, whether DST is used or * not varies over time. In order to approximate expected - * behavior, this method returns TRUE if DST is observed at any + * behavior, this method returns true if DST is observed at any * point in the current year. */ virtual UBool useDaylightTime() const; @@ -234,7 +236,7 @@ class U_I18N_API OlsonTimeZone: public BasicTimeZone { * @param base The base time. * @param inclusive Whether the base time is inclusive or not. * @param result Receives the first transition after the base time. - * @return TRUE if the transition is found. + * @return true if the transition is found. */ virtual UBool getNextTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const; @@ -244,7 +246,7 @@ class U_I18N_API OlsonTimeZone: public BasicTimeZone { * @param base The base time. * @param inclusive Whether the base time is inclusive or not. * @param result Receives the most recent transition before the base time. - * @return TRUE if the transition is found. + * @return true if the transition is found. */ virtual UBool getPreviousTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const; diff --git a/deps/icu-small/source/i18n/persncal.cpp b/deps/icu-small/source/i18n/persncal.cpp index 4d366d41f0dffe3596edb6298e93339d8ae9cbf7..ba306653af28e0423656b746d6d9d5901f4f92e4 100644 --- a/deps/icu-small/source/i18n/persncal.cpp +++ b/deps/icu-small/source/i18n/persncal.cpp @@ -79,7 +79,7 @@ PersianCalendar* PersianCalendar::clone() const { } PersianCalendar::PersianCalendar(const Locale& aLocale, UErrorCode& success) - : Calendar(TimeZone::createDefault(), aLocale, success) + : Calendar(TimeZone::forLocaleOrDefault(aLocale), aLocale, success) { setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly. } diff --git a/deps/icu-small/source/i18n/persncal.h b/deps/icu-small/source/i18n/persncal.h index a9d940db78e6c7d939f087ba2d47fb1ed3d71a3e..f330ea8a0319b26dcefe018d09b488e6157a0826 100644 --- a/deps/icu-small/source/i18n/persncal.h +++ b/deps/icu-small/source/i18n/persncal.h @@ -295,7 +295,7 @@ class PersianCalendar : public Calendar { virtual UBool inDaylightTime(UErrorCode& status) const; /** - * Returns TRUE because the Persian Calendar does have a default century + * Returns true because the Persian Calendar does have a default century * @internal */ virtual UBool haveDefaultCentury() const; diff --git a/deps/icu-small/source/i18n/pluralranges.cpp b/deps/icu-small/source/i18n/pluralranges.cpp new file mode 100644 index 0000000000000000000000000000000000000000..da10e2117d04ad42a42772d0ff347d8d8b996a66 --- /dev/null +++ b/deps/icu-small/source/i18n/pluralranges.cpp @@ -0,0 +1,144 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING + +// Allow implicit conversion from char16_t* to UnicodeString for this file: +// Helpful in toString methods and elsewhere. +#define UNISTR_FROM_STRING_EXPLICIT + +#include "unicode/numberrangeformatter.h" +#include "pluralranges.h" +#include "uresimp.h" +#include "charstr.h" +#include "uassert.h" +#include "util.h" +#include "numrange_impl.h" + +U_NAMESPACE_BEGIN + + +namespace { + +class PluralRangesDataSink : public ResourceSink { + public: + PluralRangesDataSink(StandardPluralRanges& output) : fOutput(output) {} + + void put(const char* /*key*/, ResourceValue& value, UBool /*noFallback*/, UErrorCode& status) U_OVERRIDE { + ResourceArray entriesArray = value.getArray(status); + if (U_FAILURE(status)) { return; } + fOutput.setCapacity(entriesArray.getSize(), status); + if (U_FAILURE(status)) { return; } + for (int i = 0; entriesArray.getValue(i, value); i++) { + ResourceArray pluralFormsArray = value.getArray(status); + if (U_FAILURE(status)) { return; } + if (pluralFormsArray.getSize() != 3) { + status = U_RESOURCE_TYPE_MISMATCH; + return; + } + pluralFormsArray.getValue(0, value); + StandardPlural::Form first = StandardPlural::fromString(value.getUnicodeString(status), status); + if (U_FAILURE(status)) { return; } + pluralFormsArray.getValue(1, value); + StandardPlural::Form second = StandardPlural::fromString(value.getUnicodeString(status), status); + if (U_FAILURE(status)) { return; } + pluralFormsArray.getValue(2, value); + StandardPlural::Form result = StandardPlural::fromString(value.getUnicodeString(status), status); + if (U_FAILURE(status)) { return; } + fOutput.addPluralRange(first, second, result); + } + } + + private: + StandardPluralRanges& fOutput; +}; + +void getPluralRangesData(const Locale& locale, StandardPluralRanges& output, UErrorCode& status) { + LocalUResourceBundlePointer rb(ures_openDirect(nullptr, "pluralRanges", &status)); + if (U_FAILURE(status)) { return; } + + CharString dataPath; + dataPath.append("locales/", -1, status); + dataPath.append(locale.getLanguage(), -1, status); + if (U_FAILURE(status)) { return; } + int32_t setLen; + // Not all languages are covered: fail gracefully + UErrorCode internalStatus = U_ZERO_ERROR; + const UChar* set = ures_getStringByKeyWithFallback(rb.getAlias(), dataPath.data(), &setLen, &internalStatus); + if (U_FAILURE(internalStatus)) { return; } + + dataPath.clear(); + dataPath.append("rules/", -1, status); + dataPath.appendInvariantChars(set, setLen, status); + if (U_FAILURE(status)) { return; } + PluralRangesDataSink sink(output); + ures_getAllItemsWithFallback(rb.getAlias(), dataPath.data(), sink, status); +} + +} // namespace + + +StandardPluralRanges +StandardPluralRanges::forLocale(const Locale& locale, UErrorCode& status) { + StandardPluralRanges result; + getPluralRangesData(locale, result, status); + return result; +} + +StandardPluralRanges +StandardPluralRanges::copy(UErrorCode& status) const { + StandardPluralRanges result; + if (fTriplesLen > result.fTriples.getCapacity()) { + if (result.fTriples.resize(fTriplesLen) == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return result; + } + } + uprv_memcpy(result.fTriples.getAlias(), + fTriples.getAlias(), + fTriplesLen * sizeof(fTriples[0])); + result.fTriplesLen = fTriplesLen; + return result; +} + +LocalPointer +StandardPluralRanges::toPointer(UErrorCode& status) && noexcept { + return LocalPointer(new StandardPluralRanges(std::move(*this)), status); +} + +void StandardPluralRanges::addPluralRange( + StandardPlural::Form first, + StandardPlural::Form second, + StandardPlural::Form result) { + U_ASSERT(fTriplesLen < fTriples.getCapacity()); + fTriples[fTriplesLen] = {first, second, result}; + fTriplesLen++; +} + +void StandardPluralRanges::setCapacity(int32_t length, UErrorCode& status) { + if (U_FAILURE(status)) { return; } + if (length > fTriples.getCapacity()) { + if (fTriples.resize(length, 0) == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + } + } +} + +StandardPlural::Form +StandardPluralRanges::resolve(StandardPlural::Form first, StandardPlural::Form second) const { + for (int32_t i=0; i toPointer(UErrorCode& status) && noexcept; + + /** Select rule based on the first and second forms */ + StandardPlural::Form resolve(StandardPlural::Form first, StandardPlural::Form second) const; + + /** Used for data loading. */ + void addPluralRange( + StandardPlural::Form first, + StandardPlural::Form second, + StandardPlural::Form result); + + /** Used for data loading. */ + void setCapacity(int32_t length, UErrorCode& status); + + private: + struct StandardPluralRangeTriple { + StandardPlural::Form first; + StandardPlural::Form second; + StandardPlural::Form result; + }; + + // TODO: An array is simple here, but it results in linear lookup time. + // Certain locales have 20-30 entries in this list. + // Consider changing to a smarter data structure. + typedef MaybeStackArray PluralRangeTriples; + PluralRangeTriples fTriples; + int32_t fTriplesLen = 0; +}; + +U_NAMESPACE_END + +#endif /* #if !UCONFIG_NO_FORMATTING */ +#endif //__PLURALRANGES_H__ diff --git a/deps/icu-small/source/i18n/plurfmt.cpp b/deps/icu-small/source/i18n/plurfmt.cpp index b99437630e67b5d2dc6d99ae1a1a9c8cb40c7100..aac35c5b094ff9cecf0456538f559d263cfb171e 100644 --- a/deps/icu-small/source/i18n/plurfmt.cpp +++ b/deps/icu-small/source/i18n/plurfmt.cpp @@ -549,9 +549,15 @@ void PluralFormat::parseType(const UnicodeString& source, const NFRule *rbnfLeni UnicodeString currArg = pattern.tempSubString(partStart->getLimit(), partLimit->getIndex() - partStart->getLimit()); if (rbnfLenientScanner != NULL) { - // If lenient parsing is turned ON, we've got some time consuming parsing ahead of us. - int32_t length = -1; - currMatchIndex = rbnfLenientScanner->findTextLenient(source, currArg, startingAt, &length); + // Check if non-lenient rule finds the text before call lenient parsing + int32_t tempIndex = source.indexOf(currArg, startingAt); + if (tempIndex >= 0) { + currMatchIndex = tempIndex; + } else { + // If lenient parsing is turned ON, we've got some time consuming parsing ahead of us. + int32_t length = -1; + currMatchIndex = rbnfLenientScanner->findTextLenient(source, currArg, startingAt, &length); + } } else { currMatchIndex = source.indexOf(currArg, startingAt); diff --git a/deps/icu-small/source/i18n/plurrule.cpp b/deps/icu-small/source/i18n/plurrule.cpp index 54e3b2cd86c960598a75388e35d4790bf40faab5..bc106acce23aef0fb5a350c105516d75ecab72e0 100644 --- a/deps/icu-small/source/i18n/plurrule.cpp +++ b/deps/icu-small/source/i18n/plurrule.cpp @@ -19,6 +19,7 @@ #include "unicode/ures.h" #include "unicode/numfmt.h" #include "unicode/decimfmt.h" +#include "unicode/numberrangeformatter.h" #include "charstr.h" #include "cmemory.h" #include "cstring.h" @@ -36,6 +37,8 @@ #include "unifiedcache.h" #include "number_decimalquantity.h" #include "util.h" +#include "pluralranges.h" +#include "numrange_impl.h" #if !UCONFIG_NO_FORMATTING @@ -56,6 +59,8 @@ static const UChar PK_VAR_N[]={LOW_N,0}; static const UChar PK_VAR_I[]={LOW_I,0}; static const UChar PK_VAR_F[]={LOW_F,0}; static const UChar PK_VAR_T[]={LOW_T,0}; +static const UChar PK_VAR_E[]={LOW_E,0}; +static const UChar PK_VAR_C[]={LOW_C,0}; static const UChar PK_VAR_V[]={LOW_V,0}; static const UChar PK_WITHIN[]={LOW_W,LOW_I,LOW_T,LOW_H,LOW_I,LOW_N,0}; static const UChar PK_DECIMAL[]={LOW_D,LOW_E,LOW_C,LOW_I,LOW_M,LOW_A,LOW_L,0}; @@ -67,6 +72,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(PluralKeywordEnumeration) PluralRules::PluralRules(UErrorCode& /*status*/) : UObject(), mRules(nullptr), + mStandardPluralRanges(nullptr), mInternalStatus(U_ZERO_ERROR) { } @@ -74,6 +80,7 @@ PluralRules::PluralRules(UErrorCode& /*status*/) PluralRules::PluralRules(const PluralRules& other) : UObject(other), mRules(nullptr), + mStandardPluralRanges(nullptr), mInternalStatus(U_ZERO_ERROR) { *this=other; @@ -81,6 +88,7 @@ PluralRules::PluralRules(const PluralRules& other) PluralRules::~PluralRules() { delete mRules; + delete mStandardPluralRanges; } SharedPluralRules::~SharedPluralRules() { @@ -89,14 +97,20 @@ SharedPluralRules::~SharedPluralRules() { PluralRules* PluralRules::clone() const { - PluralRules* newObj = new PluralRules(*this); // Since clone doesn't have a 'status' parameter, the best we can do is return nullptr if // the newly created object was not fully constructed properly (an error occurred). - if (newObj != nullptr && U_FAILURE(newObj->mInternalStatus)) { - delete newObj; - newObj = nullptr; + UErrorCode localStatus = U_ZERO_ERROR; + return clone(localStatus); +} + +PluralRules* +PluralRules::clone(UErrorCode& status) const { + LocalPointer newObj(new PluralRules(*this), status); + if (U_SUCCESS(status) && U_FAILURE(newObj->mInternalStatus)) { + status = newObj->mInternalStatus; + newObj.adoptInstead(nullptr); } - return newObj; + return newObj.orphan(); } PluralRules& @@ -104,6 +118,8 @@ PluralRules::operator=(const PluralRules& other) { if (this != &other) { delete mRules; mRules = nullptr; + delete mStandardPluralRanges; + mStandardPluralRanges = nullptr; mInternalStatus = other.mInternalStatus; if (U_FAILURE(mInternalStatus)) { // bail out early if the object we were copying from was already 'invalid'. @@ -119,6 +135,11 @@ PluralRules::operator=(const PluralRules& other) { mInternalStatus = mRules->fInternalStatus; } } + if (other.mStandardPluralRanges != nullptr) { + mStandardPluralRanges = other.mStandardPluralRanges->copy(mInternalStatus) + .toPointer(mInternalStatus) + .orphan(); + } } return *this; } @@ -211,11 +232,8 @@ PluralRules::forLocale(const Locale& locale, UPluralType type, UErrorCode& statu if (U_FAILURE(status)) { return nullptr; } - PluralRules *result = (*shared)->clone(); + PluralRules *result = (*shared)->clone(status); shared->removeRef(); - if (result == nullptr) { - status = U_MEMORY_ALLOCATION_ERROR; - } return result; } @@ -252,6 +270,10 @@ PluralRules::internalForLocale(const Locale& locale, UPluralType type, UErrorCod // Original impl used default rules. // Ask the question to ICU Core. + newObj->mStandardPluralRanges = StandardPluralRanges::forLocale(locale, status) + .toPointer(status) + .orphan(); + return newObj.orphan(); } @@ -272,6 +294,10 @@ PluralRules::select(const number::FormattedNumber& number, UErrorCode& status) c if (U_FAILURE(status)) { return ICU_Utility::makeBogusString(); } + if (U_FAILURE(mInternalStatus)) { + status = mInternalStatus; + return ICU_Utility::makeBogusString(); + } return select(dq); } @@ -285,6 +311,33 @@ PluralRules::select(const IFixedDecimal &number) const { } } +UnicodeString +PluralRules::select(const number::FormattedNumberRange& range, UErrorCode& status) const { + return select(range.getData(status), status); +} + +UnicodeString +PluralRules::select(const number::impl::UFormattedNumberRangeData* impl, UErrorCode& status) const { + if (U_FAILURE(status)) { + return ICU_Utility::makeBogusString(); + } + if (U_FAILURE(mInternalStatus)) { + status = mInternalStatus; + return ICU_Utility::makeBogusString(); + } + if (mStandardPluralRanges == nullptr) { + // Happens if PluralRules was constructed via createRules() + status = U_UNSUPPORTED_ERROR; + return ICU_Utility::makeBogusString(); + } + auto form1 = StandardPlural::fromString(select(impl->quantity1), status); + auto form2 = StandardPlural::fromString(select(impl->quantity2), status); + if (U_FAILURE(status)) { + return ICU_Utility::makeBogusString(); + } + auto result = mStandardPluralRanges->resolve(form1, form2); + return UnicodeString(StandardPlural::getKeyword(result), -1, US_INV); +} StringEnumeration* @@ -326,9 +379,23 @@ static double scaleForInt(double d) { return scale; } +/** + * Helper method for the overrides of getSamples() for double and FixedDecimal + * return value types. Provide only one of an allocated array of doubles or + * FixedDecimals, and a nullptr for the other. + */ static int32_t -getSamplesFromString(const UnicodeString &samples, double *dest, - int32_t destCapacity, UErrorCode& status) { +getSamplesFromString(const UnicodeString &samples, double *destDbl, + FixedDecimal* destFd, int32_t destCapacity, + UErrorCode& status) { + + if ((destDbl == nullptr && destFd == nullptr) + || (destDbl != nullptr && destFd != nullptr)) { + status = U_INTERNAL_PROGRAM_ERROR; + return 0; + } + + bool isDouble = destDbl != nullptr; int32_t sampleCount = 0; int32_t sampleStartIdx = 0; int32_t sampleEndIdx = 0; @@ -346,12 +413,15 @@ getSamplesFromString(const UnicodeString &samples, double *dest, int32_t tildeIndex = sampleRange.indexOf(TILDE); if (tildeIndex < 0) { FixedDecimal fixed(sampleRange, status); - double sampleValue = fixed.source; - if (fixed.visibleDecimalDigitCount == 0 || sampleValue != floor(sampleValue)) { - dest[sampleCount++] = sampleValue; + if (isDouble) { + double sampleValue = fixed.source; + if (fixed.visibleDecimalDigitCount == 0 || sampleValue != floor(sampleValue)) { + destDbl[sampleCount++] = sampleValue; + } + } else { + destFd[sampleCount++] = fixed; } } else { - FixedDecimal fixedLo(sampleRange.tempSubStringBetween(0, tildeIndex), status); FixedDecimal fixedHi(sampleRange.tempSubStringBetween(tildeIndex+1), status); double rangeLo = fixedLo.source; @@ -375,14 +445,21 @@ getSamplesFromString(const UnicodeString &samples, double *dest, rangeLo *= scale; rangeHi *= scale; for (double n=rangeLo; n<=rangeHi; n+=1) { - // Hack Alert: don't return any decimal samples with integer values that - // originated from a format with trailing decimals. - // This API is returning doubles, which can't distinguish having displayed - // zeros to the right of the decimal. - // This results in test failures with values mapping back to a different keyword. double sampleValue = n/scale; - if (!(sampleValue == floor(sampleValue) && fixedLo.visibleDecimalDigitCount > 0)) { - dest[sampleCount++] = sampleValue; + if (isDouble) { + // Hack Alert: don't return any decimal samples with integer values that + // originated from a format with trailing decimals. + // This API is returning doubles, which can't distinguish having displayed + // zeros to the right of the decimal. + // This results in test failures with values mapping back to a different keyword. + if (!(sampleValue == floor(sampleValue) && fixedLo.visibleDecimalDigitCount > 0)) { + destDbl[sampleCount++] = sampleValue; + } + } else { + int32_t v = (int32_t) fixedLo.getPluralOperand(PluralOperand::PLURAL_OPERAND_V); + int32_t e = (int32_t) fixedLo.getPluralOperand(PluralOperand::PLURAL_OPERAND_E); + FixedDecimal newSample = FixedDecimal::createWithExponent(sampleValue, v, e); + destFd[sampleCount++] = newSample; } if (sampleCount >= destCapacity) { break; @@ -394,24 +471,53 @@ getSamplesFromString(const UnicodeString &samples, double *dest, return sampleCount; } - int32_t PluralRules::getSamples(const UnicodeString &keyword, double *dest, int32_t destCapacity, UErrorCode& status) { - if (destCapacity == 0 || U_FAILURE(status)) { + if (U_FAILURE(status)) { return 0; } if (U_FAILURE(mInternalStatus)) { status = mInternalStatus; return 0; } + if (dest != nullptr ? destCapacity < 0 : destCapacity != 0) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } RuleChain *rc = rulesForKeyword(keyword); if (rc == nullptr) { return 0; } - int32_t numSamples = getSamplesFromString(rc->fIntegerSamples, dest, destCapacity, status); + int32_t numSamples = getSamplesFromString(rc->fIntegerSamples, dest, nullptr, destCapacity, status); if (numSamples == 0) { - numSamples = getSamplesFromString(rc->fDecimalSamples, dest, destCapacity, status); + numSamples = getSamplesFromString(rc->fDecimalSamples, dest, nullptr, destCapacity, status); + } + return numSamples; +} + +int32_t +PluralRules::getSamples(const UnicodeString &keyword, FixedDecimal *dest, + int32_t destCapacity, UErrorCode& status) { + if (U_FAILURE(status)) { + return 0; + } + if (U_FAILURE(mInternalStatus)) { + status = mInternalStatus; + return 0; + } + if (dest != nullptr ? destCapacity < 0 : destCapacity != 0) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + RuleChain *rc = rulesForKeyword(keyword); + if (rc == nullptr) { + return 0; + } + + int32_t numSamples = getSamplesFromString(rc->fIntegerSamples, nullptr, dest, destCapacity, status); + if (numSamples == 0) { + numSamples = getSamplesFromString(rc->fDecimalSamples, nullptr, dest, destCapacity, status); } return numSamples; } @@ -600,6 +706,8 @@ PluralRuleParser::parse(const UnicodeString& ruleData, PluralRules *prules, UErr case tVariableI: case tVariableF: case tVariableT: + case tVariableE: + case tVariableC: case tVariableV: U_ASSERT(curAndConstraint != nullptr); curAndConstraint->digitsType = type; @@ -984,6 +1092,10 @@ static UnicodeString tokenString(tokenType tok) { s.append(LOW_V); break; case tVariableT: s.append(LOW_T); break; + case tVariableE: + s.append(LOW_E); break; + case tVariableC: + s.append(LOW_C); break; default: s.append(TILDE); } @@ -1160,6 +1272,8 @@ PluralRuleParser::checkSyntax(UErrorCode &status) case tVariableI: case tVariableF: case tVariableT: + case tVariableE: + case tVariableC: case tVariableV: if (type != tIs && type != tMod && type != tIn && type != tNot && type != tWithin && type != tEqual && type != tNotEqual) { @@ -1176,6 +1290,8 @@ PluralRuleParser::checkSyntax(UErrorCode &status) type == tVariableI || type == tVariableF || type == tVariableT || + type == tVariableE || + type == tVariableC || type == tVariableV || type == tAt)) { status = U_UNEXPECTED_TOKEN; @@ -1207,6 +1323,8 @@ PluralRuleParser::checkSyntax(UErrorCode &status) type != tVariableI && type != tVariableF && type != tVariableT && + type != tVariableE && + type != tVariableC && type != tVariableV) { status = U_UNEXPECTED_TOKEN; } @@ -1384,6 +1502,10 @@ PluralRuleParser::getKeyType(const UnicodeString &token, tokenType keyType) keyType = tVariableF; } else if (0 == token.compare(PK_VAR_T, 1)) { keyType = tVariableT; + } else if (0 == token.compare(PK_VAR_E, 1)) { + keyType = tVariableE; + } else if (0 == token.compare(PK_VAR_C, 1)) { + keyType = tVariableC; } else if (0 == token.compare(PK_VAR_V, 1)) { keyType = tVariableV; } else if (0 == token.compare(PK_IS, 2)) { @@ -1481,13 +1603,21 @@ PluralOperand tokenTypeToPluralOperand(tokenType tt) { return PLURAL_OPERAND_V; case tVariableT: return PLURAL_OPERAND_T; + case tVariableE: + return PLURAL_OPERAND_E; + case tVariableC: + return PLURAL_OPERAND_E; default: UPRV_UNREACHABLE; // unexpected. } } -FixedDecimal::FixedDecimal(double n, int32_t v, int64_t f) { - init(n, v, f); +FixedDecimal::FixedDecimal(double n, int32_t v, int64_t f, int32_t e, int32_t c) { + init(n, v, f, e, c); +} + +FixedDecimal::FixedDecimal(double n, int32_t v, int64_t f, int32_t e) { + init(n, v, f, e); // check values. TODO make into unit test. // // long visiblePower = (int) Math.pow(10, v); @@ -1503,6 +1633,10 @@ FixedDecimal::FixedDecimal(double n, int32_t v, int64_t f) { // } } +FixedDecimal::FixedDecimal(double n, int32_t v, int64_t f) { + init(n, v, f); +} + FixedDecimal::FixedDecimal(double n, int32_t v) { // Ugly, but for samples we don't care. init(n, v, getFractionalDigits(n, v)); @@ -1522,20 +1656,50 @@ FixedDecimal::FixedDecimal() { FixedDecimal::FixedDecimal(const UnicodeString &num, UErrorCode &status) { CharString cs; - cs.appendInvariantChars(num, status); + int32_t parsedExponent = 0; + int32_t parsedCompactExponent = 0; + + int32_t exponentIdx = num.indexOf(u'e'); + if (exponentIdx < 0) { + exponentIdx = num.indexOf(u'E'); + } + int32_t compactExponentIdx = num.indexOf(u'c'); + if (compactExponentIdx < 0) { + compactExponentIdx = num.indexOf(u'C'); + } + + if (exponentIdx >= 0) { + cs.appendInvariantChars(num.tempSubString(0, exponentIdx), status); + int32_t expSubstrStart = exponentIdx + 1; + parsedExponent = ICU_Utility::parseAsciiInteger(num, expSubstrStart); + } + else if (compactExponentIdx >= 0) { + cs.appendInvariantChars(num.tempSubString(0, compactExponentIdx), status); + int32_t expSubstrStart = compactExponentIdx + 1; + parsedCompactExponent = ICU_Utility::parseAsciiInteger(num, expSubstrStart); + + parsedExponent = parsedCompactExponent; + exponentIdx = compactExponentIdx; + } + else { + cs.appendInvariantChars(num, status); + } + DecimalQuantity dl; dl.setToDecNumber(cs.toStringPiece(), status); if (U_FAILURE(status)) { init(0, 0, 0); return; } + int32_t decimalPoint = num.indexOf(DOT); double n = dl.toDouble(); if (decimalPoint == -1) { - init(n, 0, 0); + init(n, 0, 0, parsedExponent); } else { - int32_t v = num.length() - decimalPoint - 1; - init(n, v, getFractionalDigits(n, v)); + int32_t fractionNumLength = exponentIdx < 0 ? num.length() : cs.length(); + int32_t v = fractionNumLength - decimalPoint - 1; + init(n, v, getFractionalDigits(n, v), parsedExponent); } } @@ -1546,6 +1710,7 @@ FixedDecimal::FixedDecimal(const FixedDecimal &other) { decimalDigits = other.decimalDigits; decimalDigitsWithoutTrailingZeros = other.decimalDigitsWithoutTrailingZeros; intValue = other.intValue; + exponent = other.exponent; _hasIntegerValue = other._hasIntegerValue; isNegative = other.isNegative; _isNaN = other._isNaN; @@ -1554,6 +1719,10 @@ FixedDecimal::FixedDecimal(const FixedDecimal &other) { FixedDecimal::~FixedDecimal() = default; +FixedDecimal FixedDecimal::createWithExponent(double n, int32_t v, int32_t e) { + return FixedDecimal(n, v, getFractionalDigits(n, v), e); +} + void FixedDecimal::init(double n) { int32_t numFractionDigits = decimals(n); @@ -1562,10 +1731,24 @@ void FixedDecimal::init(double n) { void FixedDecimal::init(double n, int32_t v, int64_t f) { + int32_t exponent = 0; + init(n, v, f, exponent); +} + +void FixedDecimal::init(double n, int32_t v, int64_t f, int32_t e) { + // Currently, `c` is an alias for `e` + init(n, v, f, e, e); +} + +void FixedDecimal::init(double n, int32_t v, int64_t f, int32_t e, int32_t c) { isNegative = n < 0.0; source = fabs(n); _isNaN = uprv_isNaN(source); _isInfinite = uprv_isInfinite(source); + exponent = e; + if (exponent == 0) { + exponent = c; + } if (_isNaN || _isInfinite) { v = 0; f = 0; @@ -1661,7 +1844,9 @@ int64_t FixedDecimal::getFractionalDigits(double n, int32_t v) { case 3: return (int64_t)(fract*1000.0 + 0.5); default: double scaled = floor(fract * pow(10.0, (double)v) + 0.5); - if (scaled > U_INT64_MAX) { + if (scaled >= static_cast(U_INT64_MAX)) { + // Note: a double cannot accurately represent U_INT64_MAX. Casting it to double + // will round up to the next representable value, which is U_INT64_MAX + 1. return U_INT64_MAX; } else { return (int64_t)scaled; @@ -1693,7 +1878,8 @@ double FixedDecimal::getPluralOperand(PluralOperand operand) const { case PLURAL_OPERAND_F: return static_cast(decimalDigits); case PLURAL_OPERAND_T: return static_cast(decimalDigitsWithoutTrailingZeros); case PLURAL_OPERAND_V: return visibleDecimalDigitCount; - case PLURAL_OPERAND_E: return 0; + case PLURAL_OPERAND_E: return exponent; + case PLURAL_OPERAND_C: return exponent; default: UPRV_UNREACHABLE; // unexpected. } @@ -1719,6 +1905,23 @@ int32_t FixedDecimal::getVisibleFractionDigitCount() const { return visibleDecimalDigitCount; } +bool FixedDecimal::operator==(const FixedDecimal &other) const { + return source == other.source && visibleDecimalDigitCount == other.visibleDecimalDigitCount + && decimalDigits == other.decimalDigits && exponent == other.exponent; +} + +UnicodeString FixedDecimal::toString() const { + char pattern[15]; + char buffer[20]; + if (exponent != 0) { + snprintf(pattern, sizeof(pattern), "%%.%dfe%%d", visibleDecimalDigitCount); + snprintf(buffer, sizeof(buffer), pattern, source, exponent); + } else { + snprintf(pattern, sizeof(pattern), "%%.%df", visibleDecimalDigitCount); + snprintf(buffer, sizeof(buffer), pattern, source); + } + return UnicodeString(buffer, -1, US_INV); +} PluralAvailableLocalesEnumeration::PluralAvailableLocalesEnumeration(UErrorCode &status) { diff --git a/deps/icu-small/source/i18n/plurrule_impl.h b/deps/icu-small/source/i18n/plurrule_impl.h index a18cb0847a840e46b4f81cf491f98b1faa64ad1d..69d44f83d4a0fadb4d87a9b085391db96d58c5b8 100644 --- a/deps/icu-small/source/i18n/plurrule_impl.h +++ b/deps/icu-small/source/i18n/plurrule_impl.h @@ -30,6 +30,12 @@ #include "hash.h" #include "uassert.h" +/** + * A FixedDecimal version of UPLRULES_NO_UNIQUE_VALUE used in PluralRulesTest + * for parsing of samples. + */ +#define UPLRULES_NO_UNIQUE_VALUE_DECIMAL (FixedDecimal((double)-0.00123456777)) + class PluralRulesTest; U_NAMESPACE_BEGIN @@ -138,6 +144,8 @@ enum tokenType { tVariableF, tVariableV, tVariableT, + tVariableE, + tVariableC, tDecimal, tInteger, tEOF @@ -215,11 +223,20 @@ enum PluralOperand { PLURAL_OPERAND_W, /** - * Suppressed exponent for compact notation (exponent needed in - * scientific notation with compact notation to approximate i). + * Suppressed exponent for scientific notation (exponent needed in + * scientific notation to approximate i). */ PLURAL_OPERAND_E, + /** + * This operand is currently treated as an alias for `PLURAL_OPERAND_E`. + * In the future, it will represent: + * + * Suppressed exponent for compact notation (exponent needed in + * compact notation to approximate i). + */ + PLURAL_OPERAND_C, + /** * THIS OPERAND IS DEPRECATED AND HAS BEEN REMOVED FROM THE SPEC. * @@ -273,7 +290,11 @@ class U_I18N_API FixedDecimal: public IFixedDecimal, public UObject { * @param n the number, e.g. 12.345 * @param v The number of visible fraction digits, e.g. 3 * @param f The fraction digits, e.g. 345 + * @param e The exponent, e.g. 7 in 1.2e7, for scientific notation + * @param c Currently: an alias for param `e`. */ + FixedDecimal(double n, int32_t v, int64_t f, int32_t e, int32_t c); + FixedDecimal(double n, int32_t v, int64_t f, int32_t e); FixedDecimal(double n, int32_t v, int64_t f); FixedDecimal(double n, int32_t); explicit FixedDecimal(double n); @@ -282,6 +303,8 @@ class U_I18N_API FixedDecimal: public IFixedDecimal, public UObject { FixedDecimal(const UnicodeString &s, UErrorCode &ec); FixedDecimal(const FixedDecimal &other); + static FixedDecimal createWithExponent(double n, int32_t v, int32_t e); + double getPluralOperand(PluralOperand operand) const U_OVERRIDE; bool isNaN() const U_OVERRIDE; bool isInfinite() const U_OVERRIDE; @@ -291,19 +314,26 @@ class U_I18N_API FixedDecimal: public IFixedDecimal, public UObject { int32_t getVisibleFractionDigitCount() const; + void init(double n, int32_t v, int64_t f, int32_t e, int32_t c); + void init(double n, int32_t v, int64_t f, int32_t e); void init(double n, int32_t v, int64_t f); void init(double n); UBool quickInit(double n); // Try a fast-path only initialization, - // return TRUE if successful. + // return true if successful. void adjustForMinFractionDigits(int32_t min); static int64_t getFractionalDigits(double n, int32_t v); static int32_t decimals(double n); + bool operator==(const FixedDecimal &other) const; + + UnicodeString toString() const; + double source; int32_t visibleDecimalDigitCount; int64_t decimalDigits; int64_t decimalDigitsWithoutTrailingZeros; int64_t intValue; + int32_t exponent; UBool _hasIntegerValue; UBool isNegative; UBool _isNaN; @@ -320,8 +350,8 @@ public: int32_t opNum = -1; // for mod expressions, the right operand of the mod. int32_t value = -1; // valid for 'is' rules only. UVector32 *rangeList = nullptr; // for 'in', 'within' rules. Null otherwise. - UBool negated = FALSE; // TRUE for negated rules. - UBool integerOnly = FALSE; // TRUE for 'within' rules. + UBool negated = false; // true for negated rules. + UBool integerOnly = false; // true for 'within' rules. tokenType digitsType = none; // n | i | v | f constraint. AndConstraint *next = nullptr; // Internal error status, used for errors that occur during the copy constructor. @@ -357,8 +387,8 @@ public: OrConstraint *ruleHeader = nullptr; UnicodeString fDecimalSamples; // Samples strings from rule source UnicodeString fIntegerSamples; // without @decimal or @integer, otherwise unprocessed. - UBool fDecimalSamplesUnbounded = FALSE; - UBool fIntegerSamplesUnbounded = FALSE; + UBool fDecimalSamplesUnbounded = false; + UBool fIntegerSamplesUnbounded = false; // Internal error status, used for errors that occur during the copy constructor. UErrorCode fInternalStatus = U_ZERO_ERROR; diff --git a/deps/icu-small/source/i18n/quant.h b/deps/icu-small/source/i18n/quant.h index d5aa8e5eeeedee388a34035ed708ccae8b168590..df6924cc127ba62023b2e1b38fdab6f0225c641d 100644 --- a/deps/icu-small/source/i18n/quant.h +++ b/deps/icu-small/source/i18n/quant.h @@ -62,11 +62,11 @@ class Quantifier : public UnicodeFunctor, public UnicodeMatcher { * considered for matching will be text.charAt(limit-1) in the * forward direction or text.charAt(limit+1) in the backward * direction. - * @param incremental if TRUE, then assume further characters may + * @param incremental if true, then assume further characters may * be inserted at limit and check for partial matching. Otherwise * assume the text as given is complete. * @return a match degree value indicating a full match, a partial - * match, or a mismatch. If incremental is FALSE then + * match, or a mismatch. If incremental is false then * U_PARTIAL_MATCH should never be returned. */ virtual UMatchDegree matches(const Replaceable& text, @@ -81,7 +81,7 @@ class Quantifier : public UnicodeFunctor, public UnicodeMatcher { * @return A reference to 'result'. */ virtual UnicodeString& toPattern(UnicodeString& result, - UBool escapeUnprintable = FALSE) const; + UBool escapeUnprintable = false) const; /** * Implement UnicodeMatcher diff --git a/deps/icu-small/source/i18n/quantityformatter.h b/deps/icu-small/source/i18n/quantityformatter.h index 88c3f3844e924db064e343c0663a55333b66e754..30bef08634a3f4d0a11bb0257d2aab44ae4ca71c 100644 --- a/deps/icu-small/source/i18n/quantityformatter.h +++ b/deps/icu-small/source/i18n/quantityformatter.h @@ -74,18 +74,18 @@ public: * @param variant "zero", "one", "two", "few", "many", "other" * @param rawPattern the pattern for the variant e.g "{0} meters" * @param status any error returned here. - * @return TRUE on success; FALSE if status was set to a non zero error. + * @return true on success; false if status was set to a non zero error. */ UBool addIfAbsent(const char *variant, const UnicodeString &rawPattern, UErrorCode &status); /** - * returns TRUE if this object has at least the "other" variant. + * returns true if this object has at least the "other" variant. */ UBool isValid() const; /** * Gets the pattern formatter that would be used for a particular variant. - * If isValid() returns TRUE, this method is guaranteed to return a + * If isValid() returns true, this method is guaranteed to return a * non-NULL value. */ const SimpleFormatter *getByVariant(const char *variant) const; @@ -112,7 +112,7 @@ public: /** * Selects the standard plural form for the number/formatter/rules. - * TODO(13591): Remove this method. + * Used in MeasureFormat for backwards compatibility with NumberFormat. */ static StandardPlural::Form selectPlural( const Formattable &number, diff --git a/deps/icu-small/source/i18n/rbt.cpp b/deps/icu-small/source/i18n/rbt.cpp index 02d0ce6ceb20f843aaca607dba7584286f0e6b3a..651994784490148cbc8576416281ec74abcf4c1a 100644 --- a/deps/icu-small/source/i18n/rbt.cpp +++ b/deps/icu-small/source/i18n/rbt.cpp @@ -101,7 +101,7 @@ RuleBasedTransliterator::RuleBasedTransliterator( }*/ /** - * Covenience constructor with no filter. + * Convenience constructor with no filter. */ /*RuleBasedTransliterator::RuleBasedTransliterator( const UnicodeString& id, @@ -114,7 +114,7 @@ RuleBasedTransliterator::RuleBasedTransliterator( }*/ /** - * Covenience constructor with no filter and FORWARD direction. + * Convenience constructor with no filter and FORWARD direction. */ /*RuleBasedTransliterator::RuleBasedTransliterator( const UnicodeString& id, @@ -126,7 +126,7 @@ RuleBasedTransliterator::RuleBasedTransliterator( }*/ /** - * Covenience constructor with FORWARD direction. + * Convenience constructor with FORWARD direction. */ /*RuleBasedTransliterator::RuleBasedTransliterator( const UnicodeString& id, diff --git a/deps/icu-small/source/i18n/rbt.h b/deps/icu-small/source/i18n/rbt.h index b450dc23f4975c86b402372eb5c9fd009d270825..4d9991c48f8b72842ee04b00de788d04b5b875dd 100644 --- a/deps/icu-small/source/i18n/rbt.h +++ b/deps/icu-small/source/i18n/rbt.h @@ -80,7 +80,7 @@ public: UErrorCode& status);*/ /** - * Covenience constructor with no filter. + * Convenience constructor with no filter. * @internal Use transliterator factory methods instead since this class will be removed in that release. */ /*RuleBasedTransliterator(const UnicodeString& id, @@ -89,7 +89,7 @@ public: UErrorCode& status);*/ /** - * Covenience constructor with no filter and FORWARD direction. + * Convenience constructor with no filter and FORWARD direction. * @internal Use transliterator factory methods instead since this class will be removed in that release. */ /*RuleBasedTransliterator(const UnicodeString& id, @@ -97,7 +97,7 @@ public: UErrorCode& status);*/ /** - * Covenience constructor with FORWARD direction. + * Convenience constructor with FORWARD direction. * @internal Use transliterator factory methods instead since this class will be removed in that release. */ /*RuleBasedTransliterator(const UnicodeString& id, @@ -108,7 +108,7 @@ private: friend class TransliteratorRegistry; // to access TransliterationRuleData convenience ctor /** - * Covenience constructor. + * Convenience constructor. * @param id the id for the transliterator. * @param theData the rule data for the transliterator. * @param adoptedFilter the filter for the transliterator @@ -161,7 +161,7 @@ public: * to construct a new transliterator. * @param result the string to receive the rules. Previous * contents will be deleted. - * @param escapeUnprintable if TRUE then convert unprintable + * @param escapeUnprintable if true then convert unprintable * character to their hex escape representations, \uxxxx or * \Uxxxxxxxx. Unprintable characters are those other than * U+000A, U+0020..U+007E. diff --git a/deps/icu-small/source/i18n/rbt_pars.cpp b/deps/icu-small/source/i18n/rbt_pars.cpp index 3eb58a2a904a469bc932bded6a6d157bf811f3f1..69465aecb9b1423e40fec13ff7bb4e6d516d9283 100644 --- a/deps/icu-small/source/i18n/rbt_pars.cpp +++ b/deps/icu-small/source/i18n/rbt_pars.cpp @@ -945,7 +945,7 @@ void TransliteratorParser::parseRules(const UnicodeString& rule, if (c == RULE_COMMENT_CHAR) { pos = rule.indexOf((UChar)0x000A /*\n*/, pos) + 1; if (pos == 0) { - break; // No "\n" found; rest of rule is a commnet + break; // No "\n" found; rest of rule is a comment } continue; // Either fall out or restart with next line } @@ -1159,7 +1159,7 @@ void TransliteratorParser::setVariableRange(int32_t start, int32_t end, UErrorCo /** * Assert that the given character is NOT within the variable range. - * If it is, return FALSE. This is neccesary to ensure that the + * If it is, return FALSE. This is necessary to ensure that the * variable range does not overlap characters used in a rule. */ UBool TransliteratorParser::checkVariableRange(UChar32 ch) const { @@ -1557,7 +1557,7 @@ UChar TransliteratorParser::getSegmentStandin(int32_t seg, UErrorCode& status) { return 0; } c = variableNext++; - // Set a placeholder in the master variables vector that will be + // Set a placeholder in the primary variables vector that will be // filled in later by setSegmentObject(). We know that we will get // called first because setSegmentObject() will call us. variablesVector.addElement((void*) NULL, status); diff --git a/deps/icu-small/source/i18n/rbt_pars.h b/deps/icu-small/source/i18n/rbt_pars.h index d51f2e852bb5b44cfa3fd8e629ab9acca01b4935..9336d410d351e582bdbe92ac7bd423fd68cb0fa1 100644 --- a/deps/icu-small/source/i18n/rbt_pars.h +++ b/deps/icu-small/source/i18n/rbt_pars.h @@ -210,7 +210,7 @@ private: /** * Assert that the given character is NOT within the variable range. - * If it is, return FALSE. This is neccesary to ensure that the + * If it is, return false. This is necessary to ensure that the * variable range does not overlap characters used in a rule. * @param ch the given character. * @return True, if the given character is NOT within the variable range. diff --git a/deps/icu-small/source/i18n/rbt_rule.h b/deps/icu-small/source/i18n/rbt_rule.h index eb8556df0cda5dbcfb7be488b4e13853fe3699fd..76feeee3913e6ac327e8470bf2fa696b24a429cf 100644 --- a/deps/icu-small/source/i18n/rbt_rule.h +++ b/deps/icu-small/source/i18n/rbt_rule.h @@ -172,9 +172,9 @@ public: * segments, or null if there are none. The array itself is adopted, * but the pointers within it are not. * @param segsCount number of elements in segs[]. - * @param anchorStart TRUE if the the rule is anchored on the left to + * @param anchorStart true if the the rule is anchored on the left to * the context start. - * @param anchorEnd TRUE if the rule is anchored on the right to the + * @param anchorEnd true if the rule is anchored on the right to the * context limit. * @param data the rule data. * @param status Output parameter filled in with success or failure status. @@ -267,11 +267,11 @@ public: * * @param text the text * @param pos the position indices - * @param incremental if TRUE, test for partial matches that may + * @param incremental if true, test for partial matches that may * be completed by additional text inserted at pos.limit. * @return one of U_MISMATCH, * U_PARTIAL_MATCH, or U_MATCH. If - * incremental is FALSE then U_PARTIAL_MATCH will not be returned. + * incremental is false then U_PARTIAL_MATCH will not be returned. */ UMatchDegree matchAndReplace(Replaceable& text, UTransPosition& pos, diff --git a/deps/icu-small/source/i18n/rbt_set.h b/deps/icu-small/source/i18n/rbt_set.h index 9b2b8b38dba5cab97a52f29182df724504956c26..b1163a0193f862f53ba4e24d2c6fbc1cd4a6378c 100644 --- a/deps/icu-small/source/i18n/rbt_set.h +++ b/deps/icu-small/source/i18n/rbt_set.h @@ -123,14 +123,14 @@ public: /** * Transliterate the given text with the given UTransPosition - * indices. Return TRUE if the transliteration should continue - * or FALSE if it should halt (because of a U_PARTIAL_MATCH match). - * Note that FALSE is only ever returned if isIncremental is TRUE. + * indices. Return true if the transliteration should continue + * or false if it should halt (because of a U_PARTIAL_MATCH match). + * Note that false is only ever returned if isIncremental is true. * @param text the text to be transliterated * @param index the position indices, which will be updated - * @param isIncremental if TRUE, assume new text may be inserted - * at index.limit, and return FALSE if thre is a partial match. - * @return TRUE unless a U_PARTIAL_MATCH has been obtained, + * @param isIncremental if true, assume new text may be inserted + * at index.limit, and return false if thre is a partial match. + * @return true unless a U_PARTIAL_MATCH has been obtained, * indicating that transliteration should stop until more text * arrives. */ diff --git a/deps/icu-small/source/i18n/rbtz.cpp b/deps/icu-small/source/i18n/rbtz.cpp index 2c3747abdafeaf07e0a4ce9f36de9b65334e9d86..9d8eea9263a280b81a008bfcf12cf43969d67f99 100644 --- a/deps/icu-small/source/i18n/rbtz.cpp +++ b/deps/icu-small/source/i18n/rbtz.cpp @@ -403,9 +403,9 @@ RuleBasedTimeZone::getOffset(UDate date, UBool local, int32_t& rawOffset, getOffsetInternal(date, local, kFormer, kLatter, rawOffset, dstOffset, status); } -void -RuleBasedTimeZone::getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt, - int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const { +void RuleBasedTimeZone::getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt, + UTimeZoneLocalOption duplicatedTimeOpt, + int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const { getOffsetInternal(date, TRUE, nonExistingTimeOpt, duplicatedTimeOpt, rawOffset, dstOffset, status); } diff --git a/deps/icu-small/source/i18n/regexcmp.cpp b/deps/icu-small/source/i18n/regexcmp.cpp index 7b67ce82b5db1223da9bab2ecd65e0a2ba1f4281..6c3a9e10ba12f264a0c8f68c5141de0ece400ed8 100644 --- a/deps/icu-small/source/i18n/regexcmp.cpp +++ b/deps/icu-small/source/i18n/regexcmp.cpp @@ -557,7 +557,7 @@ UBool RegexCompile::doParseActions(int32_t action) // // Note: Addition of transparent input regions, with the need to // restore the original regions when failing out of a lookahead - // block, complicated this sequence. Some conbined opcodes + // block, complicated this sequence. Some combined opcodes // might make sense - or might not, lookahead aren't that common. // // Caution: min match length optimization knows about this @@ -2397,7 +2397,7 @@ void RegexCompile::compileSet(UnicodeSet *theSet) } // Remove any strings from the set. // There shoudn't be any, but just in case. - // (Case Closure can add them; if we had a simple case closure avaialble that + // (Case Closure can add them; if we had a simple case closure available that // ignored strings, that would be better.) theSet->removeAllStrings(); int32_t setSize = theSet->size(); @@ -2485,7 +2485,7 @@ void RegexCompile::compileInterval(int32_t InitOp, int32_t LoopOp) fRXPat->fCompiledPat->setElementAt(fIntervalLow, topOfBlock+2); fRXPat->fCompiledPat->setElementAt(fIntervalUpper, topOfBlock+3); - // Apend the CTR_LOOP op. The operand is the location of the CTR_INIT op. + // Append the CTR_LOOP op. The operand is the location of the CTR_INIT op. // Goes at end of the block being looped over, so just append to the code so far. appendOp(LoopOp, topOfBlock); @@ -3475,6 +3475,9 @@ int32_t RegexCompile::minMatchLength(int32_t start, int32_t end) { // value may be longer than the actual maximum; it must // never be shorter. // +// start, end: the range of the pattern to check. +// end is inclusive. +// //------------------------------------------------------------------------------ int32_t RegexCompile::maxMatchLength(int32_t start, int32_t end) { if (U_FAILURE(*fStatus)) { @@ -3720,14 +3723,14 @@ int32_t RegexCompile::maxMatchLength(int32_t start, int32_t end) { // Look-behind. Scan forward until the matching look-around end, // without processing the look-behind block. int32_t dataLoc = URX_VAL(op); - for (loc = loc + 1; loc < end; ++loc) { + for (loc = loc + 1; loc <= end; ++loc) { op = (int32_t)fRXPat->fCompiledPat->elementAti(loc); int32_t opType = URX_TYPE(op); if ((opType == URX_LA_END || opType == URX_LBN_END) && (URX_VAL(op) == dataLoc)) { break; } } - U_ASSERT(loc < end); + U_ASSERT(loc <= end); } break; diff --git a/deps/icu-small/source/i18n/regexcmp.h b/deps/icu-small/source/i18n/regexcmp.h index 85b7586793b9ff2404c3da8cffb72583ace1370e..5804ff302674a1804a1667f1b9563ef4cc9169a6 100644 --- a/deps/icu-small/source/i18n/regexcmp.h +++ b/deps/icu-small/source/i18n/regexcmp.h @@ -104,7 +104,7 @@ private: int32_t LoopOp); UBool compileInlineInterval(); // Generate inline code for a {min,max} quantifier void literalChar(UChar32 c); // Compile a literal char - void fixLiterals(UBool split=FALSE); // Generate code for pending literal characters. + void fixLiterals(UBool split=false); // Generate code for pending literal characters. void insertOp(int32_t where); // Open up a slot for a new op in the // generated code at the specified location. void appendOp(int32_t op); // Append a new op to the compiled pattern. diff --git a/deps/icu-small/source/i18n/regextxt.h b/deps/icu-small/source/i18n/regextxt.h index 9cfabbe4153416d0e14cdd6ed6d27d60b86abfff..0f64b8437e7c3291aff198c8d5ed6c1d5ba65577 100644 --- a/deps/icu-small/source/i18n/regextxt.h +++ b/deps/icu-small/source/i18n/regextxt.h @@ -29,7 +29,7 @@ U_NAMESPACE_BEGIN #endif #ifdef REGEX_DISABLE_CHUNK_MODE -# define UTEXT_FULL_TEXT_IN_CHUNK(ut,len) (FALSE) +# define UTEXT_FULL_TEXT_IN_CHUNK(ut,len) (false) #else # define UTEXT_FULL_TEXT_IN_CHUNK(ut,len) ((0==((ut)->chunkNativeStart))&&((len)==((ut)->chunkNativeLimit))&&((len)==((ut)->nativeIndexingLimit))) #endif diff --git a/deps/icu-small/source/i18n/region.cpp b/deps/icu-small/source/i18n/region.cpp index 198bea8f643a5bb68a3b8e920fab13e16a22f737..8364bd1c1b2280ce0680f69c7c83adb90d962d44 100644 --- a/deps/icu-small/source/i18n/region.cpp +++ b/deps/icu-small/source/i18n/region.cpp @@ -217,7 +217,7 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) { if ( aliasToRegion != NULL && aliasFromRegion == NULL ) { // This is just an alias from some string to a region uhash_put(newRegionAliases.getAlias(),(void *)aliasFromStr.orphan(), (void *)aliasToRegion,&status); } else { - if ( aliasFromRegion == NULL ) { // Deprecated region code not in the master codes list - so need to create a deprecated region for it. + if ( aliasFromRegion == NULL ) { // Deprecated region code not in the primary codes list - so need to create a deprecated region for it. LocalPointer newRgn(new Region, status); if ( U_SUCCESS(status) ) { aliasFromRegion = newRgn.orphan(); diff --git a/deps/icu-small/source/i18n/reldatefmt.cpp b/deps/icu-small/source/i18n/reldatefmt.cpp index f10c5ba4884b841a874ba01fe63566853c57bef6..d41ff22b9c212a45fad1e15289684672d2fb9af6 100644 --- a/deps/icu-small/source/i18n/reldatefmt.cpp +++ b/deps/icu-small/source/i18n/reldatefmt.cpp @@ -95,7 +95,7 @@ public: const UnicodeString emptyString; - // Mappping from source to target styles for alias fallback. + // Mapping from source to target styles for alias fallback. int32_t fallBackCache[UDAT_STYLE_COUNT]; void adoptCombinedDateAndTime(SimpleFormatter *fmtToAdopt) { @@ -1326,7 +1326,7 @@ ureldatefmt_formatNumeric( const URelativeDateTimeFormatter* reldatefmt, return res.extract(result, resultCapacity, *status); } -U_STABLE void U_EXPORT2 +U_CAPI void U_EXPORT2 ureldatefmt_formatNumericToResult( const URelativeDateTimeFormatter* reldatefmt, double offset, @@ -1369,7 +1369,7 @@ ureldatefmt_format( const URelativeDateTimeFormatter* reldatefmt, return res.extract(result, resultCapacity, *status); } -U_DRAFT void U_EXPORT2 +U_CAPI void U_EXPORT2 ureldatefmt_formatToResult( const URelativeDateTimeFormatter* reldatefmt, double offset, diff --git a/deps/icu-small/source/i18n/reldtfmt.cpp b/deps/icu-small/source/i18n/reldtfmt.cpp index c74c30c20ca38307237d3a03160bbcb1a2494a43..2bc59c5128b43a188234717fe327741e7a8a183a 100644 --- a/deps/icu-small/source/i18n/reldtfmt.cpp +++ b/deps/icu-small/source/i18n/reldtfmt.cpp @@ -334,7 +334,7 @@ UDate RelativeDateFormat::parse( const UnicodeString& text, ParsePosition& pos) const { // redefined here because the other parse() function hides this function's - // cunterpart on DateFormat + // counterpart on DateFormat return DateFormat::parse(text, pos); } diff --git a/deps/icu-small/source/i18n/rematch.cpp b/deps/icu-small/source/i18n/rematch.cpp index 123aa8602ba474581fb6686783703cf4acc688d1..e358dbd1e983f885888fa6caba5d0db3097ddc12 100644 --- a/deps/icu-small/source/i18n/rematch.cpp +++ b/deps/icu-small/source/i18n/rematch.cpp @@ -2072,7 +2072,7 @@ int32_t RegexMatcher::split(UText *input, UErrorCode &status) { // - // Check arguements for validity + // Check arguments for validity // if (U_FAILURE(status)) { return 0; @@ -3913,7 +3913,7 @@ void RegexMatcher::MatchAt(int64_t startIdx, UBool toEnd, UErrorCode &status) { // First time through loop. lbStartIdx = fp->fInputIdx - minML; if (lbStartIdx > 0) { - // move index to a code point boudary, if it's not on one already. + // move index to a code point boundary, if it's not on one already. UTEXT_SETNATIVEINDEX(fInputText, lbStartIdx); lbStartIdx = UTEXT_GETNATIVEINDEX(fInputText); } @@ -3999,7 +3999,7 @@ void RegexMatcher::MatchAt(int64_t startIdx, UBool toEnd, UErrorCode &status) { // First time through loop. lbStartIdx = fp->fInputIdx - minML; if (lbStartIdx > 0) { - // move index to a code point boudary, if it's not on one already. + // move index to a code point boundary, if it's not on one already. UTEXT_SETNATIVEINDEX(fInputText, lbStartIdx); lbStartIdx = UTEXT_GETNATIVEINDEX(fInputText); } diff --git a/deps/icu-small/source/i18n/rulebasedcollator.cpp b/deps/icu-small/source/i18n/rulebasedcollator.cpp index 60acf17815a5ee4ba7214d8d02354472fb8966f7..917482d65bb4d651b0880f7b50f3a3d6d0fda184 100644 --- a/deps/icu-small/source/i18n/rulebasedcollator.cpp +++ b/deps/icu-small/source/i18n/rulebasedcollator.cpp @@ -1600,10 +1600,7 @@ RuleBasedCollator::internalGetShortDefinitionString(const char *locale, appendSubtag(result, 'Z', subtag, length, errorCode); if(U_FAILURE(errorCode)) { return 0; } - if(result.length() <= capacity) { - uprv_memcpy(buffer, result.data(), result.length()); - } - return u_terminateChars(buffer, capacity, result.length(), &errorCode); + return result.extract(buffer, capacity, errorCode); } UBool diff --git a/deps/icu-small/source/i18n/scriptset.h b/deps/icu-small/source/i18n/scriptset.h index a41ab737a6dc3819b18d2ec5971caf0bc4a8541c..b770995832872d64c7d28a984f5cae199252f066 100644 --- a/deps/icu-small/source/i18n/scriptset.h +++ b/deps/icu-small/source/i18n/scriptset.h @@ -51,7 +51,7 @@ class U_I18N_API ScriptSet: public UMemory { ScriptSet &reset(UScriptCode script, UErrorCode &status); ScriptSet &intersect(const ScriptSet &other); ScriptSet &intersect(UScriptCode script, UErrorCode &status); - UBool intersects(const ScriptSet &other) const; // Sets contain at least one script in commmon. + UBool intersects(const ScriptSet &other) const; // Sets contain at least one script in common. UBool contains(const ScriptSet &other) const; // All set bits in other are also set in this. ScriptSet &setAll(); diff --git a/deps/icu-small/source/i18n/simpletz.cpp b/deps/icu-small/source/i18n/simpletz.cpp index 12c220595cd2c1cf42ab934eed19d972191a43a4..0007d4aec8977e7e68bb26eeb80783d16d75f4cd 100644 --- a/deps/icu-small/source/i18n/simpletz.cpp +++ b/deps/icu-small/source/i18n/simpletz.cpp @@ -42,7 +42,7 @@ U_NAMESPACE_BEGIN UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleTimeZone) // Use only for decodeStartRule() and decodeEndRule() where the year is not -// available. Set February to 29 days to accomodate rules with that date +// available. Set February to 29 days to accommodate rules with that date // and day-of-week-on-or-before-that-date mode (DOW_LE_DOM_MODE). // The compareToRule() method adjusts to February 28 in non-leap years. // @@ -509,8 +509,10 @@ SimpleTimeZone::getOffset(uint8_t era, int32_t year, int32_t month, int32_t day, } void -SimpleTimeZone::getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt, - int32_t& rawOffsetGMT, int32_t& savingsDST, UErrorCode& status) const { +SimpleTimeZone::getOffsetFromLocal(UDate date, UTimeZoneLocalOption nonExistingTimeOpt, + UTimeZoneLocalOption duplicatedTimeOpt, int32_t& rawOffsetGMT, + int32_t& savingsDST, UErrorCode& status) const +{ if (U_FAILURE(status)) { return; } diff --git a/deps/icu-small/source/i18n/smpdtfmt.cpp b/deps/icu-small/source/i18n/smpdtfmt.cpp index d704642b0536a4df54080a5a0a624febca459bfd..a3ec7cb026591c72f45a804a975496c4f2f2f046 100644 --- a/deps/icu-small/source/i18n/smpdtfmt.cpp +++ b/deps/icu-small/source/i18n/smpdtfmt.cpp @@ -54,6 +54,7 @@ #include "unicode/udisplaycontext.h" #include "unicode/brkiter.h" #include "unicode/rbnf.h" +#include "unicode/dtptngen.h" #include "uresimp.h" #include "olsontz.h" #include "patternprops.h" @@ -230,6 +231,13 @@ static const int32_t gFieldRangeBias[] = { static const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000; static const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000; +/** + * Maximum range for detecting daylight offset of a time zone when parsed time zone + * string indicates it's daylight saving time, but the detected time zone does not + * observe daylight saving time at the parsed date. + */ +static const double MAX_DAYLIGHT_DETECTION_RANGE = 30*365*24*60*60*1000.0; + static UMutex LOCK; UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat) @@ -650,6 +658,12 @@ SimpleDateFormat::operator==(const Format& other) const } //---------------------------------------------------------------------- +static const UChar* timeSkeletons[4] = { + u"jmmsszzzz", // kFull + u"jmmssz", // kLong + u"jmmss", // kMedium + u"jmm", // kShort +}; void SimpleDateFormat::construct(EStyle timeStyle, EStyle dateStyle, @@ -714,35 +728,75 @@ void SimpleDateFormat::construct(EStyle timeStyle, fDateOverride.setToBogus(); fTimeOverride.setToBogus(); + UnicodeString timePattern; + if (timeStyle >= kFull && timeStyle <= kShort) { + const char* baseLocID = locale.getBaseName(); + if (baseLocID[0]!=0 && uprv_strcmp(baseLocID,"und")!=0) { + UErrorCode useStatus = U_ZERO_ERROR; + Locale baseLoc(baseLocID); + Locale validLoc(getLocale(ULOC_VALID_LOCALE, useStatus)); + if (U_SUCCESS(useStatus) && validLoc!=baseLoc) { + bool useDTPG = false; + const char* baseReg = baseLoc.getCountry(); // empty string if no region + if ((baseReg[0]!=0 && uprv_strncmp(baseReg,validLoc.getCountry(),ULOC_COUNTRY_CAPACITY)!=0) + || uprv_strncmp(baseLoc.getLanguage(),validLoc.getLanguage(),ULOC_LANG_CAPACITY)!=0) { + // use DTPG if + // * baseLoc has a region and validLoc does not have the same one (or has none), OR + // * validLoc has a different language code than baseLoc + useDTPG = true; + } + if (useDTPG) { + // The standard time formats may have the wrong time cycle, because: + // the valid locale differs in important ways (region, language) from + // the base locale. + // We could *also* check whether they do actually have a mismatch with + // the time cycle preferences for the region, but that is a lot more + // work for little or no additional benefit, since just going ahead + // and always synthesizing the time format as per the following should + // create a locale-appropriate pattern with cycle that matches the + // region preferences anyway. + LocalPointer dtpg(DateTimePatternGenerator::createInstanceNoStdPat(locale, useStatus)); + if (U_SUCCESS(useStatus)) { + UnicodeString timeSkeleton(TRUE, timeSkeletons[timeStyle], -1); + timePattern = dtpg->getBestPattern(timeSkeleton, useStatus); + } + } + } + } + } + // if the pattern should include both date and time information, use the date/time // pattern string as a guide to tell use how to glue together the appropriate date // and time pattern strings. if ((timeStyle != kNone) && (dateStyle != kNone)) { - currentBundle.adoptInstead( - ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)timeStyle, NULL, &status)); - if (U_FAILURE(status)) { - status = U_INVALID_FORMAT_ERROR; - return; - } - switch (ures_getType(currentBundle.getAlias())) { - case URES_STRING: { - resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status); - break; - } - case URES_ARRAY: { - resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status); - ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status); - fTimeOverride.setTo(TRUE, ovrStr, ovrStrLen); - break; - } - default: { + UnicodeString tempus1(timePattern); + if (tempus1.length() == 0) { + currentBundle.adoptInstead( + ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)timeStyle, NULL, &status)); + if (U_FAILURE(status)) { status = U_INVALID_FORMAT_ERROR; return; } - } + switch (ures_getType(currentBundle.getAlias())) { + case URES_STRING: { + resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status); + break; + } + case URES_ARRAY: { + resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status); + ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status); + fTimeOverride.setTo(TRUE, ovrStr, ovrStrLen); + break; + } + default: { + status = U_INVALID_FORMAT_ERROR; + return; + } + } - UnicodeString tempus1(TRUE, resStr, resStrLen); + tempus1.setTo(TRUE, resStr, resStrLen); + } currentBundle.adoptInstead( ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)dateStyle, NULL, &status)); @@ -784,29 +838,32 @@ void SimpleDateFormat::construct(EStyle timeStyle, // pattern string from the resources // setTo() - see DateFormatSymbols::assignArray comments else if (timeStyle != kNone) { - currentBundle.adoptInstead( - ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)timeStyle, NULL, &status)); - if (U_FAILURE(status)) { - status = U_INVALID_FORMAT_ERROR; - return; - } - switch (ures_getType(currentBundle.getAlias())) { - case URES_STRING: { - resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status); - break; - } - case URES_ARRAY: { - resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status); - ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status); - fDateOverride.setTo(TRUE, ovrStr, ovrStrLen); - break; - } - default: { + fPattern.setTo(timePattern); + if (fPattern.length() == 0) { + currentBundle.adoptInstead( + ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)timeStyle, NULL, &status)); + if (U_FAILURE(status)) { status = U_INVALID_FORMAT_ERROR; return; } + switch (ures_getType(currentBundle.getAlias())) { + case URES_STRING: { + resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status); + break; + } + case URES_ARRAY: { + resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status); + ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status); + fDateOverride.setTo(TRUE, ovrStr, ovrStrLen); + break; + } + default: { + status = U_INVALID_FORMAT_ERROR; + return; + } + } + fPattern.setTo(TRUE, resStr, resStrLen); } - fPattern.setTo(TRUE, resStr, resStrLen); } else if (dateStyle != kNone) { currentBundle.adoptInstead( @@ -848,7 +905,8 @@ Calendar* SimpleDateFormat::initializeCalendar(TimeZone* adoptZone, const Locale& locale, UErrorCode& status) { if(!U_FAILURE(status)) { - fCalendar = Calendar::createInstance(adoptZone?adoptZone:TimeZone::createDefault(), locale, status); + fCalendar = Calendar::createInstance( + adoptZone ? adoptZone : TimeZone::forLocaleOrDefault(locale), locale, status); } return fCalendar; } @@ -2524,51 +2582,47 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition& } else { // tztype == TZTYPE_DST if (dst == 0) { if (btz != NULL) { - UDate time = localMillis + raw; - // We use the nearest daylight saving time rule. - TimeZoneTransition beforeTrs, afterTrs; - UDate beforeT = time, afterT = time; - int32_t beforeSav = 0, afterSav = 0; - UBool beforeTrsAvail, afterTrsAvail; - - // Search for DST rule before or on the time - while (TRUE) { - beforeTrsAvail = btz->getPreviousTransition(beforeT, TRUE, beforeTrs); - if (!beforeTrsAvail) { + // This implementation resolves daylight saving time offset + // closest rule after the given time. + UDate baseTime = localMillis + raw; + UDate time = baseTime; + UDate limit = baseTime + MAX_DAYLIGHT_DETECTION_RANGE; + TimeZoneTransition trs; + UBool trsAvail; + + // Search for DST rule after the given time + while (time < limit) { + trsAvail = btz->getNextTransition(time, FALSE, trs); + if (!trsAvail) { break; } - beforeT = beforeTrs.getTime() - 1; - beforeSav = beforeTrs.getFrom()->getDSTSavings(); - if (beforeSav != 0) { + resolvedSavings = trs.getTo()->getDSTSavings(); + if (resolvedSavings != 0) { break; } + time = trs.getTime(); } - // Search for DST rule after the time - while (TRUE) { - afterTrsAvail = btz->getNextTransition(afterT, FALSE, afterTrs); - if (!afterTrsAvail) { - break; + if (resolvedSavings == 0) { + // If no DST rule after the given time was found, search for + // DST rule before. + time = baseTime; + limit = baseTime - MAX_DAYLIGHT_DETECTION_RANGE; + while (time > limit) { + trsAvail = btz->getPreviousTransition(time, TRUE, trs); + if (!trsAvail) { + break; + } + resolvedSavings = trs.getFrom()->getDSTSavings(); + if (resolvedSavings != 0) { + break; + } + time = trs.getTime() - 1; } - afterT = afterTrs.getTime(); - afterSav = afterTrs.getTo()->getDSTSavings(); - if (afterSav != 0) { - break; - } - } - if (beforeTrsAvail && afterTrsAvail) { - if (time - beforeT > afterT - time) { - resolvedSavings = afterSav; - } else { - resolvedSavings = beforeSav; + if (resolvedSavings == 0) { + resolvedSavings = btz->getDSTSavings(); } - } else if (beforeTrsAvail && beforeSav != 0) { - resolvedSavings = beforeSav; - } else if (afterTrsAvail && afterSav != 0) { - resolvedSavings = afterSav; - } else { - resolvedSavings = btz->getDSTSavings(); } } else { resolvedSavings = tz.getDSTSavings(); diff --git a/deps/icu-small/source/i18n/sortkey.cpp b/deps/icu-small/source/i18n/sortkey.cpp index fb030c499083e6f1259a9e0412b8c091a9901dc9..430fd5d3500948e088c9b7d15c9bd6e7a5ec8672 100644 --- a/deps/icu-small/source/i18n/sortkey.cpp +++ b/deps/icu-small/source/i18n/sortkey.cpp @@ -20,7 +20,7 @@ // // 6/20/97 helena Java class name change. // 6/23/97 helena Added comments to make code more readable. -// 6/26/98 erm Canged to use byte arrays instead of UnicodeString +// 6/26/98 erm Changed to use byte arrays instead of UnicodeString // 7/31/98 erm hashCode: minimum inc should be 2 not 1, // Cleaned up operator= // 07/12/99 helena HPUX 11 CC port. diff --git a/deps/icu-small/source/i18n/standardplural.cpp b/deps/icu-small/source/i18n/standardplural.cpp index 0391034b3e4a8dcec42c5c0a1db06c01e4c44646..5a6069bf7ddc47a5484433c1c8eedbe48b2c7c0d 100644 --- a/deps/icu-small/source/i18n/standardplural.cpp +++ b/deps/icu-small/source/i18n/standardplural.cpp @@ -23,7 +23,7 @@ U_NAMESPACE_BEGIN static const char *gKeywords[StandardPlural::COUNT] = { - "zero", "one", "two", "few", "many", "other" + "zero", "one", "two", "few", "many", "other", "=0", "=1" }; const char *StandardPlural::getKeyword(Form p) { @@ -60,21 +60,55 @@ int32_t StandardPlural::indexOrNegativeFromString(const char *keyword) { return ZERO; } break; + case '=': + if (uprv_strcmp(keyword, "0") == 0) { + return EQ_0; + } else if (uprv_strcmp(keyword, "1") == 0) { + return EQ_1; + } + break; + // Also allow "0" and "1" + case '0': + if (*keyword == 0) { + return EQ_0; + } + break; + case '1': + if (*keyword == 0) { + return EQ_1; + } + break; default: break; } return -1; } -static const UChar gZero[] = { 0x7A, 0x65, 0x72, 0x6F }; -static const UChar gOne[] = { 0x6F, 0x6E, 0x65 }; -static const UChar gTwo[] = { 0x74, 0x77, 0x6F }; -static const UChar gFew[] = { 0x66, 0x65, 0x77 }; -static const UChar gMany[] = { 0x6D, 0x61, 0x6E, 0x79 }; -static const UChar gOther[] = { 0x6F, 0x74, 0x68, 0x65, 0x72 }; +static const UChar gZero[] = u"zero"; +static const UChar gOne[] = u"one"; +static const UChar gTwo[] = u"two"; +static const UChar gFew[] = u"few"; +static const UChar gMany[] = u"many"; +static const UChar gOther[] = u"other"; +static const UChar gEq0[] = u"=0"; +static const UChar gEq1[] = u"=1"; int32_t StandardPlural::indexOrNegativeFromString(const UnicodeString &keyword) { switch (keyword.length()) { + case 1: + if (keyword.charAt(0) == '0') { + return EQ_0; + } else if (keyword.charAt(0) == '1') { + return EQ_1; + } + break; + case 2: + if (keyword.compare(gEq0, 2) == 0) { + return EQ_0; + } else if (keyword.compare(gEq1, 2) == 0) { + return EQ_1; + } + break; case 3: if (keyword.compare(gOne, 3) == 0) { return ONE; diff --git a/deps/icu-small/source/i18n/standardplural.h b/deps/icu-small/source/i18n/standardplural.h index 33e1d605f6856bc0a7ff7e674ad38365c50a2efc..16593065c8aa91bda194bafebb917f18346fe166 100644 --- a/deps/icu-small/source/i18n/standardplural.h +++ b/deps/icu-small/source/i18n/standardplural.h @@ -35,6 +35,8 @@ public: FEW, MANY, OTHER, + EQ_0, + EQ_1, COUNT }; diff --git a/deps/icu-small/source/i18n/strmatch.h b/deps/icu-small/source/i18n/strmatch.h index 09d04ede13e61acea9c1353608da11f7789f97c6..84b1d47398fd60d1c81627c91410401071cd798f 100644 --- a/deps/icu-small/source/i18n/strmatch.h +++ b/deps/icu-small/source/i18n/strmatch.h @@ -109,11 +109,11 @@ class StringMatcher : public UnicodeFunctor, public UnicodeMatcher, public Unico * considered for matching will be text.charAt(limit-1) in the * forward direction or text.charAt(limit+1) in the backward * direction. - * @param incremental if TRUE, then assume further characters may + * @param incremental if true, then assume further characters may * be inserted at limit and check for partial matching. Otherwise * assume the text as given is complete. * @return a match degree value indicating a full match, a partial - * match, or a mismatch. If incremental is FALSE then + * match, or a mismatch. If incremental is false then * U_PARTIAL_MATCH should never be returned. */ virtual UMatchDegree matches(const Replaceable& text, @@ -128,16 +128,16 @@ class StringMatcher : public UnicodeFunctor, public UnicodeMatcher, public Unico * @return A reference to 'result'. */ virtual UnicodeString& toPattern(UnicodeString& result, - UBool escapeUnprintable = FALSE) const; + UBool escapeUnprintable = false) const; /** * Implement UnicodeMatcher - * Returns TRUE if this matcher will match a character c, where c + * Returns true if this matcher will match a character c, where c * & 0xFF == v, at offset, in the forward direction (with limit > * offset). This is used by RuleBasedTransliterator for * indexing. * @param v the given value - * @return TRUE if this matcher will match a character c, + * @return true if this matcher will match a character c, * where c & 0xFF == v */ virtual UBool matchesIndexValue(uint8_t v) const; @@ -181,7 +181,7 @@ class StringMatcher : public UnicodeFunctor, public UnicodeMatcher, public Unico * replacer that is equal to this one. * @param result the string to receive the pattern. Previous * contents will be deleted. - * @param escapeUnprintable if TRUE then convert unprintable + * @param escapeUnprintable if true then convert unprintable * character to their hex escape representations, \\uxxxx or * \\Uxxxxxxxx. Unprintable characters are defined by * Utility.isUnprintable(). diff --git a/deps/icu-small/source/i18n/stsearch.cpp b/deps/icu-small/source/i18n/stsearch.cpp index 32481a1400407528b08eb4c1ca98e1a4693ee4c3..003d86b64016f00e4722157446107ca7990039e6 100644 --- a/deps/icu-small/source/i18n/stsearch.cpp +++ b/deps/icu-small/source/i18n/stsearch.cpp @@ -184,7 +184,7 @@ StringSearch::clone() const { // operator overloading --------------------------------------------- StringSearch & StringSearch::operator=(const StringSearch &that) { - if ((*this) != that) { + if (this != &that) { UErrorCode status = U_ZERO_ERROR; m_text_ = that.m_text_; m_breakiterator_ = that.m_breakiterator_; diff --git a/deps/icu-small/source/i18n/taiwncal.h b/deps/icu-small/source/i18n/taiwncal.h index daadc124f40a18cf7867f47b83a6ef0915d92e11..bf384fa714f05b8f05ed5830eaa62b6c93e1aaa7 100644 --- a/deps/icu-small/source/i18n/taiwncal.h +++ b/deps/icu-small/source/i18n/taiwncal.h @@ -156,7 +156,7 @@ private: virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const; /** - * Returns TRUE because the Taiwan Calendar does have a default century + * Returns true because the Taiwan Calendar does have a default century * @internal */ virtual UBool haveDefaultCentury() const; diff --git a/deps/icu-small/source/i18n/timezone.cpp b/deps/icu-small/source/i18n/timezone.cpp index b90b78614aa00f2b157ed405f33422c25c175fae..fe564e6530e7b16b9647e200d1474dba9ad0a8fa 100644 --- a/deps/icu-small/source/i18n/timezone.cpp +++ b/deps/icu-small/source/i18n/timezone.cpp @@ -579,6 +579,24 @@ TimeZone::createDefault() // ------------------------------------- +TimeZone* U_EXPORT2 +TimeZone::forLocaleOrDefault(const Locale& locale) +{ + char buffer[ULOC_KEYWORDS_CAPACITY] = ""; + UErrorCode localStatus = U_ZERO_ERROR; + int32_t count = locale.getKeywordValue("timezone", buffer, sizeof(buffer), localStatus); + if (U_FAILURE(localStatus) || localStatus == U_STRING_NOT_TERMINATED_WARNING) { + // the "timezone" keyword exceeds ULOC_KEYWORDS_CAPACITY; ignore and use default. + count = 0; + } + if (count > 0) { + return TimeZone::createTimeZone(UnicodeString(buffer, count, US_INV)); + } + return TimeZone::createDefault(); +} + +// ------------------------------------- + void U_EXPORT2 TimeZone::adoptDefault(TimeZone* zone) { @@ -1660,7 +1678,7 @@ TimeZone::getIDForWindowsID(const UnicodeString& winid, const char* region, Unic winidKey[winKeyLen] = 0; ures_getByKey(zones, winidKey, zones, &tmperr); // use tmperr, because windows mapping might not - // be avaiable by design + // be available by design if (U_FAILURE(tmperr)) { ures_close(zones); return id; diff --git a/deps/icu-small/source/i18n/translit.cpp b/deps/icu-small/source/i18n/translit.cpp index a2ade1b4fe8578f83082d9edd53c65e944207740..c2a15837bedb0dbc654c8d0df5cc9e503febcc62 100644 --- a/deps/icu-small/source/i18n/translit.cpp +++ b/deps/icu-small/source/i18n/translit.cpp @@ -170,6 +170,7 @@ Transliterator* Transliterator::clone() const { * Assignment operator. */ Transliterator& Transliterator::operator=(const Transliterator& other) { + if (this == &other) { return *this; } // self-assignment: no-op ID = other.ID; // NUL-terminate the ID string ID.getTerminatedBuffer(); diff --git a/deps/icu-small/source/i18n/transreg.h b/deps/icu-small/source/i18n/transreg.h index 041244e1b02d774d0ec81381d5b829f133fba64f..0a0698862be1ac8f283748a6367f5034151f0839 100644 --- a/deps/icu-small/source/i18n/transreg.h +++ b/deps/icu-small/source/i18n/transreg.h @@ -69,7 +69,7 @@ class TransliteratorAlias : public UMemory { * it when the registry mutex is NOT held, to prevent deadlock. * It may only be called once. * - * Note: Only call create() if isRuleBased() returns FALSE. + * Note: Only call create() if isRuleBased() returns false. * * This method must be called *outside* of the TransliteratorRegistry * mutex. @@ -77,17 +77,17 @@ class TransliteratorAlias : public UMemory { Transliterator* create(UParseError&, UErrorCode&); /** - * Return TRUE if this alias is rule-based. If so, the caller + * Return true if this alias is rule-based. If so, the caller * must call parse() on it, then call TransliteratorRegistry::reget(). */ UBool isRuleBased() const; /** - * If isRuleBased() returns TRUE, then the caller must call this + * If isRuleBased() returns true, then the caller must call this * method, followed by TransliteratorRegistry::reget(). The latter * method must be called inside the TransliteratorRegistry mutex. * - * Note: Only call parse() if isRuleBased() returns TRUE. + * Note: Only call parse() if isRuleBased() returns true. * * This method must be called *outside* of the TransliteratorRegistry * mutex, because it can instantiate Transliterators embedded in @@ -144,7 +144,7 @@ class TransliteratorRegistry : public UMemory { public: /** - * Contructor + * Constructor * @param status Output param set to success/failure code. */ TransliteratorRegistry(UErrorCode& status); diff --git a/deps/icu-small/source/i18n/tridpars.h b/deps/icu-small/source/i18n/tridpars.h index 3d657ed17c9784b6837f14186875c5924d04a131..cd56146023162f6284d8f5d729c5703d7cf2036e 100644 --- a/deps/icu-small/source/i18n/tridpars.h +++ b/deps/icu-small/source/i18n/tridpars.h @@ -222,7 +222,7 @@ class TransliteratorIDParser /* not : public UObject because all methods are sta * @param source the given source. * @param target the given target. * @param variant the given variant - * @param isSourcePresent If TRUE then the source is present. + * @param isSourcePresent If true then the source is present. * If the source is not present, ANY will be * given as the source, and isSourcePresent will be null * @return an array of 4 strings: source, target, variant, and diff --git a/deps/icu-small/source/i18n/tzfmt.cpp b/deps/icu-small/source/i18n/tzfmt.cpp index 267d507aa7eca6a7d51496e9915751b0ff9d3b54..e70005a384085e71e9d5c53298138d5bbeb1df4f 100644 --- a/deps/icu-small/source/i18n/tzfmt.cpp +++ b/deps/icu-small/source/i18n/tzfmt.cpp @@ -1873,7 +1873,7 @@ TimeZoneFormat::parseOffsetFieldsWithPattern(const UnicodeString& text, int32_t // When TimeZoneFormat parse() is called from SimpleDateFormat, // leading space characters might be truncated. If the first pattern text // starts with such character (e.g. Bidi control), then we need to - // skip the leading space charcters. + // skip the leading space characters. if (idx < text.length() && !PatternProps::isWhiteSpace(text.char32At(idx))) { while (len > 0) { UChar32 ch; diff --git a/deps/icu-small/source/i18n/tznames_impl.h b/deps/icu-small/source/i18n/tznames_impl.h index 1286eeb80dc5030084671bf777f18db9a1bb80c8..417c0511f81f8ab2ba0808d1fd370ea9b1bef908 100644 --- a/deps/icu-small/source/i18n/tznames_impl.h +++ b/deps/icu-small/source/i18n/tznames_impl.h @@ -92,9 +92,9 @@ struct CharacterNode { UBool fHasValuesVector; UBool fPadding; - // No value: fValues == NULL and fHasValuesVector == FALSE - // One value: fValues == value and fHasValuesVector == FALSE - // >=2 values: fValues == UVector of values and fHasValuesVector == TRUE + // No value: fValues == NULL and fHasValuesVector == false + // One value: fValues == value and fHasValuesVector == false + // >=2 values: fValues == UVector of values and fHasValuesVector == true }; inline UBool CharacterNode::hasValues() const { diff --git a/deps/icu-small/source/i18n/ucal.cpp b/deps/icu-small/source/i18n/ucal.cpp index 8ea7fbf4f5693954449ece7759437e9b0f5795d0..39a9508ca93443a66ad21c510a428adca3cf05fd 100644 --- a/deps/icu-small/source/i18n/ucal.cpp +++ b/deps/icu-small/source/i18n/ucal.cpp @@ -33,8 +33,8 @@ U_NAMESPACE_USE static TimeZone* _createTimeZone(const UChar* zoneID, int32_t len, UErrorCode* ec) { - TimeZone* zone = NULL; - if (ec != NULL && U_SUCCESS(*ec)) { + TimeZone* zone = nullptr; + if (ec != nullptr && U_SUCCESS(*ec)) { // Note that if zoneID is invalid, we get back GMT. This odd // behavior is by design and goes back to the JDK. The only // failure we will see is a memory allocation failure. @@ -42,7 +42,7 @@ _createTimeZone(const UChar* zoneID, int32_t len, UErrorCode* ec) { UnicodeString zoneStrID; zoneStrID.setTo((UBool)(len < 0), zoneID, l); /* temporary read-only alias */ zone = TimeZone::createTimeZone(zoneStrID); - if (zone == NULL) { + if (zone == nullptr) { *ec = U_MEMORY_ALLOCATION_ERROR; } } @@ -58,20 +58,20 @@ ucal_openTimeZoneIDEnumeration(USystemTimeZoneType zoneType, const char* region, U_CAPI UEnumeration* U_EXPORT2 ucal_openTimeZones(UErrorCode* ec) { - return uenum_openFromStringEnumeration(TimeZone::createEnumeration(), ec); + return ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_ANY, nullptr, nullptr, ec); } U_CAPI UEnumeration* U_EXPORT2 ucal_openCountryTimeZones(const char* country, UErrorCode* ec) { - return uenum_openFromStringEnumeration(TimeZone::createEnumeration(country), ec); + return ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_ANY, country, nullptr, ec); } U_CAPI int32_t U_EXPORT2 ucal_getDefaultTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec) { int32_t len = 0; - if (ec != NULL && U_SUCCESS(*ec)) { + if (ec != nullptr && U_SUCCESS(*ec)) { TimeZone* zone = TimeZone::createDefault(); - if (zone == NULL) { + if (zone == nullptr) { *ec = U_MEMORY_ALLOCATION_ERROR; } else { UnicodeString id; @@ -86,17 +86,17 @@ ucal_getDefaultTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec) { U_CAPI void U_EXPORT2 ucal_setDefaultTimeZone(const UChar* zoneID, UErrorCode* ec) { TimeZone* zone = _createTimeZone(zoneID, -1, ec); - if (zone != NULL) { + if (zone != nullptr) { TimeZone::adoptDefault(zone); } } -U_DRAFT int32_t U_EXPORT2 +U_CAPI int32_t U_EXPORT2 ucal_getHostTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec) { int32_t len = 0; - if (ec != NULL && U_SUCCESS(*ec)) { + if (ec != nullptr && U_SUCCESS(*ec)) { TimeZone *zone = TimeZone::detectHostTimeZone(); - if (zone == NULL) { + if (zone == nullptr) { *ec = U_MEMORY_ALLOCATION_ERROR; } else { UnicodeString id; @@ -114,7 +114,7 @@ ucal_getDSTSavings(const UChar* zoneID, UErrorCode* ec) { TimeZone* zone = _createTimeZone(zoneID, -1, ec); if (U_SUCCESS(*ec)) { SimpleTimeZone* stz = dynamic_cast(zone); - if (stz != NULL) { + if (stz != nullptr) { result = stz->getDSTSavings(); } else { // Since there is no getDSTSavings on TimeZone, we use a @@ -219,10 +219,10 @@ ucal_setTimeZone( UCalendar* cal, if(U_FAILURE(*status)) return; - TimeZone* zone = (zoneID==NULL) ? TimeZone::createDefault() + TimeZone* zone = (zoneID==nullptr) ? TimeZone::createDefault() : _createTimeZone(zoneID, len, status); - if (zone != NULL) { + if (zone != nullptr) { ((Calendar*)cal)->adoptTimeZone(zone); } } @@ -255,8 +255,8 @@ ucal_getTimeZoneDisplayName(const UCalendar* cal, const TimeZone& tz = ((Calendar*)cal)->getTimeZone(); UnicodeString id; - if(!(result==NULL && resultLength==0)) { - // NULL destination for pure preflighting: empty dummy string + if (!(result == nullptr && resultLength == 0)) { + // Null destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer id.setTo(result, 0, resultLength); } @@ -298,12 +298,12 @@ ucal_setGregorianChange(UCalendar *cal, UDate date, UErrorCode *pErrorCode) { } Calendar *cpp_cal = (Calendar *)cal; GregorianCalendar *gregocal = dynamic_cast(cpp_cal); - // Not if(gregocal == NULL) { + // Not if(gregocal == nullptr) { // because we really want to work only with a GregorianCalendar, not with // its subclasses like BuddhistCalendar. - if (cpp_cal == NULL) { - // We normally don't check "this" pointers for NULL, but this here avoids - // compiler-generated exception-throwing code in case cal == NULL. + if (cpp_cal == nullptr) { + // We normally don't check "this" pointers for nullptr, but this here avoids + // compiler-generated exception-throwing code in case cal == nullptr. *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; return; } @@ -321,11 +321,11 @@ ucal_getGregorianChange(const UCalendar *cal, UErrorCode *pErrorCode) { } const Calendar *cpp_cal = (const Calendar *)cal; const GregorianCalendar *gregocal = dynamic_cast(cpp_cal); - // Not if(gregocal == NULL) { + // Not if(gregocal == nullptr) { // see comments in ucal_setGregorianChange(). - if (cpp_cal == NULL) { - // We normally don't check "this" pointers for NULL, but this here avoids - // compiler-generated exception-throwing code in case cal == NULL. + if (cpp_cal == nullptr) { + // We normally don't check "this" pointers for nullptr, but this here avoids + // compiler-generated exception-throwing code in case cal == nullptr. *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; return (UDate)0; } @@ -572,11 +572,11 @@ ucal_getLimit( const UCalendar* cal, U_CAPI const char * U_EXPORT2 ucal_getLocaleByType(const UCalendar *cal, ULocDataLocaleType type, UErrorCode* status) { - if (cal == NULL) { + if (cal == nullptr) { if (U_SUCCESS(*status)) { *status = U_ILLEGAL_ARGUMENT_ERROR; } - return NULL; + return nullptr; } return ((Calendar*)cal)->getLocaleID(type, *status); } @@ -617,7 +617,7 @@ U_CAPI const char * U_EXPORT2 ucal_getType(const UCalendar *cal, UErrorCode* status) { if (U_FAILURE(*status)) { - return NULL; + return nullptr; } return ((Calendar*)cal)->getType(); } @@ -662,8 +662,8 @@ ucal_getFieldDifference(UCalendar* cal, UDate target, static const UEnumeration defaultKeywordValues = { - NULL, - NULL, + nullptr, + nullptr, ulist_close_keyword_values_iterator, ulist_count_keyword_values, uenum_unextDefault, @@ -690,7 +690,7 @@ static const char * const CAL_TYPES[] = { "islamic-umalqura", "islamic-tbla", "islamic-rgsa", - NULL + nullptr }; U_CAPI UEnumeration* U_EXPORT2 @@ -700,16 +700,16 @@ ucal_getKeywordValuesForLocale(const char * /* key */, const char* locale, UBool (void)ulocimp_getRegionForSupplementalData(locale, TRUE, prefRegion, sizeof(prefRegion), status); // Read preferred calendar values from supplementalData calendarPreference - UResourceBundle *rb = ures_openDirect(NULL, "supplementalData", status); + UResourceBundle *rb = ures_openDirect(nullptr, "supplementalData", status); ures_getByKey(rb, "calendarPreferenceData", rb, status); - UResourceBundle *order = ures_getByKey(rb, prefRegion, NULL, status); - if (*status == U_MISSING_RESOURCE_ERROR && rb != NULL) { + UResourceBundle *order = ures_getByKey(rb, prefRegion, nullptr, status); + if (*status == U_MISSING_RESOURCE_ERROR && rb != nullptr) { *status = U_ZERO_ERROR; - order = ures_getByKey(rb, "001", NULL, status); + order = ures_getByKey(rb, "001", nullptr, status); } // Create a list of calendar type strings - UList *values = NULL; + UList *values = nullptr; if (U_SUCCESS(*status)) { values = ulist_createEmptyList(status); if (U_SUCCESS(*status)) { @@ -717,7 +717,7 @@ ucal_getKeywordValuesForLocale(const char * /* key */, const char* locale, UBool int32_t len; const UChar *type = ures_getStringByIndex(order, i, &len, status); char *caltype = (char*)uprv_malloc(len + 1); - if (caltype == NULL) { + if (caltype == nullptr) { *status = U_MEMORY_ALLOCATION_ERROR; break; } @@ -732,7 +732,7 @@ ucal_getKeywordValuesForLocale(const char * /* key */, const char* locale, UBool if (U_SUCCESS(*status) && !commonlyUsed) { // If not commonlyUsed, add other available values - for (int32_t i = 0; CAL_TYPES[i] != NULL; i++) { + for (int32_t i = 0; CAL_TYPES[i] != nullptr; i++) { if (!ulist_containsString(values, CAL_TYPES[i], (int32_t)uprv_strlen(CAL_TYPES[i]))) { ulist_addItemEndList(values, CAL_TYPES[i], FALSE, status); if (U_FAILURE(*status)) { @@ -743,7 +743,7 @@ ucal_getKeywordValuesForLocale(const char * /* key */, const char* locale, UBool } if (U_FAILURE(*status)) { ulist_deleteList(values); - values = NULL; + values = nullptr; } } } @@ -751,16 +751,16 @@ ucal_getKeywordValuesForLocale(const char * /* key */, const char* locale, UBool ures_close(order); ures_close(rb); - if (U_FAILURE(*status) || values == NULL) { - return NULL; + if (U_FAILURE(*status) || values == nullptr) { + return nullptr; } // Create string enumeration UEnumeration *en = (UEnumeration*)uprv_malloc(sizeof(UEnumeration)); - if (en == NULL) { + if (en == nullptr) { *status = U_MEMORY_ALLOCATION_ERROR; ulist_deleteList(values); - return NULL; + return nullptr; } ulist_resetList(values); memcpy(en, &defaultKeywordValues, sizeof(UEnumeration)); @@ -778,7 +778,7 @@ ucal_getTimeZoneTransitionDate(const UCalendar* cal, UTimeZoneTransitionType typ UDate base = ((Calendar*)cal)->getTime(*status); const TimeZone& tz = ((Calendar*)cal)->getTimeZone(); const BasicTimeZone * btz = dynamic_cast(&tz); - if (btz != NULL && U_SUCCESS(*status)) { + if (btz != nullptr && U_SUCCESS(*status)) { TimeZoneTransition tzt; UBool inclusive = (type == UCAL_TZ_TRANSITION_NEXT_INCLUSIVE || type == UCAL_TZ_TRANSITION_PREVIOUS_INCLUSIVE); UBool result = (type == UCAL_TZ_TRANSITION_NEXT || type == UCAL_TZ_TRANSITION_NEXT_INCLUSIVE)? @@ -828,4 +828,28 @@ ucal_getTimeZoneIDForWindowsID(const UChar* winid, int32_t len, const char* regi return resultLen; } +U_CAPI void U_EXPORT2 ucal_getTimeZoneOffsetFromLocal( + const UCalendar* cal, + UTimeZoneLocalOption nonExistingTimeOpt, + UTimeZoneLocalOption duplicatedTimeOpt, + int32_t* rawOffset, int32_t* dstOffset, UErrorCode* status) +{ + if (U_FAILURE(*status)) { + return; + } + UDate date = ((Calendar*)cal)->getTime(*status); + if (U_FAILURE(*status)) { + return; + } + const TimeZone& tz = ((Calendar*)cal)->getTimeZone(); + const BasicTimeZone* btz = dynamic_cast(&tz); + if (btz == nullptr) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return; + } + btz->getOffsetFromLocal( + date, nonExistingTimeOpt, duplicatedTimeOpt, + *rawOffset, *dstOffset, *status); +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/ucol_imp.h b/deps/icu-small/source/i18n/ucol_imp.h index a251fc461d3ac21c794e307fe9df50dd811d45be..f463957fd4f2d861db2f7758950e2853b6a93f49 100644 --- a/deps/icu-small/source/i18n/ucol_imp.h +++ b/deps/icu-small/source/i18n/ucol_imp.h @@ -41,10 +41,10 @@ * rules must be equivalent. * @param source first collator * @param target second collator - * @return TRUE or FALSE + * @return true or false * @internal ICU 3.0 */ -U_INTERNAL UBool U_EXPORT2 +U_CAPI UBool U_EXPORT2 ucol_equals(const UCollator *source, const UCollator *target); /** diff --git a/deps/icu-small/source/i18n/ucol_sit.cpp b/deps/icu-small/source/i18n/ucol_sit.cpp index 9fa7cd5fd73851b3b7fbf96e909ec7db7668fad1..d6bbf97b310bd352e1600dc6d224d5c21c0711dc 100644 --- a/deps/icu-small/source/i18n/ucol_sit.cpp +++ b/deps/icu-small/source/i18n/ucol_sit.cpp @@ -372,10 +372,7 @@ int32_t ucol_sit_dumpSpecs(CollatorSpec *s, char *destination, int32_t capacity, } len += s->entries[i].length(); } else { - len += s->entries[i].length(); - if(len < capacity) { - uprv_strncat(destination,s->entries[i].data(), s->entries[i].length()); - } + len += s->entries[i].extract(destination + len, capacity - len, *status); } } } diff --git a/deps/icu-small/source/i18n/ucsdet.cpp b/deps/icu-small/source/i18n/ucsdet.cpp index 46f69cf90cba6b34e1e5d89564e99d3fb1b92457..63f204d0e104210104528762a558f477416e80e2 100644 --- a/deps/icu-small/source/i18n/ucsdet.cpp +++ b/deps/icu-small/source/i18n/ucsdet.cpp @@ -193,7 +193,7 @@ ucsdet_getAllDetectableCharsets(const UCharsetDetector * /*ucsd*/, UErrorCode *s return CharsetDetector::getAllDetectableCharsets(*status); } -U_DRAFT UEnumeration * U_EXPORT2 +U_CAPI UEnumeration * U_EXPORT2 ucsdet_getDetectableCharsets(const UCharsetDetector *ucsd, UErrorCode *status) { return ((CharsetDetector *)ucsd)->getDetectableCharsets(*status); diff --git a/deps/icu-small/source/i18n/udat.cpp b/deps/icu-small/source/i18n/udat.cpp index da8befc9e3c65b221137dcbf90ce3a9c079b2515..016805aab66fddec47d1b5540182bfab5a476d0c 100644 --- a/deps/icu-small/source/i18n/udat.cpp +++ b/deps/icu-small/source/i18n/udat.cpp @@ -82,19 +82,24 @@ static UCalendarDateFields gDateFieldMapping[] = { UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_ISO_FIELD = 32 (also UCAL_DST_OFFSET) UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_ISO_LOCAL_FIELD = 33 (also UCAL_DST_OFFSET) UCAL_EXTENDED_YEAR, // UDAT_RELATED_YEAR_FIELD = 34 (not an exact match) - UCAL_FIELD_COUNT, // UDAT_FIELD_COUNT = 35 + UCAL_FIELD_COUNT, // UDAT_AM_PM_MIDNIGHT_NOON_FIELD=35 (no match) + UCAL_FIELD_COUNT, // UDAT_FLEXIBLE_DAY_PERIOD_FIELD=36 (no match) + UCAL_FIELD_COUNT, // UDAT_TIME_SEPARATOR_FIELD = 37 (no match) + // UDAT_FIELD_COUNT = 38 as of ICU 67 // UCAL_IS_LEAP_MONTH is not the target of a mapping }; U_CAPI UCalendarDateFields U_EXPORT2 udat_toCalendarDateField(UDateFormatField field) { - return gDateFieldMapping[field]; + static_assert(UDAT_FIELD_COUNT == UPRV_LENGTHOF(gDateFieldMapping), + "UDateFormatField and gDateFieldMapping should have the same number of entries and be kept in sync."); + return (field >= UDAT_ERA_FIELD && field < UPRV_LENGTHOF(gDateFieldMapping))? gDateFieldMapping[field]: UCAL_FIELD_COUNT; } /* For now- one opener. */ static UDateFormatOpener gOpener = NULL; -U_INTERNAL void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_registerOpener(UDateFormatOpener opener, UErrorCode *status) { if(U_FAILURE(*status)) return; @@ -107,7 +112,7 @@ udat_registerOpener(UDateFormatOpener opener, UErrorCode *status) umtx_unlock(NULL); } -U_INTERNAL UDateFormatOpener U_EXPORT2 +U_CAPI UDateFormatOpener U_EXPORT2 udat_unregisterOpener(UDateFormatOpener opener, UErrorCode *status) { if(U_FAILURE(*status)) return NULL; @@ -419,7 +424,7 @@ udat_setLenient( UDateFormat* fmt, ((DateFormat*)fmt)->setLenient(isLenient); } -U_DRAFT UBool U_EXPORT2 +U_CAPI UBool U_EXPORT2 udat_getBooleanAttribute(const UDateFormat* fmt, UDateFormatBooleanAttribute attr, UErrorCode* status) @@ -429,7 +434,7 @@ udat_getBooleanAttribute(const UDateFormat* fmt, //return FALSE; } -U_DRAFT void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_setBooleanAttribute(UDateFormat *fmt, UDateFormatBooleanAttribute attr, UBool newValue, @@ -452,7 +457,7 @@ udat_setCalendar(UDateFormat* fmt, ((DateFormat*)fmt)->setCalendar(*((Calendar*)calendarToSet)); } -U_DRAFT const UNumberFormat* U_EXPORT2 +U_CAPI const UNumberFormat* U_EXPORT2 udat_getNumberFormatForField(const UDateFormat* fmt, UChar field) { UErrorCode status = U_ZERO_ERROR; @@ -467,7 +472,7 @@ udat_getNumberFormat(const UDateFormat* fmt) return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat(); } -U_DRAFT void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_adoptNumberFormatForFields( UDateFormat* fmt, const UChar* fields, UNumberFormat* numberFormatToSet, @@ -489,7 +494,7 @@ udat_setNumberFormat(UDateFormat* fmt, ((DateFormat*)fmt)->setNumberFormat(*((NumberFormat*)numberFormatToSet)); } -U_DRAFT void U_EXPORT2 +U_CAPI void U_EXPORT2 udat_adoptNumberFormat( UDateFormat* fmt, UNumberFormat* numberFormatToAdopt) { diff --git a/deps/icu-small/source/i18n/udateintervalformat.cpp b/deps/icu-small/source/i18n/udateintervalformat.cpp index 388960384b563ffba239fc6837203c20c187f497..355744346a39d729c5b279a6fccd062e22e2d4fe 100644 --- a/deps/icu-small/source/i18n/udateintervalformat.cpp +++ b/deps/icu-small/source/i18n/udateintervalformat.cpp @@ -18,6 +18,7 @@ #include "unicode/timezone.h" #include "unicode/locid.h" #include "unicode/unistr.h" +#include "unicode/udisplaycontext.h" #include "formattedval_impl.h" U_NAMESPACE_USE @@ -116,7 +117,7 @@ udtitvfmt_format(const UDateIntervalFormat* formatter, } -U_DRAFT void U_EXPORT2 +U_CAPI void U_EXPORT2 udtitvfmt_formatToResult( const UDateIntervalFormat* formatter, UDate fromDate, @@ -134,7 +135,7 @@ udtitvfmt_formatToResult( } } -U_DRAFT void U_EXPORT2 +U_CAPI void U_EXPORT2 udtitvfmt_formatCalendarToResult( const UDateIntervalFormat* formatter, UCalendar* fromCalendar, @@ -151,5 +152,25 @@ udtitvfmt_formatCalendarToResult( } } +U_CAPI void U_EXPORT2 +udtitvfmt_setContext(UDateIntervalFormat* formatter, + UDisplayContext value, + UErrorCode* status) { + if (U_FAILURE(*status)) { + return; + } + reinterpret_cast(formatter)->setContext( value, *status ); +} + +U_CAPI UDisplayContext U_EXPORT2 +udtitvfmt_getContext(const UDateIntervalFormat* formatter, + UDisplayContextType type, + UErrorCode* status) { + if (U_FAILURE(*status)) { + return (UDisplayContext)0; + } + return reinterpret_cast(formatter)->getContext( type, *status ); +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/uitercollationiterator.h b/deps/icu-small/source/i18n/uitercollationiterator.h index 62b6f8341933bb3d0e540887cd05055a2144507c..3a7b1a0ec23b4728f52c3e018d77f0f199408d38 100644 --- a/deps/icu-small/source/i18n/uitercollationiterator.h +++ b/deps/icu-small/source/i18n/uitercollationiterator.h @@ -96,7 +96,7 @@ private: /** * Extends the FCD text segment forward or normalizes around pos. - * @return TRUE if success + * @return true if success */ UBool nextSegment(UErrorCode &errorCode); @@ -107,7 +107,7 @@ private: /** * Extends the FCD text segment backward or normalizes around pos. - * @return TRUE if success + * @return true if success */ UBool previousSegment(UErrorCode &errorCode); diff --git a/deps/icu-small/source/i18n/ulocdata.cpp b/deps/icu-small/source/i18n/ulocdata.cpp index f651fee6fc4efa3ac8626f7aae68073b21003d02..3046167b328db8b5af58b5d6e4fe4efd73911296 100644 --- a/deps/icu-small/source/i18n/ulocdata.cpp +++ b/deps/icu-small/source/i18n/ulocdata.cpp @@ -172,7 +172,7 @@ ulocdata_getDelimiter(ULocaleData *uld, ULocaleDataDelimiterType type, return 0; } - delimiter = ures_getStringByKey(delimiterBundle, delimiterKeys[type], &len, &localStatus); + delimiter = ures_getStringByKeyWithFallback(delimiterBundle, delimiterKeys[type], &len, &localStatus); ures_close(delimiterBundle); if ( (localStatus == U_USING_DEFAULT_WARNING) && uld->noSubstitute ) { diff --git a/deps/icu-small/source/i18n/uni2name.cpp b/deps/icu-small/source/i18n/uni2name.cpp index 9df3924ae5f1477379c43e567ff6d851b10889fb..729a1e5fa82a62f3bdb2b203912e8afa86a0dfa9 100644 --- a/deps/icu-small/source/i18n/uni2name.cpp +++ b/deps/icu-small/source/i18n/uni2name.cpp @@ -81,7 +81,7 @@ void UnicodeNameTransliterator::handleTransliterate(Replaceable& text, UTransPos return; } - // Accomodate the longest possible name plus padding + // Accommodate the longest possible name plus padding char* buf = (char*) uprv_malloc(maxLen); if (buf == NULL) { offsets.start = offsets.limit; diff --git a/deps/icu-small/source/i18n/unicode/alphaindex.h b/deps/icu-small/source/i18n/unicode/alphaindex.h index fe43995fe81155e3bc6eaa773615eeebcfcc9bfc..d72abce9acd3ecfe3f104396e0714fac49b2022f 100644 --- a/deps/icu-small/source/i18n/unicode/alphaindex.h +++ b/deps/icu-small/source/i18n/unicode/alphaindex.h @@ -549,14 +549,14 @@ public: /** - * Advance the iteration over the Buckets of this index. Return FALSE if + * Advance the iteration over the Buckets of this index. Return false if * there are no more Buckets. * * @param status Error code, will be set with the reason if the operation fails. * U_ENUM_OUT_OF_SYNC_ERROR will be reported if the index is modified while * an enumeration of its contents are in process. * - * @return TRUE if success, FALSE if at end of iteration + * @return true if success, false if at end of iteration * @stable ICU 4.8 */ virtual UBool nextBucket(UErrorCode &status); @@ -609,7 +609,7 @@ public: * @param status Error code, will be set with the reason if the operation fails. * U_ENUM_OUT_OF_SYNC_ERROR will be reported if the index is modified while * an enumeration of its contents are in process. - * @return TRUE if successful, FALSE when the iteration advances past the last item. + * @return true if successful, false when the iteration advances past the last item. * @stable ICU 4.8 */ virtual UBool nextRecord(UErrorCode &status); diff --git a/deps/icu-small/source/i18n/unicode/basictz.h b/deps/icu-small/source/i18n/unicode/basictz.h index cc8059709f49b00ce5603d1adfe369e137ead87b..ea8720ed13cf41c5eba8088cfd72ed4434cdf7ab 100644 --- a/deps/icu-small/source/i18n/unicode/basictz.h +++ b/deps/icu-small/source/i18n/unicode/basictz.h @@ -56,7 +56,7 @@ public: * @param base The base time. * @param inclusive Whether the base time is inclusive or not. * @param result Receives the first transition after the base time. - * @return TRUE if the transition is found. + * @return true if the transition is found. * @stable ICU 3.8 */ virtual UBool getNextTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const = 0; @@ -66,7 +66,7 @@ public: * @param base The base time. * @param inclusive Whether the base time is inclusive or not. * @param result Receives the most recent transition before the base time. - * @return TRUE if the transition is found. + * @return true if the transition is found. * @stable ICU 3.8 */ virtual UBool getPreviousTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const = 0; @@ -152,6 +152,17 @@ public: virtual void getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial, AnnualTimeZoneRule*& std, AnnualTimeZoneRule*& dst, UErrorCode& status) const; +#ifndef U_FORCE_HIDE_DRAFT_API + /** + * Get time zone offsets from local wall time. + * @draft ICU 69 + */ + virtual void getOffsetFromLocal( + UDate date, UTimeZoneLocalOption nonExistingTimeOpt, + UTimeZoneLocalOption duplicatedTimeOpt, int32_t& rawOffset, + int32_t& dstOffset, UErrorCode& status) const; + +#endif /* U_FORCE_HIDE_DRAFT_API */ #ifndef U_HIDE_INTERNAL_API /** @@ -161,17 +172,17 @@ public: enum { kStandard = 0x01, kDaylight = 0x03, - kFormer = 0x04, - kLatter = 0x0C + kFormer = 0x04, /* UCAL_TZ_LOCAL_FORMER */ + kLatter = 0x0C /* UCAL_TZ_LOCAL_LATTER */ }; -#endif /* U_HIDE_INTERNAL_API */ /** * Get time zone offsets from local wall time. * @internal */ - virtual void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt, + void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt, int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const; +#endif /* U_HIDE_INTERNAL_API */ protected: diff --git a/deps/icu-small/source/i18n/unicode/calendar.h b/deps/icu-small/source/i18n/unicode/calendar.h index 2a8c2935ca8e24696353e1a7e62e43e67d2703e0..be774ab26fb61998b8e888495353afcc6ac5caea 100644 --- a/deps/icu-small/source/i18n/unicode/calendar.h +++ b/deps/icu-small/source/i18n/unicode/calendar.h @@ -47,6 +47,8 @@ U_NAMESPACE_BEGIN class ICUServiceFactory; +// Do not conditionalize the following with #ifndef U_HIDE_INTERNAL_API, +// it is a return type for a virtual method (@internal) /** * @internal */ @@ -464,10 +466,10 @@ public: UBool operator!=(const Calendar& that) const {return !operator==(that);} /** - * Returns TRUE if the given Calendar object is equivalent to this + * Returns true if the given Calendar object is equivalent to this * one. An equivalent Calendar will behave exactly as this one * does, but it may be set to a different time. By contrast, for - * the operator==() method to return TRUE, the other Calendar must + * the operator==() method to return true, the other Calendar must * be set to the same time. * * @param other the Calendar to be compared with this Calendar @@ -1359,7 +1361,7 @@ public: * localeID.append(calType); * char langTag[100]; * UErrorCode errorCode = U_ZERO_ERROR; - * int32_t length = uloc_toLanguageTag(localeID.c_str(), langTag, (int32_t)sizeof(langTag), TRUE, &errorCode); + * int32_t length = uloc_toLanguageTag(localeID.c_str(), langTag, (int32_t)sizeof(langTag), true, &errorCode); * if (U_FAILURE(errorCode)) { * // deal with errors & overflow * } @@ -1410,21 +1412,21 @@ public: virtual int32_t getWeekendTransition(UCalendarDaysOfWeek dayOfWeek, UErrorCode &status) const; /** - * Returns TRUE if the given UDate is in the weekend in + * Returns true if the given UDate is in the weekend in * this calendar system. * @param date The UDate in question. * @param status The error code for the operation. - * @return TRUE if the given UDate is in the weekend in - * this calendar system, FALSE otherwise. + * @return true if the given UDate is in the weekend in + * this calendar system, false otherwise. * @stable ICU 4.4 */ virtual UBool isWeekend(UDate date, UErrorCode &status) const; /** - * Returns TRUE if this Calendar's current date-time is in the weekend in + * Returns true if this Calendar's current date-time is in the weekend in * this calendar system. - * @return TRUE if this Calendar's current date-time is in the weekend in - * this calendar system, FALSE otherwise. + * @return true if this Calendar's current date-time is in the weekend in + * this calendar system, false otherwise. * @stable ICU 4.4 */ virtual UBool isWeekend(void) const; @@ -1849,7 +1851,7 @@ private: * @param startValue starting (least max) value of field * @param endValue ending (greatest max) value of field * @param status return type - * @internal + * @internal (private) */ int32_t getActualHelper(UCalendarDateFields field, int32_t startValue, int32_t endValue, UErrorCode &status) const; @@ -2372,7 +2374,7 @@ private: * * @param key the registry key returned by a previous call to registerFactory * @param status the in/out status code, no special meanings are assigned - * @return TRUE if the factory for the key was successfully unregistered + * @return true if the factory for the key was successfully unregistered * @internal */ static UBool unregister(URegistryKey key, UErrorCode& status); @@ -2398,7 +2400,7 @@ private: #endif /* !UCONFIG_NO_SERVICE */ /** - * @return TRUE if this calendar has a default century (i.e. 03 -> 2003) + * @return true if this calendar has a default century (i.e. 03 -> 2003) * @internal */ virtual UBool haveDefaultCentury() const = 0; @@ -2458,7 +2460,7 @@ private: * @param base The base time, inclusive * @param transitionTime Receives the result time * @param status The error status - * @return TRUE if a transition is found. + * @return true if a transition is found. */ UBool getImmediatePreviousZoneTransition(UDate base, UDate *transitionTime, UErrorCode& status) const; @@ -2531,7 +2533,7 @@ Calendar::internalSet(UCalendarDateFields field, int32_t value) { fFields[field] = value; fStamp[field] = kInternallySet; - fIsSet[field] = TRUE; // Remove later + fIsSet[field] = true; // Remove later } diff --git a/deps/icu-small/source/i18n/unicode/choicfmt.h b/deps/icu-small/source/i18n/unicode/choicfmt.h index 3b2f48cb1f853ca1c3f84a735e7fc67c844daa82..cb01fca253355d7104fc9c57695de218921f621e 100644 --- a/deps/icu-small/source/i18n/unicode/choicfmt.h +++ b/deps/icu-small/source/i18n/unicode/choicfmt.h @@ -106,7 +106,7 @@ class MessageFormat; * arrays of numbers, closure flags and strings, * they are interpreted just like * the sequence of (number separator string) in an equivalent pattern string. - * closure[i]==TRUE corresponds to a less_than separator sign. + * closure[i]==true corresponds to a less_than separator sign. * The equivalent pattern string will be constructed automatically.

* *

During formatting, a number is mapped to the first range @@ -126,7 +126,7 @@ class MessageFormat; *

Here is an example of two arrays that map the number * 1..7 to the English day of the week abbreviations * Sun..Sat. No closures array is given; this is the same as - * specifying all closures to be FALSE.

+ * specifying all closures to be false.

* *
    {1,2,3,4,5,6,7},
  *     {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"}
@@ -138,7 +138,7 @@ class MessageFormat; * like the turned bracket in European notation: [-Inf, 1) == [-Inf, 1[ )

* *
    {0, 1, 1},
- *     {FALSE, FALSE, TRUE},
+ *     {false, false, true},
  *     {"no files", "one file", "many files"}
* *

Here is an example that shows formatting and parsing:

@@ -189,7 +189,7 @@ public: /** * Constructs a new ChoiceFormat with the given limits and message strings. - * All closure flags default to FALSE, + * All closure flags default to false, * equivalent to less_than_or_equal separators. * * Copies the limits and formats instead of adopting them. @@ -210,9 +210,9 @@ public: * * @param limits Array of limit values * @param closures Array of booleans specifying whether each - * element of 'limits' is open or closed. If FALSE, then the + * element of 'limits' is open or closed. If false, then the * corresponding limit number is a member of its range. - * If TRUE, then the limit number belongs to the previous range it. + * If true, then the limit number belongs to the previous range it. * @param formats Array of formats * @param count Size of 'limits', 'closures', and 'formats' arrays * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments. @@ -568,13 +568,13 @@ private: * The intervals may be closed, half open, or open. This affects * formatting but does not affect parsing. Interval i is affected * by fClosures[i] and fClosures[i+1]. If fClosures[i] - * is FALSE, then the value fChoiceLimits[i] is in interval i. + * is false, then the value fChoiceLimits[i] is in interval i. * That is, intervals i and i are: * * i-1: ... x < fChoiceLimits[i] * i: fChoiceLimits[i] <= x ... * - * If fClosures[i] is TRUE, then the value fChoiceLimits[i] is + * If fClosures[i] is true, then the value fChoiceLimits[i] is * in interval i-1. That is, intervals i-1 and i are: * * i-1: ... x <= fChoiceLimits[i] diff --git a/deps/icu-small/source/i18n/unicode/coleitr.h b/deps/icu-small/source/i18n/unicode/coleitr.h index 809d435e509b49bb7b37eeb620f3c84b3fc2061e..2696b588278cde38cfdf36773738e798182b7c91 100644 --- a/deps/icu-small/source/i18n/unicode/coleitr.h +++ b/deps/icu-small/source/i18n/unicode/coleitr.h @@ -253,7 +253,7 @@ public: /** * Checks if a comparison order is ignorable. * @param order the collation order. - * @return TRUE if a character is ignorable, FALSE otherwise. + * @return true if a character is ignorable, false otherwise. * @stable ICU 2.0 */ static inline UBool isIgnorable(int32_t order); diff --git a/deps/icu-small/source/i18n/unicode/coll.h b/deps/icu-small/source/i18n/unicode/coll.h index f5564c73944bcb1bf30123fbe5818e7ca5398b27..c750711fc158cffe55be7b21f83c8be62d45ad01 100644 --- a/deps/icu-small/source/i18n/unicode/coll.h +++ b/deps/icu-small/source/i18n/unicode/coll.h @@ -236,21 +236,21 @@ public: // Collator public methods -------------------------------------------- /** - * Returns TRUE if "other" is the same as "this". + * Returns true if "other" is the same as "this". * - * The base class implementation returns TRUE if "other" has the same type/class as "this": + * The base class implementation returns true if "other" has the same type/class as "this": * `typeid(*this) == typeid(other)`. * * Subclass implementations should do something like the following: * - * if (this == &other) { return TRUE; } - * if (!Collator::operator==(other)) { return FALSE; } // not the same class + * if (this == &other) { return true; } + * if (!Collator::operator==(other)) { return false; } // not the same class * * const MyCollator &o = (const MyCollator&)other; * (compare this vs. o's subclass fields) * * @param other Collator object to be compared - * @return TRUE if other is the same as this. + * @return true if other is the same as this. * @stable ICU 2.0 */ virtual UBool operator==(const Collator& other) const; @@ -259,7 +259,7 @@ public: * Returns true if "other" is not the same as "this". * Calls ! operator==(const Collator&) const which works for all subclasses. * @param other Collator object to be compared - * @return TRUE if other is not the same as this. + * @return true if other is not the same as this. * @stable ICU 2.0 */ virtual UBool operator!=(const Collator& other) const; @@ -304,7 +304,7 @@ public: * Starting with ICU 54, collation attributes can be specified via locale keywords as well, * in the old locale extension syntax ("el@colCaseFirst=upper") * or in language tag syntax ("el-u-kf-upper"). - * See User Guide: Collation API. + * See User Guide: Collation API. * * The UErrorCode& err parameter is used to return status information to the user. * To check whether the construction succeeded or not, you should check @@ -788,7 +788,7 @@ public: * applications who wish to cache collators, or otherwise reuse * collators when possible. The functional equivalent may change * over time. For more information, please see the + * href="https://unicode-org.github.io/icu/userguide/locale#locales-and-services"> * Locales and Services section of the ICU User Guide. * @param keyword a particular keyword as enumerated by * ucol_getKeywords. @@ -841,7 +841,7 @@ public: * Collator::createInstance to avoid undefined behavior. * @param key the registry key returned by a previous call to registerInstance * @param status the in/out status code, no special meanings are assigned - * @return TRUE if the collator for the key was successfully unregistered + * @return true if the collator for the key was successfully unregistered * @stable ICU 2.6 */ static UBool U_EXPORT2 unregister(URegistryKey key, UErrorCode& status); @@ -1139,7 +1139,7 @@ public: * This string will be normalized. * The structure and the syntax of the string is defined in the "Naming collators" * section of the users guide: - * http://userguide.icu-project.org/collation/concepts#TOC-Collator-naming-scheme + * https://unicode-org.github.io/icu/userguide/collation/concepts#collator-naming-scheme * This function supports preflighting. * * This is internal, and intended to be used with delegate converters. diff --git a/deps/icu-small/source/i18n/unicode/curramt.h b/deps/icu-small/source/i18n/unicode/curramt.h index 65e6619db30c161d6225eb8d5a9792ce32fa964c..9c8496381d7aa3826454eb0d71f6495244784e11 100644 --- a/deps/icu-small/source/i18n/unicode/curramt.h +++ b/deps/icu-small/source/i18n/unicode/curramt.h @@ -41,7 +41,7 @@ class U_I18N_API CurrencyAmount: public Measure { /** * Construct an object with the given numeric amount and the given * ISO currency code. - * @param amount a numeric object; amount.isNumeric() must be TRUE + * @param amount a numeric object; amount.isNumeric() must be true * @param isoCode the 3-letter ISO 4217 currency code; must not be * NULL and must have length 3 * @param ec input-output error code. If the amount or the isoCode diff --git a/deps/icu-small/source/i18n/unicode/datefmt.h b/deps/icu-small/source/i18n/unicode/datefmt.h index 21217e567acf7d9589a856304aa878c52b6b342a..bbba0785edaccc6cb2006193899739676dbae35c 100644 --- a/deps/icu-small/source/i18n/unicode/datefmt.h +++ b/deps/icu-small/source/i18n/unicode/datefmt.h @@ -139,7 +139,7 @@ template class U_I18N_API EnumSet * You can also use forms of the parse and format methods with ParsePosition and * FieldPosition to allow you to diff --git a/deps/icu-small/source/i18n/unicode/dcfmtsym.h b/deps/icu-small/source/i18n/unicode/dcfmtsym.h index 582e7533a4aceb3af4d52c9c54464ac4c0c3600d..d0f844a51a369fa7ec8df0fbc297bc497f0074e9 100644 --- a/deps/icu-small/source/i18n/unicode/dcfmtsym.h +++ b/deps/icu-small/source/i18n/unicode/dcfmtsym.h @@ -378,7 +378,7 @@ private: * back to the locale. */ void initialize(const Locale& locale, UErrorCode& success, - UBool useLastResortData = FALSE, const NumberingSystem* ns = nullptr); + UBool useLastResortData = false, const NumberingSystem* ns = nullptr); /** * Initialize the symbols with default values. @@ -446,7 +446,7 @@ public: inline const UnicodeString& getConstDigitSymbol(int32_t digit) const; /** - * Returns that pattern stored in currecy info. Internal API for use by NumberFormat API. + * Returns that pattern stored in currency info. Internal API for use by NumberFormat API. * @internal */ inline const char16_t* getCurrencyPattern(void) const; @@ -543,12 +543,12 @@ inline const UnicodeString& DecimalFormatSymbols::getConstDigitSymbol(int32_t di // ------------------------------------- inline void -DecimalFormatSymbols::setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propogateDigits = TRUE) { +DecimalFormatSymbols::setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propagateDigits = true) { if (symbol == kCurrencySymbol) { - fIsCustomCurrencySymbol = TRUE; + fIsCustomCurrencySymbol = true; } else if (symbol == kIntlCurrencySymbol) { - fIsCustomIntlCurrencySymbol = TRUE; + fIsCustomIntlCurrencySymbol = true; } if(symbolIn order to enable significant digits formatting, use a pattern * containing the '@' pattern character. Alternatively, - * call setSignificantDigitsUsed(TRUE). + * call setSignificantDigitsUsed(true). * *
  • In order to disable significant digits formatting, use a * pattern that does not contain the '@' pattern - * character. Alternatively, call setSignificantDigitsUsed(FALSE). + * character. Alternatively, call setSignificantDigitsUsed(false). * *
  • The number of significant digits has no effect on parsing. * @@ -817,8 +817,8 @@ class U_I18N_API DecimalFormat : public NumberFormat { /** * Sets whether lenient parsing should be enabled (it is off by default). * - * @param enable \c TRUE if lenient parsing should be used, - * \c FALSE otherwise. + * @param enable \c true if lenient parsing should be used, + * \c false otherwise. * @stable ICU 4.8 */ void setLenient(UBool enable) U_OVERRIDE; @@ -1507,7 +1507,7 @@ class U_I18N_API DecimalFormat : public NumberFormat { /** * Return whether or not scientific notation is used. - * @return TRUE if this object formats and parses scientific notation + * @return true if this object formats and parses scientific notation * @see #setScientificNotation * @see #getMinimumExponentDigits * @see #setMinimumExponentDigits @@ -1523,7 +1523,7 @@ class U_I18N_API DecimalFormat : public NumberFormat { * maximum number of integer digits is set to more than 8, the effective * maximum will be 1. This allows this call to generate a 'default' scientific * number format without additional changes. - * @param useScientific TRUE if this object formats and parses scientific + * @param useScientific true if this object formats and parses scientific * notation * @see #isScientificNotation * @see #getMinimumExponentDigits @@ -1562,7 +1562,7 @@ class U_I18N_API DecimalFormat : public NumberFormat { /** * Return whether the exponent sign is always shown. - * @return TRUE if the exponent is always prefixed with either the + * @return true if the exponent is always prefixed with either the * localized minus sign or the localized plus sign, false if only negative * exponents are prefixed with the localized minus sign. * @see #setScientificNotation @@ -1577,7 +1577,7 @@ class U_I18N_API DecimalFormat : public NumberFormat { /** * Set whether the exponent sign is always shown. This has no effect * unless scientific notation is in use. - * @param expSignAlways TRUE if the exponent is always prefixed with either + * @param expSignAlways true if the exponent is always prefixed with either * the localized minus sign or the localized plus sign, false if only * negative exponents are prefixed with the localized minus sign. * @see #setScientificNotation @@ -1674,8 +1674,15 @@ class U_I18N_API DecimalFormat : public NumberFormat { int32_t getMinimumGroupingDigits() const; /** - * Sets the minimum grouping digits. Setting to a value less than or - * equal to 1 turns off minimum grouping digits. + * Sets the minimum grouping digits. Setting the value to + * - 1: Turns off minimum grouping digits. + * - 0 or -1: The behavior is undefined. + * - UNUM_MINIMUM_GROUPING_DIGITS_AUTO: Display grouping using the default + * strategy for all locales. + * - UNUM_MINIMUM_GROUPING_DIGITS_MIN2: Display grouping using locale + * defaults, except do not show grouping on values smaller than 10000 + * (such that there is a minimum of two digits before the first + * separator). * * For more control over grouping strategies, use NumberFormatter. * @@ -1689,7 +1696,7 @@ class U_I18N_API DecimalFormat : public NumberFormat { * Allows you to get the behavior of the decimal separator with integers. * (The decimal separator will always appear with decimals.) * - * @return TRUE if the decimal separator always appear with decimals. + * @return true if the decimal separator always appear with decimals. * Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345 * @stable ICU 2.0 */ @@ -1699,7 +1706,7 @@ class U_I18N_API DecimalFormat : public NumberFormat { * Allows you to set the behavior of the decimal separator with integers. * (The decimal separator will always appear with decimals.) * - * @param newValue set TRUE if the decimal separator will always appear with decimals. + * @param newValue set true if the decimal separator will always appear with decimals. * Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345 * @stable ICU 2.0 */ @@ -1708,7 +1715,7 @@ class U_I18N_API DecimalFormat : public NumberFormat { /** * Allows you to get the parse behavior of the pattern decimal mark. * - * @return TRUE if input must contain a match to decimal mark in pattern + * @return true if input must contain a match to decimal mark in pattern * @stable ICU 54 */ UBool isDecimalPatternMatchRequired(void) const; @@ -1716,10 +1723,10 @@ class U_I18N_API DecimalFormat : public NumberFormat { /** * Allows you to set the parse behavior of the pattern decimal mark. * - * if TRUE, the input must have a decimal mark if one was specified in the pattern. When - * FALSE the decimal mark may be omitted from the input. + * if true, the input must have a decimal mark if one was specified in the pattern. When + * false the decimal mark may be omitted from the input. * - * @param newValue set TRUE if input must contain a match to decimal mark in pattern + * @param newValue set true if input must contain a match to decimal mark in pattern * @stable ICU 54 */ virtual void setDecimalPatternMatchRequired(UBool newValue); @@ -1962,7 +1969,7 @@ class U_I18N_API DecimalFormat : public NumberFormat { * to one. If the maximum significant digits count is less than * min, then it is set to min. * This function also enables the use of significant digits - * by this formatter - areSignificantDigitsUsed() will return TRUE. + * by this formatter - areSignificantDigitsUsed() will return true. * @see #areSignificantDigitsUsed * @param min the fewest significant digits to be shown * @stable ICU 3.0 @@ -1975,7 +1982,7 @@ class U_I18N_API DecimalFormat : public NumberFormat { * to one. If the minimum significant digits count is greater * than max, then it is set to max. * This function also enables the use of significant digits - * by this formatter - areSignificantDigitsUsed() will return TRUE. + * by this formatter - areSignificantDigitsUsed() will return true. * @see #areSignificantDigitsUsed * @param max the most significant digits to be shown * @stable ICU 3.0 diff --git a/deps/icu-small/source/i18n/unicode/dtfmtsym.h b/deps/icu-small/source/i18n/unicode/dtfmtsym.h index f9ec88272b2b5ce26a0ffd9b54cd135a35cbf848..f368eaef551434afacbeb27b6d3879a11a9fe635 100644 --- a/deps/icu-small/source/i18n/unicode/dtfmtsym.h +++ b/deps/icu-small/source/i18n/unicode/dtfmtsym.h @@ -919,7 +919,8 @@ private: * failure code upon return. * @param useLastResortData determine if use last resort data */ - void initializeData(const Locale& locale, const char *type, UErrorCode& status, UBool useLastResortData = FALSE); + void initializeData(const Locale& locale, const char *type, + UErrorCode& status, UBool useLastResortData = false); /** * Copy or alias an array in another object, as appropriate. @@ -983,12 +984,12 @@ private: static UDateFormatField U_EXPORT2 getPatternCharIndex(char16_t c); /** - * Returns TRUE if f (with its pattern character repeated count times) is a numeric field. + * Returns true if f (with its pattern character repeated count times) is a numeric field. */ static UBool U_EXPORT2 isNumericField(UDateFormatField f, int32_t count); /** - * Returns TRUE if c (repeated count times) is the pattern character for a numeric field. + * Returns true if c (repeated count times) is the pattern character for a numeric field. */ static UBool U_EXPORT2 isNumericPatternChar(char16_t c, int32_t count); public: diff --git a/deps/icu-small/source/i18n/unicode/dtitvfmt.h b/deps/icu-small/source/i18n/unicode/dtitvfmt.h index 4e4d712b4f5b5cc7b4ce24bfc036d177d8d9f76d..4a1ab801a04c9db51f19cd7aa94018847a0ff9ce 100644 --- a/deps/icu-small/source/i18n/unicode/dtitvfmt.h +++ b/deps/icu-small/source/i18n/unicode/dtitvfmt.h @@ -31,6 +31,7 @@ #include "unicode/dtitvinf.h" #include "unicode/dtptngen.h" #include "unicode/formattedvalue.h" +#include "unicode/udisplaycontext.h" U_NAMESPACE_BEGIN @@ -651,6 +652,34 @@ public: */ virtual void setTimeZone(const TimeZone& zone); +#ifndef U_FORCE_HIDE_DRAFT_API + /** + * Set a particular UDisplayContext value in the formatter, such as + * UDISPCTX_CAPITALIZATION_FOR_STANDALONE. This causes the formatted + * result to be capitalized appropriately for the context in which + * it is intended to be used, considering both the locale and the + * type of field at the beginning of the formatted result. + * @param value The UDisplayContext value to set. + * @param status Input/output status. If at entry this indicates a failure + * status, the function will do nothing; otherwise this will be + * updated with any new status from the function. + * @draft ICU 68 + */ + virtual void setContext(UDisplayContext value, UErrorCode& status); + + /** + * Get the formatter's UDisplayContext value for the specified UDisplayContextType, + * such as UDISPCTX_TYPE_CAPITALIZATION. + * @param type The UDisplayContextType whose value to return + * @param status Input/output status. If at entry this indicates a failure + * status, the function will do nothing; otherwise this will be + * updated with any new status from the function. + * @return The UDisplayContextValue for the specified type. + * @draft ICU 68 + */ + virtual UDisplayContext getContext(UDisplayContextType type, UErrorCode& status) const; +#endif // U_FORCE_HIDE_DRAFT_API + /** * Return the class ID for this class. This is useful only for comparing to * a return value from getDynamicClassID(). For example: @@ -796,7 +825,7 @@ private: * to be formatted into date interval string * @param toCalendar calendar set to the to date in date interval * to be formatted into date interval string - * @param fromToOnSameDay TRUE iff from and to dates are on the same day + * @param fromToOnSameDay true iff from and to dates are on the same day * (any difference is in ampm/hours or below) * @param appendTo Output parameter to receive result. * Result is appended to existing contents. @@ -867,6 +896,19 @@ private: + /** + * Converts special hour metacharacters (such as 'j') in the skeleton into locale-appropriate + * pattern characters. + * + * + * @param skeleton The skeleton to convert + * @return A copy of the skeleton, which "j" and any other special hour metacharacters converted to the regular ones. + * + */ + UnicodeString normalizeHourMetacharacters(const UnicodeString& skeleton) const; + + + /** * get separated date and time skeleton from a combined skeleton. * @@ -919,8 +961,8 @@ private: * @param dateSkeleton normalized date skeleton * @param timeSkeleton normalized time skeleton * @return whether the resource is found for the skeleton. - * TRUE if interval pattern found for the skeleton, - * FALSE otherwise. + * true if interval pattern found for the skeleton, + * false otherwise. */ UBool setSeparateDateTimePtn(const UnicodeString& dateSkeleton, const UnicodeString& timeSkeleton); @@ -948,8 +990,8 @@ private: * @param extendedBestSkeleton extended best match skeleton * @return whether the interval pattern is found * through extending skeleton or not. - * TRUE if interval pattern is found by - * extending skeleton, FALSE otherwise. + * true if interval pattern is found by + * extending skeleton, false otherwise. */ UBool setIntervalPattern(UCalendarDateFields field, const UnicodeString* skeleton, @@ -984,6 +1026,7 @@ private: * @param differenceInfo the difference between 2 skeletons * 1 means only field width differs * 2 means v/z exchange + * @param suppressDayPeriodField if true, remove the day period field from the pattern, if there is one * @param adjustedIntervalPattern adjusted interval pattern */ static void U_EXPORT2 adjustFieldWidth( @@ -991,8 +1034,20 @@ private: const UnicodeString& bestMatchSkeleton, const UnicodeString& bestMatchIntervalPattern, int8_t differenceInfo, + UBool suppressDayPeriodField, UnicodeString& adjustedIntervalPattern); + /** + * Does the same thing as UnicodeString::findAndReplace(), except that it won't perform + * the substitution inside quoted literal text. + * @param targetString The string to perform the find-replace operation on. + * @param strToReplace The string to search for and replace in the target string. + * @param strToReplaceWith The string to substitute in wherever `stringToReplace` was found. + */ + static void U_EXPORT2 findReplaceInPattern(UnicodeString& targetString, + const UnicodeString& strToReplace, + const UnicodeString& strToReplaceWith); + /** * Concat a single date pattern with a time interval pattern, * set it into the intervalPatterns, while field is time field. @@ -1137,6 +1192,11 @@ private: UnicodeString* fDatePattern; UnicodeString* fTimePattern; UnicodeString* fDateTimeFormat; + + /** + * Other formatting information + */ + UDisplayContext fCapitalizationContext; }; inline UBool diff --git a/deps/icu-small/source/i18n/unicode/dtitvinf.h b/deps/icu-small/source/i18n/unicode/dtitvinf.h index 50e19abb4ce2cbd85ca48c63f7a7b6fa04fd570d..8452614bfb8d87fd72c8f7f988ddaa8a28d3f162 100644 --- a/deps/icu-small/source/i18n/unicode/dtitvinf.h +++ b/deps/icu-small/source/i18n/unicode/dtitvinf.h @@ -307,8 +307,8 @@ public: /** Get default order -- whether the first date in pattern is later date or not. - * return default date ordering in interval pattern. TRUE if the first date - * in pattern is later date, FALSE otherwise. + * return default date ordering in interval pattern. true if the first date + * in pattern is later date, false otherwise. * @stable ICU 4.0 */ UBool getDefaultOrder() const; diff --git a/deps/icu-small/source/i18n/unicode/dtptngen.h b/deps/icu-small/source/i18n/unicode/dtptngen.h index f79c6d45dc6b2967f1f5ab85c6c21274cbfa40b4..dab7dcfb3dc61acbafcd610da96cda260c941dba 100644 --- a/deps/icu-small/source/i18n/unicode/dtptngen.h +++ b/deps/icu-small/source/i18n/unicode/dtptngen.h @@ -76,6 +76,13 @@ public: #ifndef U_HIDE_INTERNAL_API + /** + * For ICU use only. Skips loading the standard date/time patterns (which is done via DateFormat). + * + * @internal + */ + static DateTimePatternGenerator* U_EXPORT2 createInstanceNoStdPat(const Locale& uLocale, UErrorCode& status); + /** * For ICU use only * @@ -485,7 +492,6 @@ public: #if !UCONFIG_NO_FORMATTING -#ifndef U_HIDE_DRAFT_API /** * Get the default hour cycle for a locale. Uses the locale that the * DateTimePatternGenerator was initially created with. @@ -496,10 +502,9 @@ public: * which must not indicate a failure before the function call. * Set to U_UNSUPPORTED_ERROR if used on an empty instance. * @return the default hour cycle. - * @draft ICU 67 + * @stable ICU 67 */ UDateFormatHourCycle getDefaultHourCycle(UErrorCode& status) const; -#endif /* U_HIDE_DRAFT_API */ #endif /* #if !UCONFIG_NO_FORMATTING */ @@ -526,7 +531,7 @@ private: /** * Constructor. */ - DateTimePatternGenerator(const Locale& locale, UErrorCode & status); + DateTimePatternGenerator(const Locale& locale, UErrorCode & status, UBool skipStdPatterns = false); /** * Copy constructor. @@ -573,7 +578,7 @@ private: // with #13183, no longer need flags for b, B }; - void initData(const Locale &locale, UErrorCode &status); + void initData(const Locale &locale, UErrorCode &status, UBool skipStdPatterns = false); void addCanonicalItems(UErrorCode &status); void addICUPatterns(const Locale& locale, UErrorCode& status); void hackTimes(const UnicodeString& hackPattern, UErrorCode& status); diff --git a/deps/icu-small/source/i18n/unicode/fieldpos.h b/deps/icu-small/source/i18n/unicode/fieldpos.h index c9849d67a37d29da40dc9c3d37ed173ad06b7846..6c28d2d3159b66766e4b0fac5472f353aed44a14 100644 --- a/deps/icu-small/source/i18n/unicode/fieldpos.h +++ b/deps/icu-small/source/i18n/unicode/fieldpos.h @@ -161,7 +161,7 @@ public: /** * Equality operator. * @param that the object to be compared with. - * @return TRUE if the two field positions are equal, FALSE otherwise. + * @return true if the two field positions are equal, false otherwise. * @stable ICU 2.0 */ UBool operator==(const FieldPosition& that) const; @@ -169,7 +169,7 @@ public: /** * Equality operator. * @param that the object to be compared with. - * @return TRUE if the two field positions are not equal, FALSE otherwise. + * @return true if the two field positions are not equal, false otherwise. * @stable ICU 2.0 */ UBool operator!=(const FieldPosition& that) const; diff --git a/deps/icu-small/source/i18n/unicode/fmtable.h b/deps/icu-small/source/i18n/unicode/fmtable.h index 7bec4f6906e7ee4e1de0e8eb26192115a0796c6f..3a090393ac4bec545e768af6cfb4263e7f4242ce 100644 --- a/deps/icu-small/source/i18n/unicode/fmtable.h +++ b/deps/icu-small/source/i18n/unicode/fmtable.h @@ -179,7 +179,7 @@ public: /** * Equality comparison. * @param other the object to be compared with. - * @return TRUE if other are equal to this, FALSE otherwise. + * @return true if other are equal to this, false otherwise. * @stable ICU 2.0 */ UBool operator==(const Formattable &other) const; @@ -187,7 +187,7 @@ public: /** * Equality operator. * @param other the object to be compared with. - * @return TRUE if other are unequal to this, FALSE otherwise. + * @return true if other are unequal to this, false otherwise. * @stable ICU 2.0 */ UBool operator!=(const Formattable& other) const @@ -277,9 +277,9 @@ public: Type getType(void) const; /** - * Returns TRUE if the data type of this Formattable object + * Returns true if the data type of this Formattable object * is kDouble, kLong, or kInt64 - * @return TRUE if this is a pure numeric object + * @return true if this is a pure numeric object * @stable ICU 3.0 */ UBool isNumeric() const; diff --git a/deps/icu-small/source/i18n/unicode/formattedvalue.h b/deps/icu-small/source/i18n/unicode/formattedvalue.h index 4469b6328e7cb9bdd6306f96462e9ec02c6d29f4..f4e588d01cbddf48c7948439a46b21fc9abab982 100644 --- a/deps/icu-small/source/i18n/unicode/formattedvalue.h +++ b/deps/icu-small/source/i18n/unicode/formattedvalue.h @@ -116,7 +116,7 @@ class U_I18N_API ConstrainedFieldPosition : public UMemory { * Gets the field category for the current position. * * The return value is well-defined only after - * FormattedValue#nextPosition returns TRUE. + * FormattedValue#nextPosition returns true. * * @return The field category saved in the instance. * @stable ICU 64 @@ -129,7 +129,7 @@ class U_I18N_API ConstrainedFieldPosition : public UMemory { * Gets the field for the current position. * * The return value is well-defined only after - * FormattedValue#nextPosition returns TRUE. + * FormattedValue#nextPosition returns true. * * @return The field saved in the instance. * @stable ICU 64 @@ -141,7 +141,7 @@ class U_I18N_API ConstrainedFieldPosition : public UMemory { /** * Gets the INCLUSIVE start index for the current position. * - * The return value is well-defined only after FormattedValue#nextPosition returns TRUE. + * The return value is well-defined only after FormattedValue#nextPosition returns true. * * @return The start index saved in the instance. * @stable ICU 64 @@ -153,7 +153,7 @@ class U_I18N_API ConstrainedFieldPosition : public UMemory { /** * Gets the EXCLUSIVE end index stored for the current position. * - * The return value is well-defined only after FormattedValue#nextPosition returns TRUE. + * The return value is well-defined only after FormattedValue#nextPosition returns true. * * @return The end index saved in the instance. * @stable ICU 64 @@ -301,8 +301,8 @@ class U_I18N_API FormattedValue /* not : public UObject because this is an inter * see ConstrainedFieldPosition#constrainCategory * and ConstrainedFieldPosition#constrainField. * @param status Set if an error occurs. - * @return TRUE if a new occurrence of the field was found; - * FALSE otherwise or if an error was set. + * @return true if a new occurrence of the field was found; + * false otherwise or if an error was set. * * @stable ICU 64 */ diff --git a/deps/icu-small/source/i18n/unicode/fpositer.h b/deps/icu-small/source/i18n/unicode/fpositer.h index ba2a838315c7cb65ee6495503bd0e9cc964f9784..35aa5da20f2cfaa9dbdb139d1b5b21dc5de4684e 100644 --- a/deps/icu-small/source/i18n/unicode/fpositer.h +++ b/deps/icu-small/source/i18n/unicode/fpositer.h @@ -96,7 +96,7 @@ public: /** * If the current position is valid, updates the FieldPosition values, advances the iterator, - * and returns TRUE, otherwise returns FALSE. + * and returns true, otherwise returns false. * @stable ICU 4.4 */ UBool next(FieldPosition& fp); diff --git a/deps/icu-small/source/i18n/unicode/gregocal.h b/deps/icu-small/source/i18n/unicode/gregocal.h index 236bd003c160a6df43c30959ca983949048263ff..139258d822a30ca7228a3ada9dd301bd9a254cf7 100644 --- a/deps/icu-small/source/i18n/unicode/gregocal.h +++ b/deps/icu-small/source/i18n/unicode/gregocal.h @@ -344,7 +344,7 @@ public: UBool isLeapYear(int32_t year) const; /** - * Returns TRUE if the given Calendar object is equivalent to this + * Returns true if the given Calendar object is equivalent to this * one. Calendar override. * * @param other the Calendar to be compared with this Calendar @@ -756,7 +756,7 @@ public: public: // internal implementation /** - * @return TRUE if this calendar has the notion of a default century + * @return true if this calendar has the notion of a default century * @internal */ virtual UBool haveDefaultCentury() const; diff --git a/deps/icu-small/source/i18n/unicode/listformatter.h b/deps/icu-small/source/i18n/unicode/listformatter.h index a969a8744dcf586ba76bdfc48d8da417d6a4a160..3cc750c83874991f5e8d6815d39fe4f0efc26cbf 100644 --- a/deps/icu-small/source/i18n/unicode/listformatter.h +++ b/deps/icu-small/source/i18n/unicode/listformatter.h @@ -23,6 +23,8 @@ #if U_SHOW_CPLUSPLUS_API +#if !UCONFIG_NO_FORMATTING + #include "unicode/unistr.h" #include "unicode/locid.h" #include "unicode/formattedvalue.h" @@ -65,7 +67,6 @@ struct ListFormatData : public UMemory { */ -#if !UCONFIG_NO_FORMATTING /** * An immutable class containing the result of a list formatting operation. * @@ -135,7 +136,6 @@ class U_I18N_API FormattedList : public UMemory, public FormattedValue { : fData(nullptr), fErrorCode(errorCode) {} friend class ListFormatter; }; -#endif // !UCONFIG_NO_FORMATTING /** @@ -185,8 +185,6 @@ class U_I18N_API ListFormatter : public UObject{ */ static ListFormatter* createInstance(const Locale& locale, UErrorCode& errorCode); -#ifndef U_HIDE_DRAFT_API -#if !UCONFIG_NO_FORMATTING /** * Creates a ListFormatter for the given locale, list type, and style. * @@ -195,28 +193,10 @@ class U_I18N_API ListFormatter : public UObject{ * @param width The width of formatting to use. * @param errorCode ICU error code, set if no data available for the given locale. * @return A ListFormatter object created from internal data derived from CLDR data. - * @draft ICU 67 + * @stable ICU 67 */ static ListFormatter* createInstance( const Locale& locale, UListFormatterType type, UListFormatterWidth width, UErrorCode& errorCode); -#endif /* !UCONFIG_NO_FORMATTING */ -#endif /* U_HIDE_DRAFT_API */ - -#ifndef U_HIDE_INTERNAL_API - /** - * Creates a ListFormatter appropriate for a locale and style. - * - * TODO(ICU-20888): Remove this in ICU 68. - * - * @param locale The locale. - * @param style the style, either "standard", "or", "unit", "unit-narrow", or "unit-short" - * @param errorCode ICU error code, set if no data available for the given locale. - * @return A ListFormatter object created from internal data derived from - * CLDR data. - * @internal - */ - static ListFormatter* createInstance(const Locale& locale, const char* style, UErrorCode& errorCode); -#endif /* U_HIDE_INTERNAL_API */ /** * Destructor. @@ -239,7 +219,6 @@ class U_I18N_API ListFormatter : public UObject{ UnicodeString& format(const UnicodeString items[], int32_t n_items, UnicodeString& appendTo, UErrorCode& errorCode) const; -#if !UCONFIG_NO_FORMATTING /** * Formats a list of strings to a FormattedList, which exposes field * position information. The FormattedList contains more information than @@ -255,7 +234,6 @@ class U_I18N_API ListFormatter : public UObject{ const UnicodeString items[], int32_t n_items, UErrorCode& errorCode) const; -#endif // !UCONFIG_NO_FORMATTING #ifndef U_HIDE_INTERNAL_API /** @@ -279,6 +257,15 @@ class U_I18N_API ListFormatter : public UObject{ #endif /* U_HIDE_INTERNAL_API */ private: + + /** + * Creates a ListFormatter appropriate for a locale and style. + * + * @param locale The locale. + * @param style the style, either "standard", "or", "unit", "unit-narrow", or "unit-short" + */ + static ListFormatter* createInstance(const Locale& locale, const char* style, UErrorCode& errorCode); + static void initializeHash(UErrorCode& errorCode); static const ListFormatInternal* getListFormatInternal(const Locale& locale, const char *style, UErrorCode& errorCode); struct ListPatternsSink; @@ -296,6 +283,8 @@ class U_I18N_API ListFormatter : public UObject{ U_NAMESPACE_END +#endif /* #if !UCONFIG_NO_FORMATTING */ + #endif /* U_SHOW_CPLUSPLUS_API */ #endif // __LISTFORMATTER_H__ diff --git a/deps/icu-small/source/i18n/unicode/measfmt.h b/deps/icu-small/source/i18n/unicode/measfmt.h index 8f73de87fa55d63c2500fdc6e4f6b7202b21380a..f48dada2abf02af6d6d8f3060e147a71ee191b34 100644 --- a/deps/icu-small/source/i18n/unicode/measfmt.h +++ b/deps/icu-small/source/i18n/unicode/measfmt.h @@ -91,7 +91,8 @@ class DateFormat; /** *

    IMPORTANT: New users are strongly encouraged to see if * numberformatter.h fits their use case. Although not deprecated, this header - * is provided for backwards compatibility only. + * is provided for backwards compatibility only, and has much more limited + * capabilities. * * @see Format * @author Alan Liu @@ -309,7 +310,7 @@ class U_I18N_API MeasureFormat : public Format { /** * ICU use only. * Allows subclass to change locale. Note that this method also changes - * the NumberFormat object. Returns TRUE if locale changed; FALSE if no + * the NumberFormat object. Returns true if locale changed; false if no * change was made. * @internal. */ diff --git a/deps/icu-small/source/i18n/unicode/measunit.h b/deps/icu-small/source/i18n/unicode/measunit.h index 8b65497e12eb63f3d3b1d33bf54f26188996b9ac..0985ba0706eaa44a0c16081af81ad96ece8ed994 100644 --- a/deps/icu-small/source/i18n/unicode/measunit.h +++ b/deps/icu-small/source/i18n/unicode/measunit.h @@ -30,201 +30,333 @@ U_NAMESPACE_BEGIN class StringEnumeration; -struct MeasureUnitImpl; +class MeasureUnitImpl; + +namespace number { +namespace impl { +class LongNameHandler; +} +} // namespace number -#ifndef U_HIDE_DRAFT_API /** * Enumeration for unit complexity. There are three levels: * - * - SINGLE: A single unit, optionally with a power and/or SI prefix. Examples: hectare, - * square-kilometer, kilojoule, per-second. + * - SINGLE: A single unit, optionally with a power and/or SI or binary prefix. + * Examples: hectare, square-kilometer, kilojoule, per-second, mebibyte. * - COMPOUND: A unit composed of the product of multiple single units. Examples: * meter-per-second, kilowatt-hour, kilogram-meter-per-square-second. * - MIXED: A unit composed of the sum of multiple single units. Examples: foot+inch, * hour+minute+second, degree+arcminute+arcsecond. * * The complexity determines which operations are available. For example, you cannot set the power - * or SI prefix of a compound unit. + * or prefix of a compound unit. * - * @draft ICU 67 + * @stable ICU 67 */ enum UMeasureUnitComplexity { /** * A single unit, like kilojoule. * - * @draft ICU 67 + * @stable ICU 67 */ UMEASURE_UNIT_SINGLE, /** * A compound unit, like meter-per-second. * - * @draft ICU 67 + * @stable ICU 67 */ UMEASURE_UNIT_COMPOUND, /** * A mixed unit, like hour+minute. * - * @draft ICU 67 + * @stable ICU 67 */ UMEASURE_UNIT_MIXED }; + +#ifndef U_HIDE_DRAFT_API /** - * Enumeration for SI prefixes, such as "kilo". + * Enumeration for SI and binary prefixes, e.g. "kilo-", "nano-", "mebi-". + * + * Enum values should be treated as opaque: use umeas_getPrefixPower() and + * umeas_getPrefixBase() to find their corresponding values. * - * @draft ICU 67 + * @draft ICU 69 + * @see umeas_getPrefixBase + * @see umeas_getPrefixPower */ -typedef enum UMeasureSIPrefix { +typedef enum UMeasurePrefix { + /** + * The absence of an SI or binary prefix. + * + * The integer representation of this enum value is an arbitrary + * implementation detail and should not be relied upon: use + * umeas_getPrefixPower() to obtain meaningful values. + * + * @draft ICU 69 + */ + UMEASURE_PREFIX_ONE = 30 + 0, /** * SI prefix: yotta, 10^24. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_YOTTA = 24, + UMEASURE_PREFIX_YOTTA = UMEASURE_PREFIX_ONE + 24, + + /** + * ICU use only. + * Used to determine the set of base-10 SI prefixes. + * @internal + */ + UMEASURE_PREFIX_INTERNAL_MAX_SI = UMEASURE_PREFIX_YOTTA, /** * SI prefix: zetta, 10^21. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_ZETTA = 21, + UMEASURE_PREFIX_ZETTA = UMEASURE_PREFIX_ONE + 21, /** * SI prefix: exa, 10^18. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_EXA = 18, + UMEASURE_PREFIX_EXA = UMEASURE_PREFIX_ONE + 18, /** * SI prefix: peta, 10^15. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_PETA = 15, + UMEASURE_PREFIX_PETA = UMEASURE_PREFIX_ONE + 15, /** * SI prefix: tera, 10^12. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_TERA = 12, + UMEASURE_PREFIX_TERA = UMEASURE_PREFIX_ONE + 12, /** * SI prefix: giga, 10^9. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_GIGA = 9, + UMEASURE_PREFIX_GIGA = UMEASURE_PREFIX_ONE + 9, /** * SI prefix: mega, 10^6. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_MEGA = 6, + UMEASURE_PREFIX_MEGA = UMEASURE_PREFIX_ONE + 6, /** * SI prefix: kilo, 10^3. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_KILO = 3, + UMEASURE_PREFIX_KILO = UMEASURE_PREFIX_ONE + 3, /** * SI prefix: hecto, 10^2. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_HECTO = 2, + UMEASURE_PREFIX_HECTO = UMEASURE_PREFIX_ONE + 2, /** * SI prefix: deka, 10^1. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_DEKA = 1, - - /** - * The absence of an SI prefix. - * - * @draft ICU 67 - */ - UMEASURE_SI_PREFIX_ONE = 0, + UMEASURE_PREFIX_DEKA = UMEASURE_PREFIX_ONE + 1, /** * SI prefix: deci, 10^-1. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_DECI = -1, + UMEASURE_PREFIX_DECI = UMEASURE_PREFIX_ONE + -1, /** * SI prefix: centi, 10^-2. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_CENTI = -2, + UMEASURE_PREFIX_CENTI = UMEASURE_PREFIX_ONE + -2, /** * SI prefix: milli, 10^-3. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_MILLI = -3, + UMEASURE_PREFIX_MILLI = UMEASURE_PREFIX_ONE + -3, /** * SI prefix: micro, 10^-6. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_MICRO = -6, + UMEASURE_PREFIX_MICRO = UMEASURE_PREFIX_ONE + -6, /** * SI prefix: nano, 10^-9. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_NANO = -9, + UMEASURE_PREFIX_NANO = UMEASURE_PREFIX_ONE + -9, /** * SI prefix: pico, 10^-12. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_PICO = -12, + UMEASURE_PREFIX_PICO = UMEASURE_PREFIX_ONE + -12, /** * SI prefix: femto, 10^-15. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_FEMTO = -15, + UMEASURE_PREFIX_FEMTO = UMEASURE_PREFIX_ONE + -15, /** * SI prefix: atto, 10^-18. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_ATTO = -18, + UMEASURE_PREFIX_ATTO = UMEASURE_PREFIX_ONE + -18, /** * SI prefix: zepto, 10^-21. * - * @draft ICU 67 + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_ZEPTO = -21, + UMEASURE_PREFIX_ZEPTO = UMEASURE_PREFIX_ONE + -21, /** * SI prefix: yocto, 10^-24. * - * @draft ICU 67 + * @draft ICU 69 + */ + UMEASURE_PREFIX_YOCTO = UMEASURE_PREFIX_ONE + -24, + +#ifndef U_HIDE_INTERNAL_API + /** + * ICU use only. + * Used to determine the set of base-10 SI prefixes. + * @internal + */ + UMEASURE_PREFIX_INTERNAL_MIN_SI = UMEASURE_PREFIX_YOCTO, +#endif // U_HIDE_INTERNAL_API + + // Cannot conditionalize the following with #ifndef U_HIDE_INTERNAL_API, + // used in definitions of non-internal enum values + /** + * ICU use only. + * Sets the arbitrary offset of the base-1024 binary prefixes' enum values. + * @internal + */ + UMEASURE_PREFIX_INTERNAL_ONE_BIN = -60, + + /** + * Binary prefix: kibi, 1024^1. + * + * @draft ICU 69 + */ + UMEASURE_PREFIX_KIBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 1, + +#ifndef U_HIDE_INTERNAL_API + /** + * ICU use only. + * Used to determine the set of base-1024 binary prefixes. + * @internal + */ + UMEASURE_PREFIX_INTERNAL_MIN_BIN = UMEASURE_PREFIX_KIBI, +#endif // U_HIDE_INTERNAL_API + + /** + * Binary prefix: mebi, 1024^2. + * + * @draft ICU 69 + */ + UMEASURE_PREFIX_MEBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 2, + + /** + * Binary prefix: gibi, 1024^3. + * + * @draft ICU 69 + */ + UMEASURE_PREFIX_GIBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 3, + + /** + * Binary prefix: tebi, 1024^4. + * + * @draft ICU 69 + */ + UMEASURE_PREFIX_TEBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 4, + + /** + * Binary prefix: pebi, 1024^5. + * + * @draft ICU 69 + */ + UMEASURE_PREFIX_PEBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 5, + + /** + * Binary prefix: exbi, 1024^6. + * + * @draft ICU 69 + */ + UMEASURE_PREFIX_EXBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 6, + + /** + * Binary prefix: zebi, 1024^7. + * + * @draft ICU 69 + */ + UMEASURE_PREFIX_ZEBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 7, + + /** + * Binary prefix: yobi, 1024^8. + * + * @draft ICU 69 */ - UMEASURE_SI_PREFIX_YOCTO = -24 -} UMeasureSIPrefix; + UMEASURE_PREFIX_YOBI = UMEASURE_PREFIX_INTERNAL_ONE_BIN + 8, + +#ifndef U_HIDE_INTERNAL_API + /** + * ICU use only. + * Used to determine the set of base-1024 binary prefixes. + * @internal + */ + UMEASURE_PREFIX_INTERNAL_MAX_BIN = UMEASURE_PREFIX_YOBI, +#endif // U_HIDE_INTERNAL_API +} UMeasurePrefix; + +/** + * Returns the base of the factor associated with the given unit prefix: the + * base is 10 for SI prefixes (kilo, micro) and 1024 for binary prefixes (kibi, + * mebi). + * + * @draft ICU 69 + */ +U_CAPI int32_t U_EXPORT2 umeas_getPrefixBase(UMeasurePrefix unitPrefix); + +/** + * Returns the exponent of the factor associated with the given unit prefix, for + * example 3 for kilo, -6 for micro, 1 for kibi, 2 for mebi, 3 for gibi. + * + * @draft ICU 69 + */ +U_CAPI int32_t U_EXPORT2 umeas_getPrefixPower(UMeasurePrefix unitPrefix); + #endif // U_HIDE_DRAFT_API /** @@ -250,27 +382,26 @@ class U_I18N_API MeasureUnit: public UObject { */ MeasureUnit(const MeasureUnit &other); -#ifndef U_HIDE_DRAFT_API /** * Move constructor. - * @draft ICU 67 + * @stable ICU 67 */ MeasureUnit(MeasureUnit &&other) noexcept; /** - * Construct a MeasureUnit from a CLDR Unit Identifier, defined in UTS 35. - * Validates and canonicalizes the identifier. + * Construct a MeasureUnit from a CLDR Core Unit Identifier, defined in UTS + * 35. (Core unit identifiers and mixed unit identifiers are supported, long + * unit identifiers are not.) Validates and canonicalizes the identifier. * *

          * MeasureUnit example = MeasureUnit::forIdentifier("furlong-per-nanosecond")
          * 
    * - * @param identifier The CLDR Unit Identifier + * @param identifier The CLDR Unit Identifier. * @param status Set if the identifier is invalid. - * @draft ICU 67 + * @stable ICU 67 */ static MeasureUnit forIdentifier(StringPiece identifier, UErrorCode& status); -#endif // U_HIDE_DRAFT_API /** * Copy assignment operator. @@ -278,13 +409,11 @@ class U_I18N_API MeasureUnit: public UObject { */ MeasureUnit &operator=(const MeasureUnit &other); -#ifndef U_HIDE_DRAFT_API /** * Move assignment operator. - * @draft ICU 67 + * @stable ICU 67 */ MeasureUnit &operator=(MeasureUnit &&other) noexcept; -#endif // U_HIDE_DRAFT_API /** * Returns a polymorphic clone of this object. The result will @@ -333,12 +462,11 @@ class U_I18N_API MeasureUnit: public UObject { */ const char *getSubtype() const; -#ifndef U_HIDE_DRAFT_API /** - * Get the CLDR Unit Identifier for this MeasureUnit, as defined in UTS 35. + * Get CLDR Unit Identifier for this MeasureUnit, as defined in UTS 35. * * @return The string form of this unit, owned by this MeasureUnit. - * @draft ICU 67 + * @stable ICU 67 */ const char* getIdentifier() const; @@ -347,38 +475,43 @@ class U_I18N_API MeasureUnit: public UObject { * * @param status Set if an error occurs. * @return The unit complexity. - * @draft ICU 67 + * @stable ICU 67 */ UMeasureUnitComplexity getComplexity(UErrorCode& status) const; +#ifndef U_HIDE_DRAFT_API /** - * Creates a MeasureUnit which is this SINGLE unit augmented with the specified SI prefix. - * For example, UMEASURE_SI_PREFIX_KILO for "kilo". + * Creates a MeasureUnit which is this SINGLE unit augmented with the specified prefix. + * For example, UMEASURE_PREFIX_KILO for "kilo", or UMEASURE_PREFIX_KIBI for "kibi". * - * There is sufficient locale data to format all standard SI prefixes. + * There is sufficient locale data to format all standard prefixes. * * NOTE: Only works on SINGLE units. If this is a COMPOUND or MIXED unit, an error will * occur. For more information, see UMeasureUnitComplexity. * - * @param prefix The SI prefix, from UMeasureSIPrefix. + * @param prefix The prefix, from UMeasurePrefix. * @param status Set if this is not a SINGLE unit or if another error occurs. * @return A new SINGLE unit. - * @draft ICU 67 + * @draft ICU 69 */ - MeasureUnit withSIPrefix(UMeasureSIPrefix prefix, UErrorCode& status) const; + MeasureUnit withPrefix(UMeasurePrefix prefix, UErrorCode& status) const; /** - * Gets the current SI prefix of this SINGLE unit. For example, if the unit has the SI prefix - * "kilo", then UMEASURE_SI_PREFIX_KILO is returned. + * Returns the current SI or binary prefix of this SINGLE unit. For example, + * if the unit has the prefix "kilo", then UMEASURE_PREFIX_KILO is + * returned. * * NOTE: Only works on SINGLE units. If this is a COMPOUND or MIXED unit, an error will * occur. For more information, see UMeasureUnitComplexity. * * @param status Set if this is not a SINGLE unit or if another error occurs. - * @return The SI prefix of this SINGLE unit, from UMeasureSIPrefix. - * @draft ICU 67 + * @return The prefix of this SINGLE unit, from UMeasurePrefix. + * @see umeas_getPrefixBase + * @see umeas_getPrefixPower + * @draft ICU 69 */ - UMeasureSIPrefix getSIPrefix(UErrorCode& status) const; + UMeasurePrefix getPrefix(UErrorCode& status) const; +#endif // U_HIDE_DRAFT_API /** * Creates a MeasureUnit which is this SINGLE unit augmented with the specified dimensionality @@ -392,7 +525,7 @@ class U_I18N_API MeasureUnit: public UObject { * @param dimensionality The dimensionality (power). * @param status Set if this is not a SINGLE unit or if another error occurs. * @return A new SINGLE unit. - * @draft ICU 67 + * @stable ICU 67 */ MeasureUnit withDimensionality(int32_t dimensionality, UErrorCode& status) const; @@ -407,7 +540,7 @@ class U_I18N_API MeasureUnit: public UObject { * * @param status Set if this is not a SINGLE unit or if another error occurs. * @return The dimensionality (power) of this simple unit. - * @draft ICU 67 + * @stable ICU 67 */ int32_t getDimensionality(UErrorCode& status) const; @@ -421,7 +554,7 @@ class U_I18N_API MeasureUnit: public UObject { * * @param status Set if this is a MIXED unit or if another error occurs. * @return The reciprocal of the target unit. - * @draft ICU 67 + * @stable ICU 67 */ MeasureUnit reciprocal(UErrorCode& status) const; @@ -434,20 +567,19 @@ class U_I18N_API MeasureUnit: public UObject { * For example, if the receiver is "kilowatt" and the argument is "hour-per-day", then the * unit "kilowatt-hour-per-day" is returned. * - * NOTE: Only works on SINGLE and COMPOUND units. If either unit (receivee and argument) is a + * NOTE: Only works on SINGLE and COMPOUND units. If either unit (receiver and argument) is a * MIXED unit, an error will occur. For more information, see UMeasureUnitComplexity. * * @param other The MeasureUnit to multiply with the target. * @param status Set if this or other is a MIXED unit or if another error occurs. * @return The product of the target unit with the provided unit. - * @draft ICU 67 + * @stable ICU 67 */ MeasureUnit product(const MeasureUnit& other, UErrorCode& status) const; -#endif // U_HIDE_DRAFT_API -#ifndef U_HIDE_INTERNAL_API +#ifndef U_HIDE_DRAFT_API /** - * Gets the list of SINGLE units contained within a MIXED of COMPOUND unit. + * Gets the list of SINGLE units contained within a MIXED or COMPOUND unit. * * Examples: * - Given "meter-kilogram-per-second", three units will be returned: "meter", @@ -457,15 +589,12 @@ class U_I18N_API MeasureUnit: public UObject { * * If this is a SINGLE unit, an array of length 1 will be returned. * - * TODO(ICU-21021): Finalize this API and propose it as draft. - * - * @param outCount The number of elements in the return array. * @param status Set if an error occurs. - * @return An array of single units, owned by the caller. - * @internal ICU 67 Technical Preview + * @return A pair with the list of units as a LocalArray and the number of units in the list. + * @draft ICU 68 */ - LocalArray splitToSingleUnits(int32_t& outCount, UErrorCode& status) const; -#endif // U_HIDE_INTERNAL_API + inline std::pair, int32_t> splitToSingleUnits(UErrorCode& status) const; +#endif // U_HIDE_DRAFT_API /** * getAvailable gets all of the available units. @@ -540,40 +669,17 @@ class U_I18N_API MeasureUnit: public UObject { #ifndef U_HIDE_INTERNAL_API /** * ICU use only. - * Returns associated array index for this measure unit. Only valid for - * non-currency measure units. - * @internal - */ - int32_t getIndex() const; - - /** - * ICU use only. - * Returns maximum value from getIndex plus 1. - * @internal - */ - static int32_t getIndexCount(); - - /** - * ICU use only. - * @return the unit.getIndex() of the unit which has this unit.getType() and unit.getSubtype(), - * or a negative value if there is no such unit + * Returns associated array index for this measure unit. * @internal */ - static int32_t internalGetIndexForTypeAndSubtype(const char *type, const char *subtype); - - /** - * ICU use only. - * @internal - */ - static MeasureUnit resolveUnitPerUnit( - const MeasureUnit &unit, const MeasureUnit &perUnit, bool* isResolved); + int32_t getOffset() const; #endif /* U_HIDE_INTERNAL_API */ // All code between the "Start generated createXXX methods" comment and // the "End generated createXXX methods" comment is auto generated code // and must not be edited manually. For instructions on how to correctly // update this code, refer to: -// http://site.icu-project.org/design/formatting/measureformat/updating-measure-unit +// docs/processes/release/tasks/updating-measure-unit.md // // Start generated createXXX methods @@ -865,6 +971,24 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getKarat(); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of concentr: milligram-ofglucose-per-deciliter. + * Caller owns returned value and must free it. + * Also see {@link #getMilligramOfglucosePerDeciliter()}. + * @param status ICU error code. + * @draft ICU 69 + */ + static MeasureUnit *createMilligramOfglucosePerDeciliter(UErrorCode &status); + + /** + * Returns by value, unit of concentr: milligram-ofglucose-per-deciliter. + * Also see {@link #createMilligramOfglucosePerDeciliter()}. + * @draft ICU 69 + */ + static MeasureUnit getMilligramOfglucosePerDeciliter(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of concentr: milligram-per-deciliter. * Caller owns returned value and must free it. @@ -913,22 +1037,6 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getMole(); - /** - * Returns by pointer, unit of concentr: permillion. - * Caller owns returned value and must free it. - * Also see {@link #getPartPerMillion()}. - * @param status ICU error code. - * @stable ICU 57 - */ - static MeasureUnit *createPartPerMillion(UErrorCode &status); - - /** - * Returns by value, unit of concentr: permillion. - * Also see {@link #createPartPerMillion()}. - * @stable ICU 64 - */ - static MeasureUnit getPartPerMillion(); - /** * Returns by pointer, unit of concentr: percent. * Caller owns returned value and must free it. @@ -961,6 +1069,22 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getPermille(); + /** + * Returns by pointer, unit of concentr: permillion. + * Caller owns returned value and must free it. + * Also see {@link #getPartPerMillion()}. + * @param status ICU error code. + * @stable ICU 57 + */ + static MeasureUnit *createPartPerMillion(UErrorCode &status); + + /** + * Returns by value, unit of concentr: permillion. + * Also see {@link #createPartPerMillion()}. + * @stable ICU 64 + */ + static MeasureUnit getPartPerMillion(); + /** * Returns by pointer, unit of concentr: permyriad. * Caller owns returned value and must free it. @@ -1265,23 +1389,21 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getDayPerson(); -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of duration: decade. * Caller owns returned value and must free it. * Also see {@link #getDecade()}. * @param status ICU error code. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit *createDecade(UErrorCode &status); /** * Returns by value, unit of duration: decade. * Also see {@link #createDecade()}. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit getDecade(); -#endif /* U_HIDE_DRAFT_API */ /** * Returns by pointer, unit of duration: hour. @@ -1667,23 +1789,21 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getKilowattHour(); -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of energy: therm-us. * Caller owns returned value and must free it. * Also see {@link #getThermUs()}. * @param status ICU error code. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit *createThermUs(UErrorCode &status); /** * Returns by value, unit of energy: therm-us. * Also see {@link #createThermUs()}. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit getThermUs(); -#endif /* U_HIDE_DRAFT_API */ /** * Returns by pointer, unit of force: newton. @@ -1782,130 +1902,134 @@ class U_I18N_API MeasureUnit: public UObject { static MeasureUnit getMegahertz(); #ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of graphics: dot. + * Caller owns returned value and must free it. + * Also see {@link #getDot()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createDot(UErrorCode &status); + + /** + * Returns by value, unit of graphics: dot. + * Also see {@link #createDot()}. + * @draft ICU 68 + */ + static MeasureUnit getDot(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of graphics: dot-per-centimeter. * Caller owns returned value and must free it. * Also see {@link #getDotPerCentimeter()}. * @param status ICU error code. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit *createDotPerCentimeter(UErrorCode &status); /** * Returns by value, unit of graphics: dot-per-centimeter. * Also see {@link #createDotPerCentimeter()}. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit getDotPerCentimeter(); -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of graphics: dot-per-inch. * Caller owns returned value and must free it. * Also see {@link #getDotPerInch()}. * @param status ICU error code. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit *createDotPerInch(UErrorCode &status); /** * Returns by value, unit of graphics: dot-per-inch. * Also see {@link #createDotPerInch()}. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit getDotPerInch(); -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of graphics: em. * Caller owns returned value and must free it. * Also see {@link #getEm()}. * @param status ICU error code. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit *createEm(UErrorCode &status); /** * Returns by value, unit of graphics: em. * Also see {@link #createEm()}. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit getEm(); -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of graphics: megapixel. * Caller owns returned value and must free it. * Also see {@link #getMegapixel()}. * @param status ICU error code. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit *createMegapixel(UErrorCode &status); /** * Returns by value, unit of graphics: megapixel. * Also see {@link #createMegapixel()}. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit getMegapixel(); -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of graphics: pixel. * Caller owns returned value and must free it. * Also see {@link #getPixel()}. * @param status ICU error code. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit *createPixel(UErrorCode &status); /** * Returns by value, unit of graphics: pixel. * Also see {@link #createPixel()}. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit getPixel(); -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of graphics: pixel-per-centimeter. * Caller owns returned value and must free it. * Also see {@link #getPixelPerCentimeter()}. * @param status ICU error code. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit *createPixelPerCentimeter(UErrorCode &status); /** * Returns by value, unit of graphics: pixel-per-centimeter. * Also see {@link #createPixelPerCentimeter()}. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit getPixelPerCentimeter(); -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of graphics: pixel-per-inch. * Caller owns returned value and must free it. * Also see {@link #getPixelPerInch()}. * @param status ICU error code. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit *createPixelPerInch(UErrorCode &status); /** * Returns by value, unit of graphics: pixel-per-inch. * Also see {@link #createPixelPerInch()}. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit getPixelPerInch(); -#endif /* U_HIDE_DRAFT_API */ /** * Returns by pointer, unit of length: astronomical-unit. @@ -1955,6 +2079,24 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getDecimeter(); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of length: earth-radius. + * Caller owns returned value and must free it. + * Also see {@link #getEarthRadius()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createEarthRadius(UErrorCode &status); + + /** + * Returns by value, unit of length: earth-radius. + * Also see {@link #createEarthRadius()}. + * @draft ICU 68 + */ + static MeasureUnit getEarthRadius(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of length: fathom. * Caller owns returned value and must free it. @@ -2243,6 +2385,42 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getYard(); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of light: candela. + * Caller owns returned value and must free it. + * Also see {@link #getCandela()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createCandela(UErrorCode &status); + + /** + * Returns by value, unit of light: candela. + * Also see {@link #createCandela()}. + * @draft ICU 68 + */ + static MeasureUnit getCandela(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of light: lumen. + * Caller owns returned value and must free it. + * Also see {@link #getLumen()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createLumen(UErrorCode &status); + + /** + * Returns by value, unit of light: lumen. + * Also see {@link #createLumen()}. + * @draft ICU 68 + */ + static MeasureUnit getLumen(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of light: lux. * Caller owns returned value and must free it. @@ -2323,6 +2501,24 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getEarthMass(); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of mass: grain. + * Caller owns returned value and must free it. + * Also see {@link #getGrain()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createGrain(UErrorCode &status); + + /** + * Returns by value, unit of mass: grain. + * Also see {@link #createGrain()}. + * @draft ICU 68 + */ + static MeasureUnit getGrain(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of mass: gram. * Caller owns returned value and must free it. @@ -2611,23 +2807,21 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getAtmosphere(); -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of pressure: bar. * Caller owns returned value and must free it. * Also see {@link #getBar()}. * @param status ICU error code. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit *createBar(UErrorCode &status); /** * Returns by value, unit of pressure: bar. * Also see {@link #createBar()}. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit getBar(); -#endif /* U_HIDE_DRAFT_API */ /** * Returns by pointer, unit of pressure: hectopascal. @@ -2725,23 +2919,21 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getMillimeterOfMercury(); -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of pressure: pascal. * Caller owns returned value and must free it. * Also see {@link #getPascal()}. * @param status ICU error code. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit *createPascal(UErrorCode &status); /** * Returns by value, unit of pressure: pascal. * Also see {@link #createPascal()}. - * @draft ICU 65 + * @stable ICU 65 */ static MeasureUnit getPascal(); -#endif /* U_HIDE_DRAFT_API */ /** * Returns by pointer, unit of pressure: pound-force-per-square-inch. @@ -3143,6 +3335,78 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getDeciliter(); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of volume: dessert-spoon. + * Caller owns returned value and must free it. + * Also see {@link #getDessertSpoon()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createDessertSpoon(UErrorCode &status); + + /** + * Returns by value, unit of volume: dessert-spoon. + * Also see {@link #createDessertSpoon()}. + * @draft ICU 68 + */ + static MeasureUnit getDessertSpoon(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of volume: dessert-spoon-imperial. + * Caller owns returned value and must free it. + * Also see {@link #getDessertSpoonImperial()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createDessertSpoonImperial(UErrorCode &status); + + /** + * Returns by value, unit of volume: dessert-spoon-imperial. + * Also see {@link #createDessertSpoonImperial()}. + * @draft ICU 68 + */ + static MeasureUnit getDessertSpoonImperial(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of volume: dram. + * Caller owns returned value and must free it. + * Also see {@link #getDram()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createDram(UErrorCode &status); + + /** + * Returns by value, unit of volume: dram. + * Also see {@link #createDram()}. + * @draft ICU 68 + */ + static MeasureUnit getDram(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of volume: drop. + * Caller owns returned value and must free it. + * Also see {@link #getDrop()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createDrop(UErrorCode &status); + + /** + * Returns by value, unit of volume: drop. + * Also see {@link #createDrop()}. + * @draft ICU 68 + */ + static MeasureUnit getDrop(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of volume: fluid-ounce. * Caller owns returned value and must free it. @@ -3223,6 +3487,24 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getHectoliter(); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of volume: jigger. + * Caller owns returned value and must free it. + * Also see {@link #getJigger()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createJigger(UErrorCode &status); + + /** + * Returns by value, unit of volume: jigger. + * Also see {@link #createJigger()}. + * @draft ICU 68 + */ + static MeasureUnit getJigger(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of volume: liter. * Caller owns returned value and must free it. @@ -3271,6 +3553,24 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getMilliliter(); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of volume: pinch. + * Caller owns returned value and must free it. + * Also see {@link #getPinch()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createPinch(UErrorCode &status); + + /** + * Returns by value, unit of volume: pinch. + * Also see {@link #createPinch()}. + * @draft ICU 68 + */ + static MeasureUnit getPinch(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of volume: pint. * Caller owns returned value and must free it. @@ -3319,6 +3619,24 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getQuart(); +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of volume: quart-imperial. + * Caller owns returned value and must free it. + * Also see {@link #getQuartImperial()}. + * @param status ICU error code. + * @draft ICU 68 + */ + static MeasureUnit *createQuartImperial(UErrorCode &status); + + /** + * Returns by value, unit of volume: quart-imperial. + * Also see {@link #createQuartImperial()}. + * @draft ICU 68 + */ + static MeasureUnit getQuartImperial(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of volume: tablespoon. * Caller owns returned value and must free it. @@ -3351,7 +3669,6 @@ class U_I18N_API MeasureUnit: public UObject { */ static MeasureUnit getTeaspoon(); - // End generated createXXX methods protected: @@ -3369,12 +3686,6 @@ class U_I18N_API MeasureUnit: public UObject { */ void initCurrency(StringPiece isoCurrency); - /** - * For ICU use only. - * @internal - */ - void initNoUnit(const char *subtype); - #endif /* U_HIDE_INTERNAL_API */ private: @@ -3393,7 +3704,6 @@ private: MeasureUnit(int32_t typeId, int32_t subTypeId); MeasureUnit(MeasureUnitImpl&& impl); void setTo(int32_t typeId, int32_t subTypeId); - int32_t getOffset() const; static MeasureUnit *create(int typeId, int subTypeId, UErrorCode &status); /** @@ -3405,9 +3715,25 @@ private: */ static bool findBySubType(StringPiece subType, MeasureUnit* output); - friend struct MeasureUnitImpl; + /** Internal version of public API */ + LocalArray splitToSingleUnitsImpl(int32_t& outCount, UErrorCode& status) const; + + friend class MeasureUnitImpl; + + // For access to findBySubType + friend class number::impl::LongNameHandler; }; +#ifndef U_HIDE_DRAFT_API +// inline impl of @draft ICU 68 method +inline std::pair, int32_t> +MeasureUnit::splitToSingleUnits(UErrorCode& status) const { + int32_t length; + auto array = splitToSingleUnitsImpl(length, status); + return std::make_pair(std::move(array), length); +} +#endif // U_HIDE_DRAFT_API + U_NAMESPACE_END #endif // !UNCONFIG_NO_FORMATTING diff --git a/deps/icu-small/source/i18n/unicode/measure.h b/deps/icu-small/source/i18n/unicode/measure.h index a15173d739d94fcf09a69d32ea657a4bf1901e89..0ed02626b13b8f6032f0318161732f3239b0e4a2 100644 --- a/deps/icu-small/source/i18n/unicode/measure.h +++ b/deps/icu-small/source/i18n/unicode/measure.h @@ -48,7 +48,7 @@ class U_I18N_API Measure: public UObject { * Construct an object with the given numeric amount and the given * unit. After this call, the caller must not delete the given * unit object. - * @param number a numeric object; amount.isNumeric() must be TRUE + * @param number a numeric object; amount.isNumeric() must be true * @param adoptedUnit the unit object, which must not be NULL * @param ec input-output error code. If the amount or the unit * is invalid, then this will be set to a failing value. diff --git a/deps/icu-small/source/i18n/unicode/msgfmt.h b/deps/icu-small/source/i18n/unicode/msgfmt.h index 99b0eaeec1dcd82733cec5b4efafa8f11668891b..14b57a114dc3a53fd46434841ff2b7af89c4afb5 100644 --- a/deps/icu-small/source/i18n/unicode/msgfmt.h +++ b/deps/icu-small/source/i18n/unicode/msgfmt.h @@ -132,7 +132,7 @@ class NumberFormat; *
  • messageText can contain quoted literal strings including syntax characters. * A quoted literal string begins with an ASCII apostrophe and a syntax character * (usually a {curly brace}) and continues until the next single apostrophe. - * A double ASCII apostrohpe inside or outside of a quoted string represents + * A double ASCII apostrophe inside or outside of a quoted string represents * one literal apostrophe. *
  • Quotable syntax characters are the {curly braces} in all messageText parts, * plus the '#' sign in a messageText immediately inside a pluralStyle, @@ -255,7 +255,7 @@ class NumberFormat; * or preformatted values, but not pattern strings or custom format objects.

    * *

    For more details, see the - * ICU User Guide.

    + * ICU User Guide.

    * *

    Usage Information

    * @@ -920,7 +920,7 @@ private: int32_t argTypeCapacity; /** - * TRUE if there are different argTypes for the same argument. + * true if there are different argTypes for the same argument. * This only matters when the MessageFormat is used in the plain C (umsg_xxx) API * where the pattern argTypes determine how the va_arg list is read. */ diff --git a/deps/icu-small/source/i18n/unicode/nounit.h b/deps/icu-small/source/i18n/unicode/nounit.h index 61b5c16ee3955b7a02959a185dbc92699e64eb42..cee45e352df4731f78642a8dc18cf0daa2a3b439 100644 --- a/deps/icu-small/source/i18n/unicode/nounit.h +++ b/deps/icu-small/source/i18n/unicode/nounit.h @@ -29,80 +29,53 @@ U_NAMESPACE_BEGIN /** * Dimensionless unit for percent and permille. + * Prior to ICU 68, this namespace was a class with the same name. * @see NumberFormatter - * @draft ICU 60 + * @draft ICU 68 */ -class U_I18N_API NoUnit: public MeasureUnit { -public: +namespace NoUnit { /** * Returns an instance for the base unit (dimensionless and no scaling). * - * @return a NoUnit instance - * @draft ICU 60 + * Prior to ICU 68, this function returned a NoUnit by value. + * + * Since ICU 68, this function returns the same value as the default MeasureUnit constructor. + * + * @return a MeasureUnit instance + * @draft ICU 68 */ - static NoUnit U_EXPORT2 base(); + static inline MeasureUnit U_EXPORT2 base() { + return MeasureUnit(); + } /** * Returns an instance for percent, or 1/100 of a base unit. * - * @return a NoUnit instance - * @draft ICU 60 + * Prior to ICU 68, this function returned a NoUnit by value. + * + * Since ICU 68, this function returns the same value as MeasureUnit::getPercent(). + * + * @return a MeasureUnit instance + * @draft ICU 68 */ - static NoUnit U_EXPORT2 percent(); + static inline MeasureUnit U_EXPORT2 percent() { + return MeasureUnit::getPercent(); + } /** * Returns an instance for permille, or 1/1000 of a base unit. * - * @return a NoUnit instance - * @draft ICU 60 - */ - static NoUnit U_EXPORT2 permille(); - - /** - * Copy operator. - * @draft ICU 60 - */ - NoUnit(const NoUnit& other); - - /** - * Destructor. - * @draft ICU 60 - */ - virtual ~NoUnit(); - - /** - * Return a polymorphic clone of this object. The result will - * have the same class as returned by getDynamicClassID(). - * @draft ICU 60 - */ - virtual NoUnit* clone() const; - - /** - * Returns a unique class ID for this object POLYMORPHICALLY. - * This method implements a simple form of RTTI used by ICU. - * @return The class ID for this object. All objects of a given - * class have the same class ID. Objects of other classes have - * different class IDs. - * @draft ICU 60 - */ - virtual UClassID getDynamicClassID() const; - - /** - * Returns the class ID for this class. This is used to compare to - * the return value of getDynamicClassID(). - * @return The class ID for all objects of this class. - * @draft ICU 60 - */ - static UClassID U_EXPORT2 getStaticClassID(); - -private: - /** - * Constructor - * @internal (private) + * Prior to ICU 68, this function returned a NoUnit by value. + * + * Since ICU 68, this function returns the same value as MeasureUnit::getPermille(). + * + * @return a MeasureUnit instance + * @draft ICU 68 */ - NoUnit(const char* subtype); - -}; + static inline MeasureUnit U_EXPORT2 permille() { + return MeasureUnit::getPermille(); + } +} U_NAMESPACE_END diff --git a/deps/icu-small/source/i18n/unicode/numberformatter.h b/deps/icu-small/source/i18n/unicode/numberformatter.h index 615cf49f7b7539ee501a2a5af77e94e9802fc1b6..b987e64b937455bc4efca099bb4ff9087aedc93c 100644 --- a/deps/icu-small/source/i18n/unicode/numberformatter.h +++ b/deps/icu-small/source/i18n/unicode/numberformatter.h @@ -28,10 +28,9 @@ /** * \file - * \brief C++ API: Library for localized number formatting introduced in ICU 60. + * \brief C++ API: All-in-one formatter for localized numbers, currencies, and units. * - * This library was introduced in ICU 60 to simplify the process of formatting localized number strings. - * Basic usage examples: + * For a full list of options, see icu::number::NumberFormatterSettings. * *
      * // Most basic usage:
    @@ -99,6 +98,13 @@ class MultiplierParseHandler;
     }
     }
     
    +namespace units {
    +
    +// Forward declarations:
    +class UnitsRouter;
    +
    +} // namespace units
    +
     namespace number {  // icu::number
     
     // Forward declarations:
    @@ -157,6 +163,7 @@ struct RangeMacroProps;
     struct UFormattedNumberImpl;
     class MutablePatternModifier;
     class ImmutablePatternModifier;
    +struct DecimalFormatWarehouse;
     
     /**
      * Used for NumberRangeFormatter and implemented in numrange_fluent.cpp.
    @@ -339,15 +346,15 @@ class U_I18N_API Notation : public UMemory {
     
         union NotationUnion {
             // For NTN_SCIENTIFIC
    -        /** @internal */
    +        /** @internal (private) */
             struct ScientificSettings {
    -            /** @internal */
    +            /** @internal (private) */
                 int8_t fEngineeringInterval;
    -            /** @internal */
    +            /** @internal (private) */
                 bool fRequireMinInt;
    -            /** @internal */
    +            /** @internal (private) */
                 impl::digits_t fMinExponentDigits;
    -            /** @internal */
    +            /** @internal (private) */
                 UNumberSignDisplay fExponentSignDisplay;
             } scientific;
     
    @@ -371,9 +378,9 @@ class U_I18N_API Notation : public UMemory {
         UBool copyErrorTo(UErrorCode &status) const {
             if (fType == NTN_ERROR) {
                 status = fUnion.errorCode;
    -            return TRUE;
    +            return true;
             }
    -        return FALSE;
    +        return false;
         }
     
         // To allow MacroProps to initialize empty instances:
    @@ -652,6 +659,17 @@ class U_I18N_API Precision : public UMemory {
          */
         static CurrencyPrecision currency(UCurrencyUsage currencyUsage);
     
    +#ifndef U_HIDE_DRAFT_API
    +    /**
    +     * Configure how trailing zeros are displayed on numbers. For example, to hide trailing zeros
    +     * when the number is an integer, use UNUM_TRAILING_ZERO_HIDE_IF_WHOLE.
    +     *
    +     * @param trailingZeroDisplay Option to configure the display of trailing zeros.
    +     * @draft ICU 69
    +     */
    +    Precision trailingZeroDisplay(UNumberTrailingZeroDisplay trailingZeroDisplay) const;
    +#endif // U_HIDE_DRAFT_API
    +
       private:
         enum PrecisionType {
             RND_BOGUS,
    @@ -676,41 +694,41 @@ class U_I18N_API Precision : public UMemory {
         } fType;
     
         union PrecisionUnion {
    -        /** @internal */
    +        /** @internal (private) */
             struct FractionSignificantSettings {
                 // For RND_FRACTION, RND_SIGNIFICANT, and RND_FRACTION_SIGNIFICANT
    -            /** @internal */
    +            /** @internal (private) */
                 impl::digits_t fMinFrac;
    -            /** @internal */
    +            /** @internal (private) */
                 impl::digits_t fMaxFrac;
    -            /** @internal */
    +            /** @internal (private) */
                 impl::digits_t fMinSig;
    -            /** @internal */
    +            /** @internal (private) */
                 impl::digits_t fMaxSig;
    +            /** @internal (private) */
    +            UNumberRoundingPriority fPriority;
             } fracSig;
    -        /** @internal */
    +        /** @internal (private) */
             struct IncrementSettings {
                 // For RND_INCREMENT, RND_INCREMENT_ONE, and RND_INCREMENT_FIVE
    -            /** @internal */
    +            /** @internal (private) */
                 double fIncrement;
    -            /** @internal */
    +            /** @internal (private) */
                 impl::digits_t fMinFrac;
    -            /** @internal */
    +            /** @internal (private) */
                 impl::digits_t fMaxFrac;
             } increment;
             UCurrencyUsage currencyUsage; // For RND_CURRENCY
             UErrorCode errorCode; // For RND_ERROR
         } fUnion;
     
    +    UNumberTrailingZeroDisplay fTrailingZeroDisplay = UNUM_TRAILING_ZERO_AUTO;
    +
         typedef PrecisionUnion::FractionSignificantSettings FractionSignificantSettings;
         typedef PrecisionUnion::IncrementSettings IncrementSettings;
     
    -    /** The Precision encapsulates the RoundingMode when used within the implementation. */
    -    UNumberFormatRoundingMode fRoundingMode;
    -
    -    Precision(const PrecisionType& type, const PrecisionUnion& union_,
    -              UNumberFormatRoundingMode roundingMode)
    -            : fType(type), fUnion(union_), fRoundingMode(roundingMode) {}
    +    Precision(const PrecisionType& type, const PrecisionUnion& union_)
    +            : fType(type), fUnion(union_) {}
     
         Precision(UErrorCode errorCode) : fType(RND_ERROR) {
             fUnion.errorCode = errorCode;
    @@ -725,9 +743,9 @@ class U_I18N_API Precision : public UMemory {
         UBool copyErrorTo(UErrorCode &status) const {
             if (fType == RND_ERROR) {
                 status = fUnion.errorCode;
    -            return TRUE;
    +            return true;
             }
    -        return FALSE;
    +        return false;
         }
     
         // On the parent type so that this method can be called internally on Precision instances.
    @@ -737,15 +755,16 @@ class U_I18N_API Precision : public UMemory {
     
         static Precision constructSignificant(int32_t minSig, int32_t maxSig);
     
    -    static Precision
    -    constructFractionSignificant(const FractionPrecision &base, int32_t minSig, int32_t maxSig);
    +    static Precision constructFractionSignificant(
    +        const FractionPrecision &base,
    +        int32_t minSig,
    +        int32_t maxSig,
    +        UNumberRoundingPriority priority);
     
         static IncrementPrecision constructIncrement(double increment, int32_t minFrac);
     
         static CurrencyPrecision constructCurrency(UCurrencyUsage usage);
     
    -    static Precision constructPassThrough();
    -
         // To allow MacroProps/MicroProps to initialize bogus instances:
         friend struct impl::MacroProps;
         friend struct impl::MicroProps;
    @@ -766,6 +785,9 @@ class U_I18N_API Precision : public UMemory {
     
         // To allow access to the skeleton generation code:
         friend class impl::GeneratorHelpers;
    +
    +    // To allow access to isBogus and the default (bogus) constructor:
    +    friend class units::UnitsRouter;
     };
     
     /**
    @@ -779,16 +801,38 @@ class U_I18N_API Precision : public UMemory {
      */
     class U_I18N_API FractionPrecision : public Precision {
       public:
    +#ifndef U_HIDE_DRAFT_API
         /**
    -     * Ensure that no less than this number of significant digits are retained when rounding according to fraction
    -     * rules.
    +     * Override maximum fraction digits with maximum significant digits depending on the magnitude
    +     * of the number. See UNumberRoundingPriority.
          *
    -     * 

    - * For example, with integer rounding, the number 3.141 becomes "3". However, with minimum figures set to 2, 3.141 - * becomes "3.1" instead. + * @param minSignificantDigits + * Pad trailing zeros to achieve this minimum number of significant digits. + * @param maxSignificantDigits + * Round the number to achieve this maximum number of significant digits. + * @param priority + * How to disambiguate between fraction digits and significant digits. + * @return A precision for chaining or passing to the NumberFormatter precision() setter. * - *

    - * This setting does not affect the number of trailing zeros. For example, 3.01 would print as "3", not "3.0". + * @draft ICU 69 + */ + Precision withSignificantDigits( + int32_t minSignificantDigits, + int32_t maxSignificantDigits, + UNumberRoundingPriority priority) const; +#endif // U_HIDE_DRAFT_API + + /** + * Ensure that no less than this number of significant digits are retained when rounding + * according to fraction rules. + * + * For example, with integer rounding, the number 3.141 becomes "3". However, with minimum + * figures set to 2, 3.141 becomes "3.1" instead. + * + * This setting does not affect the number of trailing zeros. For example, 3.01 would print as + * "3", not "3.0". + * + * This is equivalent to `withSignificantDigits(1, minSignificantDigits, RELAXED)`. * * @param minSignificantDigits * The number of significant figures to guarantee. @@ -798,16 +842,16 @@ class U_I18N_API FractionPrecision : public Precision { Precision withMinDigits(int32_t minSignificantDigits) const; /** - * Ensure that no more than this number of significant digits are retained when rounding according to fraction - * rules. + * Ensure that no more than this number of significant digits are retained when rounding + * according to fraction rules. * - *

    - * For example, with integer rounding, the number 123.4 becomes "123". However, with maximum figures set to 2, 123.4 - * becomes "120" instead. + * For example, with integer rounding, the number 123.4 becomes "123". However, with maximum + * figures set to 2, 123.4 becomes "120" instead. * - *

    - * This setting does not affect the number of trailing zeros. For example, with fixed fraction of 2, 123.4 would - * become "120.00". + * This setting does not affect the number of trailing zeros. For example, with fixed fraction + * of 2, 123.4 would become "120.00". + * + * This is equivalent to `withSignificantDigits(1, maxSignificantDigits, STRICT)`. * * @param maxSignificantDigits * Round the number to no more than this number of significant figures. @@ -969,9 +1013,9 @@ class U_I18N_API IntegerWidth : public UMemory { UBool copyErrorTo(UErrorCode &status) const { if (fHasError) { status = fUnion.errorCode; - return TRUE; + return true; } - return FALSE; + return false; } void apply(impl::DecimalQuantity &quantity, UErrorCode &status) const; @@ -1095,11 +1139,11 @@ class U_I18N_API Scale : public UMemory { } UBool copyErrorTo(UErrorCode &status) const { - if (fError != U_ZERO_ERROR) { + if (U_FAILURE(fError)) { status = fError; - return TRUE; + return true; } - return FALSE; + return false; } void applyTo(impl::DecimalQuantity& quantity) const; @@ -1126,6 +1170,76 @@ class U_I18N_API Scale : public UMemory { namespace impl { +// Do not enclose entire StringProp with #ifndef U_HIDE_INTERNAL_API, needed for a protected field +/** + * Manages NumberFormatterSettings::usage()'s char* instance on the heap. + * @internal + */ +class U_I18N_API StringProp : public UMemory { + +#ifndef U_HIDE_INTERNAL_API + + public: + /** @internal */ + StringProp(const StringProp &other); + + /** @internal */ + StringProp &operator=(const StringProp &other); + + /** @internal */ + StringProp(StringProp &&src) U_NOEXCEPT; + + /** @internal */ + StringProp &operator=(StringProp &&src) U_NOEXCEPT; + + /** @internal */ + ~StringProp(); + + /** @internal */ + int16_t length() const { + return fLength; + } + + /** @internal + * Makes a copy of value. Set to "" to unset. + */ + void set(StringPiece value); + + /** @internal */ + bool isSet() const { + return fLength > 0; + } + +#endif // U_HIDE_INTERNAL_API + + private: + char *fValue; + int16_t fLength; + UErrorCode fError; + + StringProp() : fValue(nullptr), fLength(0), fError(U_ZERO_ERROR) { + } + + /** @internal (private) */ + UBool copyErrorTo(UErrorCode &status) const { + if (U_FAILURE(fError)) { + status = fError; + return true; + } + return false; + } + + // Allow NumberFormatterImpl to access fValue. + friend class impl::NumberFormatterImpl; + + // Allow skeleton generation code to access private members. + friend class impl::GeneratorHelpers; + + // Allow MacroProps/MicroProps to initialize empty instances and to call + // copyErrorTo(). + friend struct impl::MacroProps; +}; + // Do not enclose entire SymbolsWrapper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field /** @internal */ class U_I18N_API SymbolsWrapper : public UMemory { @@ -1192,12 +1306,12 @@ class U_I18N_API SymbolsWrapper : public UMemory { UBool copyErrorTo(UErrorCode &status) const { if (fType == SYMPTR_DFS && fPtr.dfs == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; - return TRUE; + return true; } else if (fType == SYMPTR_NS && fPtr.ns == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; - return TRUE; + return true; } - return FALSE; + return false; } private: @@ -1239,13 +1353,13 @@ class U_I18N_API Grouper : public UMemory { fGrouping2(grouping2), fMinGrouping(minGrouping), fStrategy(strategy) {} -#endif // U_HIDE_INTERNAL_API /** @internal */ int16_t getPrimary() const; /** @internal */ int16_t getSecondary() const; +#endif // U_HIDE_INTERNAL_API private: /** @@ -1309,10 +1423,10 @@ class U_I18N_API Padder : public UMemory { /** @internal */ static Padder codePoints(UChar32 cp, int32_t targetWidth, UNumberFormatPadPosition position); -#endif // U_HIDE_INTERNAL_API /** @internal */ static Padder forProperties(const DecimalFormatProperties& properties); +#endif // U_HIDE_INTERNAL_API private: UChar32 fWidth; // -3 = error; -2 = bogus; -1 = no padding @@ -1341,9 +1455,9 @@ class U_I18N_API Padder : public UMemory { UBool copyErrorTo(UErrorCode &status) const { if (fWidth == -3) { status = fUnion.errorCode; - return TRUE; + return true; } - return FALSE; + return false; } bool isValid() const { @@ -1372,10 +1486,10 @@ struct U_I18N_API MacroProps : public UMemory { Notation notation; /** @internal */ - MeasureUnit unit; // = NoUnit::base(); + MeasureUnit unit; // = MeasureUnit(); (the base dimensionless unit) /** @internal */ - MeasureUnit perUnit; // = NoUnit::base(); + MeasureUnit perUnit; // = MeasureUnit(); (the base dimensionless unit) /** @internal */ Precision precision; // = Precision(); (bogus) @@ -1409,6 +1523,12 @@ struct U_I18N_API MacroProps : public UMemory { /** @internal */ Scale scale; // = Scale(); (benign value) + /** @internal */ + StringProp usage; // = StringProp(); (no usage) + + /** @internal */ + StringProp unitDisplayCase; // = StringProp(); (nominative) + /** @internal */ const AffixPatternProvider* affixProvider = nullptr; // no ownership @@ -1430,7 +1550,8 @@ struct U_I18N_API MacroProps : public UMemory { bool copyErrorTo(UErrorCode &status) const { return notation.copyErrorTo(status) || precision.copyErrorTo(status) || padder.copyErrorTo(status) || integerWidth.copyErrorTo(status) || - symbols.copyErrorTo(status) || scale.copyErrorTo(status); + symbols.copyErrorTo(status) || scale.copyErrorTo(status) || usage.copyErrorTo(status) || + unitDisplayCase.copyErrorTo(status); } }; @@ -1507,10 +1628,15 @@ class U_I18N_API NumberFormatterSettings { * All units will be properly localized with locale data, and all units are compatible with notation styles, * rounding precisions, and other number formatter settings. * + * \note If the usage() is set, the output unit **will be changed** to + * produce localised units, according to usage, locale and unit. See + * FormattedNumber::getOutputUnit(). + * * Pass this method any instance of {@link MeasureUnit}. For units of measure: * *

          * NumberFormatter::with().unit(MeasureUnit::getMeter())
    +     * NumberFormatter::with().unit(MeasureUnit::forIdentifier("foot-per-second", status))
          * 
    * * Currency: @@ -1693,7 +1819,7 @@ class U_I18N_API NumberFormatterSettings { * * The default is HALF_EVEN. For more information on rounding mode, see the ICU userguide here: * - * http://userguide.icu-project.org/formatparse/numbers/rounding-modes + * https://unicode-org.github.io/icu/userguide/format_parse/numbers/rounding-modes * * @param roundingMode The rounding mode to use. * @return The fluent chain. @@ -2038,6 +2164,80 @@ class U_I18N_API NumberFormatterSettings { */ Derived scale(const Scale &scale) &&; +#ifndef U_HIDE_DRAFT_API + /** + * Specifies the usage for which numbers will be formatted ("person-height", + * "road", "rainfall", etc.) + * + * When a `usage` is specified, the output unit will change depending on the + * `Locale` and the unit quantity. For example, formatting length + * measurements specified in meters: + * + * `NumberFormatter::with().usage("person").unit(MeasureUnit::getMeter()).locale("en-US")` + * * When formatting 0.25, the output will be "10 inches". + * * When formatting 1.50, the output will be "4 feet and 11 inches". + * + * The input unit specified via unit() determines the type of measurement + * being formatted (e.g. "length" when the unit is "foot"). The usage + * requested will be looked for only within this category of measurement + * units. + * + * The output unit can be found via FormattedNumber::getOutputUnit(). + * + * If the usage has multiple parts (e.g. "land-agriculture-grain") and does + * not match a known usage preference, the last part will be dropped + * repeatedly until a match is found (e.g. trying "land-agriculture", then + * "land"). If a match is still not found, usage will fall back to + * "default". + * + * Setting usage to an empty string clears the usage (disables usage-based + * localized formatting). + * + * Setting a usage string but not a correct input unit will result in an + * U_ILLEGAL_ARGUMENT_ERROR. + * + * When using usage, specifying rounding or precision is unnecessary. + * Specifying a precision in some manner will override the default + * formatting. + * + * @param usage A `usage` parameter from the units resource. See the + * unitPreferenceData in *source/data/misc/units.txt*, generated from + * `unitPreferenceData` in [CLDR's + * supplemental/units.xml](https://github.com/unicode-org/cldr/blob/master/common/supplemental/units.xml). + * @return The fluent chain. + * @draft ICU 68 + */ + Derived usage(StringPiece usage) const &; + + /** + * Overload of usage() for use on an rvalue reference. + * + * @param usage The unit `usage`. + * @return The fluent chain. + * @draft ICU 68 + */ + Derived usage(StringPiece usage) &&; +#endif // U_HIDE_DRAFT_API + +#ifndef U_HIDE_DRAFT_API +#ifndef U_HIDE_INTERNAL_API + /** + * Specifies the desired case for a unit formatter's output (e.g. + * accusative, dative, genitive). + * + * @internal ICU 69 technology preview + */ + Derived unitDisplayCase(StringPiece unitDisplayCase) const &; + + /** + * Overload of unitDisplayCase() for use on an rvalue reference. + * + * @internal ICU 69 technology preview + */ + Derived unitDisplayCase(StringPiece unitDisplayCase) &&; +#endif // U_HIDE_INTERNAL_API +#endif // U_HIDE_DRAFT_API + #ifndef U_HIDE_INTERNAL_API /** @@ -2090,6 +2290,9 @@ class U_I18N_API NumberFormatterSettings { * The returned skeleton is in normalized form, such that two number formatters with equivalent * behavior should produce the same skeleton. * + * For more information on number skeleton strings, see: + * https://unicode-org.github.io/icu/userguide/format_parse/numbers/skeletons.html + * * @return A number skeleton string with behavior corresponding to this number formatter. * @stable ICU 62 */ @@ -2120,13 +2323,13 @@ class U_I18N_API NumberFormatterSettings { /** * Sets the UErrorCode if an error occurred in the fluent chain. * Preserves older error codes in the outErrorCode. - * @return TRUE if U_FAILURE(outErrorCode) + * @return true if U_FAILURE(outErrorCode) * @stable ICU 60 */ UBool copyErrorTo(UErrorCode &outErrorCode) const { if (U_FAILURE(outErrorCode)) { // Do not overwrite the older error code - return TRUE; + return true; } fMacros.copyErrorTo(outErrorCode); return U_FAILURE(outErrorCode); @@ -2385,6 +2588,10 @@ class U_I18N_API LocalizedNumberFormatter const impl::NumberFormatterImpl* fCompiled {nullptr}; char fUnsafeCallCount[8] {}; // internally cast to u_atomic_int32_t + // Owned pointer to a DecimalFormatWarehouse, used when copying a LocalizedNumberFormatter + // from a DecimalFormat. + const impl::DecimalFormatWarehouse* fWarehouse {nullptr}; + explicit LocalizedNumberFormatter(const NumberFormatterSettings& other); explicit LocalizedNumberFormatter(NumberFormatterSettings&& src) U_NOEXCEPT; @@ -2393,10 +2600,12 @@ class U_I18N_API LocalizedNumberFormatter LocalizedNumberFormatter(impl::MacroProps &¯os, const Locale &locale); - void clear(); + void resetCompiled(); void lnfMoveHelper(LocalizedNumberFormatter&& src); + void lnfCopyHelper(const LocalizedNumberFormatter& src, UErrorCode& status); + /** * @return true if the compiled formatter is available. */ @@ -2485,7 +2694,6 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { /** @copydoc FormattedValue::nextPosition() */ UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE; -#ifndef U_HIDE_DRAFT_API /** * Export the formatted number as a "numeric string" conforming to the * syntax defined in the Decimal Arithmetic Specification, available at @@ -2502,10 +2710,32 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { * for example, std::string. * @param status Set if an error occurs. * @return A StringClass containing the numeric string. - * @draft ICU 65 + * @stable ICU 65 */ template inline StringClass toDecimalNumber(UErrorCode& status) const; + +#ifndef U_HIDE_DRAFT_API + /** + * Gets the resolved output unit. + * + * The output unit is dependent upon the localized preferences for the usage + * specified via NumberFormatterSettings::usage(), and may be a unit with + * UMEASURE_UNIT_MIXED unit complexity (MeasureUnit::getComplexity()), such + * as "foot-and-inch" or "hour-and-minute-and-second". + * + * @return `MeasureUnit`. + * @draft ICU 68 + */ + MeasureUnit getOutputUnit(UErrorCode& status) const; + + /** + * Gets the gender of the formatted output. Returns "" when the gender is + * unknown, or for ungendered languages. + * + * @internal ICU 69 technology preview. + */ + const char *getGender(UErrorCode& status) const; #endif // U_HIDE_DRAFT_API #ifndef U_HIDE_INTERNAL_API @@ -2533,7 +2763,7 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { /** * Internal constructor from data type. Adopts the data pointer. - * @internal + * @internal (private) */ explicit FormattedNumber(impl::UFormattedNumberData *results) : fData(results), fErrorCode(U_ZERO_ERROR) {} @@ -2541,7 +2771,6 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { explicit FormattedNumber(UErrorCode errorCode) : fData(nullptr), fErrorCode(errorCode) {} - // TODO(ICU-20775): Propose this as API. void toDecimalNumber(ByteSink& sink, UErrorCode& status) const; // To give LocalizedNumberFormatter format methods access to this class's constructor: @@ -2551,8 +2780,6 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { friend struct impl::UFormattedNumberImpl; }; -#ifndef U_HIDE_DRAFT_API -// Note: This is draft ICU 65 template StringClass FormattedNumber::toDecimalNumber(UErrorCode& status) const { StringClass result; @@ -2560,7 +2787,6 @@ StringClass FormattedNumber::toDecimalNumber(UErrorCode& status) const { toDecimalNumber(sink, status); return result; } -#endif // U_HIDE_DRAFT_API /** * See the main description in numberformatter.h for documentation and examples. @@ -2596,6 +2822,9 @@ class U_I18N_API NumberFormatter final { * It is possible for an error to occur while parsing. See the overload of this method if you are * interested in the location of a possible parse error. * + * For more information on number skeleton strings, see: + * https://unicode-org.github.io/icu/userguide/format_parse/numbers/skeletons.html + * * @param skeleton * The skeleton string off of which to base this NumberFormatter. * @param status @@ -2612,6 +2841,9 @@ class U_I18N_API NumberFormatter final { * If an error occurs while parsing the skeleton string, the offset into the skeleton string at * which the error occurred will be saved into the UParseError, if provided. * + * For more information on number skeleton strings, see: + * https://unicode-org.github.io/icu/userguide/format_parse/numbers/skeletons.html + * * @param skeleton * The skeleton string off of which to base this NumberFormatter. * @param perror @@ -2639,4 +2871,3 @@ U_NAMESPACE_END #endif /* U_SHOW_CPLUSPLUS_API */ #endif // __NUMBERFORMATTER_H__ - diff --git a/deps/icu-small/source/i18n/unicode/numberrangeformatter.h b/deps/icu-small/source/i18n/unicode/numberrangeformatter.h index 59f14d8be53189fdc3f2892db4c9266ef67cb38d..432f2f6095dedfa9e654e3fd8a94cbf5601cd28d 100644 --- a/deps/icu-small/source/i18n/unicode/numberrangeformatter.h +++ b/deps/icu-small/source/i18n/unicode/numberrangeformatter.h @@ -16,6 +16,7 @@ #include "unicode/formattedvalue.h" #include "unicode/fpositer.h" #include "unicode/numberformatter.h" +#include "unicode/unumberrangeformatter.h" /** * \file @@ -31,7 +32,7 @@ * .numberFormatterFirst(NumberFormatter::with().adoptUnit(MeasureUnit::createMeter())) * .numberFormatterSecond(NumberFormatter::with().adoptUnit(MeasureUnit::createKilometer())) * .locale("en-GB") - * .formatRange(750, 1.2, status) + * .formatFormattableRange(750, 1.2, status) * .toString(status); * // => "750 m - 1.2 km" *
    @@ -44,130 +45,11 @@ */ -/** - * Defines how to merge fields that are identical across the range sign. - * - * @stable ICU 63 - */ -typedef enum UNumberRangeCollapse { - /** - * Use locale data and heuristics to determine how much of the string to collapse. Could end up collapsing none, - * some, or all repeated pieces in a locale-sensitive way. - * - * The heuristics used for this option are subject to change over time. - * - * @stable ICU 63 - */ - UNUM_RANGE_COLLAPSE_AUTO, - - /** - * Do not collapse any part of the number. Example: "3.2 thousand kilograms – 5.3 thousand kilograms" - * - * @stable ICU 63 - */ - UNUM_RANGE_COLLAPSE_NONE, - - /** - * Collapse the unit part of the number, but not the notation, if present. Example: "3.2 thousand – 5.3 thousand - * kilograms" - * - * @stable ICU 63 - */ - UNUM_RANGE_COLLAPSE_UNIT, - - /** - * Collapse any field that is equal across the range sign. May introduce ambiguity on the magnitude of the - * number. Example: "3.2 – 5.3 thousand kilograms" - * - * @stable ICU 63 - */ - UNUM_RANGE_COLLAPSE_ALL -} UNumberRangeCollapse; - -/** - * Defines the behavior when the two numbers in the range are identical after rounding. To programmatically detect - * when the identity fallback is used, compare the lower and upper BigDecimals via FormattedNumber. - * - * @stable ICU 63 - * @see NumberRangeFormatter - */ -typedef enum UNumberRangeIdentityFallback { - /** - * Show the number as a single value rather than a range. Example: "$5" - * - * @stable ICU 63 - */ - UNUM_IDENTITY_FALLBACK_SINGLE_VALUE, - - /** - * Show the number using a locale-sensitive approximation pattern. If the numbers were the same before rounding, - * show the single value. Example: "~$5" or "$5" - * - * @stable ICU 63 - */ - UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, - - /** - * Show the number using a locale-sensitive approximation pattern. Use the range pattern always, even if the - * inputs are the same. Example: "~$5" - * - * @stable ICU 63 - */ - UNUM_IDENTITY_FALLBACK_APPROXIMATELY, - - /** - * Show the number as the range of two equal values. Use the range pattern always, even if the inputs are the - * same. Example (with RangeCollapse.NONE): "$5 – $5" - * - * @stable ICU 63 - */ - UNUM_IDENTITY_FALLBACK_RANGE -} UNumberRangeIdentityFallback; - -/** - * Used in the result class FormattedNumberRange to indicate to the user whether the numbers formatted in the range - * were equal or not, and whether or not the identity fallback was applied. - * - * @stable ICU 63 - * @see NumberRangeFormatter - */ -typedef enum UNumberRangeIdentityResult { - /** - * Used to indicate that the two numbers in the range were equal, even before any rounding rules were applied. - * - * @stable ICU 63 - * @see NumberRangeFormatter - */ - UNUM_IDENTITY_RESULT_EQUAL_BEFORE_ROUNDING, - - /** - * Used to indicate that the two numbers in the range were equal, but only after rounding rules were applied. - * - * @stable ICU 63 - * @see NumberRangeFormatter - */ - UNUM_IDENTITY_RESULT_EQUAL_AFTER_ROUNDING, - - /** - * Used to indicate that the two numbers in the range were not equal, even after rounding rules were applied. - * - * @stable ICU 63 - * @see NumberRangeFormatter - */ - UNUM_IDENTITY_RESULT_NOT_EQUAL, - -#ifndef U_HIDE_INTERNAL_API - /** - * The number of entries in this enum. - * @internal - */ - UNUM_IDENTITY_RESULT_COUNT -#endif - -} UNumberRangeIdentityResult; - U_NAMESPACE_BEGIN +// Forward declarations: +class PluralRules; + namespace number { // icu::number // Forward declarations: @@ -182,6 +64,7 @@ struct RangeMacroProps; class DecimalQuantity; class UFormattedNumberRangeData; class NumberRangeFormatterImpl; +struct UFormattedNumberRangeImpl; } // namespace impl @@ -190,7 +73,7 @@ class NumberRangeFormatterImpl; * Export an explicit template instantiation. See datefmt.h * (When building DLLs for Windows this is required.) */ -#if U_PLATFORM == U_PF_WINDOWS && !defined(U_IN_DOXYGEN) +#if U_PLATFORM == U_PF_WINDOWS && !defined(U_IN_DOXYGEN) && !defined(U_STATIC_IMPLEMENTATION) } // namespace icu::number U_NAMESPACE_END @@ -418,8 +301,8 @@ class U_I18N_API NumberRangeFormatterSettings { /** * Sets the behavior when the two sides of the range are the same. This could happen if the same two numbers are - * passed to the formatRange function, or if different numbers are passed to the function but they become the same - * after rounding rules are applied. Possible values: + * passed to the formatFormattableRange function, or if different numbers are passed to the function but they + * become the same after rounding rules are applied. Possible values: *

    *

      *
    • SINGLE_VALUE: "5 miles"
    • @@ -474,13 +357,13 @@ class U_I18N_API NumberRangeFormatterSettings { /** * Sets the UErrorCode if an error occurred in the fluent chain. * Preserves older error codes in the outErrorCode. - * @return TRUE if U_FAILURE(outErrorCode) + * @return true if U_FAILURE(outErrorCode) * @stable ICU 63 */ UBool copyErrorTo(UErrorCode &outErrorCode) const { if (U_FAILURE(outErrorCode)) { // Do not overwrite the older error code - return TRUE; + return true; } fMacros.copyErrorTo(outErrorCode); return U_FAILURE(outErrorCode); @@ -727,36 +610,26 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { #ifndef U_HIDE_DRAFT_API /** - * Export the first formatted number as a decimal number. This endpoint + * Extracts the formatted range as a pair of decimal numbers. This endpoint * is useful for obtaining the exact number being printed after scaling * and rounding have been applied by the number range formatting pipeline. * - * The syntax of the unformatted number is a "numeric string" + * The syntax of the unformatted numbers is a "numeric string" * as defined in the Decimal Arithmetic Specification, available at * http://speleotrove.com/decimal * - * @return A decimal representation of the first formatted number. - * @draft ICU 63 - * @see NumberRangeFormatter - * @see #getSecondDecimal - */ - UnicodeString getFirstDecimal(UErrorCode& status) const; - - /** - * Export the second formatted number as a decimal number. This endpoint - * is useful for obtaining the exact number being printed after scaling - * and rounding have been applied by the number range formatting pipeline. + * Example C++17 call site: * - * The syntax of the unformatted number is a "numeric string" - * as defined in the Decimal Arithmetic Specification, available at - * http://speleotrove.com/decimal + * auto [ first, second ] = range.getDecimalNumbers(status); * - * @return A decimal representation of the second formatted number. - * @draft ICU 63 - * @see NumberRangeFormatter - * @see #getFirstDecimal + * @tparam StringClass A string class compatible with StringByteSink; + * for example, std::string. + * @param status Set if an error occurs. + * @return A pair of StringClasses containing the numeric strings. + * @draft ICU 68 */ - UnicodeString getSecondDecimal(UErrorCode& status) const; + template + inline std::pair getDecimalNumbers(UErrorCode& status) const; #endif // U_HIDE_DRAFT_API /** @@ -818,10 +691,33 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { void getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpih, UErrorCode& status) const; + void getDecimalNumbers(ByteSink& sink1, ByteSink& sink2, UErrorCode& status) const; + + const impl::UFormattedNumberRangeData* getData(UErrorCode& status) const; + + // To allow PluralRules to access the underlying data + friend class ::icu::PluralRules; + // To give LocalizedNumberRangeFormatter format methods access to this class's constructor: friend class LocalizedNumberRangeFormatter; + + // To give C API access to internals + friend struct impl::UFormattedNumberRangeImpl; }; +#ifndef U_HIDE_DRAFT_API +// inline impl of @draft ICU 68 method +template +std::pair FormattedNumberRange::getDecimalNumbers(UErrorCode& status) const { + StringClass str1; + StringClass str2; + StringByteSink sink1(&str1); + StringByteSink sink2(&str2); + getDecimalNumbers(sink1, sink2, status); + return std::make_pair(str1, str2); +} +#endif // U_HIDE_DRAFT_API + /** * See the main description in numberrangeformatter.h for documentation and examples. * diff --git a/deps/icu-small/source/i18n/unicode/numfmt.h b/deps/icu-small/source/i18n/unicode/numfmt.h index a882b6d2e5667dcf1d33012eba1e62e3268b7914..058ccb38c7f1a4a92a258232c9eee28ae1883da7 100644 --- a/deps/icu-small/source/i18n/unicode/numfmt.h +++ b/deps/icu-small/source/i18n/unicode/numfmt.h @@ -179,7 +179,7 @@ public: * *

      * For more detail on rounding modes, see: - * http://userguide.icu-project.org/formatparse/numbers/rounding-modes + * https://unicode-org.github.io/icu/userguide/format_parse/numbers/rounding-modes * * @stable ICU 2.4 */ @@ -704,8 +704,8 @@ public: /** * Sets whether lenient parsing should be enabled (it is off by default). * - * @param enable \c TRUE if lenient parsing should be used, - * \c FALSE otherwise. + * @param enable \c true if lenient parsing should be used, + * \c false otherwise. * @stable ICU 4.8 */ virtual void setLenient(UBool enable); @@ -713,8 +713,8 @@ public: /** * Returns whether lenient parsing is enabled (it is off by default). * - * @return \c TRUE if lenient parsing is enabled, - * \c FALSE otherwise. + * @return \c true if lenient parsing is enabled, + * \c false otherwise. * @see #setLenient * @stable ICU 4.8 */ @@ -870,7 +870,7 @@ public: * NumberFormat::createInstance to avoid undefined behavior. * @param key the registry key returned by a previous call to registerFactory * @param status the in/out status code, no special meanings are assigned - * @return TRUE if the factory for the key was successfully unregistered + * @return true if the factory for the key was successfully unregistered * @stable ICU 2.6 */ static UBool U_EXPORT2 unregister(URegistryKey key, UErrorCode& status); @@ -1112,7 +1112,7 @@ protected: #ifndef U_HIDE_INTERNAL_API /** * Creates the specified number format style of the desired locale. - * If mustBeDecimalFormat is TRUE, then the returned pointer is + * If mustBeDecimalFormat is true, then the returned pointer is * either a DecimalFormat or it is NULL. * @internal */ @@ -1151,7 +1151,7 @@ private: private: UBool fParseIntegerOnly; - UBool fLenient; // TRUE => lenient parse is enabled + UBool fLenient; // true => lenient parse is enabled // ISO currency code char16_t fCurrency[4]; @@ -1228,7 +1228,7 @@ public: /** * @stable ICU 2.6 */ - SimpleNumberFormatFactory(const Locale& locale, UBool visible = TRUE); + SimpleNumberFormatFactory(const Locale& locale, UBool visible = true); /** * @stable ICU 3.0 diff --git a/deps/icu-small/source/i18n/unicode/numsys.h b/deps/icu-small/source/i18n/unicode/numsys.h index 88c172bd422a511db8651951c7ee82f60cc50923..efdf0c0f669a35abaa6e13bd416aa0eb4153ff80 100644 --- a/deps/icu-small/source/i18n/unicode/numsys.h +++ b/deps/icu-small/source/i18n/unicode/numsys.h @@ -102,7 +102,7 @@ public: /** * Create a numbering system using the specified radix, type, and description. * @param radix The radix (base) for this numbering system. - * @param isAlgorithmic TRUE if the numbering system is algorithmic rather than numeric. + * @param isAlgorithmic true if the numbering system is algorithmic rather than numeric. * @param description The string representing the set of digits used in a numeric system, or the name of the RBNF * ruleset to be used in an algorithmic system. * @param status ICU status @@ -171,10 +171,10 @@ public: /** - * Returns TRUE if the given numbering system is algorithmic + * Returns true if the given numbering system is algorithmic * - * @return TRUE if the numbering system is algorithmic. - * Otherwise, return FALSE. + * @return true if the numbering system is algorithmic. + * Otherwise, return false. * @stable ICU 4.2 */ UBool isAlgorithmic() const; diff --git a/deps/icu-small/source/i18n/unicode/plurfmt.h b/deps/icu-small/source/i18n/unicode/plurfmt.h index 7373476dca8fc2274ec129a40d0a97b3eed92d6a..fde2abcfae5ac28107ad5bb5b138cbb0670b78d9 100644 --- a/deps/icu-small/source/i18n/unicode/plurfmt.h +++ b/deps/icu-small/source/i18n/unicode/plurfmt.h @@ -587,7 +587,7 @@ private: */ static int32_t findSubMessage( const MessagePattern& pattern, int32_t partIndex, - const PluralSelector& selector, void *context, double number, UErrorCode& ec); /**< @internal */ + const PluralSelector& selector, void *context, double number, UErrorCode& ec); void parseType(const UnicodeString& source, const NFRule *rbnfLenientScanner, Formattable& result, FieldPosition& pos) const; diff --git a/deps/icu-small/source/i18n/unicode/plurrule.h b/deps/icu-small/source/i18n/unicode/plurrule.h index 408efbcc4a84f8f69a377044b4a0453ca0d1cc69..19956cd32c61807a14c863714c1fc76d452d69a3 100644 --- a/deps/icu-small/source/i18n/unicode/plurrule.h +++ b/deps/icu-small/source/i18n/unicode/plurrule.h @@ -46,14 +46,20 @@ U_NAMESPACE_BEGIN class Hashtable; class IFixedDecimal; +class FixedDecimal; class RuleChain; class PluralRuleParser; class PluralKeywordEnumeration; class AndConstraint; class SharedPluralRules; +class StandardPluralRanges; namespace number { class FormattedNumber; +class FormattedNumberRange; +namespace impl { +class UFormattedNumberRangeData; +} } /** @@ -367,11 +373,35 @@ public: */ UnicodeString select(const number::FormattedNumber& number, UErrorCode& status) const; +#ifndef U_HIDE_DRAFT_API + /** + * Given a formatted number range, returns the overall plural form of the + * range. For example, "3-5" returns "other" in English. + * + * To get a FormattedNumberRange, see NumberRangeFormatter. + * + * This method only works if PluralRules was created with a locale. If it was created + * from PluralRules::createRules(), this method sets status code U_UNSUPPORTED_ERROR. + * + * @param range The number range onto which the rules will be applied. + * @param status Set if an error occurs while selecting plural keyword. + * This could happen if the FormattedNumberRange is invalid, + * or if plural ranges data is unavailable. + * @return The keyword of the selected rule. + * @draft ICU 68 + */ + UnicodeString select(const number::FormattedNumberRange& range, UErrorCode& status) const; +#endif // U_HIDE_DRAFT_API + #ifndef U_HIDE_INTERNAL_API /** - * @internal - */ + * @internal + */ UnicodeString select(const IFixedDecimal &number) const; + /** + * @internal + */ + UnicodeString select(const number::impl::UFormattedNumberRangeData* urange, UErrorCode& status) const; #endif /* U_HIDE_INTERNAL_API */ /** @@ -446,13 +476,39 @@ public: double *dest, int32_t destCapacity, UErrorCode& status); +#ifndef U_HIDE_INTERNAL_API + /** + * Internal-only function that returns FixedDecimals instead of doubles. + * + * Returns sample values for which select() would return the keyword. If + * the keyword is unknown, returns no values, but this is not an error. + * + * The number of returned values is typically small. + * + * @param keyword The keyword. + * @param dest Array into which to put the returned values. May + * be NULL if destCapacity is 0. + * @param destCapacity The capacity of the array, must be at least 0. + * @param status The error code. + * @return The count of values written. + * If more than destCapacity samples are available, then + * only destCapacity are written, and destCapacity is returned as the count, + * rather than setting a U_BUFFER_OVERFLOW_ERROR. + * (The actual number of keyword values could be unlimited.) + * @internal + */ + int32_t getSamples(const UnicodeString &keyword, + FixedDecimal *dest, int32_t destCapacity, + UErrorCode& status); +#endif /* U_HIDE_INTERNAL_API */ + /** - * Returns TRUE if the given keyword is defined in this + * Returns true if the given keyword is defined in this * PluralRules object. * * @param keyword the input keyword. - * @return TRUE if the input keyword is defined. - * Otherwise, return FALSE. + * @return true if the input keyword is defined. + * Otherwise, return false. * @stable ICU 4.0 */ UBool isKeyword(const UnicodeString& keyword) const; @@ -513,12 +569,14 @@ public: private: RuleChain *mRules; + StandardPluralRanges *mStandardPluralRanges; PluralRules(); // default constructor not implemented void parseDescription(const UnicodeString& ruleData, UErrorCode &status); int32_t getNumberValue(const UnicodeString& token) const; UnicodeString getRuleFromResource(const Locale& locale, UPluralType type, UErrorCode& status); RuleChain *rulesForKeyword(const UnicodeString &keyword) const; + PluralRules *clone(UErrorCode& status) const; /** * An internal status variable used to indicate that the object is in an 'invalid' state. diff --git a/deps/icu-small/source/i18n/unicode/rbnf.h b/deps/icu-small/source/i18n/unicode/rbnf.h index 1144bd2fb8b1babe2057eb13d9e71bbe71279f25..ce60b9bec6853a6128e7668b97f407a5afcda9da 100644 --- a/deps/icu-small/source/i18n/unicode/rbnf.h +++ b/deps/icu-small/source/i18n/unicode/rbnf.h @@ -297,7 +297,7 @@ enum URBNFRuleSetTag { * * * x.0: - * The rule is a master rule. If the full stop in + * The rule is a default rule. If the full stop in * the middle of the rule name is replaced with the decimal point * that is used in the language or DecimalFormatSymbols, then that rule will * have precedence when formatting and parsing this rule. For example, some @@ -332,9 +332,9 @@ enum URBNFRuleSetTag { * algorithms: If the rule set is a regular rule set, do the following: * *

      -

      C++ addons#

      +

      C++ addons#

      Addons are dynamically-linked shared objects written in C++. The require() function can load addons as ordinary Node.js modules. Addons provide an interface between JavaScript and C/C++ libraries.

      -

      There are three options for implementing addons: N-API, nan, or direct +

      There are three options for implementing addons: Node-API, nan, or direct use of internal V8, libuv and Node.js libraries. Unless there is a need for -direct access to functionality which is not exposed by N-API, use N-API. -Refer to C/C++ addons with N-API for more information on N-API.

      -

      When not using N-API, implementing addons is complicated, +direct access to functionality which is not exposed by Node-API, use Node-API. +Refer to C/C++ addons with Node-API for more information on +Node-API.

      +

      When not using Node-API, implementing addons is complicated, involving knowledge of several components and APIs:

      • -

        V8: the C++ library Node.js uses to provide the +

        V8: the C++ library Node.js uses to provide the JavaScript implementation. V8 provides the mechanisms for creating objects, calling functions, etc. V8's API is documented mostly in the v8.h header file (deps/v8/include/v8.h in the Node.js source @@ -186,12 +199,12 @@ threads and all of the asynchronous behaviors of the platform. It also serves as a cross-platform abstraction library, giving easy, POSIX-like access across all major operating systems to many common system tasks, such as interacting with the filesystem, sockets, timers, and system events. libuv -also provides a pthreads-like threading abstraction that may be used to -power more sophisticated asynchronous addons that need to move beyond the -standard event loop. Addon authors are encouraged to think about how to +also provides a threading abstraction similar to POSIX threads for +more sophisticated asynchronous addons that need to move beyond the +standard event loop. Addon authors should avoid blocking the event loop with I/O or other time-intensive tasks by -off-loading work via libuv to non-blocking system operations, worker threads -or a custom use of libuv's threads.

        +offloading work via libuv to non-blocking system operations, worker threads, +or a custom use of libuv threads.

      • Internal Node.js libraries. Node.js itself exports C++ APIs that addons can @@ -207,41 +220,40 @@ re-exported by Node.js and may be used to various extents by addons. See

      All of the following examples are available for download and may be used as the starting-point for an addon.

      -

      Hello world#

      +

      Hello world#

      This "Hello world" example is a simple addon, written in C++, that is the equivalent of the following JavaScript code:

      -
      module.exports.hello = () => 'world';
      +
      module.exports.hello = () => 'world';

      First, create the file hello.cc:

      // hello.cc
      -#include <node.h>
      +#include <node.h>
       
       namespace demo {
       
       using v8::FunctionCallbackInfo;
       using v8::Isolate;
       using v8::Local;
      -using v8::NewStringType;
       using v8::Object;
       using v8::String;
       using v8::Value;
       
      -void Method(const FunctionCallbackInfo<Value>& args) {
      -  Isolate* isolate = args.GetIsolate();
      -  args.GetReturnValue().Set(String::NewFromUtf8(
      -      isolate, "world", NewStringType::kNormal).ToLocalChecked());
      +void Method(const FunctionCallbackInfo<Value>& args) {
      +  Isolate* isolate = args.GetIsolate();
      +  args.GetReturnValue().Set(String::NewFromUtf8(
      +      isolate, "world").ToLocalChecked());
       }
       
      -void Initialize(Local<Object> exports) {
      -  NODE_SET_METHOD(exports, "hello", Method);
      +void Initialize(Local<Object> exports) {
      +  NODE_SET_METHOD(exports, "hello", Method);
       }
       
      -NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
      +NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
       
       }  // namespace demo

      All Node.js addons must export an initialization function following the pattern:

      -
      void Initialize(Local<Object> exports);
      -NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
      +
      void Initialize(Local<Object> exports);
      +NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)

      There is no semi-colon after NODE_MODULE as it's not a function (see node.h).

      The module_name must match the filename of the final binary (excluding @@ -251,20 +263,20 @@ and the addon module name is addon.

      When building addons with node-gyp, using the macro NODE_GYP_MODULE_NAME as the first parameter of NODE_MODULE() will ensure that the name of the final binary will be passed to NODE_MODULE().

      -

      Context-aware addons#

      +

      Context-aware addons#

      There are environments in which Node.js addons may need to be loaded multiple times in multiple contexts. For example, the Electron runtime runs multiple instances of Node.js in a single process. Each instance will have its own require() cache, and thus each instance will need a native addon to behave -correctly when loaded via require(). From the addon's perspective, this means -that it must support multiple initializations.

      +correctly when loaded via require(). This means that the addon +must support multiple initializations.

      A context-aware addon can be constructed by using the macro NODE_MODULE_INITIALIZER, which expands to the name of a function which Node.js will expect to find when it loads an addon. An addon can thus be initialized as in the following example:

      using namespace v8;
       
      -extern "C" NODE_MODULE_EXPORT void
      +extern "C" NODE_MODULE_EXPORT void
       NODE_MODULE_INITIALIZER(Local<Object> exports,
                               Local<Value> module,
                               Local<Context> context) {
      @@ -295,7 +307,7 @@ performing the following steps:

      • Define a class which will hold per-addon-instance data and which has a static member of the form -
        static void DeleteInstance(void* data) {
        +
        static void DeleteInstance(void* data) {
           // Cast `data` to an instance of the class and delete it.
         }
      • @@ -316,61 +328,60 @@ native-backed JavaScript functions. The third parameter of be called from JavaScript. The per-addon-instance data must also be passed into any asynchronous callbacks the addon may create.

        The following example illustrates the implementation of a context-aware addon:

        -
        #include <node.h>
        +
        #include <node.h>
         
         using namespace v8;
         
        -class AddonData {
        +class AddonData {
          public:
           explicit AddonData(Isolate* isolate):
        -      call_count(0) {
        +      call_count(0) {
             // Ensure this per-addon-instance data is deleted at environment cleanup.
        -    node::AddEnvironmentCleanupHook(isolate, DeleteInstance, this);
        +    node::AddEnvironmentCleanupHook(isolate, DeleteInstance, this);
           }
         
           // Per-addon data.
        -  int call_count;
        +  int call_count;
         
        -  static void DeleteInstance(void* data) {
        -    delete static_cast<AddonData*>(data);
        +  static void DeleteInstance(void* data) {
        +    delete static_cast<AddonData*>(data);
           }
         };
         
        -static void Method(const v8::FunctionCallbackInfo<v8::Value>& info) {
        +static void Method(const v8::FunctionCallbackInfo<v8::Value>& info) {
           // Retrieve the per-addon-instance data.
           AddonData* data =
        -      reinterpret_cast<AddonData*>(info.Data().As<External>()->Value());
        +      reinterpret_cast<AddonData*>(info.Data().As<External>()->Value());
           data->call_count++;
        -  info.GetReturnValue().Set((double)data->call_count);
        +  info.GetReturnValue().Set((double)data->call_count);
         }
         
         // Initialize this addon to be context-aware.
        -NODE_MODULE_INIT(/* exports, module, context */) {
        -  Isolate* isolate = context->GetIsolate();
        +NODE_MODULE_INIT(/* exports, module, context */) {
        +  Isolate* isolate = context->GetIsolate();
         
           // Create a new instance of `AddonData` for this instance of the addon and
           // tie its life cycle to that of the Node.js environment.
        -  AddonData* data = new AddonData(isolate);
        +  AddonData* data = new AddonData(isolate);
         
           // Wrap the data in a `v8::External` so we can pass it to the method we
           // expose.
        -  Local<External> external = External::New(isolate, data);
        +  Local<External> external = External::New(isolate, data);
         
           // Expose the method `Method` to JavaScript, and make sure it receives the
           // per-addon-instance data we created above by passing `external` as the
           // third parameter to the `FunctionTemplate` constructor.
        -  exports->Set(context,
        -               String::NewFromUtf8(isolate, "method", NewStringType::kNormal)
        -                  .ToLocalChecked(),
        -               FunctionTemplate::New(isolate, Method, external)
        -                  ->GetFunction(context).ToLocalChecked()).FromJust();
        +  exports->Set(context,
        +               String::NewFromUtf8(isolate, "method").ToLocalChecked(),
        +               FunctionTemplate::New(isolate, Method, external)
        +                  ->GetFunction(context).ToLocalChecked()).FromJust();
         }
        -

        Worker support#

        +
        Worker support#
        -

        Linking to libraries included with Node.js#

        +

        Linking to libraries included with Node.js#

        Node.js uses statically linked libraries such as V8, libuv and OpenSSL. All addons are required to link to V8 and may link to any of the other dependencies as well. Typically, this is as simple as including the appropriate @@ -501,8 +512,8 @@ aware of:

        When node-gyp runs, it will detect the specific release version of Node.js and download either the full source tarball or just the headers. If the full source is downloaded, addons will have complete access to the full set of -Node.js dependencies. However, if only the Node.js headers are downloaded, then -only the symbols exported by Node.js will be available.

        +Node.js dependencies. However, if only the Node.js headers are downloaded, +then only the symbols exported by Node.js will be available.

      • node-gyp can be run using the --nodedir flag pointing at a local Node.js @@ -510,7 +521,7 @@ source image. Using this option, the addon will have access to the full set of dependencies.

      -

      Loading addons using require()#

      +

      Loading addons using require()#

      The filename extension of the compiled addon binary is .node (as opposed to .dll or .so). The require() function is written to look for files with the .node file extension and initialize those as dynamically-linked @@ -522,7 +533,7 @@ JavaScript files that happen to share the same base name. For instance, if there is a file addon.js in the same directory as the binary addon.node, then require('addon') will give precedence to the addon.js file and load it instead.

      -

      Native abstractions for Node.js#

      +

      Native abstractions for Node.js#

      Each of the examples illustrated in this document directly use the Node.js and V8 APIs for implementing addons. The V8 API can, and has, changed dramatically from one V8 release to the next (and one major Node.js release to @@ -532,11 +543,11 @@ minimize the frequency and impact of such changes but there is little that Node.js can do to ensure stability of the V8 APIs.

      The Native Abstractions for Node.js (or nan) provide a set of tools that addon developers are recommended to use to keep compatibility between past and -future releases of V8 and Node.js. See the nan examples for an +future releases of V8 and Node.js. See the nan examples for an illustration of how it can be used.

      -

      N-API#

      +

      Node-API#

      Stability: 2 - Stable

      -

      N-API is an API for building native addons. It is independent from +

      Node-API is an API for building native addons. It is independent from the underlying JavaScript runtime (e.g. V8) and is maintained as part of Node.js itself. This API will be Application Binary Interface (ABI) stable across versions of Node.js. It is intended to insulate addons from @@ -546,14 +557,14 @@ recompilation. Addons are built/packaged with the same approach/tools outlined in this document (node-gyp, etc.). The only difference is the set of APIs that are used by the native code. Instead of using the V8 or Native Abstractions for Node.js APIs, the functions available -in the N-API are used.

      +in the Node-API are used.

      Creating and maintaining an addon that benefits from the ABI stability -provided by N-API carries with it certain +provided by Node-API carries with it certain implementation considerations.

      -

      To use N-API in the above "Hello world" example, replace the content of +

      To use Node-API in the above "Hello world" example, replace the content of hello.cc with the following. All other instructions remain the same.

      -
      // hello.cc using N-API
      -#include <node_api.h>
      +
      // hello.cc using Node-API
      +#include <node_api.h>
       
       namespace demo {
       
      @@ -561,7 +572,7 @@ provided by N-API carries with it certain
         napi_value greeting;
         napi_status status;
       
      -  status = napi_create_string_utf8(env, "world", NAPI_AUTO_LENGTH, &greeting);
      +  status = napi_create_string_utf8(env, "world", NAPI_AUTO_LENGTH, &greeting);
         if (status != napi_ok) return nullptr;
         return greeting;
       }
      @@ -570,41 +581,41 @@ provided by N-API carries with it certain
         napi_status status;
         napi_value fn;
       
      -  status = napi_create_function(env, nullptr, 0, Method, nullptr, &fn);
      +  status = napi_create_function(env, nullptr, 0, Method, nullptr, &fn);
         if (status != napi_ok) return nullptr;
       
      -  status = napi_set_named_property(env, exports, "hello", fn);
      +  status = napi_set_named_property(env, exports, "hello", fn);
         if (status != napi_ok) return nullptr;
         return exports;
       }
       
      -NAPI_MODULE(NODE_GYP_MODULE_NAME, init)
      +NAPI_MODULE(NODE_GYP_MODULE_NAME, init)
       
       }  // namespace demo

      The functions available and how to use them are documented in -C/C++ addons with N-API.

      -

      Addon examples#

      +C/C++ addons with Node-API.

      +

      Addon examples#

      Following are some example addons intended to help developers get started. The examples use the V8 APIs. Refer to the online V8 reference for help with the various V8 calls, and V8's Embedder's Guide for an explanation of several concepts used such as handles, scopes, function templates, etc.

      Each of these examples using the following binding.gyp file:

      -
      {
      -  "targets": [
      -    {
      -      "target_name": "addon",
      -      "sources": [ "addon.cc" ]
      -    }
      -  ]
      -}
      +
      {
      +  "targets": [
      +    {
      +      "target_name": "addon",
      +      "sources": [ "addon.cc" ]
      +    }
      +  ]
      +}

      In cases where there is more than one .cc file, simply add the additional filename to the sources array:

      -
      "sources": ["addon.cc", "myexample.cc"]
      +
      "sources": ["addon.cc", "myexample.cc"]

      Once the binding.gyp file is ready, the example addons can be configured and built using node-gyp:

      -
      $ node-gyp configure build
      -

      Function arguments#

      +
      $ node-gyp configure build
      +

      Function arguments#

      Addons will typically expose objects and functions that can be accessed from JavaScript running within Node.js. When functions are invoked from JavaScript, the input arguments and return value must be mapped to and from the C/C++ @@ -612,7 +623,7 @@ code.

      The following example illustrates how to read function arguments passed from JavaScript and how to return a result:

      // addon.cc
      -#include <node.h>
      +#include <node.h>
       
       namespace demo {
       
      @@ -620,7 +631,6 @@ JavaScript and how to return a result:

      using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Number; using v8::Object; using v8::String; @@ -629,56 +639,54 @@ JavaScript and how to return a result:

      // This is the implementation of the "add" method // Input arguments are passed using the // const FunctionCallbackInfo<Value>& args struct -void Add(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void Add(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); // Check the number of arguments passed. - if (args.Length() < 2) { + if (args.Length() < 2) { // Throw an Error that is passed back to JavaScript - isolate->ThrowException(Exception::TypeError( - String::NewFromUtf8(isolate, - "Wrong number of arguments", - NewStringType::kNormal).ToLocalChecked())); + isolate->ThrowException(Exception::TypeError( + String::NewFromUtf8(isolate, + "Wrong number of arguments").ToLocalChecked())); return; } // Check the argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - isolate->ThrowException(Exception::TypeError( - String::NewFromUtf8(isolate, - "Wrong arguments", - NewStringType::kNormal).ToLocalChecked())); + if (!args[0]->IsNumber() || !args[1]->IsNumber()) { + isolate->ThrowException(Exception::TypeError( + String::NewFromUtf8(isolate, + "Wrong arguments").ToLocalChecked())); return; } // Perform the operation - double value = - args[0].As<Number>()->Value() + args[1].As<Number>()->Value(); - Local<Number> num = Number::New(isolate, value); + double value = + args[0].As<Number>()->Value() + args[1].As<Number>()->Value(); + Local<Number> num = Number::New(isolate, value); // Set the return value (using the passed in // FunctionCallbackInfo<Value>&) - args.GetReturnValue().Set(num); + args.GetReturnValue().Set(num); } -void Init(Local<Object> exports) { - NODE_SET_METHOD(exports, "add", Add); +void Init(Local<Object> exports) { + NODE_SET_METHOD(exports, "add", Add); } -NODE_MODULE(NODE_GYP_MODULE_NAME, Init) +NODE_MODULE(NODE_GYP_MODULE_NAME, Init) } // namespace demo

      Once compiled, the example addon can be required and used from within Node.js:

      // test.js
       const addon = require('./build/Release/addon');
       
      -console.log('This should be eight:', addon.add(3, 5));
      -

      Callbacks#

      +console.log('This should be eight:', addon.add(3, 5));
      +

      Callbacks#

      It is common practice within addons to pass JavaScript functions to a C++ function and execute them from there. The following example illustrates how to invoke such callbacks:

      // addon.cc
      -#include <node.h>
      +#include <node.h>
       
       namespace demo {
       
      @@ -687,29 +695,27 @@ to invoke such callbacks:

      using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Null; using v8::Object; using v8::String; using v8::Value; -void RunCallback(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); - Local<Function> cb = Local<Function>::Cast(args[0]); +void RunCallback(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); + Local<Function> cb = Local<Function>::Cast(args[0]); const unsigned argc = 1; Local<Value> argv[argc] = { - String::NewFromUtf8(isolate, - "hello world", - NewStringType::kNormal).ToLocalChecked() }; - cb->Call(context, Null(isolate), argc, argv).ToLocalChecked(); + String::NewFromUtf8(isolate, + "hello world").ToLocalChecked() }; + cb->Call(context, Null(isolate), argc, argv).ToLocalChecked(); } -void Init(Local<Object> exports, Local<Object> module) { - NODE_SET_METHOD(module, "exports", RunCallback); +void Init(Local<Object> exports, Local<Object> module) { + NODE_SET_METHOD(module, "exports", RunCallback); } -NODE_MODULE(NODE_GYP_MODULE_NAME, Init) +NODE_MODULE(NODE_GYP_MODULE_NAME, Init) } // namespace demo

      This example uses a two-argument form of Init() that receives the full @@ -720,17 +726,17 @@ property of exports.

      // test.js
       const addon = require('./build/Release/addon');
       
      -addon((msg) => {
      -  console.log(msg);
      +addon((msg) => {
      +  console.log(msg);
       // Prints: 'hello world'
       });

      In this example, the callback function is invoked synchronously.

      -

      Object factory#

      +

      Object factory#

      Addons can create and return new objects from within a C++ function as illustrated in the following example. An object is created and returned with a property msg that echoes the string passed to createObject():

      // addon.cc
      -#include <node.h>
      +#include <node.h>
       
       namespace demo {
       
      @@ -738,46 +744,44 @@ property msg that echoes the string passed to createObject()<
       using v8::FunctionCallbackInfo;
       using v8::Isolate;
       using v8::Local;
      -using v8::NewStringType;
       using v8::Object;
       using v8::String;
       using v8::Value;
       
      -void CreateObject(const FunctionCallbackInfo<Value>& args) {
      -  Isolate* isolate = args.GetIsolate();
      -  Local<Context> context = isolate->GetCurrentContext();
      +void CreateObject(const FunctionCallbackInfo<Value>& args) {
      +  Isolate* isolate = args.GetIsolate();
      +  Local<Context> context = isolate->GetCurrentContext();
       
      -  Local<Object> obj = Object::New(isolate);
      -  obj->Set(context,
      -           String::NewFromUtf8(isolate,
      -                               "msg",
      -                               NewStringType::kNormal).ToLocalChecked(),
      -                               args[0]->ToString(context).ToLocalChecked())
      -           .FromJust();
      +  Local<Object> obj = Object::New(isolate);
      +  obj->Set(context,
      +           String::NewFromUtf8(isolate,
      +                               "msg").ToLocalChecked(),
      +                               args[0]->ToString(context).ToLocalChecked())
      +           .FromJust();
       
      -  args.GetReturnValue().Set(obj);
      +  args.GetReturnValue().Set(obj);
       }
       
      -void Init(Local<Object> exports, Local<Object> module) {
      -  NODE_SET_METHOD(module, "exports", CreateObject);
      +void Init(Local<Object> exports, Local<Object> module) {
      +  NODE_SET_METHOD(module, "exports", CreateObject);
       }
       
      -NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
      +NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
       
       }  // namespace demo

      To test it in JavaScript:

      // test.js
       const addon = require('./build/Release/addon');
       
      -const obj1 = addon('hello');
      -const obj2 = addon('world');
      -console.log(obj1.msg, obj2.msg);
      +const obj1 = addon('hello');
      +const obj2 = addon('world');
      +console.log(obj1.msg, obj2.msg);
       // Prints: 'hello world'
      -

      Function factory#

      +

      Function factory#

      Another common scenario is creating JavaScript functions that wrap C++ functions and returning those back to JavaScript:

      // addon.cc
      -#include <node.h>
      +#include <node.h>
       
       namespace demo {
       
      @@ -787,96 +791,95 @@ functions and returning those back to JavaScript:

      using v8::FunctionTemplate; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Object; using v8::String; using v8::Value; -void MyFunction(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - args.GetReturnValue().Set(String::NewFromUtf8( - isolate, "hello world", NewStringType::kNormal).ToLocalChecked()); +void MyFunction(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + args.GetReturnValue().Set(String::NewFromUtf8( + isolate, "hello world").ToLocalChecked()); } -void CreateFunction(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void CreateFunction(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); - Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction); - Local<Function> fn = tpl->GetFunction(context).ToLocalChecked(); + Local<Context> context = isolate->GetCurrentContext(); + Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction); + Local<Function> fn = tpl->GetFunction(context).ToLocalChecked(); // omit this to make it anonymous - fn->SetName(String::NewFromUtf8( - isolate, "theFunction", NewStringType::kNormal).ToLocalChecked()); + fn->SetName(String::NewFromUtf8( + isolate, "theFunction").ToLocalChecked()); - args.GetReturnValue().Set(fn); + args.GetReturnValue().Set(fn); } -void Init(Local<Object> exports, Local<Object> module) { - NODE_SET_METHOD(module, "exports", CreateFunction); +void Init(Local<Object> exports, Local<Object> module) { + NODE_SET_METHOD(module, "exports", CreateFunction); } -NODE_MODULE(NODE_GYP_MODULE_NAME, Init) +NODE_MODULE(NODE_GYP_MODULE_NAME, Init) } // namespace demo

      To test:

      // test.js
       const addon = require('./build/Release/addon');
       
      -const fn = addon();
      -console.log(fn());
      +const fn = addon();
      +console.log(fn());
       // Prints: 'hello world'
      -

      Wrapping C++ objects#

      +

      Wrapping C++ objects#

      It is also possible to wrap C++ objects/classes in a way that allows new instances to be created using the JavaScript new operator:

      // addon.cc
      -#include <node.h>
      -#include "myobject.h"
      +#include <node.h>
      +#include "myobject.h"
       
       namespace demo {
       
       using v8::Local;
       using v8::Object;
       
      -void InitAll(Local<Object> exports) {
      -  MyObject::Init(exports);
      +void InitAll(Local<Object> exports) {
      +  MyObject::Init(exports);
       }
       
      -NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)
      +NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)
       
       }  // namespace demo

      Then, in myobject.h, the wrapper class inherits from node::ObjectWrap:

      // myobject.h
      -#ifndef MYOBJECT_H
      -#define MYOBJECT_H
      +#ifndef MYOBJECT_H
      +#define MYOBJECT_H
       
      -#include <node.h>
      -#include <node_object_wrap.h>
      +#include <node.h>
      +#include <node_object_wrap.h>
       
       namespace demo {
       
      -class MyObject : public node::ObjectWrap {
      +class MyObject : public node::ObjectWrap {
        public:
      -  static void Init(v8::Local<v8::Object> exports);
      +  static void Init(v8::Local<v8::Object> exports);
       
        private:
      -  explicit MyObject(double value = 0);
      -  ~MyObject();
      +  explicit MyObject(double value = 0);
      +  ~MyObject();
       
      -  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
      -  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
       
      -  double value_;
      +  double value_;
       };
       
       }  // namespace demo
       
      -#endif
      +#endif

      In myobject.cc, implement the various methods that are to be exposed. Below, the method plusOne() is exposed by adding it to the constructor's prototype:

      // myobject.cc
      -#include "myobject.h"
      +#include "myobject.h"
       
       namespace demo {
       
      @@ -886,100 +889,98 @@ prototype:

      using v8::FunctionTemplate; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Number; using v8::Object; using v8::ObjectTemplate; using v8::String; using v8::Value; -MyObject::MyObject(double value) : value_(value) { +MyObject::MyObject(double value) : value_(value) { } -MyObject::~MyObject() { +MyObject::~MyObject() { } -void MyObject::Init(Local<Object> exports) { - Isolate* isolate = exports->GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); +void MyObject::Init(Local<Object> exports) { + Isolate* isolate = exports->GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); - Local<ObjectTemplate> addon_data_tpl = ObjectTemplate::New(isolate); - addon_data_tpl->SetInternalFieldCount(1); // 1 field for the MyObject::New() + Local<ObjectTemplate> addon_data_tpl = ObjectTemplate::New(isolate); + addon_data_tpl->SetInternalFieldCount(1); // 1 field for the MyObject::New() Local<Object> addon_data = - addon_data_tpl->NewInstance(context).ToLocalChecked(); + addon_data_tpl->NewInstance(context).ToLocalChecked(); // Prepare constructor template - Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New, addon_data); - tpl->SetClassName(String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked()); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New, addon_data); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); // Prototype - NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); + NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); - Local<Function> constructor = tpl->GetFunction(context).ToLocalChecked(); - addon_data->SetInternalField(0, constructor); - exports->Set(context, String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked(), - constructor).FromJust(); + Local<Function> constructor = tpl->GetFunction(context).ToLocalChecked(); + addon_data->SetInternalField(0, constructor); + exports->Set(context, String::NewFromUtf8( + isolate, "MyObject").ToLocalChecked(), + constructor).FromJust(); } -void MyObject::New(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); +void MyObject::New(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); - if (args.IsConstructCall()) { + if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` - double value = args[0]->IsUndefined() ? - 0 : args[0]->NumberValue(context).FromMaybe(0); - MyObject* obj = new MyObject(value); - obj->Wrap(args.This()); - args.GetReturnValue().Set(args.This()); + double value = args[0]->IsUndefined() ? + 0 : args[0]->NumberValue(context).FromMaybe(0); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); } else { // Invoked as plain function `MyObject(...)`, turn into construct call. - const int argc = 1; + const int argc = 1; Local<Value> argv[argc] = { args[0] }; Local<Function> cons = - args.Data().As<Object>()->GetInternalField(0).As<Function>(); + args.Data().As<Object>()->GetInternalField(0).As<Function>(); Local<Object> result = - cons->NewInstance(context, argc, argv).ToLocalChecked(); - args.GetReturnValue().Set(result); + cons->NewInstance(context, argc, argv).ToLocalChecked(); + args.GetReturnValue().Set(result); } } -void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); - MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder()); + MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder()); obj->value_ += 1; - args.GetReturnValue().Set(Number::New(isolate, obj->value_)); + args.GetReturnValue().Set(Number::New(isolate, obj->value_)); } } // namespace demo

      To build this example, the myobject.cc file must be added to the binding.gyp:

      -
      {
      -  "targets": [
      -    {
      -      "target_name": "addon",
      -      "sources": [
      -        "addon.cc",
      +
      {
      +  "targets": [
      +    {
      +      "target_name": "addon",
      +      "sources": [
      +        "addon.cc",
               "myobject.cc"
      -      ]
      -    }
      -  ]
      -}
      + ] + } + ] +}

      Test it with:

      // test.js
       const addon = require('./build/Release/addon');
       
      -const obj = new addon.MyObject(10);
      -console.log(obj.plusOne());
      +const obj = new addon.MyObject(10);
      +console.log(obj.plusOne());
       // Prints: 11
      -console.log(obj.plusOne());
      +console.log(obj.plusOne());
       // Prints: 12
      -console.log(obj.plusOne());
      +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 @@ -987,16 +988,16 @@ 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#

      +

      Factory of wrapped objects#

      Alternatively, it is possible to use a factory pattern to avoid explicitly creating object instances using the JavaScript new operator:

      -
      const obj = addon.createObject();
      +
      const obj = addon.createObject();
       // instead of:
       // const obj = new addon.Object();

      First, the createObject() method is implemented in addon.cc:

      // addon.cc
      -#include <node.h>
      -#include "myobject.h"
      +#include <node.h>
      +#include "myobject.h"
       
       namespace demo {
       
      @@ -1007,53 +1008,53 @@ creating object instances using the JavaScript new operator:

      using v8::String; using v8::Value; -void CreateObject(const FunctionCallbackInfo<Value>& args) { - MyObject::NewInstance(args); +void CreateObject(const FunctionCallbackInfo<Value>& args) { + MyObject::NewInstance(args); } -void InitAll(Local<Object> exports, Local<Object> module) { - MyObject::Init(exports->GetIsolate()); +void InitAll(Local<Object> exports, Local<Object> module) { + MyObject::Init(exports->GetIsolate()); - NODE_SET_METHOD(module, "exports", CreateObject); + NODE_SET_METHOD(module, "exports", CreateObject); } -NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll) +NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll) } // namespace demo

      In myobject.h, the static method NewInstance() is added to handle instantiating the object. This method takes the place of using new in JavaScript:

      // myobject.h
      -#ifndef MYOBJECT_H
      -#define MYOBJECT_H
      +#ifndef MYOBJECT_H
      +#define MYOBJECT_H
       
      -#include <node.h>
      -#include <node_object_wrap.h>
      +#include <node.h>
      +#include <node_object_wrap.h>
       
       namespace demo {
       
      -class MyObject : public node::ObjectWrap {
      +class MyObject : public node::ObjectWrap {
        public:
      -  static void Init(v8::Isolate* isolate);
      -  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void Init(v8::Isolate* isolate);
      +  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
       
        private:
      -  explicit MyObject(double value = 0);
      -  ~MyObject();
      +  explicit MyObject(double value = 0);
      +  ~MyObject();
       
      -  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
      -  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
         static v8::Global<v8::Function> constructor;
      -  double value_;
      +  double value_;
       };
       
       }  // namespace demo
       
      -#endif
      +#endif

      The implementation in myobject.cc is similar to the previous example:

      // myobject.cc
      -#include <node.h>
      -#include "myobject.h"
      +#include <node.h>
      +#include "myobject.h"
       
       namespace demo {
       
      @@ -1065,7 +1066,6 @@ JavaScript:

      using v8::Global; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Number; using v8::Object; using v8::String; @@ -1075,116 +1075,115 @@ JavaScript:

      // threads. Global<Function> MyObject::constructor; -MyObject::MyObject(double value) : value_(value) { +MyObject::MyObject(double value) : value_(value) { } -MyObject::~MyObject() { +MyObject::~MyObject() { } -void MyObject::Init(Isolate* isolate) { +void MyObject::Init(Isolate* isolate) { // Prepare constructor template - Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New); - tpl->SetClassName(String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked()); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); // Prototype - NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); + NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); - Local<Context> context = isolate->GetCurrentContext(); - constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); + Local<Context> context = isolate->GetCurrentContext(); + constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); - AddEnvironmentCleanupHook(isolate, [](void*) { - constructor.Reset(); + AddEnvironmentCleanupHook(isolate, [](void*) { + constructor.Reset(); }, nullptr); } -void MyObject::New(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); +void MyObject::New(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); - if (args.IsConstructCall()) { + if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` - double value = args[0]->IsUndefined() ? - 0 : args[0]->NumberValue(context).FromMaybe(0); - MyObject* obj = new MyObject(value); - obj->Wrap(args.This()); - args.GetReturnValue().Set(args.This()); + double value = args[0]->IsUndefined() ? + 0 : args[0]->NumberValue(context).FromMaybe(0); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); } else { // Invoked as plain function `MyObject(...)`, turn into construct call. - const int argc = 1; + const int argc = 1; Local<Value> argv[argc] = { args[0] }; - Local<Function> cons = Local<Function>::New(isolate, constructor); + Local<Function> cons = Local<Function>::New(isolate, constructor); Local<Object> instance = - cons->NewInstance(context, argc, argv).ToLocalChecked(); - args.GetReturnValue().Set(instance); + cons->NewInstance(context, argc, argv).ToLocalChecked(); + args.GetReturnValue().Set(instance); } } -void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); const unsigned argc = 1; Local<Value> argv[argc] = { args[0] }; - Local<Function> cons = Local<Function>::New(isolate, constructor); - Local<Context> context = isolate->GetCurrentContext(); + Local<Function> cons = Local<Function>::New(isolate, constructor); + Local<Context> context = isolate->GetCurrentContext(); Local<Object> instance = - cons->NewInstance(context, argc, argv).ToLocalChecked(); + cons->NewInstance(context, argc, argv).ToLocalChecked(); - args.GetReturnValue().Set(instance); + args.GetReturnValue().Set(instance); } -void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); - MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder()); + MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder()); obj->value_ += 1; - args.GetReturnValue().Set(Number::New(isolate, obj->value_)); + args.GetReturnValue().Set(Number::New(isolate, obj->value_)); } } // namespace demo

      Once again, to build this example, the myobject.cc file must be added to the binding.gyp:

      -
      {
      -  "targets": [
      -    {
      -      "target_name": "addon",
      -      "sources": [
      -        "addon.cc",
      +
      {
      +  "targets": [
      +    {
      +      "target_name": "addon",
      +      "sources": [
      +        "addon.cc",
               "myobject.cc"
      -      ]
      -    }
      -  ]
      -}
      + ] + } + ] +}

      Test it with:

      // test.js
       const createObject = require('./build/Release/addon');
       
      -const obj = createObject(10);
      -console.log(obj.plusOne());
      +const obj = createObject(10);
      +console.log(obj.plusOne());
       // Prints: 11
      -console.log(obj.plusOne());
      +console.log(obj.plusOne());
       // Prints: 12
      -console.log(obj.plusOne());
      +console.log(obj.plusOne());
       // Prints: 13
       
      -const obj2 = createObject(20);
      -console.log(obj2.plusOne());
      +const obj2 = createObject(20);
      +console.log(obj2.plusOne());
       // Prints: 21
      -console.log(obj2.plusOne());
      +console.log(obj2.plusOne());
       // Prints: 22
      -console.log(obj2.plusOne());
      +console.log(obj2.plusOne());
       // Prints: 23
      -

      Passing wrapped objects around#

      +

      Passing wrapped objects around#

      In addition to wrapping and returning C++ objects, it is possible to pass wrapped objects around by unwrapping them with the Node.js helper function node::ObjectWrap::Unwrap. The following examples shows a function add() that can take two MyObject objects as input arguments:

      // addon.cc
      -#include <node.h>
      -#include <node_object_wrap.h>
      -#include "myobject.h"
      +#include <node.h>
      +#include <node_object_wrap.h>
      +#include "myobject.h"
       
       namespace demo {
       
      @@ -1197,66 +1196,66 @@ that can take two MyObject objects as input arguments:

      using v8::String; using v8::Value; -void CreateObject(const FunctionCallbackInfo<Value>& args) { - MyObject::NewInstance(args); +void CreateObject(const FunctionCallbackInfo<Value>& args) { + MyObject::NewInstance(args); } -void Add(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); +void Add(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); - MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>( - args[0]->ToObject(context).ToLocalChecked()); - MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>( - args[1]->ToObject(context).ToLocalChecked()); + MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>( + args[0]->ToObject(context).ToLocalChecked()); + MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>( + args[1]->ToObject(context).ToLocalChecked()); - double sum = obj1->value() + obj2->value(); - args.GetReturnValue().Set(Number::New(isolate, sum)); + double sum = obj1->value() + obj2->value(); + args.GetReturnValue().Set(Number::New(isolate, sum)); } -void InitAll(Local<Object> exports) { - MyObject::Init(exports->GetIsolate()); +void InitAll(Local<Object> exports) { + MyObject::Init(exports->GetIsolate()); - NODE_SET_METHOD(exports, "createObject", CreateObject); - NODE_SET_METHOD(exports, "add", Add); + NODE_SET_METHOD(exports, "createObject", CreateObject); + NODE_SET_METHOD(exports, "add", Add); } -NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll) +NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll) } // namespace demo

      In myobject.h, a new public method is added to allow access to private values after unwrapping the object.

      // myobject.h
      -#ifndef MYOBJECT_H
      -#define MYOBJECT_H
      +#ifndef MYOBJECT_H
      +#define MYOBJECT_H
       
      -#include <node.h>
      -#include <node_object_wrap.h>
      +#include <node.h>
      +#include <node_object_wrap.h>
       
       namespace demo {
       
      -class MyObject : public node::ObjectWrap {
      +class MyObject : public node::ObjectWrap {
        public:
      -  static void Init(v8::Isolate* isolate);
      -  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
      -  inline double value() const { return value_; }
      +  static void Init(v8::Isolate* isolate);
      +  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  inline double value() const { return value_; }
       
        private:
      -  explicit MyObject(double value = 0);
      -  ~MyObject();
      +  explicit MyObject(double value = 0);
      +  ~MyObject();
       
      -  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
         static v8::Global<v8::Function> constructor;
      -  double value_;
      +  double value_;
       };
       
       }  // namespace demo
       
      -#endif
      +#endif

      The implementation of myobject.cc is similar to before:

      // myobject.cc
      -#include <node.h>
      -#include "myobject.h"
      +#include <node.h>
      +#include "myobject.h"
       
       namespace demo {
       
      @@ -1268,7 +1267,6 @@ after unwrapping the object.

      using v8::Global; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Object; using v8::String; using v8::Value; @@ -1277,60 +1275,59 @@ after unwrapping the object.

      // threads. Global<Function> MyObject::constructor; -MyObject::MyObject(double value) : value_(value) { +MyObject::MyObject(double value) : value_(value) { } -MyObject::~MyObject() { +MyObject::~MyObject() { } -void MyObject::Init(Isolate* isolate) { +void MyObject::Init(Isolate* isolate) { // Prepare constructor template - Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New); - tpl->SetClassName(String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked()); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); - Local<Context> context = isolate->GetCurrentContext(); - constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); + Local<Context> context = isolate->GetCurrentContext(); + constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); - AddEnvironmentCleanupHook(isolate, [](void*) { - constructor.Reset(); + AddEnvironmentCleanupHook(isolate, [](void*) { + constructor.Reset(); }, nullptr); } -void MyObject::New(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); +void MyObject::New(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); - if (args.IsConstructCall()) { + if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` - double value = args[0]->IsUndefined() ? - 0 : args[0]->NumberValue(context).FromMaybe(0); - MyObject* obj = new MyObject(value); - obj->Wrap(args.This()); - args.GetReturnValue().Set(args.This()); + double value = args[0]->IsUndefined() ? + 0 : args[0]->NumberValue(context).FromMaybe(0); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); } else { // Invoked as plain function `MyObject(...)`, turn into construct call. - const int argc = 1; + const int argc = 1; Local<Value> argv[argc] = { args[0] }; - Local<Function> cons = Local<Function>::New(isolate, constructor); + Local<Function> cons = Local<Function>::New(isolate, constructor); Local<Object> instance = - cons->NewInstance(context, argc, argv).ToLocalChecked(); - args.GetReturnValue().Set(instance); + cons->NewInstance(context, argc, argv).ToLocalChecked(); + args.GetReturnValue().Set(instance); } } -void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); const unsigned argc = 1; Local<Value> argv[argc] = { args[0] }; - Local<Function> cons = Local<Function>::New(isolate, constructor); - Local<Context> context = isolate->GetCurrentContext(); + Local<Function> cons = Local<Function>::New(isolate, constructor); + Local<Context> context = isolate->GetCurrentContext(); Local<Object> instance = - cons->NewInstance(context, argc, argv).ToLocalChecked(); + cons->NewInstance(context, argc, argv).ToLocalChecked(); - args.GetReturnValue().Set(instance); + args.GetReturnValue().Set(instance); } } // namespace demo
      @@ -1338,15 +1335,51 @@ MyObject::~MyObject() {
      // test.js
       const addon = require('./build/Release/addon');
       
      -const obj1 = addon.createObject(10);
      -const obj2 = addon.createObject(20);
      -const result = addon.add(obj1, obj2);
      +const obj1 = addon.createObject(10);
      +const obj2 = addon.createObject(20);
      +const result = addon.add(obj1, obj2);
       
      -console.log(result);
      -// Prints: 30
      +console.log(result); +// Prints: 30
      + diff --git a/doc/api/addons.json b/doc/api/addons.json index 12a6f6e724675af93d2f07aa5a7e21c260adcfc5..6f78b505e0e03503deb30e3bdf566dde1ff097fa 100644 --- a/doc/api/addons.json +++ b/doc/api/addons.json @@ -8,17 +8,17 @@ "name": "C++ addons", "introduced_in": "v0.10.0", "type": "misc", - "desc": "

      Addons are dynamically-linked shared objects written in C++. The\nrequire() function can load addons as ordinary Node.js modules.\nAddons provide an interface between JavaScript and C/C++ libraries.

      \n

      There are three options for implementing addons: N-API, nan, or direct\nuse of internal V8, libuv and Node.js libraries. Unless there is a need for\ndirect access to functionality which is not exposed by N-API, use N-API.\nRefer to C/C++ addons with N-API for more information on N-API.

      \n

      When not using N-API, implementing addons is complicated,\ninvolving knowledge of several components and APIs:

      \n
        \n
      • \n

        V8: the C++ library Node.js uses to provide the\nJavaScript implementation. V8 provides the mechanisms for creating objects,\ncalling functions, etc. V8's API is documented mostly in the\nv8.h header file (deps/v8/include/v8.h in the Node.js source\ntree), which is also available online.

        \n
      • \n
      • \n

        libuv: The C library that implements the Node.js event loop, its worker\nthreads and all of the asynchronous behaviors of the platform. It also\nserves as a cross-platform abstraction library, giving easy, POSIX-like\naccess across all major operating systems to many common system tasks, such\nas interacting with the filesystem, sockets, timers, and system events. libuv\nalso provides a pthreads-like threading abstraction that may be used to\npower more sophisticated asynchronous addons that need to move beyond the\nstandard event loop. Addon authors are encouraged to think about how to\navoid blocking the event loop with I/O or other time-intensive tasks by\noff-loading work via libuv to non-blocking system operations, worker threads\nor a custom use of libuv's threads.

        \n
      • \n
      • \n

        Internal Node.js libraries. Node.js itself exports C++ APIs that addons can\nuse, the most important of which is the node::ObjectWrap class.

        \n
      • \n
      • \n

        Node.js includes other statically linked libraries including OpenSSL. These\nother libraries are located in the deps/ directory in the Node.js source\ntree. Only the libuv, OpenSSL, V8 and zlib symbols are purposefully\nre-exported by Node.js and may be used to various extents by addons. See\nLinking to libraries included with Node.js for additional information.

        \n
      • \n
      \n

      All of the following examples are available for download and may\nbe used as the starting-point for an addon.

      ", + "desc": "

      Addons are dynamically-linked shared objects written in C++. The\nrequire() function can load addons as ordinary Node.js modules.\nAddons provide an interface between JavaScript and C/C++ libraries.

      \n

      There are three options for implementing addons: Node-API, nan, or direct\nuse of internal V8, libuv and Node.js libraries. Unless there is a need for\ndirect access to functionality which is not exposed by Node-API, use Node-API.\nRefer to C/C++ addons with Node-API for more information on\nNode-API.

      \n

      When not using Node-API, implementing addons is complicated,\ninvolving knowledge of several components and APIs:

      \n
        \n
      • \n

        V8: the C++ library Node.js uses to provide the\nJavaScript implementation. V8 provides the mechanisms for creating objects,\ncalling functions, etc. V8's API is documented mostly in the\nv8.h header file (deps/v8/include/v8.h in the Node.js source\ntree), which is also available online.

        \n
      • \n
      • \n

        libuv: The C library that implements the Node.js event loop, its worker\nthreads and all of the asynchronous behaviors of the platform. It also\nserves as a cross-platform abstraction library, giving easy, POSIX-like\naccess across all major operating systems to many common system tasks, such\nas interacting with the filesystem, sockets, timers, and system events. libuv\nalso provides a threading abstraction similar to POSIX threads for\nmore sophisticated asynchronous addons that need to move beyond the\nstandard event loop. Addon authors should\navoid blocking the event loop with I/O or other time-intensive tasks by\noffloading work via libuv to non-blocking system operations, worker threads,\nor a custom use of libuv threads.

        \n
      • \n
      • \n

        Internal Node.js libraries. Node.js itself exports C++ APIs that addons can\nuse, the most important of which is the node::ObjectWrap class.

        \n
      • \n
      • \n

        Node.js includes other statically linked libraries including OpenSSL. These\nother libraries are located in the deps/ directory in the Node.js source\ntree. Only the libuv, OpenSSL, V8 and zlib symbols are purposefully\nre-exported by Node.js and may be used to various extents by addons. See\nLinking to libraries included with Node.js for additional information.

        \n
      • \n
      \n

      All of the following examples are available for download and may\nbe used as the starting-point for an addon.

      ", "miscs": [ { "textRaw": "Hello world", "name": "hello_world", - "desc": "

      This \"Hello world\" example is a simple addon, written in C++, that is the\nequivalent of the following JavaScript code:

      \n
      module.exports.hello = () => 'world';\n
      \n

      First, create the file hello.cc:

      \n
      // hello.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::NewStringType;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid Method(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  args.GetReturnValue().Set(String::NewFromUtf8(\n      isolate, \"world\", NewStringType::kNormal).ToLocalChecked());\n}\n\nvoid Initialize(Local<Object> exports) {\n  NODE_SET_METHOD(exports, \"hello\", Method);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)\n\n}  // namespace demo\n
      \n

      All Node.js addons must export an initialization function following\nthe pattern:

      \n
      void Initialize(Local<Object> exports);\nNODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)\n
      \n

      There is no semi-colon after NODE_MODULE as it's not a function (see\nnode.h).

      \n

      The module_name must match the filename of the final binary (excluding\nthe .node suffix).

      \n

      In the hello.cc example, then, the initialization function is Initialize\nand the addon module name is addon.

      \n

      When building addons with node-gyp, using the macro NODE_GYP_MODULE_NAME as\nthe first parameter of NODE_MODULE() will ensure that the name of the final\nbinary will be passed to NODE_MODULE().

      ", + "desc": "

      This \"Hello world\" example is a simple addon, written in C++, that is the\nequivalent of the following JavaScript code:

      \n
      module.exports.hello = () => 'world';\n
      \n

      First, create the file hello.cc:

      \n
      // hello.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid Method(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  args.GetReturnValue().Set(String::NewFromUtf8(\n      isolate, \"world\").ToLocalChecked());\n}\n\nvoid Initialize(Local<Object> exports) {\n  NODE_SET_METHOD(exports, \"hello\", Method);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)\n\n}  // namespace demo\n
      \n

      All Node.js addons must export an initialization function following\nthe pattern:

      \n
      void Initialize(Local<Object> exports);\nNODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)\n
      \n

      There is no semi-colon after NODE_MODULE as it's not a function (see\nnode.h).

      \n

      The module_name must match the filename of the final binary (excluding\nthe .node suffix).

      \n

      In the hello.cc example, then, the initialization function is Initialize\nand the addon module name is addon.

      \n

      When building addons with node-gyp, using the macro NODE_GYP_MODULE_NAME as\nthe first parameter of NODE_MODULE() will ensure that the name of the final\nbinary will be passed to NODE_MODULE().

      ", "modules": [ { "textRaw": "Context-aware addons", "name": "context-aware_addons", - "desc": "

      There are environments in which Node.js addons may need to be loaded multiple\ntimes in multiple contexts. For example, the Electron runtime runs multiple\ninstances of Node.js in a single process. Each instance will have its own\nrequire() cache, and thus each instance will need a native addon to behave\ncorrectly when loaded via require(). From the addon's perspective, this means\nthat it must support multiple initializations.

      \n

      A context-aware addon can be constructed by using the macro\nNODE_MODULE_INITIALIZER, which expands to the name of a function which Node.js\nwill expect to find when it loads an addon. An addon can thus be initialized as\nin the following example:

      \n
      using namespace v8;\n\nextern \"C\" NODE_MODULE_EXPORT void\nNODE_MODULE_INITIALIZER(Local<Object> exports,\n                        Local<Value> module,\n                        Local<Context> context) {\n  /* Perform addon initialization steps here. */\n}\n
      \n

      Another option is to use the macro NODE_MODULE_INIT(), which will also\nconstruct a context-aware addon. Unlike NODE_MODULE(), which is used to\nconstruct an addon around a given addon initializer function,\nNODE_MODULE_INIT() serves as the declaration of such an initializer to be\nfollowed by a function body.

      \n

      The following three variables may be used inside the function body following an\ninvocation of NODE_MODULE_INIT():

      \n
        \n
      • Local<Object> exports,
      • \n
      • Local<Value> module, and
      • \n
      • Local<Context> context
      • \n
      \n

      The choice to build a context-aware addon carries with it the responsibility of\ncarefully managing global static data. Since the addon may be loaded multiple\ntimes, potentially even from different threads, any global static data stored\nin the addon must be properly protected, and must not contain any persistent\nreferences to JavaScript objects. The reason for this is that JavaScript\nobjects are only valid in one context, and will likely cause a crash when\naccessed from the wrong context or from a different thread than the one on which\nthey were created.

      \n

      The context-aware addon can be structured to avoid global static data by\nperforming the following steps:

      \n
        \n
      • Define a class which will hold per-addon-instance data and which has a static\nmember of the form\n
        static void DeleteInstance(void* data) {\n  // Cast `data` to an instance of the class and delete it.\n}\n
        \n
      • \n
      • Heap-allocate an instance of this class in the addon initializer. This can be\naccomplished using the new keyword.
      • \n
      • Call node::AddEnvironmentCleanupHook(), passing it the above-created\ninstance and a pointer to DeleteInstance(). This will ensure the instance is\ndeleted when the environment is torn down.
      • \n
      • Store the instance of the class in a v8::External, and
      • \n
      • Pass the v8::External to all methods exposed to JavaScript by passing it\nto v8::FunctionTemplate::New() or v8::Function::New() which creates the\nnative-backed JavaScript functions. The third parameter of\nv8::FunctionTemplate::New() or v8::Function::New() accepts the\nv8::External and makes it available in the native callback using the\nv8::FunctionCallbackInfo::Data() method.
      • \n
      \n

      This will ensure that the per-addon-instance data reaches each binding that can\nbe called from JavaScript. The per-addon-instance data must also be passed into\nany asynchronous callbacks the addon may create.

      \n

      The following example illustrates the implementation of a context-aware addon:

      \n
      #include <node.h>\n\nusing namespace v8;\n\nclass AddonData {\n public:\n  explicit AddonData(Isolate* isolate):\n      call_count(0) {\n    // Ensure this per-addon-instance data is deleted at environment cleanup.\n    node::AddEnvironmentCleanupHook(isolate, DeleteInstance, this);\n  }\n\n  // Per-addon data.\n  int call_count;\n\n  static void DeleteInstance(void* data) {\n    delete static_cast<AddonData*>(data);\n  }\n};\n\nstatic void Method(const v8::FunctionCallbackInfo<v8::Value>& info) {\n  // Retrieve the per-addon-instance data.\n  AddonData* data =\n      reinterpret_cast<AddonData*>(info.Data().As<External>()->Value());\n  data->call_count++;\n  info.GetReturnValue().Set((double)data->call_count);\n}\n\n// Initialize this addon to be context-aware.\nNODE_MODULE_INIT(/* exports, module, context */) {\n  Isolate* isolate = context->GetIsolate();\n\n  // Create a new instance of `AddonData` for this instance of the addon and\n  // tie its life cycle to that of the Node.js environment.\n  AddonData* data = new AddonData(isolate);\n\n  // Wrap the data in a `v8::External` so we can pass it to the method we\n  // expose.\n  Local<External> external = External::New(isolate, data);\n\n  // Expose the method `Method` to JavaScript, and make sure it receives the\n  // per-addon-instance data we created above by passing `external` as the\n  // third parameter to the `FunctionTemplate` constructor.\n  exports->Set(context,\n               String::NewFromUtf8(isolate, \"method\", NewStringType::kNormal)\n                  .ToLocalChecked(),\n               FunctionTemplate::New(isolate, Method, external)\n                  ->GetFunction(context).ToLocalChecked()).FromJust();\n}\n
      ", + "desc": "

      There are environments in which Node.js addons may need to be loaded multiple\ntimes in multiple contexts. For example, the Electron runtime runs multiple\ninstances of Node.js in a single process. Each instance will have its own\nrequire() cache, and thus each instance will need a native addon to behave\ncorrectly when loaded via require(). This means that the addon\nmust support multiple initializations.

      \n

      A context-aware addon can be constructed by using the macro\nNODE_MODULE_INITIALIZER, which expands to the name of a function which Node.js\nwill expect to find when it loads an addon. An addon can thus be initialized as\nin the following example:

      \n
      using namespace v8;\n\nextern \"C\" NODE_MODULE_EXPORT void\nNODE_MODULE_INITIALIZER(Local<Object> exports,\n                        Local<Value> module,\n                        Local<Context> context) {\n  /* Perform addon initialization steps here. */\n}\n
      \n

      Another option is to use the macro NODE_MODULE_INIT(), which will also\nconstruct a context-aware addon. Unlike NODE_MODULE(), which is used to\nconstruct an addon around a given addon initializer function,\nNODE_MODULE_INIT() serves as the declaration of such an initializer to be\nfollowed by a function body.

      \n

      The following three variables may be used inside the function body following an\ninvocation of NODE_MODULE_INIT():

      \n
        \n
      • Local<Object> exports,
      • \n
      • Local<Value> module, and
      • \n
      • Local<Context> context
      • \n
      \n

      The choice to build a context-aware addon carries with it the responsibility of\ncarefully managing global static data. Since the addon may be loaded multiple\ntimes, potentially even from different threads, any global static data stored\nin the addon must be properly protected, and must not contain any persistent\nreferences to JavaScript objects. The reason for this is that JavaScript\nobjects are only valid in one context, and will likely cause a crash when\naccessed from the wrong context or from a different thread than the one on which\nthey were created.

      \n

      The context-aware addon can be structured to avoid global static data by\nperforming the following steps:

      \n
        \n
      • Define a class which will hold per-addon-instance data and which has a static\nmember of the form\n
        static void DeleteInstance(void* data) {\n  // Cast `data` to an instance of the class and delete it.\n}\n
        \n
      • \n
      • Heap-allocate an instance of this class in the addon initializer. This can be\naccomplished using the new keyword.
      • \n
      • Call node::AddEnvironmentCleanupHook(), passing it the above-created\ninstance and a pointer to DeleteInstance(). This will ensure the instance is\ndeleted when the environment is torn down.
      • \n
      • Store the instance of the class in a v8::External, and
      • \n
      • Pass the v8::External to all methods exposed to JavaScript by passing it\nto v8::FunctionTemplate::New() or v8::Function::New() which creates the\nnative-backed JavaScript functions. The third parameter of\nv8::FunctionTemplate::New() or v8::Function::New() accepts the\nv8::External and makes it available in the native callback using the\nv8::FunctionCallbackInfo::Data() method.
      • \n
      \n

      This will ensure that the per-addon-instance data reaches each binding that can\nbe called from JavaScript. The per-addon-instance data must also be passed into\nany asynchronous callbacks the addon may create.

      \n

      The following example illustrates the implementation of a context-aware addon:

      \n
      #include <node.h>\n\nusing namespace v8;\n\nclass AddonData {\n public:\n  explicit AddonData(Isolate* isolate):\n      call_count(0) {\n    // Ensure this per-addon-instance data is deleted at environment cleanup.\n    node::AddEnvironmentCleanupHook(isolate, DeleteInstance, this);\n  }\n\n  // Per-addon data.\n  int call_count;\n\n  static void DeleteInstance(void* data) {\n    delete static_cast<AddonData*>(data);\n  }\n};\n\nstatic void Method(const v8::FunctionCallbackInfo<v8::Value>& info) {\n  // Retrieve the per-addon-instance data.\n  AddonData* data =\n      reinterpret_cast<AddonData*>(info.Data().As<External>()->Value());\n  data->call_count++;\n  info.GetReturnValue().Set((double)data->call_count);\n}\n\n// Initialize this addon to be context-aware.\nNODE_MODULE_INIT(/* exports, module, context */) {\n  Isolate* isolate = context->GetIsolate();\n\n  // Create a new instance of `AddonData` for this instance of the addon and\n  // tie its life cycle to that of the Node.js environment.\n  AddonData* data = new AddonData(isolate);\n\n  // Wrap the data in a `v8::External` so we can pass it to the method we\n  // expose.\n  Local<External> external = External::New(isolate, data);\n\n  // Expose the method `Method` to JavaScript, and make sure it receives the\n  // per-addon-instance data we created above by passing `external` as the\n  // third parameter to the `FunctionTemplate` constructor.\n  exports->Set(context,\n               String::NewFromUtf8(isolate, \"method\").ToLocalChecked(),\n               FunctionTemplate::New(isolate, Method, external)\n                  ->GetFunction(context).ToLocalChecked()).FromJust();\n}\n
      ", "modules": [ { "textRaw": "Worker support", @@ -26,13 +26,13 @@ "meta": { "changes": [ { - "version": "v12.19.0", + "version": "v14.8.0", "pr-url": "https://github.com/nodejs/node/pull/34572", "description": "Cleanup hooks may now be asynchronous." } ] }, - "desc": "

      In order to be loaded from multiple Node.js environments,\nsuch as a main thread and a Worker thread, an add-on needs to either:

      \n
        \n
      • Be an N-API addon, or
      • \n
      • Be declared as context-aware using NODE_MODULE_INIT() as described above
      • \n
      \n

      In order to support Worker threads, addons need to clean up any resources\nthey may have allocated when such a thread exists. This can be achieved through\nthe usage of the AddEnvironmentCleanupHook() function:

      \n
      void AddEnvironmentCleanupHook(v8::Isolate* isolate,\n                               void (*fun)(void* arg),\n                               void* arg);\n
      \n

      This function adds a hook that will run before a given Node.js instance shuts\ndown. If necessary, such hooks can be removed before they are run using\nRemoveEnvironmentCleanupHook(), which has the same signature. Callbacks are\nrun in last-in first-out order.

      \n

      If necessary, there is an additional pair of AddEnvironmentCleanupHook()\nand RemoveEnvironmentCleanupHook() overloads, where the cleanup hook takes a\ncallback function. This can be used for shutting down asynchronous resources,\nsuch as any libuv handles registered by the addon.

      \n

      The following addon.cc uses AddEnvironmentCleanupHook:

      \n
      // addon.cc\n#include <assert.h>\n#include <stdlib.h>\n#include <node.h>\n\nusing node::AddEnvironmentCleanupHook;\nusing v8::HandleScope;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\n\n// Note: In a real-world application, do not rely on static/global data.\nstatic char cookie[] = \"yum yum\";\nstatic int cleanup_cb1_called = 0;\nstatic int cleanup_cb2_called = 0;\n\nstatic void cleanup_cb1(void* arg) {\n  Isolate* isolate = static_cast<Isolate*>(arg);\n  HandleScope scope(isolate);\n  Local<Object> obj = Object::New(isolate);\n  assert(!obj.IsEmpty());  // assert VM is still alive\n  assert(obj->IsObject());\n  cleanup_cb1_called++;\n}\n\nstatic void cleanup_cb2(void* arg) {\n  assert(arg == static_cast<void*>(cookie));\n  cleanup_cb2_called++;\n}\n\nstatic void sanity_check(void*) {\n  assert(cleanup_cb1_called == 1);\n  assert(cleanup_cb2_called == 1);\n}\n\n// Initialize this addon to be context-aware.\nNODE_MODULE_INIT(/* exports, module, context */) {\n  Isolate* isolate = context->GetIsolate();\n\n  AddEnvironmentCleanupHook(isolate, sanity_check, nullptr);\n  AddEnvironmentCleanupHook(isolate, cleanup_cb2, cookie);\n  AddEnvironmentCleanupHook(isolate, cleanup_cb1, isolate);\n}\n
      \n

      Test in JavaScript by running:

      \n
      // test.js\nrequire('./build/Release/addon');\n
      ", + "desc": "

      In order to be loaded from multiple Node.js environments,\nsuch as a main thread and a Worker thread, an add-on needs to either:

      \n
        \n
      • Be an Node-API addon, or
      • \n
      • Be declared as context-aware using NODE_MODULE_INIT() as described above
      • \n
      \n

      In order to support Worker threads, addons need to clean up any resources\nthey may have allocated when such a thread exists. This can be achieved through\nthe usage of the AddEnvironmentCleanupHook() function:

      \n
      void AddEnvironmentCleanupHook(v8::Isolate* isolate,\n                               void (*fun)(void* arg),\n                               void* arg);\n
      \n

      This function adds a hook that will run before a given Node.js instance shuts\ndown. If necessary, such hooks can be removed before they are run using\nRemoveEnvironmentCleanupHook(), which has the same signature. Callbacks are\nrun in last-in first-out order.

      \n

      If necessary, there is an additional pair of AddEnvironmentCleanupHook()\nand RemoveEnvironmentCleanupHook() overloads, where the cleanup hook takes a\ncallback function. This can be used for shutting down asynchronous resources,\nsuch as any libuv handles registered by the addon.

      \n

      The following addon.cc uses AddEnvironmentCleanupHook:

      \n
      // addon.cc\n#include <node.h>\n#include <assert.h>\n#include <stdlib.h>\n\nusing node::AddEnvironmentCleanupHook;\nusing v8::HandleScope;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\n\n// Note: In a real-world application, do not rely on static/global data.\nstatic char cookie[] = \"yum yum\";\nstatic int cleanup_cb1_called = 0;\nstatic int cleanup_cb2_called = 0;\n\nstatic void cleanup_cb1(void* arg) {\n  Isolate* isolate = static_cast<Isolate*>(arg);\n  HandleScope scope(isolate);\n  Local<Object> obj = Object::New(isolate);\n  assert(!obj.IsEmpty());  // assert VM is still alive\n  assert(obj->IsObject());\n  cleanup_cb1_called++;\n}\n\nstatic void cleanup_cb2(void* arg) {\n  assert(arg == static_cast<void*>(cookie));\n  cleanup_cb2_called++;\n}\n\nstatic void sanity_check(void*) {\n  assert(cleanup_cb1_called == 1);\n  assert(cleanup_cb2_called == 1);\n}\n\n// Initialize this addon to be context-aware.\nNODE_MODULE_INIT(/* exports, module, context */) {\n  Isolate* isolate = context->GetIsolate();\n\n  AddEnvironmentCleanupHook(isolate, sanity_check, nullptr);\n  AddEnvironmentCleanupHook(isolate, cleanup_cb2, cookie);\n  AddEnvironmentCleanupHook(isolate, cleanup_cb1, isolate);\n}\n
      \n

      Test in JavaScript by running:

      \n
      // test.js\nrequire('./build/Release/addon');\n
      ", "type": "module", "displayName": "Worker support" } @@ -50,7 +50,7 @@ { "textRaw": "Linking to libraries included with Node.js", "name": "linking_to_libraries_included_with_node.js", - "desc": "

      Node.js uses statically linked libraries such as V8, libuv and OpenSSL. All\naddons are required to link to V8 and may link to any of the other dependencies\nas well. Typically, this is as simple as including the appropriate\n#include <...> statements (e.g. #include <v8.h>) and node-gyp will locate\nthe appropriate headers automatically. However, there are a few caveats to be\naware of:

      \n
        \n
      • \n

        When node-gyp runs, it will detect the specific release version of Node.js\nand download either the full source tarball or just the headers. If the full\nsource is downloaded, addons will have complete access to the full set of\nNode.js dependencies. However, if only the Node.js headers are downloaded, then\nonly the symbols exported by Node.js will be available.

        \n
      • \n
      • \n

        node-gyp can be run using the --nodedir flag pointing at a local Node.js\nsource image. Using this option, the addon will have access to the full set of\ndependencies.

        \n
      • \n
      ", + "desc": "

      Node.js uses statically linked libraries such as V8, libuv and OpenSSL. All\naddons are required to link to V8 and may link to any of the other dependencies\nas well. Typically, this is as simple as including the appropriate\n#include <...> statements (e.g. #include <v8.h>) and node-gyp will locate\nthe appropriate headers automatically. However, there are a few caveats to be\naware of:

      \n
        \n
      • \n

        When node-gyp runs, it will detect the specific release version of Node.js\nand download either the full source tarball or just the headers. If the full\nsource is downloaded, addons will have complete access to the full set of\nNode.js dependencies. However, if only the Node.js headers are downloaded,\nthen only the symbols exported by Node.js will be available.

        \n
      • \n
      • \n

        node-gyp can be run using the --nodedir flag pointing at a local Node.js\nsource image. Using this option, the addon will have access to the full set of\ndependencies.

        \n
      • \n
      ", "type": "module", "displayName": "Linking to libraries included with Node.js" }, @@ -68,18 +68,18 @@ { "textRaw": "Native abstractions for Node.js", "name": "native_abstractions_for_node.js", - "desc": "

      Each of the examples illustrated in this document directly use the\nNode.js and V8 APIs for implementing addons. The V8 API can, and has, changed\ndramatically from one V8 release to the next (and one major Node.js release to\nthe next). With each change, addons may need to be updated and recompiled in\norder to continue functioning. The Node.js release schedule is designed to\nminimize the frequency and impact of such changes but there is little that\nNode.js can do to ensure stability of the V8 APIs.

      \n

      The Native Abstractions for Node.js (or nan) provide a set of tools that\naddon developers are recommended to use to keep compatibility between past and\nfuture releases of V8 and Node.js. See the nan examples for an\nillustration of how it can be used.

      ", + "desc": "

      Each of the examples illustrated in this document directly use the\nNode.js and V8 APIs for implementing addons. The V8 API can, and has, changed\ndramatically from one V8 release to the next (and one major Node.js release to\nthe next). With each change, addons may need to be updated and recompiled in\norder to continue functioning. The Node.js release schedule is designed to\nminimize the frequency and impact of such changes but there is little that\nNode.js can do to ensure stability of the V8 APIs.

      \n

      The Native Abstractions for Node.js (or nan) provide a set of tools that\naddon developers are recommended to use to keep compatibility between past and\nfuture releases of V8 and Node.js. See the nan examples for an\nillustration of how it can be used.

      ", "type": "misc", "displayName": "Native abstractions for Node.js" }, { - "textRaw": "N-API", - "name": "n-api", + "textRaw": "Node-API", + "name": "node-api", "stability": 2, "stabilityText": "Stable", - "desc": "

      N-API is an API for building native addons. It is independent from\nthe underlying JavaScript runtime (e.g. V8) and is maintained as part of\nNode.js itself. This API will be Application Binary Interface (ABI) stable\nacross versions of Node.js. It is intended to insulate addons from\nchanges in the underlying JavaScript engine and allow modules\ncompiled for one version to run on later versions of Node.js without\nrecompilation. Addons are built/packaged with the same approach/tools\noutlined in this document (node-gyp, etc.). The only difference is the\nset of APIs that are used by the native code. Instead of using the V8\nor Native Abstractions for Node.js APIs, the functions available\nin the N-API are used.

      \n

      Creating and maintaining an addon that benefits from the ABI stability\nprovided by N-API carries with it certain\nimplementation considerations.

      \n

      To use N-API in the above \"Hello world\" example, replace the content of\nhello.cc with the following. All other instructions remain the same.

      \n
      // hello.cc using N-API\n#include <node_api.h>\n\nnamespace demo {\n\nnapi_value Method(napi_env env, napi_callback_info args) {\n  napi_value greeting;\n  napi_status status;\n\n  status = napi_create_string_utf8(env, \"world\", NAPI_AUTO_LENGTH, &greeting);\n  if (status != napi_ok) return nullptr;\n  return greeting;\n}\n\nnapi_value init(napi_env env, napi_value exports) {\n  napi_status status;\n  napi_value fn;\n\n  status = napi_create_function(env, nullptr, 0, Method, nullptr, &fn);\n  if (status != napi_ok) return nullptr;\n\n  status = napi_set_named_property(env, exports, \"hello\", fn);\n  if (status != napi_ok) return nullptr;\n  return exports;\n}\n\nNAPI_MODULE(NODE_GYP_MODULE_NAME, init)\n\n}  // namespace demo\n
      \n

      The functions available and how to use them are documented in\nC/C++ addons with N-API.

      ", + "desc": "

      Node-API is an API for building native addons. It is independent from\nthe underlying JavaScript runtime (e.g. V8) and is maintained as part of\nNode.js itself. This API will be Application Binary Interface (ABI) stable\nacross versions of Node.js. It is intended to insulate addons from\nchanges in the underlying JavaScript engine and allow modules\ncompiled for one version to run on later versions of Node.js without\nrecompilation. Addons are built/packaged with the same approach/tools\noutlined in this document (node-gyp, etc.). The only difference is the\nset of APIs that are used by the native code. Instead of using the V8\nor Native Abstractions for Node.js APIs, the functions available\nin the Node-API are used.

      \n

      Creating and maintaining an addon that benefits from the ABI stability\nprovided by Node-API carries with it certain\nimplementation considerations.

      \n

      To use Node-API in the above \"Hello world\" example, replace the content of\nhello.cc with the following. All other instructions remain the same.

      \n
      // hello.cc using Node-API\n#include <node_api.h>\n\nnamespace demo {\n\nnapi_value Method(napi_env env, napi_callback_info args) {\n  napi_value greeting;\n  napi_status status;\n\n  status = napi_create_string_utf8(env, \"world\", NAPI_AUTO_LENGTH, &greeting);\n  if (status != napi_ok) return nullptr;\n  return greeting;\n}\n\nnapi_value init(napi_env env, napi_value exports) {\n  napi_status status;\n  napi_value fn;\n\n  status = napi_create_function(env, nullptr, 0, Method, nullptr, &fn);\n  if (status != napi_ok) return nullptr;\n\n  status = napi_set_named_property(env, exports, \"hello\", fn);\n  if (status != napi_ok) return nullptr;\n  return exports;\n}\n\nNAPI_MODULE(NODE_GYP_MODULE_NAME, init)\n\n}  // namespace demo\n
      \n

      The functions available and how to use them are documented in\nC/C++ addons with Node-API.

      ", "type": "misc", - "displayName": "N-API" + "displayName": "Node-API" }, { "textRaw": "Addon examples", @@ -89,49 +89,49 @@ { "textRaw": "Function arguments", "name": "function_arguments", - "desc": "

      Addons will typically expose objects and functions that can be accessed from\nJavaScript running within Node.js. When functions are invoked from JavaScript,\nthe input arguments and return value must be mapped to and from the C/C++\ncode.

      \n

      The following example illustrates how to read function arguments passed from\nJavaScript and how to return a result:

      \n
      // addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Exception;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::NewStringType;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\n// This is the implementation of the \"add\" method\n// Input arguments are passed using the\n// const FunctionCallbackInfo<Value>& args struct\nvoid Add(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  // Check the number of arguments passed.\n  if (args.Length() < 2) {\n    // Throw an Error that is passed back to JavaScript\n    isolate->ThrowException(Exception::TypeError(\n        String::NewFromUtf8(isolate,\n                            \"Wrong number of arguments\",\n                            NewStringType::kNormal).ToLocalChecked()));\n    return;\n  }\n\n  // Check the argument types\n  if (!args[0]->IsNumber() || !args[1]->IsNumber()) {\n    isolate->ThrowException(Exception::TypeError(\n        String::NewFromUtf8(isolate,\n                            \"Wrong arguments\",\n                            NewStringType::kNormal).ToLocalChecked()));\n    return;\n  }\n\n  // Perform the operation\n  double value =\n      args[0].As<Number>()->Value() + args[1].As<Number>()->Value();\n  Local<Number> num = Number::New(isolate, value);\n\n  // Set the return value (using the passed in\n  // FunctionCallbackInfo<Value>&)\n  args.GetReturnValue().Set(num);\n}\n\nvoid Init(Local<Object> exports) {\n  NODE_SET_METHOD(exports, \"add\", Add);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, Init)\n\n}  // namespace demo\n
      \n

      Once compiled, the example addon can be required and used from within Node.js:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\nconsole.log('This should be eight:', addon.add(3, 5));\n
      ", + "desc": "

      Addons will typically expose objects and functions that can be accessed from\nJavaScript running within Node.js. When functions are invoked from JavaScript,\nthe input arguments and return value must be mapped to and from the C/C++\ncode.

      \n

      The following example illustrates how to read function arguments passed from\nJavaScript and how to return a result:

      \n
      // addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Exception;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\n// This is the implementation of the \"add\" method\n// Input arguments are passed using the\n// const FunctionCallbackInfo<Value>& args struct\nvoid Add(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  // Check the number of arguments passed.\n  if (args.Length() < 2) {\n    // Throw an Error that is passed back to JavaScript\n    isolate->ThrowException(Exception::TypeError(\n        String::NewFromUtf8(isolate,\n                            \"Wrong number of arguments\").ToLocalChecked()));\n    return;\n  }\n\n  // Check the argument types\n  if (!args[0]->IsNumber() || !args[1]->IsNumber()) {\n    isolate->ThrowException(Exception::TypeError(\n        String::NewFromUtf8(isolate,\n                            \"Wrong arguments\").ToLocalChecked()));\n    return;\n  }\n\n  // Perform the operation\n  double value =\n      args[0].As<Number>()->Value() + args[1].As<Number>()->Value();\n  Local<Number> num = Number::New(isolate, value);\n\n  // Set the return value (using the passed in\n  // FunctionCallbackInfo<Value>&)\n  args.GetReturnValue().Set(num);\n}\n\nvoid Init(Local<Object> exports) {\n  NODE_SET_METHOD(exports, \"add\", Add);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, Init)\n\n}  // namespace demo\n
      \n

      Once compiled, the example addon can be required and used from within Node.js:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\nconsole.log('This should be eight:', addon.add(3, 5));\n
      ", "type": "module", "displayName": "Function arguments" }, { "textRaw": "Callbacks", "name": "callbacks", - "desc": "

      It is common practice within addons to pass JavaScript functions to a C++\nfunction and execute them from there. The following example illustrates how\nto invoke such callbacks:

      \n
      // addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Context;\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::NewStringType;\nusing v8::Null;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid RunCallback(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n  Local<Function> cb = Local<Function>::Cast(args[0]);\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = {\n      String::NewFromUtf8(isolate,\n                          \"hello world\",\n                          NewStringType::kNormal).ToLocalChecked() };\n  cb->Call(context, Null(isolate), argc, argv).ToLocalChecked();\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, \"exports\", RunCallback);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, Init)\n\n}  // namespace demo\n
      \n

      This example uses a two-argument form of Init() that receives the full\nmodule object as the second argument. This allows the addon to completely\noverwrite exports with a single function instead of adding the function as a\nproperty of exports.

      \n

      To test it, run the following JavaScript:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\naddon((msg) => {\n  console.log(msg);\n// Prints: 'hello world'\n});\n
      \n

      In this example, the callback function is invoked synchronously.

      ", + "desc": "

      It is common practice within addons to pass JavaScript functions to a C++\nfunction and execute them from there. The following example illustrates how\nto invoke such callbacks:

      \n
      // addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Context;\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Null;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid RunCallback(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n  Local<Function> cb = Local<Function>::Cast(args[0]);\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = {\n      String::NewFromUtf8(isolate,\n                          \"hello world\").ToLocalChecked() };\n  cb->Call(context, Null(isolate), argc, argv).ToLocalChecked();\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, \"exports\", RunCallback);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, Init)\n\n}  // namespace demo\n
      \n

      This example uses a two-argument form of Init() that receives the full\nmodule object as the second argument. This allows the addon to completely\noverwrite exports with a single function instead of adding the function as a\nproperty of exports.

      \n

      To test it, run the following JavaScript:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\naddon((msg) => {\n  console.log(msg);\n// Prints: 'hello world'\n});\n
      \n

      In this example, the callback function is invoked synchronously.

      ", "type": "module", "displayName": "Callbacks" }, { "textRaw": "Object factory", "name": "object_factory", - "desc": "

      Addons can create and return new objects from within a C++ function as\nillustrated in the following example. An object is created and returned with a\nproperty msg that echoes the string passed to createObject():

      \n
      // addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Context;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::NewStringType;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  Local<Object> obj = Object::New(isolate);\n  obj->Set(context,\n           String::NewFromUtf8(isolate,\n                               \"msg\",\n                               NewStringType::kNormal).ToLocalChecked(),\n                               args[0]->ToString(context).ToLocalChecked())\n           .FromJust();\n\n  args.GetReturnValue().Set(obj);\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, \"exports\", CreateObject);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, Init)\n\n}  // namespace demo\n
      \n

      To test it in JavaScript:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\nconst obj1 = addon('hello');\nconst obj2 = addon('world');\nconsole.log(obj1.msg, obj2.msg);\n// Prints: 'hello world'\n
      ", + "desc": "

      Addons can create and return new objects from within a C++ function as\nillustrated in the following example. An object is created and returned with a\nproperty msg that echoes the string passed to createObject():

      \n
      // addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Context;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  Local<Object> obj = Object::New(isolate);\n  obj->Set(context,\n           String::NewFromUtf8(isolate,\n                               \"msg\").ToLocalChecked(),\n                               args[0]->ToString(context).ToLocalChecked())\n           .FromJust();\n\n  args.GetReturnValue().Set(obj);\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, \"exports\", CreateObject);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, Init)\n\n}  // namespace demo\n
      \n

      To test it in JavaScript:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\nconst obj1 = addon('hello');\nconst obj2 = addon('world');\nconsole.log(obj1.msg, obj2.msg);\n// Prints: 'hello world'\n
      ", "type": "module", "displayName": "Object factory" }, { "textRaw": "Function factory", "name": "function_factory", - "desc": "

      Another common scenario is creating JavaScript functions that wrap C++\nfunctions and returning those back to JavaScript:

      \n
      // addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Context;\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::NewStringType;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid MyFunction(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  args.GetReturnValue().Set(String::NewFromUtf8(\n      isolate, \"hello world\", NewStringType::kNormal).ToLocalChecked());\n}\n\nvoid CreateFunction(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  Local<Context> context = isolate->GetCurrentContext();\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction);\n  Local<Function> fn = tpl->GetFunction(context).ToLocalChecked();\n\n  // omit this to make it anonymous\n  fn->SetName(String::NewFromUtf8(\n      isolate, \"theFunction\", NewStringType::kNormal).ToLocalChecked());\n\n  args.GetReturnValue().Set(fn);\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, \"exports\", CreateFunction);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, Init)\n\n}  // namespace demo\n
      \n

      To test:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\nconst fn = addon();\nconsole.log(fn());\n// Prints: 'hello world'\n
      ", + "desc": "

      Another common scenario is creating JavaScript functions that wrap C++\nfunctions and returning those back to JavaScript:

      \n
      // addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Context;\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid MyFunction(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  args.GetReturnValue().Set(String::NewFromUtf8(\n      isolate, \"hello world\").ToLocalChecked());\n}\n\nvoid CreateFunction(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  Local<Context> context = isolate->GetCurrentContext();\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction);\n  Local<Function> fn = tpl->GetFunction(context).ToLocalChecked();\n\n  // omit this to make it anonymous\n  fn->SetName(String::NewFromUtf8(\n      isolate, \"theFunction\").ToLocalChecked());\n\n  args.GetReturnValue().Set(fn);\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, \"exports\", CreateFunction);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, Init)\n\n}  // namespace demo\n
      \n

      To test:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\nconst fn = addon();\nconsole.log(fn());\n// Prints: 'hello world'\n
      ", "type": "module", "displayName": "Function factory" }, { "textRaw": "Wrapping C++ objects", "name": "wrapping_c++_objects", - "desc": "

      It is also possible to wrap C++ objects/classes in a way that allows new\ninstances to be created using the JavaScript new operator:

      \n
      // addon.cc\n#include <node.h>\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing v8::Local;\nusing v8::Object;\n\nvoid InitAll(Local<Object> exports) {\n  MyObject::Init(exports);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)\n\n}  // namespace demo\n
      \n

      Then, in myobject.h, the wrapper class inherits from node::ObjectWrap:

      \n
      // myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Local<v8::Object> exports);\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n  double value_;\n};\n\n}  // namespace demo\n\n#endif\n
      \n

      In myobject.cc, implement the various methods that are to be exposed.\nBelow, the method plusOne() is exposed by adding it to the constructor's\nprototype:

      \n
      // myobject.cc\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing v8::Context;\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::NewStringType;\nusing v8::Number;\nusing v8::Object;\nusing v8::ObjectTemplate;\nusing v8::String;\nusing v8::Value;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Local<Object> exports) {\n  Isolate* isolate = exports->GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  Local<ObjectTemplate> addon_data_tpl = ObjectTemplate::New(isolate);\n  addon_data_tpl->SetInternalFieldCount(1);  // 1 field for the MyObject::New()\n  Local<Object> addon_data =\n      addon_data_tpl->NewInstance(context).ToLocalChecked();\n\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New, addon_data);\n  tpl->SetClassName(String::NewFromUtf8(\n      isolate, \"MyObject\", NewStringType::kNormal).ToLocalChecked());\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  // Prototype\n  NODE_SET_PROTOTYPE_METHOD(tpl, \"plusOne\", PlusOne);\n\n  Local<Function> constructor = tpl->GetFunction(context).ToLocalChecked();\n  addon_data->SetInternalField(0, constructor);\n  exports->Set(context, String::NewFromUtf8(\n      isolate, \"MyObject\", NewStringType::kNormal).ToLocalChecked(),\n               constructor).FromJust();\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ?\n        0 : args[0]->NumberValue(context).FromMaybe(0);\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons =\n        args.Data().As<Object>()->GetInternalField(0).As<Function>();\n    Local<Object> result =\n        cons->NewInstance(context, argc, argv).ToLocalChecked();\n    args.GetReturnValue().Set(result);\n  }\n}\n\nvoid MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());\n  obj->value_ += 1;\n\n  args.GetReturnValue().Set(Number::New(isolate, obj->value_));\n}\n\n}  // namespace demo\n
      \n

      To build this example, the myobject.cc file must be added to the\nbinding.gyp:

      \n
      {\n  \"targets\": [\n    {\n      \"target_name\": \"addon\",\n      \"sources\": [\n        \"addon.cc\",\n        \"myobject.cc\"\n      ]\n    }\n  ]\n}\n
      \n

      Test it with:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\nconst obj = new addon.MyObject(10);\nconsole.log(obj.plusOne());\n// Prints: 11\nconsole.log(obj.plusOne());\n// Prints: 12\nconsole.log(obj.plusOne());\n// Prints: 13\n
      \n

      The destructor for a wrapper object will run when the object is\ngarbage-collected. For destructor testing, there are command-line flags that\ncan be used to make it possible to force garbage collection. These flags are\nprovided by the underlying V8 JavaScript engine. They are subject to change\nor removal at any time. They are not documented by Node.js or V8, and they\nshould never be used outside of testing.

      ", + "desc": "

      It is also possible to wrap C++ objects/classes in a way that allows new\ninstances to be created using the JavaScript new operator:

      \n
      // addon.cc\n#include <node.h>\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing v8::Local;\nusing v8::Object;\n\nvoid InitAll(Local<Object> exports) {\n  MyObject::Init(exports);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)\n\n}  // namespace demo\n
      \n

      Then, in myobject.h, the wrapper class inherits from node::ObjectWrap:

      \n
      // myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Local<v8::Object> exports);\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n  double value_;\n};\n\n}  // namespace demo\n\n#endif\n
      \n

      In myobject.cc, implement the various methods that are to be exposed.\nBelow, the method plusOne() is exposed by adding it to the constructor's\nprototype:

      \n
      // myobject.cc\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing v8::Context;\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::ObjectTemplate;\nusing v8::String;\nusing v8::Value;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Local<Object> exports) {\n  Isolate* isolate = exports->GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  Local<ObjectTemplate> addon_data_tpl = ObjectTemplate::New(isolate);\n  addon_data_tpl->SetInternalFieldCount(1);  // 1 field for the MyObject::New()\n  Local<Object> addon_data =\n      addon_data_tpl->NewInstance(context).ToLocalChecked();\n\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New, addon_data);\n  tpl->SetClassName(String::NewFromUtf8(isolate, \"MyObject\").ToLocalChecked());\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  // Prototype\n  NODE_SET_PROTOTYPE_METHOD(tpl, \"plusOne\", PlusOne);\n\n  Local<Function> constructor = tpl->GetFunction(context).ToLocalChecked();\n  addon_data->SetInternalField(0, constructor);\n  exports->Set(context, String::NewFromUtf8(\n      isolate, \"MyObject\").ToLocalChecked(),\n      constructor).FromJust();\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ?\n        0 : args[0]->NumberValue(context).FromMaybe(0);\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons =\n        args.Data().As<Object>()->GetInternalField(0).As<Function>();\n    Local<Object> result =\n        cons->NewInstance(context, argc, argv).ToLocalChecked();\n    args.GetReturnValue().Set(result);\n  }\n}\n\nvoid MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());\n  obj->value_ += 1;\n\n  args.GetReturnValue().Set(Number::New(isolate, obj->value_));\n}\n\n}  // namespace demo\n
      \n

      To build this example, the myobject.cc file must be added to the\nbinding.gyp:

      \n
      {\n  \"targets\": [\n    {\n      \"target_name\": \"addon\",\n      \"sources\": [\n        \"addon.cc\",\n        \"myobject.cc\"\n      ]\n    }\n  ]\n}\n
      \n

      Test it with:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\nconst obj = new addon.MyObject(10);\nconsole.log(obj.plusOne());\n// Prints: 11\nconsole.log(obj.plusOne());\n// Prints: 12\nconsole.log(obj.plusOne());\n// Prints: 13\n
      \n

      The destructor for a wrapper object will run when the object is\ngarbage-collected. For destructor testing, there are command-line flags that\ncan be used to make it possible to force garbage collection. These flags are\nprovided by the underlying V8 JavaScript engine. They are subject to change\nor removal at any time. They are not documented by Node.js or V8, and they\nshould never be used outside of testing.

      ", "type": "module", "displayName": "Wrapping C++ objects" }, { "textRaw": "Factory of wrapped objects", "name": "factory_of_wrapped_objects", - "desc": "

      Alternatively, it is possible to use a factory pattern to avoid explicitly\ncreating object instances using the JavaScript new operator:

      \n
      const obj = addon.createObject();\n// instead of:\n// const obj = new addon.Object();\n
      \n

      First, the createObject() method is implemented in addon.cc:

      \n
      // addon.cc\n#include <node.h>\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  MyObject::NewInstance(args);\n}\n\nvoid InitAll(Local<Object> exports, Local<Object> module) {\n  MyObject::Init(exports->GetIsolate());\n\n  NODE_SET_METHOD(module, \"exports\", CreateObject);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)\n\n}  // namespace demo\n
      \n

      In myobject.h, the static method NewInstance() is added to handle\ninstantiating the object. This method takes the place of using new in\nJavaScript:

      \n
      // myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Isolate* isolate);\n  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static v8::Global<v8::Function> constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif\n
      \n

      The implementation in myobject.cc is similar to the previous example:

      \n
      // myobject.cc\n#include <node.h>\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing node::AddEnvironmentCleanupHook;\nusing v8::Context;\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Global;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::NewStringType;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\n// Warning! This is not thread-safe, this addon cannot be used for worker\n// threads.\nGlobal<Function> MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Isolate* isolate) {\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);\n  tpl->SetClassName(String::NewFromUtf8(\n      isolate, \"MyObject\", NewStringType::kNormal).ToLocalChecked());\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  // Prototype\n  NODE_SET_PROTOTYPE_METHOD(tpl, \"plusOne\", PlusOne);\n\n  Local<Context> context = isolate->GetCurrentContext();\n  constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked());\n\n  AddEnvironmentCleanupHook(isolate, [](void*) {\n    constructor.Reset();\n  }, nullptr);\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ?\n        0 : args[0]->NumberValue(context).FromMaybe(0);\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons = Local<Function>::New(isolate, constructor);\n    Local<Object> instance =\n        cons->NewInstance(context, argc, argv).ToLocalChecked();\n    args.GetReturnValue().Set(instance);\n  }\n}\n\nvoid MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = { args[0] };\n  Local<Function> cons = Local<Function>::New(isolate, constructor);\n  Local<Context> context = isolate->GetCurrentContext();\n  Local<Object> instance =\n      cons->NewInstance(context, argc, argv).ToLocalChecked();\n\n  args.GetReturnValue().Set(instance);\n}\n\nvoid MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());\n  obj->value_ += 1;\n\n  args.GetReturnValue().Set(Number::New(isolate, obj->value_));\n}\n\n}  // namespace demo\n
      \n

      Once again, to build this example, the myobject.cc file must be added to the\nbinding.gyp:

      \n
      {\n  \"targets\": [\n    {\n      \"target_name\": \"addon\",\n      \"sources\": [\n        \"addon.cc\",\n        \"myobject.cc\"\n      ]\n    }\n  ]\n}\n
      \n

      Test it with:

      \n
      // test.js\nconst createObject = require('./build/Release/addon');\n\nconst obj = createObject(10);\nconsole.log(obj.plusOne());\n// Prints: 11\nconsole.log(obj.plusOne());\n// Prints: 12\nconsole.log(obj.plusOne());\n// Prints: 13\n\nconst obj2 = createObject(20);\nconsole.log(obj2.plusOne());\n// Prints: 21\nconsole.log(obj2.plusOne());\n// Prints: 22\nconsole.log(obj2.plusOne());\n// Prints: 23\n
      ", + "desc": "

      Alternatively, it is possible to use a factory pattern to avoid explicitly\ncreating object instances using the JavaScript new operator:

      \n
      const obj = addon.createObject();\n// instead of:\n// const obj = new addon.Object();\n
      \n

      First, the createObject() method is implemented in addon.cc:

      \n
      // addon.cc\n#include <node.h>\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  MyObject::NewInstance(args);\n}\n\nvoid InitAll(Local<Object> exports, Local<Object> module) {\n  MyObject::Init(exports->GetIsolate());\n\n  NODE_SET_METHOD(module, \"exports\", CreateObject);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)\n\n}  // namespace demo\n
      \n

      In myobject.h, the static method NewInstance() is added to handle\ninstantiating the object. This method takes the place of using new in\nJavaScript:

      \n
      // myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Isolate* isolate);\n  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static v8::Global<v8::Function> constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif\n
      \n

      The implementation in myobject.cc is similar to the previous example:

      \n
      // myobject.cc\n#include <node.h>\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing node::AddEnvironmentCleanupHook;\nusing v8::Context;\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Global;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\n// Warning! This is not thread-safe, this addon cannot be used for worker\n// threads.\nGlobal<Function> MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Isolate* isolate) {\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);\n  tpl->SetClassName(String::NewFromUtf8(isolate, \"MyObject\").ToLocalChecked());\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  // Prototype\n  NODE_SET_PROTOTYPE_METHOD(tpl, \"plusOne\", PlusOne);\n\n  Local<Context> context = isolate->GetCurrentContext();\n  constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked());\n\n  AddEnvironmentCleanupHook(isolate, [](void*) {\n    constructor.Reset();\n  }, nullptr);\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ?\n        0 : args[0]->NumberValue(context).FromMaybe(0);\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons = Local<Function>::New(isolate, constructor);\n    Local<Object> instance =\n        cons->NewInstance(context, argc, argv).ToLocalChecked();\n    args.GetReturnValue().Set(instance);\n  }\n}\n\nvoid MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = { args[0] };\n  Local<Function> cons = Local<Function>::New(isolate, constructor);\n  Local<Context> context = isolate->GetCurrentContext();\n  Local<Object> instance =\n      cons->NewInstance(context, argc, argv).ToLocalChecked();\n\n  args.GetReturnValue().Set(instance);\n}\n\nvoid MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());\n  obj->value_ += 1;\n\n  args.GetReturnValue().Set(Number::New(isolate, obj->value_));\n}\n\n}  // namespace demo\n
      \n

      Once again, to build this example, the myobject.cc file must be added to the\nbinding.gyp:

      \n
      {\n  \"targets\": [\n    {\n      \"target_name\": \"addon\",\n      \"sources\": [\n        \"addon.cc\",\n        \"myobject.cc\"\n      ]\n    }\n  ]\n}\n
      \n

      Test it with:

      \n
      // test.js\nconst createObject = require('./build/Release/addon');\n\nconst obj = createObject(10);\nconsole.log(obj.plusOne());\n// Prints: 11\nconsole.log(obj.plusOne());\n// Prints: 12\nconsole.log(obj.plusOne());\n// Prints: 13\n\nconst obj2 = createObject(20);\nconsole.log(obj2.plusOne());\n// Prints: 21\nconsole.log(obj2.plusOne());\n// Prints: 22\nconsole.log(obj2.plusOne());\n// Prints: 23\n
      ", "type": "module", "displayName": "Factory of wrapped objects" }, { "textRaw": "Passing wrapped objects around", "name": "passing_wrapped_objects_around", - "desc": "

      In addition to wrapping and returning C++ objects, it is possible to pass\nwrapped objects around by unwrapping them with the Node.js helper function\nnode::ObjectWrap::Unwrap. The following examples shows a function add()\nthat can take two MyObject objects as input arguments:

      \n
      // addon.cc\n#include <node.h>\n#include <node_object_wrap.h>\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing v8::Context;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  MyObject::NewInstance(args);\n}\n\nvoid Add(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>(\n      args[0]->ToObject(context).ToLocalChecked());\n  MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>(\n      args[1]->ToObject(context).ToLocalChecked());\n\n  double sum = obj1->value() + obj2->value();\n  args.GetReturnValue().Set(Number::New(isolate, sum));\n}\n\nvoid InitAll(Local<Object> exports) {\n  MyObject::Init(exports->GetIsolate());\n\n  NODE_SET_METHOD(exports, \"createObject\", CreateObject);\n  NODE_SET_METHOD(exports, \"add\", Add);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)\n\n}  // namespace demo\n
      \n

      In myobject.h, a new public method is added to allow access to private values\nafter unwrapping the object.

      \n
      // myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Isolate* isolate);\n  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);\n  inline double value() const { return value_; }\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static v8::Global<v8::Function> constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif\n
      \n

      The implementation of myobject.cc is similar to before:

      \n
      // myobject.cc\n#include <node.h>\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing node::AddEnvironmentCleanupHook;\nusing v8::Context;\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Global;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::NewStringType;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\n// Warning! This is not thread-safe, this addon cannot be used for worker\n// threads.\nGlobal<Function> MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Isolate* isolate) {\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);\n  tpl->SetClassName(String::NewFromUtf8(\n      isolate, \"MyObject\", NewStringType::kNormal).ToLocalChecked());\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  Local<Context> context = isolate->GetCurrentContext();\n  constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked());\n\n  AddEnvironmentCleanupHook(isolate, [](void*) {\n    constructor.Reset();\n  }, nullptr);\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ?\n        0 : args[0]->NumberValue(context).FromMaybe(0);\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons = Local<Function>::New(isolate, constructor);\n    Local<Object> instance =\n        cons->NewInstance(context, argc, argv).ToLocalChecked();\n    args.GetReturnValue().Set(instance);\n  }\n}\n\nvoid MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = { args[0] };\n  Local<Function> cons = Local<Function>::New(isolate, constructor);\n  Local<Context> context = isolate->GetCurrentContext();\n  Local<Object> instance =\n      cons->NewInstance(context, argc, argv).ToLocalChecked();\n\n  args.GetReturnValue().Set(instance);\n}\n\n}  // namespace demo\n
      \n

      Test it with:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\nconst obj1 = addon.createObject(10);\nconst obj2 = addon.createObject(20);\nconst result = addon.add(obj1, obj2);\n\nconsole.log(result);\n// Prints: 30\n
      ", + "desc": "

      In addition to wrapping and returning C++ objects, it is possible to pass\nwrapped objects around by unwrapping them with the Node.js helper function\nnode::ObjectWrap::Unwrap. The following examples shows a function add()\nthat can take two MyObject objects as input arguments:

      \n
      // addon.cc\n#include <node.h>\n#include <node_object_wrap.h>\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing v8::Context;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  MyObject::NewInstance(args);\n}\n\nvoid Add(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>(\n      args[0]->ToObject(context).ToLocalChecked());\n  MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>(\n      args[1]->ToObject(context).ToLocalChecked());\n\n  double sum = obj1->value() + obj2->value();\n  args.GetReturnValue().Set(Number::New(isolate, sum));\n}\n\nvoid InitAll(Local<Object> exports) {\n  MyObject::Init(exports->GetIsolate());\n\n  NODE_SET_METHOD(exports, \"createObject\", CreateObject);\n  NODE_SET_METHOD(exports, \"add\", Add);\n}\n\nNODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)\n\n}  // namespace demo\n
      \n

      In myobject.h, a new public method is added to allow access to private values\nafter unwrapping the object.

      \n
      // myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Isolate* isolate);\n  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);\n  inline double value() const { return value_; }\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static v8::Global<v8::Function> constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif\n
      \n

      The implementation of myobject.cc is similar to before:

      \n
      // myobject.cc\n#include <node.h>\n#include \"myobject.h\"\n\nnamespace demo {\n\nusing node::AddEnvironmentCleanupHook;\nusing v8::Context;\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Global;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\n// Warning! This is not thread-safe, this addon cannot be used for worker\n// threads.\nGlobal<Function> MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Isolate* isolate) {\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);\n  tpl->SetClassName(String::NewFromUtf8(isolate, \"MyObject\").ToLocalChecked());\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  Local<Context> context = isolate->GetCurrentContext();\n  constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked());\n\n  AddEnvironmentCleanupHook(isolate, [](void*) {\n    constructor.Reset();\n  }, nullptr);\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Context> context = isolate->GetCurrentContext();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ?\n        0 : args[0]->NumberValue(context).FromMaybe(0);\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons = Local<Function>::New(isolate, constructor);\n    Local<Object> instance =\n        cons->NewInstance(context, argc, argv).ToLocalChecked();\n    args.GetReturnValue().Set(instance);\n  }\n}\n\nvoid MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = { args[0] };\n  Local<Function> cons = Local<Function>::New(isolate, constructor);\n  Local<Context> context = isolate->GetCurrentContext();\n  Local<Object> instance =\n      cons->NewInstance(context, argc, argv).ToLocalChecked();\n\n  args.GetReturnValue().Set(instance);\n}\n\n}  // namespace demo\n
      \n

      Test it with:

      \n
      // test.js\nconst addon = require('./build/Release/addon');\n\nconst obj1 = addon.createObject(10);\nconst obj2 = addon.createObject(20);\nconst result = addon.add(obj1, obj2);\n\nconsole.log(result);\n// Prints: 30\n
      ", "type": "module", "displayName": "Passing wrapped objects around" } diff --git a/doc/api/addons.md b/doc/api/addons.md index 2ad560a14e1400ccb96fab32d6f4fe1dea04eade..d3fcc6425772085838007cc71d8160f6660b3def 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -7,15 +7,16 @@ _Addons_ are dynamically-linked shared objects written in C++. The [`require()`][require] function can load addons as ordinary Node.js modules. Addons provide an interface between JavaScript and C/C++ libraries. -There are three options for implementing addons: N-API, nan, or direct +There are three options for implementing addons: Node-API, nan, or direct use of internal V8, libuv and Node.js libraries. Unless there is a need for -direct access to functionality which is not exposed by N-API, use N-API. -Refer to [C/C++ addons with N-API](n-api.html) for more information on N-API. +direct access to functionality which is not exposed by Node-API, use Node-API. +Refer to [C/C++ addons with Node-API](n-api.md) for more information on +Node-API. -When not using N-API, implementing addons is complicated, +When not using Node-API, implementing addons is complicated, involving knowledge of several components and APIs: -* V8: the C++ library Node.js uses to provide the +* [V8][]: the C++ library Node.js uses to provide the JavaScript implementation. V8 provides the mechanisms for creating objects, calling functions, etc. V8's API is documented mostly in the `v8.h` header file (`deps/v8/include/v8.h` in the Node.js source @@ -26,12 +27,12 @@ involving knowledge of several components and APIs: serves as a cross-platform abstraction library, giving easy, POSIX-like access across all major operating systems to many common system tasks, such as interacting with the filesystem, sockets, timers, and system events. libuv - also provides a pthreads-like threading abstraction that may be used to - power more sophisticated asynchronous addons that need to move beyond the - standard event loop. Addon authors are encouraged to think about how to + also provides a threading abstraction similar to POSIX threads for + more sophisticated asynchronous addons that need to move beyond the + standard event loop. Addon authors should avoid blocking the event loop with I/O or other time-intensive tasks by - off-loading work via libuv to non-blocking system operations, worker threads - or a custom use of libuv's threads. + offloading work via libuv to non-blocking system operations, worker threads, + or a custom use of libuv threads. * Internal Node.js libraries. Node.js itself exports C++ APIs that addons can use, the most important of which is the `node::ObjectWrap` class. @@ -65,7 +66,6 @@ namespace demo { using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Object; using v8::String; using v8::Value; @@ -73,7 +73,7 @@ using v8::Value; void Method(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); args.GetReturnValue().Set(String::NewFromUtf8( - isolate, "world", NewStringType::kNormal).ToLocalChecked()); + isolate, "world").ToLocalChecked()); } void Initialize(Local exports) { @@ -112,8 +112,8 @@ There are environments in which Node.js addons may need to be loaded multiple times in multiple contexts. For example, the [Electron][] runtime runs multiple instances of Node.js in a single process. Each instance will have its own `require()` cache, and thus each instance will need a native addon to behave -correctly when loaded via `require()`. From the addon's perspective, this means -that it must support multiple initializations. +correctly when loaded via `require()`. This means that the addon +must support multiple initializations. A context-aware addon can be constructed by using the macro `NODE_MODULE_INITIALIZER`, which expands to the name of a function which Node.js @@ -155,25 +155,26 @@ they were created. The context-aware addon can be structured to avoid global static data by performing the following steps: + * Define a class which will hold per-addon-instance data and which has a static -member of the form + member of the form ```cpp static void DeleteInstance(void* data) { // Cast `data` to an instance of the class and delete it. } ``` * Heap-allocate an instance of this class in the addon initializer. This can be -accomplished using the `new` keyword. + accomplished using the `new` keyword. * Call `node::AddEnvironmentCleanupHook()`, passing it the above-created -instance and a pointer to `DeleteInstance()`. This will ensure the instance is -deleted when the environment is torn down. + instance and a pointer to `DeleteInstance()`. This will ensure the instance is + deleted when the environment is torn down. * Store the instance of the class in a `v8::External`, and * Pass the `v8::External` to all methods exposed to JavaScript by passing it -to `v8::FunctionTemplate::New()` or `v8::Function::New()` which creates the -native-backed JavaScript functions. The third parameter of -`v8::FunctionTemplate::New()` or `v8::Function::New()` accepts the -`v8::External` and makes it available in the native callback using the -`v8::FunctionCallbackInfo::Data()` method. + to `v8::FunctionTemplate::New()` or `v8::Function::New()` which creates the + native-backed JavaScript functions. The third parameter of + `v8::FunctionTemplate::New()` or `v8::Function::New()` accepts the + `v8::External` and makes it available in the native callback using the + `v8::FunctionCallbackInfo::Data()` method. This will ensure that the per-addon-instance data reaches each binding that can be called from JavaScript. The per-addon-instance data must also be passed into @@ -226,8 +227,7 @@ NODE_MODULE_INIT(/* exports, module, context */) { // per-addon-instance data we created above by passing `external` as the // third parameter to the `FunctionTemplate` constructor. exports->Set(context, - String::NewFromUtf8(isolate, "method", NewStringType::kNormal) - .ToLocalChecked(), + String::NewFromUtf8(isolate, "method").ToLocalChecked(), FunctionTemplate::New(isolate, Method, external) ->GetFunction(context).ToLocalChecked()).FromJust(); } @@ -236,7 +236,7 @@ NODE_MODULE_INIT(/* exports, module, context */) { #### Worker support @@ -244,7 +244,7 @@ changes: In order to be loaded from multiple Node.js environments, such as a main thread and a Worker thread, an add-on needs to either: -* Be an N-API addon, or +* Be an Node-API addon, or * Be declared as context-aware using `NODE_MODULE_INIT()` as described above In order to support [`Worker`][] threads, addons need to clean up any resources @@ -271,9 +271,9 @@ The following `addon.cc` uses `AddEnvironmentCleanupHook`: ```cpp // addon.cc +#include #include #include -#include using node::AddEnvironmentCleanupHook; using v8::HandleScope; @@ -397,14 +397,14 @@ the appropriate headers automatically. However, there are a few caveats to be aware of: * When `node-gyp` runs, it will detect the specific release version of Node.js -and download either the full source tarball or just the headers. If the full -source is downloaded, addons will have complete access to the full set of -Node.js dependencies. However, if only the Node.js headers are downloaded, then -only the symbols exported by Node.js will be available. + and download either the full source tarball or just the headers. If the full + source is downloaded, addons will have complete access to the full set of + Node.js dependencies. However, if only the Node.js headers are downloaded, + then only the symbols exported by Node.js will be available. * `node-gyp` can be run using the `--nodedir` flag pointing at a local Node.js -source image. Using this option, the addon will have access to the full set of -dependencies. + source image. Using this option, the addon will have access to the full set of + dependencies. ### Loading addons using `require()` @@ -436,11 +436,11 @@ addon developers are recommended to use to keep compatibility between past and future releases of V8 and Node.js. See the `nan` [examples][] for an illustration of how it can be used. -## N-API +## Node-API > Stability: 2 - Stable -N-API is an API for building native addons. It is independent from +Node-API is an API for building native addons. It is independent from the underlying JavaScript runtime (e.g. V8) and is maintained as part of Node.js itself. This API will be Application Binary Interface (ABI) stable across versions of Node.js. It is intended to insulate addons from @@ -450,17 +450,17 @@ recompilation. Addons are built/packaged with the same approach/tools outlined in this document (node-gyp, etc.). The only difference is the set of APIs that are used by the native code. Instead of using the V8 or [Native Abstractions for Node.js][] APIs, the functions available -in the N-API are used. +in the Node-API are used. Creating and maintaining an addon that benefits from the ABI stability -provided by N-API carries with it certain -[implementation considerations](n-api.html#n_api_implications_of_abi_stability). +provided by Node-API carries with it certain +[implementation considerations](n-api.md#n_api_implications_of_abi_stability). -To use N-API in the above "Hello world" example, replace the content of +To use Node-API in the above "Hello world" example, replace the content of `hello.cc` with the following. All other instructions remain the same. ```cpp -// hello.cc using N-API +// hello.cc using Node-API #include namespace demo { @@ -492,7 +492,7 @@ NAPI_MODULE(NODE_GYP_MODULE_NAME, init) ``` The functions available and how to use them are documented in -[C/C++ addons with N-API](n-api.html). +[C/C++ addons with Node-API](n-api.md). ## Addon examples @@ -549,7 +549,6 @@ using v8::Exception; using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Number; using v8::Object; using v8::String; @@ -566,8 +565,7 @@ void Add(const FunctionCallbackInfo& args) { // Throw an Error that is passed back to JavaScript isolate->ThrowException(Exception::TypeError( String::NewFromUtf8(isolate, - "Wrong number of arguments", - NewStringType::kNormal).ToLocalChecked())); + "Wrong number of arguments").ToLocalChecked())); return; } @@ -575,8 +573,7 @@ void Add(const FunctionCallbackInfo& args) { if (!args[0]->IsNumber() || !args[1]->IsNumber()) { isolate->ThrowException(Exception::TypeError( String::NewFromUtf8(isolate, - "Wrong arguments", - NewStringType::kNormal).ToLocalChecked())); + "Wrong arguments").ToLocalChecked())); return; } @@ -625,7 +622,6 @@ using v8::Function; using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Null; using v8::Object; using v8::String; @@ -638,8 +634,7 @@ void RunCallback(const FunctionCallbackInfo& args) { const unsigned argc = 1; Local argv[argc] = { String::NewFromUtf8(isolate, - "hello world", - NewStringType::kNormal).ToLocalChecked() }; + "hello world").ToLocalChecked() }; cb->Call(context, Null(isolate), argc, argv).ToLocalChecked(); } @@ -687,7 +682,6 @@ using v8::Context; using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Object; using v8::String; using v8::Value; @@ -699,8 +693,7 @@ void CreateObject(const FunctionCallbackInfo& args) { Local obj = Object::New(isolate); obj->Set(context, String::NewFromUtf8(isolate, - "msg", - NewStringType::kNormal).ToLocalChecked(), + "msg").ToLocalChecked(), args[0]->ToString(context).ToLocalChecked()) .FromJust(); @@ -745,7 +738,6 @@ using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Object; using v8::String; using v8::Value; @@ -753,7 +745,7 @@ using v8::Value; void MyFunction(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); args.GetReturnValue().Set(String::NewFromUtf8( - isolate, "hello world", NewStringType::kNormal).ToLocalChecked()); + isolate, "hello world").ToLocalChecked()); } void CreateFunction(const FunctionCallbackInfo& args) { @@ -765,7 +757,7 @@ void CreateFunction(const FunctionCallbackInfo& args) { // omit this to make it anonymous fn->SetName(String::NewFromUtf8( - isolate, "theFunction", NewStringType::kNormal).ToLocalChecked()); + isolate, "theFunction").ToLocalChecked()); args.GetReturnValue().Set(fn); } @@ -861,7 +853,6 @@ using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Number; using v8::Object; using v8::ObjectTemplate; @@ -885,8 +876,7 @@ void MyObject::Init(Local exports) { // Prepare constructor template Local tpl = FunctionTemplate::New(isolate, New, addon_data); - tpl->SetClassName(String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked()); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked()); tpl->InstanceTemplate()->SetInternalFieldCount(1); // Prototype @@ -895,8 +885,8 @@ void MyObject::Init(Local exports) { Local constructor = tpl->GetFunction(context).ToLocalChecked(); addon_data->SetInternalField(0, constructor); exports->Set(context, String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked(), - constructor).FromJust(); + isolate, "MyObject").ToLocalChecked(), + constructor).FromJust(); } void MyObject::New(const FunctionCallbackInfo& args) { @@ -1066,7 +1056,6 @@ using v8::FunctionTemplate; using v8::Global; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Number; using v8::Object; using v8::String; @@ -1085,8 +1074,7 @@ MyObject::~MyObject() { void MyObject::Init(Isolate* isolate) { // Prepare constructor template Local tpl = FunctionTemplate::New(isolate, New); - tpl->SetClassName(String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked()); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked()); tpl->InstanceTemplate()->SetInternalFieldCount(1); // Prototype @@ -1290,7 +1278,6 @@ using v8::FunctionTemplate; using v8::Global; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Object; using v8::String; using v8::Value; @@ -1308,8 +1295,7 @@ MyObject::~MyObject() { void MyObject::Init(Isolate* isolate) { // Prepare constructor template Local tpl = FunctionTemplate::New(isolate, New); - tpl->SetClassName(String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked()); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked()); tpl->InstanceTemplate()->SetInternalFieldCount(1); Local context = isolate->GetCurrentContext(); @@ -1372,16 +1358,17 @@ console.log(result); // Prints: 30 ``` -[`Worker`]: worker_threads.html#worker_threads_class_worker [Electron]: https://electronjs.org/ [Embedder's Guide]: https://github.com/v8/v8/wiki/Embedder's%20Guide [Linking to libraries included with Node.js]: #addons_linking_to_libraries_included_with_node_js [Native Abstractions for Node.js]: https://github.com/nodejs/nan +[V8]: https://v8.dev/ +[`Worker`]: worker_threads.md#worker_threads_class_worker [bindings]: https://github.com/TooTallNate/node-bindings [download]: https://github.com/nodejs/node-addon-examples -[examples]: https://github.com/nodejs/nan/tree/master/examples/ +[examples]: https://github.com/nodejs/nan/tree/HEAD/examples/ [installation instructions]: https://github.com/nodejs/node-gyp#installation [libuv]: https://github.com/libuv/libuv [node-gyp]: https://github.com/nodejs/node-gyp -[require]: modules.html#modules_require_id +[require]: modules.md#modules_require_id [v8-docs]: https://v8docs.nodesource.com/ diff --git a/doc/api/all.html b/doc/api/all.html index 7dcf5e1f6549abaa7a5125b4ee146e18a1ca9522..f0a5196213a7b55e425e0c6797023b9a270eb119 100644 --- a/doc/api/all.html +++ b/doc/api/all.html @@ -1,10 +1,10 @@ - + - - Node.js v12.22.7 Documentation + + Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +
      -
      -

      Table of Contents

      - -
      + +
      -

      About this documentation#

      +

      About this documentation#

      Welcome to the official API reference documentation for Node.js!

      Node.js is a JavaScript runtime built on the V8 JavaScript engine.

      -

      Contributing#

      +

      Contributing#

      Report errors in this documentation in the issue tracker. See -the contributing guide for directions on how to submit pull requests.

      -

      Stability index#

      +the contributing guide for directions on how to submit pull requests.

      +

      Stability index#

      Throughout the documentation are indications of a section's stability. Some APIs are so proven and so relied upon that they are unlikely to ever change at all. Others are brand new and experimental, or known to be hazardous.

      The stability indices are as follows:

      -

      Stability: 0 - Deprecated. The feature may emit warnings. Backward +

      Stability: 0 - Deprecated. The feature may emit warnings. Backward compatibility is not guaranteed.

      -

      Stability: 1 - Experimental. The feature is not subject to +

      Stability: 1 - Experimental. The feature is not subject to Semantic Versioning rules. Non-backward compatible changes or removal may occur in any future release. Use of the feature is not recommended in production environments.

      -

      Stability: 2 - Stable. Compatibility with the npm ecosystem is a high +

      Stability: 2 - Stable. Compatibility with the npm ecosystem is a high priority.

      + +

      Stability: 3 - Legacy. The feature is no longer recommended for use. While it +likely will not be removed, and is still covered by semantic-versioning +guarantees, use of the feature should be avoided.

      Use caution when making use of Experimental features, particularly within modules. Users may not be aware that experimental features are being used. Bugs or behavior changes may surprise users when Experimental API modifications occur. To avoid surprises, use of an Experimental feature may need a command-line flag. Experimental features may also emit a warning.

      -

      JSON output#

      +

      Stability overview#

      + + +

      JSON output#

      Every .html document has a corresponding .json document. This is for IDEs and other utilities that consume the documentation.

      -

      System calls and man pages#

      +

      System calls and man pages#

      Node.js functions which wrap a system call will document that. The docs link to the corresponding man pages which describe how the system call works.

      Most Unix system calls have Windows analogues. Still, behavior differences may -be unavoidable.

      -

      Usage and example#

      -

      Usage#

      +be unavoidable.

      +
      +

      Usage and example#

      +

      Usage#

      node [options] [V8 options] [script.js | -e "script" | - ] [arguments]

      -

      Please see the Command Line Options document for more information.

      -

      Example#

      +

      Please see the Command-line options document for more information.

      +

      Example#

      An example of a web server written with Node.js which responds with 'Hello, World!':

      Commands in this document start with $ or > to replicate how they would @@ -4123,18 +4450,18 @@ appear in a user's terminal. Do not include the $ and >

      Lines that don’t start with $ or > character show the output of the previous command.

      -

      First, make sure to have downloaded and installed Node.js. See this guide -for further install information.

      +

      First, make sure to have downloaded and installed Node.js. See +Installing Node.js via package manager for further install information.

      Now, create an empty project folder called projects, then navigate into it.

      Linux and Mac:

      -
      $ mkdir ~/projects
      -$ cd ~/projects
      +
      $ mkdir ~/projects
      +$ cd ~/projects

      Windows CMD:

      -
      > mkdir %USERPROFILE%\projects
      -> cd %USERPROFILE%\projects
      +
      > mkdir %USERPROFILE%\projects
      +> cd %USERPROFILE%\projects

      Windows PowerShell:

      -
      > mkdir $env:USERPROFILE\projects
      -> cd $env:USERPROFILE\projects
      +
      > mkdir $env:USERPROFILE\projects
      +> cd $env:USERPROFILE\projects

      Next, create a new source file in the projects folder and call it hello-world.js.

      Open hello-world.js in any preferred text editor and @@ -4144,34 +4471,35 @@ paste in the following content:

      const hostname = '127.0.0.1'; const port = 3000; -const server = http.createServer((req, res) => { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('Hello, World!\n'); +const server = http.createServer((req, res) => { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/plain'); + res.end('Hello, World!\n'); }); -server.listen(port, hostname, () => { - console.log(`Server running at http://${hostname}:${port}/`); +server.listen(port, hostname, () => { + console.log(`Server running at http://${hostname}:${port}/`); });

      Save the file, go back to the terminal window, and enter the following command:

      -
      $ node hello-world.js
      +
      $ node hello-world.js

      Output like this should appear in the terminal:

      Server running at http://127.0.0.1:3000/

      Now, open any preferred web browser and visit http://127.0.0.1:3000.

      If the browser displays the string Hello, World!, that indicates -the server is working.

      -

      Assert#

      +the server is working.

      +
      +

      Assert#

      Stability: 2 - Stable

      -

      Source Code: lib/assert.js

      +

      Source Code: lib/assert.js

      The assert module provides a set of assertion functions for verifying invariants.

      -

      Strict assertion mode#

      +

      Strict assertion mode#

      • actual <any>
      • @@ -4798,26 +5141,29 @@ message:

        Strict assertion mode

        An alias of assert.strictEqual().

        Legacy assertion mode

        -

        Stability: 0 - Deprecated: Use assert.strictEqual() instead.

        +

        Stability: 3 - Legacy: Use assert.strictEqual() instead.

        Tests shallow, coercive equality between the actual and expected parameters -using the Abstract Equality Comparison ( == ).

        +using the Abstract Equality Comparison ( == ). NaN is special handled +and treated as being identical in case both sides are NaN.

        const assert = require('assert');
         
        -assert.equal(1, 1);
        +assert.equal(1, 1);
         // OK, 1 == 1
        -assert.equal(1, '1');
        +assert.equal(1, '1');
         // OK, 1 == '1'
        +assert.equal(NaN, NaN);
        +// OK
         
        -assert.equal(1, 2);
        +assert.equal(1, 2);
         // AssertionError: 1 == 2
        -assert.equal({ a: { b: 1 } }, { a: { b: 1 } });
        +assert.equal({ a: { b: 1 } }, { a: { b: 1 } });
         // AssertionError: { a: { b: 1 } } == { a: { b: 1 } }

        If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.

        -

        assert.fail([message])#

        +

      assert.fail([message])#

      @@ -4827,19 +5173,19 @@ parameter is an instance of an Error<

      Throws an AssertionError with the provided error message or a default error message. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.

      -
      const assert = require('assert').strict;
      +
      const assert = require('assert').strict;
       
      -assert.fail();
      +assert.fail();
       // AssertionError [ERR_ASSERTION]: Failed
       
      -assert.fail('boom');
      +assert.fail('boom');
       // AssertionError [ERR_ASSERTION]: boom
       
      -assert.fail(new TypeError('need array'));
      +assert.fail(new TypeError('need array'));
       // TypeError: need array

      Using assert.fail() with more than two arguments is possible but deprecated. See below for further details.

      -

      assert.fail(actual, expected[, message[, operator[, stackStartFn]]])#

      +

      assert.fail(actual, expected[, message[, operator[, stackStartFn]]])#

      • actual <any>
      • @@ -5084,31 +5444,32 @@ instead of the AssertionErro

        Strict assertion mode

        An alias of assert.notStrictEqual().

        Legacy assertion mode

        -

        Stability: 0 - Deprecated: Use assert.notStrictEqual() instead.

        +

        Stability: 3 - Legacy: Use assert.notStrictEqual() instead.

        Tests shallow, coercive inequality with the Abstract Equality Comparison -( != ).

        +(!= ). NaN is special handled and treated as being identical in case both +sides are NaN.

        const assert = require('assert');
         
        -assert.notEqual(1, 2);
        +assert.notEqual(1, 2);
         // OK
         
        -assert.notEqual(1, 1);
        +assert.notEqual(1, 1);
         // AssertionError: 1 != 1
         
        -assert.notEqual(1, '1');
        +assert.notEqual(1, '1');
         // AssertionError: 1 != '1'

        If the values are equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.

        -

        assert.notStrictEqual(actual, expected[, message])#

        +

      assert.notStrictEqual(actual, expected[, message])#

      assert.ok(value[, message])#

      assert.throws(fn[, error][, message])#

      Promise execution tracking#

      By default, promise executions are not assigned asyncIds due to the relatively expensive nature of the promise introspection API provided by V8. This means that programs using promises or async/await will not get correct execution and trigger ids for promise callback contexts by default.

      const ah = require('async_hooks');
      -Promise.resolve(1729).then(() => {
      -  console.log(`eid ${ah.executionAsyncId()} tid ${ah.triggerAsyncId()}`);
      +Promise.resolve(1729).then(() => {
      +  console.log(`eid ${ah.executionAsyncId()} tid ${ah.triggerAsyncId()}`);
       });
       // produces:
       // eid 1 tid 0
      @@ -5978,9 +6342,9 @@ the resource that caused (triggered) the then() callback to be exec

      Installing async hooks via async_hooks.createHook enables promise execution tracking:

      const ah = require('async_hooks');
      -ah.createHook({ init() {} }).enable(); // forces PromiseHooks to be enabled.
      -Promise.resolve(1729).then(() => {
      -  console.log(`eid ${ah.executionAsyncId()} tid ${ah.triggerAsyncId()}`);
      +ah.createHook({ init() {} }).enable(); // forces PromiseHooks to be enabled.
      +Promise.resolve(1729).then(() => {
      +  console.log(`eid ${ah.executionAsyncId()} tid ${ah.triggerAsyncId()}`);
       });
       // produces:
       // eid 7 tid 6
      @@ -5995,23 +6359,23 @@ async resource 6.

      only on chained promises. That means promises not created by then()/catch() will not have the before and after callbacks fired on them. For more details see the details of the V8 PromiseHooks API.

      -

      JavaScript embedder API#

      +

      JavaScript embedder API#

      Library developers that handle their own asynchronous resources performing tasks like I/O, connection pooling, or managing callback queues may use the AsyncResource JavaScript API so that all the appropriate callbacks are called.

      -

      Class: AsyncResource#

      +

      Class: AsyncResource#

      The class AsyncResource is designed to be extended by the embedder's async resources. Using this, users can easily trigger the lifetime events of their own resources.

      The init hook will trigger when an AsyncResource is instantiated.

      The following is an overview of the AsyncResource API.

      -
      const { AsyncResource, executionAsyncId } = require('async_hooks');
      +
      const { AsyncResource, executionAsyncId } = require('async_hooks');
       
       // AsyncResource() is meant to be extended. Instantiating a
       // new AsyncResource() also triggers init. If triggerAsyncId is omitted then
       // async_hook.executionAsyncId() is used.
      -const asyncResource = new AsyncResource(
      -  type, { triggerAsyncId: executionAsyncId(), requireManualDestroy: false }
      +const asyncResource = new AsyncResource(
      +  type, { triggerAsyncId: executionAsyncId(), requireManualDestroy: false }
       );
       
       // Run a function in the execution context of the resource. This will
      @@ -6020,17 +6384,17 @@ own resources.

      // * call the provided function `fn` with the supplied arguments // * trigger the AsyncHooks after callbacks // * restore the original execution context -asyncResource.runInAsyncScope(fn, thisArg, ...args); +asyncResource.runInAsyncScope(fn, thisArg, ...args); // Call AsyncHooks destroy callbacks. -asyncResource.emitDestroy(); +asyncResource.emitDestroy(); // Return the unique ID assigned to the AsyncResource instance. -asyncResource.asyncId(); +asyncResource.asyncId(); // Return the trigger ID for the AsyncResource instance. -asyncResource.triggerAsyncId();
      -

      new AsyncResource(type[, options])#

      +asyncResource.triggerAsyncId();
      +
      new AsyncResource(type[, options])#
      • type <string> The type of async event.
      • options <Object> @@ -6048,26 +6412,26 @@ will only take place if there is at least one active destroy hook.

      Example usage:

      -
      class DBQuery extends AsyncResource {
      -  constructor(db) {
      -    super('DBQuery');
      -    this.db = db;
      +
      class DBQuery extends AsyncResource {
      +  constructor(db) {
      +    super('DBQuery');
      +    this.db = db;
         }
       
      -  getInfo(query, callback) {
      -    this.db.get(query, (err, data) => {
      -      this.runInAsyncScope(callback, null, err, data);
      +  getInfo(query, callback) {
      +    this.db.get(query, (err, data) => {
      +      this.runInAsyncScope(callback, null, err, data);
           });
         }
       
      -  close() {
      -    this.db = null;
      -    this.emitDestroy();
      +  close() {
      +    this.db = null;
      +    this.emitDestroy();
         }
       }
      -

      Static method: AsyncResource.bind(fn[, type])#

      +
      Static method: AsyncResource.bind(fn[, type])#
      • fn <Function> The function to bind to the current execution context.
      • @@ -6077,9 +6441,9 @@ will only take place if there is at least one active destroy hook.

        Binds the given function to the current execution context.

        The returned function will have an asyncResource property referencing the AsyncResource to which the function is bound.

        -

        asyncResource.bind(fn)#

        +
        asyncResource.bind(fn)#
        • fn <Function> The function to bind to the current AsyncResource.
        • @@ -6087,7 +6451,7 @@ the AsyncResource to which the function is bound.

          Binds the given function to execute to this AsyncResource's scope.

          The returned function will have an asyncResource property referencing the AsyncResource to which the function is bound.

          -

          asyncResource.runInAsyncScope(fn[, thisArg, ...args])#

          +
          asyncResource.runInAsyncScope(fn[, thisArg, ...args])#
          @@ -6101,7 +6465,7 @@ resource. of the async resource. This will establish the context, trigger the AsyncHooks before callbacks, call the function, trigger the AsyncHooks after callbacks, and then restore the original execution context.

          -

          asyncResource.emitDestroy()#

          +
          asyncResource.emitDestroy()#
          @@ -6109,124 +6473,134 @@ then restore the original execution context.

          be thrown if it is called more than once. This must be manually called. If the resource is left to be collected by the GC then the destroy hooks will never be called.

          -

          asyncResource.asyncId()#

          +
          asyncResource.asyncId()#
          • Returns: <number> The unique asyncId assigned to the resource.
          -

          asyncResource.triggerAsyncId()#

          +
          asyncResource.triggerAsyncId()#
          • Returns: <number> The same triggerAsyncId that is passed to the AsyncResource constructor.

          -

          Using AsyncResource for a Worker thread pool#

          +

          Using AsyncResource for a Worker thread pool#

          The following example shows how to use the AsyncResource class to properly provide async tracking for a Worker pool. Other resource pools, such as database connection pools, can follow a similar model.

          Assuming that the task is adding two numbers, using a file named task_processor.js with the following content:

          const { parentPort } = require('worker_threads');
          -parentPort.on('message', (task) => {
          -  parentPort.postMessage(task.a + task.b);
          +parentPort.on('message', (task) => {
          +  parentPort.postMessage(task.a + task.b);
           });

          a Worker pool around it could use the following structure:

          -
          const { AsyncResource } = require('async_hooks');
          -const { EventEmitter } = require('events');
          +
          const { AsyncResource } = require('async_hooks');
          +const { EventEmitter } = require('events');
           const path = require('path');
          -const { Worker } = require('worker_threads');
          +const { Worker } = require('worker_threads');
           
          -const kTaskInfo = Symbol('kTaskInfo');
          -const kWorkerFreedEvent = Symbol('kWorkerFreedEvent');
          +const kTaskInfo = Symbol('kTaskInfo');
          +const kWorkerFreedEvent = Symbol('kWorkerFreedEvent');
           
          -class WorkerPoolTaskInfo extends AsyncResource {
          -  constructor(callback) {
          -    super('WorkerPoolTaskInfo');
          -    this.callback = callback;
          +class WorkerPoolTaskInfo extends AsyncResource {
          +  constructor(callback) {
          +    super('WorkerPoolTaskInfo');
          +    this.callback = callback;
             }
           
          -  done(err, result) {
          -    this.runInAsyncScope(this.callback, null, err, result);
          -    this.emitDestroy();  // `TaskInfo`s are used only once.
          +  done(err, result) {
          +    this.runInAsyncScope(this.callback, null, err, result);
          +    this.emitDestroy();  // `TaskInfo`s are used only once.
             }
           }
           
          -class WorkerPool extends EventEmitter {
          -  constructor(numThreads) {
          -    super();
          -    this.numThreads = numThreads;
          -    this.workers = [];
          -    this.freeWorkers = [];
          +class WorkerPool extends EventEmitter {
          +  constructor(numThreads) {
          +    super();
          +    this.numThreads = numThreads;
          +    this.workers = [];
          +    this.freeWorkers = [];
          +    this.tasks = [];
           
               for (let i = 0; i < numThreads; i++)
          -      this.addNewWorker();
          +      this.addNewWorker();
          +
          +    // Any time the kWorkerFreedEvent is emitted, dispatch
          +    // the next task pending in the queue, if any.
          +    this.on(kWorkerFreedEvent, () => {
          +      if (this.tasks.length > 0) {
          +        const { task, callback } = this.tasks.shift();
          +        this.runTask(task, callback);
          +      }
          +    });
             }
           
          -  addNewWorker() {
          -    const worker = new Worker(path.resolve(__dirname, 'task_processor.js'));
          -    worker.on('message', (result) => {
          +  addNewWorker() {
          +    const worker = new Worker(path.resolve(__dirname, 'task_processor.js'));
          +    worker.on('message', (result) => {
                 // In case of success: Call the callback that was passed to `runTask`,
                 // remove the `TaskInfo` associated with the Worker, and mark it as free
                 // again.
          -      worker[kTaskInfo].done(null, result);
          +      worker[kTaskInfo].done(null, result);
                 worker[kTaskInfo] = null;
          -      this.freeWorkers.push(worker);
          -      this.emit(kWorkerFreedEvent);
          +      this.freeWorkers.push(worker);
          +      this.emit(kWorkerFreedEvent);
               });
          -    worker.on('error', (err) => {
          +    worker.on('error', (err) => {
                 // In case of an uncaught exception: Call the callback that was passed to
                 // `runTask` with the error.
                 if (worker[kTaskInfo])
          -        worker[kTaskInfo].done(err, null);
          +        worker[kTaskInfo].done(err, null);
                 else
          -        this.emit('error', err);
          +        this.emit('error', err);
                 // Remove the worker from the list and start a new Worker to replace the
                 // current one.
          -      this.workers.splice(this.workers.indexOf(worker), 1);
          -      this.addNewWorker();
          +      this.workers.splice(this.workers.indexOf(worker), 1);
          +      this.addNewWorker();
               });
          -    this.workers.push(worker);
          -    this.freeWorkers.push(worker);
          -    this.emit(kWorkerFreedEvent);
          +    this.workers.push(worker);
          +    this.freeWorkers.push(worker);
          +    this.emit(kWorkerFreedEvent);
             }
           
          -  runTask(task, callback) {
          -    if (this.freeWorkers.length === 0) {
          +  runTask(task, callback) {
          +    if (this.freeWorkers.length === 0) {
                 // No free threads, wait until a worker thread becomes free.
          -      this.once(kWorkerFreedEvent, () => this.runTask(task, callback));
          +      this.tasks.push({ task, callback });
                 return;
               }
           
          -    const worker = this.freeWorkers.pop();
          -    worker[kTaskInfo] = new WorkerPoolTaskInfo(callback);
          -    worker.postMessage(task);
          +    const worker = this.freeWorkers.pop();
          +    worker[kTaskInfo] = new WorkerPoolTaskInfo(callback);
          +    worker.postMessage(task);
             }
           
          -  close() {
          -    for (const worker of this.workers) worker.terminate();
          +  close() {
          +    for (const worker of this.workers) worker.terminate();
             }
           }
           
          -module.exports = WorkerPool;
          +module.exports = WorkerPool;

          Without the explicit tracking added by the WorkerPoolTaskInfo objects, it would appear that the callbacks are associated with the individual Worker objects. However, the creation of the Workers is not associated with the creation of the tasks and does not provide information about when tasks were scheduled.

          This pool could be used as follows:

          -
          const WorkerPool = require('./worker_pool.js');
          +
          const WorkerPool = require('./worker_pool.js');
           const os = require('os');
           
          -const pool = new WorkerPool(os.cpus().length);
          +const pool = new WorkerPool(os.cpus().length);
           
           let finished = 0;
           for (let i = 0; i < 10; i++) {
          -  pool.runTask({ a: 42, b: 100 }, (err, result) => {
          -    console.log(i, err, result);
          +  pool.runTask({ a: 42, b: 100 }, (err, result) => {
          +    console.log(i, err, result);
               if (++finished === 10)
          -      pool.close();
          +      pool.close();
             });
           }
          -

          Integrating AsyncResource with EventEmitter#

          +

          Integrating AsyncResource with EventEmitter#

          Event listeners triggered by an EventEmitter may be run in a different execution context than the one that was active when eventEmitter.on() was called.

          @@ -6234,52 +6608,56 @@ called.

          associate an event listener with the correct execution context. The same approach can be applied to a Stream or a similar event-driven class.

          const { createServer } = require('http');
          -const { AsyncResource, executionAsyncId } = require('async_hooks');
          +const { AsyncResource, executionAsyncId } = require('async_hooks');
           
          -const server = createServer((req, res) => {
          -  req.on('close', AsyncResource.bind(() => {
          +const server = createServer((req, res) => {
          +  req.on('close', AsyncResource.bind(() => {
               // Execution context is bound to the current outer scope.
             }));
          -  req.on('close', () => {
          +  req.on('close', () => {
               // Execution context is bound to the scope that caused 'close' to emit.
             });
          -  res.end();
          -}).listen(3000);
          -

          Class: AsyncLocalStorage#

          + res.end(); +}).listen(3000);
          +

      Class: AsyncLocalStorage#

      This class is used to create asynchronous state within callbacks and promise chains. It allows storing data throughout the lifetime of a web request or any other asynchronous duration. It is similar to thread-local storage in other languages.

      +

      While you can create your own implementation on top of the async_hooks module, +AsyncLocalStorage should be preferred as it is a performant and memory safe +implementation that involves significant optimizations that are non-obvious to +implement.

      The following example uses AsyncLocalStorage to build a simple logger that assigns IDs to incoming HTTP requests and includes them in messages logged within each request.

      const http = require('http');
      -const { AsyncLocalStorage } = require('async_hooks');
      +const { AsyncLocalStorage } = require('async_hooks');
       
      -const asyncLocalStorage = new AsyncLocalStorage();
      +const asyncLocalStorage = new AsyncLocalStorage();
       
      -function logWithId(msg) {
      -  const id = asyncLocalStorage.getStore();
      -  console.log(`${id !== undefined ? id : '-'}:`, msg);
      +function logWithId(msg) {
      +  const id = asyncLocalStorage.getStore();
      +  console.log(`${id !== undefined ? id : '-'}:`, msg);
       }
       
       let idSeq = 0;
      -http.createServer((req, res) => {
      -  asyncLocalStorage.run(idSeq++, () => {
      -    logWithId('start');
      +http.createServer((req, res) => {
      +  asyncLocalStorage.run(idSeq++, () => {
      +    logWithId('start');
           // Imagine any chain of async operations here
      -    setImmediate(() => {
      -      logWithId('finish');
      -      res.end();
      +    setImmediate(() => {
      +      logWithId('finish');
      +      res.end();
           });
         });
      -}).listen(8080);
      +}).listen(8080);
       
      -http.get('http://localhost:8080');
      -http.get('http://localhost:8080');
      +http.get('http://localhost:8080');
      +http.get('http://localhost:8080');
       // Prints:
       //   0: start
       //   1: start
      @@ -6287,139 +6665,144 @@ http.get('http://localhost:8080');
       //   1: finish

      When having multiple instances of AsyncLocalStorage, they are independent from each other. It is safe to instantiate this class multiple times.

      -

      new AsyncLocalStorage()#

      +

      new AsyncLocalStorage()#

      Creates a new instance of AsyncLocalStorage. Store is only provided within a -run method call.

      -

      asyncLocalStorage.disable()#

      +run() call or after an enterWith() call.

      +

      asyncLocalStorage.disable()#

      -

      This method disables the instance of AsyncLocalStorage. All subsequent calls +

      Disables the instance of AsyncLocalStorage. All subsequent calls to asyncLocalStorage.getStore() will return undefined until -asyncLocalStorage.run() is called again.

      +asyncLocalStorage.run() or asyncLocalStorage.enterWith() is called again.

      When calling asyncLocalStorage.disable(), all current contexts linked to the instance will be exited.

      Calling asyncLocalStorage.disable() is required before the asyncLocalStorage can be garbage collected. This does not apply to stores provided by the asyncLocalStorage, as those objects are garbage collected along with the corresponding async resources.

      -

      This method is to be used when the asyncLocalStorage is not in use anymore +

      Use this method when the asyncLocalStorage is not in use anymore in the current process.

      -

      asyncLocalStorage.getStore()#

      +

      asyncLocalStorage.getStore()#

      -

      This method returns the current store. -If this method is called outside of an asynchronous context initialized by -calling asyncLocalStorage.run, it will return undefined.

      -

      asyncLocalStorage.enterWith(store)#

      +

      Returns the current store. +If called outside of an asynchronous context initialized by +calling asyncLocalStorage.run() or asyncLocalStorage.enterWith(), it +returns undefined.

      +

      asyncLocalStorage.enterWith(store)#

      -

      Calling asyncLocalStorage.enterWith(store) will transition into the context -for the remainder of the current synchronous execution and will persist -through any following asynchronous calls.

      +

      Transitions into the context for the remainder of the current +synchronous execution and then persists the store through any following +asynchronous calls.

      Example:

      const store = { id: 1 };
      -asyncLocalStorage.enterWith(store);
      -asyncLocalStorage.getStore(); // Returns the store object
      -someAsyncOperation(() => {
      -  asyncLocalStorage.getStore(); // Returns the same object
      +// Replaces previous store with the given store object
      +asyncLocalStorage.enterWith(store);
      +asyncLocalStorage.getStore(); // Returns the store object
      +someAsyncOperation(() => {
      +  asyncLocalStorage.getStore(); // Returns the same object
       });

      This transition will continue for the entire synchronous execution. This means that if, for example, the context is entered within an event handler subsequent event handlers will also run within that context unless -specifically bound to another context with an AsyncResource.

      +specifically bound to another context with an AsyncResource. That is why +run() should be preferred over enterWith() unless there are strong reasons +to use the latter method.

      const store = { id: 1 };
       
      -emitter.on('my-event', () => {
      -  asyncLocalStorage.enterWith(store);
      +emitter.on('my-event', () => {
      +  asyncLocalStorage.enterWith(store);
       });
      -emitter.on('my-event', () => {
      -  asyncLocalStorage.getStore(); // Returns the same object
      +emitter.on('my-event', () => {
      +  asyncLocalStorage.getStore(); // Returns the same object
       });
       
      -asyncLocalStorage.getStore(); // Returns undefined
      -emitter.emit('my-event');
      -asyncLocalStorage.getStore(); // Returns the same object
      -

      asyncLocalStorage.run(store, callback[, ...args])#

      +asyncLocalStorage.getStore(); // Returns undefined +emitter.emit('my-event'); +asyncLocalStorage.getStore(); // Returns the same object
      +

      asyncLocalStorage.run(store, callback[, ...args])#

      -

      This methods runs a function synchronously within a context and return its -return value. The store is not accessible outside of the callback function or -the asynchronous operations created within the callback.

      -

      Optionally, arguments can be passed to the function. They will be passed to -the callback function.

      -

      If the callback function throws an error, it will be thrown by run too. -The stacktrace will not be impacted by this call and the context will -be exited.

      +

      Runs a function synchronously within a context and returns its +return value. The store is not accessible outside of the callback function. +The store is accessible to any asynchronous operations created within the +callback.

      +

      The optional args are passed to the callback function.

      +

      If the callback function throws an error, the error is thrown by run() too. +The stacktrace is not impacted by this call and the context is exited.

      Example:

      const store = { id: 2 };
       try {
      -  asyncLocalStorage.run(store, () => {
      -    asyncLocalStorage.getStore(); // Returns the store object
      -    throw new Error();
      +  asyncLocalStorage.run(store, () => {
      +    asyncLocalStorage.getStore(); // Returns the store object
      +    setTimeout(() => {
      +      asyncLocalStorage.getStore(); // Returns the store object
      +    }, 200);
      +    throw new Error();
         });
       } catch (e) {
      -  asyncLocalStorage.getStore(); // Returns undefined
      +  asyncLocalStorage.getStore(); // Returns undefined
         // The error will be caught here
       }
      -

      asyncLocalStorage.exit(callback[, ...args])#

      +

      asyncLocalStorage.exit(callback[, ...args])#

      -

      This methods runs a function synchronously outside of a context and return its +

      Runs a function synchronously outside of a context and returns its return value. The store is not accessible within the callback function or -the asynchronous operations created within the callback.

      -

      Optionally, arguments can be passed to the function. They will be passed to -the callback function.

      -

      If the callback function throws an error, it will be thrown by exit too. -The stacktrace will not be impacted by this call and -the context will be re-entered.

      +the asynchronous operations created within the callback. Any getStore() +call done within the callback function will always return undefined.

      +

      The optional args are passed to the callback function.

      +

      If the callback function throws an error, the error is thrown by exit() too. +The stacktrace is not impacted by this call and the context is re-entered.

      Example:

      // Within a call to run
       try {
      -  asyncLocalStorage.getStore(); // Returns the store object or value
      -  asyncLocalStorage.exit(() => {
      -    asyncLocalStorage.getStore(); // Returns undefined
      -    throw new Error();
      +  asyncLocalStorage.getStore(); // Returns the store object or value
      +  asyncLocalStorage.exit(() => {
      +    asyncLocalStorage.getStore(); // Returns undefined
      +    throw new Error();
         });
       } catch (e) {
      -  asyncLocalStorage.getStore(); // Returns the same object or value
      +  asyncLocalStorage.getStore(); // Returns the same object or value
         // The error will be caught here
       }
      -

      Usage with async/await#

      +

      Usage with async/await#

      If, within an async function, only one await call is to run within a context, the following pattern should be used:

      -
      async function fn() {
      -  await asyncLocalStorage.run(new Map(), () => {
      -    asyncLocalStorage.getStore().set('key', value);
      -    return foo(); // The return value of foo will be awaited
      +
      async function fn() {
      +  await asyncLocalStorage.run(new Map(), () => {
      +    asyncLocalStorage.getStore().set('key', value);
      +    return foo(); // The return value of foo will be awaited
         });
       }

      In this example, the store is only available in the callback function and the functions called by foo. Outside of run, calling getStore will return undefined.

      -

      Troubleshooting#

      +

      Troubleshooting#

      In most cases your application or library code should have no issues with AsyncLocalStorage. But in rare cases you may face situations when the current store is lost in one of asynchronous operations. In those cases, @@ -6428,11 +6811,12 @@ consider the following options.

      util.promisify(), so it starts working with native promises.

      If you need to keep using callback-based API, or your code assumes a custom thenable implementation, use the AsyncResource class -to associate the asynchronous operation with the correct execution context.

      -

      Buffer#

      +to associate the asynchronous operation with the correct execution context.

      +
      +

      Buffer#

      Stability: 2 - Stable

      -

      Source Code: lib/buffer.js

      +

      Source Code: lib/buffer.js

      Buffer objects are used to represent a fixed-length sequence of bytes. Many Node.js APIs support Buffers.

      The Buffer class is a subclass of JavaScript's Uint8Array class and @@ -6441,38 +6825,40 @@ plain // Creates a zero-filled Buffer of length 10. -const buf1 = Buffer.alloc(10); +const buf1 = Buffer.alloc(10); // Creates a Buffer of length 10, // filled with bytes which all have the value `1`. -const buf2 = Buffer.alloc(10, 1); +const buf2 = Buffer.alloc(10, 1); // Creates an uninitialized buffer of length 10. // This is faster than calling Buffer.alloc() but the returned // Buffer instance might contain old data that needs to be // overwritten using fill(), write(), or other functions that fill the Buffer's // contents. -const buf3 = Buffer.allocUnsafe(10); +const buf3 = Buffer.allocUnsafe(10); // Creates a Buffer containing the bytes [1, 2, 3]. -const buf4 = Buffer.from([1, 2, 3]); +const buf4 = Buffer.from([1, 2, 3]); // Creates a Buffer containing the bytes [1, 1, 1, 1] – the entries // are all truncated using `(value & 255)` to fit into the range 0–255. -const buf5 = Buffer.from([257, 257.5, -255, '1']); +const buf5 = Buffer.from([257, 257.5, -255, '1']); // Creates a Buffer containing the UTF-8-encoded bytes for the string 'tést': // [0x74, 0xc3, 0xa9, 0x73, 0x74] (in hexadecimal notation) // [116, 195, 169, 115, 116] (in decimal notation) -const buf6 = Buffer.from('tést'); +const buf6 = Buffer.from('tést'); // Creates a Buffer containing the Latin-1 bytes [0x74, 0xe9, 0x73, 0x74]. -const buf7 = Buffer.from('tést', 'latin1'); -

      Buffers and character encodings#

      +const buf7 = Buffer.from('tést', 'latin1');
      +

      Buffers and character encodings#

      @@ -7640,16 +8145,17 @@ satisfy: 0 <= offset <= buf.length - 8. Default:<

      Reads an unsigned, big-endian 64-bit integer from buf at the specified offset.

      -
      const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);
      +

      This function is also available under the readBigUint64BE alias.

      +
      const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);
       
      -console.log(buf.readBigUInt64BE(0));
      +console.log(buf.readBigUInt64BE(0));
       // Prints: 4294967295n
      -

      buf.readBigUInt64LE([offset])#

      +

      buf.readBigUInt64LE([offset])#

      Buffer.from(), Buffer.alloc(), and Buffer.allocUnsafe()#

      In versions of Node.js prior to 6.0.0, Buffer instances were created using the Buffer constructor function, which allocates the returned Buffer differently based on what arguments are provided:

      @@ -9312,21 +9882,21 @@ potentially sensitive. if size is less than or equal to half Buffer.poolSize. Instances returned by Buffer.allocUnsafeSlow() never use the shared internal memory pool.

      -

      The --zero-fill-buffers command line option#

      +

      The --zero-fill-buffers command-line option#

      -

      Node.js can be started using the --zero-fill-buffers command line option to +

      Node.js can be started using the --zero-fill-buffers command-line option to cause all newly-allocated Buffer instances to be zero-filled upon creation by default. Without the option, buffers created with Buffer.allocUnsafe(), Buffer.allocUnsafeSlow(), and new SlowBuffer(size) are not zero-filled. Use of this flag can have a measurable negative impact on performance. Use the --zero-fill-buffers option only when necessary to enforce that newly allocated Buffer instances cannot contain old data that is potentially sensitive.

      -
      $ node --zero-fill-buffers
      -> Buffer.allocUnsafe(5);
      +
      $ node --zero-fill-buffers
      +> Buffer.allocUnsafe(5);
       <Buffer 00 00 00 00 00>
      -

      What makes Buffer.allocUnsafe() and Buffer.allocUnsafeSlow() "unsafe"?#

      +

      What makes Buffer.allocUnsafe() and Buffer.allocUnsafeSlow() "unsafe"?#

      When calling Buffer.allocUnsafe() and Buffer.allocUnsafeSlow(), the segment of allocated memory is uninitialized (it is not zeroed-out). While this design makes the allocation of memory quite fast, the allocated segment of @@ -9335,22 +9905,24 @@ created by Buffer. memory can allow this old data to be leaked when the Buffer memory is read.

      While there are clear performance advantages to using Buffer.allocUnsafe(), extra care must be taken in order to avoid -introducing security vulnerabilities into an application.

      -

      C++ addons#

      +introducing security vulnerabilities into an application.

      +
      +

      C++ addons#

      Addons are dynamically-linked shared objects written in C++. The require() function can load addons as ordinary Node.js modules. Addons provide an interface between JavaScript and C/C++ libraries.

      -

      There are three options for implementing addons: N-API, nan, or direct +

      There are three options for implementing addons: Node-API, nan, or direct use of internal V8, libuv and Node.js libraries. Unless there is a need for -direct access to functionality which is not exposed by N-API, use N-API. -Refer to C/C++ addons with N-API for more information on N-API.

      -

      When not using N-API, implementing addons is complicated, +direct access to functionality which is not exposed by Node-API, use Node-API. +Refer to C/C++ addons with Node-API for more information on +Node-API.

      +

      When not using Node-API, implementing addons is complicated, involving knowledge of several components and APIs:

      • -

        V8: the C++ library Node.js uses to provide the +

        V8: the C++ library Node.js uses to provide the JavaScript implementation. V8 provides the mechanisms for creating objects, calling functions, etc. V8's API is documented mostly in the v8.h header file (deps/v8/include/v8.h in the Node.js source @@ -9362,12 +9934,12 @@ threads and all of the asynchronous behaviors of the platform. It also serves as a cross-platform abstraction library, giving easy, POSIX-like access across all major operating systems to many common system tasks, such as interacting with the filesystem, sockets, timers, and system events. libuv -also provides a pthreads-like threading abstraction that may be used to -power more sophisticated asynchronous addons that need to move beyond the -standard event loop. Addon authors are encouraged to think about how to +also provides a threading abstraction similar to POSIX threads for +more sophisticated asynchronous addons that need to move beyond the +standard event loop. Addon authors should avoid blocking the event loop with I/O or other time-intensive tasks by -off-loading work via libuv to non-blocking system operations, worker threads -or a custom use of libuv's threads.

        +offloading work via libuv to non-blocking system operations, worker threads, +or a custom use of libuv threads.

      • Internal Node.js libraries. Node.js itself exports C++ APIs that addons can @@ -9383,41 +9955,40 @@ re-exported by Node.js and may be used to various extents by addons. See

      All of the following examples are available for download and may be used as the starting-point for an addon.

      -

      Hello world#

      +

      Hello world#

      This "Hello world" example is a simple addon, written in C++, that is the equivalent of the following JavaScript code:

      -
      module.exports.hello = () => 'world';
      +
      module.exports.hello = () => 'world';

      First, create the file hello.cc:

      // hello.cc
      -#include <node.h>
      +#include <node.h>
       
       namespace demo {
       
       using v8::FunctionCallbackInfo;
       using v8::Isolate;
       using v8::Local;
      -using v8::NewStringType;
       using v8::Object;
       using v8::String;
       using v8::Value;
       
      -void Method(const FunctionCallbackInfo<Value>& args) {
      -  Isolate* isolate = args.GetIsolate();
      -  args.GetReturnValue().Set(String::NewFromUtf8(
      -      isolate, "world", NewStringType::kNormal).ToLocalChecked());
      +void Method(const FunctionCallbackInfo<Value>& args) {
      +  Isolate* isolate = args.GetIsolate();
      +  args.GetReturnValue().Set(String::NewFromUtf8(
      +      isolate, "world").ToLocalChecked());
       }
       
      -void Initialize(Local<Object> exports) {
      -  NODE_SET_METHOD(exports, "hello", Method);
      +void Initialize(Local<Object> exports) {
      +  NODE_SET_METHOD(exports, "hello", Method);
       }
       
      -NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
      +NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
       
       }  // namespace demo

      All Node.js addons must export an initialization function following the pattern:

      -
      void Initialize(Local<Object> exports);
      -NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
      +
      void Initialize(Local<Object> exports);
      +NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)

      There is no semi-colon after NODE_MODULE as it's not a function (see node.h).

      The module_name must match the filename of the final binary (excluding @@ -9427,20 +9998,20 @@ and the addon module name is addon.

      When building addons with node-gyp, using the macro NODE_GYP_MODULE_NAME as the first parameter of NODE_MODULE() will ensure that the name of the final binary will be passed to NODE_MODULE().

      -

      Context-aware addons#

      +

      Context-aware addons#

      There are environments in which Node.js addons may need to be loaded multiple times in multiple contexts. For example, the Electron runtime runs multiple instances of Node.js in a single process. Each instance will have its own require() cache, and thus each instance will need a native addon to behave -correctly when loaded via require(). From the addon's perspective, this means -that it must support multiple initializations.

      +correctly when loaded via require(). This means that the addon +must support multiple initializations.

      A context-aware addon can be constructed by using the macro NODE_MODULE_INITIALIZER, which expands to the name of a function which Node.js will expect to find when it loads an addon. An addon can thus be initialized as in the following example:

      using namespace v8;
       
      -extern "C" NODE_MODULE_EXPORT void
      +extern "C" NODE_MODULE_EXPORT void
       NODE_MODULE_INITIALIZER(Local<Object> exports,
                               Local<Value> module,
                               Local<Context> context) {
      @@ -9471,7 +10042,7 @@ performing the following steps:

      • Define a class which will hold per-addon-instance data and which has a static member of the form -
        static void DeleteInstance(void* data) {
        +
        static void DeleteInstance(void* data) {
           // Cast `data` to an instance of the class and delete it.
         }
      • @@ -9492,61 +10063,60 @@ native-backed JavaScript functions. The third parameter of be called from JavaScript. The per-addon-instance data must also be passed into any asynchronous callbacks the addon may create.

        The following example illustrates the implementation of a context-aware addon:

        -
        #include <node.h>
        +
        #include <node.h>
         
         using namespace v8;
         
        -class AddonData {
        +class AddonData {
          public:
           explicit AddonData(Isolate* isolate):
        -      call_count(0) {
        +      call_count(0) {
             // Ensure this per-addon-instance data is deleted at environment cleanup.
        -    node::AddEnvironmentCleanupHook(isolate, DeleteInstance, this);
        +    node::AddEnvironmentCleanupHook(isolate, DeleteInstance, this);
           }
         
           // Per-addon data.
        -  int call_count;
        +  int call_count;
         
        -  static void DeleteInstance(void* data) {
        -    delete static_cast<AddonData*>(data);
        +  static void DeleteInstance(void* data) {
        +    delete static_cast<AddonData*>(data);
           }
         };
         
        -static void Method(const v8::FunctionCallbackInfo<v8::Value>& info) {
        +static void Method(const v8::FunctionCallbackInfo<v8::Value>& info) {
           // Retrieve the per-addon-instance data.
           AddonData* data =
        -      reinterpret_cast<AddonData*>(info.Data().As<External>()->Value());
        +      reinterpret_cast<AddonData*>(info.Data().As<External>()->Value());
           data->call_count++;
        -  info.GetReturnValue().Set((double)data->call_count);
        +  info.GetReturnValue().Set((double)data->call_count);
         }
         
         // Initialize this addon to be context-aware.
        -NODE_MODULE_INIT(/* exports, module, context */) {
        -  Isolate* isolate = context->GetIsolate();
        +NODE_MODULE_INIT(/* exports, module, context */) {
        +  Isolate* isolate = context->GetIsolate();
         
           // Create a new instance of `AddonData` for this instance of the addon and
           // tie its life cycle to that of the Node.js environment.
        -  AddonData* data = new AddonData(isolate);
        +  AddonData* data = new AddonData(isolate);
         
           // Wrap the data in a `v8::External` so we can pass it to the method we
           // expose.
        -  Local<External> external = External::New(isolate, data);
        +  Local<External> external = External::New(isolate, data);
         
           // Expose the method `Method` to JavaScript, and make sure it receives the
           // per-addon-instance data we created above by passing `external` as the
           // third parameter to the `FunctionTemplate` constructor.
        -  exports->Set(context,
        -               String::NewFromUtf8(isolate, "method", NewStringType::kNormal)
        -                  .ToLocalChecked(),
        -               FunctionTemplate::New(isolate, Method, external)
        -                  ->GetFunction(context).ToLocalChecked()).FromJust();
        +  exports->Set(context,
        +               String::NewFromUtf8(isolate, "method").ToLocalChecked(),
        +               FunctionTemplate::New(isolate, Method, external)
        +                  ->GetFunction(context).ToLocalChecked()).FromJust();
         }
        -

        Worker support#

        +
        Worker support#
        -

        Linking to libraries included with Node.js#

        +

        Linking to libraries included with Node.js#

        Node.js uses statically linked libraries such as V8, libuv and OpenSSL. All addons are required to link to V8 and may link to any of the other dependencies as well. Typically, this is as simple as including the appropriate @@ -9677,8 +10247,8 @@ aware of:

        When node-gyp runs, it will detect the specific release version of Node.js and download either the full source tarball or just the headers. If the full source is downloaded, addons will have complete access to the full set of -Node.js dependencies. However, if only the Node.js headers are downloaded, then -only the symbols exported by Node.js will be available.

        +Node.js dependencies. However, if only the Node.js headers are downloaded, +then only the symbols exported by Node.js will be available.

      • node-gyp can be run using the --nodedir flag pointing at a local Node.js @@ -9686,7 +10256,7 @@ source image. Using this option, the addon will have access to the full set of dependencies.

      -

      Loading addons using require()#

      +

      Loading addons using require()#

      The filename extension of the compiled addon binary is .node (as opposed to .dll or .so). The require() function is written to look for files with the .node file extension and initialize those as dynamically-linked @@ -9698,7 +10268,7 @@ JavaScript files that happen to share the same base name. For instance, if there is a file addon.js in the same directory as the binary addon.node, then require('addon') will give precedence to the addon.js file and load it instead.

      -

      Native abstractions for Node.js#

      +

      Native abstractions for Node.js#

      Each of the examples illustrated in this document directly use the Node.js and V8 APIs for implementing addons. The V8 API can, and has, changed dramatically from one V8 release to the next (and one major Node.js release to @@ -9708,11 +10278,11 @@ minimize the frequency and impact of such changes but there is little that Node.js can do to ensure stability of the V8 APIs.

      The Native Abstractions for Node.js (or nan) provide a set of tools that addon developers are recommended to use to keep compatibility between past and -future releases of V8 and Node.js. See the nan examples for an +future releases of V8 and Node.js. See the nan examples for an illustration of how it can be used.

      -

      N-API#

      +

      Node-API#

      Stability: 2 - Stable

      -

      N-API is an API for building native addons. It is independent from +

      Node-API is an API for building native addons. It is independent from the underlying JavaScript runtime (e.g. V8) and is maintained as part of Node.js itself. This API will be Application Binary Interface (ABI) stable across versions of Node.js. It is intended to insulate addons from @@ -9722,14 +10292,14 @@ recompilation. Addons are built/packaged with the same approach/tools outlined in this document (node-gyp, etc.). The only difference is the set of APIs that are used by the native code. Instead of using the V8 or Native Abstractions for Node.js APIs, the functions available -in the N-API are used.

      +in the Node-API are used.

      Creating and maintaining an addon that benefits from the ABI stability -provided by N-API carries with it certain +provided by Node-API carries with it certain implementation considerations.

      -

      To use N-API in the above "Hello world" example, replace the content of +

      To use Node-API in the above "Hello world" example, replace the content of hello.cc with the following. All other instructions remain the same.

      -
      // hello.cc using N-API
      -#include <node_api.h>
      +
      // hello.cc using Node-API
      +#include <node_api.h>
       
       namespace demo {
       
      @@ -9737,7 +10307,7 @@ provided by N-API carries with it certain
         napi_value greeting;
         napi_status status;
       
      -  status = napi_create_string_utf8(env, "world", NAPI_AUTO_LENGTH, &greeting);
      +  status = napi_create_string_utf8(env, "world", NAPI_AUTO_LENGTH, &greeting);
         if (status != napi_ok) return nullptr;
         return greeting;
       }
      @@ -9746,41 +10316,41 @@ provided by N-API carries with it certain
         napi_status status;
         napi_value fn;
       
      -  status = napi_create_function(env, nullptr, 0, Method, nullptr, &fn);
      +  status = napi_create_function(env, nullptr, 0, Method, nullptr, &fn);
         if (status != napi_ok) return nullptr;
       
      -  status = napi_set_named_property(env, exports, "hello", fn);
      +  status = napi_set_named_property(env, exports, "hello", fn);
         if (status != napi_ok) return nullptr;
         return exports;
       }
       
      -NAPI_MODULE(NODE_GYP_MODULE_NAME, init)
      +NAPI_MODULE(NODE_GYP_MODULE_NAME, init)
       
       }  // namespace demo

      The functions available and how to use them are documented in -C/C++ addons with N-API.

      -

      Addon examples#

      +C/C++ addons with Node-API.

      +

      Addon examples#

      Following are some example addons intended to help developers get started. The examples use the V8 APIs. Refer to the online V8 reference for help with the various V8 calls, and V8's Embedder's Guide for an explanation of several concepts used such as handles, scopes, function templates, etc.

      Each of these examples using the following binding.gyp file:

      -
      {
      -  "targets": [
      -    {
      -      "target_name": "addon",
      -      "sources": [ "addon.cc" ]
      -    }
      -  ]
      -}
      +
      {
      +  "targets": [
      +    {
      +      "target_name": "addon",
      +      "sources": [ "addon.cc" ]
      +    }
      +  ]
      +}

      In cases where there is more than one .cc file, simply add the additional filename to the sources array:

      -
      "sources": ["addon.cc", "myexample.cc"]
      +
      "sources": ["addon.cc", "myexample.cc"]

      Once the binding.gyp file is ready, the example addons can be configured and built using node-gyp:

      -
      $ node-gyp configure build
      -

      Function arguments#

      +
      $ node-gyp configure build
      +

      Function arguments#

      Addons will typically expose objects and functions that can be accessed from JavaScript running within Node.js. When functions are invoked from JavaScript, the input arguments and return value must be mapped to and from the C/C++ @@ -9788,7 +10358,7 @@ code.

      The following example illustrates how to read function arguments passed from JavaScript and how to return a result:

      // addon.cc
      -#include <node.h>
      +#include <node.h>
       
       namespace demo {
       
      @@ -9796,7 +10366,6 @@ JavaScript and how to return a result:

      using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Number; using v8::Object; using v8::String; @@ -9805,56 +10374,54 @@ JavaScript and how to return a result:

      // This is the implementation of the "add" method // Input arguments are passed using the // const FunctionCallbackInfo<Value>& args struct -void Add(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void Add(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); // Check the number of arguments passed. - if (args.Length() < 2) { + if (args.Length() < 2) { // Throw an Error that is passed back to JavaScript - isolate->ThrowException(Exception::TypeError( - String::NewFromUtf8(isolate, - "Wrong number of arguments", - NewStringType::kNormal).ToLocalChecked())); + isolate->ThrowException(Exception::TypeError( + String::NewFromUtf8(isolate, + "Wrong number of arguments").ToLocalChecked())); return; } // Check the argument types - if (!args[0]->IsNumber() || !args[1]->IsNumber()) { - isolate->ThrowException(Exception::TypeError( - String::NewFromUtf8(isolate, - "Wrong arguments", - NewStringType::kNormal).ToLocalChecked())); + if (!args[0]->IsNumber() || !args[1]->IsNumber()) { + isolate->ThrowException(Exception::TypeError( + String::NewFromUtf8(isolate, + "Wrong arguments").ToLocalChecked())); return; } // Perform the operation - double value = - args[0].As<Number>()->Value() + args[1].As<Number>()->Value(); - Local<Number> num = Number::New(isolate, value); + double value = + args[0].As<Number>()->Value() + args[1].As<Number>()->Value(); + Local<Number> num = Number::New(isolate, value); // Set the return value (using the passed in // FunctionCallbackInfo<Value>&) - args.GetReturnValue().Set(num); + args.GetReturnValue().Set(num); } -void Init(Local<Object> exports) { - NODE_SET_METHOD(exports, "add", Add); +void Init(Local<Object> exports) { + NODE_SET_METHOD(exports, "add", Add); } -NODE_MODULE(NODE_GYP_MODULE_NAME, Init) +NODE_MODULE(NODE_GYP_MODULE_NAME, Init) } // namespace demo

      Once compiled, the example addon can be required and used from within Node.js:

      // test.js
       const addon = require('./build/Release/addon');
       
      -console.log('This should be eight:', addon.add(3, 5));
      -

      Callbacks#

      +console.log('This should be eight:', addon.add(3, 5));
      +

      Callbacks#

      It is common practice within addons to pass JavaScript functions to a C++ function and execute them from there. The following example illustrates how to invoke such callbacks:

      // addon.cc
      -#include <node.h>
      +#include <node.h>
       
       namespace demo {
       
      @@ -9863,29 +10430,27 @@ to invoke such callbacks:

      using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Null; using v8::Object; using v8::String; using v8::Value; -void RunCallback(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); - Local<Function> cb = Local<Function>::Cast(args[0]); +void RunCallback(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); + Local<Function> cb = Local<Function>::Cast(args[0]); const unsigned argc = 1; Local<Value> argv[argc] = { - String::NewFromUtf8(isolate, - "hello world", - NewStringType::kNormal).ToLocalChecked() }; - cb->Call(context, Null(isolate), argc, argv).ToLocalChecked(); + String::NewFromUtf8(isolate, + "hello world").ToLocalChecked() }; + cb->Call(context, Null(isolate), argc, argv).ToLocalChecked(); } -void Init(Local<Object> exports, Local<Object> module) { - NODE_SET_METHOD(module, "exports", RunCallback); +void Init(Local<Object> exports, Local<Object> module) { + NODE_SET_METHOD(module, "exports", RunCallback); } -NODE_MODULE(NODE_GYP_MODULE_NAME, Init) +NODE_MODULE(NODE_GYP_MODULE_NAME, Init) } // namespace demo

      This example uses a two-argument form of Init() that receives the full @@ -9896,17 +10461,17 @@ property of exports.

      // test.js
       const addon = require('./build/Release/addon');
       
      -addon((msg) => {
      -  console.log(msg);
      +addon((msg) => {
      +  console.log(msg);
       // Prints: 'hello world'
       });

      In this example, the callback function is invoked synchronously.

      -

      Object factory#

      +

      Object factory#

      Addons can create and return new objects from within a C++ function as illustrated in the following example. An object is created and returned with a property msg that echoes the string passed to createObject():

      // addon.cc
      -#include <node.h>
      +#include <node.h>
       
       namespace demo {
       
      @@ -9914,46 +10479,44 @@ property msg that echoes the string passed to createObject()<
       using v8::FunctionCallbackInfo;
       using v8::Isolate;
       using v8::Local;
      -using v8::NewStringType;
       using v8::Object;
       using v8::String;
       using v8::Value;
       
      -void CreateObject(const FunctionCallbackInfo<Value>& args) {
      -  Isolate* isolate = args.GetIsolate();
      -  Local<Context> context = isolate->GetCurrentContext();
      +void CreateObject(const FunctionCallbackInfo<Value>& args) {
      +  Isolate* isolate = args.GetIsolate();
      +  Local<Context> context = isolate->GetCurrentContext();
       
      -  Local<Object> obj = Object::New(isolate);
      -  obj->Set(context,
      -           String::NewFromUtf8(isolate,
      -                               "msg",
      -                               NewStringType::kNormal).ToLocalChecked(),
      -                               args[0]->ToString(context).ToLocalChecked())
      -           .FromJust();
      +  Local<Object> obj = Object::New(isolate);
      +  obj->Set(context,
      +           String::NewFromUtf8(isolate,
      +                               "msg").ToLocalChecked(),
      +                               args[0]->ToString(context).ToLocalChecked())
      +           .FromJust();
       
      -  args.GetReturnValue().Set(obj);
      +  args.GetReturnValue().Set(obj);
       }
       
      -void Init(Local<Object> exports, Local<Object> module) {
      -  NODE_SET_METHOD(module, "exports", CreateObject);
      +void Init(Local<Object> exports, Local<Object> module) {
      +  NODE_SET_METHOD(module, "exports", CreateObject);
       }
       
      -NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
      +NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
       
       }  // namespace demo

      To test it in JavaScript:

      // test.js
       const addon = require('./build/Release/addon');
       
      -const obj1 = addon('hello');
      -const obj2 = addon('world');
      -console.log(obj1.msg, obj2.msg);
      +const obj1 = addon('hello');
      +const obj2 = addon('world');
      +console.log(obj1.msg, obj2.msg);
       // Prints: 'hello world'
      -

      Function factory#

      +

      Function factory#

      Another common scenario is creating JavaScript functions that wrap C++ functions and returning those back to JavaScript:

      // addon.cc
      -#include <node.h>
      +#include <node.h>
       
       namespace demo {
       
      @@ -9963,96 +10526,95 @@ functions and returning those back to JavaScript:

      using v8::FunctionTemplate; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Object; using v8::String; using v8::Value; -void MyFunction(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - args.GetReturnValue().Set(String::NewFromUtf8( - isolate, "hello world", NewStringType::kNormal).ToLocalChecked()); +void MyFunction(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + args.GetReturnValue().Set(String::NewFromUtf8( + isolate, "hello world").ToLocalChecked()); } -void CreateFunction(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void CreateFunction(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); - Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction); - Local<Function> fn = tpl->GetFunction(context).ToLocalChecked(); + Local<Context> context = isolate->GetCurrentContext(); + Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction); + Local<Function> fn = tpl->GetFunction(context).ToLocalChecked(); // omit this to make it anonymous - fn->SetName(String::NewFromUtf8( - isolate, "theFunction", NewStringType::kNormal).ToLocalChecked()); + fn->SetName(String::NewFromUtf8( + isolate, "theFunction").ToLocalChecked()); - args.GetReturnValue().Set(fn); + args.GetReturnValue().Set(fn); } -void Init(Local<Object> exports, Local<Object> module) { - NODE_SET_METHOD(module, "exports", CreateFunction); +void Init(Local<Object> exports, Local<Object> module) { + NODE_SET_METHOD(module, "exports", CreateFunction); } -NODE_MODULE(NODE_GYP_MODULE_NAME, Init) +NODE_MODULE(NODE_GYP_MODULE_NAME, Init) } // namespace demo

      To test:

      // test.js
       const addon = require('./build/Release/addon');
       
      -const fn = addon();
      -console.log(fn());
      +const fn = addon();
      +console.log(fn());
       // Prints: 'hello world'
      -

      Wrapping C++ objects#

      +

      Wrapping C++ objects#

      It is also possible to wrap C++ objects/classes in a way that allows new instances to be created using the JavaScript new operator:

      // addon.cc
      -#include <node.h>
      -#include "myobject.h"
      +#include <node.h>
      +#include "myobject.h"
       
       namespace demo {
       
       using v8::Local;
       using v8::Object;
       
      -void InitAll(Local<Object> exports) {
      -  MyObject::Init(exports);
      +void InitAll(Local<Object> exports) {
      +  MyObject::Init(exports);
       }
       
      -NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)
      +NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll)
       
       }  // namespace demo

      Then, in myobject.h, the wrapper class inherits from node::ObjectWrap:

      // myobject.h
      -#ifndef MYOBJECT_H
      -#define MYOBJECT_H
      +#ifndef MYOBJECT_H
      +#define MYOBJECT_H
       
      -#include <node.h>
      -#include <node_object_wrap.h>
      +#include <node.h>
      +#include <node_object_wrap.h>
       
       namespace demo {
       
      -class MyObject : public node::ObjectWrap {
      +class MyObject : public node::ObjectWrap {
        public:
      -  static void Init(v8::Local<v8::Object> exports);
      +  static void Init(v8::Local<v8::Object> exports);
       
        private:
      -  explicit MyObject(double value = 0);
      -  ~MyObject();
      +  explicit MyObject(double value = 0);
      +  ~MyObject();
       
      -  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
      -  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
       
      -  double value_;
      +  double value_;
       };
       
       }  // namespace demo
       
      -#endif
      +#endif

      In myobject.cc, implement the various methods that are to be exposed. Below, the method plusOne() is exposed by adding it to the constructor's prototype:

      // myobject.cc
      -#include "myobject.h"
      +#include "myobject.h"
       
       namespace demo {
       
      @@ -10062,100 +10624,98 @@ prototype:

      using v8::FunctionTemplate; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Number; using v8::Object; using v8::ObjectTemplate; using v8::String; using v8::Value; -MyObject::MyObject(double value) : value_(value) { +MyObject::MyObject(double value) : value_(value) { } -MyObject::~MyObject() { +MyObject::~MyObject() { } -void MyObject::Init(Local<Object> exports) { - Isolate* isolate = exports->GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); +void MyObject::Init(Local<Object> exports) { + Isolate* isolate = exports->GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); - Local<ObjectTemplate> addon_data_tpl = ObjectTemplate::New(isolate); - addon_data_tpl->SetInternalFieldCount(1); // 1 field for the MyObject::New() + Local<ObjectTemplate> addon_data_tpl = ObjectTemplate::New(isolate); + addon_data_tpl->SetInternalFieldCount(1); // 1 field for the MyObject::New() Local<Object> addon_data = - addon_data_tpl->NewInstance(context).ToLocalChecked(); + addon_data_tpl->NewInstance(context).ToLocalChecked(); // Prepare constructor template - Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New, addon_data); - tpl->SetClassName(String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked()); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New, addon_data); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); // Prototype - NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); + NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); - Local<Function> constructor = tpl->GetFunction(context).ToLocalChecked(); - addon_data->SetInternalField(0, constructor); - exports->Set(context, String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked(), - constructor).FromJust(); + Local<Function> constructor = tpl->GetFunction(context).ToLocalChecked(); + addon_data->SetInternalField(0, constructor); + exports->Set(context, String::NewFromUtf8( + isolate, "MyObject").ToLocalChecked(), + constructor).FromJust(); } -void MyObject::New(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); +void MyObject::New(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); - if (args.IsConstructCall()) { + if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` - double value = args[0]->IsUndefined() ? - 0 : args[0]->NumberValue(context).FromMaybe(0); - MyObject* obj = new MyObject(value); - obj->Wrap(args.This()); - args.GetReturnValue().Set(args.This()); + double value = args[0]->IsUndefined() ? + 0 : args[0]->NumberValue(context).FromMaybe(0); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); } else { // Invoked as plain function `MyObject(...)`, turn into construct call. - const int argc = 1; + const int argc = 1; Local<Value> argv[argc] = { args[0] }; Local<Function> cons = - args.Data().As<Object>()->GetInternalField(0).As<Function>(); + args.Data().As<Object>()->GetInternalField(0).As<Function>(); Local<Object> result = - cons->NewInstance(context, argc, argv).ToLocalChecked(); - args.GetReturnValue().Set(result); + cons->NewInstance(context, argc, argv).ToLocalChecked(); + args.GetReturnValue().Set(result); } } -void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); - MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder()); + MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder()); obj->value_ += 1; - args.GetReturnValue().Set(Number::New(isolate, obj->value_)); + args.GetReturnValue().Set(Number::New(isolate, obj->value_)); } } // namespace demo

      To build this example, the myobject.cc file must be added to the binding.gyp:

      -
      {
      -  "targets": [
      -    {
      -      "target_name": "addon",
      -      "sources": [
      -        "addon.cc",
      +
      {
      +  "targets": [
      +    {
      +      "target_name": "addon",
      +      "sources": [
      +        "addon.cc",
               "myobject.cc"
      -      ]
      -    }
      -  ]
      -}
      + ] + } + ] +}

      Test it with:

      // test.js
       const addon = require('./build/Release/addon');
       
      -const obj = new addon.MyObject(10);
      -console.log(obj.plusOne());
      +const obj = new addon.MyObject(10);
      +console.log(obj.plusOne());
       // Prints: 11
      -console.log(obj.plusOne());
      +console.log(obj.plusOne());
       // Prints: 12
      -console.log(obj.plusOne());
      +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 @@ -10163,16 +10723,16 @@ 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#

      +

      Factory of wrapped objects#

      Alternatively, it is possible to use a factory pattern to avoid explicitly creating object instances using the JavaScript new operator:

      -
      const obj = addon.createObject();
      +
      const obj = addon.createObject();
       // instead of:
       // const obj = new addon.Object();

      First, the createObject() method is implemented in addon.cc:

      // addon.cc
      -#include <node.h>
      -#include "myobject.h"
      +#include <node.h>
      +#include "myobject.h"
       
       namespace demo {
       
      @@ -10183,53 +10743,53 @@ creating object instances using the JavaScript new operator:

      using v8::String; using v8::Value; -void CreateObject(const FunctionCallbackInfo<Value>& args) { - MyObject::NewInstance(args); +void CreateObject(const FunctionCallbackInfo<Value>& args) { + MyObject::NewInstance(args); } -void InitAll(Local<Object> exports, Local<Object> module) { - MyObject::Init(exports->GetIsolate()); +void InitAll(Local<Object> exports, Local<Object> module) { + MyObject::Init(exports->GetIsolate()); - NODE_SET_METHOD(module, "exports", CreateObject); + NODE_SET_METHOD(module, "exports", CreateObject); } -NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll) +NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll) } // namespace demo

      In myobject.h, the static method NewInstance() is added to handle instantiating the object. This method takes the place of using new in JavaScript:

      // myobject.h
      -#ifndef MYOBJECT_H
      -#define MYOBJECT_H
      +#ifndef MYOBJECT_H
      +#define MYOBJECT_H
       
      -#include <node.h>
      -#include <node_object_wrap.h>
      +#include <node.h>
      +#include <node_object_wrap.h>
       
       namespace demo {
       
      -class MyObject : public node::ObjectWrap {
      +class MyObject : public node::ObjectWrap {
        public:
      -  static void Init(v8::Isolate* isolate);
      -  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void Init(v8::Isolate* isolate);
      +  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
       
        private:
      -  explicit MyObject(double value = 0);
      -  ~MyObject();
      +  explicit MyObject(double value = 0);
      +  ~MyObject();
       
      -  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
      -  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
         static v8::Global<v8::Function> constructor;
      -  double value_;
      +  double value_;
       };
       
       }  // namespace demo
       
      -#endif
      +#endif

      The implementation in myobject.cc is similar to the previous example:

      // myobject.cc
      -#include <node.h>
      -#include "myobject.h"
      +#include <node.h>
      +#include "myobject.h"
       
       namespace demo {
       
      @@ -10241,7 +10801,6 @@ JavaScript:

      using v8::Global; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Number; using v8::Object; using v8::String; @@ -10251,116 +10810,115 @@ JavaScript:

      // threads. Global<Function> MyObject::constructor; -MyObject::MyObject(double value) : value_(value) { +MyObject::MyObject(double value) : value_(value) { } -MyObject::~MyObject() { +MyObject::~MyObject() { } -void MyObject::Init(Isolate* isolate) { +void MyObject::Init(Isolate* isolate) { // Prepare constructor template - Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New); - tpl->SetClassName(String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked()); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); // Prototype - NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); + NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); - Local<Context> context = isolate->GetCurrentContext(); - constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); + Local<Context> context = isolate->GetCurrentContext(); + constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); - AddEnvironmentCleanupHook(isolate, [](void*) { - constructor.Reset(); + AddEnvironmentCleanupHook(isolate, [](void*) { + constructor.Reset(); }, nullptr); } -void MyObject::New(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); +void MyObject::New(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); - if (args.IsConstructCall()) { + if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` - double value = args[0]->IsUndefined() ? - 0 : args[0]->NumberValue(context).FromMaybe(0); - MyObject* obj = new MyObject(value); - obj->Wrap(args.This()); - args.GetReturnValue().Set(args.This()); + double value = args[0]->IsUndefined() ? + 0 : args[0]->NumberValue(context).FromMaybe(0); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); } else { // Invoked as plain function `MyObject(...)`, turn into construct call. - const int argc = 1; + const int argc = 1; Local<Value> argv[argc] = { args[0] }; - Local<Function> cons = Local<Function>::New(isolate, constructor); + Local<Function> cons = Local<Function>::New(isolate, constructor); Local<Object> instance = - cons->NewInstance(context, argc, argv).ToLocalChecked(); - args.GetReturnValue().Set(instance); + cons->NewInstance(context, argc, argv).ToLocalChecked(); + args.GetReturnValue().Set(instance); } } -void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); const unsigned argc = 1; Local<Value> argv[argc] = { args[0] }; - Local<Function> cons = Local<Function>::New(isolate, constructor); - Local<Context> context = isolate->GetCurrentContext(); + Local<Function> cons = Local<Function>::New(isolate, constructor); + Local<Context> context = isolate->GetCurrentContext(); Local<Object> instance = - cons->NewInstance(context, argc, argv).ToLocalChecked(); + cons->NewInstance(context, argc, argv).ToLocalChecked(); - args.GetReturnValue().Set(instance); + args.GetReturnValue().Set(instance); } -void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); - MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder()); + MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder()); obj->value_ += 1; - args.GetReturnValue().Set(Number::New(isolate, obj->value_)); + args.GetReturnValue().Set(Number::New(isolate, obj->value_)); } } // namespace demo

      Once again, to build this example, the myobject.cc file must be added to the binding.gyp:

      -
      {
      -  "targets": [
      -    {
      -      "target_name": "addon",
      -      "sources": [
      -        "addon.cc",
      +
      {
      +  "targets": [
      +    {
      +      "target_name": "addon",
      +      "sources": [
      +        "addon.cc",
               "myobject.cc"
      -      ]
      -    }
      -  ]
      -}
      + ] + } + ] +}

      Test it with:

      // test.js
       const createObject = require('./build/Release/addon');
       
      -const obj = createObject(10);
      -console.log(obj.plusOne());
      +const obj = createObject(10);
      +console.log(obj.plusOne());
       // Prints: 11
      -console.log(obj.plusOne());
      +console.log(obj.plusOne());
       // Prints: 12
      -console.log(obj.plusOne());
      +console.log(obj.plusOne());
       // Prints: 13
       
      -const obj2 = createObject(20);
      -console.log(obj2.plusOne());
      +const obj2 = createObject(20);
      +console.log(obj2.plusOne());
       // Prints: 21
      -console.log(obj2.plusOne());
      +console.log(obj2.plusOne());
       // Prints: 22
      -console.log(obj2.plusOne());
      +console.log(obj2.plusOne());
       // Prints: 23
      -

      Passing wrapped objects around#

      +

      Passing wrapped objects around#

      In addition to wrapping and returning C++ objects, it is possible to pass wrapped objects around by unwrapping them with the Node.js helper function node::ObjectWrap::Unwrap. The following examples shows a function add() that can take two MyObject objects as input arguments:

      // addon.cc
      -#include <node.h>
      -#include <node_object_wrap.h>
      -#include "myobject.h"
      +#include <node.h>
      +#include <node_object_wrap.h>
      +#include "myobject.h"
       
       namespace demo {
       
      @@ -10373,66 +10931,66 @@ that can take two MyObject objects as input arguments:

      using v8::String; using v8::Value; -void CreateObject(const FunctionCallbackInfo<Value>& args) { - MyObject::NewInstance(args); +void CreateObject(const FunctionCallbackInfo<Value>& args) { + MyObject::NewInstance(args); } -void Add(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); +void Add(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); - MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>( - args[0]->ToObject(context).ToLocalChecked()); - MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>( - args[1]->ToObject(context).ToLocalChecked()); + MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>( + args[0]->ToObject(context).ToLocalChecked()); + MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>( + args[1]->ToObject(context).ToLocalChecked()); - double sum = obj1->value() + obj2->value(); - args.GetReturnValue().Set(Number::New(isolate, sum)); + double sum = obj1->value() + obj2->value(); + args.GetReturnValue().Set(Number::New(isolate, sum)); } -void InitAll(Local<Object> exports) { - MyObject::Init(exports->GetIsolate()); +void InitAll(Local<Object> exports) { + MyObject::Init(exports->GetIsolate()); - NODE_SET_METHOD(exports, "createObject", CreateObject); - NODE_SET_METHOD(exports, "add", Add); + NODE_SET_METHOD(exports, "createObject", CreateObject); + NODE_SET_METHOD(exports, "add", Add); } -NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll) +NODE_MODULE(NODE_GYP_MODULE_NAME, InitAll) } // namespace demo

      In myobject.h, a new public method is added to allow access to private values after unwrapping the object.

      // myobject.h
      -#ifndef MYOBJECT_H
      -#define MYOBJECT_H
      +#ifndef MYOBJECT_H
      +#define MYOBJECT_H
       
      -#include <node.h>
      -#include <node_object_wrap.h>
      +#include <node.h>
      +#include <node_object_wrap.h>
       
       namespace demo {
       
      -class MyObject : public node::ObjectWrap {
      +class MyObject : public node::ObjectWrap {
        public:
      -  static void Init(v8::Isolate* isolate);
      -  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
      -  inline double value() const { return value_; }
      +  static void Init(v8::Isolate* isolate);
      +  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  inline double value() const { return value_; }
       
        private:
      -  explicit MyObject(double value = 0);
      -  ~MyObject();
      +  explicit MyObject(double value = 0);
      +  ~MyObject();
       
      -  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
      +  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
         static v8::Global<v8::Function> constructor;
      -  double value_;
      +  double value_;
       };
       
       }  // namespace demo
       
      -#endif
      +#endif

      The implementation of myobject.cc is similar to before:

      // myobject.cc
      -#include <node.h>
      -#include "myobject.h"
      +#include <node.h>
      +#include "myobject.h"
       
       namespace demo {
       
      @@ -10444,7 +11002,6 @@ after unwrapping the object.

      using v8::Global; using v8::Isolate; using v8::Local; -using v8::NewStringType; using v8::Object; using v8::String; using v8::Value; @@ -10453,60 +11010,59 @@ after unwrapping the object.

      // threads. Global<Function> MyObject::constructor; -MyObject::MyObject(double value) : value_(value) { +MyObject::MyObject(double value) : value_(value) { } -MyObject::~MyObject() { +MyObject::~MyObject() { } -void MyObject::Init(Isolate* isolate) { +void MyObject::Init(Isolate* isolate) { // Prepare constructor template - Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New); - tpl->SetClassName(String::NewFromUtf8( - isolate, "MyObject", NewStringType::kNormal).ToLocalChecked()); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); - Local<Context> context = isolate->GetCurrentContext(); - constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); + Local<Context> context = isolate->GetCurrentContext(); + constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); - AddEnvironmentCleanupHook(isolate, [](void*) { - constructor.Reset(); + AddEnvironmentCleanupHook(isolate, [](void*) { + constructor.Reset(); }, nullptr); } -void MyObject::New(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); - Local<Context> context = isolate->GetCurrentContext(); +void MyObject::New(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); - if (args.IsConstructCall()) { + if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` - double value = args[0]->IsUndefined() ? - 0 : args[0]->NumberValue(context).FromMaybe(0); - MyObject* obj = new MyObject(value); - obj->Wrap(args.This()); - args.GetReturnValue().Set(args.This()); + double value = args[0]->IsUndefined() ? + 0 : args[0]->NumberValue(context).FromMaybe(0); + MyObject* obj = new MyObject(value); + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); } else { // Invoked as plain function `MyObject(...)`, turn into construct call. - const int argc = 1; + const int argc = 1; Local<Value> argv[argc] = { args[0] }; - Local<Function> cons = Local<Function>::New(isolate, constructor); + Local<Function> cons = Local<Function>::New(isolate, constructor); Local<Object> instance = - cons->NewInstance(context, argc, argv).ToLocalChecked(); - args.GetReturnValue().Set(instance); + cons->NewInstance(context, argc, argv).ToLocalChecked(); + args.GetReturnValue().Set(instance); } } -void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) { - Isolate* isolate = args.GetIsolate(); +void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) { + Isolate* isolate = args.GetIsolate(); const unsigned argc = 1; Local<Value> argv[argc] = { args[0] }; - Local<Function> cons = Local<Function>::New(isolate, constructor); - Local<Context> context = isolate->GetCurrentContext(); + Local<Function> cons = Local<Function>::New(isolate, constructor); + Local<Context> context = isolate->GetCurrentContext(); Local<Object> instance = - cons->NewInstance(context, argc, argv).ToLocalChecked(); + cons->NewInstance(context, argc, argv).ToLocalChecked(); - args.GetReturnValue().Set(instance); + args.GetReturnValue().Set(instance); } } // namespace demo
      @@ -10514,34 +11070,34 @@ MyObject::~MyObject() {
      // test.js
       const addon = require('./build/Release/addon');
       
      -const obj1 = addon.createObject(10);
      -const obj2 = addon.createObject(20);
      -const result = addon.add(obj1, obj2);
      +const obj1 = addon.createObject(10);
      +const obj2 = addon.createObject(20);
      +const result = addon.add(obj1, obj2);
       
      -console.log(result);
      -// Prints: 30
      -

      N-API#

      +console.log(result); +// Prints: 30
      +
      +

      Node-API#

      Stability: 2 - Stable

      -

      N-API (pronounced N as in the letter, followed by API) -is an API for building native Addons. It is independent from -the underlying JavaScript runtime (for example, V8) and is maintained as part of -Node.js itself. This API will be Application Binary Interface (ABI) stable -across versions of Node.js. It is intended to insulate Addons from -changes in the underlying JavaScript engine and allow modules +

      Node-API (formerly N-API) is an API for building native Addons. It is +independent from the underlying JavaScript runtime (for example, V8) and is +maintained as part of Node.js itself. This API will be Application Binary +Interface (ABI) stable across versions of Node.js. It is intended to insulate +addons from changes in the underlying JavaScript engine and allow modules compiled for one major version to run on later major versions of Node.js without recompilation. The ABI Stability guide provides a more in-depth explanation.

      Addons are built/packaged with the same approach/tools outlined in the section titled C++ Addons. The only difference is the set of APIs that are used by the native code. Instead of using the V8 or Native Abstractions for Node.js -APIs, the functions available in the N-API are used.

      -

      APIs exposed by N-API are generally used to create and manipulate +APIs, the functions available in Node-API are used.

      +

      APIs exposed by Node-API are generally used to create and manipulate JavaScript values. Concepts and operations generally map to ideas specified in the ECMA-262 Language Specification. The APIs have the following properties:

        -
      • All N-API calls return a status code of type napi_status. This +
      • All Node-API calls return a status code of type napi_status. This status indicates whether the API call succeeded or failed.
      • The API's return value is passed via an out parameter.
      • All JavaScript values are abstracted behind an opaque type named @@ -10550,75 +11106,75 @@ status indicates whether the API call succeeded or failed.
      • using napi_get_last_error_info. More information can be found in the error handling section Error handling.
      -

      The N-API is a C API that ensures ABI stability across Node.js versions +

      Node-API is a C API that ensures ABI stability across Node.js versions and different compiler levels. A C++ API can be easier to use. To support using C++, the project maintains a C++ wrapper module called node-addon-api. This wrapper provides an inlineable C++ API. Binaries built -with node-addon-api will depend on the symbols for the N-API C-based +with node-addon-api will depend on the symbols for the Node-API C-based functions exported by Node.js. node-addon-api is a more -efficient way to write code that calls N-API. Take, for example, the +efficient way to write code that calls Node-API. Take, for example, the following node-addon-api code. The first section shows the node-addon-api code and the second section shows what actually gets used in the addon.

      -
      Object obj = Object::New(env);
      -obj["foo"] = String::New(env, "bar");
      +
      Object obj = Object::New(env);
      +obj["foo"] = String::New(env, "bar");
      napi_status status;
      -napi_value object, string;
      -status = napi_create_object(env, &object);
      +napi_value object, string;
      +status = napi_create_object(env, &object);
       if (status != napi_ok) {
      -  napi_throw_error(env, ...);
      +  napi_throw_error(env, ...);
         return;
       }
       
      -status = napi_create_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string);
      +status = napi_create_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string);
       if (status != napi_ok) {
      -  napi_throw_error(env, ...);
      +  napi_throw_error(env, ...);
         return;
       }
       
      -status = napi_set_named_property(env, object, "foo", string);
      +status = napi_set_named_property(env, object, "foo", string);
       if (status != napi_ok) {
      -  napi_throw_error(env, ...);
      +  napi_throw_error(env, ...);
         return;
       }

      The end result is that the addon only uses the exported C APIs. As a result, it still gets the benefits of the ABI stability provided by the C API.

      When using node-addon-api instead of the C APIs, start with the API docs for node-addon-api.

      -

      The N-API Resource offers an -excellent orientation and tips for developers just getting started with N-API -and node-addon-api.

      -

      Implications of ABI stability#

      -

      Although N-API provides an ABI stability guarantee, other parts of Node.js do +

      The Node-API Resource offers +an excellent orientation and tips for developers just getting started with +Node-API and node-addon-api.

      +

      Implications of ABI stability#

      +

      Although Node-API provides an ABI stability guarantee, other parts of Node.js do not, and any external libraries used from the addon may not. In particular, none of the following APIs provide an ABI stability guarantee across major versions:

      • the Node.js C++ APIs available via any of

        -
        #include <node.h>
        -#include <node_buffer.h>
        -#include <node_version.h>
        -#include <node_object_wrap.h>
        +
        #include <node.h>
        +#include <node_buffer.h>
        +#include <node_version.h>
        +#include <node_object_wrap.h>
      • the libuv APIs which are also included with Node.js and available via

        -
        #include <uv.h>
        +
        #include <uv.h>
      • the V8 API available via

        -
        #include <v8.h>
        +
        #include <v8.h>

      Thus, for an addon to remain ABI-compatible across Node.js major versions, it -must use N-API exclusively by restricting itself to using

      -
      #include <node_api.h>
      +must use Node-API exclusively by restricting itself to using

      +
      #include <node_api.h>

      and by checking, for all external libraries that it uses, that the external -library makes ABI stability guarantees similar to N-API.

      -

      Building#

      +library makes ABI stability guarantees similar to Node-API.

      +

      Building#

      Unlike modules written in JavaScript, developing and deploying Node.js -native addons using N-API requires an additional set of tools. Besides the +native addons using Node-API requires an additional set of tools. Besides the basic tools required to develop for Node.js, the native addon developer requires a toolchain that can compile C and C++ code into a binary. In addition, depending upon how the native addon is deployed, the user of @@ -10637,198 +11193,215 @@ IDE. The following command installs the necessary toolchain:

      npm install --global windows-build-tools

      The sections below describe the additional tools available for developing and deploying Node.js native addons.

      -

      Build tools#

      +

      Build tools#

      Both the tools listed here require that users of the native addon have a C/C++ toolchain installed in order to successfully install the native addon.

      -

      node-gyp#

      -

      node-gyp is a build system based on Google's GYP tool and comes -bundled with npm. GYP, and therefore node-gyp, requires that Python be -installed.

      +
      node-gyp#
      +

      node-gyp is a build system based on the gyp-next fork of +Google's GYP tool and comes bundled with npm. GYP, and therefore node-gyp, +requires that Python be installed.

      Historically, node-gyp has been the tool of choice for building native addons. It has widespread adoption and documentation. However, some developers have run into limitations in node-gyp.

      -

      CMake.js#

      +
      CMake.js#

      CMake.js is an alternative build system based on CMake.

      CMake.js is a good choice for projects that already use CMake or for developers affected by limitations in node-gyp.

      -

      Uploading precompiled binaries#

      +

      Uploading precompiled binaries#

      The three tools listed here permit native addon developers and maintainers to create and upload binaries to public or private servers. These tools are typically integrated with CI/CD build systems like Travis CI and AppVeyor to build and upload binaries for a variety of platforms and architectures. These binaries are then available for download by users who do not need to have a C/C++ toolchain installed.

      -

      node-pre-gyp#

      +
      node-pre-gyp#

      node-pre-gyp is a tool based on node-gyp that adds the ability to upload binaries to a server of the developer's choice. node-pre-gyp has particularly good support for uploading binaries to Amazon S3.

      -

      prebuild#

      +
      prebuild#

      prebuild is a tool that supports builds using either node-gyp or CMake.js. Unlike node-pre-gyp which supports a variety of servers, prebuild uploads binaries only to GitHub releases. prebuild is a good choice for GitHub projects using CMake.js.

      -

      prebuildify#

      +
      prebuildify#

      prebuildify is a tool based on node-gyp. The advantage of prebuildify is that the built binaries are bundled with the native module when it's uploaded to npm. The binaries are downloaded from npm and are immediately available to the module user when the native module is installed.

      -

      Usage#

      -

      In order to use the N-API functions, include the file node_api.h which is -located in the src directory in the node development tree:

      -
      #include <node_api.h>
      +

      Usage#

      +

      In order to use the Node-API functions, include the file node_api.h which +is located in the src directory in the node development tree:

      +
      #include <node_api.h>

      This will opt into the default NAPI_VERSION for the given release of Node.js. -In order to ensure compatibility with specific versions of N-API, the version +In order to ensure compatibility with specific versions of Node-API, the version can be specified explicitly when including the header:

      -
      #define NAPI_VERSION 3
      -#include <node_api.h>
      -

      This restricts the N-API surface to just the functionality that was available in -the specified (and earlier) versions.

      -

      Some of the N-API surface is experimental and requires explicit opt-in:

      -
      #define NAPI_EXPERIMENTAL
      -#include <node_api.h>
      +
      #define NAPI_VERSION 3
      +#include <node_api.h>
      +

      This restricts the Node-API surface to just the functionality that was available +in the specified (and earlier) versions.

      +

      Some of the Node-API surface is experimental and requires explicit opt-in:

      +
      #define NAPI_EXPERIMENTAL
      +#include <node_api.h>

      In this case the entire API surface, including any experimental APIs, will be available to the module code.

      -

      N-API version matrix#

      -

      N-API versions are additive and versioned independently from Node.js. +

      Node-API version matrix#

      +

      Node-API versions are additive and versioned independently from Node.js. Version 4 is an extension to version 3 in that it has all of the APIs from version 3 with some additions. This means that it is not necessary to recompile for new versions of Node.js which are listed as supporting a later version.

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      123456
      v6.xv6.14.2*
      v8.xv8.0.0*v8.10.0*v8.11.2v8.16.0
      v9.xv9.0.0*v9.3.0*v9.11.0*
      v10.xv10.0.0v10.0.0v10.0.0v10.16.0v10.17.0v10.20.0
      v11.xv11.0.0v11.0.0v11.0.0v11.8.0
      v12.xv12.0.0v12.0.0v12.0.0v12.0.0v12.11.0v12.17.0
      v13.xv13.0.0v13.0.0v13.0.0v13.0.0v13.0.0
      v14.xv14.0.0v14.0.0v14.0.0v14.0.0v14.0.0v14.0.0
      -

      * Indicates that the N-API version was released as experimental

      -

      Each API documented for N-API will have a header named added in:, and APIs -which are stable will have the additional header N-API version:. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      123
      v6.xv6.14.2*
      v8.xv8.6.0**v8.10.0*v8.11.2
      v9.xv9.0.0*v9.3.0*v9.11.0*
      ≥ v10.xall releasesall releasesall releases
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      45678
      v10.xv10.16.0v10.17.0v10.20.0v10.23.0
      v11.xv11.8.0
      v12.xv12.0.0v12.11.0v12.17.0v12.19.0v12.22.0
      v13.xv13.0.0v13.0.0
      v14.xv14.0.0v14.0.0v14.0.0v14.12.0v14.17.0
      v15.xv15.0.0v15.0.0v15.0.0v15.0.0v15.12.0
      v16.xv16.0.0v16.0.0v16.0.0v16.0.0v16.0.0
      +

      * Node-API was experimental.

      +

      ** Node.js 8.0.0 included Node-API as experimental. It was released as +Node-API version 1 but continued to evolve until Node.js 8.6.0. The API is +different in versions prior to Node.js 8.6.0. We recommend Node-API version 3 or +later.

      +

      Each API documented for Node-API will have a header named added in:, and APIs +which are stable will have the additional header Node-API version:. APIs are directly usable when using a Node.js version which supports -the N-API version shown in N-API version: or higher. +the Node-API version shown in Node-API version: or higher. When using a Node.js version that does not support the -N-API version: listed or if there is no N-API version: listed, +Node-API version: listed or if there is no Node-API version: listed, then the API will only be available if #define NAPI_EXPERIMENTAL precedes the inclusion of node_api.h or js_native_api.h. If an API appears not to be available on a version of Node.js which is later than the one shown in added in: then this is most likely the reason for the apparent absence.

      -

      The N-APIs associated strictly with accessing ECMAScript features from native +

      The Node-APIs associated strictly with accessing ECMAScript features from native code can be found separately in js_native_api.h and js_native_api_types.h. The APIs defined in these headers are included in node_api.h and node_api_types.h. The headers are structured in this way in order to allow -implementations of N-API outside of Node.js. For those implementations the +implementations of Node-API outside of Node.js. For those implementations the Node.js specific APIs may not be applicable.

      The Node.js-specific parts of an addon can be separated from the code that exposes the actual functionality to the JavaScript environment so that the -latter may be used with multiple implementations of N-API. In the example below, -addon.c and addon.h refer only to js_native_api.h. This ensures that -addon.c can be reused to compile against either the Node.js implementation of -N-API or any implementation of N-API outside of Node.js.

      +latter may be used with multiple implementations of Node-API. In the example +below, addon.c and addon.h refer only to js_native_api.h. This ensures +that addon.c can be reused to compile against either the Node.js +implementation of Node-API or any implementation of Node-API outside of Node.js.

      addon_node.c is a separate file that contains the Node.js specific entry point to the addon and which instantiates the addon by calling into addon.c when the addon is loaded into a Node.js environment.

      // addon.h
      -#ifndef _ADDON_H_
      -#define _ADDON_H_
      -#include <js_native_api.h>
      -napi_value create_addon(napi_env env);
      -#endif  // _ADDON_H_
      +#ifndef _ADDON_H_ +#define _ADDON_H_ +#include <js_native_api.h> +napi_value create_addon(napi_env env); +#endif // _ADDON_H_
      // addon.c
      -#include "addon.h"
      +#include "addon.h"
       
      -#define NAPI_CALL(env, call)                                      \
      +#define NAPI_CALL(env, call)                                      \
         do {                                                            \
           napi_status status = (call);                                  \
      -    if (status != napi_ok) {                                      \
      +    if (status != napi_ok) {                                      \
             const napi_extended_error_info* error_info = NULL;          \
             napi_get_last_error_info((env), &error_info);               \
             bool is_pending;                                            \
             napi_is_exception_pending((env), &is_pending);              \
      -      if (!is_pending) {                                          \
      +      if (!is_pending) {                                          \
               const char* message = (error_info->error_message == NULL) \
      -            ? "empty error message"                               \
      +            ? "empty error message"                               \
                   : error_info->error_message;                          \
               napi_throw_error((env), NULL, message);                   \
               return NULL;                                              \
      @@ -10836,13 +11409,13 @@ addon is loaded into a Node.js environment.

      } \ } while(0)
      -static napi_value -DoSomethingUseful(napi_env env, napi_callback_info info) { +static napi_value +DoSomethingUseful(napi_env env, napi_callback_info info) { // Do something useful. return NULL; } -napi_value create_addon(napi_env env) { +napi_value create_addon(napi_env env) { napi_value result; NAPI_CALL(env, napi_create_object(env, &result)); @@ -10862,8 +11435,8 @@ addon is loaded into a Node.js environment.

      return result; }
      // addon_node.c
      -#include <node_api.h>
      -#include "addon.h"
      +#include <node_api.h>
      +#include "addon.h"
       
       NAPI_MODULE_INIT() {
         // This function body is expected to return a `napi_value`.
      @@ -10871,7 +11444,7 @@ NAPI_MODULE_INIT() {
         // the body, as they are provided by the definition of `NAPI_MODULE_INIT()`.
         return create_addon(env);
       }
      -

      Environment life cycle APIs#

      +

      Environment life cycle APIs#

      Section 8.7 of the ECMAScript Language Specification defines the concept of an "Agent" as a self-contained environment in which JavaScript code runs. Multiple such Agents may be started and terminated either concurrently or in @@ -10890,19 +11463,19 @@ multiple threads.

      Native addons may need to allocate global state which they use during their entire life cycle such that the state must be unique to each instance of the addon.

      -

      To this end, N-API provides a way to allocate data such that its life cycle is -tied to the life cycle of the Agent.

      -

      napi_set_instance_data#

      +

      To this end, Node-API provides a way to allocate data such that its life cycle +is tied to the life cycle of the Agent.

      +

      napi_set_instance_data#

      -
      napi_status napi_set_instance_data(napi_env env,
      -                                   void* data,
      +
      napi_status napi_set_instance_data(napi_env env,
      +                                   void* data,
                                          napi_finalize finalize_cb,
      -                                   void* finalize_hint);
      + void* finalize_hint)
      ;
        -
      • [in] env: The environment that the N-API call is invoked under.
      • +
      • [in] env: The environment that the Node-API call is invoked under.
      • [in] data: The data item to make available to bindings of this instance.
      • [in] finalize_cb: The function to call when the environment is being torn down. The function receives data so that it might free it. @@ -10916,15 +11489,15 @@ be retrieved using napi_get_instance_data(). Any existing data asso the currently running Agent which was set by means of a previous call to napi_set_instance_data() will be overwritten. If a finalize_cb was provided by the previous call, it will not be called.

        -

        napi_get_instance_data#

        +

        napi_get_instance_data#

        -
        napi_status napi_get_instance_data(napi_env env,
        -                                   void** data);
        +
        napi_status napi_get_instance_data(napi_env env,
        +                                   void** data);
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [out] data: The data item that was previously associated with the currently running Agent by a call to napi_set_instance_data().
        @@ -10932,18 +11505,18 @@ running Agent by a call to napi_set_instance_data().
      • This API retrieves data that was previously associated with the currently running Agent via napi_set_instance_data(). If no data is set, the call will succeed and data will be set to NULL.

        -

        Basic N-API data types#

        -

        N-API exposes the following fundamental datatypes as abstractions that are +

      Basic Node-API data types#

      +

      Node-API exposes the following fundamental datatypes as abstractions that are consumed by the various APIs. These APIs should be treated as opaque, -introspectable only with other N-API calls.

      -

      napi_status#

      +introspectable only with other Node-API calls.

      +

      napi_status#

      -

      Integral status code indicating the success or failure of a N-API call. +

      Integral status code indicating the success or failure of a Node-API call. Currently, the following status codes are supported.

      -
      typedef enum {
      +
      typedef enum {
         napi_ok,
         napi_invalid_arg,
         napi_object_expected,
      @@ -10965,18 +11538,19 @@ Currently, the following status codes are supported.

      napi_date_expected, napi_arraybuffer_expected, napi_detachable_arraybuffer_expected, + napi_would_deadlock, /* unused */ } napi_status;

      If additional information is required upon an API returning a failed status, it can be obtained by calling napi_get_last_error_info.

      -

      napi_extended_error_info#

      +

      napi_extended_error_info#

      typedef struct {
      -  const char* error_message;
      -  void* engine_reserved;
      -  uint32_t engine_error_code;
      +  const char* error_message;
      +  void* engine_reserved;
      +  uint32_t engine_error_code;
         napi_status error_code;
       } napi_extended_error_info;
        @@ -10986,24 +11560,24 @@ the error. not implemented for any VM.
      • engine_error_code: VM-specific error code. This is currently not implemented for any VM.
      • -
      • error_code: The N-API status code that originated with the last error.
      • +
      • error_code: The Node-API status code that originated with the last error.

      See the Error handling section for additional information.

      -

      napi_env#

      -

      napi_env is used to represent a context that the underlying N-API +

      napi_env#

      +

      napi_env is used to represent a context that the underlying Node-API implementation can use to persist VM-specific state. This structure is passed to native functions when they're invoked, and it must be passed back when -making N-API calls. Specifically, the same napi_env that was passed in when +making Node-API calls. Specifically, the same napi_env that was passed in when the initial native function was called must be passed to any subsequent -nested N-API calls. Caching the napi_env for the purpose of general reuse, +nested Node-API calls. Caching the napi_env for the purpose of general reuse, and passing the napi_env between instances of the same addon running on different Worker threads is not allowed. The napi_env becomes invalid when an instance of a native addon is unloaded. Notification of this event is delivered through the callbacks given to napi_add_env_cleanup_hook and napi_set_instance_data.

      -

      napi_value#

      +

      napi_value#

      This is an opaque pointer that is used to represent a JavaScript value.

      -

      napi_threadsafe_function#

      +

      napi_threadsafe_function#

      Error handling#

      +

      Node-API uses both return values and JavaScript exceptions for error handling. The following sections explain the approach for each case.

      -

      Return values#

      -

      All of the N-API functions share the same error handling pattern. The +

      Return values#

      +

      All of the Node-API functions share the same error handling pattern. The return type of all API functions is napi_status.

      The return value will be napi_ok if the request was successful and no uncaught JavaScript exception was thrown. If an error occurred AND @@ -11237,30 +11811,30 @@ The format of the napi_extended_error_info structure is as follows: N-API version: 1

      typedef struct napi_extended_error_info {
      -  const char* error_message;
      -  void* engine_reserved;
      -  uint32_t engine_error_code;
      +  const char* error_message;
      +  void* engine_reserved;
      +  uint32_t engine_error_code;
         napi_status error_code;
       };
      • error_message: Textual representation of the error that occurred.
      • engine_reserved: Opaque handle reserved for engine use only.
      • engine_error_code: VM specific error code.
      • -
      • error_code: n-api status code for the last error.
      • +
      • error_code: Node-API status code for the last error.

      napi_get_last_error_info returns the information for the last -N-API call that was made.

      +Node-API call that was made.

      Do not rely on the content or format of any of the extended information as it is not subject to SemVer and may change at any time. It is intended only for logging purposes.

      -

      napi_get_last_error_info#

      +
      napi_get_last_error_info#
      -
      napi_status
      -napi_get_last_error_info(napi_env env,
      -                         const napi_extended_error_info** result);
      +
      napi_status
      +napi_get_last_error_info(napi_env env,
      +                         const napi_extended_error_info** result);
      • [in] env: The environment that the API is invoked under.
      • [out] result: The napi_extended_error_info structure with more @@ -11270,13 +11844,13 @@ information about the error.
      • This API retrieves a napi_extended_error_info structure with information about the last error that occurred.

        The content of the napi_extended_error_info returned is only valid up until -an n-api function is called on the same env.

        +a Node-API function is called on the same env.

        Do not rely on the content or format of any of the extended information as it is not subject to SemVer and may change at any time. It is intended only for logging purposes.

        This API can be called even if there is a pending JavaScript exception.

        -

        Exceptions#

        -

        Any N-API function call may result in a pending JavaScript exception. This is +

        Exceptions#

        +

        Any Node-API function call may result in a pending JavaScript exception. This is the case for any of the API functions, even those that may not cause the execution of JavaScript.

        If the napi_status returned by a function is napi_ok then no @@ -11285,10 +11859,10 @@ exception is pending and no additional action is required. If the napi_pending_exception, in order to try to recover and continue instead of simply returning immediately, napi_is_exception_pending must be called in order to determine if an exception is pending or not.

        -

        In many cases when an N-API function is called and an exception is +

        In many cases when a Node-API function is called and an exception is already pending, the function will return immediately with a napi_status of napi_pending_exception. However, this is not the case -for all functions. N-API allows a subset of the functions to be +for all functions. Node-API allows a subset of the functions to be called to allow for some minimal cleanup before returning to JavaScript. In that case, napi_status will reflect the status for the function. It will not reflect previous pending exceptions. To avoid confusion, check @@ -11297,7 +11871,7 @@ the error status after every function call.

        The first approach is to do any appropriate cleanup and then return so that execution will return to JavaScript. As part of the transition back to JavaScript, the exception will be thrown at the point in the JavaScript -code where the native method was invoked. The behavior of most N-API calls +code where the native method was invoked. The behavior of most Node-API calls is unspecified while an exception is pending, and many will simply return napi_pending_exception, so do as little as possible and then return to JavaScript where the exception can be handled.

        @@ -11310,7 +11884,7 @@ clear the exception. On success, result will contain the handle to the last JavaScript Object thrown. If it is determined, after retrieving the exception, the exception cannot be handled after all it can be re-thrown it with napi_throw where error is the -JavaScript Error object to be thrown.

        +JavaScript value to be thrown.

        The following utility functions are also available in case native code needs to throw an exception or determine if a napi_value is an instance of a JavaScript Error object: napi_throw_error, @@ -11326,7 +11900,7 @@ generated internally. The goal is for applications to use these error codes for all error checking. The associated error messages will remain, but will only be meant to be used for logging and display with the expectation that the message can change without -SemVer applying. In order to support this model with N-API, both +SemVer applying. In order to support this model with Node-API, both in internal functionality and for module specific functionality (as its good practice), the throw_ and create_ functions take an optional code parameter which is the string for the code @@ -11338,26 +11912,26 @@ the name associated with the error is also updated to be:

        and code is the code that was provided. For example, if the code is 'ERR_ERROR_1' and a TypeError is being created the name will be:

        TypeError [ERR_ERROR_1]
        -

        napi_throw#

        +
        napi_throw#
        -
        NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error);
        +
        NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error);
        • [in] env: The environment that the API is invoked under.
        • [in] error: The JavaScript value to be thrown.

        Returns napi_ok if the API succeeded.

        This API throws the JavaScript value provided.

        -

        napi_throw_error#

        +
        napi_throw_error#
        -
        NAPI_EXTERN napi_status napi_throw_error(napi_env env,
        -                                         const char* code,
        -                                         const char* msg);
        +
        NAPI_EXTERN napi_status napi_throw_error(napi_env env,
        +                                         const char* code,
        +                                         const char* msg);
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional error code to be set on the error.
        • @@ -11365,14 +11939,14 @@ is 'ERR_ERROR_1' and a TypeError is being created the

        Returns napi_ok if the API succeeded.

        This API throws a JavaScript Error with the text provided.

        -

        napi_throw_type_error#

        +
        napi_throw_type_error#
        -
        NAPI_EXTERN napi_status napi_throw_type_error(napi_env env,
        -                                              const char* code,
        -                                              const char* msg);
        +
        NAPI_EXTERN napi_status napi_throw_type_error(napi_env env,
        +                                              const char* code,
        +                                              const char* msg);
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional error code to be set on the error.
        • @@ -11380,14 +11954,14 @@ is 'ERR_ERROR_1' and a TypeError is being created the

        Returns napi_ok if the API succeeded.

        This API throws a JavaScript TypeError with the text provided.

        -

        napi_throw_range_error#

        +
        napi_throw_range_error#
        -
        NAPI_EXTERN napi_status napi_throw_range_error(napi_env env,
        -                                               const char* code,
        -                                               const char* msg);
        +
        NAPI_EXTERN napi_status napi_throw_range_error(napi_env env,
        +                                               const char* code,
        +                                               const char* msg);
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional error code to be set on the error.
        • @@ -11395,14 +11969,14 @@ is 'ERR_ERROR_1' and a TypeError is being created the

        Returns napi_ok if the API succeeded.

        This API throws a JavaScript RangeError with the text provided.

        -

        napi_is_error#

        +
        napi_is_error#
        -
        NAPI_EXTERN napi_status napi_is_error(napi_env env,
        +
        NAPI_EXTERN napi_status napi_is_error(napi_env env,
                                               napi_value value,
        -                                      bool* result);
        + bool* result)
        ;
        • [in] env: The environment that the API is invoked under.
        • [in] value: The napi_value to be checked.
        • @@ -11411,112 +11985,112 @@ an error, false otherwise.

        Returns napi_ok if the API succeeded.

        This API queries a napi_value to check if it represents an error object.

        -

        napi_create_error#

        +
        napi_create_error#
        -
        NAPI_EXTERN napi_status napi_create_error(napi_env env,
        +
        NAPI_EXTERN napi_status napi_create_error(napi_env env,
                                                   napi_value code,
                                                   napi_value msg,
        -                                          napi_value* result);
        + napi_value* result)
        ;
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional napi_value with the string for the error code to be associated with the error.
        • -
        • [in] msg: napi_value that references a JavaScript String to be used as +
        • [in] msg: napi_value that references a JavaScript string to be used as the message for the Error.
        • [out] result: napi_value representing the error created.

        Returns napi_ok if the API succeeded.

        This API returns a JavaScript Error with the text provided.

        -

        napi_create_type_error#

        +
        napi_create_type_error#
        -
        NAPI_EXTERN napi_status napi_create_type_error(napi_env env,
        +
        NAPI_EXTERN napi_status napi_create_type_error(napi_env env,
                                                        napi_value code,
                                                        napi_value msg,
        -                                               napi_value* result);
        + napi_value* result)
        ;
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional napi_value with the string for the error code to be associated with the error.
        • -
        • [in] msg: napi_value that references a JavaScript String to be used as +
        • [in] msg: napi_value that references a JavaScript string to be used as the message for the Error.
        • [out] result: napi_value representing the error created.

        Returns napi_ok if the API succeeded.

        This API returns a JavaScript TypeError with the text provided.

        -

        napi_create_range_error#

        +
        napi_create_range_error#
        -
        NAPI_EXTERN napi_status napi_create_range_error(napi_env env,
        +
        NAPI_EXTERN napi_status napi_create_range_error(napi_env env,
                                                         napi_value code,
                                                         napi_value msg,
        -                                                napi_value* result);
        + napi_value* result)
        ;
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional napi_value with the string for the error code to be associated with the error.
        • -
        • [in] msg: napi_value that references a JavaScript String to be used as +
        • [in] msg: napi_value that references a JavaScript string to be used as the message for the Error.
        • [out] result: napi_value representing the error created.

        Returns napi_ok if the API succeeded.

        This API returns a JavaScript RangeError with the text provided.

        -

        napi_get_and_clear_last_exception#

        +
        napi_get_and_clear_last_exception#
        -
        napi_status napi_get_and_clear_last_exception(napi_env env,
        -                                              napi_value* result);
        +
        napi_status napi_get_and_clear_last_exception(napi_env env,
        +                                              napi_value* result);
        • [in] env: The environment that the API is invoked under.
        • [out] result: The exception if one is pending, NULL otherwise.

        Returns napi_ok if the API succeeded.

        This API can be called even if there is a pending JavaScript exception.

        -

        napi_is_exception_pending#

        +
        napi_is_exception_pending#
        -
        napi_status napi_is_exception_pending(napi_env env, bool* result);
        +
        napi_status napi_is_exception_pending(napi_env env, bool* result);
        • [in] env: The environment that the API is invoked under.
        • [out] result: Boolean value that is set to true if an exception is pending.

        Returns napi_ok if the API succeeded.

        This API can be called even if there is a pending JavaScript exception.

        -

        napi_fatal_exception#

        +
        napi_fatal_exception#
        -
        napi_status napi_fatal_exception(napi_env env, napi_value err);
        +
        napi_status napi_fatal_exception(napi_env env, napi_value err);
        • [in] env: The environment that the API is invoked under.
        • [in] err: The error that is passed to 'uncaughtException'.

        Trigger an 'uncaughtException' in JavaScript. Useful if an async callback throws an exception with no way to recover.

        -

        Fatal errors#

        +

        Fatal errors#

        In the event of an unrecoverable error in a native module, a fatal error can be thrown to immediately terminate the process.

        -

        napi_fatal_error#

        +
        napi_fatal_error#
        -
        NAPI_NO_RETURN void napi_fatal_error(const char* location,
        -                                                 size_t location_len,
        -                                                 const char* message,
        -                                                 size_t message_len);
        +
        NAPI_NO_RETURN void napi_fatal_error(const char* location,
        +                                     size_t location_len,
        +                                     const char* message,
        +                                     size_t message_len);
        • [in] location: Optional location at which the error occurred.
        • [in] location_len: The length of the location in bytes, or @@ -11527,8 +12101,8 @@ if it is null-terminated.

        The function call does not return, the process will be terminated.

        This API can be called even if there is a pending JavaScript exception.

        -

        Object lifetime management#

        -

        As N-API calls are made, handles to objects in the heap for the underlying +

        Object lifetime management#

        +

        As Node-API calls are made, handles to objects in the heap for the underlying VM may be returned as napi_values. These handles must hold the objects 'live' until they are no longer required by the native code, otherwise the objects could be collected before the native code was @@ -11540,13 +12114,13 @@ remain valid and the objects associated with these handles will be held live for the lifespan of the native method call.

        In many cases, however, it is necessary that the handles remain valid for either a shorter or longer lifespan than that of the native method. -The sections which follow describe the N-API functions that can be used +The sections which follow describe the Node-API functions that can be used to change the handle lifespan from the default.

        -

        Making handle lifespan shorter than that of the native method#

        +

        Making handle lifespan shorter than that of the native method#

        It is often necessary to make the lifespan of handles shorter than the lifespan of a native method. For example, consider a native method that has a loop which iterates through the elements in a large array:

        -
        for (int i = 0; i < 1000000; i++) {
        +
        for (int i = 0; i < 1000000; i++) {
           napi_value result;
           napi_status status = napi_get_element(env, object, i, &result);
           if (status != napi_ok) {
        @@ -11558,12 +12132,12 @@ that has a loop which iterates through the elements in a large array:

        substantial resources. In addition, even though the native code could only use the most recent handle, all of the associated objects would also be kept alive since they all share the same scope.

        -

        To handle this case, N-API provides the ability to establish a new 'scope' to +

        To handle this case, Node-API provides the ability to establish a new 'scope' to which newly created handles will be associated. Once those handles are no longer required, the scope can be 'closed' and any handles associated with the scope are invalidated. The methods available to open/close scopes are napi_open_handle_scope and napi_close_handle_scope.

        -

        N-API only supports a single nested hierarchy of scopes. There is only one +

        Node-API only supports a single nested hierarchy of scopes. There is only one active scope at any time, and all new handles will be associated with that scope while it is active. Scopes must be closed in the reverse order from which they are opened. In addition, all scopes created within a native method @@ -11571,7 +12145,7 @@ must be closed before returning from that method.

        Taking the earlier example, adding calls to napi_open_handle_scope and napi_close_handle_scope would ensure that at most a single handle is valid throughout the execution of the loop:

        -
        for (int i = 0; i < 1000000; i++) {
        +
        for (int i = 0; i < 1000000; i++) {
           napi_handle_scope scope;
           napi_status status = napi_open_handle_scope(env, &scope);
           if (status != napi_ok) {
        @@ -11589,8 +12163,8 @@ is valid throughout the execution of the loop:

        } }

        When nesting scopes, there are cases where a handle from an -inner scope needs to live beyond the lifespan of that scope. N-API supports an -'escapable scope' in order to support this case. An escapable scope +inner scope needs to live beyond the lifespan of that scope. Node-API supports +an 'escapable scope' in order to support this case. An escapable scope allows one handle to be 'promoted' so that it 'escapes' the current scope and the lifespan of the handle changes from the current scope to that of the outer scope.

        @@ -11599,26 +12173,26 @@ scope to that of the outer scope.

        napi_close_escapable_handle_scope.

        The request to promote a handle is made through napi_escape_handle which can only be called once.

        -

        napi_open_handle_scope#

        +
        napi_open_handle_scope#
        -
        NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env,
        -                                               napi_handle_scope* result);
        +
        NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env,
        +                                               napi_handle_scope* result);
        • [in] env: The environment that the API is invoked under.
        • [out] result: napi_value representing the new scope.

        Returns napi_ok if the API succeeded.

        This API opens a new scope.

        -

        napi_close_handle_scope#

        +
        napi_close_handle_scope#
        -
        NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env,
        -                                                napi_handle_scope scope);
        +
        NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env,
        +                                                napi_handle_scope scope);
        • [in] env: The environment that the API is invoked under.
        • [in] scope: napi_value representing the scope to be closed.
        • @@ -11627,14 +12201,14 @@ can only be called once.

          This API closes the scope passed in. Scopes must be closed in the reverse order from which they were created.

          This API can be called even if there is a pending JavaScript exception.

          -

          napi_open_escapable_handle_scope#

          +
          napi_open_escapable_handle_scope#
          -
          NAPI_EXTERN napi_status
          -    napi_open_escapable_handle_scope(napi_env env,
          -                                     napi_handle_scope* result);
          +
          NAPI_EXTERN napi_status
          +    napi_open_escapable_handle_scope(napi_env env,
          +                                     napi_handle_scope* result);
          • [in] env: The environment that the API is invoked under.
          • [out] result: napi_value representing the new scope.
          • @@ -11642,14 +12216,14 @@ reverse order from which they were created.

            Returns napi_ok if the API succeeded.

            This API opens a new scope from which one object can be promoted to the outer scope.

            -

            napi_close_escapable_handle_scope#

            +
            napi_close_escapable_handle_scope#
            -
            NAPI_EXTERN napi_status
            -    napi_close_escapable_handle_scope(napi_env env,
            -                                      napi_handle_scope scope);
            +
            NAPI_EXTERN napi_status
            +    napi_close_escapable_handle_scope(napi_env env,
            +                                      napi_handle_scope scope);
            • [in] env: The environment that the API is invoked under.
            • [in] scope: napi_value representing the scope to be closed.
            • @@ -11658,15 +12232,15 @@ to the outer scope.

              This API closes the scope passed in. Scopes must be closed in the reverse order from which they were created.

              This API can be called even if there is a pending JavaScript exception.

              -

              napi_escape_handle#

              +
              napi_escape_handle#
              -
              napi_status napi_escape_handle(napi_env env,
              +
              napi_status napi_escape_handle(napi_env env,
                                              napi_escapable_handle_scope scope,
                                              napi_value escapee,
              -                               napi_value* result);
              + napi_value* result)
              ;
              • [in] env: The environment that the API is invoked under.
              • [in] scope: napi_value representing the current scope.
              • @@ -11680,7 +12254,7 @@ in the outer scope. for the lifetime of the outer scope. It can only be called once per scope. If it is called more than once an error will be returned.

                This API can be called even if there is a pending JavaScript exception.

                -

                References to objects with a lifespan longer than that of the native method#

                +

                References to objects with a lifespan longer than that of the native method#

                In some cases an addon will need to be able to create and reference objects with a lifespan longer than that of a single native method invocation. For example, to create a constructor and later use that constructor @@ -11690,7 +12264,7 @@ would not be possible with a normal handle returned as a napi_value described in the earlier section. The lifespan of a normal handle is managed by scopes and all scopes must be closed before the end of a native method.

                -

                N-API provides methods to create persistent references to an object. +

                Node-API provides methods to create persistent references to an object. Each persistent reference has an associated count with a value of 0 or higher. The count determines if the reference will keep the corresponding object live. References with a count of 0 do not @@ -11704,24 +12278,24 @@ for a reference is 0, all subsequent calls to get the object associated with the reference napi_get_reference_value will return NULL for the returned napi_value. An attempt to call napi_reference_ref for a reference whose object has been collected -will result in an error.

                +results in an error.

                References must be deleted once they are no longer required by the addon. When -a reference is deleted it will no longer prevent the corresponding object from -being collected. Failure to delete a persistent reference will result in +a reference is deleted, it will no longer prevent the corresponding object from +being collected. Failure to delete a persistent reference results in a 'memory leak' with both the native memory for the persistent reference and the corresponding object on the heap being retained forever.

                There can be multiple persistent references created which refer to the same object, each of which will either keep the object live or not based on its individual count.

                -

                napi_create_reference#

                +
                napi_create_reference#
                -
                NAPI_EXTERN napi_status napi_create_reference(napi_env env,
                +
                NAPI_EXTERN napi_status napi_create_reference(napi_env env,
                                                               napi_value value,
                -                                              uint32_t initial_refcount,
                -                                              napi_ref* result);
                + uint32_t initial_refcount, + napi_ref* result)
                ;
                • [in] env: The environment that the API is invoked under.
                • [in] value: napi_value representing the Object to which we want a @@ -11732,12 +12306,12 @@ reference.
                • Returns napi_ok if the API succeeded.

                  This API create a new reference with the specified reference count to the Object passed in.

                  -

                  napi_delete_reference#

                  +
                  napi_delete_reference#
                  -
                  NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref);
                  +
                  NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref);
                  • [in] env: The environment that the API is invoked under.
                  • [in] ref: napi_ref to be deleted.
                  • @@ -11745,14 +12319,14 @@ to the Object passed in.

                    Returns napi_ok if the API succeeded.

                    This API deletes the reference passed in.

                    This API can be called even if there is a pending JavaScript exception.

                    -

                    napi_reference_ref#

                    +
                    napi_reference_ref#
                    -
                    NAPI_EXTERN napi_status napi_reference_ref(napi_env env,
                    +
                    NAPI_EXTERN napi_status napi_reference_ref(napi_env env,
                                                                napi_ref ref,
                    -                                           uint32_t* result);
                    + uint32_t* result)
                    ;
                    • [in] env: The environment that the API is invoked under.
                    • [in] ref: napi_ref for which the reference count will be incremented.
                    • @@ -11761,14 +12335,14 @@ to the Object passed in.

                      Returns napi_ok if the API succeeded.

                      This API increments the reference count for the reference passed in and returns the resulting reference count.

                      -

                      napi_reference_unref#

                      +
                      napi_reference_unref#
                      -
                      NAPI_EXTERN napi_status napi_reference_unref(napi_env env,
                      +
                      NAPI_EXTERN napi_status napi_reference_unref(napi_env env,
                                                                    napi_ref ref,
                      -                                             uint32_t* result);
                      + uint32_t* result)
                      ;
                      • [in] env: The environment that the API is invoked under.
                      • [in] ref: napi_ref for which the reference count will be decremented.
                      • @@ -11777,14 +12351,14 @@ passed in and returns the resulting reference count.

                        Returns napi_ok if the API succeeded.

                        This API decrements the reference count for the reference passed in and returns the resulting reference count.

                        -

                        napi_get_reference_value#

                        +
                        napi_get_reference_value#
                        -
                        NAPI_EXTERN napi_status napi_get_reference_value(napi_env env,
                        +
                        NAPI_EXTERN napi_status napi_get_reference_value(napi_env env,
                                                                          napi_ref ref,
                        -                                                 napi_value* result);
                        + napi_value* result)
                        ;

                        the napi_value passed in or out of these methods is a handle to the object to which the reference is related.

                          @@ -11797,21 +12371,21 @@ object to which the reference is related.

                          If still valid, this API returns the napi_value representing the JavaScript Object associated with the napi_ref. Otherwise, result will be NULL.

                          -

                          Cleanup on exit of the current Node.js instance#

                          +

                          Cleanup on exit of the current Node.js instance#

                          While a Node.js process typically releases all its resources when exiting, embedders of Node.js, or future Worker support, may require addons to register clean-up hooks that will be run once the current Node.js instance exits.

                          -

                          N-API provides functions for registering and un-registering such callbacks. +

                          Node-API provides functions for registering and un-registering such callbacks. When those callbacks are run, all resources that are being held by the addon should be freed up.

                          -

                          napi_add_env_cleanup_hook#

                          +
                          napi_add_env_cleanup_hook#
                          -
                          NODE_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env,
                          -                                                  void (*fun)(void* arg),
                          -                                                  void* arg);
                          +
                          NODE_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env,
                          +                                                  void (*fun)(void* arg),
                          +                                                  void* arg);

                          Registers fun as a function to be run with the arg parameter once the current Node.js environment exits.

                          A function can safely be specified multiple times with different @@ -11824,37 +12398,37 @@ will be called first.

                          Typically, that happens when the resource for which this hook was added is being torn down anyway.

                          For asynchronous cleanup, napi_add_async_cleanup_hook is available.

                          -

                          napi_remove_env_cleanup_hook#

                          +
                          napi_remove_env_cleanup_hook#
                          -
                          NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env,
                          -                                                     void (*fun)(void* arg),
                          -                                                     void* arg);
                          +
                          NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env,
                          +                                                     void (*fun)(void* arg),
                          +                                                     void* arg);

                          Unregisters fun as a function to be run with the arg parameter once the current Node.js environment exits. Both the argument and the function value need to be exact matches.

                          The function must have originally been registered with napi_add_env_cleanup_hook, otherwise the process will abort.

                          -

                          napi_add_async_cleanup_hook#

                          +
                          napi_add_async_cleanup_hook#
                          -
                          NAPI_EXTERN napi_status napi_add_async_cleanup_hook(
                          +
                          NAPI_EXTERN napi_status napi_add_async_cleanup_hook(
                               napi_env env,
                               napi_async_cleanup_hook hook,
                          -    void* arg,
                          -    napi_async_cleanup_hook_handle* remove_handle);
                          + void* arg, + napi_async_cleanup_hook_handle* remove_handle)
                          ;

        Module registration#

        +

        Node-API modules are registered in a manner similar to other modules except that instead of using the NODE_MODULE macro the following is used:

        NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
        -

        The next difference is the signature for the Init method. For a N-API +

        The next difference is the signature for the Init method. For a Node-API module it is as follows:

        -
        napi_value Init(napi_env env, napi_value exports);
        +
        napi_value Init(napi_env env, napi_value exports);

        The return value from Init is treated as the exports object for the module. The Init method is passed an empty object via the exports parameter as a convenience. If Init returns NULL, the parameter passed as exports is -exported by the module. N-API modules cannot modify the module object but can -specify anything as the exports property of the module.

        +exported by the module. Node-API modules cannot modify the module object but +can specify anything as the exports property of the module.

        To add the method hello as a function so that it can be called as a method provided by the addon:

        -
        napi_value Init(napi_env env, napi_value exports) {
        +
        napi_value Init(napi_env env, napi_value exports) {
           napi_status status;
           napi_property_descriptor desc = {
             "hello",
        @@ -11926,7 +12500,7 @@ provided by the addon:

        return exports; }

        To set a function to be returned by the require() for the addon:

        -
        napi_value Init(napi_env env, napi_value exports) {
        +
        napi_value Init(napi_env env, napi_value exports) {
           napi_value method;
           napi_status status;
           status = napi_create_function(env, "exports", NAPI_AUTO_LENGTH, Method, NULL, &method);
        @@ -11936,7 +12510,7 @@ provided by the addon:

        To define a class so that new instances can be created (often used with Object wrap):

        // NOTE: partial example, not all referenced code is included
        -napi_value Init(napi_env env, napi_value exports) {
        +napi_value Init(napi_env env, napi_value exports) {
           napi_status status;
           napi_property_descriptor properties[] = {
             { "value", NULL, NULL, GetValue, SetValue, NULL, napi_writable | napi_configurable, NULL },
        @@ -11957,8 +12531,8 @@ provided by the addon:

        return exports; }
        -

        If the module will be loaded multiple times during the lifetime of the Node.js -process, use the NAPI_MODULE_INIT macro to initialize the module:

        +

        You can also use the NAPI_MODULE_INIT macro, which acts as a shorthand +for NAPI_MODULE and defining an Init function:

        NAPI_MODULE_INIT() {
           napi_value answer;
           napi_status result;
        @@ -11971,41 +12545,38 @@ process, use the NAPI_MODULE_INIT macro to initialize the module:return exports;
         }
        -

        This macro includes NAPI_MODULE, and declares an Init function with a -special name and with visibility beyond the addon. This will allow Node.js to -initialize the module even if it is loaded multiple times.

        -

        There are a few design considerations when declaring a module that may be loaded -multiple times. The documentation of context-aware addons provides more -details.

        +

        All Node-API addons are context-aware, meaning they may be loaded multiple +times. There are a few design considerations when declaring such a module. +The documentation on context-aware addons provides more details.

        The variables env and exports will be available inside the function body following the macro invocation.

        For more details on setting properties on objects, see the section on Working with JavaScript properties.

        For more details on building addon modules in general, refer to the existing API.

        -

        Working with JavaScript values#

        -

        N-API exposes a set of APIs to create all types of JavaScript values. +

        Working with JavaScript values#

        +

        Node-API exposes a set of APIs to create all types of JavaScript values. Some of these types are documented under Section 6 of the ECMAScript Language Specification.

        Fundamentally, these APIs are used to do one of the following:

        1. Create a new JavaScript object
        2. -
        3. Convert from a primitive C type to an N-API value
        4. -
        5. Convert from N-API value to a primitive C type
        6. +
        7. Convert from a primitive C type to a Node-API value
        8. +
        9. Convert from Node-API value to a primitive C type
        10. Get global instances including undefined and null
        -

        N-API values are represented by the type napi_value. -Any N-API call that requires a JavaScript value takes in a napi_value. +

        Node-API values are represented by the type napi_value. +Any Node-API call that requires a JavaScript value takes in a napi_value. In some cases, the API does check the type of the napi_value up-front. However, for better performance, it's better for the caller to make sure that the napi_value in question is of the JavaScript type expected by the API.

        -

        Enum types#

        -

        napi_key_collection_mode#

        +

        Enum types#

        +
        napi_key_collection_mode#
        -
        typedef enum {
        +
        typedef enum {
           napi_key_include_prototypes,
           napi_key_own_only
         } napi_key_collection_mode;
        @@ -12014,12 +12585,12 @@ the napi_value in question is of the JavaScript type expected by th

        napi_key_own_only limits the collected properties to the given object only. napi_key_include_prototypes will include all keys of the objects's prototype chain as well.

        -

        napi_key_filter#

        +
        napi_key_filter#
        -
        typedef enum {
        +
        typedef enum {
           napi_key_all_properties = 0,
           napi_key_writable = 1,
           napi_key_enumerable = 1 << 1,
        @@ -12028,20 +12599,20 @@ of the objects's prototype chain as well.

        napi_key_skip_symbols = 1 << 4 } napi_key_filter;

        Property filter bits. They can be or'ed to build a composite filter.

        -

        napi_key_conversion#

        +
        napi_key_conversion#
        -
        typedef enum {
        +
        typedef enum {
           napi_key_keep_numbers,
           napi_key_numbers_to_strings
         } napi_key_conversion;

        napi_key_numbers_to_strings will convert integer indices to strings. napi_key_keep_numbers will return numbers for integer indices.

        -

        napi_valuetype#

        -
        typedef enum {
        +
        napi_valuetype#
        +
        typedef enum {
           // ES6 types (corresponds to typeof)
           napi_undefined,
           napi_null,
        @@ -12060,8 +12631,8 @@ In addition to types in that section, napi_valuetype can also repre
         Functions and Objects with external data.

        A JavaScript value of type napi_external appears in JavaScript as a plain object such that no properties can be set on it, and no prototype.

        -

        napi_typedarray_type#

        -
        typedef enum {
        +
        napi_typedarray_type#
        +
        typedef enum {
           napi_int8_array,
           napi_uint8_array,
           napi_uint8_clamped_array,
        @@ -12077,36 +12648,36 @@ object such that no properties can be set on it, and no prototype.

        This represents the underlying binary scalar datatype of the TypedArray. Elements of this enum correspond to Section 22.2 of the ECMAScript Language Specification.

        -

        Object creation functions#

        -

        napi_create_array#

        +

        Object creation functions#

        +
        napi_create_array#
        -
        napi_status napi_create_array(napi_env env, napi_value* result)
        +
        napi_status napi_create_array(napi_env env, napi_value* result)
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [out] result: A napi_value representing a JavaScript Array.

        Returns napi_ok if the API succeeded.

        -

        This API returns an N-API value corresponding to a JavaScript Array type. +

        This API returns a Node-API value corresponding to a JavaScript Array type. JavaScript arrays are described in Section 22.1 of the ECMAScript Language Specification.

        -

        napi_create_array_with_length#

        +
        napi_create_array_with_length#
        -
        napi_status napi_create_array_with_length(napi_env env,
        -                                          size_t length,
        -                                          napi_value* result)
        +
        napi_status napi_create_array_with_length(napi_env env,
        +                                          size_t length,
        +                                          napi_value* result)
        • [in] env: The environment that the API is invoked under.
        • [in] length: The initial length of the Array.
        • [out] result: A napi_value representing a JavaScript Array.

        Returns napi_ok if the API succeeded.

        -

        This API returns an N-API value corresponding to a JavaScript Array type. +

        This API returns a Node-API value corresponding to a JavaScript Array type. The Array's length property is set to the passed-in length parameter. However, the underlying buffer is not guaranteed to be pre-allocated by the VM when the array is created. That behavior is left to the underlying VM @@ -12115,15 +12686,15 @@ directly read and/or written via C, consider using napi_create_external_arraybuffer.

        JavaScript arrays are described in Section 22.1 of the ECMAScript Language Specification.

        -

        napi_create_arraybuffer#

        +
        napi_create_arraybuffer#
        -
        napi_status napi_create_arraybuffer(napi_env env,
        -                                    size_t byte_length,
        -                                    void** data,
        -                                    napi_value* result)
        +
        napi_status napi_create_arraybuffer(napi_env env,
        +                                    size_t byte_length,
        +                                    void** data,
        +                                    napi_value* result)
        • [in] env: The environment that the API is invoked under.
        • [in] length: The length in bytes of the array buffer to create.
        • @@ -12131,7 +12702,7 @@ directly read and/or written via C, consider using
        • [out] result: A napi_value representing a JavaScript ArrayBuffer.

        Returns napi_ok if the API succeeded.

        -

        This API returns an N-API value corresponding to a JavaScript ArrayBuffer. +

        This API returns a Node-API value corresponding to a JavaScript ArrayBuffer. ArrayBuffers are used to represent fixed-length binary data buffers. They are normally used as a backing-buffer for TypedArray objects. The ArrayBuffer allocated will have an underlying byte buffer whose size is @@ -12142,15 +12713,15 @@ written to directly from native code. To write to this buffer from JavaScript, a typed array or DataView object would need to be created.

        JavaScript ArrayBuffer objects are described in Section 24.1 of the ECMAScript Language Specification.

        -

        napi_create_buffer#

        +
        napi_create_buffer#
        -
        napi_status napi_create_buffer(napi_env env,
        -                               size_t size,
        -                               void** data,
        -                               napi_value* result)
        +
        napi_status napi_create_buffer(napi_env env,
        +                               size_t size,
        +                               void** data,
        +                               napi_value* result)
        • [in] env: The environment that the API is invoked under.
        • [in] size: Size in bytes of the underlying buffer.
        • @@ -12160,16 +12731,16 @@ a typed array or DataView object would need to be created.

          Returns napi_ok if the API succeeded.

          This API allocates a node::Buffer object. While this is still a fully-supported data structure, in most cases using a TypedArray will suffice.

          -

          napi_create_buffer_copy#

          +
          napi_create_buffer_copy#
          -
          napi_status napi_create_buffer_copy(napi_env env,
          -                                    size_t length,
          -                                    const void* data,
          -                                    void** result_data,
          -                                    napi_value* result)
          +
          napi_status napi_create_buffer_copy(napi_env env,
          +                                    size_t length,
          +                                    const void* data,
          +                                    void** result_data,
          +                                    napi_value* result)
          • [in] env: The environment that the API is invoked under.
          • [in] size: Size in bytes of the input buffer (should be the same as the size @@ -12182,14 +12753,14 @@ of the new buffer).
          • This API allocates a node::Buffer object and initializes it with data copied from the passed-in buffer. While this is still a fully-supported data structure, in most cases using a TypedArray will suffice.

            -

            napi_create_date#

            +
            napi_create_date#
            -
            napi_status napi_create_date(napi_env env,
            -                             double time,
            -                             napi_value* result);
            +
            napi_status napi_create_date(napi_env env,
            +                             double time,
            +                             napi_value* result);
            • [in] env: The environment that the API is invoked under.
            • [in] time: ECMAScript time value in milliseconds since 01 January, 1970 UTC.
            • @@ -12201,16 +12772,16 @@ ECMAScript aligns with POSIX time specification.

              This API allocates a JavaScript Date object.

              JavaScript Date objects are described in Section 20.3 of the ECMAScript Language Specification.

              -

              napi_create_external#

              +
              napi_create_external#
              -
              napi_status napi_create_external(napi_env env,
              -                                 void* data,
              +
              napi_status napi_create_external(napi_env env,
              +                                 void* data,
                                                napi_finalize finalize_cb,
              -                                 void* finalize_hint,
              -                                 napi_value* result)
              + void* finalize_hint, + napi_value* result)
              • [in] env: The environment that the API is invoked under.
              • [in] data: Raw pointer to the external data.
              • @@ -12235,18 +12806,18 @@ object just created is ready for garbage collection. It is similar to

                The created value is not an object, and therefore does not support additional properties. It is considered a distinct value type: calling napi_typeof() with an external value yields napi_external.

                -

                napi_create_external_arraybuffer#

                +
                napi_create_external_arraybuffer#
                -
                napi_status
                -napi_create_external_arraybuffer(napi_env env,
                -                                 void* external_data,
                -                                 size_t byte_length,
                +
                napi_status
                +napi_create_external_arraybuffer(napi_env env,
                +                                 void* external_data,
                +                                 size_t byte_length,
                                                  napi_finalize finalize_cb,
                -                                 void* finalize_hint,
                -                                 napi_value* result)
                + void* finalize_hint, + napi_value* result)
                • [in] env: The environment that the API is invoked under.
                • [in] external_data: Pointer to the underlying byte buffer of the @@ -12259,7 +12830,7 @@ collection.
                • [out] result: A napi_value representing a JavaScript ArrayBuffer.

                Returns napi_ok if the API succeeded.

                -

                This API returns an N-API value corresponding to a JavaScript ArrayBuffer. +

                This API returns a Node-API value corresponding to a JavaScript ArrayBuffer. The underlying byte buffer of the ArrayBuffer is externally allocated and managed. The caller must ensure that the byte buffer remains valid until the finalize callback is called.

                @@ -12273,17 +12844,17 @@ object just created is ready for garbage collection. It is similar to

              JavaScript ArrayBuffers are described in Section 24.1 of the ECMAScript Language Specification.

              -

              napi_create_external_buffer#

              +
              napi_create_external_buffer#
              -
              napi_status napi_create_external_buffer(napi_env env,
              -                                        size_t length,
              -                                        void* data,
              +
              napi_status napi_create_external_buffer(napi_env env,
              +                                        size_t length,
              +                                        void* data,
                                                       napi_finalize finalize_cb,
              -                                        void* finalize_hint,
              -                                        napi_value* result)
              + void* finalize_hint, + napi_value* result)
              • [in] env: The environment that the API is invoked under.
              • [in] length: Size in bytes of the input buffer (should be the same as the @@ -12308,12 +12879,12 @@ object just created is ready for garbage collection. It is similar to
              • the object created by the API can be used with napi_wrap().

              For Node.js >=4 Buffers are Uint8Arrays.

              -

              napi_create_object#

              +
              napi_create_object#
              -
              napi_status napi_create_object(napi_env env, napi_value* result)
              +
              napi_status napi_create_object(napi_env env, napi_value* result)
              • [in] env: The environment that the API is invoked under.
              • [out] result: A napi_value representing a JavaScript Object.
              • @@ -12323,35 +12894,35 @@ object just created is ready for garbage collection. It is similar to It is the equivalent of doing new Object() in JavaScript.

                The JavaScript Object type is described in Section 6.1.7 of the ECMAScript Language Specification.

                -

                napi_create_symbol#

                +
                napi_create_symbol#
                -
                napi_status napi_create_symbol(napi_env env,
                +
                napi_status napi_create_symbol(napi_env env,
                                                napi_value description,
                -                               napi_value* result)
                + napi_value* result)
                • [in] env: The environment that the API is invoked under.
                • [in] description: Optional napi_value which refers to a JavaScript -String to be set as the description for the symbol.
                • -
                • [out] result: A napi_value representing a JavaScript Symbol.
                • +string to be set as the description for the symbol. +
                • [out] result: A napi_value representing a JavaScript symbol.

                Returns napi_ok if the API succeeded.

                -

                This API creates a JavaScript Symbol object from a UTF8-encoded C string.

                -

                The JavaScript Symbol type is described in Section 19.4 +

                This API creates a JavaScript symbol value from a UTF8-encoded C string.

                +

                The JavaScript symbol type is described in Section 19.4 of the ECMAScript Language Specification.

                -

                napi_create_typedarray#

                +
                napi_create_typedarray#
                -
                napi_status napi_create_typedarray(napi_env env,
                +
                napi_status napi_create_typedarray(napi_env env,
                                                    napi_typedarray_type type,
                -                                   size_t length,
                +                                   size_t length,
                                                    napi_value arraybuffer,
                -                                   size_t byte_offset,
                -                                   napi_value* result)
                + size_t byte_offset, + napi_value* result)
                • [in] env: The environment that the API is invoked under.
                • [in] type: Scalar datatype of the elements within the TypedArray.
                • @@ -12371,16 +12942,16 @@ be <= the size in bytes of the array passed in. If not, a RangeError< is raised.

                  JavaScript TypedArray objects are described in Section 22.2 of the ECMAScript Language Specification.

                  -

                  napi_create_dataview#

                  +
                  napi_create_dataview#
                  -
                  napi_status napi_create_dataview(napi_env env,
                  -                                 size_t byte_length,
                  +
                  napi_status napi_create_dataview(napi_env env,
                  +                                 size_t byte_length,
                                                    napi_value arraybuffer,
                  -                                 size_t byte_offset,
                  -                                 napi_value* result)
                  + size_t byte_offset, + napi_value* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] length: Number of elements in the DataView.
                  • @@ -12398,82 +12969,82 @@ size in bytes of the array passed in. If not, a RangeError exceptio raised.

                    JavaScript DataView objects are described in Section 24.3 of the ECMAScript Language Specification.

                    -

                    Functions to convert from C types to N-API#

                    -

                    napi_create_int32#

                    +

                    Functions to convert from C types to Node-API#

                    +
                    napi_create_int32#
                    -
                    napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)
                    +
                    napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)
                    • [in] env: The environment that the API is invoked under.
                    • [in] value: Integer value to be represented in JavaScript.
                    • -
                    • [out] result: A napi_value representing a JavaScript Number.
                    • +
                    • [out] result: A napi_value representing a JavaScript number.

                    Returns napi_ok if the API succeeded.

                    This API is used to convert from the C int32_t type to the JavaScript -Number type.

                    -

                    The JavaScript Number type is described in +number type.

                    +

                    The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification.

                    -

                    napi_create_uint32#

                    +
                    napi_create_uint32#
                    -
                    napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)
                    +
                    napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)
                    • [in] env: The environment that the API is invoked under.
                    • [in] value: Unsigned integer value to be represented in JavaScript.
                    • -
                    • [out] result: A napi_value representing a JavaScript Number.
                    • +
                    • [out] result: A napi_value representing a JavaScript number.

                    Returns napi_ok if the API succeeded.

                    This API is used to convert from the C uint32_t type to the JavaScript -Number type.

                    -

                    The JavaScript Number type is described in +number type.

                    +

                    The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification.

                    -

                    napi_create_int64#

                    +
                    napi_create_int64#
                    -
                    napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)
                    +
                    napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)
                    • [in] env: The environment that the API is invoked under.
                    • [in] value: Integer value to be represented in JavaScript.
                    • -
                    • [out] result: A napi_value representing a JavaScript Number.
                    • +
                    • [out] result: A napi_value representing a JavaScript number.

                    Returns napi_ok if the API succeeded.

                    This API is used to convert from the C int64_t type to the JavaScript -Number type.

                    -

                    The JavaScript Number type is described in Section 6.1.6 +number type.

                    +

                    The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification. Note the complete range of int64_t cannot be represented with full precision in JavaScript. Integer values outside the range of Number.MIN_SAFE_INTEGER -(2**53 - 1) - Number.MAX_SAFE_INTEGER (2**53 - 1) will lose precision.

                    -

                    napi_create_double#

                    +
                    napi_create_double#
                    -
                    napi_status napi_create_double(napi_env env, double value, napi_value* result)
                    +
                    napi_status napi_create_double(napi_env env, double value, napi_value* result)
                    • [in] env: The environment that the API is invoked under.
                    • [in] value: Double-precision value to be represented in JavaScript.
                    • -
                    • [out] result: A napi_value representing a JavaScript Number.
                    • +
                    • [out] result: A napi_value representing a JavaScript number.

                    Returns napi_ok if the API succeeded.

                    This API is used to convert from the C double type to the JavaScript -Number type.

                    -

                    The JavaScript Number type is described in +number type.

                    +

                    The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification.

                    -

                    napi_create_bigint_int64#

                    +
                    napi_create_bigint_int64#
                    -
                    napi_status napi_create_bigint_int64(napi_env env,
                    -                                     int64_t value,
                    -                                     napi_value* result);
                    +
                    napi_status napi_create_bigint_int64(napi_env env,
                    +                                     int64_t value,
                    +                                     napi_value* result);
                    • [in] env: The environment that the API is invoked under.
                    • [in] value: Integer value to be represented in JavaScript.
                    • @@ -12481,14 +13052,14 @@ outside the range of # +
                      napi_create_bigint_uint64#
                      -
                      napi_status napi_create_bigint_uint64(napi_env env,
                      -                                      uint64_t value,
                      -                                      napi_value* result);
                      +
                      napi_status napi_create_bigint_uint64(napi_env env,
                      +                                      uint64_t value,
                      +                                      napi_value* result);
                      • [in] env: The environment that the API is invoked under.
                      • [in] value: Unsigned integer value to be represented in JavaScript.
                      • @@ -12496,16 +13067,16 @@ outside the range of # +
                        napi_create_bigint_words#
                        -
                        napi_status napi_create_bigint_words(napi_env env,
                        -                                     int sign_bit,
                        -                                     size_t word_count,
                        -                                     const uint64_t* words,
                        -                                     napi_value* result);
                        +
                        napi_status napi_create_bigint_words(napi_env env,
                        +                                     int sign_bit,
                        +                                     size_t word_count,
                        +                                     const uint64_t* words,
                        +                                     napi_value* result);
                        • [in] env: The environment that the API is invoked under.
                        • [in] sign_bit: Determines if the resulting BigInt will be positive or @@ -12519,78 +13090,78 @@ negative.
                        • value.

                          The resulting BigInt is calculated as: (–1)sign_bit (words[0] × (264)0 + words[1] × (264)1 + …)

                          -

                          napi_create_string_latin1#

                          +
                          napi_create_string_latin1#
                          -
                          napi_status napi_create_string_latin1(napi_env env,
                          -                                      const char* str,
                          -                                      size_t length,
                          -                                      napi_value* result);
                          +
                          napi_status napi_create_string_latin1(napi_env env,
                          +                                      const char* str,
                          +                                      size_t length,
                          +                                      napi_value* result);
                          • [in] env: The environment that the API is invoked under.
                          • [in] str: Character buffer representing an ISO-8859-1-encoded string.
                          • [in] length: The length of the string in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.
                          • -
                          • [out] result: A napi_value representing a JavaScript String.
                          • +
                          • [out] result: A napi_value representing a JavaScript string.

                          Returns napi_ok if the API succeeded.

                          -

                          This API creates a JavaScript String object from an ISO-8859-1-encoded C +

                          This API creates a JavaScript string value from an ISO-8859-1-encoded C string. The native string is copied.

                          -

                          The JavaScript String type is described in +

                          The JavaScript string type is described in Section 6.1.4 of the ECMAScript Language Specification.

                          -

                          napi_create_string_utf16#

                          +
                          napi_create_string_utf16#
                          -
                          napi_status napi_create_string_utf16(napi_env env,
                          -                                     const char16_t* str,
                          -                                     size_t length,
                          -                                     napi_value* result)
                          +
                          napi_status napi_create_string_utf16(napi_env env,
                          +                                     const char16_t* str,
                          +                                     size_t length,
                          +                                     napi_value* result)
                          • [in] env: The environment that the API is invoked under.
                          • [in] str: Character buffer representing a UTF16-LE-encoded string.
                          • [in] length: The length of the string in two-byte code units, or NAPI_AUTO_LENGTH if it is null-terminated.
                          • -
                          • [out] result: A napi_value representing a JavaScript String.
                          • +
                          • [out] result: A napi_value representing a JavaScript string.

                          Returns napi_ok if the API succeeded.

                          -

                          This API creates a JavaScript String object from a UTF16-LE-encoded C string. +

                          This API creates a JavaScript string value from a UTF16-LE-encoded C string. The native string is copied.

                          -

                          The JavaScript String type is described in +

                          The JavaScript string type is described in Section 6.1.4 of the ECMAScript Language Specification.

                          -

                          napi_create_string_utf8#

                          +
                          napi_create_string_utf8#
                          -
                          napi_status napi_create_string_utf8(napi_env env,
                          -                                    const char* str,
                          -                                    size_t length,
                          -                                    napi_value* result)
                          +
                          napi_status napi_create_string_utf8(napi_env env,
                          +                                    const char* str,
                          +                                    size_t length,
                          +                                    napi_value* result)
                          • [in] env: The environment that the API is invoked under.
                          • [in] str: Character buffer representing a UTF8-encoded string.
                          • [in] length: The length of the string in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.
                          • -
                          • [out] result: A napi_value representing a JavaScript String.
                          • +
                          • [out] result: A napi_value representing a JavaScript string.

                          Returns napi_ok if the API succeeded.

                          -

                          This API creates a JavaScript String object from a UTF8-encoded C string. +

                          This API creates a JavaScript string value from a UTF8-encoded C string. The native string is copied.

                          -

                          The JavaScript String type is described in +

                          The JavaScript string type is described in Section 6.1.4 of the ECMAScript Language Specification.

                          -

                          Functions to convert from N-API to C types#

                          -

                          napi_get_array_length#

                          +

                          Functions to convert from Node-API to C types#

                          +
                          napi_get_array_length#
                          -
                          napi_status napi_get_array_length(napi_env env,
                          +
                          napi_status napi_get_array_length(napi_env env,
                                                             napi_value value,
                          -                                  uint32_t* result)
                          + uint32_t* result)
                          • [in] env: The environment that the API is invoked under.
                          • [in] value: napi_value representing the JavaScript Array whose length is @@ -12601,15 +13172,15 @@ being queried.
                          • This API returns the length of an array.

                            Array length is described in Section 22.1.4.1 of the ECMAScript Language Specification.

                            -

                            napi_get_arraybuffer_info#

                            +
                            napi_get_arraybuffer_info#
                            -
                            napi_status napi_get_arraybuffer_info(napi_env env,
                            +
                            napi_status napi_get_arraybuffer_info(napi_env env,
                                                                   napi_value arraybuffer,
                            -                                      void** data,
                            -                                      size_t* byte_length)
                            + void** data, + size_t* byte_length)
                            • [in] env: The environment that the API is invoked under.
                            • [in] arraybuffer: napi_value representing the ArrayBuffer being queried.
                            • @@ -12627,15 +13198,15 @@ possible safe way to use this API is in conjunction with lifetime of the ArrayBuffer. It's also safe to use the returned data buffer within the same callback as long as there are no calls to other APIs that might trigger a GC.

                              -

                              napi_get_buffer_info#

                              +
                              napi_get_buffer_info#
                              -
                              napi_status napi_get_buffer_info(napi_env env,
                              +
                              napi_status napi_get_buffer_info(napi_env env,
                                                                napi_value value,
                              -                                 void** data,
                              -                                 size_t* length)
                              + void** data, + size_t* length)
                              • [in] env: The environment that the API is invoked under.
                              • [in] value: napi_value representing the node::Buffer being queried.
                              • @@ -12648,14 +13219,14 @@ If length is 0, this may be NULL or any other pointer and it's length.

                                Warning: Use caution while using this API since the underlying data buffer's lifetime is not guaranteed if it's managed by the VM.

                                -

                                napi_get_prototype#

                                +
                                napi_get_prototype#
                                -
                                napi_status napi_get_prototype(napi_env env,
                                +
                                napi_status napi_get_prototype(napi_env env,
                                                                napi_value object,
                                -                               napi_value* result)
                                + napi_value* result)
                                • [in] env: The environment that the API is invoked under.
                                • [in] object: napi_value representing JavaScript Object whose prototype @@ -12664,18 +13235,18 @@ not the same as the function's prototype property).
                                • [out] result: napi_value representing prototype of the given object.

                                Returns napi_ok if the API succeeded.

                                -

                                napi_get_typedarray_info#

                                +
                                napi_get_typedarray_info#
                                -
                                napi_status napi_get_typedarray_info(napi_env env,
                                +
                                napi_status napi_get_typedarray_info(napi_env env,
                                                                      napi_value typedarray,
                                                                      napi_typedarray_type* type,
                                -                                     size_t* length,
                                -                                     void** data,
                                +                                     size_t* length,
                                +                                     void** data,
                                                                      napi_value* arraybuffer,
                                -                                     size_t* byte_offset)
                                + size_t* byte_offset)
                                • [in] env: The environment that the API is invoked under.
                                • [in] typedarray: napi_value representing the TypedArray whose @@ -12697,22 +13268,22 @@ in the array. Therefore, the first byte of the native array would be at

                                  This API returns various properties of a typed array.

                                  Warning: Use caution while using this API since the underlying data buffer is managed by the VM.

                                  -

                                  napi_get_dataview_info#

                                  +
                                  napi_get_dataview_info#
                                  -
                                  napi_status napi_get_dataview_info(napi_env env,
                                  +
                                  napi_status napi_get_dataview_info(napi_env env,
                                                                      napi_value dataview,
                                  -                                   size_t* byte_length,
                                  -                                   void** data,
                                  +                                   size_t* byte_length,
                                  +                                   void** data,
                                                                      napi_value* arraybuffer,
                                  -                                   size_t* byte_offset)
                                  + size_t* byte_offset)
                                  • [in] env: The environment that the API is invoked under.
                                  • [in] dataview: napi_value representing the DataView whose properties to query.
                                  • -
                                  • [out] byte_length: Number of bytes in the DataView.
                                  • +
                                  • [out] byte_length: Number of bytes in the DataView.
                                  • [out] data: The data buffer underlying the DataView. If byte_length is 0, this may be NULL or any other pointer value.
                                  • [out] arraybuffer: ArrayBuffer underlying the DataView.
                                  • @@ -12721,14 +13292,14 @@ to start projecting the DataView.

                                  Returns napi_ok if the API succeeded.

                                  This API returns various properties of a DataView.

                                  -

                                  napi_get_date_value#

                                  +
                                  napi_get_date_value#
                                  -
                                  napi_status napi_get_date_value(napi_env env,
                                  +
                                  napi_status napi_get_date_value(napi_env env,
                                                                   napi_value value,
                                  -                                double* result)
                                  + double* result)
                                  • [in] env: The environment that the API is invoked under.
                                  • [in] value: napi_value representing a JavaScript Date.
                                  • @@ -12741,12 +13312,12 @@ ECMAScript aligns with POSIX time specification.

                                    in it returns napi_date_expected.

                                    This API returns the C double primitive of time value for the given JavaScript Date.

                                    -

                                    napi_get_value_bool#

                                    +
                                    napi_get_value_bool#
                                    -
                                    napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result)
                                    +
                                    napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result)
                                    • [in] env: The environment that the API is invoked under.
                                    • [in] value: napi_value representing JavaScript Boolean.
                                    • @@ -12757,33 +13328,33 @@ in it returns napi_date_expected.

                                      passed in it returns napi_boolean_expected.

                                      This API returns the C boolean primitive equivalent of the given JavaScript Boolean.

                                      -

                                      napi_get_value_double#

                                      +
                                      napi_get_value_double#
                                      -
                                      napi_status napi_get_value_double(napi_env env,
                                      +
                                      napi_status napi_get_value_double(napi_env env,
                                                                         napi_value value,
                                      -                                  double* result)
                                      + double* result)
                                      • [in] env: The environment that the API is invoked under.
                                      • -
                                      • [in] value: napi_value representing JavaScript Number.
                                      • +
                                      • [in] value: napi_value representing JavaScript number.
                                      • [out] result: C double primitive equivalent of the given JavaScript -Number.
                                      • +number.

                                      Returns napi_ok if the API succeeded. If a non-number napi_value is passed in it returns napi_number_expected.

                                      This API returns the C double primitive equivalent of the given JavaScript -Number.

                                      -

                                      napi_get_value_bigint_int64#

                                      +number.

                                      +
                                      napi_get_value_bigint_int64#
                                      -
                                      napi_status napi_get_value_bigint_int64(napi_env env,
                                      +
                                      napi_status napi_get_value_bigint_int64(napi_env env,
                                                                               napi_value value,
                                      -                                        int64_t* result,
                                      -                                        bool* lossless);
                                      + int64_t* result, + bool* lossless)
                                      ;
                                      • [in] env: The environment that the API is invoked under
                                      • [in] value: napi_value representing JavaScript BigInt.
                                      • @@ -12796,15 +13367,15 @@ losslessly. returns napi_bigint_expected.

                                        This API returns the C int64_t primitive equivalent of the given JavaScript BigInt. If needed it will truncate the value, setting lossless to false.

                                        -

                                        napi_get_value_bigint_uint64#

                                        +
                                        napi_get_value_bigint_uint64#
                                        -
                                        napi_status napi_get_value_bigint_uint64(napi_env env,
                                        +
                                        napi_status napi_get_value_bigint_uint64(napi_env env,
                                                                                 napi_value value,
                                        -                                        uint64_t* result,
                                        -                                        bool* lossless);
                                        + uint64_t* result, + bool* lossless)
                                        ;
                                        • [in] env: The environment that the API is invoked under.
                                        • [in] value: napi_value representing JavaScript BigInt.
                                        • @@ -12817,16 +13388,16 @@ losslessly. returns napi_bigint_expected.

                                          This API returns the C uint64_t primitive equivalent of the given JavaScript BigInt. If needed it will truncate the value, setting lossless to false.

                                          -

                                          napi_get_value_bigint_words#

                                          +
                                          napi_get_value_bigint_words#
                                          -
                                          napi_status napi_get_value_bigint_words(napi_env env,
                                          +
                                          napi_status napi_get_value_bigint_words(napi_env env,
                                                                                   napi_value value,
                                          -                                        int* sign_bit,
                                          -                                        size_t* word_count,
                                          -                                        uint64_t* words);
                                          + int* sign_bit, + size_t* word_count, + uint64_t* words)
                                          ;
                                          • [in] env: The environment that the API is invoked under.
                                          • [in] value: napi_value representing JavaScript BigInt.
                                          • @@ -12841,14 +13412,14 @@ would be needed to store this BigInt.

                                            This API converts a single BigInt value into a sign bit, 64-bit little-endian array, and the number of elements in the array. sign_bit and words may be both set to NULL, in order to get only word_count.

                                            -

                                            napi_get_value_external#

                                            +
                                            napi_get_value_external#
                                            -
                                            napi_status napi_get_value_external(napi_env env,
                                            +
                                            napi_status napi_get_value_external(napi_env env,
                                                                                 napi_value value,
                                            -                                    void** result)
                                            + void** result)
                                            • [in] env: The environment that the API is invoked under.
                                            • [in] value: napi_value representing JavaScript external value.
                                            • @@ -12858,133 +13429,136 @@ both set to NULL, in order to get only word_count.

                                              passed in it returns napi_invalid_arg.

                                              This API retrieves the external data pointer that was previously passed to napi_create_external().

                                              -

                                              napi_get_value_int32#

                                              +
                                              napi_get_value_int32#
                                              -
                                              napi_status napi_get_value_int32(napi_env env,
                                              +
                                              napi_status napi_get_value_int32(napi_env env,
                                                                                napi_value value,
                                              -                                 int32_t* result)
                                              + int32_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • -
                                              • [in] value: napi_value representing JavaScript Number.
                                              • +
                                              • [in] value: napi_value representing JavaScript number.
                                              • [out] result: C int32 primitive equivalent of the given JavaScript -Number.
                                              • +number.

                                              Returns napi_ok if the API succeeded. If a non-number napi_value is passed in napi_number_expected.

                                              This API returns the C int32 primitive equivalent -of the given JavaScript Number.

                                              +of the given JavaScript number.

                                              If the number exceeds the range of the 32 bit integer, then the result is truncated to the equivalent of the bottom 32 bits. This can result in a large positive number becoming a negative number if the value is > 231 - 1.

                                              Non-finite number values (NaN, +Infinity, or -Infinity) set the result to zero.

                                              -

                                              napi_get_value_int64#

                                              +
                                              napi_get_value_int64#
                                              -
                                              napi_status napi_get_value_int64(napi_env env,
                                              +
                                              napi_status napi_get_value_int64(napi_env env,
                                                                                napi_value value,
                                              -                                 int64_t* result)
                                              + int64_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • -
                                              • [in] value: napi_value representing JavaScript Number.
                                              • +
                                              • [in] value: napi_value representing JavaScript number.
                                              • [out] result: C int64 primitive equivalent of the given JavaScript -Number.
                                              • +number.

                                              Returns napi_ok if the API succeeded. If a non-number napi_value is passed in it returns napi_number_expected.

                                              This API returns the C int64 primitive equivalent of the given JavaScript -Number.

                                              -

                                              Number values outside the range of Number.MIN_SAFE_INTEGER +number.

                                              +

                                              number values outside the range of Number.MIN_SAFE_INTEGER -(2**53 - 1) - Number.MAX_SAFE_INTEGER (2**53 - 1) will lose precision.

                                              Non-finite number values (NaN, +Infinity, or -Infinity) set the result to zero.

                                              -

                                              napi_get_value_string_latin1#

                                              +
                                              napi_get_value_string_latin1#
                                              -
                                              napi_status napi_get_value_string_latin1(napi_env env,
                                              +
                                              napi_status napi_get_value_string_latin1(napi_env env,
                                                                                        napi_value value,
                                              -                                         char* buf,
                                              -                                         size_t bufsize,
                                              -                                         size_t* result)
                                              + char* buf, + size_t bufsize, + size_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • [in] value: napi_value representing JavaScript string.
                                              • [in] buf: Buffer to write the ISO-8859-1-encoded string into. If NULL is -passed in, the length of the string (in bytes) is returned.
                                              • +passed in, the length of the string in bytes and excluding the null terminator +is returned in result.
                                              • [in] bufsize: Size of the destination buffer. When this value is -insufficient, the returned string will be truncated.
                                              • +insufficient, the returned string is truncated and null-terminated.
                                              • [out] result: Number of bytes copied into the buffer, excluding the null terminator.
                                              -

                                              Returns napi_ok if the API succeeded. If a non-String napi_value +

                                              Returns napi_ok if the API succeeded. If a non-string napi_value is passed in it returns napi_string_expected.

                                              This API returns the ISO-8859-1-encoded string corresponding the value passed in.

                                              -

                                              napi_get_value_string_utf8#

                                              +
                                              napi_get_value_string_utf8#
                                              -
                                              napi_status napi_get_value_string_utf8(napi_env env,
                                              +
                                              napi_status napi_get_value_string_utf8(napi_env env,
                                                                                      napi_value value,
                                              -                                       char* buf,
                                              -                                       size_t bufsize,
                                              -                                       size_t* result)
                                              + char* buf, + size_t bufsize, + size_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • [in] value: napi_value representing JavaScript string.
                                              • [in] buf: Buffer to write the UTF8-encoded string into. If NULL is passed -in, the length of the string (in bytes) is returned.
                                              • +in, the length of the string in bytes and excluding the null terminator is +returned in result.
                                              • [in] bufsize: Size of the destination buffer. When this value is -insufficient, the returned string will be truncated.
                                              • +insufficient, the returned string is truncated and null-terminated.
                                              • [out] result: Number of bytes copied into the buffer, excluding the null terminator.
                                              -

                                              Returns napi_ok if the API succeeded. If a non-String napi_value +

                                              Returns napi_ok if the API succeeded. If a non-string napi_value is passed in it returns napi_string_expected.

                                              This API returns the UTF8-encoded string corresponding the value passed in.

                                              -

                                              napi_get_value_string_utf16#

                                              +
                                              napi_get_value_string_utf16#
                                              -
                                              napi_status napi_get_value_string_utf16(napi_env env,
                                              +
                                              napi_status napi_get_value_string_utf16(napi_env env,
                                                                                       napi_value value,
                                              -                                        char16_t* buf,
                                              -                                        size_t bufsize,
                                              -                                        size_t* result)
                                              + char16_t* buf, + size_t bufsize, + size_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • [in] value: napi_value representing JavaScript string.
                                              • [in] buf: Buffer to write the UTF16-LE-encoded string into. If NULL is -passed in, the length of the string (in 2-byte code units) is returned.
                                              • +passed in, the length of the string in 2-byte code units and excluding the +null terminator is returned.
                                              • [in] bufsize: Size of the destination buffer. When this value is -insufficient, the returned string will be truncated.
                                              • +insufficient, the returned string is truncated and null-terminated.
                                              • [out] result: Number of 2-byte code units copied into the buffer, excluding the null terminator.
                                              -

                                              Returns napi_ok if the API succeeded. If a non-String napi_value +

                                              Returns napi_ok if the API succeeded. If a non-string napi_value is passed in it returns napi_string_expected.

                                              This API returns the UTF16-encoded string corresponding the value passed in.

                                              -

                                              napi_get_value_uint32#

                                              +
                                              napi_get_value_uint32#
                                              -
                                              napi_status napi_get_value_uint32(napi_env env,
                                              +
                                              napi_status napi_get_value_uint32(napi_env env,
                                                                                 napi_value value,
                                              -                                  uint32_t* result)
                                              + uint32_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • -
                                              • [in] value: napi_value representing JavaScript Number.
                                              • +
                                              • [in] value: napi_value representing JavaScript number.
                                              • [out] result: C primitive equivalent of the given napi_value as a uint32_t.
                                              @@ -12992,13 +13566,13 @@ is passed in it returns napi_string_expected.

                                              is passed in it returns napi_number_expected.

                                              This API returns the C primitive equivalent of the given napi_value as a uint32_t.

                                              -

                                              Functions to get global instances#

                                              -

                                              napi_get_boolean#

                                              +

                                              Functions to get global instances#

                                              +
                                              napi_get_boolean#
                                              -
                                              napi_status napi_get_boolean(napi_env env, bool value, napi_value* result)
                                              +
                                              napi_status napi_get_boolean(napi_env env, bool value, napi_value* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • [in] value: The value of the boolean to retrieve.
                                              • @@ -13008,61 +13582,61 @@ retrieve.

                                                Returns napi_ok if the API succeeded.

                                                This API is used to return the JavaScript singleton object that is used to represent the given boolean value.

                                                -

                                                napi_get_global#

                                                +
                                                napi_get_global#
                                                -
                                                napi_status napi_get_global(napi_env env, napi_value* result)
                                                +
                                                napi_status napi_get_global(napi_env env, napi_value* result)
                                                • [in] env: The environment that the API is invoked under.
                                                • [out] result: napi_value representing JavaScript global object.

                                                Returns napi_ok if the API succeeded.

                                                This API returns the global object.

                                                -

                                                napi_get_null#

                                                +
                                                napi_get_null#
                                                -
                                                napi_status napi_get_null(napi_env env, napi_value* result)
                                                +
                                                napi_status napi_get_null(napi_env env, napi_value* result)
                                                • [in] env: The environment that the API is invoked under.
                                                • [out] result: napi_value representing JavaScript null object.

                                                Returns napi_ok if the API succeeded.

                                                This API returns the null object.

                                                -

                                                napi_get_undefined#

                                                +
                                                napi_get_undefined#
                                                -
                                                napi_status napi_get_undefined(napi_env env, napi_value* result)
                                                +
                                                napi_status napi_get_undefined(napi_env env, napi_value* result)
                                                • [in] env: The environment that the API is invoked under.
                                                • [out] result: napi_value representing JavaScript Undefined value.

                                                Returns napi_ok if the API succeeded.

                                                This API returns the Undefined object.

                                                -

                                                Working with JavaScript values and abstract operations#

                                                -

                                                N-API exposes a set of APIs to perform some abstract operations on JavaScript +

        Working with JavaScript values and abstract operations#

        +

        Node-API exposes a set of APIs to perform some abstract operations on JavaScript values. Some of these operations are documented under Section 7 of the ECMAScript Language Specification.

        These APIs support doing one of the following:

          -
        1. Coerce JavaScript values to specific JavaScript types (such as Number or -String).
        2. +
        3. Coerce JavaScript values to specific JavaScript types (such as number or +string).
        4. Check the type of a JavaScript value.
        5. Check for equality between two JavaScript values.
        -

        napi_coerce_to_bool#

        +

        napi_coerce_to_bool#

        -
        napi_status napi_coerce_to_bool(napi_env env,
        +
        napi_status napi_coerce_to_bool(napi_env env,
                                         napi_value value,
        -                                napi_value* result)
        + napi_value* result)
        • [in] env: The environment that the API is invoked under.
        • [in] value: The JavaScript value to coerce.
        • @@ -13072,31 +13646,31 @@ of the ECMAScript Language Specificati

          This API implements the abstract operation ToBoolean() as defined in Section 7.1.2 of the ECMAScript Language Specification. This API can be re-entrant if getters are defined on the passed-in Object.

          -

          napi_coerce_to_number#

          +

          napi_coerce_to_number#

          -
          napi_status napi_coerce_to_number(napi_env env,
          +
          napi_status napi_coerce_to_number(napi_env env,
                                             napi_value value,
          -                                  napi_value* result)
          + napi_value* result)
          • [in] env: The environment that the API is invoked under.
          • [in] value: The JavaScript value to coerce.
          • -
          • [out] result: napi_value representing the coerced JavaScript Number.
          • +
          • [out] result: napi_value representing the coerced JavaScript number.

          Returns napi_ok if the API succeeded.

          This API implements the abstract operation ToNumber() as defined in Section 7.1.3 of the ECMAScript Language Specification. This API can be re-entrant if getters are defined on the passed-in Object.

          -

          napi_coerce_to_object#

          +

          napi_coerce_to_object#

          -
          napi_status napi_coerce_to_object(napi_env env,
          +
          napi_status napi_coerce_to_object(napi_env env,
                                             napi_value value,
          -                                  napi_value* result)
          + napi_value* result)
          • [in] env: The environment that the API is invoked under.
          • [in] value: The JavaScript value to coerce.
          • @@ -13106,29 +13680,29 @@ This API can be re-entrant if getters are defined on the passed-in Object<

            This API implements the abstract operation ToObject() as defined in Section 7.1.13 of the ECMAScript Language Specification. This API can be re-entrant if getters are defined on the passed-in Object.

            -

            napi_coerce_to_string#

            +

            napi_coerce_to_string#

            -
            napi_status napi_coerce_to_string(napi_env env,
            +
            napi_status napi_coerce_to_string(napi_env env,
                                               napi_value value,
            -                                  napi_value* result)
            + napi_value* result)
            • [in] env: The environment that the API is invoked under.
            • [in] value: The JavaScript value to coerce.
            • -
            • [out] result: napi_value representing the coerced JavaScript String.
            • +
            • [out] result: napi_value representing the coerced JavaScript string.

            Returns napi_ok if the API succeeded.

            This API implements the abstract operation ToString() as defined in Section 7.1.13 of the ECMAScript Language Specification. This API can be re-entrant if getters are defined on the passed-in Object.

            -

            napi_typeof#

            +

            napi_typeof#

            -
            napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result)
            +
            napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result)
            • [in] env: The environment that the API is invoked under.
            • [in] value: The JavaScript value whose type to query.
            • @@ -13148,15 +13722,15 @@ Specification. However, there are some differences:

              object.

              If value has a type that is invalid, an error is returned.

              -

              napi_instanceof#

              +

              napi_instanceof#

              -
              napi_status napi_instanceof(napi_env env,
              +
              napi_status napi_instanceof(napi_env env,
                                           napi_value object,
                                           napi_value constructor,
              -                            bool* result)
              + bool* result)
              • [in] env: The environment that the API is invoked under.
              • [in] object: The JavaScript value to check.
              • @@ -13168,12 +13742,12 @@ is true.

                Returns napi_ok if the API succeeded.

                This API represents invoking the instanceof Operator on the object as defined in Section 12.10.4 of the ECMAScript Language Specification.

                -

                napi_is_array#

                +

                napi_is_array#

                -
                napi_status napi_is_array(napi_env env, napi_value value, bool* result)
                +
                napi_status napi_is_array(napi_env env, napi_value value, bool* result)
                • [in] env: The environment that the API is invoked under.
                • [in] value: The JavaScript value to check.
                • @@ -13182,12 +13756,12 @@ defined in Sect

                  Returns napi_ok if the API succeeded.

                  This API represents invoking the IsArray operation on the object as defined in Section 7.2.2 of the ECMAScript Language Specification.

                  -

                  napi_is_arraybuffer#

                  +

                  napi_is_arraybuffer#

                  -
                  napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -13195,12 +13769,12 @@ as defined in Section 7.2.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is an array buffer.

                  -

                  napi_is_buffer#

                  +

                  napi_is_buffer#

                  -
                  napi_status napi_is_buffer(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_buffer(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -13209,12 +13783,12 @@ object.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is a buffer.

                  -

                  napi_is_date#

                  +

                  napi_is_date#

                  -
                  napi_status napi_is_date(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_date(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -13223,12 +13797,12 @@ object.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is a date.

                  -

                  napi_is_error#

                  +

                  napi_is_error#

                  -
                  napi_status napi_is_error(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_error(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -13236,12 +13810,12 @@ object.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is an Error.

                  -

                  napi_is_typedarray#

                  +

                  napi_is_typedarray#

                  -
                  napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -13249,12 +13823,12 @@ object.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is a typed array.

                  -

                  napi_is_dataview#

                  +

                  napi_is_dataview#

                  -
                  napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -13262,15 +13836,15 @@ object.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is a DataView.

                  -

                  napi_strict_equals#

                  +

                  napi_strict_equals#

                  -
                  napi_status napi_strict_equals(napi_env env,
                  +
                  napi_status napi_strict_equals(napi_env env,
                                                  napi_value lhs,
                                                  napi_value rhs,
                  -                               bool* result)
                  + bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] lhs: The JavaScript value to check.
                  • @@ -13280,13 +13854,13 @@ object.

                    Returns napi_ok if the API succeeded.

                    This API represents the invocation of the Strict Equality algorithm as defined in Section 7.2.14 of the ECMAScript Language Specification.

                    -

                    napi_detach_arraybuffer#

                    +

                    napi_detach_arraybuffer#

                    -
                    napi_status napi_detach_arraybuffer(napi_env env,
                    -                                    napi_value arraybuffer)
                    +
                    napi_status napi_detach_arraybuffer(napi_env env,
                    +                                    napi_value arraybuffer)
                    • [in] env: The environment that the API is invoked under.
                    • [in] arraybuffer: The JavaScript ArrayBuffer to be detached.
                    • @@ -13299,14 +13873,14 @@ detachable. For example, V8 requires that the ArrayBuffer be extern that is, created with napi_create_external_arraybuffer.

                      This API represents the invocation of the ArrayBuffer detach operation as defined in Section 24.1.1.3 of the ECMAScript Language Specification.

                      -

                      napi_is_detached_arraybuffer#

                      +

                      napi_is_detached_arraybuffer#

                      -
                      napi_status napi_is_detached_arraybuffer(napi_env env,
                      +
                      napi_status napi_is_detached_arraybuffer(napi_env env,
                                                                napi_value arraybuffer,
                      -                                         bool* result)
                      + bool* result)

        Working with JavaScript properties#

        +

        Node-API exposes a set of APIs to get and set properties on JavaScript objects. Some of these types are documented under Section 7 of the ECMAScript Language Specification.

        Properties in JavaScript are represented as a tuple of a key and a value. -Fundamentally, all property keys in N-API can be represented in one of the +Fundamentally, all property keys in Node-API can be represented in one of the following forms:

        • Named: a simple UTF8-encoded string
        • Integer-Indexed: an index value represented by uint32_t
        • -
        • JavaScript value: these are represented in N-API by napi_value. This can -be a napi_value representing a String, Number, or Symbol.
        • +
        • JavaScript value: these are represented in Node-API by napi_value. This can +be a napi_value representing a string, number, or symbol.
        -

        N-API values are represented by the type napi_value. -Any N-API call that requires a JavaScript value takes in a napi_value. +

        Node-API values are represented by the type napi_value. +Any Node-API call that requires a JavaScript value takes in a napi_value. However, it's the caller's responsibility to make sure that the napi_value in question is of the JavaScript type expected by the API.

        The APIs documented in this section provide a simple interface to @@ -13339,8 +13913,8 @@ get and set properties on arbitrary JavaScript objects represented by napi_value.

        For instance, consider the following JavaScript code snippet:

        const obj = {};
        -obj.myProp = 123;
        -

        The equivalent can be done using N-API values with the following snippet:

        +obj.myProp = 123;
        +

        The equivalent can be done using Node-API values with the following snippet:

        napi_status status = napi_generic_failure;
         
         // const obj = {}
        @@ -13359,7 +13933,7 @@ status = napi_set_named_property(env, obj, "myProp"
         
        const arr = [];
         arr[123] = 'hello';
        -

        The equivalent can be done using N-API values with the following snippet:

        +

        The equivalent can be done using Node-API values with the following snippet:

        napi_status status = napi_generic_failure;
         
         // const arr = [];
        @@ -13378,7 +13952,7 @@ status = napi_set_element(env, arr, 123, value)
         Consider the following JavaScript snippet:

        const arr = [];
         const value = arr[123];
        -

        The following is the approximate equivalent of the N-API counterpart:

        +

        The following is the approximate equivalent of the Node-API counterpart:

        napi_status status = napi_generic_failure;
         
         // const arr = []
        @@ -13392,11 +13966,11 @@ status = napi_get_element(env, arr, 123, &
         

        Finally, multiple properties can also be defined on an object for performance reasons. Consider the following JavaScript:

        const obj = {};
        -Object.defineProperties(obj, {
        +Object.defineProperties(obj, {
           'foo': { value: 123, writable: true, configurable: true, enumerable: true },
           'bar': { value: 456, writable: true, configurable: true, enumerable: true }
         });
        -

        The following is the approximate equivalent of the N-API counterpart:

        +

        The following is the approximate equivalent of the Node-API counterpart:

        napi_status status = napi_status_generic_failure;
         
         // const obj = {};
        @@ -13421,18 +13995,18 @@ status = napi_define_properties(env,
                                         sizeof(descriptors) / sizeof(descriptors[0]),
                                         descriptors);
         if (status != napi_ok) return status;
        -

        Structures#

        -

        napi_property_attributes#

        +

        Structures#

        +
        napi_property_attributes#
        -
        typedef enum {
        +
        typedef enum {
           napi_default = 0,
           napi_writable = 1 << 0,
           napi_enumerable = 1 << 1,
        @@ -13446,7 +14020,7 @@ status = napi_define_properties(env,
           napi_default_method = napi_writable | napi_configurable,
         
           // Default for object properties, like in JS obj[prop].
        -  napi_default_property = napi_writable |
        +  napi_default_jsproperty = napi_writable |
                                   napi_enumerable |
                                   napi_configurable,
         } napi_property_attributes;
        @@ -13465,15 +14039,15 @@ property is read only, not enumerable and not configurable.
      • napi_static: The property will be defined as a static property on a class as opposed to an instance property, which is the default. This is used only by napi_define_class. It is ignored by napi_define_properties.
      • -
      • napi_default_method: The property is configureable, writeable but not -enumerable like a method in a JS class.
      • -
      • napi_default_property: The property is writable, enumerable and configurable -like a property set via JS code obj.key = value.
      • +
      • napi_default_method: Like a method in a JS class, the property is +configurable and writeable, but not enumerable.
      • +
      • napi_default_jsproperty: Like a property set via assignment in JavaScript, +the property is writable, enumerable, and configurable.
      -

      napi_property_descriptor#

      +
      napi_property_descriptor#
      typedef struct {
         // One of utf8name or name should be NULL.
      -  const char* utf8name;
      +  const char* utf8name;
         napi_value name;
       
         napi_callback method;
      @@ -13482,10 +14056,10 @@ like a property set via JS code obj.key = value.
         napi_value value;
       
         napi_property_attributes attributes;
      -  void* data;
      +  void* data;
       } napi_property_descriptor;
        -
      • utf8name: Optional String describing the key for the property, +
      • utf8name: Optional string describing the key for the property, encoded as UTF8. One of utf8name or name must be provided for the property.
      • name: Optional napi_value that points to a JavaScript string or symbol @@ -13498,12 +14072,12 @@ property is a data property. If this is passed in, set getter, value and method to NULL (since these members won't be used). The given function is called implicitly by the runtime when the property is accessed from JavaScript code (or if a get on the property is -performed using a N-API call). napi_callback provides more details.
      • +performed using a Node-API call). napi_callback provides more details.
      • setter: A function to call when a set access of the property is performed. If this is passed in, set value and method to NULL (since these members won't be used). The given function is called implicitly by the runtime when the property is set from JavaScript code (or if a set on the property is -performed using a N-API call). napi_callback provides more details.
      • +performed using a Node-API call). napi_callback provides more details.
      • method: Set this to make the property descriptor object's value property to be a JavaScript function represented by method. If this is passed in, set value, getter and setter to NULL (since these members @@ -13513,17 +14087,17 @@ won't be used). napi_callback pr
      • data: The callback data passed into method, getter and setter if this function is invoked.
      -

      Functions#

      -

      napi_get_property_names#

      +

      Functions#

      +
      napi_get_property_names#
      -
      napi_status napi_get_property_names(napi_env env,
      +
      napi_status napi_get_property_names(napi_env env,
                                           napi_value object,
      -                                    napi_value* result);
      + napi_value* result)
      ;
        -
      • [in] env: The environment that the N-API call is invoked under.
      • +
      • [in] env: The environment that the Node-API call is invoked under.
      • [in] object: The object from which to retrieve the properties.
      • [out] result: A napi_value representing an array of JavaScript values that represent the property names of the object. The API can be used to @@ -13534,9 +14108,9 @@ and napi_get_element.
      • This API returns the names of the enumerable properties of object as an array of strings. The properties of object whose key is a symbol will not be included.

        -

        napi_get_all_property_names#

        +
        napi_get_all_property_names#
        napi_get_all_property_names(napi_env env,
        @@ -13546,81 +14120,81 @@ included.

        napi_key_conversion key_conversion, napi_value* result);
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object from which to retrieve the properties.
        • [in] key_mode: Whether to retrieve prototype properties as well.
        • [in] key_filter: Which properties to retrieve (enumerable/readable/writable).
        • [in] key_conversion: Whether to convert numbered property keys to strings.
        • [out] result: A napi_value representing an array of JavaScript values -that represent the property names of the object. napi_get_array_length and -napi_get_element can be used to iterate over result.
        • +that represent the property names of the object. napi_get_array_length +and napi_get_element can be used to iterate over result.

        Returns napi_ok if the API succeeded.

        This API returns an array containing the names of the available properties of this object.

        -

        napi_set_property#

        +
        napi_set_property#
        -
        napi_status napi_set_property(napi_env env,
        +
        napi_status napi_set_property(napi_env env,
                                       napi_value object,
                                       napi_value key,
        -                              napi_value value);
        + napi_value value)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object on which to set the property.
        • [in] key: The name of the property to set.
        • [in] value: The property value.

        Returns napi_ok if the API succeeded.

        This API set a property on the Object passed in.

        -

        napi_get_property#

        +
        napi_get_property#
        -
        napi_status napi_get_property(napi_env env,
        +
        napi_status napi_get_property(napi_env env,
                                       napi_value object,
                                       napi_value key,
        -                              napi_value* result);
        + napi_value* result)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object from which to retrieve the property.
        • [in] key: The name of the property to retrieve.
        • [out] result: The value of the property.

        Returns napi_ok if the API succeeded.

        This API gets the requested property from the Object passed in.

        -

        napi_has_property#

        +
        napi_has_property#
        -
        napi_status napi_has_property(napi_env env,
        +
        napi_status napi_has_property(napi_env env,
                                       napi_value object,
                                       napi_value key,
        -                              bool* result);
        + bool* result)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object to query.
        • [in] key: The name of the property whose existence to check.
        • [out] result: Whether the property exists on the object or not.

        Returns napi_ok if the API succeeded.

        This API checks if the Object passed in has the named property.

        -

        napi_delete_property#

        +
        napi_delete_property#
        -
        napi_status napi_delete_property(napi_env env,
        +
        napi_status napi_delete_property(napi_env env,
                                          napi_value object,
                                          napi_value key,
        -                                 bool* result);
        + bool* result)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object to query.
        • [in] key: The name of the property to delete.
        • [out] result: Whether the property deletion succeeded or not. result can @@ -13628,36 +14202,36 @@ optionally be ignored by passing NULL.

        Returns napi_ok if the API succeeded.

        This API attempts to delete the key own property from object.

        -

        napi_has_own_property#

        +
        napi_has_own_property#
        -
        napi_status napi_has_own_property(napi_env env,
        +
        napi_status napi_has_own_property(napi_env env,
                                           napi_value object,
                                           napi_value key,
        -                                  bool* result);
        + bool* result)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object to query.
        • [in] key: The name of the own property whose existence to check.
        • [out] result: Whether the own property exists on the object or not.

        Returns napi_ok if the API succeeded.

        This API checks if the Object passed in has the named own property. key must -be a string or a Symbol, or an error will be thrown. N-API will not perform -any conversion between data types.

        -

        napi_set_named_property#

        +be a string or a symbol, or an error will be thrown. Node-API will not +perform any conversion between data types.

        +
        napi_set_named_property#
        -
        napi_status napi_set_named_property(napi_env env,
        +
        napi_status napi_set_named_property(napi_env env,
                                             napi_value object,
        -                                    const char* utf8Name,
        -                                    napi_value value);
        + const char* utf8Name, + napi_value value)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object on which to set the property.
        • [in] utf8Name: The name of the property to set.
        • [in] value: The property value.
        • @@ -13665,17 +14239,17 @@ any conversion between data types.

          Returns napi_ok if the API succeeded.

          This method is equivalent to calling napi_set_property with a napi_value created from the string passed in as utf8Name.

          -

          napi_get_named_property#

          +
          napi_get_named_property#
          -
          napi_status napi_get_named_property(napi_env env,
          +
          napi_status napi_get_named_property(napi_env env,
                                               napi_value object,
          -                                    const char* utf8Name,
          -                                    napi_value* result);
          + const char* utf8Name, + napi_value* result)
          ;
            -
          • [in] env: The environment that the N-API call is invoked under.
          • +
          • [in] env: The environment that the Node-API call is invoked under.
          • [in] object: The object from which to retrieve the property.
          • [in] utf8Name: The name of the property to get.
          • [out] result: The value of the property.
          • @@ -13683,17 +14257,17 @@ created from the string passed in as utf8Name.

            Returns napi_ok if the API succeeded.

            This method is equivalent to calling napi_get_property with a napi_value created from the string passed in as utf8Name.

            -

            napi_has_named_property#

            +
            napi_has_named_property#
            -
            napi_status napi_has_named_property(napi_env env,
            +
            napi_status napi_has_named_property(napi_env env,
                                                 napi_value object,
            -                                    const char* utf8Name,
            -                                    bool* result);
            + const char* utf8Name, + bool* result)
            ;
              -
            • [in] env: The environment that the N-API call is invoked under.
            • +
            • [in] env: The environment that the Node-API call is invoked under.
            • [in] object: The object to query.
            • [in] utf8Name: The name of the property whose existence to check.
            • [out] result: Whether the property exists on the object or not.
            • @@ -13701,51 +14275,51 @@ created from the string passed in as utf8Name.

              Returns napi_ok if the API succeeded.

              This method is equivalent to calling napi_has_property with a napi_value created from the string passed in as utf8Name.

              -

              napi_set_element#

              +
              napi_set_element#
              -
              napi_status napi_set_element(napi_env env,
              +
              napi_status napi_set_element(napi_env env,
                                            napi_value object,
              -                             uint32_t index,
              -                             napi_value value);
              + uint32_t index, + napi_value value)
              ;
                -
              • [in] env: The environment that the N-API call is invoked under.
              • +
              • [in] env: The environment that the Node-API call is invoked under.
              • [in] object: The object from which to set the properties.
              • [in] index: The index of the property to set.
              • [in] value: The property value.

              Returns napi_ok if the API succeeded.

              This API sets and element on the Object passed in.

              -

              napi_get_element#

              +
              napi_get_element#
              -
              napi_status napi_get_element(napi_env env,
              +
              napi_status napi_get_element(napi_env env,
                                            napi_value object,
              -                             uint32_t index,
              -                             napi_value* result);
              + uint32_t index, + napi_value* result)
              ;
                -
              • [in] env: The environment that the N-API call is invoked under.
              • +
              • [in] env: The environment that the Node-API call is invoked under.
              • [in] object: The object from which to retrieve the property.
              • [in] index: The index of the property to get.
              • [out] result: The value of the property.

              Returns napi_ok if the API succeeded.

              This API gets the element at the requested index.

              -

              napi_has_element#

              +
              napi_has_element#
              -
              napi_status napi_has_element(napi_env env,
              +
              napi_status napi_has_element(napi_env env,
                                            napi_value object,
              -                             uint32_t index,
              -                             bool* result);
              + uint32_t index, + bool* result)
              ;
                -
              • [in] env: The environment that the N-API call is invoked under.
              • +
              • [in] env: The environment that the Node-API call is invoked under.
              • [in] object: The object to query.
              • [in] index: The index of the property whose existence to check.
              • [out] result: Whether the property exists on the object or not.
              • @@ -13753,17 +14327,17 @@ created from the string passed in as utf8Name.

                Returns napi_ok if the API succeeded.

                This API returns if the Object passed in has an element at the requested index.

                -

                napi_delete_element#

                +
                napi_delete_element#
                -
                napi_status napi_delete_element(napi_env env,
                +
                napi_status napi_delete_element(napi_env env,
                                                 napi_value object,
                -                                uint32_t index,
                -                                bool* result);
                + uint32_t index, + bool* result)
                ;
                  -
                • [in] env: The environment that the N-API call is invoked under.
                • +
                • [in] env: The environment that the Node-API call is invoked under.
                • [in] object: The object to query.
                • [in] index: The index of the property to delete.
                • [out] result: Whether the element deletion succeeded or not. result can @@ -13771,17 +14345,17 @@ optionally be ignored by passing NULL.

                Returns napi_ok if the API succeeded.

                This API attempts to delete the specified index from object.

                -

                napi_define_properties#

                +
                napi_define_properties#
                -
                napi_status napi_define_properties(napi_env env,
                +
                napi_status napi_define_properties(napi_env env,
                                                    napi_value object,
                -                                   size_t property_count,
                -                                   const napi_property_descriptor* properties);
                + size_t property_count, + const napi_property_descriptor* properties)
                ;
                  -
                • [in] env: The environment that the N-API call is invoked under.
                • +
                • [in] env: The environment that the Node-API call is invoked under.
                • [in] object: The object from which to retrieve the properties.
                • [in] property_count: The number of elements in the properties array.
                • [in] properties: The array of property descriptors.
                • @@ -13793,15 +14367,15 @@ object. The properties are defined using property descriptors (see this API will set the properties on the object one at a time, as defined by DefineOwnProperty() (described in Section 9.1.6 of the ECMA-262 specification).

                  -

                  napi_object_freeze#

                  +
                  napi_object_freeze#
                  -
                  napi_status napi_object_freeze(napi_env env,
                  -                               napi_value object);
                  +
                  napi_status napi_object_freeze(napi_env env,
                  +                               napi_value object);
                    -
                  • [in] env: The environment that the N-API call is invoked under.
                  • +
                  • [in] env: The environment that the Node-API call is invoked under.
                  • [in] object: The object to freeze.

                  Returns napi_ok if the API succeeded.

                  @@ -13812,15 +14386,15 @@ properties, and prevents the values of existing properties from being changed. It also prevents the object's prototype from being changed. This is described in Section 19.1.2.6 of the ECMA-262 specification.

                  -

                  napi_object_seal#

                  +
                  napi_object_seal#
                  -
                  napi_status napi_object_seal(napi_env env,
                  -                             napi_value object);
                  +
                  napi_status napi_object_seal(napi_env env,
                  +                             napi_value object);
                    -
                  • [in] env: The environment that the N-API call is invoked under.
                  • +
                  • [in] env: The environment that the Node-API call is invoked under.
                  • [in] object: The object to seal.

                  Returns napi_ok if the API succeeded.

                  @@ -13828,9 +14402,9 @@ ECMA-262 specification.

                  added to it, as well as marking all existing properties as non-configurable. This is described in Section 19.1.2.20 of the ECMA-262 specification.

                  -

                  Working with JavaScript functions#

                  -

                  N-API provides a set of APIs that allow JavaScript code to -call back into native code. N-API APIs that support calling back +

                  Working with JavaScript functions#

                  +

                  Node-API provides a set of APIs that allow JavaScript code to +call back into native code. Node-APIs that support calling back into native code take in a callback functions represented by the napi_callback type. When the JavaScript VM calls back to native code, the napi_callback function provided is invoked. The APIs @@ -13841,7 +14415,7 @@ following:

                • Get the arguments passed into the callback.
                • Return a napi_value back from the callback.
                -

                Additionally, N-API provides a set of functions which allow calling +

                Additionally, Node-API provides a set of functions which allow calling JavaScript functions from native code. One can either call a function like a regular JavaScript function call, or as a constructor function.

                @@ -13849,20 +14423,20 @@ function.

                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#

                +

                napi_call_function#

                -
                NAPI_EXTERN napi_status napi_call_function(napi_env env,
                +
                NAPI_EXTERN napi_status napi_call_function(napi_env env,
                                                            napi_value recv,
                                                            napi_value func,
                -                                           size_t argc,
                +                                           size_t argc,
                                                            const napi_value* argv,
                -                                           napi_value* result);
                + napi_value* result)
                ;
                • [in] env: The environment that the API is invoked under.
                • -
                • [in] recv: The this object passed to the called function.
                • +
                • [in] recv: The this value passed to the called function.
                • [in] func: napi_value representing the JavaScript function to be invoked.
                • [in] argc: The count of elements in the argv array.
                • [in] argv: Array of napi_values representing JavaScript values passed in @@ -13876,7 +14450,7 @@ native code into JavaScript. For the special case of calling into JavaS after an async operation, see napi_make_callback.

                  A sample use case might look as follows. Consider the following JavaScript snippet:

                  -
                  function AddTwo(num) {
                  +
                  function AddTwo(num) {
                     return num + 2;
                   }

                  Then, the above function can be invoked from a native add-on using the @@ -13894,7 +14468,7 @@ status = napi_create_int32(env, 1337, &arg if (status != napi_ok) return; napi_value* argv = &arg; -size_t argc = 1; +size_t argc = 1; // AddTwo(arg); napi_value return_val; @@ -13902,20 +14476,20 @@ status = napi_call_function(env, global, add_two, argc, argv, &return_val); if (status != napi_ok) return; // Convert the result back to a native type -int32_t result; +int32_t result; status = napi_get_value_int32(env, return_val, &result); if (status != napi_ok) return;

                  -

                  napi_create_function#

                  +

                  napi_create_function#

                  -
                  napi_status napi_create_function(napi_env env,
                  -                                 const char* utf8name,
                  -                                 size_t length,
                  +
                  napi_status napi_create_function(napi_env env,
                  +                                 const char* utf8name,
                  +                                 size_t length,
                                                    napi_callback cb,
                  -                                 void* data,
                  -                                 napi_value* result);
                  + void* data, + napi_value* result)
                  ;
                  • [in] env: The environment that the API is invoked under.
                  • [in] utf8Name: The name of the function encoded as UTF8. This is visible @@ -13939,12 +14513,12 @@ to JavaScript, in order for the function to be accessible from script.

                    In order to expose a function as part of the add-on's module exports, set the newly created function on the exports object. A sample module might look as follows:

                    -
                    napi_value SayHello(napi_env env, napi_callback_info info) {
                    +
                    napi_value SayHello(napi_env env, napi_callback_info info) {
                       printf("Hello\n");
                       return NULL;
                     }
                     
                    -napi_value Init(napi_env env, napi_value exports) {
                    +napi_value Init(napi_env env, napi_value exports) {
                       napi_status status;
                     
                       napi_value fn;
                    @@ -13960,7 +14534,7 @@ object. A sample module might look as follows:

                    NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)

                    Given the above code, the add-on can be used from JavaScript as follows:

                    const myaddon = require('./addon');
                    -myaddon.sayHello();
                    +myaddon.sayHello();

                    The string passed to require() is the name of the target in binding.gyp responsible for creating the .node file.

                    Any non-NULL data which is passed to this API via the data parameter can @@ -13969,22 +14543,22 @@ be associated with the resulting JavaScript function (which is returned in the passing both the JavaScript function and the data to napi_add_finalizer.

                    JavaScript Functions are described in Section 19.2 of the ECMAScript Language Specification.

                    -

                    napi_get_cb_info#

                    +

                    napi_get_cb_info#

                    -
                    napi_status napi_get_cb_info(napi_env env,
                    +
                    napi_status napi_get_cb_info(napi_env env,
                                                  napi_callback_info cbinfo,
                    -                             size_t* argc,
                    +                             size_t* argc,
                                                  napi_value* argv,
                                                  napi_value* thisArg,
                    -                             void** data)
                    + void** data)
                    • [in] env: The environment that the API is invoked under.
                    • [in] cbinfo: The callback info passed into the callback function.
                    • -
                    • [in-out] argc: Specifies the size of the provided argv array and receives -the actual count of arguments.
                    • +
                    • [in-out] argc: Specifies the length of the provided argv array and +receives the actual count of arguments.
                    • [out] argv: Buffer to which the napi_value representing the arguments are copied. If there are more arguments than the provided count, only the requested number of arguments are copied. If there are fewer arguments @@ -13996,14 +14570,14 @@ that represent undefined.
                    • Returns napi_ok if the API succeeded.

                      This method is used within a callback function to retrieve details about the call like the arguments and the this pointer from a given callback info.

                      -

                      napi_get_new_target#

                      +

                      napi_get_new_target#

                      -
                      napi_status napi_get_new_target(napi_env env,
                      +
                      napi_status napi_get_new_target(napi_env env,
                                                       napi_callback_info cbinfo,
                      -                                napi_value* result)
                      + napi_value* result)
                      • [in] env: The environment that the API is invoked under.
                      • [in] cbinfo: The callback info passed into the callback function.
                      • @@ -14012,16 +14586,16 @@ call like the arguments and the this pointer from a given callback

                        Returns napi_ok if the API succeeded.

                        This API returns the new.target of the constructor call. If the current callback is not a constructor call, the result is NULL.

                        -

                        napi_new_instance#

                        +

                        napi_new_instance#

                        -
                        napi_status napi_new_instance(napi_env env,
                        +
                        napi_status napi_new_instance(napi_env env,
                                                       napi_value cons,
                        -                              size_t argc,
                        +                              size_t argc,
                                                       napi_value* argv,
                        -                              napi_value* result)
                        + napi_value* result)
                        • [in] env: The environment that the API is invoked under.
                        • [in] cons: napi_value representing the JavaScript function to be invoked @@ -14035,13 +14609,13 @@ which in this case is the constructed object.
                        • This method is used to instantiate a new JavaScript value using a given napi_value that represents the constructor for the object. For example, consider the following snippet:

                          -
                          function MyObject(param) {
                          -  this.param = param;
                          +
                          function MyObject(param) {
                          +  this.param = param;
                           }
                           
                           const arg = 'hello';
                          -const value = new MyObject(arg);
                          -

                          The following can be approximated in N-API using the following snippet:

                          +const value = new MyObject(arg);
                          +

                          The following can be approximated in Node-API using the following snippet:

                          // Get the constructor function MyObject
                           napi_value global, constructor, arg, value;
                           napi_status status = napi_get_global(env, &global);
                          @@ -14055,13 +14629,13 @@ status = napi_create_string_utf8(env, "hello",
                           if (status != napi_ok) return;
                           
                           napi_value* argv = &arg;
                          -size_t argc = 1;
                          +size_t argc = 1;
                           
                           // const value = new MyObject(arg)
                           status = napi_new_instance(env, constructor, argc, argv, &value);

                          Returns napi_ok if the API succeeded.

                          -

                          Object wrap#

                          -

                          N-API offers a way to "wrap" C++ classes and instances so that the class +

                          Object wrap#

                          +

                          Node-API offers a way to "wrap" C++ classes and instances so that the class constructor and methods can be called from JavaScript.

                          1. The napi_define_class API defines a JavaScript class with constructor, @@ -14082,7 +14656,7 @@ reference to the class constructor for later instanceof checks.

                            napi_value MyClass_constructor = NULL;
                             status = napi_get_reference_value(env, MyClass::es_constructor, &MyClass_constructor);
                             assert(napi_ok == status);
                            -bool is_instance = false;
                            +bool is_instance = false;
                             status = napi_instanceof(env, es_this, MyClass_constructor, &is_instance);
                             assert(napi_ok == status);
                             if (is_instance) {
                            @@ -14100,10 +14674,10 @@ cases there is a chance that they may be unwrapped incorrectly.

                            // `openDatabase()` returns a JavaScript object that wraps a native database // handle. -const dbHandle = myAddon.openDatabase(); +const dbHandle = myAddon.openDatabase(); // `query()` returns a JavaScript object that wraps a native query handle. -const queryHandle = myAddon.query(dbHandle, 'Gimme ALL the things!'); +const queryHandle = myAddon.query(dbHandle, 'Gimme ALL the things!'); // There is an accidental error in the line below. The first parameter to // `myAddon.queryHasRecords()` should be the database handle (`dbHandle`), not @@ -14112,7 +14686,7 @@ cases there is a chance that they may be unwrapped incorrectly.

                            // // myAddon.queryHasRecords(dbHandle, queryHandle) // -while (myAddon.queryHasRecords(queryHandle, dbHandle)) { +while (myAddon.queryHasRecords(queryHandle, dbHandle)) { // retrieve records }

                            In the above example myAddon.queryHasRecords() is a method that accepts two @@ -14136,8 +14710,8 @@ set to the prototype of the constructor for query handle instances. In this case, the database handle instance can appear as a query handle instance, and it will pass the napi_instanceof() test for a query handle instance, while still containing a pointer to a database handle.

                            -

                            To this end, N-API provides type-tagging capabilities.

                            -

                            A type tag is a 128-bit integer unique to the addon. N-API provides the +

                            To this end, Node-API provides type-tagging capabilities.

                            +

                            A type tag is a 128-bit integer unique to the addon. Node-API provides the napi_type_tag structure for storing a type tag. When such a value is passed along with a JavaScript object stored in a napi_value to napi_type_tag_object(), the JavaScript object will be "marked" with the @@ -14164,8 +14738,8 @@ illustrates the use of napi_type_tag_object() and 0x9c73317f9fad44a3, 0x93c3920bf3b0ad6a }; -static napi_value -openDatabase(napi_env env, napi_callback_info info) { +static napi_value +openDatabase(napi_env env, napi_callback_info info) { napi_status status; napi_value result; @@ -14191,12 +14765,12 @@ illustrates the use of napi_type_tag_object() and // we can use `napi_check_object_type_tag()` to ensure that it is indeed such a // handle. -static napi_value -query(napi_env env, napi_callback_info info) { +static napi_value +query(napi_env env, napi_callback_info info) { napi_status status; - size_t argc = 2; + size_t argc = 2; napi_value argv[2]; - bool is_db_handle; + bool is_db_handle; status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL); if (status != napi_ok) return NULL; @@ -14215,29 +14789,30 @@ illustrates the use of napi_type_tag_object() and return NULL; } } -

                            napi_define_class#

                            +

                            napi_define_class#

                            -
                            napi_status napi_define_class(napi_env env,
                            -                              const char* utf8name,
                            -                              size_t length,
                            +
                            napi_status napi_define_class(napi_env env,
                            +                              const char* utf8name,
                            +                              size_t length,
                                                           napi_callback constructor,
                            -                              void* data,
                            -                              size_t property_count,
                            +                              void* data,
                            +                              size_t property_count,
                                                           const napi_property_descriptor* properties,
                            -                              napi_value* result);
                            + napi_value* result)
                            ;
                            • [in] env: The environment that the API is invoked under.
                            • -
                            • [in] utf8name: Name of the JavaScript constructor function; this is -not required to be the same as the C++ class name, though it is recommended -for clarity.
                            • +
                            • [in] utf8name: Name of the JavaScript constructor function; When wrapping a +C++ class, we recommend for clarity that this name be the same as that of +the C++ class.
                            • [in] length: The length of the utf8name in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.
                            • [in] constructor: Callback function that handles constructing instances -of the class. This should be a static method on the class, not an actual -C++ constructor function. napi_callback provides more details.
                            • +of the class. When wrapping a C++ class, this method must be a static member +with the napi_callback signature. A C++ class constructor cannot be +used. napi_callback provides more details.
                            • [in] data: Optional data to be passed to the constructor callback as the data property of the callback info.
                            • [in] property_count: Number of items in the properties array argument.
                            • @@ -14248,42 +14823,48 @@ See napi_property_descriptor. the class.

                            Returns napi_ok if the API succeeded.

                            -

                            Defines a JavaScript class that corresponds to a C++ class, including:

                            -
                              -
                            • A JavaScript constructor function that has the class name and invokes the -provided C++ constructor callback.
                            • -
                            • Properties on the constructor function corresponding to static data -properties, accessors, and methods of the C++ class (defined by -property descriptors with the napi_static attribute).
                            • -
                            • Properties on the constructor function's prototype object corresponding to -non-static data properties, accessors, and methods of the C++ class -(defined by property descriptors without the napi_static attribute).
                            • -
                            -

                            The C++ constructor callback should be a static method on the class that calls -the actual class constructor, then wraps the new C++ instance in a JavaScript -object, and returns the wrapper object. See napi_wrap() for details.

                            +

                            Defines a JavaScript class, including:

                            +
                              +
                            • A JavaScript constructor function that has the class name. When wrapping a +corresponding C++ class, the callback passed via constructor can be used to +instantiate a new C++ class instance, which can then be placed inside the +JavaScript object instance being constructed using napi_wrap.
                            • +
                            • Properties on the constructor function whose implementation can call +corresponding static data properties, accessors, and methods of the C++ +class (defined by property descriptors with the napi_static attribute).
                            • +
                            • Properties on the constructor function's prototype object. When wrapping a +C++ class, non-static data properties, accessors, and methods of the C++ +class can be called from the static functions given in the property +descriptors without the napi_static attribute after retrieving the C++ class +instance placed inside the JavaScript object instance by using +napi_unwrap.
                            • +
                            +

                            When wrapping a C++ class, the C++ constructor callback passed via constructor +should be a static method on the class that calls the actual class constructor, +then wraps the new C++ instance in a JavaScript object, and returns the wrapper +object. See napi_wrap for details.

                            The JavaScript constructor function returned from napi_define_class is -often saved and used later, to construct new instances of the class from native -code, and/or check whether provided values are instances of the class. In that -case, to prevent the function value from being garbage-collected, create a -persistent reference to it using napi_create_reference and ensure the -reference count is kept >= 1.

                            +often saved and used later to construct new instances of the class from native +code, and/or to check whether provided values are instances of the class. In +that case, to prevent the function value from being garbage-collected, a +strong persistent reference to it can be created using +napi_create_reference, ensuring that the reference count is kept >= 1.

                            Any non-NULL data which is passed to this API via the data parameter or via the data field of the napi_property_descriptor array items can be associated with the resulting JavaScript constructor (which is returned in the result parameter) and freed whenever the class is garbage-collected by passing both the JavaScript function and the data to napi_add_finalizer.

                            -

                            napi_wrap#

                            +

                            napi_wrap#

                            -
                            napi_status napi_wrap(napi_env env,
                            +
                            napi_status napi_wrap(napi_env env,
                                                   napi_value js_object,
                            -                      void* native_object,
                            +                      void* native_object,
                                                   napi_finalize finalize_cb,
                            -                      void* finalize_hint,
                            -                      napi_ref* result);
                            + void* finalize_hint, + napi_ref* result)
                            ;
                            • [in] env: The environment that the API is invoked under.
                            • [in] js_object: The JavaScript object that will be the wrapper for the @@ -14321,14 +14902,14 @@ required in order to enable correct disposal of the reference.

                              Calling napi_wrap() a second time on an object will return an error. To associate another native instance with the object, use napi_remove_wrap() first.

                              -

                              napi_unwrap#

                              +

                              napi_unwrap#

                              -
                              napi_status napi_unwrap(napi_env env,
                              +
                              napi_status napi_unwrap(napi_env env,
                                                       napi_value js_object,
                              -                        void** result);
                              + void** result)
                              ;
                              • [in] env: The environment that the API is invoked under.
                              • [in] js_object: The object associated with the native instance.
                              • @@ -14342,14 +14923,14 @@ corresponding napi_callback is invoked. If the callback is for an i method or accessor, then the this argument to the callback is the wrapper object; the wrapped C++ instance that is the target of the call can be obtained then by calling napi_unwrap() on the wrapper object.

                                -

                                napi_remove_wrap#

                                +

                                napi_remove_wrap#

                                -
                                napi_status napi_remove_wrap(napi_env env,
                                +
                                napi_status napi_remove_wrap(napi_env env,
                                                              napi_value js_object,
                                -                             void** result);
                                + void** result)
                                ;
                                • [in] env: The environment that the API is invoked under.
                                • [in] js_object: The object associated with the native instance.
                                • @@ -14360,14 +14941,14 @@ then by calling napi_unwrap() on the wrapper object.

                                  object js_object using napi_wrap() and removes the wrapping. If a finalize callback was associated with the wrapping, it will no longer be called when the JavaScript object becomes garbage-collected.

                                  -

                                  napi_type_tag_object#

                                  +

                                  napi_type_tag_object#

                                  -
                                  napi_status napi_type_tag_object(napi_env env,
                                  +
                                  napi_status napi_type_tag_object(napi_env env,
                                                                    napi_value js_object,
                                  -                                 const napi_type_tag* type_tag);
                                  + const napi_type_tag* type_tag)
                                  ;
                                  • [in] env: The environment that the API is invoked under.
                                  • [in] js_object: The JavaScript object to be marked.
                                  • @@ -14380,15 +14961,15 @@ attached to the object with one owned by the addon to ensure that the object has the right type.

                                    If the object already has an associated type tag, this API will return napi_invalid_arg.

                                    -

                                    napi_check_object_type_tag#

                                    +

                                    napi_check_object_type_tag#

                                    -
                                    napi_status napi_check_object_type_tag(napi_env env,
                                    +
                                    napi_status napi_check_object_type_tag(napi_env env,
                                                                            napi_value js_object,
                                                                            const napi_type_tag* type_tag,
                                    -                                       bool* result);
                                    + bool* result)
                                    ;
                                    • [in] env: The environment that the API is invoked under.
                                    • [in] js_object: The JavaScript object whose type tag to examine.
                                    • @@ -14401,17 +14982,17 @@ object. false is also returned if no type tag was found on the obje js_object. If no tag is found on js_object or, if a tag is found but it does not match type_tag, then result is set to false. If a tag is found and it matches type_tag, then result is set to true.

                                      -

                                      napi_add_finalizer#

                                      +

                                      napi_add_finalizer#

                                      -
                                      napi_status napi_add_finalizer(napi_env env,
                                      +
                                      napi_status napi_add_finalizer(napi_env env,
                                                                      napi_value js_object,
                                      -                               void* native_object,
                                      +                               void* native_object,
                                                                      napi_finalize finalize_cb,
                                      -                               void* finalize_hint,
                                      -                               napi_ref* result);
                                      + 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 @@ -14441,45 +15022,45 @@ attach each of them to the JavaScript object, and
                                      • 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#

                                        +

                          Simple asynchronous operations#

                          Addon modules often need to leverage async helpers from libuv as part of their implementation. This allows them to schedule work to be executed asynchronously so that their methods can return in advance of the work being completed. This allows them to avoid blocking overall execution of the Node.js application.

                          -

                          N-API provides an ABI-stable interface for these +

                          Node-API provides an ABI-stable interface for these supporting functions which covers the most common asynchronous use cases.

                          -

                          N-API defines the napi_async_work structure which is used to manage +

                          Node-API defines the napi_async_work structure which is used to manage asynchronous workers. Instances are created/deleted with napi_create_async_work and napi_delete_async_work.

                          The execute and complete callbacks are functions that will be invoked when the executor is ready to execute and when it completes its task respectively.

                          -

                          The execute function should avoid making any N-API calls +

                          The execute function should avoid making any Node-API calls that could result in the execution of JavaScript or interaction with -JavaScript objects. Most often, any code that needs to make N-API +JavaScript objects. Most often, any code that needs to make Node-API calls should be made in complete callback instead. Avoid using the napi_env parameter in the execute callback as it will likely execute JavaScript.

                          These functions implement the following interfaces:

                          -
                          typedef void (*napi_async_execute_callback)(napi_env env,
                          -                                            void* data);
                          -typedef void (*napi_async_complete_callback)(napi_env env,
                          +
                          typedef void (*napi_async_execute_callback)(napi_env env,
                          +                                            void* data);
                          +typedef void (*napi_async_complete_callback)(napi_env env,
                                                                        napi_status status,
                          -                                             void* data);
                          + void* data)
                          ;

                          When these methods are invoked, the data parameter passed will be the addon-provided void* data that was passed into the napi_create_async_work call.

                          Once created the async worker can be queued for execution using the napi_queue_async_work function:

                          -
                          napi_status napi_queue_async_work(napi_env env,
                          -                                  napi_async_work work);
                          +
                          napi_status napi_queue_async_work(napi_env env,
                          +                                  napi_async_work work);

                          napi_cancel_async_work can be used if the work needs to be cancelled before the work has started execution.

                          After calling napi_cancel_async_work, the complete callback will be invoked with a status value of napi_cancelled. The work should not be deleted before the complete callback invocation, even when it was cancelled.

                          -

                          napi_create_async_work#

                          +

                          napi_create_async_work#

                          -
                          NAPI_EXTERN napi_status
                          -napi_call_threadsafe_function(napi_threadsafe_function func,
                          -                              void* data,
                          -                              napi_threadsafe_function_call_mode is_blocking);
                          +
                          NAPI_EXTERN napi_status
                          +napi_call_threadsafe_function(napi_threadsafe_function func,
                          +                              void* data,
                          +                              napi_threadsafe_function_call_mode is_blocking);
                          • [in] func: The asynchronous thread-safe JavaScript function to invoke.
                          • [in] data: Data to send into JavaScript via the callback call_js_cb @@ -15112,17 +15720,20 @@ indicate that the call should block if the queue is full or napi_tsfn_nonblocking to indicate that the call should return immediately with a status of napi_queue_full whenever the queue is full.
                          +

                          This API should not be called with napi_tsfn_blocking from a JavaScript +thread, because, if the queue is full, it may cause the JavaScript thread to +deadlock.

                          This API will return napi_closing if napi_release_threadsafe_function() was called with abort set to napi_tsfn_abort from any thread. The value is only added to the queue if the API returns napi_ok.

                          This API may be called from any thread which makes use of func.

                          -

                          napi_acquire_threadsafe_function#

                          +

                          napi_acquire_threadsafe_function#

                          -
                          NAPI_EXTERN napi_status
                          -napi_acquire_threadsafe_function(napi_threadsafe_function func);
                          +
                          NAPI_EXTERN napi_status
                          +napi_acquire_threadsafe_function(napi_threadsafe_function func);
                          • [in] func: The asynchronous thread-safe JavaScript function to start making use of.
                          • @@ -15132,14 +15743,14 @@ function APIs to indicate that it will be making use of func. This func from being destroyed when all other threads have stopped making use of it.

                            This API may be called from any thread which will start making use of func.

                            -

                            napi_release_threadsafe_function#

                            +

                            napi_release_threadsafe_function#

                            -
                            NAPI_EXTERN napi_status
                            -napi_release_threadsafe_function(napi_threadsafe_function func,
                            -                                 napi_threadsafe_function_release_mode mode);
                            +
                            NAPI_EXTERN napi_status
                            +napi_release_threadsafe_function(napi_threadsafe_function func,
                            +                                 napi_threadsafe_function_release_mode mode);
                            • [in] func: The asynchronous thread-safe JavaScript function whose reference count to decrement.
                            • @@ -15155,13 +15766,13 @@ values will be placed in the queue. to any thread-safe APIs after having called this API has undefined results, as func may have been destroyed.

                              This API may be called from any thread which will stop making use of func.

                              -

                              napi_ref_threadsafe_function#

                              +

                              napi_ref_threadsafe_function#

                              -
                              NAPI_EXTERN napi_status
                              -napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func);
                              +
                              NAPI_EXTERN napi_status
                              +napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func);
                              • [in] env: The environment that the API is invoked under.
                              • [in] func: The thread-safe function to reference.
                              • @@ -15174,13 +15785,13 @@ able to be destroyed nor does napi_ref_threadsafe_function prevent being destroyed. napi_acquire_threadsafe_function and napi_release_threadsafe_function are available for that purpose.

                                This API may only be called from the main thread.

                                -

                                napi_unref_threadsafe_function#

                                +

                                napi_unref_threadsafe_function#

                                -
                                NAPI_EXTERN napi_status
                                -napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func);
                                +
                                NAPI_EXTERN napi_status
                                +napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func);
                                • [in] env: The environment that the API is invoked under.
                                • [in] func: The thread-safe function to unreference.
                                • @@ -15189,14 +15800,14 @@ being destroyed. napi_acquire_threadsafe_function and may exit before func is destroyed. Similar to uv_unref it is also idempotent.

                                  This API may only be called from the main thread.

                                  -

                                  Miscellaneous utilities#

                                  -

                                  node_api_get_module_file_name#

                                  +

                          Miscellaneous utilities#

                          +

                          node_api_get_module_file_name#

                          Stability: 1 - Experimental

                          -
                          NAPI_EXTERN napi_status
                          -node_api_get_module_file_name(napi_env env, const char** result);
                          +
                          NAPI_EXTERN napi_status
                          +node_api_get_module_file_name(napi_env env, const char** result);
                           
                          • [in] env: The environment that the API is invoked under.
                          • @@ -15206,25 +15817,26 @@ file system it will start with file://. The string is null-terminat owned by env and must thus not be modified or freed.

                          result may be an empty string if the add-on loading process fails to establish -the add-on's file name during loading.

                          -

                          C++ Embedder API#

                          +the add-on's file name during loading.

                          + +

                          C++ embedder API#

                          Node.js provides a number of C++ APIs that can be used to execute JavaScript in a Node.js environment from other C++ software.

                          -

                          The documentation for these APIs can be found in src/node.h in the Node.js +

                          The documentation for these APIs can be found in src/node.h in the Node.js source tree. In addition to the APIs exposed by Node.js, some required concepts are provided by the V8 embedder API.

                          Because using Node.js as an embedded library is different from writing code that is executed by Node.js, breaking changes do not follow typical Node.js deprecation policy and may occur on each semver-major release without prior warning.

                          -

                          Example embedding application#

                          +

                          Example embedding application#

                          The following sections will provide an overview over how to use these APIs to create an application from scratch that will perform the equivalent of node -e <code>, i.e. that will take a piece of JavaScript and run it in a Node.js-specific environment.

                          -

                          The full code can be found in the Node.js source tree.

                          -

                          Setting up per-process state#

                          +

                          The full code can be found in the Node.js source tree.

                          +

                          Setting up per-process state#

                          Node.js requires some per-process state management in order to run:

                          • Arguments parsing for Node.js CLI options,
                          • @@ -15232,16 +15844,16 @@ a Node.js-specific environment.

                          The following example shows how these can be set up. Some class names are from the node and v8 C++ namespaces, respectively.

                          -
                          int main(int argc, char** argv) {
                          -  argv = uv_setup_args(argc, argv);
                          -  std::vector<std::string> args(argv, argv + argc);
                          -  std::vector<std::string> exec_args;
                          -  std::vector<std::string> errors;
                          +
                          int main(int argc, char** argv) {
                          +  argv = uv_setup_args(argc, argv);
                          +  std::vector<std::string> args(argv, argv + argc);
                          +  std::vector<std::string> exec_args;
                          +  std::vector<std::string> errors;
                             // Parse Node.js CLI options, and print any errors that have occurred while
                             // trying to parse them.
                          -  int exit_code = node::InitializeNodeWithArgs(&args, &exec_args, &errors);
                          -  for (const std::string& error : errors)
                          -    fprintf(stderr, "%s: %s\n", args[0].c_str(), error.c_str());
                          +  int exit_code = node::InitializeNodeWithArgs(&args, &exec_args, &errors);
                          +  for (const std::string& error : errors)
                          +    fprintf(stderr, "%s: %s\n", args[0].c_str(), error.c_str());
                             if (exit_code != 0) {
                               return exit_code;
                             }
                          @@ -15250,19 +15862,19 @@ the node and v8 C++ namespaces, respectively.

                          // to create a v8::Platform instance that Node.js can use when creating // Worker threads. When no `MultiIsolatePlatform` instance is present, // Worker threads are disabled. - std::unique_ptr<MultiIsolatePlatform> platform = - MultiIsolatePlatform::Create(4); - V8::InitializePlatform(platform.get()); - V8::Initialize(); + std::unique_ptr<MultiIsolatePlatform> platform = + MultiIsolatePlatform::Create(4); + V8::InitializePlatform(platform.get()); + V8::Initialize(); // See below for the contents of this function. - int ret = RunNodeInstance(platform.get(), args, exec_args); + int ret = RunNodeInstance(platform.get(), args, exec_args); - V8::Dispose(); - V8::ShutdownPlatform(); + V8::Dispose(); + V8::ShutdownPlatform(); return ret; }
                          -

                          Per-instance state#

                          +

                          Per-instance state#

                          Node.js has a concept of a “Node.js instance”, that is commonly being referred to as node::Environment. Each node::Environment is associated with:

                            @@ -15286,164 +15898,168 @@ for tasks scheduled by the v8::Isolate.

                            The node::NewIsolate() helper function creates a v8::Isolate, sets it up with some Node.js-specific hooks (e.g. the Node.js error handler), and registers it with the platform automatically.

                            -
                            int RunNodeInstance(MultiIsolatePlatform* platform,
                            -                    const std::vector<std::string>& args,
                            -                    const std::vector<std::string>& exec_args) {
                            -  int exit_code = 0;
                            -  // Set up a libuv event loop.
                            -  uv_loop_t loop;
                            -  int ret = uv_loop_init(&loop);
                            -  if (ret != 0) {
                            -    fprintf(stderr, "%s: Failed to initialize loop: %s\n",
                            -            args[0].c_str(),
                            -            uv_err_name(ret));
                            -    return 1;
                            +
                            int RunNodeInstance(MultiIsolatePlatform* platform,
                            +                    const std::vector<std::string>& args,
                            +                    const std::vector<std::string>& exec_args) {
                            +  int exit_code = 0;
                            +  // Set up a libuv event loop.
                            +  uv_loop_t loop;
                            +  int ret = uv_loop_init(&loop);
                            +  if (ret != 0) {
                            +    fprintf(stderr, "%s: Failed to initialize loop: %s\n",
                            +            args[0].c_str(),
                            +            uv_err_name(ret));
                            +    return 1;
                               }
                             
                               std::shared_ptr<ArrayBufferAllocator> allocator =
                            -      ArrayBufferAllocator::Create();
                            +      ArrayBufferAllocator::Create();
                             
                            -  Isolate* isolate = NewIsolate(allocator, &loop, platform);
                            -  if (isolate == nullptr) {
                            -    fprintf(stderr, "%s: Failed to initialize V8 Isolate\n", args[0].c_str());
                            -    return 1;
                            +  Isolate* isolate = NewIsolate(allocator, &loop, platform);
                            +  if (isolate == nullptr) {
                            +    fprintf(stderr, "%s: Failed to initialize V8 Isolate\n", args[0].c_str());
                            +    return 1;
                               }
                             
                               {
                            -    Locker locker(isolate);
                            -    Isolate::Scope isolate_scope(isolate);
                            +    Locker locker(isolate);
                            +    Isolate::Scope isolate_scope(isolate);
                             
                            -    // Create a node::IsolateData instance that will later be released using
                            -    // node::FreeIsolateData().
                            -    std::unique_ptr<IsolateData, decltype(&node::FreeIsolateData)> isolate_data(
                            +    // Create a node::IsolateData instance that will later be released using
                            +    // node::FreeIsolateData().
                            +    std::unique_ptr<IsolateData, decltype(&node::FreeIsolateData)> isolate_data(
                                     node::CreateIsolateData(isolate, &loop, platform, allocator.get()),
                            -        node::FreeIsolateData);
                            -
                            -    // Set up a new v8::Context.
                            -    HandleScope handle_scope(isolate);
                            -    Local<Context> context = node::NewContext(isolate);
                            -    if (context.IsEmpty()) {
                            -      fprintf(stderr, "%s: Failed to initialize V8 Context\n", args[0].c_str());
                            -      return 1;
                            +        node::FreeIsolateData);
                            +
                            +    // Set up a new v8::Context.
                            +    HandleScope handle_scope(isolate);
                            +    Local<Context> context = node::NewContext(isolate);
                            +    if (context.IsEmpty()) {
                            +      fprintf(stderr, "%s: Failed to initialize V8 Context\n", args[0].c_str());
                            +      return 1;
                                 }
                             
                            -    // The v8::Context needs to be entered when node::CreateEnvironment() and
                            -    // node::LoadEnvironment() are being called.
                            -    Context::Scope context_scope(context);
                            +    // The v8::Context needs to be entered when node::CreateEnvironment() and
                            +    // node::LoadEnvironment() are being called.
                            +    Context::Scope context_scope(context);
                             
                            -    // Create a node::Environment instance that will later be released using
                            -    // node::FreeEnvironment().
                            -    std::unique_ptr<Environment, decltype(&node::FreeEnvironment)> env(
                            +    // Create a node::Environment instance that will later be released using
                            +    // node::FreeEnvironment().
                            +    std::unique_ptr<Environment, decltype(&node::FreeEnvironment)> env(
                                     node::CreateEnvironment(isolate_data.get(), context, args, exec_args),
                            -        node::FreeEnvironment);
                            -
                            -    // Set up the Node.js instance for execution, and run code inside of it.
                            -    // There is also a variant that takes a callback and provides it with
                            -    // the `require` and `process` objects, so that it can manually compile
                            -    // and run scripts as needed.
                            -    // The `require` function inside this script does *not* access the file
                            -    // system, and can only load built-in Node.js modules.
                            -    // `module.createRequire()` is being used to create one that is able to
                            -    // load files from the disk, and uses the standard CommonJS file loader
                            -    // instead of the internal-only `require` function.
                            -    MaybeLocal<Value> loadenv_ret = node::LoadEnvironment(
                            -        env.get(),
                            -        "const publicRequire ="
                            -        "  require('module').createRequire(process.cwd() + '/');"
                            -        "globalThis.require = publicRequire;"
                            -        "require('vm').runInThisContext(process.argv[1]);");
                            -
                            -    if (loadenv_ret.IsEmpty())  // There has been a JS exception.
                            -      return 1;
                            +        node::FreeEnvironment);
                            +
                            +    // Set up the Node.js instance for execution, and run code inside of it.
                            +    // There is also a variant that takes a callback and provides it with
                            +    // the `require` and `process` objects, so that it can manually compile
                            +    // and run scripts as needed.
                            +    // The `require` function inside this script does *not* access the file
                            +    // system, and can only load built-in Node.js modules.
                            +    // `module.createRequire()` is being used to create one that is able to
                            +    // load files from the disk, and uses the standard CommonJS file loader
                            +    // instead of the internal-only `require` function.
                            +    MaybeLocal<Value> loadenv_ret = node::LoadEnvironment(
                            +        env.get(),
                            +        "const publicRequire ="
                            +        "  require('module').createRequire(process.cwd() + '/');"
                            +        "globalThis.require = publicRequire;"
                            +        "require('vm').runInThisContext(process.argv[1]);");
                            +
                            +    if (loadenv_ret.IsEmpty())  // There has been a JS exception.
                            +      return 1;
                             
                                 {
                            -      // SealHandleScope protects against handle leaks from callbacks.
                            -      SealHandleScope seal(isolate);
                            -      bool more;
                            -      do {
                            -        uv_run(&loop, UV_RUN_DEFAULT);
                            -
                            -        // V8 tasks on background threads may end up scheduling new tasks in the
                            -        // foreground, which in turn can keep the event loop going. For example,
                            -        // WebAssembly.compile() may do so.
                            -        platform->DrainTasks(isolate);
                            -
                            -        // If there are new tasks, continue.
                            -        more = uv_loop_alive(&loop);
                            -        if (more) continue;
                            -
                            -        // node::EmitBeforeExit() is used to emit the 'beforeExit' event on
                            -        // the `process` object.
                            -        node::EmitBeforeExit(env.get());
                            -
                            -        // 'beforeExit' can also schedule new work that keeps the event loop
                            -        // running.
                            -        more = uv_loop_alive(&loop);
                            -      } while (more == true);
                            +      // SealHandleScope protects against handle leaks from callbacks.
                            +      SealHandleScope seal(isolate);
                            +      bool more;
                            +      do {
                            +        uv_run(&loop, UV_RUN_DEFAULT);
                            +
                            +        // V8 tasks on background threads may end up scheduling new tasks in the
                            +        // foreground, which in turn can keep the event loop going. For example,
                            +        // WebAssembly.compile() may do so.
                            +        platform->DrainTasks(isolate);
                            +
                            +        // If there are new tasks, continue.
                            +        more = uv_loop_alive(&loop);
                            +        if (more) continue;
                            +
                            +        // node::EmitProcessBeforeExit() is used to emit the 'beforeExit' event
                            +        // on the `process` object.
                            +        if (node::EmitProcessBeforeExit(env.get()).IsNothing())
                            +          break;
                            +
                            +        // 'beforeExit' can also schedule new work that keeps the event loop
                            +        // running.
                            +        more = uv_loop_alive(&loop);
                            +      } while (more == true);
                                 }
                             
                            -    // node::EmitExit() returns the current exit code.
                            -    exit_code = node::EmitExit(env.get());
                            +    // node::EmitProcessExit() returns the current exit code.
                            +    exit_code = node::EmitProcessExit(env.get()).FromMaybe(1);
                             
                            -    // node::Stop() can be used to explicitly stop the event loop and keep
                            -    // further JavaScript from running. It can be called from any thread,
                            -    // and will act like worker.terminate() if called from another thread.
                            -    node::Stop(env.get());
                            +    // node::Stop() can be used to explicitly stop the event loop and keep
                            +    // further JavaScript from running. It can be called from any thread,
                            +    // and will act like worker.terminate() if called from another thread.
                            +    node::Stop(env.get());
                               }
                             
                            -  // Unregister the Isolate with the platform and add a listener that is called
                            -  // when the Platform is done cleaning up any state it had associated with
                            -  // the Isolate.
                            -  bool platform_finished = false;
                            -  platform->AddIsolateFinishedCallback(isolate, [](void* data) {
                            -    *static_cast<bool*>(data) = true;
                            +  // Unregister the Isolate with the platform and add a listener that is called
                            +  // when the Platform is done cleaning up any state it had associated with
                            +  // the Isolate.
                            +  bool platform_finished = false;
                            +  platform->AddIsolateFinishedCallback(isolate, [](void* data) {
                            +    *static_cast<bool*>(data) = true;
                               }, &platform_finished);
                            -  platform->UnregisterIsolate(isolate);
                            -  isolate->Dispose();
                            +  platform->UnregisterIsolate(isolate);
                            +  isolate->Dispose();
                             
                            -  // Wait until the platform has cleaned up all relevant resources.
                            -  while (!platform_finished)
                            -    uv_run(&loop, UV_RUN_ONCE);
                            -  int err = uv_loop_close(&loop);
                            -  assert(err == 0);
                            +  // Wait until the platform has cleaned up all relevant resources.
                            +  while (!platform_finished)
                            +    uv_run(&loop, UV_RUN_ONCE);
                            +  int err = uv_loop_close(&loop);
                            +  assert(err == 0);
                             
                            -  return exit_code;
                            -}
                            -

                            Child process#

                            + return exit_code; +}
                          +
                          +

                          Child process#

                          Stability: 2 - Stable

                          -

                          Source Code: lib/child_process.js

                          -

                          The child_process module provides the ability to spawn child processes in +

                          Source Code: lib/child_process.js

                          +

                          The child_process module provides the ability to spawn subprocesses in a manner that is similar, but not identical, to popen(3). This capability is primarily provided by the child_process.spawn() function:

                          const { spawn } = require('child_process');
                          -const ls = spawn('ls', ['-lh', '/usr']);
                          +const ls = spawn('ls', ['-lh', '/usr']);
                           
                          -ls.stdout.on('data', (data) => {
                          -  console.log(`stdout: ${data}`);
                          +ls.stdout.on('data', (data) => {
                          +  console.log(`stdout: ${data}`);
                           });
                           
                          -ls.stderr.on('data', (data) => {
                          -  console.error(`stderr: ${data}`);
                          +ls.stderr.on('data', (data) => {
                          +  console.error(`stderr: ${data}`);
                           });
                           
                          -ls.on('close', (code) => {
                          -  console.log(`child process exited with code ${code}`);
                          +ls.on('close', (code) => {
                          +  console.log(`child process exited with code ${code}`);
                           });

                          By default, pipes for stdin, stdout, and stderr are established between -the parent Node.js process and the spawned child. These pipes have -limited (and platform-specific) capacity. If the child process writes to -stdout in excess of that limit without the output being captured, the child -process will block waiting for the pipe buffer to accept more data. This is +the parent Node.js process and the spawned subprocess. These pipes have +limited (and platform-specific) capacity. If the subprocess writes to +stdout in excess of that limit without the output being captured, the +subprocess blocks waiting for the pipe buffer to accept more data. This is identical to the behavior of pipes in the shell. Use the { stdio: 'ignore' } option if the output will not be consumed.

                          -

                          The command lookup will be performed using options.env.PATH environment -variable if passed in options object, otherwise process.env.PATH will be -used. To account for the fact that Windows environment variables are -case-insensitive Node.js will lexicographically sort all env keys and choose -the first one case-insensitively matching PATH to perform command lookup. -This may lead to issues on Windows when passing objects to env option that -have multiple variants of PATH variable.

                          +

                          The command lookup is performed using the options.env.PATH environment +variable if it is in the options object. Otherwise, process.env.PATH is +used.

                          +

                          On Windows, environment variables are case-insensitive. Node.js +lexicographically sorts the env keys and uses the first one that +case-insensitively matches. Only first (in lexicographic order) entry will be +passed to the subprocess. This might lead to issues on Windows when passing +objects to the env option that have multiple variants of the same key, such as +PATH and Path.

                          The child_process.spawn() method spawns the child process asynchronously, without blocking the Node.js event loop. The child_process.spawnSync() function provides equivalent functionality in a synchronous manner that blocks @@ -15471,18 +16087,18 @@ sending messages between parent and child. synchronous counterparts may be more convenient. In many cases, however, the synchronous methods can have significant impact on performance due to stalling the event loop while spawned processes complete.

                          -

                          Asynchronous process creation#

                          +

                          Asynchronous process creation#

                          The child_process.spawn(), child_process.fork(), child_process.exec(), and child_process.execFile() methods all follow the idiomatic asynchronous programming pattern typical of other Node.js APIs.

                          -

                          Each of the methods returns a ChildProcess instance. These objects +

                          Each of the methods returns a ChildProcess instance. These objects implement the Node.js EventEmitter API, allowing the parent process to register listener functions that are called when certain events occur during the life cycle of the child process.

                          The child_process.exec() and child_process.execFile() methods additionally allow for an optional callback function to be specified that is invoked when the child process terminates.

                          -

                          Spawning .bat and .cmd files on Windows#

                          +

                          Spawning .bat and .cmd files on Windows#

                          The importance of the distinction between child_process.exec() and child_process.execFile() can vary based on platform. On Unix-type operating systems (Unix, Linux, macOS) child_process.execFile() can be @@ -15497,40 +16113,44 @@ When running on Windows, .bat and .cmd files can be in spaces it needs to be quoted.

                          // On Windows Only...
                           const { spawn } = require('child_process');
                          -const bat = spawn('cmd.exe', ['/c', 'my.bat']);
                          +const bat = spawn('cmd.exe', ['/c', 'my.bat']);
                           
                          -bat.stdout.on('data', (data) => {
                          -  console.log(data.toString());
                          +bat.stdout.on('data', (data) => {
                          +  console.log(data.toString());
                           });
                           
                          -bat.stderr.on('data', (data) => {
                          -  console.error(data.toString());
                          +bat.stderr.on('data', (data) => {
                          +  console.error(data.toString());
                           });
                           
                          -bat.on('exit', (code) => {
                          -  console.log(`Child exited with code ${code}`);
                          +bat.on('exit', (code) => {
                          +  console.log(`Child exited with code ${code}`);
                           });
                          // OR...
                           const { exec, spawn } = require('child_process');
                          -exec('my.bat', (err, stdout, stderr) => {
                          +exec('my.bat', (err, stdout, stderr) => {
                             if (err) {
                          -    console.error(err);
                          +    console.error(err);
                               return;
                             }
                          -  console.log(stdout);
                          +  console.log(stdout);
                           });
                           
                           // Script with spaces in the filename:
                          -const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
                          +const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
                           // or:
                          -exec('"my script.cmd" a b', (err, stdout, stderr) => {
                          +exec('"my script.cmd" a b', (err, stdout, stderr) => {
                             // ...
                           });
                          -

                          child_process.exec(command[, options][, callback])#

                          +

                          child_process.exec(command[, options][, callback])#

                          Class: ChildProcess#

                          @@ -16280,7 +17013,7 @@ arbitrary command execution.

                          use the child_process.spawn(), child_process.exec(), child_process.execFile(), or child_process.fork() methods to create instances of ChildProcess.

                          -

                          Event: 'close'#

                          +

                          Event: 'close'#

                          @@ -16288,24 +17021,26 @@ instances of ChildProcess.

                        • code <number> The exit code if the child exited on its own.
                        • signal <string> The signal by which the child process was terminated.
                        -

                        The 'close' event is emitted when the stdio streams of a child process have -been closed. This is distinct from the 'exit' event, since multiple -processes might share the same stdio streams.

                        +

                        The 'close' event is emitted after a process has ended and the stdio +streams of a child process have been closed. This is distinct from the +'exit' event, since multiple processes might share the same stdio +streams. The 'close' event will always emit after 'exit' was +already emitted, or 'error' if the child failed to spawn.

                        const { spawn } = require('child_process');
                        -const ls = spawn('ls', ['-lh', '/usr']);
                        +const ls = spawn('ls', ['-lh', '/usr']);
                         
                        -ls.stdout.on('data', (data) => {
                        -  console.log(`stdout: ${data}`);
                        +ls.stdout.on('data', (data) => {
                        +  console.log(`stdout: ${data}`);
                         });
                         
                        -ls.on('close', (code) => {
                        -  console.log(`child process close all stdio with code ${code}`);
                        +ls.on('close', (code) => {
                        +  console.log(`child process close all stdio with code ${code}`);
                         });
                         
                        -ls.on('exit', (code) => {
                        -  console.log(`child process exited with code ${code}`);
                        +ls.on('exit', (code) => {
                        +  console.log(`child process exited with code ${code}`);
                         });
                        -

                        Event: 'disconnect'#

                        +

                        Event: 'disconnect'#

                        @@ -16314,7 +17049,7 @@ ls.on('exit', (process.disconnect() in child process. After disconnecting it is no longer possible to send or receive messages, and the subprocess.connected property is false.

                        -

                        Event: 'error'#

                        +

                        Event: 'error'#

                        @@ -16328,7 +17063,7 @@ property is false.

                        listening to both the 'exit' and 'error' events, guard against accidentally invoking handler functions multiple times.

                        See also subprocess.kill() and subprocess.send().

                        -

                        Event: 'exit'#

                        +

                        Event: 'exit'#

                        @@ -16347,7 +17082,7 @@ processes will not terminate immediately due to receipt of those signals. Rather, Node.js will perform a sequence of cleanup actions and then will re-raise the handled signal.

                        See waitpid(2).

                        -

                        Event: 'message'#

                        +

                        Event: 'message'#

                        @@ -16364,16 +17099,49 @@ message might not be the same as what is originally sent.

                        child process, the message argument can contain data that JSON is not able to represent. See Advanced serialization for more details.

                        -

                        subprocess.channel#

                        +

                        Event: 'spawn'#

                        +

                        The 'spawn' event is emitted once the child process has spawned successfully. +If the child process does not spawn successfully, the 'spawn' event is not +emitted and the 'error' event is emitted instead.

                        +

                        If emitted, the 'spawn' event comes before all other events and before any +data is received via stdout or stderr.

                        +

                        The 'spawn' event will fire regardless of whether an error occurs within +the spawned process. For example, if bash some-command spawns successfully, +the 'spawn' event will fire, though bash may fail to spawn some-command. +This caveat also applies when using { shell: true }.

                        +

                        subprocess.channel#

                        +
                        • <Object> A pipe representing the IPC channel to the child process.

                        The subprocess.channel property is a reference to the child's IPC channel. If no IPC channel currently exists, this property is undefined.

                        -

                        subprocess.connected#

                        +
                        subprocess.channel.ref()#
                        + +

                        This method makes the IPC channel keep the event loop of the parent process +running if .unref() has been called before.

                        +
                        subprocess.channel.unref()#
                        + +

                        This method makes the IPC channel not keep the event loop of the parent process +running, and lets it finish even while the channel is open.

                        +

                        subprocess.connected#

                        @@ -16383,7 +17151,7 @@ no IPC channel currently exists, this property is undefined.

                        The subprocess.connected property indicates whether it is still possible to send and receive messages from a child process. When subprocess.connected is false, it is no longer possible to send or receive messages.

                        -

                        subprocess.disconnect()#

                        +

                        subprocess.disconnect()#

                        @@ -16398,13 +17166,13 @@ calling subprocess.disconnect().

                        When the child process is a Node.js instance (e.g. spawned using child_process.fork()), the process.disconnect() method can be invoked within the child process to close the IPC channel as well.

                        -

                        subprocess.exitCode#

                        +

                        subprocess.exitCode#

                        The subprocess.exitCode property indicates the exit code of the child process. If the child process is still running, the field will be null.

                        -

                        subprocess.kill([signal])#

                        +

                        subprocess.kill([signal])#

                        @@ -16417,16 +17185,16 @@ argument is given, the process will be sent the 'SIGTERM' signal. S signal(7) for a list of available signals. This function returns true if kill(2) succeeds, and false otherwise.

                        const { spawn } = require('child_process');
                        -const grep = spawn('grep', ['ssh']);
                        +const grep = spawn('grep', ['ssh']);
                         
                        -grep.on('close', (code, signal) => {
                        -  console.log(
                        +grep.on('close', (code, signal) => {
                        +  console.log(
                             `child process terminated due to receipt of signal ${signal}`);
                         });
                         
                         // Send SIGHUP to process.
                        -grep.kill('SIGHUP');
                        -

                        The ChildProcess object may emit an 'error' event if the signal +grep.kill('SIGHUP'); +

                        The ChildProcess object may emit an 'error' event if the signal cannot be delivered. Sending a signal to a child process that has already exited is not an error but may have unforeseen consequences. Specifically, if the process identifier (PID) has been reassigned to another process, the signal will @@ -16434,28 +17202,32 @@ be delivered to that process instead which can have unexpected results.

                        While the function is called kill, the signal delivered to the child process may not actually terminate the process.

                        See kill(2) for reference.

                        +

                        On Windows, where POSIX signals do not exist, the signal argument will be +ignored, and the process will be killed forcefully and abruptly (similar to +'SIGKILL'). +See Signal Events for more details.

                        On Linux, child processes of child processes will not be terminated when attempting to kill their parent. This is likely to happen when running a new process in a shell or with the use of the shell option of ChildProcess:

                        'use strict';
                         const { spawn } = require('child_process');
                         
                        -const subprocess = spawn(
                        +const subprocess = spawn(
                           'sh',
                           [
                             '-c',
                             `node -e "setInterval(() => {
                               console.log(process.pid, 'is alive')
                        -    }, 500);"`
                        +    }, 500);"`,
                           ], {
                             stdio: ['inherit', 'inherit', 'inherit']
                           }
                         );
                         
                         setTimeout(() => {
                        -  subprocess.kill(); // Does not terminate the Node.js process in the shell.
                        +  subprocess.kill(); // Does not terminate the Node.js process in the shell.
                         }, 2000);
                        -

                        subprocess.killed#

                        +

                        subprocess.killed#

                        @@ -16466,20 +17238,22 @@ send a signal to the child process.

                        The subprocess.killed property indicates whether the child process successfully received a signal from subprocess.kill(). The killed property does not indicate that the child process has been terminated.

                        -

                        subprocess.pid#

                        +

                        subprocess.pid#

                        -

                        Returns the process identifier (PID) of the child process.

                        +

                        Returns the process identifier (PID) of the child process. If the child process +fails to spawn due to errors, then the value is undefined and error is +emitted.

                        const { spawn } = require('child_process');
                        -const grep = spawn('grep', ['ssh']);
                        +const grep = spawn('grep', ['ssh']);
                         
                        -console.log(`Spawned child pid: ${grep.pid}`);
                        -grep.stdin.end();
                        -

                        subprocess.ref()#

                        +console.log(`Spawned child pid: ${grep.pid}`); +grep.stdin.end();
                        +

                        subprocess.ref()#

                        @@ -16488,14 +17262,14 @@ restore the removed reference count for the child process, forcing the parent to wait for the child to exit before exiting itself.

                        const { spawn } = require('child_process');
                         
                        -const subprocess = spawn(process.argv[0], ['child_program.js'], {
                        +const subprocess = spawn(process.argv[0], ['child_program.js'], {
                           detached: true,
                           stdio: 'ignore'
                         });
                         
                        -subprocess.unref();
                        -subprocess.ref();
                        -

                        subprocess.send(message[, sendHandle[, options]][, callback])#

                        +subprocess.unref(); +subprocess.ref();
                        +

                        subprocess.send(message[, sendHandle[, options]][, callback])#

                        -

                        Stability: 1 - Experimental

                        -

                        Enable experimental Source Map v3 support for stack traces.

                        -

                        Currently, overriding Error.prepareStackTrace is ignored when the ---enable-source-maps flag is set.

                        -

                        --experimental-import-meta-resolve#

                        +

                        Enable Source Map v3 support for stack traces.

                        +

                        When using a transpiler, such as TypeScript, strack traces thrown by an +application reference the transpiled code, not the original source position. +--enable-source-maps enables caching of Source Maps and makes a best +effort to report stack traces relative to the original source file.

                        +

                        Overriding Error.prepareStackTrace prevents --enable-source-maps from +modifiying the stack trace.

                        +

                        --experimental-abortcontroller#

                        + +

                        Enable experimental AbortController and AbortSignal support.

                        +

                        --experimental-import-meta-resolve#

                        Enable experimental import.meta.resolve() support.

                        -

                        --experimental-json-modules#

                        +

                        --experimental-json-modules#

                        Enable experimental JSON support for the ES Module loader.

                        -

                        --experimental-loader=module#

                        +

                        --experimental-loader=module#

                        -

                        Specify the module of a custom experimental ECMAScript Module loader. +

                        Specify the module of a custom experimental ECMAScript Module loader. module may be either a path to a file, or an ECMAScript Module name.

                        -

                        --experimental-modules#

                        +

                        --experimental-modules#

                        Enable latest experimental modules features (deprecated).

                        -

                        --experimental-policy#

                        +

                        --experimental-policy#

                        Use the specified file as a security policy.

                        -

                        --experimental-repl-await#

                        +

                        --experimental-repl-await#

                        Enable experimental top-level await keyword support in REPL.

                        -

                        --experimental-specifier-resolution=mode#

                        +

                        --experimental-specifier-resolution=mode#

                        Sets the resolution algorithm for resolving ES module specifiers. Valid options are explicit and node.

                        The default is explicit, which requires providing the full path to a -module. The node mode will enable support for optional file extensions and +module. The node mode enables support for optional file extensions and the ability to import a directory that has an index file.

                        -

                        Please see customizing ESM specifier resolution for example usage.

                        -

                        --experimental-vm-modules#

                        +

                        See customizing ESM specifier resolution for example usage.

                        +

                        --experimental-vm-modules#

                        Enable experimental ES Module support in the vm module.

                        -

                        --experimental-wasi-unstable-preview1#

                        +

                        --experimental-wasi-unstable-preview1#

                        Enable experimental WebAssembly System Interface (WASI) support.

                        -

                        --experimental-wasm-modules#

                        +

                        --experimental-wasm-modules#

                        -

                        --force-context-aware#

                        +

                        Enable experimental WebAssembly module support.

                        +

                        --force-context-aware#

                        Disable loading native addons that are not context-aware.

                        -

                        Enable experimental WebAssembly module support.

                        -

                        --force-fips#

                        +

                        --force-fips#

                        Force FIPS-compliant crypto on startup. (Cannot be disabled from script code.) (Same requirements as --enable-fips.)

                        -

                        --frozen-intrinsics#

                        +

                        --frozen-intrinsics#

                        @@ -17751,35 +18573,73 @@ currently provided that global.Array is indeed the default intrinsi reference. Code may break under this flag.

                        --require runs prior to freezing intrinsics in order to allow polyfills to be added.

                        -

                        --heapsnapshot-signal=signal#

                        +

                        --heapsnapshot-near-heap-limit=max_count#

                        + +

                        Stability: 1 - Experimental

                        +

                        Writes a V8 heap snapshot to disk when the V8 heap usage is approaching the +heap limit. count should be a non-negative integer (in which case +Node.js will write no more than max_count snapshots to disk).

                        +

                        When generating snapshots, garbage collection may be triggered and bring +the heap usage down, therefore multiple snapshots may be written to disk +before the Node.js instance finally runs out of memory. These heap snapshots +can be compared to determine what objects are being allocated during the +time consecutive snapshots are taken. It's not guaranteed that Node.js will +write exactly max_count snapshots to disk, but it will try +its best to generate at least one and up to max_count snapshots before the +Node.js instance runs out of memory when max_count is greater than 0.

                        +

                        Generating V8 snapshots takes time and memory (both memory managed by the +V8 heap and native memory outside the V8 heap). The bigger the heap is, +the more resources it needs. Node.js will adjust the V8 heap to accommondate +the additional V8 heap memory overhead, and try its best to avoid using up +all the memory avialable to the process. When the process uses +more memory than the system deems appropriate, the process may be terminated +abruptly by the system, depending on the system configuration.

                        +
                        $ node --max-old-space-size=100 --heapsnapshot-near-heap-limit=3 index.js
                        +Wrote snapshot to Heap.20200430.100036.49580.0.001.heapsnapshot
                        +Wrote snapshot to Heap.20200430.100037.49580.0.002.heapsnapshot
                        +Wrote snapshot to Heap.20200430.100038.49580.0.003.heapsnapshot
                        +
                        +<--- Last few GCs --->
                        +
                        +[49580:0x110000000]     4826 ms: Mark-sweep 130.6 (147.8) -> 130.5 (147.8) MB, 27.4 / 0.0 ms  (average mu = 0.126, current mu = 0.034) allocation failure scavenge might not succeed
                        +[49580:0x110000000]     4845 ms: Mark-sweep 130.6 (147.8) -> 130.6 (147.8) MB, 18.8 / 0.0 ms  (average mu = 0.088, current mu = 0.031) allocation failure scavenge might not succeed
                        +
                        +
                        +<--- JS stacktrace --->
                        +
                        +FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
                        +....
                        +

                        --heapsnapshot-signal=signal#

                        Enables a signal handler that causes the Node.js process to write a heap dump when the specified signal is received. signal must be a valid signal name. Disabled by default.

                        -
                        $ node --heapsnapshot-signal=SIGUSR2 index.js &
                        -$ ps aux
                        +
                        $ node --heapsnapshot-signal=SIGUSR2 index.js &
                        +$ ps aux
                         USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
                         node         1  5.5  6.1 787252 247004 ?       Ssl  16:43   0:02 node --heapsnapshot-signal=SIGUSR2 index.js
                        -$ kill -USR2 1
                        -$ ls
                        +$ kill -USR2 1
                        +$ ls
                         Heap.20190718.133405.15554.0.001.heapsnapshot
                        -

                        --heap-prof#

                        +

                        --heap-prof#

                        Stability: 1 - Experimental

                        Starts the V8 heap profiler on start up, and writes the heap profile to disk before exit.

                        -

                        If --heap-prof-dir is not specified, the generated profile will be placed +

                        If --heap-prof-dir is not specified, the generated profile is placed in the current working directory.

                        -

                        If --heap-prof-name is not specified, the generated profile will be +

                        If --heap-prof-name is not specified, the generated profile is named Heap.${yyyymmdd}.${hhmmss}.${pid}.${tid}.${seq}.heapprofile.

                        -
                        $ node --heap-prof index.js
                        -$ ls *.heapprofile
                        +
                        $ node --heap-prof index.js
                        +$ ls *.heapprofile
                         Heap.20190409.202950.15293.0.001.heapprofile
                        -

                        --heap-prof-dir#

                        +

                        --heap-prof-dir#

                        @@ -17787,70 +18647,39 @@ Heap.20190409.202950.15293.0.001.heapprofile

                        Specify the directory where the heap profiles generated by --heap-prof will be placed.

                        The default value is controlled by the ---diagnostic-dir command line option.

                        -

                        --heap-prof-interval#

                        +--diagnostic-dir command-line option.

                        +

                        --heap-prof-interval#

                        Stability: 1 - Experimental

                        Specify the average sampling interval in bytes for the heap profiles generated by --heap-prof. The default is 512 * 1024 bytes.

                        -

                        --heap-prof-name#

                        +

                        --heap-prof-name#

                        Stability: 1 - Experimental

                        Specify the file name of the heap profile generated by --heap-prof.

                        -

                        --http-parser=library#

                        - -

                        Chooses an HTTP parser library. Available values are:

                        - -

                        The default is llhttp, unless otherwise specified when building Node.js.

                        -

                        The legacy HTTP parser is deprecated and will emit a deprecation warning.

                        -

                        This flag exists to aid in experimentation with the internal implementation of -the Node.js http parser. -This flag is likely to become a no-op and removed at some point in the future.

                        -

                        --http-server-default-timeout=milliseconds#

                        - -

                        Overrides the default value of http, https and http2 server socket -timeout. Setting the value to 0 disables server socket timeout. Unless -provided, http server sockets timeout after 120s (2 minutes). Programmatic -setting of the timeout takes precedence over the value set through this -flag.

                        -

                        --icu-data-dir=file#

                        +

                        --icu-data-dir=file#

                        Specify ICU data load path. (Overrides NODE_ICU_DATA.)

                        -

                        --input-type=type#

                        +

                        --input-type=type#

                        This configures Node.js to interpret string input as CommonJS or as an ES module. String input is input via --eval, --print, or STDIN.

                        Valid values are "commonjs" and "module". The default is "commonjs".

                        -

                        --inspect-brk[=[host:]port]#

                        +

                        --inspect-brk[=[host:]port]#

                        Activate inspector on host:port and break at start of user script. Default host:port is 127.0.0.1:9229.

                        -

                        --inspect-port=[host:]port#

                        +

                        --inspect-port=[host:]port#

                        @@ -17859,7 +18688,7 @@ Useful when activating the inspector by sending the SIGUSR1 signal.

                        Default host is 127.0.0.1.

                        See the security warning below regarding the host parameter usage.

                        -

                        --inspect[=[host:]port]#

                        +

                        --inspect[=[host:]port]#

                        @@ -17868,7 +18697,7 @@ parameter usage.

                        and profile Node.js instances. The tools attach to Node.js instances via a tcp port and communicate using the Chrome DevTools Protocol.

                        -

                        Warning: binding inspector to a public IP:port combination is insecure#

                        +
                        Warning: binding inspector to a public IP:port combination is insecure#

                        Binding the inspector to a public IP (including 0.0.0.0) with an open port is insecure, as it allows external hosts to connect to the inspector and perform a remote code execution attack.

                        @@ -17880,19 +18709,19 @@ a remote code execution

                        More specifically, --inspect=0.0.0.0 is insecure if the port (9229 by default) is not firewall-protected.

                        See the debugging security implications section for more information.

                        -

                        --inspect-publish-uid=stderr,http#

                        +

                        --inspect-publish-uid=stderr,http#

                        Specify ways of the inspector web socket url exposure.

                        By default inspector websocket url is available in stderr and under /json/list endpoint on http://host:port/json/list.

                        -

                        --insecure-http-parser#

                        +

                        --insecure-http-parser#

                        Use an insecure HTTP parser that accepts invalid HTTP headers. This may allow interoperability with non-conformant HTTP implementations. It may also allow request smuggling and other HTTP attacks that rely on invalid headers being accepted. Avoid using this option.

                        -

                        --jitless#

                        +

                        --jitless#

                        @@ -17901,51 +18730,65 @@ required on some platforms for security reasons. It can also reduce attack surface on other platforms, but the performance impact may be severe.

                        This flag is inherited from V8 and is subject to change upstream. It may disappear in a non-semver-major release.

                        -

                        --max-http-header-size=size#

                        +

                        --max-http-header-size=size#

                        -

                        Specify the maximum size, in bytes, of HTTP headers. Defaults to 8KB.

                        -

                        --napi-modules#

                        +

                        Specify the maximum size, in bytes, of HTTP headers. Defaults to 16KB.

                        +

                        --napi-modules#

                        This option is a no-op. It is kept for compatibility.

                        -

                        --no-deprecation#

                        +

                        --no-deprecation#

                        Silence deprecation warnings.

                        -

                        --no-force-async-hooks-checks#

                        +

                        --no-force-async-hooks-checks#

                        Disables runtime checks for async_hooks. These will still be enabled dynamically when async_hooks is enabled.

                        -

                        --no-warnings#

                        +

                        --no-warnings#

                        Silence all process warnings (including deprecations).

                        -

                        --openssl-config=file#

                        +

                        --node-memory-debug#

                        + +

                        Enable extra debug checks for memory leaks in Node.js internals. This is +usually only useful for developers debugging Node.js itself.

                        +

                        --openssl-config=file#

                        Load an OpenSSL configuration file on startup. Among other uses, this can be used to enable FIPS-compliant crypto if Node.js is built with ./configure --openssl-fips.

                        -

                        --pending-deprecation#

                        +

                        --pending-deprecation#

                        Emit pending deprecation warnings.

                        Pending deprecations are generally identical to a runtime deprecation with the notable exception that they are turned off by default and will not be emitted -unless either the --pending-deprecation command line flag, or the +unless either the --pending-deprecation command-line flag, or the NODE_PENDING_DEPRECATION=1 environment variable, is set. Pending deprecations are used to provide a kind of selective "early warning" mechanism that developers may leverage to detect deprecated API usage.

                        -

                        --policy-integrity=sri#

                        +

                        --policy-integrity=sri#

                        @@ -17953,7 +18796,7 @@ developers may leverage to detect deprecated API usage.

                        Instructs Node.js to error prior to running any code if the policy does not have the specified integrity. It expects a Subresource Integrity string as a parameter.

                        -

                        --preserve-symlinks#

                        +

                        --preserve-symlinks#

                        @@ -17977,7 +18820,7 @@ be thrown if moduleA attempts to require moduleB as a └── moduleA ├── index.js └── package.json
                        -

                        The --preserve-symlinks command line flag instructs Node.js to use the +

                        The --preserve-symlinks command-line flag instructs Node.js to use the symlink path for modules as opposed to the real path, allowing symbolically linked peer dependencies to be found.

                        Note, however, that using --preserve-symlinks can have other side effects. @@ -17988,7 +18831,7 @@ times, causing an exception to be thrown).

                        The --preserve-symlinks flag does not apply to the main module, which allows node --preserve-symlinks node_module/.bin/<foo> to work. To apply the same behavior for the main module, also use --preserve-symlinks-main.

                        -

                        --preserve-symlinks-main#

                        +

                        --preserve-symlinks-main#

                        @@ -17997,22 +18840,22 @@ caching the main module (require.main).

                        This flag exists so that the main module can be opted-in to the same behavior that --preserve-symlinks gives to all other imports; they are separate flags, however, for backward compatibility with older Node.js versions.

                        -

                        --preserve-symlinks-main does not imply --preserve-symlinks; it -is expected that --preserve-symlinks-main will be used in addition to +

                        --preserve-symlinks-main does not imply --preserve-symlinks; use +--preserve-symlinks-main in addition to --preserve-symlinks when it is not desirable to follow symlinks before resolving relative paths.

                        See --preserve-symlinks for more information.

                        -

                        --prof#

                        +

                        --prof#

                        Generate V8 profiler output.

                        -

                        --prof-process#

                        +

                        --prof-process#

                        Process V8 profiler output generated using the V8 option --prof.

                        -

                        --redirect-warnings=file#

                        +

                        --redirect-warnings=file#

                        @@ -18022,53 +18865,53 @@ If an error occurs while attempting to write the warning to the file, the warning will be written to stderr instead.

                        The file name may be an absolute path. If it is not, the default directory it will be written to is controlled by the ---diagnostic-dir command line option.

                        -

                        --report-compact#

                        +--diagnostic-dir command-line option.

                        +

                        --report-compact#

                        Write reports in a compact format, single-line JSON, more easily consumable by log processing systems than the default multi-line format designed for human consumption.

                        -

                        --report-dir=directory, report-directory=directory#

                        +

                        --report-dir=directory, report-directory=directory#

                        Location at which the report will be generated.

                        -

                        --report-filename=filename#

                        +

                        --report-filename=filename#

                        Name of the file to which the report will be written.

                        -

                        --report-on-fatalerror#

                        +

                        --report-on-fatalerror#

                      -

                      --v8-options#

                      +

                      --v8-options#

                      -

                      Print V8 command line options.

                      -

                      --v8-pool-size=num#

                      +

                      Print V8 command-line options.

                      +

                      --v8-pool-size=num#

                      @@ -18312,13 +19181,13 @@ will be ignored and will not be reported. on the number of online processors.

                      If the value provided is larger than V8's maximum, then the largest value will be chosen.

                      -

                      --zero-fill-buffers#

                      +

                      --zero-fill-buffers#

                      Automatically zero-fills all newly allocated Buffer and SlowBuffer instances.

                      -

                      -c, --check#

                      +

                      -c, --check#

                    If encoding is specified, a string is returned; otherwise a Buffer is returned.

                    -

                    ecdh.getPublicKey([encoding][, format])#

                    +

                    ecdh.getPublicKey([encoding][, format])#

                    @@ -19996,7 +20909,7 @@ returned.

                    'uncompressed' format.

                    If encoding is specified, a string is returned; otherwise a Buffer is returned.

                    -

                    ecdh.setPrivateKey(privateKey[, encoding])#

                    +

                    ecdh.setPrivateKey(privateKey[, encoding])#

                    @@ -20011,7 +20924,7 @@ to be a string; otherwise privateKey is expected to be a # +

                    ecdh.setPublicKey(publicKey[, encoding])#

                    @@ -20031,26 +20944,26 @@ attempts to generate the public point/key associated with the private key being set.

                    Example (obtaining a shared secret):

                    const crypto = require('crypto');
                    -const alice = crypto.createECDH('secp256k1');
                    -const bob = crypto.createECDH('secp256k1');
                    +const alice = crypto.createECDH('secp256k1');
                    +const bob = crypto.createECDH('secp256k1');
                     
                     // This is a shortcut way of specifying one of Alice's previous private
                     // keys. It would be unwise to use such a predictable private key in a real
                     // application.
                    -alice.setPrivateKey(
                    -  crypto.createHash('sha256').update('alice', 'utf8').digest()
                    +alice.setPrivateKey(
                    +  crypto.createHash('sha256').update('alice', 'utf8').digest()
                     );
                     
                     // Bob uses a newly generated cryptographically strong
                     // pseudorandom key pair
                    -bob.generateKeys();
                    +bob.generateKeys();
                     
                    -const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
                    -const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
                    +const aliceSecret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
                    +const bobSecret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
                     
                     // aliceSecret and bobSecret should be the same shared secret value
                    -console.log(aliceSecret === bobSecret);
                    -

                    Class: Hash#

                    +console.log(aliceSecret === bobSecret);
                    +

                    Class: Hash#

                    @@ -20069,39 +20982,39 @@ computed hash.
                  • objects are not to be created directly using the new keyword.

                    Example: Using Hash objects as streams:

                    const crypto = require('crypto');
                    -const hash = crypto.createHash('sha256');
                    +const hash = crypto.createHash('sha256');
                     
                    -hash.on('readable', () => {
                    +hash.on('readable', () => {
                       // Only one element is going to be produced by the
                       // hash stream.
                    -  const data = hash.read();
                    +  const data = hash.read();
                       if (data) {
                    -    console.log(data.toString('hex'));
                    +    console.log(data.toString('hex'));
                         // Prints:
                         //   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
                       }
                     });
                     
                    -hash.write('some data to hash');
                    -hash.end();
                    +hash.write('some data to hash'); +hash.end();

                    Example: Using Hash and piped streams:

                    const crypto = require('crypto');
                     const fs = require('fs');
                    -const hash = crypto.createHash('sha256');
                    +const hash = crypto.createHash('sha256');
                     
                    -const input = fs.createReadStream('test.js');
                    -input.pipe(hash).pipe(process.stdout);
                    +const input = fs.createReadStream('test.js'); +input.pipe(hash).setEncoding('hex').pipe(process.stdout);

                    Example: Using the hash.update() and hash.digest() methods:

                    const crypto = require('crypto');
                    -const hash = crypto.createHash('sha256');
                    +const hash = crypto.createHash('sha256');
                     
                    -hash.update('some data to hash');
                    -console.log(hash.digest('hex'));
                    +hash.update('some data to hash');
                    +console.log(hash.digest('hex'));
                     // Prints:
                     //   6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
                    -

                    hash.copy([options])#

                    +

                    hash.copy([options])#

                    • options <Object> stream.transform options
                    • @@ -20116,19 +21029,19 @@ specify the desired output length in bytes.

                      its hash.digest() method has been called.

                      // Calculate a rolling hash.
                       const crypto = require('crypto');
                      -const hash = crypto.createHash('sha256');
                      +const hash = crypto.createHash('sha256');
                       
                      -hash.update('one');
                      -console.log(hash.copy().digest('hex'));
                      +hash.update('one');
                      +console.log(hash.copy().digest('hex'));
                       
                      -hash.update('two');
                      -console.log(hash.copy().digest('hex'));
                      +hash.update('two');
                      +console.log(hash.copy().digest('hex'));
                       
                      -hash.update('three');
                      -console.log(hash.copy().digest('hex'));
                      +hash.update('three');
                      +console.log(hash.copy().digest('hex'));
                       
                       // Etc.
                      -

                      hash.digest([encoding])#

                      +

                      hash.digest([encoding])#

                      @@ -20142,7 +21055,7 @@ If encoding is provided a string will be returned; otherwise a Buffer is returned.

                      The Hash object can not be used again after hash.digest() method has been called. Multiple calls will cause an error to be thrown.

                      -

                      hash.update(data[, inputEncoding])#

                      +

                      hash.update(data[, inputEncoding])#

                      • algorithm <string> | <null> | <undefined>
                      • @@ -21949,7 +22895,7 @@ size, crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN (default) sets it t maximum permissible value.

                      -

                      crypto.timingSafeEqual(a, b)#

                      +

                      crypto.timingSafeEqual(a, b)#

                      @@ -21964,13 +22910,24 @@ would allow an attacker to guess one of the values. This is suitable for comparing HMAC digests or secret values like authentication cookies or capability urls.

                      a and b must both be Buffers, TypedArrays, or DataViews, and they -must have the same length.

                      +must have the same byte length.

                      +

                      If at least one of a and b is a TypedArray with more than one byte per +entry, such as Uint16Array, the result will be computed using the platform +byte order.

                      Use of crypto.timingSafeEqual does not guarantee that the surrounding code is timing-safe. Care should be taken to ensure that the surrounding code does not introduce timing vulnerabilities.

                      -

                      crypto.verify(algorithm, data, key, signature)#

                      +

                      crypto.verify(algorithm, data, key, signature)#

                      • algorithm <string> | <null> | <undefined>
                      • @@ -21988,7 +22945,7 @@ additional properties can be passed:

                        • dsaEncoding <string> For DSA and ECDSA, this option specifies the -format of the generated signature. It can be one of the following:

                          +format of the signature. It can be one of the following:

                          • 'der' (default): DER-encoded ASN.1 signature structure encoding (r, s).
                          • 'ieee-p1363': Signature format r || s as proposed in IEEE-P1363.
                          • @@ -22014,8 +22971,8 @@ maximum permissible value.

                            The signature argument is the previously calculated signature for the data.

                            Because public keys can be derived from private keys, a private key or a public key may be passed for key.

                            -

                            Notes#

                            -

                            Legacy Streams API (prior to Node.js 0.10)#

                            +

                            Notes#

                            +

                            Legacy streams API (prior to Node.js 0.10)#

                            The Crypto module was added to Node.js before there was the concept of a unified Stream API, and before there were Buffer objects for handling binary data. As such, the many of the crypto defined classes have methods not @@ -22024,7 +22981,7 @@ API (e.g. update(), final(), or digest()) and returned 'latin1' encoded strings by default rather than Buffers. This default was changed after Node.js v0.8 to use Buffer objects by default instead.

                            -

                            Recent ECDH changes#

                            +

                            Recent ECDH changes#

                            Usage of ECDH with non-dynamically generated key pairs has been simplified. Now, ecdh.setPrivateKey() can be called with a preselected private key and the associated public point (key) will be computed and stored in the object. @@ -22036,7 +22993,7 @@ API is not useful. Either a previously stored private key should be set, which automatically generates the associated public key, or ecdh.generateKeys() should be called. The main drawback of using ecdh.setPublicKey() is that it can be used to put the ECDH key pair into an inconsistent state.

                            -

                            Support for weak or compromised algorithms#

                            +

                            Support for weak or compromised algorithms#

                            The crypto module still supports some algorithms which are already compromised and are not currently recommended for use. The API also allows the use of ciphers and hashes with a small key size that are too weak for safe @@ -22054,7 +23011,7 @@ at least 2048 bits and that of the curve of ECDSA and ECDH at least smaller than 2048 bits and are not recommended.

                          See the reference for other recommendations and details.

                          -

                          CCM mode#

                          +

                          CCM mode#

                          CCM is one of the supported AEAD algorithms. Applications which use this mode must adhere to certain restrictions when using the cipher API:

                            @@ -22087,44 +23044,44 @@ authentication tag.
                            const crypto = require('crypto');
                             
                             const key = 'keykeykeykeykeykeykeykey';
                            -const nonce = crypto.randomBytes(12);
                            +const nonce = crypto.randomBytes(12);
                             
                            -const aad = Buffer.from('0123456789', 'hex');
                            +const aad = Buffer.from('0123456789', 'hex');
                             
                            -const cipher = crypto.createCipheriv('aes-192-ccm', key, nonce, {
                            +const cipher = crypto.createCipheriv('aes-192-ccm', key, nonce, {
                               authTagLength: 16
                             });
                             const plaintext = 'Hello world';
                            -cipher.setAAD(aad, {
                            -  plaintextLength: Buffer.byteLength(plaintext)
                            +cipher.setAAD(aad, {
                            +  plaintextLength: Buffer.byteLength(plaintext)
                             });
                            -const ciphertext = cipher.update(plaintext, 'utf8');
                            -cipher.final();
                            -const tag = cipher.getAuthTag();
                            +const ciphertext = cipher.update(plaintext, 'utf8');
                            +cipher.final();
                            +const tag = cipher.getAuthTag();
                             
                             // Now transmit { ciphertext, nonce, tag }.
                             
                            -const decipher = crypto.createDecipheriv('aes-192-ccm', key, nonce, {
                            +const decipher = crypto.createDecipheriv('aes-192-ccm', key, nonce, {
                               authTagLength: 16
                             });
                            -decipher.setAuthTag(tag);
                            -decipher.setAAD(aad, {
                            -  plaintextLength: ciphertext.length
                            +decipher.setAuthTag(tag);
                            +decipher.setAAD(aad, {
                            +  plaintextLength: ciphertext.length
                             });
                            -const receivedPlaintext = decipher.update(ciphertext, null, 'utf8');
                            +const receivedPlaintext = decipher.update(ciphertext, null, 'utf8');
                             
                             try {
                            -  decipher.final();
                            +  decipher.final();
                             } catch (err) {
                            -  console.error('Authentication failed!');
                            +  console.error('Authentication failed!');
                               return;
                             }
                             
                            -console.log(receivedPlaintext);
                            -

                            Crypto constants#

                            +console.log(receivedPlaintext); +

                            Crypto constants#

                            The following constants exported by crypto.constants apply to various uses of the crypto, tls, and https modules and are generally specific to OpenSSL.

                            -

                            OpenSSL options#

                            +

                            OpenSSL options#

                            @@ -22303,7 +23260,7 @@ the crypto, tls, and https modules and ar
                            ConstantInstructs OpenSSL to disable version rollback attack detection.
                            -

                            OpenSSL engine constants#

                            +

                            OpenSSL engine constants#

                            @@ -22354,7 +23311,7 @@ the crypto, tls, and https modules and ar
                            Constant
                            -

                            Other OpenSSL constants#

                            +

                            Other OpenSSL constants#

                            See the list of SSL OP Flags for details.

                            @@ -22433,7 +23390,7 @@ the crypto, tls, and https modules and ar
                            -

                            Node.js crypto constants#

                            +

                            Node.js crypto constants#

                            @@ -22448,23 +23405,26 @@ the crypto, tls, and https modules and ar -
                            ConstantSpecifies the active default cipher list used by the current Node.js process.
                            -

                            Debugger#

                            +
                            + +

                            Debugger#

                            Stability: 2 - Stable

                            -

                            Node.js includes an out-of-process debugging utility accessible via a -V8 Inspector and built-in debugging client. To use it, start Node.js -with the inspect argument followed by the path to the script to debug; a -prompt will be displayed indicating successful launch of the debugger:

                            -
                            $ node inspect myscript.js
                            -< Debugger listening on ws://127.0.0.1:9229/80e7a814-7cd3-49fb-921a-2e02228cd5ba
                            +

                            Node.js includes a command-line debugging utility. To use it, start Node.js +with the inspect argument followed by the path to the script to debug.

                            +
                            $ node inspect myscript.js
                            +< Debugger listening on ws://127.0.0.1:9229/621111f9-ffcb-4e82-b718-48a145fa5db8
                             < For help, see: https://nodejs.org/en/docs/inspector
                            +<
                             < Debugger attached.
                            -Break on start in myscript.js:1
                            -> 1 (function (exports, require, module, __filename, __dirname) { global.x = 5;
                            -  2 setTimeout(() => {
                            -  3   console.log('world');
                            +<
                            + ok
                            +Break on start in myscript.js:2
                            +  1 // myscript.js
                            +> 2 global.x = 5;
                            +  3 setTimeout(() => {
                            +  4   debugger;
                             debug>

                            The Node.js debugger client is not a full-featured debugger, but simple step and inspection are possible.

                            @@ -22472,56 +23432,63 @@ inspection are possible.

                            enable a breakpoint at that position in the code:

                            // myscript.js
                            -global.x = 5;
                            +global.x = 5;
                             setTimeout(() => {
                               debugger;
                            -  console.log('world');
                            +  console.log('world');
                             }, 1000);
                            -console.log('hello');
                            +console.log('hello');

                            Once the debugger is run, a breakpoint will occur at line 3:

                            -
                            $ node inspect myscript.js
                            -< Debugger listening on ws://127.0.0.1:9229/80e7a814-7cd3-49fb-921a-2e02228cd5ba
                            +
                            $ node inspect myscript.js
                            +< Debugger listening on ws://127.0.0.1:9229/621111f9-ffcb-4e82-b718-48a145fa5db8
                             < For help, see: https://nodejs.org/en/docs/inspector
                            +<
                             < Debugger attached.
                            -Break on start in myscript.js:1
                            -> 1 (function (exports, require, module, __filename, __dirname) { global.x = 5;
                            -  2 setTimeout(() => {
                            -  3   debugger;
                            -debug> cont
                            +<
                            + ok
                            +Break on start in myscript.js:2
                            +  1 // myscript.js
                            +> 2 global.x = 5;
                            +  3 setTimeout(() => {
                            +  4   debugger;
                            +debug> cont
                             < hello
                            -break in myscript.js:3
                            -  1 (function (exports, require, module, __filename, __dirname) { global.x = 5;
                            -  2 setTimeout(() => {
                            -> 3   debugger;
                            -  4   console.log('world');
                            -  5 }, 1000);
                            -debug> next
                            +<
                             break in myscript.js:4
                            -  2 setTimeout(() => {
                            -  3   debugger;
                            -> 4   console.log('world');
                            -  5 }, 1000);
                            -  6 console.log('hello');
                            -debug> repl
                            -Press Ctrl + C to leave debug repl
                            -> x
                            +  2 global.x = 5;
                            +  3 setTimeout(() => {
                            +> 4   debugger;
                            +  5   console.log('world');
                            +  6 }, 1000);
                            +debug> next
                            +break in myscript.js:5
                            +  3 setTimeout(() => {
                            +  4   debugger;
                            +> 5   console.log('world');
                            +  6 }, 1000);
                            +  7 console.log('hello');
                            +debug> repl
                            +Press Ctrl+C to leave debug repl
                            +> x
                             5
                            -> 2 + 2
                            +> 2 + 2
                             4
                            -debug> next
                            +debug> next
                             < world
                            -break in myscript.js:5
                            -  3   debugger;
                            -  4   console.log('world');
                            -> 5 }, 1000);
                            -  6 console.log('hello');
                            -  7
                            -debug> .exit
                            +< +break in myscript.js:6 + 4 debugger; + 5 console.log('world'); +> 6 }, 1000); + 7 console.log('hello'); + 8 +debug> .exit +$

                            The repl command allows code to be evaluated remotely. The next command steps to the next line. Type help to see what other commands are available.

                            Pressing enter without typing a command will repeat the previous debugger command.

                            -

                            Watchers#

                            +

                            Watchers#

                            It is possible to watch expression and variable values while debugging. On every breakpoint, each expression from the watchers list will be evaluated in the current context and displayed immediately before the breakpoint's @@ -22529,8 +23496,8 @@ source code listing.

                            To begin watching an expression, type watch('my_expression'). The command watchers will print the active watchers. To remove a watcher, type unwatch('my_expression').

                            -

                            Command reference#

                            -

                            Stepping#

                            +

                            Command reference#

                            +

                            Stepping#

                            • cont, c: Continue execution
                            • next, n: Step next
                            • @@ -22538,38 +23505,76 @@ source code listing.

                            • out, o: Step out
                            • pause: Pause running code (like pause button in Developer Tools)
                            -

                            Breakpoints#

                            +

                            Breakpoints#

                            • setBreakpoint(), sb(): Set breakpoint on current line
                            • setBreakpoint(line), sb(line): Set breakpoint on specific line
                            • setBreakpoint('fn()'), sb(...): Set breakpoint on a first statement in -functions body
                            • +function's body
                            • setBreakpoint('script.js', 1), sb(...): Set breakpoint on first line of script.js
                            • +
                            • setBreakpoint('script.js', 1, 'num < 4'), sb(...): Set conditional +breakpoint on first line of script.js that only breaks when num < 4 +evaluates to true
                            • clearBreakpoint('script.js', 1), cb(...): Clear breakpoint in script.js on line 1

                            It is also possible to set a breakpoint in a file (module) that is not loaded yet:

                            -
                            $ node inspect main.js
                            -< Debugger listening on ws://127.0.0.1:9229/4e3db158-9791-4274-8909-914f7facf3bd
                            +
                            $ node inspect main.js
                            +< Debugger listening on ws://127.0.0.1:9229/48a5b28a-550c-471b-b5e1-d13dd7165df9
                             < For help, see: https://nodejs.org/en/docs/inspector
                            +<
                             < Debugger attached.
                            +<
                            + ok
                             Break on start in main.js:1
                            -> 1 (function (exports, require, module, __filename, __dirname) { const mod = require('./mod.js');
                            +> 1 const mod = require('./mod.js');
                               2 mod.hello();
                               3 mod.hello();
                            -debug> setBreakpoint('mod.js', 22)
                            +debug> setBreakpoint('mod.js', 22)
                             Warning: script 'mod.js' was not loaded yet.
                            -debug> c
                            +debug> c
                             break in mod.js:22
                              20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
                              21
                            ->22 exports.hello = function() {
                            +>22 exports.hello = function() {
                              23   return 'hello from module';
                              24 };
                             debug>
                            -

                            Information#

                            +

                            It is also possible to set a conditional breakpoint that only breaks when a +given expression evaluates to true:

                            +
                            $ node inspect main.js
                            +< Debugger listening on ws://127.0.0.1:9229/ce24daa8-3816-44d4-b8ab-8273c8a66d35
                            +< For help, see: https://nodejs.org/en/docs/inspector
                            +< Debugger attached.
                            +Break on start in main.js:7
                            +  5 }
                            +  6
                            +> 7 addOne(10);
                            +  8 addOne(-1);
                            +  9
                            +debug> setBreakpoint('main.js', 4, 'num < 0')
                            +  1 'use strict';
                            +  2
                            +  3 function addOne(num) {
                            +> 4   return num + 1;
                            +  5 }
                            +  6
                            +  7 addOne(10);
                            +  8 addOne(-1);
                            +  9
                            +debug> cont
                            +break in main.js:4
                            +  2
                            +  3 function addOne(num) {
                            +> 4   return num + 1;
                            +  5 }
                            +  6
                            +debug> exec('num')
                            +-1
                            +debug>
                            +

                            Information#

                            • backtrace, bt: Print backtrace of current execution frame
                            • list(5): List scripts source code with 5 line context (5 lines before and @@ -22581,19 +23586,19 @@ breakpoint)
                            • repl: Open debugger's repl for evaluation in debugging script's context
                            • exec expr: Execute an expression in debugging script's context
                            -

                            Execution control#

                            +

                            Execution control#

                            • run: Run script (automatically runs on debugger's start)
                            • restart: Restart script
                            • kill: Kill script
                            -

                            Various#

                            +

                            Various#

                            • scripts: List all loaded scripts
                            • version: Display V8's version
                            -

                            Advanced usage#

                            -

                            V8 inspector integration for Node.js#

                            +

                            Advanced usage#

                            +

                            V8 inspector integration for Node.js#

                            V8 Inspector integration allows attaching Chrome DevTools to Node.js instances for debugging and profiling. It uses the Chrome DevTools Protocol.

                            @@ -22602,7 +23607,7 @@ Node.js application. It is also possible to supply a custom port with that flag, e.g. --inspect=9222 will accept DevTools connections on port 9222.

                            To break on the first line of the application code, pass the --inspect-brk flag instead of --inspect.

                            -
                            $ node --inspect index.js
                            +
                            $ node --inspect index.js
                             Debugger listening on ws://127.0.0.1:9229/dc9010dd-f8b8-4ac5-a510-c1a114ec7d29
                             For help, see: https://nodejs.org/en/docs/inspector

                            (In the example above, the UUID dc9010dd-f8b8-4ac5-a510-c1a114ec7d29 @@ -22611,17 +23616,18 @@ debugging sessions.)

                            If the Chrome browser is older than 66.0.3345.0, use inspector.html instead of js_app.html in the above URL.

                            Chrome DevTools doesn't support debugging worker threads yet. -ndb can be used to debug them.

                            -

                            Deprecated APIs#

                            +ndb can be used to debug them.

                            +
                            +

                            Deprecated APIs#

                            -

                            Node.js may deprecate APIs for any of the following reasons:

                            +

                            Node.js APIs might be deprecated for any of the following reasons:

                            • Use of the API is unsafe.
                            • An improved alternative API is available.
                            • Breaking changes to the API are expected in a future major release.
                            -

                            Node.js utilizes three kinds of Deprecations:

                            +

                            Node.js uses three kinds of Deprecations:

                            • Documentation-only
                            • Runtime
                            • @@ -22641,29 +23647,29 @@ be printed to stderr the first time the deprecated API is used. Whe cause an error to be thrown.

                              An End-of-Life deprecation is used when functionality is or will soon be removed from Node.js.

                              -

                              Revoking deprecations#

                              -

                              Occasionally, the deprecation of an API may be reversed. In such situations, +

                              Revoking deprecations#

                              +

                              Occasionally, the deprecation of an API might be reversed. In such situations, this document will be updated with information relevant to the decision. However, the deprecation identifier will not be modified.

                              -

                              List of deprecated APIs#

                              -

                              -

                              DEP0001: http.OutgoingMessage.prototype.flush#

                              +

                              List of deprecated APIs#

                              +

                              DEP0001: http.OutgoingMessage.prototype.flush#

                              -

                              Type: Runtime

                              -

                              The OutgoingMessage.prototype.flush() method is deprecated. Use +

                              Type: End-of-Life

                              +

                              OutgoingMessage.prototype.flush() has been removed. Use OutgoingMessage.prototype.flushHeaders() instead.

                              -

                              -

                              DEP0002: require('_linklist')#

                              +

                              DEP0002: require('_linklist')#

                              -

                              Type: Runtime

                              -

                              The _writableState.buffer property is deprecated. Use the -_writableState.getBuffer() method instead.

                              -

                              -

                              DEP0004: CryptoStream.prototype.readyState#

                              +

                              Type: End-of-Life

                              +

                              The _writableState.buffer has been removed. Use _writableState.getBuffer() +instead.

                              +

                              DEP0004: CryptoStream.prototype.readyState#

                              Type: End-of-Life

                              The CryptoStream.prototype.readyState property was removed.

                              -

                              -

                              DEP0005: Buffer() constructor#

                              +

                              DEP0005: Buffer() constructor#

                              +
                            +

                            Diagnostics Channel#

                            + +

                            Stability: 1 - Experimental

                            +

                            Source Code: lib/diagnostics_channel.js

                            +

                            The diagnostics_channel module provides an API to create named channels +to report arbitrary message data for diagnostics purposes.

                            +

                            It can be accessed using:

                            +
                            const diagnostics_channel = require('diagnostics_channel');
                            +

                            It is intended that a module writer wanting to report diagnostics messages +will create one or many top-level channels to report messages through. +Channels may also be acquired at runtime but it is not encouraged +due to the additional overhead of doing so. Channels may be exported for +convenience, but as long as the name is known it can be acquired anywhere.

                            +

                            If you intend for your module to produce diagnostics data for others to +consume it is recommended that you include documentation of what named +channels are used along with the shape of the message data. Channel names +should generally include the module name to avoid collisions with data from +other modules.

                            +

                            Public API#

                            +

                            Overview#

                            +

                            Following is a simple overview of the public API.

                            +
                            const diagnostics_channel = require('diagnostics_channel');
                            +
                            +// Get a reusable channel object
                            +const channel = diagnostics_channel.channel('my-channel');
                            +
                            +// Subscribe to the channel
                            +channel.subscribe((message, name) => {
                            +  // Received data
                            +});
                            +
                            +// Check if the channel has an active subscriber
                            +if (channel.hasSubscribers) {
                            +  // Publish data to the channel
                            +  channel.publish({
                            +    some: 'data'
                            +  });
                            +}
                            +
                            diagnostics_channel.hasSubscribers(name)#
                            + +

                            Check if there are active subscribers to the named channel. This is helpful if +the message you want to send might be expensive to prepare.

                            +

                            This API is optional but helpful when trying to publish messages from very +performance-sensitive code.

                            +
                            const diagnostics_channel = require('diagnostics_channel');
                            +
                            +if (diagnostics_channel.hasSubscribers('my-channel')) {
                            +  // There are subscribers, prepare and publish message
                            +}
                            +
                            diagnostics_channel.channel(name)#
                            + +

                            This is the primary entry-point for anyone wanting to interact with a named +channel. It produces a channel object which is optimized to reduce overhead at +publish time as much as possible.

                            +
                            const diagnostics_channel = require('diagnostics_channel');
                            +
                            +const channel = diagnostics_channel.channel('my-channel');
                            +

                            Class: Channel#

                            +

                            The class Channel represents an individual named channel within the data +pipeline. It is use to track subscribers and to publish messages when there +are subscribers present. It exists as a separate object to avoid channel +lookups at publish time, enabling very fast publish speeds and allowing +for heavy use while incurring very minimal cost. Channels are created with +diagnostics_channel.channel(name), constructing a channel directly +with new Channel(name) is not supported.

                            +
                            channel.hasSubscribers#
                            +
                              +
                            • Returns: <boolean> If there are active subscribers
                            • +
                            +

                            Check if there are active subscribers to this channel. This is helpful if +the message you want to send might be expensive to prepare.

                            +

                            This API is optional but helpful when trying to publish messages from very +performance-sensitive code.

                            +
                            const diagnostics_channel = require('diagnostics_channel');
                            +
                            +const channel = diagnostics_channel.channel('my-channel');
                            +
                            +if (channel.hasSubscribers) {
                            +  // There are subscribers, prepare and publish message
                            +}
                            +
                            channel.publish(message)#
                            +
                              +
                            • message <any> The message to send to the channel subscribers
                            • +
                            +

                            Publish a message to any subscribers to the channel. This will trigger +message handlers synchronously so they will execute within the same context.

                            +
                            const diagnostics_channel = require('diagnostics_channel');
                            +
                            +const channel = diagnostics_channel.channel('my-channel');
                            +
                            +channel.publish({
                            +  some: 'message'
                            +});
                            +
                            channel.subscribe(onMessage)#
                            + +

                            Register a message handler to subscribe to this channel. This message handler +will be run synchronously whenever a message is published to the channel. Any +errors thrown in the message handler will trigger an 'uncaughtException'.

                            +
                            const diagnostics_channel = require('diagnostics_channel');
                            +
                            +const channel = diagnostics_channel.channel('my-channel');
                            +
                            +channel.subscribe((message, name) => {
                            +  // Received data
                            +});
                            +
                            channel.unsubscribe(onMessage)#
                            +
                              +
                            • onMessage <Function> The previous subscribed handler to remove
                            • +
                            +

                            Remove a message handler previously registered to this channel with +channel.subscribe(onMessage).

                            +
                            const diagnostics_channel = require('diagnostics_channel');
                            +
                            +const channel = diagnostics_channel.channel('my-channel');
                            +
                            +function onMessage(message, name) {
                            +  // Received data
                            +}
                            +
                            +channel.subscribe(onMessage);
                            +
                            +channel.unsubscribe(onMessage);
                            +
                            +

                            DNS#

                            Stability: 2 - Stable

                            -

                            Source Code: lib/dns.js

                            +

                            Source Code: lib/dns.js

                            The dns module enables name resolution. For example, use it to look up IP addresses of host names.

                            Although named for the Domain Name System (DNS), it does not always use the @@ -24932,8 +26126,8 @@ communication. To perform name resolution the way other applications on the same system do, use dns.lookup().

                            const dns = require('dns');
                             
                            -dns.lookup('example.org', (err, address, family) => {
                            -  console.log('address: %j family: IPv%s', address, family);
                            +dns.lookup('example.org', (err, address, family) => {
                            +  console.log('address: %j family: IPv%s', address, family);
                             });
                             // address: "93.184.216.34" family: IPv4

                            All other functions in the dns module connect to an actual DNS server to @@ -24943,22 +26137,22 @@ queries. These functions do not use the same set of configuration files used by DNS queries, bypassing other name-resolution facilities.

                            const dns = require('dns');
                             
                            -dns.resolve4('archive.org', (err, addresses) => {
                            +dns.resolve4('archive.org', (err, addresses) => {
                               if (err) throw err;
                             
                            -  console.log(`addresses: ${JSON.stringify(addresses)}`);
                            +  console.log(`addresses: ${JSON.stringify(addresses)}`);
                             
                            -  addresses.forEach((a) => {
                            -    dns.reverse(a, (err, hostnames) => {
                            +  addresses.forEach((a) => {
                            +    dns.reverse(a, (err, hostnames) => {
                                   if (err) {
                                     throw err;
                                   }
                            -      console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);
                            +      console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);
                                 });
                               });
                             });

                            See the Implementation considerations section for more information.

                            -

                            Class: dns.Resolver#

                            +

                            Class: dns.Resolver#

                            @@ -24967,12 +26161,12 @@ dns.resolve4('archive.org', resolver.setServers() does not affect other resolvers:

                            -
                            const { Resolver } = require('dns');
                            -const resolver = new Resolver();
                            -resolver.setServers(['4.4.4.4']);
                            +
                            const { Resolver } = require('dns');
                            +const resolver = new Resolver();
                            +resolver.setServers(['4.4.4.4']);
                             
                             // This request will use the server at 4.4.4.4, independent of global settings.
                            -resolver.resolve4('example.org', (err, addresses) => {
                            +resolver.resolve4('example.org', (err, addresses) => {
                               // ...
                             });

                            The following methods from the dns module are available:

                            @@ -24982,6 +26176,7 @@ resolver.resolve4('example.org', resolver.resolve4()
                          • resolver.resolve6()
                          • resolver.resolveAny()
                          • +
                          • resolver.resolveCaa()
                          • resolver.resolveCname()
                          • resolver.resolveMx()
                          • resolver.resolveNaptr()
                          • @@ -24993,12 +26188,14 @@ resolver.resolve4('example.org', resolver.reverse()
                          • resolver.setServers()
                          -

                          Resolver([options])#

                          +

                          Resolver([options])#

                        • dns.ALL: If dns.V4MAPPED is specified, return resolved IPv6 addresses as well as IPv4 mapped IPv6 addresses.
                        -

                        dns.lookupService(address, port, callback)#

                        +

                        dns.lookupService(address, port, callback)#

                        @@ -25158,13 +26376,13 @@ The port will be coerced to a number. If it is not a legal port, a will be thrown.

                        On an error, err is an Error object, where err.code is the error code.

                        const dns = require('dns');
                        -dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
                        -  console.log(hostname, service);
                        +dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
                        +  console.log(hostname, service);
                           // Prints: localhost ssh
                         });

                        If this method is invoked as its util.promisify()ed version, it returns a Promise for an Object with hostname and service properties.

                        -

                        dns.resolve(hostname[, rrtype], callback)#

                        +

                        dns.resolve(hostname[, rrtype], callback)#

                        @@ -25259,10 +26477,16 @@ records. The type and structure of individual results varies based on rrty -
                        rrtyperecords containsResult typeShorthand method
                        'A'IPv4 addresses (default)<string>dns.resolve4()
                        'AAAA'IPv6 addresses<string>dns.resolve6()
                        'ANY'any records<Object>dns.resolveAny()
                        'CNAME'canonical name records<string>dns.resolveCname()
                        'MX'mail exchange records<Object>dns.resolveMx()
                        'NAPTR'name authority pointer records<Object>dns.resolveNaptr()
                        'NS'name server records<string>dns.resolveNs()
                        'PTR'pointer records<string>dns.resolvePtr()
                        'SOA'start of authority records<Object>dns.resolveSoa()
                        'SRV'service records<Object>dns.resolveSrv()
                        'TXT'text records<string[]>dns.resolveTxt()
                        + + + + + + +
                        rrtyperecords containsResult typeShorthand method
                        'A'IPv4 addresses (default)<string>dns.resolve4()
                        'AAAA'IPv6 addresses<string>dns.resolve6()
                        'ANY'any records<Object>dns.resolveAny()
                        'CAA'CA authorization records<Object>dns.resolveCaa()
                        'CNAME'canonical name records<string>dns.resolveCname()
                        'MX'mail exchange records<Object>dns.resolveMx()
                        'NAPTR'name authority pointer records<Object>dns.resolveNaptr()
                        'NS'name server records<string>dns.resolveNs()
                        'PTR'pointer records<string>dns.resolvePtr()
                        'SOA'start of authority records<Object>dns.resolveSoa()
                        'SRV'service records<Object>dns.resolveSrv()
                        'TXT'text records<string[]>dns.resolveTxt()

                        On error, err is an Error object, where err.code is one of the DNS error codes.

                        -

                        dns.resolve4(hostname[, options], callback)#

                        +

                        dns.resolve4(hostname[, options], callback)#

                        The dns.promises API provides an alternative set of asynchronous DNS methods that return Promise objects rather than using callbacks. The API is accessible via require('dns').promises.

                        -

                        Class: dnsPromises.Resolver#

                        +

                        Class: dnsPromises.Resolver#

                        @@ -25651,18 +26922,18 @@ via require('dns').promises.

                        the servers used for a resolver using resolver.setServers() does not affect other resolvers:

                        -
                        const { Resolver } = require('dns').promises;
                        -const resolver = new Resolver();
                        -resolver.setServers(['4.4.4.4']);
                        +
                        const { Resolver } = require('dns').promises;
                        +const resolver = new Resolver();
                        +resolver.setServers(['4.4.4.4']);
                         
                         // This request will use the server at 4.4.4.4, independent of global settings.
                        -resolver.resolve4('example.org').then((addresses) => {
                        +resolver.resolve4('example.org').then((addresses) => {
                           // ...
                         });
                         
                         // Alternatively, the same code can be written using async-await style.
                        -(async function() {
                        -  const addresses = await resolver.resolve4('example.org');
                        +(async function() {
                        +  const addresses = await resolver.resolve4('example.org');
                         })();

                        The following methods from the dnsPromises API are available:

                        -

                        dnsPromises.getServers()#

                        +

                        resolver.cancel()#

                        + +

                        Cancel all outstanding DNS queries made by this resolver. The corresponding +promises will be rejected with an error with code ECANCELLED.

                        +

                        dnsPromises.getServers()#

                        @@ -25697,9 +26975,9 @@ section if a custom port is used.

                        '4.4.4.4', '2001:4860:4860::8888', '4.4.4.4:1053', - '[2001:4860:4860::8888]:1053' + '[2001:4860:4860::8888]:1053', ]
                        -

                        dnsPromises.lookup(hostname[, options])#

                        +

                        dnsPromises.lookup(hostname[, options])#

                        @@ -25718,8 +26996,9 @@ an array. Otherwise, returns a single address. Default: f IPv6 addresses in the order the DNS resolver returned them. When false, IPv4 addresses are placed before IPv6 addresses. Default: currently false (addresses are reordered) but this is -expected to change in the not too distant future. -New code should use { verbatim: true }. +expected to change in the not too distant future. Default value is +configurable using dns.setDefaultResultOrder() or +--dns-result-order. New code should use { verbatim: true }.
                    @@ -25742,24 +27021,24 @@ take some time to consult the Imple using dnsPromises.lookup().

                    Example usage:

                    const dns = require('dns');
                    -const dnsPromises = dns.promises;
                    +const dnsPromises = dns.promises;
                     const options = {
                       family: 6,
                    -  hints: dns.ADDRCONFIG | dns.V4MAPPED,
                    +  hints: dns.ADDRCONFIG | dns.V4MAPPED,
                     };
                     
                    -dnsPromises.lookup('example.com', options).then((result) => {
                    -  console.log('address: %j family: IPv%s', result.address, result.family);
                    +dnsPromises.lookup('example.com', options).then((result) => {
                    +  console.log('address: %j family: IPv%s', result.address, result.family);
                       // address: "2606:2800:220:1:248:1893:25c8:1946" family: IPv6
                     });
                     
                     // When options.all is true, the result will be an Array.
                    -options.all = true;
                    -dnsPromises.lookup('example.com', options).then((result) => {
                    -  console.log('addresses: %j', result);
                    +options.all = true;
                    +dnsPromises.lookup('example.com', options).then((result) => {
                    +  console.log('addresses: %j', result);
                       // addresses: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}]
                     });
                    -

                    dnsPromises.lookupService(address, port)#

                    +

                    dnsPromises.lookupService(address, port)#

                    @@ -25774,12 +27053,12 @@ The port will be coerced to a number. If it is not a legal port, a will be thrown.

                    On error, the Promise is rejected with an Error object, where err.code is the error code.

                    -
                    const dnsPromises = require('dns').promises;
                    -dnsPromises.lookupService('127.0.0.1', 22).then((result) => {
                    -  console.log(result.hostname, result.service);
                    +
                    const dnsPromises = require('dns').promises;
                    +dnsPromises.lookupService('127.0.0.1', 22).then((result) => {
                    +  console.log(result.hostname, result.service);
                       // Prints: localhost ssh
                     });
                    -

                    dnsPromises.resolve(hostname[, rrtype])#

                    +

                    dnsPromises.resolve(hostname[, rrtype])#

                    @@ -25868,10 +27147,16 @@ based on rrtype:

                    -
                    rrtyperecords containsResult typeShorthand method
                    'A'IPv4 addresses (default)<string>dnsPromises.resolve4()
                    'AAAA'IPv6 addresses<string>dnsPromises.resolve6()
                    'ANY'any records<Object>dnsPromises.resolveAny()
                    'CNAME'canonical name records<string>dnsPromises.resolveCname()
                    'MX'mail exchange records<Object>dnsPromises.resolveMx()
                    'NAPTR'name authority pointer records<Object>dnsPromises.resolveNaptr()
                    'NS'name server records<string>dnsPromises.resolveNs()
                    'PTR'pointer records<string>dnsPromises.resolvePtr()
                    'SOA'start of authority records<Object>dnsPromises.resolveSoa()
                    'SRV'service records<Object>dnsPromises.resolveSrv()
                    'TXT'text records<string[]>dnsPromises.resolveTxt()
                    + + + + + + +
                    rrtyperecords containsResult typeShorthand method
                    'A'IPv4 addresses (default)<string>dnsPromises.resolve4()
                    'AAAA'IPv6 addresses<string>dnsPromises.resolve6()
                    'ANY'any records<Object>dnsPromises.resolveAny()
                    'CAA'CA authorization records<Object>dnsPromises.resolveCaa()
                    'CNAME'canonical name records<string>dnsPromises.resolveCname()
                    'MX'mail exchange records<Object>dnsPromises.resolveMx()
                    'NAPTR'name authority pointer records<Object>dnsPromises.resolveNaptr()
                    'NS'name server records<string>dnsPromises.resolveNs()
                    'PTR'pointer records<string>dnsPromises.resolvePtr()
                    'SOA'start of authority records<Object>dnsPromises.resolveSoa()
                    'SRV'service records<Object>dnsPromises.resolveSrv()
                    'TXT'text records<string[]>dnsPromises.resolveTxt()

                    On error, the Promise is rejected with an Error object, where err.code is one of the DNS error codes.

                    -

                    dnsPromises.resolve4(hostname[, options])#

                    +

                    dnsPromises.resolve4(hostname[, options])#

                    @@ -25889,7 +27174,7 @@ with the TTL expressed in seconds.

                    Uses the DNS protocol to resolve IPv4 addresses (A records) for the hostname. On success, the Promise is resolved with an array of IPv4 addresses (e.g. ['74.125.79.104', '74.125.79.105', '74.125.79.106']).

                    -

                    dnsPromises.resolve6(hostname[, options])#

                    +

                    dnsPromises.resolve6(hostname[, options])#

                    @@ -25907,7 +27192,7 @@ strings, with the TTL expressed in seconds.

                    Uses the DNS protocol to resolve IPv6 addresses (AAAA records) for the hostname. On success, the Promise is resolved with an array of IPv6 addresses.

                    -

                    dnsPromises.resolveAny(hostname)#

                    +

                    dnsPromises.resolveAny(hostname)#

                    @@ -25984,7 +27269,18 @@ present on the object:

                    retry: 900, expire: 1800, minttl: 60 } ]
                    -

                    dnsPromises.resolveCname(hostname)#

                    +

                    dnsPromises.resolveCaa(hostname)#

                    + + +

                    Uses the DNS protocol to resolve CAA records for the hostname. On success, +the Promise is resolved with an array of objects containing available +certification authority authorization records available for the hostname +(e.g. [{critical: 0, iodef: 'mailto:pki@example.com'},{critical: 128, issue: 'pki.example.com'}]).

                    +

                    dnsPromises.resolveCname(hostname)#

                    @@ -25994,7 +27290,7 @@ present on the object:

                    Uses the DNS protocol to resolve CNAME records for the hostname. On success, the Promise is resolved with an array of canonical name records available for the hostname (e.g. ['bar.example.com']).

                    -

                    dnsPromises.resolveMx(hostname)#

                    +

                    dnsPromises.resolveMx(hostname)#

                    @@ -26005,7 +27301,7 @@ the hostname (e.g. ['bar.example.com']).

                    hostname. On success, the Promise is resolved with an array of objects containing both a priority and exchange property (e.g. [{priority: 10, exchange: 'mx.example.com'}, ...]).

                    -

                    dnsPromises.resolveNaptr(hostname)#

                    +

                    dnsPromises.resolveNaptr(hostname)#

                    @@ -26032,7 +27328,7 @@ of objects with the following properties:

                    order: 30, preference: 100 }
                    -

                    dnsPromises.resolveNs(hostname)#

                    +

                    dnsPromises.resolveNs(hostname)#

                    @@ -26043,7 +27339,7 @@ of objects with the following properties:

                    hostname. On success, the Promise is resolved with an array of name server records available for hostname (e.g. ['ns1.example.com', 'ns2.example.com']).

                    -

                    dnsPromises.resolvePtr(hostname)#

                    +

                    dnsPromises.resolvePtr(hostname)#

                    @@ -26053,7 +27349,7 @@ records available for hostname (e.g.

                    Uses the DNS protocol to resolve pointer records (PTR records) for the hostname. On success, the Promise is resolved with an array of strings containing the reply records.

                    -

                    dnsPromises.resolveSoa(hostname)#

                    +

                    dnsPromises.resolveSoa(hostname)#

                    @@ -26082,7 +27378,7 @@ following properties:

                    expire: 604800, minttl: 3600 }
                    -

                    dnsPromises.resolveSrv(hostname)#

                    +

                    dnsPromises.resolveSrv(hostname)#

                    @@ -26105,7 +27401,7 @@ the following properties:

                    port: 21223, name: 'service.example.com' }
                    -

                    dnsPromises.resolveTxt(hostname)#

                    +

                    dnsPromises.resolveTxt(hostname)#

                    @@ -26118,7 +27414,7 @@ of the text records available for hostname (e.g. [ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Each sub-array contains TXT chunks of one record. Depending on the use case, these could be either joined together or treated separately.

                    -

                    dnsPromises.reverse(ip)#

                    +

                    dnsPromises.reverse(ip)#

                    @@ -26129,7 +27425,24 @@ treated separately.

                    array of host names.

                    On error, the Promise is rejected with an Error object, where err.code is one of the DNS error codes.

                    -

                    dnsPromises.setServers(servers)#

                    +

                    dnsPromises.setDefaultResultOrder(order)#

                    + +
                      +
                    • order <string> must be 'ipv4first' or 'verbatim'.
                    • +
                    +

                    Set the default value of verbatim in dns.lookup() and +dnsPromises.lookup(). The value could be:

                    +
                      +
                    • ipv4first: sets default verbatim false.
                    • +
                    • verbatim: sets default verbatim true.
                    • +
                    +

                    The default is ipv4first and dnsPromises.setDefaultResultOrder() have +higher priority than --dns-result-order. When using worker threads, +dnsPromises.setDefaultResultOrder() from the main thread won't affect the +default dns orders in workers.

                    +

                    dnsPromises.setServers(servers)#

                    @@ -26139,11 +27452,11 @@ is one of the DNS error codes.

                    Sets the IP address and port of servers to be used when performing DNS resolution. The servers argument is an array of RFC 5952 formatted addresses. If the port is the IANA default DNS port (53) it can be omitted.

                    -
                    dnsPromises.setServers([
                    +
                    dnsPromises.setServers([
                       '4.4.4.4',
                       '[2001:4860:4860::8888]',
                       '4.4.4.4:1053',
                    -  '[2001:4860:4860::8888]:1053'
                    +  '[2001:4860:4860::8888]:1053',
                     ]);

                    An error will be thrown if an invalid address is provided.

                    The dnsPromises.setServers() method must not be called while a DNS query is in @@ -26154,7 +27467,7 @@ That is, if attempting to resolve with the first server provided results in a NOTFOUND error, the resolve() method will not attempt to resolve with subsequent servers provided. Fallback DNS servers will only be used if the earlier ones time out or result in some other error.

                    -

                    Error codes#

                    +

                    Error codes#

                    Each DNS query can return one of the following error codes:

                    • dns.NODATA: DNS server returned answer with no data.
                    • @@ -26182,13 +27495,13 @@ earlier ones time out or result in some other error.

                    • dns.ADDRGETNETWORKPARAMS: Could not find GetNetworkParams function.
                    • dns.CANCELLED: DNS query cancelled.
                    -

                    Implementation considerations#

                    +

                    Implementation considerations#

                    Although dns.lookup() and the various dns.resolve*()/dns.reverse() functions have the same goal of associating a network name with a network address (or vice versa), their behavior is quite different. These differences can have subtle but significant consequences on the behavior of Node.js programs.

                    -

                    dns.lookup()#

                    +

                    dns.lookup()#

                    Under the hood, dns.lookup() uses the same operating system facilities as most other programs. For instance, dns.lookup() will almost always resolve a given name the same way as the ping command. On most POSIX-like @@ -26206,7 +27519,7 @@ host names. If that is an issue, consider resolving the host name 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.

                    -

                    dns.resolve(), dns.resolve*() and dns.reverse()#

                    +

                    dns.resolve(), dns.resolve*() and dns.reverse()#

                    These functions are implemented quite differently than dns.lookup(). They do not use getaddrinfo(3) and they always perform a DNS query on the network. This network communication is always done asynchronously, and does not @@ -26214,8 +27527,9 @@ use libuv's threadpool.

                    As a result, these functions cannot have the same negative impact on other processing that happens on libuv's threadpool that dns.lookup() can have.

                    They do not use the same set of configuration files than what dns.lookup() -uses. For instance, they do not use the configuration from /etc/hosts.

                    -

                    Domain#

                    +uses. For instance, they do not use the configuration from /etc/hosts.

                    + +

                    Domain#

                    events.defaultMaxListeners#

                    By default, a maximum of 10 listeners can be registered for any single event. This limit can be changed for individual EventEmitter instances using the emitter.setMaxListeners(n) method. To change the default -for all EventEmitter instances, the EventEmitter.defaultMaxListeners -property can be used. If this value is not a positive number, a TypeError -will be thrown.

                    -

                    Take caution when setting the EventEmitter.defaultMaxListeners because the +for all EventEmitter instances, the events.defaultMaxListeners +property can be used. If this value is not a positive number, a RangeError +is thrown.

                    +

                    Take caution when setting the events.defaultMaxListeners because the change affects all EventEmitter instances, including those created before the change is made. However, calling emitter.setMaxListeners(n) still has -precedence over EventEmitter.defaultMaxListeners.

                    +precedence over events.defaultMaxListeners.

                    This is not a hard limit. The EventEmitter instance will allow more listeners to be added but will output a trace warning to stderr indicating that a "possible EventEmitter memory leak" has been detected. For any single EventEmitter, the emitter.getMaxListeners() and emitter.setMaxListeners() methods can be used to temporarily avoid this warning:

                    -
                    emitter.setMaxListeners(emitter.getMaxListeners() + 1);
                    -emitter.once('event', () => {
                    +
                    emitter.setMaxListeners(emitter.getMaxListeners() + 1);
                    +emitter.once('event', () => {
                       // do stuff
                    -  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
                    +  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
                     });
                    -

                    The --trace-warnings command line flag can be used to display the +

                    The --trace-warnings command-line flag can be used to display the stack trace for such warnings.

                    The emitted warning can be inspected with process.on('warning') and will have the additional emitter, type and count properties, referring to the event emitter instance, the event’s name and the number of attached listeners, respectively. Its name property is set to 'MaxListenersExceededWarning'.

                    -

                    EventEmitter.errorMonitor#

                    +

                    events.errorMonitor#

                    This symbol shall be used to install a listener for only monitoring 'error' events. Listeners installed using this symbol are called before the regular @@ -28675,386 +30436,54 @@ events. Listeners installed using this symbol are called before the regular

                    Installing a listener using this symbol does not change the behavior once an 'error' event is emitted, therefore the process will still crash if no regular 'error' listener is installed.

                    -

                    emitter.addListener(eventName, listener)#

                    +

                    events.getEventListeners(emitterOrTarget, eventName)#

                    - -

                    Alias for emitter.on(eventName, listener).

                    -

                    emitter.emit(eventName[, ...args])#

                    - -

                    Synchronously calls each of the listeners registered for the event named -eventName, in the order they were registered, passing the supplied arguments -to each.

                    -

                    Returns true if the event had listeners, false otherwise.

                    -
                    const EventEmitter = require('events');
                    -const myEmitter = new EventEmitter();
                    -
                    -// First listener
                    -myEmitter.on('event', function firstListener() {
                    -  console.log('Helloooo! first listener');
                    -});
                    -// Second listener
                    -myEmitter.on('event', function secondListener(arg1, arg2) {
                    -  console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
                    -});
                    -// Third listener
                    -myEmitter.on('event', function thirdListener(...args) {
                    -  const parameters = args.join(', ');
                    -  console.log(`event with parameters ${parameters} in third listener`);
                    -});
                    -
                    -console.log(myEmitter.listeners('event'));
                    -
                    -myEmitter.emit('event', 1, 2, 3, 4, 5);
                    -
                    -// Prints:
                    -// [
                    -//   [Function: firstListener],
                    -//   [Function: secondListener],
                    -//   [Function: thirdListener]
                    -// ]
                    -// Helloooo! first listener
                    -// event with parameters 1, 2 in second listener
                    -// event with parameters 1, 2, 3, 4, 5 in third listener
                    -

                    emitter.eventNames()#

                    - - -

                    Returns an array listing the events for which the emitter has registered -listeners. The values in the array will be strings or Symbols.

                    -
                    const EventEmitter = require('events');
                    -const myEE = new EventEmitter();
                    -myEE.on('foo', () => {});
                    -myEE.on('bar', () => {});
                    -
                    -const sym = Symbol('symbol');
                    -myEE.on(sym, () => {});
                    +

                    Returns a copy of the array of listeners for the event named eventName.

                    +

                    For EventEmitters this behaves exactly the same as calling .listeners on +the emitter.

                    +

                    For EventTargets this is the only way to get the event listeners for the +event target. This is useful for debugging and diagnostic purposes.

                    +
                    const { getEventListeners, EventEmitter } = require('events');
                     
                    -console.log(myEE.eventNames());
                    -// Prints: [ 'foo', 'bar', Symbol(symbol) ]
                    -

                    emitter.getMaxListeners()#

                    - - -

                    Returns the current max listener value for the EventEmitter which is either -set by emitter.setMaxListeners(n) or defaults to -EventEmitter.defaultMaxListeners.

                    -

                    emitter.listenerCount(eventName)#

                    - - -

                    Returns the number of listeners listening to the event named eventName.

                    -

                    emitter.listeners(eventName)#

                    +{ + const ee = new EventEmitter(); + const listener = () => console.log('Events are fun'); + ee.on('foo', listener); + getEventListeners(ee, 'foo'); // [listener] +} +{ + const et = new EventTarget(); + const listener = () => console.log('Events are fun'); + et.addEventListener('foo', listener); + getEventListeners(et, 'foo'); // [listener] +}
                    +

                    events.once(emitter, name[, options])#

                    -

                    Returns a copy of the array of listeners for the event named eventName.

                    -
                    server.on('connection', (stream) => {
                    -  console.log('someone connected!');
                    -});
                    -console.log(util.inspect(server.listeners('connection')));
                    -// Prints: [ [Function] ]
                    -

                    emitter.off(eventName, listener)#

                    - - -

                    Alias for emitter.removeListener().

                    -

                    emitter.on(eventName, listener)#

                    - - -

                    Adds the listener function to the end of the listeners array for the -event named eventName. No checks are made to see if the listener has -already been added. Multiple calls passing the same combination of eventName -and listener will result in the listener being added, and called, multiple -times.

                    -
                    server.on('connection', (stream) => {
                    -  console.log('someone connected!');
                    -});
                    -

                    Returns a reference to the EventEmitter, so that calls can be chained.

                    -

                    By default, event listeners are invoked in the order they are added. The -emitter.prependListener() method can be used as an alternative to add the -event listener to the beginning of the listeners array.

                    -
                    const myEE = new EventEmitter();
                    -myEE.on('foo', () => console.log('a'));
                    -myEE.prependListener('foo', () => console.log('b'));
                    -myEE.emit('foo');
                    -// Prints:
                    -//   b
                    -//   a
                    -

                    emitter.once(eventName, listener)#

                    - - -

                    Adds a one-time listener function for the event named eventName. The -next time eventName is triggered, this listener is removed and then invoked.

                    -
                    server.once('connection', (stream) => {
                    -  console.log('Ah, we have our first user!');
                    -});
                    -

                    Returns a reference to the EventEmitter, so that calls can be chained.

                    -

                    By default, event listeners are invoked in the order they are added. The -emitter.prependOnceListener() method can be used as an alternative to add the -event listener to the beginning of the listeners array.

                    -
                    const myEE = new EventEmitter();
                    -myEE.once('foo', () => console.log('a'));
                    -myEE.prependOnceListener('foo', () => console.log('b'));
                    -myEE.emit('foo');
                    -// Prints:
                    -//   b
                    -//   a
                    -

                    emitter.prependListener(eventName, listener)#

                    - - -

                    Adds the listener function to the beginning of the listeners array for the -event named eventName. No checks are made to see if the listener has -already been added. Multiple calls passing the same combination of eventName -and listener will result in the listener being added, and called, multiple -times.

                    -
                    server.prependListener('connection', (stream) => {
                    -  console.log('someone connected!');
                    -});
                    -

                    Returns a reference to the EventEmitter, so that calls can be chained.

                    -

                    emitter.prependOnceListener(eventName, listener)#

                    - - -

                    Adds a one-time listener function for the event named eventName to the -beginning of the listeners array. The next time eventName is triggered, this -listener is removed, and then invoked.

                    -
                    server.prependOnceListener('connection', (stream) => {
                    -  console.log('Ah, we have our first user!');
                    -});
                    -

                    Returns a reference to the EventEmitter, so that calls can be chained.

                    -

                    emitter.removeAllListeners([eventName])#

                    - - -

                    Removes all listeners, or those of the specified eventName.

                    -

                    It is bad practice to remove listeners added elsewhere in the code, -particularly when the EventEmitter instance was created by some other -component or module (e.g. sockets or file streams).

                    -

                    Returns a reference to the EventEmitter, so that calls can be chained.

                    -

                    emitter.removeListener(eventName, listener)#

                    - - -

                    Removes the specified listener from the listener array for the event named -eventName.

                    -
                    const callback = (stream) => {
                    -  console.log('someone connected!');
                    -};
                    -server.on('connection', callback);
                    -// ...
                    -server.removeListener('connection', callback);
                    -

                    removeListener() will remove, at most, one instance of a listener from the -listener array. If any single listener has been added multiple times to the -listener array for the specified eventName, then removeListener() must be -called multiple times to remove each instance.

                    -

                    Once an event has been emitted, all listeners attached to it at the -time of emitting will be called in order. This implies that any -removeListener() or removeAllListeners() calls after emitting and -before the last listener finishes execution will not remove them from -emit() in progress. Subsequent events will behave as expected.

                    -
                    const myEmitter = new MyEmitter();
                    -
                    -const callbackA = () => {
                    -  console.log('A');
                    -  myEmitter.removeListener('event', callbackB);
                    -};
                    -
                    -const callbackB = () => {
                    -  console.log('B');
                    -};
                    -
                    -myEmitter.on('event', callbackA);
                    -
                    -myEmitter.on('event', callbackB);
                    -
                    -// callbackA removes listener callbackB but it will still be called.
                    -// Internal listener array at time of emit [callbackA, callbackB]
                    -myEmitter.emit('event');
                    -// Prints:
                    -//   A
                    -//   B
                    -
                    -// callbackB is now removed.
                    -// Internal listener array [callbackA]
                    -myEmitter.emit('event');
                    -// Prints:
                    -//   A
                    -

                    Because listeners are managed using an internal array, calling this will -change the position indices of any listener registered after the listener -being removed. This will not impact the order in which listeners are called, -but it means that any copies of the listener array as returned by -the emitter.listeners() method will need to be recreated.

                    -

                    When a single function has been added as a handler multiple times for a single -event (as in the example below), removeListener() will remove the most -recently added instance. In the example the once('ping') -listener is removed:

                    -
                    const ee = new EventEmitter();
                    -
                    -function pong() {
                    -  console.log('pong');
                    -}
                    -
                    -ee.on('ping', pong);
                    -ee.once('ping', pong);
                    -ee.removeListener('ping', pong);
                    -
                    -ee.emit('ping');
                    -ee.emit('ping');
                    -

                    Returns a reference to the EventEmitter, so that calls can be chained.

                    -

                    emitter.setMaxListeners(n)#

                    - - -

                    By default EventEmitters will print a warning if more than 10 listeners are -added for a particular event. This is a useful default that helps finding -memory leaks. The emitter.setMaxListeners() method allows the limit to be -modified for this specific EventEmitter instance. The value can be set to -Infinity (or 0) to indicate an unlimited number of listeners.

                    -

                    Returns a reference to the EventEmitter, so that calls can be chained.

                    -

                    emitter.rawListeners(eventName)#

                    - - -

                    Returns a copy of the array of listeners for the event named eventName, -including any wrappers (such as those created by .once()).

                    -
                    const emitter = new EventEmitter();
                    -emitter.once('log', () => console.log('log once'));
                    -
                    -// Returns a new Array with a function `onceWrapper` which has a property
                    -// `listener` which contains the original listener bound above
                    -const listeners = emitter.rawListeners('log');
                    -const logFnWrapper = listeners[0];
                    -
                    -// Logs "log once" to the console and does not unbind the `once` event
                    -logFnWrapper.listener();
                    -
                    -// Logs "log once" to the console and removes the listener
                    -logFnWrapper();
                    -
                    -emitter.on('log', () => console.log('log persistently'));
                    -// Will return a new Array with a single function bound by `.on()` above
                    -const newListeners = emitter.rawListeners('log');
                    -
                    -// Logs "log persistently" twice
                    -newListeners[0]();
                    -emitter.emit('log');
                    -

                    emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])#

                    - -

                    Stability: 1 - captureRejections is experimental.

                    - -

                    The Symbol.for('nodejs.rejection') method is called in case a -promise rejection happens when emitting an event and -captureRejections is enabled on the emitter. -It is possible to use events.captureRejectionSymbol in -place of Symbol.for('nodejs.rejection').

                    -
                    const { EventEmitter, captureRejectionSymbol } = require('events');
                    -
                    -class MyClass extends EventEmitter {
                    -  constructor() {
                    -    super({ captureRejections: true });
                    -  }
                    -
                    -  [captureRejectionSymbol](err, event, ...args) {
                    -    console.log('rejection happened for', event, 'with', err, ...args);
                    -    this.destroy(err);
                    -  }
                    -
                    -  destroy(err) {
                    -    // Tear the resource down here.
                    -  }
                    -}
                    -

                    events.once(emitter, name)#

                    - -

                    Creates a Promise that is fulfilled when the EventEmitter emits the given @@ -29064,130 +30493,174 @@ given event.

                    This method is intentionally generic and works with the web platform EventTarget interface, which has no special 'error' event semantics and does not listen to the 'error' event.

                    -
                    const { once, EventEmitter } = require('events');
                    +
                    const { once, EventEmitter } = require('events');
                     
                    -async function run() {
                    -  const ee = new EventEmitter();
                    +async function run() {
                    +  const ee = new EventEmitter();
                     
                    -  process.nextTick(() => {
                    -    ee.emit('myevent', 42);
                    +  process.nextTick(() => {
                    +    ee.emit('myevent', 42);
                       });
                     
                    -  const [value] = await once(ee, 'myevent');
                    -  console.log(value);
                    +  const [value] = await once(ee, 'myevent');
                    +  console.log(value);
                     
                    -  const err = new Error('kaboom');
                    -  process.nextTick(() => {
                    -    ee.emit('error', err);
                    +  const err = new Error('kaboom');
                    +  process.nextTick(() => {
                    +    ee.emit('error', err);
                       });
                     
                       try {
                    -    await once(ee, 'myevent');
                    +    await once(ee, 'myevent');
                       } catch (err) {
                    -    console.log('error happened', err);
                    +    console.log('error happened', err);
                       }
                     }
                     
                    -run();
                    +run();

                    The special handling of the 'error' event is only used when events.once() is used to wait for another event. If events.once() is used to wait for the 'error' event itself, then it is treated as any other kind of event without special handling:

                    -
                    const { EventEmitter, once } = require('events');
                    +
                    const { EventEmitter, once } = require('events');
                     
                    -const ee = new EventEmitter();
                    +const ee = new EventEmitter();
                     
                    -once(ee, 'error')
                    -  .then(([err]) => console.log('ok', err.message))
                    -  .catch((err) => console.log('error', err.message));
                    +once(ee, 'error')
                    +  .then(([err]) => console.log('ok', err.message))
                    +  .catch((err) => console.log('error', err.message));
                     
                    -ee.emit('error', new Error('boom'));
                    +ee.emit('error', new Error('boom'));
                     
                     // Prints: ok boom
                    -

                    Awaiting multiple events emitted on process.nextTick()#

                    +

                    An <AbortSignal> can be used to cancel waiting for the event:

                    +
                    const { EventEmitter, once } = require('events');
                    +
                    +const ee = new EventEmitter();
                    +const ac = new AbortController();
                    +
                    +async function foo(emitter, event, signal) {
                    +  try {
                    +    await once(emitter, event, { signal });
                    +    console.log('event emitted!');
                    +  } catch (error) {
                    +    if (error.name === 'AbortError') {
                    +      console.error('Waiting for the event was canceled!');
                    +    } else {
                    +      console.error('There was an error', error.message);
                    +    }
                    +  }
                    +}
                    +
                    +foo(ee, 'foo', ac.signal);
                    +ac.abort(); // Abort waiting for the event
                    +ee.emit('foo'); // Prints: Waiting for the event was canceled!
                    +

                    Awaiting multiple events emitted on process.nextTick()#

                    There is an edge case worth noting when using the events.once() function to await multiple events emitted on in the same batch of process.nextTick() operations, or whenever multiple events are emitted synchronously. Specifically, because the process.nextTick() queue is drained before the Promise microtask queue, and because EventEmitter emits all events synchronously, it is possible for events.once() to miss an event.

                    -
                    const { EventEmitter, once } = require('events');
                    +
                    const { EventEmitter, once } = require('events');
                     
                    -const myEE = new EventEmitter();
                    +const myEE = new EventEmitter();
                     
                    -async function foo() {
                    -  await once(myEE, 'bar');
                    -  console.log('bar');
                    +async function foo() {
                    +  await once(myEE, 'bar');
                    +  console.log('bar');
                     
                       // This Promise will never resolve because the 'foo' event will
                       // have already been emitted before the Promise is created.
                    -  await once(myEE, 'foo');
                    -  console.log('foo');
                    +  await once(myEE, 'foo');
                    +  console.log('foo');
                     }
                     
                    -process.nextTick(() => {
                    -  myEE.emit('bar');
                    -  myEE.emit('foo');
                    +process.nextTick(() => {
                    +  myEE.emit('bar');
                    +  myEE.emit('foo');
                     });
                     
                    -foo().then(() => console.log('done'));
                    +foo().then(() => console.log('done'));

                    To catch both events, create each of the Promises before awaiting either of them, then it becomes possible to use Promise.all(), Promise.race(), or Promise.allSettled():

                    -
                    const { EventEmitter, once } = require('events');
                    +
                    const { EventEmitter, once } = require('events');
                     
                    -const myEE = new EventEmitter();
                    +const myEE = new EventEmitter();
                     
                    -async function foo() {
                    -  await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')]);
                    -  console.log('foo', 'bar');
                    +async function foo() {
                    +  await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')]);
                    +  console.log('foo', 'bar');
                     }
                     
                    -process.nextTick(() => {
                    -  myEE.emit('bar');
                    -  myEE.emit('foo');
                    +process.nextTick(() => {
                    +  myEE.emit('bar');
                    +  myEE.emit('foo');
                     });
                     
                    -foo().then(() => console.log('done'));
                    -

                    events.captureRejections#

                    +foo().then(() => console.log('done'));
                    +

                    events.captureRejections#

                    Stability: 1 - captureRejections is experimental.

                    Value: <boolean>

                    Change the default captureRejections option on all new EventEmitter objects.

                    -

                    events.captureRejectionSymbol#

                    +

                    events.captureRejectionSymbol#

                    Stability: 1 - captureRejections is experimental.

                    Value: Symbol.for('nodejs.rejection')

                    See how to write a custom rejection handler.

                    -

                    events.on(emitter, eventName)[src]#

                    +

                    events.listenerCount(emitter, eventName)#

                    + +

                    Stability: 0 - Deprecated: Use emitter.listenerCount() instead.

                    + +

                    A class method that returns the number of listeners for the given eventName +registered on the given emitter.

                    +
                    const { EventEmitter, listenerCount } = require('events');
                    +const myEmitter = new EventEmitter();
                    +myEmitter.on('event', () => {});
                    +myEmitter.on('event', () => {});
                    +console.log(listenerCount(myEmitter, 'event'));
                    +// Prints: 2
                    +

                    events.on(emitter, eventName[, options])#

                    -
                    const { on, EventEmitter } = require('events');
                    +
                    const { on, EventEmitter } = require('events');
                     
                     (async () => {
                    -  const ee = new EventEmitter();
                    +  const ee = new EventEmitter();
                     
                       // Emit later on
                    -  process.nextTick(() => {
                    -    ee.emit('foo', 'bar');
                    -    ee.emit('foo', 42);
                    +  process.nextTick(() => {
                    +    ee.emit('foo', 'bar');
                    +    ee.emit('foo', 42);
                       });
                     
                    -  for await (const event of on(ee, 'foo')) {
                    +  for await (const event of on(ee, 'foo')) {
                         // The execution of this inner block is synchronous and it
                         // processes one event at a time (even with await). Do not use
                         // if concurrent execution is required.
                    -    console.log(event); // prints ['bar'] [42]
                    +    console.log(event); // prints ['bar'] [42]
                       }
                       // Unreachable here
                     })();
                    @@ -29195,964 +30668,1750 @@ foo().then(() => if the EventEmitter emits 'error'. It removes all listeners when exiting the loop. The value returned by each iteration is an array composed of the emitted event arguments.

                    -

                    File system#

                    - -

                    Stability: 2 - Stable

                    - -

                    Source Code: lib/fs.js

                    -

                    The fs module enables interacting with the file system in a -way modeled on standard POSIX functions.

                    -

                    To use this module:

                    -
                    const fs = require('fs');
                    -

                    All file system operations have synchronous, callback, and promise-based -forms.

                    -

                    Synchronous example#

                    -

                    The synchronous form blocks the Node.js event loop and further JavaScript -execution until the operation is complete. Exceptions are thrown immediately -and can be handled using try…catch, or can be allowed to bubble up.

                    -
                    const fs = require('fs');
                    -
                    -try {
                    -  fs.unlinkSync('/tmp/hello');
                    -  console.log('successfully deleted /tmp/hello');
                    -} catch (err) {
                    -  // handle the error
                    -}
                    -

                    Callback example#

                    -

                    The callback form takes a completion callback function as its last -argument and invokes the operation asynchronously. The arguments passed to -the completion callback depend on the method, but the first argument is always -reserved for an exception. If the operation is completed successfully, then -the first argument is null or undefined.

                    -
                    const fs = require('fs');
                    +

                    An <AbortSignal> can be used to cancel waiting on events:

                    +
                    const { on, EventEmitter } = require('events');
                    +const ac = new AbortController();
                     
                    -fs.unlink('/tmp/hello', (err) => {
                    -  if (err) throw err;
                    -  console.log('successfully deleted /tmp/hello');
                    -});
                    -

                    Promise example#

                    -

                    Promise-based operations return a Promise that is resolved when the -asynchronous operation is complete.

                    -
                    const fs = require('fs').promises;
                    +(async () => {
                    +  const ee = new EventEmitter();
                     
                    -(async function(path) {
                    -  try {
                    -    await fs.unlink(path);
                    -    console.log(`successfully deleted ${path}`);
                    -  } catch (error) {
                    -    console.error('there was an error:', error.message);
                    -  }
                    -})('/tmp/hello');
                    -

                    Ordering of callback and promise-based operations#

                    -

                    There is no guaranteed ordering when using either the callback or -promise-based methods. For example, the following is prone to error -because the fs.stat() operation might complete before the fs.rename() -operation:

                    -
                    fs.rename('/tmp/hello', '/tmp/world', (err) => {
                    -  if (err) throw err;
                    -  console.log('renamed complete');
                    -});
                    -fs.stat('/tmp/world', (err, stats) => {
                    -  if (err) throw err;
                    -  console.log(`stats: ${JSON.stringify(stats)}`);
                    -});
                    -

                    To correctly order the operations, move the fs.stat() call into the callback -of the fs.rename() operation:

                    -
                    fs.rename('/tmp/hello', '/tmp/world', (err) => {
                    -  if (err) throw err;
                    -  fs.stat('/tmp/world', (err, stats) => {
                    -    if (err) throw err;
                    -    console.log(`stats: ${JSON.stringify(stats)}`);
                    +  // Emit later on
                    +  process.nextTick(() => {
                    +    ee.emit('foo', 'bar');
                    +    ee.emit('foo', 42);
                       });
                    -});
                    -

                    Or, use the promise-based API:

                    -
                    const fs = require('fs').promises;
                     
                    -(async function(from, to) {
                    -  try {
                    -    await fs.rename(from, to);
                    -    const stats = await fs.stat(to);
                    -    console.log(`stats: ${JSON.stringify(stats)}`);
                    -  } catch (error) {
                    -    console.error('there was an error:', error.message);
                    +  for await (const event of on(ee, 'foo', { signal: ac.signal })) {
                    +    // The execution of this inner block is synchronous and it
                    +    // processes one event at a time (even with await). Do not use
                    +    // if concurrent execution is required.
                    +    console.log(event); // prints ['bar'] [42]
                       }
                    -})('/tmp/hello', '/tmp/world');
                    -

                    File paths#

                    -

                    Most fs operations accept filepaths that may be specified in the form of -a string, a Buffer, or a URL object using the file: protocol.

                    -

                    String form paths are interpreted as UTF-8 character sequences identifying -the absolute or relative filename. Relative paths will be resolved relative -to the current working directory as determined by calling process.cwd().

                    -

                    Example using an absolute path on POSIX:

                    -
                    const fs = require('fs');
                    +  // Unreachable here
                    +})();
                     
                    -fs.open('/open/some/file.txt', 'r', (err, fd) => {
                    -  if (err) throw err;
                    -  fs.close(fd, (err) => {
                    -    if (err) throw err;
                    -  });
                    -});
                    -

                    Example using a relative path on POSIX (relative to process.cwd()):

                    -
                    fs.open('file.txt', 'r', (err, fd) => {
                    -  if (err) throw err;
                    -  fs.close(fd, (err) => {
                    -    if (err) throw err;
                    -  });
                    -});
                    -

                    Paths specified using a Buffer are useful primarily on certain POSIX -operating systems that treat file paths as opaque byte sequences. On such -systems, it is possible for a single file path to contain sub-sequences that -use multiple character encodings. As with string paths, Buffer paths may -be relative or absolute:

                    -

                    Example using an absolute path on POSIX:

                    -
                    fs.open(Buffer.from('/open/some/file.txt'), 'r', (err, fd) => {
                    -  if (err) throw err;
                    -  fs.close(fd, (err) => {
                    -    if (err) throw err;
                    -  });
                    -});
                    -

                    On Windows, Node.js follows the concept of per-drive working directory. This -behavior can be observed when using a drive path without a backslash. For -example fs.readdirSync('C:\\') can potentially return a different result than -fs.readdirSync('C:'). For more information, see -this MSDN page.

                    -

                    URL object support#

                    +process.nextTick(() => ac.abort());
                    +

                    events.setMaxListeners(n[, ...eventTargets])#

                    -

                    For most fs module functions, the path or filename argument may be passed -as a WHATWG URL object. Only URL objects using the file: protocol -are supported.

                    -
                    const fs = require('fs');
                    -const fileUrl = new URL('file:///tmp/hello');
                    -
                    -fs.readFileSync(fileUrl);
                    -

                    file: URLs are always absolute paths.

                    -

                    Using WHATWG URL objects might introduce platform-specific behaviors.

                    -

                    On Windows, file: URLs with a host name convert to UNC paths, while file: -URLs with drive letters convert to local absolute paths. file: URLs without a -host name nor a drive letter will result in a throw:

                    -
                    // On Windows :
                    +
                    +
                    const {
                    +  setMaxListeners,
                    +  EventEmitter
                    +} = require('events');
                     
                    -// - WHATWG file URLs with hostname convert to UNC path
                    -// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file
                    -fs.readFileSync(new URL('file://hostname/p/a/t/h/file'));
                    +const target = new EventTarget();
                    +const emitter = new EventEmitter();
                     
                    -// - WHATWG file URLs with drive letters convert to absolute path
                    -// file:///C:/tmp/hello => C:\tmp\hello
                    -fs.readFileSync(new URL('file:///C:/tmp/hello'));
                    +setMaxListeners(5, target, emitter);
                    +

                    +

                    EventTarget and Event API#

                    + +

                    Stability: 1 - Experimental

                    +

                    The EventTarget and Event objects are a Node.js-specific implementation +of the EventTarget Web API that are exposed by some Node.js core APIs. +Neither the EventTarget nor Event classes are available for end +user code to create.

                    +
                    const target = getEventTargetSomehow();
                    +
                    +target.addEventListener('foo', (event) => {
                    +  console.log('foo event happened!');
                    +});
                    +

                    Node.js EventTarget vs. DOM EventTarget#

                    +

                    There are two key differences between the Node.js EventTarget and the +EventTarget Web API:

                    +
                      +
                    1. Whereas DOM EventTarget instances may be hierarchical, there is no +concept of hierarchy and event propagation in Node.js. That is, an event +dispatched to an EventTarget does not propagate through a hierarchy of +nested target objects that may each have their own set of handlers for the +event.
                    2. +
                    3. In the Node.js EventTarget, if an event listener is an async function +or returns a Promise, and the returned Promise rejects, the rejection +is automatically captured and handled the same way as a listener that +throws synchronously (see EventTarget error handling for details).
                    4. +
                    +

                    NodeEventTarget vs. EventEmitter#

                    +

                    The NodeEventTarget object implements a modified subset of the +EventEmitter API that allows it to closely emulate an EventEmitter in +certain situations. A NodeEventTarget is not an instance of EventEmitter +and cannot be used in place of an EventEmitter in most cases.

                    +
                      +
                    1. Unlike EventEmitter, any given listener can be registered at most once +per event type. Attempts to register a listener multiple times are +ignored.
                    2. +
                    3. The NodeEventTarget does not emulate the full EventEmitter API. +Specifically the prependListener(), prependOnceListener(), +rawListeners(), setMaxListeners(), getMaxListeners(), and +errorMonitor APIs are not emulated. The 'newListener' and +'removeListener' events will also not be emitted.
                    4. +
                    5. The NodeEventTarget does not implement any special default behavior +for events with type 'error'.
                    6. +
                    7. The NodeEventTarget supports EventListener objects as well as +functions as handlers for all event types.
                    8. +
                    +

                    Event listener#

                    +

                    Event listeners registered for an event type may either be JavaScript +functions or objects with a handleEvent property whose value is a function.

                    +

                    In either case, the handler function is invoked with the event argument +passed to the eventTarget.dispatchEvent() function.

                    +

                    Async functions may be used as event listeners. If an async handler function +rejects, the rejection is captured and handled as described in +EventTarget error handling.

                    +

                    An error thrown by one handler function does not prevent the other handlers +from being invoked.

                    +

                    The return value of a handler function is ignored.

                    +

                    Handlers are always invoked in the order they were added.

                    +

                    Handler functions may mutate the event object.

                    +
                    function handler1(event) {
                    +  console.log(event.type);  // Prints 'foo'
                    +  event.a = 1;
                    +}
                     
                    -// - WHATWG file URLs without hostname must have a drive letters
                    -fs.readFileSync(new URL('file:///notdriveletter/p/a/t/h/file'));
                    -fs.readFileSync(new URL('file:///c/p/a/t/h/file'));
                    -// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute
                    -

                    file: URLs with drive letters must use : as a separator just after -the drive letter. Using another separator will result in a throw.

                    -

                    On all other platforms, file: URLs with a host name are unsupported and will -result in a throw:

                    -
                    // On other platforms:
                    +async function handler2(event) {
                    +  console.log(event.type);  // Prints 'foo'
                    +  console.log(event.a);  // Prints 1
                    +}
                     
                    -// - WHATWG file URLs with hostname are unsupported
                    -// file://hostname/p/a/t/h/file => throw!
                    -fs.readFileSync(new URL('file://hostname/p/a/t/h/file'));
                    -// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute
                    +const handler3 = {
                    +  handleEvent(event) {
                    +    console.log(event.type);  // Prints 'foo'
                    +  }
                    +};
                     
                    -// - WHATWG file URLs convert to absolute path
                    -// file:///tmp/hello => /tmp/hello
                    -fs.readFileSync(new URL('file:///tmp/hello'));
                    -

                    A file: URL having encoded slash characters will result in a throw on all -platforms:

                    -
                    // On Windows
                    -fs.readFileSync(new URL('file:///C:/p/a/t/h/%2F'));
                    -fs.readFileSync(new URL('file:///C:/p/a/t/h/%2f'));
                    -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
                    -\ or / characters */
                    +const handler4 = {
                    +  async handleEvent(event) {
                    +    console.log(event.type);  // Prints 'foo'
                    +  }
                    +};
                     
                    -// On POSIX
                    -fs.readFileSync(new URL('file:///p/a/t/h/%2F'));
                    -fs.readFileSync(new URL('file:///p/a/t/h/%2f'));
                    -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
                    -/ characters */
                    -

                    On Windows, file: URLs having encoded backslash will result in a throw:

                    -
                    // On Windows
                    -fs.readFileSync(new URL('file:///C:/path/%5C'));
                    -fs.readFileSync(new URL('file:///C:/path/%5c'));
                    -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
                    -\ or / characters */
                    -

                    File descriptors#

                    -

                    On POSIX systems, for every process, the kernel maintains a table of currently -open files and resources. Each open file is assigned a simple numeric -identifier called a file descriptor. At the system-level, all file system -operations use these file descriptors to identify and track each specific -file. Windows systems use a different but conceptually similar mechanism for -tracking resources. To simplify things for users, Node.js abstracts away the -specific differences between operating systems and assigns all open files a -numeric file descriptor.

                    -

                    The fs.open() method is used to allocate a new file descriptor. Once -allocated, the file descriptor may be used to read data from, write data to, -or request information about the file.

                    -
                    fs.open('/open/some/file.txt', 'r', (err, fd) => {
                    -  if (err) throw err;
                    -  fs.fstat(fd, (err, stat) => {
                    -    if (err) throw err;
                    -    // use stat
                    +const target = getEventTargetSomehow();
                     
                    -    // always close the file descriptor!
                    -    fs.close(fd, (err) => {
                    -      if (err) throw err;
                    -    });
                    -  });
                    -});
                    -

                    Most operating systems limit the number of file descriptors that may be open -at any given time so it is critical to close the descriptor when operations -are completed. Failure to do so will result in a memory leak that will -eventually cause an application to crash.

                    -

                    Threadpool usage#

                    -

                    All file system APIs except fs.FSWatcher() and those that are explicitly -synchronous use libuv's threadpool, which can have surprising and negative -performance implications for some applications. See the -UV_THREADPOOL_SIZE documentation for more information.

                    -

                    Class: fs.Dir#

                    +target.addEventListener('foo', handler1); +target.addEventListener('foo', handler2); +target.addEventListener('foo', handler3); +target.addEventListener('foo', handler4, { once: true });
                    +

                    EventTarget error handling#

                    +

                    When a registered event listener throws (or returns a Promise that rejects), +by default the error is treated as an uncaught exception on +process.nextTick(). This means uncaught exceptions in EventTargets will +terminate the Node.js process by default.

                    +

                    Throwing within an event listener will not stop the other registered handlers +from being invoked.

                    +

                    The EventTarget does not implement any special default handling for 'error' +type events like EventEmitter.

                    +

                    Currently errors are first forwarded to the process.on('error') event +before reaching process.on('uncaughtException'). This behavior is +deprecated and will change in a future release to align EventTarget with +other Node.js APIs. Any code relying on the process.on('error') event should +be aligned with the new behavior.

                    +

                    Class: Event#

                    -

                    A class representing a directory stream.

                    -

                    Created by fs.opendir(), fs.opendirSync(), or -fsPromises.opendir().

                    -
                    const fs = require('fs');
                    -
                    -async function print(path) {
                    -  const dir = await fs.promises.opendir(path);
                    -  for await (const dirent of dir) {
                    -    console.log(dirent.name);
                    -  }
                    -}
                    -print('./').catch(console.error);
                    -

                    dir.close()#

                    +

                    The Event object is an adaptation of the Event Web API. Instances +are created internally by Node.js.

                    +
                    event.bubbles#
                    -

                    Asynchronously close the directory's underlying resource handle. -Subsequent reads will result in errors.

                    -

                    A Promise is returned that will be resolved after the resource has been -closed.

                    -

                    dir.close(callback)#

                    +

                    This is not used in Node.js and is provided purely for completeness.

                    +
                    event.cancelBubble()#
                    +

                    Alias for event.stopPropagation(). This is not used in Node.js and is +provided purely for completeness.

                    +
                    event.cancelable#
                    +
                      -
                    • callback <Function> -
                        -
                      • err <Error>
                      • +
                      • Type: <boolean> True if the event was created with the cancelable option.
                      -
                    • +
                      event.composed#
                      + + -

                      Asynchronously close the directory's underlying resource handle. -Subsequent reads will result in errors.

                      -

                      The callback will be called after the resource handle has been closed.

                      -

                      dir.closeSync()#

                      +

                      This is not used in Node.js and is provided purely for completeness.

                      +
                      event.composedPath()#
                      -

                      Synchronously close the directory's underlying resource handle. -Subsequent reads will result in errors.

                      -

                      dir.path#

                      +

                      Returns an array containing the current EventTarget as the only entry or +empty if the event is not being dispatched. This is not used in +Node.js and is provided purely for completeness.

                      +
                      event.currentTarget#
                      -

                      The read-only path of this directory as was provided to fs.opendir(), -fs.opendirSync(), or fsPromises.opendir().

                      -

                      dir.read()#

                      +

                      Alias for event.target.

                      +
                      event.defaultPrevented#
                      -

                      Asynchronously read the next directory entry via readdir(3) as an -fs.Dirent.

                      -

                      After the read is completed, a Promise is returned that will be resolved with -an fs.Dirent, or null if there are no more directory entries to read.

                      -

                      Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results.

                      -

                      dir.read(callback)#

                      +

                      Is true if cancelable is true and event.preventDefault() has been +called.

                      +
                      event.eventPhase#
                        -
                      • callback <Function> - -
                      • +

                        This is not used in Node.js and is provided purely for completeness.

                        +
                        event.isTrusted#
                        + + -

                        Asynchronously read the next directory entry via readdir(3) as an -fs.Dirent.

                        -

                        After the read is completed, the callback will be called with an -fs.Dirent, or null if there are no more directory entries to read.

                        -

                        Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results.

                        -

                        dir.readSync()#

                        +

                        The <AbortSignal> "abort" event is emitted with isTrusted set to true. The +value is false in all other cases.

                        +
                        event.preventDefault()#
                        +

                        Sets the defaultPrevented property to true if cancelable is true.

                        +
                        event.returnValue#
                        + -

                        Synchronously read the next directory entry via readdir(3) as an -fs.Dirent.

                        -

                        If there are no more directory entries to read, null will be returned.

                        -

                        Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results.

                        -

                        dir[Symbol.asyncIterator]()#

                        +

                        This is not used in Node.js and is provided purely for completeness.

                        +
                        event.srcElement#
                        -

                        Asynchronously iterates over the directory via readdir(3) until all entries have -been read.

                        -

                        Entries returned by the async iterator are always an fs.Dirent. -The null case from dir.read() is handled internally.

                        -

                        See fs.Dir for an example.

                        -

                        Directory entries returned by this iterator are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results.

                        -

                        Class: fs.Dirent#

                        +

                        Alias for event.target.

                        +
                        event.stopImmediatePropagation()#
                        -

                        A representation of a directory entry, which can be a file or a subdirectory -within the directory, as returned by reading from an fs.Dir. The -directory entry is a combination of the file name and file type pairs.

                        -

                        Additionally, when fs.readdir() or fs.readdirSync() is called with -the withFileTypes option set to true, the resulting array is filled with -fs.Dirent objects, rather than strings or Buffers.

                        -

                        dirent.isBlockDevice()#

                        +

                        Stops the invocation of event listeners after the current one completes.

                        +
                        event.stopPropagation()#
                        +

                        This is not used in Node.js and is provided purely for completeness.

                        +
                        event.target#
                        + -

                        Returns true if the fs.Dirent object describes a block device.

                        -

                        dirent.isCharacterDevice()#

                        +
                        event.timeStamp#
                        -

                        Returns true if the fs.Dirent object describes a character device.

                        -

                        dirent.isDirectory()#

                        +

                        The millisecond timestamp when the Event object was created.

                        +
                        event.type#
                        -

                        Returns true if the fs.Dirent object describes a file system -directory.

                        -

                        dirent.isFIFO()#

                        +

                        The event type identifier.

                        +

                        Class: EventTarget#

                        - -

                        Returns true if the fs.Dirent object describes a first-in-first-out -(FIFO) pipe.

                        -

                        dirent.isFile()#

                        +
                        eventTarget.addEventListener(type, listener[, options])#
                        -

                        Returns true if the fs.Dirent object describes a regular file.

                        -

                        dirent.isSocket()#

                        - +
                      • type <string>
                      • +
                      • listener <Function> | <EventListener>
                      • +
                      • options <Object>
                          -
                        • Returns: <boolean>
                        • +
                        • once <boolean> When true, the listener is automatically removed +when it is first invoked. Default: false.
                        • +
                        • passive <boolean> When true, serves as a hint that the listener will +not call the Event object's preventDefault() method. +Default: false.
                        • +
                        • capture <boolean> Not directly used by Node.js. Added for API +completeness. Default: false.
                        -

                        Returns true if the fs.Dirent object describes a socket.

                        -

                        dirent.isSymbolicLink()#

                        - - -

                        Returns true if the fs.Dirent object describes a symbolic link.

                        -

                        dirent.name#

                        +

                        Adds a new handler for the type event. Any given listener is added +only once per type and per capture option value.

                        +

                        If the once option is true, the listener is removed after the +next time a type event is dispatched.

                        +

                        The capture option is not used by Node.js in any functional way other than +tracking registered event listeners per the EventTarget specification. +Specifically, the capture option is used as part of the key when registering +a listener. Any individual listener may be added once with +capture = false, and once with capture = true.

                        +
                        function handler(event) {}
                        +
                        +const target = getEventTargetSomehow();
                        +target.addEventListener('foo', handler, { capture: true });  // first
                        +target.addEventListener('foo', handler, { capture: false }); // second
                        +
                        +// Removes the second instance of handler
                        +target.removeEventListener('foo', handler);
                        +
                        +// Removes the first instance of handler
                        +target.removeEventListener('foo', handler, { capture: true });
                        +
                        eventTarget.dispatchEvent(event)#
                          -
                        • <string> | <Buffer>
                        • +
                        • event <Event>
                        • +
                        • Returns: <boolean> true if either event’s cancelable attribute value is +false or its preventDefault() method was not invoked, otherwise false.
                        -

                        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().

                        -

                        Class: fs.FSWatcher#

                        +

                        Dispatches the event to the list of handlers for event.type.

                        +

                        The registered event listeners is synchronously invoked in the order they +were registered.

                        +
                        eventTarget.removeEventListener(type, listener)#
                        -

                        A successful call to fs.watch() method will return a new fs.FSWatcher -object.

                        -

                        All fs.FSWatcher objects emit a 'change' event whenever a specific watched -file is modified.

                        -

                        Event: 'change'#

                        - +
                      • type <string>
                      • +
                      • listener <Function> | <EventListener>
                      • +
                      • options <Object> -

                        Emitted when something changes in a watched directory or file. -See more details in fs.watch().

                        -

                        The filename argument may not be provided depending on operating system -support. If filename is provided, it will be provided as a Buffer if -fs.watch() is called with its encoding option set to 'buffer', otherwise -filename will be a UTF-8 string.

                        -
                        // Example when handled through fs.watch() listener
                        -fs.watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {
                        -  if (filename) {
                        -    console.log(filename);
                        -    // Prints: <Buffer ...>
                        -  }
                        -});
                        -

                        Event: 'close'#

                        - -

                        Emitted when the watcher stops watching for changes. The closed -fs.FSWatcher object is no longer usable in the event handler.

                        -

                        Event: 'error'#

                        - - -

                        Emitted when an error occurs while watching the file. The errored -fs.FSWatcher object is no longer usable in the event handler.

                        -

                        watcher.close()#

                        - -

                        Stop watching for changes on the given fs.FSWatcher. Once stopped, the -fs.FSWatcher object is no longer usable.

                        -

                        watcher.ref()#

                        +

                        Removes the listener from the list of handlers for event type.

                        +

                        Class: NodeEventTarget#

                        -

                        When called, requests that the Node.js event loop not exit so long as the -FSWatcher is active. Calling watcher.ref() multiple times will have -no effect.

                        -

                        By default, all FSWatcher objects are "ref'ed", making it normally -unnecessary to call watcher.ref() unless watcher.unref() had been -called previously.

                        -

                        watcher.unref()#

                        +

                        The NodeEventTarget is a Node.js-specific extension to EventTarget +that emulates a subset of the EventEmitter API.

                        +
                        nodeEventTarget.addListener(type, listener[, options])#
                        -

                        When called, the active FSWatcher object will not require the Node.js -event loop to remain active. If there is no other activity keeping the -event loop running, the process may exit before the FSWatcher object's -callback is invoked. Calling watcher.unref() multiple times will have -no effect.

                        -

                        Class: fs.StatWatcher#

                        - +
                      • +

                        type <string>

                        +
                      • +
                      • +

                        listener <Function> | <EventListener>

                        +
                      • +
                      • +

                        options <Object>

                        -

                        A successful call to fs.watchFile() method will return a new fs.StatWatcher -object.

                        -

                        watcher.ref()#

                        +
                      • +
                      • +

                        Returns: <EventTarget> this

                        +
                      • +
                      +

                      Node.js-specific extension to the EventTarget class that emulates the +equivalent EventEmitter API. The only difference between addListener() and +addEventListener() is that addListener() will return a reference to the +EventTarget.

                      +
                      nodeEventTarget.eventNames()#
                      -

                      When called, requests that the Node.js event loop not exit so long as the -StatWatcher is active. Calling watcher.ref() multiple times will have -no effect.

                      -

                      By default, all StatWatcher objects are "ref'ed", making it normally -unnecessary to call watcher.ref() unless watcher.unref() had been -called previously.

                      -

                      watcher.unref()#

                      +

                      Node.js-specific extension to the EventTarget class that returns an array +of event type names for which event listeners are registered.

                      +
                      nodeEventTarget.listenerCount(type)#
                      -

                      When called, the active StatWatcher object will not require the Node.js -event loop to remain active. If there is no other activity keeping the -event loop running, the process may exit before the StatWatcher object's -callback is invoked. Calling watcher.unref() multiple times will have -no effect.

                      -

                      Class: fs.ReadStream#

                      +

                      Node.js-specific extension to the EventTarget class that returns the number +of event listeners registered for the type.

                      +
                      nodeEventTarget.off(type, listener)#
                      -

                      Instances of fs.ReadStream are created and returned using the -fs.createReadStream() function.

                      -

                      Event: 'close'#

                      +

                      Node.js-specific alias for eventTarget.removeListener().

                      +
                      nodeEventTarget.on(type, listener[, options])#
                      -

                      Emitted when the fs.ReadStream's underlying file descriptor has been closed.

                      -

                      Event: 'open'#

                      -
                        -
                      • fd <integer> Integer file descriptor used by the ReadStream.
                      • +
                      • +

                        type <string>

                        +
                      • +
                      • +

                        listener <Function> | <EventListener>

                        +
                      • +
                      • +

                        options <Object>

                        + -

                        Emitted when the fs.ReadStream's file descriptor has been opened.

                        -

                        Event: 'ready'#

                        - -

                        Emitted when the fs.ReadStream is ready to be used.

                        -

                        Fires immediately after 'open'.

                        -

                        readStream.bytesRead#

                        +
                      • +
                      • +

                        Returns: <EventTarget> this

                        +
                      • +
                      +

                      Node.js-specific alias for eventTarget.addListener().

                      +
                      nodeEventTarget.once(type, listener[, options])#
                      -

                      The number of bytes that have been read so far.

                      -

                      readStream.path#

                      +

                      Node.js-specific extension to the EventTarget class that adds a once +listener for the given event type. This is equivalent to calling on +with the once option set to true.

                      +
                      nodeEventTarget.removeAllListeners([type])#
                      -

                      The path to the file the stream is reading from as specified in the first -argument to fs.createReadStream(). If path is passed as a string, then -readStream.path will be a string. If path is passed as a Buffer, then -readStream.path will be a Buffer.

                      -

                      readStream.pending#

                      +

                      Node.js-specific extension to the EventTarget class. If type is specified, +removes all registered listeners for type, otherwise removes all registered +listeners.

                      +
                      nodeEventTarget.removeListener(type, listener)#
                      -

                      This property is true if the underlying file has not been opened yet, -i.e. before the 'ready' event is emitted.

                      -

                      Class: fs.Stats#

                      +

                      Node.js-specific extension to the EventTarget class that removes the +listener for the given type. The only difference between removeListener() +and removeEventListener() is that removeListener() will return a reference +to the EventTarget.

                      + +

                      File system#

                      + +

                      Stability: 2 - Stable

                      + +

                      Source Code: lib/fs.js

                      +

                      The fs module enables interacting with the file system in a +way modeled on standard POSIX functions.

                      +

                      To use the promise-based APIs:

                      + +
                      import * as fs from 'fs/promises';const fs = require('fs/promises');
                      +

                      To use the callback and sync APIs:

                      + +
                      import * as fs from 'fs';const fs = require('fs');
                      +

                      All file system operations have synchronous, callback, and promise-based +forms, and are accessible using both CommonJS syntax and ES6 Modules (ESM).

                      +

                      Promise example#

                      +

                      Promise-based operations return a promise that is fulfilled when the +asynchronous operation is complete.

                      + +
                      import { unlink } from 'fs/promises';
                      +
                      +try {
                      +  await unlink('/tmp/hello');
                      +  console.log('successfully deleted /tmp/hello');
                      +} catch (error) {
                      +  console.error('there was an error:', error.message);
                      +}const { unlink } = require('fs/promises');
                      +
                      +(async function(path) {
                      +  try {
                      +    await unlink(path);
                      +    console.log(`successfully deleted ${path}`);
                      +  } catch (error) {
                      +    console.error('there was an error:', error.message);
                      +  }
                      +})('/tmp/hello');
                      +

                      Callback example#

                      +

                      The callback form takes a completion callback function as its last +argument and invokes the operation asynchronously. The arguments passed to +the completion callback depend on the method, but the first argument is always +reserved for an exception. If the operation is completed successfully, then +the first argument is null or undefined.

                      + +
                      import { unlink } from 'fs';
                      +
                      +unlink('/tmp/hello', (err) => {
                      +  if (err) throw err;
                      +  console.log('successfully deleted /tmp/hello');
                      +});const { unlink } = require('fs');
                      +
                      +unlink('/tmp/hello', (err) => {
                      +  if (err) throw err;
                      +  console.log('successfully deleted /tmp/hello');
                      +});
                      +

                      The callback-based versions of the fs module APIs are preferable over +the use of the promise APIs when maximal performance (both in terms of +execution time and memory allocation are required).

                      +

                      Synchronous example#

                      +

                      The synchronous APIs block the Node.js event loop and further JavaScript +execution until the operation is complete. Exceptions are thrown immediately +and can be handled using try…catch, or can be allowed to bubble up.

                      + +
                      import { unlinkSync } from 'fs';
                      +
                      +try {
                      +  unlinkSync('/tmp/hello');
                      +  console.log('successfully deleted /tmp/hello');
                      +} catch (err) {
                      +  // handle the error
                      +}const { unlinkSync } = require('fs');
                      +
                      +try {
                      +  unlinkSync('/tmp/hello');
                      +  console.log('successfully deleted /tmp/hello');
                      +} catch (err) {
                      +  // handle the error
                      +}
                      +

                      Promises API#

                      -

                      A fs.Stats object provides information about a file.

                      -

                      Objects returned from fs.stat(), fs.lstat() and fs.fstat() and -their synchronous counterparts are of this type. -If bigint in the options passed to those methods is true, the numeric values -will be bigint instead of number, and the object will contain additional -nanosecond-precision properties suffixed with Ns.

                      -
                      Stats {
                      -  dev: 2114,
                      -  ino: 48064969,
                      -  mode: 33188,
                      -  nlink: 1,
                      -  uid: 85,
                      -  gid: 100,
                      -  rdev: 0,
                      -  size: 527,
                      -  blksize: 4096,
                      -  blocks: 8,
                      -  atimeMs: 1318289051000.1,
                      -  mtimeMs: 1318289051000.1,
                      -  ctimeMs: 1318289051000.1,
                      -  birthtimeMs: 1318289051000.1,
                      -  atime: Mon, 10 Oct 2011 23:24:11 GMT,
                      -  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
                      -  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
                      -  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
                      -

                      bigint version:

                      -
                      BigIntStats {
                      -  dev: 2114n,
                      -  ino: 48064969n,
                      -  mode: 33188n,
                      -  nlink: 1n,
                      -  uid: 85n,
                      -  gid: 100n,
                      -  rdev: 0n,
                      -  size: 527n,
                      -  blksize: 4096n,
                      -  blocks: 8n,
                      -  atimeMs: 1318289051000n,
                      -  mtimeMs: 1318289051000n,
                      -  ctimeMs: 1318289051000n,
                      -  birthtimeMs: 1318289051000n,
                      -  atimeNs: 1318289051000000000n,
                      -  mtimeNs: 1318289051000000000n,
                      -  ctimeNs: 1318289051000000000n,
                      -  birthtimeNs: 1318289051000000000n,
                      -  atime: Mon, 10 Oct 2011 23:24:11 GMT,
                      -  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
                      -  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
                      -  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
                      -

                      stats.isBlockDevice()#

                      +

                      The fs/promises API provides asynchronous file system methods that return +promises.

                      +

                      The promise APIs use the underlying Node.js threadpool to perform file +system operations off the event loop thread. These operations are not +synchronized or threadsafe. Care must be taken when performing multiple +concurrent modifications on the same file or data corruption may occur.

                      +

                      Class: FileHandle#

                      +

                      A <FileHandle> object is an object wrapper for a numeric file descriptor.

                      +

                      Instances of the <FileHandle> object are created by the fsPromises.open() +method.

                      +

                      All <FileHandle> objects are <EventEmitter>s.

                      +

                      If a <FileHandle> is not closed using the filehandle.close() method, it will +try to automatically close the file descriptor and emit a process warning, +helping to prevent memory leaks. Please do not rely on this behavior because +it can be unreliable and the file may not be closed. Instead, always explicitly +close <FileHandle>s. Node.js may change this behavior in the future.

                      +
                      filehandle.appendFile(data[, options])#
                      + +

                      Alias of filehandle.writeFile().

                      +

                      When operating on file handles, the mode cannot be changed from what it was set +to with fsPromises.open(). Therefore, this is equivalent to +filehandle.writeFile().

                      +
                      filehandle.chmod(mode)#
                      -

                      Returns true if the fs.Stats object describes a character device.

                      -

                      stats.isDirectory()#

                      +

                      Modifies the permissions on the file. See chmod(2).

                      +
                      filehandle.chown(uid, gid)#
                      -

                      Returns true if the fs.Stats object describes a file system directory.

                      -

                      stats.isFIFO()#

                      +

                      Changes the ownership of the file. A wrapper for chown(2).

                      +
                      filehandle.close()#
                      -

                      Returns true if the fs.Stats object describes a first-in-first-out (FIFO) -pipe.

                      -

                      stats.isFile()#

                      +

                      Closes the file handle after waiting for any pending operation on the handle to +complete.

                      +
                      import { open } from 'fs/promises';
                      +
                      +let filehandle;
                      +try {
                      +  filehandle = await open('thefile.txt', 'r');
                      +} finally {
                      +  await filehandle?.close();
                      +}
                      +
                      filehandle.datasync()#
                      -

                      Returns true if the fs.Stats object describes a regular file.

                      -

                      stats.isSocket()#

                      +

                      Forces all currently queued I/O operations associated with the file to the +operating system's synchronized I/O completion state. Refer to the POSIX +fdatasync(2) documentation for details.

                      +

                      Unlike filehandle.sync this method does not flush modified metadata.

                      +
                      filehandle.fd#
                      -

                      Returns true if the fs.Stats object describes a socket.

                      -

                      stats.isSymbolicLink()#

                      +
                      filehandle.read(buffer, offset, length, position)#
                        -
                      • Returns: <boolean>
                      • +
                      • buffer <Buffer> | <TypedArray> | <DataView> A buffer that will be filled with the +file data read.
                      • +
                      • offset <integer> The location in the buffer at which to start filling. +Default: 0
                      • +
                      • length <integer> The number of bytes to read. Default: +buffer.byteLength
                      • +
                      • position <integer> The location where to begin reading data from the +file. If null, data will be read from the current file position, and +the position will be updated. If position is an integer, the current +file position will remain unchanged.
                      • +
                      • Returns: <Promise> Fulfills upon success with an object with two properties: + -

                        Returns true if the fs.Stats object describes a symbolic link.

                        -

                        This method is only valid when using fs.lstat().

                        -

                        stats.dev#

                        - -

                        The numeric identifier of the device containing the file.

                        -

                        stats.ino#

                        +

                        Reads data from the file and stores that in the given buffer.

                        +

                        If the file is not modified concurrently, the end-of-file is reached when the +number of bytes read is zero.

                        +
                        filehandle.read([options])#
                        + -

                        The file system specific "Inode" number for the file.

                        -

                        stats.mode#

                        +
                      • options <Object>
                          -
                        • <number> | <bigint>
                        • +
                        • buffer <Buffer> | <TypedArray> | <DataView> A buffer that will be filled with the +file data read. Default: Buffer.alloc(16384)
                        • +
                        • offset <integer> The location in the buffer at which to start filling. +Default: 0
                        • +
                        • length <integer> The number of bytes to read. Default: +buffer.byteLength
                        • +
                        • position <integer> The location where to begin reading data from the +file. If null, data will be read from the current file position, and +the position will be updated. If position is an integer, the current +file position will remain unchanged. Default:: null
                        -

                        A bit-field describing the file type and mode.

                        -

                        stats.nlink#

                        +
                      • +
                      • Returns: <Promise> Fulfills upon success with an object with two properties: -

                        The number of hard-links that exist for the file.

                        -

                        stats.uid#

                        - -

                        The numeric user identifier of the user that owns the file (POSIX).

                        -

                        stats.gid#

                        +

                        Reads data from the file and stores that in the given buffer.

                        +

                        If the file is not modified concurrently, the end-of-file is reached when the +number of bytes read is zero.

                        +
                        filehandle.readFile(options)#
                        + -

                        The numeric group identifier of the group that owns the file (POSIX).

                        -

                        stats.rdev#

                        +
                      • options <Object> | <string> -

                        A numeric device identifier if the file represents a device.

                        -

                        stats.size#

                        -
                          -
                        • <number> | <bigint>
                        • + +
                        • Returns: <Promise> Fulfills upon a successful read with the contents of the +file. If no encoding is specified (using options.encoding), the data is +returned as a <Buffer> object. Otherwise, the data will be a string.
                        -

                        The size of the file in bytes.

                        -

                        stats.blksize#

                        +

                        Asynchronously reads the entire contents of a file.

                        +

                        If options is a string, then it specifies the encoding.

                        +

                        The <FileHandle> has to support reading.

                        +

                        If one or more filehandle.read() calls are made on a file handle and then a +filehandle.readFile() call is made, the data will be read from the current +position till the end of the file. It doesn't always read from the beginning +of the file.

                        +
                        filehandle.readv(buffers[, position])#
                        + -

                        The file system block size for i/o operations.

                        -

                        stats.blocks#

                        +
                      • buffers <Buffer[]> | <TypedArray[]> | <DataView[]>
                      • +
                      • position <integer> The offset from the beginning of the file where the data +should be read from. If position is not a number, the data will be read +from the current position.
                      • +
                      • Returns: <Promise> Fulfills upon success an object containing two properties: -

                        The number of blocks allocated for this file.

                        -

                        stats.atimeMs#

                        +
                      • +
                      +

                      Read from a file and write to an array of <ArrayBufferView>s

                      +
                      filehandle.stat([options])#
                        -
                      • <number> | <bigint>
                      • +
                      • options <Object> +
                          +
                        • bigint <boolean> Whether the numeric values in the returned +<fs.Stats> object should be bigint. Default: false.
                        -

                        The timestamp indicating the last time this file was accessed expressed in -milliseconds since the POSIX Epoch.

                        -

                        stats.mtimeMs#

                        +
                      • +
                      • Returns: <Promise> Fulfills with an <fs.Stats> for the file.
                      • +
                      +
                      filehandle.sync()#
                      -

                      The timestamp indicating the last time this file was modified expressed in -milliseconds since the POSIX Epoch.

                      -

                      stats.ctimeMs#

                      +

                      Request that all data for the open file descriptor is flushed to the storage +device. The specific implementation is operating system and device specific. +Refer to the POSIX fsync(2) documentation for more detail.

                      +
                      filehandle.truncate(len)#
                      -

                      The timestamp indicating the last time the file status was changed expressed -in milliseconds since the POSIX Epoch.

                      -

                      stats.birthtimeMs#

                      +

                      Truncates the file.

                      +

                      If the file was larger than len bytes, only the first len bytes will be +retained in the file.

                      +

                      The following example retains only the first four bytes of the file:

                      +
                      import { open } from 'fs/promises';
                      +
                      +let filehandle = null;
                      +try {
                      +  filehandle = await open('temp.txt', 'r+');
                      +  await filehandle.truncate(4);
                      +} finally {
                      +  await filehandle?.close();
                      +}
                      +

                      If the file previously was shorter than len bytes, it is extended, and the +extended part is filled with null bytes ('\0'):

                      +

                      If len is negative then 0 will be used.

                      +
                      filehandle.utimes(atime, mtime)#
                      -

                      The timestamp indicating the creation time of this file expressed in -milliseconds since the POSIX Epoch.

                      -

                      stats.atimeNs#

                      +

                      Change the file system timestamps of the object referenced by the <FileHandle> +then resolves the promise with no arguments upon success.

                      +

                      This function does not work on AIX versions before 7.1, it will reject the +promise with an error using code UV_ENOSYS.

                      +
                      filehandle.write(buffer[, offset[, length[, position]]])#
                        -
                      • <bigint>
                      • +
                      • buffer <Buffer> | <TypedArray> | <DataView> | <string> | <Object>
                      • +
                      • offset <integer> The start position from within buffer where the data +to write begins. Default: 0
                      • +
                      • length <integer> The number of bytes from buffer to write. Default: +buffer.byteLength
                      • +
                      • position <integer> The offset from the beginning of the file where the +data from buffer should be written. If position is not a number, +the data will be written at the current position. See the POSIX pwrite(2) +documentation for more detail.
                      • +
                      • Returns: <Promise>
                      -

                      Only present when bigint: true is passed into the method that generates -the object. -The timestamp indicating the last time this file was accessed expressed in -nanoseconds since the POSIX Epoch.

                      -

                      stats.mtimeNs#

                      - +

                      Write buffer to the file.

                      +

                      If buffer is a plain object, it must have an own (not inherited) toString +function property.

                      +

                      The promise is resolved with an object containing two properties:

                      -

                      Only present when bigint: true is passed into the method that generates -the object. -The timestamp indicating the last time this file was modified expressed in -nanoseconds since the POSIX Epoch.

                      -

                      stats.ctimeNs#

                      +

                      It is unsafe to use filehandle.write() multiple times on the same file +without waiting for the promise to be resolved (or rejected). For this +scenario, use fs.createWriteStream().

                      +

                      On Linux, positional writes do not work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file.

                      +
                      filehandle.write(string[, position[, encoding]])#
                        -
                      • <bigint>
                      • +
                      • string <string> | <Object>
                      • +
                      • position <integer> The offset from the beginning of the file where the +data from string should be written. If position is not a number the +data will be written at the current position. See the POSIX pwrite(2) +documentation for more detail.
                      • +
                      • encoding <string> The expected string encoding. Default: 'utf8'
                      • +
                      • Returns: <Promise>
                      -

                      Only present when bigint: true is passed into the method that generates -the object. -The timestamp indicating the last time the file status was changed expressed -in nanoseconds since the POSIX Epoch.

                      -

                      stats.birthtimeNs#

                      - +

                      Write string to the file. If string is not a string, or an object with an +own toString function property, the promise is rejected with an error.

                      +

                      The promise is resolved with an object containing two properties:

                      -

                      Only present when bigint: true is passed into the method that generates -the object. -The timestamp indicating the creation time of this file expressed in -nanoseconds since the POSIX Epoch.

                      -

                      stats.atime#

                      +

                      It is unsafe to use filehandle.write() multiple times on the same file +without waiting for the promise to be resolved (or rejected). For this +scenario, use fs.createWriteStream().

                      +

                      On Linux, positional writes do not work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file.

                      +
                      filehandle.writeFile(data, options)#
                      +

                      Asynchronously writes data to a file, replacing the file if it already exists. +data can be a string, a buffer, an <AsyncIterable> or <Iterable> object, or an +object with an own toString function +property. The promise is resolved with no arguments upon success.

                      +

                      If options is a string, then it specifies the encoding.

                      +

                      The <FileHandle> has to support writing.

                      +

                      It is unsafe to use filehandle.writeFile() multiple times on the same file +without waiting for the promise to be resolved (or rejected).

                      +

                      If one or more filehandle.write() calls are made on a file handle and then a +filehandle.writeFile() call is made, the data will be written from the +current position till the end of the file. It doesn't always write from the +beginning of the file.

                      +
                      filehandle.writev(buffers[, position])#
                      -

                      The timestamp indicating the last time this file was modified.

                      -

                      stats.ctime#

                      +

                      Write an array of <ArrayBufferView>s to the file.

                      +

                      The promise is resolved with an object containing a two properties:

                      + +

                      It is unsafe to call writev() multiple times on the same file without waiting +for the promise to be resolved (or rejected).

                      +

                      On Linux, positional writes don't work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file.

                      +

                      fsPromises.access(path[, mode])#

                      -

                      The timestamp indicating the last time the file status was changed.

                      -

                      stats.birthtime#

                      +

                      Tests a user's permissions for the file or directory specified by path. +The mode argument is an optional integer that specifies the accessibility +checks to be performed. Check File access constants for possible values +of mode. It is possible to create a mask consisting of the bitwise OR of +two or more values (e.g. fs.constants.W_OK | fs.constants.R_OK).

                      +

                      If the accessibility check is successful, the promise is resolved with no +value. If any of the accessibility checks fail, the promise is rejected +with an <Error> object. The following example checks if the file +/etc/passwd can be read and written by the current process.

                      +
                      import { access } from 'fs/promises';
                      +import { constants } from 'fs';
                      +
                      +try {
                      +  await access('/etc/passwd', constants.R_OK | constants.W_OK);
                      +  console.log('can access');
                      +} catch {
                      +  console.error('cannot access');
                      +}
                      +

                      Using fsPromises.access() to check for the accessibility of a file before +calling fsPromises.open() is not recommended. Doing so introduces a race +condition, since other processes may change the file's state between the two +calls. Instead, user code should open/read/write the file directly and handle +the error raised if the file is not accessible.

                      +

                      fsPromises.appendFile(path, data[, options])#

                        -
                      • <Date>
                      • +
                      • path <string> | <Buffer> | <URL> | <FileHandle> filename or <FileHandle>
                      • +
                      • data <string> | <Buffer>
                      • +
                      • options <Object> | <string> + -

                        The timestamp indicating the creation time of this file.

                        -

                        Stat time values#

                        -

                        The atimeMs, mtimeMs, ctimeMs, birthtimeMs properties are -numeric values that hold the corresponding times in milliseconds. Their -precision is platform specific. When bigint: true is passed into the -method that generates the object, the properties will be bigints, -otherwise they will be numbers.

                        -

                        The atimeNs, mtimeNs, ctimeNs, birthtimeNs properties are -bigints that hold the corresponding times in nanoseconds. They are -only present when bigint: true is passed into the method that generates -the object. Their precision is platform specific.

                        -

                        atime, mtime, ctime, and birthtime are -Date object alternate representations of the various times. The -Date and number values are not connected. Assigning a new number value, or -mutating the Date value, will not be reflected in the corresponding alternate -representation.

                        -

                        The times in the stat object have the following semantics:

                        +
                      • +
                      • Returns: <Promise> Fulfills with undefined upon success.
                      • +
                      +

                      Asynchronously append data to a file, creating the file if it does not yet +exist. data can be a string or a <Buffer>.

                      +

                      If options is a string, then it specifies the encoding.

                      +

                      The mode option only affects the newly created file. See fs.open() +for more details.

                      +

                      The path may be specified as a <FileHandle> that has been opened +for appending (using fsPromises.open()).

                      +

                      fsPromises.chmod(path, mode)#

                      +
                        -
                      • atime "Access Time": Time when file data last accessed. Changed -by the mknod(2), utimes(2), and read(2) system calls.
                      • -
                      • mtime "Modified Time": Time when file data last modified. -Changed by the mknod(2), utimes(2), and write(2) system calls.
                      • -
                      • ctime "Change Time": Time when file status was last changed -(inode data modification). Changed by the chmod(2), chown(2), -link(2), mknod(2), rename(2), unlink(2), utimes(2), -read(2), and write(2) system calls.
                      • -
                      • birthtime "Birth Time": Time of file creation. Set once when the -file is created. On filesystems where birthtime is not available, -this field may instead hold either the ctime or -1970-01-01T00:00Z (ie, Unix epoch timestamp 0). This value may be greater -than atime or mtime in this case. On Darwin and other FreeBSD variants, -also set if the atime is explicitly set to an earlier value than the current -birthtime using the utimes(2) system call.
                      • +
                      • path <string> | <Buffer> | <URL>
                      • +
                      • mode <string> | <integer>
                      • +
                      • Returns: <Promise> Fulfills with undefined upon success.
                      -

                      Prior to Node.js 0.12, the ctime held the birthtime on Windows systems. As -of 0.12, ctime is not "creation time", and on Unix systems, it never was.

                      -

                      Class: fs.WriteStream#

                      +

                      Changes the permissions of a file.

                      +

                      fsPromises.chown(path, uid, gid)#

                      -

                      Instances of fs.WriteStream are created and returned using the -fs.createWriteStream() function.

                      -

                      Event: 'close'#

                      +

                      Changes the ownership of a file.

                      +

                      fsPromises.copyFile(src, dest[, mode])#

                      -

                      Emitted when the WriteStream's underlying file descriptor has been closed.

                      -

                      Event: 'open'#

                      +
                        +
                      • src <string> | <Buffer> | <URL> source filename to copy
                      • +
                      • dest <string> | <Buffer> | <URL> destination filename of the copy operation
                      • +
                      • mode <integer> Optional modifiers that specify the behavior of the copy +operation. It is possible to create a mask consisting of the bitwise OR of +two or more values (e.g. +fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE) +Default: 0. +
                          +
                        • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest +already exists.
                        • +
                        • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create +a copy-on-write reflink. If the platform does not support copy-on-write, +then a fallback copy mechanism is used.
                        • +
                        • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to +create a copy-on-write reflink. If the platform does not support +copy-on-write, then the operation will fail.
                        • +
                        +
                      • +
                      • Returns: <Promise> Fulfills with undefined upon success.
                      • +
                      +

                      Asynchronously copies src to dest. By default, dest is overwritten if it +already exists.

                      +

                      No guarantees are made about the atomicity of the copy operation. If an +error occurs after the destination file has been opened for writing, an attempt +will be made to remove the destination.

                      +
                      import { constants } from 'fs';
                      +import { copyFile } from 'fs/promises';
                      +
                      +try {
                      +  await copyFile('source.txt', 'destination.txt');
                      +  console.log('source.txt was copied to destination.txt');
                      +} catch {
                      +  console.log('The file could not be copied');
                      +}
                      +
                      +// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
                      +try {
                      +  await copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL);
                      +  console.log('source.txt was copied to destination.txt');
                      +} catch {
                      +  console.log('The file could not be copied');
                      +}
                      +

                      fsPromises.lchmod(path, mode)#

                      -

                      Emitted when the WriteStream's file is opened.

                      -

                      Event: 'ready'#

                      +

                      Changes the permissions on a symbolic link.

                      +

                      This method is only implemented on macOS.

                      +

                      fsPromises.lchown(path, uid, gid)#

                      -

                      Emitted when the fs.WriteStream is ready to be used.

                      -

                      Fires immediately after 'open'.

                      -

                      writeStream.bytesWritten#

                      + +

                      Changes the ownership on a symbolic link.

                      +

                      fsPromises.lutimes(path, atime, mtime)#

                      -

                      The number of bytes written so far. Does not include data that is still queued -for writing.

                      -

                      writeStream.path#

                      + +

                      Changes the access and modification times of a file in the same way as +fsPromises.utimes(), with the difference that if the path refers to a +symbolic link, then the link is not dereferenced: instead, the timestamps of +the symbolic link itself are changed.

                      +

                      fsPromises.link(existingPath, newPath)#

                      -

                      The path to the file the stream is writing to as specified in the first -argument to fs.createWriteStream(). If path is passed as a string, then -writeStream.path will be a string. If path is passed as a Buffer, then -writeStream.path will be a Buffer.

                      -

                      writeStream.pending#

                      + +

                      Creates a new link from the existingPath to the newPath. See the POSIX +link(2) documentation for more detail.

                      +

                      fsPromises.lstat(path[, options])#

                        -
                      • <boolean>
                      • +
                      • path <string> | <Buffer> | <URL>
                      • +
                      • options <Object> +
                          +
                        • bigint <boolean> Whether the numeric values in the returned +<fs.Stats> object should be bigint. Default: false.
                        -

                        This property is true if the underlying file has not been opened yet, -i.e. before the 'ready' event is emitted.

                        -

                        fs.access(path[, mode], callback)#

                        +
                      • +
                      • Returns: <Promise> Fulfills with the <fs.Stats> object for the given +symbolic link path.
                      • +
                      +

                      Equivalent to fsPromises.stat() unless path refers to a symbolic link, +in which case the link itself is stat-ed, not the file that it refers to. +Refer to the POSIX lstat(2) document for more detail.

                      +

                      fsPromises.mkdir(path[, options])#

                      + + +

                      Asynchronously creates a directory.

                      +

                      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 directories should be created. Calling +fsPromises.mkdir() when path is a directory that exists results in a +rejection only when recursive is false.

                      +

                      fsPromises.mkdtemp(prefix[, options])#

                      + +
                        +
                      • prefix <string>
                      • +
                      • options <string> | <Object> + +
                      • +
                      • Returns: <Promise> Fulfills with a string containing the filesystem path +of the newly created temporary directory.
                      • +
                      +

                      Creates a unique temporary directory. A unique directory name is generated by +appending six random characters to the end of the provided prefix. Due to +platform inconsistencies, avoid trailing X characters in prefix. Some +platforms, notably the BSDs, can return more than six random characters, and +replace trailing X characters in prefix with random characters.

                      +

                      The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use.

                      +
                      import { mkdtemp } from 'fs/promises';
                      +
                      +try {
                      +  await mkdtemp(path.join(os.tmpdir(), 'foo-'));
                      +} catch (err) {
                      +  console.error(err);
                      +}
                      +

                      The fsPromises.mkdtemp() method will append the six randomly selected +characters directly to the prefix string. For instance, given a directory +/tmp, if the intention is to create a temporary directory within /tmp, the +prefix must end with a trailing platform-specific path separator +(require('path').sep).

                      +

                      fsPromises.open(path, flags[, mode])#

                      + + +

                      Opens a <FileHandle>.

                      +

                      Refer to the POSIX open(2) documentation for more detail.

                      +

                      Some characters (< > : " / \ | ? *) are reserved under Windows as documented +by Naming Files, Paths, and Namespaces. Under NTFS, if the filename contains +a colon, Node.js will open a file system stream, as described by +this MSDN page.

                      +

                      fsPromises.opendir(path[, options])#

                      + +
                        +
                      • path <string> | <Buffer> | <URL>
                      • +
                      • options <Object> +
                          +
                        • encoding <string> | <null> Default: 'utf8'
                        • +
                        • bufferSize <number> Number of directory entries that are buffered +internally when reading from the directory. Higher values lead to better +performance but higher memory usage. Default: 32
                        • +
                        +
                      • +
                      • Returns: <Promise> Fulfills with an <fs.Dir>.
                      • +
                      +

                      Asynchronously open a directory for iterative scanning. See the POSIX +opendir(3) documentation for more detail.

                      +

                      Creates an <fs.Dir>, which contains all further functions for reading from +and cleaning up the directory.

                      +

                      The encoding option sets the encoding for the path while opening the +directory and subsequent read operations.

                      +

                      Example using async iteration:

                      +
                      import { opendir } from 'fs/promises';
                      +
                      +try {
                      +  const dir = await opendir('./');
                      +  for await (const dirent of dir)
                      +    console.log(dirent.name);
                      +} catch (err) {
                      +  console.error(err);
                      +}
                      +

                      When using the async iterator, the <fs.Dir> object will be automatically +closed after the iterator exits.

                      +

                      fsPromises.readdir(path[, options])#

                      + + +

                      Reads the contents of a directory.

                      +

                      The optional options argument can be a string specifying an encoding, or an +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.

                      +
                      import { readdir } from 'fs/promises';
                      +
                      +try {
                      +  const files = await readdir(path);
                      +  for (const file of files)
                      +    console.log(file);
                      +} catch (err) {
                      +  console.error(err);
                      +}
                      +

                      fsPromises.readFile(path[, options])#

                      + + +

                      Asynchronously reads the entire contents of a file.

                      +

                      If no encoding is specified (using options.encoding), the data is returned +as a <Buffer> object. Otherwise, the data will be a string.

                      +

                      If options is a string, then it specifies the encoding.

                      +

                      When the path is a directory, the behavior of fsPromises.readFile() is +platform-specific. On macOS, Linux, and Windows, the promise will be rejected +with an error. On FreeBSD, a representation of the directory's contents will be +returned.

                      +

                      It is possible to abort an ongoing readFile using an <AbortSignal>. If a +request is aborted the promise returned is rejected with an AbortError:

                      +
                      import { readFile } from 'fs/promises';
                      +
                      +try {
                      +  const controller = new AbortController();
                      +  const { signal } = controller;
                      +  const promise = readFile(fileName, { signal });
                      +
                      +  // Abort the request before the promise settles.
                      +  controller.abort();
                      +
                      +  await promise;
                      +} catch (err) {
                      +  // When a request is aborted - err is an AbortError
                      +  console.error(err);
                      +}
                      +

                      Aborting an ongoing request does not abort individual operating +system requests but rather the internal buffering fs.readFile performs.

                      +

                      Any specified <FileHandle> has to support reading.

                      +

                      fsPromises.readlink(path[, options])#

                      + + +

                      Reads the contents of the symbolic link referred to by path. See the POSIX +readlink(2) documentation for more detail. The promise is resolved with the +linkString upon success.

                      +

                      The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use for +the link path returned. If the encoding is set to 'buffer', the link path +returned will be passed as a <Buffer> object.

                      +

                      fsPromises.realpath(path[, options])#

                      + + +

                      Determines the actual location of path using the same semantics as the +fs.realpath.native() function.

                      +

                      Only paths that can be converted to UTF8 strings are supported.

                      +

                      The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use for +the path. If the encoding is set to 'buffer', the path returned will be +passed as a <Buffer> object.

                      +

                      On Linux, when Node.js is linked against musl libc, the procfs file system must +be mounted on /proc in order for this function to work. Glibc does not have +this restriction.

                      +

                      fsPromises.rename(oldPath, newPath)#

                      + + +

                      Renames oldPath to newPath.

                      +

                      fsPromises.rmdir(path[, options])#

                      + +
                        +
                      • path <string> | <Buffer> | <URL>
                      • +
                      • options <Object> +
                          +
                        • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or +EPERM error is encountered, Node.js retries the operation with a linear +backoff wait of retryDelay milliseconds longer on each try. This option +represents the number of retries. This option is ignored if the recursive +option is not true. Default: 0.
                        • +
                        • recursive <boolean> If true, perform a recursive directory removal. In +recursive mode, errors are not reported if path does not exist, and +operations are retried on failure. Default: false.
                        • +
                        • retryDelay <integer> The amount of time in milliseconds to wait between +retries. This option is ignored if the recursive option is not true. +Default: 100.
                        • +
                        +
                      • +
                      • Returns: <Promise> Fulfills with undefined upon success.
                      • +
                      +

                      Removes the directory identified by path.

                      +

                      Using fsPromises.rmdir() on a file (not a directory) results in the +promise being rejected with an ENOENT error on Windows and an ENOTDIR +error on POSIX.

                      +

                      Setting recursive to true results in behavior similar to the Unix command +rm -rf: an error will not be raised for paths that do not exist, and paths +that represent files will be deleted. The permissive behavior of the +recursive option is deprecated, ENOTDIR and ENOENT will be thrown in +the future.

                      +

                      fsPromises.rm(path[, options])#

                      + +
                        +
                      • path <string> | <Buffer> | <URL>
                      • +
                      • options <Object> +
                          +
                        • force <boolean> When true, exceptions will be ignored if path does +not exist. Default: false.
                        • +
                        • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or +EPERM error is encountered, Node.js will retry the operation with a linear +backoff wait of retryDelay milliseconds longer on each try. This option +represents the number of retries. This option is ignored if the recursive +option is not true. Default: 0.
                        • +
                        • recursive <boolean> If true, perform a recursive directory removal. In +recursive mode operations are retried on failure. Default: false.
                        • +
                        • retryDelay <integer> The amount of time in milliseconds to wait between +retries. This option is ignored if the recursive option is not true. +Default: 100.
                        • +
                        +
                      • +
                      • Returns: <Promise> Fulfills with undefined upon success.
                      • +
                      +

                      Removes files and directories (modeled on the standard POSIX rm utility).

                      +

                      fsPromises.stat(path[, options])#

                      + + +

                      fsPromises.symlink(target, path[, type])#

                      + + +

                      Creates a symbolic link.

                      +

                      The type argument is only used on Windows platforms and can be one of 'dir', +'file', or 'junction'. Windows junction points require the destination path +to be absolute. When using 'junction', the target argument will +automatically be normalized to absolute path.

                      +

                      fsPromises.truncate(path[, len])#

                      + + +

                      Truncates (shortens or extends the length) of the content at path to len +bytes.

                      +

                      fsPromises.unlink(path)#

                      + + +

                      If path refers to a symbolic link, then the link is removed without affecting +the file or directory to which that link refers. If the path refers to a file +path that is not a symbolic link, the file is deleted. See the POSIX unlink(2) +documentation for more detail.

                      +

                      fsPromises.utimes(path, atime, mtime)#

                      + + +

                      Change the file system timestamps of the object referenced by path.

                      +

                      The atime and mtime arguments follow these rules:

                      +
                        +
                      • Values can be either numbers representing Unix epoch time, Dates, or a +numeric string like '123456789.0'.
                      • +
                      • If the value can not be converted to a number, or is NaN, Infinity or +-Infinity, an Error will be thrown.
                      • +
                      +

                      fsPromises.watch(filename[, options])#

                      + +
                        +
                      • filename <string> | <Buffer> | <URL>
                      • +
                      • options <string> | <Object> +
                          +
                        • persistent <boolean> Indicates whether the process should continue to run +as long as files are being watched. Default: true.
                        • +
                        • recursive <boolean> Indicates whether all subdirectories should be +watched, or only the current directory. This applies when a directory is +specified, and only on supported platforms (See caveats). Default: +false.
                        • +
                        • encoding <string> Specifies the character encoding to be used for the +filename passed to the listener. Default: 'utf8'.
                        • +
                        • signal <AbortSignal> An <AbortSignal> used to signal when the watcher +should stop.
                        • +
                        +
                      • +
                      • Returns: <AsyncIterator> of objects with the properties: + +
                      • +
                      +

                      Returns an async iterator that watches for changes on filename, where filename +is either a file or a directory.

                      +
                      const { watch } = require('fs/promises');
                      +
                      +const ac = new AbortController();
                      +const { signal } = ac;
                      +setTimeout(() => ac.abort(), 10000);
                      +
                      +(async () => {
                      +  try {
                      +    const watcher = watch(__filename, { signal });
                      +    for await (const event of watcher)
                      +      console.log(event);
                      +  } catch (err) {
                      +    if (err.name === 'AbortError')
                      +      return;
                      +    throw err;
                      +  }
                      +})();
                      +

                      On most platforms, 'rename' is emitted whenever a filename appears or +disappears in the directory.

                      +

                      All the caveats for fs.watch() also apply to fsPromises.watch().

                      +

                      fsPromises.writeFile(file, data[, options])#

                      + + +

                      Asynchronously writes data to a file, replacing the file if it already exists. +data can be a string, a <Buffer>, or, an object with an own (not inherited) +toString function property.

                      +

                      The encoding option is ignored if data is a buffer.

                      +

                      If options is a string, then it specifies the encoding.

                      +

                      The mode option only affects the newly created file. See fs.open() +for more details.

                      +

                      Any specified <FileHandle> has to support writing.

                      +

                      It is unsafe to use fsPromises.writeFile() multiple times on the same file +without waiting for the promise to be settled.

                      +

                      Similarly to fsPromises.readFile - fsPromises.writeFile is a convenience +method that performs multiple write calls internally to write the buffer +passed to it. For performance sensitive code consider using +fs.createWriteStream().

                      +

                      It is possible to use an <AbortSignal> to cancel an fsPromises.writeFile(). +Cancelation is "best effort", and some amount of data is likely still +to be written.

                      +
                      import { writeFile } from 'fs/promises';
                      +
                      +try {
                      +  const controller = new AbortController();
                      +  const { signal } = controller;
                      +  const data = new Uint8Array(Buffer.from('Hello Node.js'));
                      +  const promise = writeFile('message.txt', data, { signal });
                      +
                      +  // Abort the request before the promise settles.
                      +  controller.abort();
                      +
                      +  await promise;
                      +} catch (err) {
                      +  // When a request is aborted - err is an AbortError
                      +  console.error(err);
                      +}
                      +

                      Aborting an ongoing request does not abort individual operating +system requests but rather the internal buffering fs.writeFile performs.

                      +

                      Callback API#

                      +

                      The callback APIs perform all operations asynchronously, without blocking the +event loop, then invoke a callback function upon completion or error.

                      +

                      The callback APIs use the underlying Node.js threadpool to perform file +system operations off the event loop thread. These operations are not +synchronized or threadsafe. Care must be taken when performing multiple +concurrent modifications on the same file or data corruption may occur.

                      +

                      fs.access(path[, mode], callback)#

                      - -

                      Synchronously tests a user's permissions for the file or directory specified -by path. The mode argument is an optional integer that specifies the -accessibility checks to be performed. Check File access constants for -possible values of mode. It is possible to create a mask consisting of -the bitwise OR of two or more values -(e.g. fs.constants.W_OK | fs.constants.R_OK).

                      -

                      If any of the accessibility checks fail, an Error will be thrown. Otherwise, -the method will return undefined.

                      -
                      try {
                      -  fs.accessSync('etc/passwd', fs.constants.R_OK | fs.constants.W_OK);
                      -  console.log('can read/write');
                      -} catch (err) {
                      -  console.error('no access!');
                      -}
                      -

                      fs.appendFile(path, data[, options], callback)#

                      +

                      fs.appendFile(path, data[, options], callback)#

                      - -

                      Synchronously append data to a file, creating the file if it does not yet -exist. data can be a string or a Buffer.

                      -
                      try {
                      -  fs.appendFileSync('message.txt', 'data to append');
                      -  console.log('The "data to append" was appended to file!');
                      -} catch (err) {
                      -  /* Handle the error */
                      -}
                      -

                      If options is a string, then it specifies the encoding:

                      -
                      fs.appendFileSync('message.txt', 'data to append', 'utf8');
                      -

                      The path may be specified as a numeric file descriptor that has been opened -for appending (using fs.open() or fs.openSync()). The file descriptor will -not be closed automatically.

                      -
                      let fd;
                      -
                      -try {
                      -  fd = fs.openSync('message.txt', 'a');
                      -  fs.appendFileSync(fd, 'data to append', 'utf8');
                      -} catch (err) {
                      -  /* Handle the error */
                      -} finally {
                      -  if (fd !== undefined)
                      -    fs.closeSync(fd);
                      -}
                      -

                      fs.chmod(path, mode, callback)#

                      +

                      fs.chmod(path, mode, callback)#

                      - -

                      For detailed information, see the documentation of the asynchronous version of -this API: fs.chmod().

                      -

                      See also: chmod(2).

                      -

                      fs.chown(path, uid, gid, callback)#

                      +

                      fs.chown(path, uid, gid, callback)#

                      - -

                      Synchronously changes owner and group of a file. Returns undefined. -This is the synchronous version of fs.chown().

                      -

                      See also: chown(2).

                      -

                      fs.close(fd, callback)#

                      +

                      See the POSIX chown(2) documentation for more detail.

                      +

                      fs.close(fd[, callback])#

                      - -

                      Synchronously copies src to dest. By default, dest is overwritten if it -already exists. Returns undefined. Node.js makes no guarantees about the -atomicity of the copy operation. If an error occurs after the destination file -has been opened for writing, Node.js will attempt to remove the destination.

                      -

                      flags is an optional integer that specifies the behavior -of the copy operation. It is possible to create a mask consisting of the bitwise -OR of two or more values (e.g. -fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

                      -
                        -
                      • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest already -exists.
                      • -
                      • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create a -copy-on-write reflink. If the platform does not support copy-on-write, then a -fallback copy mechanism is used.
                      • -
                      • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to -create a copy-on-write reflink. If the platform does not support copy-on-write, -then the operation will fail.
                      • -
                      -
                      const fs = require('fs');
                      +  console.log('source.txt was copied to destination.txt');
                      +}
                       
                       // destination.txt will be created or overwritten by default.
                      -fs.copyFileSync('source.txt', 'destination.txt');
                      -console.log('source.txt was copied to destination.txt');
                      -

                      If the third argument is a number, then it specifies flags:

                      -
                      const fs = require('fs');
                      -const { COPYFILE_EXCL } = fs.constants;
                      +copyFile('source.txt', 'destination.txt', callback);
                       
                       // By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
                      -fs.copyFileSync('source.txt', 'destination.txt', COPYFILE_EXCL);
                      -

                      fs.createReadStream(path[, options])#

                      +copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL, callback);
                      +

                      fs.createReadStream(path[, options])#

                      - -

                      Returns true if the path exists, false otherwise.

                      -

                      For detailed information, see the documentation of the asynchronous version of -this API: fs.exists().

                      -

                      fs.exists() is deprecated, but fs.existsSync() is not. The callback -parameter to fs.exists() accepts parameters that are inconsistent with other -Node.js callbacks. fs.existsSync() does not use a callback.

                      -
                      if (fs.existsSync('/etc/passwd')) {
                      -  console.log('The path exists.');
                      -}
                      -

                      fs.fchmod(fd, mode, callback)#

                      +

                      fs.fchmod(fd, mode, callback)#

                      - -

                      Synchronous fstat(2).

                      -

                      fs.fsync(fd, callback)#

                      +

                      Invokes the callback with the <fs.Stats> for the file descriptor.

                      +

                      See the POSIX fstat(2) documentation for more detail.

                      +

                      fs.fsync(fd, callback)#

                      - -

                      Synchronous version of fs.futimes(). Returns undefined.

                      -

                      fs.lchmod(path, mode, callback)#

                      +

                      fs.lchmod(path, mode, callback)#

                      - -

                      Synchronous lchown(2). Returns undefined.

                      -

                      fs.lutimes(path, atime, mtime, callback)#

                      +

                      Set the owner of the symbolic link. No arguments other than a possible +exception are given to the completion callback.

                      +

                      See the POSIX lchown(2) documentation for more detail.

                      +

                      fs.lutimes(path, atime, mtime, callback)#

                      • path <string> | <Buffer> | <URL>
                      • @@ -31440,19 +33481,7 @@ link, then the link is not dereferenced: instead, the timestamps of the symbolic link itself are changed.

                        No arguments other than a possible exception are given to the completion callback.

                        -

                        fs.lutimesSync(path, atime, mtime)#

                        - - -

                        Change the file system timestamps of the symbolic link referenced by path. -Returns undefined, or throws an exception when parameters are incorrect or -the operation fails. This is the synchronous version of fs.lutimes().

                        -

                        fs.link(existingPath, newPath, callback)#

                        +

                        fs.link(existingPath, newPath, callback)#

                        - -

                        Synchronous link(2). Returns undefined.

                        -

                        fs.lstat(path[, options], callback)#

                        +

                        Creates a new link from the existingPath to the newPath. See the POSIX +link(2) documentation for more detail. No arguments other than a possible +exception are given to the completion callback.

                        +

                        fs.lstat(path[, options], callback)#

                        - -

                        Synchronous lstat(2).

                        -

                        fs.mkdir(path[, options], callback)#

                        +

                        Retrieves the <fs.Stats> for the symbolic link referred to by the path. +The callback gets two arguments (err, stats) where stats is a <fs.Stats> +object. lstat() is identical to stat(), except that if path is a symbolic +link, then the link itself is stat-ed, not the file that it refers to.

                        +

                        See the POSIX lstat(2) documentation for more details.

                        +

                        fs.mkdir(path[, options], callback)#

                        - -

                        Synchronously creates a directory. Returns undefined, or if recursive is -true, the first directory path created. -This is the synchronous version of fs.mkdir().

                        -

                        See also: mkdir(2).

                        -

                        fs.mkdtemp(prefix[, options], callback)#

                        +

                        See the POSIX mkdir(2) documentation for more details.

                        +

                        fs.mkdtemp(prefix[, options], callback)#

                    -

                    Asynchronous file open. See open(2).

                    +

                    Asynchronous file open. See the POSIX open(2) documentation for more details.

                    mode sets the file mode (permission and sticky bits), but only if the file was created. On Windows, only the write permission can be manipulated; see fs.chmod().

                    @@ -31768,12 +33722,12 @@ a colon, Node.js will open a file system stream, as described by this MSDN page.

                    Functions based on fs.open() exhibit this behavior as well: fs.writeFile(), fs.readFile(), etc.

                    -

                    fs.opendir(path[, options], callback)#

                    +

                    fs.opendir(path[, options], callback)#

                    -
                      -
                    • path <string> | <Buffer> | <URL>
                    • -
                    • options <Object> -
                        -
                      • encoding <string> | <null> Default: 'utf8'
                      • -
                      • bufferSize <number> Number of directory entries that are buffered -internally when reading from the directory. Higher values lead to better -performance but higher memory usage. Default: 32
                      • -
                      -
                    • -
                    • Returns: <fs.Dir>
                    • -
                    -

                    Synchronously open a directory. See opendir(3).

                    -

                    Creates an fs.Dir, which contains all further functions for reading from +

                    Asynchronously open a directory. See the POSIX opendir(3) documentation for +more details.

                    +

                    Creates an <fs.Dir>, which contains all further functions for reading from and cleaning up the directory.

                    The encoding option sets the encoding for the path while opening the directory and subsequent read operations.

                    -

                    fs.openSync(path[, flags, mode])#

                    - - -

                    Returns an integer representing the file descriptor.

                    -

                    For detailed information, see the documentation of the asynchronous version of -this API: fs.open().

                    -

                    fs.read(fd, buffer, offset, length, position, callback)#

                    +

                    fs.read(fd, buffer, offset, length, position, callback)#

                    @@ -31916,8 +33817,8 @@ a Promise for an Object with bytesRead an
                  • callback <Function> @@ -31928,9 +33829,10 @@ a Promise for an Object with bytesRead an
                -

                Similar to the above fs.read function, this version takes an optional options object. -If no options object is specified, it will default with the above values.

                -

                fs.readdir(path[, options], callback)#

                +

                Similar to the fs.read() function, this version takes an optional +options object. If no options object is specified, it will default with the +above values.

                +

                fs.readdir(path[, options], callback)#

                - -

                Synchronous readdir(3).

                -

                The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the filenames returned. If the encoding is set to 'buffer', -the filenames returned will be passed as Buffer objects.

                -

                If options.withFileTypes is set to true, the result will contain -fs.Dirent objects.

                -

                fs.readFile(path[, options], callback)#

                +<fs.Dirent> objects.

                +

                fs.readFile(path[, options], callback)#

                - -

                Returns the contents of the path.

                -

                For detailed information, see the documentation of the asynchronous version of -this API: fs.readFile().

                -

                If the encoding option is specified then this function returns a -string. Otherwise it returns a buffer.

                -

                Similar to fs.readFile(), when the path is a directory, the behavior of -fs.readFileSync() is platform-specific.

                -
                // macOS, Linux, and Windows
                -fs.readFileSync('<directory>');
                -// => [Error: EISDIR: illegal operation on a directory, read <directory>]
                -
                -//  FreeBSD
                -fs.readFileSync('<directory>'); // => <data>
                -

                fs.readlink(path[, options], callback)#

                +
                Performance Considerations#
                +

                The fs.readFile() method asynchronously reads the contents of a file into +memory one chunk at a time, allowing the event loop to turn between each chunk. +This allows the read operation to have less impact on other activity that may +be using the underlying libuv thread pool but means that it will take longer +to read a complete file into memory.

                +

                The additional read overhead can vary broadly on different systems and depends +on the type of file being read. If the file type is not a regular file (a pipe +for instance) and Node.js is unable to determine an actual file size, each read +operation will load on 64kb of data. For regular files, each read will process +512kb of data.

                +

                For applications that require as-fast-as-possible reading of file contents, it +is better to use fs.read() directly and for application code to manage +reading the full contents of the file itself.

                +

                The Node.js GitHub issue #25741 provides more information and a detailed +analysis on the performance of fs.readFile() for multiple file sizes in +different Node.js versions.

                +

                fs.readlink(path[, options], callback)#

                - -

                Synchronous readlink(2). Returns the symbolic link's string value.

                -

                The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the link path returned. If the encoding is set to 'buffer', -the link path returned will be passed as a Buffer object.

                -

                fs.readSync(fd, buffer, offset, length, position)#

                - - -

                Returns the number of bytesRead.

                -

                For detailed information, see the documentation of the asynchronous version of -this API: fs.read().

                -

                fs.readSync(fd, buffer, [options])#

                - - -

                Returns the number of bytesRead.

                -

                Similar to the above fs.readSync function, this version takes an optional options object. -If no options object is specified, it will default with the above values.

                -

                For detailed information, see the documentation of the asynchronous version of -this API: fs.read().

                -

                fs.readv(fd, buffers[, position], callback)#

                +the link path returned will be passed as a <Buffer> object.

                +

                fs.readv(fd, buffers[, position], callback)#

                • fd <integer>
                • @@ -32251,20 +34047,8 @@ from the current position.

                  The callback will be given three arguments: err, bytesRead, and buffers. bytesRead is how many bytes were read from the file.

                  If this method is invoked as its util.promisify()ed version, it returns -a Promise for an Object with bytesRead and buffers properties.

                  -

                  fs.readvSync(fd, buffers[, position])#

                  - - -

                  For detailed information, see the documentation of the asynchronous version of -this API: fs.readv().

                  -

                  fs.realpath(path[, options], callback)#

                  +a promise for an Object with bytesRead and buffers properties.

                  +

                  fs.realpath(path[, options], callback)#

                  - -

                  Returns the resolved pathname.

                  -

                  For detailed information, see the documentation of the asynchronous version of -this API: fs.realpath().

                  -

                  fs.realpathSync.native(path[, options])#

                  - - -

                  Synchronous realpath(3).

                  -

                  Only paths that can be converted to UTF8 strings are supported.

                  -

                  The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the path returned. If the encoding is set to 'buffer', -the path returned will be passed as a Buffer object.

                  +the path returned will be passed as a <Buffer> object.

                  On Linux, when Node.js is linked against musl libc, the procfs file system must be mounted on /proc in order for this function to work. Glibc does not have this restriction.

                  -

                  fs.rename(oldPath, newPath, callback)#

                  +

                  fs.rename(oldPath, newPath, callback)#

                  - -

                  Synchronous rename(2). Returns undefined.

                  -

                  fs.rmdir(path[, options], callback)#

                  +

                  fs.rmdir(path[, options], callback)#

                  -

                  Stability: 1 - Recursive removal is experimental.

                  • path <string> | <Buffer> | <URL>
                  • options <Object>
                    • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or -EPERM error is encountered, Node.js will retry the operation with a linear -backoff wait of retryDelay ms longer on each try. This option represents the -number of retries. This option is ignored if the recursive option is not -true. Default: 0.
                    • +EPERM error is encountered, Node.js retries the operation with a linear +backoff wait of retryDelay milliseconds longer on each try. This option +represents the number of retries. This option is ignored if the recursive +option is not true. Default: 0.
                    • recursive <boolean> If true, perform a recursive directory removal. In recursive mode, errors are not reported if path does not exist, and operations are retried on failure. Default: false.
                    • @@ -32503,45 +34221,43 @@ retries. This option is ignored if the recursive option is not

                      Using fs.rmdir() on a file (not a directory) results in an ENOENT error on Windows and an ENOTDIR error on POSIX.

                      -

                      fs.rmdirSync(path[, options])#

                      +

                      Setting recursive to true results in behavior similar to the Unix command +rm -rf: an error will not be raised for paths that do not exist, and paths +that represent files will be deleted. The permissive behavior of the +recursive option is deprecated, ENOTDIR and ENOENT will be thrown in +the future.

                      +

                      fs.rm(path[, options], callback)#

                      -

                      Stability: 1 - Recursive removal is experimental.

                      • path <string> | <Buffer> | <URL>
                      • options <Object>
                          +
                        • force <boolean> When true, exceptions will be ignored if path does +not exist. Default: false.
                        • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or EPERM error is encountered, Node.js will retry the operation with a linear -backoff wait of retryDelay ms longer on each try. This option represents the -number of retries. This option is ignored if the recursive option is not -true. Default: 0.
                        • -
                        • recursive <boolean> If true, perform a recursive directory removal. In -recursive mode, errors are not reported if path does not exist, and -operations are retried on failure. Default: false.
                        • +backoff wait of retryDelay milliseconds longer on each try. This option +represents the number of retries. This option is ignored if the recursive +option is not true. Default: 0. +
                        • recursive <boolean> If true, perform a recursive removal. In +recursive mode operations are retried on failure. Default: false.
                        • retryDelay <integer> The amount of time in milliseconds to wait between retries. This option is ignored if the recursive option is not true. Default: 100.
                      • +
                      • callback <Function> + +
                      -

                      Synchronous rmdir(2). Returns undefined.

                      -

                      Using fs.rmdirSync() on a file (not a directory) results in an ENOENT error -on Windows and an ENOTDIR error on POSIX.

                      -

                      fs.stat(path[, options], callback)#

                      +

                      Asynchronously removes files and directories (modeled on the standard POSIX rm +utility). No arguments other than a possible exception are given to the +completion callback.

                      +

                      fs.stat(path[, options], callback)#

                      - -

                      Synchronous stat(2).

                      -

                      fs.symlink(target, path[, type], callback)#

                      +

                      fs.symlink(target, path[, type], callback)#

                      - -

                      Returns undefined.

                      -

                      For detailed information, see the documentation of the asynchronous version of -this API: fs.symlink().

                      -

                      fs.truncate(path[, len], callback)#

                      +

                      fs.truncate(path[, len], callback)#

                      - -

                      Synchronous unlink(2). Returns undefined.

                      -

                      fs.unwatchFile(filename[, listener])#

                      +

                      See the POSIX unlink(2) documentation for more details.

                      +

                      fs.unwatchFile(filename[, listener])#

                      @@ -32836,7 +34493,7 @@ no-op, not an error.

                      Using fs.watch() is more efficient than fs.watchFile() and fs.unwatchFile(). fs.watch() should be used instead of fs.watchFile() and fs.unwatchFile() when possible.

                      -

                      fs.utimes(path, atime, mtime, callback)#

                      +

                      fs.utimes(path, atime, mtime, callback)#

                      - -

                      Returns undefined.

                      -

                      For detailed information, see the documentation of the asynchronous version of -this API: fs.utimes().

                      -

                      fs.watch(filename[, options][, listener])#

                      +

                      fs.watch(filename[, options][, listener])#

                    -

                    fs.write(fd, buffer[, offset[, length[, position]]], callback)#

                    +

                    fs.write(fd, buffer[, offset[, length[, position]]], callback)#

                    - -

                    Returns undefined.

                    -

                    For detailed information, see the documentation of the asynchronous version of -this API: fs.writeFile().

                    -

                    fs.writeSync(fd, buffer[, offset[, length[, position]]])#

                    - - -

                    For detailed information, see the documentation of the asynchronous version of -this API: fs.write(fd, buffer...).

                    -

                    fs.writeSync(fd, string[, position[, encoding]])#

                    - - -

                    For detailed information, see the documentation of the asynchronous version of -this API: fs.write(fd, string...).

                    -

                    fs.writev(fd, buffers[, position], callback)#

                    +

                    fs.writev(fd, buffers[, position], callback)#

                    @@ -33334,588 +34944,769 @@ should be written. If typeof position !== 'number', the data will b at the current position.

                    The callback will be given three arguments: err, bytesWritten, and buffers. bytesWritten is how many bytes were written from buffers.

                    -

                    If this method is util.promisify()ed, it returns a Promise for an +

                    If this method is util.promisify()ed, it returns a promise for an Object with bytesWritten and buffers properties.

                    It is unsafe to use fs.writev() multiple times on the same file without waiting for the callback. For this scenario, use fs.createWriteStream().

                    On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file.

                    -

                    fs.writevSync(fd, buffers[, position])#

                    +

                    Synchronous API#

                    +

                    The synchronous APIs perform all operations synchronously, blocking the +event loop until the operation completes or fails.

                    +

                    fs.accessSync(path[, mode])#

                    -

                    For detailed information, see the documentation of the asynchronous version of -this API: fs.writev().

                    -

                    fs Promises API#

                    -

                    The fs.promises API provides an alternative set of asynchronous file system -methods that return Promise objects rather than using callbacks. The -API is accessible via require('fs').promises.

                    -

                    Class: FileHandle#

                    - -

                    A FileHandle object is a wrapper for a numeric file descriptor. -Instances of FileHandle are distinct from numeric file descriptors -in that they provide an object oriented API for working with files.

                    -

                    If a FileHandle is not closed using the -filehandle.close() method, it might automatically close the file descriptor -and will emit a process warning, thereby helping to prevent memory leaks. -Please do not rely on this behavior because it is unreliable and -the file may not be closed. Instead, always explicitly close FileHandles. -Node.js may change this behavior in the future.

                    -

                    Instances of the FileHandle object are created internally by the -fsPromises.open() method.

                    -

                    Unlike the callback-based API (fs.fstat(), fs.fchown(), fs.fchmod(), and -so on), a numeric file descriptor is not used by the promise-based API. Instead, -the promise-based API uses the FileHandle class in order to help avoid -accidental leaking of unclosed file descriptors after a Promise is resolved or -rejected.

                    -

                    filehandle.appendFile(data, options)#

                    +

                    Synchronously tests a user's permissions for the file or directory specified +by path. The mode argument is an optional integer that specifies the +accessibility checks to be performed. Check File access constants for +possible values of mode. It is possible to create a mask consisting of +the bitwise OR of two or more values +(e.g. fs.constants.W_OK | fs.constants.R_OK).

                    +

                    If any of the accessibility checks fail, an Error will be thrown. Otherwise, +the method will return undefined.

                    +
                    import { accessSync, constants } from 'fs';
                    +
                    +try {
                    +  accessSync('etc/passwd', constants.R_OK | constants.W_OK);
                    +  console.log('can read/write');
                    +} catch (err) {
                    +  console.error('no access!');
                    +}
                    +

                    fs.appendFileSync(path, data[, options])#

                    -

                    Alias of filehandle.writeFile().

                    -

                    When operating on file handles, the mode cannot be changed from what it was set -to with fsPromises.open(). Therefore, this is equivalent to -filehandle.writeFile().

                    -

                    filehandle.chmod(mode)#

                    +

                    Synchronously append data to a file, creating the file if it does not yet +exist. data can be a string or a <Buffer>.

                    +

                    The mode option only affects the newly created file. See fs.open() +for more details.

                    +
                    import { appendFileSync } from 'fs';
                    +
                    +try {
                    +  appendFileSync('message.txt', 'data to append');
                    +  console.log('The "data to append" was appended to file!');
                    +} catch (err) {
                    +  /* Handle the error */
                    +}
                    +

                    If options is a string, then it specifies the encoding:

                    +
                    import { appendFileSync } from 'fs';
                    +
                    +appendFileSync('message.txt', 'data to append', 'utf8');
                    +

                    The path may be specified as a numeric file descriptor that has been opened +for appending (using fs.open() or fs.openSync()). The file descriptor will +not be closed automatically.

                    +
                    import { openSync, closeSync, appendFileSync } from 'fs';
                    +
                    +let fd;
                    +
                    +try {
                    +  fd = openSync('message.txt', 'a');
                    +  appendFileSync(fd, 'data to append', 'utf8');
                    +} catch (err) {
                    +  /* Handle the error */
                    +} finally {
                    +  if (fd !== undefined)
                    +    closeSync(fd);
                    +}
                    +

                    fs.chmodSync(path, mode)#

                    -

                    Modifies the permissions on the file. The Promise is resolved with no -arguments upon success.

                    -

                    filehandle.chown(uid, gid)#

                    +

                    For detailed information, see the documentation of the asynchronous version of +this API: fs.chmod().

                    +

                    See the POSIX chmod(2) documentation for more detail.

                    +

                    fs.chownSync(path, uid, gid)#

                    -

                    Changes the ownership of the file then resolves the Promise with no arguments -upon success.

                    -

                    filehandle.close()#

                    +

                    Synchronously changes owner and group of a file. Returns undefined. +This is the synchronous version of fs.chown().

                    +

                    See the POSIX chown(2) documentation for more detail.

                    +

                    fs.closeSync(fd)#

                      -
                    • Returns: <Promise> A Promise that will be resolved once the underlying -file descriptor is closed, or will be rejected if an error occurs while -closing.
                    • +
                    • fd <integer>
                    -

                    Closes the file descriptor.

                    -
                    const fsPromises = require('fs').promises;
                    -async function openAndClose() {
                    -  let filehandle;
                    -  try {
                    -    filehandle = await fsPromises.open('thefile.txt', 'r');
                    -  } finally {
                    -    if (filehandle !== undefined)
                    -      await filehandle.close();
                    -  }
                    -}
                    -

                    filehandle.datasync()#

                    +

                    Closes the file descriptor. Returns undefined.

                    +

                    Calling fs.closeSync() on any file descriptor (fd) that is currently in use +through any other fs operation may lead to undefined behavior.

                    +

                    See the POSIX close(2) documentation for more detail.

                    +

                    fs.copyFileSync(src, dest[, mode])#

                    -

                    Asynchronous fdatasync(2). The Promise is resolved with no arguments upon -success.

                    -

                    filehandle.fd#

                    - +

                    Synchronously copies src to dest. By default, dest is overwritten if it +already exists. Returns undefined. Node.js makes no guarantees about the +atomicity of the copy operation. If an error occurs after the destination file +has been opened for writing, Node.js will attempt to remove the destination.

                    +

                    mode is an optional integer that specifies the behavior +of the copy operation. It is possible to create a mask consisting of the bitwise +OR of two or more values (e.g. +fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

                      -
                    • <number> The numeric file descriptor managed by the FileHandle object.
                    • +
                    • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest already +exists.
                    • +
                    • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create a +copy-on-write reflink. If the platform does not support copy-on-write, then a +fallback copy mechanism is used.
                    • +
                    • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to +create a copy-on-write reflink. If the platform does not support +copy-on-write, then the operation will fail.
                    -

                    filehandle.read(buffer, offset, length, position)#

                    +
                    import { copyFileSync, constants } from 'fs';
                    +
                    +// destination.txt will be created or overwritten by default.
                    +copyFileSync('source.txt', 'destination.txt');
                    +console.log('source.txt was copied to destination.txt');
                    +
                    +// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
                    +copyFileSync('source.txt', 'destination.txt', constants.COPYFILE_EXCL);
                    +

                    fs.existsSync(path)#

                    -

                    Read data from the file.

                    -

                    buffer is the buffer that the data will be written to.

                    -

                    offset is the offset in the buffer to start writing at.

                    -

                    length is an integer specifying the number of bytes to read.

                    -

                    position is an argument specifying where to begin reading from in the file. -If position is null, data will be read from the current file position, -and the file position will be updated. -If position is an integer, the file position will remain unchanged.

                    -

                    Following successful read, the Promise is resolved with an object with a -bytesRead property specifying the number of bytes read, and a buffer -property that is a reference to the passed in buffer argument.

                    -

                    filehandle.read(options)#

                    +

                    Returns true if the path exists, false otherwise.

                    +

                    For detailed information, see the documentation of the asynchronous version of +this API: fs.exists().

                    +

                    fs.exists() is deprecated, but fs.existsSync() is not. The callback +parameter to fs.exists() accepts parameters that are inconsistent with other +Node.js callbacks. fs.existsSync() does not use a callback.

                    +
                    import { existsSync } from 'fs';
                    +
                    +if (existsSync('/etc/passwd'))
                    +  console.log('The path exists.');
                    +

                    fs.fchmodSync(fd, mode)#

                    -

                    filehandle.readFile(options)#

                    +

                    Sets the permissions on the file. Returns undefined.

                    +

                    See the POSIX fchmod(2) documentation for more detail.

                    +

                    fs.fchownSync(fd, uid, gid)#

                    -

                    Asynchronously reads the entire contents of a file.

                    -

                    The Promise is resolved with the contents of the file. If no encoding is -specified (using options.encoding), the data is returned as a Buffer -object. Otherwise, the data will be a string.

                    -

                    If options is a string, then it specifies the encoding.

                    -

                    The FileHandle has to support reading.

                    -

                    If one or more filehandle.read() calls are made on a file handle and then a -filehandle.readFile() call is made, the data will be read from the current -position till the end of the file. It doesn't always read from the beginning -of the file.

                    -

                    filehandle.readv(buffers[, position])#

                    +

                    Sets the owner of the file. Returns undefined.

                    +

                    See the POSIX fchown(2) documentation for more detail.

                    +

                    fs.fdatasyncSync(fd)#

                    -

                    Read from a file and write to an array of ArrayBufferViews

                    -

                    The Promise is resolved with an object containing a bytesRead property -identifying the number of bytes read, and a buffers property containing -a reference to the buffers input.

                    -

                    position is the offset from the beginning of the file where this data -should be read from. If typeof position !== 'number', the data will be read -from the current position.

                    -

                    filehandle.stat([options])#

                    +

                    Forces all currently queued I/O operations associated with the file to the +operating system's synchronized I/O completion state. Refer to the POSIX +fdatasync(2) documentation for details. Returns undefined.

                    +

                    fs.fstatSync(fd[, options])#

                    -

                    Retrieves the fs.Stats for the file.

                    -

                    filehandle.sync()#

                    +

                    Retrieves the <fs.Stats> for the file descriptor.

                    +

                    See the POSIX fstat(2) documentation for more detail.

                    +

                    fs.fsyncSync(fd)#

                    -

                    Asynchronous fsync(2). The Promise is resolved with no arguments upon -success.

                    -

                    filehandle.truncate(len)#

                    +

                    Request that all data for the open file descriptor is flushed to the storage +device. The specific implementation is operating system and device specific. +Refer to the POSIX fsync(2) documentation for more detail. Returns undefined.

                    +

                    fs.ftruncateSync(fd[, len])#

                    -

                    Truncates the file then resolves the Promise with no arguments upon success.

                    -

                    If the file was larger than len bytes, only the first len bytes will be -retained in the file.

                    -

                    For example, the following program retains only the first four bytes of the -file:

                    -
                    const fs = require('fs');
                    -const fsPromises = fs.promises;
                    -
                    -console.log(fs.readFileSync('temp.txt', 'utf8'));
                    -// Prints: Node.js
                    -
                    -async function doTruncate() {
                    -  let filehandle = null;
                    -  try {
                    -    filehandle = await fsPromises.open('temp.txt', 'r+');
                    -    await filehandle.truncate(4);
                    -  } finally {
                    -    if (filehandle) {
                    -      // Close the file if it is opened.
                    -      await filehandle.close();
                    -    }
                    -  }
                    -  console.log(fs.readFileSync('temp.txt', 'utf8'));  // Prints: Node
                    -}
                    -
                    -doTruncate().catch(console.error);
                    -

                    If the file previously was shorter than len bytes, it is extended, and the -extended part is filled with null bytes ('\0'):

                    -
                    const fs = require('fs');
                    -const fsPromises = fs.promises;
                    -
                    -console.log(fs.readFileSync('temp.txt', 'utf8'));
                    -// Prints: Node.js
                    -
                    -async function doTruncate() {
                    -  let filehandle = null;
                    -  try {
                    -    filehandle = await fsPromises.open('temp.txt', 'r+');
                    -    await filehandle.truncate(10);
                    -  } finally {
                    -    if (filehandle) {
                    -      // Close the file if it is opened.
                    -      await filehandle.close();
                    -    }
                    -  }
                    -  console.log(fs.readFileSync('temp.txt', 'utf8'));  // Prints Node.js\0\0\0
                    -}
                    -
                    -doTruncate().catch(console.error);
                    -

                    The last three bytes are null bytes ('\0'), to compensate the over-truncation.

                    -

                    filehandle.utimes(atime, mtime)#

                    +

                    Truncates the file descriptor. Returns undefined.

                    +

                    For detailed information, see the documentation of the asynchronous version of +this API: fs.ftruncate().

                    +

                    fs.futimesSync(fd, atime, mtime)#

                    -

                    Change the file system timestamps of the object referenced by the FileHandle -then resolves the Promise with no arguments upon success.

                    -

                    This function does not work on AIX versions before 7.1, it will resolve the -Promise with an error using code UV_ENOSYS.

                    -

                    filehandle.write(buffer[, offset[, length[, position]]])#

                    +

                    Synchronous version of fs.futimes(). Returns undefined.

                    +

                    fs.lchmodSync(path, mode)#

                    -

                    Write buffer to the file.

                    -

                    The Promise is resolved with an object containing a bytesWritten property -identifying the number of bytes written, and a buffer property containing -a reference to the buffer written.

                    -

                    offset determines the part of the buffer to be written, and length is -an integer specifying the number of bytes to write.

                    -

                    position refers to the offset from the beginning of the file where this data -should be written. If typeof position !== 'number', the data will be written -at the current position. See pwrite(2).

                    -

                    It is unsafe to use filehandle.write() multiple times on the same file -without waiting for the Promise to be resolved (or rejected). For this -scenario, use fs.createWriteStream().

                    -

                    On Linux, positional writes do not work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file.

                    -

                    filehandle.write(string[, position[, encoding]])#

                    +

                    Changes the permissions on a symbolic link. Returns undefined.

                    +

                    This method is only implemented on macOS.

                    +

                    See the POSIX lchmod(2) documentation for more detail.

                    +

                    fs.lchownSync(path, uid, gid)#

                    -

                    Write string to the file. If string is not a string, then -the value will be coerced to one.

                    -

                    The Promise is resolved with an object containing a bytesWritten property -identifying the number of bytes written, and a buffer property containing -a reference to the string written.

                    -

                    position refers to the offset from the beginning of the file where this data -should be written. If the type of position is not a number the data -will be written at the current position. See pwrite(2).

                    -

                    encoding is the expected string encoding.

                    -

                    It is unsafe to use filehandle.write() multiple times on the same file -without waiting for the Promise to be resolved (or rejected). For this -scenario, use fs.createWriteStream().

                    -

                    On Linux, positional writes do not work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file.

                    -

                    filehandle.writeFile(data, options)#

                    +

                    Set the owner for the path. Returns undefined.

                    +

                    See the POSIX lchown(2) documentation for more details.

                    +

                    fs.lutimesSync(path, atime, mtime)#

                    -

                    Asynchronously writes data to a file, replacing the file if it already exists. -data can be a string or a buffer. The Promise will be resolved with no -arguments upon success.

                    -

                    The encoding option is ignored if data is a buffer.

                    -

                    If options is a string, then it specifies the encoding.

                    -

                    The FileHandle has to support writing.

                    -

                    It is unsafe to use filehandle.writeFile() multiple times on the same file -without waiting for the Promise to be resolved (or rejected).

                    -

                    If one or more filehandle.write() calls are made on a file handle and then a -filehandle.writeFile() call is made, the data will be written from the -current position till the end of the file. It doesn't always write from the -beginning of the file.

                    -

                    filehandle.writev(buffers[, position])#

                    +

                    Change the file system timestamps of the symbolic link referenced by path. +Returns undefined, or throws an exception when parameters are incorrect or +the operation fails. This is the synchronous version of fs.lutimes().

                    +

                    fs.linkSync(existingPath, newPath)#

                    -

                    Write an array of ArrayBufferViews to the file.

                    -

                    The Promise is resolved with an object containing a bytesWritten property -identifying the number of bytes written, and a buffers property containing -a reference to the buffers input.

                    -

                    position is the offset from the beginning of the file where this data -should be written. If typeof position !== 'number', the data will be written -at the current position.

                    -

                    It is unsafe to call writev() multiple times on the same file without waiting -for the previous operation to complete.

                    -

                    On Linux, positional writes don't work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file.

                    -

                    fsPromises.access(path[, mode])#

                    +

                    Creates a new link from the existingPath to the newPath. See the POSIX +link(2) documentation for more detail. Returns undefined.

                    +

                    fs.lstatSync(path[, options])#

                    -

                    Tests a user's permissions for the file or directory specified by path. -The mode argument is an optional integer that specifies the accessibility -checks to be performed. Check File access constants for possible values -of mode. It is possible to create a mask consisting of the bitwise OR of -two or more values (e.g. fs.constants.W_OK | fs.constants.R_OK).

                    -

                    If the accessibility check is successful, the Promise is resolved with no -value. If any of the accessibility checks fail, the Promise is rejected -with an Error object. The following example checks if the file -/etc/passwd can be read and written by the current process.

                    -
                    const fs = require('fs');
                    -const fsPromises = fs.promises;
                    -
                    -fsPromises.access('/etc/passwd', fs.constants.R_OK | fs.constants.W_OK)
                    -  .then(() => console.log('can access'))
                    -  .catch(() => console.error('cannot access'));
                    -

                    Using fsPromises.access() to check for the accessibility of a file before -calling fsPromises.open() is not recommended. Doing so introduces a race -condition, since other processes may change the file's state between the two -calls. Instead, user code should open/read/write the file directly and handle -the error raised if the file is not accessible.

                    -

                    fsPromises.appendFile(path, data[, options])#

                    - - -

                    Asynchronously append data to a file, creating the file if it does not yet -exist. data can be a string or a Buffer. The Promise will be -resolved with no arguments upon success.

                    -

                    If options is a string, then it specifies the encoding.

                    -

                    The path may be specified as a FileHandle that has been opened -for appending (using fsPromises.open()).

                    -

                    fsPromises.chmod(path, mode)#

                    +

                    Retrieves the <fs.Stats> for the symbolic link referred to by path.

                    +

                    See the POSIX lstat(2) documentation for more details.

                    +

                    fs.mkdirSync(path[, options])#

                    -

                    Changes the permissions of a file then resolves the Promise with no -arguments upon succces.

                    -

                    fsPromises.chown(path, uid, gid)#

                    -
                  +

                  Synchronously creates a directory. Returns undefined, or if recursive is +true, the first directory path created. +This is the synchronous version of fs.mkdir().

                  +

                  See the POSIX mkdir(2) documentation for more details.

                  +

                  fs.mkdtempSync(prefix[, options])#

                  + + +

                  Returns the created directory path.

                  +

                  For detailed information, see the documentation of the asynchronous version of +this API: fs.mkdtemp().

                  +

                  The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use.

                  +

                  fs.opendirSync(path[, options])#

                  +
                  • path <string> | <Buffer> | <URL>
                  • -
                  • uid <integer>
                  • -
                  • gid <integer>
                  • -
                  • Returns: <Promise>
                  • +
                  • options <Object> +
                      +
                    • encoding <string> | <null> Default: 'utf8'
                    • +
                    • bufferSize <number> Number of directory entries that are buffered +internally when reading from the directory. Higher values lead to better +performance but higher memory usage. Default: 32
                    -

                    Changes the ownership of a file then resolves the Promise with no arguments -upon success.

                    -

                    fsPromises.copyFile(src, dest[, flags])#

                    +
                  • +
                  • Returns: <fs.Dir>
                  • +
                  +

                  Synchronously open a directory. See opendir(3).

                  +

                  Creates an <fs.Dir>, which contains all further functions for reading from +and cleaning up the directory.

                  +

                  The encoding option sets the encoding for the path while opening the +directory and subsequent read operations.

                  +

                  fs.openSync(path[, flags[, mode]])#

                  -

                  Asynchronously copies src to dest. By default, dest is overwritten if it -already exists. The Promise will be resolved with no arguments upon success.

                  -

                  Node.js makes no guarantees about the atomicity of the copy operation. If an -error occurs after the destination file has been opened for writing, Node.js -will attempt to remove the destination.

                  -

                  flags is an optional integer that specifies the behavior -of the copy operation. It is possible to create a mask consisting of the bitwise -OR of two or more values (e.g. -fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

                  +

                  Returns an integer representing the file descriptor.

                  +

                  For detailed information, see the documentation of the asynchronous version of +this API: fs.open().

                  +

                  fs.readdirSync(path[, options])#

                  +
                    -
                  • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest already -exists.
                  • -
                  • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create a -copy-on-write reflink. If the platform does not support copy-on-write, then a -fallback copy mechanism is used.
                  • -
                  • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to -create a copy-on-write reflink. If the platform does not support copy-on-write, -then the operation will fail.
                  • +
                  • path <string> | <Buffer> | <URL>
                  • +
                  • options <string> | <Object> + -
                    const fsPromises = require('fs').promises;
                    +
                  • +
                  • Returns: <string[]> | <Buffer[]> | <fs.Dirent[]>
                  • +
                  +

                  Reads the contents of the directory.

                  +

                  See the POSIX readdir(3) documentation for more details.

                  +

                  The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use for +the filenames returned. If the encoding is set to 'buffer', +the filenames returned will be passed as <Buffer> objects.

                  +

                  If options.withFileTypes is set to true, the result will contain +<fs.Dirent> objects.

                  +

                  fs.readFileSync(path[, options])#

                  + + +

                  Returns the contents of the path.

                  +

                  For detailed information, see the documentation of the asynchronous version of +this API: fs.readFile().

                  +

                  If the encoding option is specified then this function returns a +string. Otherwise it returns a buffer.

                  +

                  Similar to fs.readFile(), when the path is a directory, the behavior of +fs.readFileSync() is platform-specific.

                  +
                  import { readFileSync } from 'fs';
                   
                  -// destination.txt will be created or overwritten by default.
                  -fsPromises.copyFile('source.txt', 'destination.txt')
                  -  .then(() => console.log('source.txt was copied to destination.txt'))
                  -  .catch(() => console.log('The file could not be copied'));
                  -

                  If the third argument is a number, then it specifies flags:

                  -
                  const fs = require('fs');
                  -const fsPromises = fs.promises;
                  -const { COPYFILE_EXCL } = fs.constants;
                  +// macOS, Linux, and Windows
                  +readFileSync('<directory>');
                  +// => [Error: EISDIR: illegal operation on a directory, read <directory>]
                   
                  -// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
                  -fsPromises.copyFile('source.txt', 'destination.txt', COPYFILE_EXCL)
                  -  .then(() => console.log('source.txt was copied to destination.txt'))
                  -  .catch(() => console.log('The file could not be copied'));
                  -

                  fsPromises.lchmod(path, mode)#

                  +// FreeBSD +readFileSync('<directory>'); // => <data>
                  +

                  fs.readlinkSync(path[, options])#

                  +

                  Returns the symbolic link's string value.

                  +

                  See the POSIX readlink(2) documentation for more details.

                  +

                  The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use for +the link path returned. If the encoding is set to 'buffer', +the link path returned will be passed as a <Buffer> object.

                  +

                  fs.readSync(fd, buffer, offset, length, position)#

                  + +

                  Returns the number of bytesRead.

                  +

                  For detailed information, see the documentation of the asynchronous version of +this API: fs.read().

                  +

                  fs.readSync(fd, buffer, [options])#

                  + + +

                  Returns the number of bytesRead.

                  +

                  Similar to the above fs.readSync function, this version takes an optional options object. +If no options object is specified, it will default with the above values.

                  +

                  For detailed information, see the documentation of the asynchronous version of +this API: fs.read().

                  +

                  fs.readvSync(fd, buffers[, position])#

                  + + +

                  For detailed information, see the documentation of the asynchronous version of +this API: fs.readv().

                  +

                  fs.realpathSync(path[, options])#

                  + +

                  Returns the resolved pathname.

                  +

                  For detailed information, see the documentation of the asynchronous version of +this API: fs.realpath().

                  +

                  fs.realpathSync.native(path[, options])#

                  +

                  Synchronous realpath(3).

                  +

                  Only paths that can be converted to UTF8 strings are supported.

                  +

                  The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use for +the path returned. If the encoding is set to 'buffer', +the path returned will be passed as a <Buffer> object.

                  +

                  On Linux, when Node.js is linked against musl libc, the procfs file system must +be mounted on /proc in order for this function to work. Glibc does not have +this restriction.

                  +

                  fs.renameSync(oldPath, newPath)#

                  -

                  Asynchronous link(2). The Promise is resolved with no arguments upon success.

                  -

                  fsPromises.lstat(path[, options])#

                  +

                  Renames the file from oldPath to newPath. Returns undefined.

                  +

                  See the POSIX rename(2) documentation for more details.

                  +

                  fs.rmdirSync(path[, options])#

                  @@ -33923,405 +35714,1046 @@ the symbolic link itself are changed.

                • path <string> | <Buffer> | <URL>
                • options <Object>
                    -
                  • bigint <boolean> Whether the numeric values in the returned -fs.Stats object should be bigint. Default: false.
                  • +
                  • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or +EPERM error is encountered, Node.js retries the operation with a linear +backoff wait of retryDelay milliseconds longer on each try. This option +represents the number of retries. This option is ignored if the recursive +option is not true. Default: 0.
                  • +
                  • recursive <boolean> If true, perform a recursive directory removal. In +recursive mode, errors are not reported if path does not exist, and +operations are retried on failure. Default: false.
                  • +
                  • retryDelay <integer> The amount of time in milliseconds to wait between +retries. This option is ignored if the recursive option is not true. +Default: 100.
                • -
                • Returns: <Promise>
                -

                Asynchronous lstat(2). The Promise is resolved with the fs.Stats object -for the given symbolic link path.

                -

                fsPromises.mkdir(path[, options])#

                +

                Synchronous rmdir(2). Returns undefined.

                +

                Using fs.rmdirSync() on a file (not a directory) results in an ENOENT error +on Windows and an ENOTDIR error on POSIX.

                +

                Setting recursive to true results in behavior similar to the Unix command +rm -rf: an error will not be raised for paths that do not exist, and paths +that represent files will be deleted. The permissive behavior of the +recursive option is deprecated, ENOTDIR and ENOENT will be thrown in +the future.

                +

                fs.rmSync(path[, options])#

                • path <string> | <Buffer> | <URL>
                • -
                • options <Object> | <integer> +
                • options <Object>
                    -
                  • recursive <boolean> Default: false
                  • -
                  • mode <string> | <integer> Not supported on Windows. Default: 0o777.
                  • +
                  • force <boolean> When true, exceptions will be ignored if path does +not exist. Default: false.
                  • +
                  • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or +EPERM error is encountered, Node.js will retry the operation with a linear +backoff wait of retryDelay milliseconds longer on each try. This option +represents the number of retries. This option is ignored if the recursive +option is not true. Default: 0.
                  • +
                  • recursive <boolean> If true, perform a recursive directory removal. In +recursive mode operations are retried on failure. Default: false.
                  • +
                  • retryDelay <integer> The amount of time in milliseconds to wait between +retries. This option is ignored if the recursive option is not true. +Default: 100.
                • -
                • Returns: <Promise>
                -

                Asynchronously creates a directory then resolves the Promise with either no -arguments, or the first directory path created if recursive is true.

                -

                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 directories should be created. Calling -fsPromises.mkdir() when path is a directory that exists results in a -rejection only when recursive is false.

                -

                fsPromises.mkdtemp(prefix[, options])#

                +

                Synchronously removes files and directories (modeled on the standard POSIX rm +utility). Returns undefined.

                +

                fs.statSync(path[, options])#

                -

                Creates a unique temporary directory and resolves the Promise with the created -directory path. A unique directory name is generated by appending six random -characters to the end of the provided prefix. Due to platform -inconsistencies, avoid trailing X characters in prefix. Some platforms, -notably the BSDs, can return more than six random characters, and replace -trailing X characters in prefix with random characters.

                -

                The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use.

                -
                fsPromises.mkdtemp(path.join(os.tmpdir(), 'foo-'))
                -  .catch(console.error);
                -

                The fsPromises.mkdtemp() method will append the six randomly selected -characters directly to the prefix string. For instance, given a directory -/tmp, if the intention is to create a temporary directory within /tmp, the -prefix must end with a trailing platform-specific path separator -(require('path').sep).

                -

                fsPromises.open(path, flags[, mode])#

                +

                Retrieves the <fs.Stats> for the path.

                +

                fs.symlinkSync(target, path[, type])#

                -

                Asynchronous file open that returns a Promise that, when resolved, yields a -FileHandle object. See open(2).

                -

                mode sets the file mode (permission and sticky bits), but only if the file was -created.

                -

                Some characters (< > : " / \ | ? *) are reserved under Windows as documented -by Naming Files, Paths, and Namespaces. Under NTFS, if the filename contains -a colon, Node.js will open a file system stream, as described by -this MSDN page.

                -

                fsPromises.opendir(path[, options])#

                +

                Returns undefined.

                +

                For detailed information, see the documentation of the asynchronous version of +this API: fs.symlink().

                +

                fs.truncateSync(path[, len])#

                + + +

                Truncates the file. Returns undefined. A file descriptor can also be +passed as the first argument. In this case, fs.ftruncateSync() is called.

                +

                Passing a file descriptor is deprecated and may result in an error being thrown +in the future.

                +

                fs.unlinkSync(path)#

                +

                Synchronous unlink(2). Returns undefined.

                +

                fs.utimesSync(path, atime, mtime)#

                + + +

                Returns undefined.

                +

                For detailed information, see the documentation of the asynchronous version of +this API: fs.utimes().

                +

                fs.writeFileSync(file, data[, options])#

                + + -

                Asynchronously open a directory. See opendir(3).

                -

                Creates an fs.Dir, which contains all further functions for reading from -and cleaning up the directory.

                -

                The encoding option sets the encoding for the path while opening the -directory and subsequent read operations.

                -

                Example using async iteration:

                -
                const fs = require('fs');
                +

                Returns undefined.

                +

                If data is a plain object, it must have an own (not inherited) toString +function property.

                +

                The mode option only affects the newly created file. See fs.open() +for more details.

                +

                For detailed information, see the documentation of the asynchronous version of +this API: fs.writeFile().

                +

                fs.writeSync(fd, buffer[, offset[, length[, position]]])#

                + + +

                If buffer is a plain object, it must have an own (not inherited) toString +function property.

                +

                For detailed information, see the documentation of the asynchronous version of +this API: fs.write(fd, buffer...).

                +

                fs.writeSync(fd, string[, position[, encoding]])#

                + + +

                If string is a plain object, it must have an own (not inherited) toString +function property.

                +

                For detailed information, see the documentation of the asynchronous version of +this API: fs.write(fd, string...).

                +

                fs.writevSync(fd, buffers[, position])#

                + + +

                For detailed information, see the documentation of the asynchronous version of +this API: fs.writev().

                +

                Common Objects#

                +

                The common objects are shared by all of the file system API variants +(promise, callback, and synchronous).

                +

                Class: fs.Dir#

                + +

                A class representing a directory stream.

                +

                Created by fs.opendir(), fs.opendirSync(), or +fsPromises.opendir().

                +
                import { opendir } from 'fs/promises';
                 
                -async function print(path) {
                -  const dir = await fs.promises.opendir(path);
                -  for await (const dirent of dir) {
                -    console.log(dirent.name);
                +try {
                +  const dir = await opendir('./');
                +  for await (const dirent of dir)
                +    console.log(dirent.name);
                +} catch (err) {
                +  console.error(err);
                +}
                +

                When using the async iterator, the <fs.Dir> object will be automatically +closed after the iterator exits.

                +
                dir.close()#
                + + +

                Asynchronously close the directory's underlying resource handle. +Subsequent reads will result in errors.

                +

                A promise is returned that will be resolved after the resource has been +closed.

                +
                dir.close(callback)#
                + + +

                Asynchronously close the directory's underlying resource handle. +Subsequent reads will result in errors.

                +

                The callback will be called after the resource handle has been closed.

                +
                dir.closeSync()#
                + +

                Synchronously close the directory's underlying resource handle. +Subsequent reads will result in errors.

                +
                dir.path#
                + + +

                The read-only path of this directory as was provided to fs.opendir(), +fs.opendirSync(), or fsPromises.opendir().

                +
                dir.read()#
                + + +

                Asynchronously read the next directory entry via readdir(3) as an +<fs.Dirent>.

                +

                A promise is returned that will be resolved with an <fs.Dirent>, or null +if there are no more directory entries to read.

                +

                Directory entries returned by this function are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results.

                +
                dir.read(callback)#
                + + +

                Asynchronously read the next directory entry via readdir(3) as an +<fs.Dirent>.

                +

                After the read is completed, the callback will be called with an +<fs.Dirent>, or null if there are no more directory entries to read.

                +

                Directory entries returned by this function are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results.

                +
                dir.readSync()#
                + + +

                Synchronously read the next directory entry as an <fs.Dirent>. See the +POSIX readdir(3) documentation for more detail.

                +

                If there are no more directory entries to read, null will be returned.

                +

                Directory entries returned by this function are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results.

                +
                dir[Symbol.asyncIterator]()#
                + + +

                Asynchronously iterates over the directory until all entries have +been read. Refer to the POSIX readdir(3) documentation for more detail.

                +

                Entries returned by the async iterator are always an <fs.Dirent>. +The null case from dir.read() is handled internally.

                +

                See <fs.Dir> for an example.

                +

                Directory entries returned by this iterator are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results.

                +

                Class: fs.Dirent#

                + +

                A representation of a directory entry, which can be a file or a subdirectory +within the directory, as returned by reading from an <fs.Dir>. The +directory entry is a combination of the file name and file type pairs.

                +

                Additionally, when fs.readdir() or fs.readdirSync() is called with +the withFileTypes option set to true, the resulting array is filled with +<fs.Dirent> objects, rather than strings or <Buffer>s.

                +
                dirent.isBlockDevice()#
                + + +

                Returns true if the <fs.Dirent> object describes a block device.

                +
                dirent.isCharacterDevice()#
                + + +

                Returns true if the <fs.Dirent> object describes a character device.

                +
                dirent.isDirectory()#
                + + +

                Returns true if the <fs.Dirent> object describes a file system +directory.

                +
                dirent.isFIFO()#
                + + +

                Returns true if the <fs.Dirent> object describes a first-in-first-out +(FIFO) pipe.

                +
                dirent.isFile()#
                + + +

                Returns true if the <fs.Dirent> object describes a regular file.

                +
                dirent.isSocket()#
                + + +

                Returns true if the <fs.Dirent> object describes a socket.

                +
                dirent.isSymbolicLink()#
                + + +

                Returns true if the <fs.Dirent> object describes a symbolic link.

                +
                dirent.name#
                + + +

                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().

                +

                Class: fs.FSWatcher#

                + + +

                A successful call to fs.watch() method will return a new <fs.FSWatcher> +object.

                +

                All <fs.FSWatcher> objects emit a 'change' event whenever a specific watched +file is modified.

                +
                Event: 'change'#
                + +
                  +
                • eventType <string> The type of change event that has occurred
                • +
                • filename <string> | <Buffer> The filename that changed (if relevant/available)
                • +
                +

                Emitted when something changes in a watched directory or file. +See more details in fs.watch().

                +

                The filename argument may not be provided depending on operating system +support. If filename is provided, it will be provided as a <Buffer> if +fs.watch() is called with its encoding option set to 'buffer', otherwise +filename will be a UTF-8 string.

                +
                import { watch } from 'fs';
                +// Example when handled through fs.watch() listener
                +watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {
                +  if (filename) {
                +    console.log(filename);
                +    // Prints: <Buffer ...>
                   }
                -}
                -print('./').catch(console.error);
                -

                fsPromises.readdir(path[, options])#

                +});
                +
                Event: 'close'#
                + +

                Emitted when the watcher stops watching for changes. The closed +<fs.FSWatcher> object is no longer usable in the event handler.

                +
                Event: 'error'#
                + + +

                Emitted when an error occurs while watching the file. The errored +<fs.FSWatcher> object is no longer usable in the event handler.

                +
                watcher.close()#
                + +

                Stop watching for changes on the given <fs.FSWatcher>. Once stopped, the +<fs.FSWatcher> object is no longer usable.

                +
                watcher.ref()#
                + + +

                When called, requests that the Node.js event loop not exit so long as the +<fs.FSWatcher> is active. Calling watcher.ref() multiple times will have +no effect.

                +

                By default, all <fs.FSWatcher> objects are "ref'ed", making it normally +unnecessary to call watcher.ref() unless watcher.unref() had been +called previously.

                +
                watcher.unref()#
                + + +

                When called, the active <fs.FSWatcher> object will not require the Node.js +event loop to remain active. If there is no other activity keeping the +event loop running, the process may exit before the <fs.FSWatcher> object's +callback is invoked. Calling watcher.unref() multiple times will have +no effect.

                +

                Class: fs.StatWatcher#

                + + +

                A successful call to fs.watchFile() method will return a new <fs.StatWatcher> +object.

                +
                watcher.ref()#
                + + +

                When called, requests that the Node.js event loop not exit so long as the +<fs.StatWatcher> is active. Calling watcher.ref() multiple times will have +no effect.

                +

                By default, all <fs.StatWatcher> objects are "ref'ed", making it normally +unnecessary to call watcher.ref() unless watcher.unref() had been +called previously.

                +
                watcher.unref()#
                + + +

                When called, the active <fs.StatWatcher> object will not require the Node.js +event loop to remain active. If there is no other activity keeping the +event loop running, the process may exit before the <fs.StatWatcher> object's +callback is invoked. Calling watcher.unref() multiple times will have +no effect.

                +

                Class: fs.ReadStream#

                + + +

                Instances of <fs.ReadStream> are created and returned using the +fs.createReadStream() function.

                +
                Event: 'close'#
                + +

                Emitted when the <fs.ReadStream>'s underlying file descriptor has been closed.

                +
                Event: 'open'#
                + + +

                Emitted when the <fs.ReadStream>'s file descriptor has been opened.

                +
                Event: 'ready'#
                + +

                Emitted when the <fs.ReadStream> is ready to be used.

                +

                Fires immediately after 'open'.

                +
                readStream.bytesRead#
                + + +

                The number of bytes that have been read so far.

                +
                readStream.path#
                + + +

                The path to the file the stream is reading from as specified in the first +argument to fs.createReadStream(). If path is passed as a string, then +readStream.path will be a string. If path is passed as a <Buffer>, then +readStream.path will be a <Buffer>.

                +
                readStream.pending#
                + + +

                This property is true if the underlying file has not been opened yet, +i.e. before the 'ready' event is emitted.

                +

                Class: fs.Stats#

                +

                A <fs.Stats> object provides information about a file.

                +

                Objects returned from fs.stat(), fs.lstat() and fs.fstat() and +their synchronous counterparts are of this type. +If bigint in the options passed to those methods is true, the numeric values +will be bigint instead of number, and the object will contain additional +nanosecond-precision properties suffixed with Ns.

                +
                Stats {
                +  dev: 2114,
                +  ino: 48064969,
                +  mode: 33188,
                +  nlink: 1,
                +  uid: 85,
                +  gid: 100,
                +  rdev: 0,
                +  size: 527,
                +  blksize: 4096,
                +  blocks: 8,
                +  atimeMs: 1318289051000.1,
                +  mtimeMs: 1318289051000.1,
                +  ctimeMs: 1318289051000.1,
                +  birthtimeMs: 1318289051000.1,
                +  atime: Mon, 10 Oct 2011 23:24:11 GMT,
                +  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
                +  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
                +  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
                +

                bigint version:

                +
                BigIntStats {
                +  dev: 2114n,
                +  ino: 48064969n,
                +  mode: 33188n,
                +  nlink: 1n,
                +  uid: 85n,
                +  gid: 100n,
                +  rdev: 0n,
                +  size: 527n,
                +  blksize: 4096n,
                +  blocks: 8n,
                +  atimeMs: 1318289051000n,
                +  mtimeMs: 1318289051000n,
                +  ctimeMs: 1318289051000n,
                +  birthtimeMs: 1318289051000n,
                +  atimeNs: 1318289051000000000n,
                +  mtimeNs: 1318289051000000000n,
                +  ctimeNs: 1318289051000000000n,
                +  birthtimeNs: 1318289051000000000n,
                +  atime: Mon, 10 Oct 2011 23:24:11 GMT,
                +  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
                +  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
                +  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
                +
                stats.isBlockDevice()#
                + +

                Returns true if the <fs.Stats> object describes a block device.

                +
                stats.isCharacterDevice()#
                + - -
              • Returns: <Promise>
              • +

                Returns true if the <fs.Stats> object describes a character device.

                +
                stats.isDirectory()#
                + + -

                Reads the contents of a directory then resolves the Promise with an array -of the names of the files in the directory excluding '.' and '..'.

                -

                The optional options argument can be a string specifying an encoding, or an -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.

                -
                const fs = require('fs');
                -
                -async function print(path) {
                -  const files = await fs.promises.readdir(path);
                -  for (const file of files) {
                -    console.log(file);
                -  }
                -}
                -print('./').catch(console.error);
                -

                fsPromises.readFile(path[, options])#

                +

                Returns true if the <fs.Stats> object describes a file system directory.

                +

                If the <fs.Stats> object was obtained from fs.lstat(), this method will +always return false. This is because fs.lstat() returns information +about a symbolic link itself and not the path it resolves to.

                +
                stats.isFIFO()#
                +

                Returns true if the <fs.Stats> object describes a first-in-first-out (FIFO) +pipe.

                +
                stats.isFile()#
                + - -
              • Returns: <Promise>
              • +

                Returns true if the <fs.Stats> object describes a regular file.

                +
                stats.isSocket()#
                + + -

                Asynchronously reads the entire contents of a file.

                -

                The Promise is resolved with the contents of the file. If no encoding is -specified (using options.encoding), the data is returned as a Buffer -object. Otherwise, the data will be a string.

                -

                If options is a string, then it specifies the encoding.

                -

                When the path is a directory, the behavior of fsPromises.readFile() is -platform-specific. On macOS, Linux, and Windows, the promise will be rejected -with an error. On FreeBSD, a representation of the directory's contents will be -returned.

                -

                Any specified FileHandle has to support reading.

                -

                fsPromises.readlink(path[, options])#

                +

                Returns true if the <fs.Stats> object describes a socket.

                +
                stats.isSymbolicLink()#
                +

                Returns true if the <fs.Stats> object describes a symbolic link.

                +

                This method is only valid when using fs.lstat().

                +
                stats.dev#
                - -
              • Returns: <Promise>
              • +

                The numeric identifier of the device containing the file.

                +
                stats.ino#
                + -

                Asynchronous readlink(2). The Promise is resolved with the linkString upon -success.

                -

                The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the link path returned. If the encoding is set to 'buffer', the link path -returned will be passed as a Buffer object.

                -

                fsPromises.realpath(path[, options])#

                +

                The file system specific "Inode" number for the file.

                +
                stats.mode#
                + +

                A bit-field describing the file type and mode.

                +
                stats.nlink#
                + +

                The number of hard-links that exist for the file.

                +
                stats.uid#
                + +

                The numeric user identifier of the user that owns the file (POSIX).

                +
                stats.gid#
                + +

                The numeric group identifier of the group that owns the file (POSIX).

                +
                stats.rdev#
                + +

                A numeric device identifier if the file represents a device.

                +
                stats.size#
                + +

                The size of the file in bytes.

                +
                stats.blksize#
                + +

                The file system block size for i/o operations.

                +
                stats.blocks#
                + +

                The number of blocks allocated for this file.

                +
                stats.atimeMs#
                  -
                • path <string> | <Buffer> | <URL>
                • -
                • options <string> | <Object> - -
                • -
                • Returns: <Promise>
                • +

                  The timestamp indicating the last time this file was accessed expressed in +milliseconds since the POSIX Epoch.

                  +
                  stats.mtimeMs#
                  + + -

                  Determines the actual location of path using the same semantics as the -fs.realpath.native() function then resolves the Promise with the resolved -path.

                  -

                  Only paths that can be converted to UTF8 strings are supported.

                  -

                  The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the path. If the encoding is set to 'buffer', the path returned will be -passed as a Buffer object.

                  -

                  On Linux, when Node.js is linked against musl libc, the procfs file system must -be mounted on /proc in order for this function to work. Glibc does not have -this restriction.

                  -

                  fsPromises.rename(oldPath, newPath)#

                  +

                  The timestamp indicating the last time this file was modified expressed in +milliseconds since the POSIX Epoch.

                  +
                  stats.ctimeMs#
                  -

                  Renames oldPath to newPath and resolves the Promise with no arguments -upon success.

                  -

                  fsPromises.rmdir(path[, options])#

                  +

                  The timestamp indicating the last time the file status was changed expressed +in milliseconds since the POSIX Epoch.

                  +
                  stats.birthtimeMs#
                  -

                  Stability: 1 - Recursive removal is experimental.

                  +

                  The timestamp indicating the creation time of this file expressed in +milliseconds since the POSIX Epoch.

                  +
                  stats.atimeNs#
                  +
                    -
                  • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or -EPERM error is encountered, Node.js will retry the operation with a linear -backoff wait of retryDelay ms longer on each try. This option represents the -number of retries. This option is ignored if the recursive option is not -true. Default: 0.
                  • -
                  • recursive <boolean> If true, perform a recursive directory removal. In -recursive mode, errors are not reported if path does not exist, and -operations are retried on failure. Default: false.
                  • -
                  • retryDelay <integer> The amount of time in milliseconds to wait between -retries. This option is ignored if the recursive option is not true. -Default: 100.
                  • +
                  • <bigint>
                  - -
                • Returns: <Promise>
                • +

                  Only present when bigint: true is passed into the method that generates +the object. +The timestamp indicating the last time this file was accessed expressed in +nanoseconds since the POSIX Epoch.

                  +
                  stats.mtimeNs#
                  + + -

                  Removes the directory identified by path then resolves the Promise with -no arguments upon success.

                  -

                  Using fsPromises.rmdir() on a file (not a directory) results in the -Promise being rejected with an ENOENT error on Windows and an ENOTDIR -error on POSIX.

                  -

                  fsPromises.stat(path[, options])#

                  +

                  Only present when bigint: true is passed into the method that generates +the object. +The timestamp indicating the last time this file was modified expressed in +nanoseconds since the POSIX Epoch.

                  +
                  stats.ctimeNs#
                  +

                  Only present when bigint: true is passed into the method that generates +the object. +The timestamp indicating the last time the file status was changed expressed +in nanoseconds since the POSIX Epoch.

                  +
                  stats.birthtimeNs#
                  + - -
                • Returns: <Promise>
                • +

                  Only present when bigint: true is passed into the method that generates +the object. +The timestamp indicating the creation time of this file expressed in +nanoseconds since the POSIX Epoch.

                  +
                  stats.atime#
                  + + -

                  The Promise is resolved with the fs.Stats object for the given path.

                  -

                  fsPromises.symlink(target, path[, type])#

                  +

                  The timestamp indicating the last time this file was accessed.

                  +
                  stats.mtime#
                  -

                  Creates a symbolic link then resolves the Promise with no arguments upon -success.

                  -

                  The type argument is only used on Windows platforms and can be one of 'dir', -'file', or 'junction'. Windows junction points require the destination path -to be absolute. When using 'junction', the target argument will -automatically be normalized to absolute path.

                  -

                  fsPromises.truncate(path[, len])#

                  +

                  The timestamp indicating the last time this file was modified.

                  +
                  stats.ctime#
                  -

                  Truncates the path then resolves the Promise with no arguments upon -success. The path must be a string or Buffer.

                  -

                  fsPromises.unlink(path)#

                  +

                  The timestamp indicating the last time the file status was changed.

                  +
                  stats.birthtime#
                  +

                  The timestamp indicating the creation time of this file.

                  +
                  Stat time values#
                  +

                  The atimeMs, mtimeMs, ctimeMs, birthtimeMs properties are +numeric values that hold the corresponding times in milliseconds. Their +precision is platform specific. When bigint: true is passed into the +method that generates the object, the properties will be bigints, +otherwise they will be numbers.

                  +

                  The atimeNs, mtimeNs, ctimeNs, birthtimeNs properties are +bigints that hold the corresponding times in nanoseconds. They are +only present when bigint: true is passed into the method that generates +the object. Their precision is platform specific.

                  +

                  atime, mtime, ctime, and birthtime are +Date object alternate representations of the various times. The +Date and number values are not connected. Assigning a new number value, or +mutating the Date value, will not be reflected in the corresponding alternate +representation.

                  +

                  The times in the stat object have the following semantics:

                  +
                    +
                  • atime "Access Time": Time when file data last accessed. Changed +by the mknod(2), utimes(2), and read(2) system calls.
                  • +
                  • mtime "Modified Time": Time when file data last modified. +Changed by the mknod(2), utimes(2), and write(2) system calls.
                  • +
                  • ctime "Change Time": Time when file status was last changed +(inode data modification). Changed by the chmod(2), chown(2), +link(2), mknod(2), rename(2), unlink(2), utimes(2), +read(2), and write(2) system calls.
                  • +
                  • birthtime "Birth Time": Time of file creation. Set once when the +file is created. On filesystems where birthtime is not available, +this field may instead hold either the ctime or +1970-01-01T00:00Z (ie, Unix epoch timestamp 0). This value may be greater +than atime or mtime in this case. On Darwin and other FreeBSD variants, +also set if the atime is explicitly set to an earlier value than the current +birthtime using the utimes(2) system call.
                  -

                  Asynchronous unlink(2). The Promise is resolved with no arguments upon -success.

                  -

                  fsPromises.utimes(path, atime, mtime)#

                  +

                  Prior to Node.js 0.12, the ctime held the birthtime on Windows systems. As +of 0.12, ctime is not "creation time", and on Unix systems, it never was.

                  +

                  Class: fs.WriteStream#

                  -

                  Change the file system timestamps of the object referenced by path then -resolves the Promise with no arguments upon success.

                  -

                  The atime and mtime arguments follow these rules:

                  +

                  Instances of <fs.WriteStream> are created and returned using the +fs.createWriteStream() function.

                  +
                  Event: 'close'#
                  + +

                  Emitted when the <fs.WriteStream>'s underlying file descriptor has been closed.

                  +
                  Event: 'open'#
                  +
                    -
                  • Values can be either numbers representing Unix epoch time, Dates, or a -numeric string like '123456789.0'.
                  • -
                  • If the value can not be converted to a number, or is NaN, Infinity or --Infinity, an Error will be thrown.
                  • +
                  • fd <integer> Integer file descriptor used by the <fs.WriteStream>.
                  -

                  fsPromises.writeFile(file, data[, options])#

                  +

                  Emitted when the <fs.WriteStream>'s file is opened.

                  +
                  Event: 'ready'#
                  +

                  Emitted when the <fs.WriteStream> is ready to be used.

                  +

                  Fires immediately after 'open'.

                  +
                  writeStream.bytesWritten#
                  + +

                  The number of bytes written so far. Does not include data that is still queued +for writing.

                  +
                  writeStream.close([callback])#
                  + -

                  Asynchronously writes data to a file, replacing the file if it already exists. -data can be a string or a buffer. The Promise will be resolved with no -arguments upon success.

                  -

                  The encoding option is ignored if data is a buffer.

                  -

                  If options is a string, then it specifies the encoding.

                  -

                  Any specified FileHandle has to support writing.

                  -

                  It is unsafe to use fsPromises.writeFile() multiple times on the same file -without waiting for the Promise to be resolved (or rejected).

                  -

                  FS constants#

                  +

                  Closes writeStream. Optionally accepts a +callback that will be executed once the writeStream +is closed.

                  +
                  writeStream.path#
                  + +

                  The path to the file the stream is writing to as specified in the first +argument to fs.createWriteStream(). If path is passed as a string, then +writeStream.path will be a string. If path is passed as a <Buffer>, then +writeStream.path will be a <Buffer>.

                  +
                  writeStream.pending#
                  + + +

                  This property is true if the underlying file has not been opened yet, +i.e. before the 'ready' event is emitted.

                  +

                  fs.constants#

                  + +

                  Returns an object containing commonly used constants for file system +operations.

                  +
                  FS constants#

                  The following constants are exported by fs.constants.

                  Not every constant will be available on every operating system.

                  To use more than one constant, use the bitwise OR | operator.

                  Example:

                  -
                  const fs = require('fs');
                  +
                  import { open, constants } from 'fs';
                   
                   const {
                  -  O_RDWR,
                  -  O_CREAT,
                  -  O_EXCL
                  -} = fs.constants;
                  +  O_RDWR,
                  +  O_CREAT,
                  +  O_EXCL
                  +} = constants;
                   
                  -fs.open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => {
                  +open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => {
                     // ...
                   });
                  -

                  File access constants#

                  +
                  File access constants#

                  The following constants are meant for use with fs.access().

                  @@ -34350,8 +36782,8 @@ fs.open('/path/to/my/file', O_RDWR | O_CREAT | (will behave like fs.constants.F_OK).
                  -

                  File copy constants#

                  -

                  The following constants are meant for use with fs.copyFile().

                  +
                  File copy constants#
                  +

                  The following constants are meant for use with fs.copyFile().

                  @@ -34375,7 +36807,7 @@ fs.open('/path/to/my/file', O_RDWR | O_CREAT | copy-on-write, then the operation will fail with an error.
                  Constant
                  -

                  File open constants#

                  +
                  File open constants#

                  The following constants are meant for use with fs.open().

                  @@ -34466,8 +36898,8 @@ fs.open('/path/to/my/file', O_RDWR | O_CREAT | this flag is ignored.
                  -

                  File type constants#

                  -

                  The following constants are meant for use with the fs.Stats object's +

                  File type constants#
                  +

                  The following constants are meant for use with the <fs.Stats> object's mode property for determining a file's type.

                  @@ -34507,8 +36939,8 @@ fs.open('/path/to/my/file', O_RDWR | O_CREAT |
                  File type constant for a socket.
                  -

                  File mode constants#

                  -

                  The following constants are meant for use with the fs.Stats object's +

                  File mode constants#
                  +

                  The following constants are meant for use with the <fs.Stats> object's mode property for determining the access permissions for a file.

                  @@ -34564,7 +36996,244 @@ fs.open('/path/to/my/file', O_RDWR | O_CREAT |
                  File mode indicating executable by others.
                  -

                  File system flags#

                  +

                  Notes#

                  +

                  Ordering of callback and promise-based operations#

                  +

                  Because they are executed asynchronously by the underlying thread pool, +there is no guaranteed ordering when using either the callback or +promise-based methods.

                  +

                  For example, the following is prone to error because the fs.stat() +operation might complete before the fs.rename() operation:

                  +
                  fs.rename('/tmp/hello', '/tmp/world', (err) => {
                  +  if (err) throw err;
                  +  console.log('renamed complete');
                  +});
                  +fs.stat('/tmp/world', (err, stats) => {
                  +  if (err) throw err;
                  +  console.log(`stats: ${JSON.stringify(stats)}`);
                  +});
                  +

                  It is important to correctly order the operations by awaiting the results +of one before invoking the other:

                  + +
                  import { rename, stat } from 'fs/promises';
                  +
                  +const from = '/tmp/hello';
                  +const to = '/tmp/world';
                  +
                  +try {
                  +  await rename(from, to);
                  +  const stats = await stat(to);
                  +  console.log(`stats: ${JSON.stringify(stats)}`);
                  +} catch (error) {
                  +  console.error('there was an error:', error.message);
                  +}const { rename, stat } = require('fs/promises');
                  +
                  +(async function(from, to) {
                  +  try {
                  +    await rename(from, to);
                  +    const stats = await stat(to);
                  +    console.log(`stats: ${JSON.stringify(stats)}`);
                  +  } catch (error) {
                  +    console.error('there was an error:', error.message);
                  +  }
                  +})('/tmp/hello', '/tmp/world');
                  +

                  Or, when using the callback APIs, move the fs.stat() call into the callback +of the fs.rename() operation:

                  + +
                  import { rename, stat } from 'fs';
                  +
                  +rename('/tmp/hello', '/tmp/world', (err) => {
                  +  if (err) throw err;
                  +  stat('/tmp/world', (err, stats) => {
                  +    if (err) throw err;
                  +    console.log(`stats: ${JSON.stringify(stats)}`);
                  +  });
                  +});const { rename, stat } = require('fs/promises');
                  +
                  +rename('/tmp/hello', '/tmp/world', (err) => {
                  +  if (err) throw err;
                  +  stat('/tmp/world', (err, stats) => {
                  +    if (err) throw err;
                  +    console.log(`stats: ${JSON.stringify(stats)}`);
                  +  });
                  +});
                  +

                  File paths#

                  +

                  Most fs operations accept file paths that may be specified in the form of +a string, a <Buffer>, or a <URL> object using the file: protocol.

                  +
                  String paths#
                  +

                  String form paths are interpreted as UTF-8 character sequences identifying +the absolute or relative filename. Relative paths will be resolved relative +to the current working directory as determined by calling process.cwd().

                  +

                  Example using an absolute path on POSIX:

                  +
                  import { open } from 'fs/promises';
                  +
                  +let fd;
                  +try {
                  +  fd = await open('/open/some/file.txt', 'r');
                  +  // Do something with the file
                  +} finally {
                  +  await fd.close();
                  +}
                  +

                  Example using a relative path on POSIX (relative to process.cwd()):

                  +
                  import { open } from 'fs/promises';
                  +
                  +let fd;
                  +try {
                  +  fd = await open('file.txt', 'r');
                  +  // Do something with the file
                  +} finally {
                  +  await fd.close();
                  +}
                  +
                  File URL paths#
                  + +

                  For most fs module functions, the path or filename argument may be passed +as a <URL> object using the file: protocol.

                  +
                  import { readFileSync } from 'fs';
                  +
                  +readFileSync(new URL('file:///tmp/hello'));
                  +

                  file: URLs are always absolute paths.

                  +
                  Platform-specific considerations#
                  +

                  On Windows, file: <URL>s with a host name convert to UNC paths, while file: +<URL>s with drive letters convert to local absolute paths. file: <URL>s +without a host name nor a drive letter will result in an error:

                  +
                  import { readFileSync } from 'fs';
                  +// On Windows :
                  +
                  +// - WHATWG file URLs with hostname convert to UNC path
                  +// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file
                  +readFileSync(new URL('file://hostname/p/a/t/h/file'));
                  +
                  +// - WHATWG file URLs with drive letters convert to absolute path
                  +// file:///C:/tmp/hello => C:\tmp\hello
                  +readFileSync(new URL('file:///C:/tmp/hello'));
                  +
                  +// - WHATWG file URLs without hostname must have a drive letters
                  +readFileSync(new URL('file:///notdriveletter/p/a/t/h/file'));
                  +readFileSync(new URL('file:///c/p/a/t/h/file'));
                  +// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute
                  +

                  file: <URL>s with drive letters must use : as a separator just after +the drive letter. Using another separator will result in an error.

                  +

                  On all other platforms, file: <URL>s with a host name are unsupported and +will result in an error:

                  +
                  import { readFileSync } from 'fs';
                  +// On other platforms:
                  +
                  +// - WHATWG file URLs with hostname are unsupported
                  +// file://hostname/p/a/t/h/file => throw!
                  +readFileSync(new URL('file://hostname/p/a/t/h/file'));
                  +// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute
                  +
                  +// - WHATWG file URLs convert to absolute path
                  +// file:///tmp/hello => /tmp/hello
                  +readFileSync(new URL('file:///tmp/hello'));
                  +

                  A file: <URL> having encoded slash characters will result in an error on all +platforms:

                  +
                  import { readFileSync } from 'fs';
                  +
                  +// On Windows
                  +readFileSync(new URL('file:///C:/p/a/t/h/%2F'));
                  +readFileSync(new URL('file:///C:/p/a/t/h/%2f'));
                  +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
                  +\ or / characters */
                  +
                  +// On POSIX
                  +readFileSync(new URL('file:///p/a/t/h/%2F'));
                  +readFileSync(new URL('file:///p/a/t/h/%2f'));
                  +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
                  +/ characters */
                  +

                  On Windows, file: <URL>s having encoded backslash will result in an error:

                  +
                  import { readFileSync } from 'fs';
                  +
                  +// On Windows
                  +readFileSync(new URL('file:///C:/path/%5C'));
                  +readFileSync(new URL('file:///C:/path/%5c'));
                  +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
                  +\ or / characters */
                  +
                  Buffer paths#
                  +

                  Paths specified using a <Buffer> are useful primarily on certain POSIX +operating systems that treat file paths as opaque byte sequences. On such +systems, it is possible for a single file path to contain sub-sequences that +use multiple character encodings. As with string paths, <Buffer> paths may +be relative or absolute:

                  +

                  Example using an absolute path on POSIX:

                  +
                  import { open } from 'fs/promises';
                  +
                  +let fd;
                  +try {
                  +  fd = await open(Buffer.from('/open/some/file.txt'), 'r');
                  +  // Do something with the file
                  +} finally {
                  +  await fd.close();
                  +}
                  +
                  Per-drive working directories on Windows#
                  +

                  On Windows, Node.js follows the concept of per-drive working directory. This +behavior can be observed when using a drive path without a backslash. For +example fs.readdirSync('C:\\') can potentially return a different result than +fs.readdirSync('C:'). For more information, see +this MSDN page.

                  +

                  File descriptors#

                  +

                  On POSIX systems, for every process, the kernel maintains a table of currently +open files and resources. Each open file is assigned a simple numeric +identifier called a file descriptor. At the system-level, all file system +operations use these file descriptors to identify and track each specific +file. Windows systems use a different but conceptually similar mechanism for +tracking resources. To simplify things for users, Node.js abstracts away the +differences between operating systems and assigns all open files a numeric file +descriptor.

                  +

                  The callback-based fs.open(), and synchronous fs.openSync() methods open a +file and allocate a new file descriptor. Once allocated, the file descriptor may +be used to read data from, write data to, or request information about the file.

                  +

                  Operating systems limit the number of file descriptors that may be open +at any given time so it is critical to close the descriptor when operations +are completed. Failure to do so will result in a memory leak that will +eventually cause an application to crash.

                  +
                  import { open, close, fstat } from 'fs';
                  +
                  +function closeFd(fd) {
                  +  close(fd, (err) => {
                  +    if (err) throw err;
                  +  });
                  +}
                  +
                  +open('/open/some/file.txt', 'r', (err, fd) => {
                  +  if (err) throw err;
                  +  try {
                  +    fstat(fd, (err, stat) => {
                  +      if (err) {
                  +        closeFd(fd);
                  +        throw err;
                  +      }
                  +
                  +      // use stat
                  +
                  +      closeFd(fd);
                  +    });
                  +  } catch (err) {
                  +    closeFd(fd);
                  +    throw err;
                  +  }
                  +});
                  +

                  The promise-based APIs use a <FileHandle> object in place of the numeric +file descriptor. These objects are better managed by the system to ensure +that resources are not leaked. However, it is still required that they are +closed when operations are completed:

                  +
                  import { open } from 'fs/promises';
                  +
                  +let file;
                  +try {
                  +  file = await open('/open/some/file.txt', 'r');
                  +  const stat = await file.stat();
                  +  // use stat
                  +} finally {
                  +  await file.close();
                  +}
                  +

                  Threadpool usage#

                  +

                  All callback and promise-based file system APIs ( with the exception of +fs.FSWatcher()) use libuv's threadpool. This can have surprising and negative +performance implications for some applications. See the +UV_THREADPOOL_SIZE documentation for more information.

                  +

                  File system flags#

                  The following flags are available wherever the flag option takes a string.

                    @@ -34630,31 +37299,32 @@ or O_EXCL|O_CREAT to CREATE_NEW, as accepted by

                    The exclusive flag 'x' (O_EXCL flag in open(2)) causes the operation to return an error if the path already exists. On POSIX, if the path is a symbolic link, using O_EXCL returns an error even if the link is to a path that does -not exist. The exclusive flag may or may not work with network file systems.

                    +not exist. The exclusive flag might not work with network file systems.

                    On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file.

                    -

                    Modifying a file rather than replacing it may require a flags mode of 'r+' -rather than the default mode 'w'.

                    +

                    Modifying a file rather than replacing it may require the flag option to be +set to 'r+' rather than the default 'w'.

                    The behavior of some flags are platform-specific. As such, opening a directory on macOS and Linux with the 'a+' flag, as in the example below, will return an error. In contrast, on Windows and FreeBSD, a file descriptor or a FileHandle will be returned.

                    // macOS and Linux
                    -fs.open('<directory>', 'a+', (err, fd) => {
                    +fs.open('<directory>', 'a+', (err, fd) => {
                       // => [Error: EISDIR: illegal operation on a directory, open <directory>]
                     });
                     
                     // Windows and FreeBSD
                    -fs.open('<directory>', 'a+', (err, fd) => {
                    +fs.open('<directory>', 'a+', (err, fd) => {
                       // => null, <fd>
                     });

                    On Windows, opening an existing hidden file using the 'w' flag (either through fs.open() or fs.writeFile() or fsPromises.open()) will fail with EPERM. Existing hidden files can be opened for writing with the 'r+' flag.

                    A call to fs.ftruncate() or filehandle.truncate() can be used to reset -the file contents.

                    -

                    Global objects#

                    +the file contents.

                  + +

                  Global objects#

                  These objects are available in all modules. The following variables may appear @@ -34670,7 +37340,97 @@ to be global but are not. They exist only in the scope of modules, see the

                  The objects listed here are specific to Node.js. There are built-in objects that are part of the JavaScript language itself, which are also globally accessible.

                  -

                  Class: Buffer#

                  +

                  Class: AbortController#

                  + +

                  Stability: 1 - Experimental

                  + +

                  A utility class used to signal cancelation in selected Promise-based APIs. +The API is based on the Web API AbortController.

                  +

                  To use, launch Node.js using the --experimental-abortcontroller flag.

                  +
                  const ac = new AbortController();
                  +
                  +ac.signal.addEventListener('abort', () => console.log('Aborted!'),
                  +                           { once: true });
                  +
                  +ac.abort();
                  +
                  +console.log(ac.signal.aborted);  // Prints True
                  +

                  abortController.abort()#

                  + +

                  Triggers the abort signal, causing the abortController.signal to emit +the 'abort' event.

                  +

                  abortController.signal#

                  + + +

                  Class: AbortSignal#

                  + + +

                  The AbortSignal is used to notify observers when the +abortController.abort() method is called.

                  +
                  Static method: AbortSignal.abort()#
                  + + +

                  Returns a new already aborted AbortSignal.

                  +
                  Event: 'abort'#
                  + +

                  The 'abort' event is emitted when the abortController.abort() method +is called. The callback is invoked with a single object argument with a +single type property set to 'abort':

                  +
                  const ac = new AbortController();
                  +
                  +// Use either the onabort property...
                  +ac.signal.onabort = () => console.log('aborted!');
                  +
                  +// Or the EventTarget API...
                  +ac.signal.addEventListener('abort', (event) => {
                  +  console.log(event.type);  // Prints 'abort'
                  +}, { once: true });
                  +
                  +ac.abort();
                  +

                  The AbortController with which the AbortSignal is associated will only +ever trigger the 'abort' event once. We recommended that code check +that the abortSignal.aborted attribute is false before adding an 'abort' +event listener.

                  +

                  Any event listeners attached to the AbortSignal should use the +{ once: true } option (or, if using the EventEmitter APIs to attach a +listener, use the once() method) to ensure that the event listener is +removed as soon as the 'abort' event is handled. Failure to do so may +result in memory leaks.

                  +
                  abortSignal.aborted#
                  + +
                    +
                  • Type: <boolean> True after the AbortController has been aborted.
                  • +
                  +
                  abortSignal.onabort#
                  + + +

                  An optional callback function that may be set by user code to be notified +when the abortController.abort() function has been called.

                  +

                  Class: Buffer#

                  @@ -34679,29 +37439,29 @@ accessible.

                • <Function>

                Used to handle binary data. See the buffer section.

                -

                __dirname#

                +

                __dirname#

                This variable may appear to be global but is not. See __dirname.

                -

                __filename#

                +

                __filename#

                This variable may appear to be global but is not. See __filename.

                -

                clearImmediate(immediateObject)#

                +

                clearImmediate(immediateObject)#

                clearImmediate is described in the timers section.

                -

                clearInterval(intervalObject)#

                +

                clearInterval(intervalObject)#

                clearInterval is described in the timers section.

                -

                clearTimeout(timeoutObject)#

                +

                clearTimeout(timeoutObject)#

                clearTimeout is described in the timers section.

                -

                console#

                +

                console#

                @@ -34710,9 +37470,9 @@ accessible.

              • <Object>

              Used to print to stdout and stderr. See the console section.

              -

              exports#

              +

              exports#

              This variable may appear to be global but is not. See exports.

              -

              global#

              +

              global#

              @@ -34724,9 +37484,9 @@ accessible.

              within the browser var something will define a new global variable. In Node.js this is different. The top-level scope is not the global scope; var something inside a Node.js module will be local to that module.

              -

              module#

              +

              module#

              This variable may appear to be global but is not. See module.

              -

              process#

              +

              process#

              @@ -34735,7 +37495,7 @@ Node.js this is different. The top-level scope is not the global scope;
            • <Object>

            The process object. See the process object section.

            -

            queueMicrotask(callback)#

            +

            queueMicrotask(callback)#

            @@ -34755,64 +37515,64 @@ within each turn of the Node.js event loop.

            // `process.nextTick()` here would result in the 'load' event always emitting // before any other promise jobs. -DataHandler.prototype.load = async function load(key) { - const hit = this._cache.get(url); +DataHandler.prototype.load = async function load(key) { + const hit = this._cache.get(key); if (hit !== undefined) { - queueMicrotask(() => { - this.emit('load', hit); + queueMicrotask(() => { + this.emit('load', hit); }); return; } - const data = await fetchData(key); - this._cache.set(url, data); - this.emit('load', data); + const data = await fetchData(key); + this._cache.set(key, data); + this.emit('load', data); };
            -

            require()#

            +

            require()#

            This variable may appear to be global but is not. See require().

            -

            setImmediate(callback[, ...args])#

            +

            setImmediate(callback[, ...args])#

            setImmediate is described in the timers section.

            -

            setInterval(callback, delay[, ...args])#

            +

            setInterval(callback, delay[, ...args])#

            setInterval is described in the timers section.

            -

            setTimeout(callback, delay[, ...args])#

            +

            setTimeout(callback, delay[, ...args])#

            setTimeout is described in the timers section.

            -

            TextDecoder#

            +

            TextDecoder#

            The WHATWG TextDecoder class. See the TextDecoder section.

            -

            TextEncoder#

            +

            TextEncoder#

            The WHATWG TextEncoder class. See the TextEncoder section.

            -

            URL#

            +

            URL#

            The WHATWG URL class. See the URL section.

            -

            URLSearchParams#

            +

            URLSearchParams#

            The WHATWG URLSearchParams class. See the URLSearchParams section.

            -

            WebAssembly#

            +

            WebAssembly#

            @@ -34822,11 +37582,12 @@ DataHandler.prototype.load = async

            The object that acts as the namespace for all W3C WebAssembly related functionality. See the -Mozilla Developer Network for usage and compatibility.

            -

            HTTP#

            +Mozilla Developer Network for usage and compatibility.

            + +

            HTTP#

            Stability: 2 - Stable

            -

            Source Code: lib/http.js

            +

            Source Code: lib/http.js

            To use the HTTP server and client one must require('http').

            The HTTP interfaces in Node.js are designed to support many features of the protocol which have been traditionally difficult to use. @@ -34857,7 +37618,7 @@ list like the following:

            'CONNECTION', 'keep-alive', 'Host', 'mysite.com', 'accepT', '*/*' ]
            -

            Class: http.Agent#

            +

            Class: http.Agent#

            @@ -34885,17 +37646,17 @@ longer in use, because unused sockets consume OS resources.

            a 'close' event or an 'agentRemove' event. When intending to keep one HTTP request open for a long time without keeping it in the agent, something like the following may be done:

            -
            http.get(options, (res) => {
            +
            http.get(options, (res) => {
               // Do stuff
            -}).on('socket', (socket) => {
            -  socket.emit('agentRemove');
            +}).on('socket', (socket) => {
            +  socket.emit('agentRemove');
             });

            An agent may also be used for an individual request. By providing {agent: false} as an option to the http.get() or http.request() functions, a one-time use Agent with default options will be used for the client connection.

            agent:false:

            -
            http.get({
            +
            http.get({
               hostname: 'localhost',
               port: 80,
               path: '/',
            @@ -34903,15 +37664,17 @@ for the client connection.

            }, (res) => { // Do stuff with response });
            -

            new Agent([options])#

            +

            new Agent([options])#

          @@ -34965,10 +37734,10 @@ This will set the timeout when the socket is created. of these values set to their respective defaults.

          To configure any of them, a custom http.Agent instance must be created.

          const http = require('http');
          -const keepAliveAgent = new http.Agent({ keepAlive: true });
          -options.agent = keepAliveAgent;
          -http.request(options, onResponseCallback);
          -

          agent.createConnection(options[, callback])#

          +const keepAliveAgent = new http.Agent({ keepAlive: true }); +options.agent = keepAliveAgent; +http.request(options, onResponseCallback);
          +

          agent.createConnection(options[, callback])#

          @@ -34987,7 +37756,7 @@ socket/stream from this function, or by passing the socket/stream to callb a subclass of <stream.Duplex>, unless the user specifies a socket type other than <net.Socket>.

          callback has a signature of (err, stream).

          -

          agent.keepSocketAlive(socket)#

          +

          agent.keepSocketAlive(socket)#

          @@ -34996,15 +37765,15 @@ type other than <net.Socket>

          Called when socket is detached from a request and could be persisted by the Agent. Default behavior is to:

          -
          socket.setKeepAlive(true, this.keepAliveMsecs);
          -socket.unref();
          +
          socket.setKeepAlive(true, this.keepAliveMsecs);
          +socket.unref();
           return true;

          This method can be overridden by a particular Agent subclass. If this method returns a falsy value, the socket will be destroyed instead of persisting it for use with the next request.

          The socket argument can be an instance of <net.Socket>, a subclass of <stream.Duplex>.

          -

          agent.reuseSocket(socket, request)#

          +

          agent.reuseSocket(socket, request)#

          @@ -35014,21 +37783,21 @@ it for use with the next request.

        Called when socket is attached to request after being persisted because of the keep-alive options. Default behavior is to:

        -
        socket.ref();
        +
        socket.ref();

        This method can be overridden by a particular Agent subclass.

        The socket argument can be an instance of <net.Socket>, a subclass of <stream.Duplex>.

        -

        agent.destroy()#

        +

        agent.destroy()#

        Destroy any sockets that are currently in use by the agent.

        It is usually not necessary to do this. However, if using an agent with keepAlive enabled, then it is best to explicitly shut down -the agent when it will no longer be used. Otherwise, -sockets may hang open for quite a long time before the server +the agent when it is no longer needed. Otherwise, +sockets might stay open for quite a long time before the server terminates them.

        -

        agent.freeSockets#

        +

        agent.freeSockets#

        @@ -35039,7 +37808,7 @@ terminates them.

        the agent when keepAlive is enabled. Do not modify.

        Sockets in the freeSockets list will be automatically destroyed and removed from the array on 'timeout'.

        -

        agent.getName(options)#

        +

        agent.getName(options)#

        @@ -35061,7 +37830,7 @@ connection can be reused. For an HTTP agent, this returns host:port:localAddress or host:port:localAddress:family. For an HTTPS agent, the name includes the CA, cert, ciphers, and other HTTPS/TLS-specific options that determine socket reusability.

        -

        agent.maxFreeSockets#

        +

        agent.maxFreeSockets#

        @@ -35071,7 +37840,7 @@ that determine socket reusability.

        By default set to 256. For agents with keepAlive enabled, this sets the maximum number of sockets that will be left open in the free state.

        -

        agent.maxSockets#

        +

        agent.maxSockets#

        @@ -35080,16 +37849,16 @@ state.

      By default set to Infinity. Determines how many concurrent sockets the agent can have open per origin. Origin is the returned value of agent.getName().

      -

      agent.maxTotalSockets#

      +

      agent.maxTotalSockets#

      By default set to Infinity. Determines how many concurrent sockets the agent can have open. Unlike maxSockets, this parameter applies across all origins.

      -

      agent.requests#

      +

      agent.requests#

      @@ -35098,7 +37867,7 @@ can have open. Unlike maxSockets, this parameter applies across all

      An object which contains queues of requests that have not yet been assigned to sockets. Do not modify.

      -

      agent.sockets#

      +

      agent.sockets#

      @@ -35107,7 +37876,7 @@ sockets. Do not modify.

      An object which contains arrays of sockets currently in use by the agent. Do not modify.

      -

      Class: http.ClientRequest#

      +

      Class: http.ClientRequest#

      @@ -35138,13 +37907,13 @@ the data is read it will consume memory that can eventually lead to a 'aborted' event.

      Node.js does not check whether Content-Length and the length of the body which has been transmitted are equal or not.

      -

      Event: 'abort'#

      +

      Event: 'abort'#

      Emitted when the request has been aborted by the client. This event is only emitted on the first call to abort().

      -

      Event: 'connect'#

      +

      Event: 'connect'#

      @@ -35162,28 +37931,28 @@ type other than <net.Socket>A client and server pair demonstrating how to listen for the 'connect' event:

      const http = require('http');
       const net = require('net');
      -const { URL } = require('url');
      +const { URL } = require('url');
       
       // Create an HTTP tunneling proxy
      -const proxy = http.createServer((req, res) => {
      -  res.writeHead(200, { 'Content-Type': 'text/plain' });
      -  res.end('okay');
      +const proxy = http.createServer((req, res) => {
      +  res.writeHead(200, { 'Content-Type': 'text/plain' });
      +  res.end('okay');
       });
      -proxy.on('connect', (req, clientSocket, head) => {
      +proxy.on('connect', (req, clientSocket, head) => {
         // Connect to an origin server
      -  const { port, hostname } = new URL(`http://${req.url}`);
      -  const serverSocket = net.connect(port || 80, hostname, () => {
      -    clientSocket.write('HTTP/1.1 200 Connection Established\r\n' +
      +  const { port, hostname } = new URL(`http://${req.url}`);
      +  const serverSocket = net.connect(port || 80, hostname, () => {
      +    clientSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                           'Proxy-agent: Node.js-Proxy\r\n' +
                           '\r\n');
      -    serverSocket.write(head);
      -    serverSocket.pipe(clientSocket);
      -    clientSocket.pipe(serverSocket);
      +    serverSocket.write(head);
      +    serverSocket.pipe(clientSocket);
      +    clientSocket.pipe(serverSocket);
         });
       });
       
       // Now that proxy is running
      -proxy.listen(1337, '127.0.0.1', () => {
      +proxy.listen(1337, '127.0.0.1', () => {
       
         // Make a request to a tunneling proxy
         const options = {
      @@ -35193,33 +37962,33 @@ proxy.listen(1337, '1
           path: 'www.google.com:80'
         };
       
      -  const req = http.request(options);
      -  req.end();
      +  const req = http.request(options);
      +  req.end();
       
      -  req.on('connect', (res, socket, head) => {
      -    console.log('got connected!');
      +  req.on('connect', (res, socket, head) => {
      +    console.log('got connected!');
       
           // Make a request over an HTTP tunnel
      -    socket.write('GET / HTTP/1.1\r\n' +
      +    socket.write('GET / HTTP/1.1\r\n' +
                        'Host: www.google.com:80\r\n' +
                        'Connection: close\r\n' +
                        '\r\n');
      -    socket.on('data', (chunk) => {
      -      console.log(chunk.toString());
      +    socket.on('data', (chunk) => {
      +      console.log(chunk.toString());
           });
      -    socket.on('end', () => {
      -      proxy.close();
      +    socket.on('end', () => {
      +      proxy.close();
           });
         });
       });
      -

      Event: 'continue'#

      +

      Event: 'continue'#

      Emitted when the server sends a '100 Continue' HTTP response, usually because the request contained 'Expect: 100-continue'. This is an instruction that the client should send the request body.

      -

      Event: 'information'#

      +

      Event: 'information'#

      @@ -35249,17 +38018,17 @@ and array with the raw header names followed by their respective values.

      }; // Make a request -const req = http.request(options); -req.end(); +const req = http.request(options); +req.end(); -req.on('information', (info) => { - console.log(`Got information prior to main response: ${info.statusCode}`); +req.on('information', (info) => { + console.log(`Got information prior to main response: ${info.statusCode}`); });

      101 Upgrade statuses do not fire this event due to their break from the traditional HTTP request/response chain, such as web sockets, in-place TLS upgrades, or HTTP 2.0. To be notified of 101 Upgrade notices, listen for the 'upgrade' event instead.

      -

      Event: 'response'#

      +

      Event: 'response'#

      @@ -35268,7 +38037,7 @@ upgrades, or HTTP 2.0. To be notified of 101 Upgrade notices, listen for the

      Emitted when a response is received to this request. This event is emitted only once.

      -

      Event: 'socket'#

      +

      Event: 'socket'#

      @@ -35278,14 +38047,14 @@ once.

      This event is guaranteed to be passed an instance of the <net.Socket> class, a subclass of <stream.Duplex>, unless the user specifies a socket type other than <net.Socket>.

      -

      Event: 'timeout'#

      +

      Event: 'timeout'#

      Emitted when the underlying socket times out from inactivity. This only notifies that the socket has been idle. The request must be aborted manually.

      See also: request.setTimeout().

      -

      Event: 'upgrade'#

      +

      Event: 'upgrade'#

      @@ -35305,21 +38074,21 @@ type other than <net.Socket>const http = require('http'); // Create an HTTP server -const server = http.createServer((req, res) => { - res.writeHead(200, { 'Content-Type': 'text/plain' }); - res.end('okay'); +const server = http.createServer((req, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('okay'); }); -server.on('upgrade', (req, socket, head) => { - socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' + +server.on('upgrade', (req, socket, head) => { + socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' + 'Upgrade: WebSocket\r\n' + 'Connection: Upgrade\r\n' + '\r\n'); - socket.pipe(socket); // echo back + socket.pipe(socket); // echo back }); // Now that server is running -server.listen(1337, '127.0.0.1', () => { +server.listen(1337, '127.0.0.1', () => { // make a request const options = { @@ -35331,22 +38100,23 @@ server.listen(1337, ' } }; - const req = http.request(options); - req.end(); + const req = http.request(options); + req.end(); - req.on('upgrade', (res, socket, upgradeHead) => { - console.log('got upgraded!'); - socket.end(); - process.exit(0); + req.on('upgrade', (res, socket, upgradeHead) => { + console.log('got upgraded!'); + socket.end(); + process.exit(0); }); }); -

      request.abort()#

      +

      request.abort()#

      +

      Stability: 0 - Deprecated: Use request.destroy() instead.

      Marks the request as aborting. Calling this will cause remaining data in the response to be dropped and the socket to be destroyed.

      -

      request.aborted#

      +

      request.aborted#

      +
        +
      • error <Error> Optional, an error to emit with 'error' event.
      • +
      • Returns: <this>
      • +
      +

      Destroy the request. Optionally emit an 'error' event, +and emit a 'close' event. Calling this will cause remaining data +in the response to be dropped and the socket to be destroyed.

      +

      See writable.destroy() for further details.

      +
      request.destroyed#
      + + +

      Is true after request.destroy() has been called.

      +

      See writable.destroyed for further details.

      +

      request.finished#

        @@ -35407,7 +38207,7 @@ is finished.

        The request.finished property will be true if request.end() has been called. request.end() will automatically be called if the request was initiated via http.get().

        -

        request.flushHeaders()#

        +

        request.flushHeaders()#

        @@ -35418,7 +38218,7 @@ then tries to pack the request headers and data into a single TCP packet.

        That's usually desired (it saves a TCP round-trip), but not when the first data is not sent until possibly much later. request.flushHeaders() bypasses the optimization and kickstarts the request.

        -

        request.getHeader(name)#

        +

        request.getHeader(name)#

        @@ -35429,49 +38229,63 @@ the optimization and kickstarts the request.

        Reads out a header on the request. The name is case-insensitive. The type of the return value depends on the arguments provided to request.setHeader().

        -
        request.setHeader('content-type', 'text/html');
        -request.setHeader('Content-Length', Buffer.byteLength(body));
        -request.setHeader('Cookie', ['type=ninja', 'language=javascript']);
        -const contentType = request.getHeader('Content-Type');
        +
        request.setHeader('content-type', 'text/html');
        +request.setHeader('Content-Length', Buffer.byteLength(body));
        +request.setHeader('Cookie', ['type=ninja', 'language=javascript']);
        +const contentType = request.getHeader('Content-Type');
         // 'contentType' is 'text/html'
        -const contentLength = request.getHeader('Content-Length');
        +const contentLength = request.getHeader('Content-Length');
         // 'contentLength' is of type number
        -const cookie = request.getHeader('Cookie');
        +const cookie = request.getHeader('Cookie');
         // 'cookie' is of type string[]
        -

        request.maxHeadersCount#

        +

        request.getRawHeaderNames()#

        + + +

        Returns an array containing the unique names of the current outgoing raw +headers. Header names are returned with their exact casing being set.

        +
        request.setHeader('Foo', 'bar');
        +request.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
        +
        +const headerNames = request.getRawHeaderNames();
        +// headerNames === ['Foo', 'Set-Cookie']
        +

        request.maxHeadersCount#

        Limits maximum response headers count. If set to 0, no limit will be applied.

        -

        request.path#

        +

        request.path#

        -

        request.method#

        +

        request.method#

        -

        request.host#

        +

        request.host#

        -

        request.protocol#

        +

        request.protocol#

        -

        request.removeHeader(name)#

        +

        request.removeHeader(name)#

        @@ -35479,10 +38293,10 @@ request.setHeader('Cookie', [<string>

      Removes a header that's already defined into headers object.

      -
      request.removeHeader('Content-Type');
      -

      request.reusedSocket#

      +
      request.removeHeader('Content-Type');
      +

      request.reusedSocket#

      • <boolean> Whether the request is send through a reused socket.
      • @@ -35494,16 +38308,16 @@ may run into a 'ECONNRESET' error.

        // Server has a 5 seconds keep-alive timeout by default http - .createServer((req, res) => { - res.write('hello\n'); - res.end(); + .createServer((req, res) => { + res.write('hello\n'); + res.end(); }) - .listen(3000); + .listen(3000); setInterval(() => { // Adapting a keep-alive agent - http.get('http://localhost:3000', { agent }, (res) => { - res.on('data', (data) => { + http.get('http://localhost:3000', { agent }, (res) => { + res.on('data', (data) => { // Do nothing }); }); @@ -35511,23 +38325,23 @@ http

        By marking a request whether it reused socket or not, we can do automatic error retry base on it.

        const http = require('http');
        -const agent = new http.Agent({ keepAlive: true });
        +const agent = new http.Agent({ keepAlive: true });
         
        -function retriableRequest() {
        +function retriableRequest() {
           const req = http
        -    .get('http://localhost:3000', { agent }, (res) => {
        +    .get('http://localhost:3000', { agent }, (res) => {
               // ...
             })
        -    .on('error', (err) => {
        +    .on('error', (err) => {
               // Check if retry is needed
        -      if (req.reusedSocket && err.code === 'ECONNRESET') {
        -        retriableRequest();
        +      if (req.reusedSocket && err.code === 'ECONNRESET') {
        +        retriableRequest();
               }
             });
         }
         
        -retriableRequest();
        -

        request.setHeader(name, value)#

        +retriableRequest();
        +

        request.setHeader(name, value)#

        @@ -35541,10 +38355,10 @@ here to send multiple headers with the same name. Non-string values will be stored without modification. Therefore, request.getHeader() may return non-string values. However, the non-string values will be converted to strings for network transmission.

        -
        request.setHeader('Content-Type', 'application/json');
        +
        request.setHeader('Content-Type', 'application/json');

        or

        -
        request.setHeader('Cookie', ['type=ninja', 'language=javascript']);
        -

        request.setNoDelay([noDelay])#

        +
        request.setHeader('Cookie', ['type=ninja', 'language=javascript']);
        +

        request.setNoDelay([noDelay])#

        @@ -35553,7 +38367,7 @@ for network transmission.

      Once a socket is assigned to this request and is connected socket.setNoDelay() will be called.

      -

      request.setSocketKeepAlive([enable][, initialDelay])#

      +

      request.setSocketKeepAlive([enable][, initialDelay])#

      @@ -35563,7 +38377,7 @@ for network transmission.

      Once a socket is assigned to this request and is connected socket.setKeepAlive() will be called.

      -

      request.setTimeout(timeout[, callback])#

      +

      request.setTimeout(timeout[, callback])#

      + @@ -35890,26 +38724,30 @@ the Server object, passing the socket as an argument, if a timeout occurs.

      If there is a 'timeout' event listener on the Server object, then it will be called with the timed-out socket as an argument.

      -

      By default, the Server's timeout value is 2 minutes, and sockets are -destroyed automatically if they time out. However, if a callback is assigned -to the Server's 'timeout' event, timeouts must be handled explicitly.

      -

      To change the default timeout use the --http-server-default-timeout -flag.

      -

      server.timeout#

      +

      By default, the Server does not timeout sockets. However, if a callback +is assigned to the Server's 'timeout' event, timeouts must be handled +explicitly.

      +

      server.timeout#

        -
      • <number> Timeout in milliseconds. Default: 120000 (2 minutes).
      • +
      • <number> Timeout in milliseconds. Default: 0 (no timeout)

      The number of milliseconds of inactivity before a socket is presumed to have timed out.

      A value of 0 will disable the timeout behavior on incoming connections.

      The socket timeout logic is set up on connection, so changing this value only affects new connections to the server, not any existing connections.

      -

      To change the default timeout use the --http-server-default-timeout -flag.

      -

      server.keepAliveTimeout#

      +

      server.keepAliveTimeout#

      @@ -35927,7 +38765,7 @@ A value of 0 makes the http server behave similarly to Node.js vers to 8.0.0, which did not have a keep-alive timeout.

      The socket timeout logic is set up on connection, so changing this value only affects new connections to the server, not any existing connections.

      -

      Class: http.ServerResponse#

      +

      Class: http.ServerResponse#

      @@ -35936,13 +38774,13 @@ affects new connections to the server, not any existing connections.

      This object is created internally by an HTTP server, not by the user. It is passed as the second parameter to the 'request' event.

      -

      Event: 'close'#

      +

      Event: 'close'#

      -

      Indicates that the the response is completed, or its underlying connection was +

      Indicates that the response is completed, or its underlying connection was terminated prematurely (before the response completion).

      -

      Event: 'finish'#

      +

      Event: 'finish'#

      @@ -35950,7 +38788,7 @@ terminated prematurely (before the response completion).

      emitted when the last segment of the response headers and body have been handed off to the operating system for transmission over the network. It does not imply that the client has received anything yet.

      -

      response.addTrailers(headers)#

      +

      response.addTrailers(headers)#

      @@ -35964,27 +38802,28 @@ response; if it is not (e.g. if the request was HTTP/1.0), they will be silently discarded.

      HTTP requires the Trailer header to be sent in order to emit trailers, with a list of the header fields in its value. E.g.,

      -
      response.writeHead(200, { 'Content-Type': 'text/plain',
      +
      response.writeHead(200, { 'Content-Type': 'text/plain',
                                 'Trailer': 'Content-MD5' });
      -response.write(fileData);
      -response.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' });
      -response.end();
      +response.write(fileData); +response.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' }); +response.end();

      Attempting to set a header field name or value that contains invalid characters will result in a TypeError being thrown.

      -

      response.connection#

      +

      response.connection#

      +

      Stability: 0 - Deprecated. Use response.socket.

      See response.socket.

      -

      response.cork()#

      +

      response.cork()#

      See writable.cork().

      -

      response.end([data[, encoding]][, callback])#

      +

      response.end([data[, encoding]][, callback])#

      + +

      Finishes the outgoing message. If any parts of the body are unsent, it will +flush them to the underlying system. If the message is chunked, it will +send the terminating chunk 0\r\n\r\n, and send the trailer (if any).

      +

      If chunk is specified, it is equivalent to call +outgoingMessage.write(chunk, encoding), followed by +outgoingMessage.end(callback).

      +

      If callback is provided, it will be called when the message is finished. +(equivalent to the callback to event finish)

      +

      outgoingMessage.flushHeaders()#

      + +

      Compulsorily flushes the message headers

      +

      For efficiency reason, Node.js normally buffers the message headers +until outgoingMessage.end() is called or the first chunk of message data +is written. It then tries to pack the headers and data into a single TCP +packet.

      +

      It is usually desired (it saves a TCP round-trip), but not when the first +data is not sent until possibly much later. outgoingMessage.flushHeaders() +bypasses the optimization and kickstarts the request.

      +

      outgoingMessage.getHeader(name)#

      + + +

      Gets the value of HTTP header with the given name. If such a name doesn't +exist in message, it will be undefined.

      +

      outgoingMessage.getHeaderNames()#

      + + +

      Returns an array of names of headers of the outgoing outgoingMessage. All +names are lowercase.

      +

      outgoingMessage.getHeaders()#

      + + +

      Returns a shallow copy of the current outgoing headers. Since a shallow +copy is used, array values may be mutated without additional calls to +various header-related HTTP module methods. The keys of the returned +object are the header names and the values are the respective header +values. All header names are lowercase.

      +

      The object returned by the outgoingMessage.getHeaders() method does +not prototypically inherit from the JavaScript Object. This means that +typical Object methods such as obj.toString(), obj.hasOwnProperty(), +and others are not defined and will not work.

      +
      outgoingMessage.setHeader('Foo', 'bar');
      +outgoingMessage.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);
      +
      +const headers = outgoingMessage.getHeaders();
      +// headers === { foo: 'bar', 'set-cookie': ['foo=bar', 'bar=baz'] }
      +

      outgoingMessage.hasHeader(name)#

      + + +

      Returns true if the header identified by name is currently set in the +outgoing headers. The header name is case-insensitive.

      +
      const hasContentType = outgoingMessage.hasHeader('content-type');
      +

      outgoingMessage.headersSent#

      + + +

      Read-only. true if the headers were sent, otherwise false.

      +

      outgoingMessage.pipe()#

      + +

      Overrides the pipe method of legacy Stream which is the parent class of +http.outgoingMessage.

      +

      Since OutgoingMessage should be a write-only stream, +call this function will throw an Error. Thus, it disabled the pipe method +it inherits from Stream.

      +

      The User should not call this function directly.

      +

      outgoingMessage.removeHeader()#

      + +

      Removes a header that is queued for implicit sending.

      +
      outgoingMessage.removeHeader('Content-Encoding');
      +

      outgoingMessage.setHeader(name, value)#

      + + +

      Sets a single header value for the header object.

      +

      outgoingMessage.setTimeout(msesc[, callback])#

      + + +

      occurs, Same as binding to the timeout event.

      + +

      Once a socket is associated with the message and is connected, +socket.setTimeout() will be called with msecs as the first parameter.

      +

      outgoingMessage.socket#

      + + +

      Reference to the underlying socket. Usually, users will not want to access +this property.

      +

      After calling outgoingMessage.end(), this property will be nulled.

      +

      outgoingMessage.uncork()#

      + +

      See writable.uncork()

      +

      outgoingMessage.writableCorked#

      + + +

      This outgoingMessage.writableCorked will return the time how many +outgoingMessage.cork() have been called.

      +

      outgoingMessage.writableEnded#

      + + +

      Readonly, true if outgoingMessage.end() has been called. Noted that +this property does not reflect whether the data has been flush. For that +purpose, use message.writableFinished instead.

      +

      outgoingMessage.writableFinished#

      + + +

      Readonly. true if all data has been flushed to the underlying system.

      +

      outgoingMessage.writableHighWaterMark#

      + + +

      This outgoingMessage.writableHighWaterMark will be the highWaterMark of +underlying socket if socket exists. Else, it would be the default +highWaterMark.

      +

      highWaterMark is the maximum amount of data that can be potentially +buffered by the socket.

      +

      outgoingMessage.writableLength#

      + + +

      Readonly, This outgoingMessage.writableLength contains the number of +bytes (or objects) in the buffer ready to send.

      +

      outgoingMessage.writableObjectMode#

      + + +

      Readonly, always returns false.

      +

      outgoingMessage.write(chunk[, encoding][, callback])#

      + + +

      If this method is called and the header is not sent, it will call +this._implicitHeader to flush implicit header. +If the message should not have a body (indicated by this._hasBody), +the call is ignored and chunk will not be sent. It could be useful +when handling a particular message which must not include a body. +e.g. response to HEAD request, 204 and 304 response.

      +

      chunk can be a string or a buffer. When chunk is a string, the +encoding parameter specifies how to encode chunk into a byte stream. +callback will be called when the chunk is flushed.

      +

      If the message is transferred in chucked encoding +(indicated by this.chunkedEncoding), chunk will be flushed as +one chunk among a stream of chunks. Otherwise, it will be flushed as the +body of message.

      +

      This method handles the raw body of the HTTP message and has nothing to do +with higher-level multi-part body encodings that may be used.

      +

      If it is the first call to this method of a message, it will send the +buffered header first, then flush the chunk as described above.

      +

      The second and successive calls to this method will assume the data +will be streamed and send the new data separately. It means that the response +is buffered up to the first chunk of the body.

      +

      Returns true if the entire data was flushed successfully to the kernel +buffer. Returns false if all or part of the data was queued in the user +memory. Event drain will be emitted when the buffer is free again.

      +

      http.METHODS#

      @@ -36590,7 +39753,7 @@ URL {
    • <string[]>
    • A list of the HTTP methods that are supported by the parser.

      -

      http.STATUS_CODES#

      +

      http.STATUS_CODES#

      @@ -36599,12 +39762,14 @@ URL {

      A collection of all the standard HTTP response status codes, and the short description of each. For example, http.STATUS_CODES[404] === 'Not Found'.

      -

      http.createServer([options][, requestListener])#

      +

      http.createServer([options][, requestListener])#

      https.createServer([options][, requestListener])#

      @@ -40271,29 +43739,29 @@ This method is identical to server.listen()const fs = require('fs'); const options = { - key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), - cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') + key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), + cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') }; -https.createServer(options, (req, res) => { - res.writeHead(200); - res.end('hello world\n'); -}).listen(8000); +https.createServer(options, (req, res) => { + res.writeHead(200); + res.end('hello world\n'); +}).listen(8000);

      Or

      const https = require('https');
       const fs = require('fs');
       
       const options = {
      -  pfx: fs.readFileSync('test/fixtures/test_cert.pfx'),
      +  pfx: fs.readFileSync('test/fixtures/test_cert.pfx'),
         passphrase: 'sample'
       };
       
      -https.createServer(options, (req, res) => {
      -  res.writeHead(200);
      -  res.end('hello world\n');
      -}).listen(8000);
      -

      https.get(options[, callback])#

      -

      https.get(url[, options][, callback])#

      +https.createServer(options, (req, res) => { + res.writeHead(200); + res.end('hello world\n'); +}).listen(8000);
      +

      https.get(options[, callback])#

      +

      https.get(url[, options][, callback])#

      Detecting internationalization support#

      To verify that ICU is enabled at all (system-icu, small-icu, or full-icu), simply checking the existence of Intl should suffice:

      -
      const hasICU = typeof Intl === 'object';
      +
      const hasICU = typeof Intl === 'object';

      Alternatively, checking for process.versions.icu, a property defined only when ICU is enabled, works too:

      -
      const hasICU = typeof process.versions.icu === 'string';
      +
      const hasICU = typeof process.versions.icu === 'string';

      To check for support for a non-English locale (i.e. full-icu or system-icu), Intl.DateTimeFormat can be a good distinguishing factor:

      const hasFullICU = (() => {
         try {
      -    const january = new Date(9e8);
      -    const spanish = new Intl.DateTimeFormat('es', { month: 'long' });
      -    return spanish.format(january) === 'enero';
      +    const january = new Date(9e8);
      +    const spanish = new Intl.DateTimeFormat('es', { month: 'long' });
      +    return spanish.format(january) === 'enero';
         } catch (err) {
           return false;
         }
      @@ -40930,25 +44407,26 @@ to be helpful:

      • btest402: Generally used to check whether Node.js with Intl support is built correctly.
      • -
      • Test262: ECMAScript's official conformance test suite includes a section +
      • Test262: ECMAScript's official conformance test suite includes a section dedicated to ECMA-402.
      • -
      -

      Modules: CommonJS modules#

      +
      + +

      Modules: CommonJS modules#

      Stability: 2 - Stable

      In the Node.js module system, each file is treated as a separate module. For example, consider a file named foo.js:

      const circle = require('./circle.js');
      -console.log(`The area of a circle of radius 4 is ${circle.area(4)}`);
      +console.log(`The area of a circle of radius 4 is ${circle.area(4)}`);

      On the first line, foo.js loads the module circle.js that is in the same directory as foo.js.

      Here are the contents of circle.js:

      -
      const { PI } = Math;
      +
      const { PI } = Math;
       
      -exports.area = (r) => PI * r ** 2;
      +exports.area = (r) => PI * r ** 2;
       
      -exports.circumference = (r) => 2 * PI * r;
      +exports.circumference = (r) => 2 * PI * r;

      The module circle.js has exported the functions area() and circumference(). Functions and objects are added to the root of a module by specifying additional properties on the special exports object.

      @@ -40958,22 +44436,22 @@ In this example, the variable PI is private to circle.jsThe module.exports property can be assigned a new value (such as a function or object).

      Below, bar.js makes use of the square module, which exports a Square class:

      -
      const Square = require('./square.js');
      -const mySquare = new Square(2);
      -console.log(`The area of mySquare is ${mySquare.area()}`);
      +
      const Square = require('./square.js');
      +const mySquare = new Square(2);
      +console.log(`The area of mySquare is ${mySquare.area()}`);

      The square module is defined in square.js:

      // Assigning to exports will not modify module, must use module.exports
      -module.exports = class Square {
      -  constructor(width) {
      -    this.width = width;
      +module.exports = class Square {
      +  constructor(width) {
      +    this.width = width;
         }
       
      -  area() {
      -    return this.width ** 2;
      +  area() {
      +    return this.width ** 2;
         }
       };

      The module system is implemented in the require('module') module.

      -

      Accessing the main module#

      +

      Accessing the main module#

      When a file is run directly from Node.js, require.main is set to its module. That means that it is possible to determine whether a file has been @@ -40983,7 +44461,7 @@ run directly by testing require.main === module.

      Because module provides a filename property (normally equivalent to __filename), the entry point of the current application can be obtained by checking require.main.filename.

      -

      Addenda: Package manager tips#

      +

      Package manager tips#

      The semantics of the Node.js require() function were designed to be general enough to support reasonable directory structures. Package manager programs @@ -41026,18 +44504,18 @@ also add the /usr/lib/node_modules folder to the $NODE_PATHnode_modules folders are all relative, and based on the real path of the files making the calls to require(), the packages themselves can be anywhere.

      -

      Addenda: The .mjs extension#

      +

      The .mjs extension#

      It is not possible to require() files that have the .mjs extension. Attempting to do so will throw an error. The .mjs extension is reserved for ECMAScript Modules which cannot be loaded via require(). See ECMAScript Modules for more details.

      -

      All together...#

      +

      All together...#

      To get the exact filename that will be loaded when require() is called, use the require.resolve() function.

      Putting together all of the above, here is the high-level algorithm in pseudocode of what require() does:

      -
      require(X) from module at path Y
      +
      require(X) from module at path Y
       1. If X is a core module,
          a. return the core module
          b. STOP
      @@ -41098,7 +44576,7 @@ LOAD_PACKAGE_IMPORTS(X, DIR)
       2. If no scope was found, return.
       3. If the SCOPE/package.json "imports" is null or undefined, return.
       4. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE),
      -  ["node", "require"]) defined in the ESM resolver.
      +  ["node", "require"]) defined in the ESM resolver.
       5. RESOLVE_ESM_MATCH(MATCH).
       
       LOAD_PACKAGE_EXPORTS(X, DIR)
      @@ -41109,7 +44587,7 @@ LOAD_PACKAGE_EXPORTS(X, DIR)
       3. Parse DIR/NAME/package.json, and look for "exports" field.
       4. If "exports" is null or undefined, return.
       5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH,
      -   `package.json` "exports", ["node", "require"]) defined in the ESM resolver.
      +   `package.json` "exports", ["node", "require"]) defined in the ESM resolver.
       6. RESOLVE_ESM_MATCH(MATCH)
       
       LOAD_PACKAGE_SELF(X, DIR)
      @@ -41119,7 +44597,7 @@ LOAD_PACKAGE_SELF(X, DIR)
       4. If the SCOPE/package.json "name" is not the first segment of X, return.
       5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(SCOPE),
          "." + X.slice("name".length), `package.json` "exports", ["node", "require"])
      -   defined in the ESM resolver.
      +   defined in the ESM resolver.
       6. RESOLVE_ESM_MATCH(MATCH)
       
       RESOLVE_ESM_MATCH(MATCH)
      @@ -41131,8 +44609,9 @@ RESOLVE_ESM_MATCH(MATCH)
       4. Otherwise, if EXACT is false,
          a. LOAD_AS_FILE(RESOLVED_PATH)
          b. LOAD_AS_DIRECTORY(RESOLVED_PATH)
      -5. THROW "not found"
      -

      Caching#

      +5. THROW "not found" +
      +

      Caching#

      Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will get exactly the same object @@ -41143,7 +44622,7 @@ important feature. With it, "partially done" objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles.

      To have a module execute code multiple times, export a function, and call that function.

      -

      Module caching caveats#

      +

      Module caching caveats#

      Modules are cached based on their resolved filename. Since modules may resolve to a different filename based on the location of the calling module (loading @@ -41154,8 +44633,17 @@ resolved filenames can point to the same file, but the cache will still treat them as different modules and will reload the file multiple times. For example, require('./foo') and require('./FOO') return two different objects, irrespective of whether or not ./foo and ./FOO are the same file.

      -

      Core modules#

      +

      Core modules#

      +

      Node.js has several modules compiled into the binary. These modules are described in greater detail elsewhere in this documentation.

      The core modules are defined within the Node.js source and are located in the @@ -41163,30 +44651,34 @@ described in greater detail elsewhere in this documentation.

      Core modules are always preferentially loaded if their identifier is passed to require(). For instance, require('http') will always return the built in HTTP module, even if there is a file by that name.

      -

      Cycles#

      +

      Core modules can also be identified using the node: prefix, in which case +it bypasses the require cache. For instance, require('node:http') will +always return the built in HTTP module, even if there is require.cache entry +by that name.

      +

      Cycles#

      When there are circular require() calls, a module might not have finished executing when it is returned.

      Consider this situation:

      a.js:

      -
      console.log('a starting');
      -exports.done = false;
      +
      console.log('a starting');
      +exports.done = false;
       const b = require('./b.js');
      -console.log('in a, b.done = %j', b.done);
      -exports.done = true;
      -console.log('a done');
      +console.log('in a, b.done = %j', b.done); +exports.done = true; +console.log('a done');

      b.js:

      -
      console.log('b starting');
      -exports.done = false;
      +
      console.log('b starting');
      +exports.done = false;
       const a = require('./a.js');
      -console.log('in b, a.done = %j', a.done);
      -exports.done = true;
      -console.log('b done');
      +console.log('in b, a.done = %j', a.done); +exports.done = true; +console.log('b done');

      main.js:

      -
      console.log('main starting');
      +
      console.log('main starting');
       const a = require('./a.js');
       const b = require('./b.js');
      -console.log('in main, a.done = %j, b.done = %j', a.done, b.done);
      +console.log('in main, a.done = %j, b.done = %j', a.done, b.done);

      When main.js loads a.js, then a.js in turn loads b.js. At that point, b.js tries to load a.js. In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the @@ -41194,7 +44686,7 @@ loop, an unfinished copy of the a.js exports objec provided to the a.js module.

      By the time main.js has loaded both modules, they're both finished. The output of this program would thus be:

      -
      $ node main.js
      +
      $ node main.js
       main starting
       a starting
       b starting
      @@ -41205,7 +44697,7 @@ a done
       in main, a.done = true, b.done = true

      Careful planning is required to allow cyclic module dependencies to work correctly within an application.

      -

      File modules#

      +

      File modules#

      If the exact filename is not found, then Node.js will attempt to load the required filename with the added extensions: .js, .json, and finally @@ -41223,7 +44715,7 @@ example, require('/home/marco/foo.js') will load the file at either be a core module or is loaded from a node_modules folder.

      If the given path does not exist, require() will throw an Error with its code property set to 'MODULE_NOT_FOUND'.

      -

      Folders as modules#

      +

      Folders as modules#

      It is convenient to organize programs and libraries into self-contained directories, and then provide a single entry point to those directories. @@ -41232,8 +44724,8 @@ an argument.

      The first is to create a package.json file in the root of the folder, which specifies a main module. An example package.json file might look like this:

      -
      { "name" : "some-library",
      -  "main" : "./lib/some-library.js" }
      +
      { "name" : "some-library",
      +  "main" : "./lib/some-library.js" }

      If this was in a folder at ./some-library, then require('./some-library') would attempt to load ./some-library/lib/some-library.js.

      @@ -41250,7 +44742,7 @@ example, then require('./some-library') would attempt to load:

      If these attempts fail, then Node.js will report the entire module as missing with the default error:

      Error: Cannot find module 'some-library'
      -

      Loading from node_modules folders#

      +

      Loading from node_modules folders#

      If the module identifier passed to require() is not a core module, and does not begin with '/', '../', or @@ -41276,7 +44768,7 @@ module by including a path suffix after the module name. For instance require('example-module/path/to/file') would resolve path/to/file relative to where example-module is located. The suffixed path follows the same module resolution semantics.

      -

      Loading from the global folders#

      +

      Loading from the global folders#

      If the NODE_PATH environment variable is set to a colon-delimited list of absolute paths, then Node.js will search those paths for modules if they @@ -41301,11 +44793,11 @@ configured node_prefix.

      These are mostly for historic reasons.

      It is strongly encouraged to place dependencies in the local node_modules folder. These will be loaded faster, and more reliably.

      -

      The module wrapper#

      +

      The module wrapper#

      Before a module's code is executed, Node.js will wrap it with a function wrapper that looks like the following:

      -
      (function(exports, require, module, __filename, __dirname) {
      +
      (function(exports, require, module, __filename, __dirname) {
       // Module code actually lives in here
       });

      By doing this, Node.js achieves a few things:

      @@ -41322,8 +44814,8 @@ module's absolute filename and directory path. -

      The module scope#

      -

      __dirname#

      +

      The module scope#

      +

      __dirname#

      @@ -41334,11 +44826,11 @@ module's absolute filename and directory path.

      The directory name of the current module. This is the same as the path.dirname() of the __filename.

      Example: running node example.js from /Users/mjr

      -
      console.log(__dirname);
      +
      console.log(__dirname);
       // Prints: /Users/mjr
      -console.log(path.dirname(__filename));
      +console.log(path.dirname(__filename));
       // Prints: /Users/mjr
      -

      __filename#

      +

      __filename#

      @@ -41353,9 +44845,9 @@ command line.

      See __dirname for the directory name of the current module.

      Examples:

      Running node example.js from /Users/mjr

      -
      console.log(__filename);
      +
      console.log(__filename);
       // Prints: /Users/mjr/example.js
      -console.log(__dirname);
      +console.log(__dirname);
       // Prints: /Users/mjr

      Given two modules: a and b, where b is a dependency of a and there is a directory structure of:

      @@ -41366,7 +44858,7 @@ command line.

      References to __filename within b.js will return /Users/mjr/app/node_modules/b/b.js while references to __filename within a.js will return /Users/mjr/app/a.js.

      -

      exports#

      +

      exports#

      @@ -41377,7 +44869,7 @@ command line.

      A reference to the module.exports that is shorter to type. See the section about the exports shortcut for details on when to use exports and when to use module.exports.

      -

      module#

      +

      module#

      @@ -41388,7 +44880,7 @@ See the section about the exports shortcutA reference to the current module, see the section about the module object. In particular, module.exports is used for defining what a module exports and makes available through require().

      -

      require(id)#

      +

      require(id)#

      @@ -41413,7 +44905,7 @@ Windows in the same way they would on Unix systems.

      // Importing a module from node_modules or Node.js built-in module: const crypto = require('crypto');
      -

      require.cache#

      +
      require.cache#
      @@ -41426,9 +44918,18 @@ This does not apply to native addons, for which reload error.

      Adding or replacing entries is also possible. This cache is checked before native modules and if a name matching a native module is added to the cache, -no require call is -going to receive the native module anymore. Use with care!

      -

      require.extensions#

      +only node:-prefixed require calls are going to receive the native module. +Use with care!

      + +
      const assert = require('assert');
      +const realFs = require('fs');
      +
      +const fakeFs = {};
      +require.cache.fs = { exports: fakeFs };
      +
      +assert.strictEqual(require('fs'), fakeFs);
      +assert.strictEqual(require('node:fs'), realFs);
      +
      require.extensions#
      @@ -41438,14 +44939,14 @@ going to receive the native module anymore. Use with care!

      Instruct require on how to handle certain file extensions.

      Process files with the extension .sjs as .js:

      -
      require.extensions['.sjs'] = require.extensions['.js'];
      +
      require.extensions['.sjs'] = require.extensions['.js'];

      Deprecated. In the past, this list has been used to load non-JavaScript modules into Node.js by compiling them on-demand. However, in practice, there are much better ways to do this, such as loading modules via some other Node.js program, or compiling them to JavaScript ahead of time.

      Avoid using require.extensions. Use could cause subtle bugs and resolving the extensions gets slower with each registered extension.

      -

      require.main#

      +
      require.main#
      @@ -41456,10 +44957,10 @@ extensions gets slower with each registered extension.

      process launched. See "Accessing the main module".

      In entry.js script:

      -
      console.log(require.main);
      +
      console.log(require.main);
      node entry.js
      -
      Module {
      +
      Module {
         id: '.',
         path: '/absolute/path/to',
         exports: {},
      @@ -41472,7 +44973,7 @@ See "Accessing the main module"
            '/absolute/path/node_modules',
            '/absolute/node_modules',
            '/node_modules' ] }
      -

      require.resolve(request[, options])#

      +
      require.resolve(request[, options])#
      +

      node: URLs are supported as an alternative means to load Node.js builtin +modules. This URL scheme allows for builtin modules to be referenced by valid +absolute URL strings.

      +
      import fs from 'node:fs/promises';
      +

      Builtin modules#

      +

      Core modules provide named exports of their public API. A +default export is also provided which is the value of the CommonJS exports. +The default export can be used for, among other things, modifying the named +exports. Named exports of builtin modules are updated only by calling +module.syncBuiltinESMExports().

      +
      import EventEmitter from 'events';
      +const e = new EventEmitter();
      +
      import { readFile } from 'fs';
      +readFile('./foo.txt', (err, source) => {
      +  if (err) {
      +    console.error(err);
      +  } else {
      +    console.log(source);
      +  }
      +});
      +
      import fs, { readFileSync } from 'fs';
      +import { syncBuiltinESMExports } from 'module';
      +
      +fs.readFileSync = () => Buffer.from('Hello, ESM');
      +syncBuiltinESMExports();
      +
      +fs.readFileSync === readFileSync;
      +

      import() expressions#

      +

      Dynamic import() is supported in both CommonJS and ES modules. In CommonJS +modules it can be used to load ES modules.

      +

      import.meta#

      -

      The import.meta metaproperty is an Object that contains the following -property:

      +

      The import.meta meta property is an Object that contains the following +properties.

      +

      import.meta.url#

        -
      • url <string> The absolute file: URL of the module.
      • +
      • <string> The absolute file: URL of the module.
      -

      Differences between ES modules and CommonJS#

      -

      Mandatory file extensions#

      -

      A file extension must be provided when using the import keyword. Directory -indexes (e.g. './startup/index.js') must also be fully specified.

      -

      This behavior matches how import behaves in browser environments, assuming a -typically configured server.

      -

      No NODE_PATH#

      -

      NODE_PATH is not part of resolving import specifiers. Please use symlinks -if this behavior is desired.

      -

      No require, exports, module.exports, __filename, __dirname#

      -

      These CommonJS variables are not available in ES modules.

      -

      require can be imported into an ES module using module.createRequire().

      -

      Equivalents of __filename and __dirname can be created inside of each file -via import.meta.url.

      -
      import { fileURLToPath } from 'url';
      -import { dirname } from 'path';
      -
      -const __filename = fileURLToPath(import.meta.url);
      -const __dirname = dirname(__filename);
      -

      No require.resolve#

      -

      Former use cases relying on require.resolve to determine the resolved path -of a module can be supported via import.meta.resolve, which is experimental -and supported via the --experimental-import-meta-resolve flag:

      -
      (async () => {
      -  const dependencyAsset = await import.meta.resolve('component-lib/asset.css');
      -})();
      +

      This is defined exactly the same as it is in browsers providing the URL of the +current module file.

      +

      This enables useful patterns such as relative file loading:

      +
      import { readFileSync } from 'fs';
      +const buffer = readFileSync(new URL('./data.proto', import.meta.url));
      +

      import.meta.resolve(specifier[, parent])#

      + +

      Stability: 1 - Experimental

      +

      This feature is only available with the --experimental-import-meta-resolve +command flag enabled.

      +
        +
      • specifier <string> The module specifier to resolve relative to parent.
      • +
      • parent <string> The absolute parent module URL to resolve from. If none +is specified, the value of import.meta.url is used as the default.
      • +
      • Returns: <Promise>
      • +
      +

      Provides a module-relative resolution function scoped to each module, returning +the URL string.

      + +
      const dependencyAsset = await import.meta.resolve('component-lib/asset.css');

      import.meta.resolve also accepts a second argument which is the parent module from which to resolve from:

      -
      (async () => {
      -  // Equivalent to import.meta.resolve('./dep')
      -  await import.meta.resolve('./dep', import.meta.url);
      -})();
      + +
      await import.meta.resolve('./dep', import.meta.url);

      This function is asynchronous because the ES module resolver in Node.js is -asynchronous. With the introduction of Top-Level Await, these use cases -will be easier as they won't require an async function wrapper.

      -

      No require.extensions#

      -

      require.extensions is not used by import. The expectation is that loader -hooks can provide this workflow in the future.

      -

      No require.cache#

      -

      require.cache is not used by import. It has a separate cache.

      -

      URL-based paths#

      -

      ES modules are resolved and cached based upon -URL semantics. This means that files containing -special characters such as # and ? need to be escaped.

      -

      Modules are loaded multiple times if the import specifier used to resolve -them has a different query or fragment.

      -
      import './foo.mjs?query=1'; // loads ./foo.mjs with query of "?query=1"
      -import './foo.mjs?query=2'; // loads ./foo.mjs with query of "?query=2"
      -

      For now, only modules using the file: protocol can be loaded.

      -

      Interoperability with CommonJS#

      -

      require#

      -

      require always treats the files it references as CommonJS. This applies -whether require is used the traditional way within a CommonJS environment, or -in an ES module environment using module.createRequire().

      -

      To include an ES module into CommonJS, use import().

      -

      import statements#

      +allowed to be asynchronous.

      +

      Interoperability with CommonJS#

      +

      import statements#

      An import statement can reference an ES module or a CommonJS module. -import statements are permitted only in ES modules. For similar functionality -in CommonJS, see import().

      +import statements are permitted only in ES modules, but dynamic import() +expressions are supported in CommonJS for loading ES modules.

      When importing CommonJS modules, the module.exports object is provided as the default export. Named exports may be available, provided by static analysis as a convenience for better ecosystem compatibility.

      -

      Additional experimental flags are available for importing -Wasm modules or -JSON modules. For importing native modules or -JSON modules unflagged, see module.createRequire().

      -

      The specifier of an import statement (the string after the from keyword) -can either be an URL-style relative path like './file.mjs' or a package name -like 'fs'.

      -

      Like in CommonJS, files within packages can be accessed by appending a path to -the package name; unless the package’s package.json contains an -"exports" field, in which case files within packages need to be accessed -via the path defined in "exports".

      -
      import { sin, cos } from 'geometry/trigonometry-functions.mjs';
      -

      import() expressions#

      -

      Dynamic import() is supported in both CommonJS and ES modules. It can be -used to include ES module files from CommonJS code.

      -

      CommonJS Namespaces#

      +

      require#

      +

      The CommonJS module require always treats the files it references as CommonJS.

      +

      Using require to load an ES module is not supported because ES modules have +asynchronous execution. Instead, use import() to load an ES module +from a CommonJS module.

      +

      CommonJS Namespaces#

      CommonJS modules consist of a module.exports object which can be of any type.

      When importing a CommonJS module, it can be reliably imported using the ES module default import or its corresponding sugar syntax:

      @@ -41924,8 +45463,8 @@ module default import or its corresponding sugar syntax:

      // for `{ default as cjsSugar }` in the above import statement: import cjsSugar from 'cjs'; -console.log(cjs); -console.log(cjs === cjsSugar); +console.log(cjs); +console.log(cjs === cjsSugar); // Prints: // <module.exports> // true
      @@ -41936,8 +45475,8 @@ a namespace with a default export key pointing to the CommonJS import * as m from 'cjs' or a dynamic import:

      import * as m from 'cjs';
      -console.log(m);
      -console.log(m === await import('cjs'));
      +console.log(m);
      +console.log(m === await import('cjs'));
       // Prints:
       //   [Module] { default: <module.exports> }
       //   true
      @@ -41946,20 +45485,20 @@ in addition attempts to determine the CommonJS named exports of every imported CommonJS module to provide them as separate ES module exports using a static analysis process.

      For example, consider a CommonJS module written:

      -
      // cjs.cjs
      -exports.name = 'exported';
      +
      // cjs.cjs
      +exports.name = 'exported';

      The preceding module supports named imports in ES modules:

      import { name } from './cjs.cjs';
      -console.log(name);
      +console.log(name);
       // Prints: 'exported'
       
       import cjs from './cjs.cjs';
      -console.log(cjs);
      +console.log(cjs);
       // Prints: { name: 'exported' }
       
       import * as m from './cjs.cjs';
      -console.log(m);
      +console.log(m);
       // Prints: [Module] { default: { name: 'exported' }, name: 'exported' }

      As can be seen from the last example of the Module Namespace Exotic Object being logged, the name export is copied off of the module.exports object and set @@ -41970,45 +45509,46 @@ for these named exports.

      always correctly detect named exports. In these cases, using the default import form described above can be a better option.

      Named exports detection covers many common export patterns, reexport patterns -and build tool and transpiler outputs. See cjs-module-lexer for the exact +and build tool and transpiler outputs. See cjs-module-lexer for the exact semantics implemented.

      -

      Builtin modules#

      -

      Core modules provide named exports of their public API. A -default export is also provided which is the value of the CommonJS exports. -The default export can be used for, among other things, modifying the named -exports. Named exports of builtin modules are updated only by calling -module.syncBuiltinESMExports().

      -
      import EventEmitter from 'events';
      -const e = new EventEmitter();
      -
      import { readFile } from 'fs';
      -readFile('./foo.txt', (err, source) => {
      -  if (err) {
      -    console.error(err);
      -  } else {
      -    console.log(source);
      -  }
      -});
      -
      import fs, { readFileSync } from 'fs';
      -import { syncBuiltinESMExports } from 'module';
      -
      -fs.readFileSync = () => Buffer.from('Hello, ESM');
      -syncBuiltinESMExports();
      -
      -fs.readFileSync === readFileSync;
      -

      CommonJS, JSON, and native modules#

      -

      CommonJS, JSON, and native modules can be used with +

      Differences between ES modules and CommonJS#

      +
      No require, exports or module.exports#
      +

      In most cases, the ES module import can be used to load CommonJS modules.

      +

      If needed, a require function can be constructed within an ES module using module.createRequire().

      -
      // cjs.cjs
      -module.exports = 'cjs';
      -
      -// esm.mjs
      -import { createRequire } from 'module';
      -
      -const require = createRequire(import.meta.url);
      -
      -const cjs = require('./cjs.cjs');
      -cjs === 'cjs'; // true
      -

      Experimental JSON modules#

      +
      No __filename or __dirname#
      +

      These CommonJS variables are not available in ES modules.

      +

      __filename and __dirname use cases can be replicated via +import.meta.url.

      +
      No JSON Module Loading#
      +

      JSON imports are still experimental and only supported via the +--experimental-json-modules flag.

      +

      Local JSON files can be loaded relative to import.meta.url with fs directly:

      + +
      import { readFile } from 'fs/promises';
      +const json = JSON.parse(await readFile(new URL('./dat.json', import.meta.url)));
      +

      Alternatively module.createRequire() can be used.

      +
      No Native Module Loading#
      +

      Native modules are not currently supported with ES module imports.

      +

      They can instead be loaded with module.createRequire() or +process.dlopen.

      +
      No require.resolve#
      +

      Relative resolution can be handled via new URL('./local', import.meta.url).

      +

      For a complete require.resolve replacement, there is a flagged experimental +import.meta.resolve API.

      +

      Alternatively module.createRequire() can be used.

      +
      No NODE_PATH#
      +

      NODE_PATH is not part of resolving import specifiers. Please use symlinks +if this behavior is desired.

      +
      No require.extensions#
      +

      require.extensions is not used by import. The expectation is that loader +hooks can provide this workflow in the future.

      +
      No require.cache#
      +

      require.cache is not used by import as the ES module loader has its own +separate cache.

      +

      +

      JSON modules#

      +

      Stability: 1 - Experimental

      Currently importing JSON modules are only supported in the commonjs mode and are loaded using the CJS loader. WHATWG JSON modules specification are still being standardized, and are experimentally supported by including the @@ -42027,7 +45567,9 @@ same path.

      to work.

      node index.mjs # fails
       node --experimental-json-modules index.mjs # works
      -

      Experimental Wasm modules#

      +

      +

      Wasm modules#

      +

      Stability: 1 - Experimental

      Importing Web Assembly modules is supported under the --experimental-wasm-modules flag, allowing any .wasm files to be imported as normal modules while also supporting their module imports.

      @@ -42035,19 +45577,34 @@ imported as normal modules while also supporting their module imports.

      ES Module Integration Proposal for Web Assembly.

      For example, an index.mjs containing:

      import * as M from './module.wasm';
      -console.log(M);
      +console.log(M);

      executed under:

      node --experimental-wasm-modules index.mjs

      would provide the exports interface for the instantiation of module.wasm.

      -

      Experimental loaders#

      +

      +

      Top-level await#

      +

      Stability: 1 - Experimental

      +

      The await keyword may be used in the top level (outside of async functions) +within modules as per the ECMAScript Top-Level await proposal.

      +

      Assuming an a.mjs with

      + +
      export const five = await Promise.resolve(5);
      +

      And a b.mjs with

      +
      import { five } from './a.mjs';
      +
      +console.log(five); // Logs `5`
      +
      node b.mjs # works
      +

      +

      Loaders#

      +

      Stability: 1 - Experimental

      Note: This API is currently being redesigned and will still change.

      To customize the default module resolution, loader hooks can optionally be provided via a --experimental-loader ./loader-name.mjs argument to Node.js.

      When hooks are used they only apply to ES module loading and not to any CommonJS modules loaded.

      -

      Hooks#

      -

      resolve(specifier, context, defaultResolve)#

      +

      Hooks#

      +
      resolve(specifier, context, defaultResolve)#

      Note: The loaders API is being redesigned. This hook may disappear or its signature may change. Do not rely on the API described below.

      @@ -42081,37 +45638,37 @@ Node.js module specifier resolution behavior
      when calling defaultReso context.conditions array passed to it must include all elements of the context.conditions array originally passed into the resolve hook.

      /**
      - * @param {string} specifier
      - * @param {{
      + * @param {string} specifier
      + * @param {{
        *   conditions: !Array<string>,
        *   parentURL: !(string | undefined),
      - * }} context
      - * @param {Function} defaultResolve
      - * @returns {Promise<{ url: string }>}
      + * }} context
      + * @param {Function} defaultResolve
      + * @returns {Promise<{ url: string }>}
        */
      -export async function resolve(specifier, context, defaultResolve) {
      +export async function resolve(specifier, context, defaultResolve) {
         const { parentURL = null } = context;
      -  if (Math.random() > 0.5) { // Some condition.
      +  if (Math.random() > 0.5) { // Some condition.
           // For some or all specifiers, do some custom logic for resolving.
           // Always return an object of the form {url: <string>}.
           return {
             url: parentURL ?
      -        new URL(specifier, parentURL).href :
      -        new URL(specifier).href,
      +        new URL(specifier, parentURL).href :
      +        new URL(specifier).href,
           };
         }
      -  if (Math.random() < 0.5) { // Another condition.
      +  if (Math.random() < 0.5) { // Another condition.
           // When calling `defaultResolve`, the arguments can be modified. In this
           // case it's adding another value for matching conditional exports.
      -    return defaultResolve(specifier, {
      +    return defaultResolve(specifier, {
             ...context,
      -      conditions: [...context.conditions, 'another-condition'],
      +      conditions: [...context.conditions, 'another-condition'],
           });
         }
         // Defer to Node.js for all other specifiers.
      -  return defaultResolve(specifier, context, defaultResolve);
      +  return defaultResolve(specifier, context, defaultResolve);
       }
      -

      getFormat(url, context, defaultGetFormat)#

      +
      getFormat(url, context, defaultGetFormat)#

      Note: The loaders API is being redesigned. This hook may disappear or its signature may change. Do not rely on the API described below.

      @@ -42165,27 +45722,22 @@ of the following:

      - - - - - -
      formatDescriptionAcceptable Types For source Returned by getSource or transformSource
      'builtin'Load a Node.js builtin moduleNot applicable
      'dynamic'Use a dynamic instantiate hookNot applicable
      'commonjs'Load a Node.js CommonJS moduleNot applicable
      'json'Load a JSON file{ string, ArrayBuffer, TypedArray }
      'module'Load an ES module{ string, ArrayBuffer, TypedArray }
      'wasm'Load a WebAssembly module{ ArrayBuffer, TypedArray }
      +
      formatDescriptionAcceptable Types For source Returned by getSource or transformSource
      'builtin'Load a Node.js builtin moduleNot applicable
      'commonjs'Load a Node.js CommonJS moduleNot applicable
      'json'Load a JSON file{ string, ArrayBuffer, TypedArray }
      'module'Load an ES module{ string, ArrayBuffer, TypedArray }
      'wasm'Load a WebAssembly module{ ArrayBuffer, TypedArray }

      Note: These types all correspond to classes defined in ECMAScript.

      Note: If the source value of a text-based format (i.e., 'json', 'module') is -not a string, it is converted to a string using util.TextDecoder.

      +not a string, it is converted to a string using util.TextDecoder.

      /**
      - * @param {string} url
      - * @param {Object} context (currently empty)
      - * @param {Function} defaultGetFormat
      - * @returns {Promise<{ format: string }>}
      + * @param {string} url
      + * @param {Object} context (currently empty)
      + * @param {Function} defaultGetFormat
      + * @returns {Promise<{ format: string }>}
        */
      -export async function getFormat(url, context, defaultGetFormat) {
      -  if (Math.random() > 0.5) { // Some condition.
      +export async function getFormat(url, context, defaultGetFormat) {
      +  if (Math.random() > 0.5) { // Some condition.
           // For some or all URLs, do some custom logic for determining format.
           // Always return an object of the form {format: <string>}, where the
           // format is one of the strings in the preceding table.
      @@ -42194,9 +45746,9 @@ not a string, it is converted to a string using // Defer to Node.js for all other URLs.
      -  return defaultGetFormat(url, context, defaultGetFormat);
      +  return defaultGetFormat(url, context, defaultGetFormat);
       }
      -

      getSource(url, context, defaultGetSource)#

      +
      getSource(url, context, defaultGetSource)#

      Note: The loaders API is being redesigned. This hook may disappear or its signature may change. Do not rely on the API described below.

      @@ -42219,14 +45771,14 @@ signature may change. Do not rely on the API described below.

      the source code of an ES module specifier. This would allow a loader to potentially avoid reading files from disk.

      /**
      - * @param {string} url
      - * @param {{ format: string }} context
      - * @param {Function} defaultGetSource
      - * @returns {Promise<{ source: !(string | SharedArrayBuffer | Uint8Array) }>}
      + * @param {string} url
      + * @param {{ format: string }} context
      + * @param {Function} defaultGetSource
      + * @returns {Promise<{ source: !(string | SharedArrayBuffer | Uint8Array) }>}
        */
      -export async function getSource(url, context, defaultGetSource) {
      +export async function getSource(url, context, defaultGetSource) {
         const { format } = context;
      -  if (Math.random() > 0.5) { // Some condition.
      +  if (Math.random() > 0.5) { // Some condition.
           // For some or all URLs, do some custom logic for retrieving the source.
           // Always return an object of the form {source: <string|buffer>}.
           return {
      @@ -42234,10 +45786,9 @@ potentially avoid reading files from disk.

      }; } // Defer to Node.js for all other URLs. - return defaultGetSource(url, context, defaultGetSource); + return defaultGetSource(url, context, defaultGetSource); }
      -

      transformSource(source, context, defaultTransformSource)#

      -
      NODE_OPTIONS='--experimental-loader ./custom-loader.mjs' node x.js
      +
      transformSource(source, context, defaultTransformSource)#

      Note: The loaders API is being redesigned. This hook may disappear or its signature may change. Do not rely on the API described below.

      @@ -42263,17 +45814,17 @@ done anything with it.

      JavaScript, a resolve hook is also necessary in order to register any unknown-to-Node.js file extensions. See the transpiler loader example below.

      /**
      - * @param {!(string | SharedArrayBuffer | Uint8Array)} source
      - * @param {{
      + * @param {!(string | SharedArrayBuffer | Uint8Array)} source
      + * @param {{
        *   format: string,
        *   url: string,
      - * }} context
      - * @param {Function} defaultTransformSource
      - * @returns {Promise<{ source: !(string | SharedArrayBuffer | Uint8Array) }>}
      + * }} context
      + * @param {Function} defaultTransformSource
      + * @returns {Promise<{ source: !(string | SharedArrayBuffer | Uint8Array) }>}
        */
      -export async function transformSource(source, context, defaultTransformSource) {
      +export async function transformSource(source, context, defaultTransformSource) {
         const { url, format } = context;
      -  if (Math.random() > 0.5) { // Some condition.
      +  if (Math.random() > 0.5) { // Some condition.
           // For some or all URLs, do some custom logic for modifying the source.
           // Always return an object of the form {source: <string|buffer>}.
           return {
      @@ -42281,9 +45832,9 @@ unknown-to-Node.js file extensions. See the tra
           };
         }
         // Defer to Node.js for all other sources.
      -  return defaultTransformSource(source, context, defaultTransformSource);
      +  return defaultTransformSource(source, context, defaultTransformSource);
       }
      -

      getGlobalPreloadCode()#

      +
      getGlobalPreloadCode()#

      Note: The loaders API is being redesigned. This hook may disappear or its signature may change. Do not rely on the API described below.

      @@ -42300,9 +45851,9 @@ builtins like "fs": getBuiltin(request: string).

      If the code needs more advanced require features, it has to construct its own require using module.createRequire().

      /**
      - * @returns {string} Code to run before application startup
      + * @returns {string} Code to run before application startup
        */
      -export function getGlobalPreloadCode() {
      +export function getGlobalPreloadCode() {
         return `\
       globalThis.someInjectedProperty = 42;
       console.log('I just set some globals!');
      @@ -42313,37 +45864,10 @@ const require = createRequire(process.cwd() + '/<preload>');
       // [...]
       `;
       }
      -

      dynamicInstantiate hook#

      -
      -

      Note: The loaders API is being redesigned. This hook may disappear or its -signature may change. Do not rely on the API described below.

      -
      -

      To create a custom dynamic module that doesn't correspond to one of the -existing format interpretations, the dynamicInstantiate hook can be used. -This hook is called only for modules that return format: 'dynamic' from -the getFormat hook.

      -
      /**
      - * @param {string} url
      - * @returns {object} response
      - * @returns {array} response.exports
      - * @returns {function} response.execute
      - */
      -export async function dynamicInstantiate(url) {
      -  return {
      -    exports: ['customExportName'],
      -    execute: (exports) => {
      -      // Get and set functions provided for pre-allocated export names
      -      exports.customExportName.set('value');
      -    }
      -  };
      -}
      -

      With the list of module exports provided upfront, the execute function will -then be called at the exact point of module evaluation order for that module -in the import tree.

      -

      Examples#

      +

      Examples#

      The various loader hooks can be used together to accomplish wide-ranging customizations of Node.js’ code loading and evaluation behaviors.

      -

      HTTPS loader#

      +
      HTTPS loader#

      In current Node.js, specifiers starting with https:// are unsupported. The loader below registers hooks to enable rudimentary support for such specifiers. While this may seem like a significant improvement to Node.js core @@ -42353,63 +45877,63 @@ and there is no security.

      // https-loader.mjs
       import { get } from 'https';
       
      -export function resolve(specifier, context, defaultResolve) {
      +export function resolve(specifier, context, defaultResolve) {
         const { parentURL = null } = context;
       
         // Normally Node.js would error on specifiers starting with 'https://', so
         // this hook intercepts them and converts them into absolute URLs to be
         // passed along to the later hooks below.
      -  if (specifier.startsWith('https://')) {
      +  if (specifier.startsWith('https://')) {
           return {
             url: specifier
           };
      -  } else if (parentURL && parentURL.startsWith('https://')) {
      +  } else if (parentURL && parentURL.startsWith('https://')) {
           return {
      -      url: new URL(specifier, parentURL).href
      +      url: new URL(specifier, parentURL).href
           };
         }
       
         // Let Node.js handle all other specifiers.
      -  return defaultResolve(specifier, context, defaultResolve);
      +  return defaultResolve(specifier, context, defaultResolve);
       }
       
      -export function getFormat(url, context, defaultGetFormat) {
      +export function getFormat(url, context, defaultGetFormat) {
         // This loader assumes all network-provided JavaScript is ES module code.
      -  if (url.startsWith('https://')) {
      +  if (url.startsWith('https://')) {
           return {
             format: 'module'
           };
         }
       
         // Let Node.js handle all other URLs.
      -  return defaultGetFormat(url, context, defaultGetFormat);
      +  return defaultGetFormat(url, context, defaultGetFormat);
       }
       
      -export function getSource(url, context, defaultGetSource) {
      +export function getSource(url, context, defaultGetSource) {
         // For JavaScript to be loaded over the network, we need to fetch and
         // return it.
      -  if (url.startsWith('https://')) {
      -    return new Promise((resolve, reject) => {
      -      get(url, (res) => {
      +  if (url.startsWith('https://')) {
      +    return new Promise((resolve, reject) => {
      +      get(url, (res) => {
               let data = '';
      -        res.on('data', (chunk) => data += chunk);
      -        res.on('end', () => resolve({ source: data }));
      -      }).on('error', (err) => reject(err));
      +        res.on('data', (chunk) => data += chunk);
      +        res.on('end', () => resolve({ source: data }));
      +      }).on('error', (err) => reject(err));
           });
         }
       
         // Let Node.js handle all other URLs.
      -  return defaultGetSource(url, context, defaultGetSource);
      +  return defaultGetSource(url, context, defaultGetSource);
       }
      // main.mjs
      -import { VERSION } from 'https://coffeescript.org/browser-compiler-modern/coffeescript.js';
      +import { VERSION } from 'https://coffeescript.org/browser-compiler-modern/coffeescript.js';
       
      -console.log(VERSION);
      +console.log(VERSION);

      With the preceding loader, running node --experimental-loader ./https-loader.mjs ./main.mjs prints the current version of CoffeeScript per the module at the URL in main.mjs.

      -

      Transpiler loader#

      +
      Transpiler loader#

      Sources that are in formats Node.js doesn’t understand can be converted into JavaScript using the transformSource hook. Before that hook gets called, however, other hooks need to tell Node.js not to throw an error on unknown file @@ -42418,61 +45942,61 @@ types; and to tell Node.js how to load this new file type.

      Node.js; a transpiler loader should only be used for development and testing purposes.

      // coffeescript-loader.mjs
      -import { URL, pathToFileURL } from 'url';
      -import CoffeeScript from 'coffeescript';
      +import { URL, pathToFileURL } from 'url';
      +import CoffeeScript from 'coffeescript';
       
      -const baseURL = pathToFileURL(`${process.cwd()}/`).href;
      +const baseURL = pathToFileURL(`${process.cwd()}/`).href;
       
       // CoffeeScript files end in .coffee, .litcoffee or .coffee.md.
       const extensionsRegex = /\.coffee$|\.litcoffee$|\.coffee\.md$/;
       
      -export function resolve(specifier, context, defaultResolve) {
      +export function resolve(specifier, context, defaultResolve) {
         const { parentURL = baseURL } = context;
       
         // Node.js normally errors on unknown file extensions, so return a URL for
         // specifiers ending in the CoffeeScript file extensions.
      -  if (extensionsRegex.test(specifier)) {
      +  if (extensionsRegex.test(specifier)) {
           return {
      -      url: new URL(specifier, parentURL).href
      +      url: new URL(specifier, parentURL).href
           };
         }
       
         // Let Node.js handle all other specifiers.
      -  return defaultResolve(specifier, context, defaultResolve);
      +  return defaultResolve(specifier, context, defaultResolve);
       }
       
      -export function getFormat(url, context, defaultGetFormat) {
      +export function getFormat(url, context, defaultGetFormat) {
         // Now that we patched resolve to let CoffeeScript URLs through, we need to
         // tell Node.js what format such URLs should be interpreted as. For the
         // purposes of this loader, all CoffeeScript URLs are ES modules.
      -  if (extensionsRegex.test(url)) {
      +  if (extensionsRegex.test(url)) {
           return {
             format: 'module'
           };
         }
       
         // Let Node.js handle all other URLs.
      -  return defaultGetFormat(url, context, defaultGetFormat);
      +  return defaultGetFormat(url, context, defaultGetFormat);
       }
       
      -export function transformSource(source, context, defaultTransformSource) {
      +export function transformSource(source, context, defaultTransformSource) {
         const { url, format } = context;
       
      -  if (extensionsRegex.test(url)) {
      +  if (extensionsRegex.test(url)) {
           return {
      -      source: CoffeeScript.compile(source, { bare: true })
      +      source: CoffeeScript.compile(source, { bare: true })
           };
         }
       
         // Let Node.js handle all other sources.
      -  return defaultTransformSource(source, context, defaultTransformSource);
      +  return defaultTransformSource(source, context, defaultTransformSource);
       }
      # main.coffee
       import { scream } from './scream.coffee'
      -console.log scream 'hello, world'
      +console.log scream 'hello, world'
       
       import { version } from 'process'
      -console.log "Brought to you by Node.js version #{version}"
      +console.log "Brought to you by Node.js version #{version}"
      # scream.coffee
       export scream = (str) -> str.toUpperCase()

      With the preceding loader, running @@ -42481,8 +46005,8 @@ causes main.coffee to be turned into JavaScript after its source co loaded from disk but before Node.js executes it; and so on for any .coffee, .litcoffee or .coffee.md files referenced via import statements of any loaded file.

      -

      Resolution algorithm#

      -

      Features#

      +

      Resolution algorithm#

      +

      Features#

      The resolver has the following properties:

      • FileURL-based resolution as is used by ES modules
      • @@ -42492,7 +46016,7 @@ loaded file.

      • No folder mains
      • Bare specifier package resolution lookup through node_modules
      -

      Resolver algorithm#

      +

      Resolver algorithm#

      The algorithm to load an ES module specifier is given through the ESM_RESOLVE method below. It returns the resolved URL for a module specifier relative to a parentURL.

      @@ -42518,8 +46042,10 @@ for the package that is an invalid type or string target. subpath in the package for the given module.
    • Package Import Not Defined: Package imports do not define the specifier.
    • Module Not Found: The package or module requested does not exist.
    • +
    • Unsupported Directory Import: The resolved path corresponds to a directory, +which is not a supported target for module imports.
    • -

      Resolver Algorithm Specification#

      +

      Resolver Algorithm Specification#

      ESM_RESOLVE(specifier, parentURL)

        @@ -42960,7 +46486,8 @@ error.
      1. Return the parsed JSON source of the file at pjsonURL.
      -

      Customizing ESM specifier resolution algorithm#

      +

      Customizing ESM specifier resolution algorithm#

      +

      Stability: 1 - Experimental

      The current specifier resolution does not support all default behavior of the CommonJS loader. One of the behavior differences is automatic resolution of file extensions and the ability to import directories that have an index @@ -42970,23 +46497,27 @@ the extension resolution algorithm. The default mode is explicit, w requires the full path to a module be provided to the loader. To enable the automatic extension resolution and importing from directories that include an index file use the node mode.

      -
      $ node index.mjs
      +
      $ node index.mjs
       success!
      -$ node index # Failure!
      +$ node index # Failure!
       Error: Cannot find module
      -$ node --experimental-specifier-resolution=node index
      +$ node --experimental-specifier-resolution=node index
       success!
      - -

      Modules: module API#

      +
      +
      +

      Modules: module API#

      -

      The Module object#

      + +

      The Module object#

      Provides general utility methods when interacting with instances of Module, the module variable often seen in CommonJS modules. Accessed via import 'module' or require('module').

      -

      module.builtinModules#

      +

      module.builtinModules#

      @@ -42996,14 +46527,14 @@ via import 'module' or require('module').

      A list of the names of all modules provided by Node.js. Can be used to verify if a module is maintained by a third party or not.

      module in this context isn't the same object that's provided -by the module wrapper. To access it, require the Module module:

      -
      // module.mjs
      +by the module wrapper. To access it, require the Module module:

      + +
      // module.mjs
       // In an ECMAScript module
      -import { builtinModules as builtin } from 'module';
      -
      // module.cjs
      +import { builtinModules as builtin } from 'module';// module.cjs
       // In a CommonJS module
      -const builtin = require('module').builtinModules;
      -

      module.createRequire(filename)#

      +const builtin = require('module').builtinModules;
      +

      module.createRequire(filename)#

      @@ -43013,12 +46544,12 @@ function. Must be a file URL object, file URL string, or absolute path string.
    • Returns: <require> Require function
    • -
      import { createRequire } from 'module';
      -const require = createRequire(import.meta.url);
      +
      import { createRequire } from 'module';
      +const require = createRequire(import.meta.url);
       
       // sibling-module.js is a CommonJS module.
       const siblingModule = require('./sibling-module');
      -

      module.createRequireFromPath(filename)#

      +

      module.createRequireFromPath(filename)#

      @@ -43029,11 +46560,11 @@ function.
    • Returns: <require> Require function
    • const { createRequireFromPath } = require('module');
      -const requireUtil = createRequireFromPath('../src/utils/');
      +const requireUtil = createRequireFromPath('../src/utils/');
       
       // Require `../src/utils/some-tool`
       requireUtil('./some-tool');
      -

      module.syncBuiltinESMExports()#

      +

      module.syncBuiltinESMExports()#

      @@ -43041,24 +46572,32 @@ requireUtil('./some-tool');
      builtin ES Modules to match the properties of the CommonJS exports. It does not add or remove exported names from the ES Modules.

      const fs = require('fs');
      +const assert = require('assert');
       const { syncBuiltinESMExports } = require('module');
       
      -fs.readFile = null;
      +fs.readFile = newAPI;
       
      -delete fs.readFileSync;
      +delete fs.readFileSync;
       
      -fs.newAPI = function newAPI() {
      +function newAPI() {
         // ...
      -};
      +}
       
      -syncBuiltinESMExports();
      +fs.newAPI = newAPI;
       
      -import('fs').then((esmFS) => {
      -  assert.strictEqual(esmFS.readFile, null);
      -  assert.strictEqual('readFileSync' in fs, true);
      -  assert.strictEqual(esmFS.newAPI, undefined);
      +syncBuiltinESMExports();
      +
      +import('fs').then((esmFS) => {
      +  // It syncs the existing readFile property with the new value
      +  assert.strictEqual(esmFS.readFile, newAPI);
      +  // readFileSync has been deleted from the required fs
      +  assert.strictEqual('readFileSync' in fs, false);
      +  // syncBuiltinESMExports() does not remove readFileSync from esmFS
      +  assert.strictEqual('readFileSync' in esmFS, true);
      +  // syncBuiltinESMExports() does not add names
      +  assert.strictEqual(esmFS.newAPI, undefined);
       });
      -

      Source map v3 support#

      +

      Source map v3 support#

      @@ -43069,33 +46608,29 @@ populated when source map parsing is enabled and

      To enable source map parsing, Node.js must be run with the flag --enable-source-maps, or with code coverage enabled by setting NODE_V8_COVERAGE=dir.

      -
      // module.mjs
      +
      +
      // module.mjs
       // In an ECMAScript module
      -import { findSourceMap, SourceMap } from 'module';
      -
      // module.cjs
      +import { findSourceMap, SourceMap } from 'module';// module.cjs
       // In a CommonJS module
      -const { findSourceMap, SourceMap } = require('module');
      -

      module.findSourceMap(path[, error])#

      +const { findSourceMap, SourceMap } = require('module');
      + +

      +

      module.findSourceMap(path)#

      path is the resolved path for the file for which a corresponding source map should be fetched.

      -

      The error instance should be passed as the second parameter to findSourceMap -in exceptional flows, such as when an overridden -Error.prepareStackTrace(error, trace) is invoked. Modules are not added to -the module cache until they are successfully loaded. In these cases, source maps -are associated with the error instance along with the path.

      -

      Class: module.SourceMap#

      +

      Class: module.SourceMap#

      -

      new SourceMap(payload)#

      +
      new SourceMap(payload)#
      @@ -43110,12 +46645,12 @@ are associated with the error instance along with the pathmappings: <string>
    • sourceRoot: <string>
    • -

      sourceMap.payload#

      +
      sourceMap.payload#

      Getter for the payload used to construct the SourceMap instance.

      -

      sourceMap.findEntry(lineNumber, columnNumber)#

      +
      sourceMap.findEntry(lineNumber, columnNumber)#
      -

      Modules: Packages#

      +
    • name: <string>
    • +
      +
      +

      Modules: Packages#

      + -

      Introduction#

      +

      Introduction#

      A package is a folder tree described by a package.json file. The package consists of the folder containing the package.json file and all subfolders until the next folder containing another package.json file, or a folder named node_modules.

      This page provides guidance for package authors writing package.json files along with a reference for the package.json fields defined by Node.js.

      -

      Determining module system#

      +

      Determining module system#

      Node.js will treat the following as ES modules when passed to node as the initial input, or when referenced by import statements within ES module code:

        @@ -43200,7 +46738,7 @@ all sources are CommonJS. Being explicit about the type of the pack future-proof the package in case the default type of Node.js ever changes, and it will also make things easier for build tools and loaders to determine how the files in the package should be interpreted.

        -

        package.json and file extensions#

        +

        package.json and file extensions#

        Within a package, the package.json "type" field defines how Node.js should interpret .js files. If a package.json file does not have a "type" field, .js files are treated as CommonJS.

        @@ -43247,7 +46785,10 @@ extension (since both .js and .cjs files are treated a "commonjs" package).

      -

      --input-type flag#

      +

      --input-type flag#

      +

      Strings passed in as an argument to --eval (or -e), or piped to node via STDIN, are treated as ES modules when the --input-type=module flag is set.

      @@ -43257,7 +46798,7 @@ is set.

      For completeness there is also --input-type=commonjs, for explicitly running string input as CommonJS. This is the default behavior if --input-type is unspecified.

      -

      Package entry points#

      +

      Package entry points#

      In a package’s package.json file, two fields can define entry points for a package: "main" and "exports". The "main" field is supported in all versions of Node.js, but its capabilities are limited: it only defines @@ -43287,46 +46828,46 @@ previously supported entry point is exported. It is best to explicitly specify entry points so that the package’s public API is well-defined. For example, a project that previous exported main, lib, feature, and the package.json could use the following package.exports:

      -
      {
      -  "name": "my-mod",
      -  "exports": {
      -    ".": "./lib/index.js",
      -    "./lib": "./lib/index.js",
      -    "./lib/index": "./lib/index.js",
      -    "./lib/index.js": "./lib/index.js",
      -    "./feature": "./feature/index.js",
      -    "./feature/index.js": "./feature/index.js",
      -    "./package.json": "./package.json"
      -  }
      -}
      +
      {
      +  "name": "my-mod",
      +  "exports": {
      +    ".": "./lib/index.js",
      +    "./lib": "./lib/index.js",
      +    "./lib/index": "./lib/index.js",
      +    "./lib/index.js": "./lib/index.js",
      +    "./feature": "./feature/index.js",
      +    "./feature/index.js": "./feature/index.js",
      +    "./package.json": "./package.json"
      +  }
      +}

      Alternatively a project could choose to export entire folders:

      -
      {
      -  "name": "my-mod",
      -  "exports": {
      -    ".": "./lib/index.js",
      -    "./lib": "./lib/index.js",
      -    "./lib/*": "./lib/*.js",
      -    "./feature": "./feature/index.js",
      -    "./feature/*": "./feature/*.js",
      -    "./package.json": "./package.json"
      -  }
      -}
      +
      {
      +  "name": "my-mod",
      +  "exports": {
      +    ".": "./lib/index.js",
      +    "./lib": "./lib/index.js",
      +    "./lib/*": "./lib/*.js",
      +    "./feature": "./feature/index.js",
      +    "./feature/*": "./feature/*.js",
      +    "./package.json": "./package.json"
      +  }
      +}

      As a last resort, package encapsulation can be disabled entirely by creating an export for the root of the package "./*": "./*". This exposes every file in the package at the cost of disabling the encapsulation and potential tooling benefits this provides. As the ES Module loader in Node.js enforces the use of -the full specifier path, exporting the root rather than being explicit +the full specifier path, exporting the root rather than being explicit about entry is less expressive than either of the prior examples. Not only is encapsulation lost but module consumers are unable to import feature from 'my-mod/feature' as they need to provide the full path import feature from 'my-mod/feature/index.js.

      -

      Main entry point export#

      +

      Main entry point export#

      To set the main entry point for a package, it is advisable to define both "exports" and "main" in the package’s package.json file:

      -
      {
      -  "main": "./main.js",
      -  "exports": "./main.js"
      -}
      +
      {
      +  "main": "./main.js",
      +  "exports": "./main.js"
      +}

      When the "exports" field is defined, all subpaths of the package are encapsulated and no longer available to importers. For example, require('pkg/subpath.js') throws an ERR_PACKAGE_PATH_NOT_EXPORTED @@ -43336,26 +46877,30 @@ about package interfaces for tools and when handling semver upgrades for a package. It is not a strong encapsulation since a direct require of any absolute subpath of the package such as require('/path/to/node_modules/pkg/subpath.js') will still load subpath.js.

      -

      Subpath exports#

      -

      Stability: 1 - Experimental

      +

      Subpath exports#

      +

      When using the "exports" field, custom subpaths can be defined along with the main entry point by treating the main entry point as the "." subpath:

      -
      {
      -  "main": "./main.js",
      -  "exports": {
      -    ".": "./main.js",
      -    "./submodule": "./src/submodule.js"
      -  }
      -}
      +
      {
      +  "main": "./main.js",
      +  "exports": {
      +    ".": "./main.js",
      +    "./submodule": "./src/submodule.js"
      +  }
      +}

      Now only the defined subpath in "exports" can be imported by a consumer:

      import submodule from 'es-module-package/submodule';
       // Loads ./node_modules/es-module-package/src/submodule.js

      While other subpaths will error:

      import submodule from 'es-module-package/private-module.js';
       // Throws ERR_PACKAGE_PATH_NOT_EXPORTED
      -

      Subpath imports#

      -

      Stability: 1 - Experimental

      +

      Subpath imports#

      +

      In addition to the "exports" field, it is possible to define internal package import maps that only apply to import specifiers from within the package itself.

      @@ -43364,17 +46909,17 @@ disambiguated from package specifiers.

      For example, the imports field can be used to gain the benefits of conditional exports for internal modules:

      // package.json
      -{
      -  "imports": {
      -    "#dep": {
      -      "node": "dep-node-native",
      -      "default": "./dep-polyfill.js"
      -    }
      -  },
      -  "dependencies": {
      -    "dep-node-native": "^1.0.0"
      -  }
      -}
      +{ + "imports": { + "#dep": { + "node": "dep-node-native", + "default": "./dep-polyfill.js" + } + }, + "dependencies": { + "dep-node-native": "^1.0.0" + } +}

      where import '#dep' does not get the resolution of the external package dep-node-native (including its exports in turn), and instead gets the local file ./dep-polyfill.js relative to the package in other environments.

      @@ -43382,22 +46927,26 @@ file ./dep-polyfill.js relative to the package in other environment packages.

      The resolution rules for the imports field are otherwise analogous to the exports field.

      -

      Subpath patterns#

      -

      Stability: 1 - Experimental

      +

      Subpath patterns#

      +

      For packages with a small number of exports or imports, we recommend explicitly listing each exports subpath entry. But for packages that have large numbers of subpaths, this might cause package.json bloat and maintenance issues.

      For these use cases, subpath export patterns can be used instead:

      // ./node_modules/es-module-package/package.json
      -{
      -  "exports": {
      -    "./features/*": "./src/features/*.js"
      -  },
      -  "imports": {
      -    "#internal/*": "./src/internal/*.js"
      -  }
      -}
      +{ + "exports": { + "./features/*": "./src/features/*.js" + }, + "imports": { + "#internal/*": "./src/internal/*.js" + } +}
      +

      * maps expose nested subpaths as it is a string replacement syntax +only.

      The left hand matching pattern must always end in *. All instances of * on the right hand side will then be replaced with this value, including if it contains any / separators.

      @@ -43417,37 +46966,62 @@ patterns since the individual exports for a package can be determined by treating the right hand side target pattern as a ** glob against the list of files within the package. Because node_modules paths are forbidden in exports targets, this expansion is dependent on only the files of the package itself.

      -

      Exports sugar#

      -

      Stability: 1 - Experimental

      +

      To exclude private subfolders from patterns, null targets can be used:

      +
      // ./node_modules/es-module-package/package.json
      +{
      +  "exports": {
      +    "./features/*": "./src/features/*.js",
      +    "./features/private-internal/*": null
      +  }
      +}
      +
      import featureInternal from 'es-module-package/features/private-internal/m';
      +// Throws: ERR_PACKAGE_PATH_NOT_EXPORTED
      +
      +import featureX from 'es-module-package/features/x';
      +// Loads ./node_modules/es-module-package/src/features/x.js
      +

      Exports sugar#

      +

      If the "." export is the only export, the "exports" field provides sugar for this case being the direct "exports" field value.

      If the "." export has a fallback array or string value, then the "exports" field can be set to this value directly.

      -
      {
      -  "exports": {
      -    ".": "./main.js"
      -  }
      -}
      +
      {
      +  "exports": {
      +    ".": "./main.js"
      +  }
      +}

      can be written:

      -
      {
      -  "exports": "./main.js"
      -}
      -

      Conditional exports#

      -

      Stability: 1 - Experimental

      +
      {
      +  "exports": "./main.js"
      +}
      +

      Conditional exports#

      +

      Conditional exports provide a way to map to different paths depending on certain conditions. They are supported for both CommonJS and ES module imports.

      For example, a package that wants to provide different ES module exports for require() and import can be written:

      // package.json
      -{
      -  "main": "./main-require.cjs",
      -  "exports": {
      -    "import": "./main-module.js",
      -    "require": "./main-require.cjs"
      -  },
      -  "type": "module"
      -}
      -

      Node.js supports the following conditions out of the box:

      +{ + "main": "./main-require.cjs", + "exports": { + "import": "./main-module.js", + "require": "./main-require.cjs" + }, + "type": "module" +} +

      Node.js implements the following conditions:

      • "import" - matches when the package is loaded via import or import(), or via any top-level import or resolve operation by the @@ -43469,23 +47043,19 @@ or ES module file. This condition should always come last.
      • matching, earlier entries have higher priority and take precedence over later entries. The general rule is that conditions should be from most specific to least specific in object order.

        -

        Other conditions such as "browser", "electron", "deno", "react-native", -etc., are unknown to Node.js, and thus ignored. Runtimes or tools other than -Node.js can use them at their discretion. Further restrictions, definitions, or -guidance on condition names might occur in the future.

        Using the "import" and "require" conditions can lead to some hazards, which are further explained in the dual CommonJS/ES module packages section.

        Conditional exports can also be extended to exports subpaths, for example:

        -
        {
        -  "main": "./main.js",
        -  "exports": {
        -    ".": "./main.js",
        -    "./feature": {
        -      "node": "./feature-node.js",
        -      "default": "./feature.js"
        -    }
        -  }
        -}
        +
        {
        +  "main": "./main.js",
        +  "exports": {
        +    ".": "./main.js",
        +    "./feature": {
        +      "node": "./feature-node.js",
        +      "default": "./feature.js"
        +    }
        +  }
        +}

        Defines a package where require('pkg/feature') and import 'pkg/feature' could provide different implementations between Node.js and other JS environments.

        @@ -43496,26 +47066,28 @@ these JS environments from having to pretend to be existing environments in order to support packages with conditional exports. For this reason, using "node" and "default" condition branches is usually preferable to using "node" and "browser" condition branches.

        -

        Nested conditions#

        -

        Stability: 1 - Experimental

        +

        Nested conditions#

        In addition to direct mappings, Node.js also supports nested condition objects.

        For example, to define a package that only has dual mode entry points for use in Node.js but not the browser:

        -
        {
        -  "main": "./main.js",
        -  "exports": {
        -    "node": {
        -      "import": "./feature-node.mjs",
        -      "require": "./feature-node.cjs"
        -    },
        -    "default": "./feature.mjs",
        -  }
        -}
        +
        {
        +  "main": "./main.js",
        +  "exports": {
        +    "node": {
        +      "import": "./feature-node.mjs",
        +      "require": "./feature-node.cjs"
        +    },
        +    "default": "./feature.mjs",
        +  }
        +}

        Conditions continue to be matched in order as with flat conditions. If a nested conditional does not have any mapping it will continue checking the remaining conditions of the parent condition. In this way nested conditions behave analogously to nested JavaScript if statements.

        -

        Resolving user conditions#

        +

        Resolving user conditions#

        +

        When running Node.js, custom user conditions can be added with the --conditions flag:

        node --conditions=development main.js
        @@ -43523,18 +47095,68 @@ conditions behave analogously to nested JavaScript if statements."node", "default", "import", and "require" conditions as appropriate.

        Any number of custom conditions can be set with repeat flags.

        -

        Self-referencing a package using its name#

        +

        Conditions Definitions#

        +

        The "import", "require", "node" and "default" conditions are defined +and implemented in Node.js core, +as specified above.

        +

        Other condition strings are unknown to Node.js and thus ignored by default. +Runtimes or tools other than Node.js can use them at their discretion.

        +

        These user conditions can be enabled in Node.js via the --conditions +flag.

        +

        The following condition definitions are currently endorsed by Node.js:

        +
          +
        • "browser" - any environment which implements a standard subset of global +browser APIs available from JavaScript in web browsers, including the DOM +APIs.
        • +
        • "development" - can be used to define a development-only environment +entry point. Must always be mutually exclusive with "production".
        • +
        • "production" - can be used to define a production environment entry +point. Must always be mutually exclusive with "development".
        • +
        +

        The above user conditions can be enabled in Node.js via the --conditions +flag.

        +

        Platform specific conditions such as "deno", "electron", or "react-native" +may be used, but while there remain no implementation or integration intent +from these platforms, the above are not explicitly endorsed by Node.js.

        +

        New conditions definitions may be added to this list by creating a pull request +to the Node.js documentation for this section. The requirements for listing +a new condition definition here are that:

        +
          +
        • The definition should be clear and unambiguous for all implementers.
        • +
        • The use case for why the condition is needed should be clearly justified.
        • +
        • There should exist sufficient existing implementation usage.
        • +
        • The condition name should not conflict with another condition definition or +condition in wide usage.
        • +
        • The listing of the condition definition should provide a coordination +benefit to the ecosystem that wouldn't otherwise be possible. For example, +this would not necessarily be the case for company-specific or +application-specific conditions.
        • +
        +

        The above definitions may be moved to a dedicated conditions registry in due +course.

        +

        Self-referencing a package using its name#

        +

        Within a package, the values defined in the package’s package.json "exports" field can be referenced via the package’s name. For example, assuming the package.json is:

        // package.json
        -{
        -  "name": "a-package",
        -  "exports": {
        -    ".": "./main.mjs",
        -    "./foo": "./foo.js"
        -  }
        -}
        +{ + "name": "a-package", + "exports": { + ".": "./main.mjs", + "./foo": "./foo.js" + } +}

        Then any module in that package can reference an export in the package itself:

        // ./a-module.mjs
         import { something } from 'a-package'; // Imports "something" from ./main.mjs.
        @@ -43550,9 +47172,22 @@ error:

        import { another } from 'a-package/m.mjs';

        Self-referencing is also available when using require, both in an ES module, and in a CommonJS one. For example, this code will also work:

        -
        // ./a-module.js
        +
        // ./a-module.js
         const { something } = require('a-package/foo'); // Loads from ./foo.js.
        -

        Dual CommonJS/ES module packages#

        +

        Finally, self-referencing also works with scoped packages. For example, this +code will also work:

        +
        // package.json
        +{
        +  "name": "@my/package",
        +  "exports": "./index.js"
        +}
        + +
        // ./index.js
        +module.exports = 42;
        // ./other.js +console.log(require('@my/package'));
        +
        $ node other.js
        +42
        +

      Dual CommonJS/ES module packages#

      Prior to the introduction of support for ES modules in Node.js, it was a common pattern for package authors to include both CommonJS and ES module JavaScript sources in their package, with package.json "main" specifying the @@ -43568,7 +47203,7 @@ exports). Unlike in the scenario where "module" is only used by or ES module files are transpiled into CommonJS on the fly before evaluation by Node.js, the files referenced by the ES module entry point are evaluated as ES modules.

      -

      Dual package hazard#

      +

      Dual package hazard#

      When an application is using a package that provides both CommonJS and ES module sources, there is a risk of certain bugs if both versions of the package get loaded. This potential comes from the fact that the pkgInstance created by @@ -43588,7 +47223,7 @@ the other. This differs from how import and require st all-CommonJS or all-ES module environments, respectively, and therefore is surprising to users. It also differs from the behavior users are familiar with when using transpilation via tools like Babel or esm.

      -

      Writing dual packages while avoiding or minimizing hazards#

      +

      Writing dual packages while avoiding or minimizing hazards#

      First, the hazard described in the previous section occurs when a package contains both CommonJS and ES module sources and both sources are provided for use in Node.js, either via separate main entry points or exported paths. A @@ -43616,30 +47251,30 @@ than import pkg from 'pkg'; pkg.name. browsers.

    • The hazards described in the previous section are avoided or minimized.
    • -

      Approach #1: Use an ES module wrapper#

      +
      Approach #1: Use an ES module wrapper#

      Write the package in CommonJS or transpile ES module sources into CommonJS, and create an ES module wrapper file that defines the named exports. Using Conditional exports, the ES module wrapper is used for import and the CommonJS entry point for require.

      // ./node_modules/pkg/package.json
      -{
      -  "type": "module",
      -  "main": "./index.cjs",
      -  "exports": {
      -    "import": "./wrapper.mjs",
      -    "require": "./index.cjs"
      -  }
      -}
      +{ + "type": "module", + "main": "./index.cjs", + "exports": { + "import": "./wrapper.mjs", + "require": "./index.cjs" + } +}

      The preceding example uses explicit extensions .mjs and .cjs. If your files use the .js extension, "type": "module" will cause such files to be treated as ES modules, just as "type": "commonjs" would cause them to be treated as CommonJS. See Enabling.

      -
      // ./node_modules/pkg/index.cjs
      -exports.name = 'value';
      +
      // ./node_modules/pkg/index.cjs
      +exports.name = 'value';
      // ./node_modules/pkg/wrapper.mjs
       import cjsModule from './index.cjs';
      -export const name = cjsModule.name;
      +export const name = cjsModule.name;

      In this example, the name from import { name } from 'pkg' is the same singleton as the name from const { name } = require('pkg'). Therefore === returns true when comparing the two names and the divergent specifier hazard @@ -43650,7 +47285,7 @@ or if support in the wrapper for the import pkg from 'pkg' pattern then the wrapper would instead be written to export the default optionally along with any named exports as well:

      import cjsModule from './index.cjs';
      -export const name = cjsModule.name;
      +export const name = cjsModule.name;
       export default cjsModule;

      This approach is appropriate for any of the following use cases:

        @@ -43674,26 +47309,26 @@ application, such as by dependencies; or if the CommonJS version can be loaded but doesn’t affect the ES module version (for example, because the package is stateless):

        // ./node_modules/pkg/package.json
        -{
        -  "type": "module",
        -  "main": "./index.cjs",
        -  "exports": {
        -    ".": "./index.cjs",
        -    "./module": "./wrapper.mjs"
        -  }
        -}
        -

        Approach #2: Isolate state#

        +{ + "type": "module", + "main": "./index.cjs", + "exports": { + ".": "./index.cjs", + "./module": "./wrapper.mjs" + } +} +
        Approach #2: Isolate state#

        A package.json file can define the separate CommonJS and ES module entry points directly:

        // ./node_modules/pkg/package.json
        -{
        -  "type": "module",
        -  "main": "./index.cjs",
        -  "exports": {
        -    "import": "./index.mjs",
        -    "require": "./index.cjs"
        -  }
        -}
        +{ + "type": "module", + "main": "./index.cjs", + "exports": { + "import": "./index.mjs", + "require": "./index.cjs" + } +}

        This can be done if both the CommonJS and ES module versions of the package are equivalent, for example because one is the transpiled output of the other; and the package’s management of state is carefully isolated (or the package is @@ -43713,8 +47348,8 @@ CommonJS and ES module instances of the package:

        If possible, contain all state within an instantiated object. JavaScript’s Date, for example, needs to be instantiated to contain state; if it were a package, it would be used like this:

        -
        import Date from 'date';
        -const someDate = new Date();
        +
        import Date from 'date';
        +const someDate = new Date();
         // someDate contains state; Date does not

        The new keyword isn’t required; a package’s function can return a new object, or modify a passed-in object, to keep the state external to the @@ -43724,9 +47359,9 @@ package.

        Isolate the state in one or more CommonJS files that are shared between the CommonJS and ES module versions of the package. For example, if the CommonJS and ES module entry points are index.cjs and index.mjs, respectively:

        -
        // ./node_modules/pkg/index.cjs
        +
        // ./node_modules/pkg/index.cjs
         const state = require('./state.cjs');
        -module.exports.state = state;
        +module.exports.state = state;
        // ./node_modules/pkg/index.mjs
         import state from './state.cjs';
         export {
        @@ -43756,15 +47391,15 @@ execution between the CommonJS and ES module versions of a package.

        conditional exports for consumers could be to add an export, e.g. "./module", to point to an all-ES module-syntax version of the package:

        // ./node_modules/pkg/package.json
        -{
        -  "type": "module",
        -  "main": "./index.cjs",
        -  "exports": {
        -    ".": "./index.cjs",
        -    "./module": "./index.mjs"
        -  }
        -}
        -

        Node.js package.json field definitions#

        +{ + "type": "module", + "main": "./index.cjs", + "exports": { + ".": "./index.cjs", + "./module": "./index.mjs" + } +}
        +

      Node.js package.json field definitions#

      This section describes the fields used by the Node.js runtime. Other tools (such as npm) use additional fields which are ignored by Node.js and not documented here.

      @@ -43772,44 +47407,60 @@ additional fields which are ignored by Node.js and not documented here.

      • "name" - Relevant when using named imports within a package. Also used by package managers as the name of the package.
      • +
      • "main" - The default module when loading the package, if exports is not +specified, and in versions of Node.js prior to the introduction of exports.
      • "type" - The package type determining whether to load .js files as CommonJS or ES modules.
      • "exports" - Package exports and conditional exports. When present, limits which submodules can be loaded from within the package.
      • -
      • "main" - The default module when loading the package, if exports is not -specified, and in versions of Node.js prior to the introduction of exports.
      • "imports" - Package imports, for use by modules within the package itself.
      -

      "name"#

      +

      "name"#

      -
      {
      -  "name": "package-name"
      -}
      +
      {
      +  "name": "package-name"
      +}

      The "name" field defines your package’s name. Publishing to the npm registry requires a name that satisfies certain requirements.

      The "name" field can be used in addition to the "exports" field to self-reference a package using its name.

      -

      "type"#

      +

      "main"#

      + + +
      {
      +  "main": "./main.js"
      +}
      +

      The "main" field defines the script that is used when the package directory +is loaded via require(). Its value +is a path.

      +
      require('./path/to/directory'); // This resolves to ./path/to/directory/main.js.
      +

      When a package has an "exports" field, this will take precedence over the +"main" field when importing the package by name.

      +

      "type"#

      +
      +

      Net#

      Stability: 2 - Stable

      -

      Source Code: lib/net.js

      +

      Source Code: lib/net.js

      The net module provides an asynchronous network API for creating stream-based TCP or IPC servers (net.createServer()) and clients (net.createConnection()).

      It can be accessed using:

      const net = require('net');
      -

      IPC support#

      +

      IPC support#

      The net module supports IPC with named pipes on Windows, and Unix domain sockets on other operating systems.

      -

      Identifying paths for IPC connections#

      +

      Identifying paths for IPC connections#

      net.connect(), net.createConnection(), server.listen() and socket.connect() take a path parameter to identify IPC endpoints.

      On Unix, the local domain is also known as the Unix domain. The path is a @@ -43952,9 +47587,128 @@ Unlike Unix domain sockets, Windows will close and remove the pipe when the owning process exits.

      JavaScript string escaping requires paths to be specified with extra backslash escaping such as:

      -
      net.createServer().listen(
      -  path.join('\\\\?\\pipe', process.cwd(), 'myctl'));
      -

      Class: net.Server#

      +
      net.createServer().listen(
      +  path.join('\\\\?\\pipe', process.cwd(), 'myctl'));
      +

      Class: net.BlockList#

      + +

      The BlockList object can be used with some network APIs to specify rules for +disabling inbound or outbound access to specific IP addresses, IP ranges, or +IP subnets.

      +

      blockList.addAddress(address[, type])#

      + + +

      Adds a rule to block the given IP address.

      +

      blockList.addRange(start, end[, type])#

      + + +

      Adds a rule to block a range of IP addresses from start (inclusive) to +end (inclusive).

      +

      blockList.addSubnet(net, prefix[, type])#

      + +
        +
      • net <string> | <net.SocketAddress> The network IPv4 or IPv6 address.
      • +
      • prefix <number> The number of CIDR prefix bits. For IPv4, this +must be a value between 0 and 32. For IPv6, this must be between +0 and 128.
      • +
      • type <string> Either 'ipv4' or 'ipv6'. Default: 'ipv4'.
      • +
      +

      Adds a rule to block a range of IP addresses specified as a subnet mask.

      +

      blockList.check(address[, type])#

      + + +

      Returns true if the given IP address matches any of the rules added to the +BlockList.

      +
      const blockList = new net.BlockList();
      +blockList.addAddress('123.123.123.123');
      +blockList.addRange('10.0.0.1', '10.0.0.10');
      +blockList.addSubnet('8592:757c:efae:4e45::', 64, 'ipv6');
      +
      +console.log(blockList.check('123.123.123.123'));  // Prints: true
      +console.log(blockList.check('10.0.0.3'));  // Prints: true
      +console.log(blockList.check('222.111.111.222'));  // Prints: false
      +
      +// IPv6 notation for IPv4 addresses works:
      +console.log(blockList.check('::ffff:7b7b:7b7b', 'ipv6')); // Prints: true
      +console.log(blockList.check('::ffff:123.123.123.123', 'ipv6')); // Prints: true
      +

      blockList.rules#

      + + +

      The list of rules added to the blocklist.

      +

      Class: net.SocketAddress#

      + +

      new net.SocketAddress([options])#

      + +
        +
      • options <Object> +
          +
        • address <string> The network address as either an IPv4 or IPv6 string. +Default: '127.0.0.1' if family is 'ipv4'; '::' if family is +'ipv6'.
        • +
        • family <string> One of either 'ipv4' or 'ipv6'. **Default**: 'ipv4'`.
        • +
        • flowlabel <number> An IPv6 flow-label used only if family is 'ipv6'.
        • +
        • port <number> An IP port.
        • +
        +
      • +
      +

      socketaddress.address#

      + + +

      socketaddress.family#

      + +
        +
      • Type <string> Either 'ipv4' or 'ipv6'.
      • +
      +

      socketaddress.flowlabel#

      + + +

      socketaddress.port#

      + + +

      Class: net.Server#

      @@ -43962,7 +47716,7 @@ escaping such as:

    • Extends: <EventEmitter>
    • This class is used to create a TCP or IPC server.

      -

      new net.Server([options][, connectionListener])#

      +

      new net.Server([options][, connectionListener])#

      net.Server is an EventEmitter with the following events:

      -

      Event: 'close'#

      +

      Event: 'close'#

      Emitted when the server closes. If connections exist, this event is not emitted until all connections are ended.

      -

      Event: 'connection'#

      +

      Event: 'connection'#

      @@ -43986,7 +47740,7 @@ event is not emitted until all connections are ended.

      Emitted when a new connection is made. socket is an instance of net.Socket.

      -

      Event: 'error'#

      +

      Event: 'error'#

      @@ -43997,12 +47751,12 @@ event is not emitted until all connections are ended.

      event will not be emitted directly following this event unless server.close() is manually called. See the example in discussion of server.listen().

      -

      Event: 'listening'#

      +

      Event: 'listening'#

      Emitted when the server has been bound after calling server.listen().

      -

      server.address()#

      +

      server.address()#

      @@ -44015,20 +47769,20 @@ as reported by the operating system if listening on an IP socket { port: 12346, family: 'IPv4', address: '127.0.0.1' }.

      For a server listening on a pipe or Unix domain socket, the name is returned as a string.

      -
      const server = net.createServer((socket) => {
      -  socket.end('goodbye\n');
      -}).on('error', (err) => {
      +
      const server = net.createServer((socket) => {
      +  socket.end('goodbye\n');
      +}).on('error', (err) => {
         // Handle errors here.
         throw err;
       });
       
       // Grab an arbitrary unused port.
      -server.listen(() => {
      -  console.log('opened server on', server.address());
      +server.listen(() => {
      +  console.log('opened server on', server.address());
       });

      server.address() returns null before the 'listening' event has been emitted or after calling server.close().

      -

      server.close([callback])#

      +

      server.close([callback])#

      @@ -44042,7 +47796,7 @@ when all connections are ended and the server emits a callback
      will be called once the 'close' event occurs. Unlike that event, it will be called with an Error as its only argument if the server was not open when it was closed.

      -

      server.connections#

      +

      server.connections#

      @@ -44054,7 +47808,7 @@ was not open when it was closed.

      This becomes null when sending a socket to a child with child_process.fork(). To poll forks and get current number of active connections, use asynchronous server.getConnections() instead.

      -

      server.getConnections(callback)#

      +

      server.getConnections(callback)#

      @@ -44065,10 +47819,11 @@ connections, use asynchronous Asynchronously get the number of concurrent connections on the server. Works when sockets were sent to forks.

      Callback should take two arguments err and count.

      -

      server.listen()#

      +

      server.listen()#

      Start a server listening for connections. A net.Server can be a TCP or an IPC server depending on what it listens to.

      Possible signatures:

      + +

      This function is asynchronous. When the server starts listening, the 'listening' event will be emitted. The last parameter callback will be added as a listener for the 'listening' event.

      @@ -44096,16 +47852,16 @@ called. Otherwise, an ERR_SERVER_ALREADY_LISTEN error will be throw This happens when another server is already listening on the requested port/path/handle. One way to handle this would be to retry after a certain amount of time:

      -
      server.on('error', (e) => {
      -  if (e.code === 'EADDRINUSE') {
      -    console.log('Address in use, retrying...');
      +
      server.on('error', (e) => {
      +  if (e.code === 'EADDRINUSE') {
      +    console.log('Address in use, retrying...');
           setTimeout(() => {
      -      server.close();
      -      server.listen(PORT, HOST);
      +      server.close();
      +      server.listen(PORT, HOST);
           }, 1000);
         }
       });
      -

      server.listen(handle[, backlog][, callback])#

      +
      server.listen(handle[, backlog][, callback])#
      @@ -44121,7 +47877,7 @@ already been bound to a port, a Unix domain socket, or a Windows named pipe.

      underlying _handle member), or an object with an fd member that is a valid file descriptor.

      Listening on a file descriptor is not supported on Windows.

      -

      server.listen(options[, callback])#

      +
      server.listen(options[, callback])#
      • enable <boolean> Default: false
      • @@ -44684,7 +48452,14 @@ delay before the first keepalive probe is sent on an idle socket.

        data packet received and the first keepalive probe. Setting 0 for initialDelay will leave the value unchanged from the default (or previous) setting.

        -

        socket.setNoDelay([noDelay])#

        +

        Enabling the keep-alive functionality will set the following socket options:

        +
          +
        • SO_KEEPALIVE=1
        • +
        • TCP_KEEPIDLE=initialDelay
        • +
        • TCP_KEEPCNT=10
        • +
        • TCP_KEEPINTVL=1
        • +
        +

        socket.setNoDelay([noDelay])#

        @@ -44699,7 +48474,7 @@ to optimize throughput at the expense of latency.

        Passing true for noDelay or not passing an argument will disable Nagle's algorithm for the socket. Passing false for noDelay will enable Nagle's algorithm.

        -

        socket.setTimeout(timeout[, callback])#

        +

        socket.setTimeout(timeout[, callback])#

        @@ -44713,15 +48488,24 @@ the socket. By default net.Socket do not have a timeout.

        When an idle timeout is triggered the socket will receive a 'timeout' event but the connection will not be severed. The user must manually call socket.end() or socket.destroy() to end the connection.

        -
        socket.setTimeout(3000);
        -socket.on('timeout', () => {
        -  console.log('socket timeout');
        -  socket.end();
        +
        socket.setTimeout(3000);
        +socket.on('timeout', () => {
        +  console.log('socket timeout');
        +  socket.end();
         });

        If timeout is 0, then the existing idle timeout is disabled.

        The optional callback parameter will be added as a one-time listener for the 'timeout' event.

        -

        socket.unref()#

        +

        socket.timeout#

        + + +

        The socket timeout in milliseconds as set by socket.setTimeout(). +It is undefined if a timeout has not been set.

        +

        socket.unref()#

        @@ -44731,7 +48515,7 @@ socket.on('timeout', # +

        socket.write(data[, encoding][, callback])#

        @@ -44750,7 +48534,21 @@ buffer. Returns false if all or part of the data was queued in user written out, which may not be immediately.

        See Writable stream write() method for more information.

        -

        net.connect()#

        +

        socket.readyState#

        + + +

        This property represents the state of the connection as a string.

        +
          +
        • If the stream is connecting socket.readyState is opening.
        • +
        • If the stream is readable and writable, it is open.
        • +
        • If the stream is readable and not writable, it is readOnly.
        • +
        • If the stream is not readable and writable, it is writeOnly.
        • +
        +

      net.connect()#

      Aliases to net.createConnection().

      Possible signatures:

      @@ -44761,7 +48559,7 @@ connections.
    • net.connect(port[, host][, connectListener]) for TCP connections.
    • -

      net.connect(options[, connectListener])#

      +

      net.connect(options[, connectListener])#

      @@ -44772,7 +48570,7 @@ for TCP connections.

      Alias to net.createConnection(options[, connectListener]).

      -

      net.connect(path[, connectListener])#

      +

      net.connect(path[, connectListener])#

      @@ -44783,7 +48581,7 @@ for TCP connections.

      Alias to net.createConnection(path[, connectListener]).

      -

      net.connect(port[, host][, connectListener])#

      +

      net.connect(port[, host][, connectListener])#

      @@ -44795,7 +48593,7 @@ for TCP connections.

      Alias to net.createConnection(port[, host][, connectListener]).

      -

      net.createConnection()#

      +

      net.createConnection()#

      A factory function, which creates a new net.Socket, immediately initiates connection with socket.connect(), then returns the net.Socket that starts the connection.

      @@ -44811,7 +48609,7 @@ for IPC connections. for TCP connections.

      The net.connect() function is an alias to this function.

      -

      net.createConnection(options[, connectListener])#

      +

      net.createConnection(options[, connectListener])#

      @@ -44837,21 +48635,21 @@ it starts the connection.

      Following is an example of a client of the echo server described in the net.createServer() section:

      const net = require('net');
      -const client = net.createConnection({ port: 8124 }, () => {
      +const client = net.createConnection({ port: 8124 }, () => {
         // 'connect' listener.
      -  console.log('connected to server!');
      -  client.write('world!\r\n');
      +  console.log('connected to server!');
      +  client.write('world!\r\n');
       });
      -client.on('data', (data) => {
      -  console.log(data.toString());
      -  client.end();
      +client.on('data', (data) => {
      +  console.log(data.toString());
      +  client.end();
       });
      -client.on('end', () => {
      -  console.log('disconnected from server');
      +client.on('end', () => {
      +  console.log('disconnected from server');
       });

      To connect on the socket /tmp/echo.sock:

      -
      const client = net.createConnection({ path: '/tmp/echo.sock' });
      -

      net.createConnection(path[, connectListener])#

      +
      const client = net.createConnection({ path: '/tmp/echo.sock' });
      +

      net.createConnection(path[, connectListener])#

      @@ -44870,7 +48668,7 @@ See Identifying paths for I immediately initiates connection with socket.connect(path[, connectListener]), then returns the net.Socket that starts the connection.

      -

      net.createConnection(port[, host][, connectListener])#

      +

      net.createConnection(port[, host][, connectListener])#

      @@ -44891,15 +48689,16 @@ then returns the net.Socket that starts the connection.

      immediately initiates connection with socket.connect(port[, host][, connectListener]), then returns the net.Socket that starts the connection.

      -

      net.createServer([options][, connectionListener])#

      +

      net.createServer([options][, connectionListener])#

      • options <Object>
          -
        • allowHalfOpen <boolean> Indicates whether half-opened TCP -connections are allowed. Default: false.
        • +
        • allowHalfOpen <boolean> If set to false, then the socket will +automatically end the writable side when the readable side ends. +Default: false.
        • pauseOnConnect <boolean> Indicates whether the socket should be paused on incoming connections. Default: false.
        @@ -44910,10 +48709,12 @@ paused on incoming connections. Default: false.

        Creates a new TCP or IPC server.

        If allowHalfOpen is set to true, when the other end of the socket -sends a FIN packet, the server will only send a FIN packet back when -socket.end() is explicitly called, until then the connection is -half-closed (non-readable but still writable). See 'end' event -and RFC 1122 (section 4.2.2.13) for more information.

        +signals the end of transmission, the server will only send back the end of +transmission when socket.end() is explicitly called. For example, in the +context of TCP, when a FIN packed is received, a FIN packed is sent +back only when socket.end() is explicitly called. Until then the +connection is half-closed (non-readable but still writable). See 'end' +event and RFC 1122 (section 4.2.2.13) for more information.

        If pauseOnConnect is set to true, then the socket associated with each incoming connection will be paused, and no data will be read from its handle. This allows connections to be passed between processes without any data being @@ -44924,30 +48725,30 @@ read by the original process. To begin reading data from a paused socket, call

        Here is an example of an TCP echo server which listens for connections on port 8124:

        const net = require('net');
        -const server = net.createServer((c) => {
        +const server = net.createServer((c) => {
           // 'connection' listener.
        -  console.log('client connected');
        -  c.on('end', () => {
        -    console.log('client disconnected');
        +  console.log('client connected');
        +  c.on('end', () => {
        +    console.log('client disconnected');
           });
        -  c.write('hello\r\n');
        -  c.pipe(c);
        +  c.write('hello\r\n');
        +  c.pipe(c);
         });
        -server.on('error', (err) => {
        +server.on('error', (err) => {
           throw err;
         });
        -server.listen(8124, () => {
        -  console.log('server bound');
        +server.listen(8124, () => {
        +  console.log('server bound');
         });

        Test this by using telnet:

        -
        $ telnet localhost 8124
        +
        $ telnet localhost 8124

        To listen on the socket /tmp/echo.sock:

        -
        server.listen('/tmp/echo.sock', () => {
        -  console.log('server bound');
        +
        server.listen('/tmp/echo.sock', () => {
        +  console.log('server bound');
         });

        Use nc to connect to a Unix domain socket server:

        -
        $ nc -U /tmp/echo.sock
        -

        net.isIP(input)#

        +
        $ nc -U /tmp/echo.sock
        +

      net.isIP(input)#

      @@ -44958,7 +48759,7 @@ server.listen(8124, Tests if input is an IP address. Returns 0 for invalid strings, returns 4 for IP version 4 addresses, and returns 6 for IP version 6 addresses.

      -

      net.isIPv4(input)#

      +

      net.isIPv4(input)#

      @@ -44967,7 +48768,7 @@ addresses.

    • Returns: <boolean>
    • Returns true if input is a version 4 IP address, otherwise returns false.

      -

      net.isIPv6(input)#

      +

      net.isIPv6(input)#

      @@ -44975,15 +48776,16 @@ addresses.

    • input <string>
    • Returns: <boolean>
    • -

      Returns true if input is a version 6 IP address, otherwise returns false.

      -

      OS#

      +

      Returns true if input is a version 6 IP address, otherwise returns false.

      +
      +

      OS#

      Stability: 2 - Stable

      -

      Source Code: lib/os.js

      +

      Source Code: lib/os.js

      The os module provides operating system-related utility methods and properties. It can be accessed using:

      const os = require('os');
      -

      os.EOL#

      +

      os.EOL#

      @@ -44995,7 +48797,7 @@ properties. It can be accessed using:

    • \n on POSIX
    • \r\n on Windows
    • -

      os.arch()#

      +

      os.arch()#

      @@ -45006,7 +48808,7 @@ properties. It can be accessed using:

      compiled. Possible values are 'arm', 'arm64', 'ia32', 'mips', 'mipsel', 'ppc', 'ppc64', 's390', 's390x', 'x32', and 'x64'.

      The return value is equivalent to process.arch.

      -

      os.constants#

      +

      os.constants#

      @@ -45016,7 +48818,7 @@ compiled. Possible values are 'arm', 'arm64', 'i

      Contains commonly used operating system-specific constants for error codes, process signals, and so on. The specific constants defined are described in OS constants.

      -

      os.cpus()#

      +

      os.cpus()#

      @@ -45083,11 +48885,23 @@ process signals, and so on. The specific constants defined are described in idle: 1070905480, irq: 20 } - } + }, ]

      nice values are POSIX-only. On Windows, the nice values of all processors are always 0.

      -

      os.endianness()#

      +

      os.devNull#

      + + +

      The platform-specific file path of the null device.

      +
        +
      • \\.\nul on Windows
      • +
      • /dev/null on POSIX
      • +
      +

      os.endianness()#

      @@ -45097,7 +48911,7 @@ are always 0.

      Returns a string identifying the endianness of the CPU for which the Node.js binary was compiled.

      Possible values are 'BE' for big endian and 'LE' for little endian.

      -

      os.freemem()#

      +

      os.freemem()#

      @@ -45105,7 +48919,7 @@ binary was compiled.

    • Returns: <integer>
    • Returns the amount of free system memory in bytes as an integer.

      -

      os.getPriority([pid])#

      +

      os.getPriority([pid])#

      @@ -45116,7 +48930,7 @@ binary was compiled.

      Returns the scheduling priority for the process specified by pid. If pid is not provided or is 0, the priority of the current process is returned.

      -

      os.homedir()#

      +

      os.homedir()#

      @@ -45128,7 +48942,7 @@ not provided or is 0, the priority of the current process is return uses the effective UID to look up the user's home directory.

      On Windows, it uses the USERPROFILE environment variable if defined. Otherwise it uses the path to the profile directory of the current user.

      -

      os.hostname()#

      +

      os.hostname()#

      @@ -45136,7 +48950,7 @@ Otherwise it uses the path to the profile directory of the current user.

    • Returns: <string>
    • Returns the host name of the operating system as a string.

      -

      os.loadavg()#

      +

      os.loadavg()#

      @@ -45148,7 +48962,7 @@ Otherwise it uses the path to the profile directory of the current user.

      system and expressed as a fractional number.

      The load average is a Unix-specific concept. On Windows, the return value is always [0, 0, 0].

      -

      os.networkInterfaces()#

      +

      os.networkInterfaces()#

      @@ -45214,7 +49028,7 @@ to null. } ] }
      -

      os.platform()#

      +

      os.platform()#

      @@ -45226,8 +49040,8 @@ at compile time. Possible values are 'aix', 'darwin', 'linux', 'openbsd', 'sunos', and 'win32'.

      The return value is equivalent to process.platform.

      The value 'android' may also be returned if Node.js is built on the Android -operating system. Android support is experimental.

      -

      os.release()#

      +operating system. Android support is experimental.

      +

      os.release()#

      @@ -45238,7 +49052,7 @@ operating system. uname(3). On Windows, GetVersionExW() is used. See https://en.wikipedia.org/wiki/Uname#Examples for more information.

      -

      os.setPriority([pid, ]priority)#

      +

      os.setPriority([pid, ]priority)#

      @@ -45258,13 +49072,13 @@ confusion, set priority to one of the priority constants.

      On Windows, setting priority to PRIORITY_HIGHEST requires elevated user privileges. Otherwise the set priority will be silently reduced to PRIORITY_HIGH.

      -

      os.tmpdir()#

      +

      os.tmpdir()#

      os.totalmem()#

      @@ -45283,7 +49097,7 @@ string.

    • Returns: <integer>
    • Returns the total amount of system memory in bytes as an integer.

      -

      os.type()#

      +

      os.type()#

      @@ -45294,7 +49108,7 @@ string.

      returns 'Linux' on Linux, 'Darwin' on macOS, and 'Windows_NT' on Windows.

      See https://en.wikipedia.org/wiki/Uname#Examples for additional information about the output of running uname(3) on various operating systems.

      -

      os.uptime()#

      +

      os.uptime()#

      +
      +

      Path#

      Stability: 2 - Stable

      -

      Source Code: lib/path.js

      +

      Source Code: lib/path.js

      The path module provides utilities for working with file and directory paths. It can be accessed using:

      const path = require('path');
      -

      Windows vs. POSIX#

      +

      Windows vs. POSIX#

      The default operation of the path module varies based on the operating system on which a Node.js application is running. Specifically, when running on a Windows operating system, the path module will assume that Windows-style paths are being used.

      So using path.basename() might yield different results on POSIX and Windows:

      On POSIX:

      -
      path.basename('C:\\temp\\myfile.html');
      +
      path.basename('C:\\temp\\myfile.html');
       // Returns: 'C:\\temp\\myfile.html'

      On Windows:

      -
      path.basename('C:\\temp\\myfile.html');
      +
      path.basename('C:\\temp\\myfile.html');
       // Returns: 'myfile.html'

      To achieve consistent results when working with Windows file paths on any operating system, use path.win32:

      On POSIX and Windows:

      -
      path.win32.basename('C:\\temp\\myfile.html');
      +
      path.win32.basename('C:\\temp\\myfile.html');
       // Returns: 'myfile.html'

      To achieve consistent results when working with POSIX file paths on any operating system, use path.posix:

      On POSIX and Windows:

      -
      path.posix.basename('/tmp/myfile.html');
      +
      path.posix.basename('/tmp/myfile.html');
       // Returns: 'myfile.html'

      On Windows Node.js follows the concept of per-drive working directory. This behavior can be observed when using a drive path without a backslash. For example, path.resolve('C:\\') can potentially return a different result than path.resolve('C:'). For more information, see this MSDN page.

      -

      path.basename(path[, ext])#

      +

      path.basename(path[, ext])#

      • <Object>
      • @@ -48047,7 +52183,25 @@ process.argv.forEach((val, Child Process documentation), the process.channel property is a reference to the IPC channel. If no IPC channel exists, this property is undefined.

        -

        process.chdir(directory)#

        +

        process.channel.ref()#

        + +

        This method makes the IPC channel keep the event loop of the process +running if .unref() has been called before.

        +

        Typically, this is managed through the number of 'disconnect' and 'message' +listeners on the process object. However, this method can be used to +explicitly request a specific behavior.

        +

        process.channel.unref()#

        + +

        This method makes the IPC channel not keep the event loop of the process +running, and lets it finish even while the channel is open.

        +

        Typically, this is managed through the number of 'disconnect' and 'message' +listeners on the process object. However, this method can be used to +explicitly request a specific behavior.

        +

      process.chdir(directory)#

      @@ -48057,15 +52211,15 @@ property is undefined.

      The process.chdir() method changes the current working directory of the Node.js process or throws an exception if doing so fails (for instance, if the specified directory does not exist).

      -
      console.log(`Starting directory: ${process.cwd()}`);
      +
      console.log(`Starting directory: ${process.cwd()}`);
       try {
      -  process.chdir('/tmp');
      -  console.log(`New directory: ${process.cwd()}`);
      +  process.chdir('/tmp');
      +  console.log(`New directory: ${process.cwd()}`);
       } catch (err) {
      -  console.error(`chdir: ${err}`);
      +  console.error(`chdir: ${err}`);
       }

      This feature is not available in Worker threads.

      -

      process.config#

      +

      process.config#

      @@ -48106,7 +52260,7 @@ running the ./configure script.

      The process.config property is not read-only and there are existing modules in the ecosystem that are known to extend, modify, or entirely replace the value of process.config.

      -

      process.connected#

      +

      process.connected#

      @@ -48119,7 +52273,7 @@ and Cluster documentation), the process.connect process.disconnect() is called.

      Once process.connected is false, it is no longer possible to send messages over the IPC channel using process.send().

      -

      process.cpuUsage([previousValue])#

      +

      process.cpuUsage([previousValue])#

      @@ -48140,16 +52294,16 @@ spent in user and system code respectively, and may end up being greater than actual elapsed time if multiple CPU cores are performing work for this process.

      The result of a previous call to process.cpuUsage() can be passed as the argument to the function, to get a diff reading.

      -
      const startUsage = process.cpuUsage();
      +
      const startUsage = process.cpuUsage();
       // { user: 38579, system: 6986 }
       
       // spin the CPU for 500 milliseconds
      -const now = Date.now();
      -while (Date.now() - now < 500);
      +const now = Date.now();
      +while (Date.now() - now < 500);
       
      -console.log(process.cpuUsage(startUsage));
      +console.log(process.cpuUsage(startUsage));
       // { user: 514883, system: 11226 }
      -

      process.cwd()#

      +

      process.cwd()#

      @@ -48158,8 +52312,8 @@ argument to the function, to get a diff reading.

      The process.cwd() method returns the current working directory of the Node.js process.

      -
      console.log(`Current directory: ${process.cwd()}`);
      -

      process.debugPort#

      +
      console.log(`Current directory: ${process.cwd()}`);
      +

      process.debugPort#

      @@ -48167,8 +52321,8 @@ process.

    • <number>
    • The port used by the Node.js debugger when enabled.

      -
      process.debugPort = 5858;
      -

      process.disconnect()#

      +
      process.debugPort = 5858;
      +

      process.disconnect()#

      @@ -48180,7 +52334,7 @@ once there are no other connections keeping it alive.

      ChildProcess.disconnect() from the parent process.

      If the Node.js process was not spawned with an IPC channel, process.disconnect() will be undefined.

      -

      process.dlopen(module, filename[, flags])#

      +

      process.dlopen(module, filename[, flags])#

      -

      Stability: 1 - Experimental

      If true, a diagnostic report is generated on fatal errors, such as out of memory errors or failed C++ assertions.

      -
      console.log(`Report on fatal error: ${process.report.reportOnFatalError}`);
      -

      process.report.reportOnSignal#

      +
      console.log(`Report on fatal error: ${process.report.reportOnFatalError}`);
      +

      process.report.reportOnSignal#

      @@ -50134,8 +54455,8 @@ stream as a string. This method allows asynchronous iteration of readline.Interface will always consume the input stream fully.

      Performance is not on par with the traditional 'line' event API. Use 'line' instead for performance-sensitive applications.

      -
      async function processLineByLine() {
      -  const rl = readline.createInterface({
      +
      async function processLineByLine() {
      +  const rl = readline.createInterface({
           // ...
         });
       
      @@ -50144,12 +54465,23 @@ instead for performance-sensitive applications.

      // `line`. } }
      -

      rl.line#

      +

      readline.createInterface() will start to consume the input stream once +invoked. Having asynchronous operations between interface creation and +asynchronous iteration may result in missed lines.

      +

      rl.line#

      The current input data being processed by node.

      This can be used when collecting input from a TTY stream to retrieve the @@ -50161,17 +54493,17 @@ unintended consequences if rl.cursor is not also controlled.

      If not using a TTY stream for input, use the 'line' event.

      One possible use case would be as follows:

      const values = ['lorem ipsum', 'dolor sit amet'];
      -const rl = readline.createInterface(process.stdin);
      -const showResults = debounce(() => {
      -  console.log(
      +const rl = readline.createInterface(process.stdin);
      +const showResults = debounce(() => {
      +  console.log(
           '\n',
      -    values.filter((val) => val.startsWith(rl.line)).join(' ')
      +    values.filter((val) => val.startsWith(rl.line)).join(' ')
         );
       }, 300);
      -process.stdin.on('keypress', (c, k) => {
      -  showResults();
      +process.stdin.on('keypress', (c, k) => {
      +  showResults();
       });
      -

      rl.cursor#

      +

      rl.cursor#

      @@ -50183,9 +54515,9 @@ process.stdin.on('keypress', # +

      rl.getCursorPos()#

      • Returns: <Object> @@ -50198,7 +54530,7 @@ as well as the column where the terminal caret will be rendered.

        Returns the real position of the cursor in relation to the input prompt + string. Long input (wrapping) strings, as well as multiple line prompts are included in the calculations.

        -

        readline.clearLine(stream, dir[, callback])#

        +

      readline.clearLine(stream, dir[, callback])#

      +
      +

      REPL#

      Stability: 2 - Stable

      -

      Source Code: lib/repl.js

      +

      Source Code: lib/repl.js

      The repl module provides a Read-Eval-Print-Loop (REPL) implementation that is available both as a standalone program or includible in other applications. It can be accessed using:

      const repl = require('repl');
      -

      Design and features#

      +

      Design and features#

      The repl module exports the repl.REPLServer class. While running, instances of repl.REPLServer will accept individual lines of user input, evaluate those according to a user-defined evaluation function, then output the @@ -50629,11 +54984,11 @@ ANSI-styled output, saving and restoring current REPL session state, error recovery, and customizable evaluation functions. Terminals that do not support ANSI styles and Emacs-style line editing automatically fall back to a limited feature set.

      -

      Commands and special keys#

      +

      Commands and special keys#

      The following special commands are supported by all REPL instances:

        -
      • .break: When in the process of inputting a multi-line expression, entering -the .break command (or pressing the <ctrl>-C key combination) will abort +
      • .break: When in the process of inputting a multi-line expression, enter +the .break command (or press Ctrl+C) to abort further input or processing of that expression.
      • .clear: Resets the REPL context to an empty object and clears any multi-line expression being input.
      • @@ -50643,9 +54998,10 @@ multi-line expression being input. > .save ./file/to/save.js
      • .load: Load a file into the current REPL session. > .load ./file/to/load.js
      • -
      • .editor: Enter editor mode (<ctrl>-D to finish, <ctrl>-C to cancel).
      • +
      • .editor: Enter editor mode (Ctrl+D to finish, +Ctrl+C to cancel).
      -
      > .editor
      +
      > .editor
       // Entering editor mode (^D to finish, ^C to cancel)
       function welcome(name) {
         return `Hello ${name}!`;
      @@ -50658,62 +55014,63 @@ welcome('Node.js User');
       >

      The following key combinations in the REPL have these special effects:

        -
      • <ctrl>-C: When pressed once, has the same effect as the .break command. +
      • Ctrl+C: When pressed once, has the same effect as the +.break command. When pressed twice on a blank line, has the same effect as the .exit command.
      • -
      • <ctrl>-D: Has the same effect as the .exit command.
      • -
      • <tab>: When pressed on a blank line, displays global and local (scope) +
      • Ctrl+D: Has the same effect as the .exit command.
      • +
      • Tab: When pressed on a blank line, displays global and local (scope) variables. When pressed while entering other input, displays relevant autocompletion options.

      For key bindings related to the reverse-i-search, see reverse-i-search. For all other key bindings, see TTY keybindings.

      -

      Default evaluation#

      +

      Default evaluation#

      By default, all instances of repl.REPLServer use an evaluation function that evaluates JavaScript expressions and provides access to Node.js built-in modules. This default behavior can be overridden by passing in an alternative evaluation function when the repl.REPLServer instance is created.

      -

      JavaScript expressions#

      +
      JavaScript expressions#

      The default evaluator supports direct evaluation of JavaScript expressions:

      -
      > 1 + 1
      +
      > 1 + 1
       2
      -> const m = 2
      +> const m = 2
       undefined
      -> m + 1
      +> m + 1
       3

      Unless otherwise scoped within blocks or functions, variables declared either implicitly or using the const, let, or var keywords are declared at the global scope.

      -

      Global and local scope#

      +
      Global and local scope#

      The default evaluator provides access to any variables that exist in the global scope. It is possible to expose a variable to the REPL explicitly by assigning it to the context object associated with each REPLServer:

      const repl = require('repl');
       const msg = 'message';
       
      -repl.start('> ').context.m = msg;
      +repl.start('> ').context.m = msg;

      Properties in the context object appear as local within the REPL:

      -
      $ node repl_test.js
      -> m
      +
      $ node repl_test.js
      +> m
       'message'

      Context properties are not read-only by default. To specify read-only globals, context properties must be defined using Object.defineProperty():

      const repl = require('repl');
       const msg = 'message';
       
      -const r = repl.start('> ');
      -Object.defineProperty(r.context, 'm', {
      +const r = repl.start('> ');
      +Object.defineProperty(r.context, 'm', {
         configurable: false,
         enumerable: true,
         value: msg
       });
      -

      Accessing core Node.js modules#

      +
      Accessing core Node.js modules#

      The default evaluator will automatically load Node.js core modules into the REPL environment when used. For instance, unless otherwise declared as a global or scoped variable, the input fs will be evaluated on-demand as global.fs = require('fs').

      -
      > fs.createReadStream('./some/file');
      -

      Global uncaught exceptions#

      +
      > fs.createReadStream('./some/file');
      +
      Global uncaught exceptions#
      +
      +

      Stream[src]#

      Stability: 2 - Stable

      -

      Source Code: lib/stream.js

      +

      Source Code: lib/stream.js

      A stream is an abstract interface for working with streaming data in Node.js. The stream module provides an API for implementing the stream interface.

      There are many stream objects provided by Node.js. For instance, a @@ -51761,11 +56142,11 @@ are both stream instances.

      const stream = require('stream');

      The stream module is useful for creating new types of stream instances. It is usually not necessary to use the stream module to consume streams.

      -

      Organization of this document#

      +

      Organization of this document#

      This document contains two primary sections and a third section for notes. The first section explains how to use existing streams within an application. The second section explains how to create new types of streams.

      -

      Types of streams#

      +

      Types of streams#

      There are four fundamental stream types within Node.js:

      • Writable: streams to which data can be written (for example, @@ -51778,9 +56159,9 @@ second section explains how to create new types of streams.

        is written and read (for example, zlib.createDeflate()).

      Additionally, this module includes the utility functions -stream.pipeline(), stream.finished() and +stream.pipeline(), stream.finished() and stream.Readable.from().

      -

      Object mode#

      +

      Object mode#

      All streams created by Node.js APIs operate exclusively on strings and Buffer (or Uint8Array) objects. It is possible, however, for stream implementations to work with other types of JavaScript values (with the exception of null, @@ -51789,11 +56170,10 @@ operate in "object mode".

      Stream instances are switched into object mode using the objectMode option when the stream is created. Attempting to switch an existing stream into object mode is not safe.

      -

      Buffering#

      +

      Buffering#

      Both Writable and Readable streams will store data in an internal -buffer that can be retrieved using writable.writableBuffer or -readable.readableBuffer, respectively.

      +buffer.

      The amount of data potentially buffered depends on the highWaterMark option passed into the stream's constructor. For normal streams, the highWaterMark option specifies a total number of bytes. For streams operating @@ -51829,43 +56209,47 @@ consumption of data received from the socket and whose Writableto the socket. Because data may be written to the socket at a faster or slower rate than data is received, each side should operate (and buffer) independently of the other.

      -

      API for stream consumers#

      +

      The mechanics of the internal buffering are an internal implementation detail +and may be changed at any time. However, for certain advanced implementations, +the internal buffers can be retrieved using writable.writableBuffer or +readable.readableBuffer. Use of these undocumented properties is discouraged.

      +

      API for stream consumers#

      Almost all Node.js applications, no matter how simple, use streams in some manner. The following is an example of using streams in a Node.js application that implements an HTTP server:

      const http = require('http');
       
      -const server = http.createServer((req, res) => {
      +const server = http.createServer((req, res) => {
         // `req` is an http.IncomingMessage, which is a readable stream.
         // `res` is an http.ServerResponse, which is a writable stream.
       
         let body = '';
         // Get the data as utf8 strings.
         // If an encoding is not set, Buffer objects will be received.
      -  req.setEncoding('utf8');
      +  req.setEncoding('utf8');
       
         // Readable streams emit 'data' events once a listener is added.
      -  req.on('data', (chunk) => {
      +  req.on('data', (chunk) => {
           body += chunk;
         });
       
         // The 'end' event indicates that the entire body has been received.
      -  req.on('end', () => {
      +  req.on('end', () => {
           try {
      -      const data = JSON.parse(body);
      +      const data = JSON.parse(body);
             // Write back something interesting to the user:
      -      res.write(typeof data);
      -      res.end();
      +      res.write(typeof data);
      +      res.end();
           } catch (er) {
             // uh oh! bad json!
      -      res.statusCode = 400;
      -      return res.end(`error: ${er.message}`);
      +      res.statusCode = 400;
      +      return res.end(`error: ${er.message}`);
           }
         });
       });
       
      -server.listen(1337);
      +server.listen(1337);
       
       // $ curl localhost:1337 -d "{}"
       // object
      @@ -51887,7 +56271,7 @@ are not required to implement the stream interfaces directly and will generally
       have no reason to call require('stream').

      Developers wishing to implement new types of streams should refer to the section API for stream implementers.

      -

      Writable streams#

      +

      Writable streams#

      Writable streams are an abstraction for a destination to which data is written.

      Examples of Writable streams include:

      @@ -51908,16 +56292,16 @@ written.

      While specific instances of Writable streams may differ in various ways, all Writable streams follow the same fundamental usage pattern as illustrated in the example below:

      -
      const myStream = getWritableStreamSomehow();
      -myStream.write('some data');
      -myStream.write('some more data');
      -myStream.end('done writing data');
      -

      Class: stream.Writable#

      +
      const myStream = getWritableStreamSomehow();
      +myStream.write('some data');
      +myStream.write('some more data');
      +myStream.end('done writing data');
      +
      Class: stream.Writable#
      -
      Event: 'close'#
      +
      Event: 'close'#
      • error <Error> Optional, an error to emit with 'error' event.
      • @@ -52060,10 +56454,32 @@ an ERR_STREAM_DESTROYED error. This is a destructive and immediate way to destroy a stream. Previous calls to write() may not have drained, and may trigger an ERR_STREAM_DESTROYED error. Use end() instead of destroy if data should flush before close, or wait for -the 'drain' event before destroying the stream. -Implementors should not override this method, +the 'drain' event before destroying the stream.

        + +
        const { Writable } = require('stream');
        +
        +const myStream = new Writable();
        +
        +const fooErr = new Error('foo error');
        +myStream.destroy(fooErr);
        +myStream.on('error', (fooErr) => console.error(fooErr.message)); // foo error
        const { Writable } = require('stream'); + +const myStream = new Writable(); + +myStream.destroy(); +myStream.on('error', function wontHappen() {});
        +
        const { Writable } = require('stream');
        +
        +const myStream = new Writable();
        +myStream.destroy();
        +
        +myStream.write('foo', (error) => console.error(error.code));
        +// ERR_STREAM_DESTROYED
        +

        Once destroy() has been called any further calls will be a no-op and no +further errors except from _destroy() may be emitted as 'error'.

        +

        Implementors should not override this method, but instead implement writable._destroy().

        -
        writable.destroyed#
        +
        writable.destroyed#
        @@ -52071,11 +56487,20 @@ but instead implement writ
      • <boolean>

      Is true after writable.destroy() has been called.

      -
      writable.end([chunk[, encoding]][, callback])#
      +
      const { Writable } = require('stream');
      +
      +const myStream = new Writable();
      +
      +console.log(myStream.destroyed); // false
      +myStream.destroy();
      +console.log(myStream.destroyed); // true
      +
      writable.end([chunk[, encoding]][, callback])#
      • error <Error> Error which will be passed as payload in 'error' event
      • @@ -52550,10 +56994,12 @@ called and readableFlowing is not true.

        Destroy the stream. Optionally emit an 'error' event, and emit a 'close' event (unless emitClose is set to false). After this call, the readable stream will release any internal resources and subsequent calls to push() -will be ignored. -Implementors should not override this method, but instead implement +will be ignored.

        +

        Once destroy() has been called any further calls will be a no-op and no +further errors except from _destroy() may be emitted as 'error'.

        +

        Implementors should not override this method, but instead implement readable._destroy().

        -
        readable.destroyed#
        +
        readable.destroyed#
        @@ -52561,7 +57007,7 @@ Implementors should not override this method, but instead implement
      • <boolean>

      Is true after readable.destroy() has been called.

      -
      readable.isPaused()#
      +
      readable.isPaused()#
      @@ -52572,14 +57018,14 @@ Implementors should not override this method, but instead implement Readable. This is used primarily by the mechanism that underlies the readable.pipe() method. In most typical cases, there will be no reason to use this method directly.

      -
      const readable = new stream.Readable();
      +
      const readable = new stream.Readable();
       
      -readable.isPaused(); // === false
      -readable.pause();
      -readable.isPaused(); // === true
      -readable.resume();
      -readable.isPaused(); // === false
      -
      readable.pause()#
      +readable.isPaused(); // === false +readable.pause(); +readable.isPaused(); // === true +readable.resume(); +readable.isPaused(); // === false
      +
      readable.pause()#
      @@ -52589,19 +57035,19 @@ readable.isPaused(); // === false

      The readable.pause() method will cause a stream in flowing mode to stop emitting 'data' events, switching out of flowing mode. Any data that becomes available will remain in the internal buffer.

      -
      const readable = getReadableStreamSomehow();
      -readable.on('data', (chunk) => {
      -  console.log(`Received ${chunk.length} bytes of data.`);
      -  readable.pause();
      -  console.log('There will be no additional data for 1 second.');
      +
      const readable = getReadableStreamSomehow();
      +readable.on('data', (chunk) => {
      +  console.log(`Received ${chunk.length} bytes of data.`);
      +  readable.pause();
      +  console.log('There will be no additional data for 1 second.');
         setTimeout(() => {
      -    console.log('Now data will start flowing again.');
      -    readable.resume();
      +    console.log('Now data will start flowing again.');
      +    readable.resume();
         }, 1000);
       });

      The readable.pause() method has no effect if there is a 'readable' event listener.

      -
      readable.pipe(destination[, options])#
      +
      readable.pipe(destination[, options])#
      @@ -52623,26 +57069,26 @@ so that the destination Writable stream is not overwhelmed by a fas

      The following example pipes all of the data from the readable into a file named file.txt:

      const fs = require('fs');
      -const readable = getReadableStreamSomehow();
      -const writable = fs.createWriteStream('file.txt');
      +const readable = getReadableStreamSomehow();
      +const writable = fs.createWriteStream('file.txt');
       // All the data from readable goes into 'file.txt'.
      -readable.pipe(writable);
      +readable.pipe(writable);

      It is possible to attach multiple Writable streams to a single Readable stream.

      The readable.pipe() method returns a reference to the destination stream making it possible to set up chains of piped streams:

      const fs = require('fs');
      -const r = fs.createReadStream('file.txt');
      -const z = zlib.createGzip();
      -const w = fs.createWriteStream('file.txt.gz');
      -r.pipe(z).pipe(w);
      +const r = fs.createReadStream('file.txt'); +const z = zlib.createGzip(); +const w = fs.createWriteStream('file.txt.gz'); +r.pipe(z).pipe(w);

      By default, stream.end() is called on the destination Writable stream when the source Readable stream emits 'end', so that the destination is no longer writable. To disable this default behavior, the end option can be passed as false, causing the destination stream to remain open:

      -
      reader.pipe(writer, { end: false });
      -reader.on('end', () => {
      -  writer.end('Goodbye\n');
      +
      reader.pipe(writer, { end: false });
      +reader.on('end', () => {
      +  writer.end('Goodbye\n');
       });

      One important caveat is that if the Readable stream emits an error during processing, the Writable destination is not closed automatically. If an @@ -52650,7 +57096,7 @@ error occurs, it will be necessary to manually close each stream in ord to prevent memory leaks.

      The process.stderr and process.stdout Writable streams are never closed until the Node.js process exits, regardless of the specified options.

      -
      readable.read([size])#
      +
      readable.read([size])#
      @@ -52669,25 +57115,25 @@ the stream has ended, in which case all of the data remaining in the internal buffer will be returned.

      If the size argument is not specified, all of the data contained in the internal buffer will be returned.

      -

      The size argument must be less than or equal to 1 GB.

      +

      The size argument must be less than or equal to 1 GiB.

      The readable.read() method should only be called on Readable streams operating in paused mode. In flowing mode, readable.read() is called automatically until the internal buffer is fully drained.

      -
      const readable = getReadableStreamSomehow();
      +
      const readable = getReadableStreamSomehow();
       
       // 'readable' may be triggered multiple times as data is buffered in
      -readable.on('readable', () => {
      +readable.on('readable', () => {
         let chunk;
      -  console.log('Stream is readable (new data received in buffer)');
      +  console.log('Stream is readable (new data received in buffer)');
         // Use a loop to make sure we read all currently available data
      -  while (null !== (chunk = readable.read())) {
      -    console.log(`Read ${chunk.length} bytes of data...`);
      +  while (null !== (chunk = readable.read())) {
      +    console.log(`Read ${chunk.length} bytes of data...`);
         }
       });
       
       // 'end' will be triggered once when there is no more data available
      -readable.on('end', () => {
      -  console.log('Reached end of stream.');
      +readable.on('end', () => {
      +  console.log('Reached end of stream.');
       });

      Each call to readable.read() returns a chunk of data, or null. The chunks are not concatenated. A while loop is necessary to consume all data @@ -52700,15 +57146,15 @@ emitted when there is no more data to come.

      to collect chunks across multiple 'readable' events:

      const chunks = [];
       
      -readable.on('readable', () => {
      +readable.on('readable', () => {
         let chunk;
      -  while (null !== (chunk = readable.read())) {
      -    chunks.push(chunk);
      +  while (null !== (chunk = readable.read())) {
      +    chunks.push(chunk);
         }
       });
       
      -readable.on('end', () => {
      -  const content = chunks.join('');
      +readable.on('end', () => {
      +  const content = chunks.join('');
       });

      A Readable stream in object mode will always return a single item from a call to readable.read(size), regardless of the value of the @@ -52717,15 +57163,26 @@ a call to readable.read(size)< also be emitted.

      Calling stream.read([size]) after the 'end' event has been emitted will return null. No runtime error will be raised.

      -
      readable.readable#
      +
      readable.readable#
      -

      Is true if it is safe to call readable.read().

      -
      readable.readableEncoding#
      +

      Is true if it is safe to call readable.read(), which means +the stream has not been destroyed or emitted 'error' or 'end'.

      +
      readable.readableDidRead#
      + + +

      Allows determining if the stream has been or is about to be read. +Returns true if 'data', 'end', 'error' or 'close' has been +emitted.

      +
      readable.readableEncoding#
      @@ -52734,7 +57191,7 @@ been emitted will return null. No runtime error will be raised.

      Getter for the property encoding of a given Readable stream. The encoding property can be set using the readable.setEncoding() method.

      -
      readable.readableEnded#
      +
      readable.readableEnded#
      @@ -52742,7 +57199,7 @@ property can be set using the <boolean>

      Becomes true when 'end' event is emitted.

      -
      readable.readableFlowing#
      +
      readable.readableFlowing#
      @@ -52751,7 +57208,7 @@ property can be set using the

      This property reflects the current state of a Readable stream as described in the Three states section.

      -
      readable.readableHighWaterMark#
      +
      readable.readableHighWaterMark#
      @@ -52760,7 +57217,7 @@ in the Three states section.

      Returns the value of highWaterMark passed when constructing this Readable.

      -
      readable.readableLength#
      +
      readable.readableLength#
      @@ -52770,7 +57227,7 @@ in the Three states section.

      This property contains the number of bytes (or objects) in the queue ready to be read. The value provides introspection data regarding the status of the highWaterMark.

      -
      readable.readableObjectMode#
      +
      readable.readableObjectMode#
      @@ -52778,7 +57235,7 @@ the status of the highWaterMark.

    • <boolean>
    • Getter for the property objectMode of a given Readable stream.

      -
      readable.resume()#
      +
      readable.resume()#
      • error <Error>
      • @@ -53036,9 +57501,23 @@ Implementors should not override this method, but instead implement readable._destroy(). The default implementation of _destroy() for Transform also emit 'close' unless emitClose is set in false.

        -

        stream.finished(stream[, options], callback)#

        +

        Once destroy() has been called, any further calls will be a no-op and no +further errors except from _destroy() may be emitted as 'error'.

        +

        stream.finished(stream[, options], callback)#

        • stream <Stream> A readable and/or writable stream.
        • @@ -53063,56 +57542,86 @@ listeners. or has experienced an error or a premature close event.

          const { finished } = require('stream');
           
          -const rs = fs.createReadStream('archive.tar');
          +const rs = fs.createReadStream('archive.tar');
           
          -finished(rs, (err) => {
          +finished(rs, (err) => {
             if (err) {
          -    console.error('Stream failed.', err);
          +    console.error('Stream failed.', err);
             } else {
          -    console.log('Stream is done reading.');
          +    console.log('Stream is done reading.');
             }
           });
           
          -rs.resume(); // Drain the stream.
          +rs.resume(); // Drain the stream.

      Especially useful in error handling scenarios where a stream is destroyed prematurely (like an aborted HTTP request), and will not emit 'end' or 'finish'.

      The finished API is promisify-able as well;

      -
      const finished = util.promisify(stream.finished);
      +
      const finished = util.promisify(stream.finished);
       
      -const rs = fs.createReadStream('archive.tar');
      +const rs = fs.createReadStream('archive.tar');
       
      -async function run() {
      -  await finished(rs);
      -  console.log('Stream is done reading.');
      +async function run() {
      +  await finished(rs);
      +  console.log('Stream is done reading.');
       }
       
      -run().catch(console.error);
      -rs.resume(); // Drain the stream.
      +run().catch(console.error); +rs.resume(); // Drain the stream.

      stream.finished() leaves dangling event listeners (in particular 'error', 'end', 'finish' and 'close') after callback has been invoked. The reason for this is so that unexpected 'error' events (due to incorrect stream implementations) do not cause unexpected crashes. If this is unwanted behavior then the returned cleanup function needs to be invoked in the callback:

      -
      const cleanup = finished(rs, (err) => {
      -  cleanup();
      +
      const cleanup = finished(rs, (err) => {
      +  cleanup();
         // ...
       });
      -

      stream.pipeline(...streams, callback)#

      +

      stream.pipeline(source[, ...transforms], destination, callback)#

      +

      stream.pipeline(streams, callback)#

      -

      A module method to pipe between streams forwarding errors and properly cleaning -up and provide a callback when the pipeline is complete.

      +

      A module method to pipe between streams and generators forwarding errors and +properly cleaning up and provide a callback when the pipeline is complete.

      const { pipeline } = require('stream');
       const fs = require('fs');
       const zlib = require('zlib');
      @@ -53122,31 +57631,50 @@ up and provide a callback when the pipeline is complete.

      // A pipeline to gzip a potentially huge tar file efficiently: -pipeline( - fs.createReadStream('archive.tar'), - zlib.createGzip(), - fs.createWriteStream('archive.tar.gz'), +pipeline( + fs.createReadStream('archive.tar'), + zlib.createGzip(), + fs.createWriteStream('archive.tar.gz'), (err) => { if (err) { - console.error('Pipeline failed.', err); + console.error('Pipeline failed.', err); } else { - console.log('Pipeline succeeded.'); + console.log('Pipeline succeeded.'); } } );

      The pipeline API is promisify-able as well:

      -
      const pipeline = util.promisify(stream.pipeline);
      +
      const pipeline = util.promisify(stream.pipeline);
      +
      +async function run() {
      +  await pipeline(
      +    fs.createReadStream('archive.tar'),
      +    zlib.createGzip(),
      +    fs.createWriteStream('archive.tar.gz')
      +  );
      +  console.log('Pipeline succeeded.');
      +}
       
      -async function run() {
      -  await pipeline(
      -    fs.createReadStream('archive.tar'),
      -    zlib.createGzip(),
      -    fs.createWriteStream('archive.tar.gz')
      +run().catch(console.error);
      +

      The pipeline API also supports async generators:

      +
      const pipeline = util.promisify(stream.pipeline);
      +const fs = require('fs');
      +
      +async function run() {
      +  await pipeline(
      +    fs.createReadStream('lowercase.txt'),
      +    async function* (source) {
      +      source.setEncoding('utf8');  // Work with strings rather than `Buffer`s.
      +      for await (const chunk of source) {
      +        yield chunk.toUpperCase();
      +      }
      +    },
      +    fs.createWriteStream('uppercase.txt')
         );
      -  console.log('Pipeline succeeded.');
      +  console.log('Pipeline succeeded.');
       }
       
      -run().catch(console.error);
      +run().catch(console.error);

      stream.pipeline() will call stream.destroy(err) on all streams except:

      • Readable streams which have emitted 'end' or 'close'.
      • @@ -53155,7 +57683,7 @@ run().catch(console.error);

      stream.pipeline() leaves dangling event listeners on the streams after the callback has been invoked. In the case of reuse of streams after failure, this can cause event listener leaks and swallowed errors.

      -

      stream.Readable.from(iterable, [options])#

      +

      stream.Readable.from(iterable, [options])#

      @@ -53169,22 +57697,22 @@ this is explicitly opted out by setting options.objectMode to Returns: <stream.Readable>

      A utility method for creating readable streams out of iterators.

      -
      const { Readable } = require('stream');
      +
      const { Readable } = require('stream');
       
      -async function * generate() {
      +async function * generate() {
         yield 'hello';
         yield 'streams';
       }
       
      -const readable = Readable.from(generate());
      +const readable = Readable.from(generate());
       
      -readable.on('data', (chunk) => {
      -  console.log(chunk);
      +readable.on('data', (chunk) => {
      +  console.log(chunk);
       });

      Calling Readable.from(string) or Readable.from(buffer) will not have the strings or buffers be iterated to match the other streams semantics for performance reasons.

      -

      API for stream implementers#

      +

      API for stream implementers#

      The stream module API has been designed to make it possible to easily implement streams using JavaScript's prototypal inheritance model.

      @@ -53193,15 +57721,11 @@ of the four basic stream classes (stream.Writable, stream.Rea stream.Duplex, or stream.Transform), making sure they call the appropriate parent class constructor:

      -
      const { Writable } = require('stream');
      -
      -class MyWritable extends Writable {
      -  constructor({ highWaterMark, ...options }) {
      -    super({
      -      highWaterMark,
      -      autoDestroy: true,
      -      emitClose: true
      -    });
      +
      const { Writable } = require('stream');
      +
      +class MyWritable extends Writable {
      +  constructor({ highWaterMark, ...options }) {
      +    super({ highWaterMark });
           // ...
         }
       }
      @@ -53254,7 +57778,7 @@ as 'error', 'data', 'end', 'finish' Doing so can break current and future stream invariants leading to behavior and/or compatibility issues with other streams, stream utilities, and user expectations.

      -

      Simplified construction#

      +

      Simplified construction#

      @@ -53262,24 +57786,26 @@ expectations.

      inheritance. This can be accomplished by directly creating instances of the stream.Writable, stream.Readable, stream.Duplex or stream.Transform objects and passing appropriate methods as constructor options.

      -
      const { Writable } = require('stream');
      +
      const { Writable } = require('stream');
       
      -const myWritable = new Writable({
      -  write(chunk, encoding, callback) {
      +const myWritable = new Writable({
      +  write(chunk, encoding, callback) {
           // ...
         }
       });
      -

      Implementing a writable stream#

      +

      Implementing a writable stream#

      The stream.Writable class is extended to implement a Writable stream.

      Custom Writable streams must call the new stream.Writable([options]) constructor and implement the writable._write() and/or writable._writev() method.

      -

      new stream.Writable([options])#

      +
      new stream.Writable([options])#

      tls.connect(options[, callback])#

      tls.connect(path[, options][, callback])#

      @@ -55790,7 +60356,7 @@ socket.on('end', ()

      Same as tls.connect() except that path can be provided as an argument instead of an option.

      A path option, if specified, will take precedence over the path argument.

      -

      tls.connect(port[, host][, options][, callback])#

      +

      tls.connect(port[, host][, options][, callback])#

      @@ -55805,7 +60371,7 @@ as an argument instead of an option.

      as arguments instead of options.

      A port or host option, if specified, will take precedence over any port or host argument.

      -

      tls.createSecureContext([options])#

      +

      tls.createSecureContext([options])#

      -

      Legacy urlObject#

      +

      Stability: 3 - Legacy: Use the WHATWG URL API instead.

      +

      Legacy urlObject#

      -

      Stability: 0 - Deprecated: Use the WHATWG URL API instead.

      +

      Stability: 3 - Legacy: Use the WHATWG URL API instead.

      The legacy urlObject (require('url').Url) is created and returned by the url.parse() function.

      -

      urlObject.auth#

      +
      urlObject.auth#

      The auth property is the username and password portion of the URL, also referred to as userinfo. This string subset follows the protocol and double slashes (if present) and precedes the host component, delimited by @. The string is either the username, or it is the username and password separated by :.

      For example: 'user:pass'.

      -

      urlObject.hash#

      +
      urlObject.hash#

      The hash property is the fragment identifier portion of the URL including the leading # character.

      For example: '#hash'.

      -

      urlObject.host#

      +
      urlObject.host#

      The host property is the full lower-cased host portion of the URL, including the port if specified.

      For example: 'sub.example.com:8080'.

      -

      urlObject.hostname#

      +
      urlObject.hostname#

      The hostname property is the lower-cased host name portion of the host component without the port included.

      For example: 'sub.example.com'.

      -

      urlObject.href#

      +
      urlObject.href#

      The href property is the full URL string that was parsed with both the protocol and host components converted to lower-case.

      For example: 'http://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'.

      -

      urlObject.path#

      +
      urlObject.path#

      The path property is a concatenation of the pathname and search components.

      For example: '/p/a/t/h?query=string'.

      No decoding of the path is performed.

      -

      urlObject.pathname#

      +
      urlObject.pathname#

      The pathname property consists of the entire path section of the URL. This is everything following the host (including the port) and before the start of the query or hash components, delimited by either the ASCII question mark (?) or hash (#) characters.

      For example: '/p/a/t/h'.

      No decoding of the path string is performed.

      -

      urlObject.port#

      +
      urlObject.port#

      The port property is the numeric port portion of the host component.

      For example: '8080'.

      -

      urlObject.protocol#

      +
      urlObject.protocol#

      The protocol property identifies the URL's lower-cased protocol scheme.

      For example: 'http:'.

      -

      urlObject.query#

      +
      urlObject.query#

      The query property is either the query string without the leading ASCII question mark (?), or an object returned by the querystring module's parse() method. Whether the query property is a string or object is @@ -58192,20 +62887,22 @@ determined by the parseQueryString argument passed to url.par

      For example: 'query=string' or {'query': 'string'}.

      If returned as a string, no decoding of the query string is performed. If returned as an object, both keys and values are decoded.

      -

      urlObject.search#

      +
      urlObject.search#

      The search property consists of the entire "query string" portion of the URL, including the leading ASCII question mark (?) character.

      For example: '?query=string'.

      No decoding of the query string is performed.

      -

      urlObject.slashes#

      +
      urlObject.slashes#

      The slashes property is a boolean with a value of true if two ASCII forward-slash characters (/) are required following the colon in the protocol.

      -

      url.format(urlObject)#

      +

      url.format(urlObject)#

      -

      Stability: 0 - Deprecated: Use the WHATWG URL API instead.

      +

      Stability: 3 - Legacy: Use the WHATWG URL API instead.

      • urlObject <Object> | <string> A URL object (as returned by url.parse() or constructed otherwise). If a string, it is converted to an object by passing @@ -58223,7 +62920,8 @@ it to url.parse().

      The url.format() method returns a formatted URL string derived from urlObject.

      -
      url.format({
      +
      const url = require('url');
      +url.format({
         protocol: 'https',
         hostname: 'example.com',
         pathname: '/some/path',
      @@ -58306,11 +63004,13 @@ character, the literal string # is appended to result.
       string, an Error is thrown.
       
    • result is returned.
    • -

      url.parse(urlString[, parseQueryString[, slashesDenoteHost]])#

      +

      url.parse(urlString[, parseQueryString[, slashesDenoteHost]])#

      -

      Stability: 0 - Deprecated: Use the WHATWG URL API instead.

      +

      Stability: 3 - Legacy: Use the WHATWG URL API instead.

      • urlString <string> The URL string to parse.
      • parseQueryString <boolean> If true, the query property will always @@ -58344,25 +63044,27 @@ use the WHATWG URL API. Because the url.parse() method lenient, non-standard algorithm for parsing URL strings, security issues can be introduced. Specifically, issues with host name spoofing and incorrect handling of usernames and passwords have been identified.

        -

        url.resolve(from, to)#

        +

        url.resolve(from, to)#

        -

        Stability: 0 - Deprecated: Use the WHATWG URL API instead.

        +

        Stability: 3 - Legacy: Use the WHATWG URL API instead.

        • from <string> The Base URL being resolved against.
        • to <string> The HREF URL being resolved.
        • @@ -58370,22 +63072,36 @@ incorrect handling of usernames and passwords have been identified.

          The url.resolve() method resolves a target URL relative to a base URL in a manner similar to that of a Web browser resolving an anchor tag HREF.

          const url = require('url');
          -url.resolve('/one/two/three', 'four');         // '/one/two/four'
          -url.resolve('http://example.com/', '/one');    // 'http://example.com/one'
          -url.resolve('http://example.com/one', '/two'); // 'http://example.com/two'
          +url.resolve('/one/two/three', 'four'); // '/one/two/four' +url.resolve('http://example.com/', '/one'); // 'http://example.com/one' +url.resolve('http://example.com/one', '/two'); // 'http://example.com/two'
      +

      You can achieve the same result using the WHATWG URL API:

      +
      function resolve(from, to) {
      +  const resolvedUrl = new URL(to, new URL(from, 'resolve://'));
      +  if (resolvedUrl.protocol === 'resolve:') {
      +    // `from` is a relative URL.
      +    const { pathname, search, hash } = resolvedUrl;
      +    return pathname + search + hash;
      +  }
      +  return resolvedUrl.toString();
      +}
      +
      +resolve('/one/two/three', 'four');         // '/one/two/four'
      +resolve('http://example.com/', '/one');    // 'http://example.com/one'
      +resolve('http://example.com/one', '/two'); // 'http://example.com/two'

      -

      Percent-encoding in URLs#

      +

      Percent-encoding in URLs#

      URLs are permitted to only contain a certain range of characters. Any character falling outside of that range must be encoded. How such characters are encoded, and which characters to encode depends entirely on where the character is located within the structure of the URL.

      -

      Legacy API#

      +

      Legacy API#

      Within the Legacy API, spaces (' ') and the following characters will be automatically escaped in the properties of URL objects:

      < > " ` \r \n \t { } | \ ^ '

      For example, the ASCII space character (' ') is encoded as %20. The ASCII forward slash (/) character is encoded as %3C.

      -

      WHATWG API#

      +

      WHATWG API#

      The WHATWG URL Standard uses a more selective and fine grained approach to selecting encoded characters than that used by the Legacy API.

      The WHATWG algorithm defines four "percent-encode sets" that describe ranges @@ -58418,20 +63134,21 @@ specific conditions, in addition to all other cases.

      When non-ASCII characters appear within a host name, the host name is encoded using the Punycode algorithm. Note, however, that a host name may contain both Punycode encoded and percent-encoded characters:

      -
      const myURL = new URL('https://%CF%80.example.com/foo');
      -console.log(myURL.href);
      +
      const myURL = new URL('https://%CF%80.example.com/foo');
      +console.log(myURL.href);
       // Prints https://xn--1xa.example.com/foo
      -console.log(myURL.origin);
      -// Prints https://xn--1xa.example.com
      -

      Util#

      +console.log(myURL.origin); +// Prints https://xn--1xa.example.com
      +
      +

      Util#

      Stability: 2 - Stable

      -

      Source Code: lib/util.js

      +

      Source Code: lib/util.js

      The util module supports the needs of Node.js internal APIs. Many of the utilities are useful for application and module developers as well. To access it:

      const util = require('util');
      -

      util.callbackify(original)#

      +

      util.callbackify(original)#

      @@ -58446,14 +63163,14 @@ first argument will be the rejection reason (or null if the P resolved), and the second argument will be the resolved value.

      const util = require('util');
       
      -async function fn() {
      +async function fn() {
         return 'hello world';
       }
      -const callbackFunction = util.callbackify(fn);
      +const callbackFunction = util.callbackify(fn);
       
      -callbackFunction((err, ret) => {
      +callbackFunction((err, ret) => {
         if (err) throw err;
      -  console.log(ret);
      +  console.log(ret);
       });

      Will print:

      hello world
      @@ -58464,17 +63181,17 @@ event, and if not handled will exit.

      wrapped function rejects a Promise with a falsy value as a reason, the value is wrapped in an Error with the original value stored in a field named reason.

      -
      function fn() {
      -  return Promise.reject(null);
      +
      function fn() {
      +  return Promise.reject(null);
       }
      -const callbackFunction = util.callbackify(fn);
      +const callbackFunction = util.callbackify(fn);
       
      -callbackFunction((err, ret) => {
      +callbackFunction((err, ret) => {
         // When the Promise was rejected with `null` it is wrapped with an Error and
         // the original value is stored in `reason`.
      -  err && err.hasOwnProperty('reason') && err.reason === null;  // true
      +  err && err.hasOwnProperty('reason') && err.reason === null;  // true
       });
      -

      util.debuglog(section[, callback])#

      +

      util.debuglog(section[, callback])#

      @@ -58491,9 +63208,9 @@ environment variable. If the section name appears within the value environment variable, then the returned function operates similar to console.error(). If not, then the returned function is a no-op.

      const util = require('util');
      -const debuglog = util.debuglog('foo');
      +const debuglog = util.debuglog('foo');
       
      -debuglog('hello from foo [%d]', 123);
      +debuglog('hello from foo [%d]', 123);

      If this program is run with NODE_DEBUG=foo in the environment, then it will output something like:

      FOO 3245: hello from foo [123]
      @@ -58501,9 +63218,9 @@ it will output something like:

      environment variable set, then it will not print anything.

      The section supports wildcard also:

      const util = require('util');
      -const debuglog = util.debuglog('foo-bar');
      +const debuglog = util.debuglog('foo-bar');
       
      -debuglog('hi there, it\'s foo-bar [%d]', 2333);
      +debuglog('hi there, it\'s foo-bar [%d]', 2333);

      if it is run with NODE_DEBUG=foo* in the environment, then it will output something like:

      FOO-BAR 3257: hi there, it's foo-bar [2333]
      @@ -58513,12 +63230,38 @@ environment variable: NODE_DEBUG=fs,net,tls.

      with a different function that doesn't have any initialization or unnecessary wrapping.

      const util = require('util');
      -let debuglog = util.debuglog('internals', (debug) => {
      +let debuglog = util.debuglog('internals', (debug) => {
         // Replace with a logging function that optimizes out
         // testing if the section is enabled
         debuglog = debug;
       });
      -

      util.deprecate(fn, msg[, code])#

      +

      debuglog().enabled#

      + + +

      The util.debuglog().enabled getter is used to create a test that can be used +in conditionals based on the existence of the NODE_DEBUG environment variable. +If the section name appears within the value of that environment variable, +then the returned value will be true. If not, then the returned value will be +false.

      +
      const util = require('util');
      +const enabled = util.debuglog('foo').enabled;
      +if (enabled) {
      +  console.log('hello from foo [%d]', 123);
      +}
      +

      If this program is run with NODE_DEBUG=foo in the environment, then it will +output something like:

      +
      hello from foo [123]
      +

      util.debug(section)#

      + +

      Alias for util.debuglog. Usage allows for readability of that doesn't imply +logging when only using util.debuglog().enabled.

      +

      util.deprecate(fn, msg[, code])#

      +

      Stability: 3 - Legacy: Use ES2015 class syntax and extends keyword instead.

      • constructor <Function>
      • superConstructor <Function>
      • @@ -58704,53 +63463,55 @@ prototype of constructor will be set to a new object created from As an additional convenience, superConstructor will be accessible through the constructor.super_ property.

        const util = require('util');
        -const EventEmitter = require('events');
        +const EventEmitter = require('events');
         
        -function MyStream() {
        -  EventEmitter.call(this);
        +function MyStream() {
        +  EventEmitter.call(this);
         }
         
        -util.inherits(MyStream, EventEmitter);
        +util.inherits(MyStream, EventEmitter);
         
        -MyStream.prototype.write = function(data) {
        -  this.emit('data', data);
        +MyStream.prototype.write = function(data) {
        +  this.emit('data', data);
         };
         
        -const stream = new MyStream();
        +const stream = new MyStream();
         
        -console.log(stream instanceof EventEmitter); // true
        -console.log(MyStream.super_ === EventEmitter); // true
        +console.log(stream instanceof EventEmitter); // true
        +console.log(MyStream.super_ === EventEmitter); // true
         
        -stream.on('data', (data) => {
        -  console.log(`Received data: "${data}"`);
        +stream.on('data', (data) => {
        +  console.log(`Received data: "${data}"`);
         });
        -stream.write('It works!'); // Received data: "It works!"
        +stream.write('It works!'); // Received data: "It works!"

        ES6 example using class and extends:

        -
        const EventEmitter = require('events');
        +
        const EventEmitter = require('events');
         
        -class MyStream extends EventEmitter {
        -  write(data) {
        -    this.emit('data', data);
        +class MyStream extends EventEmitter {
        +  write(data) {
        +    this.emit('data', data);
           }
         }
         
        -const stream = new MyStream();
        +const stream = new MyStream();
         
        -stream.on('data', (data) => {
        -  console.log(`Received data: "${data}"`);
        +stream.on('data', (data) => {
        +  console.log(`Received data: "${data}"`);
         });
        -stream.write('With ES6');
        -

        util.inspect(object[, options])#

        -

        util.inspect(object[, showHidden[, depth[, colors]]])#

        +stream.write('With ES6');
        +

      util.inspect(object[, options])#

      +

      util.inspect(object[, showHidden[, depth[, colors]]])#

      vm.createContext([contextObject[, options]])#

      Instances of the worker.MessagePort class represent one end of an asynchronous, two-way communications channel. It can be used to transfer structured data, memory regions and other MessagePorts between different Workers.

      -

      With the exception of MessagePorts being EventEmitters rather -than EventTargets, this implementation matches browser MessagePorts.

      -

      Event: 'close'#

      +

      This implementation matches browser MessagePorts.

      +

      Event: 'close'#

      The 'close' event is emitted once either side of the channel has been disconnected.

      -
      const { MessageChannel } = require('worker_threads');
      -const { port1, port2 } = new MessageChannel();
      +
      const { MessageChannel } = require('worker_threads');
      +const { port1, port2 } = new MessageChannel();
       
       // Prints:
       //   foobar
       //   closed!
      -port2.on('message', (message) => console.log(message));
      -port2.on('close', () => console.log('closed!'));
      +port2.on('message', (message) => console.log(message));
      +port2.on('close', () => console.log('closed!'));
       
      -port1.postMessage('foobar');
      -port1.close();
      -

      Event: 'message'#

      +port1.postMessage('foobar'); +port1.close();
      +

      Event: 'message'#

      @@ -62486,15 +67547,20 @@ port1.close();
      input of port.postMessage().

      Listeners on this event will receive a clone of the value parameter as passed to postMessage() and no further arguments.

      -

      Event: 'messageerror'#

      +

      Event: 'messageerror'#

      The 'messageerror' event is emitted when deserializing a message failed.

      -

      port.close()#

      +

      Currently, this event is emitted when there is an error occurring while +instantiating the posted JS object on the receiving end. Such situations +are rare, but can happen, for instance, when certain Node.js API objects +are received in a vm.Context (where Node.js APIs are currently +unavailable).

      +

      port.close()#

      @@ -62503,14 +67569,18 @@ This method can be called when no further communication will happen over this MessagePort.

      The 'close' event will be emitted on both MessagePort instances that are part of the channel.

      -

      port.postMessage(value[, transferList])#

      +

      port.postMessage(value[, transferList])#

      + diff --git a/doc/api/async_hooks.json b/doc/api/async_hooks.json index e32022b454939746fd6358abe02a09af3607364f..42198c4cb6c060171d1f6d7d6fed25c52ad7640e 100644 --- a/doc/api/async_hooks.json +++ b/doc/api/async_hooks.json @@ -8,7 +8,7 @@ "introduced_in": "v8.1.0", "stability": 1, "stabilityText": "Experimental", - "desc": "

      Source Code: lib/async_hooks.js

      \n

      The async_hooks module provides an API to track asynchronous resources. It\ncan be accessed using:

      \n
      const async_hooks = require('async_hooks');\n
      ", + "desc": "

      Source Code: lib/async_hooks.js

      \n

      The async_hooks module provides an API to track asynchronous resources. It\ncan be accessed using:

      \n
      const async_hooks = require('async_hooks');\n
      ", "modules": [ { "textRaw": "Terminology", @@ -18,363 +18,11 @@ "displayName": "Terminology" }, { - "textRaw": "Public API", - "name": "public_api", - "modules": [ - { - "textRaw": "Overview", - "name": "overview", - "desc": "

      Following is a simple overview of the public API.

      \n
      const async_hooks = require('async_hooks');\n\n// Return the ID of the current execution context.\nconst eid = async_hooks.executionAsyncId();\n\n// Return the ID of the handle responsible for triggering the callback of the\n// current execution scope to call.\nconst tid = async_hooks.triggerAsyncId();\n\n// Create a new AsyncHook instance. All of these callbacks are optional.\nconst asyncHook =\n    async_hooks.createHook({ init, before, after, destroy, promiseResolve });\n\n// Allow callbacks of this AsyncHook instance to call. This is not an implicit\n// action after running the constructor, and must be explicitly run to begin\n// executing callbacks.\nasyncHook.enable();\n\n// Disable listening for new asynchronous events.\nasyncHook.disable();\n\n//\n// The following are the callbacks that can be passed to createHook().\n//\n\n// init is called during object construction. The resource may not have\n// completed construction when this callback runs, therefore all fields of the\n// resource referenced by \"asyncId\" may not have been populated.\nfunction init(asyncId, type, triggerAsyncId, resource) { }\n\n// Before is called just before the resource's callback is called. It can be\n// called 0-N times for handles (e.g. TCPWrap), and will be called exactly 1\n// time for requests (e.g. FSReqCallback).\nfunction before(asyncId) { }\n\n// After is called just after the resource's callback has finished.\nfunction after(asyncId) { }\n\n// Destroy is called when the resource is destroyed.\nfunction destroy(asyncId) { }\n\n// promiseResolve is called only for promise resources, when the\n// `resolve` function passed to the `Promise` constructor is invoked\n// (either directly or through other means of resolving a promise).\nfunction promiseResolve(asyncId) { }\n
      ", - "methods": [ - { - "textRaw": "`async_hooks.createHook(callbacks)`", - "type": "method", - "name": "createHook", - "meta": { - "added": [ - "v8.1.0" - ], - "changes": [] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {AsyncHook} Instance used for disabling and enabling hooks", - "name": "return", - "type": "AsyncHook", - "desc": "Instance used for disabling and enabling hooks" - }, - "params": [ - { - "textRaw": "`callbacks` {Object} The [Hook Callbacks][] to register", - "name": "callbacks", - "type": "Object", - "desc": "The [Hook Callbacks][] to register", - "options": [ - { - "textRaw": "`init` {Function} The [`init` callback][].", - "name": "init", - "type": "Function", - "desc": "The [`init` callback][]." - }, - { - "textRaw": "`before` {Function} The [`before` callback][].", - "name": "before", - "type": "Function", - "desc": "The [`before` callback][]." - }, - { - "textRaw": "`after` {Function} The [`after` callback][].", - "name": "after", - "type": "Function", - "desc": "The [`after` callback][]." - }, - { - "textRaw": "`destroy` {Function} The [`destroy` callback][].", - "name": "destroy", - "type": "Function", - "desc": "The [`destroy` callback][]." - }, - { - "textRaw": "`promiseResolve` {Function} The [`promiseResolve` callback][].", - "name": "promiseResolve", - "type": "Function", - "desc": "The [`promiseResolve` callback][]." - } - ] - } - ] - } - ], - "desc": "

      Registers functions to be called for different lifetime events of each async\noperation.

      \n

      The callbacks init()/before()/after()/destroy() are called for the\nrespective asynchronous event during a resource's lifetime.

      \n

      All callbacks are optional. For example, if only resource cleanup needs to\nbe tracked, then only the destroy callback needs to be passed. The\nspecifics of all functions that can be passed to callbacks is in the\nHook Callbacks section.

      \n
      const async_hooks = require('async_hooks');\n\nconst asyncHook = async_hooks.createHook({\n  init(asyncId, type, triggerAsyncId, resource) { },\n  destroy(asyncId) { }\n});\n
      \n

      The callbacks will be inherited via the prototype chain:

      \n
      class MyAsyncCallbacks {\n  init(asyncId, type, triggerAsyncId, resource) { }\n  destroy(asyncId) {}\n}\n\nclass MyAddedCallbacks extends MyAsyncCallbacks {\n  before(asyncId) { }\n  after(asyncId) { }\n}\n\nconst asyncHook = async_hooks.createHook(new MyAddedCallbacks());\n
      ", - "modules": [ - { - "textRaw": "Error handling", - "name": "error_handling", - "desc": "

      If any AsyncHook callbacks throw, the application will print the stack trace\nand exit. The exit path does follow that of an uncaught exception, but\nall 'uncaughtException' listeners are removed, thus forcing the process to\nexit. The 'exit' callbacks will still be called unless the application is run\nwith --abort-on-uncaught-exception, in which case a stack trace will be\nprinted and the application exits, leaving a core file.

      \n

      The reason for this error handling behavior is that these callbacks are running\nat potentially volatile points in an object's lifetime, for example during\nclass construction and destruction. Because of this, it is deemed necessary to\nbring down the process quickly in order to prevent an unintentional abort in the\nfuture. This is subject to change in the future if a comprehensive analysis is\nperformed to ensure an exception can follow the normal control flow without\nunintentional side effects.

      ", - "type": "module", - "displayName": "Error handling" - }, - { - "textRaw": "Printing in AsyncHooks callbacks", - "name": "printing_in_asynchooks_callbacks", - "desc": "

      Because printing to the console is an asynchronous operation, console.log()\nwill cause the AsyncHooks callbacks to be called. Using console.log() or\nsimilar asynchronous operations inside an AsyncHooks callback function will thus\ncause an infinite recursion. An easy solution to this when debugging is to use a\nsynchronous logging operation such as fs.writeFileSync(file, msg, flag).\nThis will print to the file and will not invoke AsyncHooks recursively because\nit is synchronous.

      \n
      const fs = require('fs');\nconst util = require('util');\n\nfunction debug(...args) {\n  // Use a function like this one when debugging inside an AsyncHooks callback\n  fs.writeFileSync('log.out', `${util.format(...args)}\\n`, { flag: 'a' });\n}\n
      \n

      If an asynchronous operation is needed for logging, it is possible to keep\ntrack of what caused the asynchronous operation using the information\nprovided by AsyncHooks itself. The logging should then be skipped when\nit was the logging itself that caused AsyncHooks callback to call. By\ndoing this the otherwise infinite recursion is broken.

      ", - "type": "module", - "displayName": "Printing in AsyncHooks callbacks" - } - ] - } - ], - "type": "module", - "displayName": "Overview" - } - ], - "classes": [ - { - "textRaw": "Class: `AsyncHook`", - "type": "class", - "name": "AsyncHook", - "desc": "

      The class AsyncHook exposes an interface for tracking lifetime events\nof asynchronous operations.

      ", - "methods": [ - { - "textRaw": "`asyncHook.enable()`", - "type": "method", - "name": "enable", - "signatures": [ - { - "return": { - "textRaw": "Returns: {AsyncHook} A reference to `asyncHook`.", - "name": "return", - "type": "AsyncHook", - "desc": "A reference to `asyncHook`." - }, - "params": [] - } - ], - "desc": "

      Enable the callbacks for a given AsyncHook instance. If no callbacks are\nprovided enabling is a noop.

      \n

      The AsyncHook instance is disabled by default. If the AsyncHook instance\nshould be enabled immediately after creation, the following pattern can be used.

      \n
      const async_hooks = require('async_hooks');\n\nconst hook = async_hooks.createHook(callbacks).enable();\n
      " - }, - { - "textRaw": "`asyncHook.disable()`", - "type": "method", - "name": "disable", - "signatures": [ - { - "return": { - "textRaw": "Returns: {AsyncHook} A reference to `asyncHook`.", - "name": "return", - "type": "AsyncHook", - "desc": "A reference to `asyncHook`." - }, - "params": [] - } - ], - "desc": "

      Disable the callbacks for a given AsyncHook instance from the global pool of\nAsyncHook callbacks to be executed. Once a hook has been disabled it will not\nbe called again until enabled.

      \n

      For API consistency disable() also returns the AsyncHook instance.

      " - }, - { - "textRaw": "`async_hooks.executionAsyncResource()`", - "type": "method", - "name": "executionAsyncResource", - "meta": { - "added": [ - "v12.17.0" - ], - "changes": [] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {Object} The resource representing the current execution. Useful to store data within the resource.", - "name": "return", - "type": "Object", - "desc": "The resource representing the current execution. Useful to store data within the resource." - }, - "params": [] - } - ], - "desc": "

      Resource objects returned by executionAsyncResource() are most often internal\nNode.js handle objects with undocumented APIs. Using any functions or properties\non the object is likely to crash your application and should be avoided.

      \n

      Using executionAsyncResource() in the top-level execution context will\nreturn an empty object as there is no handle or request object to use,\nbut having an object representing the top-level can be helpful.

      \n
      const { open } = require('fs');\nconst { executionAsyncId, executionAsyncResource } = require('async_hooks');\n\nconsole.log(executionAsyncId(), executionAsyncResource());  // 1 {}\nopen(__filename, 'r', (err, fd) => {\n  console.log(executionAsyncId(), executionAsyncResource());  // 7 FSReqWrap\n});\n
      \n

      This can be used to implement continuation local storage without the\nuse of a tracking Map to store the metadata:

      \n
      const { createServer } = require('http');\nconst {\n  executionAsyncId,\n  executionAsyncResource,\n  createHook\n} = require('async_hooks');\nconst sym = Symbol('state'); // Private symbol to avoid pollution\n\ncreateHook({\n  init(asyncId, type, triggerAsyncId, resource) {\n    const cr = executionAsyncResource();\n    if (cr) {\n      resource[sym] = cr[sym];\n    }\n  }\n}).enable();\n\nconst server = createServer((req, res) => {\n  executionAsyncResource()[sym] = { state: req.url };\n  setTimeout(function() {\n    res.end(JSON.stringify(executionAsyncResource()[sym]));\n  }, 100);\n}).listen(3000);\n
      " - }, - { - "textRaw": "`async_hooks.executionAsyncId()`", - "type": "method", - "name": "executionAsyncId", - "meta": { - "added": [ - "v8.1.0" - ], - "changes": [ - { - "version": "v8.2.0", - "pr-url": "https://github.com/nodejs/node/pull/13490", - "description": "Renamed from `currentId`" - } - ] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {number} The `asyncId` of the current execution context. Useful to track when something calls.", - "name": "return", - "type": "number", - "desc": "The `asyncId` of the current execution context. Useful to track when something calls." - }, - "params": [] - } - ], - "desc": "
      const async_hooks = require('async_hooks');\n\nconsole.log(async_hooks.executionAsyncId());  // 1 - bootstrap\nfs.open(path, 'r', (err, fd) => {\n  console.log(async_hooks.executionAsyncId());  // 6 - open()\n});\n
      \n

      The ID returned from executionAsyncId() is related to execution timing, not\ncausality (which is covered by triggerAsyncId()):

      \n
      const server = net.createServer((conn) => {\n  // Returns the ID of the server, not of the new connection, because the\n  // callback runs in the execution scope of the server's MakeCallback().\n  async_hooks.executionAsyncId();\n\n}).listen(port, () => {\n  // Returns the ID of a TickObject (i.e. process.nextTick()) because all\n  // callbacks passed to .listen() are wrapped in a nextTick().\n  async_hooks.executionAsyncId();\n});\n
      \n

      Promise contexts may not get precise executionAsyncIds by default.\nSee the section on promise execution tracking.

      " - }, - { - "textRaw": "`async_hooks.triggerAsyncId()`", - "type": "method", - "name": "triggerAsyncId", - "signatures": [ - { - "return": { - "textRaw": "Returns: {number} The ID of the resource responsible for calling the callback that is currently being executed.", - "name": "return", - "type": "number", - "desc": "The ID of the resource responsible for calling the callback that is currently being executed." - }, - "params": [] - } - ], - "desc": "
      const server = net.createServer((conn) => {\n  // The resource that caused (or triggered) this callback to be called\n  // was that of the new connection. Thus the return value of triggerAsyncId()\n  // is the asyncId of \"conn\".\n  async_hooks.triggerAsyncId();\n\n}).listen(port, () => {\n  // Even though all callbacks passed to .listen() are wrapped in a nextTick()\n  // the callback itself exists because the call to the server's .listen()\n  // was made. So the return value would be the ID of the server.\n  async_hooks.triggerAsyncId();\n});\n
      \n

      Promise contexts may not get valid triggerAsyncIds by default. See\nthe section on promise execution tracking.

      " - } - ], - "modules": [ - { - "textRaw": "Hook callbacks", - "name": "hook_callbacks", - "desc": "

      Key events in the lifetime of asynchronous events have been categorized into\nfour areas: instantiation, before/after the callback is called, and when the\ninstance is destroyed.

      ", - "methods": [ - { - "textRaw": "`init(asyncId, type, triggerAsyncId, resource)`", - "type": "method", - "name": "init", - "signatures": [ - { - "params": [ - { - "textRaw": "`asyncId` {number} A unique ID for the async resource.", - "name": "asyncId", - "type": "number", - "desc": "A unique ID for the async resource." - }, - { - "textRaw": "`type` {string} The type of the async resource.", - "name": "type", - "type": "string", - "desc": "The type of the async resource." - }, - { - "textRaw": "`triggerAsyncId` {number} The unique ID of the async resource in whose execution context this async resource was created.", - "name": "triggerAsyncId", - "type": "number", - "desc": "The unique ID of the async resource in whose execution context this async resource was created." - }, - { - "textRaw": "`resource` {Object} Reference to the resource representing the async operation, needs to be released during _destroy_.", - "name": "resource", - "type": "Object", - "desc": "Reference to the resource representing the async operation, needs to be released during _destroy_." - } - ] - } - ], - "desc": "

      Called when a class is constructed that has the possibility to emit an\nasynchronous event. This does not mean the instance must call\nbefore/after before destroy is called, only that the possibility\nexists.

      \n

      This behavior can be observed by doing something like opening a resource then\nclosing it before the resource can be used. The following snippet demonstrates\nthis.

      \n
      require('net').createServer().listen(function() { this.close(); });\n// OR\nclearTimeout(setTimeout(() => {}, 10));\n
      \n

      Every new resource is assigned an ID that is unique within the scope of the\ncurrent Node.js instance.

      ", - "modules": [ - { - "textRaw": "`type`", - "name": "`type`", - "desc": "

      The type is a string identifying the type of resource that caused\ninit to be called. Generally, it will correspond to the name of the\nresource's constructor.

      \n
      FSEVENTWRAP, FSREQCALLBACK, GETADDRINFOREQWRAP, GETNAMEINFOREQWRAP, HTTPINCOMINGMESSAGE,\nHTTPCLIENTREQUEST, JSSTREAM, PIPECONNECTWRAP, PIPEWRAP, PROCESSWRAP, QUERYWRAP,\nSHUTDOWNWRAP, SIGNALWRAP, STATWATCHER, TCPCONNECTWRAP, TCPSERVERWRAP, TCPWRAP,\nTTYWRAP, UDPSENDWRAP, UDPWRAP, WRITEWRAP, ZLIB, SSLCONNECTION, PBKDF2REQUEST,\nRANDOMBYTESREQUEST, TLSWRAP, Microtask, Timeout, Immediate, TickObject\n
      \n

      There is also the PROMISE resource type, which is used to track Promise\ninstances and asynchronous work scheduled by them.

      \n

      Users are able to define their own type when using the public embedder API.

      \n

      It is possible to have type name collisions. Embedders are encouraged to use\nunique prefixes, such as the npm package name, to prevent collisions when\nlistening to the hooks.

      ", - "type": "module", - "displayName": "`type`" - }, - { - "textRaw": "`triggerAsyncId`", - "name": "`triggerasyncid`", - "desc": "

      triggerAsyncId is the asyncId of the resource that caused (or \"triggered\")\nthe new resource to initialize and that caused init to call. This is different\nfrom async_hooks.executionAsyncId() that only shows when a resource was\ncreated, while triggerAsyncId shows why a resource was created.

      \n

      The following is a simple demonstration of triggerAsyncId:

      \n
      async_hooks.createHook({\n  init(asyncId, type, triggerAsyncId) {\n    const eid = async_hooks.executionAsyncId();\n    fs.writeSync(\n      process.stdout.fd,\n      `${type}(${asyncId}): trigger: ${triggerAsyncId} execution: ${eid}\\n`);\n  }\n}).enable();\n\nrequire('net').createServer((conn) => {}).listen(8080);\n
      \n

      Output when hitting the server with nc localhost 8080:

      \n
      TCPSERVERWRAP(5): trigger: 1 execution: 1\nTCPWRAP(7): trigger: 5 execution: 0\n
      \n

      The TCPSERVERWRAP is the server which receives the connections.

      \n

      The TCPWRAP is the new connection from the client. When a new\nconnection is made, the TCPWrap instance is immediately constructed. This\nhappens outside of any JavaScript stack. (An executionAsyncId() of 0 means\nthat it is being executed from C++ with no JavaScript stack above it.) With only\nthat information, it would be impossible to link resources together in\nterms of what caused them to be created, so triggerAsyncId is given the task\nof propagating what resource is responsible for the new resource's existence.

      ", - "type": "module", - "displayName": "`triggerAsyncId`" - }, - { - "textRaw": "`resource`", - "name": "`resource`", - "desc": "

      resource is an object that represents the actual async resource that has\nbeen initialized. This can contain useful information that can vary based on\nthe value of type. For instance, for the GETADDRINFOREQWRAP resource type,\nresource provides the host name used when looking up the IP address for the\nhost in net.Server.listen(). The API for accessing this information is\nnot supported, but using the Embedder API, users can provide\nand document their own resource objects. For example, such a resource object\ncould contain the SQL query being executed.

      \n

      In the case of Promises, the resource object will have an\nisChainedPromise property, set to true if the promise has a parent promise,\nand false otherwise. For example, in the case of b = a.then(handler), a is\nconsidered a parent Promise of b. Here, b is considered a chained promise.

      \n

      In some cases the resource object is reused for performance reasons, it is\nthus not safe to use it as a key in a WeakMap or add properties to it.

      ", - "type": "module", - "displayName": "`resource`" - }, - { - "textRaw": "Asynchronous context example", - "name": "asynchronous_context_example", - "desc": "

      The following is an example with additional information about the calls to\ninit between the before and after calls, specifically what the\ncallback to listen() will look like. The output formatting is slightly more\nelaborate to make calling context easier to see.

      \n
      let indent = 0;\nasync_hooks.createHook({\n  init(asyncId, type, triggerAsyncId) {\n    const eid = async_hooks.executionAsyncId();\n    const indentStr = ' '.repeat(indent);\n    fs.writeSync(\n      process.stdout.fd,\n      `${indentStr}${type}(${asyncId}):` +\n      ` trigger: ${triggerAsyncId} execution: ${eid}\\n`);\n  },\n  before(asyncId) {\n    const indentStr = ' '.repeat(indent);\n    fs.writeSync(process.stdout.fd, `${indentStr}before:  ${asyncId}\\n`);\n    indent += 2;\n  },\n  after(asyncId) {\n    indent -= 2;\n    const indentStr = ' '.repeat(indent);\n    fs.writeSync(process.stdout.fd, `${indentStr}after:  ${asyncId}\\n`);\n  },\n  destroy(asyncId) {\n    const indentStr = ' '.repeat(indent);\n    fs.writeSync(process.stdout.fd, `${indentStr}destroy:  ${asyncId}\\n`);\n  },\n}).enable();\n\nrequire('net').createServer(() => {}).listen(8080, () => {\n  // Let's wait 10ms before logging the server started.\n  setTimeout(() => {\n    console.log('>>>', async_hooks.executionAsyncId());\n  }, 10);\n});\n
      \n

      Output from only starting the server:

      \n
      TCPSERVERWRAP(5): trigger: 1 execution: 1\nTickObject(6): trigger: 5 execution: 1\nbefore:  6\n  Timeout(7): trigger: 6 execution: 6\nafter:   6\ndestroy: 6\nbefore:  7\n>>> 7\n  TickObject(8): trigger: 7 execution: 7\nafter:   7\nbefore:  8\nafter:   8\n
      \n

      As illustrated in the example, executionAsyncId() and execution each specify\nthe value of the current execution context; which is delineated by calls to\nbefore and after.

      \n

      Only using execution to graph resource allocation results in the following:

      \n
        root(1)\n     ^\n     |\nTickObject(6)\n     ^\n     |\n Timeout(7)\n
      \n

      The TCPSERVERWRAP is not part of this graph, even though it was the reason for\nconsole.log() being called. This is because binding to a port without a host\nname is a synchronous operation, but to maintain a completely asynchronous\nAPI the user's callback is placed in a process.nextTick(). Which is why\nTickObject is present in the output and is a 'parent' for .listen()\ncallback.

      \n

      The graph only shows when a resource was created, not why, so to track\nthe why use triggerAsyncId. Which can be represented with the following\ngraph:

      \n
       bootstrap(1)\n     |\n     ˅\nTCPSERVERWRAP(5)\n     |\n     ˅\n TickObject(6)\n     |\n     ˅\n  Timeout(7)\n
      ", - "type": "module", - "displayName": "Asynchronous context example" - } - ] - }, - { - "textRaw": "`before(asyncId)`", - "type": "method", - "name": "before", - "signatures": [ - { - "params": [ - { - "textRaw": "`asyncId` {number}", - "name": "asyncId", - "type": "number" - } - ] - } - ], - "desc": "

      When an asynchronous operation is initiated (such as a TCP server receiving a\nnew connection) or completes (such as writing data to disk) a callback is\ncalled to notify the user. The before callback is called just before said\ncallback is executed. asyncId is the unique identifier assigned to the\nresource about to execute the callback.

      \n

      The before callback will be called 0 to N times. The before callback\nwill typically be called 0 times if the asynchronous operation was cancelled\nor, for example, if no connections are received by a TCP server. Persistent\nasynchronous resources like a TCP server will typically call the before\ncallback multiple times, while other operations like fs.open() will call\nit only once.

      " - }, - { - "textRaw": "`after(asyncId)`", - "type": "method", - "name": "after", - "signatures": [ - { - "params": [ - { - "textRaw": "`asyncId` {number}", - "name": "asyncId", - "type": "number" - } - ] - } - ], - "desc": "

      Called immediately after the callback specified in before is completed.

      \n

      If an uncaught exception occurs during execution of the callback, then after\nwill run after the 'uncaughtException' event is emitted or a domain's\nhandler runs.

      " - }, - { - "textRaw": "`destroy(asyncId)`", - "type": "method", - "name": "destroy", - "signatures": [ - { - "params": [ - { - "textRaw": "`asyncId` {number}", - "name": "asyncId", - "type": "number" - } - ] - } - ], - "desc": "

      Called after the resource corresponding to asyncId is destroyed. It is also\ncalled asynchronously from the embedder API emitDestroy().

      \n

      Some resources depend on garbage collection for cleanup, so if a reference is\nmade to the resource object passed to init it is possible that destroy\nwill never be called, causing a memory leak in the application. If the resource\ndoes not depend on garbage collection, then this will not be an issue.

      " - }, - { - "textRaw": "`promiseResolve(asyncId)`", - "type": "method", - "name": "promiseResolve", - "meta": { - "added": [ - "v8.6.0" - ], - "changes": [] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`asyncId` {number}", - "name": "asyncId", - "type": "number" - } - ] - } - ], - "desc": "

      Called when the resolve function passed to the Promise constructor is\ninvoked (either directly or through other means of resolving a promise).

      \n

      resolve() does not do any observable synchronous work.

      \n

      The Promise is not necessarily fulfilled or rejected at this point if the\nPromise was resolved by assuming the state of another Promise.

      \n
      new Promise((resolve) => resolve(true)).then((a) => {});\n
      \n

      calls the following callbacks:

      \n
      init for PROMISE with id 5, trigger id: 1\n  promise resolve 5      # corresponds to resolve(true)\ninit for PROMISE with id 6, trigger id: 5  # the Promise returned by then()\n  before 6               # the then() callback is entered\n  promise resolve 6      # the then() callback resolves the promise by returning\n  after 6\n
      " - } - ], - "type": "module", - "displayName": "Hook callbacks" - } - ] - } - ], + "textRaw": "Overview", + "name": "overview", + "desc": "

      Following is a simple overview of the public API.

      \n
      const async_hooks = require('async_hooks');\n\n// Return the ID of the current execution context.\nconst eid = async_hooks.executionAsyncId();\n\n// Return the ID of the handle responsible for triggering the callback of the\n// current execution scope to call.\nconst tid = async_hooks.triggerAsyncId();\n\n// Create a new AsyncHook instance. All of these callbacks are optional.\nconst asyncHook =\n    async_hooks.createHook({ init, before, after, destroy, promiseResolve });\n\n// Allow callbacks of this AsyncHook instance to call. This is not an implicit\n// action after running the constructor, and must be explicitly run to begin\n// executing callbacks.\nasyncHook.enable();\n\n// Disable listening for new asynchronous events.\nasyncHook.disable();\n\n//\n// The following are the callbacks that can be passed to createHook().\n//\n\n// init is called during object construction. The resource may not have\n// completed construction when this callback runs, therefore all fields of the\n// resource referenced by \"asyncId\" may not have been populated.\nfunction init(asyncId, type, triggerAsyncId, resource) { }\n\n// Before is called just before the resource's callback is called. It can be\n// called 0-N times for handles (such as TCPWrap), and will be called exactly 1\n// time for requests (such as FSReqCallback).\nfunction before(asyncId) { }\n\n// After is called just after the resource's callback has finished.\nfunction after(asyncId) { }\n\n// Destroy is called when the resource is destroyed.\nfunction destroy(asyncId) { }\n\n// promiseResolve is called only for promise resources, when the\n// `resolve` function passed to the `Promise` constructor is invoked\n// (either directly or through other means of resolving a promise).\nfunction promiseResolve(asyncId) { }\n
      ", "type": "module", - "displayName": "Public API" + "displayName": "Overview" }, { "textRaw": "Promise execution tracking", @@ -400,7 +48,7 @@ "name": "bind", "meta": { "added": [ - "v12.19.0" + "v14.8.0" ], "changes": [] }, @@ -432,7 +80,7 @@ "name": "bind", "meta": { "added": [ - "v12.19.0" + "v14.8.0" ], "changes": [] }, @@ -577,7 +225,7 @@ { "textRaw": "Using `AsyncResource` for a `Worker` thread pool", "name": "using_`asyncresource`_for_a_`worker`_thread_pool", - "desc": "

      The following example shows how to use the AsyncResource class to properly\nprovide async tracking for a Worker pool. Other resource pools, such as\ndatabase connection pools, can follow a similar model.

      \n

      Assuming that the task is adding two numbers, using a file named\ntask_processor.js with the following content:

      \n
      const { parentPort } = require('worker_threads');\nparentPort.on('message', (task) => {\n  parentPort.postMessage(task.a + task.b);\n});\n
      \n

      a Worker pool around it could use the following structure:

      \n
      const { AsyncResource } = require('async_hooks');\nconst { EventEmitter } = require('events');\nconst path = require('path');\nconst { Worker } = require('worker_threads');\n\nconst kTaskInfo = Symbol('kTaskInfo');\nconst kWorkerFreedEvent = Symbol('kWorkerFreedEvent');\n\nclass WorkerPoolTaskInfo extends AsyncResource {\n  constructor(callback) {\n    super('WorkerPoolTaskInfo');\n    this.callback = callback;\n  }\n\n  done(err, result) {\n    this.runInAsyncScope(this.callback, null, err, result);\n    this.emitDestroy();  // `TaskInfo`s are used only once.\n  }\n}\n\nclass WorkerPool extends EventEmitter {\n  constructor(numThreads) {\n    super();\n    this.numThreads = numThreads;\n    this.workers = [];\n    this.freeWorkers = [];\n\n    for (let i = 0; i < numThreads; i++)\n      this.addNewWorker();\n  }\n\n  addNewWorker() {\n    const worker = new Worker(path.resolve(__dirname, 'task_processor.js'));\n    worker.on('message', (result) => {\n      // In case of success: Call the callback that was passed to `runTask`,\n      // remove the `TaskInfo` associated with the Worker, and mark it as free\n      // again.\n      worker[kTaskInfo].done(null, result);\n      worker[kTaskInfo] = null;\n      this.freeWorkers.push(worker);\n      this.emit(kWorkerFreedEvent);\n    });\n    worker.on('error', (err) => {\n      // In case of an uncaught exception: Call the callback that was passed to\n      // `runTask` with the error.\n      if (worker[kTaskInfo])\n        worker[kTaskInfo].done(err, null);\n      else\n        this.emit('error', err);\n      // Remove the worker from the list and start a new Worker to replace the\n      // current one.\n      this.workers.splice(this.workers.indexOf(worker), 1);\n      this.addNewWorker();\n    });\n    this.workers.push(worker);\n    this.freeWorkers.push(worker);\n    this.emit(kWorkerFreedEvent);\n  }\n\n  runTask(task, callback) {\n    if (this.freeWorkers.length === 0) {\n      // No free threads, wait until a worker thread becomes free.\n      this.once(kWorkerFreedEvent, () => this.runTask(task, callback));\n      return;\n    }\n\n    const worker = this.freeWorkers.pop();\n    worker[kTaskInfo] = new WorkerPoolTaskInfo(callback);\n    worker.postMessage(task);\n  }\n\n  close() {\n    for (const worker of this.workers) worker.terminate();\n  }\n}\n\nmodule.exports = WorkerPool;\n
      \n

      Without the explicit tracking added by the WorkerPoolTaskInfo objects,\nit would appear that the callbacks are associated with the individual Worker\nobjects. However, the creation of the Workers is not associated with the\ncreation of the tasks and does not provide information about when tasks\nwere scheduled.

      \n

      This pool could be used as follows:

      \n
      const WorkerPool = require('./worker_pool.js');\nconst os = require('os');\n\nconst pool = new WorkerPool(os.cpus().length);\n\nlet finished = 0;\nfor (let i = 0; i < 10; i++) {\n  pool.runTask({ a: 42, b: 100 }, (err, result) => {\n    console.log(i, err, result);\n    if (++finished === 10)\n      pool.close();\n  });\n}\n
      ", + "desc": "

      The following example shows how to use the AsyncResource class to properly\nprovide async tracking for a Worker pool. Other resource pools, such as\ndatabase connection pools, can follow a similar model.

      \n

      Assuming that the task is adding two numbers, using a file named\ntask_processor.js with the following content:

      \n
      const { parentPort } = require('worker_threads');\nparentPort.on('message', (task) => {\n  parentPort.postMessage(task.a + task.b);\n});\n
      \n

      a Worker pool around it could use the following structure:

      \n
      const { AsyncResource } = require('async_hooks');\nconst { EventEmitter } = require('events');\nconst path = require('path');\nconst { Worker } = require('worker_threads');\n\nconst kTaskInfo = Symbol('kTaskInfo');\nconst kWorkerFreedEvent = Symbol('kWorkerFreedEvent');\n\nclass WorkerPoolTaskInfo extends AsyncResource {\n  constructor(callback) {\n    super('WorkerPoolTaskInfo');\n    this.callback = callback;\n  }\n\n  done(err, result) {\n    this.runInAsyncScope(this.callback, null, err, result);\n    this.emitDestroy();  // `TaskInfo`s are used only once.\n  }\n}\n\nclass WorkerPool extends EventEmitter {\n  constructor(numThreads) {\n    super();\n    this.numThreads = numThreads;\n    this.workers = [];\n    this.freeWorkers = [];\n    this.tasks = [];\n\n    for (let i = 0; i < numThreads; i++)\n      this.addNewWorker();\n\n    // Any time the kWorkerFreedEvent is emitted, dispatch\n    // the next task pending in the queue, if any.\n    this.on(kWorkerFreedEvent, () => {\n      if (this.tasks.length > 0) {\n        const { task, callback } = this.tasks.shift();\n        this.runTask(task, callback);\n      }\n    });\n  }\n\n  addNewWorker() {\n    const worker = new Worker(path.resolve(__dirname, 'task_processor.js'));\n    worker.on('message', (result) => {\n      // In case of success: Call the callback that was passed to `runTask`,\n      // remove the `TaskInfo` associated with the Worker, and mark it as free\n      // again.\n      worker[kTaskInfo].done(null, result);\n      worker[kTaskInfo] = null;\n      this.freeWorkers.push(worker);\n      this.emit(kWorkerFreedEvent);\n    });\n    worker.on('error', (err) => {\n      // In case of an uncaught exception: Call the callback that was passed to\n      // `runTask` with the error.\n      if (worker[kTaskInfo])\n        worker[kTaskInfo].done(err, null);\n      else\n        this.emit('error', err);\n      // Remove the worker from the list and start a new Worker to replace the\n      // current one.\n      this.workers.splice(this.workers.indexOf(worker), 1);\n      this.addNewWorker();\n    });\n    this.workers.push(worker);\n    this.freeWorkers.push(worker);\n    this.emit(kWorkerFreedEvent);\n  }\n\n  runTask(task, callback) {\n    if (this.freeWorkers.length === 0) {\n      // No free threads, wait until a worker thread becomes free.\n      this.tasks.push({ task, callback });\n      return;\n    }\n\n    const worker = this.freeWorkers.pop();\n    worker[kTaskInfo] = new WorkerPoolTaskInfo(callback);\n    worker.postMessage(task);\n  }\n\n  close() {\n    for (const worker of this.workers) worker.terminate();\n  }\n}\n\nmodule.exports = WorkerPool;\n
      \n

      Without the explicit tracking added by the WorkerPoolTaskInfo objects,\nit would appear that the callbacks are associated with the individual Worker\nobjects. However, the creation of the Workers is not associated with the\ncreation of the tasks and does not provide information about when tasks\nwere scheduled.

      \n

      This pool could be used as follows:

      \n
      const WorkerPool = require('./worker_pool.js');\nconst os = require('os');\n\nconst pool = new WorkerPool(os.cpus().length);\n\nlet finished = 0;\nfor (let i = 0; i < 10; i++) {\n  pool.runTask({ a: 42, b: 100 }, (err, result) => {\n    console.log(i, err, result);\n    if (++finished === 10)\n      pool.close();\n  });\n}\n
      ", "type": "module", "displayName": "Using `AsyncResource` for a `Worker` thread pool" }, @@ -593,18 +241,360 @@ "displayName": "JavaScript embedder API" } ], + "methods": [ + { + "textRaw": "`async_hooks.createHook(callbacks)`", + "type": "method", + "name": "createHook", + "meta": { + "added": [ + "v8.1.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {AsyncHook} Instance used for disabling and enabling hooks", + "name": "return", + "type": "AsyncHook", + "desc": "Instance used for disabling and enabling hooks" + }, + "params": [ + { + "textRaw": "`callbacks` {Object} The [Hook Callbacks][] to register", + "name": "callbacks", + "type": "Object", + "desc": "The [Hook Callbacks][] to register", + "options": [ + { + "textRaw": "`init` {Function} The [`init` callback][].", + "name": "init", + "type": "Function", + "desc": "The [`init` callback][]." + }, + { + "textRaw": "`before` {Function} The [`before` callback][].", + "name": "before", + "type": "Function", + "desc": "The [`before` callback][]." + }, + { + "textRaw": "`after` {Function} The [`after` callback][].", + "name": "after", + "type": "Function", + "desc": "The [`after` callback][]." + }, + { + "textRaw": "`destroy` {Function} The [`destroy` callback][].", + "name": "destroy", + "type": "Function", + "desc": "The [`destroy` callback][]." + }, + { + "textRaw": "`promiseResolve` {Function} The [`promiseResolve` callback][].", + "name": "promiseResolve", + "type": "Function", + "desc": "The [`promiseResolve` callback][]." + } + ] + } + ] + } + ], + "desc": "

      Registers functions to be called for different lifetime events of each async\noperation.

      \n

      The callbacks init()/before()/after()/destroy() are called for the\nrespective asynchronous event during a resource's lifetime.

      \n

      All callbacks are optional. For example, if only resource cleanup needs to\nbe tracked, then only the destroy callback needs to be passed. The\nspecifics of all functions that can be passed to callbacks is in the\nHook Callbacks section.

      \n
      const async_hooks = require('async_hooks');\n\nconst asyncHook = async_hooks.createHook({\n  init(asyncId, type, triggerAsyncId, resource) { },\n  destroy(asyncId) { }\n});\n
      \n

      The callbacks will be inherited via the prototype chain:

      \n
      class MyAsyncCallbacks {\n  init(asyncId, type, triggerAsyncId, resource) { }\n  destroy(asyncId) {}\n}\n\nclass MyAddedCallbacks extends MyAsyncCallbacks {\n  before(asyncId) { }\n  after(asyncId) { }\n}\n\nconst asyncHook = async_hooks.createHook(new MyAddedCallbacks());\n
      \n

      Because promises are asynchronous resources whose lifecycle is tracked\nvia the async hooks mechanism, the init(), before(), after(), and\ndestroy() callbacks must not be async functions that return promises.

      ", + "modules": [ + { + "textRaw": "Error handling", + "name": "error_handling", + "desc": "

      If any AsyncHook callbacks throw, the application will print the stack trace\nand exit. The exit path does follow that of an uncaught exception, but\nall 'uncaughtException' listeners are removed, thus forcing the process to\nexit. The 'exit' callbacks will still be called unless the application is run\nwith --abort-on-uncaught-exception, in which case a stack trace will be\nprinted and the application exits, leaving a core file.

      \n

      The reason for this error handling behavior is that these callbacks are running\nat potentially volatile points in an object's lifetime, for example during\nclass construction and destruction. Because of this, it is deemed necessary to\nbring down the process quickly in order to prevent an unintentional abort in the\nfuture. This is subject to change in the future if a comprehensive analysis is\nperformed to ensure an exception can follow the normal control flow without\nunintentional side effects.

      ", + "type": "module", + "displayName": "Error handling" + }, + { + "textRaw": "Printing in AsyncHooks callbacks", + "name": "printing_in_asynchooks_callbacks", + "desc": "

      Because printing to the console is an asynchronous operation, console.log()\nwill cause the AsyncHooks callbacks to be called. Using console.log() or\nsimilar asynchronous operations inside an AsyncHooks callback function will thus\ncause an infinite recursion. An easy solution to this when debugging is to use a\nsynchronous logging operation such as fs.writeFileSync(file, msg, flag).\nThis will print to the file and will not invoke AsyncHooks recursively because\nit is synchronous.

      \n
      const fs = require('fs');\nconst util = require('util');\n\nfunction debug(...args) {\n  // Use a function like this one when debugging inside an AsyncHooks callback\n  fs.writeFileSync('log.out', `${util.format(...args)}\\n`, { flag: 'a' });\n}\n
      \n

      If an asynchronous operation is needed for logging, it is possible to keep\ntrack of what caused the asynchronous operation using the information\nprovided by AsyncHooks itself. The logging should then be skipped when\nit was the logging itself that caused AsyncHooks callback to call. By\ndoing this the otherwise infinite recursion is broken.

      ", + "type": "module", + "displayName": "Printing in AsyncHooks callbacks" + } + ] + } + ], "classes": [ + { + "textRaw": "Class: `AsyncHook`", + "type": "class", + "name": "AsyncHook", + "desc": "

      The class AsyncHook exposes an interface for tracking lifetime events\nof asynchronous operations.

      ", + "methods": [ + { + "textRaw": "`asyncHook.enable()`", + "type": "method", + "name": "enable", + "signatures": [ + { + "return": { + "textRaw": "Returns: {AsyncHook} A reference to `asyncHook`.", + "name": "return", + "type": "AsyncHook", + "desc": "A reference to `asyncHook`." + }, + "params": [] + } + ], + "desc": "

      Enable the callbacks for a given AsyncHook instance. If no callbacks are\nprovided, enabling is a no-op.

      \n

      The AsyncHook instance is disabled by default. If the AsyncHook instance\nshould be enabled immediately after creation, the following pattern can be used.

      \n
      const async_hooks = require('async_hooks');\n\nconst hook = async_hooks.createHook(callbacks).enable();\n
      " + }, + { + "textRaw": "`asyncHook.disable()`", + "type": "method", + "name": "disable", + "signatures": [ + { + "return": { + "textRaw": "Returns: {AsyncHook} A reference to `asyncHook`.", + "name": "return", + "type": "AsyncHook", + "desc": "A reference to `asyncHook`." + }, + "params": [] + } + ], + "desc": "

      Disable the callbacks for a given AsyncHook instance from the global pool of\nAsyncHook callbacks to be executed. Once a hook has been disabled it will not\nbe called again until enabled.

      \n

      For API consistency disable() also returns the AsyncHook instance.

      " + }, + { + "textRaw": "`async_hooks.executionAsyncResource()`", + "type": "method", + "name": "executionAsyncResource", + "meta": { + "added": [ + "v13.9.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {Object} The resource representing the current execution. Useful to store data within the resource.", + "name": "return", + "type": "Object", + "desc": "The resource representing the current execution. Useful to store data within the resource." + }, + "params": [] + } + ], + "desc": "

      Resource objects returned by executionAsyncResource() are most often internal\nNode.js handle objects with undocumented APIs. Using any functions or properties\non the object is likely to crash your application and should be avoided.

      \n

      Using executionAsyncResource() in the top-level execution context will\nreturn an empty object as there is no handle or request object to use,\nbut having an object representing the top-level can be helpful.

      \n
      const { open } = require('fs');\nconst { executionAsyncId, executionAsyncResource } = require('async_hooks');\n\nconsole.log(executionAsyncId(), executionAsyncResource());  // 1 {}\nopen(__filename, 'r', (err, fd) => {\n  console.log(executionAsyncId(), executionAsyncResource());  // 7 FSReqWrap\n});\n
      \n

      This can be used to implement continuation local storage without the\nuse of a tracking Map to store the metadata:

      \n
      const { createServer } = require('http');\nconst {\n  executionAsyncId,\n  executionAsyncResource,\n  createHook\n} = require('async_hooks');\nconst sym = Symbol('state'); // Private symbol to avoid pollution\n\ncreateHook({\n  init(asyncId, type, triggerAsyncId, resource) {\n    const cr = executionAsyncResource();\n    if (cr) {\n      resource[sym] = cr[sym];\n    }\n  }\n}).enable();\n\nconst server = createServer((req, res) => {\n  executionAsyncResource()[sym] = { state: req.url };\n  setTimeout(function() {\n    res.end(JSON.stringify(executionAsyncResource()[sym]));\n  }, 100);\n}).listen(3000);\n
      " + }, + { + "textRaw": "`async_hooks.executionAsyncId()`", + "type": "method", + "name": "executionAsyncId", + "meta": { + "added": [ + "v8.1.0" + ], + "changes": [ + { + "version": "v8.2.0", + "pr-url": "https://github.com/nodejs/node/pull/13490", + "description": "Renamed from `currentId`." + } + ] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {number} The `asyncId` of the current execution context. Useful to track when something calls.", + "name": "return", + "type": "number", + "desc": "The `asyncId` of the current execution context. Useful to track when something calls." + }, + "params": [] + } + ], + "desc": "
      const async_hooks = require('async_hooks');\n\nconsole.log(async_hooks.executionAsyncId());  // 1 - bootstrap\nfs.open(path, 'r', (err, fd) => {\n  console.log(async_hooks.executionAsyncId());  // 6 - open()\n});\n
      \n

      The ID returned from executionAsyncId() is related to execution timing, not\ncausality (which is covered by triggerAsyncId()):

      \n
      const server = net.createServer((conn) => {\n  // Returns the ID of the server, not of the new connection, because the\n  // callback runs in the execution scope of the server's MakeCallback().\n  async_hooks.executionAsyncId();\n\n}).listen(port, () => {\n  // Returns the ID of a TickObject (process.nextTick()) because all\n  // callbacks passed to .listen() are wrapped in a nextTick().\n  async_hooks.executionAsyncId();\n});\n
      \n

      Promise contexts may not get precise executionAsyncIds by default.\nSee the section on promise execution tracking.

      " + }, + { + "textRaw": "`async_hooks.triggerAsyncId()`", + "type": "method", + "name": "triggerAsyncId", + "signatures": [ + { + "return": { + "textRaw": "Returns: {number} The ID of the resource responsible for calling the callback that is currently being executed.", + "name": "return", + "type": "number", + "desc": "The ID of the resource responsible for calling the callback that is currently being executed." + }, + "params": [] + } + ], + "desc": "
      const server = net.createServer((conn) => {\n  // The resource that caused (or triggered) this callback to be called\n  // was that of the new connection. Thus the return value of triggerAsyncId()\n  // is the asyncId of \"conn\".\n  async_hooks.triggerAsyncId();\n\n}).listen(port, () => {\n  // Even though all callbacks passed to .listen() are wrapped in a nextTick()\n  // the callback itself exists because the call to the server's .listen()\n  // was made. So the return value would be the ID of the server.\n  async_hooks.triggerAsyncId();\n});\n
      \n

      Promise contexts may not get valid triggerAsyncIds by default. See\nthe section on promise execution tracking.

      " + } + ], + "modules": [ + { + "textRaw": "Hook callbacks", + "name": "hook_callbacks", + "desc": "

      Key events in the lifetime of asynchronous events have been categorized into\nfour areas: instantiation, before/after the callback is called, and when the\ninstance is destroyed.

      ", + "methods": [ + { + "textRaw": "`init(asyncId, type, triggerAsyncId, resource)`", + "type": "method", + "name": "init", + "signatures": [ + { + "params": [ + { + "textRaw": "`asyncId` {number} A unique ID for the async resource.", + "name": "asyncId", + "type": "number", + "desc": "A unique ID for the async resource." + }, + { + "textRaw": "`type` {string} The type of the async resource.", + "name": "type", + "type": "string", + "desc": "The type of the async resource." + }, + { + "textRaw": "`triggerAsyncId` {number} The unique ID of the async resource in whose execution context this async resource was created.", + "name": "triggerAsyncId", + "type": "number", + "desc": "The unique ID of the async resource in whose execution context this async resource was created." + }, + { + "textRaw": "`resource` {Object} Reference to the resource representing the async operation, needs to be released during _destroy_.", + "name": "resource", + "type": "Object", + "desc": "Reference to the resource representing the async operation, needs to be released during _destroy_." + } + ] + } + ], + "desc": "

      Called when a class is constructed that has the possibility to emit an\nasynchronous event. This does not mean the instance must call\nbefore/after before destroy is called, only that the possibility\nexists.

      \n

      This behavior can be observed by doing something like opening a resource then\nclosing it before the resource can be used. The following snippet demonstrates\nthis.

      \n
      require('net').createServer().listen(function() { this.close(); });\n// OR\nclearTimeout(setTimeout(() => {}, 10));\n
      \n

      Every new resource is assigned an ID that is unique within the scope of the\ncurrent Node.js instance.

      ", + "modules": [ + { + "textRaw": "`type`", + "name": "`type`", + "desc": "

      The type is a string identifying the type of resource that caused\ninit to be called. Generally, it will correspond to the name of the\nresource's constructor.

      \n
      FSEVENTWRAP, FSREQCALLBACK, GETADDRINFOREQWRAP, GETNAMEINFOREQWRAP, HTTPINCOMINGMESSAGE,\nHTTPCLIENTREQUEST, JSSTREAM, PIPECONNECTWRAP, PIPEWRAP, PROCESSWRAP, QUERYWRAP,\nSHUTDOWNWRAP, SIGNALWRAP, STATWATCHER, TCPCONNECTWRAP, TCPSERVERWRAP, TCPWRAP,\nTTYWRAP, UDPSENDWRAP, UDPWRAP, WRITEWRAP, ZLIB, SSLCONNECTION, PBKDF2REQUEST,\nRANDOMBYTESREQUEST, TLSWRAP, Microtask, Timeout, Immediate, TickObject\n
      \n

      There is also the PROMISE resource type, which is used to track Promise\ninstances and asynchronous work scheduled by them.

      \n

      Users are able to define their own type when using the public embedder API.

      \n

      It is possible to have type name collisions. Embedders are encouraged to use\nunique prefixes, such as the npm package name, to prevent collisions when\nlistening to the hooks.

      ", + "type": "module", + "displayName": "`type`" + }, + { + "textRaw": "`triggerAsyncId`", + "name": "`triggerasyncid`", + "desc": "

      triggerAsyncId is the asyncId of the resource that caused (or \"triggered\")\nthe new resource to initialize and that caused init to call. This is different\nfrom async_hooks.executionAsyncId() that only shows when a resource was\ncreated, while triggerAsyncId shows why a resource was created.

      \n

      The following is a simple demonstration of triggerAsyncId:

      \n
      const { fd } = process.stdout;\n\nasync_hooks.createHook({\n  init(asyncId, type, triggerAsyncId) {\n    const eid = async_hooks.executionAsyncId();\n    fs.writeSync(\n      fd,\n      `${type}(${asyncId}): trigger: ${triggerAsyncId} execution: ${eid}\\n`);\n  }\n}).enable();\n\nnet.createServer((conn) => {}).listen(8080);\n
      \n

      Output when hitting the server with nc localhost 8080:

      \n
      TCPSERVERWRAP(5): trigger: 1 execution: 1\nTCPWRAP(7): trigger: 5 execution: 0\n
      \n

      The TCPSERVERWRAP is the server which receives the connections.

      \n

      The TCPWRAP is the new connection from the client. When a new\nconnection is made, the TCPWrap instance is immediately constructed. This\nhappens outside of any JavaScript stack. (An executionAsyncId() of 0 means\nthat it is being executed from C++ with no JavaScript stack above it.) With only\nthat information, it would be impossible to link resources together in\nterms of what caused them to be created, so triggerAsyncId is given the task\nof propagating what resource is responsible for the new resource's existence.

      ", + "type": "module", + "displayName": "`triggerAsyncId`" + }, + { + "textRaw": "`resource`", + "name": "`resource`", + "desc": "

      resource is an object that represents the actual async resource that has\nbeen initialized. This can contain useful information that can vary based on\nthe value of type. For instance, for the GETADDRINFOREQWRAP resource type,\nresource provides the host name used when looking up the IP address for the\nhost in net.Server.listen(). The API for accessing this information is\nnot supported, but using the Embedder API, users can provide\nand document their own resource objects. For example, such a resource object\ncould contain the SQL query being executed.

      \n

      In some cases the resource object is reused for performance reasons, it is\nthus not safe to use it as a key in a WeakMap or add properties to it.

      ", + "type": "module", + "displayName": "`resource`" + }, + { + "textRaw": "Asynchronous context example", + "name": "asynchronous_context_example", + "desc": "

      The following is an example with additional information about the calls to\ninit between the before and after calls, specifically what the\ncallback to listen() will look like. The output formatting is slightly more\nelaborate to make calling context easier to see.

      \n
      const { fd } = process.stdout;\n\nlet indent = 0;\nasync_hooks.createHook({\n  init(asyncId, type, triggerAsyncId) {\n    const eid = async_hooks.executionAsyncId();\n    const indentStr = ' '.repeat(indent);\n    fs.writeSync(\n      fd,\n      `${indentStr}${type}(${asyncId}):` +\n      ` trigger: ${triggerAsyncId} execution: ${eid}\\n`);\n  },\n  before(asyncId) {\n    const indentStr = ' '.repeat(indent);\n    fs.writeSync(fd, `${indentStr}before:  ${asyncId}\\n`);\n    indent += 2;\n  },\n  after(asyncId) {\n    indent -= 2;\n    const indentStr = ' '.repeat(indent);\n    fs.writeSync(fd, `${indentStr}after:  ${asyncId}\\n`);\n  },\n  destroy(asyncId) {\n    const indentStr = ' '.repeat(indent);\n    fs.writeSync(fd, `${indentStr}destroy:  ${asyncId}\\n`);\n  },\n}).enable();\n\nnet.createServer(() => {}).listen(8080, () => {\n  // Let's wait 10ms before logging the server started.\n  setTimeout(() => {\n    console.log('>>>', async_hooks.executionAsyncId());\n  }, 10);\n});\n
      \n

      Output from only starting the server:

      \n
      TCPSERVERWRAP(5): trigger: 1 execution: 1\nTickObject(6): trigger: 5 execution: 1\nbefore:  6\n  Timeout(7): trigger: 6 execution: 6\nafter:   6\ndestroy: 6\nbefore:  7\n>>> 7\n  TickObject(8): trigger: 7 execution: 7\nafter:   7\nbefore:  8\nafter:   8\n
      \n

      As illustrated in the example, executionAsyncId() and execution each specify\nthe value of the current execution context; which is delineated by calls to\nbefore and after.

      \n

      Only using execution to graph resource allocation results in the following:

      \n
        root(1)\n     ^\n     |\nTickObject(6)\n     ^\n     |\n Timeout(7)\n
      \n

      The TCPSERVERWRAP is not part of this graph, even though it was the reason for\nconsole.log() being called. This is because binding to a port without a host\nname is a synchronous operation, but to maintain a completely asynchronous\nAPI the user's callback is placed in a process.nextTick(). Which is why\nTickObject is present in the output and is a 'parent' for .listen()\ncallback.

      \n

      The graph only shows when a resource was created, not why, so to track\nthe why use triggerAsyncId. Which can be represented with the following\ngraph:

      \n
       bootstrap(1)\n     |\n     ˅\nTCPSERVERWRAP(5)\n     |\n     ˅\n TickObject(6)\n     |\n     ˅\n  Timeout(7)\n
      ", + "type": "module", + "displayName": "Asynchronous context example" + } + ] + }, + { + "textRaw": "`before(asyncId)`", + "type": "method", + "name": "before", + "signatures": [ + { + "params": [ + { + "textRaw": "`asyncId` {number}", + "name": "asyncId", + "type": "number" + } + ] + } + ], + "desc": "

      When an asynchronous operation is initiated (such as a TCP server receiving a\nnew connection) or completes (such as writing data to disk) a callback is\ncalled to notify the user. The before callback is called just before said\ncallback is executed. asyncId is the unique identifier assigned to the\nresource about to execute the callback.

      \n

      The before callback will be called 0 to N times. The before callback\nwill typically be called 0 times if the asynchronous operation was cancelled\nor, for example, if no connections are received by a TCP server. Persistent\nasynchronous resources like a TCP server will typically call the before\ncallback multiple times, while other operations like fs.open() will call\nit only once.

      " + }, + { + "textRaw": "`after(asyncId)`", + "type": "method", + "name": "after", + "signatures": [ + { + "params": [ + { + "textRaw": "`asyncId` {number}", + "name": "asyncId", + "type": "number" + } + ] + } + ], + "desc": "

      Called immediately after the callback specified in before is completed.

      \n

      If an uncaught exception occurs during execution of the callback, then after\nwill run after the 'uncaughtException' event is emitted or a domain's\nhandler runs.

      " + }, + { + "textRaw": "`destroy(asyncId)`", + "type": "method", + "name": "destroy", + "signatures": [ + { + "params": [ + { + "textRaw": "`asyncId` {number}", + "name": "asyncId", + "type": "number" + } + ] + } + ], + "desc": "

      Called after the resource corresponding to asyncId is destroyed. It is also\ncalled asynchronously from the embedder API emitDestroy().

      \n

      Some resources depend on garbage collection for cleanup, so if a reference is\nmade to the resource object passed to init it is possible that destroy\nwill never be called, causing a memory leak in the application. If the resource\ndoes not depend on garbage collection, then this will not be an issue.

      " + }, + { + "textRaw": "`promiseResolve(asyncId)`", + "type": "method", + "name": "promiseResolve", + "meta": { + "added": [ + "v8.6.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`asyncId` {number}", + "name": "asyncId", + "type": "number" + } + ] + } + ], + "desc": "

      Called when the resolve function passed to the Promise constructor is\ninvoked (either directly or through other means of resolving a promise).

      \n

      resolve() does not do any observable synchronous work.

      \n

      The Promise is not necessarily fulfilled or rejected at this point if the\nPromise was resolved by assuming the state of another Promise.

      \n
      new Promise((resolve) => resolve(true)).then((a) => {});\n
      \n

      calls the following callbacks:

      \n
      init for PROMISE with id 5, trigger id: 1\n  promise resolve 5      # corresponds to resolve(true)\ninit for PROMISE with id 6, trigger id: 5  # the Promise returned by then()\n  before 6               # the then() callback is entered\n  promise resolve 6      # the then() callback resolves the promise by returning\n  after 6\n
      " + } + ], + "type": "module", + "displayName": "Hook callbacks" + } + ] + }, { "textRaw": "Class: `AsyncLocalStorage`", "type": "class", "name": "AsyncLocalStorage", "meta": { "added": [ - "v12.17.0" + "v13.10.0" ], "changes": [] }, - "desc": "

      This class is used to create asynchronous state within callbacks and promise\nchains. It allows storing data throughout the lifetime of a web request\nor any other asynchronous duration. It is similar to thread-local storage\nin other languages.

      \n

      The following example uses AsyncLocalStorage to build a simple logger\nthat assigns IDs to incoming HTTP requests and includes them in messages\nlogged within each request.

      \n
      const http = require('http');\nconst { AsyncLocalStorage } = require('async_hooks');\n\nconst asyncLocalStorage = new AsyncLocalStorage();\n\nfunction logWithId(msg) {\n  const id = asyncLocalStorage.getStore();\n  console.log(`${id !== undefined ? id : '-'}:`, msg);\n}\n\nlet idSeq = 0;\nhttp.createServer((req, res) => {\n  asyncLocalStorage.run(idSeq++, () => {\n    logWithId('start');\n    // Imagine any chain of async operations here\n    setImmediate(() => {\n      logWithId('finish');\n      res.end();\n    });\n  });\n}).listen(8080);\n\nhttp.get('http://localhost:8080');\nhttp.get('http://localhost:8080');\n// Prints:\n//   0: start\n//   1: start\n//   0: finish\n//   1: finish\n
      \n

      When having multiple instances of AsyncLocalStorage, they are independent\nfrom each other. It is safe to instantiate this class multiple times.

      ", + "desc": "

      This class is used to create asynchronous state within callbacks and promise\nchains. It allows storing data throughout the lifetime of a web request\nor any other asynchronous duration. It is similar to thread-local storage\nin other languages.

      \n

      While you can create your own implementation on top of the async_hooks module,\nAsyncLocalStorage should be preferred as it is a performant and memory safe\nimplementation that involves significant optimizations that are non-obvious to\nimplement.

      \n

      The following example uses AsyncLocalStorage to build a simple logger\nthat assigns IDs to incoming HTTP requests and includes them in messages\nlogged within each request.

      \n
      const http = require('http');\nconst { AsyncLocalStorage } = require('async_hooks');\n\nconst asyncLocalStorage = new AsyncLocalStorage();\n\nfunction logWithId(msg) {\n  const id = asyncLocalStorage.getStore();\n  console.log(`${id !== undefined ? id : '-'}:`, msg);\n}\n\nlet idSeq = 0;\nhttp.createServer((req, res) => {\n  asyncLocalStorage.run(idSeq++, () => {\n    logWithId('start');\n    // Imagine any chain of async operations here\n    setImmediate(() => {\n      logWithId('finish');\n      res.end();\n    });\n  });\n}).listen(8080);\n\nhttp.get('http://localhost:8080');\nhttp.get('http://localhost:8080');\n// Prints:\n//   0: start\n//   1: start\n//   0: finish\n//   1: finish\n
      \n

      When having multiple instances of AsyncLocalStorage, they are independent\nfrom each other. It is safe to instantiate this class multiple times.

      ", "methods": [ { "textRaw": "`asyncLocalStorage.disable()`", @@ -612,7 +602,7 @@ "name": "disable", "meta": { "added": [ - "v12.17.0" + "v13.10.0" ], "changes": [] }, @@ -621,7 +611,7 @@ "params": [] } ], - "desc": "

      This method disables the instance of AsyncLocalStorage. All subsequent calls\nto asyncLocalStorage.getStore() will return undefined until\nasyncLocalStorage.run() is called again.

      \n

      When calling asyncLocalStorage.disable(), all current contexts linked to the\ninstance will be exited.

      \n

      Calling asyncLocalStorage.disable() is required before the\nasyncLocalStorage can be garbage collected. This does not apply to stores\nprovided by the asyncLocalStorage, as those objects are garbage collected\nalong with the corresponding async resources.

      \n

      This method is to be used when the asyncLocalStorage is not in use anymore\nin the current process.

      " + "desc": "

      Disables the instance of AsyncLocalStorage. All subsequent calls\nto asyncLocalStorage.getStore() will return undefined until\nasyncLocalStorage.run() or asyncLocalStorage.enterWith() is called again.

      \n

      When calling asyncLocalStorage.disable(), all current contexts linked to the\ninstance will be exited.

      \n

      Calling asyncLocalStorage.disable() is required before the\nasyncLocalStorage can be garbage collected. This does not apply to stores\nprovided by the asyncLocalStorage, as those objects are garbage collected\nalong with the corresponding async resources.

      \n

      Use this method when the asyncLocalStorage is not in use anymore\nin the current process.

      " }, { "textRaw": "`asyncLocalStorage.getStore()`", @@ -629,7 +619,7 @@ "name": "getStore", "meta": { "added": [ - "v12.17.0" + "v13.10.0" ], "changes": [] }, @@ -643,7 +633,7 @@ "params": [] } ], - "desc": "

      This method returns the current store.\nIf this method is called outside of an asynchronous context initialized by\ncalling asyncLocalStorage.run, it will return undefined.

      " + "desc": "

      Returns the current store.\nIf called outside of an asynchronous context initialized by\ncalling asyncLocalStorage.run() or asyncLocalStorage.enterWith(), it\nreturns undefined.

      " }, { "textRaw": "`asyncLocalStorage.enterWith(store)`", @@ -651,7 +641,7 @@ "name": "enterWith", "meta": { "added": [ - "v12.17.0" + "v13.11.0" ], "changes": [] }, @@ -666,7 +656,7 @@ ] } ], - "desc": "

      Calling asyncLocalStorage.enterWith(store) will transition into the context\nfor the remainder of the current synchronous execution and will persist\nthrough any following asynchronous calls.

      \n

      Example:

      \n
      const store = { id: 1 };\nasyncLocalStorage.enterWith(store);\nasyncLocalStorage.getStore(); // Returns the store object\nsomeAsyncOperation(() => {\n  asyncLocalStorage.getStore(); // Returns the same object\n});\n
      \n

      This transition will continue for the entire synchronous execution.\nThis means that if, for example, the context is entered within an event\nhandler subsequent event handlers will also run within that context unless\nspecifically bound to another context with an AsyncResource.

      \n
      const store = { id: 1 };\n\nemitter.on('my-event', () => {\n  asyncLocalStorage.enterWith(store);\n});\nemitter.on('my-event', () => {\n  asyncLocalStorage.getStore(); // Returns the same object\n});\n\nasyncLocalStorage.getStore(); // Returns undefined\nemitter.emit('my-event');\nasyncLocalStorage.getStore(); // Returns the same object\n
      " + "desc": "

      Transitions into the context for the remainder of the current\nsynchronous execution and then persists the store through any following\nasynchronous calls.

      \n

      Example:

      \n
      const store = { id: 1 };\n// Replaces previous store with the given store object\nasyncLocalStorage.enterWith(store);\nasyncLocalStorage.getStore(); // Returns the store object\nsomeAsyncOperation(() => {\n  asyncLocalStorage.getStore(); // Returns the same object\n});\n
      \n

      This transition will continue for the entire synchronous execution.\nThis means that if, for example, the context is entered within an event\nhandler subsequent event handlers will also run within that context unless\nspecifically bound to another context with an AsyncResource. That is why\nrun() should be preferred over enterWith() unless there are strong reasons\nto use the latter method.

      \n
      const store = { id: 1 };\n\nemitter.on('my-event', () => {\n  asyncLocalStorage.enterWith(store);\n});\nemitter.on('my-event', () => {\n  asyncLocalStorage.getStore(); // Returns the same object\n});\n\nasyncLocalStorage.getStore(); // Returns undefined\nemitter.emit('my-event');\nasyncLocalStorage.getStore(); // Returns the same object\n
      " }, { "textRaw": "`asyncLocalStorage.run(store, callback[, ...args])`", @@ -674,7 +664,7 @@ "name": "run", "meta": { "added": [ - "v12.17.0" + "v13.10.0" ], "changes": [] }, @@ -699,7 +689,7 @@ ] } ], - "desc": "

      This methods runs a function synchronously within a context and return its\nreturn value. The store is not accessible outside of the callback function or\nthe asynchronous operations created within the callback.

      \n

      Optionally, arguments can be passed to the function. They will be passed to\nthe callback function.

      \n

      If the callback function throws an error, it will be thrown by run too.\nThe stacktrace will not be impacted by this call and the context will\nbe exited.

      \n

      Example:

      \n
      const store = { id: 2 };\ntry {\n  asyncLocalStorage.run(store, () => {\n    asyncLocalStorage.getStore(); // Returns the store object\n    throw new Error();\n  });\n} catch (e) {\n  asyncLocalStorage.getStore(); // Returns undefined\n  // The error will be caught here\n}\n
      " + "desc": "

      Runs a function synchronously within a context and returns its\nreturn value. The store is not accessible outside of the callback function.\nThe store is accessible to any asynchronous operations created within the\ncallback.

      \n

      The optional args are passed to the callback function.

      \n

      If the callback function throws an error, the error is thrown by run() too.\nThe stacktrace is not impacted by this call and the context is exited.

      \n

      Example:

      \n
      const store = { id: 2 };\ntry {\n  asyncLocalStorage.run(store, () => {\n    asyncLocalStorage.getStore(); // Returns the store object\n    setTimeout(() => {\n      asyncLocalStorage.getStore(); // Returns the store object\n    }, 200);\n    throw new Error();\n  });\n} catch (e) {\n  asyncLocalStorage.getStore(); // Returns undefined\n  // The error will be caught here\n}\n
      " }, { "textRaw": "`asyncLocalStorage.exit(callback[, ...args])`", @@ -707,7 +697,7 @@ "name": "exit", "meta": { "added": [ - "v12.17.0" + "v13.10.0" ], "changes": [] }, @@ -727,7 +717,7 @@ ] } ], - "desc": "

      This methods runs a function synchronously outside of a context and return its\nreturn value. The store is not accessible within the callback function or\nthe asynchronous operations created within the callback.

      \n

      Optionally, arguments can be passed to the function. They will be passed to\nthe callback function.

      \n

      If the callback function throws an error, it will be thrown by exit too.\nThe stacktrace will not be impacted by this call and\nthe context will be re-entered.

      \n

      Example:

      \n
      // Within a call to run\ntry {\n  asyncLocalStorage.getStore(); // Returns the store object or value\n  asyncLocalStorage.exit(() => {\n    asyncLocalStorage.getStore(); // Returns undefined\n    throw new Error();\n  });\n} catch (e) {\n  asyncLocalStorage.getStore(); // Returns the same object or value\n  // The error will be caught here\n}\n
      " + "desc": "

      Runs a function synchronously outside of a context and returns its\nreturn value. The store is not accessible within the callback function or\nthe asynchronous operations created within the callback. Any getStore()\ncall done within the callback function will always return undefined.

      \n

      The optional args are passed to the callback function.

      \n

      If the callback function throws an error, the error is thrown by exit() too.\nThe stacktrace is not impacted by this call and the context is re-entered.

      \n

      Example:

      \n
      // Within a call to run\ntry {\n  asyncLocalStorage.getStore(); // Returns the store object or value\n  asyncLocalStorage.exit(() => {\n    asyncLocalStorage.getStore(); // Returns undefined\n    throw new Error();\n  });\n} catch (e) {\n  asyncLocalStorage.getStore(); // Returns the same object or value\n  // The error will be caught here\n}\n
      " } ], "modules": [ @@ -749,7 +739,7 @@ "signatures": [ { "params": [], - "desc": "

      Creates a new instance of AsyncLocalStorage. Store is only provided within a\nrun method call.

      " + "desc": "

      Creates a new instance of AsyncLocalStorage. Store is only provided within a\nrun() call or after an enterWith() call.

      " } ] } diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md index 8ddcbbce18a0a207576f266a11e8ccc9646bcdf5..f1c964fc20f4f38d0520cb71494f1052046d0f03 100644 --- a/doc/api/async_hooks.md +++ b/doc/api/async_hooks.md @@ -25,9 +25,7 @@ as the abstract concept that is a resource. If [`Worker`][]s are used, each thread has an independent `async_hooks` interface, and each thread will use a new set of async IDs. -## Public API - -### Overview +## Overview Following is a simple overview of the public API. @@ -63,8 +61,8 @@ asyncHook.disable(); function init(asyncId, type, triggerAsyncId, resource) { } // Before is called just before the resource's callback is called. It can be -// called 0-N times for handles (e.g. TCPWrap), and will be called exactly 1 -// time for requests (e.g. FSReqCallback). +// called 0-N times for handles (such as TCPWrap), and will be called exactly 1 +// time for requests (such as FSReqCallback). function before(asyncId) { } // After is called just after the resource's callback has finished. @@ -79,7 +77,7 @@ function destroy(asyncId) { } function promiseResolve(asyncId) { } ``` -#### `async_hooks.createHook(callbacks)` +## `async_hooks.createHook(callbacks)` * Returns: {Object} The resource representing the current execution. @@ -542,14 +543,14 @@ const server = createServer((req, res) => { }).listen(3000); ``` -#### `async_hooks.executionAsyncId()` +### `async_hooks.executionAsyncId()` * Returns: {number} The `asyncId` of the current execution context. Useful to @@ -574,7 +575,7 @@ const server = net.createServer((conn) => { async_hooks.executionAsyncId(); }).listen(port, () => { - // Returns the ID of a TickObject (i.e. process.nextTick()) because all + // Returns the ID of a TickObject (process.nextTick()) because all // callbacks passed to .listen() are wrapped in a nextTick(). async_hooks.executionAsyncId(); }); @@ -583,7 +584,7 @@ const server = net.createServer((conn) => { Promise contexts may not get precise `executionAsyncIds` by default. See the section on [promise execution tracking][]. -#### `async_hooks.triggerAsyncId()` +### `async_hooks.triggerAsyncId()` * Returns: {number} The ID of the resource responsible for calling the callback that is currently being executed. @@ -702,14 +703,14 @@ asyncResource.triggerAsyncId(); * `type` {string} The type of async event. * `options` {Object} * `triggerAsyncId` {number} The ID of the execution context that created this - async event. **Default:** `executionAsyncId()`. + async event. **Default:** `executionAsyncId()`. * `requireManualDestroy` {boolean} If set to `true`, disables `emitDestroy` - when the object is garbage collected. This usually does not need to be set - (even if `emitDestroy` is called manually), unless the resource's `asyncId` - is retrieved and the sensitive API's `emitDestroy` is called with it. - When set to `false`, the `emitDestroy` call on garbage collection - will only take place if there is at least one active `destroy` hook. - **Default:** `false`. + when the object is garbage collected. This usually does not need to be set + (even if `emitDestroy` is called manually), unless the resource's `asyncId` + is retrieved and the sensitive API's `emitDestroy` is called with it. + When set to `false`, the `emitDestroy` call on garbage collection + will only take place if there is at least one active `destroy` hook. + **Default:** `false`. Example usage: @@ -735,7 +736,7 @@ class DBQuery extends AsyncResource { #### Static method: `AsyncResource.bind(fn[, type])` * `fn` {Function} The function to bind to the current execution context. @@ -749,7 +750,7 @@ the `AsyncResource` to which the function is bound. #### `asyncResource.bind(fn)` * `fn` {Function} The function to bind to the current `AsyncResource`. @@ -790,7 +791,7 @@ never be called. #### `asyncResource.triggerAsyncId()` * Returns: {number} The same `triggerAsyncId` that is passed to the -`AsyncResource` constructor. + `AsyncResource` constructor. ### Using `AsyncResource` for a `Worker` thread pool @@ -838,9 +839,19 @@ class WorkerPool extends EventEmitter { this.numThreads = numThreads; this.workers = []; this.freeWorkers = []; + this.tasks = []; for (let i = 0; i < numThreads; i++) this.addNewWorker(); + + // Any time the kWorkerFreedEvent is emitted, dispatch + // the next task pending in the queue, if any. + this.on(kWorkerFreedEvent, () => { + if (this.tasks.length > 0) { + const { task, callback } = this.tasks.shift(); + this.runTask(task, callback); + } + }); } addNewWorker() { @@ -874,7 +885,7 @@ class WorkerPool extends EventEmitter { runTask(task, callback) { if (this.freeWorkers.length === 0) { // No free threads, wait until a worker thread becomes free. - this.once(kWorkerFreedEvent, () => this.runTask(task, callback)); + this.tasks.push({ task, callback }); return; } @@ -942,7 +953,7 @@ const server = createServer((req, res) => { ## Class: `AsyncLocalStorage` This class is used to create asynchronous state within callbacks and promise @@ -950,6 +961,11 @@ chains. It allows storing data throughout the lifetime of a web request or any other asynchronous duration. It is similar to thread-local storage in other languages. +While you can create your own implementation on top of the `async_hooks` module, +`AsyncLocalStorage` should be preferred as it is a performant and memory safe +implementation that involves significant optimizations that are non-obvious to +implement. + The following example uses `AsyncLocalStorage` to build a simple logger that assigns IDs to incoming HTTP requests and includes them in messages logged within each request. @@ -991,20 +1007,20 @@ from each other. It is safe to instantiate this class multiple times. ### `new AsyncLocalStorage()` Creates a new instance of `AsyncLocalStorage`. Store is only provided within a -`run` method call. +`run()` call or after an `enterWith()` call. ### `asyncLocalStorage.disable()` -This method disables the instance of `AsyncLocalStorage`. All subsequent calls +Disables the instance of `AsyncLocalStorage`. All subsequent calls to `asyncLocalStorage.getStore()` will return `undefined` until -`asyncLocalStorage.run()` is called again. +`asyncLocalStorage.run()` or `asyncLocalStorage.enterWith()` is called again. When calling `asyncLocalStorage.disable()`, all current contexts linked to the instance will be exited. @@ -1014,35 +1030,37 @@ Calling `asyncLocalStorage.disable()` is required before the provided by the `asyncLocalStorage`, as those objects are garbage collected along with the corresponding async resources. -This method is to be used when the `asyncLocalStorage` is not in use anymore +Use this method when the `asyncLocalStorage` is not in use anymore in the current process. ### `asyncLocalStorage.getStore()` * Returns: {any} -This method returns the current store. -If this method is called outside of an asynchronous context initialized by -calling `asyncLocalStorage.run`, it will return `undefined`. +Returns the current store. +If called outside of an asynchronous context initialized by +calling `asyncLocalStorage.run()` or `asyncLocalStorage.enterWith()`, it +returns `undefined`. ### `asyncLocalStorage.enterWith(store)` * `store` {any} -Calling `asyncLocalStorage.enterWith(store)` will transition into the context -for the remainder of the current synchronous execution and will persist -through any following asynchronous calls. +Transitions into the context for the remainder of the current +synchronous execution and then persists the store through any following +asynchronous calls. Example: ```js const store = { id: 1 }; +// Replaces previous store with the given store object asyncLocalStorage.enterWith(store); asyncLocalStorage.getStore(); // Returns the store object someAsyncOperation(() => { @@ -1053,7 +1071,9 @@ someAsyncOperation(() => { This transition will continue for the _entire_ synchronous execution. This means that if, for example, the context is entered within an event handler subsequent event handlers will also run within that context unless -specifically bound to another context with an `AsyncResource`. +specifically bound to another context with an `AsyncResource`. That is why +`run()` should be preferred over `enterWith()` unless there are strong reasons +to use the latter method. ```js const store = { id: 1 }; @@ -1072,23 +1092,22 @@ asyncLocalStorage.getStore(); // Returns the same object ### `asyncLocalStorage.run(store, callback[, ...args])` * `store` {any} * `callback` {Function} * `...args` {any} -This methods runs a function synchronously within a context and return its -return value. The store is not accessible outside of the callback function or -the asynchronous operations created within the callback. +Runs a function synchronously within a context and returns its +return value. The store is not accessible outside of the callback function. +The store is accessible to any asynchronous operations created within the +callback. -Optionally, arguments can be passed to the function. They will be passed to -the callback function. +The optional `args` are passed to the callback function. -If the callback function throws an error, it will be thrown by `run` too. -The stacktrace will not be impacted by this call and the context will -be exited. +If the callback function throws an error, the error is thrown by `run()` too. +The stacktrace is not impacted by this call and the context is exited. Example: @@ -1097,6 +1116,9 @@ const store = { id: 2 }; try { asyncLocalStorage.run(store, () => { asyncLocalStorage.getStore(); // Returns the store object + setTimeout(() => { + asyncLocalStorage.getStore(); // Returns the store object + }, 200); throw new Error(); }); } catch (e) { @@ -1107,22 +1129,21 @@ try { ### `asyncLocalStorage.exit(callback[, ...args])` * `callback` {Function} * `...args` {any} -This methods runs a function synchronously outside of a context and return its +Runs a function synchronously outside of a context and returns its return value. The store is not accessible within the callback function or -the asynchronous operations created within the callback. +the asynchronous operations created within the callback. Any `getStore()` +call done within the callback function will always return `undefined`. -Optionally, arguments can be passed to the function. They will be passed to -the callback function. +The optional `args` are passed to the callback function. -If the callback function throws an error, it will be thrown by `exit` too. -The stacktrace will not be impacted by this call and -the context will be re-entered. +If the callback function throws an error, the error is thrown by `exit()` too. +The stacktrace is not impacted by this call and the context is re-entered. Example: @@ -1172,16 +1193,16 @@ If you need to keep using callback-based API, or your code assumes a custom thenable implementation, use the [`AsyncResource`][] class to associate the asynchronous operation with the correct execution context. +[Hook Callbacks]: #async_hooks_hook_callbacks +[PromiseHooks]: https://docs.google.com/document/d/1rda3yKGHimKIhg5YeoAmCOtyURgsbTH_qaYR79FELlk/edit [`AsyncResource`]: #async_hooks_class_asyncresource +[`EventEmitter`]: events.md#events_class_eventemitter +[`Stream`]: stream.md#stream_stream +[`Worker`]: worker_threads.md#worker_threads_class_worker [`after` callback]: #async_hooks_after_asyncid [`before` callback]: #async_hooks_before_asyncid [`destroy` callback]: #async_hooks_destroy_asyncid [`init` callback]: #async_hooks_init_asyncid_type_triggerasyncid_resource [`promiseResolve` callback]: #async_hooks_promiseresolve_asyncid -[`EventEmitter`]: events.html#events_class_eventemitter -[Hook Callbacks]: #async_hooks_hook_callbacks -[PromiseHooks]: https://docs.google.com/document/d/1rda3yKGHimKIhg5YeoAmCOtyURgsbTH_qaYR79FELlk/edit -[`Stream`]: stream.html#stream_stream -[`Worker`]: worker_threads.html#worker_threads_class_worker +[`util.promisify()`]: util.md#util_util_promisify_original [promise execution tracking]: #async_hooks_promise_execution_tracking -[`util.promisify()`]: util.html#util_util_promisify_original diff --git a/doc/api/buffer.html b/doc/api/buffer.html index a61f5d495806f1eaa25139f596fb50c6a7a7bd79..01aed5720ac595b5726ba9e5c7932586d55d313b 100644 --- a/doc/api/buffer.html +++ b/doc/api/buffer.html @@ -1,10 +1,10 @@ - + - - Buffer | Node.js v12.22.7 Documentation + + Buffer | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      - +
      -

      Buffer#

      +

      Buffer#

      Stability: 2 - Stable

      -

      Source Code: lib/buffer.js

      +

      Source Code: lib/buffer.js

      Buffer objects are used to represent a fixed-length sequence of bytes. Many Node.js APIs support Buffers.

      The Buffer class is a subclass of JavaScript's Uint8Array class and @@ -264,38 +290,40 @@ plain // Creates a zero-filled Buffer of length 10. -const buf1 = Buffer.alloc(10); +const buf1 = Buffer.alloc(10); // Creates a Buffer of length 10, // filled with bytes which all have the value `1`. -const buf2 = Buffer.alloc(10, 1); +const buf2 = Buffer.alloc(10, 1); // Creates an uninitialized buffer of length 10. // This is faster than calling Buffer.alloc() but the returned // Buffer instance might contain old data that needs to be // overwritten using fill(), write(), or other functions that fill the Buffer's // contents. -const buf3 = Buffer.allocUnsafe(10); +const buf3 = Buffer.allocUnsafe(10); // Creates a Buffer containing the bytes [1, 2, 3]. -const buf4 = Buffer.from([1, 2, 3]); +const buf4 = Buffer.from([1, 2, 3]); // Creates a Buffer containing the bytes [1, 1, 1, 1] – the entries // are all truncated using `(value & 255)` to fit into the range 0–255. -const buf5 = Buffer.from([257, 257.5, -255, '1']); +const buf5 = Buffer.from([257, 257.5, -255, '1']); // Creates a Buffer containing the UTF-8-encoded bytes for the string 'tést': // [0x74, 0xc3, 0xa9, 0x73, 0x74] (in hexadecimal notation) // [116, 195, 169, 115, 116] (in decimal notation) -const buf6 = Buffer.from('tést'); +const buf6 = Buffer.from('tést'); // Creates a Buffer containing the Latin-1 bytes [0x74, 0xe9, 0x73, 0x74]. -const buf7 = Buffer.from('tést', 'latin1'); -

      Buffers and character encodings#

      +const buf7 = Buffer.from('tést', 'latin1');
      +

      Buffers and character encodings#

      @@ -1463,16 +1610,17 @@ satisfy: 0 <= offset <= buf.length - 8. Default:<

      Reads an unsigned, big-endian 64-bit integer from buf at the specified offset.

      -
      const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);
      +

      This function is also available under the readBigUint64BE alias.

      +
      const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);
       
      -console.log(buf.readBigUInt64BE(0));
      +console.log(buf.readBigUInt64BE(0));
       // Prints: 4294967295n
      -

      buf.readBigUInt64LE([offset])#

      +

      buf.readBigUInt64LE([offset])#

      Buffer.from(), Buffer.alloc(), and Buffer.allocUnsafe()#

      In versions of Node.js prior to 6.0.0, Buffer instances were created using the Buffer constructor function, which allocates the returned Buffer differently based on what arguments are provided:

      @@ -3135,21 +3347,21 @@ potentially sensitive. if size is less than or equal to half Buffer.poolSize. Instances returned by Buffer.allocUnsafeSlow() never use the shared internal memory pool.

      -

      The --zero-fill-buffers command line option#

      +

      The --zero-fill-buffers command-line option#

      -

      Node.js can be started using the --zero-fill-buffers command line option to +

      Node.js can be started using the --zero-fill-buffers command-line option to cause all newly-allocated Buffer instances to be zero-filled upon creation by default. Without the option, buffers created with Buffer.allocUnsafe(), Buffer.allocUnsafeSlow(), and new SlowBuffer(size) are not zero-filled. Use of this flag can have a measurable negative impact on performance. Use the --zero-fill-buffers option only when necessary to enforce that newly allocated Buffer instances cannot contain old data that is potentially sensitive.

      -
      $ node --zero-fill-buffers
      -> Buffer.allocUnsafe(5);
      +
      $ node --zero-fill-buffers
      +> Buffer.allocUnsafe(5);
       <Buffer 00 00 00 00 00>
      -

      What makes Buffer.allocUnsafe() and Buffer.allocUnsafeSlow() "unsafe"?#

      +

      What makes Buffer.allocUnsafe() and Buffer.allocUnsafeSlow() "unsafe"?#

      When calling Buffer.allocUnsafe() and Buffer.allocUnsafeSlow(), the segment of allocated memory is uninitialized (it is not zeroed-out). While this design makes the allocation of memory quite fast, the allocated segment of @@ -3158,10 +3370,46 @@ created by Buffer. memory can allow this old data to be leaked when the Buffer memory is read.

      While there are clear performance advantages to using Buffer.allocUnsafe(), extra care must be taken in order to avoid -introducing security vulnerabilities into an application.

      +introducing security vulnerabilities into an application.

      + diff --git a/doc/api/buffer.json b/doc/api/buffer.json index 0c2adcb2b41948e218394f3835cdfb4a34015a3e..876cb6e9806f53faeff621e5a7bfa0b95bbdc85a 100644 --- a/doc/api/buffer.json +++ b/doc/api/buffer.json @@ -8,13 +8,18 @@ "introduced_in": "v0.1.90", "stability": 2, "stabilityText": "Stable", - "desc": "

      Source Code: lib/buffer.js

      \n

      Buffer objects are used to represent a fixed-length sequence of bytes. Many\nNode.js APIs support Buffers.

      \n

      The Buffer class is a subclass of JavaScript's Uint8Array class and\nextends it with methods that cover additional use cases. Node.js APIs accept\nplain Uint8Arrays wherever Buffers are supported as well.

      \n

      The Buffer class is within the global scope, making it unlikely that one\nwould need to ever use require('buffer').Buffer.

      \n
      // Creates a zero-filled Buffer of length 10.\nconst buf1 = Buffer.alloc(10);\n\n// Creates a Buffer of length 10,\n// filled with bytes which all have the value `1`.\nconst buf2 = Buffer.alloc(10, 1);\n\n// Creates an uninitialized buffer of length 10.\n// This is faster than calling Buffer.alloc() but the returned\n// Buffer instance might contain old data that needs to be\n// overwritten using fill(), write(), or other functions that fill the Buffer's\n// contents.\nconst buf3 = Buffer.allocUnsafe(10);\n\n// Creates a Buffer containing the bytes [1, 2, 3].\nconst buf4 = Buffer.from([1, 2, 3]);\n\n// Creates a Buffer containing the bytes [1, 1, 1, 1] – the entries\n// are all truncated using `(value & 255)` to fit into the range 0–255.\nconst buf5 = Buffer.from([257, 257.5, -255, '1']);\n\n// Creates a Buffer containing the UTF-8-encoded bytes for the string 'tést':\n// [0x74, 0xc3, 0xa9, 0x73, 0x74] (in hexadecimal notation)\n// [116, 195, 169, 115, 116] (in decimal notation)\nconst buf6 = Buffer.from('tést');\n\n// Creates a Buffer containing the Latin-1 bytes [0x74, 0xe9, 0x73, 0x74].\nconst buf7 = Buffer.from('tést', 'latin1');\n
      ", + "desc": "

      Source Code: lib/buffer.js

      \n

      Buffer objects are used to represent a fixed-length sequence of bytes. Many\nNode.js APIs support Buffers.

      \n

      The Buffer class is a subclass of JavaScript's Uint8Array class and\nextends it with methods that cover additional use cases. Node.js APIs accept\nplain Uint8Arrays wherever Buffers are supported as well.

      \n

      The Buffer class is within the global scope, making it unlikely that one\nwould need to ever use require('buffer').Buffer.

      \n
      // Creates a zero-filled Buffer of length 10.\nconst buf1 = Buffer.alloc(10);\n\n// Creates a Buffer of length 10,\n// filled with bytes which all have the value `1`.\nconst buf2 = Buffer.alloc(10, 1);\n\n// Creates an uninitialized buffer of length 10.\n// This is faster than calling Buffer.alloc() but the returned\n// Buffer instance might contain old data that needs to be\n// overwritten using fill(), write(), or other functions that fill the Buffer's\n// contents.\nconst buf3 = Buffer.allocUnsafe(10);\n\n// Creates a Buffer containing the bytes [1, 2, 3].\nconst buf4 = Buffer.from([1, 2, 3]);\n\n// Creates a Buffer containing the bytes [1, 1, 1, 1] – the entries\n// are all truncated using `(value & 255)` to fit into the range 0–255.\nconst buf5 = Buffer.from([257, 257.5, -255, '1']);\n\n// Creates a Buffer containing the UTF-8-encoded bytes for the string 'tést':\n// [0x74, 0xc3, 0xa9, 0x73, 0x74] (in hexadecimal notation)\n// [116, 195, 169, 115, 116] (in decimal notation)\nconst buf6 = Buffer.from('tést');\n\n// Creates a Buffer containing the Latin-1 bytes [0x74, 0xe9, 0x73, 0x74].\nconst buf7 = Buffer.from('tést', 'latin1');\n
      ", "modules": [ { "textRaw": "Buffers and character encodings", "name": "buffers_and_character_encodings", "meta": { "changes": [ + { + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/36952", + "description": "Introduced `base64url` encoding." + }, { "version": "v6.4.0", "pr-url": "https://github.com/nodejs/node/pull/7111", @@ -27,7 +32,7 @@ } ] }, - "desc": "

      When converting between Buffers and strings, a character encoding may be\nspecified. If no character encoding is specified, UTF-8 will be used as the\ndefault.

      \n
      const buf = Buffer.from('hello world', 'utf8');\n\nconsole.log(buf.toString('hex'));\n// Prints: 68656c6c6f20776f726c64\nconsole.log(buf.toString('base64'));\n// Prints: aGVsbG8gd29ybGQ=\n\nconsole.log(Buffer.from('fhqwhgads', 'utf8'));\n// Prints: <Buffer 66 68 71 77 68 67 61 64 73>\nconsole.log(Buffer.from('fhqwhgads', 'utf16le'));\n// Prints: <Buffer 66 00 68 00 71 00 77 00 68 00 67 00 61 00 64 00 73 00>\n
      \n

      The character encodings currently supported by Node.js are the following:

      \n
        \n
      • \n

        'utf8': Multi-byte encoded Unicode characters. Many web pages and other\ndocument formats use UTF-8. This is the default character encoding.\nWhen decoding a Buffer into a string that does not exclusively contain\nvalid UTF-8 data, the Unicode replacement character U+FFFD � will be used\nto represent those errors.

        \n
      • \n
      • \n

        'utf16le': Multi-byte encoded Unicode characters. Unlike 'utf8', each\ncharacter in the string will be encoded using either 2 or 4 bytes.\nNode.js only supports the little-endian variant of UTF-16.

        \n
      • \n
      • \n

        'latin1': Latin-1 stands for ISO-8859-1. This character encoding only\nsupports the Unicode characters from U+0000 to U+00FF. Each character is\nencoded using a single byte. Characters that do not fit into that range are\ntruncated and will be mapped to characters in that range.

        \n
      • \n
      \n

      Converting a Buffer into a string using one of the above is referred to as\ndecoding, and converting a string into a Buffer is referred to as encoding.

      \n

      Node.js also supports the following two binary-to-text encodings. For\nbinary-to-text encodings, the naming convention is reversed: Converting a\nBuffer into a string is typically referred to as encoding, and converting a\nstring into a Buffer as decoding.

      \n
        \n
      • \n

        'base64': Base64 encoding. When creating a Buffer from a string,\nthis encoding will also correctly accept \"URL and Filename Safe Alphabet\" as\nspecified in RFC 4648, Section 5. Whitespace characters such as spaces,\ntabs, and new lines contained within the base64-encoded string are ignored.

        \n
      • \n
      • \n

        'hex': Encode each byte as two hexadecimal characters. Data truncation\nmay occur when decoding strings that do exclusively contain valid hexadecimal\ncharacters. See below for an example.

        \n
      • \n
      \n

      The following legacy character encodings are also supported:

      \n
        \n
      • \n

        'ascii': For 7-bit ASCII data only. When encoding a string into a\nBuffer, this is equivalent to using 'latin1'. When decoding a Buffer\ninto a string, using this encoding will additionally unset the highest bit of\neach byte before decoding as 'latin1'.\nGenerally, there should be no reason to use this encoding, as 'utf8'\n(or, if the data is known to always be ASCII-only, 'latin1') will be a\nbetter choice when encoding or decoding ASCII-only text. It is only provided\nfor legacy compatibility.

        \n
      • \n
      • \n

        'binary': Alias for 'latin1'. See binary strings for more background\non this topic. The name of this encoding can be very misleading, as all of the\nencodings listed here convert between strings and binary data. For converting\nbetween strings and Buffers, typically 'utf-8' is the right choice.

        \n
      • \n
      • \n

        'ucs2': Alias of 'utf16le'. UCS-2 used to refer to a variant of UTF-16\nthat did not support characters that had code points larger than U+FFFF.\nIn Node.js, these code points are always supported.

        \n
      • \n
      \n
      Buffer.from('1ag', 'hex');\n// Prints <Buffer 1a>, data truncated when first non-hexadecimal value\n// ('g') encountered.\n\nBuffer.from('1a7g', 'hex');\n// Prints <Buffer 1a>, data truncated when data ends in single digit ('7').\n\nBuffer.from('1634', 'hex');\n// Prints <Buffer 16 34>, all data represented.\n
      \n

      Modern Web browsers follow the WHATWG Encoding Standard which aliases\nboth 'latin1' and 'ISO-8859-1' to 'win-1252'. This means that while doing\nsomething like http.get(), if the returned charset is one of those listed in\nthe WHATWG specification it is possible that the server actually returned\n'win-1252'-encoded data, and using 'latin1' encoding may incorrectly decode\nthe characters.

      ", + "desc": "

      When converting between Buffers and strings, a character encoding may be\nspecified. If no character encoding is specified, UTF-8 will be used as the\ndefault.

      \n
      const buf = Buffer.from('hello world', 'utf8');\n\nconsole.log(buf.toString('hex'));\n// Prints: 68656c6c6f20776f726c64\nconsole.log(buf.toString('base64'));\n// Prints: aGVsbG8gd29ybGQ=\n\nconsole.log(Buffer.from('fhqwhgads', 'utf8'));\n// Prints: <Buffer 66 68 71 77 68 67 61 64 73>\nconsole.log(Buffer.from('fhqwhgads', 'utf16le'));\n// Prints: <Buffer 66 00 68 00 71 00 77 00 68 00 67 00 61 00 64 00 73 00>\n
      \n

      The character encodings currently supported by Node.js are the following:

      \n
        \n
      • \n

        'utf8': Multi-byte encoded Unicode characters. Many web pages and other\ndocument formats use UTF-8. This is the default character encoding.\nWhen decoding a Buffer into a string that does not exclusively contain\nvalid UTF-8 data, the Unicode replacement character U+FFFD � will be used\nto represent those errors.

        \n
      • \n
      • \n

        'utf16le': Multi-byte encoded Unicode characters. Unlike 'utf8', each\ncharacter in the string will be encoded using either 2 or 4 bytes.\nNode.js only supports the little-endian variant of UTF-16.

        \n
      • \n
      • \n

        'latin1': Latin-1 stands for ISO-8859-1. This character encoding only\nsupports the Unicode characters from U+0000 to U+00FF. Each character is\nencoded using a single byte. Characters that do not fit into that range are\ntruncated and will be mapped to characters in that range.

        \n
      • \n
      \n

      Converting a Buffer into a string using one of the above is referred to as\ndecoding, and converting a string into a Buffer is referred to as encoding.

      \n

      Node.js also supports the following binary-to-text encodings. For\nbinary-to-text encodings, the naming convention is reversed: Converting a\nBuffer into a string is typically referred to as encoding, and converting a\nstring into a Buffer as decoding.

      \n
        \n
      • \n

        'base64': Base64 encoding. When creating a Buffer from a string,\nthis encoding will also correctly accept \"URL and Filename Safe Alphabet\" as\nspecified in RFC 4648, Section 5. Whitespace characters such as spaces,\ntabs, and new lines contained within the base64-encoded string are ignored.

        \n
      • \n
      • \n

        'base64url': base64url encoding as specified in\nRFC 4648, Section 5. When creating a Buffer from a string, this\nencoding will also correctly accept regular base64-encoded strings. When\nencoding a Buffer to a string, this encoding will omit padding.

        \n
      • \n
      • \n

        'hex': Encode each byte as two hexadecimal characters. Data truncation\nmay occur when decoding strings that do exclusively contain valid hexadecimal\ncharacters. See below for an example.

        \n
      • \n
      \n

      The following legacy character encodings are also supported:

      \n
        \n
      • \n

        'ascii': For 7-bit ASCII data only. When encoding a string into a\nBuffer, this is equivalent to using 'latin1'. When decoding a Buffer\ninto a string, using this encoding will additionally unset the highest bit of\neach byte before decoding as 'latin1'.\nGenerally, there should be no reason to use this encoding, as 'utf8'\n(or, if the data is known to always be ASCII-only, 'latin1') will be a\nbetter choice when encoding or decoding ASCII-only text. It is only provided\nfor legacy compatibility.

        \n
      • \n
      • \n

        'binary': Alias for 'latin1'. See binary strings for more background\non this topic. The name of this encoding can be very misleading, as all of the\nencodings listed here convert between strings and binary data. For converting\nbetween strings and Buffers, typically 'utf-8' is the right choice.

        \n
      • \n
      • \n

        'ucs2': Alias of 'utf16le'. UCS-2 used to refer to a variant of UTF-16\nthat did not support characters that had code points larger than U+FFFF.\nIn Node.js, these code points are always supported.

        \n
      • \n
      \n
      Buffer.from('1ag', 'hex');\n// Prints <Buffer 1a>, data truncated when first non-hexadecimal value\n// ('g') encountered.\n\nBuffer.from('1a7g', 'hex');\n// Prints <Buffer 1a>, data truncated when data ends in single digit ('7').\n\nBuffer.from('1634', 'hex');\n// Prints <Buffer 16 34>, all data represented.\n
      \n

      Modern Web browsers follow the WHATWG Encoding Standard which aliases\nboth 'latin1' and 'ISO-8859-1' to 'win-1252'. This means that while doing\nsomething like http.get(), if the returned charset is one of those listed in\nthe WHATWG specification it is possible that the server actually returned\n'win-1252'-encoded data, and using 'latin1' encoding may incorrectly decode\nthe characters.

      ", "type": "module", "displayName": "Buffers and character encodings" }, @@ -43,7 +48,7 @@ } ] }, - "desc": "

      Buffer instances are also JavaScript Uint8Array and TypedArray\ninstances. All TypedArray methods are available on Buffers. There are,\nhowever, subtle incompatibilities between the Buffer API and the\nTypedArray API.

      \n

      In particular:

      \n
        \n
      • While TypedArray#slice() creates a copy of part of the TypedArray,\nBuffer#slice() creates a view over the existing Buffer\nwithout copying. This behavior can be surprising, and only exists for legacy\ncompatibility. TypedArray#subarray() can be used to achieve the behavior\nof Buffer#slice() on both Buffers and other\nTypedArrays.
      • \n
      • buf.toString() is incompatible with its TypedArray equivalent.
      • \n
      • A number of methods, e.g. buf.indexOf(), support additional arguments.
      • \n
      \n

      There are two ways to create new TypedArray instances from a Buffer:

      \n
        \n
      • Passing a Buffer to a TypedArray constructor will copy the Buffers\ncontents, interpreted as an array of integers, and not as a byte sequence\nof the target type.
      • \n
      \n
      const buf = Buffer.from([1, 2, 3, 4]);\nconst uint32array = new Uint32Array(buf);\n\nconsole.log(uint32array);\n\n// Prints: Uint32Array(4) [ 1, 2, 3, 4 ]\n
      \n
        \n
      • Passing the Buffers underlying ArrayBuffer will create a\nTypedArray that shares its memory with the Buffer.
      • \n
      \n
      const buf = Buffer.from('hello', 'utf16le');\nconst uint16arr = new Uint16Array(\n  buf.buffer,\n  buf.byteOffset,\n  buf.length / Uint16Array.BYTES_PER_ELEMENT);\n\nconsole.log(uint16array);\n\n// Prints: Uint16Array(5) [ 104, 101, 108, 108, 111 ]\n
      \n

      It is possible to create a new Buffer that shares the same allocated\nmemory as a TypedArray instance by using the TypedArray object’s\n.buffer property in the same way. Buffer.from()\nbehaves like new Uint8Array() in this context.

      \n
      const arr = new Uint16Array(2);\n\narr[0] = 5000;\narr[1] = 4000;\n\n// Copies the contents of `arr`.\nconst buf1 = Buffer.from(arr);\n\n// Shares memory with `arr`.\nconst buf2 = Buffer.from(arr.buffer);\n\nconsole.log(buf1);\n// Prints: <Buffer 88 a0>\nconsole.log(buf2);\n// Prints: <Buffer 88 13 a0 0f>\n\narr[1] = 6000;\n\nconsole.log(buf1);\n// Prints: <Buffer 88 a0>\nconsole.log(buf2);\n// Prints: <Buffer 88 13 70 17>\n
      \n

      When creating a Buffer using a TypedArray's .buffer, it is\npossible to use only a portion of the underlying ArrayBuffer by passing in\nbyteOffset and length parameters.

      \n
      const arr = new Uint16Array(20);\nconst buf = Buffer.from(arr.buffer, 0, 16);\n\nconsole.log(buf.length);\n// Prints: 16\n
      \n

      The Buffer.from() and TypedArray.from() have different signatures and\nimplementations. Specifically, the TypedArray variants accept a second\nargument that is a mapping function that is invoked on every element of the\ntyped array:

      \n
        \n
      • TypedArray.from(source[, mapFn[, thisArg]])
      • \n
      \n

      The Buffer.from() method, however, does not support the use of a mapping\nfunction:

      \n", + "desc": "

      Buffer instances are also JavaScript Uint8Array and TypedArray\ninstances. All TypedArray methods are available on Buffers. There are,\nhowever, subtle incompatibilities between the Buffer API and the\nTypedArray API.

      \n

      In particular:

      \n\n

      There are two ways to create new TypedArray instances from a Buffer:

      \n
        \n
      • Passing a Buffer to a TypedArray constructor will copy the Buffers\ncontents, interpreted as an array of integers, and not as a byte sequence\nof the target type.
      • \n
      \n
      const buf = Buffer.from([1, 2, 3, 4]);\nconst uint32array = new Uint32Array(buf);\n\nconsole.log(uint32array);\n\n// Prints: Uint32Array(4) [ 1, 2, 3, 4 ]\n
      \n
        \n
      • Passing the Buffers underlying ArrayBuffer will create a\nTypedArray that shares its memory with the Buffer.
      • \n
      \n
      const buf = Buffer.from('hello', 'utf16le');\nconst uint16array = new Uint16Array(\n  buf.buffer,\n  buf.byteOffset,\n  buf.length / Uint16Array.BYTES_PER_ELEMENT);\n\nconsole.log(uint16array);\n\n// Prints: Uint16Array(5) [ 104, 101, 108, 108, 111 ]\n
      \n

      It is possible to create a new Buffer that shares the same allocated\nmemory as a TypedArray instance by using the TypedArray object’s\n.buffer property in the same way. Buffer.from()\nbehaves like new Uint8Array() in this context.

      \n
      const arr = new Uint16Array(2);\n\narr[0] = 5000;\narr[1] = 4000;\n\n// Copies the contents of `arr`.\nconst buf1 = Buffer.from(arr);\n\n// Shares memory with `arr`.\nconst buf2 = Buffer.from(arr.buffer);\n\nconsole.log(buf1);\n// Prints: <Buffer 88 a0>\nconsole.log(buf2);\n// Prints: <Buffer 88 13 a0 0f>\n\narr[1] = 6000;\n\nconsole.log(buf1);\n// Prints: <Buffer 88 a0>\nconsole.log(buf2);\n// Prints: <Buffer 88 13 70 17>\n
      \n

      When creating a Buffer using a TypedArray's .buffer, it is\npossible to use only a portion of the underlying ArrayBuffer by passing in\nbyteOffset and length parameters.

      \n
      const arr = new Uint16Array(20);\nconst buf = Buffer.from(arr.buffer, 0, 16);\n\nconsole.log(buf.length);\n// Prints: 16\n
      \n

      The Buffer.from() and TypedArray.from() have different signatures and\nimplementations. Specifically, the TypedArray variants accept a second\nargument that is a mapping function that is invoked on every element of the\ntyped array:

      \n
        \n
      • TypedArray.from(source[, mapFn[, thisArg]])
      • \n
      \n

      The Buffer.from() method, however, does not support the use of a mapping\nfunction:

      \n", "type": "module", "displayName": "Buffers and TypedArrays" }, @@ -58,35 +63,55 @@ "textRaw": "`buffer` module APIs", "name": "`buffer`_module_apis", "desc": "

      While, the Buffer object is available as a global, there are additional\nBuffer-related APIs that are available only via the buffer module\naccessed using require('buffer').

      ", - "properties": [ + "methods": [ { - "textRaw": "`INSPECT_MAX_BYTES` {integer} **Default:** `50`", - "type": "integer", - "name": "INSPECT_MAX_BYTES", + "textRaw": "`buffer.atob(data)`", + "type": "method", + "name": "atob", "meta": { "added": [ - "v0.5.4" + "v14.17.0" ], "changes": [] }, - "default": "`50`", - "desc": "

      Returns the maximum number of bytes that will be returned when\nbuf.inspect() is called. This can be overridden by user modules. See\nutil.inspect() for more details on buf.inspect() behavior.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`data` {any} The Base64-encoded input string.", + "name": "data", + "type": "any", + "desc": "The Base64-encoded input string." + } + ] + } + ], + "desc": "

      Decodes a string of Base64-encoded data into bytes, and encodes those bytes\ninto a string using Latin-1 (ISO-8859-1).

      \n

      The data may be any JavaScript-value that can be coerced into a string.

      \n

      This function is only provided for compatibility with legacy web platform APIs\nand should never be used in new code, because they use strings to represent\nbinary data and predate the introduction of typed arrays in JavaScript.\nFor code running using Node.js APIs, converting between base64-encoded strings\nand binary data should be performed using Buffer.from(str, 'base64') and\nbuf.toString('base64').

      " }, { - "textRaw": "`kMaxLength` {integer} The largest size allowed for a single `Buffer` instance.", - "type": "integer", - "name": "kMaxLength", + "textRaw": "`buffer.btoa(data)`", + "type": "method", + "name": "btoa", "meta": { "added": [ - "v3.0.0" + "v14.17.0" ], "changes": [] }, - "desc": "

      An alias for buffer.constants.MAX_LENGTH.

      ", - "shortDesc": "The largest size allowed for a single `Buffer` instance." - } - ], - "methods": [ + "signatures": [ + { + "params": [ + { + "textRaw": "`data` {any} An ASCII (Latin1) string.", + "name": "data", + "type": "any", + "desc": "An ASCII (Latin1) string." + } + ] + } + ], + "desc": "

      Decodes a string into bytes using Latin-1 (ISO-8859), and encodes those bytes\ninto a string using Base64.

      \n

      The data may be any JavaScript-value that can be coerced into a string.

      \n

      This function is only provided for compatibility with legacy web platform APIs\nand should never be used in new code, because they use strings to represent\nbinary data and predate the introduction of typed arrays in JavaScript.\nFor code running using Node.js APIs, converting between base64-encoded strings\nand binary data should be performed using Buffer.from(str, 'base64') and\nbuf.toString('base64').

      " + }, { "textRaw": "`buffer.transcode(source, fromEnc, toEnc)`", "type": "method", @@ -135,6 +160,47 @@ "desc": "

      Re-encodes the given Buffer or Uint8Array instance from one character\nencoding to another. Returns a new Buffer instance.

      \n

      Throws if the fromEnc or toEnc specify invalid character encodings or if\nconversion from fromEnc to toEnc is not permitted.

      \n

      Encodings supported by buffer.transcode() are: 'ascii', 'utf8',\n'utf16le', 'ucs2', 'latin1', and 'binary'.

      \n

      The transcoding process will use substitution characters if a given byte\nsequence cannot be adequately represented in the target encoding. For instance:

      \n
      const buffer = require('buffer');\n\nconst newBuf = buffer.transcode(Buffer.from('€'), 'utf8', 'ascii');\nconsole.log(newBuf.toString('ascii'));\n// Prints: '?'\n
      \n

      Because the Euro () sign is not representable in US-ASCII, it is replaced\nwith ? in the transcoded Buffer.

      " } ], + "properties": [ + { + "textRaw": "`INSPECT_MAX_BYTES` {integer} **Default:** `50`", + "type": "integer", + "name": "INSPECT_MAX_BYTES", + "meta": { + "added": [ + "v0.5.4" + ], + "changes": [] + }, + "default": "`50`", + "desc": "

      Returns the maximum number of bytes that will be returned when\nbuf.inspect() is called. This can be overridden by user modules. See\nutil.inspect() for more details on buf.inspect() behavior.

      " + }, + { + "textRaw": "`kMaxLength` {integer} The largest size allowed for a single `Buffer` instance.", + "type": "integer", + "name": "kMaxLength", + "meta": { + "added": [ + "v3.0.0" + ], + "changes": [] + }, + "desc": "

      An alias for buffer.constants.MAX_LENGTH.

      ", + "shortDesc": "The largest size allowed for a single `Buffer` instance." + }, + { + "textRaw": "`kStringMaxLength` {integer} The largest length allowed for a single `string` instance.", + "type": "integer", + "name": "kStringMaxLength", + "meta": { + "added": [ + "v3.0.0" + ], + "changes": [] + }, + "desc": "

      An alias for buffer.constants.MAX_STRING_LENGTH.

      ", + "shortDesc": "The largest length allowed for a single `string` instance." + } + ], "classes": [ { "textRaw": "Class: `SlowBuffer`", @@ -183,9 +249,15 @@ "added": [ "v8.2.0" ], - "changes": [] - }, - "desc": "

      On 32-bit architectures, this value currently is 230 - 1 (~1GB).\nOn 64-bit architectures, this value currently is 231 - 1 (~2GB).

      \n

      This value is also available as buffer.kMaxLength.

      ", + "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/32116", + "description": "Value is changed from 231 - 1 to 232 - 1 on 64-bit architectures." + } + ] + }, + "desc": "

      On 32-bit architectures, this value currently is 230 - 1 (~1GB).

      \n

      On 64-bit architectures, this value currently is 232 - 1 (~4GB).

      \n

      It reflects v8::TypedArray::kMaxLength under the hood.

      \n

      This value is also available as buffer.kMaxLength.

      ", "shortDesc": "The largest size allowed for a single `Buffer` instance." }, { @@ -215,17 +287,17 @@ "desc": "

      In versions of Node.js prior to 6.0.0, Buffer instances were created using the\nBuffer constructor function, which allocates the returned Buffer\ndifferently based on what arguments are provided:

      \n
        \n
      • Passing a number as the first argument to Buffer() (e.g. new Buffer(10))\nallocates a new Buffer object of the specified size. Prior to Node.js 8.0.0,\nthe memory allocated for such Buffer instances is not initialized and\ncan contain sensitive data. Such Buffer instances must be subsequently\ninitialized by using either buf.fill(0) or by writing to the\nentire Buffer before reading data from the Buffer.\nWhile this behavior is intentional to improve performance,\ndevelopment experience has demonstrated that a more explicit distinction is\nrequired between creating a fast-but-uninitialized Buffer versus creating a\nslower-but-safer Buffer. Since Node.js 8.0.0, Buffer(num) and new Buffer(num) return a Buffer with initialized memory.
      • \n
      • Passing a string, array, or Buffer as the first argument copies the\npassed object's data into the Buffer.
      • \n
      • Passing an ArrayBuffer or a SharedArrayBuffer returns a Buffer\nthat shares allocated memory with the given array buffer.
      • \n
      \n

      Because the behavior of new Buffer() is different depending on the type of the\nfirst argument, security and reliability issues can be inadvertently introduced\ninto applications when argument validation or Buffer initialization is not\nperformed.

      \n

      For example, if an attacker can cause an application to receive a number where\na string is expected, the application may call new Buffer(100)\ninstead of new Buffer(\"100\"), leading it to allocate a 100 byte buffer instead\nof allocating a 3 byte buffer with content \"100\". This is commonly possible\nusing JSON API calls. Since JSON distinguishes between numeric and string types,\nit allows injection of numbers where a naively written application that does not\nvalidate its input sufficiently might expect to always receive a string.\nBefore Node.js 8.0.0, the 100 byte buffer might contain\narbitrary pre-existing in-memory data, so may be used to expose in-memory\nsecrets to a remote attacker. Since Node.js 8.0.0, exposure of memory cannot\noccur because the data is zero-filled. However, other attacks are still\npossible, such as causing very large buffers to be allocated by the server,\nleading to performance degradation or crashing on memory exhaustion.

      \n

      To make the creation of Buffer instances more reliable and less error-prone,\nthe various forms of the new Buffer() constructor have been deprecated\nand replaced by separate Buffer.from(), Buffer.alloc(), and\nBuffer.allocUnsafe() methods.

      \n

      Developers should migrate all existing uses of the new Buffer() constructors\nto one of these new APIs.

      \n\n

      Buffer instances returned by Buffer.allocUnsafe() and\nBuffer.from(array) may be allocated off a shared internal memory pool\nif size is less than or equal to half Buffer.poolSize. Instances\nreturned by Buffer.allocUnsafeSlow() never use the shared internal\nmemory pool.

      ", "modules": [ { - "textRaw": "The `--zero-fill-buffers` command line option", - "name": "the_`--zero-fill-buffers`_command_line_option", + "textRaw": "The `--zero-fill-buffers` command-line option", + "name": "the_`--zero-fill-buffers`_command-line_option", "meta": { "added": [ "v5.10.0" ], "changes": [] }, - "desc": "

      Node.js can be started using the --zero-fill-buffers command line option to\ncause all newly-allocated Buffer instances to be zero-filled upon creation by\ndefault. Without the option, buffers created with Buffer.allocUnsafe(),\nBuffer.allocUnsafeSlow(), and new SlowBuffer(size) are not zero-filled.\nUse of this flag can have a measurable negative impact on performance. Use the\n--zero-fill-buffers option only when necessary to enforce that newly allocated\nBuffer instances cannot contain old data that is potentially sensitive.

      \n
      $ node --zero-fill-buffers\n> Buffer.allocUnsafe(5);\n<Buffer 00 00 00 00 00>\n
      ", + "desc": "

      Node.js can be started using the --zero-fill-buffers command-line option to\ncause all newly-allocated Buffer instances to be zero-filled upon creation by\ndefault. Without the option, buffers created with Buffer.allocUnsafe(),\nBuffer.allocUnsafeSlow(), and new SlowBuffer(size) are not zero-filled.\nUse of this flag can have a measurable negative impact on performance. Use the\n--zero-fill-buffers option only when necessary to enforce that newly allocated\nBuffer instances cannot contain old data that is potentially sensitive.

      \n
      $ node --zero-fill-buffers\n> Buffer.allocUnsafe(5);\n<Buffer 00 00 00 00 00>\n
      ", "type": "module", - "displayName": "The `--zero-fill-buffers` command line option" + "displayName": "The `--zero-fill-buffers` command-line option" }, { "textRaw": "What makes `Buffer.allocUnsafe()` and `Buffer.allocUnsafeSlow()` \"unsafe\"?", @@ -240,6 +312,168 @@ } ], "classes": [ + { + "textRaw": "Class: `Blob`", + "type": "class", + "name": "Blob", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "stability": 1, + "stabilityText": "Experimental", + "desc": "

      A Blob encapsulates immutable, raw data that can be safely shared across\nmultiple worker threads.

      ", + "methods": [ + { + "textRaw": "`blob.arrayBuffer()`", + "type": "method", + "name": "arrayBuffer", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {Promise}", + "name": "return", + "type": "Promise" + }, + "params": [] + } + ], + "desc": "

      Returns a promise that fulfills with an <ArrayBuffer> containing a copy of\nthe Blob data.

      " + }, + { + "textRaw": "`blob.slice([start, [end, [type]]])`", + "type": "method", + "name": "slice", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`start` {number} The starting index.", + "name": "start", + "type": "number", + "desc": "The starting index." + }, + { + "textRaw": "`end` {number} The ending index.", + "name": "end", + "type": "number", + "desc": "The ending index." + }, + { + "textRaw": "`type` {string} The content-type for the new `Blob`", + "name": "type", + "type": "string", + "desc": "The content-type for the new `Blob`" + } + ] + } + ], + "desc": "

      Creates and returns a new Blob containing a subset of this Blob objects\ndata. The original Blob is not alterered.

      " + }, + { + "textRaw": "`blob.text()`", + "type": "method", + "name": "text", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {Promise}", + "name": "return", + "type": "Promise" + }, + "params": [] + } + ], + "desc": "

      Returns a promise that resolves the contents of the Blob decoded as a UTF-8\nstring.

      " + } + ], + "properties": [ + { + "textRaw": "`blob.size`", + "name": "size", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "desc": "

      The total size of the Blob in bytes.

      " + }, + { + "textRaw": "`type` Type: {string}", + "type": "string", + "name": "Type", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "desc": "

      The content-type of the Blob.

      " + } + ], + "modules": [ + { + "textRaw": "`Blob` objects and `MessageChannel`", + "name": "`blob`_objects_and_`messagechannel`", + "desc": "

      Once a <Blob> object is created, it can be sent via MessagePort to multiple\ndestinations without transfering or immediately copying the data. The data\ncontained by the Blob is copied only when the arrayBuffer() or text()\nmethods are called.

      \n
      const { Blob } = require('buffer');\nconst blob = new Blob(['hello there']);\nconst { setTimeout: delay } = require('timers/promises');\n\nconst mc1 = new MessageChannel();\nconst mc2 = new MessageChannel();\n\nmc1.port1.onmessage = async ({ data }) => {\n  console.log(await data.arrayBuffer());\n  mc1.port1.close();\n};\n\nmc2.port1.onmessage = async ({ data }) => {\n  await delay(1000);\n  console.log(await data.arrayBuffer());\n  mc2.port1.close();\n};\n\nmc1.port2.postMessage(blob);\nmc2.port2.postMessage(blob);\n\n// The Blob is still usable after posting.\ndata.text().then(console.log);\n
      ", + "type": "module", + "displayName": "`Blob` objects and `MessageChannel`" + } + ], + "signatures": [ + { + "params": [ + { + "textRaw": "`sources` {string[]|ArrayBuffer[]|TypedArray[]|DataView[]|Blob[]} An array of string, {ArrayBuffer}, {TypedArray}, {DataView}, or {Blob} objects, or any mix of such objects, that will be stored within the `Blob`.", + "name": "sources", + "type": "string[]|ArrayBuffer[]|TypedArray[]|DataView[]|Blob[]", + "desc": "An array of string, {ArrayBuffer}, {TypedArray}, {DataView}, or {Blob} objects, or any mix of such objects, that will be stored within the `Blob`." + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`encoding` {string} The character encoding to use for string sources. **Default**: `'utf8'`.", + "name": "encoding", + "type": "string", + "desc": "The character encoding to use for string sources. **Default**: `'utf8'`." + }, + { + "textRaw": "`type` {string} The Blob content-type. The intent is for `type` to convey the MIME media type of the data, however no validation of the type format is performed.", + "name": "type", + "type": "string", + "desc": "The Blob content-type. The intent is for `type` to convey the MIME media type of the data, however no validation of the type format is performed." + } + ] + } + ], + "desc": "

      Creates a new Blob object containing a concatenation of the given sources.

      \n

      <ArrayBuffer>, <TypedArray>, <DataView>, and <Buffer> sources are copied into\nthe 'Blob' and can therefore be safely modified after the 'Blob' is created.

      \n

      String sources are also copied into the Blob.

      " + } + ] + }, { "textRaw": "Class: `Buffer`", "type": "class", @@ -400,7 +634,7 @@ ] } ], - "desc": "

      Returns the byte length of a string when encoded using encoding.\nThis is not the same as String.prototype.length, which does not account\nfor the encoding that is used to convert the string into bytes.

      \n

      For 'base64' and 'hex', this function assumes valid input. For strings that\ncontain non-base64/hex-encoded data (e.g. whitespace), the return value might be\ngreater than the length of a Buffer created from the string.

      \n
      const str = '\\u00bd + \\u00bc = \\u00be';\n\nconsole.log(`${str}: ${str.length} characters, ` +\n            `${Buffer.byteLength(str, 'utf8')} bytes`);\n// Prints: ½ + ¼ = ¾: 9 characters, 12 bytes\n
      \n

      When string is a Buffer/DataView/TypedArray/ArrayBuffer/\nSharedArrayBuffer, the byte length as reported by .byteLength\nis returned.

      " + "desc": "

      Returns the byte length of a string when encoded using encoding.\nThis is not the same as String.prototype.length, which does not account\nfor the encoding that is used to convert the string into bytes.

      \n

      For 'base64', 'base64url', and 'hex', this function assumes valid input.\nFor strings that contain non-base64/hex-encoded data (e.g. whitespace), the\nreturn value might be greater than the length of a Buffer created from the\nstring.

      \n
      const str = '\\u00bd + \\u00bc = \\u00be';\n\nconsole.log(`${str}: ${str.length} characters, ` +\n            `${Buffer.byteLength(str, 'utf8')} bytes`);\n// Prints: ½ + ¼ = ¾: 9 characters, 12 bytes\n
      \n

      When string is a Buffer/DataView/TypedArray/ArrayBuffer/\nSharedArrayBuffer, the byte length as reported by .byteLength\nis returned.

      " }, { "textRaw": "Static method: `Buffer.compare(buf1, buf2)`", @@ -542,7 +776,7 @@ ] } ], - "desc": "

      This creates a view of the ArrayBuffer without copying the underlying\nmemory. For example, when passed a reference to the .buffer property of a\nTypedArray instance, the newly created Buffer will share the same\nallocated memory as the TypedArray.

      \n
      const arr = new Uint16Array(2);\n\narr[0] = 5000;\narr[1] = 4000;\n\n// Shares memory with `arr`.\nconst buf = Buffer.from(arr.buffer);\n\nconsole.log(buf);\n// Prints: <Buffer 88 13 a0 0f>\n\n// Changing the original Uint16Array changes the Buffer also.\narr[1] = 6000;\n\nconsole.log(buf);\n// Prints: <Buffer 88 13 70 17>\n
      \n

      The optional byteOffset and length arguments specify a memory range within\nthe arrayBuffer that will be shared by the Buffer.

      \n
      const ab = new ArrayBuffer(10);\nconst buf = Buffer.from(ab, 0, 2);\n\nconsole.log(buf.length);\n// Prints: 2\n
      \n

      A TypeError will be thrown if arrayBuffer is not an ArrayBuffer or a\nSharedArrayBuffer or another type appropriate for Buffer.from()\nvariants.

      " + "desc": "

      This creates a view of the ArrayBuffer without copying the underlying\nmemory. For example, when passed a reference to the .buffer property of a\nTypedArray instance, the newly created Buffer will share the same\nallocated memory as the TypedArray's underlying ArrayBuffer.

      \n
      const arr = new Uint16Array(2);\n\narr[0] = 5000;\narr[1] = 4000;\n\n// Shares memory with `arr`.\nconst buf = Buffer.from(arr.buffer);\n\nconsole.log(buf);\n// Prints: <Buffer 88 13 a0 0f>\n\n// Changing the original Uint16Array changes the Buffer also.\narr[1] = 6000;\n\nconsole.log(buf);\n// Prints: <Buffer 88 13 70 17>\n
      \n

      The optional byteOffset and length arguments specify a memory range within\nthe arrayBuffer that will be shared by the Buffer.

      \n
      const ab = new ArrayBuffer(10);\nconst buf = Buffer.from(ab, 0, 2);\n\nconsole.log(buf.length);\n// Prints: 2\n
      \n

      A TypeError will be thrown if arrayBuffer is not an ArrayBuffer or a\nSharedArrayBuffer or another type appropriate for Buffer.from()\nvariants.

      \n

      It is important to remember that a backing ArrayBuffer can cover a range\nof memory that extends beyond the bounds of a TypedArray view. A new\nBuffer created using the buffer property of a TypedArray may extend\nbeyond the range of the TypedArray:

      \n
      const arrA = Uint8Array.from([0x63, 0x64, 0x65, 0x66]); // 4 elements\nconst arrB = new Uint8Array(arrA.buffer, 1, 2); // 2 elements\nconsole.log(arrA.buffer === arrB.buffer); // true\n\nconst buf = Buffer.from(arrB.buffer);\nconsole.log(buf);\n// Prints: <Buffer 63 64 65 66>\n
      " }, { "textRaw": "Static method: `Buffer.from(buffer)`", @@ -661,7 +895,7 @@ ] } ], - "desc": "

      Returns true if obj is a Buffer, false otherwise.

      " + "desc": "

      Returns true if obj is a Buffer, false otherwise.

      \n
      Buffer.isBuffer(Buffer.alloc(10)); // true\nBuffer.isBuffer(Buffer.from('foo')); // true\nBuffer.isBuffer('a string'); // false\nBuffer.isBuffer([]); // false\nBuffer.isBuffer(new Uint8Array(1024)); // false\n
      " }, { "textRaw": "Static method: `Buffer.isEncoding(encoding)`", @@ -711,13 +945,6 @@ "textRaw": "`[index]` `index` {integer}", "type": "integer", "name": "index", - "meta": { - "type": "property", - "name": [ - "index" - ], - "changes": [] - }, "desc": "

      The index operator [index] can be used to get and set the octet at position\nindex in buf. The values refer to individual bytes, so the legal value\nrange is between 0x00 and 0xFF (hex) or 0 and 255 (decimal).

      \n

      This operator is inherited from Uint8Array, so its behavior on out-of-bounds\naccess is the same as Uint8Array. In other words, buf[index] returns\nundefined when index is negative or greater or equal to buf.length, and\nbuf[index] = value does not modify the buffer if index is negative or\n>= buf.length.

      \n
      // Copy an ASCII string into a `Buffer` one byte at a time.\n// (This only works for ASCII-only strings. In general, one should use\n// `Buffer.from()` to perform this conversion.)\n\nconst str = 'Node.js';\nconst buf = Buffer.allocUnsafe(str.length);\n\nfor (let i = 0; i < str.length; i++) {\n  buf[i] = str.charCodeAt(i);\n}\n\nconsole.log(buf.toString('utf8'));\n// Prints: Node.js\n
      " }, { @@ -878,7 +1105,7 @@ ] } ], - "desc": "

      Copies data from a region of buf to a region in target, even if the target\nmemory region overlaps with buf.

      \n

      TypedArray#set() performs the same operation, and is available for all\nTypedArrays, including Node.js Buffers, although it takes different\nfunction arguments.

      \n
      // Create two `Buffer` instances.\nconst buf1 = Buffer.allocUnsafe(26);\nconst buf2 = Buffer.allocUnsafe(26).fill('!');\n\nfor (let i = 0; i < 26; i++) {\n  // 97 is the decimal ASCII value for 'a'.\n  buf1[i] = i + 97;\n}\n\n// Copy `buf1` bytes 16 through 19 into `buf2` starting at byte 8 of `buf2`.\nbuf1.copy(buf2, 8, 16, 20);\n// This is equivalent to:\n// buf2.set(buf1.subarray(16, 20), 8);\n\nconsole.log(buf2.toString('ascii', 0, 25));\n// Prints: !!!!!!!!qrst!!!!!!!!!!!!!\n
      \n
      // Create a `Buffer` and copy data from one region to an overlapping region\n// within the same `Buffer`.\n\nconst buf = Buffer.allocUnsafe(26);\n\nfor (let i = 0; i < 26; i++) {\n  // 97 is the decimal ASCII value for 'a'.\n  buf[i] = i + 97;\n}\n\nbuf.copy(buf, 0, 4, 10);\n\nconsole.log(buf.toString());\n// Prints: efghijghijklmnopqrstuvwxyz\n
      " + "desc": "

      Copies data from a region of buf to a region in target, even if the target\nmemory region overlaps with buf.

      \n

      TypedArray.prototype.set() performs the same operation, and is available\nfor all TypedArrays, including Node.js Buffers, although it takes\ndifferent function arguments.

      \n
      // Create two `Buffer` instances.\nconst buf1 = Buffer.allocUnsafe(26);\nconst buf2 = Buffer.allocUnsafe(26).fill('!');\n\nfor (let i = 0; i < 26; i++) {\n  // 97 is the decimal ASCII value for 'a'.\n  buf1[i] = i + 97;\n}\n\n// Copy `buf1` bytes 16 through 19 into `buf2` starting at byte 8 of `buf2`.\nbuf1.copy(buf2, 8, 16, 20);\n// This is equivalent to:\n// buf2.set(buf1.subarray(16, 20), 8);\n\nconsole.log(buf2.toString('ascii', 0, 25));\n// Prints: !!!!!!!!qrst!!!!!!!!!!!!!\n
      \n
      // Create a `Buffer` and copy data from one region to an overlapping region\n// within the same `Buffer`.\n\nconst buf = Buffer.allocUnsafe(26);\n\nfor (let i = 0; i < 26; i++) {\n  // 97 is the decimal ASCII value for 'a'.\n  buf[i] = i + 97;\n}\n\nbuf.copy(buf, 0, 4, 10);\n\nconsole.log(buf.toString());\n// Prints: efghijghijklmnopqrstuvwxyz\n
      " }, { "textRaw": "`buf.entries()`", @@ -1073,7 +1300,10 @@ "description": "The `value` can now be a `Uint8Array`." }, { - "version": "v5.7.0, v4.4.0", + "version": [ + "v5.7.0", + "v4.4.0" + ], "pr-url": "https://github.com/nodejs/node/pull/4803", "description": "When `encoding` is being passed, the `byteOffset` parameter is no longer required." } @@ -1111,7 +1341,7 @@ ] } ], - "desc": "

      If value is:

      \n
        \n
      • a string, value is interpreted according to the character encoding in\nencoding.
      • \n
      • a Buffer or Uint8Array, value will be used in its entirety.\nTo compare a partial Buffer, use buf.slice().
      • \n
      • a number, value will be interpreted as an unsigned 8-bit integer\nvalue between 0 and 255.
      • \n
      \n
      const buf = Buffer.from('this is a buffer');\n\nconsole.log(buf.indexOf('this'));\n// Prints: 0\nconsole.log(buf.indexOf('is'));\n// Prints: 2\nconsole.log(buf.indexOf(Buffer.from('a buffer')));\n// Prints: 8\nconsole.log(buf.indexOf(97));\n// Prints: 8 (97 is the decimal ASCII value for 'a')\nconsole.log(buf.indexOf(Buffer.from('a buffer example')));\n// Prints: -1\nconsole.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8)));\n// Prints: 8\n\nconst utf16Buffer = Buffer.from('\\u039a\\u0391\\u03a3\\u03a3\\u0395', 'utf16le');\n\nconsole.log(utf16Buffer.indexOf('\\u03a3', 0, 'utf16le'));\n// Prints: 4\nconsole.log(utf16Buffer.indexOf('\\u03a3', -4, 'utf16le'));\n// Prints: 6\n
      \n

      If value is not a string, number, or Buffer, this method will throw a\nTypeError. If value is a number, it will be coerced to a valid byte value,\nan integer between 0 and 255.

      \n

      If byteOffset is not a number, it will be coerced to a number. If the result\nof coercion is NaN or 0, then the entire buffer will be searched. This\nbehavior matches String#indexOf().

      \n
      const b = Buffer.from('abcdef');\n\n// Passing a value that's a number, but not a valid byte.\n// Prints: 2, equivalent to searching for 99 or 'c'.\nconsole.log(b.indexOf(99.9));\nconsole.log(b.indexOf(256 + 99));\n\n// Passing a byteOffset that coerces to NaN or 0.\n// Prints: 1, searching the whole buffer.\nconsole.log(b.indexOf('b', undefined));\nconsole.log(b.indexOf('b', {}));\nconsole.log(b.indexOf('b', null));\nconsole.log(b.indexOf('b', []));\n
      \n

      If value is an empty string or empty Buffer and byteOffset is less\nthan buf.length, byteOffset will be returned. If value is empty and\nbyteOffset is at least buf.length, buf.length will be returned.

      " + "desc": "

      If value is:

      \n
        \n
      • a string, value is interpreted according to the character encoding in\nencoding.
      • \n
      • a Buffer or Uint8Array, value will be used in its entirety.\nTo compare a partial Buffer, use buf.slice().
      • \n
      • a number, value will be interpreted as an unsigned 8-bit integer\nvalue between 0 and 255.
      • \n
      \n
      const buf = Buffer.from('this is a buffer');\n\nconsole.log(buf.indexOf('this'));\n// Prints: 0\nconsole.log(buf.indexOf('is'));\n// Prints: 2\nconsole.log(buf.indexOf(Buffer.from('a buffer')));\n// Prints: 8\nconsole.log(buf.indexOf(97));\n// Prints: 8 (97 is the decimal ASCII value for 'a')\nconsole.log(buf.indexOf(Buffer.from('a buffer example')));\n// Prints: -1\nconsole.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8)));\n// Prints: 8\n\nconst utf16Buffer = Buffer.from('\\u039a\\u0391\\u03a3\\u03a3\\u0395', 'utf16le');\n\nconsole.log(utf16Buffer.indexOf('\\u03a3', 0, 'utf16le'));\n// Prints: 4\nconsole.log(utf16Buffer.indexOf('\\u03a3', -4, 'utf16le'));\n// Prints: 6\n
      \n

      If value is not a string, number, or Buffer, this method will throw a\nTypeError. If value is a number, it will be coerced to a valid byte value,\nan integer between 0 and 255.

      \n

      If byteOffset is not a number, it will be coerced to a number. If the result\nof coercion is NaN or 0, then the entire buffer will be searched. This\nbehavior matches String.prototype.indexOf().

      \n
      const b = Buffer.from('abcdef');\n\n// Passing a value that's a number, but not a valid byte.\n// Prints: 2, equivalent to searching for 99 or 'c'.\nconsole.log(b.indexOf(99.9));\nconsole.log(b.indexOf(256 + 99));\n\n// Passing a byteOffset that coerces to NaN or 0.\n// Prints: 1, searching the whole buffer.\nconsole.log(b.indexOf('b', undefined));\nconsole.log(b.indexOf('b', {}));\nconsole.log(b.indexOf('b', null));\nconsole.log(b.indexOf('b', []));\n
      \n

      If value is an empty string or empty Buffer and byteOffset is less\nthan buf.length, byteOffset will be returned. If value is empty and\nbyteOffset is at least buf.length, buf.length will be returned.

      " }, { "textRaw": "`buf.keys()`", @@ -1183,7 +1413,7 @@ ] } ], - "desc": "

      Identical to buf.indexOf(), except the last occurrence of value is found\nrather than the first occurrence.

      \n
      const buf = Buffer.from('this buffer is a buffer');\n\nconsole.log(buf.lastIndexOf('this'));\n// Prints: 0\nconsole.log(buf.lastIndexOf('buffer'));\n// Prints: 17\nconsole.log(buf.lastIndexOf(Buffer.from('buffer')));\n// Prints: 17\nconsole.log(buf.lastIndexOf(97));\n// Prints: 15 (97 is the decimal ASCII value for 'a')\nconsole.log(buf.lastIndexOf(Buffer.from('yolo')));\n// Prints: -1\nconsole.log(buf.lastIndexOf('buffer', 5));\n// Prints: 5\nconsole.log(buf.lastIndexOf('buffer', 4));\n// Prints: -1\n\nconst utf16Buffer = Buffer.from('\\u039a\\u0391\\u03a3\\u03a3\\u0395', 'utf16le');\n\nconsole.log(utf16Buffer.lastIndexOf('\\u03a3', undefined, 'utf16le'));\n// Prints: 6\nconsole.log(utf16Buffer.lastIndexOf('\\u03a3', -5, 'utf16le'));\n// Prints: 4\n
      \n

      If value is not a string, number, or Buffer, this method will throw a\nTypeError. If value is a number, it will be coerced to a valid byte value,\nan integer between 0 and 255.

      \n

      If byteOffset is not a number, it will be coerced to a number. Any arguments\nthat coerce to NaN, like {} or undefined, will search the whole buffer.\nThis behavior matches String#lastIndexOf().

      \n
      const b = Buffer.from('abcdef');\n\n// Passing a value that's a number, but not a valid byte.\n// Prints: 2, equivalent to searching for 99 or 'c'.\nconsole.log(b.lastIndexOf(99.9));\nconsole.log(b.lastIndexOf(256 + 99));\n\n// Passing a byteOffset that coerces to NaN.\n// Prints: 1, searching the whole buffer.\nconsole.log(b.lastIndexOf('b', undefined));\nconsole.log(b.lastIndexOf('b', {}));\n\n// Passing a byteOffset that coerces to 0.\n// Prints: -1, equivalent to passing 0.\nconsole.log(b.lastIndexOf('b', null));\nconsole.log(b.lastIndexOf('b', []));\n
      \n

      If value is an empty string or empty Buffer, byteOffset will be returned.

      " + "desc": "

      Identical to buf.indexOf(), except the last occurrence of value is found\nrather than the first occurrence.

      \n
      const buf = Buffer.from('this buffer is a buffer');\n\nconsole.log(buf.lastIndexOf('this'));\n// Prints: 0\nconsole.log(buf.lastIndexOf('buffer'));\n// Prints: 17\nconsole.log(buf.lastIndexOf(Buffer.from('buffer')));\n// Prints: 17\nconsole.log(buf.lastIndexOf(97));\n// Prints: 15 (97 is the decimal ASCII value for 'a')\nconsole.log(buf.lastIndexOf(Buffer.from('yolo')));\n// Prints: -1\nconsole.log(buf.lastIndexOf('buffer', 5));\n// Prints: 5\nconsole.log(buf.lastIndexOf('buffer', 4));\n// Prints: -1\n\nconst utf16Buffer = Buffer.from('\\u039a\\u0391\\u03a3\\u03a3\\u0395', 'utf16le');\n\nconsole.log(utf16Buffer.lastIndexOf('\\u03a3', undefined, 'utf16le'));\n// Prints: 6\nconsole.log(utf16Buffer.lastIndexOf('\\u03a3', -5, 'utf16le'));\n// Prints: 4\n
      \n

      If value is not a string, number, or Buffer, this method will throw a\nTypeError. If value is a number, it will be coerced to a valid byte value,\nan integer between 0 and 255.

      \n

      If byteOffset is not a number, it will be coerced to a number. Any arguments\nthat coerce to NaN, like {} or undefined, will search the whole buffer.\nThis behavior matches String.prototype.lastIndexOf().

      \n
      const b = Buffer.from('abcdef');\n\n// Passing a value that's a number, but not a valid byte.\n// Prints: 2, equivalent to searching for 99 or 'c'.\nconsole.log(b.lastIndexOf(99.9));\nconsole.log(b.lastIndexOf(256 + 99));\n\n// Passing a byteOffset that coerces to NaN.\n// Prints: 1, searching the whole buffer.\nconsole.log(b.lastIndexOf('b', undefined));\nconsole.log(b.lastIndexOf('b', {}));\n\n// Passing a byteOffset that coerces to 0.\n// Prints: -1, equivalent to passing 0.\nconsole.log(b.lastIndexOf('b', null));\nconsole.log(b.lastIndexOf('b', []));\n
      \n

      If value is an empty string or empty Buffer, byteOffset will be returned.

      " }, { "textRaw": "`buf.readBigInt64BE([offset])`", @@ -1222,7 +1452,8 @@ "name": "readBigInt64LE", "meta": { "added": [ - "v12.0.0" + "v12.0.0", + "v10.20.0" ], "changes": [] }, @@ -1252,11 +1483,12 @@ "name": "readBigUInt64BE", "meta": { "added": [ - "v12.0.0" + "v12.0.0", + "v10.20.0" ], "changes": [ { - "version": "v12.19.0", + "version": "v14.10.0", "pr-url": "https://github.com/nodejs/node/pull/34960", "description": "This function is also available as `buf.readBigUint64BE()`." } @@ -1280,7 +1512,7 @@ ] } ], - "desc": "

      Reads an unsigned, big-endian 64-bit integer from buf at the specified\noffset.

      \n
      const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);\n\nconsole.log(buf.readBigUInt64BE(0));\n// Prints: 4294967295n\n
      " + "desc": "

      Reads an unsigned, big-endian 64-bit integer from buf at the specified\noffset.

      \n

      This function is also available under the readBigUint64BE alias.

      \n
      const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);\n\nconsole.log(buf.readBigUInt64BE(0));\n// Prints: 4294967295n\n
      " }, { "textRaw": "`buf.readBigUInt64LE([offset])`", @@ -1293,7 +1525,10 @@ ], "changes": [ { - "version": "v12.19.0", + "version": [ + "v14.10.0", + "v12.19.0" + ], "pr-url": "https://github.com/nodejs/node/pull/34960", "description": "This function is also available as `buf.readBigUint64LE()`." } @@ -1317,7 +1552,7 @@ ] } ], - "desc": "

      Reads an unsigned, little-endian 64-bit integer from buf at the specified\noffset.

      \n
      const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);\n\nconsole.log(buf.readBigUInt64LE(0));\n// Prints: 18446744069414584320n\n
      " + "desc": "

      Reads an unsigned, little-endian 64-bit integer from buf at the specified\noffset.

      \n

      This function is also available under the readBigUint64LE alias.

      \n
      const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]);\n\nconsole.log(buf.readBigUInt64LE(0));\n// Prints: 18446744069414584320n\n
      " }, { "textRaw": "`buf.readDoubleBE([offset])`", @@ -1735,7 +1970,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.readUint8()`." }, @@ -1764,7 +1999,7 @@ ] } ], - "desc": "

      Reads an unsigned 8-bit integer from buf at the specified offset.

      \n
      const buf = Buffer.from([1, -2]);\n\nconsole.log(buf.readUInt8(0));\n// Prints: 1\nconsole.log(buf.readUInt8(1));\n// Prints: 254\nconsole.log(buf.readUInt8(2));\n// Throws ERR_OUT_OF_RANGE.\n
      " + "desc": "

      Reads an unsigned 8-bit integer from buf at the specified offset.

      \n

      This function is also available under the readUint8 alias.

      \n
      const buf = Buffer.from([1, -2]);\n\nconsole.log(buf.readUInt8(0));\n// Prints: 1\nconsole.log(buf.readUInt8(1));\n// Prints: 254\nconsole.log(buf.readUInt8(2));\n// Throws ERR_OUT_OF_RANGE.\n
      " }, { "textRaw": "`buf.readUInt16BE([offset])`", @@ -1776,7 +2011,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.readUint16BE()`." }, @@ -1805,7 +2040,7 @@ ] } ], - "desc": "

      Reads an unsigned, big-endian 16-bit integer from buf at the specified\noffset.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56]);\n\nconsole.log(buf.readUInt16BE(0).toString(16));\n// Prints: 1234\nconsole.log(buf.readUInt16BE(1).toString(16));\n// Prints: 3456\n
      " + "desc": "

      Reads an unsigned, big-endian 16-bit integer from buf at the specified\noffset.

      \n

      This function is also available under the readUint16BE alias.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56]);\n\nconsole.log(buf.readUInt16BE(0).toString(16));\n// Prints: 1234\nconsole.log(buf.readUInt16BE(1).toString(16));\n// Prints: 3456\n
      " }, { "textRaw": "`buf.readUInt16LE([offset])`", @@ -1817,7 +2052,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.readUint16LE()`." }, @@ -1846,7 +2081,7 @@ ] } ], - "desc": "

      Reads an unsigned, little-endian 16-bit integer from buf at the specified\noffset.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56]);\n\nconsole.log(buf.readUInt16LE(0).toString(16));\n// Prints: 3412\nconsole.log(buf.readUInt16LE(1).toString(16));\n// Prints: 5634\nconsole.log(buf.readUInt16LE(2).toString(16));\n// Throws ERR_OUT_OF_RANGE.\n
      " + "desc": "

      Reads an unsigned, little-endian 16-bit integer from buf at the specified\noffset.

      \n

      This function is also available under the readUint16LE alias.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56]);\n\nconsole.log(buf.readUInt16LE(0).toString(16));\n// Prints: 3412\nconsole.log(buf.readUInt16LE(1).toString(16));\n// Prints: 5634\nconsole.log(buf.readUInt16LE(2).toString(16));\n// Throws ERR_OUT_OF_RANGE.\n
      " }, { "textRaw": "`buf.readUInt32BE([offset])`", @@ -1858,7 +2093,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.readUint32BE()`." }, @@ -1887,7 +2122,7 @@ ] } ], - "desc": "

      Reads an unsigned, big-endian 32-bit integer from buf at the specified\noffset.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]);\n\nconsole.log(buf.readUInt32BE(0).toString(16));\n// Prints: 12345678\n
      " + "desc": "

      Reads an unsigned, big-endian 32-bit integer from buf at the specified\noffset.

      \n

      This function is also available under the readUint32BE alias.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]);\n\nconsole.log(buf.readUInt32BE(0).toString(16));\n// Prints: 12345678\n
      " }, { "textRaw": "`buf.readUInt32LE([offset])`", @@ -1899,7 +2134,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.readUint32LE()`." }, @@ -1928,7 +2163,7 @@ ] } ], - "desc": "

      Reads an unsigned, little-endian 32-bit integer from buf at the specified\noffset.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]);\n\nconsole.log(buf.readUInt32LE(0).toString(16));\n// Prints: 78563412\nconsole.log(buf.readUInt32LE(1).toString(16));\n// Throws ERR_OUT_OF_RANGE.\n
      " + "desc": "

      Reads an unsigned, little-endian 32-bit integer from buf at the specified\noffset.

      \n

      This function is also available under the readUint32LE alias.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]);\n\nconsole.log(buf.readUInt32LE(0).toString(16));\n// Prints: 78563412\nconsole.log(buf.readUInt32LE(1).toString(16));\n// Throws ERR_OUT_OF_RANGE.\n
      " }, { "textRaw": "`buf.readUIntBE(offset, byteLength)`", @@ -1940,7 +2175,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.readUintBE()`." }, @@ -1974,7 +2209,7 @@ ] } ], - "desc": "

      Reads byteLength number of bytes from buf at the specified offset\nand interprets the result as an unsigned big-endian integer supporting\nup to 48 bits of accuracy.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);\n\nconsole.log(buf.readUIntBE(0, 6).toString(16));\n// Prints: 1234567890ab\nconsole.log(buf.readUIntBE(1, 6).toString(16));\n// Throws ERR_OUT_OF_RANGE.\n
      " + "desc": "

      Reads byteLength number of bytes from buf at the specified offset\nand interprets the result as an unsigned big-endian integer supporting\nup to 48 bits of accuracy.

      \n

      This function is also available under the readUintBE alias.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);\n\nconsole.log(buf.readUIntBE(0, 6).toString(16));\n// Prints: 1234567890ab\nconsole.log(buf.readUIntBE(1, 6).toString(16));\n// Throws ERR_OUT_OF_RANGE.\n
      " }, { "textRaw": "`buf.readUIntLE(offset, byteLength)`", @@ -1986,7 +2221,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.readUintLE()`." }, @@ -2020,7 +2255,7 @@ ] } ], - "desc": "

      Reads byteLength number of bytes from buf at the specified offset\nand interprets the result as an unsigned, little-endian integer supporting\nup to 48 bits of accuracy.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);\n\nconsole.log(buf.readUIntLE(0, 6).toString(16));\n// Prints: ab9078563412\n
      " + "desc": "

      Reads byteLength number of bytes from buf at the specified offset\nand interprets the result as an unsigned, little-endian integer supporting\nup to 48 bits of accuracy.

      \n

      This function is also available under the readUintLE alias.

      \n
      const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]);\n\nconsole.log(buf.readUIntLE(0, 6).toString(16));\n// Prints: ab9078563412\n
      " }, { "textRaw": "`buf.subarray([start[, end]])`", @@ -2057,7 +2292,7 @@ ] } ], - "desc": "

      Returns a new Buffer that references the same memory as the original, but\noffset and cropped by the start and end indices.

      \n

      Specifying end greater than buf.length will return the same result as\nthat of end equal to buf.length.

      \n

      This method is inherited from TypedArray#subarray().

      \n

      Modifying the new Buffer slice will modify the memory in the original Buffer\nbecause the allocated memory of the two objects overlap.

      \n
      // Create a `Buffer` with the ASCII alphabet, take a slice, and modify one byte\n// from the original `Buffer`.\n\nconst buf1 = Buffer.allocUnsafe(26);\n\nfor (let i = 0; i < 26; i++) {\n  // 97 is the decimal ASCII value for 'a'.\n  buf1[i] = i + 97;\n}\n\nconst buf2 = buf1.subarray(0, 3);\n\nconsole.log(buf2.toString('ascii', 0, buf2.length));\n// Prints: abc\n\nbuf1[0] = 33;\n\nconsole.log(buf2.toString('ascii', 0, buf2.length));\n// Prints: !bc\n
      \n

      Specifying negative indexes causes the slice to be generated relative to the\nend of buf rather than the beginning.

      \n
      const buf = Buffer.from('buffer');\n\nconsole.log(buf.subarray(-6, -1).toString());\n// Prints: buffe\n// (Equivalent to buf.subarray(0, 5).)\n\nconsole.log(buf.subarray(-6, -2).toString());\n// Prints: buff\n// (Equivalent to buf.subarray(0, 4).)\n\nconsole.log(buf.subarray(-5, -2).toString());\n// Prints: uff\n// (Equivalent to buf.subarray(1, 4).)\n
      " + "desc": "

      Returns a new Buffer that references the same memory as the original, but\noffset and cropped by the start and end indices.

      \n

      Specifying end greater than buf.length will return the same result as\nthat of end equal to buf.length.

      \n

      This method is inherited from TypedArray.prototype.subarray().

      \n

      Modifying the new Buffer slice will modify the memory in the original Buffer\nbecause the allocated memory of the two objects overlap.

      \n
      // Create a `Buffer` with the ASCII alphabet, take a slice, and modify one byte\n// from the original `Buffer`.\n\nconst buf1 = Buffer.allocUnsafe(26);\n\nfor (let i = 0; i < 26; i++) {\n  // 97 is the decimal ASCII value for 'a'.\n  buf1[i] = i + 97;\n}\n\nconst buf2 = buf1.subarray(0, 3);\n\nconsole.log(buf2.toString('ascii', 0, buf2.length));\n// Prints: abc\n\nbuf1[0] = 33;\n\nconsole.log(buf2.toString('ascii', 0, buf2.length));\n// Prints: !bc\n
      \n

      Specifying negative indexes causes the slice to be generated relative to the\nend of buf rather than the beginning.

      \n
      const buf = Buffer.from('buffer');\n\nconsole.log(buf.subarray(-6, -1).toString());\n// Prints: buffe\n// (Equivalent to buf.subarray(0, 5).)\n\nconsole.log(buf.subarray(-6, -2).toString());\n// Prints: buff\n// (Equivalent to buf.subarray(0, 4).)\n\nconsole.log(buf.subarray(-5, -2).toString());\n// Prints: uff\n// (Equivalent to buf.subarray(1, 4).)\n
      " }, { "textRaw": "`buf.slice([start[, end]])`", @@ -2069,7 +2304,10 @@ ], "changes": [ { - "version": "v7.1.0, v6.9.2", + "version": [ + "v7.1.0", + "v6.9.2" + ], "pr-url": "https://github.com/nodejs/node/pull/9341", "description": "Coercing the offsets to integers now handles values outside the 32-bit integer range properly." }, @@ -2321,7 +2559,8 @@ "name": "writeBigInt64BE", "meta": { "added": [ - "v12.0.0" + "v12.0.0", + "v10.20.0" ], "changes": [] }, @@ -2401,7 +2640,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.10.0", "pr-url": "https://github.com/nodejs/node/pull/34960", "description": "This function is also available as `buf.writeBigUint64BE()`." } @@ -2432,7 +2671,7 @@ ] } ], - "desc": "

      Writes value to buf at the specified offset as big-endian.

      \n
      const buf = Buffer.allocUnsafe(8);\n\nbuf.writeBigUInt64BE(0xdecafafecacefaden, 0);\n\nconsole.log(buf);\n// Prints: <Buffer de ca fa fe ca ce fa de>\n
      " + "desc": "

      Writes value to buf at the specified offset as big-endian.

      \n

      This function is also available under the writeBigUint64BE alias.

      \n
      const buf = Buffer.allocUnsafe(8);\n\nbuf.writeBigUInt64BE(0xdecafafecacefaden, 0);\n\nconsole.log(buf);\n// Prints: <Buffer de ca fa fe ca ce fa de>\n
      " }, { "textRaw": "`buf.writeBigUInt64LE(value[, offset])`", @@ -2440,11 +2679,12 @@ "name": "writeBigUInt64LE", "meta": { "added": [ - "v12.0.0" + "v12.0.0", + "v10.20.0" ], "changes": [ { - "version": "v12.19.0", + "version": "v14.10.0", "pr-url": "https://github.com/nodejs/node/pull/34960", "description": "This function is also available as `buf.writeBigUint64LE()`." } @@ -2475,7 +2715,7 @@ ] } ], - "desc": "

      Writes value to buf at the specified offset as little-endian

      \n
      const buf = Buffer.allocUnsafe(8);\n\nbuf.writeBigUInt64LE(0xdecafafecacefaden, 0);\n\nconsole.log(buf);\n// Prints: <Buffer de fa ce ca fe fa ca de>\n
      " + "desc": "

      Writes value to buf at the specified offset as little-endian

      \n
      const buf = Buffer.allocUnsafe(8);\n\nbuf.writeBigUInt64LE(0xdecafafecacefaden, 0);\n\nconsole.log(buf);\n// Prints: <Buffer de fa ce ca fe fa ca de>\n
      \n

      This function is also available under the writeBigUint64LE alias.

      " }, { "textRaw": "`buf.writeDoubleBE(value[, offset])`", @@ -2604,7 +2844,7 @@ ] } ], - "desc": "

      Writes value to buf at the specified offset as big-endian. Behavior is\nundefined when value is anything other than a JavaScript number.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeFloatBE(0xcafebabe, 0);\n\nconsole.log(buf);\n// Prints: <Buffer 4f 4a fe bb>\n\n
      " + "desc": "

      Writes value to buf at the specified offset as big-endian. Behavior is\nundefined when value is anything other than a JavaScript number.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeFloatBE(0xcafebabe, 0);\n\nconsole.log(buf);\n// Prints: <Buffer 4f 4a fe bb>\n
      " }, { "textRaw": "`buf.writeFloatLE(value[, offset])`", @@ -2910,7 +3150,7 @@ ] } ], - "desc": "

      Writes byteLength bytes of value to buf at the specified offset\nas big-endian. Supports up to 48 bits of accuracy. Behavior is undefined when\nvalue is anything other than a signed integer.

      \n
      const buf = Buffer.allocUnsafe(6);\n\nbuf.writeIntBE(0x1234567890ab, 0, 6);\n\nconsole.log(buf);\n// Prints: <Buffer 12 34 56 78 90 ab>\n\n
      " + "desc": "

      Writes byteLength bytes of value to buf at the specified offset\nas big-endian. Supports up to 48 bits of accuracy. Behavior is undefined when\nvalue is anything other than a signed integer.

      \n
      const buf = Buffer.allocUnsafe(6);\n\nbuf.writeIntBE(0x1234567890ab, 0, 6);\n\nconsole.log(buf);\n// Prints: <Buffer 12 34 56 78 90 ab>\n
      " }, { "textRaw": "`buf.writeIntLE(value, offset, byteLength)`", @@ -2970,7 +3210,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.writeUint8()`." }, @@ -3006,7 +3246,7 @@ ] } ], - "desc": "

      Writes value to buf at the specified offset. value must be a\nvalid unsigned 8-bit integer. Behavior is undefined when value is anything\nother than an unsigned 8-bit integer.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeUInt8(0x3, 0);\nbuf.writeUInt8(0x4, 1);\nbuf.writeUInt8(0x23, 2);\nbuf.writeUInt8(0x42, 3);\n\nconsole.log(buf);\n// Prints: <Buffer 03 04 23 42>\n
      " + "desc": "

      Writes value to buf at the specified offset. value must be a\nvalid unsigned 8-bit integer. Behavior is undefined when value is anything\nother than an unsigned 8-bit integer.

      \n

      This function is also available under the writeUint8 alias.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeUInt8(0x3, 0);\nbuf.writeUInt8(0x4, 1);\nbuf.writeUInt8(0x23, 2);\nbuf.writeUInt8(0x42, 3);\n\nconsole.log(buf);\n// Prints: <Buffer 03 04 23 42>\n
      " }, { "textRaw": "`buf.writeUInt16BE(value[, offset])`", @@ -3018,7 +3258,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.writeUint16BE()`." }, @@ -3054,7 +3294,7 @@ ] } ], - "desc": "

      Writes value to buf at the specified offset as big-endian. The value\nmust be a valid unsigned 16-bit integer. Behavior is undefined when value\nis anything other than an unsigned 16-bit integer.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeUInt16BE(0xdead, 0);\nbuf.writeUInt16BE(0xbeef, 2);\n\nconsole.log(buf);\n// Prints: <Buffer de ad be ef>\n
      " + "desc": "

      Writes value to buf at the specified offset as big-endian. The value\nmust be a valid unsigned 16-bit integer. Behavior is undefined when value\nis anything other than an unsigned 16-bit integer.

      \n

      This function is also available under the writeUint16BE alias.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeUInt16BE(0xdead, 0);\nbuf.writeUInt16BE(0xbeef, 2);\n\nconsole.log(buf);\n// Prints: <Buffer de ad be ef>\n
      " }, { "textRaw": "`buf.writeUInt16LE(value[, offset])`", @@ -3066,7 +3306,10 @@ ], "changes": [ { - "version": "v12.19.0", + "version": [ + "v14.9.0", + "v12.19.0" + ], "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.writeUint16LE()`." }, @@ -3102,7 +3345,7 @@ ] } ], - "desc": "

      Writes value to buf at the specified offset as little-endian. The value\nmust be a valid unsigned 16-bit integer. Behavior is undefined when value is\nanything other than an unsigned 16-bit integer.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeUInt16LE(0xdead, 0);\nbuf.writeUInt16LE(0xbeef, 2);\n\nconsole.log(buf);\n// Prints: <Buffer ad de ef be>\n
      " + "desc": "

      Writes value to buf at the specified offset as little-endian. The value\nmust be a valid unsigned 16-bit integer. Behavior is undefined when value is\nanything other than an unsigned 16-bit integer.

      \n

      This function is also available under the writeUint16LE alias.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeUInt16LE(0xdead, 0);\nbuf.writeUInt16LE(0xbeef, 2);\n\nconsole.log(buf);\n// Prints: <Buffer ad de ef be>\n
      " }, { "textRaw": "`buf.writeUInt32BE(value[, offset])`", @@ -3114,7 +3357,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.writeUint32BE()`." }, @@ -3150,7 +3393,7 @@ ] } ], - "desc": "

      Writes value to buf at the specified offset as big-endian. The value\nmust be a valid unsigned 32-bit integer. Behavior is undefined when value\nis anything other than an unsigned 32-bit integer.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeUInt32BE(0xfeedface, 0);\n\nconsole.log(buf);\n// Prints: <Buffer fe ed fa ce>\n
      " + "desc": "

      Writes value to buf at the specified offset as big-endian. The value\nmust be a valid unsigned 32-bit integer. Behavior is undefined when value\nis anything other than an unsigned 32-bit integer.

      \n

      This function is also available under the writeUint32BE alias.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeUInt32BE(0xfeedface, 0);\n\nconsole.log(buf);\n// Prints: <Buffer fe ed fa ce>\n
      " }, { "textRaw": "`buf.writeUInt32LE(value[, offset])`", @@ -3162,7 +3405,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.writeUint32LE()`." }, @@ -3198,7 +3441,7 @@ ] } ], - "desc": "

      Writes value to buf at the specified offset as little-endian. The value\nmust be a valid unsigned 32-bit integer. Behavior is undefined when value is\nanything other than an unsigned 32-bit integer.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeUInt32LE(0xfeedface, 0);\n\nconsole.log(buf);\n// Prints: <Buffer ce fa ed fe>\n
      " + "desc": "

      Writes value to buf at the specified offset as little-endian. The value\nmust be a valid unsigned 32-bit integer. Behavior is undefined when value is\nanything other than an unsigned 32-bit integer.

      \n

      This function is also available under the writeUint32LE alias.

      \n
      const buf = Buffer.allocUnsafe(4);\n\nbuf.writeUInt32LE(0xfeedface, 0);\n\nconsole.log(buf);\n// Prints: <Buffer ce fa ed fe>\n
      " }, { "textRaw": "`buf.writeUIntBE(value, offset, byteLength)`", @@ -3210,7 +3453,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.writeUintBE()`." }, @@ -3251,7 +3494,7 @@ ] } ], - "desc": "

      Writes byteLength bytes of value to buf at the specified offset\nas big-endian. Supports up to 48 bits of accuracy. Behavior is undefined\nwhen value is anything other than an unsigned integer.

      \n
      const buf = Buffer.allocUnsafe(6);\n\nbuf.writeUIntBE(0x1234567890ab, 0, 6);\n\nconsole.log(buf);\n// Prints: <Buffer 12 34 56 78 90 ab>\n
      " + "desc": "

      Writes byteLength bytes of value to buf at the specified offset\nas big-endian. Supports up to 48 bits of accuracy. Behavior is undefined\nwhen value is anything other than an unsigned integer.

      \n

      This function is also available under the writeUintBE alias.

      \n
      const buf = Buffer.allocUnsafe(6);\n\nbuf.writeUIntBE(0x1234567890ab, 0, 6);\n\nconsole.log(buf);\n// Prints: <Buffer 12 34 56 78 90 ab>\n
      " }, { "textRaw": "`buf.writeUIntLE(value, offset, byteLength)`", @@ -3263,7 +3506,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.9.0", "pr-url": "https://github.com/nodejs/node/pull/34729", "description": "This function is also available as `buf.writeUintLE()`." }, @@ -3304,7 +3547,7 @@ ] } ], - "desc": "

      Writes byteLength bytes of value to buf at the specified offset\nas little-endian. Supports up to 48 bits of accuracy. Behavior is undefined\nwhen value is anything other than an unsigned integer.

      \n
      const buf = Buffer.allocUnsafe(6);\n\nbuf.writeUIntLE(0x1234567890ab, 0, 6);\n\nconsole.log(buf);\n// Prints: <Buffer ab 90 78 56 34 12>\n
      " + "desc": "

      Writes byteLength bytes of value to buf at the specified offset\nas little-endian. Supports up to 48 bits of accuracy. Behavior is undefined\nwhen value is anything other than an unsigned integer.

      \n

      This function is also available under the writeUintLE alias.

      \n
      const buf = Buffer.allocUnsafe(6);\n\nbuf.writeUIntLE(0x1234567890ab, 0, 6);\n\nconsole.log(buf);\n// Prints: <Buffer ab 90 78 56 34 12>\n
      " } ], "signatures": [ diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 36fa358bcc3c01a78499cf33e6005969477edb7f..60c857f78e7c0e9710ee5fdd469f7b73a4ee721a 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -50,6 +50,9 @@ const buf7 = Buffer.from('tést', 'latin1'); ## Buffers and character encodings + +> Stability: 1 - Experimental + +A [`Blob`][] encapsulates immutable, raw data that can be safely shared across +multiple worker threads. + +### `new buffer.Blob([sources[, options]])` + + +* `sources` {string[]|ArrayBuffer[]|TypedArray[]|DataView[]|Blob[]} An array + of string, {ArrayBuffer}, {TypedArray}, {DataView}, or {Blob} objects, or + any mix of such objects, that will be stored within the `Blob`. +* `options` {Object} + * `encoding` {string} The character encoding to use for string sources. + **Default**: `'utf8'`. + * `type` {string} The Blob content-type. The intent is for `type` to convey + the MIME media type of the data, however no validation of the type format + is performed. + +Creates a new `Blob` object containing a concatenation of the given sources. + +{ArrayBuffer}, {TypedArray}, {DataView}, and {Buffer} sources are copied into +the 'Blob' and can therefore be safely modified after the 'Blob' is created. + +String sources are also copied into the `Blob`. + +### `blob.arrayBuffer()` + + +* Returns: {Promise} + +Returns a promise that fulfills with an {ArrayBuffer} containing a copy of +the `Blob` data. + +### `blob.size` + + +The total size of the `Blob` in bytes. + +### `blob.slice([start, [end, [type]]])` + + +* `start` {number} The starting index. +* `end` {number} The ending index. +* `type` {string} The content-type for the new `Blob` + +Creates and returns a new `Blob` containing a subset of this `Blob` objects +data. The original `Blob` is not alterered. + +### `blob.text()` + + +* Returns: {Promise} + +Returns a promise that resolves the contents of the `Blob` decoded as a UTF-8 +string. + +### `blob.type` + + +* Type: {string} + +The content-type of the `Blob`. + +### `Blob` objects and `MessageChannel` + +Once a {Blob} object is created, it can be sent via `MessagePort` to multiple +destinations without transfering or immediately copying the data. The data +contained by the `Blob` is copied only when the `arrayBuffer()` or `text()` +methods are called. + +```js +const { Blob } = require('buffer'); +const blob = new Blob(['hello there']); +const { setTimeout: delay } = require('timers/promises'); + +const mc1 = new MessageChannel(); +const mc2 = new MessageChannel(); + +mc1.port1.onmessage = async ({ data }) => { + console.log(await data.arrayBuffer()); + mc1.port1.close(); +}; + +mc2.port1.onmessage = async ({ data }) => { + await delay(1000); + console.log(await data.arrayBuffer()); + mc2.port1.close(); +}; + +mc1.port2.postMessage(blob); +mc2.port2.postMessage(blob); + +// The Blob is still usable after posting. +data.text().then(console.log); +``` + ## Class: `Buffer` The `Buffer` class is a global type for dealing with binary data directly. @@ -469,9 +590,10 @@ Returns the byte length of a string when encoded using `encoding`. This is not the same as [`String.prototype.length`][], which does not account for the encoding that is used to convert the string into bytes. -For `'base64'` and `'hex'`, this function assumes valid input. For strings that -contain non-base64/hex-encoded data (e.g. whitespace), the return value might be -greater than the length of a `Buffer` created from the string. +For `'base64'`, `'base64url'`, and `'hex'`, this function assumes valid input. +For strings that contain non-base64/hex-encoded data (e.g. whitespace), the +return value might be greater than the length of a `Buffer` created from the +string. ```js const str = '\u00bd + \u00bc = \u00be'; @@ -599,7 +721,7 @@ added: v5.10.0 This creates a view of the [`ArrayBuffer`][] without copying the underlying memory. For example, when passed a reference to the `.buffer` property of a [`TypedArray`][] instance, the newly created `Buffer` will share the same -allocated memory as the [`TypedArray`][]. +allocated memory as the [`TypedArray`][]'s underlying `ArrayBuffer`. ```js const arr = new Uint16Array(2); @@ -635,6 +757,21 @@ A `TypeError` will be thrown if `arrayBuffer` is not an [`ArrayBuffer`][] or a [`SharedArrayBuffer`][] or another type appropriate for `Buffer.from()` variants. +It is important to remember that a backing `ArrayBuffer` can cover a range +of memory that extends beyond the bounds of a `TypedArray` view. A new +`Buffer` created using the `buffer` property of a `TypedArray` may extend +beyond the range of the `TypedArray`: + +```js +const arrA = Uint8Array.from([0x63, 0x64, 0x65, 0x66]); // 4 elements +const arrB = new Uint8Array(arrA.buffer, 1, 2); // 2 elements +console.log(arrA.buffer === arrB.buffer); // true + +const buf = Buffer.from(arrB.buffer); +console.log(buf); +// Prints: +``` + ### Static method: `Buffer.from(buffer)` * `index` {integer} @@ -928,9 +1069,9 @@ added: v0.1.90 Copies data from a region of `buf` to a region in `target`, even if the `target` memory region overlaps with `buf`. -[`TypedArray#set()`][] performs the same operation, and is available for all -TypedArrays, including Node.js `Buffer`s, although it takes different -function arguments. +[`TypedArray.prototype.set()`][] performs the same operation, and is available +for all TypedArrays, including Node.js `Buffer`s, although it takes +different function arguments. ```js // Create two `Buffer` instances. @@ -1135,7 +1276,9 @@ changes: - version: v8.0.0 pr-url: https://github.com/nodejs/node/pull/10236 description: The `value` can now be a `Uint8Array`. - - version: v5.7.0, v4.4.0 + - version: + - v5.7.0 + - v4.4.0 pr-url: https://github.com/nodejs/node/pull/4803 description: When `encoding` is being passed, the `byteOffset` parameter is no longer required. @@ -1189,7 +1332,7 @@ an integer between 0 and 255. If `byteOffset` is not a number, it will be coerced to a number. If the result of coercion is `NaN` or `0`, then the entire buffer will be searched. This -behavior matches [`String#indexOf()`][]. +behavior matches [`String.prototype.indexOf()`][]. ```js const b = Buffer.from('abcdef'); @@ -1289,7 +1432,7 @@ an integer between 0 and 255. If `byteOffset` is not a number, it will be coerced to a number. Any arguments that coerce to `NaN`, like `{}` or `undefined`, will search the whole buffer. -This behavior matches [`String#lastIndexOf()`][]. +This behavior matches [`String.prototype.lastIndexOf()`][]. ```js const b = Buffer.from('abcdef'); @@ -1362,7 +1505,9 @@ values. ### `buf.readBigInt64LE([offset])` * `offset` {integer} Number of bytes to skip before starting to read. Must @@ -1377,9 +1522,11 @@ values. ### `buf.readBigUInt64BE([offset])` @@ -1391,6 +1538,8 @@ changes: Reads an unsigned, big-endian 64-bit integer from `buf` at the specified `offset`. +This function is also available under the `readBigUint64BE` alias. + ```js const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]); @@ -1404,7 +1553,9 @@ added: - v12.0.0 - v10.20.0 changes: - - version: v12.19.0 + - version: + - v14.10.0 + - v12.19.0 pr-url: https://github.com/nodejs/node/pull/34960 description: This function is also available as `buf.readBigUint64LE()`. --> @@ -1416,6 +1567,8 @@ changes: Reads an unsigned, little-endian 64-bit integer from `buf` at the specified `offset`. +This function is also available under the `readBigUint64LE` alias. + ```js const buf = Buffer.from([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff]); @@ -1716,7 +1869,7 @@ console.log(buf.readIntLE(0, 6).toString(16)); * `value` {bigint} Number to be written to `buf`. @@ -2310,7 +2481,7 @@ added: - v12.0.0 - v10.20.0 changes: - - version: v12.19.0 + - version: v14.10.0 pr-url: https://github.com/nodejs/node/pull/34960 description: This function is also available as `buf.writeBigUint64BE()`. --> @@ -2322,6 +2493,8 @@ changes: Writes `value` to `buf` at the specified `offset` as big-endian. +This function is also available under the `writeBigUint64BE` alias. + ```js const buf = Buffer.allocUnsafe(8); @@ -2333,9 +2506,11 @@ console.log(buf); ### `buf.writeBigUInt64LE(value[, offset])` @@ -2356,6 +2531,8 @@ console.log(buf); // Prints: ``` +This function is also available under the `writeBigUint64LE` alias. + ### `buf.writeDoubleBE(value[, offset])` + +* `data` {any} The Base64-encoded input string. + +Decodes a string of Base64-encoded data into bytes, and encodes those bytes +into a string using Latin-1 (ISO-8859-1). + +The `data` may be any JavaScript-value that can be coerced into a string. + +**This function is only provided for compatibility with legacy web platform APIs +and should never be used in new code, because they use strings to represent +binary data and predate the introduction of typed arrays in JavaScript. +For code running using Node.js APIs, converting between base64-encoded strings +and binary data should be performed using `Buffer.from(str, 'base64')` and +`buf.toString('base64')`.** + +### `buffer.btoa(data)` + + +* `data` {any} An ASCII (Latin1) string. + +Decodes a string into bytes using Latin-1 (ISO-8859), and encodes those bytes +into a string using Base64. + +The `data` may be any JavaScript-value that can be coerced into a string. + +**This function is only provided for compatibility with legacy web platform APIs +and should never be used in new code, because they use strings to represent +binary data and predate the introduction of typed arrays in JavaScript. +For code running using Node.js APIs, converting between base64-encoded strings +and binary data should be performed using `Buffer.from(str, 'base64')` and +`buf.toString('base64')`.** + ### `buffer.INSPECT_MAX_BYTES` + +* {integer} The largest length allowed for a single `string` instance. + +An alias for [`buffer.constants.MAX_STRING_LENGTH`][]. + ### `buffer.transcode(source, fromEnc, toEnc)` * {integer} The largest size allowed for a single `Buffer` instance. On 32-bit architectures, this value currently is 230 - 1 (~1GB). -On 64-bit architectures, this value currently is 231 - 1 (~2GB). + +On 64-bit architectures, this value currently is 232 - 1 (~4GB). + +It reflects [`v8::TypedArray::kMaxLength`][] under the hood. This value is also available as [`buffer.kMaxLength`][]. @@ -3224,12 +3470,12 @@ if `size` is less than or equal to half [`Buffer.poolSize`][]. Instances returned by [`Buffer.allocUnsafeSlow()`][] *never* use the shared internal memory pool. -### The `--zero-fill-buffers` command line option +### The `--zero-fill-buffers` command-line option -Node.js can be started using the `--zero-fill-buffers` command line option to +Node.js can be started using the `--zero-fill-buffers` command-line option to cause all newly-allocated `Buffer` instances to be zero-filled upon creation by default. Without the option, buffers created with [`Buffer.allocUnsafe()`][], [`Buffer.allocUnsafeSlow()`][], and `new SlowBuffer(size)` are not zero-filled. @@ -3256,9 +3502,15 @@ While there are clear performance advantages to using [`Buffer.allocUnsafe()`][], extra care *must* be taken in order to avoid introducing security vulnerabilities into an application. +[ASCII]: https://en.wikipedia.org/wiki/ASCII +[Base64]: https://en.wikipedia.org/wiki/Base64 +[ISO-8859-1]: https://en.wikipedia.org/wiki/ISO-8859-1 [RFC 4648, Section 5]: https://tools.ietf.org/html/rfc4648#section-5 +[UTF-16]: https://en.wikipedia.org/wiki/UTF-16 +[UTF-8]: https://en.wikipedia.org/wiki/UTF-8 [WHATWG Encoding Standard]: https://encoding.spec.whatwg.org/ [`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer +[`Blob`]: https://developer.mozilla.org/en-US/docs/Web/API/Blob [`Buffer.alloc()`]: #buffer_static_method_buffer_alloc_size_fill_encoding [`Buffer.allocUnsafe()`]: #buffer_static_method_buffer_allocunsafe_size [`Buffer.allocUnsafeSlow()`]: #buffer_static_method_buffer_allocunsafeslow_size @@ -3269,18 +3521,18 @@ introducing security vulnerabilities into an application. [`Buffer.from(string)`]: #buffer_static_method_buffer_from_string_encoding [`Buffer.poolSize`]: #buffer_class_property_buffer_poolsize [`DataView`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView -[`ERR_INVALID_BUFFER_SIZE`]: errors.html#ERR_INVALID_BUFFER_SIZE -[`ERR_INVALID_OPT_VALUE`]: errors.html#ERR_INVALID_OPT_VALUE -[`ERR_OUT_OF_RANGE`]: errors.html#ERR_OUT_OF_RANGE +[`ERR_INVALID_BUFFER_SIZE`]: errors.md#ERR_INVALID_BUFFER_SIZE +[`ERR_INVALID_OPT_VALUE`]: errors.md#ERR_INVALID_OPT_VALUE +[`ERR_OUT_OF_RANGE`]: errors.md#ERR_OUT_OF_RANGE [`JSON.stringify()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify [`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer -[`String#indexOf()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf -[`String#lastIndexOf()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf +[`String.prototype.indexOf()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf +[`String.prototype.lastIndexOf()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf [`String.prototype.length`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length [`TypedArray.from()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from -[`TypedArray#set()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set -[`TypedArray#slice()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice -[`TypedArray#subarray()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray +[`TypedArray.prototype.set()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set +[`TypedArray.prototype.slice()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice +[`TypedArray.prototype.subarray()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray [`TypedArray`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray [`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array [`buf.buffer`]: #buffer_buf_buffer @@ -3296,12 +3548,9 @@ introducing security vulnerabilities into an application. [`buffer.constants.MAX_LENGTH`]: #buffer_buffer_constants_max_length [`buffer.constants.MAX_STRING_LENGTH`]: #buffer_buffer_constants_max_string_length [`buffer.kMaxLength`]: #buffer_buffer_kmaxlength -[`util.inspect()`]: util.html#util_util_inspect_object_options -[ASCII]: https://en.wikipedia.org/wiki/ASCII -[Base64]: https://en.wikipedia.org/wiki/Base64 -[ISO-8859-1]: https://en.wikipedia.org/wiki/ISO-8859-1 -[UTF-8]: https://en.wikipedia.org/wiki/UTF-8 -[UTF-16]: https://en.wikipedia.org/wiki/UTF-16 +[`util.inspect()`]: util.md#util_util_inspect_object_options +[`v8::TypedArray::kMaxLength`]: https://v8.github.io/api/head/classv8_1_1TypedArray.html#a54a48f4373da0850663c4393d843b9b0 +[base64url]: https://tools.ietf.org/html/rfc4648#section-5 [binary strings]: https://developer.mozilla.org/en-US/docs/Web/API/DOMString/Binary [endianness]: https://en.wikipedia.org/wiki/Endianness [iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols diff --git a/doc/api/child_process.html b/doc/api/child_process.html index dab73f9836d87e10b241b59e415560b3eab29ba0..305d53829eff71b5b82533887bfc5b6f696cdce8 100644 --- a/doc/api/child_process.html +++ b/doc/api/child_process.html @@ -1,10 +1,10 @@ - + - - Child process | Node.js v12.22.7 Documentation + + Child process | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      - +
      -

      Child process#

      +

      Child process#

      Stability: 2 - Stable

      -

      Source Code: lib/child_process.js

      -

      The child_process module provides the ability to spawn child processes in +

      Source Code: lib/child_process.js

      +

      The child_process module provides the ability to spawn subprocesses in a manner that is similar, but not identical, to popen(3). This capability is primarily provided by the child_process.spawn() function:

      const { spawn } = require('child_process');
      -const ls = spawn('ls', ['-lh', '/usr']);
      +const ls = spawn('ls', ['-lh', '/usr']);
       
      -ls.stdout.on('data', (data) => {
      -  console.log(`stdout: ${data}`);
      +ls.stdout.on('data', (data) => {
      +  console.log(`stdout: ${data}`);
       });
       
      -ls.stderr.on('data', (data) => {
      -  console.error(`stderr: ${data}`);
      +ls.stderr.on('data', (data) => {
      +  console.error(`stderr: ${data}`);
       });
       
      -ls.on('close', (code) => {
      -  console.log(`child process exited with code ${code}`);
      +ls.on('close', (code) => {
      +  console.log(`child process exited with code ${code}`);
       });

      By default, pipes for stdin, stdout, and stderr are established between -the parent Node.js process and the spawned child. These pipes have -limited (and platform-specific) capacity. If the child process writes to -stdout in excess of that limit without the output being captured, the child -process will block waiting for the pipe buffer to accept more data. This is +the parent Node.js process and the spawned subprocess. These pipes have +limited (and platform-specific) capacity. If the subprocess writes to +stdout in excess of that limit without the output being captured, the +subprocess blocks waiting for the pipe buffer to accept more data. This is identical to the behavior of pipes in the shell. Use the { stdio: 'ignore' } option if the output will not be consumed.

      -

      The command lookup will be performed using options.env.PATH environment -variable if passed in options object, otherwise process.env.PATH will be -used. To account for the fact that Windows environment variables are -case-insensitive Node.js will lexicographically sort all env keys and choose -the first one case-insensitively matching PATH to perform command lookup. -This may lead to issues on Windows when passing objects to env option that -have multiple variants of PATH variable.

      +

      The command lookup is performed using the options.env.PATH environment +variable if it is in the options object. Otherwise, process.env.PATH is +used.

      +

      On Windows, environment variables are case-insensitive. Node.js +lexicographically sorts the env keys and uses the first one that +case-insensitively matches. Only first (in lexicographic order) entry will be +passed to the subprocess. This might lead to issues on Windows when passing +objects to the env option that have multiple variants of the same key, such as +PATH and Path.

      The child_process.spawn() method spawns the child process asynchronously, without blocking the Node.js event loop. The child_process.spawnSync() function provides equivalent functionality in a synchronous manner that blocks @@ -253,18 +273,18 @@ sending messages between parent and child. synchronous counterparts may be more convenient. In many cases, however, the synchronous methods can have significant impact on performance due to stalling the event loop while spawned processes complete.

      -

      Asynchronous process creation#

      +

      Asynchronous process creation#

      The child_process.spawn(), child_process.fork(), child_process.exec(), and child_process.execFile() methods all follow the idiomatic asynchronous programming pattern typical of other Node.js APIs.

      -

      Each of the methods returns a ChildProcess instance. These objects +

      Each of the methods returns a ChildProcess instance. These objects implement the Node.js EventEmitter API, allowing the parent process to register listener functions that are called when certain events occur during the life cycle of the child process.

      The child_process.exec() and child_process.execFile() methods additionally allow for an optional callback function to be specified that is invoked when the child process terminates.

      -

      Spawning .bat and .cmd files on Windows#

      +

      Spawning .bat and .cmd files on Windows#

      The importance of the distinction between child_process.exec() and child_process.execFile() can vary based on platform. On Unix-type operating systems (Unix, Linux, macOS) child_process.execFile() can be @@ -279,40 +299,44 @@ When running on Windows, .bat and .cmd files can be in spaces it needs to be quoted.

      // On Windows Only...
       const { spawn } = require('child_process');
      -const bat = spawn('cmd.exe', ['/c', 'my.bat']);
      +const bat = spawn('cmd.exe', ['/c', 'my.bat']);
       
      -bat.stdout.on('data', (data) => {
      -  console.log(data.toString());
      +bat.stdout.on('data', (data) => {
      +  console.log(data.toString());
       });
       
      -bat.stderr.on('data', (data) => {
      -  console.error(data.toString());
      +bat.stderr.on('data', (data) => {
      +  console.error(data.toString());
       });
       
      -bat.on('exit', (code) => {
      -  console.log(`Child exited with code ${code}`);
      +bat.on('exit', (code) => {
      +  console.log(`Child exited with code ${code}`);
       });
      // OR...
       const { exec, spawn } = require('child_process');
      -exec('my.bat', (err, stdout, stderr) => {
      +exec('my.bat', (err, stdout, stderr) => {
         if (err) {
      -    console.error(err);
      +    console.error(err);
           return;
         }
      -  console.log(stdout);
      +  console.log(stdout);
       });
       
       // Script with spaces in the filename:
      -const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
      +const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
       // or:
      -exec('"my script.cmd" a b', (err, stdout, stderr) => {
      +exec('"my script.cmd" a b', (err, stdout, stderr) => {
         // ...
       });
      -

      child_process.exec(command[, options][, callback])#

      +

      child_process.exec(command[, options][, callback])#

      Class: ChildProcess#

      @@ -1062,7 +1199,7 @@ arbitrary command execution.

      use the child_process.spawn(), child_process.exec(), child_process.execFile(), or child_process.fork() methods to create instances of ChildProcess.

      -

      Event: 'close'#

      +

      Event: 'close'#

      @@ -1070,24 +1207,26 @@ instances of ChildProcess.

    • code <number> The exit code if the child exited on its own.
    • signal <string> The signal by which the child process was terminated.
    • -

      The 'close' event is emitted when the stdio streams of a child process have -been closed. This is distinct from the 'exit' event, since multiple -processes might share the same stdio streams.

      +

      The 'close' event is emitted after a process has ended and the stdio +streams of a child process have been closed. This is distinct from the +'exit' event, since multiple processes might share the same stdio +streams. The 'close' event will always emit after 'exit' was +already emitted, or 'error' if the child failed to spawn.

      const { spawn } = require('child_process');
      -const ls = spawn('ls', ['-lh', '/usr']);
      +const ls = spawn('ls', ['-lh', '/usr']);
       
      -ls.stdout.on('data', (data) => {
      -  console.log(`stdout: ${data}`);
      +ls.stdout.on('data', (data) => {
      +  console.log(`stdout: ${data}`);
       });
       
      -ls.on('close', (code) => {
      -  console.log(`child process close all stdio with code ${code}`);
      +ls.on('close', (code) => {
      +  console.log(`child process close all stdio with code ${code}`);
       });
       
      -ls.on('exit', (code) => {
      -  console.log(`child process exited with code ${code}`);
      +ls.on('exit', (code) => {
      +  console.log(`child process exited with code ${code}`);
       });
      -

      Event: 'disconnect'#

      +

      Event: 'disconnect'#

      @@ -1096,7 +1235,7 @@ ls.on('exit', (process.disconnect() in child process. After disconnecting it is no longer possible to send or receive messages, and the subprocess.connected property is false.

      -

      Event: 'error'#

      +

      Event: 'error'#

      @@ -1110,7 +1249,7 @@ property is false.

      listening to both the 'exit' and 'error' events, guard against accidentally invoking handler functions multiple times.

      See also subprocess.kill() and subprocess.send().

      -

      Event: 'exit'#

      +

      Event: 'exit'#

      @@ -1129,7 +1268,7 @@ processes will not terminate immediately due to receipt of those signals. Rather, Node.js will perform a sequence of cleanup actions and then will re-raise the handled signal.

      See waitpid(2).

      -

      Event: 'message'#

      +

      Event: 'message'#

      @@ -1146,16 +1285,49 @@ message might not be the same as what is originally sent.

      child process, the message argument can contain data that JSON is not able to represent. See Advanced serialization for more details.

      -

      subprocess.channel#

      +

      Event: 'spawn'#

      +

      The 'spawn' event is emitted once the child process has spawned successfully. +If the child process does not spawn successfully, the 'spawn' event is not +emitted and the 'error' event is emitted instead.

      +

      If emitted, the 'spawn' event comes before all other events and before any +data is received via stdout or stderr.

      +

      The 'spawn' event will fire regardless of whether an error occurs within +the spawned process. For example, if bash some-command spawns successfully, +the 'spawn' event will fire, though bash may fail to spawn some-command. +This caveat also applies when using { shell: true }.

      +

      subprocess.channel#

      +
      • <Object> A pipe representing the IPC channel to the child process.

      The subprocess.channel property is a reference to the child's IPC channel. If no IPC channel currently exists, this property is undefined.

      -

      subprocess.connected#

      +
      subprocess.channel.ref()#
      + +

      This method makes the IPC channel keep the event loop of the parent process +running if .unref() has been called before.

      +
      subprocess.channel.unref()#
      + +

      This method makes the IPC channel not keep the event loop of the parent process +running, and lets it finish even while the channel is open.

      +

      subprocess.connected#

      @@ -1165,7 +1337,7 @@ no IPC channel currently exists, this property is undefined.

      The subprocess.connected property indicates whether it is still possible to send and receive messages from a child process. When subprocess.connected is false, it is no longer possible to send or receive messages.

      -

      subprocess.disconnect()#

      +

      subprocess.disconnect()#

      @@ -1180,13 +1352,13 @@ calling subprocess.disconnect().

      When the child process is a Node.js instance (e.g. spawned using child_process.fork()), the process.disconnect() method can be invoked within the child process to close the IPC channel as well.

      -

      subprocess.exitCode#

      +

      subprocess.exitCode#

      The subprocess.exitCode property indicates the exit code of the child process. If the child process is still running, the field will be null.

      -

      subprocess.kill([signal])#

      +

      subprocess.kill([signal])#

      @@ -1199,16 +1371,16 @@ argument is given, the process will be sent the 'SIGTERM' signal. S signal(7) for a list of available signals. This function returns true if kill(2) succeeds, and false otherwise.

      const { spawn } = require('child_process');
      -const grep = spawn('grep', ['ssh']);
      +const grep = spawn('grep', ['ssh']);
       
      -grep.on('close', (code, signal) => {
      -  console.log(
      +grep.on('close', (code, signal) => {
      +  console.log(
           `child process terminated due to receipt of signal ${signal}`);
       });
       
       // Send SIGHUP to process.
      -grep.kill('SIGHUP');
      -

      The ChildProcess object may emit an 'error' event if the signal +grep.kill('SIGHUP'); +

      The ChildProcess object may emit an 'error' event if the signal cannot be delivered. Sending a signal to a child process that has already exited is not an error but may have unforeseen consequences. Specifically, if the process identifier (PID) has been reassigned to another process, the signal will @@ -1216,28 +1388,32 @@ be delivered to that process instead which can have unexpected results.

      While the function is called kill, the signal delivered to the child process may not actually terminate the process.

      See kill(2) for reference.

      +

      On Windows, where POSIX signals do not exist, the signal argument will be +ignored, and the process will be killed forcefully and abruptly (similar to +'SIGKILL'). +See Signal Events for more details.

      On Linux, child processes of child processes will not be terminated when attempting to kill their parent. This is likely to happen when running a new process in a shell or with the use of the shell option of ChildProcess:

      'use strict';
       const { spawn } = require('child_process');
       
      -const subprocess = spawn(
      +const subprocess = spawn(
         'sh',
         [
           '-c',
           `node -e "setInterval(() => {
             console.log(process.pid, 'is alive')
      -    }, 500);"`
      +    }, 500);"`,
         ], {
           stdio: ['inherit', 'inherit', 'inherit']
         }
       );
       
       setTimeout(() => {
      -  subprocess.kill(); // Does not terminate the Node.js process in the shell.
      +  subprocess.kill(); // Does not terminate the Node.js process in the shell.
       }, 2000);
      -

      subprocess.killed#

      +

      subprocess.killed#

      @@ -1248,20 +1424,22 @@ send a signal to the child process.

      The subprocess.killed property indicates whether the child process successfully received a signal from subprocess.kill(). The killed property does not indicate that the child process has been terminated.

      -

      subprocess.pid#

      +

      subprocess.pid#

      -

      Returns the process identifier (PID) of the child process.

      +

      Returns the process identifier (PID) of the child process. If the child process +fails to spawn due to errors, then the value is undefined and error is +emitted.

      const { spawn } = require('child_process');
      -const grep = spawn('grep', ['ssh']);
      +const grep = spawn('grep', ['ssh']);
       
      -console.log(`Spawned child pid: ${grep.pid}`);
      -grep.stdin.end();
      -

      subprocess.ref()#

      +console.log(`Spawned child pid: ${grep.pid}`); +grep.stdin.end();
      +

      subprocess.ref()#

      @@ -1270,14 +1448,14 @@ restore the removed reference count for the child process, forcing the parent to wait for the child to exit before exiting itself.

      const { spawn } = require('child_process');
       
      -const subprocess = spawn(process.argv[0], ['child_program.js'], {
      +const subprocess = spawn(process.argv[0], ['child_program.js'], {
         detached: true,
         stdio: 'ignore'
       });
       
      -subprocess.unref();
      -subprocess.ref();
      -

      subprocess.send(message[, sendHandle[, options]][, callback])#

      +subprocess.unref(); +subprocess.ref();
      +

      subprocess.send(message[, sendHandle[, options]][, callback])#

      -

      Stability: 1 - Experimental

      -

      Enable experimental Source Map v3 support for stack traces.

      -

      Currently, overriding Error.prepareStackTrace is ignored when the ---enable-source-maps flag is set.

      -

      --experimental-import-meta-resolve#

      +

      Enable Source Map v3 support for stack traces.

      +

      When using a transpiler, such as TypeScript, strack traces thrown by an +application reference the transpiled code, not the original source position. +--enable-source-maps enables caching of Source Maps and makes a best +effort to report stack traces relative to the original source file.

      +

      Overriding Error.prepareStackTrace prevents --enable-source-maps from +modifiying the stack trace.

      +

      --experimental-abortcontroller#

      + +

      Enable experimental AbortController and AbortSignal support.

      +

      --experimental-import-meta-resolve#

      Enable experimental import.meta.resolve() support.

      -

      --experimental-json-modules#

      +

      --experimental-json-modules#

      Enable experimental JSON support for the ES Module loader.

      -

      --experimental-loader=module#

      +

      --experimental-loader=module#

      -

      Specify the module of a custom experimental ECMAScript Module loader. +

      Specify the module of a custom experimental ECMAScript Module loader. module may be either a path to a file, or an ECMAScript Module name.

      -

      --experimental-modules#

      +

      --experimental-modules#

      Enable latest experimental modules features (deprecated).

      -

      --experimental-policy#

      +

      --experimental-policy#

      Use the specified file as a security policy.

      -

      --experimental-repl-await#

      +

      --experimental-repl-await#

      Enable experimental top-level await keyword support in REPL.

      -

      --experimental-specifier-resolution=mode#

      +

      --experimental-specifier-resolution=mode#

      Sets the resolution algorithm for resolving ES module specifiers. Valid options are explicit and node.

      The default is explicit, which requires providing the full path to a -module. The node mode will enable support for optional file extensions and +module. The node mode enables support for optional file extensions and the ability to import a directory that has an index file.

      -

      Please see customizing ESM specifier resolution for example usage.

      -

      --experimental-vm-modules#

      +

      See customizing ESM specifier resolution for example usage.

      +

      --experimental-vm-modules#

      Enable experimental ES Module support in the vm module.

      -

      --experimental-wasi-unstable-preview1#

      +

      --experimental-wasi-unstable-preview1#

      Enable experimental WebAssembly System Interface (WASI) support.

      -

      --experimental-wasm-modules#

      +

      --experimental-wasm-modules#

      -

      --force-context-aware#

      +

      Enable experimental WebAssembly module support.

      +

      --force-context-aware#

      Disable loading native addons that are not context-aware.

      -

      Enable experimental WebAssembly module support.

      -

      --force-fips#

      +

      --force-fips#

      Force FIPS-compliant crypto on startup. (Cannot be disabled from script code.) (Same requirements as --enable-fips.)

      -

      --frozen-intrinsics#

      +

      --frozen-intrinsics#

      @@ -491,35 +547,73 @@ currently provided that global.Array is indeed the default intrinsi reference. Code may break under this flag.

      --require runs prior to freezing intrinsics in order to allow polyfills to be added.

      -

      --heapsnapshot-signal=signal#

      +

      --heapsnapshot-near-heap-limit=max_count#

      + +

      Stability: 1 - Experimental

      +

      Writes a V8 heap snapshot to disk when the V8 heap usage is approaching the +heap limit. count should be a non-negative integer (in which case +Node.js will write no more than max_count snapshots to disk).

      +

      When generating snapshots, garbage collection may be triggered and bring +the heap usage down, therefore multiple snapshots may be written to disk +before the Node.js instance finally runs out of memory. These heap snapshots +can be compared to determine what objects are being allocated during the +time consecutive snapshots are taken. It's not guaranteed that Node.js will +write exactly max_count snapshots to disk, but it will try +its best to generate at least one and up to max_count snapshots before the +Node.js instance runs out of memory when max_count is greater than 0.

      +

      Generating V8 snapshots takes time and memory (both memory managed by the +V8 heap and native memory outside the V8 heap). The bigger the heap is, +the more resources it needs. Node.js will adjust the V8 heap to accommondate +the additional V8 heap memory overhead, and try its best to avoid using up +all the memory avialable to the process. When the process uses +more memory than the system deems appropriate, the process may be terminated +abruptly by the system, depending on the system configuration.

      +
      $ node --max-old-space-size=100 --heapsnapshot-near-heap-limit=3 index.js
      +Wrote snapshot to Heap.20200430.100036.49580.0.001.heapsnapshot
      +Wrote snapshot to Heap.20200430.100037.49580.0.002.heapsnapshot
      +Wrote snapshot to Heap.20200430.100038.49580.0.003.heapsnapshot
      +
      +<--- Last few GCs --->
      +
      +[49580:0x110000000]     4826 ms: Mark-sweep 130.6 (147.8) -> 130.5 (147.8) MB, 27.4 / 0.0 ms  (average mu = 0.126, current mu = 0.034) allocation failure scavenge might not succeed
      +[49580:0x110000000]     4845 ms: Mark-sweep 130.6 (147.8) -> 130.6 (147.8) MB, 18.8 / 0.0 ms  (average mu = 0.088, current mu = 0.031) allocation failure scavenge might not succeed
      +
      +
      +<--- JS stacktrace --->
      +
      +FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
      +....
      +

      --heapsnapshot-signal=signal#

      Enables a signal handler that causes the Node.js process to write a heap dump when the specified signal is received. signal must be a valid signal name. Disabled by default.

      -
      $ node --heapsnapshot-signal=SIGUSR2 index.js &
      -$ ps aux
      +
      $ node --heapsnapshot-signal=SIGUSR2 index.js &
      +$ ps aux
       USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
       node         1  5.5  6.1 787252 247004 ?       Ssl  16:43   0:02 node --heapsnapshot-signal=SIGUSR2 index.js
      -$ kill -USR2 1
      -$ ls
      +$ kill -USR2 1
      +$ ls
       Heap.20190718.133405.15554.0.001.heapsnapshot
      -

      --heap-prof#

      +

      --heap-prof#

      Stability: 1 - Experimental

      Starts the V8 heap profiler on start up, and writes the heap profile to disk before exit.

      -

      If --heap-prof-dir is not specified, the generated profile will be placed +

      If --heap-prof-dir is not specified, the generated profile is placed in the current working directory.

      -

      If --heap-prof-name is not specified, the generated profile will be +

      If --heap-prof-name is not specified, the generated profile is named Heap.${yyyymmdd}.${hhmmss}.${pid}.${tid}.${seq}.heapprofile.

      -
      $ node --heap-prof index.js
      -$ ls *.heapprofile
      +
      $ node --heap-prof index.js
      +$ ls *.heapprofile
       Heap.20190409.202950.15293.0.001.heapprofile
      -

      --heap-prof-dir#

      +

      --heap-prof-dir#

      @@ -527,70 +621,39 @@ Heap.20190409.202950.15293.0.001.heapprofile

      Specify the directory where the heap profiles generated by --heap-prof will be placed.

      The default value is controlled by the ---diagnostic-dir command line option.

      -

      --heap-prof-interval#

      +--diagnostic-dir command-line option.

      +

      --heap-prof-interval#

      Stability: 1 - Experimental

      Specify the average sampling interval in bytes for the heap profiles generated by --heap-prof. The default is 512 * 1024 bytes.

      -

      --heap-prof-name#

      +

      --heap-prof-name#

      Stability: 1 - Experimental

      Specify the file name of the heap profile generated by --heap-prof.

      -

      --http-parser=library#

      - -

      Chooses an HTTP parser library. Available values are:

      - -

      The default is llhttp, unless otherwise specified when building Node.js.

      -

      The legacy HTTP parser is deprecated and will emit a deprecation warning.

      -

      This flag exists to aid in experimentation with the internal implementation of -the Node.js http parser. -This flag is likely to become a no-op and removed at some point in the future.

      -

      --http-server-default-timeout=milliseconds#

      - -

      Overrides the default value of http, https and http2 server socket -timeout. Setting the value to 0 disables server socket timeout. Unless -provided, http server sockets timeout after 120s (2 minutes). Programmatic -setting of the timeout takes precedence over the value set through this -flag.

      -

      --icu-data-dir=file#

      +

      --icu-data-dir=file#

      Specify ICU data load path. (Overrides NODE_ICU_DATA.)

      -

      --input-type=type#

      +

      --input-type=type#

      This configures Node.js to interpret string input as CommonJS or as an ES module. String input is input via --eval, --print, or STDIN.

      Valid values are "commonjs" and "module". The default is "commonjs".

      -

      --inspect-brk[=[host:]port]#

      +

      --inspect-brk[=[host:]port]#

      Activate inspector on host:port and break at start of user script. Default host:port is 127.0.0.1:9229.

      -

      --inspect-port=[host:]port#

      +

      --inspect-port=[host:]port#

      @@ -599,7 +662,7 @@ Useful when activating the inspector by sending the SIGUSR1 signal.

      Default host is 127.0.0.1.

      See the security warning below regarding the host parameter usage.

      -

      --inspect[=[host:]port]#

      +

      --inspect[=[host:]port]#

      @@ -608,7 +671,7 @@ parameter usage.

      and profile Node.js instances. The tools attach to Node.js instances via a tcp port and communicate using the Chrome DevTools Protocol.

      -

      Warning: binding inspector to a public IP:port combination is insecure#

      +
      Warning: binding inspector to a public IP:port combination is insecure#

      Binding the inspector to a public IP (including 0.0.0.0) with an open port is insecure, as it allows external hosts to connect to the inspector and perform a remote code execution attack.

      @@ -620,19 +683,19 @@ a remote code execution

      More specifically, --inspect=0.0.0.0 is insecure if the port (9229 by default) is not firewall-protected.

      See the debugging security implications section for more information.

      -

      --inspect-publish-uid=stderr,http#

      +

      --inspect-publish-uid=stderr,http#

      Specify ways of the inspector web socket url exposure.

      By default inspector websocket url is available in stderr and under /json/list endpoint on http://host:port/json/list.

      -

      --insecure-http-parser#

      +

      --insecure-http-parser#

      Use an insecure HTTP parser that accepts invalid HTTP headers. This may allow interoperability with non-conformant HTTP implementations. It may also allow request smuggling and other HTTP attacks that rely on invalid headers being accepted. Avoid using this option.

      -

      --jitless#

      +

      --jitless#

      @@ -641,51 +704,65 @@ required on some platforms for security reasons. It can also reduce attack surface on other platforms, but the performance impact may be severe.

      This flag is inherited from V8 and is subject to change upstream. It may disappear in a non-semver-major release.

      -

      --max-http-header-size=size#

      +

      --max-http-header-size=size#

      -

      Specify the maximum size, in bytes, of HTTP headers. Defaults to 8KB.

      -

      --napi-modules#

      +

      Specify the maximum size, in bytes, of HTTP headers. Defaults to 16KB.

      +

      --napi-modules#

      This option is a no-op. It is kept for compatibility.

      -

      --no-deprecation#

      +

      --no-deprecation#

      Silence deprecation warnings.

      -

      --no-force-async-hooks-checks#

      +

      --no-force-async-hooks-checks#

      Disables runtime checks for async_hooks. These will still be enabled dynamically when async_hooks is enabled.

      -

      --no-warnings#

      +

      --no-warnings#

      Silence all process warnings (including deprecations).

      -

      --openssl-config=file#

      +

      --node-memory-debug#

      + +

      Enable extra debug checks for memory leaks in Node.js internals. This is +usually only useful for developers debugging Node.js itself.

      +

      --openssl-config=file#

      Load an OpenSSL configuration file on startup. Among other uses, this can be used to enable FIPS-compliant crypto if Node.js is built with ./configure --openssl-fips.

      -

      --pending-deprecation#

      +

      --pending-deprecation#

      Emit pending deprecation warnings.

      Pending deprecations are generally identical to a runtime deprecation with the notable exception that they are turned off by default and will not be emitted -unless either the --pending-deprecation command line flag, or the +unless either the --pending-deprecation command-line flag, or the NODE_PENDING_DEPRECATION=1 environment variable, is set. Pending deprecations are used to provide a kind of selective "early warning" mechanism that developers may leverage to detect deprecated API usage.

      -

      --policy-integrity=sri#

      +

      --policy-integrity=sri#

      @@ -693,7 +770,7 @@ developers may leverage to detect deprecated API usage.

      Instructs Node.js to error prior to running any code if the policy does not have the specified integrity. It expects a Subresource Integrity string as a parameter.

      -

      --preserve-symlinks#

      +

      --preserve-symlinks#

      @@ -717,7 +794,7 @@ be thrown if moduleA attempts to require moduleB as a └── moduleA ├── index.js └── package.json
      -

      The --preserve-symlinks command line flag instructs Node.js to use the +

      The --preserve-symlinks command-line flag instructs Node.js to use the symlink path for modules as opposed to the real path, allowing symbolically linked peer dependencies to be found.

      Note, however, that using --preserve-symlinks can have other side effects. @@ -728,7 +805,7 @@ times, causing an exception to be thrown).

      The --preserve-symlinks flag does not apply to the main module, which allows node --preserve-symlinks node_module/.bin/<foo> to work. To apply the same behavior for the main module, also use --preserve-symlinks-main.

      -

      --preserve-symlinks-main#

      +

      --preserve-symlinks-main#

      @@ -737,22 +814,22 @@ caching the main module (require.main).

      This flag exists so that the main module can be opted-in to the same behavior that --preserve-symlinks gives to all other imports; they are separate flags, however, for backward compatibility with older Node.js versions.

      -

      --preserve-symlinks-main does not imply --preserve-symlinks; it -is expected that --preserve-symlinks-main will be used in addition to +

      --preserve-symlinks-main does not imply --preserve-symlinks; use +--preserve-symlinks-main in addition to --preserve-symlinks when it is not desirable to follow symlinks before resolving relative paths.

      See --preserve-symlinks for more information.

      -

      --prof#

      +

      --prof#

      Generate V8 profiler output.

      -

      --prof-process#

      +

      --prof-process#

      Process V8 profiler output generated using the V8 option --prof.

      -

      --redirect-warnings=file#

      +

      --redirect-warnings=file#

      @@ -762,53 +839,53 @@ If an error occurs while attempting to write the warning to the file, the warning will be written to stderr instead.

      The file name may be an absolute path. If it is not, the default directory it will be written to is controlled by the ---diagnostic-dir command line option.

      -

      --report-compact#

      +--diagnostic-dir command-line option.

      +

      --report-compact#

      Write reports in a compact format, single-line JSON, more easily consumable by log processing systems than the default multi-line format designed for human consumption.

      -

      --report-dir=directory, report-directory=directory#

      +

      --report-dir=directory, report-directory=directory#

      Location at which the report will be generated.

      -

      --report-filename=filename#

      +

      --report-filename=filename#

      Name of the file to which the report will be written.

      -

      --report-on-fatalerror#

      +

      --report-on-fatalerror#

      + diff --git a/doc/api/deprecations.json b/doc/api/deprecations.json index 14ab9454c809944c4a4671bdd2679b819b197955..566fa3f8aaac6705248b016f2833437454e50ffc 100644 --- a/doc/api/deprecations.json +++ b/doc/api/deprecations.json @@ -8,29 +8,33 @@ "name": "Deprecated APIs", "introduced_in": "v7.7.0", "type": "misc", - "desc": "

      Node.js may deprecate APIs for any of the following reasons:

      \n
        \n
      • Use of the API is unsafe.
      • \n
      • An improved alternative API is available.
      • \n
      • Breaking changes to the API are expected in a future major release.
      • \n
      \n

      Node.js utilizes three kinds of Deprecations:

      \n
        \n
      • Documentation-only
      • \n
      • Runtime
      • \n
      • End-of-Life
      • \n
      \n

      A Documentation-only deprecation is one that is expressed only within the\nNode.js API docs. These generate no side-effects while running Node.js.\nSome Documentation-only deprecations trigger a runtime warning when launched\nwith --pending-deprecation flag (or its alternative,\nNODE_PENDING_DEPRECATION=1 environment variable), similarly to Runtime\ndeprecations below. Documentation-only deprecations that support that flag\nare explicitly labeled as such in the\nlist of Deprecated APIs.

      \n

      A Runtime deprecation will, by default, generate a process warning that will\nbe printed to stderr the first time the deprecated API is used. When the\n--throw-deprecation command-line flag is used, a Runtime deprecation will\ncause an error to be thrown.

      \n

      An End-of-Life deprecation is used when functionality is or will soon be removed\nfrom Node.js.

      ", + "desc": "

      Node.js APIs might be deprecated for any of the following reasons:

      \n
        \n
      • Use of the API is unsafe.
      • \n
      • An improved alternative API is available.
      • \n
      • Breaking changes to the API are expected in a future major release.
      • \n
      \n

      Node.js uses three kinds of Deprecations:

      \n
        \n
      • Documentation-only
      • \n
      • Runtime
      • \n
      • End-of-Life
      • \n
      \n

      A Documentation-only deprecation is one that is expressed only within the\nNode.js API docs. These generate no side-effects while running Node.js.\nSome Documentation-only deprecations trigger a runtime warning when launched\nwith --pending-deprecation flag (or its alternative,\nNODE_PENDING_DEPRECATION=1 environment variable), similarly to Runtime\ndeprecations below. Documentation-only deprecations that support that flag\nare explicitly labeled as such in the\nlist of Deprecated APIs.

      \n

      A Runtime deprecation will, by default, generate a process warning that will\nbe printed to stderr the first time the deprecated API is used. When the\n--throw-deprecation command-line flag is used, a Runtime deprecation will\ncause an error to be thrown.

      \n

      An End-of-Life deprecation is used when functionality is or will soon be removed\nfrom Node.js.

      ", "miscs": [ { "textRaw": "Revoking deprecations", "name": "revoking_deprecations", - "desc": "

      Occasionally, the deprecation of an API may be reversed. In such situations,\nthis document will be updated with information relevant to the decision.\nHowever, the deprecation identifier will not be modified.

      ", + "desc": "

      Occasionally, the deprecation of an API might be reversed. In such situations,\nthis document will be updated with information relevant to the decision.\nHowever, the deprecation identifier will not be modified.

      ", "type": "misc", "displayName": "Revoking deprecations" }, { "textRaw": "List of deprecated APIs", "name": "list_of_deprecated_apis", - "desc": "

      ", "modules": [ { "textRaw": "DEP0001: `http.OutgoingMessage.prototype.flush`", "name": "dep0001:_`http.outgoingmessage.prototype.flush`", "meta": { "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31164", + "description": "End-of-Life." + }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -42,7 +46,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The OutgoingMessage.prototype.flush() method is deprecated. Use\nOutgoingMessage.prototype.flushHeaders() instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      OutgoingMessage.prototype.flush() has been removed. Use\nOutgoingMessage.prototype.flushHeaders() instead.

      ", "type": "module", "displayName": "DEP0001: `http.OutgoingMessage.prototype.flush`" }, @@ -68,7 +72,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The _linklist module is deprecated. Please use a userland alternative.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The _linklist module is deprecated. Please use a userland alternative.

      ", "type": "module", "displayName": "DEP0002: `require('_linklist')`" }, @@ -77,10 +81,15 @@ "name": "dep0003:_`_writablestate.buffer`", "meta": { "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31165", + "description": "End-of-Life." + }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -92,7 +101,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The _writableState.buffer property is deprecated. Use the\n_writableState.getBuffer() method instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The _writableState.buffer has been removed. Use _writableState.getBuffer()\ninstead.

      ", "type": "module", "displayName": "DEP0003: `_writableState.buffer`" }, @@ -108,20 +117,20 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { - "version": "0.4.0", + "version": "v0.4.0", "commit": "9c7f89bf56abd37a796fea621ad2e47dd33d2b82", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: End-of-Life

      \n

      The CryptoStream.prototype.readyState property was removed.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The CryptoStream.prototype.readyState property was removed.

      ", "type": "module", "displayName": "DEP0004: `CryptoStream.prototype.readyState`" }, @@ -147,7 +156,7 @@ } ] }, - "desc": "

      Type: Runtime (supports --pending-deprecation)

      \n

      The Buffer() function and new Buffer() constructor are deprecated due to\nAPI usability issues that can lead to accidental security issues.

      \n

      As an alternative, use one of the following methods of constructing Buffer\nobjects:

      \n\n

      Without --pending-deprecation, runtime warnings occur only for code not in\nnode_modules. This means there will not be deprecation warnings for\nBuffer() usage in dependencies. With --pending-deprecation, a runtime\nwarning results no matter where the Buffer() usage occurs.

      \n

      ", + "desc": "

      Type: Runtime (supports --pending-deprecation)

      \n

      The Buffer() function and new Buffer() constructor are deprecated due to\nAPI usability issues that can lead to accidental security issues.

      \n

      As an alternative, use one of the following methods of constructing Buffer\nobjects:

      \n\n

      Without --pending-deprecation, runtime warnings occur only for code not in\nnode_modules. This means there will not be deprecation warnings for\nBuffer() usage in dependencies. With --pending-deprecation, a runtime\nwarning results no matter where the Buffer() usage occurs.

      ", "type": "module", "displayName": "DEP0005: `Buffer()` constructor" }, @@ -163,8 +172,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -174,12 +183,12 @@ "description": "Runtime deprecation." }, { - "version": "v0.5.11", + "version": "v0.5.10", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: End-of-Life

      \n

      Within the child_process module's spawn(), fork(), and exec()\nmethods, the options.customFds option is deprecated. The options.stdio\noption should be used instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Within the child_process module's spawn(), fork(), and exec()\nmethods, the options.customFds option is deprecated. The options.stdio\noption should be used instead.

      ", "type": "module", "displayName": "DEP0006: `child_process` `options.customFds`" }, @@ -210,7 +219,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      In an earlier version of the Node.js cluster, a boolean property with the name\nsuicide was added to the Worker object. The intent of this property was to\nprovide an indication of how and why the Worker instance exited. In Node.js\n6.0.0, the old property was deprecated and replaced with a new\nworker.exitedAfterDisconnect property. The old property name did not\nprecisely describe the actual semantics and was unnecessarily emotion-laden.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      In an earlier version of the Node.js cluster, a boolean property with the name\nsuicide was added to the Worker object. The intent of this property was to\nprovide an indication of how and why the Worker instance exited. In Node.js\n6.0.0, the old property was deprecated and replaced with a new\nworker.exitedAfterDisconnect property. The old property name did not\nprecisely describe the actual semantics and was unnecessarily emotion-laden.

      ", "type": "module", "displayName": "DEP0007: Replace `cluster` `worker.suicide` with `worker.exitedAfterDisconnect`" }, @@ -231,7 +240,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The constants module is deprecated. When requiring access to constants\nrelevant to specific Node.js builtin modules, developers should instead refer\nto the constants property exposed by the relevant module. For instance,\nrequire('fs').constants and require('os').constants.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The constants module is deprecated. When requiring access to constants\nrelevant to specific Node.js builtin modules, developers should instead refer\nto the constants property exposed by the relevant module. For instance,\nrequire('fs').constants and require('os').constants.

      ", "type": "module", "displayName": "DEP0008: `require('constants')`" }, @@ -240,6 +249,11 @@ "name": "dep0009:_`crypto.pbkdf2`_without_digest", "meta": { "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31166", + "description": "End-of-Life (for `digest === null`)." + }, { "version": "v11.0.0", "pr-url": "https://github.com/nodejs/node/pull/22861", @@ -262,7 +276,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Use of the crypto.pbkdf2() API without specifying a digest was deprecated\nin Node.js 6.0 because the method defaulted to using the non-recommended\n'SHA1' digest. Previously, a deprecation warning was printed. Starting in\nNode.js 8.0.0, calling crypto.pbkdf2() or crypto.pbkdf2Sync() with\ndigest set to undefined will throw a TypeError.

      \n

      Beginning in Node.js v11.0.0, calling these functions with digest set to\nnull will print a deprecation warning to align with the behavior when digest\nis undefined.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Use of the crypto.pbkdf2() API without specifying a digest was deprecated\nin Node.js 6.0 because the method defaulted to using the non-recommended\n'SHA1' digest. Previously, a deprecation warning was printed. Starting in\nNode.js 8.0.0, calling crypto.pbkdf2() or crypto.pbkdf2Sync() with\ndigest set to undefined will throw a TypeError.

      \n

      Beginning in Node.js v11.0.0, calling these functions with digest set to\nnull would print a deprecation warning to align with the behavior when digest\nis undefined.

      \n

      Now, however, passing either undefined or null will throw a TypeError.

      ", "type": "module", "displayName": "DEP0009: `crypto.pbkdf2` without digest" }, @@ -278,8 +292,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -291,7 +305,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The crypto.createCredentials() API was removed. Please use\ntls.createSecureContext() instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The crypto.createCredentials() API was removed. Please use\ntls.createSecureContext() instead.

      ", "type": "module", "displayName": "DEP0010: `crypto.createCredentials`" }, @@ -307,8 +321,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -320,7 +334,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The crypto.Credentials class was removed. Please use tls.SecureContext\ninstead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The crypto.Credentials class was removed. Please use tls.SecureContext\ninstead.

      ", "type": "module", "displayName": "DEP0011: `crypto.Credentials`" }, @@ -336,8 +350,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -349,7 +363,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      Domain.dispose() has been removed. Recover from failed I/O actions\nexplicitly via error event handlers set on the domain instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Domain.dispose() has been removed. Recover from failed I/O actions\nexplicitly via error event handlers set on the domain instead.

      ", "type": "module", "displayName": "DEP0012: `Domain.dispose`" }, @@ -370,7 +384,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      Calling an asynchronous function without a callback throws a TypeError\nin Node.js 10.0.0 onwards. See https://github.com/nodejs/node/pull/12562.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Calling an asynchronous function without a callback throws a TypeError\nin Node.js 10.0.0 onwards. See https://github.com/nodejs/node/pull/12562.

      ", "type": "module", "displayName": "DEP0013: `fs` asynchronous function without callback" }, @@ -384,19 +398,19 @@ "pr-url": "https://github.com/nodejs/node/pull/9683", "description": "End-of-Life." }, - { - "version": "v6.0.0", - "pr-url": "https://github.com/nodejs/node/pull/4525", - "description": "Runtime deprecation." - }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, + { + "version": "v6.0.0", + "pr-url": "https://github.com/nodejs/node/pull/4525", + "description": "Runtime deprecation." + }, { "version": "v0.1.96", "commit": "c93e0aaf062081db3ec40ac45b3e2c979d5759d6", @@ -404,7 +418,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The fs.read() legacy String interface is deprecated. Use the Buffer\nAPI as mentioned in the documentation instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The fs.read() legacy String interface is deprecated. Use the Buffer\nAPI as mentioned in the documentation instead.

      ", "type": "module", "displayName": "DEP0014: `fs.read` legacy String interface" }, @@ -418,19 +432,19 @@ "pr-url": "https://github.com/nodejs/node/pull/9683", "description": "End-of-Life." }, - { - "version": "v6.0.0", - "pr-url": "https://github.com/nodejs/node/pull/4525", - "description": "Runtime deprecation." - }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, + { + "version": "v6.0.0", + "pr-url": "https://github.com/nodejs/node/pull/4525", + "description": "Runtime deprecation." + }, { "version": "v0.1.96", "commit": "c93e0aaf062081db3ec40ac45b3e2c979d5759d6", @@ -438,7 +452,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The fs.readSync() legacy String interface is deprecated. Use the\nBuffer API as mentioned in the documentation instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The fs.readSync() legacy String interface is deprecated. Use the\nBuffer API as mentioned in the documentation instead.

      ", "type": "module", "displayName": "DEP0015: `fs.readSync` legacy String interface" }, @@ -447,6 +461,11 @@ "name": "dep0016:_`global`/`root`", "meta": { "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31167", + "description": "End-of-Life." + }, { "version": "v6.12.0", "pr-url": "https://github.com/nodejs/node/pull/10116", @@ -459,7 +478,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The GLOBAL and root aliases for the global property are deprecated\nand should no longer be used.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The GLOBAL and root aliases for the global property were deprecated\nin Node.js 6.0.0 and have since been removed.

      ", "type": "module", "displayName": "DEP0016: `GLOBAL`/`root`" }, @@ -480,7 +499,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      Intl.v8BreakIterator was a non-standard extension and has been removed.\nSee Intl.Segmenter.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Intl.v8BreakIterator was a non-standard extension and has been removed.\nSee Intl.Segmenter.

      ", "type": "module", "displayName": "DEP0017: `Intl.v8BreakIterator`" }, @@ -496,7 +515,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Unhandled promise rejections are deprecated. In the future, promise rejections\nthat are not handled will terminate the Node.js process with a non-zero exit\ncode.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Unhandled promise rejections are deprecated. In the future, promise rejections\nthat are not handled will terminate the Node.js process with a non-zero exit\ncode.

      ", "type": "module", "displayName": "DEP0018: Unhandled promise rejections" }, @@ -512,8 +531,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -525,7 +544,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      In certain cases, require('.') could resolve outside the package directory.\nThis behavior has been removed.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      In certain cases, require('.') could resolve outside the package directory.\nThis behavior has been removed.

      ", "type": "module", "displayName": "DEP0019: `require('.')` resolved outside directory" }, @@ -536,8 +555,8 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -549,7 +568,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The Server.connections property is deprecated. Please use the\nServer.getConnections() method instead.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The Server.connections property is deprecated. Please use the\nServer.getConnections() method instead.

      ", "type": "module", "displayName": "DEP0020: `Server.connections`" }, @@ -565,8 +584,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -578,7 +597,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The Server.listenFD() method was deprecated and removed. Please use\nServer.listen({fd: <number>}) instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The Server.listenFD() method was deprecated and removed. Please use\nServer.listen({fd: <number>}) instead.

      ", "type": "module", "displayName": "DEP0021: `Server.listenFD`" }, @@ -587,6 +606,11 @@ "name": "dep0022:_`os.tmpdir()`", "meta": { "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31169", + "description": "End-of-Life." + }, { "version": "v7.0.0", "pr-url": "https://github.com/nodejs/node/pull/6739", @@ -594,7 +618,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The os.tmpDir() API is deprecated. Please use os.tmpdir() instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The os.tmpDir() API was deprecated in Node.js 7.0.0 and has since been\nremoved. Please use os.tmpdir() instead.

      ", "type": "module", "displayName": "DEP0022: `os.tmpDir()`" }, @@ -610,8 +634,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -623,7 +647,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The os.getNetworkInterfaces() method is deprecated. Please use the\nos.networkInterfaces() method instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The os.getNetworkInterfaces() method is deprecated. Please use the\nos.networkInterfaces() method instead.

      ", "type": "module", "displayName": "DEP0023: `os.getNetworkInterfaces()`" }, @@ -644,7 +668,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The REPLServer.prototype.convertToContext() API has been removed.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The REPLServer.prototype.convertToContext() API has been removed.

      ", "type": "module", "displayName": "DEP0024: `REPLServer.prototype.convertToContext()`" }, @@ -655,8 +679,8 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -668,7 +692,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The sys module is deprecated. Please use the util module instead.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The sys module is deprecated. Please use the util module instead.

      ", "type": "module", "displayName": "DEP0025: `require('sys')`" }, @@ -684,8 +708,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -697,7 +721,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      util.print() has been removed. Please use console.log() instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      util.print() has been removed. Please use console.log() instead.

      ", "type": "module", "displayName": "DEP0026: `util.print()`" }, @@ -713,8 +737,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -726,7 +750,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      util.puts() has been removed. Please use console.log() instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      util.puts() has been removed. Please use console.log() instead.

      ", "type": "module", "displayName": "DEP0027: `util.puts()`" }, @@ -742,8 +766,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -755,7 +779,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      util.debug() has been removed. Please use console.error() instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      util.debug() has been removed. Please use console.error() instead.

      ", "type": "module", "displayName": "DEP0028: `util.debug()`" }, @@ -771,8 +795,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -784,7 +808,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      util.error() has been removed. Please use console.error() instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      util.error() has been removed. Please use console.error() instead.

      ", "type": "module", "displayName": "DEP0029: `util.error()`" }, @@ -805,7 +829,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The SlowBuffer class is deprecated. Please use\nBuffer.allocUnsafeSlow(size) instead.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The SlowBuffer class is deprecated. Please use\nBuffer.allocUnsafeSlow(size) instead.

      ", "type": "module", "displayName": "DEP0030: `SlowBuffer`" }, @@ -826,7 +850,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The ecdh.setPublicKey() method is now deprecated as its inclusion in the\nAPI is not useful.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The ecdh.setPublicKey() method is now deprecated as its inclusion in the\nAPI is not useful.

      ", "type": "module", "displayName": "DEP0031: `ecdh.setPublicKey()`" }, @@ -837,8 +861,8 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -850,7 +874,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The domain module is deprecated and should not be used.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The domain module is deprecated and should not be used.

      ", "type": "module", "displayName": "DEP0032: `domain` module" }, @@ -861,8 +885,8 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -874,7 +898,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The EventEmitter.listenerCount(emitter, eventName) API is\ndeprecated. Please use emitter.listenerCount(eventName) instead.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The events.listenerCount(emitter, eventName) API is\ndeprecated. Please use emitter.listenerCount(eventName) instead.

      ", "type": "module", "displayName": "DEP0033: `EventEmitter.listenerCount()`" }, @@ -885,20 +909,20 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": "v1.0.0", - "pr-url": "https://github.com/iojs/io.js/pull/166", + "pr-url": "https://github.com/nodejs/node/pull/166", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The fs.exists(path, callback) API is deprecated. Please use\nfs.stat() or fs.access() instead.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The fs.exists(path, callback) API is deprecated. Please use\nfs.stat() or fs.access() instead.

      ", "type": "module", "displayName": "DEP0034: `fs.exists(path, callback)`" }, @@ -909,8 +933,8 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -921,7 +945,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The fs.lchmod(path, mode, callback) API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The fs.lchmod(path, mode, callback) API is deprecated.

      ", "type": "module", "displayName": "DEP0035: `fs.lchmod(path, mode, callback)`" }, @@ -932,8 +956,8 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -944,7 +968,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The fs.lchmodSync(path, mode) API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The fs.lchmodSync(path, mode) API is deprecated.

      ", "type": "module", "displayName": "DEP0036: `fs.lchmodSync(path, mode)`" }, @@ -960,8 +984,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -972,7 +996,7 @@ } ] }, - "desc": "

      Type: Deprecation revoked

      \n

      The fs.lchown(path, uid, gid, callback) API was deprecated. The\ndeprecation was revoked because the requisite supporting APIs were added in\nlibuv.

      \n

      ", + "desc": "

      Type: Deprecation revoked

      \n

      The fs.lchown(path, uid, gid, callback) API was deprecated. The\ndeprecation was revoked because the requisite supporting APIs were added in\nlibuv.

      ", "type": "module", "displayName": "DEP0037: `fs.lchown(path, uid, gid, callback)`" }, @@ -988,8 +1012,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -1000,7 +1024,7 @@ } ] }, - "desc": "

      Type: Deprecation revoked

      \n

      The fs.lchownSync(path, uid, gid) API was deprecated. The deprecation was\nrevoked because the requisite supporting APIs were added in libuv.

      \n

      ", + "desc": "

      Type: Deprecation revoked

      \n

      The fs.lchownSync(path, uid, gid) API was deprecated. The deprecation was\nrevoked because the requisite supporting APIs were added in libuv.

      ", "type": "module", "displayName": "DEP0038: `fs.lchownSync(path, uid, gid)`" }, @@ -1011,8 +1035,8 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -1024,7 +1048,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The require.extensions property is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The require.extensions property is deprecated.

      ", "type": "module", "displayName": "DEP0039: `require.extensions`" }, @@ -1040,7 +1064,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The punycode module is deprecated. Please use a userland alternative\ninstead.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The punycode module is deprecated. Please use a userland alternative\ninstead.

      ", "type": "module", "displayName": "DEP0040: `punycode` module" }, @@ -1056,8 +1080,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -1069,7 +1093,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The NODE_REPL_HISTORY_FILE environment variable was removed. Please use\nNODE_REPL_HISTORY instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The NODE_REPL_HISTORY_FILE environment variable was removed. Please use\nNODE_REPL_HISTORY instead.

      ", "type": "module", "displayName": "DEP0041: `NODE_REPL_HISTORY_FILE` environment variable" }, @@ -1085,8 +1109,8 @@ }, { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." @@ -1098,7 +1122,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The tls.CryptoStream class was removed. Please use\ntls.TLSSocket instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The tls.CryptoStream class was removed. Please use\ntls.TLSSocket instead.

      ", "type": "module", "displayName": "DEP0042: `tls.CryptoStream`" }, @@ -1137,7 +1161,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The tls.SecurePair class is deprecated. Please use\ntls.TLSSocket instead.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The tls.SecurePair class is deprecated. Please use\ntls.TLSSocket instead.

      ", "type": "module", "displayName": "DEP0043: `tls.SecurePair`" }, @@ -1148,23 +1172,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isArray() API is deprecated. Please use Array.isArray()\ninstead.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isArray() API is deprecated. Please use Array.isArray()\ninstead.

      ", "type": "module", "displayName": "DEP0044: `util.isArray()`" }, @@ -1175,23 +1199,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isBoolean() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isBoolean() API is deprecated.

      ", "type": "module", "displayName": "DEP0045: `util.isBoolean()`" }, @@ -1202,23 +1226,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isBuffer() API is deprecated. Please use\nBuffer.isBuffer() instead.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isBuffer() API is deprecated. Please use\nBuffer.isBuffer() instead.

      ", "type": "module", "displayName": "DEP0046: `util.isBuffer()`" }, @@ -1229,23 +1253,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isDate() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isDate() API is deprecated.

      ", "type": "module", "displayName": "DEP0047: `util.isDate()`" }, @@ -1256,23 +1280,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isError() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isError() API is deprecated.

      ", "type": "module", "displayName": "DEP0048: `util.isError()`" }, @@ -1283,23 +1307,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isFunction() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isFunction() API is deprecated.

      ", "type": "module", "displayName": "DEP0049: `util.isFunction()`" }, @@ -1310,23 +1334,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isNull() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isNull() API is deprecated.

      ", "type": "module", "displayName": "DEP0050: `util.isNull()`" }, @@ -1337,23 +1361,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isNullOrUndefined() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isNullOrUndefined() API is deprecated.

      ", "type": "module", "displayName": "DEP0051: `util.isNullOrUndefined()`" }, @@ -1364,52 +1388,52 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isNumber() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isNumber() API is deprecated.

      ", "type": "module", "displayName": "DEP0052: `util.isNumber()`" }, { - "textRaw": "DEP0053 `util.isObject()`", - "name": "dep0053_`util.isobject()`", + "textRaw": "DEP0053: `util.isObject()`", + "name": "dep0053:_`util.isobject()`", "meta": { "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isObject() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isObject() API is deprecated.

      ", "type": "module", - "displayName": "DEP0053 `util.isObject()`" + "displayName": "DEP0053: `util.isObject()`" }, { "textRaw": "DEP0054: `util.isPrimitive()`", @@ -1418,23 +1442,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isPrimitive() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isPrimitive() API is deprecated.

      ", "type": "module", "displayName": "DEP0054: `util.isPrimitive()`" }, @@ -1445,23 +1469,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isRegExp() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isRegExp() API is deprecated.

      ", "type": "module", "displayName": "DEP0055: `util.isRegExp()`" }, @@ -1472,23 +1496,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isString() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isString() API is deprecated.

      ", "type": "module", "displayName": "DEP0056: `util.isString()`" }, @@ -1499,23 +1523,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isSymbol() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isSymbol() API is deprecated.

      ", "type": "module", "displayName": "DEP0057: `util.isSymbol()`" }, @@ -1526,23 +1550,23 @@ "changes": [ { "version": [ - "v4.8.6", - "v6.12.0" + "v6.12.0", + "v4.8.6" ], "pr-url": "https://github.com/nodejs/node/pull/10116", "description": "A deprecation code has been assigned." }, { "version": [ - "v3.3.1", - "v4.0.0" + "v4.0.0", + "v3.3.1" ], "pr-url": "https://github.com/nodejs/node/pull/2447", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.isUndefined() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.isUndefined() API is deprecated.

      ", "type": "module", "displayName": "DEP0058: `util.isUndefined()`" }, @@ -1563,7 +1587,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util.log() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util.log() API is deprecated.

      ", "type": "module", "displayName": "DEP0059: `util.log()`" }, @@ -1584,7 +1608,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The util._extend() API is deprecated.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The util._extend() API is deprecated.

      ", "type": "module", "displayName": "DEP0060: `util._extend()`" }, @@ -1610,7 +1634,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The fs.SyncWriteStream class was never intended to be a publicly accessible\nAPI and has been removed. No alternative API is available. Please use a userland\nalternative.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The fs.SyncWriteStream class was never intended to be a publicly accessible\nAPI and has been removed. No alternative API is available. Please use a userland\nalternative.

      ", "type": "module", "displayName": "DEP0061: `fs.SyncWriteStream`" }, @@ -1619,19 +1643,19 @@ "name": "dep0062:_`node_--debug`", "meta": { "changes": [ - { - "version": "v8.0.0", - "pr-url": "https://github.com/nodejs/node/pull/10970", - "description": "Runtime deprecation." - }, { "version": "v12.0.0", "pr-url": "https://github.com/nodejs/node/pull/25828", "description": "End-of-Life." + }, + { + "version": "v8.0.0", + "pr-url": "https://github.com/nodejs/node/pull/10970", + "description": "Runtime deprecation." } ] }, - "desc": "

      Type: End-of-Life

      \n

      --debug activates the legacy V8 debugger interface, which was removed as\nof V8 5.8. It is replaced by Inspector which is activated with --inspect\ninstead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      --debug activates the legacy V8 debugger interface, which was removed as\nof V8 5.8. It is replaced by Inspector which is activated with --inspect\ninstead.

      ", "type": "module", "displayName": "DEP0062: `node --debug`" }, @@ -1647,7 +1671,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The http module ServerResponse.prototype.writeHeader() API is\ndeprecated. Please use ServerResponse.prototype.writeHead() instead.

      \n

      The ServerResponse.prototype.writeHeader() method was never documented as an\nofficially supported API.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The http module ServerResponse.prototype.writeHeader() API is\ndeprecated. Please use ServerResponse.prototype.writeHead() instead.

      \n

      The ServerResponse.prototype.writeHeader() method was never documented as an\nofficially supported API.

      ", "type": "module", "displayName": "DEP0063: `ServerResponse.prototype.writeHeader()`" }, @@ -1686,7 +1710,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The tls.createSecurePair() API was deprecated in documentation in Node.js\n0.11.3. Users should use tls.Socket instead.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The tls.createSecurePair() API was deprecated in documentation in Node.js\n0.11.3. Users should use tls.Socket instead.

      ", "type": "module", "displayName": "DEP0064: `tls.createSecurePair()`" }, @@ -1707,7 +1731,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The repl module's REPL_MODE_MAGIC constant, used for replMode option, has\nbeen removed. Its behavior has been functionally identical to that of\nREPL_MODE_SLOPPY since Node.js 6.0.0, when V8 5.0 was imported. Please use\nREPL_MODE_SLOPPY instead.

      \n

      The NODE_REPL_MODE environment variable is used to set the underlying\nreplMode of an interactive node session. Its value, magic, is also\nremoved. Please use sloppy instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The repl module's REPL_MODE_MAGIC constant, used for replMode option, has\nbeen removed. Its behavior has been functionally identical to that of\nREPL_MODE_SLOPPY since Node.js 6.0.0, when V8 5.0 was imported. Please use\nREPL_MODE_SLOPPY instead.

      \n

      The NODE_REPL_MODE environment variable is used to set the underlying\nreplMode of an interactive node session. Its value, magic, is also\nremoved. Please use sloppy instead.

      ", "type": "module", "displayName": "DEP0065: `repl.REPL_MODE_MAGIC` and `NODE_REPL_MODE=magic`" }, @@ -1728,7 +1752,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The http module OutgoingMessage.prototype._headers and\nOutgoingMessage.prototype._headerNames properties are deprecated. Use one of\nthe public methods (e.g. OutgoingMessage.prototype.getHeader(),\nOutgoingMessage.prototype.getHeaders(),\nOutgoingMessage.prototype.getHeaderNames(),\nOutgoingMessage.prototype.hasHeader(),\nOutgoingMessage.prototype.removeHeader(),\nOutgoingMessage.prototype.setHeader()) for working with outgoing headers.

      \n

      The OutgoingMessage.prototype._headers and\nOutgoingMessage.prototype._headerNames properties were never documented as\nofficially supported properties.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The http module OutgoingMessage.prototype._headers and\nOutgoingMessage.prototype._headerNames properties are deprecated. Use one of\nthe public methods (e.g. OutgoingMessage.prototype.getHeader(),\nOutgoingMessage.prototype.getHeaders(),\nOutgoingMessage.prototype.getHeaderNames(),\nOutgoingMessage.prototype.getRawHeaderNames(),\nOutgoingMessage.prototype.hasHeader(),\nOutgoingMessage.prototype.removeHeader(),\nOutgoingMessage.prototype.setHeader()) for working with outgoing headers.

      \n

      The OutgoingMessage.prototype._headers and\nOutgoingMessage.prototype._headerNames properties were never documented as\nofficially supported properties.

      ", "type": "module", "displayName": "DEP0066: `OutgoingMessage.prototype._headers, OutgoingMessage.prototype._headerNames`" }, @@ -1744,7 +1768,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The http module OutgoingMessage.prototype._renderHeaders() API is\ndeprecated.

      \n

      The OutgoingMessage.prototype._renderHeaders property was never documented as\nan officially supported API.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The http module OutgoingMessage.prototype._renderHeaders() API is\ndeprecated.

      \n

      The OutgoingMessage.prototype._renderHeaders property was never documented as\nan officially supported API.

      ", "type": "module", "displayName": "DEP0067: `OutgoingMessage.prototype._renderHeaders`" }, @@ -1760,7 +1784,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      node debug corresponds to the legacy CLI debugger which has been replaced with\na V8-inspector based CLI debugger available through node inspect.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      node debug corresponds to the legacy CLI debugger which has been replaced with\na V8-inspector based CLI debugger available through node inspect.

      ", "type": "module", "displayName": "DEP0068: `node debug`" }, @@ -1786,7 +1810,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      DebugContext has been removed in V8 and is not available in Node.js 10+.

      \n

      DebugContext was an experimental API.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      DebugContext has been removed in V8 and is not available in Node.js 10+.

      \n

      DebugContext was an experimental API.

      ", "type": "module", "displayName": "DEP0069: `vm.runInDebugContext(string)`" }, @@ -1807,7 +1831,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      async_hooks.currentId() was renamed to async_hooks.executionAsyncId() for\nclarity.

      \n

      This change was made while async_hooks was an experimental API.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      async_hooks.currentId() was renamed to async_hooks.executionAsyncId() for\nclarity.

      \n

      This change was made while async_hooks was an experimental API.

      ", "type": "module", "displayName": "DEP0070: `async_hooks.currentId()`" }, @@ -1828,7 +1852,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      async_hooks.triggerId() was renamed to async_hooks.triggerAsyncId() for\nclarity.

      \n

      This change was made while async_hooks was an experimental API.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      async_hooks.triggerId() was renamed to async_hooks.triggerAsyncId() for\nclarity.

      \n

      This change was made while async_hooks was an experimental API.

      ", "type": "module", "displayName": "DEP0071: `async_hooks.triggerId()`" }, @@ -1849,7 +1873,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      async_hooks.AsyncResource.triggerId() was renamed to\nasync_hooks.AsyncResource.triggerAsyncId() for clarity.

      \n

      This change was made while async_hooks was an experimental API.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      async_hooks.AsyncResource.triggerId() was renamed to\nasync_hooks.AsyncResource.triggerAsyncId() for clarity.

      \n

      This change was made while async_hooks was an experimental API.

      ", "type": "module", "displayName": "DEP0072: `async_hooks.AsyncResource.triggerId()`" }, @@ -1870,7 +1894,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      Accessing several internal, undocumented properties of net.Server instances\nwith inappropriate names is deprecated.

      \n

      As the original API was undocumented and not generally useful for non-internal\ncode, no replacement API is provided.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Accessing several internal, undocumented properties of net.Server instances\nwith inappropriate names is deprecated.

      \n

      As the original API was undocumented and not generally useful for non-internal\ncode, no replacement API is provided.

      ", "type": "module", "displayName": "DEP0073: Several internal properties of `net.Server`" }, @@ -1886,7 +1910,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The REPLServer.bufferedCommand property was deprecated in favor of\nREPLServer.clearBufferedCommand().

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The REPLServer.bufferedCommand property was deprecated in favor of\nREPLServer.clearBufferedCommand().

      ", "type": "module", "displayName": "DEP0074: `REPLServer.bufferedCommand`" }, @@ -1902,7 +1926,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      REPLServer.parseREPLKeyword() was removed from userland visibility.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      REPLServer.parseREPLKeyword() was removed from userland visibility.

      ", "type": "module", "displayName": "DEP0075: `REPLServer.parseREPLKeyword()`" }, @@ -1923,7 +1947,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      tls.parseCertString() is a trivial parsing helper that was made public by\nmistake. This function can usually be replaced with:

      \n
      const querystring = require('querystring');\nquerystring.parse(str, '\\n', '=');\n
      \n

      This function is not completely equivalent to querystring.parse(). One\ndifference is that querystring.parse() does url decoding:

      \n
      > querystring.parse('%E5%A5%BD=1', '\\n', '=');\n{ '好': '1' }\n> tls.parseCertString('%E5%A5%BD=1');\n{ '%E5%A5%BD': '1' }\n
      \n

      ", + "desc": "

      Type: Runtime

      \n

      tls.parseCertString() is a trivial parsing helper that was made public by\nmistake. This function can usually be replaced with:

      \n
      const querystring = require('querystring');\nquerystring.parse(str, '\\n', '=');\n
      \n

      This function is not completely equivalent to querystring.parse(). One\ndifference is that querystring.parse() does url decoding:

      \n
      > querystring.parse('%E5%A5%BD=1', '\\n', '=');\n{ '好': '1' }\n> tls.parseCertString('%E5%A5%BD=1');\n{ '%E5%A5%BD': '1' }\n
      ", "type": "module", "displayName": "DEP0076: `tls.parseCertString()`" }, @@ -1939,7 +1963,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Module._debug() is deprecated.

      \n

      The Module._debug() function was never documented as an officially\nsupported API.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Module._debug() is deprecated.

      \n

      The Module._debug() function was never documented as an officially\nsupported API.

      ", "type": "module", "displayName": "DEP0077: `Module._debug()`" }, @@ -1955,7 +1979,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      REPLServer.turnOffEditorMode() was removed from userland visibility.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      REPLServer.turnOffEditorMode() was removed from userland visibility.

      ", "type": "module", "displayName": "DEP0078: `REPLServer.turnOffEditorMode()`" }, @@ -1981,7 +2005,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      Using a property named inspect on an object to specify a custom inspection\nfunction for util.inspect() is deprecated. Use util.inspect.custom\ninstead. For backward compatibility with Node.js prior to version 6.4.0, both\nmay be specified.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Using a property named inspect on an object to specify a custom inspection\nfunction for util.inspect() is deprecated. Use util.inspect.custom\ninstead. For backward compatibility with Node.js prior to version 6.4.0, both\ncan be specified.

      ", "type": "module", "displayName": "DEP0079: Custom inspection function on objects via `.inspect()`" }, @@ -1997,7 +2021,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The internal path._makeLong() was not intended for public use. However,\nuserland modules have found it useful. The internal API is deprecated\nand replaced with an identical, public path.toNamespacedPath() method.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The internal path._makeLong() was not intended for public use. However,\nuserland modules have found it useful. The internal API is deprecated\nand replaced with an identical, public path.toNamespacedPath() method.

      ", "type": "module", "displayName": "DEP0080: `path._makeLong()`" }, @@ -2013,7 +2037,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      fs.truncate() fs.truncateSync() usage with a file descriptor is\ndeprecated. Please use fs.ftruncate() or fs.ftruncateSync() to work with\nfile descriptors.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      fs.truncate() fs.truncateSync() usage with a file descriptor is\ndeprecated. Please use fs.ftruncate() or fs.ftruncateSync() to work with\nfile descriptors.

      ", "type": "module", "displayName": "DEP0081: `fs.truncate()` using a file descriptor" }, @@ -2029,7 +2053,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      REPLServer.prototype.memory() is only necessary for the internal mechanics of\nthe REPLServer itself. Do not use this function.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      REPLServer.prototype.memory() is only necessary for the internal mechanics of\nthe REPLServer itself. Do not use this function.

      ", "type": "module", "displayName": "DEP0082: `REPLServer.prototype.memory()`" }, @@ -2050,7 +2074,7 @@ } ] }, - "desc": "

      Type: End-of-Life.

      \n

      The ecdhCurve option to tls.createSecureContext() and tls.TLSSocket could\nbe set to false to disable ECDH entirely on the server only. This mode was\ndeprecated in preparation for migrating to OpenSSL 1.1.0 and consistency with\nthe client and is now unsupported. Use the ciphers parameter instead.

      \n

      ", + "desc": "

      Type: End-of-Life.

      \n

      The ecdhCurve option to tls.createSecureContext() and tls.TLSSocket could\nbe set to false to disable ECDH entirely on the server only. This mode was\ndeprecated in preparation for migrating to OpenSSL 1.1.0 and consistency with\nthe client and is now unsupported. Use the ciphers parameter instead.

      ", "type": "module", "displayName": "DEP0083: Disabling ECDH by setting `ecdhCurve` to `false`" }, @@ -2071,7 +2095,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      Since Node.js versions 4.4.0 and 5.2.0, several modules only intended for\ninternal usage were mistakenly exposed to user code through require(). These\nmodules were:

      \n
        \n
      • v8/tools/codemap
      • \n
      • v8/tools/consarray
      • \n
      • v8/tools/csvparser
      • \n
      • v8/tools/logreader
      • \n
      • v8/tools/profile_view
      • \n
      • v8/tools/profile
      • \n
      • v8/tools/SourceMap
      • \n
      • v8/tools/splaytree
      • \n
      • v8/tools/tickprocessor-driver
      • \n
      • v8/tools/tickprocessor
      • \n
      • node-inspect/lib/_inspect (from 7.6.0)
      • \n
      • node-inspect/lib/internal/inspect_client (from 7.6.0)
      • \n
      • node-inspect/lib/internal/inspect_repl (from 7.6.0)
      • \n
      \n

      The v8/* modules do not have any exports, and if not imported in a specific\norder would in fact throw errors. As such there are virtually no legitimate use\ncases for importing them through require().

      \n

      On the other hand, node-inspect may be installed locally through a package\nmanager, as it is published on the npm registry under the same name. No source\ncode modification is necessary if that is done.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Since Node.js versions 4.4.0 and 5.2.0, several modules only intended for\ninternal usage were mistakenly exposed to user code through require(). These\nmodules were:

      \n
        \n
      • v8/tools/codemap
      • \n
      • v8/tools/consarray
      • \n
      • v8/tools/csvparser
      • \n
      • v8/tools/logreader
      • \n
      • v8/tools/profile_view
      • \n
      • v8/tools/profile
      • \n
      • v8/tools/SourceMap
      • \n
      • v8/tools/splaytree
      • \n
      • v8/tools/tickprocessor-driver
      • \n
      • v8/tools/tickprocessor
      • \n
      • node-inspect/lib/_inspect (from 7.6.0)
      • \n
      • node-inspect/lib/internal/inspect_client (from 7.6.0)
      • \n
      • node-inspect/lib/internal/inspect_repl (from 7.6.0)
      • \n
      \n

      The v8/* modules do not have any exports, and if not imported in a specific\norder would in fact throw errors. As such there are virtually no legitimate use\ncases for importing them through require().

      \n

      On the other hand, node-inspect can be installed locally through a package\nmanager, as it is published on the npm registry under the same name. No source\ncode modification is necessary if that is done.

      ", "type": "module", "displayName": "DEP0084: requiring bundled internal dependencies" }, @@ -2081,21 +2105,21 @@ "meta": { "changes": [ { - "version": "10.0.0", + "version": "v10.0.0", "pr-url": "https://github.com/nodejs/node/pull/17147", "description": "End-of-Life." }, { "version": [ - "v8.10.0", - "v9.4.0" + "v9.4.0", + "v8.10.0" ], "pr-url": "https://github.com/nodejs/node/pull/16972", "description": "Runtime deprecation." } ] }, - "desc": "

      Type: End-of-Life

      \n

      The AsyncHooks sensitive API was never documented and had various minor issues.\nUse the AsyncResource API instead. See\nhttps://github.com/nodejs/node/issues/15572.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The AsyncHooks sensitive API was never documented and had various minor issues.\nUse the AsyncResource API instead. See\nhttps://github.com/nodejs/node/issues/15572.

      ", "type": "module", "displayName": "DEP0085: AsyncHooks sensitive API" }, @@ -2105,21 +2129,21 @@ "meta": { "changes": [ { - "version": "10.0.0", + "version": "v10.0.0", "pr-url": "https://github.com/nodejs/node/pull/17147", "description": "End-of-Life." }, { "version": [ - "v8.10.0", - "v9.4.0" + "v9.4.0", + "v8.10.0" ], "pr-url": "https://github.com/nodejs/node/pull/16972", "description": "Runtime deprecation." } ] }, - "desc": "

      Type: End-of-Life

      \n

      runInAsyncIdScope doesn't emit the 'before' or 'after' event and can thus\ncause a lot of issues. See https://github.com/nodejs/node/issues/14328.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      runInAsyncIdScope doesn't emit the 'before' or 'after' event and can thus\ncause a lot of issues. See https://github.com/nodejs/node/issues/14328.

      ", "type": "module", "displayName": "DEP0086: Remove `runInAsyncIdScope`" }, @@ -2136,14 +2160,14 @@ { "version": [ "v9.9.0", - "v10.0.0" + "v8.13.0" ], "pr-url": "https://github.com/nodejs/node/pull/17002", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Deprecation revoked

      \n

      Importing assert directly was not recommended as the exposed functions use\nloose equality checks. The deprecation was revoked because use of the assert\nmodule is not discouraged, and the deprecation caused developer confusion.

      \n

      ", + "desc": "

      Type: Deprecation revoked

      \n

      Importing assert directly was not recommended as the exposed functions use\nloose equality checks. The deprecation was revoked because use of the assert\nmodule is not discouraged, and the deprecation caused developer confusion.

      ", "type": "module", "displayName": "DEP0089: `require('assert')`" }, @@ -2164,7 +2188,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      Node.js used to support all GCM authentication tag lengths which are accepted by\nOpenSSL when calling decipher.setAuthTag(). Beginning with Node.js\nv11.0.0, only authentication tag lengths of 128, 120, 112, 104, 96, 64, and 32\nbits are allowed. Authentication tags of other lengths are invalid per\nNIST SP 800-38D.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Node.js used to support all GCM authentication tag lengths which are accepted by\nOpenSSL when calling decipher.setAuthTag(). Beginning with Node.js\nv11.0.0, only authentication tag lengths of 128, 120, 112, 104, 96, 64, and 32\nbits are allowed. Authentication tags of other lengths are invalid per\nNIST SP 800-38D.

      ", "type": "module", "displayName": "DEP0090: Invalid GCM authentication tag lengths" }, @@ -2180,7 +2204,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The crypto.DEFAULT_ENCODING property is deprecated.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The crypto.DEFAULT_ENCODING property is deprecated.

      ", "type": "module", "displayName": "DEP0091: `crypto.DEFAULT_ENCODING`" }, @@ -2196,13 +2220,13 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      Assigning properties to the top-level this as an alternative\nto module.exports is deprecated. Developers should use exports\nor module.exports instead.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      Assigning properties to the top-level this as an alternative\nto module.exports is deprecated. Developers should use exports\nor module.exports instead.

      ", "type": "module", "displayName": "DEP0092: Top-level `this` bound to `module.exports`" }, { - "textRaw": "DEP0093: `crypto.fips` is deprecated and replaced.", - "name": "dep0093:_`crypto.fips`_is_deprecated_and_replaced.", + "textRaw": "DEP0093: `crypto.fips` is deprecated and replaced", + "name": "dep0093:_`crypto.fips`_is_deprecated_and_replaced", "meta": { "changes": [ { @@ -2212,13 +2236,13 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The crypto.fips property is deprecated. Please use crypto.setFips()\nand crypto.getFips() instead.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The crypto.fips property is deprecated. Please use crypto.setFips()\nand crypto.getFips() instead.

      ", "type": "module", - "displayName": "DEP0093: `crypto.fips` is deprecated and replaced." + "displayName": "DEP0093: `crypto.fips` is deprecated and replaced" }, { - "textRaw": "DEP0094: Using `assert.fail()` with more than one argument.", - "name": "dep0094:_using_`assert.fail()`_with_more_than_one_argument.", + "textRaw": "DEP0094: Using `assert.fail()` with more than one argument", + "name": "dep0094:_using_`assert.fail()`_with_more_than_one_argument", "meta": { "changes": [ { @@ -2228,9 +2252,9 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Using assert.fail() with more than one argument is deprecated. Use\nassert.fail() with only one argument or use a different assert module\nmethod.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Using assert.fail() with more than one argument is deprecated. Use\nassert.fail() with only one argument or use a different assert module\nmethod.

      ", "type": "module", - "displayName": "DEP0094: Using `assert.fail()` with more than one argument." + "displayName": "DEP0094: Using `assert.fail()` with more than one argument" }, { "textRaw": "DEP0095: `timers.enroll()`", @@ -2244,7 +2268,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      timers.enroll() is deprecated. Please use the publicly documented\nsetTimeout() or setInterval() instead.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      timers.enroll() is deprecated. Please use the publicly documented\nsetTimeout() or setInterval() instead.

      ", "type": "module", "displayName": "DEP0095: `timers.enroll()`" }, @@ -2260,7 +2284,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      timers.unenroll() is deprecated. Please use the publicly documented\nclearTimeout() or clearInterval() instead.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      timers.unenroll() is deprecated. Please use the publicly documented\nclearTimeout() or clearInterval() instead.

      ", "type": "module", "displayName": "DEP0096: `timers.unenroll()`" }, @@ -2276,7 +2300,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Users of MakeCallback that add the domain property to carry context,\nshould start using the async_context variant of MakeCallback or\nCallbackScope, or the high-level AsyncResource class.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Users of MakeCallback that add the domain property to carry context,\nshould start using the async_context variant of MakeCallback or\nCallbackScope, or the high-level AsyncResource class.

      ", "type": "module", "displayName": "DEP0097: `MakeCallback` with `domain` property" }, @@ -2288,20 +2312,20 @@ { "version": "v12.0.0", "pr-url": "https://github.com/nodejs/node/pull/26530", - "description": "End-of-Life" + "description": "End-of-Life." }, { "version": [ - "v8.12.0", + "v10.0.0", "v9.6.0", - "v10.0.0" + "v8.12.0" ], "pr-url": "https://github.com/nodejs/node/pull/18632", "description": "Runtime deprecation." } ] }, - "desc": "

      Type: End-of-Life

      \n

      The embedded API provided by AsyncHooks exposes .emitBefore() and\n.emitAfter() methods which are very easy to use incorrectly which can lead\nto unrecoverable errors.

      \n

      Use asyncResource.runInAsyncScope() API instead which provides a much\nsafer, and more convenient, alternative. See\nhttps://github.com/nodejs/node/pull/18513.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The embedded API provided by AsyncHooks exposes .emitBefore() and\n.emitAfter() methods which are very easy to use incorrectly which can lead\nto unrecoverable errors.

      \n

      Use asyncResource.runInAsyncScope() API instead which provides a much\nsafer, and more convenient, alternative. See\nhttps://github.com/nodejs/node/pull/18513.

      ", "type": "module", "displayName": "DEP0098: AsyncHooks embedder `AsyncResource.emitBefore` and `AsyncResource.emitAfter` APIs" }, @@ -2317,7 +2341,7 @@ } ] }, - "desc": "

      Type: Compile-time

      \n

      Certain versions of node::MakeCallback APIs available to native modules are\ndeprecated. Please use the versions of the API that accept an async_context\nparameter.

      \n

      ", + "desc": "

      Type: Compile-time

      \n

      Certain versions of node::MakeCallback APIs available to native modules are\ndeprecated. Please use the versions of the API that accept an async_context\nparameter.

      ", "type": "module", "displayName": "DEP0099: Async context-unaware `node::MakeCallback` C++ APIs" }, @@ -2337,7 +2361,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      process.assert() is deprecated. Please use the assert module instead.

      \n

      This was never a documented feature.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      process.assert() is deprecated. Please use the assert module instead.

      \n

      This was never a documented feature.

      ", "type": "module", "displayName": "DEP0100: `process.assert()`" }, @@ -2353,13 +2377,13 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The --with-lttng compile-time option has been removed.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The --with-lttng compile-time option has been removed.

      ", "type": "module", "displayName": "DEP0101: `--with-lttng`" }, { - "textRaw": "DEP0102: Using `noAssert` in `Buffer#(read|write)` operations.", - "name": "dep0102:_using_`noassert`_in_`buffer#(read|write)`_operations.", + "textRaw": "DEP0102: Using `noAssert` in `Buffer#(read|write)` operations", + "name": "dep0102:_using_`noassert`_in_`buffer#(read|write)`_operations", "meta": { "changes": [ { @@ -2369,9 +2393,9 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      Using the noAssert argument has no functionality anymore. All input is going\nto be verified, no matter if it is set to true or not. Skipping the verification\ncould lead to hard to find errors and crashes.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Using the noAssert argument has no functionality anymore. All input is going\nto be verified, no matter if it is set to true or not. Skipping the verification\ncould lead to hard to find errors and crashes.

      ", "type": "module", - "displayName": "DEP0102: Using `noAssert` in `Buffer#(read|write)` operations." + "displayName": "DEP0102: Using `noAssert` in `Buffer#(read|write)` operations" }, { "textRaw": "DEP0103: `process.binding('util').is[...]` typechecks", @@ -2390,7 +2414,7 @@ } ] }, - "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      Using process.binding() in general should be avoided. The type checking\nmethods in particular can be replaced by using util.types.

      \n

      This deprecation has been superseded by the deprecation of the\nprocess.binding() API (DEP0111).

      \n

      ", + "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      Using process.binding() in general should be avoided. The type checking\nmethods in particular can be replaced by using util.types.

      \n

      This deprecation has been superseded by the deprecation of the\nprocess.binding() API (DEP0111).

      ", "type": "module", "displayName": "DEP0103: `process.binding('util').is[...]` typechecks" }, @@ -2406,7 +2430,7 @@ } ] }, - "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      When assigning a non-string property to process.env, the assigned value is\nimplicitly converted to a string. This behavior is deprecated if the assigned\nvalue is not a string, boolean, or number. In the future, such assignment may\nresult in a thrown error. Please convert the property to a string before\nassigning it to process.env.

      \n

      ", + "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      When assigning a non-string property to process.env, the assigned value is\nimplicitly converted to a string. This behavior is deprecated if the assigned\nvalue is not a string, boolean, or number. In the future, such assignment might\nresult in a thrown error. Please convert the property to a string before\nassigning it to process.env.

      ", "type": "module", "displayName": "DEP0104: `process.env` string coercion" }, @@ -2427,7 +2451,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      decipher.finaltol() has never been documented and was an alias for\ndecipher.final(). This API has been removed, and it is recommended to use\ndecipher.final() instead.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      decipher.finaltol() has never been documented and was an alias for\ndecipher.final(). This API has been removed, and it is recommended to use\ndecipher.final() instead.

      ", "type": "module", "displayName": "DEP0105: `decipher.finaltol`" }, @@ -2448,7 +2472,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Using crypto.createCipher() and crypto.createDecipher() should be\navoided as they use a weak key derivation function (MD5 with no salt) and static\ninitialization vectors. It is recommended to derive a key using\ncrypto.pbkdf2() or crypto.scrypt() and to use\ncrypto.createCipheriv() and crypto.createDecipheriv() to obtain the\nCipher and Decipher objects respectively.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Using crypto.createCipher() and crypto.createDecipher() should be\navoided as they use a weak key derivation function (MD5 with no salt) and static\ninitialization vectors. It is recommended to derive a key using\ncrypto.pbkdf2() or crypto.scrypt() and to use\ncrypto.createCipheriv() and crypto.createDecipheriv() to obtain the\nCipher and Decipher objects respectively.

      ", "type": "module", "displayName": "DEP0106: `crypto.createCipher` and `crypto.createDecipher`" }, @@ -2469,7 +2493,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      This was an undocumented helper function not intended for use outside Node.js\ncore and obsoleted by the removal of NPN (Next Protocol Negotiation) support.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      This was an undocumented helper function not intended for use outside Node.js\ncore and obsoleted by the removal of NPN (Next Protocol Negotiation) support.

      ", "type": "module", "displayName": "DEP0107: `tls.convertNPNProtocols()`" }, @@ -2490,7 +2514,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Deprecated alias for zlib.bytesWritten. This original name was chosen\nbecause it also made sense to interpret the value as the number of bytes\nread by the engine, but is inconsistent with other streams in Node.js that\nexpose values under these names.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Deprecated alias for zlib.bytesWritten. This original name was chosen\nbecause it also made sense to interpret the value as the number of bytes\nread by the engine, but is inconsistent with other streams in Node.js that\nexpose values under these names.

      ", "type": "module", "displayName": "DEP0108: `zlib.bytesRead`" }, @@ -2506,7 +2530,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Some previously supported (but strictly invalid) URLs were accepted through the\nhttp.request(), http.get(), https.request(),\nhttps.get(), and tls.checkServerIdentity() APIs because those were\naccepted by the legacy url.parse() API. The mentioned APIs now use the WHATWG\nURL parser that requires strictly valid URLs. Passing an invalid URL is\ndeprecated and support will be removed in the future.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Some previously supported (but strictly invalid) URLs were accepted through the\nhttp.request(), http.get(), https.request(),\nhttps.get(), and tls.checkServerIdentity() APIs because those were\naccepted by the legacy url.parse() API. The mentioned APIs now use the WHATWG\nURL parser that requires strictly valid URLs. Passing an invalid URL is\ndeprecated and support will be removed in the future.

      ", "type": "module", "displayName": "DEP0109: `http`, `https`, and `tls` support for invalid URLs" }, @@ -2522,7 +2546,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The produceCachedData option is deprecated. Use\nscript.createCachedData() instead.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      The produceCachedData option is deprecated. Use\nscript.createCachedData() instead.

      ", "type": "module", "displayName": "DEP0110: `vm.Script` cached data" }, @@ -2531,19 +2555,19 @@ "name": "dep0111:_`process.binding()`", "meta": { "changes": [ - { - "version": "v10.9.0", - "pr-url": "https://github.com/nodejs/node/pull/22004", - "description": "Documentation-only deprecation." - }, { "version": "v11.12.0", "pr-url": "https://github.com/nodejs/node/pull/26500", "description": "Added support for `--pending-deprecation`." + }, + { + "version": "v10.9.0", + "pr-url": "https://github.com/nodejs/node/pull/22004", + "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      process.binding() is for use by Node.js internal code only.

      \n

      ", + "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      process.binding() is for use by Node.js internal code only.

      ", "type": "module", "displayName": "DEP0111: `process.binding()`" }, @@ -2559,7 +2583,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The dgram module previously contained several APIs that were never meant to\naccessed outside of Node.js core: Socket.prototype._handle,\nSocket.prototype._receiving, Socket.prototype._bindState,\nSocket.prototype._queue, Socket.prototype._reuseAddr,\nSocket.prototype._healthCheck(), Socket.prototype._stopReceiving(), and\ndgram._createSocketHandle().

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The dgram module previously contained several APIs that were never meant to\naccessed outside of Node.js core: Socket.prototype._handle,\nSocket.prototype._receiving, Socket.prototype._bindState,\nSocket.prototype._queue, Socket.prototype._reuseAddr,\nSocket.prototype._healthCheck(), Socket.prototype._stopReceiving(), and\ndgram._createSocketHandle().

      ", "type": "module", "displayName": "DEP0112: `dgram` private APIs" }, @@ -2580,7 +2604,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      Cipher.setAuthTag() and Decipher.getAuthTag() are no longer available. They\nwere never documented and would throw when called.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Cipher.setAuthTag() and Decipher.getAuthTag() are no longer available. They\nwere never documented and would throw when called.

      ", "type": "module", "displayName": "DEP0113: `Cipher.setAuthTag()`, `Decipher.getAuthTag()`" }, @@ -2601,7 +2625,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      The crypto._toBuf() function was not designed to be used by modules outside\nof Node.js core and was removed.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The crypto._toBuf() function was not designed to be used by modules outside\nof Node.js core and was removed.

      ", "type": "module", "displayName": "DEP0114: `crypto._toBuf()`" }, @@ -2620,7 +2644,7 @@ } ] }, - "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      In recent versions of Node.js, there is no difference between\ncrypto.randomBytes() and crypto.pseudoRandomBytes(). The latter is\ndeprecated along with the undocumented aliases crypto.prng() and\ncrypto.rng() in favor of crypto.randomBytes() and may be removed in a\nfuture release.

      \n

      ", + "desc": "\n\n

      Type: Documentation-only (supports --pending-deprecation)

      \n

      In recent versions of Node.js, there is no difference between\ncrypto.randomBytes() and crypto.pseudoRandomBytes(). The latter is\ndeprecated along with the undocumented aliases crypto.prng() and\ncrypto.rng() in favor of crypto.randomBytes() and might be removed in a\nfuture release.

      ", "type": "module", "displayName": "DEP0115: `crypto.prng()`, `crypto.pseudoRandomBytes()`, `crypto.rng()`" }, @@ -2629,6 +2653,11 @@ "name": "dep0116:_legacy_url_api", "meta": { "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/37784", + "description": "Deprecation revoked. Status changed to \"Legacy\"." + }, { "version": "v11.0.0", "pr-url": "https://github.com/nodejs/node/pull/22715", @@ -2636,7 +2665,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The Legacy URL API is deprecated. This includes url.format(),\nurl.parse(), url.resolve(), and the legacy urlObject. Please\nuse the WHATWG URL API instead.

      \n

      ", + "desc": "

      Type: Deprecation revoked

      \n

      The Legacy URL API is deprecated. This includes url.format(),\nurl.parse(), url.resolve(), and the legacy urlObject. Please\nuse the WHATWG URL API instead.

      ", "type": "module", "displayName": "DEP0116: Legacy URL API" }, @@ -2657,7 +2686,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      Previous versions of Node.js exposed handles to internal native objects through\nthe _handle property of the Cipher, Decipher, DiffieHellman,\nDiffieHellmanGroup, ECDH, Hash, Hmac, Sign, and Verify classes.\nThe _handle property has been removed because improper use of the native\nobject can lead to crashing the application.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Previous versions of Node.js exposed handles to internal native objects through\nthe _handle property of the Cipher, Decipher, DiffieHellman,\nDiffieHellmanGroup, ECDH, Hash, Hmac, Sign, and Verify classes.\nThe _handle property has been removed because improper use of the native\nobject can lead to crashing the application.

      ", "type": "module", "displayName": "DEP0117: Native crypto handles" }, @@ -2673,7 +2702,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Previous versions of Node.js supported dns.lookup() with a falsy host name\nlike dns.lookup(false) due to backward compatibility.\nThis behavior is undocumented and is thought to be unused in real world apps.\nIt will become an error in future versions of Node.js.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Previous versions of Node.js supported dns.lookup() with a falsy host name\nlike dns.lookup(false) due to backward compatibility.\nThis behavior is undocumented and is thought to be unused in real world apps.\nIt will become an error in future versions of Node.js.

      ", "type": "module", "displayName": "DEP0118: `dns.lookup()` support for a falsy host name" }, @@ -2689,7 +2718,7 @@ } ] }, - "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      process.binding('uv').errname() is deprecated. Please use\nutil.getSystemErrorName() instead.

      \n

      ", + "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      process.binding('uv').errname() is deprecated. Please use\nutil.getSystemErrorName() instead.

      ", "type": "module", "displayName": "DEP0119: `process.binding('uv').errname()` private API" }, @@ -2710,7 +2739,7 @@ } ] }, - "desc": "

      Type: End-of-Life

      \n

      Windows Performance Counter support has been removed from Node.js. The\nundocumented COUNTER_NET_SERVER_CONNECTION(),\nCOUNTER_NET_SERVER_CONNECTION_CLOSE(), COUNTER_HTTP_SERVER_REQUEST(),\nCOUNTER_HTTP_SERVER_RESPONSE(), COUNTER_HTTP_CLIENT_REQUEST(), and\nCOUNTER_HTTP_CLIENT_RESPONSE() functions have been deprecated.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      Windows Performance Counter support has been removed from Node.js. The\nundocumented COUNTER_NET_SERVER_CONNECTION(),\nCOUNTER_NET_SERVER_CONNECTION_CLOSE(), COUNTER_HTTP_SERVER_REQUEST(),\nCOUNTER_HTTP_SERVER_RESPONSE(), COUNTER_HTTP_CLIENT_REQUEST(), and\nCOUNTER_HTTP_CLIENT_RESPONSE() functions have been deprecated.

      ", "type": "module", "displayName": "DEP0120: Windows Performance Counter support" }, @@ -2726,7 +2755,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The undocumented net._setSimultaneousAccepts() function was originally\nintended for debugging and performance tuning when using the child_process\nand cluster modules on Windows. The function is not generally useful and\nis being removed. See discussion here:\nhttps://github.com/nodejs/node/issues/18391

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The undocumented net._setSimultaneousAccepts() function was originally\nintended for debugging and performance tuning when using the child_process\nand cluster modules on Windows. The function is not generally useful and\nis being removed. See discussion here:\nhttps://github.com/nodejs/node/issues/18391

      ", "type": "module", "displayName": "DEP0121: `net._setSimultaneousAccepts()`" }, @@ -2742,7 +2771,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Please use Server.prototype.setSecureContext() instead.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Please use Server.prototype.setSecureContext() instead.

      ", "type": "module", "displayName": "DEP0122: `tls` `Server.prototype.setOptions()`" }, @@ -2758,7 +2787,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Setting the TLS ServerName to an IP address is not permitted by\nRFC 6066. This will be ignored in a future version.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Setting the TLS ServerName to an IP address is not permitted by\nRFC 6066. This will be ignored in a future version.

      ", "type": "module", "displayName": "DEP0123: setting the TLS ServerName to an IP address" }, @@ -2774,7 +2803,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      This property is a reference to the instance itself.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      This property is a reference to the instance itself.

      ", "type": "module", "displayName": "DEP0124: using `REPLServer.rli`" }, @@ -2790,7 +2819,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The _stream_wrap module is deprecated.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The _stream_wrap module is deprecated.

      ", "type": "module", "displayName": "DEP0125: `require('_stream_wrap')`" }, @@ -2806,7 +2835,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The previously undocumented timers.active() is deprecated.\nPlease use the publicly documented timeout.refresh() instead.\nIf re-referencing the timeout is necessary, timeout.ref() can be used\nwith no performance impact since Node.js 10.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The previously undocumented timers.active() is deprecated.\nPlease use the publicly documented timeout.refresh() instead.\nIf re-referencing the timeout is necessary, timeout.ref() can be used\nwith no performance impact since Node.js 10.

      ", "type": "module", "displayName": "DEP0126: `timers.active()`" }, @@ -2822,7 +2851,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The previously undocumented and \"private\" timers._unrefActive() is deprecated.\nPlease use the publicly documented timeout.refresh() instead.\nIf unreferencing the timeout is necessary, timeout.unref() can be used\nwith no performance impact since Node.js 10.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The previously undocumented and \"private\" timers._unrefActive() is deprecated.\nPlease use the publicly documented timeout.refresh() instead.\nIf unreferencing the timeout is necessary, timeout.unref() can be used\nwith no performance impact since Node.js 10.

      ", "type": "module", "displayName": "DEP0127: `timers._unrefActive()`" }, @@ -2838,7 +2867,7 @@ } ] }, - "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      Modules that have an invalid main entry (e.g., ./does-not-exist.js) and\nalso have an index.js file in the top level directory will resolve the\nindex.js file. That is deprecated and is going to throw an error in future\nNode.js versions.

      \n

      ", + "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      Modules that have an invalid main entry (e.g., ./does-not-exist.js) and\nalso have an index.js file in the top level directory will resolve the\nindex.js file. That is deprecated and is going to throw an error in future\nNode.js versions.

      ", "type": "module", "displayName": "DEP0128: modules with an invalid `main` entry and an `index.js` file" }, @@ -2847,6 +2876,11 @@ "name": "dep0129:_`childprocess._channel`", "meta": { "changes": [ + { + "version": "v13.0.0", + "pr-url": "https://github.com/nodejs/node/pull/27949", + "description": "Runtime deprecation." + }, { "version": "v11.14.0", "pr-url": "https://github.com/nodejs/node/pull/26982", @@ -2854,7 +2888,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      The _channel property of child process objects returned by spawn() and\nsimilar functions is not intended for public use. Use ChildProcess.channel\ninstead.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      The _channel property of child process objects returned by spawn() and\nsimilar functions is not intended for public use. Use ChildProcess.channel\ninstead.

      ", "type": "module", "displayName": "DEP0129: `ChildProcess._channel`" }, @@ -2863,6 +2897,11 @@ "name": "dep0130:_`module.createrequirefrompath()`", "meta": { "changes": [ + { + "version": "v13.0.0", + "pr-url": "https://github.com/nodejs/node/pull/27951", + "description": "Runtime deprecation." + }, { "version": "v12.2.0", "pr-url": "https://github.com/nodejs/node/pull/27405", @@ -2870,7 +2909,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      Module.createRequireFromPath() is deprecated. Please use module.createRequire() instead.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Module.createRequireFromPath() is deprecated. Please use\nmodule.createRequire() instead.

      ", "type": "module", "displayName": "DEP0130: `Module.createRequireFromPath()`" }, @@ -2880,9 +2919,9 @@ "meta": { "changes": [ { - "version": "v12.22.0", - "pr-url": "https://github.com/nodejs/node/pull/37603", - "description": "Runtime deprecation." + "version": "v13.0.0", + "pr-url": "https://github.com/nodejs/node/pull/29589", + "description": "This feature has been removed." }, { "version": "v12.3.0", @@ -2891,7 +2930,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      The legacy HTTP parser, used by default in versions of Node.js prior to 12.0.0,\nis deprecated. This deprecation applies to users of the\n--http-parser=legacy command-line flag.

      \n

      ", + "desc": "

      Type: End-of-Life

      \n

      The legacy HTTP parser, used by default in versions of Node.js prior to 12.0.0,\nis deprecated and has been removed in v13.0.0. Prior to v13.0.0, the\n--http-parser=legacy command-line flag could be used to revert to using the\nlegacy parser.

      ", "type": "module", "displayName": "DEP0131: Legacy HTTP parser" }, @@ -2907,7 +2946,7 @@ } ] }, - "desc": "

      Type: Runtime

      \n

      Passing a callback to worker.terminate() is deprecated. Use the returned\nPromise instead, or a listener to the worker’s 'exit' event.

      \n

      ", + "desc": "

      Type: Runtime

      \n

      Passing a callback to worker.terminate() is deprecated. Use the returned\nPromise instead, or a listener to the worker’s 'exit' event.

      ", "type": "module", "displayName": "DEP0132: `worker.terminate()` with callback" }, @@ -2923,7 +2962,7 @@ } ] }, - "desc": "

      Type: Documentation-only

      \n

      Prefer response.socket over response.connection and\nrequest.socket over request.connection.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      Prefer response.socket over response.connection and\nrequest.socket over request.connection.

      ", "type": "module", "displayName": "DEP0133: `http` `connection`" }, @@ -2939,26 +2978,77 @@ } ] }, - "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      The process._tickCallback property was never documented as\nan officially supported API.

      \n

      ", + "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      The process._tickCallback property was never documented as\nan officially supported API.

      ", "type": "module", "displayName": "DEP0134: `process._tickCallback`" }, + { + "textRaw": "DEP0135: `WriteStream.open()` and `ReadStream.open()` are internal", + "name": "dep0135:_`writestream.open()`_and_`readstream.open()`_are_internal", + "meta": { + "changes": [ + { + "version": "v13.0.0", + "pr-url": "https://github.com/nodejs/node/pull/29061", + "description": "Runtime deprecation." + } + ] + }, + "desc": "

      Type: Runtime

      \n

      WriteStream.open() and ReadStream.open() are undocumented internal\nAPIs that do not make sense to use in userland. File streams should always be\nopened through their corresponding factory methods fs.createWriteStream()\nand fs.createReadStream()) or by passing a file descriptor in options.

      ", + "type": "module", + "displayName": "DEP0135: `WriteStream.open()` and `ReadStream.open()` are internal" + }, { "textRaw": "DEP0136: `http` `finished`", "name": "dep0136:_`http`_`finished`", "meta": { "changes": [ { - "version": "v12.16.0", + "version": [ + "v13.4.0", + "v12.16.0" + ], "pr-url": "https://github.com/nodejs/node/pull/28679", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      response.finished indicates whether response.end() has been\ncalled, not whether 'finish' has been emitted and the underlying data\nis flushed.

      \n

      Use response.writableFinished or response.writableEnded\naccordingly instead to avoid the ambigiuty.

      \n

      To maintain existing behaviour response.finished should be replaced with\nresponse.writableEnded.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      response.finished indicates whether response.end() has been\ncalled, not whether 'finish' has been emitted and the underlying data\nis flushed.

      \n

      Use response.writableFinished or response.writableEnded\naccordingly instead to avoid the ambiguity.

      \n

      To maintain existing behaviour response.finished should be replaced with\nresponse.writableEnded.

      ", "type": "module", "displayName": "DEP0136: `http` `finished`" }, + { + "textRaw": "DEP0137: Closing fs.FileHandle on garbage collection", + "name": "dep0137:_closing_fs.filehandle_on_garbage_collection", + "meta": { + "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/28396", + "description": "Runtime deprecation." + } + ] + }, + "desc": "

      Type: Runtime

      \n

      Allowing a fs.FileHandle object to be closed on garbage collection is\ndeprecated. In the future, doing so might result in a thrown error that will\nterminate the process.

      \n

      Please ensure that all fs.FileHandle objects are explicitly closed using\nFileHandle.prototype.close() when the fs.FileHandle is no longer needed:

      \n
      const fsPromises = require('fs').promises;\nasync function openAndClose() {\n  let filehandle;\n  try {\n    filehandle = await fsPromises.open('thefile.txt', 'r');\n  } finally {\n    if (filehandle !== undefined)\n      await filehandle.close();\n  }\n}\n
      ", + "type": "module", + "displayName": "DEP0137: Closing fs.FileHandle on garbage collection" + }, + { + "textRaw": "DEP0138: `process.mainModule`", + "name": "dep0138:_`process.mainmodule`", + "meta": { + "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/32232", + "description": "Documentation-only deprecation." + } + ] + }, + "desc": "

      Type: Documentation-only

      \n

      process.mainModule is a CommonJS-only feature while process global\nobject is shared with non-CommonJS environment. Its use within ECMAScript\nmodules is unsupported.

      \n

      It is deprecated in favor of require.main, because it serves the same\npurpose and is only available on CommonJS environment.

      ", + "type": "module", + "displayName": "DEP0138: `process.mainModule`" + }, { "textRaw": "DEP0139: `process.umask()` with no arguments", "name": "dep0139:_`process.umask()`_with_no_arguments", @@ -2966,18 +3056,85 @@ "changes": [ { "version": [ - "v12.19.0", - "v14.0.0" + "v14.0.0", + "v12.19.0" ], "pr-url": "https://github.com/nodejs/node/pull/32499", "description": "Documentation-only deprecation." } ] }, - "desc": "

      Type: Documentation-only

      \n

      Calling process.umask() with no argument causes the process-wide umask to be\nwritten twice. This introduces a race condition between threads, and is a\npotential security vulnerability. There is no safe, cross-platform alternative\nAPI.

      \n

      ", + "desc": "

      Type: Documentation-only

      \n

      Calling process.umask() with no argument causes the process-wide umask to be\nwritten twice. This introduces a race condition between threads, and is a\npotential security vulnerability. There is no safe, cross-platform alternative\nAPI.

      ", "type": "module", "displayName": "DEP0139: `process.umask()` with no arguments" }, + { + "textRaw": "DEP0140: Use `request.destroy()` instead of `request.abort()`", + "name": "dep0140:_use_`request.destroy()`_instead_of_`request.abort()`", + "meta": { + "changes": [ + { + "version": [ + "v14.1.0", + "v13.14.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/32807", + "description": "Documentation-only deprecation." + } + ] + }, + "desc": "

      Type: Documentation-only

      \n

      Use request.destroy() instead of request.abort().

      ", + "type": "module", + "displayName": "DEP0140: Use `request.destroy()` instead of `request.abort()`" + }, + { + "textRaw": "DEP0141: `repl.inputStream` and `repl.outputStream`", + "name": "dep0141:_`repl.inputstream`_and_`repl.outputstream`", + "meta": { + "changes": [ + { + "version": "v14.3.0", + "pr-url": "https://github.com/nodejs/node/pull/33294", + "description": "Documentation-only (supports [`--pending-deprecation`][])." + } + ] + }, + "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      The repl module exported the input and output stream twice. Use .input\ninstead of .inputStream and .output instead of .outputStream.

      ", + "type": "module", + "displayName": "DEP0141: `repl.inputStream` and `repl.outputStream`" + }, + { + "textRaw": "DEP0142: `repl._builtinLibs`", + "name": "dep0142:_`repl._builtinlibs`", + "meta": { + "changes": [ + { + "version": "v14.3.0", + "pr-url": "https://github.com/nodejs/node/pull/33294", + "description": "Documentation-only (supports [`--pending-deprecation`][])." + } + ] + }, + "desc": "

      Type: Documentation-only

      \n

      The repl module exports a _builtinLibs property that contains an array with\nnative modules. It was incomplete so far and instead it's better to rely upon\nrequire('module').builtinModules.

      ", + "type": "module", + "displayName": "DEP0142: `repl._builtinLibs`" + }, + { + "textRaw": "DEP0143: `Transform._transformState`", + "name": "dep0143:_`transform._transformstate`", + "meta": { + "changes": [ + { + "version": "v14.5.0", + "pr-url": "https://github.com/nodejs/node/pull/33126", + "description": "Runtime deprecation." + } + ] + }, + "desc": "

      Type: Runtime\nTransform._transformState will be removed in future versions where it is\nno longer required due to simplification of the implementation.

      ", + "type": "module", + "displayName": "DEP0143: `Transform._transformState`" + }, { "textRaw": "DEP0144: `module.parent`", "name": "dep0144:_`module.parent`", @@ -2985,8 +3142,8 @@ "changes": [ { "version": [ - "v12.19.0", - "v14.6.0" + "v14.6.0", + "v12.19.0" ], "pr-url": "https://github.com/nodejs/node/pull/32217", "description": "Documentation-only deprecation." @@ -2996,6 +3153,70 @@ "desc": "

      Type: Documentation-only

      \n

      A CommonJS module can access the first module that required it using\nmodule.parent. This feature is deprecated because it does not work\nconsistently in the presence of ECMAScript modules and because it gives an\ninaccurate representation of the CommonJS module graph.

      \n

      Some modules use it to check if they are the entry point of the current process.\nInstead, it is recommended to compare require.main and module:

      \n
      if (require.main === module) {\n  // Code section that will run only if current file is the entry point.\n}\n
      \n

      When looking for the CommonJS modules that have required the current one,\nrequire.cache and module.children can be used:

      \n
      const moduleParents = Object.values(require.cache)\n  .filter((m) => m.children.includes(module));\n
      ", "type": "module", "displayName": "DEP0144: `module.parent`" + }, + { + "textRaw": "DEP0145: `socket.bufferSize`", + "name": "dep0145:_`socket.buffersize`", + "meta": { + "changes": [ + { + "version": "v14.6.0", + "pr-url": "https://github.com/nodejs/node/pull/34088", + "description": "Documentation-only deprecation." + } + ] + }, + "desc": "

      Type: Documentation-only

      \n

      socket.bufferSize is just an alias for writable.writableLength.

      ", + "type": "module", + "displayName": "DEP0145: `socket.bufferSize`" + }, + { + "textRaw": "DEP0146: `new crypto.Certificate()`", + "name": "dep0146:_`new_crypto.certificate()`", + "meta": { + "changes": [ + { + "version": "v14.9.0", + "pr-url": "https://github.com/nodejs/node/pull/34697", + "description": "Documentation-only deprecation." + } + ] + }, + "desc": "

      Type: Documentation-only

      \n

      The crypto.Certificate() constructor is deprecated. Use\nstatic methods of crypto.Certificate() instead.

      ", + "type": "module", + "displayName": "DEP0146: `new crypto.Certificate()`" + }, + { + "textRaw": "DEP0147: `fs.rmdir(path, { recursive: true })`", + "name": "dep0147:_`fs.rmdir(path,_{_recursive:_true_})`", + "meta": { + "changes": [ + { + "version": "v14.14.0", + "pr-url": "https://github.com/nodejs/node/pull/35579", + "description": "Documentation-only deprecation." + } + ] + }, + "desc": "

      Type: Documentation-only

      \n

      In future versions of Node.js, fs.rmdir(path, { recursive: true }) will throw\non nonexistent paths, or when given a file as a target.\nUse fs.rm(path, { recursive: true, force: true }) instead.

      ", + "type": "module", + "displayName": "DEP0147: `fs.rmdir(path, { recursive: true })`" + }, + { + "textRaw": "DEP0151: Main index lookup and extension searching", + "name": "dep0151:_main_index_lookup_and_extension_searching", + "meta": { + "changes": [ + { + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/36918", + "description": "Documentation-only deprecation with `--pending-deprecation` support." + } + ] + }, + "desc": "

      Type: Documentation-only (supports --pending-deprecation)

      \n

      Previously, index.js and extension searching lookups would apply to\nimport 'pkg' main entry point resolution, even when resolving ES modules.

      \n

      With this deprecation, all ES module main entry point resolutions require\nan explicit \"exports\" or \"main\" entry with the exact file extension.

      ", + "type": "module", + "displayName": "DEP0151: Main index lookup and extension searching" } ], "type": "misc", diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 59df3c52cce6f452826c00e58598756f7073cbfe..484d565cc72d9ddbc992f669c59e9c93a756a2f9 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -3,13 +3,13 @@ -Node.js may deprecate APIs for any of the following reasons: +Node.js APIs might be deprecated for any of the following reasons: * Use of the API is unsafe. * An improved alternative API is available. * Breaking changes to the API are expected in a future major release. -Node.js utilizes three kinds of Deprecations: +Node.js uses three kinds of Deprecations: * Documentation-only * Runtime @@ -34,19 +34,21 @@ from Node.js. ## Revoking deprecations -Occasionally, the deprecation of an API may be reversed. In such situations, +Occasionally, the deprecation of an API might be reversed. In such situations, this document will be updated with information relevant to the decision. However, the deprecation identifier will not be modified. ## List of deprecated APIs - ### DEP0001: `http.OutgoingMessage.prototype.flush` -Type: Runtime +Type: End-of-Life -The `OutgoingMessage.prototype.flush()` method is deprecated. Use +`OutgoingMessage.prototype.flush()` has been removed. Use `OutgoingMessage.prototype.flushHeaders()` instead. - ### DEP0002: `require('_linklist')` -Type: Runtime +Type: End-of-Life -The `_writableState.buffer` property is deprecated. Use the -`_writableState.getBuffer()` method instead. +The `_writableState.buffer` has been removed. Use `_writableState.getBuffer()` +instead. - ### DEP0004: `CryptoStream.prototype.readyState` @@ -118,7 +120,6 @@ Type: End-of-Life The `CryptoStream.prototype.readyState` property was removed. - ### DEP0005: `Buffer()` constructor @@ -183,7 +183,6 @@ Within the [`child_process`][] module's `spawn()`, `fork()`, and `exec()` methods, the `options.customFds` option is deprecated. The `options.stdio` option should be used instead. - ### DEP0007: Replace `cluster` `worker.suicide` with `worker.exitedAfterDisconnect` -Type: Runtime +Type: End-of-Life Use of the [`crypto.pbkdf2()`][] API without specifying a digest was deprecated in Node.js 6.0 because the method defaulted to using the non-recommended @@ -256,10 +256,11 @@ Node.js 8.0.0, calling `crypto.pbkdf2()` or `crypto.pbkdf2Sync()` with `digest` set to `undefined` will throw a `TypeError`. Beginning in Node.js v11.0.0, calling these functions with `digest` set to -`null` will print a deprecation warning to align with the behavior when `digest` +`null` would print a deprecation warning to align with the behavior when `digest` is `undefined`. - +Now, however, passing either `undefined` or `null` will throw a `TypeError`. + ### DEP0010: `crypto.createCredentials` -Type: Runtime +Type: End-of-Life -The `GLOBAL` and `root` aliases for the `global` property are deprecated -and should no longer be used. +The `GLOBAL` and `root` aliases for the `global` property were deprecated +in Node.js 6.0.0 and have since been removed. - ### DEP0017: `Intl.v8BreakIterator` -Type: Runtime +Type: End-of-Life -The `os.tmpDir()` API is deprecated. Please use [`os.tmpdir()`][] instead. +The `os.tmpDir()` API was deprecated in Node.js 7.0.0 and has since been +removed. Please use [`os.tmpdir()`][] instead. - ### DEP0023: `os.getNetworkInterfaces()` @@ -747,13 +731,12 @@ Type: Documentation-only The [`fs.exists(path, callback)`][] API is deprecated. Please use [`fs.stat()`][] or [`fs.access()`][] instead. - ### DEP0035: `fs.lchmod(path, mode, callback)` @@ -949,18 +923,17 @@ Type: Documentation-only The [`util.isArray()`][] API is deprecated. Please use `Array.isArray()` instead. - ### DEP0045: `util.isBoolean()` @@ -969,18 +942,17 @@ Type: Documentation-only The [`util.isBoolean()`][] API is deprecated. - ### DEP0046: `util.isBuffer()` @@ -990,18 +962,17 @@ Type: Documentation-only The [`util.isBuffer()`][] API is deprecated. Please use [`Buffer.isBuffer()`][] instead. - ### DEP0047: `util.isDate()` @@ -1010,18 +981,17 @@ Type: Documentation-only The [`util.isDate()`][] API is deprecated. - ### DEP0048: `util.isError()` @@ -1030,18 +1000,17 @@ Type: Documentation-only The [`util.isError()`][] API is deprecated. - ### DEP0049: `util.isFunction()` @@ -1050,18 +1019,17 @@ Type: Documentation-only The [`util.isFunction()`][] API is deprecated. - ### DEP0050: `util.isNull()` @@ -1070,18 +1038,17 @@ Type: Documentation-only The [`util.isNull()`][] API is deprecated. - ### DEP0051: `util.isNullOrUndefined()` @@ -1090,18 +1057,17 @@ Type: Documentation-only The [`util.isNullOrUndefined()`][] API is deprecated. - ### DEP0052: `util.isNumber()` @@ -1110,18 +1076,17 @@ Type: Documentation-only The [`util.isNumber()`][] API is deprecated. - -### DEP0053 `util.isObject()` +### DEP0053: `util.isObject()` @@ -1130,18 +1095,17 @@ Type: Documentation-only The [`util.isObject()`][] API is deprecated. - ### DEP0054: `util.isPrimitive()` @@ -1150,18 +1114,17 @@ Type: Documentation-only The [`util.isPrimitive()`][] API is deprecated. - ### DEP0055: `util.isRegExp()` @@ -1170,18 +1133,17 @@ Type: Documentation-only The [`util.isRegExp()`][] API is deprecated. - ### DEP0056: `util.isString()` @@ -1190,18 +1152,17 @@ Type: Documentation-only The [`util.isString()`][] API is deprecated. - ### DEP0057: `util.isSymbol()` @@ -1210,18 +1171,17 @@ Type: Documentation-only The [`util.isSymbol()`][] API is deprecated. - ### DEP0058: `util.isUndefined()` @@ -1230,7 +1190,6 @@ Type: Documentation-only The [`util.isUndefined()`][] API is deprecated. - ### DEP0059: `util.log()` Type: End-of-Life @@ -1301,7 +1257,6 @@ Type: End-of-Life of V8 5.8. It is replaced by Inspector which is activated with `--inspect` instead. - ### DEP0063: `ServerResponse.prototype.writeHeader()` @@ -1758,16 +1692,15 @@ The AsyncHooks sensitive API was never documented and had various minor issues. Use the `AsyncResource` API instead. See . - ### DEP0086: Remove `runInAsyncIdScope` @@ -1777,7 +1710,6 @@ Type: End-of-Life `runInAsyncIdScope` doesn't emit the `'before'` or `'after'` event and can thus cause a lot of issues. See . - ### DEP0089: `require('assert')` @@ -1797,7 +1729,6 @@ Importing assert directly was not recommended as the exposed functions use loose equality checks. The deprecation was revoked because use of the `assert` module is not discouraged, and the deprecation caused developer confusion. - ### DEP0090: Invalid GCM authentication tag lengths @@ -1942,7 +1865,6 @@ Use [`asyncResource.runInAsyncScope()`][] API instead which provides a much safer, and more convenient, alternative. See . - ### DEP0099: Async context-unaware `node::MakeCallback` C++ APIs Type: Documentation-only (supports [`--pending-deprecation`][]) `process.binding()` is for use by Node.js internal code only. - ### DEP0112: `dgram` private APIs + + + Type: Documentation-only (supports [`--pending-deprecation`][]) In recent versions of Node.js, there is no difference between [`crypto.randomBytes()`][] and `crypto.pseudoRandomBytes()`. The latter is deprecated along with the undocumented aliases `crypto.prng()` and -`crypto.rng()` in favor of [`crypto.randomBytes()`][] and may be removed in a +`crypto.rng()` in favor of [`crypto.randomBytes()`][] and might be removed in a future release. - ### DEP0116: Legacy URL API -Type: Documentation-only +Type: Deprecation revoked The [Legacy URL API][] is deprecated. This includes [`url.format()`][], [`url.parse()`][], [`url.resolve()`][], and the [legacy `urlObject`][]. Please use the [WHATWG URL API][] instead. - ### DEP0117: Native crypto handles -Type: Documentation-only +Type: Runtime The `_channel` property of child process objects returned by `spawn()` and similar functions is not intended for public use. Use `ChildProcess.channel` instead. - ### DEP0130: `Module.createRequireFromPath()` -Type: Documentation-only +Type: Runtime -Module.createRequireFromPath() is deprecated. Please use [`module.createRequire()`][] instead. +Module.createRequireFromPath() is deprecated. Please use +[`module.createRequire()`][] instead. - ### DEP0131: Legacy HTTP parser -Type: Runtime +Type: End-of-Life The legacy HTTP parser, used by default in versions of Node.js prior to 12.0.0, -is deprecated. This deprecation applies to users of the -[`--http-parser=legacy`][] command-line flag. +is deprecated and has been removed in v13.0.0. Prior to v13.0.0, the +`--http-parser=legacy` command-line flag could be used to revert to using the +legacy parser. - ### DEP0132: `worker.terminate()` with callback + +Type: Runtime + +[`WriteStream.open()`][] and [`ReadStream.open()`][] are undocumented internal +APIs that do not make sense to use in userland. File streams should always be +opened through their corresponding factory methods [`fs.createWriteStream()`][] +and [`fs.createReadStream()`][]) or by passing a file descriptor in options. + ### DEP0136: `http` `finished` @@ -2540,18 +2459,64 @@ called, not whether `'finish'` has been emitted and the underlying data is flushed. Use [`response.writableFinished`][] or [`response.writableEnded`][] -accordingly instead to avoid the ambigiuty. +accordingly instead to avoid the ambiguity. To maintain existing behaviour `response.finished` should be replaced with `response.writableEnded`. - +### DEP0137: Closing fs.FileHandle on garbage collection + + +Type: Runtime + +Allowing a [`fs.FileHandle`][] object to be closed on garbage collection is +deprecated. In the future, doing so might result in a thrown error that will +terminate the process. + +Please ensure that all `fs.FileHandle` objects are explicitly closed using +`FileHandle.prototype.close()` when the `fs.FileHandle` is no longer needed: + +```js +const fsPromises = require('fs').promises; +async function openAndClose() { + let filehandle; + try { + filehandle = await fsPromises.open('thefile.txt', 'r'); + } finally { + if (filehandle !== undefined) + await filehandle.close(); + } +} +``` + +### DEP0138: `process.mainModule` + + +Type: Documentation-only + +[`process.mainModule`][] is a CommonJS-only feature while `process` global +object is shared with non-CommonJS environment. Its use within ECMAScript +modules is unsupported. + +It is deprecated in favor of [`require.main`][], because it serves the same +purpose and is only available on CommonJS environment. + ### DEP0139: `process.umask()` with no arguments @@ -2563,13 +2528,64 @@ written twice. This introduces a race condition between threads, and is a potential security vulnerability. There is no safe, cross-platform alternative API. - +### DEP0140: Use `request.destroy()` instead of `request.abort()` + + +Type: Documentation-only + +Use [`request.destroy()`][] instead of [`request.abort()`][]. + +### DEP0141: `repl.inputStream` and `repl.outputStream` + + +Type: Documentation-only (supports [`--pending-deprecation`][]) + +The `repl` module exported the input and output stream twice. Use `.input` +instead of `.inputStream` and `.output` instead of `.outputStream`. + +### DEP0142: `repl._builtinLibs` + + +Type: Documentation-only + +The `repl` module exports a `_builtinLibs` property that contains an array with +native modules. It was incomplete so far and instead it's better to rely upon +`require('module').builtinModules`. + +### DEP0143: `Transform._transformState` + +Type: Runtime +`Transform._transformState` will be removed in future versions where it is +no longer required due to simplification of the implementation. + ### DEP0144: `module.parent` @@ -2598,115 +2614,184 @@ const moduleParents = Object.values(require.cache) .filter((m) => m.children.includes(module)); ``` -[`--http-parser=legacy`]: cli.html#cli_http_parser_library -[`--pending-deprecation`]: cli.html#cli_pending_deprecation -[`--throw-deprecation`]: cli.html#cli_throw_deprecation -[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_static_method_buffer_allocunsafeslow_size -[`Buffer.from(array)`]: buffer.html#buffer_static_method_buffer_from_array -[`Buffer.from(buffer)`]: buffer.html#buffer_static_method_buffer_from_buffer -[`Buffer.isBuffer()`]: buffer.html#buffer_static_method_buffer_isbuffer_obj -[`Cipher`]: crypto.html#crypto_class_cipher -[`Decipher`]: crypto.html#crypto_class_decipher -[`EventEmitter.listenerCount(emitter, eventName)`]: events.html#events_eventemitter_listenercount_emitter_eventname -[`REPLServer.clearBufferedCommand()`]: repl.html#repl_replserver_clearbufferedcommand -[`Server.connections`]: net.html#net_server_connections -[`Server.getConnections()`]: net.html#net_server_getconnections_callback -[`Server.listen({fd: })`]: net.html#net_server_listen_handle_backlog_callback -[`SlowBuffer`]: buffer.html#buffer_class_slowbuffer -[`assert`]: assert.html -[`asyncResource.runInAsyncScope()`]: async_hooks.html#async_hooks_asyncresource_runinasyncscope_fn_thisarg_args -[`child_process`]: child_process.html -[`clearInterval()`]: timers.html#timers_clearinterval_timeout -[`clearTimeout()`]: timers.html#timers_cleartimeout_timeout -[`console.error()`]: console.html#console_console_error_data_args -[`console.log()`]: console.html#console_console_log_data_args -[`crypto.DEFAULT_ENCODING`]: crypto.html#crypto_crypto_default_encoding -[`crypto.createCipher()`]: crypto.html#crypto_crypto_createcipher_algorithm_password_options -[`crypto.createCipheriv()`]: crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv_options -[`crypto.createDecipher()`]: crypto.html#crypto_crypto_createdecipher_algorithm_password_options -[`crypto.createDecipheriv()`]: crypto.html#crypto_crypto_createdecipheriv_algorithm_key_iv_options -[`crypto.fips`]: crypto.html#crypto_crypto_fips -[`crypto.pbkdf2()`]: crypto.html#crypto_crypto_pbkdf2_password_salt_iterations_keylen_digest_callback -[`crypto.randomBytes()`]: crypto.html#crypto_crypto_randombytes_size_callback -[`crypto.scrypt()`]: crypto.html#crypto_crypto_scrypt_password_salt_keylen_options_callback -[`decipher.final()`]: crypto.html#crypto_decipher_final_outputencoding -[`decipher.setAuthTag()`]: crypto.html#crypto_decipher_setauthtag_buffer -[`domain`]: domain.html -[`ecdh.setPublicKey()`]: crypto.html#crypto_ecdh_setpublickey_publickey_encoding -[`emitter.listenerCount(eventName)`]: events.html#events_emitter_listenercount_eventname -[`fs.access()`]: fs.html#fs_fs_access_path_mode_callback -[`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 -[`http.get()`]: http.html#http_http_get_options_callback -[`http.request()`]: http.html#http_http_request_options_callback -[`https.get()`]: https.html#https_https_get_options_callback -[`https.request()`]: https.html#https_https_request_options_callback -[`module.createRequire()`]: module.html#module_module_createrequire_filename -[`os.networkInterfaces()`]: os.html#os_os_networkinterfaces -[`os.tmpdir()`]: os.html#os_os_tmpdir -[`process.env`]: process.html#process_process_env -[`punycode`]: punycode.html -[`require.extensions`]: modules.html#modules_require_extensions -[`request.socket`]: http.html#http_request_socket -[`request.connection`]: http.html#http_request_connection -[`response.socket`]: http.html#http_response_socket -[`response.connection`]: http.html#http_response_connection -[`response.end()`]: http.html#http_response_end_data_encoding_callback -[`response.finished`]: http.html#http_response_finished -[`response.writableFinished`]: http.html#http_response_writablefinished -[`response.writableEnded`]: http.html#http_response_writableended -[`script.createCachedData()`]: vm.html#vm_script_createcacheddata -[`setInterval()`]: timers.html#timers_setinterval_callback_delay_args -[`setTimeout()`]: timers.html#timers_settimeout_callback_delay_args -[`timeout.ref()`]: timers.html#timers_timeout_ref -[`timeout.refresh()`]: timers.html#timers_timeout_refresh -[`timeout.unref()`]: timers.html#timers_timeout_unref -[`tls.CryptoStream`]: tls.html#tls_class_tls_cryptostream -[`tls.SecureContext`]: tls.html#tls_tls_createsecurecontext_options -[`tls.SecurePair`]: tls.html#tls_class_tls_securepair -[`tls.TLSSocket`]: tls.html#tls_class_tls_tlssocket -[`tls.checkServerIdentity()`]: tls.html#tls_tls_checkserveridentity_hostname_cert -[`tls.createSecureContext()`]: tls.html#tls_tls_createsecurecontext_options -[`url.format()`]: url.html#url_url_format_urlobject -[`url.parse()`]: url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost -[`url.resolve()`]: url.html#url_url_resolve_from_to -[`util._extend()`]: util.html#util_util_extend_target_source -[`util.getSystemErrorName()`]: util.html#util_util_getsystemerrorname_err -[`util.inspect()`]: util.html#util_util_inspect_object_options -[`util.inspect.custom`]: util.html#util_util_inspect_custom -[`util.isArray()`]: util.html#util_util_isarray_object -[`util.isBoolean()`]: util.html#util_util_isboolean_object -[`util.isBuffer()`]: util.html#util_util_isbuffer_object -[`util.isDate()`]: util.html#util_util_isdate_object -[`util.isError()`]: util.html#util_util_iserror_object -[`util.isFunction()`]: util.html#util_util_isfunction_object -[`util.isNull()`]: util.html#util_util_isnull_object -[`util.isNullOrUndefined()`]: util.html#util_util_isnullorundefined_object -[`util.isNumber()`]: util.html#util_util_isnumber_object -[`util.isObject()`]: util.html#util_util_isobject_object -[`util.isPrimitive()`]: util.html#util_util_isprimitive_object -[`util.isRegExp()`]: util.html#util_util_isregexp_object -[`util.isString()`]: util.html#util_util_isstring_object -[`util.isSymbol()`]: util.html#util_util_issymbol_object -[`util.isUndefined()`]: util.html#util_util_isundefined_object -[`util.log()`]: util.html#util_util_log_string -[`util.types`]: util.html#util_util_types -[`util`]: util.html -[`worker.exitedAfterDisconnect`]: cluster.html#cluster_worker_exitedafterdisconnect -[`worker.terminate()`]: worker_threads.html#worker_threads_worker_terminate -[`zlib.bytesWritten`]: zlib.html#zlib_zlib_byteswritten -[Legacy URL API]: url.html#url_legacy_url_api +### DEP0145: `socket.bufferSize` + + +Type: Documentation-only + +[`socket.bufferSize`][] is just an alias for [`writable.writableLength`][]. + +### DEP0146: `new crypto.Certificate()` + + +Type: Documentation-only + +The [`crypto.Certificate()` constructor][] is deprecated. Use +[static methods of `crypto.Certificate()`][] instead. + +### DEP0147: `fs.rmdir(path, { recursive: true })` + + +Type: Documentation-only + +In future versions of Node.js, `fs.rmdir(path, { recursive: true })` will throw +on nonexistent paths, or when given a file as a target. +Use `fs.rm(path, { recursive: true, force: true })` instead. + +### DEP0151: Main index lookup and extension searching + + +Type: Documentation-only (supports [`--pending-deprecation`][]) + +Previously, `index.js` and extension searching lookups would apply to +`import 'pkg'` main entry point resolution, even when resolving ES modules. + +With this deprecation, all ES module main entry point resolutions require +an explicit [`"exports"` or `"main"` entry][] with the exact file extension. + +[Legacy URL API]: url.md#url_legacy_url_api [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 -[WHATWG URL API]: url.html#url_the_whatwg_url_api -[alloc]: buffer.html#buffer_static_method_buffer_alloc_size_fill_encoding -[alloc_unsafe_size]: buffer.html#buffer_static_method_buffer_allocunsafe_size -[from_arraybuffer]: buffer.html#buffer_static_method_buffer_from_arraybuffer_byteoffset_length -[from_string_encoding]: buffer.html#buffer_static_method_buffer_from_string_encoding -[legacy `urlObject`]: url.html#url_legacy_urlobject +[WHATWG URL API]: url.md#url_the_whatwg_url_api +[`"exports"` or `"main"` entry]: packages.md#packages_main_entry_point_export +[`--pending-deprecation`]: cli.md#cli_pending_deprecation +[`--throw-deprecation`]: cli.md#cli_throw_deprecation +[`Buffer.allocUnsafeSlow(size)`]: buffer.md#buffer_static_method_buffer_allocunsafeslow_size +[`Buffer.from(array)`]: buffer.md#buffer_static_method_buffer_from_array +[`Buffer.from(buffer)`]: buffer.md#buffer_static_method_buffer_from_buffer +[`Buffer.isBuffer()`]: buffer.md#buffer_static_method_buffer_isbuffer_obj +[`Cipher`]: crypto.md#crypto_class_cipher +[`Decipher`]: crypto.md#crypto_class_decipher +[`REPLServer.clearBufferedCommand()`]: repl.md#repl_replserver_clearbufferedcommand +[`ReadStream.open()`]: fs.md#fs_class_fs_readstream +[`Server.connections`]: net.md#net_server_connections +[`Server.getConnections()`]: net.md#net_server_getconnections_callback +[`Server.listen({fd: })`]: net.md#net_server_listen_handle_backlog_callback +[`SlowBuffer`]: buffer.md#buffer_class_slowbuffer +[`WriteStream.open()`]: fs.md#fs_class_fs_writestream +[`assert`]: assert.md +[`asyncResource.runInAsyncScope()`]: async_hooks.md#async_hooks_asyncresource_runinasyncscope_fn_thisarg_args +[`child_process`]: child_process.md +[`clearInterval()`]: timers.md#timers_clearinterval_timeout +[`clearTimeout()`]: timers.md#timers_cleartimeout_timeout +[`console.error()`]: console.md#console_console_error_data_args +[`console.log()`]: console.md#console_console_log_data_args +[`crypto.Certificate()` constructor]: crypto.md#crypto_legacy_api +[`crypto.DEFAULT_ENCODING`]: crypto.md#crypto_crypto_default_encoding +[`crypto.createCipher()`]: crypto.md#crypto_crypto_createcipher_algorithm_password_options +[`crypto.createCipheriv()`]: crypto.md#crypto_crypto_createcipheriv_algorithm_key_iv_options +[`crypto.createDecipher()`]: crypto.md#crypto_crypto_createdecipher_algorithm_password_options +[`crypto.createDecipheriv()`]: crypto.md#crypto_crypto_createdecipheriv_algorithm_key_iv_options +[`crypto.fips`]: crypto.md#crypto_crypto_fips +[`crypto.pbkdf2()`]: crypto.md#crypto_crypto_pbkdf2_password_salt_iterations_keylen_digest_callback +[`crypto.randomBytes()`]: crypto.md#crypto_crypto_randombytes_size_callback +[`crypto.scrypt()`]: crypto.md#crypto_crypto_scrypt_password_salt_keylen_options_callback +[`decipher.final()`]: crypto.md#crypto_decipher_final_outputencoding +[`decipher.setAuthTag()`]: crypto.md#crypto_decipher_setauthtag_buffer +[`domain`]: domain.md +[`ecdh.setPublicKey()`]: crypto.md#crypto_ecdh_setpublickey_publickey_encoding +[`emitter.listenerCount(eventName)`]: events.md#events_emitter_listenercount_eventname +[`events.listenerCount(emitter, eventName)`]: events.md#events_events_listenercount_emitter_eventname +[`fs.FileHandle`]: fs.md#fs_class_filehandle +[`fs.access()`]: fs.md#fs_fs_access_path_mode_callback +[`fs.createReadStream()`]: fs.md#fs_fs_createreadstream_path_options +[`fs.createWriteStream()`]: fs.md#fs_fs_createwritestream_path_options +[`fs.exists(path, callback)`]: fs.md#fs_fs_exists_path_callback +[`fs.lchmod(path, mode, callback)`]: fs.md#fs_fs_lchmod_path_mode_callback +[`fs.lchmodSync(path, mode)`]: fs.md#fs_fs_lchmodsync_path_mode +[`fs.lchown(path, uid, gid, callback)`]: fs.md#fs_fs_lchown_path_uid_gid_callback +[`fs.lchownSync(path, uid, gid)`]: fs.md#fs_fs_lchownsync_path_uid_gid +[`fs.read()`]: fs.md#fs_fs_read_fd_buffer_offset_length_position_callback +[`fs.readSync()`]: fs.md#fs_fs_readsync_fd_buffer_offset_length_position +[`fs.stat()`]: fs.md#fs_fs_stat_path_options_callback +[`http.get()`]: http.md#http_http_get_options_callback +[`http.request()`]: http.md#http_http_request_options_callback +[`https.get()`]: https.md#https_https_get_options_callback +[`https.request()`]: https.md#https_https_request_options_callback +[`module.createRequire()`]: module.md#module_module_createrequire_filename +[`os.networkInterfaces()`]: os.md#os_os_networkinterfaces +[`os.tmpdir()`]: os.md#os_os_tmpdir +[`process.env`]: process.md#process_process_env +[`process.mainModule`]: process.md#process_process_mainmodule +[`punycode`]: punycode.md +[`request.abort()`]: http.md#http_request_abort +[`request.connection`]: http.md#http_request_connection +[`request.destroy()`]: http.md#http_request_destroy_error +[`request.socket`]: http.md#http_request_socket +[`require.extensions`]: modules.md#modules_require_extensions +[`require.main`]: modules.md#modules_accessing_the_main_module +[`response.connection`]: http.md#http_response_connection +[`response.end()`]: http.md#http_response_end_data_encoding_callback +[`response.finished`]: http.md#http_response_finished +[`response.socket`]: http.md#http_response_socket +[`response.writableEnded`]: http.md#http_response_writableended +[`response.writableFinished`]: http.md#http_response_writablefinished +[`script.createCachedData()`]: vm.md#vm_script_createcacheddata +[`setInterval()`]: timers.md#timers_setinterval_callback_delay_args +[`setTimeout()`]: timers.md#timers_settimeout_callback_delay_args +[`socket.bufferSize`]: net.md#net_socket_buffersize +[`timeout.ref()`]: timers.md#timers_timeout_ref +[`timeout.refresh()`]: timers.md#timers_timeout_refresh +[`timeout.unref()`]: timers.md#timers_timeout_unref +[`tls.CryptoStream`]: tls.md#tls_class_tls_cryptostream +[`tls.SecureContext`]: tls.md#tls_tls_createsecurecontext_options +[`tls.SecurePair`]: tls.md#tls_class_tls_securepair +[`tls.TLSSocket`]: tls.md#tls_class_tls_tlssocket +[`tls.checkServerIdentity()`]: tls.md#tls_tls_checkserveridentity_hostname_cert +[`tls.createSecureContext()`]: tls.md#tls_tls_createsecurecontext_options +[`url.format()`]: url.md#url_url_format_urlobject +[`url.parse()`]: url.md#url_url_parse_urlstring_parsequerystring_slashesdenotehost +[`url.resolve()`]: url.md#url_url_resolve_from_to +[`util._extend()`]: util.md#util_util_extend_target_source +[`util.getSystemErrorName()`]: util.md#util_util_getsystemerrorname_err +[`util.inspect()`]: util.md#util_util_inspect_object_options +[`util.inspect.custom`]: util.md#util_util_inspect_custom +[`util.isArray()`]: util.md#util_util_isarray_object +[`util.isBoolean()`]: util.md#util_util_isboolean_object +[`util.isBuffer()`]: util.md#util_util_isbuffer_object +[`util.isDate()`]: util.md#util_util_isdate_object +[`util.isError()`]: util.md#util_util_iserror_object +[`util.isFunction()`]: util.md#util_util_isfunction_object +[`util.isNull()`]: util.md#util_util_isnull_object +[`util.isNullOrUndefined()`]: util.md#util_util_isnullorundefined_object +[`util.isNumber()`]: util.md#util_util_isnumber_object +[`util.isObject()`]: util.md#util_util_isobject_object +[`util.isPrimitive()`]: util.md#util_util_isprimitive_object +[`util.isRegExp()`]: util.md#util_util_isregexp_object +[`util.isString()`]: util.md#util_util_isstring_object +[`util.isSymbol()`]: util.md#util_util_issymbol_object +[`util.isUndefined()`]: util.md#util_util_isundefined_object +[`util.log()`]: util.md#util_util_log_string +[`util.types`]: util.md#util_util_types +[`util`]: util.md +[`worker.exitedAfterDisconnect`]: cluster.md#cluster_worker_exitedafterdisconnect +[`worker.terminate()`]: worker_threads.md#worker_threads_worker_terminate +[`writable.writableLength`]: stream.md#stream_writable_writablelength +[`zlib.bytesWritten`]: zlib.md#zlib_zlib_byteswritten +[alloc]: buffer.md#buffer_static_method_buffer_alloc_size_fill_encoding +[alloc_unsafe_size]: buffer.md#buffer_static_method_buffer_allocunsafe_size +[from_arraybuffer]: buffer.md#buffer_static_method_buffer_from_arraybuffer_byteoffset_length +[from_string_encoding]: buffer.md#buffer_static_method_buffer_from_string_encoding +[legacy `urlObject`]: url.md#url_legacy_urlobject +[static methods of `crypto.Certificate()`]: crypto.md#crypto_class_certificate diff --git a/doc/api/dgram.html b/doc/api/dgram.html index fc4d9c904aba81f69bbc68a18d1d28f16c246dba..df37359a18fc0069c471bbbe4db9a51ca8d06242 100644 --- a/doc/api/dgram.html +++ b/doc/api/dgram.html @@ -1,10 +1,10 @@ - + - - UDP/datagram sockets | Node.js v12.22.7 Documentation + + UDP/datagram sockets | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      -
      -

      Table of Contents

      -
      +
      -

      UDP/datagram sockets#

      +

      UDP/datagram sockets#

      Stability: 2 - Stable

      -

      Source Code: lib/dgram.js

      +

      Source Code: lib/dgram.js

      The dgram module provides an implementation of UDP datagram sockets.

      const dgram = require('dgram');
      -const server = dgram.createSocket('udp4');
      +const server = dgram.createSocket('udp4');
       
      -server.on('error', (err) => {
      -  console.log(`server error:\n${err.stack}`);
      -  server.close();
      +server.on('error', (err) => {
      +  console.log(`server error:\n${err.stack}`);
      +  server.close();
       });
       
      -server.on('message', (msg, rinfo) => {
      -  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
      +server.on('message', (msg, rinfo) => {
      +  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
       });
       
      -server.on('listening', () => {
      -  const address = server.address();
      -  console.log(`server listening ${address.address}:${address.port}`);
      +server.on('listening', () => {
      +  const address = server.address();
      +  console.log(`server listening ${address.address}:${address.port}`);
       });
       
      -server.bind(41234);
      +server.bind(41234);
       // Prints: server listening 0.0.0.0:41234
      -

      Class: dgram.Socket#

      +

      Class: dgram.Socket#

      @@ -218,19 +230,19 @@ server.bind(41234);

      Encapsulates the datagram functionality.

      New instances of dgram.Socket are created using dgram.createSocket(). The new keyword is not to be used to create dgram.Socket instances.

      -

      Event: 'close'#

      +

      Event: 'close'#

      The 'close' event is emitted after a socket is closed with close(). Once triggered, no new 'message' events will be emitted on this socket.

      -

      Event: 'connect'#

      +

      Event: 'connect'#

      The 'connect' event is emitted after a socket is associated to a remote address as a result of a successful connect() call.

      -

      Event: 'error'#

      +

      Event: 'error'#

      @@ -239,7 +251,7 @@ address as a result of a successful # +

      Event: 'listening'#

      @@ -248,7 +260,7 @@ can receive data. This happens either explicitly with socket.bind() implicitly the first time data is sent using socket.send(). Until the dgram.Socket is listening, the underlying system resources do not exist and calls such as socket.address() and socket.setTTL() will fail.

      -

      Event: 'message'#

      +

      Event: 'message'#

      @@ -270,7 +282,7 @@ address, the interface name is added to the address. For example, a packet received on the en0 interface might have the address field set to 'fe80::2618:1234:ab11:3b9c%en0', where '%en0' is the interface name as a zone ID suffix.

      -

      socket.addMembership(multicastAddress[, multicastInterface])#

      +

      socket.addMembership(multicastAddress[, multicastInterface])#

      @@ -290,18 +302,18 @@ port, listening on all interfaces.

      EADDRINUSE error will occur:

      const cluster = require('cluster');
       const dgram = require('dgram');
      -if (cluster.isMaster) {
      -  cluster.fork(); // Works ok.
      -  cluster.fork(); // Fails with EADDRINUSE.
      +if (cluster.isMaster) {
      +  cluster.fork(); // Works ok.
      +  cluster.fork(); // Fails with EADDRINUSE.
       } else {
      -  const s = dgram.createSocket('udp4');
      -  s.bind(1234, () => {
      -    s.addMembership('224.0.0.114');
      +  const s = dgram.createSocket('udp4');
      +  s.bind(1234, () => {
      +    s.addMembership('224.0.0.114');
         });
       }
      -

      socket.addSourceSpecificMembership(sourceAddress, groupAddress[, multicastInterface])#

      +

      socket.addSourceSpecificMembership(sourceAddress, groupAddress[, multicastInterface])#

      • sourceAddress <string>
      • @@ -316,7 +328,7 @@ membership to it. To add membership to every available interface, call socket.addSourceSpecificMembership() multiple times, once per interface.

        When called on an unbound socket, this method will implicitly bind to a random port, listening on all interfaces.

        -

        socket.address()#

        +

        socket.address()#

        @@ -327,12 +339,12 @@ port, listening on all interfaces.

        For UDP sockets, this object will contain address, family and port properties.

        This method throws EBADF if called on an unbound socket.

        -

        socket.bind([port][, address][, callback])#

        +

        socket.bind([port][, address][, callback])#

      -

      dns.lookupService(address, port, callback)#

      +

      dns.lookupService(address, port, callback)#

      @@ -430,13 +472,13 @@ The port will be coerced to a number. If it is not a legal port, a will be thrown.

      On an error, err is an Error object, where err.code is the error code.

      const dns = require('dns');
      -dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
      -  console.log(hostname, service);
      +dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
      +  console.log(hostname, service);
         // Prints: localhost ssh
       });

      If this method is invoked as its util.promisify()ed version, it returns a Promise for an Object with hostname and service properties.

      -

      dns.resolve(hostname[, rrtype], callback)#

      +

      dns.resolve(hostname[, rrtype], callback)#

      @@ -531,10 +573,16 @@ records. The type and structure of individual results varies based on rrty -
      rrtyperecords containsResult typeShorthand method
      'A'IPv4 addresses (default)<string>dns.resolve4()
      'AAAA'IPv6 addresses<string>dns.resolve6()
      'ANY'any records<Object>dns.resolveAny()
      'CNAME'canonical name records<string>dns.resolveCname()
      'MX'mail exchange records<Object>dns.resolveMx()
      'NAPTR'name authority pointer records<Object>dns.resolveNaptr()
      'NS'name server records<string>dns.resolveNs()
      'PTR'pointer records<string>dns.resolvePtr()
      'SOA'start of authority records<Object>dns.resolveSoa()
      'SRV'service records<Object>dns.resolveSrv()
      'TXT'text records<string[]>dns.resolveTxt()
      + + + + + + +
      rrtyperecords containsResult typeShorthand method
      'A'IPv4 addresses (default)<string>dns.resolve4()
      'AAAA'IPv6 addresses<string>dns.resolve6()
      'ANY'any records<Object>dns.resolveAny()
      'CAA'CA authorization records<Object>dns.resolveCaa()
      'CNAME'canonical name records<string>dns.resolveCname()
      'MX'mail exchange records<Object>dns.resolveMx()
      'NAPTR'name authority pointer records<Object>dns.resolveNaptr()
      'NS'name server records<string>dns.resolveNs()
      'PTR'pointer records<string>dns.resolvePtr()
      'SOA'start of authority records<Object>dns.resolveSoa()
      'SRV'service records<Object>dns.resolveSrv()
      'TXT'text records<string[]>dns.resolveTxt()

      On error, err is an Error object, where err.code is one of the DNS error codes.

      -

      dns.resolve4(hostname[, options], callback)#

      +

      dns.resolve4(hostname[, options], callback)#

      The dns.promises API provides an alternative set of asynchronous DNS methods that return Promise objects rather than using callbacks. The API is accessible via require('dns').promises.

      -

      Class: dnsPromises.Resolver#

      +

      Class: dnsPromises.Resolver#

      @@ -923,18 +1018,18 @@ via require('dns').promises.

      the servers used for a resolver using resolver.setServers() does not affect other resolvers:

      -
      const { Resolver } = require('dns').promises;
      -const resolver = new Resolver();
      -resolver.setServers(['4.4.4.4']);
      +
      const { Resolver } = require('dns').promises;
      +const resolver = new Resolver();
      +resolver.setServers(['4.4.4.4']);
       
       // This request will use the server at 4.4.4.4, independent of global settings.
      -resolver.resolve4('example.org').then((addresses) => {
      +resolver.resolve4('example.org').then((addresses) => {
         // ...
       });
       
       // Alternatively, the same code can be written using async-await style.
      -(async function() {
      -  const addresses = await resolver.resolve4('example.org');
      +(async function() {
      +  const addresses = await resolver.resolve4('example.org');
       })();

      The following methods from the dnsPromises API are available:

      -

      dnsPromises.getServers()#

      +

      resolver.cancel()#

      + +

      Cancel all outstanding DNS queries made by this resolver. The corresponding +promises will be rejected with an error with code ECANCELLED.

      +

      dnsPromises.getServers()#

      @@ -969,9 +1071,9 @@ section if a custom port is used.

      '4.4.4.4', '2001:4860:4860::8888', '4.4.4.4:1053', - '[2001:4860:4860::8888]:1053' + '[2001:4860:4860::8888]:1053', ]
      -

      dnsPromises.lookup(hostname[, options])#

      +

      dnsPromises.lookup(hostname[, options])#

      @@ -990,8 +1092,9 @@ an array. Otherwise, returns a single address. Default: f IPv6 addresses in the order the DNS resolver returned them. When false, IPv4 addresses are placed before IPv6 addresses. Default: currently false (addresses are reordered) but this is -expected to change in the not too distant future. -New code should use { verbatim: true }. +expected to change in the not too distant future. Default value is +configurable using dns.setDefaultResultOrder() or +--dns-result-order. New code should use { verbatim: true }. @@ -1014,24 +1117,24 @@ take some time to consult the Imple using dnsPromises.lookup().

      Example usage:

      const dns = require('dns');
      -const dnsPromises = dns.promises;
      +const dnsPromises = dns.promises;
       const options = {
         family: 6,
      -  hints: dns.ADDRCONFIG | dns.V4MAPPED,
      +  hints: dns.ADDRCONFIG | dns.V4MAPPED,
       };
       
      -dnsPromises.lookup('example.com', options).then((result) => {
      -  console.log('address: %j family: IPv%s', result.address, result.family);
      +dnsPromises.lookup('example.com', options).then((result) => {
      +  console.log('address: %j family: IPv%s', result.address, result.family);
         // address: "2606:2800:220:1:248:1893:25c8:1946" family: IPv6
       });
       
       // When options.all is true, the result will be an Array.
      -options.all = true;
      -dnsPromises.lookup('example.com', options).then((result) => {
      -  console.log('addresses: %j', result);
      +options.all = true;
      +dnsPromises.lookup('example.com', options).then((result) => {
      +  console.log('addresses: %j', result);
         // addresses: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}]
       });
      -

      dnsPromises.lookupService(address, port)#

      +

      dnsPromises.lookupService(address, port)#

      @@ -1046,12 +1149,12 @@ The port will be coerced to a number. If it is not a legal port, a will be thrown.

      On error, the Promise is rejected with an Error object, where err.code is the error code.

      -
      const dnsPromises = require('dns').promises;
      -dnsPromises.lookupService('127.0.0.1', 22).then((result) => {
      -  console.log(result.hostname, result.service);
      +
      const dnsPromises = require('dns').promises;
      +dnsPromises.lookupService('127.0.0.1', 22).then((result) => {
      +  console.log(result.hostname, result.service);
         // Prints: localhost ssh
       });
      -

      dnsPromises.resolve(hostname[, rrtype])#

      +

      dnsPromises.resolve(hostname[, rrtype])#

      @@ -1140,10 +1243,16 @@ based on rrtype:

      -
      rrtyperecords containsResult typeShorthand method
      'A'IPv4 addresses (default)<string>dnsPromises.resolve4()
      'AAAA'IPv6 addresses<string>dnsPromises.resolve6()
      'ANY'any records<Object>dnsPromises.resolveAny()
      'CNAME'canonical name records<string>dnsPromises.resolveCname()
      'MX'mail exchange records<Object>dnsPromises.resolveMx()
      'NAPTR'name authority pointer records<Object>dnsPromises.resolveNaptr()
      'NS'name server records<string>dnsPromises.resolveNs()
      'PTR'pointer records<string>dnsPromises.resolvePtr()
      'SOA'start of authority records<Object>dnsPromises.resolveSoa()
      'SRV'service records<Object>dnsPromises.resolveSrv()
      'TXT'text records<string[]>dnsPromises.resolveTxt()
      + + + + + + +
      rrtyperecords containsResult typeShorthand method
      'A'IPv4 addresses (default)<string>dnsPromises.resolve4()
      'AAAA'IPv6 addresses<string>dnsPromises.resolve6()
      'ANY'any records<Object>dnsPromises.resolveAny()
      'CAA'CA authorization records<Object>dnsPromises.resolveCaa()
      'CNAME'canonical name records<string>dnsPromises.resolveCname()
      'MX'mail exchange records<Object>dnsPromises.resolveMx()
      'NAPTR'name authority pointer records<Object>dnsPromises.resolveNaptr()
      'NS'name server records<string>dnsPromises.resolveNs()
      'PTR'pointer records<string>dnsPromises.resolvePtr()
      'SOA'start of authority records<Object>dnsPromises.resolveSoa()
      'SRV'service records<Object>dnsPromises.resolveSrv()
      'TXT'text records<string[]>dnsPromises.resolveTxt()

      On error, the Promise is rejected with an Error object, where err.code is one of the DNS error codes.

      -

      dnsPromises.resolve4(hostname[, options])#

      +

      dnsPromises.resolve4(hostname[, options])#

      @@ -1161,7 +1270,7 @@ with the TTL expressed in seconds.

      Uses the DNS protocol to resolve IPv4 addresses (A records) for the hostname. On success, the Promise is resolved with an array of IPv4 addresses (e.g. ['74.125.79.104', '74.125.79.105', '74.125.79.106']).

      -

      dnsPromises.resolve6(hostname[, options])#

      +

      dnsPromises.resolve6(hostname[, options])#

      @@ -1179,7 +1288,7 @@ strings, with the TTL expressed in seconds.

      Uses the DNS protocol to resolve IPv6 addresses (AAAA records) for the hostname. On success, the Promise is resolved with an array of IPv6 addresses.

      -

      dnsPromises.resolveAny(hostname)#

      +

      dnsPromises.resolveAny(hostname)#

      @@ -1256,7 +1365,18 @@ present on the object:

      retry: 900, expire: 1800, minttl: 60 } ]
      -

      dnsPromises.resolveCname(hostname)#

      +

      dnsPromises.resolveCaa(hostname)#

      + + +

      Uses the DNS protocol to resolve CAA records for the hostname. On success, +the Promise is resolved with an array of objects containing available +certification authority authorization records available for the hostname +(e.g. [{critical: 0, iodef: 'mailto:pki@example.com'},{critical: 128, issue: 'pki.example.com'}]).

      +

      dnsPromises.resolveCname(hostname)#

      @@ -1266,7 +1386,7 @@ present on the object:

      Uses the DNS protocol to resolve CNAME records for the hostname. On success, the Promise is resolved with an array of canonical name records available for the hostname (e.g. ['bar.example.com']).

      -

      dnsPromises.resolveMx(hostname)#

      +

      dnsPromises.resolveMx(hostname)#

      @@ -1277,7 +1397,7 @@ the hostname (e.g. ['bar.example.com']).

      hostname. On success, the Promise is resolved with an array of objects containing both a priority and exchange property (e.g. [{priority: 10, exchange: 'mx.example.com'}, ...]).

      -

      dnsPromises.resolveNaptr(hostname)#

      +

      dnsPromises.resolveNaptr(hostname)#

      @@ -1304,7 +1424,7 @@ of objects with the following properties:

      order: 30, preference: 100 }
      -

      dnsPromises.resolveNs(hostname)#

      +

      dnsPromises.resolveNs(hostname)#

      @@ -1315,7 +1435,7 @@ of objects with the following properties:

      hostname. On success, the Promise is resolved with an array of name server records available for hostname (e.g. ['ns1.example.com', 'ns2.example.com']).

      -

      dnsPromises.resolvePtr(hostname)#

      +

      dnsPromises.resolvePtr(hostname)#

      @@ -1325,7 +1445,7 @@ records available for hostname (e.g.

      Uses the DNS protocol to resolve pointer records (PTR records) for the hostname. On success, the Promise is resolved with an array of strings containing the reply records.

      -

      dnsPromises.resolveSoa(hostname)#

      +

      dnsPromises.resolveSoa(hostname)#

      @@ -1354,7 +1474,7 @@ following properties:

      expire: 604800, minttl: 3600 }
      -

      dnsPromises.resolveSrv(hostname)#

      +

      dnsPromises.resolveSrv(hostname)#

      @@ -1377,7 +1497,7 @@ the following properties:

      port: 21223, name: 'service.example.com' }
      -

      dnsPromises.resolveTxt(hostname)#

      +

      dnsPromises.resolveTxt(hostname)#

      @@ -1390,7 +1510,7 @@ of the text records available for hostname (e.g. [ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Each sub-array contains TXT chunks of one record. Depending on the use case, these could be either joined together or treated separately.

      -

      dnsPromises.reverse(ip)#

      +

      dnsPromises.reverse(ip)#

      @@ -1401,7 +1521,24 @@ treated separately.

      array of host names.

      On error, the Promise is rejected with an Error object, where err.code is one of the DNS error codes.

      -

      dnsPromises.setServers(servers)#

      +

      dnsPromises.setDefaultResultOrder(order)#

      + +
        +
      • order <string> must be 'ipv4first' or 'verbatim'.
      • +
      +

      Set the default value of verbatim in dns.lookup() and +dnsPromises.lookup(). The value could be:

      +
        +
      • ipv4first: sets default verbatim false.
      • +
      • verbatim: sets default verbatim true.
      • +
      +

      The default is ipv4first and dnsPromises.setDefaultResultOrder() have +higher priority than --dns-result-order. When using worker threads, +dnsPromises.setDefaultResultOrder() from the main thread won't affect the +default dns orders in workers.

      +

      dnsPromises.setServers(servers)#

      @@ -1411,11 +1548,11 @@ is one of the DNS error codes.

      Sets the IP address and port of servers to be used when performing DNS resolution. The servers argument is an array of RFC 5952 formatted addresses. If the port is the IANA default DNS port (53) it can be omitted.

      -
      dnsPromises.setServers([
      +
      dnsPromises.setServers([
         '4.4.4.4',
         '[2001:4860:4860::8888]',
         '4.4.4.4:1053',
      -  '[2001:4860:4860::8888]:1053'
      +  '[2001:4860:4860::8888]:1053',
       ]);

      An error will be thrown if an invalid address is provided.

      The dnsPromises.setServers() method must not be called while a DNS query is in @@ -1426,7 +1563,7 @@ That is, if attempting to resolve with the first server provided results in a NOTFOUND error, the resolve() method will not attempt to resolve with subsequent servers provided. Fallback DNS servers will only be used if the earlier ones time out or result in some other error.

      -

      Error codes#

      +

      Error codes#

      Each DNS query can return one of the following error codes:

      • dns.NODATA: DNS server returned answer with no data.
      • @@ -1454,13 +1591,13 @@ earlier ones time out or result in some other error.

      • dns.ADDRGETNETWORKPARAMS: Could not find GetNetworkParams function.
      • dns.CANCELLED: DNS query cancelled.
      -

      Implementation considerations#

      +

      Implementation considerations#

      Although dns.lookup() and the various dns.resolve*()/dns.reverse() functions have the same goal of associating a network name with a network address (or vice versa), their behavior is quite different. These differences can have subtle but significant consequences on the behavior of Node.js programs.

      -

      dns.lookup()#

      +

      dns.lookup()#

      Under the hood, dns.lookup() uses the same operating system facilities as most other programs. For instance, dns.lookup() will almost always resolve a given name the same way as the ping command. On most POSIX-like @@ -1478,7 +1615,7 @@ host names. If that is an issue, consider resolving the host name 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.

      -

      dns.resolve(), dns.resolve*() and dns.reverse()#

      +

      dns.resolve(), dns.resolve*() and dns.reverse()#

      These functions are implemented quite differently than dns.lookup(). They do not use getaddrinfo(3) and they always perform a DNS query on the network. This network communication is always done asynchronously, and does not @@ -1486,10 +1623,46 @@ use libuv's threadpool.

      As a result, these functions cannot have the same negative impact on other processing that happens on libuv's threadpool that dns.lookup() can have.

      They do not use the same set of configuration files than what dns.lookup() -uses. For instance, they do not use the configuration from /etc/hosts.

      +uses. For instance, they do not use the configuration from /etc/hosts.

      + diff --git a/doc/api/dns.json b/doc/api/dns.json index 872f2b84e2fb2b38011390fc1441271ba6907fff..916fe03b7aab8ea7cda11a6108da4d00a05efd60 100644 --- a/doc/api/dns.json +++ b/doc/api/dns.json @@ -8,7 +8,7 @@ "introduced_in": "v0.10.0", "stability": 2, "stabilityText": "Stable", - "desc": "

      Source Code: lib/dns.js

      \n

      The dns module enables name resolution. For example, use it to look up IP\naddresses of host names.

      \n

      Although named for the Domain Name System (DNS), it does not always use the\nDNS protocol for lookups. dns.lookup() uses the operating system\nfacilities to perform name resolution. It may not need to perform any network\ncommunication. To perform name resolution the way other applications on the same\nsystem do, use dns.lookup().

      \n
      const dns = require('dns');\n\ndns.lookup('example.org', (err, address, family) => {\n  console.log('address: %j family: IPv%s', address, family);\n});\n// address: \"93.184.216.34\" family: IPv4\n
      \n

      All other functions in the dns module connect to an actual DNS server to\nperform name resolution. They will always use the network to perform DNS\nqueries. These functions do not use the same set of configuration files used by\ndns.lookup() (e.g. /etc/hosts). Use these functions to always perform\nDNS queries, bypassing other name-resolution facilities.

      \n
      const dns = require('dns');\n\ndns.resolve4('archive.org', (err, addresses) => {\n  if (err) throw err;\n\n  console.log(`addresses: ${JSON.stringify(addresses)}`);\n\n  addresses.forEach((a) => {\n    dns.reverse(a, (err, hostnames) => {\n      if (err) {\n        throw err;\n      }\n      console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);\n    });\n  });\n});\n
      \n

      See the Implementation considerations section for more information.

      ", + "desc": "

      Source Code: lib/dns.js

      \n

      The dns module enables name resolution. For example, use it to look up IP\naddresses of host names.

      \n

      Although named for the Domain Name System (DNS), it does not always use the\nDNS protocol for lookups. dns.lookup() uses the operating system\nfacilities to perform name resolution. It may not need to perform any network\ncommunication. To perform name resolution the way other applications on the same\nsystem do, use dns.lookup().

      \n
      const dns = require('dns');\n\ndns.lookup('example.org', (err, address, family) => {\n  console.log('address: %j family: IPv%s', address, family);\n});\n// address: \"93.184.216.34\" family: IPv4\n
      \n

      All other functions in the dns module connect to an actual DNS server to\nperform name resolution. They will always use the network to perform DNS\nqueries. These functions do not use the same set of configuration files used by\ndns.lookup() (e.g. /etc/hosts). Use these functions to always perform\nDNS queries, bypassing other name-resolution facilities.

      \n
      const dns = require('dns');\n\ndns.resolve4('archive.org', (err, addresses) => {\n  if (err) throw err;\n\n  console.log(`addresses: ${JSON.stringify(addresses)}`);\n\n  addresses.forEach((a) => {\n    dns.reverse(a, (err, hostnames) => {\n      if (err) {\n        throw err;\n      }\n      console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);\n    });\n  });\n});\n
      \n

      See the Implementation considerations section for more information.

      ", "classes": [ { "textRaw": "Class: `dns.Resolver`", @@ -20,7 +20,7 @@ ], "changes": [] }, - "desc": "

      An independent resolver for DNS requests.

      \n

      Creating a new resolver uses the default server settings. Setting\nthe servers used for a resolver using\nresolver.setServers() does not affect\nother resolvers:

      \n
      const { Resolver } = require('dns');\nconst resolver = new Resolver();\nresolver.setServers(['4.4.4.4']);\n\n// This request will use the server at 4.4.4.4, independent of global settings.\nresolver.resolve4('example.org', (err, addresses) => {\n  // ...\n});\n
      \n

      The following methods from the dns module are available:

      \n", + "desc": "

      An independent resolver for DNS requests.

      \n

      Creating a new resolver uses the default server settings. Setting\nthe servers used for a resolver using\nresolver.setServers() does not affect\nother resolvers:

      \n
      const { Resolver } = require('dns');\nconst resolver = new Resolver();\nresolver.setServers(['4.4.4.4']);\n\n// This request will use the server at 4.4.4.4, independent of global settings.\nresolver.resolve4('example.org', (err, addresses) => {\n  // ...\n});\n
      \n

      The following methods from the dns module are available:

      \n", "methods": [ { "textRaw": "`Resolver([options])`", @@ -32,7 +32,12 @@ ], "changes": [ { - "version": "v12.18.3", + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/39610", + "description": "The `options` object now accepts a `tries` option." + }, + { + "version": "v14.5.0", "pr-url": "https://github.com/nodejs/node/pull/33472", "description": "The constructor now accepts an `options` object. The single supported option is `timeout`." } @@ -43,7 +48,7 @@ "params": [] } ], - "desc": "

      Create a new resolver.

      \n
        \n
      • options <Object>\n
          \n
        • timeout <integer> Query timeout in milliseconds, or -1 to use the\ndefault timeout.
        • \n
        \n
      • \n
      " + "desc": "

      Create a new resolver.

      \n
        \n
      • options <Object>\n
          \n
        • timeout <integer> Query timeout in milliseconds, or -1 to use the\ndefault timeout.
        • \n
        • tries <integer> The number of tries the resolver will try contacting\neach name server before giving up. Default: 4
        • \n
        \n
      • \n
      " }, { "textRaw": "`resolver.cancel()`", @@ -61,6 +66,38 @@ } ], "desc": "

      Cancel all outstanding DNS queries made by this resolver. The corresponding\ncallbacks will be called with an error with code ECANCELLED.

      " + }, + { + "textRaw": "`resolver.setLocalAddress([ipv4][, ipv6])`", + "type": "method", + "name": "setLocalAddress", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`ipv4` {string} A string representation of an IPv4 address. **Default:** `'0.0.0.0'`", + "name": "ipv4", + "type": "string", + "default": "`'0.0.0.0'`", + "desc": "A string representation of an IPv4 address." + }, + { + "textRaw": "`ipv6` {string} A string representation of an IPv6 address. **Default:** `'::0'`", + "name": "ipv6", + "type": "string", + "default": "`'::0'`", + "desc": "A string representation of an IPv6 address." + } + ] + } + ], + "desc": "

      The resolver instance will send its requests from the specified IP address.\nThis allows programs to specify outbound interfaces when used on multi-homed\nsystems.

      \n

      If a v4 or v6 address is not specified, it is set to the default, and the\noperating system will choose a local address automatically.

      \n

      The resolver will use the v4 local address when making requests to IPv4 DNS\nservers, and the v6 local address when making requests to IPv6 DNS servers.\nThe rrtype of resolution requests has no impact on the local address used.

      " } ] } @@ -86,7 +123,7 @@ "params": [] } ], - "desc": "

      Returns an array of IP address strings, formatted according to RFC 5952,\nthat are currently configured for DNS resolution. A string will include a port\nsection if a custom port is used.

      \n\n
      [\n  '4.4.4.4',\n  '2001:4860:4860::8888',\n  '4.4.4.4:1053',\n  '[2001:4860:4860::8888]:1053'\n]\n
      " + "desc": "

      Returns an array of IP address strings, formatted according to RFC 5952,\nthat are currently configured for DNS resolution. A string will include a port\nsection if a custom port is used.

      \n\n
      [\n  '4.4.4.4',\n  '2001:4860:4860::8888',\n  '4.4.4.4:1053',\n  '[2001:4860:4860::8888]:1053',\n]\n
      " }, { "textRaw": "`dns.lookup(hostname[, options], callback)`", @@ -143,10 +180,10 @@ "desc": "When `true`, the callback returns all resolved addresses in an array. Otherwise, returns a single address." }, { - "textRaw": "`verbatim` {boolean} When `true`, the callback receives IPv4 and IPv6 addresses in the order the DNS resolver returned them. When `false`, IPv4 addresses are placed before IPv6 addresses. **Default:** currently `false` (addresses are reordered) but this is expected to change in the not too distant future. New code should use `{ verbatim: true }`.", + "textRaw": "`verbatim` {boolean} When `true`, the callback receives IPv4 and IPv6 addresses in the order the DNS resolver returned them. When `false`, IPv4 addresses are placed before IPv6 addresses. **Default:** currently `false` (addresses are reordered) but this is expected to change in the not too distant future. Default value is configurable using [`dns.setDefaultResultOrder()`][] or [`--dns-result-order`][]. New code should use `{ verbatim: true }`.", "name": "verbatim", "type": "boolean", - "default": "currently `false` (addresses are reordered) but this is expected to change in the not too distant future. New code should use `{ verbatim: true }`", + "default": "currently `false` (addresses are reordered) but this is expected to change in the not too distant future. Default value is configurable using [`dns.setDefaultResultOrder()`][] or [`--dns-result-order`][]. New code should use `{ verbatim: true }`", "desc": "When `true`, the callback receives IPv4 and IPv6 addresses in the order the DNS resolver returned them. When `false`, IPv4 addresses are placed before IPv6 addresses." } ] @@ -186,7 +223,7 @@ "meta": { "changes": [ { - "version": "v12.17.0", + "version": "v14.0.0", "pr-url": "https://github.com/nodejs/node/pull/32183", "description": "Added support for the `dns.ALL` flag." } @@ -296,7 +333,7 @@ ] } ], - "desc": "

      Uses the DNS protocol to resolve a host name (e.g. 'nodejs.org') into an array\nof the resource records. The callback function has arguments\n(err, records). When successful, records will be an array of resource\nrecords. The type and structure of individual results varies based on rrtype:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      rrtyperecords containsResult typeShorthand method
      'A'IPv4 addresses (default)<string>dns.resolve4()
      'AAAA'IPv6 addresses<string>dns.resolve6()
      'ANY'any records<Object>dns.resolveAny()
      'CNAME'canonical name records<string>dns.resolveCname()
      'MX'mail exchange records<Object>dns.resolveMx()
      'NAPTR'name authority pointer records<Object>dns.resolveNaptr()
      'NS'name server records<string>dns.resolveNs()
      'PTR'pointer records<string>dns.resolvePtr()
      'SOA'start of authority records<Object>dns.resolveSoa()
      'SRV'service records<Object>dns.resolveSrv()
      'TXT'text records<string[]>dns.resolveTxt()
      \n

      On error, err is an Error object, where err.code is one of the\nDNS error codes.

      " + "desc": "

      Uses the DNS protocol to resolve a host name (e.g. 'nodejs.org') into an array\nof the resource records. The callback function has arguments\n(err, records). When successful, records will be an array of resource\nrecords. The type and structure of individual results varies based on rrtype:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      rrtyperecords containsResult typeShorthand method
      'A'IPv4 addresses (default)<string>dns.resolve4()
      'AAAA'IPv6 addresses<string>dns.resolve6()
      'ANY'any records<Object>dns.resolveAny()
      'CAA'CA authorization records<Object>dns.resolveCaa()
      'CNAME'canonical name records<string>dns.resolveCname()
      'MX'mail exchange records<Object>dns.resolveMx()
      'NAPTR'name authority pointer records<Object>dns.resolveNaptr()
      'NS'name server records<string>dns.resolveNs()
      'PTR'pointer records<string>dns.resolvePtr()
      'SOA'start of authority records<Object>dns.resolveSoa()
      'SRV'service records<Object>dns.resolveSrv()
      'TXT'text records<string[]>dns.resolveTxt()
      \n

      On error, err is an Error object, where err.code is one of the\nDNS error codes.

      " }, { "textRaw": "`dns.resolve4(hostname[, options], callback)`", @@ -492,6 +529,46 @@ ], "desc": "

      Uses the DNS protocol to resolve CNAME records for the hostname. The\naddresses argument passed to the callback function\nwill contain an array of canonical name records available for the hostname\n(e.g. ['bar.example.com']).

      " }, + { + "textRaw": "`dns.resolveCaa(hostname, callback)`", + "type": "method", + "name": "resolveCaa", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`hostname` {string}", + "name": "hostname", + "type": "string" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`records` {Object[]}", + "name": "records", + "type": "Object[]" + } + ] + } + ] + } + ], + "desc": "

      Uses the DNS protocol to resolve CAA records for the hostname. The\naddresses argument passed to the callback function\nwill contain an array of certification authority authorization records\navailable for the hostname (e.g. [{critical: 0, iodef: 'mailto:pki@example.com'}, {critical: 128, issue: 'pki.example.com'}]).

      " + }, { "textRaw": "`dns.resolveMx(hostname, callback)`", "type": "method", @@ -744,33 +821,10 @@ }, "signatures": [ { - "params": [ - { - "textRaw": "`hostname` {string}", - "name": "hostname", - "type": "string" - }, - { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ - { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" - }, - { - "textRaw": "`records` <string[][]>", - "name": "records", - "desc": "<string[][]>" - } - ] - } - ] + "params": [] } ], - "desc": "

      Uses the DNS protocol to resolve text queries (TXT records) for the\nhostname. The records argument passed to the callback function is a\ntwo-dimensional array of the text records available for hostname (e.g.\n[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Each sub-array contains TXT chunks of\none record. Depending on the use case, these could be either joined together or\ntreated separately.

      " + "desc": "\n\n\n

      Uses the DNS protocol to resolve text queries (TXT records) for the\nhostname. The records argument passed to the callback function is a\ntwo-dimensional array of the text records available for hostname (e.g.\n[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Each sub-array contains TXT chunks of\none record. Depending on the use case, these could be either joined together or\ntreated separately.

      " }, { "textRaw": "`dns.reverse(ip, callback)`", @@ -812,6 +866,30 @@ ], "desc": "

      Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an\narray of host names.

      \n

      On error, err is an Error object, where err.code is\none of the DNS error codes.

      " }, + { + "textRaw": "`dns.setDefaultResultOrder(order)`", + "type": "method", + "name": "setDefaultResultOrder", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`order` {string} must be `'ipv4first'` or `'verbatim'`.", + "name": "order", + "type": "string", + "desc": "must be `'ipv4first'` or `'verbatim'`." + } + ] + } + ], + "desc": "

      Set the default value of verbatim in dns.lookup() and\ndnsPromises.lookup(). The value could be:

      \n
        \n
      • ipv4first: sets default verbatim false.
      • \n
      • verbatim: sets default verbatim true.
      • \n
      \n

      The default is ipv4first and dns.setDefaultResultOrder() have higher\npriority than --dns-result-order. When using worker threads,\ndns.setDefaultResultOrder() from the main thread won't affect the default\ndns orders in workers.

      " + }, { "textRaw": "`dns.setServers(servers)`", "type": "method", @@ -834,13 +912,28 @@ ] } ], - "desc": "

      Sets the IP address and port of servers to be used when performing DNS\nresolution. The servers argument is an array of RFC 5952 formatted\naddresses. If the port is the IANA default DNS port (53) it can be omitted.

      \n
      dns.setServers([\n  '4.4.4.4',\n  '[2001:4860:4860::8888]',\n  '4.4.4.4:1053',\n  '[2001:4860:4860::8888]:1053'\n]);\n
      \n

      An error will be thrown if an invalid address is provided.

      \n

      The dns.setServers() method must not be called while a DNS query is in\nprogress.

      \n

      The dns.setServers() method affects only dns.resolve(),\ndns.resolve*() and dns.reverse() (and specifically not\ndns.lookup()).

      \n

      This method works much like\nresolve.conf.\nThat is, if attempting to resolve with the first server provided results in a\nNOTFOUND error, the resolve() method will not attempt to resolve with\nsubsequent servers provided. Fallback DNS servers will only be used if the\nearlier ones time out or result in some other error.

      " + "desc": "

      Sets the IP address and port of servers to be used when performing DNS\nresolution. The servers argument is an array of RFC 5952 formatted\naddresses. If the port is the IANA default DNS port (53) it can be omitted.

      \n
      dns.setServers([\n  '4.4.4.4',\n  '[2001:4860:4860::8888]',\n  '4.4.4.4:1053',\n  '[2001:4860:4860::8888]:1053',\n]);\n
      \n

      An error will be thrown if an invalid address is provided.

      \n

      The dns.setServers() method must not be called while a DNS query is in\nprogress.

      \n

      The dns.setServers() method affects only dns.resolve(),\ndns.resolve*() and dns.reverse() (and specifically not\ndns.lookup()).

      \n

      This method works much like\nresolve.conf.\nThat is, if attempting to resolve with the first server provided results in a\nNOTFOUND error, the resolve() method will not attempt to resolve with\nsubsequent servers provided. Fallback DNS servers will only be used if the\nearlier ones time out or result in some other error.

      " } ], "modules": [ { "textRaw": "DNS promises API", "name": "dns_promises_api", + "meta": { + "added": [ + "v10.6.0" + ], + "changes": [ + { + "version": [ + "v11.14.0", + "v10.17.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/26592", + "description": "This API is no longer experimental." + } + ] + }, "desc": "

      The dns.promises API provides an alternative set of asynchronous DNS methods\nthat return Promise objects rather than using callbacks. The API is accessible\nvia require('dns').promises.

      ", "classes": [ { @@ -853,10 +946,27 @@ ], "changes": [] }, - "desc": "

      An independent resolver for DNS requests.

      \n

      Creating a new resolver uses the default server settings. Setting\nthe servers used for a resolver using\nresolver.setServers() does not affect\nother resolvers:

      \n
      const { Resolver } = require('dns').promises;\nconst resolver = new Resolver();\nresolver.setServers(['4.4.4.4']);\n\n// This request will use the server at 4.4.4.4, independent of global settings.\nresolver.resolve4('example.org').then((addresses) => {\n  // ...\n});\n\n// Alternatively, the same code can be written using async-await style.\n(async function() {\n  const addresses = await resolver.resolve4('example.org');\n})();\n
      \n

      The following methods from the dnsPromises API are available:

      \n" + "desc": "

      An independent resolver for DNS requests.

      \n

      Creating a new resolver uses the default server settings. Setting\nthe servers used for a resolver using\nresolver.setServers() does not affect\nother resolvers:

      \n
      const { Resolver } = require('dns').promises;\nconst resolver = new Resolver();\nresolver.setServers(['4.4.4.4']);\n\n// This request will use the server at 4.4.4.4, independent of global settings.\nresolver.resolve4('example.org').then((addresses) => {\n  // ...\n});\n\n// Alternatively, the same code can be written using async-await style.\n(async function() {\n  const addresses = await resolver.resolve4('example.org');\n})();\n
      \n

      The following methods from the dnsPromises API are available:

      \n" } ], "methods": [ + { + "textRaw": "`resolver.cancel()`", + "type": "method", + "name": "cancel", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      Cancel all outstanding DNS queries made by this resolver. The corresponding\npromises will be rejected with an error with code ECANCELLED.

      " + }, { "textRaw": "`dnsPromises.getServers()`", "type": "method", @@ -877,7 +987,7 @@ "params": [] } ], - "desc": "

      Returns an array of IP address strings, formatted according to RFC 5952,\nthat are currently configured for DNS resolution. A string will include a port\nsection if a custom port is used.

      \n\n
      [\n  '4.4.4.4',\n  '2001:4860:4860::8888',\n  '4.4.4.4:1053',\n  '[2001:4860:4860::8888]:1053'\n]\n
      " + "desc": "

      Returns an array of IP address strings, formatted according to RFC 5952,\nthat are currently configured for DNS resolution. A string will include a port\nsection if a custom port is used.

      \n\n
      [\n  '4.4.4.4',\n  '2001:4860:4860::8888',\n  '4.4.4.4:1053',\n  '[2001:4860:4860::8888]:1053',\n]\n
      " }, { "textRaw": "`dnsPromises.lookup(hostname[, options])`", @@ -923,10 +1033,10 @@ "desc": "When `true`, the `Promise` is resolved with all addresses in an array. Otherwise, returns a single address." }, { - "textRaw": "`verbatim` {boolean} When `true`, the `Promise` is resolved with IPv4 and IPv6 addresses in the order the DNS resolver returned them. When `false`, IPv4 addresses are placed before IPv6 addresses. **Default:** currently `false` (addresses are reordered) but this is expected to change in the not too distant future. New code should use `{ verbatim: true }`.", + "textRaw": "`verbatim` {boolean} When `true`, the `Promise` is resolved with IPv4 and IPv6 addresses in the order the DNS resolver returned them. When `false`, IPv4 addresses are placed before IPv6 addresses. **Default:** currently `false` (addresses are reordered) but this is expected to change in the not too distant future. Default value is configurable using [`dns.setDefaultResultOrder()`][] or [`--dns-result-order`][]. New code should use `{ verbatim: true }`.", "name": "verbatim", "type": "boolean", - "default": "currently `false` (addresses are reordered) but this is expected to change in the not too distant future. New code should use `{ verbatim: true }`", + "default": "currently `false` (addresses are reordered) but this is expected to change in the not too distant future. Default value is configurable using [`dns.setDefaultResultOrder()`][] or [`--dns-result-order`][]. New code should use `{ verbatim: true }`", "desc": "When `true`, the `Promise` is resolved with IPv4 and IPv6 addresses in the order the DNS resolver returned them. When `false`, IPv4 addresses are placed before IPv6 addresses." } ] @@ -993,7 +1103,7 @@ ] } ], - "desc": "

      Uses the DNS protocol to resolve a host name (e.g. 'nodejs.org') into an array\nof the resource records. When successful, the Promise is resolved with an\narray of resource records. The type and structure of individual results vary\nbased on rrtype:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      rrtyperecords containsResult typeShorthand method
      'A'IPv4 addresses (default)<string>dnsPromises.resolve4()
      'AAAA'IPv6 addresses<string>dnsPromises.resolve6()
      'ANY'any records<Object>dnsPromises.resolveAny()
      'CNAME'canonical name records<string>dnsPromises.resolveCname()
      'MX'mail exchange records<Object>dnsPromises.resolveMx()
      'NAPTR'name authority pointer records<Object>dnsPromises.resolveNaptr()
      'NS'name server records<string>dnsPromises.resolveNs()
      'PTR'pointer records<string>dnsPromises.resolvePtr()
      'SOA'start of authority records<Object>dnsPromises.resolveSoa()
      'SRV'service records<Object>dnsPromises.resolveSrv()
      'TXT'text records<string[]>dnsPromises.resolveTxt()
      \n

      On error, the Promise is rejected with an Error object, where err.code\nis one of the DNS error codes.

      " + "desc": "

      Uses the DNS protocol to resolve a host name (e.g. 'nodejs.org') into an array\nof the resource records. When successful, the Promise is resolved with an\narray of resource records. The type and structure of individual results vary\nbased on rrtype:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      rrtyperecords containsResult typeShorthand method
      'A'IPv4 addresses (default)<string>dnsPromises.resolve4()
      'AAAA'IPv6 addresses<string>dnsPromises.resolve6()
      'ANY'any records<Object>dnsPromises.resolveAny()
      'CAA'CA authorization records<Object>dnsPromises.resolveCaa()
      'CNAME'canonical name records<string>dnsPromises.resolveCname()
      'MX'mail exchange records<Object>dnsPromises.resolveMx()
      'NAPTR'name authority pointer records<Object>dnsPromises.resolveNaptr()
      'NS'name server records<string>dnsPromises.resolveNs()
      'PTR'pointer records<string>dnsPromises.resolvePtr()
      'SOA'start of authority records<Object>dnsPromises.resolveSoa()
      'SRV'service records<Object>dnsPromises.resolveSrv()
      'TXT'text records<string[]>dnsPromises.resolveTxt()
      \n

      On error, the Promise is rejected with an Error object, where err.code\nis one of the DNS error codes.

      " }, { "textRaw": "`dnsPromises.resolve4(hostname[, options])`", @@ -1092,6 +1202,29 @@ ], "desc": "

      Uses the DNS protocol to resolve all records (also known as ANY or * query).\nOn success, the Promise is resolved with an array containing various types of\nrecords. Each object has a property type that indicates the type of the\ncurrent record. And depending on the type, additional properties will be\npresent on the object:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      TypeProperties
      'A'address/ttl
      'AAAA'address/ttl
      'CNAME'value
      'MX'Refer to dnsPromises.resolveMx()
      'NAPTR'Refer to dnsPromises.resolveNaptr()
      'NS'value
      'PTR'value
      'SOA'Refer to dnsPromises.resolveSoa()
      'SRV'Refer to dnsPromises.resolveSrv()
      'TXT'This type of record contains an array property called entries which refers to dnsPromises.resolveTxt(), e.g. { entries: ['...'], type: 'TXT' }
      \n

      Here is an example of the result object:

      \n\n
      [ { type: 'A', address: '127.0.0.1', ttl: 299 },\n  { type: 'CNAME', value: 'example.com' },\n  { type: 'MX', exchange: 'alt4.aspmx.l.example.com', priority: 50 },\n  { type: 'NS', value: 'ns1.example.com' },\n  { type: 'TXT', entries: [ 'v=spf1 include:_spf.example.com ~all' ] },\n  { type: 'SOA',\n    nsname: 'ns1.example.com',\n    hostmaster: 'admin.example.com',\n    serial: 156696742,\n    refresh: 900,\n    retry: 900,\n    expire: 1800,\n    minttl: 60 } ]\n
      " }, + { + "textRaw": "`dnsPromises.resolveCaa(hostname)`", + "type": "method", + "name": "resolveCaa", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`hostname` {string}", + "name": "hostname", + "type": "string" + } + ] + } + ], + "desc": "

      Uses the DNS protocol to resolve CAA records for the hostname. On success,\nthe Promise is resolved with an array of objects containing available\ncertification authority authorization records available for the hostname\n(e.g. [{critical: 0, iodef: 'mailto:pki@example.com'},{critical: 128, issue: 'pki.example.com'}]).

      " + }, { "textRaw": "`dnsPromises.resolveCname(hostname)`", "type": "method", @@ -1299,6 +1432,30 @@ ], "desc": "

      Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an\narray of host names.

      \n

      On error, the Promise is rejected with an Error object, where err.code\nis one of the DNS error codes.

      " }, + { + "textRaw": "`dnsPromises.setDefaultResultOrder(order)`", + "type": "method", + "name": "setDefaultResultOrder", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`order` {string} must be `'ipv4first'` or `'verbatim'`.", + "name": "order", + "type": "string", + "desc": "must be `'ipv4first'` or `'verbatim'`." + } + ] + } + ], + "desc": "

      Set the default value of verbatim in dns.lookup() and\ndnsPromises.lookup(). The value could be:

      \n
        \n
      • ipv4first: sets default verbatim false.
      • \n
      • verbatim: sets default verbatim true.
      • \n
      \n

      The default is ipv4first and dnsPromises.setDefaultResultOrder() have\nhigher priority than --dns-result-order. When using worker threads,\ndnsPromises.setDefaultResultOrder() from the main thread won't affect the\ndefault dns orders in workers.

      " + }, { "textRaw": "`dnsPromises.setServers(servers)`", "type": "method", @@ -1321,7 +1478,7 @@ ] } ], - "desc": "

      Sets the IP address and port of servers to be used when performing DNS\nresolution. The servers argument is an array of RFC 5952 formatted\naddresses. If the port is the IANA default DNS port (53) it can be omitted.

      \n
      dnsPromises.setServers([\n  '4.4.4.4',\n  '[2001:4860:4860::8888]',\n  '4.4.4.4:1053',\n  '[2001:4860:4860::8888]:1053'\n]);\n
      \n

      An error will be thrown if an invalid address is provided.

      \n

      The dnsPromises.setServers() method must not be called while a DNS query is in\nprogress.

      \n

      This method works much like\nresolve.conf.\nThat is, if attempting to resolve with the first server provided results in a\nNOTFOUND error, the resolve() method will not attempt to resolve with\nsubsequent servers provided. Fallback DNS servers will only be used if the\nearlier ones time out or result in some other error.

      " + "desc": "

      Sets the IP address and port of servers to be used when performing DNS\nresolution. The servers argument is an array of RFC 5952 formatted\naddresses. If the port is the IANA default DNS port (53) it can be omitted.

      \n
      dnsPromises.setServers([\n  '4.4.4.4',\n  '[2001:4860:4860::8888]',\n  '4.4.4.4:1053',\n  '[2001:4860:4860::8888]:1053',\n]);\n
      \n

      An error will be thrown if an invalid address is provided.

      \n

      The dnsPromises.setServers() method must not be called while a DNS query is in\nprogress.

      \n

      This method works much like\nresolve.conf.\nThat is, if attempting to resolve with the first server provided results in a\nNOTFOUND error, the resolve() method will not attempt to resolve with\nsubsequent servers provided. Fallback DNS servers will only be used if the\nearlier ones time out or result in some other error.

      " } ], "type": "module", diff --git a/doc/api/dns.md b/doc/api/dns.md index 78f421bd29d1586aa4f2ca14d393fee93fea5918..6a50fa0335d3920b3c40357e42382df870c09eb2 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -81,6 +81,7 @@ The following methods from the `dns` module are available: * [`resolver.resolve4()`][`dns.resolve4()`] * [`resolver.resolve6()`][`dns.resolve6()`] * [`resolver.resolveAny()`][`dns.resolveAny()`] +* [`resolver.resolveCaa()`][`dns.resolveCaa()`] * [`resolver.resolveCname()`][`dns.resolveCname()`] * [`resolver.resolveMx()`][`dns.resolveMx()`] * [`resolver.resolveNaptr()`][`dns.resolveNaptr()`] @@ -96,7 +97,10 @@ The following methods from the `dns` module are available: + +* `ipv4` {string} A string representation of an IPv4 address. + **Default:** `'0.0.0.0'` +* `ipv6` {string} A string representation of an IPv6 address. + **Default:** `'::0'` + +The resolver instance will send its requests from the specified IP address. +This allows programs to specify outbound interfaces when used on multi-homed +systems. + +If a v4 or v6 address is not specified, it is set to the default, and the +operating system will choose a local address automatically. + +The resolver will use the v4 local address when making requests to IPv4 DNS +servers, and the v6 local address when making requests to IPv6 DNS servers. +The `rrtype` of resolution requests has no impact on the local address used. + ## `dns.getServers()` @@ -226,13 +254,13 @@ changes: The following flags can be passed as hints to [`dns.lookup()`][]. * `dns.ADDRCONFIG`: Limits returned address types to the types of non-loopback -addresses configured on the system. For example, IPv4 addresses are only -returned if the current system has at least one IPv4 address configured. + addresses configured on the system. For example, IPv4 addresses are only + returned if the current system has at least one IPv4 address configured. * `dns.V4MAPPED`: If the IPv6 family was specified, but no IPv6 addresses were -found, then return IPv4 mapped IPv6 addresses. It is not supported -on some operating systems (e.g FreeBSD 10.1). + found, then return IPv4 mapped IPv6 addresses. It is not supported + on some operating systems (e.g FreeBSD 10.1). * `dns.ALL`: If `dns.V4MAPPED` is specified, return resolved IPv6 addresses as -well as IPv4 mapped IPv6 addresses. + well as IPv4 mapped IPv6 addresses. ## `dns.lookupService(address, port, callback)` + +* `hostname` {string} +* `callback` {Function} + * `err` {Error} + * `records` {Object[]} + +Uses the DNS protocol to resolve `CAA` records for the `hostname`. The +`addresses` argument passed to the `callback` function +will contain an array of certification authority authorization records +available for the `hostname` (e.g. `[{critical: 0, iodef: +'mailto:pki@example.com'}, {critical: 128, issue: 'pki.example.com'}]`). + ## `dns.resolveMx(hostname, callback)` + * `hostname` {string} * `callback` {Function} * `err` {Error} * `records` <string[][]> + Uses the DNS protocol to resolve text queries (`TXT` records) for the `hostname`. The `records` argument passed to the `callback` function is a @@ -586,6 +633,23 @@ array of host names. On error, `err` is an [`Error`][] object, where `err.code` is one of the [DNS error codes][]. +## `dns.setDefaultResultOrder(order)` + + +* `order` {string} must be `'ipv4first'` or `'verbatim'`. + +Set the default value of `verbatim` in [`dns.lookup()`][] and +[`dnsPromises.lookup()`][]. The value could be: +* `ipv4first`: sets default `verbatim` `false`. +* `verbatim`: sets default `verbatim` `true`. + +The default is `ipv4first` and [`dns.setDefaultResultOrder()`][] have higher +priority than [`--dns-result-order`][]. When using [worker threads][], +[`dns.setDefaultResultOrder()`][] from the main thread won't affect the default +dns orders in workers. + ## `dns.setServers(servers)` The `dns.promises` API provides an alternative set of asynchronous DNS methods that return `Promise` objects rather than using callbacks. The API is accessible @@ -663,6 +736,7 @@ The following methods from the `dnsPromises` API are available: * [`resolver.resolve4()`][`dnsPromises.resolve4()`] * [`resolver.resolve6()`][`dnsPromises.resolve6()`] * [`resolver.resolveAny()`][`dnsPromises.resolveAny()`] +* [`resolver.resolveCaa()`][`dnsPromises.resolveCaa()`] * [`resolver.resolveCname()`][`dnsPromises.resolveCname()`] * [`resolver.resolveMx()`][`dnsPromises.resolveMx()`] * [`resolver.resolveNaptr()`][`dnsPromises.resolveNaptr()`] @@ -674,6 +748,14 @@ The following methods from the `dnsPromises` API are available: * [`resolver.reverse()`][`dnsPromises.reverse()`] * [`resolver.setServers()`][`dnsPromises.setServers()`] +### `resolver.cancel()` + + +Cancel all outstanding DNS queries made by this resolver. The corresponding +promises will be rejected with an error with code `ECANCELLED`. + ### `dnsPromises.getServers()` + +* `hostname` {string} + +Uses the DNS protocol to resolve `CAA` records for the `hostname`. On success, +the `Promise` is resolved with an array of objects containing available +certification authority authorization records available for the `hostname` +(e.g. `[{critical: 0, iodef: 'mailto:pki@example.com'},{critical: 128, issue: +'pki.example.com'}]`). + ### `dnsPromises.resolveCname(hostname)` + +* `order` {string} must be `'ipv4first'` or `'verbatim'`. + +Set the default value of `verbatim` in [`dns.lookup()`][] and +[`dnsPromises.lookup()`][]. The value could be: +* `ipv4first`: sets default `verbatim` `false`. +* `verbatim`: sets default `verbatim` `true`. + +The default is `ipv4first` and [`dnsPromises.setDefaultResultOrder()`][] have +higher priority than [`--dns-result-order`][]. When using [worker threads][], +[`dnsPromises.setDefaultResultOrder()`][] from the main thread won't affect the +default dns orders in workers. + ### `dnsPromises.setServers(servers)` -

      Stability: 1 - Experimental. The feature is not subject to +

      Stability: 1 - Experimental. The feature is not subject to Semantic Versioning rules. Non-backward compatible changes or removal may occur in any future release. Use of the feature is not recommended in production environments.

      -

      Stability: 2 - Stable. Compatibility with the npm ecosystem is a high +

      Stability: 2 - Stable. Compatibility with the npm ecosystem is a high priority.

      + +

      Stability: 3 - Legacy. The feature is no longer recommended for use. While it +likely will not be removed, and is still covered by semantic-versioning +guarantees, use of the feature should be avoided.

      Use caution when making use of Experimental features, particularly within modules. Users may not be aware that experimental features are being used. Bugs or behavior changes may surprise users when Experimental API modifications occur. To avoid surprises, use of an Experimental feature may need a command-line flag. Experimental features may also emit a warning.

      -

      JSON output#

      +

      Stability overview#

      +
      APIStability
      assert(2) Stable
      async_hooks(1) Experimental
      buffer(2) Stable
      child_process(2) Stable
      cluster(2) Stable
      console(2) Stable
      crypto(2) Stable
      dgram(2) Stable
      diagnostics_channel(1) Experimental
      dns(2) Stable
      domain(0) Deprecated
      fs(2) Stable
      http(2) Stable
      http/2(2) Stable
      https(2) Stable
      inspector(2) Stable
      module(2) Stable
      os(2) Stable
      path(2) Stable
      performance_measurement_apis(2) Stable
      punycode(0) Deprecated
      querystring(3) Legacy
      readline(2) Stable
      repl(2) Stable
      stream(2) Stable
      string_decoder(2) Stable
      timers(2) Stable
      tls_(ssl)(2) Stable
      trace_events(1) Experimental
      tty(2) Stable
      url(2) Stable
      util(2) Stable
      vm(2) Stable
      webassembly_system_interface_(wasi)(1) Experimental
      worker_threads(2) Stable
      zlib(2) Stable
      +

      JSON output#

      Every .html document has a corresponding .json document. This is for IDEs and other utilities that consume the documentation.

      -

      System calls and man pages#

      +

      System calls and man pages#

      Node.js functions which wrap a system call will document that. The docs link to the corresponding man pages which describe how the system call works.

      Most Unix system calls have Windows analogues. Still, behavior differences may -be unavoidable.

      +be unavoidable.

      + diff --git a/doc/api/documentation.json b/doc/api/documentation.json index 522292f754a171fdb3db3e47aa68a8256a6d449f..1de9a5c94ef1458ddbd2a7f5ccf5a50553290eeb 100644 --- a/doc/api/documentation.json +++ b/doc/api/documentation.json @@ -13,7 +13,7 @@ { "textRaw": "Contributing", "name": "contributing", - "desc": "

      Report errors in this documentation in the issue tracker. See\nthe contributing guide for directions on how to submit pull requests.

      ", + "desc": "

      Report errors in this documentation in the issue tracker. See\nthe contributing guide for directions on how to submit pull requests.

      ", "type": "misc", "displayName": "Contributing" }, @@ -21,7 +21,14 @@ "textRaw": "Stability index", "name": "Stability index", "type": "misc", - "desc": "

      Throughout the documentation are indications of a section's stability. Some APIs\nare so proven and so relied upon that they are unlikely to ever change at all.\nOthers are brand new and experimental, or known to be hazardous.

      \n

      The stability indices are as follows:

      \n
      \n

      Stability: 0 - Deprecated. The feature may emit warnings. Backward\ncompatibility is not guaranteed.

      \n
      \n\n
      \n

      Stability: 1 - Experimental. The feature is not subject to\nSemantic Versioning rules. Non-backward compatible changes or removal may\noccur in any future release. Use of the feature is not recommended in\nproduction environments.

      \n
      \n\n
      \n

      Stability: 2 - Stable. Compatibility with the npm ecosystem is a high\npriority.

      \n
      \n

      Use caution when making use of Experimental features, particularly within\nmodules. Users may not be aware that experimental features are being used.\nBugs or behavior changes may surprise users when Experimental API\nmodifications occur. To avoid surprises, use of an Experimental feature may need\na command-line flag. Experimental features may also emit a warning.

      " + "desc": "

      Throughout the documentation are indications of a section's stability. Some APIs\nare so proven and so relied upon that they are unlikely to ever change at all.\nOthers are brand new and experimental, or known to be hazardous.

      \n

      The stability indices are as follows:

      \n
      \n

      Stability: 0 - Deprecated. The feature may emit warnings. Backward\ncompatibility is not guaranteed.

      \n
      \n\n
      \n

      Stability: 1 - Experimental. The feature is not subject to\nSemantic Versioning rules. Non-backward compatible changes or removal may\noccur in any future release. Use of the feature is not recommended in\nproduction environments.

      \n
      \n\n
      \n

      Stability: 2 - Stable. Compatibility with the npm ecosystem is a high\npriority.

      \n
      \n\n
      \n

      Stability: 3 - Legacy. The feature is no longer recommended for use. While it\nlikely will not be removed, and is still covered by semantic-versioning\nguarantees, use of the feature should be avoided.

      \n
      \n

      Use caution when making use of Experimental features, particularly within\nmodules. Users may not be aware that experimental features are being used.\nBugs or behavior changes may surprise users when Experimental API\nmodifications occur. To avoid surprises, use of an Experimental feature may need\na command-line flag. Experimental features may also emit a warning.

      " + }, + { + "textRaw": "Stability overview", + "name": "stability_overview", + "desc": "
      APIStability
      assert(2) Stable
      async_hooks(1) Experimental
      buffer(2) Stable
      child_process(2) Stable
      cluster(2) Stable
      console(2) Stable
      crypto(2) Stable
      dgram(2) Stable
      diagnostics_channel(1) Experimental
      dns(2) Stable
      domain(0) Deprecated
      fs(2) Stable
      http(2) Stable
      http/2(2) Stable
      https(2) Stable
      inspector(2) Stable
      module(2) Stable
      os(2) Stable
      path(2) Stable
      performance_measurement_apis(2) Stable
      punycode(0) Deprecated
      querystring(3) Legacy
      readline(2) Stable
      repl(2) Stable
      stream(2) Stable
      string_decoder(2) Stable
      timers(2) Stable
      tls_(ssl)(2) Stable
      trace_events(1) Experimental
      tty(2) Stable
      url(2) Stable
      util(2) Stable
      vm(2) Stable
      webassembly_system_interface_(wasi)(1) Experimental
      worker_threads(2) Stable
      zlib(2) Stable
      ", + "type": "misc", + "displayName": "Stability overview" }, { "textRaw": "JSON output", diff --git a/doc/api/documentation.md b/doc/api/documentation.md index 779b02d14c7bfe56ba556bc8adf8a3d0c3ca7f69..d8ba4e7d49c4b5df4637720a81b13aa725a9cc2c 100644 --- a/doc/api/documentation.md +++ b/doc/api/documentation.md @@ -37,12 +37,60 @@ The stability indices are as follows: > Stability: 2 - Stable. Compatibility with the npm ecosystem is a high > priority. + + +> Stability: 3 - Legacy. The feature is no longer recommended for use. While it +> likely will not be removed, and is still covered by semantic-versioning +> guarantees, use of the feature should be avoided. + Use caution when making use of Experimental features, particularly within modules. Users may not be aware that experimental features are being used. Bugs or behavior changes may surprise users when Experimental API modifications occur. To avoid surprises, use of an Experimental feature may need a command-line flag. Experimental features may also emit a [warning][]. +## Stability overview + +| API | Stability | +| --- | --------- | +| [assert](assert.html) | (2) Stable | +| [async_hooks](async_hooks.html) | (1) Experimental | +| [buffer](buffer.html) | (2) Stable | +| [child_process](child_process.html) | (2) Stable | +| [cluster](cluster.html) | (2) Stable | +| [console](console.html) | (2) Stable | +| [crypto](crypto.html) | (2) Stable | +| [dgram](dgram.html) | (2) Stable | +| [diagnostics_channel](diagnostics_channel.html) | (1) Experimental | +| [dns](dns.html) | (2) Stable | +| [domain](domain.html) | (0) Deprecated | +| [fs](fs.html) | (2) Stable | +| [http](http.html) | (2) Stable | +| [http/2](http2.html) | (2) Stable | +| [https](https.html) | (2) Stable | +| [inspector](inspector.html) | (2) Stable | +| [module](modules.html) | (2) Stable | +| [os](os.html) | (2) Stable | +| [path](path.html) | (2) Stable | +| [performance_measurement_apis](perf_hooks.html) | (2) Stable | +| [punycode](punycode.html) | (0) Deprecated | +| [querystring](querystring.html) | (3) Legacy | +| [readline](readline.html) | (2) Stable | +| [repl](repl.html) | (2) Stable | +| [stream](stream.html) | (2) Stable | +| [string_decoder](string_decoder.html) | (2) Stable | +| [timers](timers.html) | (2) Stable | +| [tls_(ssl)](tls.html) | (2) Stable | +| [trace_events](tracing.html) | (1) Experimental | +| [tty](tty.html) | (2) Stable | +| [url](url.html) | (2) Stable | +| [util](util.html) | (2) Stable | +| [vm](vm.html) | (2) Stable | +| [webassembly_system_interface_(wasi)](wasi.html) | (1) Experimental | +| [worker_threads](worker_threads.html) | (2) Stable | +| [zlib](zlib.html) | (2) Stable | + + ## JSON output + diff --git a/doc/api/domain.json b/doc/api/domain.json index 47e42a7d6700dc51c9e6fb55debbfeea18be20c5..6f993d70627693c2b5097f8a06297a05647ce089 100644 --- a/doc/api/domain.json +++ b/doc/api/domain.json @@ -12,6 +12,7 @@ "changes": [ { "version": "v8.8.0", + "pr-url": "https://github.com/nodejs/node/pull/15695", "description": "Any `Promise`s created in VM contexts no longer have a `.domain` property. Their handlers are still executed in the proper domain, however, and `Promise`s created in the main context still possess a `.domain` property." }, { @@ -24,13 +25,13 @@ "introduced_in": "v0.10.0", "stability": 0, "stabilityText": "Deprecated", - "desc": "

      Source Code: lib/domain.js

      \n

      This module is pending deprecation. Once a replacement API has been\nfinalized, this module will be fully deprecated. Most developers should\nnot have cause to use this module. Users who absolutely must have\nthe functionality that domains provide may rely on it for the time being\nbut should expect to have to migrate to a different solution\nin the future.

      \n

      Domains provide a way to handle multiple different IO operations as a\nsingle group. If any of the event emitters or callbacks registered to a\ndomain emit an 'error' event, or throw an error, then the domain object\nwill be notified, rather than losing the context of the error in the\nprocess.on('uncaughtException') handler, or causing the program to\nexit immediately with an error code.

      ", + "desc": "

      Source Code: lib/domain.js

      \n

      This module is pending deprecation. Once a replacement API has been\nfinalized, this module will be fully deprecated. Most developers should\nnot have cause to use this module. Users who absolutely must have\nthe functionality that domains provide may rely on it for the time being\nbut should expect to have to migrate to a different solution\nin the future.

      \n

      Domains provide a way to handle multiple different IO operations as a\nsingle group. If any of the event emitters or callbacks registered to a\ndomain emit an 'error' event, or throw an error, then the domain object\nwill be notified, rather than losing the context of the error in the\nprocess.on('uncaughtException') handler, or causing the program to\nexit immediately with an error code.

      ", "miscs": [ { "textRaw": "Warning: Don't ignore errors!", "name": "Warning: Don't ignore errors!", "type": "misc", - "desc": "

      Domain error handlers are not a substitute for closing down a\nprocess when an error occurs.

      \n

      By the very nature of how throw works in JavaScript, there is almost\nnever any way to safely \"pick up where it left off\", without leaking\nreferences, or creating some other sort of undefined brittle state.

      \n

      The safest way to respond to a thrown error is to shut down the\nprocess. Of course, in a normal web server, there may be many\nopen connections, and it is not reasonable to abruptly shut those down\nbecause an error was triggered by someone else.

      \n

      The better approach is to send an error response to the request that\ntriggered the error, while letting the others finish in their normal\ntime, and stop listening for new requests in that worker.

      \n

      In this way, domain usage goes hand-in-hand with the cluster module,\nsince the master process can fork a new worker when a worker\nencounters an error. For Node.js programs that scale to multiple\nmachines, the terminating proxy or service registry can take note of\nthe failure, and react accordingly.

      \n

      For example, this is not a good idea:

      \n
      // XXX WARNING! BAD IDEA!\n\nconst d = require('domain').create();\nd.on('error', (er) => {\n  // The error won't crash the process, but what it does is worse!\n  // Though we've prevented abrupt process restarting, we are leaking\n  // resources like crazy if this ever happens.\n  // This is no better than process.on('uncaughtException')!\n  console.log(`error, but oh well ${er.message}`);\n});\nd.run(() => {\n  require('http').createServer((req, res) => {\n    handleRequest(req, res);\n  }).listen(PORT);\n});\n
      \n

      By using the context of a domain, and the resilience of separating our\nprogram into multiple worker processes, we can react more\nappropriately, and handle errors with much greater safety.

      \n
      // Much better!\n\nconst cluster = require('cluster');\nconst PORT = +process.env.PORT || 1337;\n\nif (cluster.isMaster) {\n  // A more realistic scenario would have more than 2 workers,\n  // and perhaps not put the master and worker in the same file.\n  //\n  // It is also possible to get a bit fancier about logging, and\n  // implement whatever custom logic is needed to prevent DoS\n  // attacks and other bad behavior.\n  //\n  // See the options in the cluster documentation.\n  //\n  // The important thing is that the master does very little,\n  // increasing our resilience to unexpected errors.\n\n  cluster.fork();\n  cluster.fork();\n\n  cluster.on('disconnect', (worker) => {\n    console.error('disconnect!');\n    cluster.fork();\n  });\n\n} else {\n  // the worker\n  //\n  // This is where we put our bugs!\n\n  const domain = require('domain');\n\n  // See the cluster documentation for more details about using\n  // worker processes to serve requests. How it works, caveats, etc.\n\n  const server = require('http').createServer((req, res) => {\n    const d = domain.create();\n    d.on('error', (er) => {\n      console.error(`error ${er.stack}`);\n\n      // We're in dangerous territory!\n      // By definition, something unexpected occurred,\n      // which we probably didn't want.\n      // Anything can happen now! Be very careful!\n\n      try {\n        // Make sure we close down within 30 seconds\n        const killtimer = setTimeout(() => {\n          process.exit(1);\n        }, 30000);\n        // But don't keep the process open just for that!\n        killtimer.unref();\n\n        // Stop taking new requests.\n        server.close();\n\n        // Let the master know we're dead. This will trigger a\n        // 'disconnect' in the cluster master, and then it will fork\n        // a new worker.\n        cluster.worker.disconnect();\n\n        // Try to send an error to the request that triggered the problem\n        res.statusCode = 500;\n        res.setHeader('content-type', 'text/plain');\n        res.end('Oops, there was a problem!\\n');\n      } catch (er2) {\n        // Oh well, not much we can do at this point.\n        console.error(`Error sending 500! ${er2.stack}`);\n      }\n    });\n\n    // Because req and res were created before this domain existed,\n    // we need to explicitly add them.\n    // See the explanation of implicit vs explicit binding below.\n    d.add(req);\n    d.add(res);\n\n    // Now run the handler function in the domain.\n    d.run(() => {\n      handleRequest(req, res);\n    });\n  });\n  server.listen(PORT);\n}\n\n// This part is not important. Just an example routing thing.\n// Put fancy application logic here.\nfunction handleRequest(req, res) {\n  switch (req.url) {\n    case '/error':\n      // We do some async stuff, and then...\n      setTimeout(() => {\n        // Whoops!\n        flerb.bark();\n      }, timeout);\n      break;\n    default:\n      res.end('ok');\n  }\n}\n
      " + "desc": "

      Domain error handlers are not a substitute for closing down a\nprocess when an error occurs.

      \n

      By the very nature of how throw works in JavaScript, there is almost\nnever any way to safely \"pick up where it left off\", without leaking\nreferences, or creating some other sort of undefined brittle state.

      \n

      The safest way to respond to a thrown error is to shut down the\nprocess. Of course, in a normal web server, there may be many\nopen connections, and it is not reasonable to abruptly shut those down\nbecause an error was triggered by someone else.

      \n

      The better approach is to send an error response to the request that\ntriggered the error, while letting the others finish in their normal\ntime, and stop listening for new requests in that worker.

      \n

      In this way, domain usage goes hand-in-hand with the cluster module,\nsince the master process can fork a new worker when a worker\nencounters an error. For Node.js programs that scale to multiple\nmachines, the terminating proxy or service registry can take note of\nthe failure, and react accordingly.

      \n

      For example, this is not a good idea:

      \n
      // XXX WARNING! BAD IDEA!\n\nconst d = require('domain').create();\nd.on('error', (er) => {\n  // The error won't crash the process, but what it does is worse!\n  // Though we've prevented abrupt process restarting, we are leaking\n  // a lot of resources if this ever happens.\n  // This is no better than process.on('uncaughtException')!\n  console.log(`error, but oh well ${er.message}`);\n});\nd.run(() => {\n  require('http').createServer((req, res) => {\n    handleRequest(req, res);\n  }).listen(PORT);\n});\n
      \n

      By using the context of a domain, and the resilience of separating our\nprogram into multiple worker processes, we can react more\nappropriately, and handle errors with much greater safety.

      \n
      // Much better!\n\nconst cluster = require('cluster');\nconst PORT = +process.env.PORT || 1337;\n\nif (cluster.isMaster) {\n  // A more realistic scenario would have more than 2 workers,\n  // and perhaps not put the master and worker in the same file.\n  //\n  // It is also possible to get a bit fancier about logging, and\n  // implement whatever custom logic is needed to prevent DoS\n  // attacks and other bad behavior.\n  //\n  // See the options in the cluster documentation.\n  //\n  // The important thing is that the master does very little,\n  // increasing our resilience to unexpected errors.\n\n  cluster.fork();\n  cluster.fork();\n\n  cluster.on('disconnect', (worker) => {\n    console.error('disconnect!');\n    cluster.fork();\n  });\n\n} else {\n  // the worker\n  //\n  // This is where we put our bugs!\n\n  const domain = require('domain');\n\n  // See the cluster documentation for more details about using\n  // worker processes to serve requests. How it works, caveats, etc.\n\n  const server = require('http').createServer((req, res) => {\n    const d = domain.create();\n    d.on('error', (er) => {\n      console.error(`error ${er.stack}`);\n\n      // We're in dangerous territory!\n      // By definition, something unexpected occurred,\n      // which we probably didn't want.\n      // Anything can happen now! Be very careful!\n\n      try {\n        // Make sure we close down within 30 seconds\n        const killtimer = setTimeout(() => {\n          process.exit(1);\n        }, 30000);\n        // But don't keep the process open just for that!\n        killtimer.unref();\n\n        // Stop taking new requests.\n        server.close();\n\n        // Let the master know we're dead. This will trigger a\n        // 'disconnect' in the cluster master, and then it will fork\n        // a new worker.\n        cluster.worker.disconnect();\n\n        // Try to send an error to the request that triggered the problem\n        res.statusCode = 500;\n        res.setHeader('content-type', 'text/plain');\n        res.end('Oops, there was a problem!\\n');\n      } catch (er2) {\n        // Oh well, not much we can do at this point.\n        console.error(`Error sending 500! ${er2.stack}`);\n      }\n    });\n\n    // Because req and res were created before this domain existed,\n    // we need to explicitly add them.\n    // See the explanation of implicit vs explicit binding below.\n    d.add(req);\n    d.add(res);\n\n    // Now run the handler function in the domain.\n    d.run(() => {\n      handleRequest(req, res);\n    });\n  });\n  server.listen(PORT);\n}\n\n// This part is not important. Just an example routing thing.\n// Put fancy application logic here.\nfunction handleRequest(req, res) {\n  switch (req.url) {\n    case '/error':\n      // We do some async stuff, and then...\n      setTimeout(() => {\n        // Whoops!\n        flerb.bark();\n      }, timeout);\n      break;\n    default:\n      res.end('ok');\n  }\n}\n
      " }, { "textRaw": "Additions to `Error` objects", diff --git a/doc/api/domain.md b/doc/api/domain.md index 0b79ec5b37e861f3e80f2f1cf18919c86bc4bdd9..5ce428fc8823708c5a0e95268f2be075e92cbf73 100644 --- a/doc/api/domain.md +++ b/doc/api/domain.md @@ -3,6 +3,7 @@ deprecated: v1.4.2 changes: - version: v8.8.0 + pr-url: https://github.com/nodejs/node/pull/15695 description: Any `Promise`s created in VM contexts no longer have a `.domain` property. Their handlers are still executed in the proper domain, however, and `Promise`s created in the main @@ -68,7 +69,7 @@ const d = require('domain').create(); d.on('error', (er) => { // The error won't crash the process, but what it does is worse! // Though we've prevented abrupt process restarting, we are leaking - // resources like crazy if this ever happens. + // a lot of resources if this ever happens. // This is no better than process.on('uncaughtException')! console.log(`error, but oh well ${er.message}`); }); @@ -478,10 +479,10 @@ Domains will not interfere with the error handling mechanisms for promises. In other words, no `'error'` event will be emitted for unhandled `Promise` rejections. -[`Error`]: errors.html#errors_class_error +[`Error`]: errors.md#errors_class_error [`domain.add(emitter)`]: #domain_domain_add_emitter [`domain.bind(callback)`]: #domain_domain_bind_callback [`domain.exit()`]: #domain_domain_exit -[`setInterval()`]: timers.html#timers_setinterval_callback_delay_args -[`setTimeout()`]: timers.html#timers_settimeout_callback_delay_args +[`setInterval()`]: timers.md#timers_setinterval_callback_delay_args +[`setTimeout()`]: timers.md#timers_settimeout_callback_delay_args [`throw`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw diff --git a/doc/api/embedding.html b/doc/api/embedding.html index c7296f303040fb09daade78a4d2b2464b5850224..54fa4be9b659894d92f8d1783dfbdce63abbe830 100644 --- a/doc/api/embedding.html +++ b/doc/api/embedding.html @@ -1,10 +1,10 @@ - + - - C++ Embedder API | Node.js v12.22.7 Documentation + + C++ embedder API | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      -
      -

      Table of Contents

      -
      +
      -

      C++ Embedder API#

      +

      C++ embedder API#

      Node.js provides a number of C++ APIs that can be used to execute JavaScript in a Node.js environment from other C++ software.

      -

      The documentation for these APIs can be found in src/node.h in the Node.js +

      The documentation for these APIs can be found in src/node.h in the Node.js source tree. In addition to the APIs exposed by Node.js, some required concepts are provided by the V8 embedder API.

      Because using Node.js as an embedded library is different from writing code that is executed by Node.js, breaking changes do not follow typical Node.js deprecation policy and may occur on each semver-major release without prior warning.

      -

      Example embedding application#

      +

      Example embedding application#

      The following sections will provide an overview over how to use these APIs to create an application from scratch that will perform the equivalent of node -e <code>, i.e. that will take a piece of JavaScript and run it in a Node.js-specific environment.

      -

      The full code can be found in the Node.js source tree.

      -

      Setting up per-process state#

      +

      The full code can be found in the Node.js source tree.

      +

      Setting up per-process state#

      Node.js requires some per-process state management in order to run:

      • Arguments parsing for Node.js CLI options,
      • @@ -156,16 +166,16 @@ a Node.js-specific environment.

      The following example shows how these can be set up. Some class names are from the node and v8 C++ namespaces, respectively.

      -
      int main(int argc, char** argv) {
      -  argv = uv_setup_args(argc, argv);
      -  std::vector<std::string> args(argv, argv + argc);
      -  std::vector<std::string> exec_args;
      -  std::vector<std::string> errors;
      +
      int main(int argc, char** argv) {
      +  argv = uv_setup_args(argc, argv);
      +  std::vector<std::string> args(argv, argv + argc);
      +  std::vector<std::string> exec_args;
      +  std::vector<std::string> errors;
         // Parse Node.js CLI options, and print any errors that have occurred while
         // trying to parse them.
      -  int exit_code = node::InitializeNodeWithArgs(&args, &exec_args, &errors);
      -  for (const std::string& error : errors)
      -    fprintf(stderr, "%s: %s\n", args[0].c_str(), error.c_str());
      +  int exit_code = node::InitializeNodeWithArgs(&args, &exec_args, &errors);
      +  for (const std::string& error : errors)
      +    fprintf(stderr, "%s: %s\n", args[0].c_str(), error.c_str());
         if (exit_code != 0) {
           return exit_code;
         }
      @@ -174,19 +184,19 @@ the node and v8 C++ namespaces, respectively.

      // to create a v8::Platform instance that Node.js can use when creating // Worker threads. When no `MultiIsolatePlatform` instance is present, // Worker threads are disabled. - std::unique_ptr<MultiIsolatePlatform> platform = - MultiIsolatePlatform::Create(4); - V8::InitializePlatform(platform.get()); - V8::Initialize(); + std::unique_ptr<MultiIsolatePlatform> platform = + MultiIsolatePlatform::Create(4); + V8::InitializePlatform(platform.get()); + V8::Initialize(); // See below for the contents of this function. - int ret = RunNodeInstance(platform.get(), args, exec_args); + int ret = RunNodeInstance(platform.get(), args, exec_args); - V8::Dispose(); - V8::ShutdownPlatform(); + V8::Dispose(); + V8::ShutdownPlatform(); return ret; }
      -

      Per-instance state#

      +

      Per-instance state#

      Node.js has a concept of a “Node.js instance”, that is commonly being referred to as node::Environment. Each node::Environment is associated with:

        @@ -210,132 +220,169 @@ for tasks scheduled by the v8::Isolate.

        The node::NewIsolate() helper function creates a v8::Isolate, sets it up with some Node.js-specific hooks (e.g. the Node.js error handler), and registers it with the platform automatically.

        -
        int RunNodeInstance(MultiIsolatePlatform* platform,
        -                    const std::vector<std::string>& args,
        -                    const std::vector<std::string>& exec_args) {
        -  int exit_code = 0;
        -  // Set up a libuv event loop.
        -  uv_loop_t loop;
        -  int ret = uv_loop_init(&loop);
        -  if (ret != 0) {
        -    fprintf(stderr, "%s: Failed to initialize loop: %s\n",
        -            args[0].c_str(),
        -            uv_err_name(ret));
        -    return 1;
        +
        int RunNodeInstance(MultiIsolatePlatform* platform,
        +                    const std::vector<std::string>& args,
        +                    const std::vector<std::string>& exec_args) {
        +  int exit_code = 0;
        +  // Set up a libuv event loop.
        +  uv_loop_t loop;
        +  int ret = uv_loop_init(&loop);
        +  if (ret != 0) {
        +    fprintf(stderr, "%s: Failed to initialize loop: %s\n",
        +            args[0].c_str(),
        +            uv_err_name(ret));
        +    return 1;
           }
         
           std::shared_ptr<ArrayBufferAllocator> allocator =
        -      ArrayBufferAllocator::Create();
        +      ArrayBufferAllocator::Create();
         
        -  Isolate* isolate = NewIsolate(allocator, &loop, platform);
        -  if (isolate == nullptr) {
        -    fprintf(stderr, "%s: Failed to initialize V8 Isolate\n", args[0].c_str());
        -    return 1;
        +  Isolate* isolate = NewIsolate(allocator, &loop, platform);
        +  if (isolate == nullptr) {
        +    fprintf(stderr, "%s: Failed to initialize V8 Isolate\n", args[0].c_str());
        +    return 1;
           }
         
           {
        -    Locker locker(isolate);
        -    Isolate::Scope isolate_scope(isolate);
        +    Locker locker(isolate);
        +    Isolate::Scope isolate_scope(isolate);
         
        -    // Create a node::IsolateData instance that will later be released using
        -    // node::FreeIsolateData().
        -    std::unique_ptr<IsolateData, decltype(&node::FreeIsolateData)> isolate_data(
        +    // Create a node::IsolateData instance that will later be released using
        +    // node::FreeIsolateData().
        +    std::unique_ptr<IsolateData, decltype(&node::FreeIsolateData)> isolate_data(
                 node::CreateIsolateData(isolate, &loop, platform, allocator.get()),
        -        node::FreeIsolateData);
        +        node::FreeIsolateData);
         
        -    // Set up a new v8::Context.
        -    HandleScope handle_scope(isolate);
        -    Local<Context> context = node::NewContext(isolate);
        -    if (context.IsEmpty()) {
        -      fprintf(stderr, "%s: Failed to initialize V8 Context\n", args[0].c_str());
        -      return 1;
        +    // Set up a new v8::Context.
        +    HandleScope handle_scope(isolate);
        +    Local<Context> context = node::NewContext(isolate);
        +    if (context.IsEmpty()) {
        +      fprintf(stderr, "%s: Failed to initialize V8 Context\n", args[0].c_str());
        +      return 1;
             }
         
        -    // The v8::Context needs to be entered when node::CreateEnvironment() and
        -    // node::LoadEnvironment() are being called.
        -    Context::Scope context_scope(context);
        +    // The v8::Context needs to be entered when node::CreateEnvironment() and
        +    // node::LoadEnvironment() are being called.
        +    Context::Scope context_scope(context);
         
        -    // Create a node::Environment instance that will later be released using
        -    // node::FreeEnvironment().
        -    std::unique_ptr<Environment, decltype(&node::FreeEnvironment)> env(
        +    // Create a node::Environment instance that will later be released using
        +    // node::FreeEnvironment().
        +    std::unique_ptr<Environment, decltype(&node::FreeEnvironment)> env(
                 node::CreateEnvironment(isolate_data.get(), context, args, exec_args),
        -        node::FreeEnvironment);
        +        node::FreeEnvironment);
         
        -    // Set up the Node.js instance for execution, and run code inside of it.
        -    // There is also a variant that takes a callback and provides it with
        -    // the `require` and `process` objects, so that it can manually compile
        -    // and run scripts as needed.
        -    // The `require` function inside this script does *not* access the file
        -    // system, and can only load built-in Node.js modules.
        -    // `module.createRequire()` is being used to create one that is able to
        -    // load files from the disk, and uses the standard CommonJS file loader
        -    // instead of the internal-only `require` function.
        -    MaybeLocal<Value> loadenv_ret = node::LoadEnvironment(
        -        env.get(),
        -        "const publicRequire ="
        -        "  require('module').createRequire(process.cwd() + '/');"
        -        "globalThis.require = publicRequire;"
        -        "require('vm').runInThisContext(process.argv[1]);");
        +    // Set up the Node.js instance for execution, and run code inside of it.
        +    // There is also a variant that takes a callback and provides it with
        +    // the `require` and `process` objects, so that it can manually compile
        +    // and run scripts as needed.
        +    // The `require` function inside this script does *not* access the file
        +    // system, and can only load built-in Node.js modules.
        +    // `module.createRequire()` is being used to create one that is able to
        +    // load files from the disk, and uses the standard CommonJS file loader
        +    // instead of the internal-only `require` function.
        +    MaybeLocal<Value> loadenv_ret = node::LoadEnvironment(
        +        env.get(),
        +        "const publicRequire ="
        +        "  require('module').createRequire(process.cwd() + '/');"
        +        "globalThis.require = publicRequire;"
        +        "require('vm').runInThisContext(process.argv[1]);");
         
        -    if (loadenv_ret.IsEmpty())  // There has been a JS exception.
        -      return 1;
        +    if (loadenv_ret.IsEmpty())  // There has been a JS exception.
        +      return 1;
         
             {
        -      // SealHandleScope protects against handle leaks from callbacks.
        -      SealHandleScope seal(isolate);
        -      bool more;
        -      do {
        -        uv_run(&loop, UV_RUN_DEFAULT);
        +      // SealHandleScope protects against handle leaks from callbacks.
        +      SealHandleScope seal(isolate);
        +      bool more;
        +      do {
        +        uv_run(&loop, UV_RUN_DEFAULT);
         
        -        // V8 tasks on background threads may end up scheduling new tasks in the
        -        // foreground, which in turn can keep the event loop going. For example,
        -        // WebAssembly.compile() may do so.
        -        platform->DrainTasks(isolate);
        +        // V8 tasks on background threads may end up scheduling new tasks in the
        +        // foreground, which in turn can keep the event loop going. For example,
        +        // WebAssembly.compile() may do so.
        +        platform->DrainTasks(isolate);
         
        -        // If there are new tasks, continue.
        -        more = uv_loop_alive(&loop);
        -        if (more) continue;
        +        // If there are new tasks, continue.
        +        more = uv_loop_alive(&loop);
        +        if (more) continue;
         
        -        // node::EmitBeforeExit() is used to emit the 'beforeExit' event on
        -        // the `process` object.
        -        node::EmitBeforeExit(env.get());
        +        // node::EmitProcessBeforeExit() is used to emit the 'beforeExit' event
        +        // on the `process` object.
        +        if (node::EmitProcessBeforeExit(env.get()).IsNothing())
        +          break;
         
        -        // 'beforeExit' can also schedule new work that keeps the event loop
        -        // running.
        -        more = uv_loop_alive(&loop);
        -      } while (more == true);
        +        // 'beforeExit' can also schedule new work that keeps the event loop
        +        // running.
        +        more = uv_loop_alive(&loop);
        +      } while (more == true);
             }
         
        -    // node::EmitExit() returns the current exit code.
        -    exit_code = node::EmitExit(env.get());
        +    // node::EmitProcessExit() returns the current exit code.
        +    exit_code = node::EmitProcessExit(env.get()).FromMaybe(1);
         
        -    // node::Stop() can be used to explicitly stop the event loop and keep
        -    // further JavaScript from running. It can be called from any thread,
        -    // and will act like worker.terminate() if called from another thread.
        -    node::Stop(env.get());
        +    // node::Stop() can be used to explicitly stop the event loop and keep
        +    // further JavaScript from running. It can be called from any thread,
        +    // and will act like worker.terminate() if called from another thread.
        +    node::Stop(env.get());
           }
         
        -  // Unregister the Isolate with the platform and add a listener that is called
        -  // when the Platform is done cleaning up any state it had associated with
        -  // the Isolate.
        -  bool platform_finished = false;
        -  platform->AddIsolateFinishedCallback(isolate, [](void* data) {
        -    *static_cast<bool*>(data) = true;
        +  // Unregister the Isolate with the platform and add a listener that is called
        +  // when the Platform is done cleaning up any state it had associated with
        +  // the Isolate.
        +  bool platform_finished = false;
        +  platform->AddIsolateFinishedCallback(isolate, [](void* data) {
        +    *static_cast<bool*>(data) = true;
           }, &platform_finished);
        -  platform->UnregisterIsolate(isolate);
        -  isolate->Dispose();
        +  platform->UnregisterIsolate(isolate);
        +  isolate->Dispose();
         
        -  // Wait until the platform has cleaned up all relevant resources.
        -  while (!platform_finished)
        -    uv_run(&loop, UV_RUN_ONCE);
        -  int err = uv_loop_close(&loop);
        -  assert(err == 0);
        +  // Wait until the platform has cleaned up all relevant resources.
        +  while (!platform_finished)
        +    uv_run(&loop, UV_RUN_ONCE);
        +  int err = uv_loop_close(&loop);
        +  assert(err == 0);
         
        -  return exit_code;
        -}
        + return exit_code; +}
      + diff --git a/doc/api/embedding.json b/doc/api/embedding.json index c96833f8feab6a31ae78f01067b2027630649cbc..6aade9263ad5a5a8a49ac17aa49f5c4c73f517e0 100644 --- a/doc/api/embedding.json +++ b/doc/api/embedding.json @@ -3,10 +3,10 @@ "source": "doc/api/embedding.md", "modules": [ { - "textRaw": "C++ Embedder API", + "textRaw": "C++ embedder API", "name": "c++_embedder_api", - "introduced_in": "v12.19.0", - "desc": "

      Node.js provides a number of C++ APIs that can be used to execute JavaScript\nin a Node.js environment from other C++ software.

      \n

      The documentation for these APIs can be found in src/node.h in the Node.js\nsource tree. In addition to the APIs exposed by Node.js, some required concepts\nare provided by the V8 embedder API.

      \n

      Because using Node.js as an embedded library is different from writing code\nthat is executed by Node.js, breaking changes do not follow typical Node.js\ndeprecation policy and may occur on each semver-major release without prior\nwarning.

      \n

      Example embedding application

      \n

      The following sections will provide an overview over how to use these APIs\nto create an application from scratch that will perform the equivalent of\nnode -e <code>, i.e. that will take a piece of JavaScript and run it in\na Node.js-specific environment.

      \n

      The full code can be found in the Node.js source tree.

      ", + "introduced_in": "v14.0.0", + "desc": "

      Node.js provides a number of C++ APIs that can be used to execute JavaScript\nin a Node.js environment from other C++ software.

      \n

      The documentation for these APIs can be found in src/node.h in the Node.js\nsource tree. In addition to the APIs exposed by Node.js, some required concepts\nare provided by the V8 embedder API.

      \n

      Because using Node.js as an embedded library is different from writing code\nthat is executed by Node.js, breaking changes do not follow typical Node.js\ndeprecation policy and may occur on each semver-major release without prior\nwarning.

      \n

      Example embedding application

      \n

      The following sections will provide an overview over how to use these APIs\nto create an application from scratch that will perform the equivalent of\nnode -e <code>, i.e. that will take a piece of JavaScript and run it in\na Node.js-specific environment.

      \n

      The full code can be found in the Node.js source tree.

      ", "modules": [ { "textRaw": "Setting up per-process state", @@ -18,13 +18,13 @@ { "textRaw": "Per-instance state", "name": "per-instance_state", - "desc": "

      Node.js has a concept of a “Node.js instance”, that is commonly being referred\nto as node::Environment. Each node::Environment is associated with:

      \n
        \n
      • Exactly one v8::Isolate, i.e. one JS Engine instance,
      • \n
      • Exactly one uv_loop_t, i.e. one event loop, and
      • \n
      • A number of v8::Contexts, but exactly one main v8::Context.
      • \n
      • One node::IsolateData instance that contains information that could be\nshared by multiple node::Environments that use the same v8::Isolate.\nCurrently, no testing if performed for this scenario.
      • \n
      \n

      In order to set up a v8::Isolate, an v8::ArrayBuffer::Allocator needs\nto be provided. One possible choice is the default Node.js allocator, which\ncan be created through node::ArrayBufferAllocator::Create(). Using the Node.js\nallocator allows minor performance optimizations when addons use the Node.js\nC++ Buffer API, and is required in order to track ArrayBuffer memory in\nprocess.memoryUsage().

      \n

      Additionally, each v8::Isolate that is used for a Node.js instance needs to\nbe registered and unregistered with the MultiIsolatePlatform instance, if one\nis being used, in order for the platform to know which event loop to use\nfor tasks scheduled by the v8::Isolate.

      \n

      The node::NewIsolate() helper function creates a v8::Isolate,\nsets it up with some Node.js-specific hooks (e.g. the Node.js error handler),\nand registers it with the platform automatically.

      \n
      int RunNodeInstance(MultiIsolatePlatform* platform,\n                    const std::vector<std::string>& args,\n                    const std::vector<std::string>& exec_args) {\n  int exit_code = 0;\n  // Set up a libuv event loop.\n  uv_loop_t loop;\n  int ret = uv_loop_init(&loop);\n  if (ret != 0) {\n    fprintf(stderr, \"%s: Failed to initialize loop: %s\\n\",\n            args[0].c_str(),\n            uv_err_name(ret));\n    return 1;\n  }\n\n  std::shared_ptr<ArrayBufferAllocator> allocator =\n      ArrayBufferAllocator::Create();\n\n  Isolate* isolate = NewIsolate(allocator, &loop, platform);\n  if (isolate == nullptr) {\n    fprintf(stderr, \"%s: Failed to initialize V8 Isolate\\n\", args[0].c_str());\n    return 1;\n  }\n\n  {\n    Locker locker(isolate);\n    Isolate::Scope isolate_scope(isolate);\n\n    // Create a node::IsolateData instance that will later be released using\n    // node::FreeIsolateData().\n    std::unique_ptr<IsolateData, decltype(&node::FreeIsolateData)> isolate_data(\n        node::CreateIsolateData(isolate, &loop, platform, allocator.get()),\n        node::FreeIsolateData);\n\n    // Set up a new v8::Context.\n    HandleScope handle_scope(isolate);\n    Local<Context> context = node::NewContext(isolate);\n    if (context.IsEmpty()) {\n      fprintf(stderr, \"%s: Failed to initialize V8 Context\\n\", args[0].c_str());\n      return 1;\n    }\n\n    // The v8::Context needs to be entered when node::CreateEnvironment() and\n    // node::LoadEnvironment() are being called.\n    Context::Scope context_scope(context);\n\n    // Create a node::Environment instance that will later be released using\n    // node::FreeEnvironment().\n    std::unique_ptr<Environment, decltype(&node::FreeEnvironment)> env(\n        node::CreateEnvironment(isolate_data.get(), context, args, exec_args),\n        node::FreeEnvironment);\n\n    // Set up the Node.js instance for execution, and run code inside of it.\n    // There is also a variant that takes a callback and provides it with\n    // the `require` and `process` objects, so that it can manually compile\n    // and run scripts as needed.\n    // The `require` function inside this script does *not* access the file\n    // system, and can only load built-in Node.js modules.\n    // `module.createRequire()` is being used to create one that is able to\n    // load files from the disk, and uses the standard CommonJS file loader\n    // instead of the internal-only `require` function.\n    MaybeLocal<Value> loadenv_ret = node::LoadEnvironment(\n        env.get(),\n        \"const publicRequire =\"\n        \"  require('module').createRequire(process.cwd() + '/');\"\n        \"globalThis.require = publicRequire;\"\n        \"require('vm').runInThisContext(process.argv[1]);\");\n\n    if (loadenv_ret.IsEmpty())  // There has been a JS exception.\n      return 1;\n\n    {\n      // SealHandleScope protects against handle leaks from callbacks.\n      SealHandleScope seal(isolate);\n      bool more;\n      do {\n        uv_run(&loop, UV_RUN_DEFAULT);\n\n        // V8 tasks on background threads may end up scheduling new tasks in the\n        // foreground, which in turn can keep the event loop going. For example,\n        // WebAssembly.compile() may do so.\n        platform->DrainTasks(isolate);\n\n        // If there are new tasks, continue.\n        more = uv_loop_alive(&loop);\n        if (more) continue;\n\n        // node::EmitBeforeExit() is used to emit the 'beforeExit' event on\n        // the `process` object.\n        node::EmitBeforeExit(env.get());\n\n        // 'beforeExit' can also schedule new work that keeps the event loop\n        // running.\n        more = uv_loop_alive(&loop);\n      } while (more == true);\n    }\n\n    // node::EmitExit() returns the current exit code.\n    exit_code = node::EmitExit(env.get());\n\n    // node::Stop() can be used to explicitly stop the event loop and keep\n    // further JavaScript from running. It can be called from any thread,\n    // and will act like worker.terminate() if called from another thread.\n    node::Stop(env.get());\n  }\n\n  // Unregister the Isolate with the platform and add a listener that is called\n  // when the Platform is done cleaning up any state it had associated with\n  // the Isolate.\n  bool platform_finished = false;\n  platform->AddIsolateFinishedCallback(isolate, [](void* data) {\n    *static_cast<bool*>(data) = true;\n  }, &platform_finished);\n  platform->UnregisterIsolate(isolate);\n  isolate->Dispose();\n\n  // Wait until the platform has cleaned up all relevant resources.\n  while (!platform_finished)\n    uv_run(&loop, UV_RUN_ONCE);\n  int err = uv_loop_close(&loop);\n  assert(err == 0);\n\n  return exit_code;\n}\n
      ", + "desc": "

      Node.js has a concept of a “Node.js instance”, that is commonly being referred\nto as node::Environment. Each node::Environment is associated with:

      \n
        \n
      • Exactly one v8::Isolate, i.e. one JS Engine instance,
      • \n
      • Exactly one uv_loop_t, i.e. one event loop, and
      • \n
      • A number of v8::Contexts, but exactly one main v8::Context.
      • \n
      • One node::IsolateData instance that contains information that could be\nshared by multiple node::Environments that use the same v8::Isolate.\nCurrently, no testing if performed for this scenario.
      • \n
      \n

      In order to set up a v8::Isolate, an v8::ArrayBuffer::Allocator needs\nto be provided. One possible choice is the default Node.js allocator, which\ncan be created through node::ArrayBufferAllocator::Create(). Using the Node.js\nallocator allows minor performance optimizations when addons use the Node.js\nC++ Buffer API, and is required in order to track ArrayBuffer memory in\nprocess.memoryUsage().

      \n

      Additionally, each v8::Isolate that is used for a Node.js instance needs to\nbe registered and unregistered with the MultiIsolatePlatform instance, if one\nis being used, in order for the platform to know which event loop to use\nfor tasks scheduled by the v8::Isolate.

      \n

      The node::NewIsolate() helper function creates a v8::Isolate,\nsets it up with some Node.js-specific hooks (e.g. the Node.js error handler),\nand registers it with the platform automatically.

      \n
      int RunNodeInstance(MultiIsolatePlatform* platform,\n                    const std::vector<std::string>& args,\n                    const std::vector<std::string>& exec_args) {\n  int exit_code = 0;\n  // Set up a libuv event loop.\n  uv_loop_t loop;\n  int ret = uv_loop_init(&loop);\n  if (ret != 0) {\n    fprintf(stderr, \"%s: Failed to initialize loop: %s\\n\",\n            args[0].c_str(),\n            uv_err_name(ret));\n    return 1;\n  }\n\n  std::shared_ptr<ArrayBufferAllocator> allocator =\n      ArrayBufferAllocator::Create();\n\n  Isolate* isolate = NewIsolate(allocator, &loop, platform);\n  if (isolate == nullptr) {\n    fprintf(stderr, \"%s: Failed to initialize V8 Isolate\\n\", args[0].c_str());\n    return 1;\n  }\n\n  {\n    Locker locker(isolate);\n    Isolate::Scope isolate_scope(isolate);\n\n    // Create a node::IsolateData instance that will later be released using\n    // node::FreeIsolateData().\n    std::unique_ptr<IsolateData, decltype(&node::FreeIsolateData)> isolate_data(\n        node::CreateIsolateData(isolate, &loop, platform, allocator.get()),\n        node::FreeIsolateData);\n\n    // Set up a new v8::Context.\n    HandleScope handle_scope(isolate);\n    Local<Context> context = node::NewContext(isolate);\n    if (context.IsEmpty()) {\n      fprintf(stderr, \"%s: Failed to initialize V8 Context\\n\", args[0].c_str());\n      return 1;\n    }\n\n    // The v8::Context needs to be entered when node::CreateEnvironment() and\n    // node::LoadEnvironment() are being called.\n    Context::Scope context_scope(context);\n\n    // Create a node::Environment instance that will later be released using\n    // node::FreeEnvironment().\n    std::unique_ptr<Environment, decltype(&node::FreeEnvironment)> env(\n        node::CreateEnvironment(isolate_data.get(), context, args, exec_args),\n        node::FreeEnvironment);\n\n    // Set up the Node.js instance for execution, and run code inside of it.\n    // There is also a variant that takes a callback and provides it with\n    // the `require` and `process` objects, so that it can manually compile\n    // and run scripts as needed.\n    // The `require` function inside this script does *not* access the file\n    // system, and can only load built-in Node.js modules.\n    // `module.createRequire()` is being used to create one that is able to\n    // load files from the disk, and uses the standard CommonJS file loader\n    // instead of the internal-only `require` function.\n    MaybeLocal<Value> loadenv_ret = node::LoadEnvironment(\n        env.get(),\n        \"const publicRequire =\"\n        \"  require('module').createRequire(process.cwd() + '/');\"\n        \"globalThis.require = publicRequire;\"\n        \"require('vm').runInThisContext(process.argv[1]);\");\n\n    if (loadenv_ret.IsEmpty())  // There has been a JS exception.\n      return 1;\n\n    {\n      // SealHandleScope protects against handle leaks from callbacks.\n      SealHandleScope seal(isolate);\n      bool more;\n      do {\n        uv_run(&loop, UV_RUN_DEFAULT);\n\n        // V8 tasks on background threads may end up scheduling new tasks in the\n        // foreground, which in turn can keep the event loop going. For example,\n        // WebAssembly.compile() may do so.\n        platform->DrainTasks(isolate);\n\n        // If there are new tasks, continue.\n        more = uv_loop_alive(&loop);\n        if (more) continue;\n\n        // node::EmitProcessBeforeExit() is used to emit the 'beforeExit' event\n        // on the `process` object.\n        if (node::EmitProcessBeforeExit(env.get()).IsNothing())\n          break;\n\n        // 'beforeExit' can also schedule new work that keeps the event loop\n        // running.\n        more = uv_loop_alive(&loop);\n      } while (more == true);\n    }\n\n    // node::EmitProcessExit() returns the current exit code.\n    exit_code = node::EmitProcessExit(env.get()).FromMaybe(1);\n\n    // node::Stop() can be used to explicitly stop the event loop and keep\n    // further JavaScript from running. It can be called from any thread,\n    // and will act like worker.terminate() if called from another thread.\n    node::Stop(env.get());\n  }\n\n  // Unregister the Isolate with the platform and add a listener that is called\n  // when the Platform is done cleaning up any state it had associated with\n  // the Isolate.\n  bool platform_finished = false;\n  platform->AddIsolateFinishedCallback(isolate, [](void* data) {\n    *static_cast<bool*>(data) = true;\n  }, &platform_finished);\n  platform->UnregisterIsolate(isolate);\n  isolate->Dispose();\n\n  // Wait until the platform has cleaned up all relevant resources.\n  while (!platform_finished)\n    uv_run(&loop, UV_RUN_ONCE);\n  int err = uv_loop_close(&loop);\n  assert(err == 0);\n\n  return exit_code;\n}\n
      ", "type": "module", "displayName": "Per-instance state" } ], "type": "module", - "displayName": "C++ Embedder API" + "displayName": "C++ embedder API" } ] } \ No newline at end of file diff --git a/doc/api/embedding.md b/doc/api/embedding.md index 9d884dae1a4818aa4a8946f4fd5f2d9233c9b7f5..7dc4a2db7fca639547f320b7f53d7ec8cb9e3e73 100644 --- a/doc/api/embedding.md +++ b/doc/api/embedding.md @@ -1,6 +1,6 @@ -# C++ Embedder API +# C++ embedder API - + Node.js provides a number of C++ APIs that can be used to execute JavaScript in a Node.js environment from other C++ software. @@ -181,9 +181,10 @@ int RunNodeInstance(MultiIsolatePlatform* platform, more = uv_loop_alive(&loop); if (more) continue; - // node::EmitBeforeExit() is used to emit the 'beforeExit' event on - // the `process` object. - node::EmitBeforeExit(env.get()); + // node::EmitProcessBeforeExit() is used to emit the 'beforeExit' event + // on the `process` object. + if (node::EmitProcessBeforeExit(env.get()).IsNothing()) + break; // 'beforeExit' can also schedule new work that keeps the event loop // running. @@ -191,8 +192,8 @@ int RunNodeInstance(MultiIsolatePlatform* platform, } while (more == true); } - // node::EmitExit() returns the current exit code. - exit_code = node::EmitExit(env.get()); + // node::EmitProcessExit() returns the current exit code. + exit_code = node::EmitProcessExit(env.get()).FromMaybe(1); // node::Stop() can be used to explicitly stop the event loop and keep // further JavaScript from running. It can be called from any thread, @@ -220,8 +221,8 @@ int RunNodeInstance(MultiIsolatePlatform* platform, } ``` -[`process.memoryUsage()`]: process.html#process_process_memoryusage -[CLI options]: cli.html -[deprecation policy]: deprecations.html -[embedtest.cc]: https://github.com/nodejs/node/blob/master/test/embedding/embedtest.cc -[src/node.h]: https://github.com/nodejs/node/blob/master/src/node.h +[CLI options]: cli.md +[`process.memoryUsage()`]: process.md#process_process_memoryusage +[deprecation policy]: deprecations.md +[embedtest.cc]: https://github.com/nodejs/node/blob/HEAD/test/embedding/embedtest.cc +[src/node.h]: https://github.com/nodejs/node/blob/HEAD/src/node.h diff --git a/doc/api/errors.html b/doc/api/errors.html index b89052dfeaba1f4128fe12f04e710505e0912c22..3aca479db264f61529510a1c93d0aedc6af4baf7 100644 --- a/doc/api/errors.html +++ b/doc/api/errors.html @@ -1,10 +1,10 @@ - + - - Errors | Node.js v12.22.7 Documentation + + Errors | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      -
      -

      Table of Contents

      -
      +
      -

      Errors#

      +

      Errors#

      Applications running in Node.js will generally experience four categories of @@ -488,7 +515,7 @@ are raised typically by the assert module.

      All JavaScript and system errors raised by Node.js inherit from, or are instances of, the standard JavaScript <Error> class and are guaranteed to provide at least the properties available on that class.

      -

      Error propagation and interception#

      +

      Error propagation and interception#

      Node.js supports several mechanisms for propagating and handling errors that occur while an application is running. How these errors are reported and @@ -520,9 +547,9 @@ that should be handled.

      const fs = require('fs');
      -fs.readFile('a file that does not exist', (err, data) => {
      +fs.readFile('a file that does not exist', (err, data) => {
         if (err) {
      -    console.error('There was an error reading the file!', err);
      +    console.error('There was an error reading the file!', err);
           return;
         }
         // Otherwise handle the data
      @@ -532,17 +559,17 @@ fs.readFile('a file that does not exist', When an asynchronous method is called on an object that is an
       EventEmitter, errors can be routed to that object's 'error' event.

      const net = require('net');
      -const connection = net.connect('localhost');
      +const connection = net.connect('localhost');
       
       // Adding an 'error' event handler to a stream:
      -connection.on('error', (err) => {
      +connection.on('error', (err) => {
         // If the connection is reset by the server, or if it can't
         // connect at all, or on any sort of error encountered by
         // the connection, the error will be sent here.
      -  console.error(err);
      +  console.error(err);
       });
       
      -connection.pipe(process.stdout);
      +connection.pipe(process.stdout);
    • A handful of typically asynchronous methods in the Node.js API may still @@ -561,19 +588,19 @@ provided, the error will be thrown, causing the Node.js process to report an uncaught exception and crash unless either: The domain module is used appropriately or a handler has been registered for the 'uncaughtException' event.

      -
      const EventEmitter = require('events');
      -const ee = new EventEmitter();
      +
      const EventEmitter = require('events');
      +const ee = new EventEmitter();
       
      -setImmediate(() => {
      +setImmediate(() => {
         // This will crash the process because no 'error' event
         // handler has been added.
      -  ee.emit('error', new Error('This will crash'));
      +  ee.emit('error', new Error('This will crash'));
       });

      Errors generated in this way cannot be intercepted using try…catch as they are thrown after the calling code has already exited.

      Developers must refer to the documentation for each method to determine exactly how errors raised by those methods are propagated.

      -

      Error-first callbacks#

      +

      Error-first callbacks#

      Most asynchronous methods exposed by the Node.js core API follow an idiomatic pattern referred to as an error-first callback. With this pattern, a callback @@ -583,16 +610,16 @@ completes or an error is raised, the callback function is called with the the first argument will be passed as null.

      const fs = require('fs');
       
      -function errorFirstCallback(err, data) {
      +function errorFirstCallback(err, data) {
         if (err) {
      -    console.error('There was an error', err);
      +    console.error('There was an error', err);
           return;
         }
      -  console.log(data);
      +  console.log(data);
       }
       
      -fs.readFile('/some/file/that/does-not-exist', errorFirstCallback);
      -fs.readFile('/some/file/that/does-exist', errorFirstCallback);
      +fs.readFile('/some/file/that/does-not-exist', errorFirstCallback); +fs.readFile('/some/file/that/does-exist', errorFirstCallback);

      The JavaScript try…catch mechanism cannot be used to intercept errors generated by asynchronous APIs. A common mistake for beginners is to try to use throw inside an error-first callback:

      @@ -600,7 +627,7 @@ use throw inside an error-first callback:

      const fs = require('fs'); try { - fs.readFile('/some/file/that/does-not-exist', (err, data) => { + fs.readFile('/some/file/that/does-not-exist', (err, data) => { // Mistaken assumption: throwing here... if (err) { throw err; @@ -608,7 +635,7 @@ use throw inside an error-first callback:

      }); } catch (err) { // This will not catch the throw! - console.error(err); + console.error(err); }

      This will not work because the callback function passed to fs.readFile() is called asynchronously. By the time the callback has been called, the @@ -616,7 +643,7 @@ surrounding code, including the try…catch block, will have alread Throwing an error inside the callback can crash the Node.js process in most cases. If domains are enabled, or a handler has been registered with process.on('uncaughtException'), such errors can be intercepted.

      -

      Class: Error#

      +
    • Class: Error#

      A generic JavaScript <Error> object that does not denote any specific circumstance of why the error occurred. Error objects capture a "stack trace" @@ -624,7 +651,7 @@ detailing the point in the code at which the Error was instantiated provide a text description of the error.

      All errors generated by Node.js, including all system and JavaScript errors, will either be instances of, or inherit from, the Error class.

      -

      new Error(message)#

      +

      new Error(message)#

      @@ -635,7 +662,7 @@ represent the point in the code at which new Error() was called. St are dependent on V8's stack trace API. Stack traces extend only to either (a) the beginning of synchronous code execution, or (b) the number of frames given by the property Error.stackTraceLimit, whichever is smaller.

      -

      Error.captureStackTrace(targetObject[, constructorOpt])#

      +

      Error.captureStackTrace(targetObject[, constructorOpt])#

      • targetObject <Object>
      • constructorOpt <Function>
      • @@ -644,8 +671,8 @@ given by the property Error.stackTraceLimit, whichever is smaller.< a string representing the location in the code at which Error.captureStackTrace() was called.

        const myObject = {};
        -Error.captureStackTrace(myObject);
        -myObject.stack;  // Similar to `new Error().stack`
        +Error.captureStackTrace(myObject); +myObject.stack; // Similar to `new Error().stack`

        The first line of the trace will be prefixed with ${myObject.name}: ${myObject.message}.

        The optional constructorOpt argument accepts a function. If given, all frames @@ -653,15 +680,15 @@ above constructorOpt, including constructorOpt, will b generated stack trace.

        The constructorOpt argument is useful for hiding implementation details of error generation from the user. For instance:

        -
        function MyError() {
        -  Error.captureStackTrace(this, MyError);
        +
        function MyError() {
        +  Error.captureStackTrace(this, MyError);
         }
         
         // Without passing MyError to captureStackTrace, the MyError
         // frame would show up in the .stack property. By passing
         // the constructor, we omit that frame, and retain all frames below it.
        -new MyError().stack;
        -

        Error.stackTraceLimit#

        +new MyError().stack;
        +

        Error.stackTraceLimit#

        @@ -672,7 +699,7 @@ collected by a stack trace (whether generated by new Error().stack will affect any stack trace captured after the value has been changed.

        If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

        -

        error.code#

        +

        error.code#

        @@ -681,7 +708,7 @@ not capture any frames.

        between major versions of Node.js. In contrast, error.message strings may change between any versions of Node.js. See Node.js error codes for details about specific codes.

        -

        error.message#

        +

        error.message#

        @@ -691,10 +718,10 @@ appear in the first line of the stack trace of the Error, however c this property after the Error object is created may not change the first line of the stack trace (for example, when error.stack is read before this property is changed).

        -
        const err = new Error('The message');
        -console.error(err.message);
        +
        const err = new Error('The message');
        +console.error(err.message);
         // Prints: The message
        -

        error.stack#

        +

        error.stack#

        @@ -720,14 +747,14 @@ itself calls a JavaScript function, the frame representing the cheetahify< will not be present in the stack traces:

        const cheetahify = require('./native-binding.node');
         
        -function makeFaster() {
        +function makeFaster() {
           // `cheetahify()` *synchronously* calls speedy.
        -  cheetahify(function speedy() {
        -    throw new Error('oh no!');
        +  cheetahify(function speedy() {
        +    throw new Error('oh no!');
           });
         }
         
        -makeFaster();
        +makeFaster();
         // will throw:
         //   /home/gbusey/file.js:6
         //       throw new Error('oh no!');
        @@ -756,24 +783,24 @@ a user program, or its dependencies.
         

        The number of frames captured by the stack trace is bounded by the smaller of Error.stackTraceLimit or the number of available frames on the current event loop tick.

        -

        Class: AssertionError#

        +

      Class: AssertionError#

      Indicates the failure of an assertion. For details, see Class: assert.AssertionError.

      -

      Class: RangeError#

      +

      Class: RangeError#

      Indicates that a provided argument was not within the set or range of acceptable values for a function; whether that is a numeric range, or outside the set of options for a given function parameter.

      -
      require('net').connect(-1);
      +
      require('net').connect(-1);
       // Throws "RangeError: "port" option should be >= 0 and < 65536: -1"

      Node.js will generate and throw RangeError instances immediately as a form of argument validation.

      -

      Class: ReferenceError#

      +

      Class: ReferenceError#

      @@ -786,7 +813,7 @@ will do so.

      // Throws ReferenceError, doesNotExist is not a variable in this program.

      Unless an application is dynamically generating and running code, ReferenceError instances indicate a bug in the code or its dependencies.

      -

      Class: SyntaxError#

      +

      Class: SyntaxError#

      @@ -795,13 +822,13 @@ generated and propagated as a result of code evaluation. Code evaluation may happen as a result of eval, Function, require, or vm. These errors are almost always indicative of a broken program.

      try {
      -  require('vm').runInThisContext('binary ! isNotOk');
      +  require('vm').runInThisContext('binary ! isNotOk');
       } catch (err) {
         // 'err' will be a SyntaxError.
       }

      SyntaxError instances are unrecoverable in the context that created them – they may only be caught by other contexts.

      -

      Class: SystemError#

      +

      Class: SystemError#

      @@ -815,65 +842,65 @@ failed
    • code <string> The string error code
    • dest <string> If present, the file path destination when reporting a file system error
    • -
    • errno <number> | <string> The system-provided error number
    • +
    • errno <number> The system-provided error number
    • info <Object> If present, extra details about the error condition
    • message <string> A system-provided human-readable description of the error
    • path <string> If present, the file path when reporting a file system error
    • port <number> If present, the network connection port that is not available
    • syscall <string> The name of the system call that triggered the error
    • -

      error.address#

      +

      error.address#

      If present, error.address is a string describing the address to which a network connection failed.

      -

      error.code#

      +

      error.code#

      The error.code property is a string representing the error code.

      -

      error.dest#

      +

      error.dest#

      If present, error.dest is the file path destination when reporting a file system error.

      -

      error.errno#

      +

      error.errno#

      -

      The error.errno property is a number or a string. If it is a number, it is a -negative value which corresponds to the error code defined in -libuv Error handling. See the libuv errno.h header file -(deps/uv/include/uv/errno.h in the Node.js source tree) for details. In case -of a string, it is the same as error.code.

      -

      error.info#

      +

      The error.errno property is a negative number which corresponds +to the error code defined in libuv Error handling.

      +

      On Windows the error number provided by the system will be normalized by libuv.

      +

      To get the string representation of the error code, use +util.getSystemErrorName(error.errno).

      +

      error.info#

      If present, error.info is an object with details about the error condition.

      -

      error.message#

      +

      error.message#

      error.message is a system-provided human-readable description of the error.

      -

      error.path#

      +

      error.path#

      If present, error.path is a string containing a relevant invalid pathname.

      -

      error.port#

      +

      error.port#

      If present, error.port is the network connection port that is not available.

      -

      error.syscall#

      +

      error.syscall#

      The error.syscall property is a string describing the syscall that failed.

      -

      Common system errors#

      +

      Common system errors#

      This is a list of system errors commonly-encountered when writing a Node.js program. For a comprehensive list, see the errno(3) man page.

      -

      Class: TypeError#

      +

      Class: TypeError#

      Indicates that a provided argument is not an allowable type. For example, passing a function to a parameter which expects a string would be a TypeError.

      -
      require('url').parse(() => { });
      +
      require('url').parse(() => { });
       // Throws TypeError, since it expected a string.

      Node.js will generate and throw TypeError instances immediately as a form of argument validation.

      -

      Exceptions vs. errors#

      +

      Exceptions vs. errors#

      A JavaScript exception is a value that is thrown as a result of an invalid operation or as the target of a throw statement. While it is not required @@ -968,23 +995,32 @@ instances of Error.

      Some exceptions are unrecoverable at the JavaScript layer. Such exceptions will always cause the Node.js process to crash. Examples include assert() checks or abort() calls in the C++ layer.

      -

      OpenSSL errors#

      +

      OpenSSL errors#

      Errors originating in crypto or tls are of class Error, and in addition to the standard .code and .message properties, may have some additional OpenSSL-specific properties.

      -

      error.opensslErrorStack#

      +

      error.opensslErrorStack#

      An array of errors that can give context to where in the OpenSSL library an error originates from.

      -

      error.function#

      +

      error.function#

      The OpenSSL function the error originates in.

      -

      error.library#

      +

      error.library#

      The OpenSSL library the error originates in.

      -

      error.reason#

      +

      error.reason#

      A human-readable string describing the reason for the error.

      -

      Node.js error codes#

      +

      Node.js error codes#

      +

      +

      ABORT_ERR#

      + +

      Used when an operation has been aborted (typically using an AbortController).

      +

      APIs not using AbortSignals typically do not raise an error with this code.

      +

      This code does not use the regular ERR_* convention Node.js errors use in +order to be compatible with the web platform's AbortError.

      -

      ERR_AMBIGUOUS_ARGUMENT#

      +

      ERR_AMBIGUOUS_ARGUMENT#

      A function argument is being used in a way that suggests that the function signature may be misunderstood. This is thrown by the assert module when the message parameter in assert.throws(block, message) matches the error message @@ -992,30 +1028,30 @@ thrown by block because that usage suggests that the user believes is the expected message rather than the message the AssertionError will display if block does not throw.

      -

      ERR_ARG_NOT_ITERABLE#

      +

      ERR_ARG_NOT_ITERABLE#

      An iterable argument (i.e. a value that works with for...of loops) was required, but not provided to a Node.js API.

      -

      ERR_ASSERTION#

      +

      ERR_ASSERTION#

      A special type of error that can be triggered whenever Node.js detects an exceptional logic violation that should never occur. These are raised typically by the assert module.

      -

      ERR_ASYNC_CALLBACK#

      +

      ERR_ASYNC_CALLBACK#

      An attempt was made to register something that is not a function as an AsyncHooks callback.

      -

      ERR_ASYNC_TYPE#

      +

      ERR_ASYNC_TYPE#

      The type of an asynchronous resource was invalid. Users are also able to define their own types if using the public embedder API.

      -

      ERR_BROTLI_COMPRESSION_FAILED#

      +

      ERR_BROTLI_COMPRESSION_FAILED#

      Data passed to a Brotli stream was not successfully compressed.

      -

      ERR_BROTLI_INVALID_PARAM#

      +

      ERR_BROTLI_INVALID_PARAM#

      An invalid parameter key was passed during construction of a Brotli stream.

      -

      ERR_BUFFER_CONTEXT_NOT_AVAILABLE#

      +

      ERR_BUFFER_CONTEXT_NOT_AVAILABLE#

      An attempt was made to create a Node.js Buffer instance from addon or embedder code, while in a JS engine Context that is not associated with a Node.js instance. The data passed to the Buffer method will have been released @@ -1025,920 +1061,988 @@ instance is to create a normal Uint8Array, which only differs in th prototype of the resulting object. Uint8Arrays are generally accepted in all Node.js core APIs where Buffers are; they are available in all Contexts.

      -

      ERR_BUFFER_OUT_OF_BOUNDS#

      +

      ERR_BUFFER_OUT_OF_BOUNDS#

      An operation outside the bounds of a Buffer was attempted.

      -

      ERR_BUFFER_TOO_LARGE#

      +

      ERR_BUFFER_TOO_LARGE#

      An attempt has been made to create a Buffer larger than the maximum allowed size.

      -

      ERR_CANNOT_WATCH_SIGINT#

      +

      ERR_CANNOT_WATCH_SIGINT#

      Node.js was unable to watch for the SIGINT signal.

      -

      ERR_CHILD_CLOSED_BEFORE_REPLY#

      +

      ERR_CHILD_CLOSED_BEFORE_REPLY#

      A child process was closed before the parent received a reply.

      -

      ERR_CHILD_PROCESS_IPC_REQUIRED#

      +

      ERR_CHILD_PROCESS_IPC_REQUIRED#

      Used when a child process is being forked without specifying an IPC channel.

      -

      ERR_CHILD_PROCESS_STDIO_MAXBUFFER#

      +

      ERR_CHILD_PROCESS_STDIO_MAXBUFFER#

      Used when the main process is trying to read data from the child process's STDERR/STDOUT, and the data's length is longer than the maxBuffer option.

      +

      +

      ERR_CLOSED_MESSAGE_PORT#

      + +

      There was an attempt to use a MessagePort instance in a closed +state, usually after .close() has been called.

      -

      ERR_CONSOLE_WRITABLE_STREAM#

      +

      ERR_CONSOLE_WRITABLE_STREAM#

      Console was instantiated without stdout stream, or Console has a non-writable stdout or stderr stream.

      -

      -

      ERR_CONSTRUCT_CALL_REQUIRED#

      -

      A constructor for a class was called without new.

      -

      ERR_CONSTRUCT_CALL_INVALID#

      +

      ERR_CONSTRUCT_CALL_INVALID#

      A class constructor was called that is not callable.

      +

      +

      ERR_CONSTRUCT_CALL_REQUIRED#

      +

      A constructor for a class was called without new.

      +

      +

      ERR_CONTEXT_NOT_INITIALIZED#

      +

      The vm context passed into the API is not yet initialized. This could happen +when an error occurs (and is caught) during the creation of the +context, for example, when the allocation fails or the maximum call stack +size is reached when the context is created.

      -

      ERR_CPU_USAGE#

      +

      ERR_CPU_USAGE#

      The native call from process.cpuUsage could not be processed.

      -

      ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED#

      +

      ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED#

      A client certificate engine was requested that is not supported by the version of OpenSSL being used.

      -

      ERR_CRYPTO_ECDH_INVALID_FORMAT#

      +

      ERR_CRYPTO_ECDH_INVALID_FORMAT#

      An invalid value for the format argument was passed to the crypto.ECDH() class getPublicKey() method.

      -

      ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY#

      +

      ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY#

      An invalid value for the key argument has been passed to the crypto.ECDH() class computeSecret() method. It means that the public key lies outside of the elliptic curve.

      -

      ERR_CRYPTO_ENGINE_UNKNOWN#

      +

      ERR_CRYPTO_ENGINE_UNKNOWN#

      An invalid crypto engine identifier was passed to require('crypto').setEngine().

      -

      ERR_CRYPTO_FIPS_FORCED#

      +

      ERR_CRYPTO_FIPS_FORCED#

      The --force-fips command-line argument was used but there was an attempt to enable or disable FIPS mode in the crypto module.

      -

      ERR_CRYPTO_FIPS_UNAVAILABLE#

      +

      ERR_CRYPTO_FIPS_UNAVAILABLE#

      An attempt was made to enable or disable FIPS mode, but FIPS mode was not available.

      -

      ERR_CRYPTO_HASH_FINALIZED#

      +

      ERR_CRYPTO_HASH_FINALIZED#

      hash.digest() was called multiple times. The hash.digest() method must be called no more than one time per instance of a Hash object.

      -

      ERR_CRYPTO_HASH_UPDATE_FAILED#

      +

      ERR_CRYPTO_HASH_UPDATE_FAILED#

      hash.update() failed for any reason. This should rarely, if ever, happen.

      -

      ERR_CRYPTO_INCOMPATIBLE_KEY#

      +

      ERR_CRYPTO_INCOMPATIBLE_KEY#

      The given crypto keys are incompatible with the attempted operation.

      -

      ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS#

      +

      ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS#

      The selected public or private key encoding is incompatible with other options.

      -

      ERR_CRYPTO_INVALID_DIGEST#

      +

      ERR_CRYPTO_INVALID_DIGEST#

      An invalid crypto digest algorithm was specified.

      -

      ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE#

      +

      ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE#

      The given crypto key object's type is invalid for the attempted operation.

      -

      ERR_CRYPTO_INVALID_STATE#

      +

      ERR_CRYPTO_INVALID_STATE#

      A crypto method was used on an object that was in an invalid state. For instance, calling cipher.getAuthTag() before calling cipher.final().

      -

      ERR_CRYPTO_PBKDF2_ERROR#

      +

      ERR_CRYPTO_PBKDF2_ERROR#

      The PBKDF2 algorithm failed for unspecified reasons. OpenSSL does not provide more details and therefore neither does Node.js.

      -

      ERR_CRYPTO_SCRYPT_INVALID_PARAMETER#

      +

      ERR_CRYPTO_SCRYPT_INVALID_PARAMETER#

      One or more crypto.scrypt() or crypto.scryptSync() parameters are outside their legal range.

      -

      ERR_CRYPTO_SCRYPT_NOT_SUPPORTED#

      +

      ERR_CRYPTO_SCRYPT_NOT_SUPPORTED#

      Node.js was compiled without scrypt support. Not possible with the official release binaries but can happen with custom builds, including distro builds.

      -

      ERR_CRYPTO_SIGN_KEY_REQUIRED#

      +

      ERR_CRYPTO_SIGN_KEY_REQUIRED#

      A signing key was not provided to the sign.sign() method.

      -

      ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH#

      +

      ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH#

      crypto.timingSafeEqual() was called with Buffer, TypedArray, or DataView arguments of different lengths.

      -

      ERR_CRYPTO_UNKNOWN_CIPHER#

      +

      ERR_CRYPTO_UNKNOWN_CIPHER#

      An unknown cipher was specified.

      -

      ERR_CRYPTO_UNKNOWN_DH_GROUP#

      +

      ERR_CRYPTO_UNKNOWN_DH_GROUP#

      An unknown Diffie-Hellman group name was given. See crypto.getDiffieHellman() for a list of valid group names.

      +

      +

      ERR_DLOPEN_FAILED#

      + +

      A call to process.dlopen() failed.

      +

      +

      ERR_DEBUGGER_ERROR#

      + +

      An error occurred with the debugger.

      +

      +

      ERR_DEBUGGER_STARTUP_ERROR#

      + +

      The debugger timed out waiting for the required host/port to be free.

      -

      ERR_DIR_CLOSED#

      +

      ERR_DIR_CLOSED#

      The fs.Dir was previously closed.

      -

      ERR_DIR_CONCURRENT_OPERATION#

      +

      ERR_DIR_CONCURRENT_OPERATION#

      A synchronous read or close call was attempted on an fs.Dir which has ongoing asynchronous operations.

      -

      ERR_DNS_SET_SERVERS_FAILED#

      +

      ERR_DNS_SET_SERVERS_FAILED#

      c-ares failed to set the DNS server.

      -

      ERR_DOMAIN_CALLBACK_NOT_AVAILABLE#

      +

      ERR_DOMAIN_CALLBACK_NOT_AVAILABLE#

      The domain module was not usable since it could not establish the required error handling hooks, because process.setUncaughtExceptionCaptureCallback() had been called at an earlier point in time.

      -

      ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE#

      +

      ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE#

      process.setUncaughtExceptionCaptureCallback() could not be called because the domain module has been loaded at an earlier point in time.

      The stack trace is extended to include the point in time at which the domain module had been loaded.

      -

      ERR_ENCODING_INVALID_ENCODED_DATA#

      +

      ERR_ENCODING_INVALID_ENCODED_DATA#

      Data provided to TextDecoder() API was invalid according to the encoding provided.

      -

      ERR_ENCODING_NOT_SUPPORTED#

      +

      ERR_ENCODING_NOT_SUPPORTED#

      Encoding provided to TextDecoder() API was not one of the WHATWG Supported Encodings.

      +

      +

      ERR_EVAL_ESM_CANNOT_PRINT#

      +

      --print cannot be used with ESM input.

      +

      +

      ERR_EVENT_RECURSION#

      +

      Thrown when an attempt is made to recursively dispatch an event on EventTarget.

      -

      ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE#

      +

      ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE#

      The JS execution context is not associated with a Node.js environment. This may occur when Node.js is used as an embedded library and some hooks for the JS engine are not set up properly.

      -

      ERR_FALSY_VALUE_REJECTION#

      +

      ERR_FALSY_VALUE_REJECTION#

      A Promise that was callbackified via util.callbackify() was rejected with a falsy value.

      +

      +

      ERR_FEATURE_UNAVAILABLE_ON_PLATFORM#

      + +

      Used when a feature that is not available +to the current platform which is running Node.js is used.

      +

      +

      ERR_FS_EISDIR#

      +

      Path is a directory.

      -

      ERR_FS_FILE_TOO_LARGE#

      +

      ERR_FS_FILE_TOO_LARGE#

      An attempt has been made to read a file whose size is larger than the maximum allowed size for a Buffer.

      -

      ERR_FS_INVALID_SYMLINK_TYPE#

      +

      ERR_FS_INVALID_SYMLINK_TYPE#

      An invalid symlink type was passed to the fs.symlink() or fs.symlinkSync() methods.

      -

      ERR_HTTP_HEADERS_SENT#

      +

      ERR_HTTP_HEADERS_SENT#

      An attempt was made to add more headers after the headers had already been sent.

      -

      ERR_HTTP_INVALID_HEADER_VALUE#

      +

      ERR_HTTP_INVALID_HEADER_VALUE#

      An invalid HTTP header value was specified.

      -

      ERR_HTTP_INVALID_STATUS_CODE#

      +

      ERR_HTTP_INVALID_STATUS_CODE#

      Status code was outside the regular status code range (100-999).

      -

      ERR_HTTP_TRAILER_INVALID#

      +

      ERR_HTTP_TRAILER_INVALID#

      The Trailer header was set even though the transfer encoding does not support that.

      -

      ERR_HTTP2_ALTSVC_INVALID_ORIGIN#

      +

      ERR_HTTP2_ALTSVC_INVALID_ORIGIN#

      HTTP/2 ALTSVC frames require a valid origin.

      -

      ERR_HTTP2_ALTSVC_LENGTH#

      +

      ERR_HTTP2_ALTSVC_LENGTH#

      HTTP/2 ALTSVC frames are limited to a maximum of 16,382 payload bytes.

      -

      ERR_HTTP2_CONNECT_AUTHORITY#

      +

      ERR_HTTP2_CONNECT_AUTHORITY#

      For HTTP/2 requests using the CONNECT method, the :authority pseudo-header is required.

      -

      ERR_HTTP2_CONNECT_PATH#

      +

      ERR_HTTP2_CONNECT_PATH#

      For HTTP/2 requests using the CONNECT method, the :path pseudo-header is forbidden.

      -

      ERR_HTTP2_CONNECT_SCHEME#

      +

      ERR_HTTP2_CONNECT_SCHEME#

      For HTTP/2 requests using the CONNECT method, the :scheme pseudo-header is forbidden.

      -

      ERR_HTTP2_ERROR#

      +

      ERR_HTTP2_ERROR#

      A non-specific HTTP/2 error has occurred.

      -

      ERR_HTTP2_GOAWAY_SESSION#

      +

      ERR_HTTP2_GOAWAY_SESSION#

      New HTTP/2 Streams may not be opened after the Http2Session has received a GOAWAY frame from the connected peer.

      +

      +

      ERR_HTTP2_HEADER_SINGLE_VALUE#

      +

      Multiple values were provided for an HTTP/2 header field that was required to +have only a single value.

      -

      ERR_HTTP2_HEADERS_AFTER_RESPOND#

      +

      ERR_HTTP2_HEADERS_AFTER_RESPOND#

      An additional headers was specified after an HTTP/2 response was initiated.

      -

      ERR_HTTP2_HEADERS_SENT#

      +

      ERR_HTTP2_HEADERS_SENT#

      An attempt was made to send multiple response headers.

      -

      -

      ERR_HTTP2_HEADER_SINGLE_VALUE#

      -

      Multiple values were provided for an HTTP/2 header field that was required to -have only a single value.

      -

      ERR_HTTP2_INFO_STATUS_NOT_ALLOWED#

      +

      ERR_HTTP2_INFO_STATUS_NOT_ALLOWED#

      Informational HTTP status codes (1xx) may not be set as the response status code on HTTP/2 responses.

      -

      ERR_HTTP2_INVALID_CONNECTION_HEADERS#

      +

      ERR_HTTP2_INVALID_CONNECTION_HEADERS#

      HTTP/1 connection specific headers are forbidden to be used in HTTP/2 requests and responses.

      -

      ERR_HTTP2_INVALID_HEADER_VALUE#

      +

      ERR_HTTP2_INVALID_HEADER_VALUE#

      An invalid HTTP/2 header value was specified.

      -

      ERR_HTTP2_INVALID_INFO_STATUS#

      +

      ERR_HTTP2_INVALID_INFO_STATUS#

      An invalid HTTP informational status code has been specified. Informational status codes must be an integer between 100 and 199 (inclusive).

      -

      ERR_HTTP2_INVALID_ORIGIN#

      +

      ERR_HTTP2_INVALID_ORIGIN#

      HTTP/2 ORIGIN frames require a valid origin.

      -

      ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH#

      +

      ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH#

      Input Buffer and Uint8Array instances passed to the http2.getUnpackedSettings() API must have a length that is a multiple of six.

      -

      ERR_HTTP2_INVALID_PSEUDOHEADER#

      +

      ERR_HTTP2_INVALID_PSEUDOHEADER#

      Only valid HTTP/2 pseudoheaders (:status, :path, :authority, :scheme, and :method) may be used.

      -

      ERR_HTTP2_INVALID_SESSION#

      +

      ERR_HTTP2_INVALID_SESSION#

      An action was performed on an Http2Session object that had already been destroyed.

      -

      ERR_HTTP2_INVALID_SETTING_VALUE#

      +

      ERR_HTTP2_INVALID_SETTING_VALUE#

      An invalid value has been specified for an HTTP/2 setting.

      -

      ERR_HTTP2_INVALID_STREAM#

      +

      ERR_HTTP2_INVALID_STREAM#

      An operation was performed on a stream that had already been destroyed.

      -

      ERR_HTTP2_MAX_PENDING_SETTINGS_ACK#

      +

      ERR_HTTP2_MAX_PENDING_SETTINGS_ACK#

      Whenever an HTTP/2 SETTINGS frame is sent to a connected peer, the peer is required to send an acknowledgment that it has received and applied the new SETTINGS. By default, a maximum number of unacknowledged SETTINGS frames may be sent at any given time. This error code is used when that limit has been reached.

      -

      ERR_HTTP2_NESTED_PUSH#

      +

      ERR_HTTP2_NESTED_PUSH#

      An attempt was made to initiate a new push stream from within a push stream. Nested push streams are not permitted.

      +

      +

      ERR_HTTP2_NO_MEM#

      +

      Out of memory when using the http2session.setLocalWindowSize(windowSize) API.

      -

      ERR_HTTP2_NO_SOCKET_MANIPULATION#

      +

      ERR_HTTP2_NO_SOCKET_MANIPULATION#

      An attempt was made to directly manipulate (read, write, pause, resume, etc.) a socket attached to an Http2Session.

      -

      ERR_HTTP2_ORIGIN_LENGTH#

      +

      ERR_HTTP2_ORIGIN_LENGTH#

      HTTP/2 ORIGIN frames are limited to a length of 16382 bytes.

      -

      ERR_HTTP2_OUT_OF_STREAMS#

      +

      ERR_HTTP2_OUT_OF_STREAMS#

      The number of streams created on a single HTTP/2 session reached the maximum limit.

      -

      ERR_HTTP2_PAYLOAD_FORBIDDEN#

      +

      ERR_HTTP2_PAYLOAD_FORBIDDEN#

      A message payload was specified for an HTTP response code for which a payload is forbidden.

      -

      ERR_HTTP2_PING_CANCEL#

      +

      ERR_HTTP2_PING_CANCEL#

      An HTTP/2 ping was canceled.

      -

      ERR_HTTP2_PING_LENGTH#

      +

      ERR_HTTP2_PING_LENGTH#

      HTTP/2 ping payloads must be exactly 8 bytes in length.

      -

      ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED#

      +

      ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED#

      An HTTP/2 pseudo-header has been used inappropriately. Pseudo-headers are header key names that begin with the : prefix.

      -

      ERR_HTTP2_PUSH_DISABLED#

      +

      ERR_HTTP2_PUSH_DISABLED#

      An attempt was made to create a push stream, which had been disabled by the client.

      -

      ERR_HTTP2_SEND_FILE#

      +

      ERR_HTTP2_SEND_FILE#

      An attempt was made to use the Http2Stream.prototype.responseWithFile() API to send a directory.

      -

      ERR_HTTP2_SEND_FILE_NOSEEK#

      +

      ERR_HTTP2_SEND_FILE_NOSEEK#

      An attempt was made to use the Http2Stream.prototype.responseWithFile() API to send something other than a regular file, but offset or length options were provided.

      -

      ERR_HTTP2_SESSION_ERROR#

      +

      ERR_HTTP2_SESSION_ERROR#

      The Http2Session closed with a non-zero error code.

      -

      ERR_HTTP2_SETTINGS_CANCEL#

      +

      ERR_HTTP2_SETTINGS_CANCEL#

      The Http2Session settings canceled.

      -

      ERR_HTTP2_SOCKET_BOUND#

      +

      ERR_HTTP2_SOCKET_BOUND#

      An attempt was made to connect a Http2Session object to a net.Socket or tls.TLSSocket that had already been bound to another Http2Session object.

      -

      ERR_HTTP2_SOCKET_UNBOUND#

      +

      ERR_HTTP2_SOCKET_UNBOUND#

      An attempt was made to use the socket property of an Http2Session that has already been closed.

      -

      ERR_HTTP2_STATUS_101#

      +

      ERR_HTTP2_STATUS_101#

      Use of the 101 Informational status code is forbidden in HTTP/2.

      -

      ERR_HTTP2_STATUS_INVALID#

      +

      ERR_HTTP2_STATUS_INVALID#

      An invalid HTTP status code has been specified. Status codes must be an integer between 100 and 599 (inclusive).

      -

      ERR_HTTP2_STREAM_CANCEL#

      +

      ERR_HTTP2_STREAM_CANCEL#

      An Http2Stream was destroyed before any data was transmitted to the connected peer.

      -

      ERR_HTTP2_STREAM_ERROR#

      +

      ERR_HTTP2_STREAM_ERROR#

      A non-zero error code was been specified in an RST_STREAM frame.

      -

      ERR_HTTP2_STREAM_SELF_DEPENDENCY#

      +

      ERR_HTTP2_STREAM_SELF_DEPENDENCY#

      When setting the priority for an HTTP/2 stream, the stream may be marked as a dependency for a parent stream. This error code is used when an attempt is made to mark a stream and dependent of itself.

      -

      ERR_HTTP2_TRAILERS_ALREADY_SENT#

      +

      ERR_HTTP2_TRAILERS_ALREADY_SENT#

      Trailing headers have already been sent on the Http2Stream.

      -

      ERR_HTTP2_TRAILERS_NOT_READY#

      +

      ERR_HTTP2_TRAILERS_NOT_READY#

      The http2stream.sendTrailers() method cannot be called until after the 'wantTrailers' event is emitted on an Http2Stream object. The 'wantTrailers' event will only be emitted if the waitForTrailers option is set for the Http2Stream.

      -

      ERR_HTTP2_UNSUPPORTED_PROTOCOL#

      +

      ERR_HTTP2_UNSUPPORTED_PROTOCOL#

      http2.connect() was passed a URL that uses any protocol other than http: or https:.

      -

      -

      ERR_INTERNAL_ASSERTION#

      -

      There was a bug in Node.js or incorrect usage of Node.js internals. -To fix the error, open an issue at https://github.com/nodejs/node/issues.

      -

      ERR_INCOMPATIBLE_OPTION_PAIR#

      +

      ERR_INCOMPATIBLE_OPTION_PAIR#

      An option pair is incompatible with each other and cannot be used at the same time.

      -

      ERR_INPUT_TYPE_NOT_ALLOWED#

      +

      ERR_INPUT_TYPE_NOT_ALLOWED#

      Stability: 1 - Experimental

      The --input-type flag was used to attempt to execute a file. This flag can only be used with input via --eval, --print or STDIN.

      -

      ERR_INSPECTOR_ALREADY_ACTIVATED#

      +

      ERR_INSPECTOR_ALREADY_ACTIVATED#

      While using the inspector module, an attempt was made to activate the inspector when it already started to listen on a port. Use inspector.close() before activating it on a different address.

      -

      ERR_INSPECTOR_ALREADY_CONNECTED#

      +

      ERR_INSPECTOR_ALREADY_CONNECTED#

      While using the inspector module, an attempt was made to connect when the inspector was already connected.

      -

      ERR_INSPECTOR_CLOSED#

      +

      ERR_INSPECTOR_CLOSED#

      While using the inspector module, an attempt was made to use the inspector after the session had already closed.

      -

      ERR_INSPECTOR_COMMAND#

      +

      ERR_INSPECTOR_COMMAND#

      An error occurred while issuing a command via the inspector module.

      -

      ERR_INSPECTOR_NOT_ACTIVE#

      +

      ERR_INSPECTOR_NOT_ACTIVE#

      The inspector is not active when inspector.waitForDebugger() is called.

      -

      ERR_INSPECTOR_NOT_AVAILABLE#

      +

      ERR_INSPECTOR_NOT_AVAILABLE#

      The inspector module is not available for use.

      -

      ERR_INSPECTOR_NOT_CONNECTED#

      +

      ERR_INSPECTOR_NOT_CONNECTED#

      While using the inspector module, an attempt was made to use the inspector before it was connected.

      -

      ERR_INSPECTOR_NOT_WORKER#

      +

      ERR_INSPECTOR_NOT_WORKER#

      An API was called on the main thread that can only be used from the worker thread.

      +

      +

      ERR_INTERNAL_ASSERTION#

      +

      There was a bug in Node.js or incorrect usage of Node.js internals. +To fix the error, open an issue at https://github.com/nodejs/node/issues.

      -

      ERR_INVALID_ADDRESS_FAMILY#

      +

      ERR_INVALID_ADDRESS_FAMILY#

      The provided address family is not understood by the Node.js API.

      -

      ERR_INVALID_ARG_TYPE#

      +

      ERR_INVALID_ARG_TYPE#

      An argument of the wrong type was passed to a Node.js API.

      -

      ERR_INVALID_ARG_VALUE#

      +

      ERR_INVALID_ARG_VALUE#

      An invalid or unsupported value was passed for a given argument.

      -

      ERR_INVALID_ASYNC_ID#

      +

      ERR_INVALID_ASYNC_ID#

      An invalid asyncId or triggerAsyncId was passed using AsyncHooks. An id less than -1 should never happen.

      -

      ERR_INVALID_BUFFER_SIZE#

      +

      ERR_INVALID_BUFFER_SIZE#

      A swap was performed on a Buffer but its size was not compatible with the operation.

      -

      ERR_INVALID_CALLBACK#

      +

      ERR_INVALID_CALLBACK#

      A callback function was required but was not been provided to a Node.js API.

      -

      ERR_INVALID_CHAR#

      +

      ERR_INVALID_CHAR#

      Invalid characters were detected in headers.

      -

      ERR_INVALID_CURSOR_POS#

      +

      ERR_INVALID_CURSOR_POS#

      A cursor on a given stream cannot be moved to a specified row without a specified column.

      -

      ERR_INVALID_FD#

      +

      ERR_INVALID_FD#

      A file descriptor ('fd') was not valid (e.g. it was a negative value).

      -

      ERR_INVALID_FD_TYPE#

      +

      ERR_INVALID_FD_TYPE#

      A file descriptor ('fd') type was not valid.

      -

      ERR_INVALID_FILE_URL_HOST#

      +

      ERR_INVALID_FILE_URL_HOST#

      A Node.js API that consumes file: URLs (such as certain functions in the fs module) encountered a file URL with an incompatible host. This situation can only occur on Unix-like systems where only localhost or an empty host is supported.

      -

      ERR_INVALID_FILE_URL_PATH#

      +

      ERR_INVALID_FILE_URL_PATH#

      A Node.js API that consumes file: URLs (such as certain functions in the fs module) encountered a file URL with an incompatible path. The exact semantics for determining whether a path can be used is platform-dependent.

      -

      ERR_INVALID_HANDLE_TYPE#

      +

      ERR_INVALID_HANDLE_TYPE#

      An attempt was made to send an unsupported "handle" over an IPC communication channel to a child process. See subprocess.send() and process.send() for more information.

      -

      ERR_INVALID_HTTP_TOKEN#

      +

      ERR_INVALID_HTTP_TOKEN#

      An invalid HTTP token was supplied.

      -

      ERR_INVALID_IP_ADDRESS#

      +

      ERR_INVALID_IP_ADDRESS#

      An IP address is not valid.

      +

      +

      ERR_INVALID_MODULE#

      + +

      An attempt was made to load a module that does not exist or was otherwise not +valid.

      -

      ERR_INVALID_MODULE_SPECIFIER#

      +

      ERR_INVALID_MODULE_SPECIFIER#

      The imported module string is an invalid URL, package name, or package subpath specifier.

      -

      ERR_INVALID_OPT_VALUE#

      +

      ERR_INVALID_OPT_VALUE#

      An invalid or unexpected value was passed in an options object.

      -

      ERR_INVALID_OPT_VALUE_ENCODING#

      +

      ERR_INVALID_OPT_VALUE_ENCODING#

      An invalid or unknown file encoding was passed.

      -

      ERR_INVALID_PACKAGE_CONFIG#

      +

      ERR_INVALID_PACKAGE_CONFIG#

      An invalid package.json file was found which failed parsing.

      -

      ERR_INVALID_PACKAGE_TARGET#

      +

      ERR_INVALID_PACKAGE_TARGET#

      The package.json "exports" field contains an invalid target mapping value for the attempted module resolution.

      -

      ERR_INVALID_PERFORMANCE_MARK#

      +

      ERR_INVALID_PERFORMANCE_MARK#

      While using the Performance Timing API (perf_hooks), a performance mark is invalid.

      -

      ERR_INVALID_PROTOCOL#

      +

      ERR_INVALID_PROTOCOL#

      An invalid options.protocol was passed to http.request().

      -

      ERR_INVALID_REPL_EVAL_CONFIG#

      +

      ERR_INVALID_REPL_EVAL_CONFIG#

      Both breakEvalOnSigint and eval options were set in the REPL config, which is not supported.

      -

      ERR_INVALID_REPL_INPUT#

      -

      The input may not be used in the REPL. All prohibited inputs are -documented in the REPL's documentation.

      +

      ERR_INVALID_REPL_INPUT#

      +

      The input may not be used in the REPL. The conditions under which this +error is used are described in the REPL documentation.

      -

      ERR_INVALID_RETURN_PROPERTY#

      +

      ERR_INVALID_RETURN_PROPERTY#

      Thrown in case a function option does not provide a valid value for one of its returned object properties on execution.

      -

      ERR_INVALID_RETURN_PROPERTY_VALUE#

      +

      ERR_INVALID_RETURN_PROPERTY_VALUE#

      Thrown in case a function option does not provide an expected value type for one of its returned object properties on execution.

      -

      ERR_INVALID_RETURN_VALUE#

      +

      ERR_INVALID_RETURN_VALUE#

      Thrown in case a function option does not return an expected value type on execution, such as when a function is expected to return a promise.

      -

      ERR_INVALID_SYNC_FORK_INPUT#

      +

      ERR_INVALID_SYNC_FORK_INPUT#

      A Buffer, TypedArray, DataView or string was provided as stdio input to an asynchronous fork. See the documentation for the child_process module for more information.

      -

      ERR_INVALID_THIS#

      +

      ERR_INVALID_THIS#

      A Node.js API function was called with an incompatible this value.

      -
      const urlSearchParams = new URLSearchParams('foo=bar&baz=new');
      +
      const urlSearchParams = new URLSearchParams('foo=bar&baz=new');
       
      -const buf = Buffer.alloc(1);
      -urlSearchParams.has.call(buf, 'foo');
      +const buf = Buffer.alloc(1);
      +urlSearchParams.has.call(buf, 'foo');
       // Throws a TypeError with code 'ERR_INVALID_THIS'

      -

      ERR_INVALID_TRANSFER_OBJECT#

      +

      ERR_INVALID_TRANSFER_OBJECT#

      An invalid transfer object was passed to postMessage().

      -

      ERR_INVALID_TUPLE#

      +

      ERR_INVALID_TUPLE#

      An element in the iterable provided to the WHATWG URLSearchParams constructor did not represent a [name, value] tuple – that is, if an element is not iterable, or does not consist of exactly two elements.

      -

      ERR_INVALID_URI#

      +

      ERR_INVALID_URI#

      An invalid URI was passed.

      -

      ERR_INVALID_URL#

      +

      ERR_INVALID_URL#

      An invalid URL was passed to the WHATWG URL constructor to be parsed. The thrown error object typically has an additional property 'input' that contains the URL that failed to parse.

      -

      ERR_INVALID_URL_SCHEME#

      +

      ERR_INVALID_URL_SCHEME#

      An attempt was made to use a URL of an incompatible scheme (protocol) for a specific purpose. It is only used in the WHATWG URL API support in the fs module (which only accepts URLs with 'file' scheme), but may be used in other Node.js APIs as well in the future.

      -

      ERR_IPC_CHANNEL_CLOSED#

      +

      ERR_IPC_CHANNEL_CLOSED#

      An attempt was made to use an IPC communication channel that was already closed.

      -

      ERR_IPC_DISCONNECTED#

      +

      ERR_IPC_DISCONNECTED#

      An attempt was made to disconnect an IPC communication channel that was already disconnected. See the documentation for the child_process module for more information.

      -

      ERR_IPC_ONE_PIPE#

      +

      ERR_IPC_ONE_PIPE#

      An attempt was made to create a child Node.js process using more than one IPC communication channel. See the documentation for the child_process module for more information.

      -

      ERR_IPC_SYNC_FORK#

      +

      ERR_IPC_SYNC_FORK#

      An attempt was made to open an IPC communication channel with a synchronously forked Node.js process. See the documentation for the child_process module for more information.

      -

      ERR_MANIFEST_ASSERT_INTEGRITY#

      +

      ERR_MANIFEST_ASSERT_INTEGRITY#

      An attempt was made to load a resource, but the resource did not match the integrity defined by the policy manifest. See the documentation for policy manifests for more information.

      -

      ERR_MANIFEST_DEPENDENCY_MISSING#

      +

      ERR_MANIFEST_DEPENDENCY_MISSING#

      An attempt was made to load a resource, but the resource was not listed as a dependency from the location that attempted to load it. See the documentation for policy manifests for more information.

      -

      ERR_MANIFEST_INTEGRITY_MISMATCH#

      +

      ERR_MANIFEST_INTEGRITY_MISMATCH#

      An attempt was made to load a policy manifest, but the manifest had multiple entries for a resource which did not match each other. Update the manifest entries to match in order to resolve this error. See the documentation for policy manifests for more information.

      -

      ERR_MANIFEST_INVALID_RESOURCE_FIELD#

      +

      ERR_MANIFEST_INVALID_RESOURCE_FIELD#

      A policy manifest resource had an invalid value for one of its fields. Update the manifest entry to match in order to resolve this error. See the documentation for policy manifests for more information.

      +

      +

      ERR_MANIFEST_INVALID_SPECIFIER#

      +

      A policy manifest resource had an invalid value for one of its dependency +mappings. Update the manifest entry to match to resolve this error. See the +documentation for policy manifests for more information.

      -

      ERR_MANIFEST_PARSE_POLICY#

      +

      ERR_MANIFEST_PARSE_POLICY#

      An attempt was made to load a policy manifest, but the manifest was unable to be parsed. See the documentation for policy manifests for more information.

      -

      ERR_MANIFEST_TDZ#

      +

      ERR_MANIFEST_TDZ#

      An attempt was made to read from a policy manifest, but the manifest initialization has not yet taken place. This is likely a bug in Node.js.

      -

      ERR_MANIFEST_UNKNOWN_ONERROR#

      +

      ERR_MANIFEST_UNKNOWN_ONERROR#

      A policy manifest was loaded, but had an unknown value for its "onerror" behavior. See the documentation for policy manifests for more information.

      -

      ERR_MEMORY_ALLOCATION_FAILED#

      +

      ERR_MEMORY_ALLOCATION_FAILED#

      An attempt was made to allocate memory (usually in the C++ layer) but it failed.

      -

      ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE#

      +

      ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE#

      A message posted to a MessagePort could not be deserialized in the target vm Context. Not all Node.js objects can be successfully instantiated in any context at this time, and attempting to transfer them using postMessage() can fail on the receiving side in that case.

      -

      ERR_METHOD_NOT_IMPLEMENTED#

      +

      ERR_METHOD_NOT_IMPLEMENTED#

      A method is required but not implemented.

      -

      ERR_MISSING_ARGS#

      +

      ERR_MISSING_ARGS#

      A required argument of a Node.js API was not passed. This is only used for strict compliance with the API specification (which in some cases may accept func(undefined) but not func()). In most native Node.js APIs, func(undefined) and func() are treated identically, and the ERR_INVALID_ARG_TYPE error code may be used instead.

      -

      -

      ERR_MISSING_DYNAMIC_INSTANTIATE_HOOK#

      -

      Stability: 1 - Experimental

      -

      An ES Module loader hook specified format: 'dynamic' but did not provide -a dynamicInstantiate hook.

      +

      +

      ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST#

      +

      An object that needs to be explicitly listed in the transferList argument +is in the object passed to a postMessage() call, but is not provided +in the transferList for that call. Usually, this is a MessagePort.

      -

      ERR_MISSING_OPTION#

      +

      ERR_MISSING_OPTION#

      For APIs that accept options objects, some options might be mandatory. This code is thrown if a required option is missing.

      -

      -

      ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST#

      -

      An object that needs to be explicitly listed in the transferList argument -was found in the object passed to a postMessage() call, but not provided in -the transferList for that call. Usually, this is a MessagePort.

      -

      ERR_MISSING_PASSPHRASE#

      +

      ERR_MISSING_PASSPHRASE#

      An attempt was made to read an encrypted key without specifying a passphrase.

      -

      ERR_MISSING_PLATFORM_FOR_WORKER#

      +

      ERR_MISSING_PLATFORM_FOR_WORKER#

      The V8 platform used by this instance of Node.js does not support creating Workers. This is caused by lack of embedder support for Workers. In particular, this error will not occur with standard builds of Node.js.

      -

      ERR_MODULE_NOT_FOUND#

      +

      ERR_MODULE_NOT_FOUND#

      Stability: 1 - Experimental

      An ES Module could not be resolved.

      -

      ERR_MULTIPLE_CALLBACK#

      +

      ERR_MULTIPLE_CALLBACK#

      A callback was called more than once.

      A callback is almost always meant to only be called once as the query can either be fulfilled or rejected but not both at the same time. The latter would be possible by calling a callback more than once.

      -

      ERR_NAPI_CONS_FUNCTION#

      -

      While using N-API, a constructor passed was not a function.

      +

      ERR_NAPI_CONS_FUNCTION#

      +

      While using Node-API, a constructor passed was not a function.

      -

      ERR_NAPI_INVALID_DATAVIEW_ARGS#

      +

      ERR_NAPI_INVALID_DATAVIEW_ARGS#

      While calling napi_create_dataview(), a given offset was outside the bounds of the dataview or offset + length was larger than a length of given buffer.

      -

      ERR_NAPI_INVALID_TYPEDARRAY_ALIGNMENT#

      +

      ERR_NAPI_INVALID_TYPEDARRAY_ALIGNMENT#

      While calling napi_create_typedarray(), the provided offset was not a multiple of the element size.

      -

      ERR_NAPI_INVALID_TYPEDARRAY_LENGTH#

      +

      ERR_NAPI_INVALID_TYPEDARRAY_LENGTH#

      While calling napi_create_typedarray(), (length * size_of_element) + byte_offset was larger than the length of given buffer.

      -

      ERR_NAPI_TSFN_CALL_JS#

      +

      ERR_NAPI_TSFN_CALL_JS#

      An error occurred while invoking the JavaScript portion of the thread-safe function.

      -

      ERR_NAPI_TSFN_GET_UNDEFINED#

      +

      ERR_NAPI_TSFN_GET_UNDEFINED#

      An error occurred while attempting to retrieve the JavaScript undefined value.

      -

      ERR_NAPI_TSFN_START_IDLE_LOOP#

      +

      ERR_NAPI_TSFN_START_IDLE_LOOP#

      On the main thread, values are removed from the queue associated with the thread-safe function in an idle loop. This error indicates that an error has occurred when attempting to start the loop.

      -

      ERR_NAPI_TSFN_STOP_IDLE_LOOP#

      +

      ERR_NAPI_TSFN_STOP_IDLE_LOOP#

      Once no more items are left in the queue, the idle loop must be suspended. This error indicates that the idle loop has failed to stop.

      -

      ERR_NO_CRYPTO#

      +

      ERR_NO_CRYPTO#

      An attempt was made to use crypto features while Node.js was not compiled with OpenSSL crypto support.

      -

      ERR_NO_ICU#

      +

      ERR_NO_ICU#

      An attempt was made to use features that require ICU, but Node.js was not compiled with ICU support.

      -

      ERR_NON_CONTEXT_AWARE_DISABLED#

      +

      ERR_NON_CONTEXT_AWARE_DISABLED#

      A non-context-aware native addon was loaded in a process that disallows them.

      +

      +

      ERR_OPERATION_FAILED#

      +

      An operation failed. This is typically used to signal the general failure of an +asynchronous operation.

      -

      ERR_OUT_OF_RANGE#

      +

      ERR_OUT_OF_RANGE#

      A given value is out of the accepted range.

      -

      ERR_PACKAGE_IMPORT_NOT_DEFINED#

      +

      ERR_PACKAGE_IMPORT_NOT_DEFINED#

      The package.json "imports" field does not define the given internal package specifier mapping.

      -

      ERR_PACKAGE_PATH_NOT_EXPORTED#

      +

      ERR_PACKAGE_PATH_NOT_EXPORTED#

      The package.json "exports" field does not export the requested subpath. Because exports are encapsulated, private internal modules that are not exported cannot be imported through the package resolution, unless using an absolute URL.

      -

      ERR_PROTO_ACCESS#

      +

      ERR_PROTO_ACCESS#

      Accessing Object.prototype.__proto__ has been forbidden using --disable-proto=throw. Object.getPrototypeOf and Object.setPrototypeOf should be used to get and set the prototype of an object.

      -

      ERR_REQUIRE_ESM#

      +

      ERR_REQUIRE_ESM#

      Stability: 1 - Experimental

      An attempt was made to require() an ES Module.

      -

      ERR_SCRIPT_EXECUTION_INTERRUPTED#

      +

      ERR_SCRIPT_EXECUTION_INTERRUPTED#

      Script execution was interrupted by SIGINT (For example, Ctrl+C was pressed.)

      -

      ERR_SCRIPT_EXECUTION_TIMEOUT#

      +

      ERR_SCRIPT_EXECUTION_TIMEOUT#

      Script execution timed out, possibly due to bugs in the script being executed.

      -

      ERR_SERVER_ALREADY_LISTEN#

      +

      ERR_SERVER_ALREADY_LISTEN#

      The server.listen() method was called while a net.Server was already listening. This applies to all instances of net.Server, including HTTP, HTTPS, and HTTP/2 Server instances.

      -

      ERR_SERVER_NOT_RUNNING#

      +

      ERR_SERVER_NOT_RUNNING#

      The server.close() method was called when a net.Server was not running. This applies to all instances of net.Server, including HTTP, HTTPS, and HTTP/2 Server instances.

      -

      ERR_SOCKET_ALREADY_BOUND#

      +

      ERR_SOCKET_ALREADY_BOUND#

      An attempt was made to bind a socket that has already been bound.

      -

      ERR_SOCKET_BAD_BUFFER_SIZE#

      +

      ERR_SOCKET_BAD_BUFFER_SIZE#

      An invalid (negative) size was passed for either the recvBufferSize or sendBufferSize options in dgram.createSocket().

      -

      ERR_SOCKET_BAD_PORT#

      +

      ERR_SOCKET_BAD_PORT#

      An API function expecting a port >= 0 and < 65536 received an invalid value.

      -

      ERR_SOCKET_BAD_TYPE#

      +

      ERR_SOCKET_BAD_TYPE#

      An API function expecting a socket type (udp4 or udp6) received an invalid value.

      -

      ERR_SOCKET_BUFFER_SIZE#

      +

      ERR_SOCKET_BUFFER_SIZE#

      While using dgram.createSocket(), the size of the receive or send Buffer could not be determined.

      -

      -

      ERR_SOCKET_CANNOT_SEND#

      -

      Data could be sent on a socket.

      -

      ERR_SOCKET_CLOSED#

      +

      ERR_SOCKET_CLOSED#

      An attempt was made to operate on an already closed socket.

      -

      ERR_SOCKET_DGRAM_IS_CONNECTED#

      +

      ERR_SOCKET_DGRAM_IS_CONNECTED#

      A dgram.connect() call was made on an already connected socket.

      -

      ERR_SOCKET_DGRAM_NOT_CONNECTED#

      +

      ERR_SOCKET_DGRAM_NOT_CONNECTED#

      A dgram.disconnect() or dgram.remoteAddress() call was made on a disconnected socket.

      -

      ERR_SOCKET_DGRAM_NOT_RUNNING#

      +

      ERR_SOCKET_DGRAM_NOT_RUNNING#

      A call was made and the UDP subsystem was not running.

      -

      ERR_SRI_PARSE#

      +

      ERR_SRI_PARSE#

      A string was provided for a Subresource Integrity check, but was unable to be parsed. Check the format of integrity attributes by looking at the Subresource Integrity specification.

      +

      +

      ERR_STREAM_ALREADY_FINISHED#

      +

      A stream method was called that cannot complete because the stream was +finished.

      -

      ERR_STREAM_CANNOT_PIPE#

      +

      ERR_STREAM_CANNOT_PIPE#

      An attempt was made to call stream.pipe() on a Writable stream.

      -

      ERR_STREAM_DESTROYED#

      +

      ERR_STREAM_DESTROYED#

      A stream method was called that cannot complete because the stream was destroyed using stream.destroy().

      -

      ERR_STREAM_NULL_VALUES#

      +

      ERR_STREAM_NULL_VALUES#

      An attempt was made to call stream.write() with a null chunk.

      -

      ERR_STREAM_PREMATURE_CLOSE#

      +

      ERR_STREAM_PREMATURE_CLOSE#

      An error returned by stream.finished() and stream.pipeline(), when a stream or a pipeline ends non gracefully with no explicit error.

      -

      ERR_STREAM_PUSH_AFTER_EOF#

      +

      ERR_STREAM_PUSH_AFTER_EOF#

      An attempt was made to call stream.push() after a null(EOF) had been pushed to the stream.

      -

      ERR_STREAM_UNSHIFT_AFTER_END_EVENT#

      +

      ERR_STREAM_UNSHIFT_AFTER_END_EVENT#

      An attempt was made to call stream.unshift() after the 'end' event was emitted.

      -

      ERR_STREAM_WRAP#

      +

      ERR_STREAM_WRAP#

      Prevents an abort if a string decoder was set on the Socket or if the decoder is in objectMode.

      -
      const Socket = require('net').Socket;
      -const instance = new Socket();
      +
      const Socket = require('net').Socket;
      +const instance = new Socket();
       
      -instance.setEncoding('utf8');
      +instance.setEncoding('utf8');

      -

      ERR_STREAM_WRITE_AFTER_END#

      +

      ERR_STREAM_WRITE_AFTER_END#

      An attempt was made to call stream.write() after stream.end() has been called.

      -

      ERR_STRING_TOO_LONG#

      +

      ERR_STRING_TOO_LONG#

      An attempt has been made to create a string longer than the maximum allowed length.

      -

      ERR_SYNTHETIC#

      +

      ERR_SYNTHETIC#

      An artificial error object used to capture the call stack for diagnostic reports.

      -

      ERR_SYSTEM_ERROR#

      +

      ERR_SYSTEM_ERROR#

      An unspecified or non-specific system error has occurred within the Node.js process. The error object will have an err.info object property with additional details.

      +

      +

      ERR_TLS_CERT_ALTNAME_FORMAT#

      +

      This error is thrown by checkServerIdentity if a user-supplied +subjectaltname property violates encoding rules. Certificate objects produced +by Node.js itself always comply with encoding rules and will never cause +this error.

      -

      ERR_TLS_CERT_ALTNAME_INVALID#

      +

      ERR_TLS_CERT_ALTNAME_INVALID#

      While using TLS, the host name/IP of the peer did not match any of the subjectAltNames in its certificate.

      -

      ERR_TLS_DH_PARAM_SIZE#

      +

      ERR_TLS_DH_PARAM_SIZE#

      While using TLS, the parameter offered for the Diffie-Hellman (DH) key-agreement protocol is too small. By default, the key length must be greater than or equal to 1024 bits to avoid vulnerabilities, even though it is strongly recommended to use 2048 bits or larger for stronger security.

      -

      ERR_TLS_HANDSHAKE_TIMEOUT#

      +

      ERR_TLS_HANDSHAKE_TIMEOUT#

      A TLS/SSL handshake timed out. In this case, the server must also abort the connection.

      -

      ERR_TLS_INVALID_CONTEXT#

      +

      ERR_TLS_INVALID_CONTEXT#

      The context must be a SecureContext.

      -

      -

      ERR_TLS_INVALID_STATE#

      - -

      The TLS socket must be connected and securily established. Ensure the 'secure' -event is emitted before continuing.

      -

      ERR_TLS_INVALID_PROTOCOL_METHOD#

      +

      ERR_TLS_INVALID_PROTOCOL_METHOD#

      The specified secureProtocol method is invalid. It is either unknown, or disabled because it is insecure.

      -

      ERR_TLS_INVALID_PROTOCOL_VERSION#

      +

      ERR_TLS_INVALID_PROTOCOL_VERSION#

      Valid TLS protocol versions are 'TLSv1', 'TLSv1.1', or 'TLSv1.2'.

      +

      +

      ERR_TLS_INVALID_STATE#

      + +

      The TLS socket must be connected and securily established. Ensure the 'secure' +event is emitted before continuing.

      -

      ERR_TLS_PROTOCOL_VERSION_CONFLICT#

      +

      ERR_TLS_PROTOCOL_VERSION_CONFLICT#

      Attempting to set a TLS protocol minVersion or maxVersion conflicts with an attempt to set the secureProtocol explicitly. Use one mechanism or the other.

      +

      +

      ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED#

      +

      Failed to set PSK identity hint. Hint may be too long.

      -

      ERR_TLS_RENEGOTIATION_DISABLED#

      +

      ERR_TLS_RENEGOTIATION_DISABLED#

      An attempt was made to renegotiate TLS on a socket instance with TLS disabled.

      -

      ERR_TLS_REQUIRED_SERVER_NAME#

      +

      ERR_TLS_REQUIRED_SERVER_NAME#

      While using TLS, the server.addContext() method was called without providing a host name in the first parameter.

      -

      ERR_TLS_SESSION_ATTACK#

      +

      ERR_TLS_SESSION_ATTACK#

      An excessive amount of TLS renegotiations is detected, which is a potential vector for denial-of-service attacks.

      -

      ERR_TLS_SNI_FROM_SERVER#

      +

      ERR_TLS_SNI_FROM_SERVER#

      An attempt was made to issue Server Name Indication from a TLS server-side socket, which is only valid from a client.

      -

      -

      ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED#

      -

      Failed to set PSK identity hint. Hint may be too long.

      -

      ERR_TRACE_EVENTS_CATEGORY_REQUIRED#

      +

      ERR_TRACE_EVENTS_CATEGORY_REQUIRED#

      The trace_events.createTracing() method requires at least one trace event category.

      -

      ERR_TRACE_EVENTS_UNAVAILABLE#

      +

      ERR_TRACE_EVENTS_UNAVAILABLE#

      The trace_events module could not be loaded because Node.js was compiled with the --without-v8-platform flag.

      -

      -

      ERR_TRANSFERRING_EXTERNALIZED_SHAREDARRAYBUFFER#

      -

      A SharedArrayBuffer whose memory is not managed by the JavaScript engine -or by Node.js was encountered during serialization. Such a SharedArrayBuffer -cannot be serialized.

      -

      This can only happen when native addons create SharedArrayBuffers in -"externalized" mode, or put existing SharedArrayBuffer into externalized mode.

      -

      ERR_TRANSFORM_ALREADY_TRANSFORMING#

      +

      ERR_TRANSFORM_ALREADY_TRANSFORMING#

      A Transform stream finished while it was still transforming.

      -

      ERR_TRANSFORM_WITH_LENGTH_0#

      +

      ERR_TRANSFORM_WITH_LENGTH_0#

      A Transform stream finished with data still in the write buffer.

      -

      ERR_TTY_INIT_FAILED#

      +

      ERR_TTY_INIT_FAILED#

      The initialization of a TTY failed due to a system error.

      -

      ERR_UNAVAILABLE_DURING_EXIT#

      -

      Function was called within a process.on('exit') handler that shouldn't be -called within process.on('exit') handler.

      +

      ERR_UNAVAILABLE_DURING_EXIT#

      +

      Function was called within a process.on('exit') handler that shouldn't be +called within process.on('exit') handler.

      -

      ERR_UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SET#

      +

      ERR_UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SET#

      process.setUncaughtExceptionCaptureCallback() was called twice, without first resetting the callback to null.

      This error is designed to prevent accidentally overwriting a callback registered from another module.

      -

      ERR_UNESCAPED_CHARACTERS#

      +

      ERR_UNESCAPED_CHARACTERS#

      A string that contained unescaped characters was received.

      -

      ERR_UNHANDLED_ERROR#

      +

      ERR_UNHANDLED_ERROR#

      An unhandled error occurred (for instance, when an 'error' event is emitted by an EventEmitter but an 'error' handler is not registered).

      -

      ERR_UNKNOWN_BUILTIN_MODULE#

      +

      ERR_UNKNOWN_BUILTIN_MODULE#

      Used to identify a specific kind of internal Node.js error that should not typically be triggered by user code. Instances of this error point to an internal bug within the Node.js binary itself.

      -

      ERR_UNKNOWN_CREDENTIAL#

      +

      ERR_UNKNOWN_CREDENTIAL#

      A Unix group or user identifier that does not exist was passed.

      -

      ERR_UNKNOWN_ENCODING#

      +

      ERR_UNKNOWN_ENCODING#

      An invalid or unknown encoding option was passed to an API.

      -

      ERR_UNKNOWN_FILE_EXTENSION#

      +

      ERR_UNKNOWN_FILE_EXTENSION#

      Stability: 1 - Experimental

      An attempt was made to load a module with an unknown or unsupported file extension.

      -

      ERR_UNKNOWN_MODULE_FORMAT#

      +

      ERR_UNKNOWN_MODULE_FORMAT#

      Stability: 1 - Experimental

      An attempt was made to load a module with an unknown or unsupported format.

      -

      ERR_UNKNOWN_SIGNAL#

      +

      ERR_UNKNOWN_SIGNAL#

      An invalid or unknown process signal was passed to an API expecting a valid signal (such as subprocess.kill()).

      -

      ERR_UNSUPPORTED_DIR_IMPORT#

      +

      ERR_UNSUPPORTED_DIR_IMPORT#

      import a directory URL is unsupported. Instead, self-reference a package using its name and define a custom subpath in the "exports" field of the package.json file.

      @@ -1947,17 +2051,17 @@ the "exports" field of import './index.js'; // supported import 'package-name'; // supported

      -

      ERR_UNSUPPORTED_ESM_URL_SCHEME#

      +

      ERR_UNSUPPORTED_ESM_URL_SCHEME#

      import with URL schemes other than file and data is unsupported.

      -

      ERR_VALID_PERFORMANCE_ENTRY_TYPE#

      +

      ERR_VALID_PERFORMANCE_ENTRY_TYPE#

      While using the Performance Timing API (perf_hooks), no valid performance -entry types were found.

      +entry types are found.

      -

      ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING#

      +

      ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING#

      A dynamic import callback was not specified.

      -

      ERR_VM_MODULE_ALREADY_LINKED#

      +

      ERR_VM_MODULE_ALREADY_LINKED#

      The module attempted to be linked is not eligible for linking, because of one of the following reasons:

        @@ -1966,68 +2070,71 @@ the following reasons:

      • Linking has failed for this module (linkingStatus is 'errored')

      -

      ERR_VM_MODULE_CACHED_DATA_REJECTED#

      +

      ERR_VM_MODULE_CACHED_DATA_REJECTED#

      The cachedData option passed to a module constructor is invalid.

      -

      ERR_VM_MODULE_CANNOT_CREATE_CACHED_DATA#

      +

      ERR_VM_MODULE_CANNOT_CREATE_CACHED_DATA#

      Cached data cannot be created for modules which have already been evaluated.

      -

      ERR_VM_MODULE_DIFFERENT_CONTEXT#

      +

      ERR_VM_MODULE_DIFFERENT_CONTEXT#

      The module being returned from the linker function is from a different context than the parent module. Linked modules must share the same context.

      -

      ERR_VM_MODULE_LINKING_ERRORED#

      +

      ERR_VM_MODULE_LINKING_ERRORED#

      The linker function returned a module for which linking has failed.

      +

      +

      ERR_VM_MODULE_LINK_FAILURE#

      +

      The module was unable to be linked due to a failure.

      -

      ERR_VM_MODULE_NOT_MODULE#

      +

      ERR_VM_MODULE_NOT_MODULE#

      The fulfilled value of a linking promise is not a vm.Module object.

      -

      ERR_VM_MODULE_STATUS#

      +

      ERR_VM_MODULE_STATUS#

      The current module's status does not allow for this operation. The specific meaning of the error depends on the specific function.

      -

      ERR_WASI_ALREADY_STARTED#

      +

      ERR_WASI_ALREADY_STARTED#

      The WASI instance has already started.

      -

      ERR_WASI_NOT_STARTED#

      +

      ERR_WASI_NOT_STARTED#

      The WASI instance has not been started.

      -

      ERR_WORKER_INIT_FAILED#

      +

      ERR_WORKER_INIT_FAILED#

      The Worker initialization failed.

      -

      ERR_WORKER_INVALID_EXEC_ARGV#

      +

      ERR_WORKER_INVALID_EXEC_ARGV#

      The execArgv option passed to the Worker constructor contains invalid flags.

      -

      ERR_WORKER_NOT_RUNNING#

      +

      ERR_WORKER_NOT_RUNNING#

      An operation failed because the Worker instance is not currently running.

      -

      ERR_WORKER_OUT_OF_MEMORY#

      +

      ERR_WORKER_OUT_OF_MEMORY#

      The Worker instance terminated because it reached its memory limit.

      -

      ERR_WORKER_PATH#

      +

      ERR_WORKER_PATH#

      The path for the main script of a worker is neither an absolute path nor a relative path starting with ./ or ../.

      -

      ERR_WORKER_UNSERIALIZABLE_ERROR#

      +

      ERR_WORKER_UNSERIALIZABLE_ERROR#

      All attempts at serializing an uncaught exception from a worker thread failed.

      -

      ERR_WORKER_UNSUPPORTED_EXTENSION#

      +

      ERR_WORKER_UNSUPPORTED_EXTENSION#

      The pathname used for the main script of a worker has an unknown file extension.

      -

      ERR_WORKER_UNSUPPORTED_OPERATION#

      +

      ERR_WORKER_UNSUPPORTED_OPERATION#

      The requested functionality is not supported in worker threads.

      -

      ERR_ZLIB_INITIALIZATION_FAILED#

      +

      ERR_ZLIB_INITIALIZATION_FAILED#

      Creation of a zlib object failed due to incorrect configuration.

      -

      HPE_HEADER_OVERFLOW#

      +

      HPE_HEADER_OVERFLOW#

      Builtin modules#

      +

      Core modules provide named exports of their public API. A +default export is also provided which is the value of the CommonJS exports. +The default export can be used for, among other things, modifying the named +exports. Named exports of builtin modules are updated only by calling +module.syncBuiltinESMExports().

      +
      import EventEmitter from 'events';
      +const e = new EventEmitter();
      +
      import { readFile } from 'fs';
      +readFile('./foo.txt', (err, source) => {
      +  if (err) {
      +    console.error(err);
      +  } else {
      +    console.log(source);
      +  }
      +});
      +
      import fs, { readFileSync } from 'fs';
      +import { syncBuiltinESMExports } from 'module';
      +
      +fs.readFileSync = () => Buffer.from('Hello, ESM');
      +syncBuiltinESMExports();
      +
      +fs.readFileSync === readFileSync;
      +

      import() expressions#

      +

      Dynamic import() is supported in both CommonJS and ES modules. In CommonJS +modules it can be used to load ES modules.

      +

      import.meta#

      -

      The import.meta metaproperty is an Object that contains the following -property:

      +

      The import.meta meta property is an Object that contains the following +properties.

      +

      import.meta.url#

        -
      • url <string> The absolute file: URL of the module.
      • +
      • <string> The absolute file: URL of the module.
      -

      Differences between ES modules and CommonJS#

      -

      Mandatory file extensions#

      -

      A file extension must be provided when using the import keyword. Directory -indexes (e.g. './startup/index.js') must also be fully specified.

      -

      This behavior matches how import behaves in browser environments, assuming a -typically configured server.

      -

      No NODE_PATH#

      -

      NODE_PATH is not part of resolving import specifiers. Please use symlinks -if this behavior is desired.

      -

      No require, exports, module.exports, __filename, __dirname#

      -

      These CommonJS variables are not available in ES modules.

      -

      require can be imported into an ES module using module.createRequire().

      -

      Equivalents of __filename and __dirname can be created inside of each file -via import.meta.url.

      -
      import { fileURLToPath } from 'url';
      -import { dirname } from 'path';
      -
      -const __filename = fileURLToPath(import.meta.url);
      -const __dirname = dirname(__filename);
      -

      No require.resolve#

      -

      Former use cases relying on require.resolve to determine the resolved path -of a module can be supported via import.meta.resolve, which is experimental -and supported via the --experimental-import-meta-resolve flag:

      -
      (async () => {
      -  const dependencyAsset = await import.meta.resolve('component-lib/asset.css');
      -})();
      +

      This is defined exactly the same as it is in browsers providing the URL of the +current module file.

      +

      This enables useful patterns such as relative file loading:

      +
      import { readFileSync } from 'fs';
      +const buffer = readFileSync(new URL('./data.proto', import.meta.url));
      +

      import.meta.resolve(specifier[, parent])#

      + +

      Stability: 1 - Experimental

      +

      This feature is only available with the --experimental-import-meta-resolve +command flag enabled.

      +
        +
      • specifier <string> The module specifier to resolve relative to parent.
      • +
      • parent <string> The absolute parent module URL to resolve from. If none +is specified, the value of import.meta.url is used as the default.
      • +
      • Returns: <Promise>
      • +
      +

      Provides a module-relative resolution function scoped to each module, returning +the URL string.

      + +
      const dependencyAsset = await import.meta.resolve('component-lib/asset.css');

      import.meta.resolve also accepts a second argument which is the parent module from which to resolve from:

      -
      (async () => {
      -  // Equivalent to import.meta.resolve('./dep')
      -  await import.meta.resolve('./dep', import.meta.url);
      -})();
      + +
      await import.meta.resolve('./dep', import.meta.url);

      This function is asynchronous because the ES module resolver in Node.js is -asynchronous. With the introduction of Top-Level Await, these use cases -will be easier as they won't require an async function wrapper.

      -

      No require.extensions#

      -

      require.extensions is not used by import. The expectation is that loader -hooks can provide this workflow in the future.

      -

      No require.cache#

      -

      require.cache is not used by import. It has a separate cache.

      -

      URL-based paths#

      -

      ES modules are resolved and cached based upon -URL semantics. This means that files containing -special characters such as # and ? need to be escaped.

      -

      Modules are loaded multiple times if the import specifier used to resolve -them has a different query or fragment.

      -
      import './foo.mjs?query=1'; // loads ./foo.mjs with query of "?query=1"
      -import './foo.mjs?query=2'; // loads ./foo.mjs with query of "?query=2"
      -

      For now, only modules using the file: protocol can be loaded.

      -

      Interoperability with CommonJS#

      -

      require#

      -

      require always treats the files it references as CommonJS. This applies -whether require is used the traditional way within a CommonJS environment, or -in an ES module environment using module.createRequire().

      -

      To include an ES module into CommonJS, use import().

      -

      import statements#

      +allowed to be asynchronous.

      +

      Interoperability with CommonJS#

      +

      import statements#

      An import statement can reference an ES module or a CommonJS module. -import statements are permitted only in ES modules. For similar functionality -in CommonJS, see import().

      +import statements are permitted only in ES modules, but dynamic import() +expressions are supported in CommonJS for loading ES modules.

      When importing CommonJS modules, the module.exports object is provided as the default export. Named exports may be available, provided by static analysis as a convenience for better ecosystem compatibility.

      -

      Additional experimental flags are available for importing -Wasm modules or -JSON modules. For importing native modules or -JSON modules unflagged, see module.createRequire().

      -

      The specifier of an import statement (the string after the from keyword) -can either be an URL-style relative path like './file.mjs' or a package name -like 'fs'.

      -

      Like in CommonJS, files within packages can be accessed by appending a path to -the package name; unless the package’s package.json contains an -"exports" field, in which case files within packages need to be accessed -via the path defined in "exports".

      -
      import { sin, cos } from 'geometry/trigonometry-functions.mjs';
      -

      import() expressions#

      -

      Dynamic import() is supported in both CommonJS and ES modules. It can be -used to include ES module files from CommonJS code.

      -

      CommonJS Namespaces#

      +

      require#

      +

      The CommonJS module require always treats the files it references as CommonJS.

      +

      Using require to load an ES module is not supported because ES modules have +asynchronous execution. Instead, use import() to load an ES module +from a CommonJS module.

      +

      CommonJS Namespaces#

      CommonJS modules consist of a module.exports object which can be of any type.

      When importing a CommonJS module, it can be reliably imported using the ES module default import or its corresponding sugar syntax:

      @@ -423,8 +472,8 @@ module default import or its corresponding sugar syntax:

      // for `{ default as cjsSugar }` in the above import statement: import cjsSugar from 'cjs'; -console.log(cjs); -console.log(cjs === cjsSugar); +console.log(cjs); +console.log(cjs === cjsSugar); // Prints: // <module.exports> // true
      @@ -435,8 +484,8 @@ a namespace with a default export key pointing to the CommonJS import * as m from 'cjs' or a dynamic import:

      import * as m from 'cjs';
      -console.log(m);
      -console.log(m === await import('cjs'));
      +console.log(m);
      +console.log(m === await import('cjs'));
       // Prints:
       //   [Module] { default: <module.exports> }
       //   true
      @@ -445,20 +494,20 @@ in addition attempts to determine the CommonJS named exports of every imported CommonJS module to provide them as separate ES module exports using a static analysis process.

      For example, consider a CommonJS module written:

      -
      // cjs.cjs
      -exports.name = 'exported';
      +
      // cjs.cjs
      +exports.name = 'exported';

      The preceding module supports named imports in ES modules:

      import { name } from './cjs.cjs';
      -console.log(name);
      +console.log(name);
       // Prints: 'exported'
       
       import cjs from './cjs.cjs';
      -console.log(cjs);
      +console.log(cjs);
       // Prints: { name: 'exported' }
       
       import * as m from './cjs.cjs';
      -console.log(m);
      +console.log(m);
       // Prints: [Module] { default: { name: 'exported' }, name: 'exported' }

      As can be seen from the last example of the Module Namespace Exotic Object being logged, the name export is copied off of the module.exports object and set @@ -469,45 +518,46 @@ for these named exports.

      always correctly detect named exports. In these cases, using the default import form described above can be a better option.

      Named exports detection covers many common export patterns, reexport patterns -and build tool and transpiler outputs. See cjs-module-lexer for the exact +and build tool and transpiler outputs. See cjs-module-lexer for the exact semantics implemented.

      -

      Builtin modules#

      -

      Core modules provide named exports of their public API. A -default export is also provided which is the value of the CommonJS exports. -The default export can be used for, among other things, modifying the named -exports. Named exports of builtin modules are updated only by calling -module.syncBuiltinESMExports().

      -
      import EventEmitter from 'events';
      -const e = new EventEmitter();
      -
      import { readFile } from 'fs';
      -readFile('./foo.txt', (err, source) => {
      -  if (err) {
      -    console.error(err);
      -  } else {
      -    console.log(source);
      -  }
      -});
      -
      import fs, { readFileSync } from 'fs';
      -import { syncBuiltinESMExports } from 'module';
      -
      -fs.readFileSync = () => Buffer.from('Hello, ESM');
      -syncBuiltinESMExports();
      -
      -fs.readFileSync === readFileSync;
      -

      CommonJS, JSON, and native modules#

      -

      CommonJS, JSON, and native modules can be used with +

      Differences between ES modules and CommonJS#

      +
      No require, exports or module.exports#
      +

      In most cases, the ES module import can be used to load CommonJS modules.

      +

      If needed, a require function can be constructed within an ES module using module.createRequire().

      -
      // cjs.cjs
      -module.exports = 'cjs';
      -
      -// esm.mjs
      -import { createRequire } from 'module';
      -
      -const require = createRequire(import.meta.url);
      -
      -const cjs = require('./cjs.cjs');
      -cjs === 'cjs'; // true
      -

      Experimental JSON modules#

      +
      No __filename or __dirname#
      +

      These CommonJS variables are not available in ES modules.

      +

      __filename and __dirname use cases can be replicated via +import.meta.url.

      +
      No JSON Module Loading#
      +

      JSON imports are still experimental and only supported via the +--experimental-json-modules flag.

      +

      Local JSON files can be loaded relative to import.meta.url with fs directly:

      + +
      import { readFile } from 'fs/promises';
      +const json = JSON.parse(await readFile(new URL('./dat.json', import.meta.url)));
      +

      Alternatively module.createRequire() can be used.

      +
      No Native Module Loading#
      +

      Native modules are not currently supported with ES module imports.

      +

      They can instead be loaded with module.createRequire() or +process.dlopen.

      +
      No require.resolve#
      +

      Relative resolution can be handled via new URL('./local', import.meta.url).

      +

      For a complete require.resolve replacement, there is a flagged experimental +import.meta.resolve API.

      +

      Alternatively module.createRequire() can be used.

      +
      No NODE_PATH#
      +

      NODE_PATH is not part of resolving import specifiers. Please use symlinks +if this behavior is desired.

      +
      No require.extensions#
      +

      require.extensions is not used by import. The expectation is that loader +hooks can provide this workflow in the future.

      +
      No require.cache#
      +

      require.cache is not used by import as the ES module loader has its own +separate cache.

      +

      +

      JSON modules#

      +

      Stability: 1 - Experimental

      Currently importing JSON modules are only supported in the commonjs mode and are loaded using the CJS loader. WHATWG JSON modules specification are still being standardized, and are experimentally supported by including the @@ -526,7 +576,9 @@ same path.

      to work.

      node index.mjs # fails
       node --experimental-json-modules index.mjs # works
      -

      Experimental Wasm modules#

      +

      +

      Wasm modules#

      +

      Stability: 1 - Experimental

      Importing Web Assembly modules is supported under the --experimental-wasm-modules flag, allowing any .wasm files to be imported as normal modules while also supporting their module imports.

      @@ -534,19 +586,34 @@ imported as normal modules while also supporting their module imports.

      ES Module Integration Proposal for Web Assembly.

      For example, an index.mjs containing:

      import * as M from './module.wasm';
      -console.log(M);
      +console.log(M);

      executed under:

      node --experimental-wasm-modules index.mjs

      would provide the exports interface for the instantiation of module.wasm.

      -

      Experimental loaders#

      +

      +

      Top-level await#

      +

      Stability: 1 - Experimental

      +

      The await keyword may be used in the top level (outside of async functions) +within modules as per the ECMAScript Top-Level await proposal.

      +

      Assuming an a.mjs with

      + +
      export const five = await Promise.resolve(5);
      +

      And a b.mjs with

      +
      import { five } from './a.mjs';
      +
      +console.log(five); // Logs `5`
      +
      node b.mjs # works
      +

      +

      Loaders#

      +

      Stability: 1 - Experimental

      Note: This API is currently being redesigned and will still change.

      To customize the default module resolution, loader hooks can optionally be provided via a --experimental-loader ./loader-name.mjs argument to Node.js.

      When hooks are used they only apply to ES module loading and not to any CommonJS modules loaded.

      -

      Hooks#

      -

      resolve(specifier, context, defaultResolve)#

      +

      Hooks#

      +
      resolve(specifier, context, defaultResolve)#

      Note: The loaders API is being redesigned. This hook may disappear or its signature may change. Do not rely on the API described below.

      @@ -580,37 +647,37 @@ Node.js module specifier resolution behavior
      when calling defaultReso context.conditions array passed to it must include all elements of the context.conditions array originally passed into the resolve hook.

      /**
      - * @param {string} specifier
      - * @param {{
      + * @param {string} specifier
      + * @param {{
        *   conditions: !Array<string>,
        *   parentURL: !(string | undefined),
      - * }} context
      - * @param {Function} defaultResolve
      - * @returns {Promise<{ url: string }>}
      + * }} context
      + * @param {Function} defaultResolve
      + * @returns {Promise<{ url: string }>}
        */
      -export async function resolve(specifier, context, defaultResolve) {
      +export async function resolve(specifier, context, defaultResolve) {
         const { parentURL = null } = context;
      -  if (Math.random() > 0.5) { // Some condition.
      +  if (Math.random() > 0.5) { // Some condition.
           // For some or all specifiers, do some custom logic for resolving.
           // Always return an object of the form {url: <string>}.
           return {
             url: parentURL ?
      -        new URL(specifier, parentURL).href :
      -        new URL(specifier).href,
      +        new URL(specifier, parentURL).href :
      +        new URL(specifier).href,
           };
         }
      -  if (Math.random() < 0.5) { // Another condition.
      +  if (Math.random() < 0.5) { // Another condition.
           // When calling `defaultResolve`, the arguments can be modified. In this
           // case it's adding another value for matching conditional exports.
      -    return defaultResolve(specifier, {
      +    return defaultResolve(specifier, {
             ...context,
      -      conditions: [...context.conditions, 'another-condition'],
      +      conditions: [...context.conditions, 'another-condition'],
           });
         }
         // Defer to Node.js for all other specifiers.
      -  return defaultResolve(specifier, context, defaultResolve);
      +  return defaultResolve(specifier, context, defaultResolve);
       }
      -

      getFormat(url, context, defaultGetFormat)#

      +
      getFormat(url, context, defaultGetFormat)#

      Note: The loaders API is being redesigned. This hook may disappear or its signature may change. Do not rely on the API described below.

      @@ -664,27 +731,22 @@ of the following:

      - - - - - -
      formatDescriptionAcceptable Types For source Returned by getSource or transformSource
      'builtin'Load a Node.js builtin moduleNot applicable
      'dynamic'Use a dynamic instantiate hookNot applicable
      'commonjs'Load a Node.js CommonJS moduleNot applicable
      'json'Load a JSON file{ string, ArrayBuffer, TypedArray }
      'module'Load an ES module{ string, ArrayBuffer, TypedArray }
      'wasm'Load a WebAssembly module{ ArrayBuffer, TypedArray }
      +
      formatDescriptionAcceptable Types For source Returned by getSource or transformSource
      'builtin'Load a Node.js builtin moduleNot applicable
      'commonjs'Load a Node.js CommonJS moduleNot applicable
      'json'Load a JSON file{ string, ArrayBuffer, TypedArray }
      'module'Load an ES module{ string, ArrayBuffer, TypedArray }
      'wasm'Load a WebAssembly module{ ArrayBuffer, TypedArray }

      Note: These types all correspond to classes defined in ECMAScript.

      Note: If the source value of a text-based format (i.e., 'json', 'module') is -not a string, it is converted to a string using util.TextDecoder.

      +not a string, it is converted to a string using util.TextDecoder.

      /**
      - * @param {string} url
      - * @param {Object} context (currently empty)
      - * @param {Function} defaultGetFormat
      - * @returns {Promise<{ format: string }>}
      + * @param {string} url
      + * @param {Object} context (currently empty)
      + * @param {Function} defaultGetFormat
      + * @returns {Promise<{ format: string }>}
        */
      -export async function getFormat(url, context, defaultGetFormat) {
      -  if (Math.random() > 0.5) { // Some condition.
      +export async function getFormat(url, context, defaultGetFormat) {
      +  if (Math.random() > 0.5) { // Some condition.
           // For some or all URLs, do some custom logic for determining format.
           // Always return an object of the form {format: <string>}, where the
           // format is one of the strings in the preceding table.
      @@ -693,9 +755,9 @@ not a string, it is converted to a string using // Defer to Node.js for all other URLs.
      -  return defaultGetFormat(url, context, defaultGetFormat);
      +  return defaultGetFormat(url, context, defaultGetFormat);
       }
      -

      getSource(url, context, defaultGetSource)#

      +
      getSource(url, context, defaultGetSource)#

      Note: The loaders API is being redesigned. This hook may disappear or its signature may change. Do not rely on the API described below.

      @@ -718,14 +780,14 @@ signature may change. Do not rely on the API described below.

      the source code of an ES module specifier. This would allow a loader to potentially avoid reading files from disk.

      /**
      - * @param {string} url
      - * @param {{ format: string }} context
      - * @param {Function} defaultGetSource
      - * @returns {Promise<{ source: !(string | SharedArrayBuffer | Uint8Array) }>}
      + * @param {string} url
      + * @param {{ format: string }} context
      + * @param {Function} defaultGetSource
      + * @returns {Promise<{ source: !(string | SharedArrayBuffer | Uint8Array) }>}
        */
      -export async function getSource(url, context, defaultGetSource) {
      +export async function getSource(url, context, defaultGetSource) {
         const { format } = context;
      -  if (Math.random() > 0.5) { // Some condition.
      +  if (Math.random() > 0.5) { // Some condition.
           // For some or all URLs, do some custom logic for retrieving the source.
           // Always return an object of the form {source: <string|buffer>}.
           return {
      @@ -733,10 +795,9 @@ potentially avoid reading files from disk.

      }; } // Defer to Node.js for all other URLs. - return defaultGetSource(url, context, defaultGetSource); + return defaultGetSource(url, context, defaultGetSource); }
      -

      transformSource(source, context, defaultTransformSource)#

      -
      NODE_OPTIONS='--experimental-loader ./custom-loader.mjs' node x.js
      +
      transformSource(source, context, defaultTransformSource)#

      Note: The loaders API is being redesigned. This hook may disappear or its signature may change. Do not rely on the API described below.

      @@ -762,17 +823,17 @@ done anything with it.

      JavaScript, a resolve hook is also necessary in order to register any unknown-to-Node.js file extensions. See the transpiler loader example below.

      /**
      - * @param {!(string | SharedArrayBuffer | Uint8Array)} source
      - * @param {{
      + * @param {!(string | SharedArrayBuffer | Uint8Array)} source
      + * @param {{
        *   format: string,
        *   url: string,
      - * }} context
      - * @param {Function} defaultTransformSource
      - * @returns {Promise<{ source: !(string | SharedArrayBuffer | Uint8Array) }>}
      + * }} context
      + * @param {Function} defaultTransformSource
      + * @returns {Promise<{ source: !(string | SharedArrayBuffer | Uint8Array) }>}
        */
      -export async function transformSource(source, context, defaultTransformSource) {
      +export async function transformSource(source, context, defaultTransformSource) {
         const { url, format } = context;
      -  if (Math.random() > 0.5) { // Some condition.
      +  if (Math.random() > 0.5) { // Some condition.
           // For some or all URLs, do some custom logic for modifying the source.
           // Always return an object of the form {source: <string|buffer>}.
           return {
      @@ -780,9 +841,9 @@ unknown-to-Node.js file extensions. See the tra
           };
         }
         // Defer to Node.js for all other sources.
      -  return defaultTransformSource(source, context, defaultTransformSource);
      +  return defaultTransformSource(source, context, defaultTransformSource);
       }
      -

      getGlobalPreloadCode()#

      +
      getGlobalPreloadCode()#

      Note: The loaders API is being redesigned. This hook may disappear or its signature may change. Do not rely on the API described below.

      @@ -799,9 +860,9 @@ builtins like "fs": getBuiltin(request: string).

      If the code needs more advanced require features, it has to construct its own require using module.createRequire().

      /**
      - * @returns {string} Code to run before application startup
      + * @returns {string} Code to run before application startup
        */
      -export function getGlobalPreloadCode() {
      +export function getGlobalPreloadCode() {
         return `\
       globalThis.someInjectedProperty = 42;
       console.log('I just set some globals!');
      @@ -812,37 +873,10 @@ const require = createRequire(process.cwd() + '/<preload>');
       // [...]
       `;
       }
      -

      dynamicInstantiate hook#

      -
      -

      Note: The loaders API is being redesigned. This hook may disappear or its -signature may change. Do not rely on the API described below.

      -
      -

      To create a custom dynamic module that doesn't correspond to one of the -existing format interpretations, the dynamicInstantiate hook can be used. -This hook is called only for modules that return format: 'dynamic' from -the getFormat hook.

      -
      /**
      - * @param {string} url
      - * @returns {object} response
      - * @returns {array} response.exports
      - * @returns {function} response.execute
      - */
      -export async function dynamicInstantiate(url) {
      -  return {
      -    exports: ['customExportName'],
      -    execute: (exports) => {
      -      // Get and set functions provided for pre-allocated export names
      -      exports.customExportName.set('value');
      -    }
      -  };
      -}
      -

      With the list of module exports provided upfront, the execute function will -then be called at the exact point of module evaluation order for that module -in the import tree.

      -

      Examples#

      +

      Examples#

      The various loader hooks can be used together to accomplish wide-ranging customizations of Node.js’ code loading and evaluation behaviors.

      -

      HTTPS loader#

      +
      HTTPS loader#

      In current Node.js, specifiers starting with https:// are unsupported. The loader below registers hooks to enable rudimentary support for such specifiers. While this may seem like a significant improvement to Node.js core @@ -852,63 +886,63 @@ and there is no security.

      // https-loader.mjs
       import { get } from 'https';
       
      -export function resolve(specifier, context, defaultResolve) {
      +export function resolve(specifier, context, defaultResolve) {
         const { parentURL = null } = context;
       
         // Normally Node.js would error on specifiers starting with 'https://', so
         // this hook intercepts them and converts them into absolute URLs to be
         // passed along to the later hooks below.
      -  if (specifier.startsWith('https://')) {
      +  if (specifier.startsWith('https://')) {
           return {
             url: specifier
           };
      -  } else if (parentURL && parentURL.startsWith('https://')) {
      +  } else if (parentURL && parentURL.startsWith('https://')) {
           return {
      -      url: new URL(specifier, parentURL).href
      +      url: new URL(specifier, parentURL).href
           };
         }
       
         // Let Node.js handle all other specifiers.
      -  return defaultResolve(specifier, context, defaultResolve);
      +  return defaultResolve(specifier, context, defaultResolve);
       }
       
      -export function getFormat(url, context, defaultGetFormat) {
      +export function getFormat(url, context, defaultGetFormat) {
         // This loader assumes all network-provided JavaScript is ES module code.
      -  if (url.startsWith('https://')) {
      +  if (url.startsWith('https://')) {
           return {
             format: 'module'
           };
         }
       
         // Let Node.js handle all other URLs.
      -  return defaultGetFormat(url, context, defaultGetFormat);
      +  return defaultGetFormat(url, context, defaultGetFormat);
       }
       
      -export function getSource(url, context, defaultGetSource) {
      +export function getSource(url, context, defaultGetSource) {
         // For JavaScript to be loaded over the network, we need to fetch and
         // return it.
      -  if (url.startsWith('https://')) {
      -    return new Promise((resolve, reject) => {
      -      get(url, (res) => {
      +  if (url.startsWith('https://')) {
      +    return new Promise((resolve, reject) => {
      +      get(url, (res) => {
               let data = '';
      -        res.on('data', (chunk) => data += chunk);
      -        res.on('end', () => resolve({ source: data }));
      -      }).on('error', (err) => reject(err));
      +        res.on('data', (chunk) => data += chunk);
      +        res.on('end', () => resolve({ source: data }));
      +      }).on('error', (err) => reject(err));
           });
         }
       
         // Let Node.js handle all other URLs.
      -  return defaultGetSource(url, context, defaultGetSource);
      +  return defaultGetSource(url, context, defaultGetSource);
       }
      // main.mjs
      -import { VERSION } from 'https://coffeescript.org/browser-compiler-modern/coffeescript.js';
      +import { VERSION } from 'https://coffeescript.org/browser-compiler-modern/coffeescript.js';
       
      -console.log(VERSION);
      +console.log(VERSION);

      With the preceding loader, running node --experimental-loader ./https-loader.mjs ./main.mjs prints the current version of CoffeeScript per the module at the URL in main.mjs.

      -

      Transpiler loader#

      +
      Transpiler loader#

      Sources that are in formats Node.js doesn’t understand can be converted into JavaScript using the transformSource hook. Before that hook gets called, however, other hooks need to tell Node.js not to throw an error on unknown file @@ -917,61 +951,61 @@ types; and to tell Node.js how to load this new file type.

      Node.js; a transpiler loader should only be used for development and testing purposes.

      // coffeescript-loader.mjs
      -import { URL, pathToFileURL } from 'url';
      -import CoffeeScript from 'coffeescript';
      +import { URL, pathToFileURL } from 'url';
      +import CoffeeScript from 'coffeescript';
       
      -const baseURL = pathToFileURL(`${process.cwd()}/`).href;
      +const baseURL = pathToFileURL(`${process.cwd()}/`).href;
       
       // CoffeeScript files end in .coffee, .litcoffee or .coffee.md.
       const extensionsRegex = /\.coffee$|\.litcoffee$|\.coffee\.md$/;
       
      -export function resolve(specifier, context, defaultResolve) {
      +export function resolve(specifier, context, defaultResolve) {
         const { parentURL = baseURL } = context;
       
         // Node.js normally errors on unknown file extensions, so return a URL for
         // specifiers ending in the CoffeeScript file extensions.
      -  if (extensionsRegex.test(specifier)) {
      +  if (extensionsRegex.test(specifier)) {
           return {
      -      url: new URL(specifier, parentURL).href
      +      url: new URL(specifier, parentURL).href
           };
         }
       
         // Let Node.js handle all other specifiers.
      -  return defaultResolve(specifier, context, defaultResolve);
      +  return defaultResolve(specifier, context, defaultResolve);
       }
       
      -export function getFormat(url, context, defaultGetFormat) {
      +export function getFormat(url, context, defaultGetFormat) {
         // Now that we patched resolve to let CoffeeScript URLs through, we need to
         // tell Node.js what format such URLs should be interpreted as. For the
         // purposes of this loader, all CoffeeScript URLs are ES modules.
      -  if (extensionsRegex.test(url)) {
      +  if (extensionsRegex.test(url)) {
           return {
             format: 'module'
           };
         }
       
         // Let Node.js handle all other URLs.
      -  return defaultGetFormat(url, context, defaultGetFormat);
      +  return defaultGetFormat(url, context, defaultGetFormat);
       }
       
      -export function transformSource(source, context, defaultTransformSource) {
      +export function transformSource(source, context, defaultTransformSource) {
         const { url, format } = context;
       
      -  if (extensionsRegex.test(url)) {
      +  if (extensionsRegex.test(url)) {
           return {
      -      source: CoffeeScript.compile(source, { bare: true })
      +      source: CoffeeScript.compile(source, { bare: true })
           };
         }
       
         // Let Node.js handle all other sources.
      -  return defaultTransformSource(source, context, defaultTransformSource);
      +  return defaultTransformSource(source, context, defaultTransformSource);
       }
      # main.coffee
       import { scream } from './scream.coffee'
      -console.log scream 'hello, world'
      +console.log scream 'hello, world'
       
       import { version } from 'process'
      -console.log "Brought to you by Node.js version #{version}"
      +console.log "Brought to you by Node.js version #{version}"
      # scream.coffee
       export scream = (str) -> str.toUpperCase()

      With the preceding loader, running @@ -980,8 +1014,8 @@ causes main.coffee to be turned into JavaScript after its source co loaded from disk but before Node.js executes it; and so on for any .coffee, .litcoffee or .coffee.md files referenced via import statements of any loaded file.

      -

      Resolution algorithm#

      -

      Features#

      +

      Resolution algorithm#

      +

      Features#

      The resolver has the following properties:

      • FileURL-based resolution as is used by ES modules
      • @@ -991,7 +1025,7 @@ loaded file.

      • No folder mains
      • Bare specifier package resolution lookup through node_modules
      -

      Resolver algorithm#

      +

      Resolver algorithm#

      The algorithm to load an ES module specifier is given through the ESM_RESOLVE method below. It returns the resolved URL for a module specifier relative to a parentURL.

      @@ -1017,8 +1051,10 @@ for the package that is an invalid type or string target. subpath in the package for the given module.
    • Package Import Not Defined: Package imports do not define the specifier.
    • Module Not Found: The package or module requested does not exist.
    • +
    • Unsupported Directory Import: The resolved path corresponds to a directory, +which is not a supported target for module imports.
    • -

      Resolver Algorithm Specification#

      +

      Resolver Algorithm Specification#

      ESM_RESOLVE(specifier, parentURL)

        @@ -1459,7 +1495,8 @@ error.
      1. Return the parsed JSON source of the file at pjsonURL.
      -

      Customizing ESM specifier resolution algorithm#

      +

      Customizing ESM specifier resolution algorithm#

      +

      Stability: 1 - Experimental

      The current specifier resolution does not support all default behavior of the CommonJS loader. One of the behavior differences is automatic resolution of file extensions and the ability to import directories that have an index @@ -1469,16 +1506,52 @@ the extension resolution algorithm. The default mode is explicit, w requires the full path to a module be provided to the loader. To enable the automatic extension resolution and importing from directories that include an index file use the node mode.

      -
      $ node index.mjs
      +
      $ node index.mjs
       success!
      -$ node index # Failure!
      +$ node index # Failure!
       Error: Cannot find module
      -$ node --experimental-specifier-resolution=node index
      +$ node --experimental-specifier-resolution=node index
       success!
      - +
      + diff --git a/doc/api/esm.json b/doc/api/esm.json index 29fedcf2b046e8bac61aac870fbbd23cc5f2fced..669935ca1fc91333ee313dcf6c93fd11f4e7827c 100644 --- a/doc/api/esm.json +++ b/doc/api/esm.json @@ -9,25 +9,34 @@ "changes": [ { "version": [ - "v12.22.0" + "v14.17.0" ], "pr-url": "https://github.com/nodejs/node/pull/35781", "description": "Stabilize modules implementation." }, { "version": [ - "v12.20.0" + "v14.13.0" ], "pr-url": "https://github.com/nodejs/node/pull/35249", "description": "Support for detection of CommonJS named exports." }, { - "version": "v12.20.0", + "version": "v14.8.0", + "pr-url": "https://github.com/nodejs/node/pull/34558", + "description": "Unflag Top-Level Await." + }, + { + "version": [ + "v14.0.0", + "v13.14.0" + ], "pr-url": "https://github.com/nodejs/node/pull/31974", "description": "Remove experimental modules warning." }, { "version": [ + "v13.2.0", "v12.17.0" ], "pr-url": "https://github.com/nodejs/node/pull/29866", @@ -47,7 +56,29 @@ "textRaw": "`meta` {Object}", "type": "Object", "name": "meta", - "desc": "

      The import.meta metaproperty is an Object that contains the following\nproperty:

      \n
        \n
      • url <string> The absolute file: URL of the module.
      • \n
      " + "desc": "

      The import.meta meta property is an Object that contains the following\nproperties.

      ", + "properties": [ + { + "textRaw": "`url` {string} The absolute `file:` URL of the module.", + "type": "string", + "name": "url", + "desc": "

      This is defined exactly the same as it is in browsers providing the URL of the\ncurrent module file.

      \n

      This enables useful patterns such as relative file loading:

      \n
      import { readFileSync } from 'fs';\nconst buffer = readFileSync(new URL('./data.proto', import.meta.url));\n
      ", + "shortDesc": "The absolute `file:` URL of the module." + } + ], + "methods": [ + { + "textRaw": "`import.meta.resolve(specifier[, parent])`", + "type": "method", + "name": "resolve", + "signatures": [ + { + "params": [] + } + ], + "desc": "\n
      \n

      Stability: 1 - Experimental

      \n
      \n

      This feature is only available with the --experimental-import-meta-resolve\ncommand flag enabled.

      \n
        \n
      • specifier <string> The module specifier to resolve relative to parent.
      • \n
      • parent <string> The absolute parent module URL to resolve from. If none\nis specified, the value of import.meta.url is used as the default.
      • \n
      • Returns: <Promise>
      • \n
      \n

      Provides a module-relative resolution function scoped to each module, returning\nthe URL string.

      \n\n
      const dependencyAsset = await import.meta.resolve('component-lib/asset.css');\n
      \n

      import.meta.resolve also accepts a second argument which is the parent module\nfrom which to resolve from:

      \n\n
      await import.meta.resolve('./dep', import.meta.url);\n
      \n

      This function is asynchronous because the ES module resolver in Node.js is\nallowed to be asynchronous.

      " + } + ] } ], "miscs": [ @@ -63,25 +94,34 @@ "changes": [ { "version": [ - "v12.22.0" + "v14.17.0" ], "pr-url": "https://github.com/nodejs/node/pull/35781", "description": "Stabilize modules implementation." }, { "version": [ - "v12.20.0" + "v14.13.0" ], "pr-url": "https://github.com/nodejs/node/pull/35249", "description": "Support for detection of CommonJS named exports." }, { - "version": "v12.20.0", + "version": "v14.8.0", + "pr-url": "https://github.com/nodejs/node/pull/34558", + "description": "Unflag Top-Level Await." + }, + { + "version": [ + "v14.0.0", + "v13.14.0" + ], "pr-url": "https://github.com/nodejs/node/pull/31974", "description": "Remove experimental modules warning." }, { "version": [ + "v13.2.0", "v12.17.0" ], "pr-url": "https://github.com/nodejs/node/pull/29866", @@ -100,7 +140,7 @@ { "textRaw": "Introduction", "name": "esm", - "desc": "

      ECMAScript modules are the official standard format to package JavaScript\ncode for reuse. Modules are defined using a variety of import and\nexport statements.

      \n

      The following example of an ES module exports a function:

      \n
      // addTwo.mjs\nfunction addTwo(num) {\n  return num + 2;\n}\n\nexport { addTwo };\n
      \n

      The following example of an ES module imports the function from addTwo.mjs:

      \n
      // app.mjs\nimport { addTwo } from './addTwo.mjs';\n\n// Prints: 6\nconsole.log(addTwo(4));\n
      \n

      Node.js fully supports ECMAScript modules as they are currently specified and\nprovides interoperability between them and its original module format,\nCommonJS.

      \n\n

      \n\n

      ", + "desc": "

      ECMAScript modules are the official standard format to package JavaScript\ncode for reuse. Modules are defined using a variety of import and\nexport statements.

      \n

      The following example of an ES module exports a function:

      \n
      // addTwo.mjs\nfunction addTwo(num) {\n  return num + 2;\n}\n\nexport { addTwo };\n
      \n

      The following example of an ES module imports the function from addTwo.mjs:

      \n
      // app.mjs\nimport { addTwo } from './addTwo.mjs';\n\n// Prints: 6\nconsole.log(addTwo(4));\n
      \n

      Node.js fully supports ECMAScript modules as they are currently specified and\nprovides interoperability between them and its original module format,\nCommonJS.

      \n\n

      \n\n

      ", "type": "misc", "displayName": "esm" }, @@ -124,20 +164,28 @@ { "textRaw": "Terminology", "name": "terminology", - "desc": "

      The specifier of an import statement is the string after the from keyword,\ne.g. 'path' in import { sep } from 'path'. Specifiers are also used in\nexport from statements, and as the argument to an import() expression.

      \n

      There are four types of specifiers:

      \n
        \n
      • \n

        Bare specifiers like 'some-package'. They refer to an entry point of a\npackage by the package name.

        \n
      • \n
      • \n

        Deep import specifiers like 'some-package/lib/shuffle.mjs'. They refer to\na path within a package prefixed by the package name.

        \n
      • \n
      • \n

        Relative specifiers like './startup.js' or '../config.mjs'. They refer\nto a path relative to the location of the importing file.

        \n
      • \n
      • \n

        Absolute specifiers like 'file:///opt/nodejs/config.js'. They refer\ndirectly and explicitly to a full path.

        \n
      • \n
      \n

      Bare specifiers, and the bare specifier portion of deep import specifiers, are\nstrings; but everything else in a specifier is a URL.

      \n

      file:, node:, and data: URLs are supported. A specifier like\n'https://example.com/app.js' may be supported by browsers but it is not\nsupported in Node.js.

      \n

      Specifiers may not begin with / or //. These are reserved for potential\nfuture use. The root of the current volume may be referenced via file:///.

      ", + "desc": "

      The specifier of an import statement is the string after the from keyword,\ne.g. 'path' in import { sep } from 'path'. Specifiers are also used in\nexport from statements, and as the argument to an import() expression.

      \n

      There are three types of specifiers:

      \n
        \n
      • \n

        Relative specifiers like './startup.js' or '../config.mjs'. They refer\nto a path relative to the location of the importing file. The file extension\nis always necessary for these.

        \n
      • \n
      • \n

        Bare specifiers like 'some-package' or 'some-package/shuffle'. They can\nrefer to the main entry point of a package by the package name, or a\nspecific feature module within a package prefixed by the package name as per\nthe examples respectively. Including the file extension is only necessary\nfor packages without an \"exports\" field.

        \n
      • \n
      • \n

        Absolute specifiers like 'file:///opt/nodejs/config.js'. They refer\ndirectly and explicitly to a full path.

        \n
      • \n
      \n

      Bare specifier resolutions are handled by the Node.js module resolution\nalgorithm. All other specifier resolutions are always only resolved with\nthe standard relative URL resolution semantics.

      \n

      Like in CommonJS, module files within packages can be accessed by appending a\npath to the package name unless the package’s package.json contains an\n\"exports\" field, in which case files within packages can only be accessed\nvia the paths defined in \"exports\".

      \n

      For details on these package resolution rules that apply to bare specifiers in\nthe Node.js module resolution, see the packages documentation.

      ", + "type": "module", + "displayName": "Terminology" + }, + { + "textRaw": "Mandatory file extensions", + "name": "mandatory_file_extensions", + "desc": "

      A file extension must be provided when using the import keyword to resolve\nrelative or absolute specifiers. Directory indexes (e.g. './startup/index.js')\nmust also be fully specified.

      \n

      This behavior matches how import behaves in browser environments, assuming a\ntypically configured server.

      ", + "type": "module", + "displayName": "Mandatory file extensions" + }, + { + "textRaw": "URLs", + "name": "urls", + "desc": "

      ES modules are resolved and cached as URLs. This means that files containing\nspecial characters such as # and ? need to be escaped.

      \n

      file:, node:, and data: URL schemes are supported. A specifier like\n'https://example.com/app.js' is not supported natively in Node.js unless using\na custom HTTPS loader.

      ", "modules": [ { - "textRaw": "`node:` Imports", - "name": "`node:`_imports", - "meta": { - "added": [ - "v12.20.0" - ], - "changes": [] - }, - "desc": "

      node: URLs are supported as a means to load Node.js builtin modules. This\nURL scheme allows for builtin modules to be referenced by valid absolute URL\nstrings.

      \n
      import fs from 'node:fs/promises';\n
      ", + "textRaw": "`file:` URLs", + "name": "`file:`_urls", + "desc": "

      Modules are loaded multiple times if the import specifier used to resolve\nthem has a different query or fragment.

      \n
      import './foo.mjs?query=1'; // loads ./foo.mjs with query of \"?query=1\"\nimport './foo.mjs?query=2'; // loads ./foo.mjs with query of \"?query=2\"\n
      \n

      The volume root may be referenced via /, // or file:///. Given the\ndifferences between URL and path resolution (such as percent encoding\ndetails), it is recommended to use url.pathToFileURL when importing a path.

      ", "type": "module", - "displayName": "`node:` Imports" + "displayName": "`file:` URLs" }, { "textRaw": "`data:` Imports", @@ -151,139 +199,174 @@ "desc": "

      data: URLs are supported for importing with the following MIME types:

      \n
        \n
      • text/javascript for ES Modules
      • \n
      • application/json for JSON
      • \n
      • application/wasm for Wasm
      • \n
      \n

      data: URLs only resolve Bare specifiers for builtin modules\nand Absolute specifiers. Resolving\nRelative specifiers does not work because data: is not a\nspecial scheme. For example, attempting to load ./foo\nfrom data:text/javascript,import \"./foo\"; fails to resolve because there\nis no concept of relative resolution for data: URLs. An example of a data:\nURLs being used is:

      \n
      import 'data:text/javascript,console.log(\"hello!\");';\nimport _ from 'data:application/json,\"world!\"';\n
      ", "type": "module", "displayName": "`data:` Imports" + }, + { + "textRaw": "`node:` Imports", + "name": "`node:`_imports", + "meta": { + "added": [ + "v14.13.1", + "v12.20.0" + ], + "changes": [ + { + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/37246", + "description": "Added `node:` import support to `require(...)`." + } + ] + }, + "desc": "

      node: URLs are supported as an alternative means to load Node.js builtin\nmodules. This URL scheme allows for builtin modules to be referenced by valid\nabsolute URL strings.

      \n
      import fs from 'node:fs/promises';\n
      ", + "type": "module", + "displayName": "`node:` Imports" } ], "type": "module", - "displayName": "Terminology" + "displayName": "URLs" } ], "type": "misc", "displayName": "`import` Specifiers" }, { - "textRaw": "Differences between ES modules and CommonJS", - "name": "differences_between_es_modules_and_commonjs", - "modules": [ - { - "textRaw": "Mandatory file extensions", - "name": "mandatory_file_extensions", - "desc": "

      A file extension must be provided when using the import keyword. Directory\nindexes (e.g. './startup/index.js') must also be fully specified.

      \n

      This behavior matches how import behaves in browser environments, assuming a\ntypically configured server.

      ", - "type": "module", - "displayName": "Mandatory file extensions" - }, - { - "textRaw": "No `NODE_PATH`", - "name": "no_`node_path`", - "desc": "

      NODE_PATH is not part of resolving import specifiers. Please use symlinks\nif this behavior is desired.

      ", - "type": "module", - "displayName": "No `NODE_PATH`" - }, - { - "textRaw": "No `require`, `exports`, `module.exports`, `__filename`, `__dirname`", - "name": "no_`require`,_`exports`,_`module.exports`,_`__filename`,_`__dirname`", - "desc": "

      These CommonJS variables are not available in ES modules.

      \n

      require can be imported into an ES module using module.createRequire().

      \n

      Equivalents of __filename and __dirname can be created inside of each file\nvia import.meta.url.

      \n
      import { fileURLToPath } from 'url';\nimport { dirname } from 'path';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n
      ", - "type": "module", - "displayName": "No `require`, `exports`, `module.exports`, `__filename`, `__dirname`" - }, - { - "textRaw": "No `require.resolve`", - "name": "no_`require.resolve`", - "desc": "

      Former use cases relying on require.resolve to determine the resolved path\nof a module can be supported via import.meta.resolve, which is experimental\nand supported via the --experimental-import-meta-resolve flag:

      \n
      (async () => {\n  const dependencyAsset = await import.meta.resolve('component-lib/asset.css');\n})();\n
      \n

      import.meta.resolve also accepts a second argument which is the parent module\nfrom which to resolve from:

      \n
      (async () => {\n  // Equivalent to import.meta.resolve('./dep')\n  await import.meta.resolve('./dep', import.meta.url);\n})();\n
      \n

      This function is asynchronous because the ES module resolver in Node.js is\nasynchronous. With the introduction of Top-Level Await, these use cases\nwill be easier as they won't require an async function wrapper.

      ", - "type": "module", - "displayName": "No `require.resolve`" - }, - { - "textRaw": "No `require.extensions`", - "name": "no_`require.extensions`", - "desc": "

      require.extensions is not used by import. The expectation is that loader\nhooks can provide this workflow in the future.

      ", - "type": "module", - "displayName": "No `require.extensions`" - }, - { - "textRaw": "No `require.cache`", - "name": "no_`require.cache`", - "desc": "

      require.cache is not used by import. It has a separate cache.

      ", - "type": "module", - "displayName": "No `require.cache`" - }, - { - "textRaw": "URL-based paths", - "name": "url-based_paths", - "desc": "

      ES modules are resolved and cached based upon\nURL semantics. This means that files containing\nspecial characters such as # and ? need to be escaped.

      \n

      Modules are loaded multiple times if the import specifier used to resolve\nthem has a different query or fragment.

      \n
      import './foo.mjs?query=1'; // loads ./foo.mjs with query of \"?query=1\"\nimport './foo.mjs?query=2'; // loads ./foo.mjs with query of \"?query=2\"\n
      \n

      For now, only modules using the file: protocol can be loaded.

      ", - "type": "module", - "displayName": "URL-based paths" - } - ], + "textRaw": "Builtin modules", + "name": "builtin_modules", + "desc": "

      Core modules provide named exports of their public API. A\ndefault export is also provided which is the value of the CommonJS exports.\nThe default export can be used for, among other things, modifying the named\nexports. Named exports of builtin modules are updated only by calling\nmodule.syncBuiltinESMExports().

      \n
      import EventEmitter from 'events';\nconst e = new EventEmitter();\n
      \n
      import { readFile } from 'fs';\nreadFile('./foo.txt', (err, source) => {\n  if (err) {\n    console.error(err);\n  } else {\n    console.log(source);\n  }\n});\n
      \n
      import fs, { readFileSync } from 'fs';\nimport { syncBuiltinESMExports } from 'module';\n\nfs.readFileSync = () => Buffer.from('Hello, ESM');\nsyncBuiltinESMExports();\n\nfs.readFileSync === readFileSync;\n
      ", + "type": "misc", + "displayName": "Builtin modules" + }, + { + "textRaw": "`import()` expressions", + "name": "`import()`_expressions", + "desc": "

      Dynamic import() is supported in both CommonJS and ES modules. In CommonJS\nmodules it can be used to load ES modules.

      ", "type": "misc", - "displayName": "Differences between ES modules and CommonJS" + "displayName": "`import()` expressions" }, { "textRaw": "Interoperability with CommonJS", "name": "interoperability_with_commonjs", "modules": [ + { + "textRaw": "`import` statements", + "name": "`import`_statements", + "desc": "

      An import statement can reference an ES module or a CommonJS module.\nimport statements are permitted only in ES modules, but dynamic import()\nexpressions are supported in CommonJS for loading ES modules.

      \n

      When importing CommonJS modules, the\nmodule.exports object is provided as the default export. Named exports may be\navailable, provided by static analysis as a convenience for better ecosystem\ncompatibility.

      ", + "type": "module", + "displayName": "`import` statements" + }, { "textRaw": "`require`", "name": "`require`", - "desc": "

      require always treats the files it references as CommonJS. This applies\nwhether require is used the traditional way within a CommonJS environment, or\nin an ES module environment using module.createRequire().

      \n

      To include an ES module into CommonJS, use import().

      ", + "desc": "

      The CommonJS module require always treats the files it references as CommonJS.

      \n

      Using require to load an ES module is not supported because ES modules have\nasynchronous execution. Instead, use import() to load an ES module\nfrom a CommonJS module.

      ", "type": "module", "displayName": "`require`" }, { - "textRaw": "`import` statements", - "name": "`import`_statements", - "desc": "

      An import statement can reference an ES module or a CommonJS module.\nimport statements are permitted only in ES modules. For similar functionality\nin CommonJS, see import().

      \n

      When importing CommonJS modules, the\nmodule.exports object is provided as the default export. Named exports may be\navailable, provided by static analysis as a convenience for better ecosystem\ncompatibility.

      \n

      Additional experimental flags are available for importing\nWasm modules or\nJSON modules. For importing native modules or\nJSON modules unflagged, see module.createRequire().

      \n

      The specifier of an import statement (the string after the from keyword)\ncan either be an URL-style relative path like './file.mjs' or a package name\nlike 'fs'.

      \n

      Like in CommonJS, files within packages can be accessed by appending a path to\nthe package name; unless the package’s package.json contains an\n\"exports\" field, in which case files within packages need to be accessed\nvia the path defined in \"exports\".

      \n
      import { sin, cos } from 'geometry/trigonometry-functions.mjs';\n
      ", + "textRaw": "CommonJS Namespaces", + "name": "commonjs_namespaces", + "desc": "

      CommonJS modules consist of a module.exports object which can be of any type.

      \n

      When importing a CommonJS module, it can be reliably imported using the ES\nmodule default import or its corresponding sugar syntax:

      \n\n
      import { default as cjs } from 'cjs';\n\n// The following import statement is \"syntax sugar\" (equivalent but sweeter)\n// for `{ default as cjsSugar }` in the above import statement:\nimport cjsSugar from 'cjs';\n\nconsole.log(cjs);\nconsole.log(cjs === cjsSugar);\n// Prints:\n//   <module.exports>\n//   true\n
      \n

      The ECMAScript Module Namespace representation of a CommonJS module is always\na namespace with a default export key pointing to the CommonJS\nmodule.exports value.

      \n

      This Module Namespace Exotic Object can be directly observed either when using\nimport * as m from 'cjs' or a dynamic import:

      \n\n
      import * as m from 'cjs';\nconsole.log(m);\nconsole.log(m === await import('cjs'));\n// Prints:\n//   [Module] { default: <module.exports> }\n//   true\n
      \n

      For better compatibility with existing usage in the JS ecosystem, Node.js\nin addition attempts to determine the CommonJS named exports of every imported\nCommonJS module to provide them as separate ES module exports using a static\nanalysis process.

      \n

      For example, consider a CommonJS module written:

      \n
      // cjs.cjs\nexports.name = 'exported';\n
      \n

      The preceding module supports named imports in ES modules:

      \n\n
      import { name } from './cjs.cjs';\nconsole.log(name);\n// Prints: 'exported'\n\nimport cjs from './cjs.cjs';\nconsole.log(cjs);\n// Prints: { name: 'exported' }\n\nimport * as m from './cjs.cjs';\nconsole.log(m);\n// Prints: [Module] { default: { name: 'exported' }, name: 'exported' }\n
      \n

      As can be seen from the last example of the Module Namespace Exotic Object being\nlogged, the name export is copied off of the module.exports object and set\ndirectly on the ES module namespace when the module is imported.

      \n

      Live binding updates or new exports added to module.exports are not detected\nfor these named exports.

      \n

      The detection of named exports is based on common syntax patterns but does not\nalways correctly detect named exports. In these cases, using the default\nimport form described above can be a better option.

      \n

      Named exports detection covers many common export patterns, reexport patterns\nand build tool and transpiler outputs. See cjs-module-lexer for the exact\nsemantics implemented.

      ", "type": "module", - "displayName": "`import` statements" + "displayName": "CommonJS Namespaces" }, { - "textRaw": "`import()` expressions", - "name": "`import()`_expressions", - "desc": "

      Dynamic import() is supported in both CommonJS and ES modules. It can be\nused to include ES module files from CommonJS code.

      ", + "textRaw": "Differences between ES modules and CommonJS", + "name": "differences_between_es_modules_and_commonjs", + "modules": [ + { + "textRaw": "No `require`, `exports` or `module.exports`", + "name": "no_`require`,_`exports`_or_`module.exports`", + "desc": "

      In most cases, the ES module import can be used to load CommonJS modules.

      \n

      If needed, a require function can be constructed within an ES module using\nmodule.createRequire().

      ", + "type": "module", + "displayName": "No `require`, `exports` or `module.exports`" + }, + { + "textRaw": "No `__filename` or `__dirname`", + "name": "no_`__filename`_or_`__dirname`", + "desc": "

      These CommonJS variables are not available in ES modules.

      \n

      __filename and __dirname use cases can be replicated via\nimport.meta.url.

      ", + "type": "module", + "displayName": "No `__filename` or `__dirname`" + }, + { + "textRaw": "No JSON Module Loading", + "name": "no_json_module_loading", + "desc": "

      JSON imports are still experimental and only supported via the\n--experimental-json-modules flag.

      \n

      Local JSON files can be loaded relative to import.meta.url with fs directly:

      \n\n
      import { readFile } from 'fs/promises';\nconst json = JSON.parse(await readFile(new URL('./dat.json', import.meta.url)));\n
      \n

      Alternatively module.createRequire() can be used.

      ", + "type": "module", + "displayName": "No JSON Module Loading" + }, + { + "textRaw": "No Native Module Loading", + "name": "no_native_module_loading", + "desc": "

      Native modules are not currently supported with ES module imports.

      \n

      They can instead be loaded with module.createRequire() or\nprocess.dlopen.

      ", + "type": "module", + "displayName": "No Native Module Loading" + }, + { + "textRaw": "No `require.resolve`", + "name": "no_`require.resolve`", + "desc": "

      Relative resolution can be handled via new URL('./local', import.meta.url).

      \n

      For a complete require.resolve replacement, there is a flagged experimental\nimport.meta.resolve API.

      \n

      Alternatively module.createRequire() can be used.

      ", + "type": "module", + "displayName": "No `require.resolve`" + }, + { + "textRaw": "No `NODE_PATH`", + "name": "no_`node_path`", + "desc": "

      NODE_PATH is not part of resolving import specifiers. Please use symlinks\nif this behavior is desired.

      ", + "type": "module", + "displayName": "No `NODE_PATH`" + }, + { + "textRaw": "No `require.extensions`", + "name": "no_`require.extensions`", + "desc": "

      require.extensions is not used by import. The expectation is that loader\nhooks can provide this workflow in the future.

      ", + "type": "module", + "displayName": "No `require.extensions`" + }, + { + "textRaw": "No `require.cache`", + "name": "no_`require.cache`", + "desc": "

      require.cache is not used by import as the ES module loader has its own\nseparate cache.

      \n

      ", + "type": "module", + "displayName": "No `require.cache`" + } + ], "type": "module", - "displayName": "`import()` expressions" + "displayName": "Differences between ES modules and CommonJS" } ], "type": "misc", "displayName": "Interoperability with CommonJS" }, { - "textRaw": "CommonJS Namespaces", - "name": "commonjs_namespaces", - "desc": "

      CommonJS modules consist of a module.exports object which can be of any type.

      \n

      When importing a CommonJS module, it can be reliably imported using the ES\nmodule default import or its corresponding sugar syntax:

      \n\n
      import { default as cjs } from 'cjs';\n\n// The following import statement is \"syntax sugar\" (equivalent but sweeter)\n// for `{ default as cjsSugar }` in the above import statement:\nimport cjsSugar from 'cjs';\n\nconsole.log(cjs);\nconsole.log(cjs === cjsSugar);\n// Prints:\n//   <module.exports>\n//   true\n
      \n

      The ECMAScript Module Namespace representation of a CommonJS module is always\na namespace with a default export key pointing to the CommonJS\nmodule.exports value.

      \n

      This Module Namespace Exotic Object can be directly observed either when using\nimport * as m from 'cjs' or a dynamic import:

      \n\n
      import * as m from 'cjs';\nconsole.log(m);\nconsole.log(m === await import('cjs'));\n// Prints:\n//   [Module] { default: <module.exports> }\n//   true\n
      \n

      For better compatibility with existing usage in the JS ecosystem, Node.js\nin addition attempts to determine the CommonJS named exports of every imported\nCommonJS module to provide them as separate ES module exports using a static\nanalysis process.

      \n

      For example, consider a CommonJS module written:

      \n
      // cjs.cjs\nexports.name = 'exported';\n
      \n

      The preceding module supports named imports in ES modules:

      \n\n
      import { name } from './cjs.cjs';\nconsole.log(name);\n// Prints: 'exported'\n\nimport cjs from './cjs.cjs';\nconsole.log(cjs);\n// Prints: { name: 'exported' }\n\nimport * as m from './cjs.cjs';\nconsole.log(m);\n// Prints: [Module] { default: { name: 'exported' }, name: 'exported' }\n
      \n

      As can be seen from the last example of the Module Namespace Exotic Object being\nlogged, the name export is copied off of the module.exports object and set\ndirectly on the ES module namespace when the module is imported.

      \n

      Live binding updates or new exports added to module.exports are not detected\nfor these named exports.

      \n

      The detection of named exports is based on common syntax patterns but does not\nalways correctly detect named exports. In these cases, using the default\nimport form described above can be a better option.

      \n

      Named exports detection covers many common export patterns, reexport patterns\nand build tool and transpiler outputs. See cjs-module-lexer for the exact\nsemantics implemented.

      ", - "type": "misc", - "displayName": "CommonJS Namespaces" - }, - { - "textRaw": "Builtin modules", - "name": "builtin_modules", - "desc": "

      Core modules provide named exports of their public API. A\ndefault export is also provided which is the value of the CommonJS exports.\nThe default export can be used for, among other things, modifying the named\nexports. Named exports of builtin modules are updated only by calling\nmodule.syncBuiltinESMExports().

      \n
      import EventEmitter from 'events';\nconst e = new EventEmitter();\n
      \n
      import { readFile } from 'fs';\nreadFile('./foo.txt', (err, source) => {\n  if (err) {\n    console.error(err);\n  } else {\n    console.log(source);\n  }\n});\n
      \n
      import fs, { readFileSync } from 'fs';\nimport { syncBuiltinESMExports } from 'module';\n\nfs.readFileSync = () => Buffer.from('Hello, ESM');\nsyncBuiltinESMExports();\n\nfs.readFileSync === readFileSync;\n
      ", - "type": "misc", - "displayName": "Builtin modules" - }, - { - "textRaw": "CommonJS, JSON, and native modules", - "name": "commonjs,_json,_and_native_modules", - "desc": "

      CommonJS, JSON, and native modules can be used with\nmodule.createRequire().

      \n
      // cjs.cjs\nmodule.exports = 'cjs';\n\n// esm.mjs\nimport { createRequire } from 'module';\n\nconst require = createRequire(import.meta.url);\n\nconst cjs = require('./cjs.cjs');\ncjs === 'cjs'; // true\n
      ", + "textRaw": "JSON modules", + "name": "json_modules", + "stability": 1, + "stabilityText": "Experimental", + "desc": "

      Currently importing JSON modules are only supported in the commonjs mode\nand are loaded using the CJS loader. WHATWG JSON modules specification are\nstill being standardized, and are experimentally supported by including the\nadditional flag --experimental-json-modules when running Node.js.

      \n

      When the --experimental-json-modules flag is included, both the\ncommonjs and module mode use the new experimental JSON\nloader. The imported JSON only exposes a default. There is no\nsupport for named exports. A cache entry is created in the CommonJS\ncache to avoid duplication. The same object is returned in\nCommonJS if the JSON module has already been imported from the\nsame path.

      \n

      Assuming an index.mjs with

      \n\n
      import packageConfig from './package.json';\n
      \n

      The --experimental-json-modules flag is needed for the module\nto work.

      \n
      node index.mjs # fails\nnode --experimental-json-modules index.mjs # works\n
      \n

      ", "type": "misc", - "displayName": "CommonJS, JSON, and native modules" + "displayName": "JSON modules" }, { - "textRaw": "Experimental JSON modules", - "name": "experimental_json_modules", - "desc": "

      Currently importing JSON modules are only supported in the commonjs mode\nand are loaded using the CJS loader. WHATWG JSON modules specification are\nstill being standardized, and are experimentally supported by including the\nadditional flag --experimental-json-modules when running Node.js.

      \n

      When the --experimental-json-modules flag is included, both the\ncommonjs and module mode use the new experimental JSON\nloader. The imported JSON only exposes a default. There is no\nsupport for named exports. A cache entry is created in the CommonJS\ncache to avoid duplication. The same object is returned in\nCommonJS if the JSON module has already been imported from the\nsame path.

      \n

      Assuming an index.mjs with

      \n\n
      import packageConfig from './package.json';\n
      \n

      The --experimental-json-modules flag is needed for the module\nto work.

      \n
      node index.mjs # fails\nnode --experimental-json-modules index.mjs # works\n
      ", + "textRaw": "Wasm modules", + "name": "wasm_modules", + "stability": 1, + "stabilityText": "Experimental", + "desc": "

      Importing Web Assembly modules is supported under the\n--experimental-wasm-modules flag, allowing any .wasm files to be\nimported as normal modules while also supporting their module imports.

      \n

      This integration is in line with the\nES Module Integration Proposal for Web Assembly.

      \n

      For example, an index.mjs containing:

      \n
      import * as M from './module.wasm';\nconsole.log(M);\n
      \n

      executed under:

      \n
      node --experimental-wasm-modules index.mjs\n
      \n

      would provide the exports interface for the instantiation of module.wasm.

      \n

      ", "type": "misc", - "displayName": "Experimental JSON modules" + "displayName": "Wasm modules" }, { - "textRaw": "Experimental Wasm modules", - "name": "experimental_wasm_modules", - "desc": "

      Importing Web Assembly modules is supported under the\n--experimental-wasm-modules flag, allowing any .wasm files to be\nimported as normal modules while also supporting their module imports.

      \n

      This integration is in line with the\nES Module Integration Proposal for Web Assembly.

      \n

      For example, an index.mjs containing:

      \n
      import * as M from './module.wasm';\nconsole.log(M);\n
      \n

      executed under:

      \n
      node --experimental-wasm-modules index.mjs\n
      \n

      would provide the exports interface for the instantiation of module.wasm.

      ", + "textRaw": "Top-level `await`", + "name": "top-level_`await`", + "stability": 1, + "stabilityText": "Experimental", + "desc": "

      The await keyword may be used in the top level (outside of async functions)\nwithin modules as per the ECMAScript Top-Level await proposal.

      \n

      Assuming an a.mjs with

      \n\n
      export const five = await Promise.resolve(5);\n
      \n

      And a b.mjs with

      \n
      import { five } from './a.mjs';\n\nconsole.log(five); // Logs `5`\n
      \n
      node b.mjs # works\n
      \n

      ", "type": "misc", - "displayName": "Experimental Wasm modules" + "displayName": "Top-level `await`" }, { - "textRaw": "Experimental loaders", - "name": "Experimental loaders", + "textRaw": "Loaders", + "name": "Loaders", + "stability": 1, + "stabilityText": "Experimental", "type": "misc", "desc": "

      Note: This API is currently being redesigned and will still change.

      \n

      To customize the default module resolution, loader hooks can optionally be\nprovided via a --experimental-loader ./loader-name.mjs argument to Node.js.

      \n

      When hooks are used they only apply to ES module loading and not to any\nCommonJS modules loaded.

      ", "miscs": [ @@ -311,7 +394,7 @@ "params": [] } ], - "desc": "
      \n

      Note: The loaders API is being redesigned. This hook may disappear or its\nsignature may change. Do not rely on the API described below.

      \n
      \n\n

      The getFormat hook provides a way to define a custom method of determining how\na URL should be interpreted. The format returned also affects what the\nacceptable forms of source values are for a module when parsing. This can be one\nof the following:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      formatDescriptionAcceptable Types For source Returned by getSource or transformSource
      'builtin'Load a Node.js builtin moduleNot applicable
      'dynamic'Use a dynamic instantiate hookNot applicable
      'commonjs'Load a Node.js CommonJS moduleNot applicable
      'json'Load a JSON file{ string, ArrayBuffer, TypedArray }
      'module'Load an ES module{ string, ArrayBuffer, TypedArray }
      'wasm'Load a WebAssembly module{ ArrayBuffer, TypedArray }
      \n

      Note: These types all correspond to classes defined in ECMAScript.

      \n\n

      Note: If the source value of a text-based format (i.e., 'json', 'module') is\nnot a string, it is converted to a string using util.TextDecoder.

      \n
      /**\n * @param {string} url\n * @param {Object} context (currently empty)\n * @param {Function} defaultGetFormat\n * @returns {Promise<{ format: string }>}\n */\nexport async function getFormat(url, context, defaultGetFormat) {\n  if (Math.random() > 0.5) { // Some condition.\n    // For some or all URLs, do some custom logic for determining format.\n    // Always return an object of the form {format: <string>}, where the\n    // format is one of the strings in the preceding table.\n    return {\n      format: 'module',\n    };\n  }\n  // Defer to Node.js for all other URLs.\n  return defaultGetFormat(url, context, defaultGetFormat);\n}\n
      " + "desc": "
      \n

      Note: The loaders API is being redesigned. This hook may disappear or its\nsignature may change. Do not rely on the API described below.

      \n
      \n\n

      The getFormat hook provides a way to define a custom method of determining how\na URL should be interpreted. The format returned also affects what the\nacceptable forms of source values are for a module when parsing. This can be one\nof the following:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      formatDescriptionAcceptable Types For source Returned by getSource or transformSource
      'builtin'Load a Node.js builtin moduleNot applicable
      'commonjs'Load a Node.js CommonJS moduleNot applicable
      'json'Load a JSON file{ string, ArrayBuffer, TypedArray }
      'module'Load an ES module{ string, ArrayBuffer, TypedArray }
      'wasm'Load a WebAssembly module{ ArrayBuffer, TypedArray }
      \n

      Note: These types all correspond to classes defined in ECMAScript.

      \n\n

      Note: If the source value of a text-based format (i.e., 'json', 'module') is\nnot a string, it is converted to a string using util.TextDecoder.

      \n
      /**\n * @param {string} url\n * @param {Object} context (currently empty)\n * @param {Function} defaultGetFormat\n * @returns {Promise<{ format: string }>}\n */\nexport async function getFormat(url, context, defaultGetFormat) {\n  if (Math.random() > 0.5) { // Some condition.\n    // For some or all URLs, do some custom logic for determining format.\n    // Always return an object of the form {format: <string>}, where the\n    // format is one of the strings in the preceding table.\n    return {\n      format: 'module',\n    };\n  }\n  // Defer to Node.js for all other URLs.\n  return defaultGetFormat(url, context, defaultGetFormat);\n}\n
      " }, { "textRaw": "`getSource(url, context, defaultGetSource)`", @@ -333,7 +416,7 @@ "params": [] } ], - "desc": "
      NODE_OPTIONS='--experimental-loader ./custom-loader.mjs' node x.js\n
      \n
      \n

      Note: The loaders API is being redesigned. This hook may disappear or its\nsignature may change. Do not rely on the API described below.

      \n
      \n\n

      The transformSource hook provides a way to modify the source code of a loaded\nES module file after the source string has been loaded but before Node.js has\ndone anything with it.

      \n

      If this hook is used to convert unknown-to-Node.js file types into executable\nJavaScript, a resolve hook is also necessary in order to register any\nunknown-to-Node.js file extensions. See the transpiler loader example below.

      \n
      /**\n * @param {!(string | SharedArrayBuffer | Uint8Array)} source\n * @param {{\n *   format: string,\n *   url: string,\n * }} context\n * @param {Function} defaultTransformSource\n * @returns {Promise<{ source: !(string | SharedArrayBuffer | Uint8Array) }>}\n */\nexport async function transformSource(source, context, defaultTransformSource) {\n  const { url, format } = context;\n  if (Math.random() > 0.5) { // Some condition.\n    // For some or all URLs, do some custom logic for modifying the source.\n    // Always return an object of the form {source: <string|buffer>}.\n    return {\n      source: '...',\n    };\n  }\n  // Defer to Node.js for all other sources.\n  return defaultTransformSource(source, context, defaultTransformSource);\n}\n
      " + "desc": "
      \n

      Note: The loaders API is being redesigned. This hook may disappear or its\nsignature may change. Do not rely on the API described below.

      \n
      \n\n

      The transformSource hook provides a way to modify the source code of a loaded\nES module file after the source string has been loaded but before Node.js has\ndone anything with it.

      \n

      If this hook is used to convert unknown-to-Node.js file types into executable\nJavaScript, a resolve hook is also necessary in order to register any\nunknown-to-Node.js file extensions. See the transpiler loader example below.

      \n
      /**\n * @param {!(string | SharedArrayBuffer | Uint8Array)} source\n * @param {{\n *   format: string,\n *   url: string,\n * }} context\n * @param {Function} defaultTransformSource\n * @returns {Promise<{ source: !(string | SharedArrayBuffer | Uint8Array) }>}\n */\nexport async function transformSource(source, context, defaultTransformSource) {\n  const { url, format } = context;\n  if (Math.random() > 0.5) { // Some condition.\n    // For some or all URLs, do some custom logic for modifying the source.\n    // Always return an object of the form {source: <string|buffer>}.\n    return {\n      source: '...',\n    };\n  }\n  // Defer to Node.js for all other sources.\n  return defaultTransformSource(source, context, defaultTransformSource);\n}\n
      " }, { "textRaw": "`getGlobalPreloadCode()`", @@ -344,17 +427,10 @@ "params": [] } ], - "desc": "
      \n

      Note: The loaders API is being redesigned. This hook may disappear or its\nsignature may change. Do not rely on the API described below.

      \n
      \n\n

      Sometimes it might be necessary to run some code inside of the same global scope\nthat the application runs in. This hook allows the return of a string that is\nrun as sloppy-mode script on startup.

      \n

      Similar to how CommonJS wrappers work, the code runs in an implicit function\nscope. The only argument is a require-like function that can be used to load\nbuiltins like \"fs\": getBuiltin(request: string).

      \n

      If the code needs more advanced require features, it has to construct\nits own require using module.createRequire().

      \n
      /**\n * @returns {string} Code to run before application startup\n */\nexport function getGlobalPreloadCode() {\n  return `\\\nglobalThis.someInjectedProperty = 42;\nconsole.log('I just set some globals!');\n\nconst { createRequire } = getBuiltin('module');\n\nconst require = createRequire(process.cwd() + '/<preload>');\n// [...]\n`;\n}\n
      " + "desc": "
      \n

      Note: The loaders API is being redesigned. This hook may disappear or its\nsignature may change. Do not rely on the API described below.

      \n
      \n\n

      Sometimes it might be necessary to run some code inside of the same global scope\nthat the application runs in. This hook allows the return of a string that is\nrun as sloppy-mode script on startup.

      \n

      Similar to how CommonJS wrappers work, the code runs in an implicit function\nscope. The only argument is a require-like function that can be used to load\nbuiltins like \"fs\": getBuiltin(request: string).

      \n

      If the code needs more advanced require features, it has to construct\nits own require using module.createRequire().

      \n
      /**\n * @returns {string} Code to run before application startup\n */\nexport function getGlobalPreloadCode() {\n  return `\\\nglobalThis.someInjectedProperty = 42;\nconsole.log('I just set some globals!');\n\nconst { createRequire } = getBuiltin('module');\n\nconst require = createRequire(process.cwd() + '/<preload>');\n// [...]\n`;\n}\n
      \n

      Examples

      \n

      The various loader hooks can be used together to accomplish wide-ranging\ncustomizations of Node.js’ code loading and evaluation behaviors.

      " } ], "modules": [ - { - "textRaw": "dynamicInstantiate hook", - "name": "dynamicinstantiate_hook", - "desc": "
      \n

      Note: The loaders API is being redesigned. This hook may disappear or its\nsignature may change. Do not rely on the API described below.

      \n
      \n

      To create a custom dynamic module that doesn't correspond to one of the\nexisting format interpretations, the dynamicInstantiate hook can be used.\nThis hook is called only for modules that return format: 'dynamic' from\nthe getFormat hook.

      \n
      /**\n * @param {string} url\n * @returns {object} response\n * @returns {array} response.exports\n * @returns {function} response.execute\n */\nexport async function dynamicInstantiate(url) {\n  return {\n    exports: ['customExportName'],\n    execute: (exports) => {\n      // Get and set functions provided for pre-allocated export names\n      exports.customExportName.set('value');\n    }\n  };\n}\n
      \n

      With the list of module exports provided upfront, the execute function will\nthen be called at the exact point of module evaluation order for that module\nin the import tree.

      \n

      Examples

      \n

      The various loader hooks can be used together to accomplish wide-ranging\ncustomizations of Node.js’ code loading and evaluation behaviors.

      ", - "type": "module", - "displayName": "dynamicInstantiate hook" - }, { "textRaw": "HTTPS loader", "name": "https_loader", @@ -389,7 +465,7 @@ { "textRaw": "Resolver algorithm", "name": "resolver_algorithm", - "desc": "

      The algorithm to load an ES module specifier is given through the\nESM_RESOLVE method below. It returns the resolved URL for a\nmodule specifier relative to a parentURL.

      \n

      The algorithm to determine the module format of a resolved URL is\nprovided by ESM_FORMAT, which returns the unique module\nformat for any file. The \"module\" format is returned for an ECMAScript\nModule, while the \"commonjs\" format is used to indicate loading through the\nlegacy CommonJS loader. Additional formats such as \"addon\" can be extended in\nfuture updates.

      \n

      In the following algorithms, all subroutine errors are propagated as errors\nof these top-level routines unless stated otherwise.

      \n

      defaultConditions is the conditional environment name array,\n[\"node\", \"import\"].

      \n

      The resolver can throw the following errors:

      \n
        \n
      • Invalid Module Specifier: Module specifier is an invalid URL, package name\nor package subpath specifier.
      • \n
      • Invalid Package Configuration: package.json configuration is invalid or\ncontains an invalid configuration.
      • \n
      • Invalid Package Target: Package exports or imports define a target module\nfor the package that is an invalid type or string target.
      • \n
      • Package Path Not Exported: Package exports do not define or permit a target\nsubpath in the package for the given module.
      • \n
      • Package Import Not Defined: Package imports do not define the specifier.
      • \n
      • Module Not Found: The package or module requested does not exist.
      • \n
      ", + "desc": "

      The algorithm to load an ES module specifier is given through the\nESM_RESOLVE method below. It returns the resolved URL for a\nmodule specifier relative to a parentURL.

      \n

      The algorithm to determine the module format of a resolved URL is\nprovided by ESM_FORMAT, which returns the unique module\nformat for any file. The \"module\" format is returned for an ECMAScript\nModule, while the \"commonjs\" format is used to indicate loading through the\nlegacy CommonJS loader. Additional formats such as \"addon\" can be extended in\nfuture updates.

      \n

      In the following algorithms, all subroutine errors are propagated as errors\nof these top-level routines unless stated otherwise.

      \n

      defaultConditions is the conditional environment name array,\n[\"node\", \"import\"].

      \n

      The resolver can throw the following errors:

      \n
        \n
      • Invalid Module Specifier: Module specifier is an invalid URL, package name\nor package subpath specifier.
      • \n
      • Invalid Package Configuration: package.json configuration is invalid or\ncontains an invalid configuration.
      • \n
      • Invalid Package Target: Package exports or imports define a target module\nfor the package that is an invalid type or string target.
      • \n
      • Package Path Not Exported: Package exports do not define or permit a target\nsubpath in the package for the given module.
      • \n
      • Package Import Not Defined: Package imports do not define the specifier.
      • \n
      • Module Not Found: The package or module requested does not exist.
      • \n
      • Unsupported Directory Import: The resolved path corresponds to a directory,\nwhich is not a supported target for module imports.
      • \n
      ", "type": "module", "displayName": "Resolver algorithm" }, @@ -403,6 +479,8 @@ { "textRaw": "Customizing ESM specifier resolution algorithm", "name": "customizing_esm_specifier_resolution_algorithm", + "stability": 1, + "stabilityText": "Experimental", "desc": "

      The current specifier resolution does not support all default behavior of\nthe CommonJS loader. One of the behavior differences is automatic resolution\nof file extensions and the ability to import directories that have an index\nfile.

      \n

      The --experimental-specifier-resolution=[mode] flag can be used to customize\nthe extension resolution algorithm. The default mode is explicit, which\nrequires the full path to a module be provided to the loader. To enable the\nautomatic extension resolution and importing from directories that include an\nindex file use the node mode.

      \n
      $ node index.mjs\nsuccess!\n$ node index # Failure!\nError: Cannot find module\n$ node --experimental-specifier-resolution=node index\nsuccess!\n
      \n", "type": "module", "displayName": "Customizing ESM specifier resolution algorithm" @@ -417,7 +495,29 @@ "textRaw": "`meta` {Object}", "type": "Object", "name": "meta", - "desc": "

      The import.meta metaproperty is an Object that contains the following\nproperty:

      \n
        \n
      • url <string> The absolute file: URL of the module.
      • \n
      " + "desc": "

      The import.meta meta property is an Object that contains the following\nproperties.

      ", + "properties": [ + { + "textRaw": "`url` {string} The absolute `file:` URL of the module.", + "type": "string", + "name": "url", + "desc": "

      This is defined exactly the same as it is in browsers providing the URL of the\ncurrent module file.

      \n

      This enables useful patterns such as relative file loading:

      \n
      import { readFileSync } from 'fs';\nconst buffer = readFileSync(new URL('./data.proto', import.meta.url));\n
      ", + "shortDesc": "The absolute `file:` URL of the module." + } + ], + "methods": [ + { + "textRaw": "`import.meta.resolve(specifier[, parent])`", + "type": "method", + "name": "resolve", + "signatures": [ + { + "params": [] + } + ], + "desc": "\n
      \n

      Stability: 1 - Experimental

      \n
      \n

      This feature is only available with the --experimental-import-meta-resolve\ncommand flag enabled.

      \n
        \n
      • specifier <string> The module specifier to resolve relative to parent.
      • \n
      • parent <string> The absolute parent module URL to resolve from. If none\nis specified, the value of import.meta.url is used as the default.
      • \n
      • Returns: <Promise>
      • \n
      \n

      Provides a module-relative resolution function scoped to each module, returning\nthe URL string.

      \n\n
      const dependencyAsset = await import.meta.resolve('component-lib/asset.css');\n
      \n

      import.meta.resolve also accepts a second argument which is the parent module\nfrom which to resolve from:

      \n\n
      await import.meta.resolve('./dep', import.meta.url);\n
      \n

      This function is asynchronous because the ES module resolver in Node.js is\nallowed to be asynchronous.

      " + } + ] } ] } diff --git a/doc/api/esm.md b/doc/api/esm.md index 3c76d1d6cc5cac3a41ac8854aeee5919f74827d8..632569537b62e7d851debe50a06c66ef327f5bdb 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -6,17 +6,23 @@ added: v8.5.0 changes: - version: - - v12.22.0 + - v14.17.0 pr-url: https://github.com/nodejs/node/pull/35781 description: Stabilize modules implementation. - version: - - v12.20.0 + - v14.13.0 pr-url: https://github.com/nodejs/node/pull/35249 description: Support for detection of CommonJS named exports. - - version: v12.20.0 + - version: v14.8.0 + pr-url: https://github.com/nodejs/node/pull/34558 + description: Unflag Top-Level Await. + - version: + - v14.0.0 + - v13.14.0 pr-url: https://github.com/nodejs/node/pull/31974 description: Remove experimental modules warning. - version: + - v13.2.0 - v12.17.0 pr-url: https://github.com/nodejs/node/pull/29866 description: Loading ECMAScript modules no longer requires a command-line flag. @@ -63,9 +69,9 @@ provides interoperability between them and its original module format, [CommonJS][]. - - - + + + ## Enabling @@ -75,7 +81,7 @@ Node.js treats JavaScript code as CommonJS modules by default. Authors can tell Node.js to treat JavaScript code as ECMAScript modules via the `.mjs` file extension, the `package.json` [`"type"`][] field, or the `--input-type` flag. See -[Modules: Packages](packages.html#packages_determining_module_system) for more +[Modules: Packages](packages.md#packages_determining_module_system) for more details. @@ -96,7 +102,7 @@ details. ## Packages -This section was moved to [Modules: Packages](packages.html). +This section was moved to [Modules: Packages](packages.md). ## `import` Specifiers @@ -106,44 +112,65 @@ The _specifier_ of an `import` statement is the string after the `from` keyword, e.g. `'path'` in `import { sep } from 'path'`. Specifiers are also used in `export from` statements, and as the argument to an `import()` expression. -There are four types of specifiers: - -* _Bare specifiers_ like `'some-package'`. They refer to an entry point of a - package by the package name. - -* _Deep import specifiers_ like `'some-package/lib/shuffle.mjs'`. They refer to - a path within a package prefixed by the package name. +There are three types of specifiers: * _Relative specifiers_ like `'./startup.js'` or `'../config.mjs'`. They refer - to a path relative to the location of the importing file. + to a path relative to the location of the importing file. _The file extension + is always necessary for these._ + +* _Bare specifiers_ like `'some-package'` or `'some-package/shuffle'`. They can + refer to the main entry point of a package by the package name, or a + specific feature module within a package prefixed by the package name as per + the examples respectively. _Including the file extension is only necessary + for packages without an [`"exports"`][] field._ * _Absolute specifiers_ like `'file:///opt/nodejs/config.js'`. They refer directly and explicitly to a full path. -Bare specifiers, and the bare specifier portion of deep import specifiers, are -strings; but everything else in a specifier is a URL. +Bare specifier resolutions are handled by the [Node.js module resolution +algorithm][]. All other specifier resolutions are always only resolved with +the standard relative [URL][] resolution semantics. -`file:`, `node:`, and `data:` URLs are supported. A specifier like -`'https://example.com/app.js'` may be supported by browsers but it is not -supported in Node.js. +Like in CommonJS, module files within packages can be accessed by appending a +path to the package name unless the package’s [`package.json`][] contains an +[`"exports"`][] field, in which case files within packages can only be accessed +via the paths defined in [`"exports"`][]. -Specifiers may not begin with `/` or `//`. These are reserved for potential -future use. The root of the current volume may be referenced via `file:///`. +For details on these package resolution rules that apply to bare specifiers in +the Node.js module resolution, see the [packages documentation](packages.md). -#### `node:` Imports +### Mandatory file extensions - +A file extension must be provided when using the `import` keyword to resolve +relative or absolute specifiers. Directory indexes (e.g. `'./startup/index.js'`) +must also be fully specified. + +This behavior matches how `import` behaves in browser environments, assuming a +typically configured server. + +### URLs + +ES modules are resolved and cached as URLs. This means that files containing +special characters such as `#` and `?` need to be escaped. + +`file:`, `node:`, and `data:` URL schemes are supported. A specifier like +`'https://example.com/app.js'` is not supported natively in Node.js unless using +a [custom HTTPS loader][]. -`node:` URLs are supported as a means to load Node.js builtin modules. This -URL scheme allows for builtin modules to be referenced by valid absolute URL -strings. +#### `file:` URLs + +Modules are loaded multiple times if the `import` specifier used to resolve +them has a different query or fragment. ```js -import fs from 'node:fs/promises'; +import './foo.mjs?query=1'; // loads ./foo.mjs with query of "?query=1" +import './foo.mjs?query=2'; // loads ./foo.mjs with query of "?query=2" ``` +The volume root may be referenced via `/`, `//` or `file:///`. Given the +differences between [URL][] and path resolution (such as percent encoding +details), it is recommended to use [url.pathToFileURL][] when importing a path. + #### `data:` Imports -The `import.meta` metaproperty is an `Object` that contains the following -property: +`node:` URLs are supported as an alternative means to load Node.js builtin +modules. This URL scheme allows for builtin modules to be referenced by valid +absolute URL strings. -* `url` {string} The absolute `file:` URL of the module. +```js +import fs from 'node:fs/promises'; +``` -## Differences between ES modules and CommonJS +## Builtin modules -### Mandatory file extensions +[Core modules][] provide named exports of their public API. A +default export is also provided which is the value of the CommonJS exports. +The default export can be used for, among other things, modifying the named +exports. Named exports of builtin modules are updated only by calling +[`module.syncBuiltinESMExports()`][]. -A file extension must be provided when using the `import` keyword. Directory -indexes (e.g. `'./startup/index.js'`) must also be fully specified. +```js +import EventEmitter from 'events'; +const e = new EventEmitter(); +``` -This behavior matches how `import` behaves in browser environments, assuming a -typically configured server. +```js +import { readFile } from 'fs'; +readFile('./foo.txt', (err, source) => { + if (err) { + console.error(err); + } else { + console.log(source); + } +}); +``` -### No `NODE_PATH` +```js +import fs, { readFileSync } from 'fs'; +import { syncBuiltinESMExports } from 'module'; -`NODE_PATH` is not part of resolving `import` specifiers. Please use symlinks -if this behavior is desired. +fs.readFileSync = () => Buffer.from('Hello, ESM'); +syncBuiltinESMExports(); -### No `require`, `exports`, `module.exports`, `__filename`, `__dirname` +fs.readFileSync === readFileSync; +``` -These CommonJS variables are not available in ES modules. +## `import()` expressions -`require` can be imported into an ES module using [`module.createRequire()`][]. +[Dynamic `import()`][] is supported in both CommonJS and ES modules. In CommonJS +modules it can be used to load ES modules. -Equivalents of `__filename` and `__dirname` can be created inside of each file -via [`import.meta.url`][]. +## `import.meta` -```js -import { fileURLToPath } from 'url'; -import { dirname } from 'path'; +* {Object} -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); -``` +The `import.meta` meta property is an `Object` that contains the following +properties. -### No `require.resolve` +### `import.meta.url` -Former use cases relying on `require.resolve` to determine the resolved path -of a module can be supported via `import.meta.resolve`, which is experimental -and supported via the `--experimental-import-meta-resolve` flag: +* {string} The absolute `file:` URL of the module. -```js -(async () => { - const dependencyAsset = await import.meta.resolve('component-lib/asset.css'); -})(); -``` +This is defined exactly the same as it is in browsers providing the URL of the +current module file. -`import.meta.resolve` also accepts a second argument which is the parent module -from which to resolve from: +This enables useful patterns such as relative file loading: ```js -(async () => { - // Equivalent to import.meta.resolve('./dep') - await import.meta.resolve('./dep', import.meta.url); -})(); +import { readFileSync } from 'fs'; +const buffer = readFileSync(new URL('./data.proto', import.meta.url)); ``` -This function is asynchronous because the ES module resolver in Node.js is -asynchronous. With the introduction of [Top-Level Await][], these use cases -will be easier as they won't require an async function wrapper. - -### No `require.extensions` +### `import.meta.resolve(specifier[, parent])` + -`require.extensions` is not used by `import`. The expectation is that loader -hooks can provide this workflow in the future. +> Stability: 1 - Experimental -### No `require.cache` +This feature is only available with the `--experimental-import-meta-resolve` +command flag enabled. -`require.cache` is not used by `import`. It has a separate cache. +* `specifier` {string} The module specifier to resolve relative to `parent`. +* `parent` {string} The absolute parent module URL to resolve from. If none + is specified, the value of `import.meta.url` is used as the default. +* Returns: {Promise} -### URL-based paths +Provides a module-relative resolution function scoped to each module, returning +the URL string. -ES modules are resolved and cached based upon -[URL](https://url.spec.whatwg.org/) semantics. This means that files containing -special characters such as `#` and `?` need to be escaped. + +```js +const dependencyAsset = await import.meta.resolve('component-lib/asset.css'); +``` -Modules are loaded multiple times if the `import` specifier used to resolve -them has a different query or fragment. +`import.meta.resolve` also accepts a second argument which is the parent module +from which to resolve from: + ```js -import './foo.mjs?query=1'; // loads ./foo.mjs with query of "?query=1" -import './foo.mjs?query=2'; // loads ./foo.mjs with query of "?query=2" +await import.meta.resolve('./dep', import.meta.url); ``` -For now, only modules using the `file:` protocol can be loaded. +This function is asynchronous because the ES module resolver in Node.js is +allowed to be asynchronous. ## Interoperability with CommonJS -### `require` - -`require` always treats the files it references as CommonJS. This applies -whether `require` is used the traditional way within a CommonJS environment, or -in an ES module environment using [`module.createRequire()`][]. - -To include an ES module into CommonJS, use [`import()`][]. - ### `import` statements An `import` statement can reference an ES module or a CommonJS module. -`import` statements are permitted only in ES modules. For similar functionality -in CommonJS, see [`import()`][]. +`import` statements are permitted only in ES modules, but dynamic [`import()`][] +expressions are supported in CommonJS for loading ES modules. When importing [CommonJS modules](#esm_commonjs_namespaces), the `module.exports` object is provided as the default export. Named exports may be available, provided by static analysis as a convenience for better ecosystem compatibility. -Additional experimental flags are available for importing -[Wasm modules](#esm_experimental_wasm_modules) or -[JSON modules](#esm_experimental_json_modules). For importing native modules or -JSON modules unflagged, see [`module.createRequire()`][]. - -The _specifier_ of an `import` statement (the string after the `from` keyword) -can either be an URL-style relative path like `'./file.mjs'` or a package name -like `'fs'`. - -Like in CommonJS, files within packages can be accessed by appending a path to -the package name; unless the package’s [`package.json`][] contains an -[`"exports"`][] field, in which case files within packages need to be accessed -via the path defined in [`"exports"`][]. - -```js -import { sin, cos } from 'geometry/trigonometry-functions.mjs'; -``` +### `require` -### `import()` expressions +The CommonJS module `require` always treats the files it references as CommonJS. -[Dynamic `import()`][] is supported in both CommonJS and ES modules. It can be -used to include ES module files from CommonJS code. +Using `require` to load an ES module is not supported because ES modules have +asynchronous execution. Instead, use [`import()`][] to load an ES module +from a CommonJS module. -## CommonJS Namespaces +### CommonJS Namespaces CommonJS modules consist of a `module.exports` object which can be of any type. @@ -351,7 +383,7 @@ analysis process. For example, consider a CommonJS module written: -```js +```cjs // cjs.cjs exports.name = 'exported'; ``` @@ -388,59 +420,73 @@ Named exports detection covers many common export patterns, reexport patterns and build tool and transpiler outputs. See [cjs-module-lexer][] for the exact semantics implemented. -## Builtin modules +### Differences between ES modules and CommonJS -[Core modules][] provide named exports of their public API. A -default export is also provided which is the value of the CommonJS exports. -The default export can be used for, among other things, modifying the named -exports. Named exports of builtin modules are updated only by calling -[`module.syncBuiltinESMExports()`][]. +#### No `require`, `exports` or `module.exports` -```js -import EventEmitter from 'events'; -const e = new EventEmitter(); -``` +In most cases, the ES module `import` can be used to load CommonJS modules. + +If needed, a `require` function can be constructed within an ES module using +[`module.createRequire()`][]. + +#### No `__filename` or `__dirname` +These CommonJS variables are not available in ES modules. + +`__filename` and `__dirname` use cases can be replicated via +[`import.meta.url`][]. + +#### No JSON Module Loading + +JSON imports are still experimental and only supported via the +`--experimental-json-modules` flag. + +Local JSON files can be loaded relative to `import.meta.url` with `fs` directly: + + ```js -import { readFile } from 'fs'; -readFile('./foo.txt', (err, source) => { - if (err) { - console.error(err); - } else { - console.log(source); - } -}); +import { readFile } from 'fs/promises'; +const json = JSON.parse(await readFile(new URL('./dat.json', import.meta.url))); ``` -```js -import fs, { readFileSync } from 'fs'; -import { syncBuiltinESMExports } from 'module'; +Alternatively `module.createRequire()` can be used. -fs.readFileSync = () => Buffer.from('Hello, ESM'); -syncBuiltinESMExports(); +#### No Native Module Loading -fs.readFileSync === readFileSync; -``` +Native modules are not currently supported with ES module imports. -## CommonJS, JSON, and native modules +They can instead be loaded with [`module.createRequire()`][] or +[`process.dlopen`][]. -CommonJS, JSON, and native modules can be used with -[`module.createRequire()`][]. +#### No `require.resolve` -```js -// cjs.cjs -module.exports = 'cjs'; +Relative resolution can be handled via `new URL('./local', import.meta.url)`. -// esm.mjs -import { createRequire } from 'module'; +For a complete `require.resolve` replacement, there is a flagged experimental +[`import.meta.resolve`][] API. -const require = createRequire(import.meta.url); +Alternatively `module.createRequire()` can be used. -const cjs = require('./cjs.cjs'); -cjs === 'cjs'; // true -``` +#### No `NODE_PATH` + +`NODE_PATH` is not part of resolving `import` specifiers. Please use symlinks +if this behavior is desired. + +#### No `require.extensions` + +`require.extensions` is not used by `import`. The expectation is that loader +hooks can provide this workflow in the future. + +#### No `require.cache` + +`require.cache` is not used by `import` as the ES module loader has its own +separate cache. + + + +## JSON modules -## Experimental JSON modules +> Stability: 1 - Experimental Currently importing JSON modules are only supported in the `commonjs` mode and are loaded using the CJS loader. [WHATWG JSON modules specification][] are @@ -470,7 +516,11 @@ node index.mjs # fails node --experimental-json-modules index.mjs # works ``` -## Experimental Wasm modules + + +## Wasm modules + +> Stability: 1 - Experimental Importing Web Assembly modules is supported under the `--experimental-wasm-modules` flag, allowing any `.wasm` files to be @@ -494,7 +544,39 @@ node --experimental-wasm-modules index.mjs would provide the exports interface for the instantiation of `module.wasm`. -## Experimental loaders + + +## Top-level `await` + +> Stability: 1 - Experimental + +The `await` keyword may be used in the top level (outside of async functions) +within modules as per the [ECMAScript Top-Level `await` proposal][]. + +Assuming an `a.mjs` with + + +```js +export const five = await Promise.resolve(5); +``` + +And a `b.mjs` with + +```js +import { five } from './a.mjs'; + +console.log(five); // Logs `5` +``` + +```bash +node b.mjs # works +``` + + + +## Loaders + +> Stability: 1 - Experimental **Note: This API is currently being redesigned and will still change.** @@ -587,14 +669,13 @@ a URL should be interpreted. The `format` returned also affects what the acceptable forms of source values are for a module when parsing. This can be one of the following: -| `format` | Description | Acceptable Types For `source` Returned by `getSource` or `transformSource` | -| ------------ | ------------------------------ | -------------------------------------------------------------------------- | -| `'builtin'` | Load a Node.js builtin module | Not applicable | -| `'dynamic'` | Use a [dynamic instantiate hook][] | Not applicable | -| `'commonjs'` | Load a Node.js CommonJS module | Not applicable | -| `'json'` | Load a JSON file | { [`string`][], [`ArrayBuffer`][], [`TypedArray`][] } | -| `'module'` | Load an ES module | { [`string`][], [`ArrayBuffer`][], [`TypedArray`][] } | -| `'wasm'` | Load a WebAssembly module | { [`ArrayBuffer`][], [`TypedArray`][] } | +| `format` | Description | Acceptable Types For `source` Returned by `getSource` or `transformSource` | +| ------------ | ------------------------------ | -------------------------------------------------------------------------- | +| `'builtin'` | Load a Node.js builtin module | Not applicable | +| `'commonjs'` | Load a Node.js CommonJS module | Not applicable | +| `'json'` | Load a JSON file | { [`string`][], [`ArrayBuffer`][], [`TypedArray`][] } | +| `'module'` | Load an ES module | { [`string`][], [`ArrayBuffer`][], [`TypedArray`][] } | +| `'wasm'` | Load a WebAssembly module | { [`ArrayBuffer`][], [`TypedArray`][] } | Note: These types all correspond to classes defined in ECMAScript. @@ -664,10 +745,6 @@ export async function getSource(url, context, defaultGetSource) { #### `transformSource(source, context, defaultTransformSource)` -```console -NODE_OPTIONS='--experimental-loader ./custom-loader.mjs' node x.js -``` - > Note: The loaders API is being redesigned. This hook may disappear or its > signature may change. Do not rely on the API described below. @@ -745,38 +822,6 @@ const require = createRequire(process.cwd() + '/'); } ``` -#### dynamicInstantiate hook - -> Note: The loaders API is being redesigned. This hook may disappear or its -> signature may change. Do not rely on the API described below. - -To create a custom dynamic module that doesn't correspond to one of the -existing `format` interpretations, the `dynamicInstantiate` hook can be used. -This hook is called only for modules that return `format: 'dynamic'` from -the `getFormat` hook. - -```js -/** - * @param {string} url - * @returns {object} response - * @returns {array} response.exports - * @returns {function} response.execute - */ -export async function dynamicInstantiate(url) { - return { - exports: ['customExportName'], - execute: (exports) => { - // Get and set functions provided for pre-allocated export names - exports.customExportName.set('value'); - } - }; -} -``` - -With the list of module exports provided upfront, the `execute` function will -then be called at the exact point of module evaluation order for that module -in the import tree. - ### Examples The various loader hooks can be used together to accomplish wide-ranging @@ -985,6 +1030,8 @@ The resolver can throw the following errors: subpath in the package for the given module. * _Package Import Not Defined_: Package imports do not define the specifier. * _Module Not Found_: The package or module requested does not exist. +* _Unsupported Directory Import_: The resolved path corresponds to a directory, + which is not a supported target for module imports. ### Resolver Algorithm Specification @@ -1242,6 +1289,8 @@ _internal_, _conditions_) ### Customizing ESM specifier resolution algorithm +> Stability: 1 - Experimental + The current specifier resolution does not support all default behavior of the CommonJS loader. One of the behavior differences is automatic resolution of file extensions and the ability to import directories that have an index @@ -1263,34 +1312,39 @@ success! ``` -[CommonJS]: modules.html -[Conditional exports]: packages.html#packages_conditional_exports +[6.1.7 Array Index]: https://tc39.es/ecma262/#integer-index +[CommonJS]: modules.md +[Conditional exports]: packages.md#packages_conditional_exports +[Core modules]: modules.md#modules_core_modules [Dynamic `import()`]: https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports +[ECMAScript Top-Level `await` proposal]: https://github.com/tc39/proposal-top-level-await/ [ES Module Integration Proposal for Web Assembly]: https://github.com/webassembly/esm-integration +[Node.js Module Resolution Algorithm]: #esm_resolver_algorithm_specification [Terminology]: #esm_terminology +[URL]: https://url.spec.whatwg.org/ [WHATWG JSON modules specification]: https://html.spec.whatwg.org/#creating-a-json-module-script +[`"exports"`]: packages.md#packages_exports +[`"type"`]: packages.md#packages_type +[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer +[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer +[`TypedArray`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray +[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array [`data:` URLs]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs [`export`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export [`import()`]: #esm_import_expressions -[`import.meta.url`]: #esm_import_meta +[`import.meta.resolve`]: #esm_import_meta_resolve_specifier_parent +[`import.meta.url`]: #esm_import_meta_url [`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import -[`module.createRequire()`]: module.html#module_module_createrequire_filename -[`module.syncBuiltinESMExports()`]: module.html#module_module_syncbuiltinesmexports -[`transformSource` hook]: #esm_transformsource_source_context_defaulttransformsource -[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer -[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer +[`module.createRequire()`]: module.md#module_module_createrequire_filename +[`module.syncBuiltinESMExports()`]: module.md#module_module_syncbuiltinesmexports +[`package.json`]: packages.md#packages_node_js_package_json_field_definitions +[`process.dlopen`]: process.md#process_process_dlopen_module_filename_flags [`string`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String -[`TypedArray`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray -[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array -[dynamic instantiate hook]: #esm_code_dynamicinstantiate_code_hook +[`transformSource` hook]: #esm_transformsource_source_context_defaulttransformsource [`util.TextDecoder`]: util.md#util_class_util_textdecoder -[cjs-module-lexer]: https://github.com/guybedford/cjs-module-lexer/tree/1.2.1 +[cjs-module-lexer]: https://github.com/guybedford/cjs-module-lexer/tree/1.2.2 +[custom https loader]: #esm_https_loader [special scheme]: https://url.spec.whatwg.org/#special-scheme [the official standard format]: https://tc39.github.io/ecma262/#sec-modules [transpiler loader example]: #esm_transpiler_loader -[6.1.7 Array Index]: https://tc39.es/ecma262/#integer-index -[Top-Level Await]: https://github.com/tc39/proposal-top-level-await -[Core modules]: modules.html#modules_core_modules -[`package.json`]: packages.html#packages_node_js_package_json_field_definitions -[`"exports"`]: packages.html#packages_exports -[`"type"`]: packages.html#packages_type +[url.pathToFileURL]: url.md#url_url_pathtofileurl_path diff --git a/doc/api/events.html b/doc/api/events.html index 78cacec65ccf4af40dcfe384f246e3be526dcacc..c6320ad62a92470f20ca2c75a8fa8c2d135ef51b 100644 --- a/doc/api/events.html +++ b/doc/api/events.html @@ -1,10 +1,10 @@ - + - - Events | Node.js v12.22.7 Documentation + + Events | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      -
      -

      Table of Contents

      -
      + +
    • Class: NodeEventTarget + +
    • + + + + +
      -

      Events#

      +

      Events#

      Stability: 2 - Stable

      -

      Source Code: lib/events.js

      +

      Source Code: lib/events.js

      Much of the Node.js core API is built around an idiomatic asynchronous event-driven architecture in which certain kinds of objects (called "emitters") emit named events that cause Function objects ("listeners") to be called.

      @@ -191,28 +253,28 @@ event names are camel-cased strings but any valid JavaScript property key can be used.

      When the EventEmitter object emits an event, all of the functions attached to that specific event are called synchronously. Any values returned by the -called listeners are ignored and will be discarded.

      +called listeners are ignored and discarded.

      The following example shows a simple EventEmitter instance with a single listener. The eventEmitter.on() method is used to register listeners, while the eventEmitter.emit() method is used to trigger the event.

      -
      const EventEmitter = require('events');
      +
      const EventEmitter = require('events');
       
      -class MyEmitter extends EventEmitter {}
      +class MyEmitter extends EventEmitter {}
       
      -const myEmitter = new MyEmitter();
      -myEmitter.on('event', () => {
      -  console.log('an event occurred!');
      +const myEmitter = new MyEmitter();
      +myEmitter.on('event', () => {
      +  console.log('an event occurred!');
       });
      -myEmitter.emit('event');
      -

      Passing arguments and this to listeners#

      +myEmitter.emit('event');
      +

      Passing arguments and this to listeners#

      The eventEmitter.emit() method allows an arbitrary set of arguments to be passed to the listener functions. Keep in mind that when an ordinary listener function is called, the standard this keyword is intentionally set to reference the EventEmitter instance to which the listener is attached.

      -
      const myEmitter = new MyEmitter();
      -myEmitter.on('event', function(a, b) {
      -  console.log(a, b, this, this === myEmitter);
      +
      const myEmitter = new MyEmitter();
      +myEmitter.on('event', function(a, b) {
      +  console.log(a, b, this, this === myEmitter);
         // Prints:
         //   a b MyEmitter {
         //     domain: null,
      @@ -220,123 +282,126 @@ myEmitter.on('event', //     _eventsCount: 1,
         //     _maxListeners: undefined } true
       });
      -myEmitter.emit('event', 'a', 'b');
      +myEmitter.emit('event', 'a', 'b');

      It is possible to use ES6 Arrow Functions as listeners, however, when doing so, the this keyword will no longer reference the EventEmitter instance:

      -
      const myEmitter = new MyEmitter();
      -myEmitter.on('event', (a, b) => {
      -  console.log(a, b, this);
      +
      const myEmitter = new MyEmitter();
      +myEmitter.on('event', (a, b) => {
      +  console.log(a, b, this);
         // Prints: a b {}
       });
      -myEmitter.emit('event', 'a', 'b');
      -

      Asynchronous vs. synchronous#

      +myEmitter.emit('event', 'a', 'b');
      +

      Asynchronous vs. synchronous#

      The EventEmitter calls all listeners synchronously in the order in which they were registered. This ensures the proper sequencing of events and helps avoid race conditions and logic errors. When appropriate, listener functions can switch to an asynchronous mode of operation using the setImmediate() or process.nextTick() methods:

      -
      const myEmitter = new MyEmitter();
      -myEmitter.on('event', (a, b) => {
      -  setImmediate(() => {
      -    console.log('this happens asynchronously');
      +
      const myEmitter = new MyEmitter();
      +myEmitter.on('event', (a, b) => {
      +  setImmediate(() => {
      +    console.log('this happens asynchronously');
         });
       });
      -myEmitter.emit('event', 'a', 'b');
      -

      Handling events only once#

      +myEmitter.emit('event', 'a', 'b');
      +

      Handling events only once#

      When a listener is registered using the eventEmitter.on() method, that -listener will be invoked every time the named event is emitted.

      -
      const myEmitter = new MyEmitter();
      +listener is invoked every time the named event is emitted.

      +
      const myEmitter = new MyEmitter();
       let m = 0;
      -myEmitter.on('event', () => {
      -  console.log(++m);
      +myEmitter.on('event', () => {
      +  console.log(++m);
       });
      -myEmitter.emit('event');
      +myEmitter.emit('event');
       // Prints: 1
      -myEmitter.emit('event');
      +myEmitter.emit('event');
       // Prints: 2

      Using the eventEmitter.once() method, it is possible to register a listener that is called at most once for a particular event. Once the event is emitted, the listener is unregistered and then called.

      -
      const myEmitter = new MyEmitter();
      +
      const myEmitter = new MyEmitter();
       let m = 0;
      -myEmitter.once('event', () => {
      -  console.log(++m);
      +myEmitter.once('event', () => {
      +  console.log(++m);
       });
      -myEmitter.emit('event');
      +myEmitter.emit('event');
       // Prints: 1
      -myEmitter.emit('event');
      +myEmitter.emit('event');
       // Ignored
      -

      Error events#

      +

      Error events#

      When an error occurs within an EventEmitter instance, the typical action is for an 'error' event to be emitted. These are treated as special cases within Node.js.

      If an EventEmitter does not have at least one listener registered for the 'error' event, and an 'error' event is emitted, the error is thrown, a stack trace is printed, and the Node.js process exits.

      -
      const myEmitter = new MyEmitter();
      -myEmitter.emit('error', new Error('whoops!'));
      +
      const myEmitter = new MyEmitter();
      +myEmitter.emit('error', new Error('whoops!'));
       // Throws and crashes Node.js

      To guard against crashing the Node.js process the domain module can be used. (Note, however, that the domain module is deprecated.)

      As a best practice, listeners should always be added for the 'error' events.

      -
      const myEmitter = new MyEmitter();
      -myEmitter.on('error', (err) => {
      -  console.error('whoops! there was an error');
      +
      const myEmitter = new MyEmitter();
      +myEmitter.on('error', (err) => {
      +  console.error('whoops! there was an error');
       });
      -myEmitter.emit('error', new Error('whoops!'));
      +myEmitter.emit('error', new Error('whoops!'));
       // Prints: whoops! there was an error

      It is possible to monitor 'error' events without consuming the emitted error -by installing a listener using the symbol errorMonitor.

      -
      const myEmitter = new MyEmitter();
      -myEmitter.on(EventEmitter.errorMonitor, (err) => {
      -  MyMonitoringTool.log(err);
      +by installing a listener using the symbol events.errorMonitor.

      +
      const { EventEmitter, errorMonitor } = require('events');
      +
      +const myEmitter = new EventEmitter();
      +myEmitter.on(errorMonitor, (err) => {
      +  MyMonitoringTool.log(err);
       });
      -myEmitter.emit('error', new Error('whoops!'));
      +myEmitter.emit('error', new Error('whoops!'));
       // Still throws and crashes Node.js
      -

      Capture rejections of promises#

      +

      Capture rejections of promises#

      Stability: 1 - captureRejections is experimental.

      Using async functions with event handlers is problematic, because it can lead to an unhandled rejection in case of a thrown exception:

      -
      const ee = new EventEmitter();
      -ee.on('something', async (value) => {
      -  throw new Error('kaboom');
      +
      const ee = new EventEmitter();
      +ee.on('something', async (value) => {
      +  throw new Error('kaboom');
       });

      The captureRejections option in the EventEmitter constructor or the global setting change this behavior, installing a .then(undefined, handler) handler on the Promise. This handler routes the exception asynchronously to the Symbol.for('nodejs.rejection') method if there is one, or to 'error' event handler if there is none.

      -
      const ee1 = new EventEmitter({ captureRejections: true });
      -ee1.on('something', async (value) => {
      -  throw new Error('kaboom');
      +
      const ee1 = new EventEmitter({ captureRejections: true });
      +ee1.on('something', async (value) => {
      +  throw new Error('kaboom');
       });
       
      -ee1.on('error', console.log);
      +ee1.on('error', console.log);
       
      -const ee2 = new EventEmitter({ captureRejections: true });
      -ee2.on('something', async (value) => {
      -  throw new Error('kaboom');
      +const ee2 = new EventEmitter({ captureRejections: true });
      +ee2.on('something', async (value) => {
      +  throw new Error('kaboom');
       });
       
      -ee2[Symbol.for('nodejs.rejection')] = console.log;
      -

      Setting EventEmitter.captureRejections = true will change the default for all +ee2[Symbol.for('nodejs.rejection')] = console.log;

      +

      Setting events.captureRejections = true will change the default for all new instances of EventEmitter.

      -
      EventEmitter.captureRejections = true;
      -const ee1 = new EventEmitter();
      -ee1.on('something', async (value) => {
      -  throw new Error('kaboom');
      +
      const events = require('events');
      +events.captureRejections = true;
      +const ee1 = new events.EventEmitter();
      +ee1.on('something', async (value) => {
      +  throw new Error('kaboom');
       });
       
      -ee1.on('error', console.log);
      +ee1.on('error', console.log);

      The 'error' events that are generated by the captureRejections behavior do not have a catch handler to avoid infinite error loops: the recommendation is to not use async functions as 'error' event handlers.

      -

      Class: EventEmitter#

      +

      Class: EventEmitter#

      Creates a Promise that is fulfilled when the EventEmitter emits the given @@ -849,130 +941,174 @@ given event.

      This method is intentionally generic and works with the web platform EventTarget interface, which has no special 'error' event semantics and does not listen to the 'error' event.

      -
      const { once, EventEmitter } = require('events');
      +
      const { once, EventEmitter } = require('events');
       
      -async function run() {
      -  const ee = new EventEmitter();
      +async function run() {
      +  const ee = new EventEmitter();
       
      -  process.nextTick(() => {
      -    ee.emit('myevent', 42);
      +  process.nextTick(() => {
      +    ee.emit('myevent', 42);
         });
       
      -  const [value] = await once(ee, 'myevent');
      -  console.log(value);
      +  const [value] = await once(ee, 'myevent');
      +  console.log(value);
       
      -  const err = new Error('kaboom');
      -  process.nextTick(() => {
      -    ee.emit('error', err);
      +  const err = new Error('kaboom');
      +  process.nextTick(() => {
      +    ee.emit('error', err);
         });
       
         try {
      -    await once(ee, 'myevent');
      +    await once(ee, 'myevent');
         } catch (err) {
      -    console.log('error happened', err);
      +    console.log('error happened', err);
         }
       }
       
      -run();
      +run();

      The special handling of the 'error' event is only used when events.once() is used to wait for another event. If events.once() is used to wait for the 'error' event itself, then it is treated as any other kind of event without special handling:

      -
      const { EventEmitter, once } = require('events');
      +
      const { EventEmitter, once } = require('events');
       
      -const ee = new EventEmitter();
      +const ee = new EventEmitter();
       
      -once(ee, 'error')
      -  .then(([err]) => console.log('ok', err.message))
      -  .catch((err) => console.log('error', err.message));
      +once(ee, 'error')
      +  .then(([err]) => console.log('ok', err.message))
      +  .catch((err) => console.log('error', err.message));
       
      -ee.emit('error', new Error('boom'));
      +ee.emit('error', new Error('boom'));
       
       // Prints: ok boom
      -

      Awaiting multiple events emitted on process.nextTick()#

      +

      An <AbortSignal> can be used to cancel waiting for the event:

      +
      const { EventEmitter, once } = require('events');
      +
      +const ee = new EventEmitter();
      +const ac = new AbortController();
      +
      +async function foo(emitter, event, signal) {
      +  try {
      +    await once(emitter, event, { signal });
      +    console.log('event emitted!');
      +  } catch (error) {
      +    if (error.name === 'AbortError') {
      +      console.error('Waiting for the event was canceled!');
      +    } else {
      +      console.error('There was an error', error.message);
      +    }
      +  }
      +}
      +
      +foo(ee, 'foo', ac.signal);
      +ac.abort(); // Abort waiting for the event
      +ee.emit('foo'); // Prints: Waiting for the event was canceled!
      +

      Awaiting multiple events emitted on process.nextTick()#

      There is an edge case worth noting when using the events.once() function to await multiple events emitted on in the same batch of process.nextTick() operations, or whenever multiple events are emitted synchronously. Specifically, because the process.nextTick() queue is drained before the Promise microtask queue, and because EventEmitter emits all events synchronously, it is possible for events.once() to miss an event.

      -
      const { EventEmitter, once } = require('events');
      +
      const { EventEmitter, once } = require('events');
       
      -const myEE = new EventEmitter();
      +const myEE = new EventEmitter();
       
      -async function foo() {
      -  await once(myEE, 'bar');
      -  console.log('bar');
      +async function foo() {
      +  await once(myEE, 'bar');
      +  console.log('bar');
       
         // This Promise will never resolve because the 'foo' event will
         // have already been emitted before the Promise is created.
      -  await once(myEE, 'foo');
      -  console.log('foo');
      +  await once(myEE, 'foo');
      +  console.log('foo');
       }
       
      -process.nextTick(() => {
      -  myEE.emit('bar');
      -  myEE.emit('foo');
      +process.nextTick(() => {
      +  myEE.emit('bar');
      +  myEE.emit('foo');
       });
       
      -foo().then(() => console.log('done'));
      +foo().then(() => console.log('done'));

      To catch both events, create each of the Promises before awaiting either of them, then it becomes possible to use Promise.all(), Promise.race(), or Promise.allSettled():

      -
      const { EventEmitter, once } = require('events');
      +
      const { EventEmitter, once } = require('events');
       
      -const myEE = new EventEmitter();
      +const myEE = new EventEmitter();
       
      -async function foo() {
      -  await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')]);
      -  console.log('foo', 'bar');
      +async function foo() {
      +  await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')]);
      +  console.log('foo', 'bar');
       }
       
      -process.nextTick(() => {
      -  myEE.emit('bar');
      -  myEE.emit('foo');
      +process.nextTick(() => {
      +  myEE.emit('bar');
      +  myEE.emit('foo');
       });
       
      -foo().then(() => console.log('done'));
      -

      events.captureRejections#

      +foo().then(() => console.log('done'));
      +

      events.captureRejections#

      Stability: 1 - captureRejections is experimental.

      Value: <boolean>

      Change the default captureRejections option on all new EventEmitter objects.

      -

      events.captureRejectionSymbol#

      +

      events.captureRejectionSymbol#

      Stability: 1 - captureRejections is experimental.

      Value: Symbol.for('nodejs.rejection')

      See how to write a custom rejection handler.

      -

      events.on(emitter, eventName)[src]#

      +

      events.listenerCount(emitter, eventName)#

      +

      Stability: 0 - Deprecated: Use emitter.listenerCount() instead.

      + +

      A class method that returns the number of listeners for the given eventName +registered on the given emitter.

      +
      const { EventEmitter, listenerCount } = require('events');
      +const myEmitter = new EventEmitter();
      +myEmitter.on('event', () => {});
      +myEmitter.on('event', () => {});
      +console.log(listenerCount(myEmitter, 'event'));
      +// Prints: 2
      +

      events.on(emitter, eventName[, options])#

      + -
      const { on, EventEmitter } = require('events');
      +
      const { on, EventEmitter } = require('events');
       
       (async () => {
      -  const ee = new EventEmitter();
      +  const ee = new EventEmitter();
       
         // Emit later on
      -  process.nextTick(() => {
      -    ee.emit('foo', 'bar');
      -    ee.emit('foo', 42);
      +  process.nextTick(() => {
      +    ee.emit('foo', 'bar');
      +    ee.emit('foo', 42);
         });
       
      -  for await (const event of on(ee, 'foo')) {
      +  for await (const event of on(ee, 'foo')) {
           // The execution of this inner block is synchronous and it
           // processes one event at a time (even with await). Do not use
           // if concurrent execution is required.
      -    console.log(event); // prints ['bar'] [42]
      +    console.log(event); // prints ['bar'] [42]
         }
         // Unreachable here
       })();
      @@ -980,9 +1116,541 @@ foo().then(() => if the EventEmitter emits 'error'. It removes all listeners when exiting the loop. The value returned by each iteration is an array composed of the emitted event arguments.

      +

      An <AbortSignal> can be used to cancel waiting on events:

      +
      const { on, EventEmitter } = require('events');
      +const ac = new AbortController();
      +
      +(async () => {
      +  const ee = new EventEmitter();
      +
      +  // Emit later on
      +  process.nextTick(() => {
      +    ee.emit('foo', 'bar');
      +    ee.emit('foo', 42);
      +  });
      +
      +  for await (const event of on(ee, 'foo', { signal: ac.signal })) {
      +    // The execution of this inner block is synchronous and it
      +    // processes one event at a time (even with await). Do not use
      +    // if concurrent execution is required.
      +    console.log(event); // prints ['bar'] [42]
      +  }
      +  // Unreachable here
      +})();
      +
      +process.nextTick(() => ac.abort());
      +

      events.setMaxListeners(n[, ...eventTargets])#

      + + +
      const {
      +  setMaxListeners,
      +  EventEmitter
      +} = require('events');
      +
      +const target = new EventTarget();
      +const emitter = new EventEmitter();
      +
      +setMaxListeners(5, target, emitter);
      +

      +

      EventTarget and Event API#

      + +

      Stability: 1 - Experimental

      +

      The EventTarget and Event objects are a Node.js-specific implementation +of the EventTarget Web API that are exposed by some Node.js core APIs. +Neither the EventTarget nor Event classes are available for end +user code to create.

      +
      const target = getEventTargetSomehow();
      +
      +target.addEventListener('foo', (event) => {
      +  console.log('foo event happened!');
      +});
      +

      Node.js EventTarget vs. DOM EventTarget#

      +

      There are two key differences between the Node.js EventTarget and the +EventTarget Web API:

      +
        +
      1. Whereas DOM EventTarget instances may be hierarchical, there is no +concept of hierarchy and event propagation in Node.js. That is, an event +dispatched to an EventTarget does not propagate through a hierarchy of +nested target objects that may each have their own set of handlers for the +event.
      2. +
      3. In the Node.js EventTarget, if an event listener is an async function +or returns a Promise, and the returned Promise rejects, the rejection +is automatically captured and handled the same way as a listener that +throws synchronously (see EventTarget error handling for details).
      4. +
      +

      NodeEventTarget vs. EventEmitter#

      +

      The NodeEventTarget object implements a modified subset of the +EventEmitter API that allows it to closely emulate an EventEmitter in +certain situations. A NodeEventTarget is not an instance of EventEmitter +and cannot be used in place of an EventEmitter in most cases.

      +
        +
      1. Unlike EventEmitter, any given listener can be registered at most once +per event type. Attempts to register a listener multiple times are +ignored.
      2. +
      3. The NodeEventTarget does not emulate the full EventEmitter API. +Specifically the prependListener(), prependOnceListener(), +rawListeners(), setMaxListeners(), getMaxListeners(), and +errorMonitor APIs are not emulated. The 'newListener' and +'removeListener' events will also not be emitted.
      4. +
      5. The NodeEventTarget does not implement any special default behavior +for events with type 'error'.
      6. +
      7. The NodeEventTarget supports EventListener objects as well as +functions as handlers for all event types.
      8. +
      +

      Event listener#

      +

      Event listeners registered for an event type may either be JavaScript +functions or objects with a handleEvent property whose value is a function.

      +

      In either case, the handler function is invoked with the event argument +passed to the eventTarget.dispatchEvent() function.

      +

      Async functions may be used as event listeners. If an async handler function +rejects, the rejection is captured and handled as described in +EventTarget error handling.

      +

      An error thrown by one handler function does not prevent the other handlers +from being invoked.

      +

      The return value of a handler function is ignored.

      +

      Handlers are always invoked in the order they were added.

      +

      Handler functions may mutate the event object.

      +
      function handler1(event) {
      +  console.log(event.type);  // Prints 'foo'
      +  event.a = 1;
      +}
      +
      +async function handler2(event) {
      +  console.log(event.type);  // Prints 'foo'
      +  console.log(event.a);  // Prints 1
      +}
      +
      +const handler3 = {
      +  handleEvent(event) {
      +    console.log(event.type);  // Prints 'foo'
      +  }
      +};
      +
      +const handler4 = {
      +  async handleEvent(event) {
      +    console.log(event.type);  // Prints 'foo'
      +  }
      +};
      +
      +const target = getEventTargetSomehow();
      +
      +target.addEventListener('foo', handler1);
      +target.addEventListener('foo', handler2);
      +target.addEventListener('foo', handler3);
      +target.addEventListener('foo', handler4, { once: true });
      +

      EventTarget error handling#

      +

      When a registered event listener throws (or returns a Promise that rejects), +by default the error is treated as an uncaught exception on +process.nextTick(). This means uncaught exceptions in EventTargets will +terminate the Node.js process by default.

      +

      Throwing within an event listener will not stop the other registered handlers +from being invoked.

      +

      The EventTarget does not implement any special default handling for 'error' +type events like EventEmitter.

      +

      Currently errors are first forwarded to the process.on('error') event +before reaching process.on('uncaughtException'). This behavior is +deprecated and will change in a future release to align EventTarget with +other Node.js APIs. Any code relying on the process.on('error') event should +be aligned with the new behavior.

      +

      Class: Event#

      + +

      The Event object is an adaptation of the Event Web API. Instances +are created internally by Node.js.

      +
      event.bubbles#
      + + +

      This is not used in Node.js and is provided purely for completeness.

      +
      event.cancelBubble()#
      + +

      Alias for event.stopPropagation(). This is not used in Node.js and is +provided purely for completeness.

      +
      event.cancelable#
      + +
        +
      • Type: <boolean> True if the event was created with the cancelable option.
      • +
      +
      event.composed#
      + + +

      This is not used in Node.js and is provided purely for completeness.

      +
      event.composedPath()#
      + +

      Returns an array containing the current EventTarget as the only entry or +empty if the event is not being dispatched. This is not used in +Node.js and is provided purely for completeness.

      +
      event.currentTarget#
      + + +

      Alias for event.target.

      +
      event.defaultPrevented#
      + + +

      Is true if cancelable is true and event.preventDefault() has been +called.

      +
      event.eventPhase#
      + +
        +
      • Type: <number> Returns 0 while an event is not being dispatched, 2 while +it is being dispatched.
      • +
      +

      This is not used in Node.js and is provided purely for completeness.

      +
      event.isTrusted#
      + + +

      The <AbortSignal> "abort" event is emitted with isTrusted set to true. The +value is false in all other cases.

      +
      event.preventDefault()#
      + +

      Sets the defaultPrevented property to true if cancelable is true.

      +
      event.returnValue#
      + +
        +
      • Type: <boolean> True if the event has not been canceled.
      • +
      +

      This is not used in Node.js and is provided purely for completeness.

      +
      event.srcElement#
      + + +

      Alias for event.target.

      +
      event.stopImmediatePropagation()#
      + +

      Stops the invocation of event listeners after the current one completes.

      +
      event.stopPropagation()#
      + +

      This is not used in Node.js and is provided purely for completeness.

      +
      event.target#
      + + +
      event.timeStamp#
      + + +

      The millisecond timestamp when the Event object was created.

      +
      event.type#
      + + +

      The event type identifier.

      +

      Class: EventTarget#

      + +
      eventTarget.addEventListener(type, listener[, options])#
      + +
        +
      • type <string>
      • +
      • listener <Function> | <EventListener>
      • +
      • options <Object> +
          +
        • once <boolean> When true, the listener is automatically removed +when it is first invoked. Default: false.
        • +
        • passive <boolean> When true, serves as a hint that the listener will +not call the Event object's preventDefault() method. +Default: false.
        • +
        • capture <boolean> Not directly used by Node.js. Added for API +completeness. Default: false.
        • +
        +
      • +
      +

      Adds a new handler for the type event. Any given listener is added +only once per type and per capture option value.

      +

      If the once option is true, the listener is removed after the +next time a type event is dispatched.

      +

      The capture option is not used by Node.js in any functional way other than +tracking registered event listeners per the EventTarget specification. +Specifically, the capture option is used as part of the key when registering +a listener. Any individual listener may be added once with +capture = false, and once with capture = true.

      +
      function handler(event) {}
      +
      +const target = getEventTargetSomehow();
      +target.addEventListener('foo', handler, { capture: true });  // first
      +target.addEventListener('foo', handler, { capture: false }); // second
      +
      +// Removes the second instance of handler
      +target.removeEventListener('foo', handler);
      +
      +// Removes the first instance of handler
      +target.removeEventListener('foo', handler, { capture: true });
      +
      eventTarget.dispatchEvent(event)#
      + +
        +
      • event <Event>
      • +
      • Returns: <boolean> true if either event’s cancelable attribute value is +false or its preventDefault() method was not invoked, otherwise false.
      • +
      +

      Dispatches the event to the list of handlers for event.type.

      +

      The registered event listeners is synchronously invoked in the order they +were registered.

      +
      eventTarget.removeEventListener(type, listener)#
      + + +

      Removes the listener from the list of handlers for event type.

      +

      Class: NodeEventTarget#

      + + +

      The NodeEventTarget is a Node.js-specific extension to EventTarget +that emulates a subset of the EventEmitter API.

      +
      nodeEventTarget.addListener(type, listener[, options])#
      + + +

      Node.js-specific extension to the EventTarget class that emulates the +equivalent EventEmitter API. The only difference between addListener() and +addEventListener() is that addListener() will return a reference to the +EventTarget.

      +
      nodeEventTarget.eventNames()#
      + + +

      Node.js-specific extension to the EventTarget class that returns an array +of event type names for which event listeners are registered.

      +
      nodeEventTarget.listenerCount(type)#
      + + +

      Node.js-specific extension to the EventTarget class that returns the number +of event listeners registered for the type.

      +
      nodeEventTarget.off(type, listener)#
      + + +

      Node.js-specific alias for eventTarget.removeListener().

      +
      nodeEventTarget.on(type, listener[, options])#
      + + +

      Node.js-specific alias for eventTarget.addListener().

      +
      nodeEventTarget.once(type, listener[, options])#
      + + +

      Node.js-specific extension to the EventTarget class that adds a once +listener for the given event type. This is equivalent to calling on +with the once option set to true.

      +
      nodeEventTarget.removeAllListeners([type])#
      + + +

      Node.js-specific extension to the EventTarget class. If type is specified, +removes all registered listeners for type, otherwise removes all registered +listeners.

      +
      nodeEventTarget.removeListener(type, listener)#
      + + +

      Node.js-specific extension to the EventTarget class that removes the +listener for the given type. The only difference between removeListener() +and removeEventListener() is that removeListener() will return a reference +to the EventTarget.

      + diff --git a/doc/api/events.json b/doc/api/events.json index ea26248e603826eb7140b5e329c646e7bd3e429f..051c8ae90a0d336de5ba37fd3facea20fa86a706 100644 --- a/doc/api/events.json +++ b/doc/api/events.json @@ -9,7 +9,7 @@ "stability": 2, "stabilityText": "Stable", "type": "module", - "desc": "

      Source Code: lib/events.js

      \n

      Much of the Node.js core API is built around an idiomatic asynchronous\nevent-driven architecture in which certain kinds of objects (called \"emitters\")\nemit named events that cause Function objects (\"listeners\") to be called.

      \n

      For instance: a net.Server object emits an event each time a peer\nconnects to it; a fs.ReadStream emits an event when the file is opened;\na stream emits an event whenever data is available to be read.

      \n

      All objects that emit events are instances of the EventEmitter class. These\nobjects expose an eventEmitter.on() function that allows one or more\nfunctions to be attached to named events emitted by the object. Typically,\nevent names are camel-cased strings but any valid JavaScript property key\ncan be used.

      \n

      When the EventEmitter object emits an event, all of the functions attached\nto that specific event are called synchronously. Any values returned by the\ncalled listeners are ignored and will be discarded.

      \n

      The following example shows a simple EventEmitter instance with a single\nlistener. The eventEmitter.on() method is used to register listeners, while\nthe eventEmitter.emit() method is used to trigger the event.

      \n
      const EventEmitter = require('events');\n\nclass MyEmitter extends EventEmitter {}\n\nconst myEmitter = new MyEmitter();\nmyEmitter.on('event', () => {\n  console.log('an event occurred!');\n});\nmyEmitter.emit('event');\n
      ", + "desc": "

      Source Code: lib/events.js

      \n

      Much of the Node.js core API is built around an idiomatic asynchronous\nevent-driven architecture in which certain kinds of objects (called \"emitters\")\nemit named events that cause Function objects (\"listeners\") to be called.

      \n

      For instance: a net.Server object emits an event each time a peer\nconnects to it; a fs.ReadStream emits an event when the file is opened;\na stream emits an event whenever data is available to be read.

      \n

      All objects that emit events are instances of the EventEmitter class. These\nobjects expose an eventEmitter.on() function that allows one or more\nfunctions to be attached to named events emitted by the object. Typically,\nevent names are camel-cased strings but any valid JavaScript property key\ncan be used.

      \n

      When the EventEmitter object emits an event, all of the functions attached\nto that specific event are called synchronously. Any values returned by the\ncalled listeners are ignored and discarded.

      \n

      The following example shows a simple EventEmitter instance with a single\nlistener. The eventEmitter.on() method is used to register listeners, while\nthe eventEmitter.emit() method is used to trigger the event.

      \n
      const EventEmitter = require('events');\n\nclass MyEmitter extends EventEmitter {}\n\nconst myEmitter = new MyEmitter();\nmyEmitter.on('event', () => {\n  console.log('an event occurred!');\n});\nmyEmitter.emit('event');\n
      ", "modules": [ { "textRaw": "Passing arguments and `this` to listeners", @@ -28,14 +28,14 @@ { "textRaw": "Handling events only once", "name": "handling_events_only_once", - "desc": "

      When a listener is registered using the eventEmitter.on() method, that\nlistener will be invoked every time the named event is emitted.

      \n
      const myEmitter = new MyEmitter();\nlet m = 0;\nmyEmitter.on('event', () => {\n  console.log(++m);\n});\nmyEmitter.emit('event');\n// Prints: 1\nmyEmitter.emit('event');\n// Prints: 2\n
      \n

      Using the eventEmitter.once() method, it is possible to register a listener\nthat is called at most once for a particular event. Once the event is emitted,\nthe listener is unregistered and then called.

      \n
      const myEmitter = new MyEmitter();\nlet m = 0;\nmyEmitter.once('event', () => {\n  console.log(++m);\n});\nmyEmitter.emit('event');\n// Prints: 1\nmyEmitter.emit('event');\n// Ignored\n
      ", + "desc": "

      When a listener is registered using the eventEmitter.on() method, that\nlistener is invoked every time the named event is emitted.

      \n
      const myEmitter = new MyEmitter();\nlet m = 0;\nmyEmitter.on('event', () => {\n  console.log(++m);\n});\nmyEmitter.emit('event');\n// Prints: 1\nmyEmitter.emit('event');\n// Prints: 2\n
      \n

      Using the eventEmitter.once() method, it is possible to register a listener\nthat is called at most once for a particular event. Once the event is emitted,\nthe listener is unregistered and then called.

      \n
      const myEmitter = new MyEmitter();\nlet m = 0;\nmyEmitter.once('event', () => {\n  console.log(++m);\n});\nmyEmitter.emit('event');\n// Prints: 1\nmyEmitter.emit('event');\n// Ignored\n
      ", "type": "module", "displayName": "Handling events only once" }, { "textRaw": "Error events", "name": "error_events", - "desc": "

      When an error occurs within an EventEmitter instance, the typical action is\nfor an 'error' event to be emitted. These are treated as special cases\nwithin Node.js.

      \n

      If an EventEmitter does not have at least one listener registered for the\n'error' event, and an 'error' event is emitted, the error is thrown, a\nstack trace is printed, and the Node.js process exits.

      \n
      const myEmitter = new MyEmitter();\nmyEmitter.emit('error', new Error('whoops!'));\n// Throws and crashes Node.js\n
      \n

      To guard against crashing the Node.js process the domain module can be\nused. (Note, however, that the domain module is deprecated.)

      \n

      As a best practice, listeners should always be added for the 'error' events.

      \n
      const myEmitter = new MyEmitter();\nmyEmitter.on('error', (err) => {\n  console.error('whoops! there was an error');\n});\nmyEmitter.emit('error', new Error('whoops!'));\n// Prints: whoops! there was an error\n
      \n

      It is possible to monitor 'error' events without consuming the emitted error\nby installing a listener using the symbol errorMonitor.

      \n
      const myEmitter = new MyEmitter();\nmyEmitter.on(EventEmitter.errorMonitor, (err) => {\n  MyMonitoringTool.log(err);\n});\nmyEmitter.emit('error', new Error('whoops!'));\n// Still throws and crashes Node.js\n
      ", + "desc": "

      When an error occurs within an EventEmitter instance, the typical action is\nfor an 'error' event to be emitted. These are treated as special cases\nwithin Node.js.

      \n

      If an EventEmitter does not have at least one listener registered for the\n'error' event, and an 'error' event is emitted, the error is thrown, a\nstack trace is printed, and the Node.js process exits.

      \n
      const myEmitter = new MyEmitter();\nmyEmitter.emit('error', new Error('whoops!'));\n// Throws and crashes Node.js\n
      \n

      To guard against crashing the Node.js process the domain module can be\nused. (Note, however, that the domain module is deprecated.)

      \n

      As a best practice, listeners should always be added for the 'error' events.

      \n
      const myEmitter = new MyEmitter();\nmyEmitter.on('error', (err) => {\n  console.error('whoops! there was an error');\n});\nmyEmitter.emit('error', new Error('whoops!'));\n// Prints: whoops! there was an error\n
      \n

      It is possible to monitor 'error' events without consuming the emitted error\nby installing a listener using the symbol events.errorMonitor.

      \n
      const { EventEmitter, errorMonitor } = require('events');\n\nconst myEmitter = new EventEmitter();\nmyEmitter.on(errorMonitor, (err) => {\n  MyMonitoringTool.log(err);\n});\nmyEmitter.emit('error', new Error('whoops!'));\n// Still throws and crashes Node.js\n
      ", "type": "module", "displayName": "Error events" }, @@ -44,9 +44,737 @@ "name": "capture_rejections_of_promises", "stability": 1, "stabilityText": "captureRejections is experimental.", - "desc": "

      Using async functions with event handlers is problematic, because it\ncan lead to an unhandled rejection in case of a thrown exception:

      \n
      const ee = new EventEmitter();\nee.on('something', async (value) => {\n  throw new Error('kaboom');\n});\n
      \n

      The captureRejections option in the EventEmitter constructor or the global\nsetting change this behavior, installing a .then(undefined, handler)\nhandler on the Promise. This handler routes the exception\nasynchronously to the Symbol.for('nodejs.rejection') method\nif there is one, or to 'error' event handler if there is none.

      \n
      const ee1 = new EventEmitter({ captureRejections: true });\nee1.on('something', async (value) => {\n  throw new Error('kaboom');\n});\n\nee1.on('error', console.log);\n\nconst ee2 = new EventEmitter({ captureRejections: true });\nee2.on('something', async (value) => {\n  throw new Error('kaboom');\n});\n\nee2[Symbol.for('nodejs.rejection')] = console.log;\n
      \n

      Setting EventEmitter.captureRejections = true will change the default for all\nnew instances of EventEmitter.

      \n
      EventEmitter.captureRejections = true;\nconst ee1 = new EventEmitter();\nee1.on('something', async (value) => {\n  throw new Error('kaboom');\n});\n\nee1.on('error', console.log);\n
      \n

      The 'error' events that are generated by the captureRejections behavior\ndo not have a catch handler to avoid infinite error loops: the\nrecommendation is to not use async functions as 'error' event handlers.

      ", + "desc": "

      Using async functions with event handlers is problematic, because it\ncan lead to an unhandled rejection in case of a thrown exception:

      \n
      const ee = new EventEmitter();\nee.on('something', async (value) => {\n  throw new Error('kaboom');\n});\n
      \n

      The captureRejections option in the EventEmitter constructor or the global\nsetting change this behavior, installing a .then(undefined, handler)\nhandler on the Promise. This handler routes the exception\nasynchronously to the Symbol.for('nodejs.rejection') method\nif there is one, or to 'error' event handler if there is none.

      \n
      const ee1 = new EventEmitter({ captureRejections: true });\nee1.on('something', async (value) => {\n  throw new Error('kaboom');\n});\n\nee1.on('error', console.log);\n\nconst ee2 = new EventEmitter({ captureRejections: true });\nee2.on('something', async (value) => {\n  throw new Error('kaboom');\n});\n\nee2[Symbol.for('nodejs.rejection')] = console.log;\n
      \n

      Setting events.captureRejections = true will change the default for all\nnew instances of EventEmitter.

      \n
      const events = require('events');\nevents.captureRejections = true;\nconst ee1 = new events.EventEmitter();\nee1.on('something', async (value) => {\n  throw new Error('kaboom');\n});\n\nee1.on('error', console.log);\n
      \n

      The 'error' events that are generated by the captureRejections behavior\ndo not have a catch handler to avoid infinite error loops: the\nrecommendation is to not use async functions as 'error' event handlers.

      ", "type": "module", "displayName": "Capture rejections of promises" + }, + { + "textRaw": "`EventTarget` and `Event` API", + "name": "`eventtarget`_and_`event`_api", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "stability": 1, + "stabilityText": "Experimental", + "desc": "

      The EventTarget and Event objects are a Node.js-specific implementation\nof the EventTarget Web API that are exposed by some Node.js core APIs.\nNeither the EventTarget nor Event classes are available for end\nuser code to create.

      \n
      const target = getEventTargetSomehow();\n\ntarget.addEventListener('foo', (event) => {\n  console.log('foo event happened!');\n});\n
      ", + "modules": [ + { + "textRaw": "Node.js `EventTarget` vs. DOM `EventTarget`", + "name": "node.js_`eventtarget`_vs._dom_`eventtarget`", + "desc": "

      There are two key differences between the Node.js EventTarget and the\nEventTarget Web API:

      \n
        \n
      1. Whereas DOM EventTarget instances may be hierarchical, there is no\nconcept of hierarchy and event propagation in Node.js. That is, an event\ndispatched to an EventTarget does not propagate through a hierarchy of\nnested target objects that may each have their own set of handlers for the\nevent.
      2. \n
      3. In the Node.js EventTarget, if an event listener is an async function\nor returns a Promise, and the returned Promise rejects, the rejection\nis automatically captured and handled the same way as a listener that\nthrows synchronously (see EventTarget error handling for details).
      4. \n
      ", + "type": "module", + "displayName": "Node.js `EventTarget` vs. DOM `EventTarget`" + }, + { + "textRaw": "`NodeEventTarget` vs. `EventEmitter`", + "name": "`nodeeventtarget`_vs._`eventemitter`", + "desc": "

      The NodeEventTarget object implements a modified subset of the\nEventEmitter API that allows it to closely emulate an EventEmitter in\ncertain situations. A NodeEventTarget is not an instance of EventEmitter\nand cannot be used in place of an EventEmitter in most cases.

      \n
        \n
      1. Unlike EventEmitter, any given listener can be registered at most once\nper event type. Attempts to register a listener multiple times are\nignored.
      2. \n
      3. The NodeEventTarget does not emulate the full EventEmitter API.\nSpecifically the prependListener(), prependOnceListener(),\nrawListeners(), setMaxListeners(), getMaxListeners(), and\nerrorMonitor APIs are not emulated. The 'newListener' and\n'removeListener' events will also not be emitted.
      4. \n
      5. The NodeEventTarget does not implement any special default behavior\nfor events with type 'error'.
      6. \n
      7. The NodeEventTarget supports EventListener objects as well as\nfunctions as handlers for all event types.
      8. \n
      ", + "type": "module", + "displayName": "`NodeEventTarget` vs. `EventEmitter`" + }, + { + "textRaw": "Event listener", + "name": "event_listener", + "desc": "

      Event listeners registered for an event type may either be JavaScript\nfunctions or objects with a handleEvent property whose value is a function.

      \n

      In either case, the handler function is invoked with the event argument\npassed to the eventTarget.dispatchEvent() function.

      \n

      Async functions may be used as event listeners. If an async handler function\nrejects, the rejection is captured and handled as described in\nEventTarget error handling.

      \n

      An error thrown by one handler function does not prevent the other handlers\nfrom being invoked.

      \n

      The return value of a handler function is ignored.

      \n

      Handlers are always invoked in the order they were added.

      \n

      Handler functions may mutate the event object.

      \n
      function handler1(event) {\n  console.log(event.type);  // Prints 'foo'\n  event.a = 1;\n}\n\nasync function handler2(event) {\n  console.log(event.type);  // Prints 'foo'\n  console.log(event.a);  // Prints 1\n}\n\nconst handler3 = {\n  handleEvent(event) {\n    console.log(event.type);  // Prints 'foo'\n  }\n};\n\nconst handler4 = {\n  async handleEvent(event) {\n    console.log(event.type);  // Prints 'foo'\n  }\n};\n\nconst target = getEventTargetSomehow();\n\ntarget.addEventListener('foo', handler1);\ntarget.addEventListener('foo', handler2);\ntarget.addEventListener('foo', handler3);\ntarget.addEventListener('foo', handler4, { once: true });\n
      ", + "type": "module", + "displayName": "Event listener" + }, + { + "textRaw": "`EventTarget` error handling", + "name": "`eventtarget`_error_handling", + "desc": "

      When a registered event listener throws (or returns a Promise that rejects),\nby default the error is treated as an uncaught exception on\nprocess.nextTick(). This means uncaught exceptions in EventTargets will\nterminate the Node.js process by default.

      \n

      Throwing within an event listener will not stop the other registered handlers\nfrom being invoked.

      \n

      The EventTarget does not implement any special default handling for 'error'\ntype events like EventEmitter.

      \n

      Currently errors are first forwarded to the process.on('error') event\nbefore reaching process.on('uncaughtException'). This behavior is\ndeprecated and will change in a future release to align EventTarget with\nother Node.js APIs. Any code relying on the process.on('error') event should\nbe aligned with the new behavior.

      ", + "type": "module", + "displayName": "`EventTarget` error handling" + } + ], + "classes": [ + { + "textRaw": "Class: `Event`", + "type": "class", + "name": "Event", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      The Event object is an adaptation of the Event Web API. Instances\nare created internally by Node.js.

      ", + "properties": [ + { + "textRaw": "`bubbles` Type: {boolean} Always returns `false`.", + "type": "boolean", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      This is not used in Node.js and is provided purely for completeness.

      ", + "shortDesc": "Always returns `false`." + }, + { + "textRaw": "`cancelable` Type: {boolean} True if the event was created with the `cancelable` option.", + "type": "boolean", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "True if the event was created with the `cancelable` option." + }, + { + "textRaw": "`composed` Type: {boolean} Always returns `false`.", + "type": "boolean", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      This is not used in Node.js and is provided purely for completeness.

      ", + "shortDesc": "Always returns `false`." + }, + { + "textRaw": "`currentTarget` Type: {EventTarget} The `EventTarget` dispatching the event.", + "type": "EventTarget", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      Alias for event.target.

      ", + "shortDesc": "The `EventTarget` dispatching the event." + }, + { + "textRaw": "`defaultPrevented` Type: {boolean}", + "type": "boolean", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      Is true if cancelable is true and event.preventDefault() has been\ncalled.

      " + }, + { + "textRaw": "`eventPhase` Type: {number} Returns `0` while an event is not being dispatched, `2` while it is being dispatched.", + "type": "number", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      This is not used in Node.js and is provided purely for completeness.

      ", + "shortDesc": "Returns `0` while an event is not being dispatched, `2` while it is being dispatched." + }, + { + "textRaw": "`isTrusted` Type: {boolean}", + "type": "boolean", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      The <AbortSignal> \"abort\" event is emitted with isTrusted set to true. The\nvalue is false in all other cases.

      " + }, + { + "textRaw": "`returnValue` Type: {boolean} True if the event has not been canceled.", + "type": "boolean", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      This is not used in Node.js and is provided purely for completeness.

      ", + "shortDesc": "True if the event has not been canceled." + }, + { + "textRaw": "`srcElement` Type: {EventTarget} The `EventTarget` dispatching the event.", + "type": "EventTarget", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      Alias for event.target.

      ", + "shortDesc": "The `EventTarget` dispatching the event." + }, + { + "textRaw": "`target` Type: {EventTarget} The `EventTarget` dispatching the event.", + "type": "EventTarget", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "The `EventTarget` dispatching the event." + }, + { + "textRaw": "`timeStamp` Type: {number}", + "type": "number", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      The millisecond timestamp when the Event object was created.

      " + }, + { + "textRaw": "`type` Type: {string}", + "type": "string", + "name": "Type", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      The event type identifier.

      " + } + ], + "methods": [ + { + "textRaw": "`event.cancelBubble()`", + "type": "method", + "name": "cancelBubble", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      Alias for event.stopPropagation(). This is not used in Node.js and is\nprovided purely for completeness.

      " + }, + { + "textRaw": "`event.composedPath()`", + "type": "method", + "name": "composedPath", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      Returns an array containing the current EventTarget as the only entry or\nempty if the event is not being dispatched. This is not used in\nNode.js and is provided purely for completeness.

      " + }, + { + "textRaw": "`event.preventDefault()`", + "type": "method", + "name": "preventDefault", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      Sets the defaultPrevented property to true if cancelable is true.

      " + }, + { + "textRaw": "`event.stopImmediatePropagation()`", + "type": "method", + "name": "stopImmediatePropagation", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      Stops the invocation of event listeners after the current one completes.

      " + }, + { + "textRaw": "`event.stopPropagation()`", + "type": "method", + "name": "stopPropagation", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      This is not used in Node.js and is provided purely for completeness.

      " + } + ] + }, + { + "textRaw": "Class: `EventTarget`", + "type": "class", + "name": "EventTarget", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "methods": [ + { + "textRaw": "`eventTarget.addEventListener(type, listener[, options])`", + "type": "method", + "name": "addEventListener", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`type` {string}", + "name": "type", + "type": "string" + }, + { + "textRaw": "`listener` {Function|EventListener}", + "name": "listener", + "type": "Function|EventListener" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`once` {boolean} When `true`, the listener is automatically removed when it is first invoked. **Default:** `false`.", + "name": "once", + "type": "boolean", + "default": "`false`", + "desc": "When `true`, the listener is automatically removed when it is first invoked." + }, + { + "textRaw": "`passive` {boolean} When `true`, serves as a hint that the listener will not call the `Event` object's `preventDefault()` method. **Default:** `false`.", + "name": "passive", + "type": "boolean", + "default": "`false`", + "desc": "When `true`, serves as a hint that the listener will not call the `Event` object's `preventDefault()` method." + }, + { + "textRaw": "`capture` {boolean} Not directly used by Node.js. Added for API completeness. **Default:** `false`.", + "name": "capture", + "type": "boolean", + "default": "`false`", + "desc": "Not directly used by Node.js. Added for API completeness." + } + ] + } + ] + } + ], + "desc": "

      Adds a new handler for the type event. Any given listener is added\nonly once per type and per capture option value.

      \n

      If the once option is true, the listener is removed after the\nnext time a type event is dispatched.

      \n

      The capture option is not used by Node.js in any functional way other than\ntracking registered event listeners per the EventTarget specification.\nSpecifically, the capture option is used as part of the key when registering\na listener. Any individual listener may be added once with\ncapture = false, and once with capture = true.

      \n
      function handler(event) {}\n\nconst target = getEventTargetSomehow();\ntarget.addEventListener('foo', handler, { capture: true });  // first\ntarget.addEventListener('foo', handler, { capture: false }); // second\n\n// Removes the second instance of handler\ntarget.removeEventListener('foo', handler);\n\n// Removes the first instance of handler\ntarget.removeEventListener('foo', handler, { capture: true });\n
      " + }, + { + "textRaw": "`eventTarget.dispatchEvent(event)`", + "type": "method", + "name": "dispatchEvent", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {boolean} `true` if either event’s `cancelable` attribute value is false or its `preventDefault()` method was not invoked, otherwise `false`.", + "name": "return", + "type": "boolean", + "desc": "`true` if either event’s `cancelable` attribute value is false or its `preventDefault()` method was not invoked, otherwise `false`." + }, + "params": [ + { + "textRaw": "`event` {Event}", + "name": "event", + "type": "Event" + } + ] + } + ], + "desc": "

      Dispatches the event to the list of handlers for event.type.

      \n

      The registered event listeners is synchronously invoked in the order they\nwere registered.

      " + }, + { + "textRaw": "`eventTarget.removeEventListener(type, listener)`", + "type": "method", + "name": "removeEventListener", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`type` {string}", + "name": "type", + "type": "string" + }, + { + "textRaw": "`listener` {Function|EventListener}", + "name": "listener", + "type": "Function|EventListener" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`capture` {boolean}", + "name": "capture", + "type": "boolean" + } + ] + } + ] + } + ], + "desc": "

      Removes the listener from the list of handlers for event type.

      " + } + ] + }, + { + "textRaw": "Class: `NodeEventTarget`", + "type": "class", + "name": "NodeEventTarget", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "\n

      The NodeEventTarget is a Node.js-specific extension to EventTarget\nthat emulates a subset of the EventEmitter API.

      ", + "methods": [ + { + "textRaw": "`nodeEventTarget.addListener(type, listener[, options])`", + "type": "method", + "name": "addListener", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {EventTarget} this", + "name": "return", + "type": "EventTarget", + "desc": "this" + }, + "params": [ + { + "textRaw": "`type` {string}", + "name": "type", + "type": "string" + }, + { + "textRaw": "`listener` {Function|EventListener}", + "name": "listener", + "type": "Function|EventListener" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`once` {boolean}", + "name": "once", + "type": "boolean" + } + ] + } + ] + } + ], + "desc": "

      Node.js-specific extension to the EventTarget class that emulates the\nequivalent EventEmitter API. The only difference between addListener() and\naddEventListener() is that addListener() will return a reference to the\nEventTarget.

      " + }, + { + "textRaw": "`nodeEventTarget.eventNames()`", + "type": "method", + "name": "eventNames", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {string[]}", + "name": "return", + "type": "string[]" + }, + "params": [] + } + ], + "desc": "

      Node.js-specific extension to the EventTarget class that returns an array\nof event type names for which event listeners are registered.

      " + }, + { + "textRaw": "`nodeEventTarget.listenerCount(type)`", + "type": "method", + "name": "listenerCount", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {number}", + "name": "return", + "type": "number" + }, + "params": [ + { + "textRaw": "`type` {string}", + "name": "type", + "type": "string" + } + ] + } + ], + "desc": "

      Node.js-specific extension to the EventTarget class that returns the number\nof event listeners registered for the type.

      " + }, + { + "textRaw": "`nodeEventTarget.off(type, listener)`", + "type": "method", + "name": "off", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {EventTarget} this", + "name": "return", + "type": "EventTarget", + "desc": "this" + }, + "params": [ + { + "textRaw": "`type` {string}", + "name": "type", + "type": "string" + }, + { + "textRaw": "`listener` {Function|EventListener}", + "name": "listener", + "type": "Function|EventListener" + } + ] + } + ], + "desc": "

      Node.js-specific alias for eventTarget.removeListener().

      " + }, + { + "textRaw": "`nodeEventTarget.on(type, listener[, options])`", + "type": "method", + "name": "on", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {EventTarget} this", + "name": "return", + "type": "EventTarget", + "desc": "this" + }, + "params": [ + { + "textRaw": "`type` {string}", + "name": "type", + "type": "string" + }, + { + "textRaw": "`listener` {Function|EventListener}", + "name": "listener", + "type": "Function|EventListener" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`once` {boolean}", + "name": "once", + "type": "boolean" + } + ] + } + ] + } + ], + "desc": "

      Node.js-specific alias for eventTarget.addListener().

      " + }, + { + "textRaw": "`nodeEventTarget.once(type, listener[, options])`", + "type": "method", + "name": "once", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {EventTarget} this", + "name": "return", + "type": "EventTarget", + "desc": "this" + }, + "params": [ + { + "textRaw": "`type` {string}", + "name": "type", + "type": "string" + }, + { + "textRaw": "`listener` {Function|EventListener}", + "name": "listener", + "type": "Function|EventListener" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object" + } + ] + } + ], + "desc": "

      Node.js-specific extension to the EventTarget class that adds a once\nlistener for the given event type. This is equivalent to calling on\nwith the once option set to true.

      " + }, + { + "textRaw": "`nodeEventTarget.removeAllListeners([type])`", + "type": "method", + "name": "removeAllListeners", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {EventTarget} this", + "name": "return", + "type": "EventTarget", + "desc": "this" + }, + "params": [ + { + "textRaw": "`type` {string}", + "name": "type", + "type": "string" + } + ] + } + ], + "desc": "

      Node.js-specific extension to the EventTarget class. If type is specified,\nremoves all registered listeners for type, otherwise removes all registered\nlisteners.

      " + }, + { + "textRaw": "`nodeEventTarget.removeListener(type, listener)`", + "type": "method", + "name": "removeListener", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {EventTarget} this", + "name": "return", + "type": "EventTarget", + "desc": "this" + }, + "params": [ + { + "textRaw": "`type` {string}", + "name": "type", + "type": "string" + }, + { + "textRaw": "`listener` {Function|EventListener}", + "name": "listener", + "type": "Function|EventListener" + } + ] + } + ], + "desc": "

      Node.js-specific extension to the EventTarget class that removes the\nlistener for the given type. The only difference between removeListener()\nand removeEventListener() is that removeListener() will return a reference\nto the EventTarget.

      " + } + ] + } + ], + "type": "module", + "displayName": "`EventTarget` and `Event` API" } ], "classes": [ @@ -60,16 +788,19 @@ ], "changes": [ { - "version": "v12.16.0", + "version": [ + "v13.4.0", + "v12.16.0" + ], "pr-url": "https://github.com/nodejs/node/pull/27867", "description": "Added captureRejections option." } ] }, - "desc": "

      The EventEmitter class is defined and exposed by the events module:

      \n
      const EventEmitter = require('events');\n
      \n

      All EventEmitters emit the event 'newListener' when new listeners are\nadded and 'removeListener' when existing listeners are removed.

      \n

      It supports the following option:

      \n", + "desc": "

      The EventEmitter class is defined and exposed by the events module:

      \n
      const EventEmitter = require('events');\n
      \n

      All EventEmitters emit the event 'newListener' when new listeners are\nadded and 'removeListener' when existing listeners are removed.

      \n

      It supports the following option:

      \n", "events": [ { - "textRaw": "Event: 'newListener'", + "textRaw": "Event: `'newListener'`", "type": "event", "name": "newListener", "meta": { @@ -92,7 +823,7 @@ "desc": "The event handler function" } ], - "desc": "

      The EventEmitter instance will emit its own 'newListener' event before\na listener is added to its internal array of listeners.

      \n

      Listeners registered for the 'newListener' event will be passed the event\nname and a reference to the listener being added.

      \n

      The fact that the event is triggered before adding the listener has a subtle\nbut important side effect: any additional listeners registered to the same\nname within the 'newListener' callback will be inserted before the\nlistener that is in the process of being added.

      \n
      const myEmitter = new MyEmitter();\n// Only do this once so we don't loop forever\nmyEmitter.once('newListener', (event, listener) => {\n  if (event === 'event') {\n    // Insert a new listener in front\n    myEmitter.on('event', () => {\n      console.log('B');\n    });\n  }\n});\nmyEmitter.on('event', () => {\n  console.log('A');\n});\nmyEmitter.emit('event');\n// Prints:\n//   B\n//   A\n
      " + "desc": "

      The EventEmitter instance will emit its own 'newListener' event before\na listener is added to its internal array of listeners.

      \n

      Listeners registered for the 'newListener' event are passed the event\nname and a reference to the listener being added.

      \n

      The fact that the event is triggered before adding the listener has a subtle\nbut important side effect: any additional listeners registered to the same\nname within the 'newListener' callback are inserted before the\nlistener that is in the process of being added.

      \n
      class MyEmitter extends EventEmitter {}\n\nconst myEmitter = new MyEmitter();\n// Only do this once so we don't loop forever\nmyEmitter.once('newListener', (event, listener) => {\n  if (event === 'event') {\n    // Insert a new listener in front\n    myEmitter.on('event', () => {\n      console.log('B');\n    });\n  }\n});\nmyEmitter.on('event', () => {\n  console.log('A');\n});\nmyEmitter.emit('event');\n// Prints:\n//   B\n//   A\n
      " }, { "textRaw": "Event: `'removeListener'`", @@ -104,7 +835,10 @@ ], "changes": [ { - "version": "v6.1.0, v4.7.0", + "version": [ + "v6.1.0", + "v4.7.0" + ], "pr-url": "https://github.com/nodejs/node/pull/6394", "description": "For listeners attached using `.once()`, the `listener` argument now yields the original listener function." } @@ -128,41 +862,6 @@ } ], "methods": [ - { - "textRaw": "`EventEmitter.listenerCount(emitter, eventName)`", - "type": "method", - "name": "listenerCount", - "meta": { - "added": [ - "v0.9.12" - ], - "deprecated": [ - "v3.2.0" - ], - "changes": [] - }, - "stability": 0, - "stabilityText": "Deprecated: Use [`emitter.listenerCount()`][] instead.", - "signatures": [ - { - "params": [ - { - "textRaw": "`emitter` {EventEmitter} The emitter to query", - "name": "emitter", - "type": "EventEmitter", - "desc": "The emitter to query" - }, - { - "textRaw": "`eventName` {string|symbol} The event name", - "name": "eventName", - "type": "string|symbol", - "desc": "The event name" - } - ] - } - ], - "desc": "

      A class method that returns the number of listeners for the given eventName\nregistered on the given emitter.

      \n
      const myEmitter = new MyEmitter();\nmyEmitter.on('event', () => {});\nmyEmitter.on('event', () => {});\nconsole.log(EventEmitter.listenerCount(myEmitter, 'event'));\n// Prints: 2\n
      " - }, { "textRaw": "`emitter.addListener(eventName, listener)`", "type": "method", @@ -244,7 +943,7 @@ "params": [] } ], - "desc": "

      Returns an array listing the events for which the emitter has registered\nlisteners. The values in the array will be strings or Symbols.

      \n
      const EventEmitter = require('events');\nconst myEE = new EventEmitter();\nmyEE.on('foo', () => {});\nmyEE.on('bar', () => {});\n\nconst sym = Symbol('symbol');\nmyEE.on(sym, () => {});\n\nconsole.log(myEE.eventNames());\n// Prints: [ 'foo', 'bar', Symbol(symbol) ]\n
      " + "desc": "

      Returns an array listing the events for which the emitter has registered\nlisteners. The values in the array are strings or Symbols.

      \n
      const EventEmitter = require('events');\nconst myEE = new EventEmitter();\nmyEE.on('foo', () => {});\nmyEE.on('bar', () => {});\n\nconst sym = Symbol('symbol');\nmyEE.on(sym, () => {});\n\nconsole.log(myEE.eventNames());\n// Prints: [ 'foo', 'bar', Symbol(symbol) ]\n
      " }, { "textRaw": "`emitter.getMaxListeners()`", @@ -266,7 +965,7 @@ "params": [] } ], - "desc": "

      Returns the current max listener value for the EventEmitter which is either\nset by emitter.setMaxListeners(n) or defaults to\nEventEmitter.defaultMaxListeners.

      " + "desc": "

      Returns the current max listener value for the EventEmitter which is either\nset by emitter.setMaxListeners(n) or defaults to\nevents.defaultMaxListeners.

      " }, { "textRaw": "`emitter.listenerCount(eventName)`", @@ -563,7 +1262,7 @@ ] } ], - "desc": "

      Removes the specified listener from the listener array for the event named\neventName.

      \n
      const callback = (stream) => {\n  console.log('someone connected!');\n};\nserver.on('connection', callback);\n// ...\nserver.removeListener('connection', callback);\n
      \n

      removeListener() will remove, at most, one instance of a listener from the\nlistener array. If any single listener has been added multiple times to the\nlistener array for the specified eventName, then removeListener() must be\ncalled multiple times to remove each instance.

      \n

      Once an event has been emitted, all listeners attached to it at the\ntime of emitting will be called in order. This implies that any\nremoveListener() or removeAllListeners() calls after emitting and\nbefore the last listener finishes execution will not remove them from\nemit() in progress. Subsequent events will behave as expected.

      \n
      const myEmitter = new MyEmitter();\n\nconst callbackA = () => {\n  console.log('A');\n  myEmitter.removeListener('event', callbackB);\n};\n\nconst callbackB = () => {\n  console.log('B');\n};\n\nmyEmitter.on('event', callbackA);\n\nmyEmitter.on('event', callbackB);\n\n// callbackA removes listener callbackB but it will still be called.\n// Internal listener array at time of emit [callbackA, callbackB]\nmyEmitter.emit('event');\n// Prints:\n//   A\n//   B\n\n// callbackB is now removed.\n// Internal listener array [callbackA]\nmyEmitter.emit('event');\n// Prints:\n//   A\n
      \n

      Because listeners are managed using an internal array, calling this will\nchange the position indices of any listener registered after the listener\nbeing removed. This will not impact the order in which listeners are called,\nbut it means that any copies of the listener array as returned by\nthe emitter.listeners() method will need to be recreated.

      \n

      When a single function has been added as a handler multiple times for a single\nevent (as in the example below), removeListener() will remove the most\nrecently added instance. In the example the once('ping')\nlistener is removed:

      \n
      const ee = new EventEmitter();\n\nfunction pong() {\n  console.log('pong');\n}\n\nee.on('ping', pong);\nee.once('ping', pong);\nee.removeListener('ping', pong);\n\nee.emit('ping');\nee.emit('ping');\n
      \n

      Returns a reference to the EventEmitter, so that calls can be chained.

      " + "desc": "

      Removes the specified listener from the listener array for the event named\neventName.

      \n
      const callback = (stream) => {\n  console.log('someone connected!');\n};\nserver.on('connection', callback);\n// ...\nserver.removeListener('connection', callback);\n
      \n

      removeListener() will remove, at most, one instance of a listener from the\nlistener array. If any single listener has been added multiple times to the\nlistener array for the specified eventName, then removeListener() must be\ncalled multiple times to remove each instance.

      \n

      Once an event is emitted, all listeners attached to it at the\ntime of emitting are called in order. This implies that any\nremoveListener() or removeAllListeners() calls after emitting and\nbefore the last listener finishes execution will not remove them from\nemit() in progress. Subsequent events behave as expected.

      \n
      const myEmitter = new MyEmitter();\n\nconst callbackA = () => {\n  console.log('A');\n  myEmitter.removeListener('event', callbackB);\n};\n\nconst callbackB = () => {\n  console.log('B');\n};\n\nmyEmitter.on('event', callbackA);\n\nmyEmitter.on('event', callbackB);\n\n// callbackA removes listener callbackB but it will still be called.\n// Internal listener array at time of emit [callbackA, callbackB]\nmyEmitter.emit('event');\n// Prints:\n//   A\n//   B\n\n// callbackB is now removed.\n// Internal listener array [callbackA]\nmyEmitter.emit('event');\n// Prints:\n//   A\n
      \n

      Because listeners are managed using an internal array, calling this will\nchange the position indices of any listener registered after the listener\nbeing removed. This will not impact the order in which listeners are called,\nbut it means that any copies of the listener array as returned by\nthe emitter.listeners() method will need to be recreated.

      \n

      When a single function has been added as a handler multiple times for a single\nevent (as in the example below), removeListener() will remove the most\nrecently added instance. In the example the once('ping')\nlistener is removed:

      \n
      const ee = new EventEmitter();\n\nfunction pong() {\n  console.log('pong');\n}\n\nee.on('ping', pong);\nee.once('ping', pong);\nee.removeListener('ping', pong);\n\nee.emit('ping');\nee.emit('ping');\n
      \n

      Returns a reference to the EventEmitter, so that calls can be chained.

      " }, { "textRaw": "`emitter.setMaxListeners(n)`", @@ -622,36 +1321,13 @@ "desc": "

      Returns a copy of the array of listeners for the event named eventName,\nincluding any wrappers (such as those created by .once()).

      \n
      const emitter = new EventEmitter();\nemitter.once('log', () => console.log('log once'));\n\n// Returns a new Array with a function `onceWrapper` which has a property\n// `listener` which contains the original listener bound above\nconst listeners = emitter.rawListeners('log');\nconst logFnWrapper = listeners[0];\n\n// Logs \"log once\" to the console and does not unbind the `once` event\nlogFnWrapper.listener();\n\n// Logs \"log once\" to the console and removes the listener\nlogFnWrapper();\n\nemitter.on('log', () => console.log('log persistently'));\n// Will return a new Array with a single function bound by `.on()` above\nconst newListeners = emitter.rawListeners('log');\n\n// Logs \"log persistently\" twice\nnewListeners[0]();\nemitter.emit('log');\n
      " } ], - "properties": [ - { - "textRaw": "`EventEmitter.defaultMaxListeners`", - "name": "defaultMaxListeners", - "meta": { - "added": [ - "v0.11.2" - ], - "changes": [] - }, - "desc": "

      By default, a maximum of 10 listeners can be registered for any single\nevent. This limit can be changed for individual EventEmitter instances\nusing the emitter.setMaxListeners(n) method. To change the default\nfor all EventEmitter instances, the EventEmitter.defaultMaxListeners\nproperty can be used. If this value is not a positive number, a TypeError\nwill be thrown.

      \n

      Take caution when setting the EventEmitter.defaultMaxListeners because the\nchange affects all EventEmitter instances, including those created before\nthe change is made. However, calling emitter.setMaxListeners(n) still has\nprecedence over EventEmitter.defaultMaxListeners.

      \n

      This is not a hard limit. The EventEmitter instance will allow\nmore listeners to be added but will output a trace warning to stderr indicating\nthat a \"possible EventEmitter memory leak\" has been detected. For any single\nEventEmitter, the emitter.getMaxListeners() and emitter.setMaxListeners()\nmethods can be used to temporarily avoid this warning:

      \n
      emitter.setMaxListeners(emitter.getMaxListeners() + 1);\nemitter.once('event', () => {\n  // do stuff\n  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));\n});\n
      \n

      The --trace-warnings command line flag can be used to display the\nstack trace for such warnings.

      \n

      The emitted warning can be inspected with process.on('warning') and will\nhave the additional emitter, type and count properties, referring to\nthe event emitter instance, the event’s name and the number of attached\nlisteners, respectively.\nIts name property is set to 'MaxListenersExceededWarning'.

      " - }, - { - "textRaw": "`EventEmitter.errorMonitor`", - "name": "errorMonitor", - "meta": { - "added": [ - "v12.17.0" - ], - "changes": [] - }, - "desc": "

      This symbol shall be used to install a listener for only monitoring 'error'\nevents. Listeners installed using this symbol are called before the regular\n'error' listeners are called.

      \n

      Installing a listener using this symbol does not change the behavior once an\n'error' event is emitted, therefore the process will still crash if no\nregular 'error' listener is installed.

      " - } - ], "modules": [ { "textRaw": "`emitter[Symbol.for('nodejs.rejection')](err, eventName[, ...args])`", "name": "`emitter[symbol.for('nodejs.rejection')](err,_eventname[,_...args])`", "meta": { "added": [ + "v13.4.0", "v12.16.0" ], "changes": [] @@ -665,17 +1341,110 @@ ] } ], + "properties": [ + { + "textRaw": "`events.defaultMaxListeners`", + "name": "defaultMaxListeners", + "meta": { + "added": [ + "v0.11.2" + ], + "changes": [] + }, + "desc": "

      By default, a maximum of 10 listeners can be registered for any single\nevent. This limit can be changed for individual EventEmitter instances\nusing the emitter.setMaxListeners(n) method. To change the default\nfor all EventEmitter instances, the events.defaultMaxListeners\nproperty can be used. If this value is not a positive number, a RangeError\nis thrown.

      \n

      Take caution when setting the events.defaultMaxListeners because the\nchange affects all EventEmitter instances, including those created before\nthe change is made. However, calling emitter.setMaxListeners(n) still has\nprecedence over events.defaultMaxListeners.

      \n

      This is not a hard limit. The EventEmitter instance will allow\nmore listeners to be added but will output a trace warning to stderr indicating\nthat a \"possible EventEmitter memory leak\" has been detected. For any single\nEventEmitter, the emitter.getMaxListeners() and emitter.setMaxListeners()\nmethods can be used to temporarily avoid this warning:

      \n
      emitter.setMaxListeners(emitter.getMaxListeners() + 1);\nemitter.once('event', () => {\n  // do stuff\n  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));\n});\n
      \n

      The --trace-warnings command-line flag can be used to display the\nstack trace for such warnings.

      \n

      The emitted warning can be inspected with process.on('warning') and will\nhave the additional emitter, type and count properties, referring to\nthe event emitter instance, the event’s name and the number of attached\nlisteners, respectively.\nIts name property is set to 'MaxListenersExceededWarning'.

      " + }, + { + "textRaw": "`events.errorMonitor`", + "name": "errorMonitor", + "meta": { + "added": [ + "v13.6.0", + "v12.17.0" + ], + "changes": [] + }, + "desc": "

      This symbol shall be used to install a listener for only monitoring 'error'\nevents. Listeners installed using this symbol are called before the regular\n'error' listeners are called.

      \n

      Installing a listener using this symbol does not change the behavior once an\n'error' event is emitted, therefore the process will still crash if no\nregular 'error' listener is installed.

      " + }, + { + "textRaw": "`events.captureRejections`", + "name": "captureRejections", + "meta": { + "added": [ + "v13.4.0", + "v12.16.0" + ], + "changes": [] + }, + "stability": 1, + "stabilityText": "captureRejections is experimental.", + "desc": "

      Value: <boolean>

      \n

      Change the default captureRejections option on all new EventEmitter objects.

      " + }, + { + "textRaw": "`events.captureRejectionSymbol`", + "name": "captureRejectionSymbol", + "meta": { + "added": [ + "v13.4.0", + "v12.16.0" + ], + "changes": [] + }, + "stability": 1, + "stabilityText": "captureRejections is experimental.", + "desc": "

      Value: Symbol.for('nodejs.rejection')

      \n

      See how to write a custom rejection handler.

      " + } + ], "methods": [ { - "textRaw": "`events.once(emitter, name)`", + "textRaw": "`events.getEventListeners(emitterOrTarget, eventName)`", "type": "method", - "name": "once", + "name": "getEventListeners", "meta": { "added": [ - "v11.13.0" + "v14.17.0" ], "changes": [] }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {Function[]}", + "name": "return", + "type": "Function[]" + }, + "params": [ + { + "textRaw": "`emitterOrTarget` {EventEmitter|EventTarget}", + "name": "emitterOrTarget", + "type": "EventEmitter|EventTarget" + }, + { + "textRaw": "`eventName` {string|symbol}", + "name": "eventName", + "type": "string|symbol" + } + ] + } + ], + "desc": "

      Returns a copy of the array of listeners for the event named eventName.

      \n

      For EventEmitters this behaves exactly the same as calling .listeners on\nthe emitter.

      \n

      For EventTargets this is the only way to get the event listeners for the\nevent target. This is useful for debugging and diagnostic purposes.

      \n
      const { getEventListeners, EventEmitter } = require('events');\n\n{\n  const ee = new EventEmitter();\n  const listener = () => console.log('Events are fun');\n  ee.on('foo', listener);\n  getEventListeners(ee, 'foo'); // [listener]\n}\n{\n  const et = new EventTarget();\n  const listener = () => console.log('Events are fun');\n  et.addEventListener('foo', listener);\n  getEventListeners(et, 'foo'); // [listener]\n}\n
      " + }, + { + "textRaw": "`events.once(emitter, name[, options])`", + "type": "method", + "name": "once", + "meta": { + "added": [ + "v11.13.0", + "v10.16.0" + ], + "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/34912", + "description": "The `signal` option is supported now." + } + ] + }, "signatures": [ { "return": { @@ -693,11 +1462,24 @@ "textRaw": "`name` {string}", "name": "name", "type": "string" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`signal` {AbortSignal} Can be used to cancel waiting for the event.", + "name": "signal", + "type": "AbortSignal", + "desc": "Can be used to cancel waiting for the event." + } + ] } ] } ], - "desc": "

      Creates a Promise that is fulfilled when the EventEmitter emits the given\nevent or that is rejected if the EventEmitter emits 'error' while waiting.\nThe Promise will resolve with an array of all the arguments emitted to the\ngiven event.

      \n

      This method is intentionally generic and works with the web platform\nEventTarget interface, which has no special\n'error' event semantics and does not listen to the 'error' event.

      \n
      const { once, EventEmitter } = require('events');\n\nasync function run() {\n  const ee = new EventEmitter();\n\n  process.nextTick(() => {\n    ee.emit('myevent', 42);\n  });\n\n  const [value] = await once(ee, 'myevent');\n  console.log(value);\n\n  const err = new Error('kaboom');\n  process.nextTick(() => {\n    ee.emit('error', err);\n  });\n\n  try {\n    await once(ee, 'myevent');\n  } catch (err) {\n    console.log('error happened', err);\n  }\n}\n\nrun();\n
      \n

      The special handling of the 'error' event is only used when events.once()\nis used to wait for another event. If events.once() is used to wait for the\n'error' event itself, then it is treated as any other kind of event without\nspecial handling:

      \n
      const { EventEmitter, once } = require('events');\n\nconst ee = new EventEmitter();\n\nonce(ee, 'error')\n  .then(([err]) => console.log('ok', err.message))\n  .catch((err) => console.log('error', err.message));\n\nee.emit('error', new Error('boom'));\n\n// Prints: ok boom\n
      ", + "desc": "

      Creates a Promise that is fulfilled when the EventEmitter emits the given\nevent or that is rejected if the EventEmitter emits 'error' while waiting.\nThe Promise will resolve with an array of all the arguments emitted to the\ngiven event.

      \n

      This method is intentionally generic and works with the web platform\nEventTarget interface, which has no special\n'error' event semantics and does not listen to the 'error' event.

      \n
      const { once, EventEmitter } = require('events');\n\nasync function run() {\n  const ee = new EventEmitter();\n\n  process.nextTick(() => {\n    ee.emit('myevent', 42);\n  });\n\n  const [value] = await once(ee, 'myevent');\n  console.log(value);\n\n  const err = new Error('kaboom');\n  process.nextTick(() => {\n    ee.emit('error', err);\n  });\n\n  try {\n    await once(ee, 'myevent');\n  } catch (err) {\n    console.log('error happened', err);\n  }\n}\n\nrun();\n
      \n

      The special handling of the 'error' event is only used when events.once()\nis used to wait for another event. If events.once() is used to wait for the\n'error' event itself, then it is treated as any other kind of event without\nspecial handling:

      \n
      const { EventEmitter, once } = require('events');\n\nconst ee = new EventEmitter();\n\nonce(ee, 'error')\n  .then(([err]) => console.log('ok', err.message))\n  .catch((err) => console.log('error', err.message));\n\nee.emit('error', new Error('boom'));\n\n// Prints: ok boom\n
      \n

      An <AbortSignal> can be used to cancel waiting for the event:

      \n
      const { EventEmitter, once } = require('events');\n\nconst ee = new EventEmitter();\nconst ac = new AbortController();\n\nasync function foo(emitter, event, signal) {\n  try {\n    await once(emitter, event, { signal });\n    console.log('event emitted!');\n  } catch (error) {\n    if (error.name === 'AbortError') {\n      console.error('Waiting for the event was canceled!');\n    } else {\n      console.error('There was an error', error.message);\n    }\n  }\n}\n\nfoo(ee, 'foo', ac.signal);\nac.abort(); // Abort waiting for the event\nee.emit('foo'); // Prints: Waiting for the event was canceled!\n
      ", "modules": [ { "textRaw": "Awaiting multiple events emitted on `process.nextTick()`", @@ -709,11 +1491,47 @@ ] }, { - "textRaw": "events.on(emitter, eventName)", + "textRaw": "`events.listenerCount(emitter, eventName)`", + "type": "method", + "name": "listenerCount", + "meta": { + "added": [ + "v0.9.12" + ], + "deprecated": [ + "v3.2.0" + ], + "changes": [] + }, + "stability": 0, + "stabilityText": "Deprecated: Use [`emitter.listenerCount()`][] instead.", + "signatures": [ + { + "params": [ + { + "textRaw": "`emitter` {EventEmitter} The emitter to query", + "name": "emitter", + "type": "EventEmitter", + "desc": "The emitter to query" + }, + { + "textRaw": "`eventName` {string|symbol} The event name", + "name": "eventName", + "type": "string|symbol", + "desc": "The event name" + } + ] + } + ], + "desc": "

      A class method that returns the number of listeners for the given eventName\nregistered on the given emitter.

      \n
      const { EventEmitter, listenerCount } = require('events');\nconst myEmitter = new EventEmitter();\nmyEmitter.on('event', () => {});\nmyEmitter.on('event', () => {});\nconsole.log(listenerCount(myEmitter, 'event'));\n// Prints: 2\n
      " + }, + { + "textRaw": "`events.on(emitter, eventName[, options])`", "type": "method", "name": "on", "meta": { "added": [ + "v13.6.0", "v12.16.0" ], "changes": [] @@ -737,39 +1555,54 @@ "name": "eventName", "type": "string|symbol", "desc": "The name of the event being listened for" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`signal` {AbortSignal} Can be used to cancel awaiting events.", + "name": "signal", + "type": "AbortSignal", + "desc": "Can be used to cancel awaiting events." + } + ] } ] } ], - "desc": "
      const { on, EventEmitter } = require('events');\n\n(async () => {\n  const ee = new EventEmitter();\n\n  // Emit later on\n  process.nextTick(() => {\n    ee.emit('foo', 'bar');\n    ee.emit('foo', 42);\n  });\n\n  for await (const event of on(ee, 'foo')) {\n    // The execution of this inner block is synchronous and it\n    // processes one event at a time (even with await). Do not use\n    // if concurrent execution is required.\n    console.log(event); // prints ['bar'] [42]\n  }\n  // Unreachable here\n})();\n
      \n

      Returns an AsyncIterator that iterates eventName events. It will throw\nif the EventEmitter emits 'error'. It removes all listeners when\nexiting the loop. The value returned by each iteration is an array\ncomposed of the emitted event arguments.

      " - } - ], - "properties": [ - { - "textRaw": "`events.captureRejections`", - "name": "captureRejections", - "meta": { - "added": [ - "v12.16.0" - ], - "changes": [] - }, - "stability": 1, - "stabilityText": "captureRejections is experimental.", - "desc": "

      Value: <boolean>

      \n

      Change the default captureRejections option on all new EventEmitter objects.

      " + "desc": "
      const { on, EventEmitter } = require('events');\n\n(async () => {\n  const ee = new EventEmitter();\n\n  // Emit later on\n  process.nextTick(() => {\n    ee.emit('foo', 'bar');\n    ee.emit('foo', 42);\n  });\n\n  for await (const event of on(ee, 'foo')) {\n    // The execution of this inner block is synchronous and it\n    // processes one event at a time (even with await). Do not use\n    // if concurrent execution is required.\n    console.log(event); // prints ['bar'] [42]\n  }\n  // Unreachable here\n})();\n
      \n

      Returns an AsyncIterator that iterates eventName events. It will throw\nif the EventEmitter emits 'error'. It removes all listeners when\nexiting the loop. The value returned by each iteration is an array\ncomposed of the emitted event arguments.

      \n

      An <AbortSignal> can be used to cancel waiting on events:

      \n
      const { on, EventEmitter } = require('events');\nconst ac = new AbortController();\n\n(async () => {\n  const ee = new EventEmitter();\n\n  // Emit later on\n  process.nextTick(() => {\n    ee.emit('foo', 'bar');\n    ee.emit('foo', 42);\n  });\n\n  for await (const event of on(ee, 'foo', { signal: ac.signal })) {\n    // The execution of this inner block is synchronous and it\n    // processes one event at a time (even with await). Do not use\n    // if concurrent execution is required.\n    console.log(event); // prints ['bar'] [42]\n  }\n  // Unreachable here\n})();\n\nprocess.nextTick(() => ac.abort());\n
      " }, { - "textRaw": "events.captureRejectionSymbol", - "name": "captureRejectionSymbol", + "textRaw": "`events.setMaxListeners(n[, ...eventTargets])`", + "type": "method", + "name": "setMaxListeners", "meta": { "added": [ - "v12.16.0" + "v14.17.0" ], "changes": [] }, - "stability": 1, - "stabilityText": "captureRejections is experimental.", - "desc": "

      Value: Symbol.for('nodejs.rejection')

      \n

      See how to write a custom rejection handler.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`n` {number} A non-negative number. The maximum number of listeners per `EventTarget` event.", + "name": "n", + "type": "number", + "desc": "A non-negative number. The maximum number of listeners per `EventTarget` event." + }, + { + "textRaw": "`...eventsTargets` {EventTarget[]|EventEmitter[]} Zero or more {EventTarget} or {EventEmitter} instances. If none are specified, `n` is set as the default max for all newly created {EventTarget} and {EventEmitter} objects.", + "name": "...eventsTargets", + "type": "EventTarget[]|EventEmitter[]", + "desc": "Zero or more {EventTarget} or {EventEmitter} instances. If none are specified, `n` is set as the default max for all newly created {EventTarget} and {EventEmitter} objects." + } + ] + } + ], + "desc": "
      const {\n  setMaxListeners,\n  EventEmitter\n} = require('events');\n\nconst target = new EventTarget();\nconst emitter = new EventEmitter();\n\nsetMaxListeners(5, target, emitter);\n
      \n

      " } ] } diff --git a/doc/api/events.md b/doc/api/events.md index eecfa96f8c4312c81a731628a4d96b4f50818602..5cc49018e0ec1128c4bedb97cac0f6d63866447b 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -24,7 +24,7 @@ can be used. When the `EventEmitter` object emits an event, all of the functions attached to that specific event are called _synchronously_. Any values returned by the -called listeners are _ignored_ and will be discarded. +called listeners are _ignored_ and discarded. The following example shows a simple `EventEmitter` instance with a single listener. The `eventEmitter.on()` method is used to register listeners, while @@ -97,7 +97,7 @@ myEmitter.emit('event', 'a', 'b'); ## Handling events only once When a listener is registered using the `eventEmitter.on()` method, that -listener will be invoked _every time_ the named event is emitted. +listener is invoked _every time_ the named event is emitted. ```js const myEmitter = new MyEmitter(); @@ -158,11 +158,13 @@ myEmitter.emit('error', new Error('whoops!')); ``` It is possible to monitor `'error'` events without consuming the emitted error -by installing a listener using the symbol `errorMonitor`. +by installing a listener using the symbol `events.errorMonitor`. ```js -const myEmitter = new MyEmitter(); -myEmitter.on(EventEmitter.errorMonitor, (err) => { +const { EventEmitter, errorMonitor } = require('events'); + +const myEmitter = new EventEmitter(); +myEmitter.on(errorMonitor, (err) => { MyMonitoringTool.log(err); }); myEmitter.emit('error', new Error('whoops!')); @@ -205,12 +207,13 @@ ee2.on('something', async (value) => { ee2[Symbol.for('nodejs.rejection')] = console.log; ``` -Setting `EventEmitter.captureRejections = true` will change the default for all +Setting `events.captureRejections = true` will change the default for all new instances of `EventEmitter`. ```js -EventEmitter.captureRejections = true; -const ee1 = new EventEmitter(); +const events = require('events'); +events.captureRejections = true; +const ee1 = new events.EventEmitter(); ee1.on('something', async (value) => { throw new Error('kaboom'); }); @@ -226,7 +229,9 @@ recommendation is to **not use `async` functions as `'error'` event handlers**. @@ -244,9 +249,9 @@ It supports the following option: * `captureRejections` {boolean} It enables [automatic capturing of promise rejection][capturerejections]. - Default: `false`. + **Default:** `false`. -### Event: 'newListener' +### Event: `'newListener'` @@ -257,15 +262,17 @@ added: v0.1.26 The `EventEmitter` instance will emit its own `'newListener'` event *before* a listener is added to its internal array of listeners. -Listeners registered for the `'newListener'` event will be passed the event +Listeners registered for the `'newListener'` event are passed the event name and a reference to the listener being added. The fact that the event is triggered before adding the listener has a subtle but important side effect: any *additional* listeners registered to the same -`name` *within* the `'newListener'` callback will be inserted *before* the +`name` *within* the `'newListener'` callback are inserted *before* the listener that is in the process of being added. ```js +class MyEmitter extends EventEmitter {} + const myEmitter = new MyEmitter(); // Only do this once so we don't loop forever myEmitter.once('newListener', (event, listener) => { @@ -289,7 +296,9 @@ myEmitter.emit('event'); - -> Stability: 0 - Deprecated: Use [`emitter.listenerCount()`][] instead. - -* `emitter` {EventEmitter} The emitter to query -* `eventName` {string|symbol} The event name - -A class method that returns the number of listeners for the given `eventName` -registered on the given `emitter`. - -```js -const myEmitter = new MyEmitter(); -myEmitter.on('event', () => {}); -myEmitter.on('event', () => {}); -console.log(EventEmitter.listenerCount(myEmitter, 'event')); -// Prints: 2 -``` - -### `EventEmitter.defaultMaxListeners` - - -By default, a maximum of `10` listeners can be registered for any single -event. This limit can be changed for individual `EventEmitter` instances -using the [`emitter.setMaxListeners(n)`][] method. To change the default -for *all* `EventEmitter` instances, the `EventEmitter.defaultMaxListeners` -property can be used. If this value is not a positive number, a `TypeError` -will be thrown. - -Take caution when setting the `EventEmitter.defaultMaxListeners` because the -change affects *all* `EventEmitter` instances, including those created before -the change is made. However, calling [`emitter.setMaxListeners(n)`][] still has -precedence over `EventEmitter.defaultMaxListeners`. - -This is not a hard limit. The `EventEmitter` instance will allow -more listeners to be added but will output a trace warning to stderr indicating -that a "possible EventEmitter memory leak" has been detected. For any single -`EventEmitter`, the `emitter.getMaxListeners()` and `emitter.setMaxListeners()` -methods can be used to temporarily avoid this warning: - -```js -emitter.setMaxListeners(emitter.getMaxListeners() + 1); -emitter.once('event', () => { - // do stuff - emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0)); -}); -``` - -The [`--trace-warnings`][] command line flag can be used to display the -stack trace for such warnings. - -The emitted warning can be inspected with [`process.on('warning')`][] and will -have the additional `emitter`, `type` and `count` properties, referring to -the event emitter instance, the event’s name and the number of attached -listeners, respectively. -Its `name` property is set to `'MaxListenersExceededWarning'`. - -### `EventEmitter.errorMonitor` - - -This symbol shall be used to install a listener for only monitoring `'error'` -events. Listeners installed using this symbol are called before the regular -`'error'` listeners are called. - -Installing a listener using this symbol does not change the behavior once an -`'error'` event is emitted, therefore the process will still crash if no -regular `'error'` listener is installed. - ### `emitter.addListener(eventName, listener)` > Stability: 1 - captureRejections is experimental. @@ -819,13 +755,110 @@ class MyClass extends EventEmitter { } ``` -## `events.once(emitter, name)` +## `events.defaultMaxListeners` + +By default, a maximum of `10` listeners can be registered for any single +event. This limit can be changed for individual `EventEmitter` instances +using the [`emitter.setMaxListeners(n)`][] method. To change the default +for *all* `EventEmitter` instances, the `events.defaultMaxListeners` +property can be used. If this value is not a positive number, a `RangeError` +is thrown. + +Take caution when setting the `events.defaultMaxListeners` because the +change affects *all* `EventEmitter` instances, including those created before +the change is made. However, calling [`emitter.setMaxListeners(n)`][] still has +precedence over `events.defaultMaxListeners`. + +This is not a hard limit. The `EventEmitter` instance will allow +more listeners to be added but will output a trace warning to stderr indicating +that a "possible EventEmitter memory leak" has been detected. For any single +`EventEmitter`, the `emitter.getMaxListeners()` and `emitter.setMaxListeners()` +methods can be used to temporarily avoid this warning: + +```js +emitter.setMaxListeners(emitter.getMaxListeners() + 1); +emitter.once('event', () => { + // do stuff + emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0)); +}); +``` + +The [`--trace-warnings`][] command-line flag can be used to display the +stack trace for such warnings. + +The emitted warning can be inspected with [`process.on('warning')`][] and will +have the additional `emitter`, `type` and `count` properties, referring to +the event emitter instance, the event’s name and the number of attached +listeners, respectively. +Its `name` property is set to `'MaxListenersExceededWarning'`. + +## `events.errorMonitor` + + +This symbol shall be used to install a listener for only monitoring `'error'` +events. Listeners installed using this symbol are called before the regular +`'error'` listeners are called. + +Installing a listener using this symbol does not change the behavior once an +`'error'` event is emitted, therefore the process will still crash if no +regular `'error'` listener is installed. + +## `events.getEventListeners(emitterOrTarget, eventName)` + +* `emitterOrTarget` {EventEmitter|EventTarget} +* `eventName` {string|symbol} +* Returns: {Function[]} + +Returns a copy of the array of listeners for the event named `eventName`. + +For `EventEmitter`s this behaves exactly the same as calling `.listeners` on +the emitter. + +For `EventTarget`s this is the only way to get the event listeners for the +event target. This is useful for debugging and diagnostic purposes. + +```js +const { getEventListeners, EventEmitter } = require('events'); + +{ + const ee = new EventEmitter(); + const listener = () => console.log('Events are fun'); + ee.on('foo', listener); + getEventListeners(ee, 'foo'); // [listener] +} +{ + const et = new EventTarget(); + const listener = () => console.log('Events are fun'); + et.addEventListener('foo', listener); + getEventListeners(et, 'foo'); // [listener] +} +``` + +## `events.once(emitter, name[, options])` + * `emitter` {EventEmitter} * `name` {string} +* `options` {Object} + * `signal` {AbortSignal} Can be used to cancel waiting for the event. * Returns: {Promise} Creates a `Promise` that is fulfilled when the `EventEmitter` emits the given @@ -884,6 +917,32 @@ ee.emit('error', new Error('boom')); // Prints: ok boom ``` +An {AbortSignal} can be used to cancel waiting for the event: + +```js +const { EventEmitter, once } = require('events'); + +const ee = new EventEmitter(); +const ac = new AbortController(); + +async function foo(emitter, event, signal) { + try { + await once(emitter, event, { signal }); + console.log('event emitted!'); + } catch (error) { + if (error.name === 'AbortError') { + console.error('Waiting for the event was canceled!'); + } else { + console.error('There was an error', error.message); + } + } +} + +foo(ee, 'foo', ac.signal); +ac.abort(); // Abort waiting for the event +ee.emit('foo'); // Prints: Waiting for the event was canceled! +``` + ### Awaiting multiple events emitted on `process.nextTick()` There is an edge case worth noting when using the `events.once()` function @@ -940,7 +999,9 @@ foo().then(() => console.log('done')); ## `events.captureRejections` > Stability: 1 - captureRejections is experimental. @@ -949,9 +1010,11 @@ Value: {boolean} Change the default `captureRejections` option on all new `EventEmitter` objects. -## events.captureRejectionSymbol +## `events.captureRejectionSymbol` > Stability: 1 - captureRejections is experimental. @@ -960,13 +1023,40 @@ Value: `Symbol.for('nodejs.rejection')` See how to write a custom [rejection handler][rejection]. -## events.on(emitter, eventName) +## `events.listenerCount(emitter, eventName)` + +> Stability: 0 - Deprecated: Use [`emitter.listenerCount()`][] instead. + +* `emitter` {EventEmitter} The emitter to query +* `eventName` {string|symbol} The event name + +A class method that returns the number of listeners for the given `eventName` +registered on the given `emitter`. + +```js +const { EventEmitter, listenerCount } = require('events'); +const myEmitter = new EventEmitter(); +myEmitter.on('event', () => {}); +myEmitter.on('event', () => {}); +console.log(listenerCount(myEmitter, 'event')); +// Prints: 2 +``` + +## `events.on(emitter, eventName[, options])` + * `emitter` {EventEmitter} * `eventName` {string|symbol} The name of the event being listened for +* `options` {Object} + * `signal` {AbortSignal} Can be used to cancel awaiting events. * Returns: {AsyncIterator} that iterates `eventName` events emitted by the `emitter` ```js @@ -996,18 +1086,542 @@ if the `EventEmitter` emits `'error'`. It removes all listeners when exiting the loop. The `value` returned by each iteration is an array composed of the emitted event arguments. +An {AbortSignal} can be used to cancel waiting on events: + +```js +const { on, EventEmitter } = require('events'); +const ac = new AbortController(); + +(async () => { + const ee = new EventEmitter(); + + // Emit later on + process.nextTick(() => { + ee.emit('foo', 'bar'); + ee.emit('foo', 42); + }); + + for await (const event of on(ee, 'foo', { signal: ac.signal })) { + // The execution of this inner block is synchronous and it + // processes one event at a time (even with await). Do not use + // if concurrent execution is required. + console.log(event); // prints ['bar'] [42] + } + // Unreachable here +})(); + +process.nextTick(() => ac.abort()); +``` + +## `events.setMaxListeners(n[, ...eventTargets])` + + +* `n` {number} A non-negative number. The maximum number of listeners per + `EventTarget` event. +* `...eventsTargets` {EventTarget[]|EventEmitter[]} Zero or more {EventTarget} + or {EventEmitter} instances. If none are specified, `n` is set as the default + max for all newly created {EventTarget} and {EventEmitter} objects. + +```js +const { + setMaxListeners, + EventEmitter +} = require('events'); + +const target = new EventTarget(); +const emitter = new EventEmitter(); + +setMaxListeners(5, target, emitter); +``` + + +## `EventTarget` and `Event` API + + +> Stability: 1 - Experimental + +The `EventTarget` and `Event` objects are a Node.js-specific implementation +of the [`EventTarget` Web API][] that are exposed by some Node.js core APIs. +Neither the `EventTarget` nor `Event` classes are available for end +user code to create. + +```js +const target = getEventTargetSomehow(); + +target.addEventListener('foo', (event) => { + console.log('foo event happened!'); +}); +``` + +### Node.js `EventTarget` vs. DOM `EventTarget` + +There are two key differences between the Node.js `EventTarget` and the +[`EventTarget` Web API][]: + +1. Whereas DOM `EventTarget` instances *may* be hierarchical, there is no + concept of hierarchy and event propagation in Node.js. That is, an event + dispatched to an `EventTarget` does not propagate through a hierarchy of + nested target objects that may each have their own set of handlers for the + event. +2. In the Node.js `EventTarget`, if an event listener is an async function + or returns a `Promise`, and the returned `Promise` rejects, the rejection + is automatically captured and handled the same way as a listener that + throws synchronously (see [`EventTarget` error handling][] for details). + +### `NodeEventTarget` vs. `EventEmitter` + +The `NodeEventTarget` object implements a modified subset of the +`EventEmitter` API that allows it to closely *emulate* an `EventEmitter` in +certain situations. A `NodeEventTarget` is *not* an instance of `EventEmitter` +and cannot be used in place of an `EventEmitter` in most cases. + +1. Unlike `EventEmitter`, any given `listener` can be registered at most once + per event `type`. Attempts to register a `listener` multiple times are + ignored. +2. The `NodeEventTarget` does not emulate the full `EventEmitter` API. + Specifically the `prependListener()`, `prependOnceListener()`, + `rawListeners()`, `setMaxListeners()`, `getMaxListeners()`, and + `errorMonitor` APIs are not emulated. The `'newListener'` and + `'removeListener'` events will also not be emitted. +3. The `NodeEventTarget` does not implement any special default behavior + for events with type `'error'`. +3. The `NodeEventTarget` supports `EventListener` objects as well as + functions as handlers for all event types. + +### Event listener + +Event listeners registered for an event `type` may either be JavaScript +functions or objects with a `handleEvent` property whose value is a function. + +In either case, the handler function is invoked with the `event` argument +passed to the `eventTarget.dispatchEvent()` function. + +Async functions may be used as event listeners. If an async handler function +rejects, the rejection is captured and handled as described in +[`EventTarget` error handling][]. + +An error thrown by one handler function does not prevent the other handlers +from being invoked. + +The return value of a handler function is ignored. + +Handlers are always invoked in the order they were added. + +Handler functions may mutate the `event` object. + +```js +function handler1(event) { + console.log(event.type); // Prints 'foo' + event.a = 1; +} + +async function handler2(event) { + console.log(event.type); // Prints 'foo' + console.log(event.a); // Prints 1 +} + +const handler3 = { + handleEvent(event) { + console.log(event.type); // Prints 'foo' + } +}; + +const handler4 = { + async handleEvent(event) { + console.log(event.type); // Prints 'foo' + } +}; + +const target = getEventTargetSomehow(); + +target.addEventListener('foo', handler1); +target.addEventListener('foo', handler2); +target.addEventListener('foo', handler3); +target.addEventListener('foo', handler4, { once: true }); +``` + +### `EventTarget` error handling + +When a registered event listener throws (or returns a Promise that rejects), +by default the error is treated as an uncaught exception on +`process.nextTick()`. This means uncaught exceptions in `EventTarget`s will +terminate the Node.js process by default. + +Throwing within an event listener will *not* stop the other registered handlers +from being invoked. + +The `EventTarget` does not implement any special default handling for `'error'` +type events like `EventEmitter`. + +Currently errors are first forwarded to the `process.on('error')` event +before reaching `process.on('uncaughtException')`. This behavior is +deprecated and will change in a future release to align `EventTarget` with +other Node.js APIs. Any code relying on the `process.on('error')` event should +be aligned with the new behavior. + +### Class: `Event` + + +The `Event` object is an adaptation of the [`Event` Web API][]. Instances +are created internally by Node.js. + +#### `event.bubbles` + + +* Type: {boolean} Always returns `false`. + +This is not used in Node.js and is provided purely for completeness. + +#### `event.cancelBubble()` + + +Alias for `event.stopPropagation()`. This is not used in Node.js and is +provided purely for completeness. + +#### `event.cancelable` + + +* Type: {boolean} True if the event was created with the `cancelable` option. + +#### `event.composed` + + +* Type: {boolean} Always returns `false`. + +This is not used in Node.js and is provided purely for completeness. + +#### `event.composedPath()` + + +Returns an array containing the current `EventTarget` as the only entry or +empty if the event is not being dispatched. This is not used in +Node.js and is provided purely for completeness. + +#### `event.currentTarget` + + +* Type: {EventTarget} The `EventTarget` dispatching the event. + +Alias for `event.target`. + +#### `event.defaultPrevented` + + +* Type: {boolean} + +Is `true` if `cancelable` is `true` and `event.preventDefault()` has been +called. + +#### `event.eventPhase` + + +* Type: {number} Returns `0` while an event is not being dispatched, `2` while + it is being dispatched. + +This is not used in Node.js and is provided purely for completeness. + +#### `event.isTrusted` + + +* Type: {boolean} + +The {AbortSignal} `"abort"` event is emitted with `isTrusted` set to `true`. The +value is `false` in all other cases. + +#### `event.preventDefault()` + + +Sets the `defaultPrevented` property to `true` if `cancelable` is `true`. + +#### `event.returnValue` + + +* Type: {boolean} True if the event has not been canceled. + +This is not used in Node.js and is provided purely for completeness. + +#### `event.srcElement` + + +* Type: {EventTarget} The `EventTarget` dispatching the event. + +Alias for `event.target`. + +#### `event.stopImmediatePropagation()` + + +Stops the invocation of event listeners after the current one completes. + +#### `event.stopPropagation()` + + +This is not used in Node.js and is provided purely for completeness. + +#### `event.target` + + +* Type: {EventTarget} The `EventTarget` dispatching the event. + +#### `event.timeStamp` + + +* Type: {number} + +The millisecond timestamp when the `Event` object was created. + +#### `event.type` + + +* Type: {string} + +The event type identifier. + +### Class: `EventTarget` + + +#### `eventTarget.addEventListener(type, listener[, options])` + + +* `type` {string} +* `listener` {Function|EventListener} +* `options` {Object} + * `once` {boolean} When `true`, the listener is automatically removed + when it is first invoked. **Default:** `false`. + * `passive` {boolean} When `true`, serves as a hint that the listener will + not call the `Event` object's `preventDefault()` method. + **Default:** `false`. + * `capture` {boolean} Not directly used by Node.js. Added for API + completeness. **Default:** `false`. + +Adds a new handler for the `type` event. Any given `listener` is added +only once per `type` and per `capture` option value. + +If the `once` option is `true`, the `listener` is removed after the +next time a `type` event is dispatched. + +The `capture` option is not used by Node.js in any functional way other than +tracking registered event listeners per the `EventTarget` specification. +Specifically, the `capture` option is used as part of the key when registering +a `listener`. Any individual `listener` may be added once with +`capture = false`, and once with `capture = true`. + +```js +function handler(event) {} + +const target = getEventTargetSomehow(); +target.addEventListener('foo', handler, { capture: true }); // first +target.addEventListener('foo', handler, { capture: false }); // second + +// Removes the second instance of handler +target.removeEventListener('foo', handler); + +// Removes the first instance of handler +target.removeEventListener('foo', handler, { capture: true }); +``` + +#### `eventTarget.dispatchEvent(event)` + + +* `event` {Event} +* Returns: {boolean} `true` if either event’s `cancelable` attribute value is + false or its `preventDefault()` method was not invoked, otherwise `false`. + +Dispatches the `event` to the list of handlers for `event.type`. + +The registered event listeners is synchronously invoked in the order they +were registered. + +#### `eventTarget.removeEventListener(type, listener)` + + +* `type` {string} +* `listener` {Function|EventListener} +* `options` {Object} + * `capture` {boolean} + +Removes the `listener` from the list of handlers for event `type`. + +### Class: `NodeEventTarget` + + +* Extends: {EventTarget} + +The `NodeEventTarget` is a Node.js-specific extension to `EventTarget` +that emulates a subset of the `EventEmitter` API. + +#### `nodeEventTarget.addListener(type, listener[, options])` + + +* `type` {string} +* `listener` {Function|EventListener} +* `options` {Object} + * `once` {boolean} + +* Returns: {EventTarget} this + +Node.js-specific extension to the `EventTarget` class that emulates the +equivalent `EventEmitter` API. The only difference between `addListener()` and +`addEventListener()` is that `addListener()` will return a reference to the +`EventTarget`. + +#### `nodeEventTarget.eventNames()` + + +* Returns: {string[]} + +Node.js-specific extension to the `EventTarget` class that returns an array +of event `type` names for which event listeners are registered. + +#### `nodeEventTarget.listenerCount(type)` + + +* `type` {string} + +* Returns: {number} + +Node.js-specific extension to the `EventTarget` class that returns the number +of event listeners registered for the `type`. + +#### `nodeEventTarget.off(type, listener)` + + +* `type` {string} +* `listener` {Function|EventListener} + +* Returns: {EventTarget} this + +Node.js-specific alias for `eventTarget.removeListener()`. + +#### `nodeEventTarget.on(type, listener[, options])` + + +* `type` {string} +* `listener` {Function|EventListener} +* `options` {Object} + * `once` {boolean} + +* Returns: {EventTarget} this + +Node.js-specific alias for `eventTarget.addListener()`. + +#### `nodeEventTarget.once(type, listener[, options])` + + +* `type` {string} +* `listener` {Function|EventListener} +* `options` {Object} + +* Returns: {EventTarget} this + +Node.js-specific extension to the `EventTarget` class that adds a `once` +listener for the given event `type`. This is equivalent to calling `on` +with the `once` option set to `true`. + +#### `nodeEventTarget.removeAllListeners([type])` + + +* `type` {string} + +* Returns: {EventTarget} this + +Node.js-specific extension to the `EventTarget` class. If `type` is specified, +removes all registered listeners for `type`, otherwise removes all registered +listeners. + +#### `nodeEventTarget.removeListener(type, listener)` + + +* `type` {string} +* `listener` {Function|EventListener} + +* Returns: {EventTarget} this + +Node.js-specific extension to the `EventTarget` class that removes the +`listener` for the given `type`. The only difference between `removeListener()` +and `removeEventListener()` is that `removeListener()` will return a reference +to the `EventTarget`. + [WHATWG-EventTarget]: https://dom.spec.whatwg.org/#interface-eventtarget -[`--trace-warnings`]: cli.html#cli_trace_warnings -[`EventEmitter.defaultMaxListeners`]: #events_eventemitter_defaultmaxlisteners -[`domain`]: domain.html +[`--trace-warnings`]: cli.md#cli_trace_warnings +[`EventTarget` Web API]: https://dom.spec.whatwg.org/#eventtarget +[`EventTarget` error handling]: #events_eventtarget_error_handling +[`Event` Web API]: https://dom.spec.whatwg.org/#event +[`domain`]: domain.md [`emitter.listenerCount()`]: #events_emitter_listenercount_eventname [`emitter.removeListener()`]: #events_emitter_removelistener_eventname_listener [`emitter.setMaxListeners(n)`]: #events_emitter_setmaxlisteners_n -[`fs.ReadStream`]: fs.html#fs_class_fs_readstream -[`net.Server`]: net.html#net_class_net_server -[`process.on('warning')`]: process.html#process_event_warning -[stream]: stream.html +[`events.defaultMaxListeners`]: #events_events_defaultmaxlisteners +[`fs.ReadStream`]: fs.md#fs_class_fs_readstream +[`net.Server`]: net.md#net_class_net_server +[`process.on('warning')`]: process.md#process_event_warning [capturerejections]: #events_capture_rejections_of_promises +[error]: #events_error_events [rejection]: #events_emitter_symbol_for_nodejs_rejection_err_eventname_args [rejectionsymbol]: #events_events_capturerejectionsymbol -[error]: #events_error_events +[stream]: stream.md diff --git a/doc/api/fs.html b/doc/api/fs.html index 87d353e3f1de98629c1ad289c086bbd8b6819617..db70d2a9c00012323b1eeb53a60c37188abcc124 100644 --- a/doc/api/fs.html +++ b/doc/api/fs.html @@ -1,10 +1,10 @@ - + - - File system | Node.js v12.22.7 Documentation + + File system | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      -
      -

      Table of Contents

      -
      + +
      -

      File system#

      +

      File system#

      Stability: 2 - Stable

      -

      Source Code: lib/fs.js

      +

      Source Code: lib/fs.js

      The fs module enables interacting with the file system in a way modeled on standard POSIX functions.

      -

      To use this module:

      -
      const fs = require('fs');
      +

      To use the promise-based APIs:

      + +
      import * as fs from 'fs/promises';const fs = require('fs/promises');
      +

      To use the callback and sync APIs:

      + +
      import * as fs from 'fs';const fs = require('fs');

      All file system operations have synchronous, callback, and promise-based -forms.

      -

      Synchronous example#

      -

      The synchronous form blocks the Node.js event loop and further JavaScript -execution until the operation is complete. Exceptions are thrown immediately -and can be handled using try…catch, or can be allowed to bubble up.

      -
      const fs = require('fs');
      +forms, and are accessible using both CommonJS syntax and ES6 Modules (ESM).

      +

      Promise example#

      +

      Promise-based operations return a promise that is fulfilled when the +asynchronous operation is complete.

      + +
      import { unlink } from 'fs/promises';
       
       try {
      -  fs.unlinkSync('/tmp/hello');
      -  console.log('successfully deleted /tmp/hello');
      -} catch (err) {
      -  // handle the error
      -}
      -

      Callback example#

      + await unlink('/tmp/hello'); + console.log('successfully deleted /tmp/hello'); +} catch (error) { + console.error('there was an error:', error.message); +}
      const { unlink } = require('fs/promises'); + +(async function(path) { + try { + await unlink(path); + console.log(`successfully deleted ${path}`); + } catch (error) { + console.error('there was an error:', error.message); + } +})('/tmp/hello');
      +

      Callback example#

      The callback form takes a completion callback function as its last argument and invokes the operation asynchronously. The arguments passed to the completion callback depend on the method, but the first argument is always reserved for an exception. If the operation is completed successfully, then the first argument is null or undefined.

      -
      const fs = require('fs');
       
      -fs.unlink('/tmp/hello', (err) => {
      -  if (err) throw err;
      -  console.log('successfully deleted /tmp/hello');
      -});
      -

      Promise example#

      -

      Promise-based operations return a Promise that is resolved when the -asynchronous operation is complete.

      -
      const fs = require('fs').promises;
      +
      import { unlink } from 'fs';
       
      -(async function(path) {
      -  try {
      -    await fs.unlink(path);
      -    console.log(`successfully deleted ${path}`);
      -  } catch (error) {
      -    console.error('there was an error:', error.message);
      -  }
      -})('/tmp/hello');
      -

      Ordering of callback and promise-based operations#

      -

      There is no guaranteed ordering when using either the callback or -promise-based methods. For example, the following is prone to error -because the fs.stat() operation might complete before the fs.rename() -operation:

      -
      fs.rename('/tmp/hello', '/tmp/world', (err) => {
      -  if (err) throw err;
      -  console.log('renamed complete');
      -});
      -fs.stat('/tmp/world', (err, stats) => {
      +unlink('/tmp/hello', (err) => {
         if (err) throw err;
      -  console.log(`stats: ${JSON.stringify(stats)}`);
      -});
      -

      To correctly order the operations, move the fs.stat() call into the callback -of the fs.rename() operation:

      -
      fs.rename('/tmp/hello', '/tmp/world', (err) => {
      -  if (err) throw err;
      -  fs.stat('/tmp/world', (err, stats) => {
      -    if (err) throw err;
      -    console.log(`stats: ${JSON.stringify(stats)}`);
      -  });
      -});
      -

      Or, use the promise-based API:

      -
      const fs = require('fs').promises;
      -
      -(async function(from, to) {
      -  try {
      -    await fs.rename(from, to);
      -    const stats = await fs.stat(to);
      -    console.log(`stats: ${JSON.stringify(stats)}`);
      -  } catch (error) {
      -    console.error('there was an error:', error.message);
      -  }
      -})('/tmp/hello', '/tmp/world');
      -

      File paths#

      -

      Most fs operations accept filepaths that may be specified in the form of -a string, a Buffer, or a URL object using the file: protocol.

      -

      String form paths are interpreted as UTF-8 character sequences identifying -the absolute or relative filename. Relative paths will be resolved relative -to the current working directory as determined by calling process.cwd().

      -

      Example using an absolute path on POSIX:

      -
      const fs = require('fs');
      +  console.log('successfully deleted /tmp/hello');
      +});const { unlink } = require('fs');
       
      -fs.open('/open/some/file.txt', 'r', (err, fd) => {
      -  if (err) throw err;
      -  fs.close(fd, (err) => {
      -    if (err) throw err;
      -  });
      -});
      -

      Example using a relative path on POSIX (relative to process.cwd()):

      -
      fs.open('file.txt', 'r', (err, fd) => {
      -  if (err) throw err;
      -  fs.close(fd, (err) => {
      -    if (err) throw err;
      -  });
      -});
      -

      Paths specified using a Buffer are useful primarily on certain POSIX -operating systems that treat file paths as opaque byte sequences. On such -systems, it is possible for a single file path to contain sub-sequences that -use multiple character encodings. As with string paths, Buffer paths may -be relative or absolute:

      -

      Example using an absolute path on POSIX:

      -
      fs.open(Buffer.from('/open/some/file.txt'), 'r', (err, fd) => {
      +unlink('/tmp/hello', (err) => {
         if (err) throw err;
      -  fs.close(fd, (err) => {
      -    if (err) throw err;
      -  });
      +  console.log('successfully deleted /tmp/hello');
       });
      -

      On Windows, Node.js follows the concept of per-drive working directory. This -behavior can be observed when using a drive path without a backslash. For -example fs.readdirSync('C:\\') can potentially return a different result than -fs.readdirSync('C:'). For more information, see -this MSDN page.

      -

      URL object support#

      - -

      For most fs module functions, the path or filename argument may be passed -as a WHATWG URL object. Only URL objects using the file: protocol -are supported.

      -
      const fs = require('fs');
      -const fileUrl = new URL('file:///tmp/hello');
      -
      -fs.readFileSync(fileUrl);
      -

      file: URLs are always absolute paths.

      -

      Using WHATWG URL objects might introduce platform-specific behaviors.

      -

      On Windows, file: URLs with a host name convert to UNC paths, while file: -URLs with drive letters convert to local absolute paths. file: URLs without a -host name nor a drive letter will result in a throw:

      -
      // On Windows :
      -
      -// - WHATWG file URLs with hostname convert to UNC path
      -// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file
      -fs.readFileSync(new URL('file://hostname/p/a/t/h/file'));
      -
      -// - WHATWG file URLs with drive letters convert to absolute path
      -// file:///C:/tmp/hello => C:\tmp\hello
      -fs.readFileSync(new URL('file:///C:/tmp/hello'));
      -
      -// - WHATWG file URLs without hostname must have a drive letters
      -fs.readFileSync(new URL('file:///notdriveletter/p/a/t/h/file'));
      -fs.readFileSync(new URL('file:///c/p/a/t/h/file'));
      -// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute
      -

      file: URLs with drive letters must use : as a separator just after -the drive letter. Using another separator will result in a throw.

      -

      On all other platforms, file: URLs with a host name are unsupported and will -result in a throw:

      -
      // On other platforms:
      -
      -// - WHATWG file URLs with hostname are unsupported
      -// file://hostname/p/a/t/h/file => throw!
      -fs.readFileSync(new URL('file://hostname/p/a/t/h/file'));
      -// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute
      +

      The callback-based versions of the fs module APIs are preferable over +the use of the promise APIs when maximal performance (both in terms of +execution time and memory allocation are required).

      +

      Synchronous example#

      +

      The synchronous APIs block the Node.js event loop and further JavaScript +execution until the operation is complete. Exceptions are thrown immediately +and can be handled using try…catch, or can be allowed to bubble up.

      -// - WHATWG file URLs convert to absolute path -// file:///tmp/hello => /tmp/hello -fs.readFileSync(new URL('file:///tmp/hello'));
      -

      A file: URL having encoded slash characters will result in a throw on all -platforms:

      -
      // On Windows
      -fs.readFileSync(new URL('file:///C:/p/a/t/h/%2F'));
      -fs.readFileSync(new URL('file:///C:/p/a/t/h/%2f'));
      -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
      -\ or / characters */
      +
      import { unlinkSync } from 'fs';
       
      -// On POSIX
      -fs.readFileSync(new URL('file:///p/a/t/h/%2F'));
      -fs.readFileSync(new URL('file:///p/a/t/h/%2f'));
      -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
      -/ characters */
      -

      On Windows, file: URLs having encoded backslash will result in a throw:

      -
      // On Windows
      -fs.readFileSync(new URL('file:///C:/path/%5C'));
      -fs.readFileSync(new URL('file:///C:/path/%5c'));
      -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
      -\ or / characters */
      -

      File descriptors#

      -

      On POSIX systems, for every process, the kernel maintains a table of currently -open files and resources. Each open file is assigned a simple numeric -identifier called a file descriptor. At the system-level, all file system -operations use these file descriptors to identify and track each specific -file. Windows systems use a different but conceptually similar mechanism for -tracking resources. To simplify things for users, Node.js abstracts away the -specific differences between operating systems and assigns all open files a -numeric file descriptor.

      -

      The fs.open() method is used to allocate a new file descriptor. Once -allocated, the file descriptor may be used to read data from, write data to, -or request information about the file.

      -
      fs.open('/open/some/file.txt', 'r', (err, fd) => {
      -  if (err) throw err;
      -  fs.fstat(fd, (err, stat) => {
      -    if (err) throw err;
      -    // use stat
      +try {
      +  unlinkSync('/tmp/hello');
      +  console.log('successfully deleted /tmp/hello');
      +} catch (err) {
      +  // handle the error
      +}const { unlinkSync } = require('fs');
       
      -    // always close the file descriptor!
      -    fs.close(fd, (err) => {
      -      if (err) throw err;
      -    });
      -  });
      -});
      -

      Most operating systems limit the number of file descriptors that may be open -at any given time so it is critical to close the descriptor when operations -are completed. Failure to do so will result in a memory leak that will -eventually cause an application to crash.

      -

      Threadpool usage#

      -

      All file system APIs except fs.FSWatcher() and those that are explicitly -synchronous use libuv's threadpool, which can have surprising and negative -performance implications for some applications. See the -UV_THREADPOOL_SIZE documentation for more information.

      -

      Class: fs.Dir#

      +try { + unlinkSync('/tmp/hello'); + console.log('successfully deleted /tmp/hello'); +} catch (err) { + // handle the error +}
      +

      Promises API#

      -

      A class representing a directory stream.

      -

      Created by fs.opendir(), fs.opendirSync(), or -fsPromises.opendir().

      -
      const fs = require('fs');
      -
      -async function print(path) {
      -  const dir = await fs.promises.opendir(path);
      -  for await (const dirent of dir) {
      -    console.log(dirent.name);
      -  }
      -}
      -print('./').catch(console.error);
      -

      dir.close()#

      +

      The fs/promises API provides asynchronous file system methods that return +promises.

      +

      The promise APIs use the underlying Node.js threadpool to perform file +system operations off the event loop thread. These operations are not +synchronized or threadsafe. Care must be taken when performing multiple +concurrent modifications on the same file or data corruption may occur.

      +

      Class: FileHandle#

      - -

      Asynchronously close the directory's underlying resource handle. -Subsequent reads will result in errors.

      -

      A Promise is returned that will be resolved after the resource has been -closed.

      -

      dir.close(callback)#

      +

      A <FileHandle> object is an object wrapper for a numeric file descriptor.

      +

      Instances of the <FileHandle> object are created by the fsPromises.open() +method.

      +

      All <FileHandle> objects are <EventEmitter>s.

      +

      If a <FileHandle> is not closed using the filehandle.close() method, it will +try to automatically close the file descriptor and emit a process warning, +helping to prevent memory leaks. Please do not rely on this behavior because +it can be unreliable and the file may not be closed. Instead, always explicitly +close <FileHandle>s. Node.js may change this behavior in the future.

      +
      filehandle.appendFile(data[, options])#
      -

      Asynchronously close the directory's underlying resource handle. -Subsequent reads will result in errors.

      -

      The callback will be called after the resource handle has been closed.

      -

      dir.closeSync()#

      +

      Alias of filehandle.writeFile().

      +

      When operating on file handles, the mode cannot be changed from what it was set +to with fsPromises.open(). Therefore, this is equivalent to +filehandle.writeFile().

      +
      filehandle.chmod(mode)#
      -

      Synchronously close the directory's underlying resource handle. -Subsequent reads will result in errors.

      -

      dir.path#

      +
        +
      • mode <integer> the file mode bit mask.
      • +
      • Returns: <Promise> Fulfills with undefined upon success.
      • +
      +

      Modifies the permissions on the file. See chmod(2).

      +
      filehandle.chown(uid, gid)#
      -

      The read-only path of this directory as was provided to fs.opendir(), -fs.opendirSync(), or fsPromises.opendir().

      -

      dir.read()#

      +

      Changes the ownership of the file. A wrapper for chown(2).

      +
      filehandle.close()#
      -

      Asynchronously read the next directory entry via readdir(3) as an -fs.Dirent.

      -

      After the read is completed, a Promise is returned that will be resolved with -an fs.Dirent, or null if there are no more directory entries to read.

      -

      Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results.

      -

      dir.read(callback)#

      +

      Closes the file handle after waiting for any pending operation on the handle to +complete.

      +
      import { open } from 'fs/promises';
      +
      +let filehandle;
      +try {
      +  filehandle = await open('thefile.txt', 'r');
      +} finally {
      +  await filehandle?.close();
      +}
      +
      filehandle.datasync()#
        -
      • callback <Function> - -
      • +

        Forces all currently queued I/O operations associated with the file to the +operating system's synchronized I/O completion state. Refer to the POSIX +fdatasync(2) documentation for details.

        +

        Unlike filehandle.sync this method does not flush modified metadata.

        +
        filehandle.fd#
        + + -

        Asynchronously read the next directory entry via readdir(3) as an -fs.Dirent.

        -

        After the read is completed, the callback will be called with an -fs.Dirent, or null if there are no more directory entries to read.

        -

        Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results.

        -

        dir.readSync()#

        +
        filehandle.read(buffer, offset, length, position)#
        -

        Synchronously read the next directory entry via readdir(3) as an -fs.Dirent.

        -

        If there are no more directory entries to read, null will be returned.

        -

        Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results.

        -

        dir[Symbol.asyncIterator]()#

        - +
      • buffer <Buffer> | <TypedArray> | <DataView> A buffer that will be filled with the +file data read.
      • +
      • offset <integer> The location in the buffer at which to start filling. +Default: 0
      • +
      • length <integer> The number of bytes to read. Default: +buffer.byteLength
      • +
      • position <integer> The location where to begin reading data from the +file. If null, data will be read from the current file position, and +the position will be updated. If position is an integer, the current +file position will remain unchanged.
      • +
      • Returns: <Promise> Fulfills upon success with an object with two properties: -

        Asynchronously iterates over the directory via readdir(3) until all entries have -been read.

        -

        Entries returned by the async iterator are always an fs.Dirent. -The null case from dir.read() is handled internally.

        -

        See fs.Dir for an example.

        -

        Directory entries returned by this iterator are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results.

        -

        Class: fs.Dirent#

        - -

        A representation of a directory entry, which can be a file or a subdirectory -within the directory, as returned by reading from an fs.Dir. The -directory entry is a combination of the file name and file type pairs.

        -

        Additionally, when fs.readdir() or fs.readdirSync() is called with -the withFileTypes option set to true, the resulting array is filled with -fs.Dirent objects, rather than strings or Buffers.

        -

        dirent.isBlockDevice()#

        +
      • +
      +

      Reads data from the file and stores that in the given buffer.

      +

      If the file is not modified concurrently, the end-of-file is reached when the +number of bytes read is zero.

      +
      filehandle.read([options])#
        -
      • Returns: <boolean>
      • +
      • options <Object> +
          +
        • buffer <Buffer> | <TypedArray> | <DataView> A buffer that will be filled with the +file data read. Default: Buffer.alloc(16384)
        • +
        • offset <integer> The location in the buffer at which to start filling. +Default: 0
        • +
        • length <integer> The number of bytes to read. Default: +buffer.byteLength
        • +
        • position <integer> The location where to begin reading data from the +file. If null, data will be read from the current file position, and +the position will be updated. If position is an integer, the current +file position will remain unchanged. Default:: null
        -

        Returns true if the fs.Dirent object describes a block device.

        -

        dirent.isCharacterDevice()#

        - +
      • +
      • Returns: <Promise> Fulfills upon success with an object with two properties: +
      -

      Returns true if the fs.Dirent object describes a character device.

      -

      dirent.isDirectory()#

      +

      Reads data from the file and stores that in the given buffer.

      +

      If the file is not modified concurrently, the end-of-file is reached when the +number of bytes read is zero.

      +
      filehandle.readFile(options)#
        -
      • Returns: <boolean>
      • +
      • options <Object> | <string> + -

        Returns true if the fs.Dirent object describes a file system -directory.

        -

        dirent.isFIFO()#

        +
      • +
      • Returns: <Promise> Fulfills upon a successful read with the contents of the +file. If no encoding is specified (using options.encoding), the data is +returned as a <Buffer> object. Otherwise, the data will be a string.
      • +
      +

      Asynchronously reads the entire contents of a file.

      +

      If options is a string, then it specifies the encoding.

      +

      The <FileHandle> has to support reading.

      +

      If one or more filehandle.read() calls are made on a file handle and then a +filehandle.readFile() call is made, the data will be read from the current +position till the end of the file. It doesn't always read from the beginning +of the file.

      +
      filehandle.readv(buffers[, position])#
        -
      • Returns: <boolean>
      • +
      • buffers <Buffer[]> | <TypedArray[]> | <DataView[]>
      • +
      • position <integer> The offset from the beginning of the file where the data +should be read from. If position is not a number, the data will be read +from the current position.
      • +
      • Returns: <Promise> Fulfills upon success an object containing two properties: + -

        Returns true if the fs.Dirent object describes a first-in-first-out -(FIFO) pipe.

        -

        dirent.isFile()#

        +
      • +
      +

      Read from a file and write to an array of <ArrayBufferView>s

      +
      filehandle.stat([options])#
      -

      Returns true if the fs.Dirent object describes a regular file.

      -

      dirent.isSocket()#

      +
      filehandle.sync()#
      -

      Returns true if the fs.Dirent object describes a socket.

      -

      dirent.isSymbolicLink()#

      +

      Request that all data for the open file descriptor is flushed to the storage +device. The specific implementation is operating system and device specific. +Refer to the POSIX fsync(2) documentation for more detail.

      +
      filehandle.truncate(len)#
      -

      Returns true if the fs.Dirent object describes a symbolic link.

      -

      dirent.name#

      +

      Truncates the file.

      +

      If the file was larger than len bytes, only the first len bytes will be +retained in the file.

      +

      The following example retains only the first four bytes of the file:

      +
      import { open } from 'fs/promises';
      +
      +let filehandle = null;
      +try {
      +  filehandle = await open('temp.txt', 'r+');
      +  await filehandle.truncate(4);
      +} finally {
      +  await filehandle?.close();
      +}
      +

      If the file previously was shorter than len bytes, it is extended, and the +extended part is filled with null bytes ('\0'):

      +

      If len is negative then 0 will be used.

      +
      filehandle.utimes(atime, mtime)#
      -

      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().

      -

      Class: fs.FSWatcher#

      +

      Change the file system timestamps of the object referenced by the <FileHandle> +then resolves the promise with no arguments upon success.

      +

      This function does not work on AIX versions before 7.1, it will reject the +promise with an error using code UV_ENOSYS.

      +
      filehandle.write(buffer[, offset[, length[, position]]])#
        -
      • Extends <EventEmitter>
      • +
      • buffer <Buffer> | <TypedArray> | <DataView> | <string> | <Object>
      • +
      • offset <integer> The start position from within buffer where the data +to write begins. Default: 0
      • +
      • length <integer> The number of bytes from buffer to write. Default: +buffer.byteLength
      • +
      • position <integer> The offset from the beginning of the file where the +data from buffer should be written. If position is not a number, +the data will be written at the current position. See the POSIX pwrite(2) +documentation for more detail.
      • +
      • Returns: <Promise>
      -

      A successful call to fs.watch() method will return a new fs.FSWatcher -object.

      -

      All fs.FSWatcher objects emit a 'change' event whenever a specific watched -file is modified.

      -

      Event: 'change'#

      - +

      Write buffer to the file.

      +

      If buffer is a plain object, it must have an own (not inherited) toString +function property.

      +

      The promise is resolved with an object containing two properties:

      -

      Emitted when something changes in a watched directory or file. -See more details in fs.watch().

      -

      The filename argument may not be provided depending on operating system -support. If filename is provided, it will be provided as a Buffer if -fs.watch() is called with its encoding option set to 'buffer', otherwise -filename will be a UTF-8 string.

      -
      // Example when handled through fs.watch() listener
      -fs.watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {
      -  if (filename) {
      -    console.log(filename);
      -    // Prints: <Buffer ...>
      -  }
      -});
      -

      Event: 'close'#

      - -

      Emitted when the watcher stops watching for changes. The closed -fs.FSWatcher object is no longer usable in the event handler.

      -

      Event: 'error'#

      +

      It is unsafe to use filehandle.write() multiple times on the same file +without waiting for the promise to be resolved (or rejected). For this +scenario, use fs.createWriteStream().

      +

      On Linux, positional writes do not work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file.

      +
      filehandle.write(string[, position[, encoding]])#
        -
      • error <Error>
      • +
      • string <string> | <Object>
      • +
      • position <integer> The offset from the beginning of the file where the +data from string should be written. If position is not a number the +data will be written at the current position. See the POSIX pwrite(2) +documentation for more detail.
      • +
      • encoding <string> The expected string encoding. Default: 'utf8'
      • +
      • Returns: <Promise>
      -

      Emitted when an error occurs while watching the file. The errored -fs.FSWatcher object is no longer usable in the event handler.

      -

      watcher.close()#

      - -

      Stop watching for changes on the given fs.FSWatcher. Once stopped, the -fs.FSWatcher object is no longer usable.

      -

      watcher.ref()#

      - +

      Write string to the file. If string is not a string, or an object with an +own toString function property, the promise is rejected with an error.

      +

      The promise is resolved with an object containing two properties:

      -

      When called, requests that the Node.js event loop not exit so long as the -FSWatcher is active. Calling watcher.ref() multiple times will have -no effect.

      -

      By default, all FSWatcher objects are "ref'ed", making it normally -unnecessary to call watcher.ref() unless watcher.unref() had been -called previously.

      -

      watcher.unref()#

      +

      It is unsafe to use filehandle.write() multiple times on the same file +without waiting for the promise to be resolved (or rejected). For this +scenario, use fs.createWriteStream().

      +

      On Linux, positional writes do not work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file.

      +
      filehandle.writeFile(data, options)#
      +

      Asynchronously writes data to a file, replacing the file if it already exists. +data can be a string, a buffer, an <AsyncIterable> or <Iterable> object, or an +object with an own toString function +property. The promise is resolved with no arguments upon success.

      +

      If options is a string, then it specifies the encoding.

      +

      The <FileHandle> has to support writing.

      +

      It is unsafe to use filehandle.writeFile() multiple times on the same file +without waiting for the promise to be resolved (or rejected).

      +

      If one or more filehandle.write() calls are made on a file handle and then a +filehandle.writeFile() call is made, the data will be written from the +current position till the end of the file. It doesn't always write from the +beginning of the file.

      +
      filehandle.writev(buffers[, position])#
      -

      A successful call to fs.watchFile() method will return a new fs.StatWatcher -object.

      -

      watcher.ref()#

      - +

      Write an array of <ArrayBufferView>s to the file.

      +

      The promise is resolved with an object containing a two properties:

      -

      When called, requests that the Node.js event loop not exit so long as the -StatWatcher is active. Calling watcher.ref() multiple times will have -no effect.

      -

      By default, all StatWatcher objects are "ref'ed", making it normally -unnecessary to call watcher.ref() unless watcher.unref() had been -called previously.

      -

      watcher.unref()#

      +

      It is unsafe to call writev() multiple times on the same file without waiting +for the promise to be resolved (or rejected).

      +

      On Linux, positional writes don't work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file.

      +

      fsPromises.access(path[, mode])#

      -

      When called, the active StatWatcher object will not require the Node.js -event loop to remain active. If there is no other activity keeping the -event loop running, the process may exit before the StatWatcher object's -callback is invoked. Calling watcher.unref() multiple times will have -no effect.

      -

      Class: fs.ReadStream#

      +

      Tests a user's permissions for the file or directory specified by path. +The mode argument is an optional integer that specifies the accessibility +checks to be performed. Check File access constants for possible values +of mode. It is possible to create a mask consisting of the bitwise OR of +two or more values (e.g. fs.constants.W_OK | fs.constants.R_OK).

      +

      If the accessibility check is successful, the promise is resolved with no +value. If any of the accessibility checks fail, the promise is rejected +with an <Error> object. The following example checks if the file +/etc/passwd can be read and written by the current process.

      +
      import { access } from 'fs/promises';
      +import { constants } from 'fs';
      +
      +try {
      +  await access('/etc/passwd', constants.R_OK | constants.W_OK);
      +  console.log('can access');
      +} catch {
      +  console.error('cannot access');
      +}
      +

      Using fsPromises.access() to check for the accessibility of a file before +calling fsPromises.open() is not recommended. Doing so introduces a race +condition, since other processes may change the file's state between the two +calls. Instead, user code should open/read/write the file directly and handle +the error raised if the file is not accessible.

      +

      fsPromises.appendFile(path, data[, options])#

      +

      Asynchronously append data to a file, creating the file if it does not yet +exist. data can be a string or a <Buffer>.

      +

      If options is a string, then it specifies the encoding.

      +

      The mode option only affects the newly created file. See fs.open() +for more details.

      +

      The path may be specified as a <FileHandle> that has been opened +for appending (using fsPromises.open()).

      +

      fsPromises.chmod(path, mode)#

      -

      Emitted when the fs.ReadStream's file descriptor has been opened.

      -

      Event: 'ready'#

      - -

      Emitted when the fs.ReadStream is ready to be used.

      -

      Fires immediately after 'open'.

      -

      readStream.bytesRead#

      +

      Changes the permissions of a file.

      +

      fsPromises.chown(path, uid, gid)#

      -

      The number of bytes that have been read so far.

      -

      readStream.path#

      +

      Changes the ownership of a file.

      +

      fsPromises.copyFile(src, dest[, mode])#

        -
      • <string> | <Buffer>
      • +
      • src <string> | <Buffer> | <URL> source filename to copy
      • +
      • dest <string> | <Buffer> | <URL> destination filename of the copy operation
      • +
      • mode <integer> Optional modifiers that specify the behavior of the copy +operation. It is possible to create a mask consisting of the bitwise OR of +two or more values (e.g. +fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE) +Default: 0. +
          +
        • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest +already exists.
        • +
        • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create +a copy-on-write reflink. If the platform does not support copy-on-write, +then a fallback copy mechanism is used.
        • +
        • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to +create a copy-on-write reflink. If the platform does not support +copy-on-write, then the operation will fail.
        -

        The path to the file the stream is reading from as specified in the first -argument to fs.createReadStream(). If path is passed as a string, then -readStream.path will be a string. If path is passed as a Buffer, then -readStream.path will be a Buffer.

        -

        readStream.pending#

        +
      • +
      • Returns: <Promise> Fulfills with undefined upon success.
      • +
      +

      Asynchronously copies src to dest. By default, dest is overwritten if it +already exists.

      +

      No guarantees are made about the atomicity of the copy operation. If an +error occurs after the destination file has been opened for writing, an attempt +will be made to remove the destination.

      +
      import { constants } from 'fs';
      +import { copyFile } from 'fs/promises';
      +
      +try {
      +  await copyFile('source.txt', 'destination.txt');
      +  console.log('source.txt was copied to destination.txt');
      +} catch {
      +  console.log('The file could not be copied');
      +}
      +
      +// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
      +try {
      +  await copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL);
      +  console.log('source.txt was copied to destination.txt');
      +} catch {
      +  console.log('The file could not be copied');
      +}
      +

      fsPromises.lchmod(path, mode)#

      -

      This property is true if the underlying file has not been opened yet, -i.e. before the 'ready' event is emitted.

      -

      Class: fs.Stats#

      +

      Changes the permissions on a symbolic link.

      +

      This method is only implemented on macOS.

      +

      fsPromises.lchown(path, uid, gid)#

      -

      A fs.Stats object provides information about a file.

      -

      Objects returned from fs.stat(), fs.lstat() and fs.fstat() and -their synchronous counterparts are of this type. -If bigint in the options passed to those methods is true, the numeric values -will be bigint instead of number, and the object will contain additional -nanosecond-precision properties suffixed with Ns.

      -
      Stats {
      -  dev: 2114,
      -  ino: 48064969,
      -  mode: 33188,
      -  nlink: 1,
      -  uid: 85,
      -  gid: 100,
      -  rdev: 0,
      -  size: 527,
      -  blksize: 4096,
      -  blocks: 8,
      -  atimeMs: 1318289051000.1,
      -  mtimeMs: 1318289051000.1,
      -  ctimeMs: 1318289051000.1,
      -  birthtimeMs: 1318289051000.1,
      -  atime: Mon, 10 Oct 2011 23:24:11 GMT,
      -  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
      -  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
      -  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
      -

      bigint version:

      -
      BigIntStats {
      -  dev: 2114n,
      -  ino: 48064969n,
      -  mode: 33188n,
      -  nlink: 1n,
      -  uid: 85n,
      -  gid: 100n,
      -  rdev: 0n,
      -  size: 527n,
      -  blksize: 4096n,
      -  blocks: 8n,
      -  atimeMs: 1318289051000n,
      -  mtimeMs: 1318289051000n,
      -  ctimeMs: 1318289051000n,
      -  birthtimeMs: 1318289051000n,
      -  atimeNs: 1318289051000000000n,
      -  mtimeNs: 1318289051000000000n,
      -  ctimeNs: 1318289051000000000n,
      -  birthtimeNs: 1318289051000000000n,
      -  atime: Mon, 10 Oct 2011 23:24:11 GMT,
      -  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
      -  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
      -  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
      -

      stats.isBlockDevice()#

      - -

      Returns true if the fs.Stats object describes a block device.

      -

      stats.isCharacterDevice()#

      +

      Changes the ownership on a symbolic link.

      +

      fsPromises.lutimes(path, atime, mtime)#

      -

      Returns true if the fs.Stats object describes a character device.

      -

      stats.isDirectory()#

      +

      Changes the access and modification times of a file in the same way as +fsPromises.utimes(), with the difference that if the path refers to a +symbolic link, then the link is not dereferenced: instead, the timestamps of +the symbolic link itself are changed.

      +

      fsPromises.link(existingPath, newPath)#

      -

      Returns true if the fs.Stats object describes a file system directory.

      -

      stats.isFIFO()#

      +

      Creates a new link from the existingPath to the newPath. See the POSIX +link(2) documentation for more detail.

      +

      fsPromises.lstat(path[, options])#

      -

      Returns true if the fs.Stats object describes a first-in-first-out (FIFO) -pipe.

      -

      stats.isFile()#

      - +
    • path <string> | <Buffer> | <URL>
    • +
    • options <Object> -

      Returns true if the fs.Stats object describes a regular file.

      -

      stats.isSocket()#

      - - -

      Returns true if the fs.Stats object describes a socket.

      -

      stats.isSymbolicLink()#

      +

      Equivalent to fsPromises.stat() unless path refers to a symbolic link, +in which case the link itself is stat-ed, not the file that it refers to. +Refer to the POSIX lstat(2) document for more detail.

      +

      fsPromises.mkdir(path[, options])#

      -

      Returns true if the fs.Stats object describes a symbolic link.

      -

      This method is only valid when using fs.lstat().

      -

      stats.dev#

      - -

      The numeric identifier of the device containing the file.

      -

      stats.ino#

      - -

      The file system specific "Inode" number for the file.

      -

      stats.mode#

      - -

      A bit-field describing the file type and mode.

      -

      stats.nlink#

      - -

      The number of hard-links that exist for the file.

      -

      stats.uid#

      - -

      The numeric user identifier of the user that owns the file (POSIX).

      -

      stats.gid#

      - -

      The numeric group identifier of the group that owns the file (POSIX).

      -

      stats.rdev#

      - -

      A numeric device identifier if the file represents a device.

      -

      stats.size#

      - -

      The size of the file in bytes.

      -

      stats.blksize#

      +
    • path <string> | <Buffer> | <URL>
    • +
    • options <Object> | <integer> -

      The file system block size for i/o operations.

      -

      stats.blocks#

      -
        -
      • <number> | <bigint>
      • + +
      • Returns: <Promise> Upon success, fulfills with undefined if recursive +is false, or the first directory path created if recursive is true.
      -

      The number of blocks allocated for this file.

      -

      stats.atimeMs#

      +

      Asynchronously creates a directory.

      +

      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 directories should be created. Calling +fsPromises.mkdir() when path is a directory that exists results in a +rejection only when recursive is false.

      +

      fsPromises.mkdtemp(prefix[, options])#

      -

      The timestamp indicating the last time this file was accessed expressed in -milliseconds since the POSIX Epoch.

      -

      stats.mtimeMs#

      - +
    • prefix <string>
    • +
    • options <string> | <Object> -

      The timestamp indicating the last time this file was modified expressed in -milliseconds since the POSIX Epoch.

      -

      stats.ctimeMs#

      - -
        -
      • <number> | <bigint>
      • + +
      • Returns: <Promise> Fulfills with a string containing the filesystem path +of the newly created temporary directory.
      -

      The timestamp indicating the last time the file status was changed expressed -in milliseconds since the POSIX Epoch.

      -

      stats.birthtimeMs#

      +

      Creates a unique temporary directory. A unique directory name is generated by +appending six random characters to the end of the provided prefix. Due to +platform inconsistencies, avoid trailing X characters in prefix. Some +platforms, notably the BSDs, can return more than six random characters, and +replace trailing X characters in prefix with random characters.

      +

      The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use.

      +
      import { mkdtemp } from 'fs/promises';
      +
      +try {
      +  await mkdtemp(path.join(os.tmpdir(), 'foo-'));
      +} catch (err) {
      +  console.error(err);
      +}
      +

      The fsPromises.mkdtemp() method will append the six randomly selected +characters directly to the prefix string. For instance, given a directory +/tmp, if the intention is to create a temporary directory within /tmp, the +prefix must end with a trailing platform-specific path separator +(require('path').sep).

      +

      fsPromises.open(path, flags[, mode])#

      -

      The timestamp indicating the creation time of this file expressed in -milliseconds since the POSIX Epoch.

      -

      stats.atimeNs#

      +

      Opens a <FileHandle>.

      +

      Refer to the POSIX open(2) documentation for more detail.

      +

      Some characters (< > : " / \ | ? *) are reserved under Windows as documented +by Naming Files, Paths, and Namespaces. Under NTFS, if the filename contains +a colon, Node.js will open a file system stream, as described by +this MSDN page.

      +

      fsPromises.opendir(path[, options])#

        -
      • <bigint>
      • +
      • path <string> | <Buffer> | <URL>
      • +
      • options <Object> +
          +
        • encoding <string> | <null> Default: 'utf8'
        • +
        • bufferSize <number> Number of directory entries that are buffered +internally when reading from the directory. Higher values lead to better +performance but higher memory usage. Default: 32
        -

        Only present when bigint: true is passed into the method that generates -the object. -The timestamp indicating the last time this file was accessed expressed in -nanoseconds since the POSIX Epoch.

        -

        stats.mtimeNs#

        +
      • +
      • Returns: <Promise> Fulfills with an <fs.Dir>.
      • +
      +

      Asynchronously open a directory for iterative scanning. See the POSIX +opendir(3) documentation for more detail.

      +

      Creates an <fs.Dir>, which contains all further functions for reading from +and cleaning up the directory.

      +

      The encoding option sets the encoding for the path while opening the +directory and subsequent read operations.

      +

      Example using async iteration:

      +
      import { opendir } from 'fs/promises';
      +
      +try {
      +  const dir = await opendir('./');
      +  for await (const dirent of dir)
      +    console.log(dirent.name);
      +} catch (err) {
      +  console.error(err);
      +}
      +

      When using the async iterator, the <fs.Dir> object will be automatically +closed after the iterator exits.

      +

      fsPromises.readdir(path[, options])#

        -
      • <bigint>
      • +
      • path <string> | <Buffer> | <URL>
      • +
      • options <string> | <Object> + -

        Only present when bigint: true is passed into the method that generates -the object. -The timestamp indicating the last time this file was modified expressed in -nanoseconds since the POSIX Epoch.

        -

        stats.ctimeNs#

        +
      • +
      • Returns: <Promise> Fulfills with an array of the names of the files in +the directory excluding '.' and '..'.
      • +
      +

      Reads the contents of a directory.

      +

      The optional options argument can be a string specifying an encoding, or an +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.

      +
      import { readdir } from 'fs/promises';
      +
      +try {
      +  const files = await readdir(path);
      +  for (const file of files)
      +    console.log(file);
      +} catch (err) {
      +  console.error(err);
      +}
      +

      fsPromises.readFile(path[, options])#

      +

      Asynchronously reads the entire contents of a file.

      +

      If no encoding is specified (using options.encoding), the data is returned +as a <Buffer> object. Otherwise, the data will be a string.

      +

      If options is a string, then it specifies the encoding.

      +

      When the path is a directory, the behavior of fsPromises.readFile() is +platform-specific. On macOS, Linux, and Windows, the promise will be rejected +with an error. On FreeBSD, a representation of the directory's contents will be +returned.

      +

      It is possible to abort an ongoing readFile using an <AbortSignal>. If a +request is aborted the promise returned is rejected with an AbortError:

      +
      import { readFile } from 'fs/promises';
      +
      +try {
      +  const controller = new AbortController();
      +  const { signal } = controller;
      +  const promise = readFile(fileName, { signal });
      +
      +  // Abort the request before the promise settles.
      +  controller.abort();
      +
      +  await promise;
      +} catch (err) {
      +  // When a request is aborted - err is an AbortError
      +  console.error(err);
      +}
      +

      Aborting an ongoing request does not abort individual operating +system requests but rather the internal buffering fs.readFile performs.

      +

      Any specified <FileHandle> has to support reading.

      +

      fsPromises.readlink(path[, options])#

        -
      • <bigint>
      • +
      • path <string> | <Buffer> | <URL>
      • +
      • options <string> | <Object> + -

        Only present when bigint: true is passed into the method that generates -the object. -The timestamp indicating the creation time of this file expressed in -nanoseconds since the POSIX Epoch.

        -

        stats.atime#

        +
      • +
      • Returns: <Promise> Fulfills with the linkString upon success.
      • +
      +

      Reads the contents of the symbolic link referred to by path. See the POSIX +readlink(2) documentation for more detail. The promise is resolved with the +linkString upon success.

      +

      The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use for +the link path returned. If the encoding is set to 'buffer', the link path +returned will be passed as a <Buffer> object.

      +

      fsPromises.realpath(path[, options])#

      +

      Determines the actual location of path using the same semantics as the +fs.realpath.native() function.

      +

      Only paths that can be converted to UTF8 strings are supported.

      +

      The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use for +the path. If the encoding is set to 'buffer', the path returned will be +passed as a <Buffer> object.

      +

      On Linux, when Node.js is linked against musl libc, the procfs file system must +be mounted on /proc in order for this function to work. Glibc does not have +this restriction.

      +

      fsPromises.rename(oldPath, newPath)#

      -

      The timestamp indicating the last time this file was modified.

      -

      stats.ctime#

      +

      Renames oldPath to newPath.

      +

      fsPromises.rmdir(path[, options])#

        -
      • <Date>
      • +
      • path <string> | <Buffer> | <URL>
      • +
      • options <Object> +
          +
        • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or +EPERM error is encountered, Node.js retries the operation with a linear +backoff wait of retryDelay milliseconds longer on each try. This option +represents the number of retries. This option is ignored if the recursive +option is not true. Default: 0.
        • +
        • recursive <boolean> If true, perform a recursive directory removal. In +recursive mode, errors are not reported if path does not exist, and +operations are retried on failure. Default: false.
        • +
        • retryDelay <integer> The amount of time in milliseconds to wait between +retries. This option is ignored if the recursive option is not true. +Default: 100.
        -

        The timestamp indicating the last time the file status was changed.

        -

        stats.birthtime#

        +
      • +
      • Returns: <Promise> Fulfills with undefined upon success.
      • +
      +

      Removes the directory identified by path.

      +

      Using fsPromises.rmdir() on a file (not a directory) results in the +promise being rejected with an ENOENT error on Windows and an ENOTDIR +error on POSIX.

      +

      Setting recursive to true results in behavior similar to the Unix command +rm -rf: an error will not be raised for paths that do not exist, and paths +that represent files will be deleted. The permissive behavior of the +recursive option is deprecated, ENOTDIR and ENOENT will be thrown in +the future.

      +

      fsPromises.rm(path[, options])#

      -

      The timestamp indicating the creation time of this file.

      -

      Stat time values#

      -

      The atimeMs, mtimeMs, ctimeMs, birthtimeMs properties are -numeric values that hold the corresponding times in milliseconds. Their -precision is platform specific. When bigint: true is passed into the -method that generates the object, the properties will be bigints, -otherwise they will be numbers.

      -

      The atimeNs, mtimeNs, ctimeNs, birthtimeNs properties are -bigints that hold the corresponding times in nanoseconds. They are -only present when bigint: true is passed into the method that generates -the object. Their precision is platform specific.

      -

      atime, mtime, ctime, and birthtime are -Date object alternate representations of the various times. The -Date and number values are not connected. Assigning a new number value, or -mutating the Date value, will not be reflected in the corresponding alternate -representation.

      -

      The times in the stat object have the following semantics:

      +
    • path <string> | <Buffer> | <URL>
    • +
    • options <Object>
        -
      • atime "Access Time": Time when file data last accessed. Changed -by the mknod(2), utimes(2), and read(2) system calls.
      • -
      • mtime "Modified Time": Time when file data last modified. -Changed by the mknod(2), utimes(2), and write(2) system calls.
      • -
      • ctime "Change Time": Time when file status was last changed -(inode data modification). Changed by the chmod(2), chown(2), -link(2), mknod(2), rename(2), unlink(2), utimes(2), -read(2), and write(2) system calls.
      • -
      • birthtime "Birth Time": Time of file creation. Set once when the -file is created. On filesystems where birthtime is not available, -this field may instead hold either the ctime or -1970-01-01T00:00Z (ie, Unix epoch timestamp 0). This value may be greater -than atime or mtime in this case. On Darwin and other FreeBSD variants, -also set if the atime is explicitly set to an earlier value than the current -birthtime using the utimes(2) system call.
      • +
      • force <boolean> When true, exceptions will be ignored if path does +not exist. Default: false.
      • +
      • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or +EPERM error is encountered, Node.js will retry the operation with a linear +backoff wait of retryDelay milliseconds longer on each try. This option +represents the number of retries. This option is ignored if the recursive +option is not true. Default: 0.
      • +
      • recursive <boolean> If true, perform a recursive directory removal. In +recursive mode operations are retried on failure. Default: false.
      • +
      • retryDelay <integer> The amount of time in milliseconds to wait between +retries. This option is ignored if the recursive option is not true. +Default: 100.
      -

      Prior to Node.js 0.12, the ctime held the birthtime on Windows systems. As -of 0.12, ctime is not "creation time", and on Unix systems, it never was.

      -

      Class: fs.WriteStream#

      +
    • +
    • Returns: <Promise> Fulfills with undefined upon success.
    • + +

      Removes files and directories (modeled on the standard POSIX rm utility).

      +

      fsPromises.stat(path[, options])#

      +

      fsPromises.symlink(target, path[, type])#

      -

      Emitted when the WriteStream's underlying file descriptor has been closed.

      -

      Event: 'open'#

      + +

      Creates a symbolic link.

      +

      The type argument is only used on Windows platforms and can be one of 'dir', +'file', or 'junction'. Windows junction points require the destination path +to be absolute. When using 'junction', the target argument will +automatically be normalized to absolute path.

      +

      fsPromises.truncate(path[, len])#

      -

      Emitted when the WriteStream's file is opened.

      -

      Event: 'ready'#

      +

      Truncates (shortens or extends the length) of the content at path to len +bytes.

      +

      fsPromises.unlink(path)#

      -

      Emitted when the fs.WriteStream is ready to be used.

      -

      Fires immediately after 'open'.

      -

      writeStream.bytesWritten#

      + +

      If path refers to a symbolic link, then the link is removed without affecting +the file or directory to which that link refers. If the path refers to a file +path that is not a symbolic link, the file is deleted. See the POSIX unlink(2) +documentation for more detail.

      +

      fsPromises.utimes(path, atime, mtime)#

      -

      The number of bytes written so far. Does not include data that is still queued -for writing.

      -

      writeStream.path#

      + +

      Change the file system timestamps of the object referenced by path.

      +

      The atime and mtime arguments follow these rules:

      +
        +
      • Values can be either numbers representing Unix epoch time, Dates, or a +numeric string like '123456789.0'.
      • +
      • If the value can not be converted to a number, or is NaN, Infinity or +-Infinity, an Error will be thrown.
      • +
      +

      fsPromises.watch(filename[, options])#

      -

      The path to the file the stream is writing to as specified in the first -argument to fs.createWriteStream(). If path is passed as a string, then -writeStream.path will be a string. If path is passed as a Buffer, then -writeStream.path will be a Buffer.

      -

      writeStream.pending#

      +
        +
      • filename <string> | <Buffer> | <URL>
      • +
      • options <string> | <Object> +
          +
        • persistent <boolean> Indicates whether the process should continue to run +as long as files are being watched. Default: true.
        • +
        • recursive <boolean> Indicates whether all subdirectories should be +watched, or only the current directory. This applies when a directory is +specified, and only on supported platforms (See caveats). Default: +false.
        • +
        • encoding <string> Specifies the character encoding to be used for the +filename passed to the listener. Default: 'utf8'.
        • +
        • signal <AbortSignal> An <AbortSignal> used to signal when the watcher +should stop.
        • +
        +
      • +
      • Returns: <AsyncIterator> of objects with the properties: + +
      • +
      +

      Returns an async iterator that watches for changes on filename, where filename +is either a file or a directory.

      +
      const { watch } = require('fs/promises');
      +
      +const ac = new AbortController();
      +const { signal } = ac;
      +setTimeout(() => ac.abort(), 10000);
      +
      +(async () => {
      +  try {
      +    const watcher = watch(__filename, { signal });
      +    for await (const event of watcher)
      +      console.log(event);
      +  } catch (err) {
      +    if (err.name === 'AbortError')
      +      return;
      +    throw err;
      +  }
      +})();
      +

      On most platforms, 'rename' is emitted whenever a filename appears or +disappears in the directory.

      +

      All the caveats for fs.watch() also apply to fsPromises.watch().

      +

      fsPromises.writeFile(file, data[, options])#

      +

      Asynchronously writes data to a file, replacing the file if it already exists. +data can be a string, a <Buffer>, or, an object with an own (not inherited) +toString function property.

      +

      The encoding option is ignored if data is a buffer.

      +

      If options is a string, then it specifies the encoding.

      +

      The mode option only affects the newly created file. See fs.open() +for more details.

      +

      Any specified <FileHandle> has to support writing.

      +

      It is unsafe to use fsPromises.writeFile() multiple times on the same file +without waiting for the promise to be settled.

      +

      Similarly to fsPromises.readFile - fsPromises.writeFile is a convenience +method that performs multiple write calls internally to write the buffer +passed to it. For performance sensitive code consider using +fs.createWriteStream().

      +

      It is possible to use an <AbortSignal> to cancel an fsPromises.writeFile(). +Cancelation is "best effort", and some amount of data is likely still +to be written.

      +
      import { writeFile } from 'fs/promises';
      +
      +try {
      +  const controller = new AbortController();
      +  const { signal } = controller;
      +  const data = new Uint8Array(Buffer.from('Hello Node.js'));
      +  const promise = writeFile('message.txt', data, { signal });
      +
      +  // Abort the request before the promise settles.
      +  controller.abort();
      +
      +  await promise;
      +} catch (err) {
      +  // When a request is aborted - err is an AbortError
      +  console.error(err);
      +}
      +

      Aborting an ongoing request does not abort individual operating +system requests but rather the internal buffering fs.writeFile performs.

      +

      Callback API#

      +

      The callback APIs perform all operations asynchronously, without blocking the +event loop, then invoke a callback function upon completion or error.

      +

      The callback APIs use the underlying Node.js threadpool to perform file +system operations off the event loop thread. These operations are not +synchronized or threadsafe. Care must be taken when performing multiple +concurrent modifications on the same file or data corruption may occur.

      +

      fs.access(path[, mode], callback)#

      - -

      Synchronously tests a user's permissions for the file or directory specified -by path. The mode argument is an optional integer that specifies the -accessibility checks to be performed. Check File access constants for -possible values of mode. It is possible to create a mask consisting of -the bitwise OR of two or more values -(e.g. fs.constants.W_OK | fs.constants.R_OK).

      -

      If any of the accessibility checks fail, an Error will be thrown. Otherwise, -the method will return undefined.

      -
      try {
      -  fs.accessSync('etc/passwd', fs.constants.R_OK | fs.constants.W_OK);
      -  console.log('can read/write');
      -} catch (err) {
      -  console.error('no access!');
      -}
      -

      fs.appendFile(path, data[, options], callback)#

      + try { + readMyData(fd); + } finally { + close(fd, (err) => { + if (err) throw err; + }); + } +});
      +

      The "not recommended" examples above check for accessibility and then use the +file; the "recommended" examples are better because they use the file directly +and handle the error, if any.

      +

      In general, check for the accessibility of a file only if the file will not be +used directly, for example when its accessibility is a signal from another +process.

      +

      On Windows, access-control policies (ACLs) on a directory may limit access to +a file or directory. The fs.access() function, however, does not check the +ACL and therefore may report that a path is accessible even if the ACL restricts +the user from reading or writing to it.

      +

      fs.appendFile(path, data[, options], callback)#

      - -

      Synchronously append data to a file, creating the file if it does not yet -exist. data can be a string or a Buffer.

      -
      try {
      -  fs.appendFileSync('message.txt', 'data to append');
      -  console.log('The "data to append" was appended to file!');
      -} catch (err) {
      -  /* Handle the error */
      -}
      -

      If options is a string, then it specifies the encoding:

      -
      fs.appendFileSync('message.txt', 'data to append', 'utf8');
      -

      The path may be specified as a numeric file descriptor that has been opened -for appending (using fs.open() or fs.openSync()). The file descriptor will -not be closed automatically.

      -
      let fd;
      -
      -try {
      -  fd = fs.openSync('message.txt', 'a');
      -  fs.appendFileSync(fd, 'data to append', 'utf8');
      -} catch (err) {
      -  /* Handle the error */
      -} finally {
      -  if (fd !== undefined)
      -    fs.closeSync(fd);
      -}
      -

      fs.chmod(path, mode, callback)#

      +

      fs.chmod(path, mode, callback)#

      Synchronous API#

      +

      The synchronous APIs perform all operations synchronously, blocking the +event loop until the operation completes or fails.

      +

      fs.accessSync(path[, mode])#

      + +

      Synchronously tests a user's permissions for the file or directory specified +by path. The mode argument is an optional integer that specifies the +accessibility checks to be performed. Check File access constants for +possible values of mode. It is possible to create a mask consisting of +the bitwise OR of two or more values +(e.g. fs.constants.W_OK | fs.constants.R_OK).

      +

      If any of the accessibility checks fail, an Error will be thrown. Otherwise, +the method will return undefined.

      +
      import { accessSync, constants } from 'fs';
      +
      +try {
      +  accessSync('etc/passwd', constants.R_OK | constants.W_OK);
      +  console.log('can read/write');
      +} catch (err) {
      +  console.error('no access!');
      +}
      +

      fs.appendFileSync(path, data[, options])#

      + -

      Returns the contents of the path.

      -

      For detailed information, see the documentation of the asynchronous version of -this API: fs.readFile().

      -

      If the encoding option is specified then this function returns a -string. Otherwise it returns a buffer.

      -

      Similar to fs.readFile(), when the path is a directory, the behavior of -fs.readFileSync() is platform-specific.

      -
      // macOS, Linux, and Windows
      -fs.readFileSync('<directory>');
      -// => [Error: EISDIR: illegal operation on a directory, read <directory>]
      +

      Synchronously append data to a file, creating the file if it does not yet +exist. data can be a string or a <Buffer>.

      +

      The mode option only affects the newly created file. See fs.open() +for more details.

      +
      import { appendFileSync } from 'fs';
       
      -//  FreeBSD
      -fs.readFileSync('<directory>'); // => <data>
      -

      fs.readlink(path[, options], callback)#

      +try { + appendFileSync('message.txt', 'data to append'); + console.log('The "data to append" was appended to file!'); +} catch (err) { + /* Handle the error */ +}
      +

      If options is a string, then it specifies the encoding:

      +
      import { appendFileSync } from 'fs';
      +
      +appendFileSync('message.txt', 'data to append', 'utf8');
      +

      The path may be specified as a numeric file descriptor that has been opened +for appending (using fs.open() or fs.openSync()). The file descriptor will +not be closed automatically.

      +
      import { openSync, closeSync, appendFileSync } from 'fs';
      +
      +let fd;
      +
      +try {
      +  fd = openSync('message.txt', 'a');
      +  appendFileSync(fd, 'data to append', 'utf8');
      +} catch (err) {
      +  /* Handle the error */
      +} finally {
      +  if (fd !== undefined)
      +    closeSync(fd);
      +}
      +

      fs.chmodSync(path, mode)#

      -

      Asynchronous readlink(2). The callback gets two arguments (err, linkString).

      -

      The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the link path passed to the callback. If the encoding is set to 'buffer', -the link path returned will be passed as a Buffer object.

      -

      fs.readlinkSync(path[, options])#

      +

      For detailed information, see the documentation of the asynchronous version of +this API: fs.chmod().

      +

      See the POSIX chmod(2) documentation for more detail.

      +

      fs.chownSync(path, uid, gid)#

      • path <string> | <Buffer> | <URL>
      • -
      • options <string> | <Object> - -
      • -
      • Returns: <string> | <Buffer>
      • +

        Synchronously changes owner and group of a file. Returns undefined. +This is the synchronous version of fs.chown().

        +

        See the POSIX chown(2) documentation for more detail.

        +

        fs.closeSync(fd)#

        + + -

        Synchronous readlink(2). Returns the symbolic link's string value.

        -

        The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the link path returned. If the encoding is set to 'buffer', -the link path returned will be passed as a Buffer object.

        -

        fs.readSync(fd, buffer, offset, length, position)#

        +

        Closes the file descriptor. Returns undefined.

        +

        Calling fs.closeSync() on any file descriptor (fd) that is currently in use +through any other fs operation may lead to undefined behavior.

        +

        See the POSIX close(2) documentation for more detail.

        +

        fs.copyFileSync(src, dest[, mode])#

        -

        Returns the number of bytesRead.

        -

        For detailed information, see the documentation of the asynchronous version of -this API: fs.read().

        -

        fs.readSync(fd, buffer, [options])#

        +

        Synchronously copies src to dest. By default, dest is overwritten if it +already exists. Returns undefined. Node.js makes no guarantees about the +atomicity of the copy operation. If an error occurs after the destination file +has been opened for writing, Node.js will attempt to remove the destination.

        +

        mode is an optional integer that specifies the behavior +of the copy operation. It is possible to create a mask consisting of the bitwise +OR of two or more values (e.g. +fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

        +
          +
        • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest already +exists.
        • +
        • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create a +copy-on-write reflink. If the platform does not support copy-on-write, then a +fallback copy mechanism is used.
        • +
        • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to +create a copy-on-write reflink. If the platform does not support +copy-on-write, then the operation will fail.
        • +
        +
        import { copyFileSync, constants } from 'fs';
        +
        +// destination.txt will be created or overwritten by default.
        +copyFileSync('source.txt', 'destination.txt');
        +console.log('source.txt was copied to destination.txt');
        +
        +// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
        +copyFileSync('source.txt', 'destination.txt', constants.COPYFILE_EXCL);
        +

        fs.existsSync(path)#

        -

        Returns the number of bytesRead.

        -

        Similar to the above fs.readSync function, this version takes an optional options object. -If no options object is specified, it will default with the above values.

        +

        Returns true if the path exists, false otherwise.

        For detailed information, see the documentation of the asynchronous version of -this API: fs.read().

        -

        fs.readv(fd, buffers[, position], callback)#

        +this API: fs.exists().

        +

        fs.exists() is deprecated, but fs.existsSync() is not. The callback +parameter to fs.exists() accepts parameters that are inconsistent with other +Node.js callbacks. fs.existsSync() does not use a callback.

        +
        import { existsSync } from 'fs';
        +
        +if (existsSync('/etc/passwd'))
        +  console.log('The path exists.');
        +

        fs.fchmodSync(fd, mode)#

        • fd <integer>
        • -
        • buffers <ArrayBufferView[]>
        • -
        • position <integer>
        • -
        • callback <Function> - -
        • +

          Sets the permissions on the file. Returns undefined.

          +

          See the POSIX fchmod(2) documentation for more detail.

          +

          fs.fchownSync(fd, uid, gid)#

          + + -

          Read from a file specified by fd and write to an array of ArrayBufferViews -using readv().

          -

          position is the offset from the beginning of the file from where data -should be read. If typeof position !== 'number', the data will be read -from the current position.

          -

          The callback will be given three arguments: err, bytesRead, and -buffers. bytesRead is how many bytes were read from the file.

          -

          If this method is invoked as its util.promisify()ed version, it returns -a Promise for an Object with bytesRead and buffers properties.

          -

          fs.readvSync(fd, buffers[, position])#

          +

          Sets the owner of the file. Returns undefined.

          +

          See the POSIX fchown(2) documentation for more detail.

          +

          fs.fdatasyncSync(fd)#

          -

          For detailed information, see the documentation of the asynchronous version of -this API: fs.readv().

          -

          fs.realpath(path[, options], callback)#

          +

          Forces all currently queued I/O operations associated with the file to the +operating system's synchronized I/O completion state. Refer to the POSIX +fdatasync(2) documentation for details. Returns undefined.

          +

          fs.fstatSync(fd[, options])#

          -

          Asynchronously computes the canonical pathname by resolving ., .. and -symbolic links.

          -

          A canonical pathname is not necessarily unique. Hard links and bind mounts can -expose a file system entity through many pathnames.

          -

          This function behaves like realpath(3), with some exceptions:

          -
            -
          1. -

            No case conversion is performed on case-insensitive file systems.

            -
          2. -
          3. -

            The maximum number of symbolic links is platform-independent and generally -(much) higher than what the native realpath(3) implementation supports.

            -
          4. -
          -

          The callback gets two arguments (err, resolvedPath). May use process.cwd -to resolve relative paths.

          -

          Only paths that can be converted to UTF8 strings are supported.

          -

          The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the path passed to the callback. If the encoding is set to 'buffer', -the path returned will be passed as a Buffer object.

          -

          If path resolves to a socket or a pipe, the function will return a system -dependent name for that object.

          -

          fs.realpath.native(path[, options], callback)#

          +

          Retrieves the <fs.Stats> for the file descriptor.

          +

          See the POSIX fstat(2) documentation for more detail.

          +

          fs.fsyncSync(fd)#

          -

          Asynchronous realpath(3).

          -

          The callback gets two arguments (err, resolvedPath).

          -

          Only paths that can be converted to UTF8 strings are supported.

          -

          The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the path passed to the callback. If the encoding is set to 'buffer', -the path returned will be passed as a Buffer object.

          -

          On Linux, when Node.js is linked against musl libc, the procfs file system must -be mounted on /proc in order for this function to work. Glibc does not have -this restriction.

          -

          fs.realpathSync(path[, options])#

          +

          Truncates the file descriptor. Returns undefined.

          +

          For detailed information, see the documentation of the asynchronous version of +this API: fs.ftruncate().

          +

          fs.futimesSync(fd, atime, mtime)#

          -

          Returns the resolved pathname.

          -

          For detailed information, see the documentation of the asynchronous version of -this API: fs.realpath().

          -

          fs.realpathSync.native(path[, options])#

          +

          Synchronous version of fs.futimes(). Returns undefined.

          +

          fs.lchmodSync(path, mode)#

          -

          Synchronous realpath(3).

          -

          Only paths that can be converted to UTF8 strings are supported.

          -

          The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the path returned. If the encoding is set to 'buffer', -the path returned will be passed as a Buffer object.

          -

          On Linux, when Node.js is linked against musl libc, the procfs file system must -be mounted on /proc in order for this function to work. Glibc does not have -this restriction.

          -

          fs.rename(oldPath, newPath, callback)#

          +

          Changes the permissions on a symbolic link. Returns undefined.

          +

          This method is only implemented on macOS.

          +

          See the POSIX lchmod(2) documentation for more detail.

          +

          fs.lchownSync(path, uid, gid)#

            -
          • oldPath <string> | <Buffer> | <URL>
          • -
          • newPath <string> | <Buffer> | <URL>
          • -
          • callback <Function> - -
          • +

            Set the owner for the path. Returns undefined.

            +

            See the POSIX lchown(2) documentation for more details.

            +

            fs.lutimesSync(path, atime, mtime)#

            + + -

            Asynchronously rename file at oldPath to the pathname provided -as newPath. In the case that newPath already exists, it will -be overwritten. If there is a directory at newPath, an error will -be raised instead. No arguments other than a possible exception are -given to the completion callback.

            -

            See also: rename(2).

            -
            fs.rename('oldFile.txt', 'newFile.txt', (err) => {
            -  if (err) throw err;
            -  console.log('Rename complete!');
            -});
            -

            fs.renameSync(oldPath, newPath)#

            +

            Change the file system timestamps of the symbolic link referenced by path. +Returns undefined, or throws an exception when parameters are incorrect or +the operation fails. This is the synchronous version of fs.lutimes().

            +

            fs.linkSync(existingPath, newPath)#

            -

            Synchronous rename(2). Returns undefined.

            -

            fs.rmdir(path[, options], callback)#

            +

            Creates a new link from the existingPath to the newPath. See the POSIX +link(2) documentation for more detail. Returns undefined.

            +

            fs.lstatSync(path[, options])#

            -

            Stability: 1 - Recursive removal is experimental.

            • path <string> | <Buffer> | <URL>
            • options <Object>
                -
              • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or -EPERM error is encountered, Node.js will retry the operation with a linear -backoff wait of retryDelay ms longer on each try. This option represents the -number of retries. This option is ignored if the recursive option is not -true. Default: 0.
              • -
              • recursive <boolean> If true, perform a recursive directory removal. In -recursive mode, errors are not reported if path does not exist, and -operations are retried on failure. Default: false.
              • -
              • retryDelay <integer> The amount of time in milliseconds to wait between -retries. This option is ignored if the recursive option is not true. -Default: 100.
              • -
              -
            • -
            • callback <Function> -
                -
              • err <Error>
              • +
              • bigint <boolean> Whether the numeric values in the returned +<fs.Stats> object should be bigint. Default: false.
              • +
              • throwIfNoEntry <boolean> Whether an exception will be thrown +if no file system entry exists, rather than returning undefined. +Default: true.
            • +
            • Returns: <fs.Stats>
            -

            Asynchronous rmdir(2). No arguments other than a possible exception are given -to the completion callback.

            -

            Using fs.rmdir() on a file (not a directory) results in an ENOENT error on -Windows and an ENOTDIR error on POSIX.

            -

            fs.rmdirSync(path[, options])#

            +

            Retrieves the <fs.Stats> for the symbolic link referred to by path.

            +

            See the POSIX lstat(2) documentation for more details.

            +

            fs.mkdirSync(path[, options])#

            -

            Stability: 1 - Recursive removal is experimental.

            • path <string> | <Buffer> | <URL>
            • -
            • options <Object> +
            • options <Object> | <integer>
                -
              • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or -EPERM error is encountered, Node.js will retry the operation with a linear -backoff wait of retryDelay ms longer on each try. This option represents the -number of retries. This option is ignored if the recursive option is not -true. Default: 0.
              • -
              • recursive <boolean> If true, perform a recursive directory removal. In -recursive mode, errors are not reported if path does not exist, and -operations are retried on failure. Default: false.
              • -
              • retryDelay <integer> The amount of time in milliseconds to wait between -retries. This option is ignored if the recursive option is not true. -Default: 100.
              • +
              • recursive <boolean> Default: false
              • +
              • mode <string> | <integer> Not supported on Windows. Default: 0o777.
            • +
            • Returns: <string> | <undefined>
            -

            Synchronous rmdir(2). Returns undefined.

            -

            Using fs.rmdirSync() on a file (not a directory) results in an ENOENT error -on Windows and an ENOTDIR error on POSIX.

            -

            fs.stat(path[, options], callback)#

            +

            Synchronously creates a directory. Returns undefined, or if recursive is +true, the first directory path created. +This is the synchronous version of fs.mkdir().

            +

            See the POSIX mkdir(2) documentation for more details.

            +

            fs.mkdtempSync(prefix[, options])#

            -

            Asynchronous stat(2). The callback gets two arguments (err, stats) where -stats is an fs.Stats object.

            -

            In case of an error, the err.code will be one of Common System Errors.

            -

            Using fs.stat() to check for the existence of a file before calling -fs.open(), fs.readFile() or fs.writeFile() is not recommended. -Instead, user code should open/read/write the file directly and handle the -error raised if the file is not available.

            -

            To check if a file exists without manipulating it afterwards, fs.access() -is recommended.

            -

            For example, given the following directory structure:

            -
            - txtDir
            --- file.txt
            -- app.js
            -

            The next program will check for the stats of the given paths:

            -
            const fs = require('fs');
            -
            -const pathsToCheck = ['./txtDir', './txtDir/file.txt'];
            -
            -for (let i = 0; i < pathsToCheck.length; i++) {
            -  fs.stat(pathsToCheck[i], function(err, stats) {
            -    console.log(stats.isDirectory());
            -    console.log(stats);
            -  });
            -}
            -

            The resulting output will resemble:

            -
            true
            -Stats {
            -  dev: 16777220,
            -  mode: 16877,
            -  nlink: 3,
            -  uid: 501,
            -  gid: 20,
            -  rdev: 0,
            -  blksize: 4096,
            -  ino: 14214262,
            -  size: 96,
            -  blocks: 0,
            -  atimeMs: 1561174653071.963,
            -  mtimeMs: 1561174614583.3518,
            -  ctimeMs: 1561174626623.5366,
            -  birthtimeMs: 1561174126937.2893,
            -  atime: 2019-06-22T03:37:33.072Z,
            -  mtime: 2019-06-22T03:36:54.583Z,
            -  ctime: 2019-06-22T03:37:06.624Z,
            -  birthtime: 2019-06-22T03:28:46.937Z
            -}
            -false
            -Stats {
            -  dev: 16777220,
            -  mode: 33188,
            -  nlink: 1,
            -  uid: 501,
            -  gid: 20,
            -  rdev: 0,
            -  blksize: 4096,
            -  ino: 14214074,
            -  size: 8,
            -  blocks: 8,
            -  atimeMs: 1561174616618.8555,
            -  mtimeMs: 1561174614584,
            -  ctimeMs: 1561174614583.8145,
            -  birthtimeMs: 1561174007710.7478,
            -  atime: 2019-06-22T03:36:56.619Z,
            -  mtime: 2019-06-22T03:36:54.584Z,
            -  ctime: 2019-06-22T03:36:54.584Z,
            -  birthtime: 2019-06-22T03:26:47.711Z
            -}
            -

            fs.statSync(path[, options])#

            +

            Returns the created directory path.

            +

            For detailed information, see the documentation of the asynchronous version of +this API: fs.mkdtemp().

            +

            The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use.

            +

            fs.opendirSync(path[, options])#

            @@ -3878,586 +4712,461 @@ Stats {
          • path <string> | <Buffer> | <URL>
          • options <Object>
              -
            • bigint <boolean> Whether the numeric values in the returned -fs.Stats object should be bigint. Default: false.
            • +
            • encoding <string> | <null> Default: 'utf8'
            • +
            • bufferSize <number> Number of directory entries that are buffered +internally when reading from the directory. Higher values lead to better +performance but higher memory usage. Default: 32
          • -
          • Returns: <fs.Stats>
          • +
          • Returns: <fs.Dir>
          -

          Synchronous stat(2).

          -

          fs.symlink(target, path[, type], callback)#

          +

          Synchronously open a directory. See opendir(3).

          +

          Creates an <fs.Dir>, which contains all further functions for reading from +and cleaning up the directory.

          +

          The encoding option sets the encoding for the path while opening the +directory and subsequent read operations.

          +

          fs.openSync(path[, flags[, mode]])#

          -

          Asynchronous symlink(2) which creates the link called path pointing to -target. No arguments other than a possible exception are given to the -completion callback.

          -

          The type argument is only available on Windows and ignored on other platforms. -It can be set to 'dir', 'file', or 'junction'. If the type argument is -not set, Node.js will autodetect target type and use 'file' or 'dir'. If -the target does not exist, 'file' will be used. Windows junction points -require the destination path to be absolute. When using 'junction', the -target argument will automatically be normalized to absolute path.

          -

          Relative targets are relative to the link’s parent directory.

          -
          fs.symlink('./mew', './example/mewtwo', callback);
          -

          The above example creates a symbolic link mewtwo in the example which points -to mew in the same directory:

          -
          $ tree example/
          -example/
          -├── mew
          -└── mewtwo -> ./mew
          -

          fs.symlinkSync(target, path[, type])#

          +

          Returns an integer representing the file descriptor.

          +

          For detailed information, see the documentation of the asynchronous version of +this API: fs.open().

          +

          fs.readdirSync(path[, options])#

          +

          Reads the contents of the directory.

          +

          See the POSIX readdir(3) documentation for more details.

          +

          The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use for +the filenames returned. If the encoding is set to 'buffer', +the filenames returned will be passed as <Buffer> objects.

          +

          If options.withFileTypes is set to true, the result will contain +<fs.Dirent> objects.

          +

          fs.readFileSync(path[, options])#

          -

          Asynchronous truncate(2). No arguments other than a possible exception are -given to the completion callback. A file descriptor can also be passed as the -first argument. In this case, fs.ftruncate() is called.

          -

          Passing a file descriptor is deprecated and may result in an error being thrown -in the future.

          -

          fs.truncateSync(path[, len])#

          - - -

          Synchronous truncate(2). Returns undefined. A file descriptor can also be -passed as the first argument. In this case, fs.ftruncateSync() is called.

          -

          Passing a file descriptor is deprecated and may result in an error being thrown -in the future.

          -

          fs.unlink(path, callback)#

          +

          Returns the contents of the path.

          +

          For detailed information, see the documentation of the asynchronous version of +this API: fs.readFile().

          +

          If the encoding option is specified then this function returns a +string. Otherwise it returns a buffer.

          +

          Similar to fs.readFile(), when the path is a directory, the behavior of +fs.readFileSync() is platform-specific.

          +
          import { readFileSync } from 'fs';
          +
          +// macOS, Linux, and Windows
          +readFileSync('<directory>');
          +// => [Error: EISDIR: illegal operation on a directory, read <directory>]
          +
          +//  FreeBSD
          +readFileSync('<directory>'); // => <data>
          +

          fs.readlinkSync(path[, options])#

          -

          Asynchronously removes a file or symbolic link. No arguments other than a -possible exception are given to the completion callback.

          -
          // Assuming that 'path/file.txt' is a regular file.
          -fs.unlink('path/file.txt', (err) => {
          -  if (err) throw err;
          -  console.log('path/file.txt was deleted');
          -});
          -

          fs.unlink() will not work on a directory, empty or otherwise. To remove a -directory, use fs.rmdir().

          -

          See also: unlink(2).

          -

          fs.unlinkSync(path)#

          +

          Returns the symbolic link's string value.

          +

          See the POSIX readlink(2) documentation for more details.

          +

          The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use for +the link path returned. If the encoding is set to 'buffer', +the link path returned will be passed as a <Buffer> object.

          +

          fs.readSync(fd, buffer, offset, length, position)#

          -

          Synchronous unlink(2). Returns undefined.

          -

          fs.unwatchFile(filename[, listener])#

          - - -

          Stop watching for changes on filename. If listener is specified, only that -particular listener is removed. Otherwise, all listeners are removed, -effectively stopping watching of filename.

          -

          Calling fs.unwatchFile() with a filename that is not being watched is a -no-op, not an error.

          -

          Using fs.watch() is more efficient than fs.watchFile() and -fs.unwatchFile(). fs.watch() should be used instead of fs.watchFile() -and fs.unwatchFile() when possible.

          -

          fs.utimes(path, atime, mtime, callback)#

          +

          Returns the number of bytesRead.

          +

          For detailed information, see the documentation of the asynchronous version of +this API: fs.read().

          +

          fs.readSync(fd, buffer, [options])#

          -

          Change the file system timestamps of the object referenced by path.

          -

          The atime and mtime arguments follow these rules:

          +

          Returns the number of bytesRead.

          +

          Similar to the above fs.readSync function, this version takes an optional options object. +If no options object is specified, it will default with the above values.

          +

          For detailed information, see the documentation of the asynchronous version of +this API: fs.read().

          +

          fs.readvSync(fd, buffers[, position])#

          +
            -
          • Values can be either numbers representing Unix epoch time in seconds, -Dates, or a numeric string like '123456789.0'.
          • -
          • If the value can not be converted to a number, or is NaN, Infinity or --Infinity, an Error will be thrown.
          • +
          • fd <integer>
          • +
          • buffers <ArrayBufferView[]>
          • +
          • position <integer>
          • +
          • Returns: <number> The number of bytes read.
          -

          fs.utimesSync(path, atime, mtime)#

          +

          For detailed information, see the documentation of the asynchronous version of +this API: fs.readv().

          +

          fs.realpathSync(path[, options])#

          +

          Returns the resolved pathname.

          For detailed information, see the documentation of the asynchronous version of -this API: fs.utimes().

          -

          fs.watch(filename[, options][, listener])#

          +this API: fs.realpath().

          +

          fs.realpathSync.native(path[, options])#

          -

          Watch for changes on filename, where filename is either a file or a -directory.

          -

          The second argument is optional. If options is provided as a string, it -specifies the encoding. Otherwise options should be passed as an object.

          -

          The listener callback gets two arguments (eventType, filename). eventType -is either 'rename' or 'change', and filename is the name of the file -which triggered the event.

          -

          On most platforms, 'rename' is emitted whenever a filename appears or -disappears in the directory.

          -

          The listener callback is attached to the 'change' event fired by -fs.FSWatcher, but it is not the same thing as the 'change' value of -eventType.

          -

          Caveats#

          - -

          The fs.watch API is not 100% consistent across platforms, and is -unavailable in some situations.

          -

          The recursive option is only supported on macOS and Windows.

          -

          On Windows, no events will be emitted if the watched directory is moved or -renamed. An EPERM error is reported when the watched directory is deleted.

          -

          Availability#

          - -

          This feature depends on the underlying operating system providing a way -to be notified of filesystem changes.

          -
            -
          • On Linux systems, this uses inotify(7).
          • -
          • On BSD systems, this uses kqueue(2).
          • -
          • On macOS, this uses kqueue(2) for files and FSEvents for -directories.
          • -
          • On SunOS systems (including Solaris and SmartOS), this uses event ports.
          • -
          • On Windows systems, this feature depends on ReadDirectoryChangesW.
          • -
          • On Aix systems, this feature depends on AHAFS, which must be enabled.
          • -
          • On IBM i systems, this feature is not supported.
          • +
          • Returns: <string> | <Buffer>
          -

          If the underlying functionality is not available for some reason, then -fs.watch() will not be able to function and may thrown an exception. -For example, watching files or directories can be unreliable, and in some -cases impossible, on network file systems (NFS, SMB, etc) or host file systems -when using virtualization software such as Vagrant or Docker.

          -

          It is still possible to use fs.watchFile(), which uses stat polling, but -this method is slower and less reliable.

          -

          Inodes#

          - -

          On Linux and macOS systems, fs.watch() resolves the path to an inode and -watches the inode. If the watched path is deleted and recreated, it is assigned -a new inode. The watch will emit an event for the delete but will continue -watching the original inode. Events for the new inode will not be emitted. -This is expected behavior.

          -

          AIX files retain the same inode for the lifetime of a file. Saving and closing a -watched file on AIX will result in two notifications (one for adding new -content, and one for truncation).

          -

          Filename argument#

          - -

          Providing filename argument in the callback is only supported on Linux, -macOS, Windows, and AIX. Even on supported platforms, filename is not always -guaranteed to be provided. Therefore, don't assume that filename argument is -always provided in the callback, and have some fallback logic if it is null.

          -
          fs.watch('somedir', (eventType, filename) => {
          -  console.log(`event type is: ${eventType}`);
          -  if (filename) {
          -    console.log(`filename provided: ${filename}`);
          -  } else {
          -    console.log('filename not provided');
          -  }
          -});
          -

          fs.watchFile(filename[, options], listener)#

          +

          Synchronous realpath(3).

          +

          Only paths that can be converted to UTF8 strings are supported.

          +

          The optional options argument can be a string specifying an encoding, or an +object with an encoding property specifying the character encoding to use for +the path returned. If the encoding is set to 'buffer', +the path returned will be passed as a <Buffer> object.

          +

          On Linux, when Node.js is linked against musl libc, the procfs file system must +be mounted on /proc in order for this function to work. Glibc does not have +this restriction.

          +

          fs.renameSync(oldPath, newPath)#

          + + +

          Renames the file from oldPath to newPath. Returns undefined.

          +

          See the POSIX rename(2) documentation for more details.

          +

          fs.rmdirSync(path[, options])#

            -
          • filename <string> | <Buffer> | <URL>
          • +
          • path <string> | <Buffer> | <URL>
          • options <Object>
              -
            • bigint <boolean> Default: false
            • -
            • persistent <boolean> Default: true
            • -
            • interval <integer> Default: 5007
            • +
            • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or +EPERM error is encountered, Node.js retries the operation with a linear +backoff wait of retryDelay milliseconds longer on each try. This option +represents the number of retries. This option is ignored if the recursive +option is not true. Default: 0.
            • +
            • recursive <boolean> If true, perform a recursive directory removal. In +recursive mode, errors are not reported if path does not exist, and +operations are retried on failure. Default: false.
            • +
            • retryDelay <integer> The amount of time in milliseconds to wait between +retries. This option is ignored if the recursive option is not true. +Default: 100.
          • -
          • listener <Function> +
          +

          Synchronous rmdir(2). Returns undefined.

          +

          Using fs.rmdirSync() on a file (not a directory) results in an ENOENT error +on Windows and an ENOTDIR error on POSIX.

          +

          Setting recursive to true results in behavior similar to the Unix command +rm -rf: an error will not be raised for paths that do not exist, and paths +that represent files will be deleted. The permissive behavior of the +recursive option is deprecated, ENOTDIR and ENOENT will be thrown in +the future.

          +

          fs.rmSync(path[, options])#

          +
            -
          • current <fs.Stats>
          • -
          • previous <fs.Stats>
          • +
          • path <string> | <Buffer> | <URL>
          • +
          • options <Object> +
              +
            • force <boolean> When true, exceptions will be ignored if path does +not exist. Default: false.
            • +
            • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or +EPERM error is encountered, Node.js will retry the operation with a linear +backoff wait of retryDelay milliseconds longer on each try. This option +represents the number of retries. This option is ignored if the recursive +option is not true. Default: 0.
            • +
            • recursive <boolean> If true, perform a recursive directory removal. In +recursive mode operations are retried on failure. Default: false.
            • +
            • retryDelay <integer> The amount of time in milliseconds to wait between +retries. This option is ignored if the recursive option is not true. +Default: 100.
          • -
          • Returns: <fs.StatWatcher>
          • -
          -

          Watch for changes on filename. The callback listener will be called each -time the file is accessed.

          -

          The options argument may be omitted. If provided, it should be an object. The -options object may contain a boolean named persistent that indicates -whether the process should continue to run as long as files are being watched. -The options object may specify an interval property indicating how often the -target should be polled in milliseconds.

          -

          The listener gets two arguments the current stat object and the previous -stat object:

          -
          fs.watchFile('message.text', (curr, prev) => {
          -  console.log(`the current mtime is: ${curr.mtime}`);
          -  console.log(`the previous mtime was: ${prev.mtime}`);
          -});
          -

          These stat objects are instances of fs.Stat. If the bigint option is true, -the numeric values in these objects are specified as BigInts.

          -

          To be notified when the file was modified, not just accessed, it is necessary -to compare curr.mtime and prev.mtime.

          -

          When an fs.watchFile operation results in an ENOENT error, it -will invoke the listener once, with all the fields zeroed (or, for dates, the -Unix Epoch). If the file is created later on, the listener will be called -again, with the latest stat objects. This is a change in functionality since -v0.10.

          -

          Using fs.watch() is more efficient than fs.watchFile and -fs.unwatchFile. fs.watch should be used instead of fs.watchFile and -fs.unwatchFile when possible.

          -

          When a file being watched by fs.watchFile() disappears and reappears, -then the contents of previous in the second callback event (the file's -reappearance) will be the same as the contents of previous in the first -callback event (its disappearance).

          -

          This happens when:

          -
            -
          • the file is deleted, followed by a restore
          • -
          • the file is renamed and then renamed a second time back to its original name
          -

          fs.write(fd, buffer[, offset[, length[, position]]], callback)#

          +

          Synchronously removes files and directories (modeled on the standard POSIX rm +utility). Returns undefined.

          +

          fs.statSync(path[, options])#

          -

          Write buffer to the file specified by fd.

          -

          offset determines the part of the buffer to be written, and length is -an integer specifying the number of bytes to write.

          -

          position refers to the offset from the beginning of the file where this data -should be written. If typeof position !== 'number', the data will be written -at the current position. See pwrite(2).

          -

          The callback will be given three arguments (err, bytesWritten, buffer) where -bytesWritten specifies how many bytes were written from buffer.

          -

          If this method is invoked as its util.promisify()ed version, it returns -a Promise for an Object with bytesWritten and buffer properties.

          -

          It is unsafe to use fs.write() multiple times on the same file without waiting -for the callback. For this scenario, fs.createWriteStream() is -recommended.

          -

          On Linux, positional writes don't work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file.

          -

          fs.write(fd, string[, position[, encoding]], callback)#

          +

          Retrieves the <fs.Stats> for the path.

          +

          fs.symlinkSync(target, path[, type])#

            -
          • fd <integer>
          • -
          • string <string>
          • -
          • position <integer>
          • -
          • encoding <string> Default: 'utf8'
          • -
          • callback <Function> - -
          • +

            Returns undefined.

            +

            For detailed information, see the documentation of the asynchronous version of +this API: fs.symlink().

            +

            fs.truncateSync(path[, len])#

            + + -

            Write string to the file specified by fd. If string is not a string, then -the value will be coerced to one.

            -

            position refers to the offset from the beginning of the file where this data -should be written. If typeof position !== 'number' the data will be written at -the current position. See pwrite(2).

            -

            encoding is the expected string encoding.

            -

            The callback will receive the arguments (err, written, string) where written -specifies how many bytes the passed string required to be written. Bytes -written is not necessarily the same as string characters written. See -Buffer.byteLength.

            -

            It is unsafe to use fs.write() multiple times on the same file without waiting -for the callback. For this scenario, fs.createWriteStream() is -recommended.

            -

            On Linux, positional writes don't work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file.

            -

            On Windows, if the file descriptor is connected to the console (e.g. fd == 1 -or stdout) a string containing non-ASCII characters will not be rendered -properly by default, regardless of the encoding used. -It is possible to configure the console to render UTF-8 properly by changing the -active codepage with the chcp 65001 command. See the chcp docs for more -details.

            -

            fs.writeFile(file, data[, options], callback)#

            +

            Truncates the file. Returns undefined. A file descriptor can also be +passed as the first argument. In this case, fs.ftruncateSync() is called.

            +

            Passing a file descriptor is deprecated and may result in an error being thrown +in the future.

            +

            fs.unlinkSync(path)#

            -

            When file is a filename, asynchronously writes data to the file, replacing the -file if it already exists. data can be a string or a buffer.

            -

            When file is a file descriptor, the behavior is similar to calling -fs.write() directly (which is recommended). See the notes below on using -a file descriptor.

            -

            The encoding option is ignored if data is a buffer.

            -
            const data = new Uint8Array(Buffer.from('Hello Node.js'));
            -fs.writeFile('message.txt', data, (err) => {
            -  if (err) throw err;
            -  console.log('The file has been saved!');
            -});
            -

            If options is a string, then it specifies the encoding:

            -
            fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback);
            -

            It is unsafe to use fs.writeFile() multiple times on the same file without -waiting for the callback. For this scenario, fs.createWriteStream() is -recommended.

            -

            Using fs.writeFile() with file descriptors#

            -

            When file is a file descriptor, the behavior is almost identical to directly -calling fs.write() like:

            -
            fs.write(fd, Buffer.from(data, options.encoding), callback);
            -

            The difference from directly calling fs.write() is that under some unusual -conditions, fs.write() may write only part of the buffer and will need to be -retried to write the remaining data, whereas fs.writeFile() will retry until -the data is entirely written (or an error occurs).

            -

            The implications of this are a common source of confusion. In -the file descriptor case, the file is not replaced! The data is not necessarily -written to the beginning of the file, and the file's original data may remain -before and/or after the newly written data.

            -

            For example, if fs.writeFile() is called twice in a row, first to write the -string 'Hello', then to write the string ', World', the file would contain -'Hello, World', and might contain some of the file's original data (depending -on the size of the original file, and the position of the file descriptor). If -a file name had been used instead of a descriptor, the file would be guaranteed -to contain only ', World'.

            -

            fs.writeFileSync(file, data[, options])#

            +

            Returns undefined.

            +

            For detailed information, see the documentation of the asynchronous version of +this API: fs.utimes().

            +

            fs.writeFileSync(file, data[, options])#

            -

            Retrieves the fs.Stats for the file.

            -

            filehandle.sync()#

            +

            Returns true if the <fs.Dirent> object describes a file system +directory.

            +
            dirent.isFIFO()#
            -

            Asynchronous fsync(2). The Promise is resolved with no arguments upon -success.

            -

            filehandle.truncate(len)#

            +

            Returns true if the <fs.Dirent> object describes a first-in-first-out +(FIFO) pipe.

            +
            dirent.isFile()#
            -

            Truncates the file then resolves the Promise with no arguments upon success.

            -

            If the file was larger than len bytes, only the first len bytes will be -retained in the file.

            -

            For example, the following program retains only the first four bytes of the -file:

            -
            const fs = require('fs');
            -const fsPromises = fs.promises;
            -
            -console.log(fs.readFileSync('temp.txt', 'utf8'));
            -// Prints: Node.js
            -
            -async function doTruncate() {
            -  let filehandle = null;
            -  try {
            -    filehandle = await fsPromises.open('temp.txt', 'r+');
            -    await filehandle.truncate(4);
            -  } finally {
            -    if (filehandle) {
            -      // Close the file if it is opened.
            -      await filehandle.close();
            -    }
            -  }
            -  console.log(fs.readFileSync('temp.txt', 'utf8'));  // Prints: Node
            -}
            -
            -doTruncate().catch(console.error);
            -

            If the file previously was shorter than len bytes, it is extended, and the -extended part is filled with null bytes ('\0'):

            -
            const fs = require('fs');
            -const fsPromises = fs.promises;
            -
            -console.log(fs.readFileSync('temp.txt', 'utf8'));
            -// Prints: Node.js
            -
            -async function doTruncate() {
            -  let filehandle = null;
            -  try {
            -    filehandle = await fsPromises.open('temp.txt', 'r+');
            -    await filehandle.truncate(10);
            -  } finally {
            -    if (filehandle) {
            -      // Close the file if it is opened.
            -      await filehandle.close();
            -    }
            -  }
            -  console.log(fs.readFileSync('temp.txt', 'utf8'));  // Prints Node.js\0\0\0
            -}
            -
            -doTruncate().catch(console.error);
            -

            The last three bytes are null bytes ('\0'), to compensate the over-truncation.

            -

            filehandle.utimes(atime, mtime)#

            +

            Returns true if the <fs.Dirent> object describes a regular file.

            +
            dirent.isSocket()#
            -

            Change the file system timestamps of the object referenced by the FileHandle -then resolves the Promise with no arguments upon success.

            -

            This function does not work on AIX versions before 7.1, it will resolve the -Promise with an error using code UV_ENOSYS.

            -

            filehandle.write(buffer[, offset[, length[, position]]])#

            +

            Returns true if the <fs.Dirent> object describes a socket.

            +
            dirent.isSymbolicLink()#
            -

            Write buffer to the file.

            -

            The Promise is resolved with an object containing a bytesWritten property -identifying the number of bytes written, and a buffer property containing -a reference to the buffer written.

            -

            offset determines the part of the buffer to be written, and length is -an integer specifying the number of bytes to write.

            -

            position refers to the offset from the beginning of the file where this data -should be written. If typeof position !== 'number', the data will be written -at the current position. See pwrite(2).

            -

            It is unsafe to use filehandle.write() multiple times on the same file -without waiting for the Promise to be resolved (or rejected). For this -scenario, use fs.createWriteStream().

            -

            On Linux, positional writes do not work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file.

            -

            filehandle.write(string[, position[, encoding]])#

            +

            Returns true if the <fs.Dirent> object describes a symbolic link.

            +
            dirent.name#
            -

            Write string to the file. If string is not a string, then -the value will be coerced to one.

            -

            The Promise is resolved with an object containing a bytesWritten property -identifying the number of bytes written, and a buffer property containing -a reference to the string written.

            -

            position refers to the offset from the beginning of the file where this data -should be written. If the type of position is not a number the data -will be written at the current position. See pwrite(2).

            -

            encoding is the expected string encoding.

            -

            It is unsafe to use filehandle.write() multiple times on the same file -without waiting for the Promise to be resolved (or rejected). For this -scenario, use fs.createWriteStream().

            -

            On Linux, positional writes do not work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file.

            -

            filehandle.writeFile(data, options)#

            +

            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().

            +

            Class: fs.FSWatcher#

            -

            Asynchronously writes data to a file, replacing the file if it already exists. -data can be a string or a buffer. The Promise will be resolved with no -arguments upon success.

            -

            The encoding option is ignored if data is a buffer.

            -

            If options is a string, then it specifies the encoding.

            -

            The FileHandle has to support writing.

            -

            It is unsafe to use filehandle.writeFile() multiple times on the same file -without waiting for the Promise to be resolved (or rejected).

            -

            If one or more filehandle.write() calls are made on a file handle and then a -filehandle.writeFile() call is made, the data will be written from the -current position till the end of the file. It doesn't always write from the -beginning of the file.

            -

            filehandle.writev(buffers[, position])#

            +

            A successful call to fs.watch() method will return a new <fs.FSWatcher> +object.

            +

            All <fs.FSWatcher> objects emit a 'change' event whenever a specific watched +file is modified.

            +
            Event: 'change'#
            -

            Write an array of ArrayBufferViews to the file.

            -

            The Promise is resolved with an object containing a bytesWritten property -identifying the number of bytes written, and a buffers property containing -a reference to the buffers input.

            -

            position is the offset from the beginning of the file where this data -should be written. If typeof position !== 'number', the data will be written -at the current position.

            -

            It is unsafe to call writev() multiple times on the same file without waiting -for the previous operation to complete.

            -

            On Linux, positional writes don't work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file.

            -

            fsPromises.access(path[, mode])#

            +

            Emitted when something changes in a watched directory or file. +See more details in fs.watch().

            +

            The filename argument may not be provided depending on operating system +support. If filename is provided, it will be provided as a <Buffer> if +fs.watch() is called with its encoding option set to 'buffer', otherwise +filename will be a UTF-8 string.

            +
            import { watch } from 'fs';
            +// Example when handled through fs.watch() listener
            +watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {
            +  if (filename) {
            +    console.log(filename);
            +    // Prints: <Buffer ...>
            +  }
            +});
            +
            Event: 'close'#
            +

            Emitted when the watcher stops watching for changes. The closed +<fs.FSWatcher> object is no longer usable in the event handler.

            +
            Event: 'error'#
            + -

            Tests a user's permissions for the file or directory specified by path. -The mode argument is an optional integer that specifies the accessibility -checks to be performed. Check File access constants for possible values -of mode. It is possible to create a mask consisting of the bitwise OR of -two or more values (e.g. fs.constants.W_OK | fs.constants.R_OK).

            -

            If the accessibility check is successful, the Promise is resolved with no -value. If any of the accessibility checks fail, the Promise is rejected -with an Error object. The following example checks if the file -/etc/passwd can be read and written by the current process.

            -
            const fs = require('fs');
            -const fsPromises = fs.promises;
            -
            -fsPromises.access('/etc/passwd', fs.constants.R_OK | fs.constants.W_OK)
            -  .then(() => console.log('can access'))
            -  .catch(() => console.error('cannot access'));
            -

            Using fsPromises.access() to check for the accessibility of a file before -calling fsPromises.open() is not recommended. Doing so introduces a race -condition, since other processes may change the file's state between the two -calls. Instead, user code should open/read/write the file directly and handle -the error raised if the file is not accessible.

            -

            fsPromises.appendFile(path, data[, options])#

            +

            Emitted when an error occurs while watching the file. The errored +<fs.FSWatcher> object is no longer usable in the event handler.

            +
            watcher.close()#
            +

            Stop watching for changes on the given <fs.FSWatcher>. Once stopped, the +<fs.FSWatcher> object is no longer usable.

            +
            watcher.ref()#
            +
              -
            • path <string> | <Buffer> | <URL> | <FileHandle> filename or FileHandle
            • -
            • data <string> | <Buffer>
            • -
            • options <Object> | <string> - -
            • -
            • Returns: <Promise>
            • +

              When called, requests that the Node.js event loop not exit so long as the +<fs.FSWatcher> is active. Calling watcher.ref() multiple times will have +no effect.

              +

              By default, all <fs.FSWatcher> objects are "ref'ed", making it normally +unnecessary to call watcher.ref() unless watcher.unref() had been +called previously.

              +
              watcher.unref()#
              + + -

              Asynchronously append data to a file, creating the file if it does not yet -exist. data can be a string or a Buffer. The Promise will be -resolved with no arguments upon success.

              -

              If options is a string, then it specifies the encoding.

              -

              The path may be specified as a FileHandle that has been opened -for appending (using fsPromises.open()).

              -

              fsPromises.chmod(path, mode)#

              +

              When called, the active <fs.FSWatcher> object will not require the Node.js +event loop to remain active. If there is no other activity keeping the +event loop running, the process may exit before the <fs.FSWatcher> object's +callback is invoked. Calling watcher.unref() multiple times will have +no effect.

              +

              Class: fs.StatWatcher#

              -

              Changes the permissions of a file then resolves the Promise with no -arguments upon succces.

              -

              fsPromises.chown(path, uid, gid)#

              +

              A successful call to fs.watchFile() method will return a new <fs.StatWatcher> +object.

              +
              watcher.ref()#
              -

              Changes the ownership of a file then resolves the Promise with no arguments -upon success.

              -

              fsPromises.copyFile(src, dest[, flags])#

              +

              When called, requests that the Node.js event loop not exit so long as the +<fs.StatWatcher> is active. Calling watcher.ref() multiple times will have +no effect.

              +

              By default, all <fs.StatWatcher> objects are "ref'ed", making it normally +unnecessary to call watcher.ref() unless watcher.unref() had been +called previously.

              +
              watcher.unref()#
              -

              Asynchronously copies src to dest. By default, dest is overwritten if it -already exists. The Promise will be resolved with no arguments upon success.

              -

              Node.js makes no guarantees about the atomicity of the copy operation. If an -error occurs after the destination file has been opened for writing, Node.js -will attempt to remove the destination.

              -

              flags is an optional integer that specifies the behavior -of the copy operation. It is possible to create a mask consisting of the bitwise -OR of two or more values (e.g. -fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

              +

              When called, the active <fs.StatWatcher> object will not require the Node.js +event loop to remain active. If there is no other activity keeping the +event loop running, the process may exit before the <fs.StatWatcher> object's +callback is invoked. Calling watcher.unref() multiple times will have +no effect.

              +

              Class: fs.ReadStream#

              +
                -
              • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest already -exists.
              • -
              • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create a -copy-on-write reflink. If the platform does not support copy-on-write, then a -fallback copy mechanism is used.
              • -
              • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to -create a copy-on-write reflink. If the platform does not support copy-on-write, -then the operation will fail.
              • +
              • Extends: <stream.Readable>
              -
              const fsPromises = require('fs').promises;
              -
              -// destination.txt will be created or overwritten by default.
              -fsPromises.copyFile('source.txt', 'destination.txt')
              -  .then(() => console.log('source.txt was copied to destination.txt'))
              -  .catch(() => console.log('The file could not be copied'));
              -

              If the third argument is a number, then it specifies flags:

              -
              const fs = require('fs');
              -const fsPromises = fs.promises;
              -const { COPYFILE_EXCL } = fs.constants;
              -
              -// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
              -fsPromises.copyFile('source.txt', 'destination.txt', COPYFILE_EXCL)
              -  .then(() => console.log('source.txt was copied to destination.txt'))
              -  .catch(() => console.log('The file could not be copied'));
              -

              fsPromises.lchmod(path, mode)#

              +

              Instances of <fs.ReadStream> are created and returned using the +fs.createReadStream() function.

              +
              Event: 'close'#
              +

              Emitted when the <fs.ReadStream>'s underlying file descriptor has been closed.

              +
              Event: 'open'#
              + -

              Changes the permissions on a symbolic link then resolves the Promise with -no arguments upon success. This method is only implemented on macOS.

              -

              fsPromises.lchown(path, uid, gid)#

              +

              Emitted when the <fs.ReadStream>'s file descriptor has been opened.

              +
              Event: 'ready'#
              +

              Emitted when the <fs.ReadStream> is ready to be used.

              +

              Fires immediately after 'open'.

              +
              readStream.bytesRead#
              + -

              Changes the ownership on a symbolic link then resolves the Promise with -no arguments upon success.

              -

              fsPromises.lutimes(path, atime, mtime)#

              +

              The number of bytes that have been read so far.

              +
              readStream.path#
              -

              Changes the access and modification times of a file in the same way as -fsPromises.utimes(), with the difference that if the path refers to a -symbolic link, then the link is not dereferenced: instead, the timestamps of -the symbolic link itself are changed.

              -

              Upon success, the Promise is resolved without arguments.

              -

              fsPromises.link(existingPath, newPath)#

              +

              The path to the file the stream is reading from as specified in the first +argument to fs.createReadStream(). If path is passed as a string, then +readStream.path will be a string. If path is passed as a <Buffer>, then +readStream.path will be a <Buffer>.

              +
              readStream.pending#
              -

              Asynchronous link(2). The Promise is resolved with no arguments upon success.

              -

              fsPromises.lstat(path[, options])#

              +

              This property is true if the underlying file has not been opened yet, +i.e. before the 'ready' event is emitted.

              +

              Class: fs.Stats#

              +

              A <fs.Stats> object provides information about a file.

              +

              Objects returned from fs.stat(), fs.lstat() and fs.fstat() and +their synchronous counterparts are of this type. +If bigint in the options passed to those methods is true, the numeric values +will be bigint instead of number, and the object will contain additional +nanosecond-precision properties suffixed with Ns.

              +
              Stats {
              +  dev: 2114,
              +  ino: 48064969,
              +  mode: 33188,
              +  nlink: 1,
              +  uid: 85,
              +  gid: 100,
              +  rdev: 0,
              +  size: 527,
              +  blksize: 4096,
              +  blocks: 8,
              +  atimeMs: 1318289051000.1,
              +  mtimeMs: 1318289051000.1,
              +  ctimeMs: 1318289051000.1,
              +  birthtimeMs: 1318289051000.1,
              +  atime: Mon, 10 Oct 2011 23:24:11 GMT,
              +  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
              +  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
              +  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
              +

              bigint version:

              +
              BigIntStats {
              +  dev: 2114n,
              +  ino: 48064969n,
              +  mode: 33188n,
              +  nlink: 1n,
              +  uid: 85n,
              +  gid: 100n,
              +  rdev: 0n,
              +  size: 527n,
              +  blksize: 4096n,
              +  blocks: 8n,
              +  atimeMs: 1318289051000n,
              +  mtimeMs: 1318289051000n,
              +  ctimeMs: 1318289051000n,
              +  birthtimeMs: 1318289051000n,
              +  atimeNs: 1318289051000000000n,
              +  mtimeNs: 1318289051000000000n,
              +  ctimeNs: 1318289051000000000n,
              +  birthtimeNs: 1318289051000000000n,
              +  atime: Mon, 10 Oct 2011 23:24:11 GMT,
              +  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
              +  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
              +  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
              +
              stats.isBlockDevice()#
              +
                -
              • path <string> | <Buffer> | <URL>
              • -
              • options <Object> -
                  -
                • bigint <boolean> Whether the numeric values in the returned -fs.Stats object should be bigint. Default: false.
                • +
                • Returns: <boolean>
                -
              • -
              • Returns: <Promise>
              • +

                Returns true if the <fs.Stats> object describes a block device.

                +
                stats.isCharacterDevice()#
                + + -

                Asynchronous lstat(2). The Promise is resolved with the fs.Stats object -for the given symbolic link path.

                -

                fsPromises.mkdir(path[, options])#

                +

                Returns true if the <fs.Stats> object describes a character device.

                +
                stats.isDirectory()#
                -

                Asynchronously creates a directory then resolves the Promise with either no -arguments, or the first directory path created if recursive is true.

                -

                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 directories should be created. Calling -fsPromises.mkdir() when path is a directory that exists results in a -rejection only when recursive is false.

                -

                fsPromises.mkdtemp(prefix[, options])#

                +

                Returns true if the <fs.Stats> object describes a file system directory.

                +

                If the <fs.Stats> object was obtained from fs.lstat(), this method will +always return false. This is because fs.lstat() returns information +about a symbolic link itself and not the path it resolves to.

                +
                stats.isFIFO()#
                -

                Creates a unique temporary directory and resolves the Promise with the created -directory path. A unique directory name is generated by appending six random -characters to the end of the provided prefix. Due to platform -inconsistencies, avoid trailing X characters in prefix. Some platforms, -notably the BSDs, can return more than six random characters, and replace -trailing X characters in prefix with random characters.

                -

                The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use.

                -
                fsPromises.mkdtemp(path.join(os.tmpdir(), 'foo-'))
                -  .catch(console.error);
                -

                The fsPromises.mkdtemp() method will append the six randomly selected -characters directly to the prefix string. For instance, given a directory -/tmp, if the intention is to create a temporary directory within /tmp, the -prefix must end with a trailing platform-specific path separator -(require('path').sep).

                -

                fsPromises.open(path, flags[, mode])#

                +

                Returns true if the <fs.Stats> object describes a first-in-first-out (FIFO) +pipe.

                +
                stats.isFile()#
                -

                Asynchronous file open that returns a Promise that, when resolved, yields a -FileHandle object. See open(2).

                -

                mode sets the file mode (permission and sticky bits), but only if the file was -created.

                -

                Some characters (< > : " / \ | ? *) are reserved under Windows as documented -by Naming Files, Paths, and Namespaces. Under NTFS, if the filename contains -a colon, Node.js will open a file system stream, as described by -this MSDN page.

                -

                fsPromises.opendir(path[, options])#

                +

                Returns true if the <fs.Stats> object describes a regular file.

                +
                stats.isSocket()#
                -

                Asynchronously open a directory. See opendir(3).

                -

                Creates an fs.Dir, which contains all further functions for reading from -and cleaning up the directory.

                -

                The encoding option sets the encoding for the path while opening the -directory and subsequent read operations.

                -

                Example using async iteration:

                -
                const fs = require('fs');
                -
                -async function print(path) {
                -  const dir = await fs.promises.opendir(path);
                -  for await (const dirent of dir) {
                -    console.log(dirent.name);
                -  }
                -}
                -print('./').catch(console.error);
                -

                fsPromises.readdir(path[, options])#

                +

                Returns true if the <fs.Stats> object describes a socket.

                +
                stats.isSymbolicLink()#
                +

                Returns true if the <fs.Stats> object describes a symbolic link.

                +

                This method is only valid when using fs.lstat().

                +
                stats.dev#
                - -
              • Returns: <Promise>
              • +

                The numeric identifier of the device containing the file.

                +
                stats.ino#
                + -

                Reads the contents of a directory then resolves the Promise with an array -of the names of the files in the directory excluding '.' and '..'.

                -

                The optional options argument can be a string specifying an encoding, or an -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.

                -
                const fs = require('fs');
                -
                -async function print(path) {
                -  const files = await fs.promises.readdir(path);
                -  for (const file of files) {
                -    console.log(file);
                -  }
                -}
                -print('./').catch(console.error);
                -

                fsPromises.readFile(path[, options])#

                - +

                The file system specific "Inode" number for the file.

                +
                stats.mode#
                +

                A bit-field describing the file type and mode.

                +
                stats.nlink#
                - -
              • Returns: <Promise>
              • +

                The number of hard-links that exist for the file.

                +
                stats.uid#
                + -

                Asynchronously reads the entire contents of a file.

                -

                The Promise is resolved with the contents of the file. If no encoding is -specified (using options.encoding), the data is returned as a Buffer -object. Otherwise, the data will be a string.

                -

                If options is a string, then it specifies the encoding.

                -

                When the path is a directory, the behavior of fsPromises.readFile() is -platform-specific. On macOS, Linux, and Windows, the promise will be rejected -with an error. On FreeBSD, a representation of the directory's contents will be -returned.

                -

                Any specified FileHandle has to support reading.

                -

                fsPromises.readlink(path[, options])#

                - +

                The numeric user identifier of the user that owns the file (POSIX).

                +
                stats.gid#
                +

                The numeric group identifier of the group that owns the file (POSIX).

                +
                stats.rdev#
                - -
              • Returns: <Promise>
              • +

                A numeric device identifier if the file represents a device.

                +
                stats.size#
                + -

                Asynchronous readlink(2). The Promise is resolved with the linkString upon -success.

                -

                The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the link path returned. If the encoding is set to 'buffer', the link path -returned will be passed as a Buffer object.

                -

                fsPromises.realpath(path[, options])#

                - +

                The size of the file in bytes.

                +
                stats.blksize#
                +

                The file system block size for i/o operations.

                +
                stats.blocks#
                - -
              • Returns: <Promise>
              • +

                The number of blocks allocated for this file.

                +
                stats.atimeMs#
                + + -

                Determines the actual location of path using the same semantics as the -fs.realpath.native() function then resolves the Promise with the resolved -path.

                -

                Only paths that can be converted to UTF8 strings are supported.

                -

                The optional options argument can be a string specifying an encoding, or an -object with an encoding property specifying the character encoding to use for -the path. If the encoding is set to 'buffer', the path returned will be -passed as a Buffer object.

                -

                On Linux, when Node.js is linked against musl libc, the procfs file system must -be mounted on /proc in order for this function to work. Glibc does not have -this restriction.

                -

                fsPromises.rename(oldPath, newPath)#

                +

                The timestamp indicating the last time this file was accessed expressed in +milliseconds since the POSIX Epoch.

                +
                stats.mtimeMs#
                -

                Renames oldPath to newPath and resolves the Promise with no arguments -upon success.

                -

                fsPromises.rmdir(path[, options])#

                +

                The timestamp indicating the last time this file was modified expressed in +milliseconds since the POSIX Epoch.

                +
                stats.ctimeMs#
                -

                Stability: 1 - Recursive removal is experimental.

                +

                The timestamp indicating the last time the file status was changed expressed +in milliseconds since the POSIX Epoch.

                +
                stats.birthtimeMs#
                +
                  -
                • maxRetries <integer> If an EBUSY, EMFILE, ENFILE, ENOTEMPTY, or -EPERM error is encountered, Node.js will retry the operation with a linear -backoff wait of retryDelay ms longer on each try. This option represents the -number of retries. This option is ignored if the recursive option is not -true. Default: 0.
                • -
                • recursive <boolean> If true, perform a recursive directory removal. In -recursive mode, errors are not reported if path does not exist, and -operations are retried on failure. Default: false.
                • -
                • retryDelay <integer> The amount of time in milliseconds to wait between -retries. This option is ignored if the recursive option is not true. -Default: 100.
                • +
                • <number> | <bigint>
                - -
              • Returns: <Promise>
              • +

                The timestamp indicating the creation time of this file expressed in +milliseconds since the POSIX Epoch.

                +
                stats.atimeNs#
                + + -

                Removes the directory identified by path then resolves the Promise with -no arguments upon success.

                -

                Using fsPromises.rmdir() on a file (not a directory) results in the -Promise being rejected with an ENOENT error on Windows and an ENOTDIR -error on POSIX.

                -

                fsPromises.stat(path[, options])#

                +

                Only present when bigint: true is passed into the method that generates +the object. +The timestamp indicating the last time this file was accessed expressed in +nanoseconds since the POSIX Epoch.

                +
                stats.mtimeNs#
                + +

                Only present when bigint: true is passed into the method that generates +the object. +The timestamp indicating the last time this file was modified expressed in +nanoseconds since the POSIX Epoch.

                +
                stats.ctimeNs#
                + +

                Only present when bigint: true is passed into the method that generates +the object. +The timestamp indicating the last time the file status was changed expressed +in nanoseconds since the POSIX Epoch.

                +
                stats.birthtimeNs#
                + - -
              • Returns: <Promise>
              • +

                Only present when bigint: true is passed into the method that generates +the object. +The timestamp indicating the creation time of this file expressed in +nanoseconds since the POSIX Epoch.

                +
                stats.atime#
                + + -

                The Promise is resolved with the fs.Stats object for the given path.

                -

                fsPromises.symlink(target, path[, type])#

                +

                The timestamp indicating the last time this file was accessed.

                +
                stats.mtime#
                -

                Creates a symbolic link then resolves the Promise with no arguments upon -success.

                -

                The type argument is only used on Windows platforms and can be one of 'dir', -'file', or 'junction'. Windows junction points require the destination path -to be absolute. When using 'junction', the target argument will -automatically be normalized to absolute path.

                -

                fsPromises.truncate(path[, len])#

                +

                The timestamp indicating the last time this file was modified.

                +
                stats.ctime#
                -

                Truncates the path then resolves the Promise with no arguments upon -success. The path must be a string or Buffer.

                -

                fsPromises.unlink(path)#

                +

                The timestamp indicating the last time the file status was changed.

                +
                stats.birthtime#
                +

                The timestamp indicating the creation time of this file.

                +
                Stat time values#
                +

                The atimeMs, mtimeMs, ctimeMs, birthtimeMs properties are +numeric values that hold the corresponding times in milliseconds. Their +precision is platform specific. When bigint: true is passed into the +method that generates the object, the properties will be bigints, +otherwise they will be numbers.

                +

                The atimeNs, mtimeNs, ctimeNs, birthtimeNs properties are +bigints that hold the corresponding times in nanoseconds. They are +only present when bigint: true is passed into the method that generates +the object. Their precision is platform specific.

                +

                atime, mtime, ctime, and birthtime are +Date object alternate representations of the various times. The +Date and number values are not connected. Assigning a new number value, or +mutating the Date value, will not be reflected in the corresponding alternate +representation.

                +

                The times in the stat object have the following semantics:

                +
                  +
                • atime "Access Time": Time when file data last accessed. Changed +by the mknod(2), utimes(2), and read(2) system calls.
                • +
                • mtime "Modified Time": Time when file data last modified. +Changed by the mknod(2), utimes(2), and write(2) system calls.
                • +
                • ctime "Change Time": Time when file status was last changed +(inode data modification). Changed by the chmod(2), chown(2), +link(2), mknod(2), rename(2), unlink(2), utimes(2), +read(2), and write(2) system calls.
                • +
                • birthtime "Birth Time": Time of file creation. Set once when the +file is created. On filesystems where birthtime is not available, +this field may instead hold either the ctime or +1970-01-01T00:00Z (ie, Unix epoch timestamp 0). This value may be greater +than atime or mtime in this case. On Darwin and other FreeBSD variants, +also set if the atime is explicitly set to an earlier value than the current +birthtime using the utimes(2) system call.
                -

                Asynchronous unlink(2). The Promise is resolved with no arguments upon -success.

                -

                fsPromises.utimes(path, atime, mtime)#

                +

                Prior to Node.js 0.12, the ctime held the birthtime on Windows systems. As +of 0.12, ctime is not "creation time", and on Unix systems, it never was.

                +

                Class: fs.WriteStream#

                -

                Change the file system timestamps of the object referenced by path then -resolves the Promise with no arguments upon success.

                -

                The atime and mtime arguments follow these rules:

                +

                Instances of <fs.WriteStream> are created and returned using the +fs.createWriteStream() function.

                +
                Event: 'close'#
                + +

                Emitted when the <fs.WriteStream>'s underlying file descriptor has been closed.

                +
                Event: 'open'#
                +
                  -
                • Values can be either numbers representing Unix epoch time, Dates, or a -numeric string like '123456789.0'.
                • -
                • If the value can not be converted to a number, or is NaN, Infinity or --Infinity, an Error will be thrown.
                • +
                • fd <integer> Integer file descriptor used by the <fs.WriteStream>.
                -

                fsPromises.writeFile(file, data[, options])#

                +

                Emitted when the <fs.WriteStream>'s file is opened.

                +
                Event: 'ready'#
                +

                Emitted when the <fs.WriteStream> is ready to be used.

                +

                Fires immediately after 'open'.

                +
                writeStream.bytesWritten#
                + +

                The number of bytes written so far. Does not include data that is still queued +for writing.

                +
                writeStream.close([callback])#
                + -

                Asynchronously writes data to a file, replacing the file if it already exists. -data can be a string or a buffer. The Promise will be resolved with no -arguments upon success.

                -

                The encoding option is ignored if data is a buffer.

                -

                If options is a string, then it specifies the encoding.

                -

                Any specified FileHandle has to support writing.

                -

                It is unsafe to use fsPromises.writeFile() multiple times on the same file -without waiting for the Promise to be resolved (or rejected).

                -

                FS constants#

                +

                Closes writeStream. Optionally accepts a +callback that will be executed once the writeStream +is closed.

                +
                writeStream.path#
                + +

                The path to the file the stream is writing to as specified in the first +argument to fs.createWriteStream(). If path is passed as a string, then +writeStream.path will be a string. If path is passed as a <Buffer>, then +writeStream.path will be a <Buffer>.

                +
                writeStream.pending#
                + + +

                This property is true if the underlying file has not been opened yet, +i.e. before the 'ready' event is emitted.

                +

                fs.constants#

                + +

                Returns an object containing commonly used constants for file system +operations.

                +
                FS constants#

                The following constants are exported by fs.constants.

                Not every constant will be available on every operating system.

                To use more than one constant, use the bitwise OR | operator.

                Example:

                -
                const fs = require('fs');
                +
                import { open, constants } from 'fs';
                 
                 const {
                -  O_RDWR,
                -  O_CREAT,
                -  O_EXCL
                -} = fs.constants;
                +  O_RDWR,
                +  O_CREAT,
                +  O_EXCL
                +} = constants;
                 
                -fs.open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => {
                +open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => {
                   // ...
                 });
                -

                File access constants#

                +
                File access constants#

                The following constants are meant for use with fs.access().

                @@ -5569,8 +6075,8 @@ fs.open('/path/to/my/file', O_RDWR | O_CREAT | (will behave like fs.constants.F_OK).
                -

                File copy constants#

                -

                The following constants are meant for use with fs.copyFile().

                +
                File copy constants#
                +

                The following constants are meant for use with fs.copyFile().

                @@ -5594,7 +6100,7 @@ fs.open('/path/to/my/file', O_RDWR | O_CREAT | copy-on-write, then the operation will fail with an error.
                Constant
                -

                File open constants#

                +
                File open constants#

                The following constants are meant for use with fs.open().

                @@ -5685,8 +6191,8 @@ fs.open('/path/to/my/file', O_RDWR | O_CREAT | this flag is ignored.
                -

                File type constants#

                -

                The following constants are meant for use with the fs.Stats object's +

                File type constants#
                +

                The following constants are meant for use with the <fs.Stats> object's mode property for determining a file's type.

                @@ -5726,8 +6232,8 @@ fs.open('/path/to/my/file', O_RDWR | O_CREAT |
                File type constant for a socket.
                -

                File mode constants#

                -

                The following constants are meant for use with the fs.Stats object's +

                File mode constants#
                +

                The following constants are meant for use with the <fs.Stats> object's mode property for determining the access permissions for a file.

                @@ -5783,7 +6289,244 @@ fs.open('/path/to/my/file', O_RDWR | O_CREAT |
                File mode indicating executable by others.
                -

                File system flags#

                +

      Notes#

      +

      Ordering of callback and promise-based operations#

      +

      Because they are executed asynchronously by the underlying thread pool, +there is no guaranteed ordering when using either the callback or +promise-based methods.

      +

      For example, the following is prone to error because the fs.stat() +operation might complete before the fs.rename() operation:

      +
      fs.rename('/tmp/hello', '/tmp/world', (err) => {
      +  if (err) throw err;
      +  console.log('renamed complete');
      +});
      +fs.stat('/tmp/world', (err, stats) => {
      +  if (err) throw err;
      +  console.log(`stats: ${JSON.stringify(stats)}`);
      +});
      +

      It is important to correctly order the operations by awaiting the results +of one before invoking the other:

      + +
      import { rename, stat } from 'fs/promises';
      +
      +const from = '/tmp/hello';
      +const to = '/tmp/world';
      +
      +try {
      +  await rename(from, to);
      +  const stats = await stat(to);
      +  console.log(`stats: ${JSON.stringify(stats)}`);
      +} catch (error) {
      +  console.error('there was an error:', error.message);
      +}const { rename, stat } = require('fs/promises');
      +
      +(async function(from, to) {
      +  try {
      +    await rename(from, to);
      +    const stats = await stat(to);
      +    console.log(`stats: ${JSON.stringify(stats)}`);
      +  } catch (error) {
      +    console.error('there was an error:', error.message);
      +  }
      +})('/tmp/hello', '/tmp/world');
      +

      Or, when using the callback APIs, move the fs.stat() call into the callback +of the fs.rename() operation:

      + +
      import { rename, stat } from 'fs';
      +
      +rename('/tmp/hello', '/tmp/world', (err) => {
      +  if (err) throw err;
      +  stat('/tmp/world', (err, stats) => {
      +    if (err) throw err;
      +    console.log(`stats: ${JSON.stringify(stats)}`);
      +  });
      +});const { rename, stat } = require('fs/promises');
      +
      +rename('/tmp/hello', '/tmp/world', (err) => {
      +  if (err) throw err;
      +  stat('/tmp/world', (err, stats) => {
      +    if (err) throw err;
      +    console.log(`stats: ${JSON.stringify(stats)}`);
      +  });
      +});
      +

      File paths#

      +

      Most fs operations accept file paths that may be specified in the form of +a string, a <Buffer>, or a <URL> object using the file: protocol.

      +
      String paths#
      +

      String form paths are interpreted as UTF-8 character sequences identifying +the absolute or relative filename. Relative paths will be resolved relative +to the current working directory as determined by calling process.cwd().

      +

      Example using an absolute path on POSIX:

      +
      import { open } from 'fs/promises';
      +
      +let fd;
      +try {
      +  fd = await open('/open/some/file.txt', 'r');
      +  // Do something with the file
      +} finally {
      +  await fd.close();
      +}
      +

      Example using a relative path on POSIX (relative to process.cwd()):

      +
      import { open } from 'fs/promises';
      +
      +let fd;
      +try {
      +  fd = await open('file.txt', 'r');
      +  // Do something with the file
      +} finally {
      +  await fd.close();
      +}
      +
      File URL paths#
      + +

      For most fs module functions, the path or filename argument may be passed +as a <URL> object using the file: protocol.

      +
      import { readFileSync } from 'fs';
      +
      +readFileSync(new URL('file:///tmp/hello'));
      +

      file: URLs are always absolute paths.

      +
      Platform-specific considerations#
      +

      On Windows, file: <URL>s with a host name convert to UNC paths, while file: +<URL>s with drive letters convert to local absolute paths. file: <URL>s +without a host name nor a drive letter will result in an error:

      +
      import { readFileSync } from 'fs';
      +// On Windows :
      +
      +// - WHATWG file URLs with hostname convert to UNC path
      +// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file
      +readFileSync(new URL('file://hostname/p/a/t/h/file'));
      +
      +// - WHATWG file URLs with drive letters convert to absolute path
      +// file:///C:/tmp/hello => C:\tmp\hello
      +readFileSync(new URL('file:///C:/tmp/hello'));
      +
      +// - WHATWG file URLs without hostname must have a drive letters
      +readFileSync(new URL('file:///notdriveletter/p/a/t/h/file'));
      +readFileSync(new URL('file:///c/p/a/t/h/file'));
      +// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute
      +

      file: <URL>s with drive letters must use : as a separator just after +the drive letter. Using another separator will result in an error.

      +

      On all other platforms, file: <URL>s with a host name are unsupported and +will result in an error:

      +
      import { readFileSync } from 'fs';
      +// On other platforms:
      +
      +// - WHATWG file URLs with hostname are unsupported
      +// file://hostname/p/a/t/h/file => throw!
      +readFileSync(new URL('file://hostname/p/a/t/h/file'));
      +// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute
      +
      +// - WHATWG file URLs convert to absolute path
      +// file:///tmp/hello => /tmp/hello
      +readFileSync(new URL('file:///tmp/hello'));
      +

      A file: <URL> having encoded slash characters will result in an error on all +platforms:

      +
      import { readFileSync } from 'fs';
      +
      +// On Windows
      +readFileSync(new URL('file:///C:/p/a/t/h/%2F'));
      +readFileSync(new URL('file:///C:/p/a/t/h/%2f'));
      +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
      +\ or / characters */
      +
      +// On POSIX
      +readFileSync(new URL('file:///p/a/t/h/%2F'));
      +readFileSync(new URL('file:///p/a/t/h/%2f'));
      +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
      +/ characters */
      +

      On Windows, file: <URL>s having encoded backslash will result in an error:

      +
      import { readFileSync } from 'fs';
      +
      +// On Windows
      +readFileSync(new URL('file:///C:/path/%5C'));
      +readFileSync(new URL('file:///C:/path/%5c'));
      +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
      +\ or / characters */
      +
      Buffer paths#
      +

      Paths specified using a <Buffer> are useful primarily on certain POSIX +operating systems that treat file paths as opaque byte sequences. On such +systems, it is possible for a single file path to contain sub-sequences that +use multiple character encodings. As with string paths, <Buffer> paths may +be relative or absolute:

      +

      Example using an absolute path on POSIX:

      +
      import { open } from 'fs/promises';
      +
      +let fd;
      +try {
      +  fd = await open(Buffer.from('/open/some/file.txt'), 'r');
      +  // Do something with the file
      +} finally {
      +  await fd.close();
      +}
      +
      Per-drive working directories on Windows#
      +

      On Windows, Node.js follows the concept of per-drive working directory. This +behavior can be observed when using a drive path without a backslash. For +example fs.readdirSync('C:\\') can potentially return a different result than +fs.readdirSync('C:'). For more information, see +this MSDN page.

      +

      File descriptors#

      +

      On POSIX systems, for every process, the kernel maintains a table of currently +open files and resources. Each open file is assigned a simple numeric +identifier called a file descriptor. At the system-level, all file system +operations use these file descriptors to identify and track each specific +file. Windows systems use a different but conceptually similar mechanism for +tracking resources. To simplify things for users, Node.js abstracts away the +differences between operating systems and assigns all open files a numeric file +descriptor.

      +

      The callback-based fs.open(), and synchronous fs.openSync() methods open a +file and allocate a new file descriptor. Once allocated, the file descriptor may +be used to read data from, write data to, or request information about the file.

      +

      Operating systems limit the number of file descriptors that may be open +at any given time so it is critical to close the descriptor when operations +are completed. Failure to do so will result in a memory leak that will +eventually cause an application to crash.

      +
      import { open, close, fstat } from 'fs';
      +
      +function closeFd(fd) {
      +  close(fd, (err) => {
      +    if (err) throw err;
      +  });
      +}
      +
      +open('/open/some/file.txt', 'r', (err, fd) => {
      +  if (err) throw err;
      +  try {
      +    fstat(fd, (err, stat) => {
      +      if (err) {
      +        closeFd(fd);
      +        throw err;
      +      }
      +
      +      // use stat
      +
      +      closeFd(fd);
      +    });
      +  } catch (err) {
      +    closeFd(fd);
      +    throw err;
      +  }
      +});
      +

      The promise-based APIs use a <FileHandle> object in place of the numeric +file descriptor. These objects are better managed by the system to ensure +that resources are not leaked. However, it is still required that they are +closed when operations are completed:

      +
      import { open } from 'fs/promises';
      +
      +let file;
      +try {
      +  file = await open('/open/some/file.txt', 'r');
      +  const stat = await file.stat();
      +  // use stat
      +} finally {
      +  await file.close();
      +}
      +

      Threadpool usage#

      +

      All callback and promise-based file system APIs ( with the exception of +fs.FSWatcher()) use libuv's threadpool. This can have surprising and negative +performance implications for some applications. See the +UV_THREADPOOL_SIZE documentation for more information.

      +

      File system flags#

      The following flags are available wherever the flag option takes a string.

        @@ -5849,33 +6592,69 @@ or O_EXCL|O_CREAT to CREATE_NEW, as accepted by

        The exclusive flag 'x' (O_EXCL flag in open(2)) causes the operation to return an error if the path already exists. On POSIX, if the path is a symbolic link, using O_EXCL returns an error even if the link is to a path that does -not exist. The exclusive flag may or may not work with network file systems.

        +not exist. The exclusive flag might not work with network file systems.

        On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file.

        -

        Modifying a file rather than replacing it may require a flags mode of 'r+' -rather than the default mode 'w'.

        +

        Modifying a file rather than replacing it may require the flag option to be +set to 'r+' rather than the default 'w'.

        The behavior of some flags are platform-specific. As such, opening a directory on macOS and Linux with the 'a+' flag, as in the example below, will return an error. In contrast, on Windows and FreeBSD, a file descriptor or a FileHandle will be returned.

        // macOS and Linux
        -fs.open('<directory>', 'a+', (err, fd) => {
        +fs.open('<directory>', 'a+', (err, fd) => {
           // => [Error: EISDIR: illegal operation on a directory, open <directory>]
         });
         
         // Windows and FreeBSD
        -fs.open('<directory>', 'a+', (err, fd) => {
        +fs.open('<directory>', 'a+', (err, fd) => {
           // => null, <fd>
         });

        On Windows, opening an existing hidden file using the 'w' flag (either through fs.open() or fs.writeFile() or fsPromises.open()) will fail with EPERM. Existing hidden files can be opened for writing with the 'r+' flag.

        A call to fs.ftruncate() or filehandle.truncate() can be used to reset -the file contents.

        +the file contents.

      + diff --git a/doc/api/fs.json b/doc/api/fs.json index 1fe8ce0d8433068029e606225e1f14c6c3569558..608dbc25484ed8cbf743a7f03701ede0764ab284 100644 --- a/doc/api/fs.json +++ b/doc/api/fs.json @@ -8,76 +8,58 @@ "introduced_in": "v0.10.0", "stability": 2, "stabilityText": "Stable", - "desc": "

      Source Code: lib/fs.js

      \n

      The fs module enables interacting with the file system in a\nway modeled on standard POSIX functions.

      \n

      To use this module:

      \n
      const fs = require('fs');\n
      \n

      All file system operations have synchronous, callback, and promise-based\nforms.

      ", + "desc": "

      Source Code: lib/fs.js

      \n

      The fs module enables interacting with the file system in a\nway modeled on standard POSIX functions.

      \n

      To use the promise-based APIs:

      \n
      import * as fs from 'fs/promises';\n
      \n
      const fs = require('fs/promises');\n
      \n

      To use the callback and sync APIs:

      \n
      import * as fs from 'fs';\n
      \n
      const fs = require('fs');\n
      \n

      All file system operations have synchronous, callback, and promise-based\nforms, and are accessible using both CommonJS syntax and ES6 Modules (ESM).

      ", "modules": [ { - "textRaw": "Synchronous example", - "name": "synchronous_example", - "desc": "

      The synchronous form blocks the Node.js event loop and further JavaScript\nexecution until the operation is complete. Exceptions are thrown immediately\nand can be handled using try…catch, or can be allowed to bubble up.

      \n
      const fs = require('fs');\n\ntry {\n  fs.unlinkSync('/tmp/hello');\n  console.log('successfully deleted /tmp/hello');\n} catch (err) {\n  // handle the error\n}\n
      ", + "textRaw": "Promise example", + "name": "promise_example", + "desc": "

      Promise-based operations return a promise that is fulfilled when the\nasynchronous operation is complete.

      \n
      import { unlink } from 'fs/promises';\n\ntry {\n  await unlink('/tmp/hello');\n  console.log('successfully deleted /tmp/hello');\n} catch (error) {\n  console.error('there was an error:', error.message);\n}\n
      \n
      const { unlink } = require('fs/promises');\n\n(async function(path) {\n  try {\n    await unlink(path);\n    console.log(`successfully deleted ${path}`);\n  } catch (error) {\n    console.error('there was an error:', error.message);\n  }\n})('/tmp/hello');\n
      ", "type": "module", - "displayName": "Synchronous example" + "displayName": "Promise example" }, { "textRaw": "Callback example", "name": "callback_example", - "desc": "

      The callback form takes a completion callback function as its last\nargument and invokes the operation asynchronously. The arguments passed to\nthe completion callback depend on the method, but the first argument is always\nreserved for an exception. If the operation is completed successfully, then\nthe first argument is null or undefined.

      \n
      const fs = require('fs');\n\nfs.unlink('/tmp/hello', (err) => {\n  if (err) throw err;\n  console.log('successfully deleted /tmp/hello');\n});\n
      ", + "desc": "

      The callback form takes a completion callback function as its last\nargument and invokes the operation asynchronously. The arguments passed to\nthe completion callback depend on the method, but the first argument is always\nreserved for an exception. If the operation is completed successfully, then\nthe first argument is null or undefined.

      \n
      import { unlink } from 'fs';\n\nunlink('/tmp/hello', (err) => {\n  if (err) throw err;\n  console.log('successfully deleted /tmp/hello');\n});\n
      \n
      const { unlink } = require('fs');\n\nunlink('/tmp/hello', (err) => {\n  if (err) throw err;\n  console.log('successfully deleted /tmp/hello');\n});\n
      \n

      The callback-based versions of the fs module APIs are preferable over\nthe use of the promise APIs when maximal performance (both in terms of\nexecution time and memory allocation are required).

      ", "type": "module", "displayName": "Callback example" }, { - "textRaw": "Promise example", - "name": "promise_example", - "desc": "

      Promise-based operations return a Promise that is resolved when the\nasynchronous operation is complete.

      \n
      const fs = require('fs').promises;\n\n(async function(path) {\n  try {\n    await fs.unlink(path);\n    console.log(`successfully deleted ${path}`);\n  } catch (error) {\n    console.error('there was an error:', error.message);\n  }\n})('/tmp/hello');\n
      ", - "type": "module", - "displayName": "Promise example" - }, - { - "textRaw": "Ordering of callback and promise-based operations", - "name": "ordering_of_callback_and_promise-based_operations", - "desc": "

      There is no guaranteed ordering when using either the callback or\npromise-based methods. For example, the following is prone to error\nbecause the fs.stat() operation might complete before the fs.rename()\noperation:

      \n
      fs.rename('/tmp/hello', '/tmp/world', (err) => {\n  if (err) throw err;\n  console.log('renamed complete');\n});\nfs.stat('/tmp/world', (err, stats) => {\n  if (err) throw err;\n  console.log(`stats: ${JSON.stringify(stats)}`);\n});\n
      \n

      To correctly order the operations, move the fs.stat() call into the callback\nof the fs.rename() operation:

      \n
      fs.rename('/tmp/hello', '/tmp/world', (err) => {\n  if (err) throw err;\n  fs.stat('/tmp/world', (err, stats) => {\n    if (err) throw err;\n    console.log(`stats: ${JSON.stringify(stats)}`);\n  });\n});\n
      \n

      Or, use the promise-based API:

      \n
      const fs = require('fs').promises;\n\n(async function(from, to) {\n  try {\n    await fs.rename(from, to);\n    const stats = await fs.stat(to);\n    console.log(`stats: ${JSON.stringify(stats)}`);\n  } catch (error) {\n    console.error('there was an error:', error.message);\n  }\n})('/tmp/hello', '/tmp/world');\n
      ", + "textRaw": "Synchronous example", + "name": "synchronous_example", + "desc": "

      The synchronous APIs block the Node.js event loop and further JavaScript\nexecution until the operation is complete. Exceptions are thrown immediately\nand can be handled using try…catch, or can be allowed to bubble up.

      \n
      import { unlinkSync } from 'fs';\n\ntry {\n  unlinkSync('/tmp/hello');\n  console.log('successfully deleted /tmp/hello');\n} catch (err) {\n  // handle the error\n}\n
      \n
      const { unlinkSync } = require('fs');\n\ntry {\n  unlinkSync('/tmp/hello');\n  console.log('successfully deleted /tmp/hello');\n} catch (err) {\n  // handle the error\n}\n
      ", "type": "module", - "displayName": "Ordering of callback and promise-based operations" + "displayName": "Synchronous example" }, { - "textRaw": "File paths", - "name": "file_paths", - "desc": "

      Most fs operations accept filepaths that may be specified in the form of\na string, a Buffer, or a URL object using the file: protocol.

      \n

      String form paths are interpreted as UTF-8 character sequences identifying\nthe absolute or relative filename. Relative paths will be resolved relative\nto the current working directory as determined by calling process.cwd().

      \n

      Example using an absolute path on POSIX:

      \n
      const fs = require('fs');\n\nfs.open('/open/some/file.txt', 'r', (err, fd) => {\n  if (err) throw err;\n  fs.close(fd, (err) => {\n    if (err) throw err;\n  });\n});\n
      \n

      Example using a relative path on POSIX (relative to process.cwd()):

      \n
      fs.open('file.txt', 'r', (err, fd) => {\n  if (err) throw err;\n  fs.close(fd, (err) => {\n    if (err) throw err;\n  });\n});\n
      \n

      Paths specified using a Buffer are useful primarily on certain POSIX\noperating systems that treat file paths as opaque byte sequences. On such\nsystems, it is possible for a single file path to contain sub-sequences that\nuse multiple character encodings. As with string paths, Buffer paths may\nbe relative or absolute:

      \n

      Example using an absolute path on POSIX:

      \n
      fs.open(Buffer.from('/open/some/file.txt'), 'r', (err, fd) => {\n  if (err) throw err;\n  fs.close(fd, (err) => {\n    if (err) throw err;\n  });\n});\n
      \n

      On Windows, Node.js follows the concept of per-drive working directory. This\nbehavior can be observed when using a drive path without a backslash. For\nexample fs.readdirSync('C:\\\\') can potentially return a different result than\nfs.readdirSync('C:'). For more information, see\nthis MSDN page.

      ", - "modules": [ - { - "textRaw": "URL object support", - "name": "url_object_support", - "meta": { - "added": [ - "v7.6.0" + "textRaw": "Promises API", + "name": "promises_api", + "meta": { + "added": [ + "v10.0.0" + ], + "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31553", + "description": "Exposed as `require('fs/promises')`." + }, + { + "version": [ + "v11.14.0", + "v10.17.0" ], - "changes": [] + "pr-url": "https://github.com/nodejs/node/pull/26581", + "description": "This API is no longer experimental." }, - "desc": "

      For most fs module functions, the path or filename argument may be passed\nas a WHATWG URL object. Only URL objects using the file: protocol\nare supported.

      \n
      const fs = require('fs');\nconst fileUrl = new URL('file:///tmp/hello');\n\nfs.readFileSync(fileUrl);\n
      \n

      file: URLs are always absolute paths.

      \n

      Using WHATWG URL objects might introduce platform-specific behaviors.

      \n

      On Windows, file: URLs with a host name convert to UNC paths, while file:\nURLs with drive letters convert to local absolute paths. file: URLs without a\nhost name nor a drive letter will result in a throw:

      \n
      // On Windows :\n\n// - WHATWG file URLs with hostname convert to UNC path\n// file://hostname/p/a/t/h/file => \\\\hostname\\p\\a\\t\\h\\file\nfs.readFileSync(new URL('file://hostname/p/a/t/h/file'));\n\n// - WHATWG file URLs with drive letters convert to absolute path\n// file:///C:/tmp/hello => C:\\tmp\\hello\nfs.readFileSync(new URL('file:///C:/tmp/hello'));\n\n// - WHATWG file URLs without hostname must have a drive letters\nfs.readFileSync(new URL('file:///notdriveletter/p/a/t/h/file'));\nfs.readFileSync(new URL('file:///c/p/a/t/h/file'));\n// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute\n
      \n

      file: URLs with drive letters must use : as a separator just after\nthe drive letter. Using another separator will result in a throw.

      \n

      On all other platforms, file: URLs with a host name are unsupported and will\nresult in a throw:

      \n
      // On other platforms:\n\n// - WHATWG file URLs with hostname are unsupported\n// file://hostname/p/a/t/h/file => throw!\nfs.readFileSync(new URL('file://hostname/p/a/t/h/file'));\n// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute\n\n// - WHATWG file URLs convert to absolute path\n// file:///tmp/hello => /tmp/hello\nfs.readFileSync(new URL('file:///tmp/hello'));\n
      \n

      A file: URL having encoded slash characters will result in a throw on all\nplatforms:

      \n
      // On Windows\nfs.readFileSync(new URL('file:///C:/p/a/t/h/%2F'));\nfs.readFileSync(new URL('file:///C:/p/a/t/h/%2f'));\n/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded\n\\ or / characters */\n\n// On POSIX\nfs.readFileSync(new URL('file:///p/a/t/h/%2F'));\nfs.readFileSync(new URL('file:///p/a/t/h/%2f'));\n/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded\n/ characters */\n
      \n

      On Windows, file: URLs having encoded backslash will result in a throw:

      \n
      // On Windows\nfs.readFileSync(new URL('file:///C:/path/%5C'));\nfs.readFileSync(new URL('file:///C:/path/%5c'));\n/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded\n\\ or / characters */\n
      ", - "type": "module", - "displayName": "URL object support" - } - ], - "type": "module", - "displayName": "File paths" - }, - { - "textRaw": "File descriptors", - "name": "file_descriptors", - "desc": "

      On POSIX systems, for every process, the kernel maintains a table of currently\nopen files and resources. Each open file is assigned a simple numeric\nidentifier called a file descriptor. At the system-level, all file system\noperations use these file descriptors to identify and track each specific\nfile. Windows systems use a different but conceptually similar mechanism for\ntracking resources. To simplify things for users, Node.js abstracts away the\nspecific differences between operating systems and assigns all open files a\nnumeric file descriptor.

      \n

      The fs.open() method is used to allocate a new file descriptor. Once\nallocated, the file descriptor may be used to read data from, write data to,\nor request information about the file.

      \n
      fs.open('/open/some/file.txt', 'r', (err, fd) => {\n  if (err) throw err;\n  fs.fstat(fd, (err, stat) => {\n    if (err) throw err;\n    // use stat\n\n    // always close the file descriptor!\n    fs.close(fd, (err) => {\n      if (err) throw err;\n    });\n  });\n});\n
      \n

      Most operating systems limit the number of file descriptors that may be open\nat any given time so it is critical to close the descriptor when operations\nare completed. Failure to do so will result in a memory leak that will\neventually cause an application to crash.

      ", - "type": "module", - "displayName": "File descriptors" - }, - { - "textRaw": "Threadpool usage", - "name": "threadpool_usage", - "desc": "

      All file system APIs except fs.FSWatcher() and those that are explicitly\nsynchronous use libuv's threadpool, which can have surprising and negative\nperformance implications for some applications. See the\nUV_THREADPOOL_SIZE documentation for more information.

      ", - "type": "module", - "displayName": "Threadpool usage" - }, - { - "textRaw": "`fs` Promises API", - "name": "`fs`_promises_api", - "desc": "

      The fs.promises API provides an alternative set of asynchronous file system\nmethods that return Promise objects rather than using callbacks. The\nAPI is accessible via require('fs').promises.

      ", + { + "version": "v10.1.0", + "pr-url": "https://github.com/nodejs/node/pull/20504", + "description": "The API is accessible via `require('fs').promises` only." + } + ] + }, + "desc": "

      The fs/promises API provides asynchronous file system methods that return\npromises.

      \n

      The promise APIs use the underlying Node.js threadpool to perform file\nsystem operations off the event loop thread. These operations are not\nsynchronized or threadsafe. Care must be taken when performing multiple\nconcurrent modifications on the same file or data corruption may occur.

      ", "classes": [ { "textRaw": "Class: `FileHandle`", @@ -89,10 +71,10 @@ ], "changes": [] }, - "desc": "

      A FileHandle object is a wrapper for a numeric file descriptor.\nInstances of FileHandle are distinct from numeric file descriptors\nin that they provide an object oriented API for working with files.

      \n

      If a FileHandle is not closed using the\nfilehandle.close() method, it might automatically close the file descriptor\nand will emit a process warning, thereby helping to prevent memory leaks.\nPlease do not rely on this behavior because it is unreliable and\nthe file may not be closed. Instead, always explicitly close FileHandles.\nNode.js may change this behavior in the future.

      \n

      Instances of the FileHandle object are created internally by the\nfsPromises.open() method.

      \n

      Unlike the callback-based API (fs.fstat(), fs.fchown(), fs.fchmod(), and\nso on), a numeric file descriptor is not used by the promise-based API. Instead,\nthe promise-based API uses the FileHandle class in order to help avoid\naccidental leaking of unclosed file descriptors after a Promise is resolved or\nrejected.

      ", + "desc": "

      A <FileHandle> object is an object wrapper for a numeric file descriptor.

      \n

      Instances of the <FileHandle> object are created by the fsPromises.open()\nmethod.

      \n

      All <FileHandle> objects are <EventEmitter>s.

      \n

      If a <FileHandle> is not closed using the filehandle.close() method, it will\ntry to automatically close the file descriptor and emit a process warning,\nhelping to prevent memory leaks. Please do not rely on this behavior because\nit can be unreliable and the file may not be closed. Instead, always explicitly\nclose <FileHandle>s. Node.js may change this behavior in the future.

      ", "methods": [ { - "textRaw": "`filehandle.appendFile(data, options)`", + "textRaw": "`filehandle.appendFile(data[, options])`", "type": "method", "name": "appendFile", "meta": { @@ -104,15 +86,16 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { - "textRaw": "`data` {string|Buffer}", + "textRaw": "`data` {string|Buffer|TypedArray|DataView}", "name": "data", - "type": "string|Buffer" + "type": "string|Buffer|TypedArray|DataView" }, { "textRaw": "`options` {Object|string}", @@ -145,20 +128,22 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { - "textRaw": "`mode` {integer}", + "textRaw": "`mode` {integer} the file mode bit mask.", "name": "mode", - "type": "integer" + "type": "integer", + "desc": "the file mode bit mask." } ] } ], - "desc": "

      Modifies the permissions on the file. The Promise is resolved with no\narguments upon success.

      " + "desc": "

      Modifies the permissions on the file. See chmod(2).

      " }, { "textRaw": "`filehandle.chown(uid, gid)`", @@ -173,25 +158,28 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { - "textRaw": "`uid` {integer}", + "textRaw": "`uid` {integer} The file's new owner's user id.", "name": "uid", - "type": "integer" + "type": "integer", + "desc": "The file's new owner's user id." }, { - "textRaw": "`gid` {integer}", + "textRaw": "`gid` {integer} The file's new group's group id.", "name": "gid", - "type": "integer" + "type": "integer", + "desc": "The file's new group's group id." } ] } ], - "desc": "

      Changes the ownership of the file then resolves the Promise with no arguments\nupon success.

      " + "desc": "

      Changes the ownership of the file. A wrapper for chown(2).

      " }, { "textRaw": "`filehandle.close()`", @@ -206,15 +194,15 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise} A `Promise` that will be resolved once the underlying file descriptor is closed, or will be rejected if an error occurs while closing.", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", "type": "Promise", - "desc": "A `Promise` that will be resolved once the underlying file descriptor is closed, or will be rejected if an error occurs while closing." + "desc": "Fulfills with `undefined` upon success." }, "params": [] } ], - "desc": "

      Closes the file descriptor.

      \n
      const fsPromises = require('fs').promises;\nasync function openAndClose() {\n  let filehandle;\n  try {\n    filehandle = await fsPromises.open('thefile.txt', 'r');\n  } finally {\n    if (filehandle !== undefined)\n      await filehandle.close();\n  }\n}\n
      " + "desc": "

      Closes the file handle after waiting for any pending operation on the handle to\ncomplete.

      \n
      import { open } from 'fs/promises';\n\nlet filehandle;\ntry {\n  filehandle = await open('thefile.txt', 'r');\n} finally {\n  await filehandle?.close();\n}\n
      " }, { "textRaw": "`filehandle.datasync()`", @@ -229,14 +217,15 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [] } ], - "desc": "

      Asynchronous fdatasync(2). The Promise is resolved with no arguments upon\nsuccess.

      " + "desc": "

      Forces all currently queued I/O operations associated with the file to the\noperating system's synchronized I/O completion state. Refer to the POSIX\nfdatasync(2) documentation for details.

      \n

      Unlike filehandle.sync this method does not flush modified metadata.

      " }, { "textRaw": "`filehandle.read(buffer, offset, length, position)`", @@ -251,42 +240,64 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills upon success with an object with two properties:", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills upon success with an object with two properties:", + "options": [ + { + "textRaw": "`bytesRead` {integer} The number of bytes read", + "name": "bytesRead", + "type": "integer", + "desc": "The number of bytes read" + }, + { + "textRaw": "`buffer` {Buffer|TypedArray|DataView} A reference to the passed in `buffer` argument.", + "name": "buffer", + "type": "Buffer|TypedArray|DataView", + "desc": "A reference to the passed in `buffer` argument." + } + ] }, "params": [ { - "textRaw": "`buffer` {Buffer|Uint8Array}", + "textRaw": "`buffer` {Buffer|TypedArray|DataView} A buffer that will be filled with the file data read.", "name": "buffer", - "type": "Buffer|Uint8Array" + "type": "Buffer|TypedArray|DataView", + "desc": "A buffer that will be filled with the file data read." }, { - "textRaw": "`offset` {integer}", + "textRaw": "`offset` {integer} The location in the buffer at which to start filling. **Default:** `0`", "name": "offset", - "type": "integer" + "type": "integer", + "default": "`0`", + "desc": "The location in the buffer at which to start filling." }, { - "textRaw": "`length` {integer}", + "textRaw": "`length` {integer} The number of bytes to read. **Default:** `buffer.byteLength`", "name": "length", - "type": "integer" + "type": "integer", + "default": "`buffer.byteLength`", + "desc": "The number of bytes to read." }, { - "textRaw": "`position` {integer}", + "textRaw": "`position` {integer} The location where to begin reading data from the file. If `null`, data will be read from the current file position, and the position will be updated. If `position` is an integer, the current file position will remain unchanged.", "name": "position", - "type": "integer" + "type": "integer", + "desc": "The location where to begin reading data from the file. If `null`, data will be read from the current file position, and the position will be updated. If `position` is an integer, the current file position will remain unchanged." } ] } ], - "desc": "

      Read data from the file.

      \n

      buffer is the buffer that the data will be written to.

      \n

      offset is the offset in the buffer to start writing at.

      \n

      length is an integer specifying the number of bytes to read.

      \n

      position is an argument specifying where to begin reading from in the file.\nIf position is null, data will be read from the current file position,\nand the file position will be updated.\nIf position is an integer, the file position will remain unchanged.

      \n

      Following successful read, the Promise is resolved with an object with a\nbytesRead property specifying the number of bytes read, and a buffer\nproperty that is a reference to the passed in buffer argument.

      " + "desc": "

      Reads data from the file and stores that in the given buffer.

      \n

      If the file is not modified concurrently, the end-of-file is reached when the\nnumber of bytes read is zero.

      " }, { - "textRaw": "`filehandle.read(options)`", + "textRaw": "`filehandle.read([options])`", "type": "method", "name": "read", "meta": { "added": [ + "v13.11.0", "v12.17.0" ], "changes": [] @@ -294,9 +305,24 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills upon success with an object with two properties:", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills upon success with an object with two properties:", + "options": [ + { + "textRaw": "`bytesRead` {integer} The number of bytes read", + "name": "bytesRead", + "type": "integer", + "desc": "The number of bytes read" + }, + { + "textRaw": "`buffer` {Buffer|TypedArray|DataView} A reference to the passed in `buffer` argument.", + "name": "buffer", + "type": "Buffer|TypedArray|DataView", + "desc": "A reference to the passed in `buffer` argument." + } + ] }, "params": [ { @@ -305,34 +331,39 @@ "type": "Object", "options": [ { - "textRaw": "`buffer` {Buffer|Uint8Array} **Default:** `Buffer.alloc(16384)`", + "textRaw": "`buffer` {Buffer|TypedArray|DataView} A buffer that will be filled with the file data read. **Default:** `Buffer.alloc(16384)`", "name": "buffer", - "type": "Buffer|Uint8Array", - "default": "`Buffer.alloc(16384)`" + "type": "Buffer|TypedArray|DataView", + "default": "`Buffer.alloc(16384)`", + "desc": "A buffer that will be filled with the file data read." }, { - "textRaw": "`offset` {integer} **Default:** `0`", + "textRaw": "`offset` {integer} The location in the buffer at which to start filling. **Default:** `0`", "name": "offset", "type": "integer", - "default": "`0`" + "default": "`0`", + "desc": "The location in the buffer at which to start filling." }, { - "textRaw": "`length` {integer} **Default:** `buffer.length`", + "textRaw": "`length` {integer} The number of bytes to read. **Default:** `buffer.byteLength`", "name": "length", "type": "integer", - "default": "`buffer.length`" + "default": "`buffer.byteLength`", + "desc": "The number of bytes to read." }, { - "textRaw": "`position` {integer} **Default:** `null`", + "textRaw": "`position` {integer} The location where to begin reading data from the file. If `null`, data will be read from the current file position, and the position will be updated. If `position` is an integer, the current file position will remain unchanged. **Default:**: `null`", "name": "position", "type": "integer", - "default": "`null`" + "default": ": `null`", + "desc": "The location where to begin reading data from the file. If `null`, data will be read from the current file position, and the position will be updated. If `position` is an integer, the current file position will remain unchanged." } ] } ] } - ] + ], + "desc": "

      Reads data from the file and stores that in the given buffer.

      \n

      If the file is not modified concurrently, the end-of-file is reached when the\nnumber of bytes read is zero.

      " }, { "textRaw": "`filehandle.readFile(options)`", @@ -347,9 +378,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills upon a successful read with the contents of the file. If no encoding is specified (using `options.encoding`), the data is returned as a {Buffer} object. Otherwise, the data will be a string.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills upon a successful read with the contents of the file. If no encoding is specified (using `options.encoding`), the data is returned as a {Buffer} object. Otherwise, the data will be a string." }, "params": [ { @@ -362,13 +394,19 @@ "name": "encoding", "type": "string|null", "default": "`null`" + }, + { + "textRaw": "`signal` {AbortSignal} allows aborting an in-progress readFile", + "name": "signal", + "type": "AbortSignal", + "desc": "allows aborting an in-progress readFile" } ] } ] } ], - "desc": "

      Asynchronously reads the entire contents of a file.

      \n

      The Promise is resolved with the contents of the file. If no encoding is\nspecified (using options.encoding), the data is returned as a Buffer\nobject. Otherwise, the data will be a string.

      \n

      If options is a string, then it specifies the encoding.

      \n

      The FileHandle has to support reading.

      \n

      If one or more filehandle.read() calls are made on a file handle and then a\nfilehandle.readFile() call is made, the data will be read from the current\nposition till the end of the file. It doesn't always read from the beginning\nof the file.

      " + "desc": "

      Asynchronously reads the entire contents of a file.

      \n

      If options is a string, then it specifies the encoding.

      \n

      The <FileHandle> has to support reading.

      \n

      If one or more filehandle.read() calls are made on a file handle and then a\nfilehandle.readFile() call is made, the data will be read from the current\nposition till the end of the file. It doesn't always read from the beginning\nof the file.

      " }, { "textRaw": "`filehandle.readv(buffers[, position])`", @@ -376,6 +414,7 @@ "name": "readv", "meta": { "added": [ + "v13.13.0", "v12.17.0" ], "changes": [] @@ -383,25 +422,41 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills upon success an object containing two properties:", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills upon success an object containing two properties:", + "options": [ + { + "textRaw": "`bytesRead` {integer} the number of bytes read", + "name": "bytesRead", + "type": "integer", + "desc": "the number of bytes read" + }, + { + "textRaw": "`buffers` {Buffer[]|TypedArray[]|DataView[]} property containing a reference to the `buffers` input.", + "name": "buffers", + "type": "Buffer[]|TypedArray[]|DataView[]", + "desc": "property containing a reference to the `buffers` input." + } + ] }, "params": [ { - "textRaw": "`buffers` {ArrayBufferView[]}", + "textRaw": "`buffers` {Buffer[]|TypedArray[]|DataView[]}", "name": "buffers", - "type": "ArrayBufferView[]" + "type": "Buffer[]|TypedArray[]|DataView[]" }, { - "textRaw": "`position` {integer}", + "textRaw": "`position` {integer} The offset from the beginning of the file where the data should be read from. If `position` is not a `number`, the data will be read from the current position.", "name": "position", - "type": "integer" + "type": "integer", + "desc": "The offset from the beginning of the file where the data should be read from. If `position` is not a `number`, the data will be read from the current position." } ] } ], - "desc": "

      Read from a file and write to an array of ArrayBufferViews

      \n

      The Promise is resolved with an object containing a bytesRead property\nidentifying the number of bytes read, and a buffers property containing\na reference to the buffers input.

      \n

      position is the offset from the beginning of the file where this data\nshould be read from. If typeof position !== 'number', the data will be read\nfrom the current position.

      " + "desc": "

      Read from a file and write to an array of <ArrayBufferView>s

      " }, { "textRaw": "`filehandle.stat([options])`", @@ -422,9 +477,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with an {fs.Stats} for the file.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with an {fs.Stats} for the file." }, "params": [ { @@ -433,18 +489,17 @@ "type": "Object", "options": [ { - "textRaw": "`bigint` {boolean} Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`. **Default:** `false`.", + "textRaw": "`bigint` {boolean} Whether the numeric values in the returned {fs.Stats} object should be `bigint`. **Default:** `false`.", "name": "bigint", "type": "boolean", "default": "`false`", - "desc": "Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`." + "desc": "Whether the numeric values in the returned {fs.Stats} object should be `bigint`." } ] } ] } - ], - "desc": "

      Retrieves the fs.Stats for the file.

      " + ] }, { "textRaw": "`filehandle.sync()`", @@ -459,14 +514,15 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fufills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fufills with `undefined` upon success." }, "params": [] } ], - "desc": "

      Asynchronous fsync(2). The Promise is resolved with no arguments upon\nsuccess.

      " + "desc": "

      Request that all data for the open file descriptor is flushed to the storage\ndevice. The specific implementation is operating system and device specific.\nRefer to the POSIX fsync(2) documentation for more detail.

      " }, { "textRaw": "`filehandle.truncate(len)`", @@ -481,9 +537,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -495,7 +552,7 @@ ] } ], - "desc": "

      Truncates the file then resolves the Promise with no arguments upon success.

      \n

      If the file was larger than len bytes, only the first len bytes will be\nretained in the file.

      \n

      For example, the following program retains only the first four bytes of the\nfile:

      \n
      const fs = require('fs');\nconst fsPromises = fs.promises;\n\nconsole.log(fs.readFileSync('temp.txt', 'utf8'));\n// Prints: Node.js\n\nasync function doTruncate() {\n  let filehandle = null;\n  try {\n    filehandle = await fsPromises.open('temp.txt', 'r+');\n    await filehandle.truncate(4);\n  } finally {\n    if (filehandle) {\n      // Close the file if it is opened.\n      await filehandle.close();\n    }\n  }\n  console.log(fs.readFileSync('temp.txt', 'utf8'));  // Prints: Node\n}\n\ndoTruncate().catch(console.error);\n
      \n

      If the file previously was shorter than len bytes, it is extended, and the\nextended part is filled with null bytes ('\\0'):

      \n
      const fs = require('fs');\nconst fsPromises = fs.promises;\n\nconsole.log(fs.readFileSync('temp.txt', 'utf8'));\n// Prints: Node.js\n\nasync function doTruncate() {\n  let filehandle = null;\n  try {\n    filehandle = await fsPromises.open('temp.txt', 'r+');\n    await filehandle.truncate(10);\n  } finally {\n    if (filehandle) {\n      // Close the file if it is opened.\n      await filehandle.close();\n    }\n  }\n  console.log(fs.readFileSync('temp.txt', 'utf8'));  // Prints Node.js\\0\\0\\0\n}\n\ndoTruncate().catch(console.error);\n
      \n

      The last three bytes are null bytes ('\\0'), to compensate the over-truncation.

      " + "desc": "

      Truncates the file.

      \n

      If the file was larger than len bytes, only the first len bytes will be\nretained in the file.

      \n

      The following example retains only the first four bytes of the file:

      \n
      import { open } from 'fs/promises';\n\nlet filehandle = null;\ntry {\n  filehandle = await open('temp.txt', 'r+');\n  await filehandle.truncate(4);\n} finally {\n  await filehandle?.close();\n}\n
      \n

      If the file previously was shorter than len bytes, it is extended, and the\nextended part is filled with null bytes ('\\0'):

      \n

      If len is negative then 0 will be used.

      " }, { "textRaw": "`filehandle.utimes(atime, mtime)`", @@ -528,7 +585,7 @@ ] } ], - "desc": "

      Change the file system timestamps of the object referenced by the FileHandle\nthen resolves the Promise with no arguments upon success.

      \n

      This function does not work on AIX versions before 7.1, it will resolve the\nPromise with an error using code UV_ENOSYS.

      " + "desc": "

      Change the file system timestamps of the object referenced by the <FileHandle>\nthen resolves the promise with no arguments upon success.

      \n

      This function does not work on AIX versions before 7.1, it will reject the\npromise with an error using code UV_ENOSYS.

      " }, { "textRaw": "`filehandle.write(buffer[, offset[, length[, position]]])`", @@ -538,7 +595,18 @@ "added": [ "v10.0.0" ], - "changes": [] + "changes": [ + { + "version": "v14.12.0", + "pr-url": "https://github.com/nodejs/node/pull/34993", + "description": "The `buffer` parameter will stringify an object with an explicit `toString` function." + }, + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31030", + "description": "The `buffer` parameter won't coerce unsupported input to buffers anymore." + } + ] }, "signatures": [ { @@ -549,29 +617,34 @@ }, "params": [ { - "textRaw": "`buffer` {Buffer|Uint8Array}", + "textRaw": "`buffer` {Buffer|TypedArray|DataView|string|Object}", "name": "buffer", - "type": "Buffer|Uint8Array" + "type": "Buffer|TypedArray|DataView|string|Object" }, { - "textRaw": "`offset` {integer}", + "textRaw": "`offset` {integer} The start position from within `buffer` where the data to write begins. **Default:** `0`", "name": "offset", - "type": "integer" + "type": "integer", + "default": "`0`", + "desc": "The start position from within `buffer` where the data to write begins." }, { - "textRaw": "`length` {integer}", + "textRaw": "`length` {integer} The number of bytes from `buffer` to write. **Default:** `buffer.byteLength`", "name": "length", - "type": "integer" + "type": "integer", + "default": "`buffer.byteLength`", + "desc": "The number of bytes from `buffer` to write." }, { - "textRaw": "`position` {integer}", + "textRaw": "`position` {integer} The offset from the beginning of the file where the data from `buffer` should be written. If `position` is not a `number`, the data will be written at the current position. See the POSIX pwrite(2) documentation for more detail.", "name": "position", - "type": "integer" + "type": "integer", + "desc": "The offset from the beginning of the file where the data from `buffer` should be written. If `position` is not a `number`, the data will be written at the current position. See the POSIX pwrite(2) documentation for more detail." } ] } ], - "desc": "

      Write buffer to the file.

      \n

      The Promise is resolved with an object containing a bytesWritten property\nidentifying the number of bytes written, and a buffer property containing\na reference to the buffer written.

      \n

      offset determines the part of the buffer to be written, and length is\nan integer specifying the number of bytes to write.

      \n

      position refers to the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number', the data will be written\nat the current position. See pwrite(2).

      \n

      It is unsafe to use filehandle.write() multiple times on the same file\nwithout waiting for the Promise to be resolved (or rejected). For this\nscenario, use fs.createWriteStream().

      \n

      On Linux, positional writes do not work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      " + "desc": "

      Write buffer to the file.

      \n

      If buffer is a plain object, it must have an own (not inherited) toString\nfunction property.

      \n

      The promise is resolved with an object containing two properties:

      \n\n

      It is unsafe to use filehandle.write() multiple times on the same file\nwithout waiting for the promise to be resolved (or rejected). For this\nscenario, use fs.createWriteStream().

      \n

      On Linux, positional writes do not work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      " }, { "textRaw": "`filehandle.write(string[, position[, encoding]])`", @@ -581,7 +654,18 @@ "added": [ "v10.0.0" ], - "changes": [] + "changes": [ + { + "version": "v14.12.0", + "pr-url": "https://github.com/nodejs/node/pull/34993", + "description": "The `string` parameter will stringify an object with an explicit `toString` function." + }, + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31030", + "description": "The `string` parameter won't coerce unsupported input to strings anymore." + } + ] }, "signatures": [ { @@ -592,25 +676,27 @@ }, "params": [ { - "textRaw": "`string` {string}", + "textRaw": "`string` {string|Object}", "name": "string", - "type": "string" + "type": "string|Object" }, { - "textRaw": "`position` {integer}", + "textRaw": "`position` {integer} The offset from the beginning of the file where the data from `string` should be written. If `position` is not a `number` the data will be written at the current position. See the POSIX pwrite(2) documentation for more detail.", "name": "position", - "type": "integer" + "type": "integer", + "desc": "The offset from the beginning of the file where the data from `string` should be written. If `position` is not a `number` the data will be written at the current position. See the POSIX pwrite(2) documentation for more detail." }, { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "textRaw": "`encoding` {string} The expected string encoding. **Default:** `'utf8'`", "name": "encoding", "type": "string", - "default": "`'utf8'`" + "default": "`'utf8'`", + "desc": "The expected string encoding." } ] } ], - "desc": "

      Write string to the file. If string is not a string, then\nthe value will be coerced to one.

      \n

      The Promise is resolved with an object containing a bytesWritten property\nidentifying the number of bytes written, and a buffer property containing\na reference to the string written.

      \n

      position refers to the offset from the beginning of the file where this data\nshould be written. If the type of position is not a number the data\nwill be written at the current position. See pwrite(2).

      \n

      encoding is the expected string encoding.

      \n

      It is unsafe to use filehandle.write() multiple times on the same file\nwithout waiting for the Promise to be resolved (or rejected). For this\nscenario, use fs.createWriteStream().

      \n

      On Linux, positional writes do not work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      " + "desc": "

      Write string to the file. If string is not a string, or an object with an\nown toString function property, the promise is rejected with an error.

      \n

      The promise is resolved with an object containing two properties:

      \n\n

      It is unsafe to use filehandle.write() multiple times on the same file\nwithout waiting for the promise to be resolved (or rejected). For this\nscenario, use fs.createWriteStream().

      \n

      On Linux, positional writes do not work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      " }, { "textRaw": "`filehandle.writeFile(data, options)`", @@ -620,7 +706,23 @@ "added": [ "v10.0.0" ], - "changes": [] + "changes": [ + { + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/37490", + "description": "The `data` argument supports `AsyncIterable`, `Iterable` and `Stream`." + }, + { + "version": "v14.12.0", + "pr-url": "https://github.com/nodejs/node/pull/34993", + "description": "The `data` parameter will stringify an object with an explicit `toString` function." + }, + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31030", + "description": "The `data` parameter won't coerce unsupported input to strings anymore." + } + ] }, "signatures": [ { @@ -631,9 +733,9 @@ }, "params": [ { - "textRaw": "`data` {string|Buffer|Uint8Array}", + "textRaw": "`data` {string|Buffer|TypedArray|DataView|Object|AsyncIterable|Iterable |Stream}", "name": "data", - "type": "string|Buffer|Uint8Array" + "type": "string|Buffer|TypedArray|DataView|Object|AsyncIterable|Iterable |Stream" }, { "textRaw": "`options` {Object|string}", @@ -641,17 +743,18 @@ "type": "Object|string", "options": [ { - "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", + "textRaw": "`encoding` {string|null} The expected character encoding when `data` is a string. **Default:** `'utf8'`", "name": "encoding", "type": "string|null", - "default": "`'utf8'`" + "default": "`'utf8'`", + "desc": "The expected character encoding when `data` is a string." } ] } ] } ], - "desc": "

      Asynchronously writes data to a file, replacing the file if it already exists.\ndata can be a string or a buffer. The Promise will be resolved with no\narguments upon success.

      \n

      The encoding option is ignored if data is a buffer.

      \n

      If options is a string, then it specifies the encoding.

      \n

      The FileHandle has to support writing.

      \n

      It is unsafe to use filehandle.writeFile() multiple times on the same file\nwithout waiting for the Promise to be resolved (or rejected).

      \n

      If one or more filehandle.write() calls are made on a file handle and then a\nfilehandle.writeFile() call is made, the data will be written from the\ncurrent position till the end of the file. It doesn't always write from the\nbeginning of the file.

      " + "desc": "

      Asynchronously writes data to a file, replacing the file if it already exists.\ndata can be a string, a buffer, an <AsyncIterable> or <Iterable> object, or an\nobject with an own toString function\nproperty. The promise is resolved with no arguments upon success.

      \n

      If options is a string, then it specifies the encoding.

      \n

      The <FileHandle> has to support writing.

      \n

      It is unsafe to use filehandle.writeFile() multiple times on the same file\nwithout waiting for the promise to be resolved (or rejected).

      \n

      If one or more filehandle.write() calls are made on a file handle and then a\nfilehandle.writeFile() call is made, the data will be written from the\ncurrent position till the end of the file. It doesn't always write from the\nbeginning of the file.

      " }, { "textRaw": "`filehandle.writev(buffers[, position])`", @@ -672,24 +775,25 @@ }, "params": [ { - "textRaw": "`buffers` {ArrayBufferView[]}", + "textRaw": "`buffers` {Buffer[]|TypedArray[]|DataView[]}", "name": "buffers", - "type": "ArrayBufferView[]" + "type": "Buffer[]|TypedArray[]|DataView[]" }, { - "textRaw": "`position` {integer}", + "textRaw": "`position` {integer} The offset from the beginning of the file where the data from `buffers` should be written. If `position` is not a `number`, the data will be written at the current position.", "name": "position", - "type": "integer" + "type": "integer", + "desc": "The offset from the beginning of the file where the data from `buffers` should be written. If `position` is not a `number`, the data will be written at the current position." } ] } ], - "desc": "

      Write an array of ArrayBufferViews to the file.

      \n

      The Promise is resolved with an object containing a bytesWritten property\nidentifying the number of bytes written, and a buffers property containing\na reference to the buffers input.

      \n

      position is the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number', the data will be written\nat the current position.

      \n

      It is unsafe to call writev() multiple times on the same file without waiting\nfor the previous operation to complete.

      \n

      On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      " + "desc": "

      Write an array of <ArrayBufferView>s to the file.

      \n

      The promise is resolved with an object containing a two properties:

      \n\n

      It is unsafe to call writev() multiple times on the same file without waiting\nfor the promise to be resolved (or rejected).

      \n

      On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      " } ], "properties": [ { - "textRaw": "`fd` {number} The numeric file descriptor managed by the `FileHandle` object.", + "textRaw": "`fd` {number} The numeric file descriptor managed by the {FileHandle} object.", "type": "number", "name": "fd", "meta": { @@ -698,7 +802,7 @@ ], "changes": [] }, - "desc": "The numeric file descriptor managed by the `FileHandle` object." + "desc": "The numeric file descriptor managed by the {FileHandle} object." } ] } @@ -717,9 +821,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -736,7 +841,7 @@ ] } ], - "desc": "

      Tests a user's permissions for the file or directory specified by path.\nThe mode argument is an optional integer that specifies the accessibility\nchecks to be performed. Check File access constants for possible values\nof mode. It is possible to create a mask consisting of the bitwise OR of\ntwo or more values (e.g. fs.constants.W_OK | fs.constants.R_OK).

      \n

      If the accessibility check is successful, the Promise is resolved with no\nvalue. If any of the accessibility checks fail, the Promise is rejected\nwith an Error object. The following example checks if the file\n/etc/passwd can be read and written by the current process.

      \n
      const fs = require('fs');\nconst fsPromises = fs.promises;\n\nfsPromises.access('/etc/passwd', fs.constants.R_OK | fs.constants.W_OK)\n  .then(() => console.log('can access'))\n  .catch(() => console.error('cannot access'));\n
      \n

      Using fsPromises.access() to check for the accessibility of a file before\ncalling fsPromises.open() is not recommended. Doing so introduces a race\ncondition, since other processes may change the file's state between the two\ncalls. Instead, user code should open/read/write the file directly and handle\nthe error raised if the file is not accessible.

      " + "desc": "

      Tests a user's permissions for the file or directory specified by path.\nThe mode argument is an optional integer that specifies the accessibility\nchecks to be performed. Check File access constants for possible values\nof mode. It is possible to create a mask consisting of the bitwise OR of\ntwo or more values (e.g. fs.constants.W_OK | fs.constants.R_OK).

      \n

      If the accessibility check is successful, the promise is resolved with no\nvalue. If any of the accessibility checks fail, the promise is rejected\nwith an <Error> object. The following example checks if the file\n/etc/passwd can be read and written by the current process.

      \n
      import { access } from 'fs/promises';\nimport { constants } from 'fs';\n\ntry {\n  await access('/etc/passwd', constants.R_OK | constants.W_OK);\n  console.log('can access');\n} catch {\n  console.error('cannot access');\n}\n
      \n

      Using fsPromises.access() to check for the accessibility of a file before\ncalling fsPromises.open() is not recommended. Doing so introduces a race\ncondition, since other processes may change the file's state between the two\ncalls. Instead, user code should open/read/write the file directly and handle\nthe error raised if the file is not accessible.

      " }, { "textRaw": "`fsPromises.appendFile(path, data[, options])`", @@ -751,16 +856,17 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { - "textRaw": "`path` {string|Buffer|URL|FileHandle} filename or `FileHandle`", + "textRaw": "`path` {string|Buffer|URL|FileHandle} filename or {FileHandle}", "name": "path", "type": "string|Buffer|URL|FileHandle", - "desc": "filename or `FileHandle`" + "desc": "filename or {FileHandle}" }, { "textRaw": "`data` {string|Buffer}", @@ -796,7 +902,7 @@ ] } ], - "desc": "

      Asynchronously append data to a file, creating the file if it does not yet\nexist. data can be a string or a Buffer. The Promise will be\nresolved with no arguments upon success.

      \n

      If options is a string, then it specifies the encoding.

      \n

      The path may be specified as a FileHandle that has been opened\nfor appending (using fsPromises.open()).

      " + "desc": "

      Asynchronously append data to a file, creating the file if it does not yet\nexist. data can be a string or a <Buffer>.

      \n

      If options is a string, then it specifies the encoding.

      \n

      The mode option only affects the newly created file. See fs.open()\nfor more details.

      \n

      The path may be specified as a <FileHandle> that has been opened\nfor appending (using fsPromises.open()).

      " }, { "textRaw": "`fsPromises.chmod(path, mode)`", @@ -811,9 +917,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -829,7 +936,7 @@ ] } ], - "desc": "

      Changes the permissions of a file then resolves the Promise with no\narguments upon succces.

      " + "desc": "

      Changes the permissions of a file.

      " }, { "textRaw": "`fsPromises.chown(path, uid, gid)`", @@ -844,9 +951,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -867,10 +975,10 @@ ] } ], - "desc": "

      Changes the ownership of a file then resolves the Promise with no arguments\nupon success.

      " + "desc": "

      Changes the ownership of a file.

      " }, { - "textRaw": "`fsPromises.copyFile(src, dest[, flags])`", + "textRaw": "`fsPromises.copyFile(src, dest[, mode])`", "type": "method", "name": "copyFile", "meta": { @@ -888,9 +996,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -906,16 +1015,33 @@ "desc": "destination filename of the copy operation" }, { - "textRaw": "`flags` {number} modifiers for copy operation. **Default:** `0`.", - "name": "flags", - "type": "number", + "textRaw": "`mode` {integer} Optional modifiers that specify the behavior of the copy operation. It is possible to create a mask consisting of the bitwise OR of two or more values (e.g. `fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`) **Default:** `0`.", + "name": "mode", + "type": "integer", "default": "`0`", - "desc": "modifiers for copy operation." + "desc": "Optional modifiers that specify the behavior of the copy operation. It is possible to create a mask consisting of the bitwise OR of two or more values (e.g. `fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`)", + "options": [ + { + "textRaw": "`fs.constants.COPYFILE_EXCL`: The copy operation will fail if `dest` already exists.", + "name": "fs.constants.COPYFILE_EXCL", + "desc": "The copy operation will fail if `dest` already exists." + }, + { + "textRaw": "`fs.constants.COPYFILE_FICLONE`: The copy operation will attempt to create a copy-on-write reflink. If the platform does not support copy-on-write, then a fallback copy mechanism is used.", + "name": "fs.constants.COPYFILE_FICLONE", + "desc": "The copy operation will attempt to create a copy-on-write reflink. If the platform does not support copy-on-write, then a fallback copy mechanism is used." + }, + { + "textRaw": "`fs.constants.COPYFILE_FICLONE_FORCE`: The copy operation will attempt to create a copy-on-write reflink. If the platform does not support copy-on-write, then the operation will fail.", + "name": "fs.constants.COPYFILE_FICLONE_FORCE", + "desc": "The copy operation will attempt to create a copy-on-write reflink. If the platform does not support copy-on-write, then the operation will fail." + } + ] } ] } ], - "desc": "

      Asynchronously copies src to dest. By default, dest is overwritten if it\nalready exists. The Promise will be resolved with no arguments upon success.

      \n

      Node.js makes no guarantees about the atomicity of the copy operation. If an\nerror occurs after the destination file has been opened for writing, Node.js\nwill attempt to remove the destination.

      \n

      flags is an optional integer that specifies the behavior\nof the copy operation. It is possible to create a mask consisting of the bitwise\nOR of two or more values (e.g.\nfs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

      \n
        \n
      • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest already\nexists.
      • \n
      • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create a\ncopy-on-write reflink. If the platform does not support copy-on-write, then a\nfallback copy mechanism is used.
      • \n
      • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to\ncreate a copy-on-write reflink. If the platform does not support copy-on-write,\nthen the operation will fail.
      • \n
      \n
      const fsPromises = require('fs').promises;\n\n// destination.txt will be created or overwritten by default.\nfsPromises.copyFile('source.txt', 'destination.txt')\n  .then(() => console.log('source.txt was copied to destination.txt'))\n  .catch(() => console.log('The file could not be copied'));\n
      \n

      If the third argument is a number, then it specifies flags:

      \n
      const fs = require('fs');\nconst fsPromises = fs.promises;\nconst { COPYFILE_EXCL } = fs.constants;\n\n// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.\nfsPromises.copyFile('source.txt', 'destination.txt', COPYFILE_EXCL)\n  .then(() => console.log('source.txt was copied to destination.txt'))\n  .catch(() => console.log('The file could not be copied'));\n
      " + "desc": "

      Asynchronously copies src to dest. By default, dest is overwritten if it\nalready exists.

      \n

      No guarantees are made about the atomicity of the copy operation. If an\nerror occurs after the destination file has been opened for writing, an attempt\nwill be made to remove the destination.

      \n
      import { constants } from 'fs';\nimport { copyFile } from 'fs/promises';\n\ntry {\n  await copyFile('source.txt', 'destination.txt');\n  console.log('source.txt was copied to destination.txt');\n} catch {\n  console.log('The file could not be copied');\n}\n\n// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.\ntry {\n  await copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL);\n  console.log('source.txt was copied to destination.txt');\n} catch {\n  console.log('The file could not be copied');\n}\n
      " }, { "textRaw": "`fsPromises.lchmod(path, mode)`", @@ -930,9 +1056,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -948,7 +1075,7 @@ ] } ], - "desc": "

      Changes the permissions on a symbolic link then resolves the Promise with\nno arguments upon success. This method is only implemented on macOS.

      " + "desc": "

      Changes the permissions on a symbolic link.

      \n

      This method is only implemented on macOS.

      " }, { "textRaw": "`fsPromises.lchown(path, uid, gid)`", @@ -969,9 +1096,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -992,7 +1120,7 @@ ] } ], - "desc": "

      Changes the ownership on a symbolic link then resolves the Promise with\nno arguments upon success.

      " + "desc": "

      Changes the ownership on a symbolic link.

      " }, { "textRaw": "`fsPromises.lutimes(path, atime, mtime)`", @@ -1000,6 +1128,7 @@ "name": "lutimes", "meta": { "added": [ + "v14.5.0", "v12.19.0" ], "changes": [] @@ -1007,9 +1136,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -1030,7 +1160,7 @@ ] } ], - "desc": "

      Changes the access and modification times of a file in the same way as\nfsPromises.utimes(), with the difference that if the path refers to a\nsymbolic link, then the link is not dereferenced: instead, the timestamps of\nthe symbolic link itself are changed.

      \n

      Upon success, the Promise is resolved without arguments.

      " + "desc": "

      Changes the access and modification times of a file in the same way as\nfsPromises.utimes(), with the difference that if the path refers to a\nsymbolic link, then the link is not dereferenced: instead, the timestamps of\nthe symbolic link itself are changed.

      " }, { "textRaw": "`fsPromises.link(existingPath, newPath)`", @@ -1045,9 +1175,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -1063,7 +1194,7 @@ ] } ], - "desc": "

      Asynchronous link(2). The Promise is resolved with no arguments upon success.

      " + "desc": "

      Creates a new link from the existingPath to the newPath. See the POSIX\nlink(2) documentation for more detail.

      " }, { "textRaw": "`fsPromises.lstat(path[, options])`", @@ -1084,9 +1215,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with the {fs.Stats} object for the given symbolic link `path`.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with the {fs.Stats} object for the given symbolic link `path`." }, "params": [ { @@ -1100,18 +1232,18 @@ "type": "Object", "options": [ { - "textRaw": "`bigint` {boolean} Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`. **Default:** `false`.", + "textRaw": "`bigint` {boolean} Whether the numeric values in the returned {fs.Stats} object should be `bigint`. **Default:** `false`.", "name": "bigint", "type": "boolean", "default": "`false`", - "desc": "Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`." + "desc": "Whether the numeric values in the returned {fs.Stats} object should be `bigint`." } ] } ] } ], - "desc": "

      Asynchronous lstat(2). The Promise is resolved with the fs.Stats object\nfor the given symbolic link path.

      " + "desc": "

      Equivalent to fsPromises.stat() unless path refers to a symbolic link,\nin which case the link itself is stat-ed, not the file that it refers to.\nRefer to the POSIX lstat(2) document for more detail.

      " }, { "textRaw": "`fsPromises.mkdir(path[, options])`", @@ -1126,9 +1258,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Upon success, fulfills with `undefined` if `recursive` is `false`, or the first directory path created if `recursive` is `true`.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Upon success, fulfills with `undefined` if `recursive` is `false`, or the first directory path created if `recursive` is `true`." }, "params": [ { @@ -1159,7 +1292,7 @@ ] } ], - "desc": "

      Asynchronously creates a directory then resolves the Promise with either no\narguments, or the first directory path created if recursive is true.

      \n

      The optional options argument can be an integer specifying mode (permission\nand sticky bits), or an object with a mode property and a recursive\nproperty indicating whether parent directories should be created. Calling\nfsPromises.mkdir() when path is a directory that exists results in a\nrejection only when recursive is false.

      " + "desc": "

      Asynchronously creates a directory.

      \n

      The optional options argument can be an integer specifying mode (permission\nand sticky bits), or an object with a mode property and a recursive\nproperty indicating whether parent directories should be created. Calling\nfsPromises.mkdir() when path is a directory that exists results in a\nrejection only when recursive is false.

      " }, { "textRaw": "`fsPromises.mkdtemp(prefix[, options])`", @@ -1169,14 +1302,21 @@ "added": [ "v10.0.0" ], - "changes": [] + "changes": [ + { + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/39028", + "description": "The `prefix` parameter now accepts an empty string." + } + ] }, "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with a string containing the filesystem path of the newly created temporary directory.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with a string containing the filesystem path of the newly created temporary directory." }, "params": [ { @@ -1200,7 +1340,7 @@ ] } ], - "desc": "

      Creates a unique temporary directory and resolves the Promise with the created\ndirectory path. A unique directory name is generated by appending six random\ncharacters to the end of the provided prefix. Due to platform\ninconsistencies, avoid trailing X characters in prefix. Some platforms,\nnotably the BSDs, can return more than six random characters, and replace\ntrailing X characters in prefix with random characters.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use.

      \n
      fsPromises.mkdtemp(path.join(os.tmpdir(), 'foo-'))\n  .catch(console.error);\n
      \n

      The fsPromises.mkdtemp() method will append the six randomly selected\ncharacters directly to the prefix string. For instance, given a directory\n/tmp, if the intention is to create a temporary directory within /tmp, the\nprefix must end with a trailing platform-specific path separator\n(require('path').sep).

      " + "desc": "

      Creates a unique temporary directory. A unique directory name is generated by\nappending six random characters to the end of the provided prefix. Due to\nplatform inconsistencies, avoid trailing X characters in prefix. Some\nplatforms, notably the BSDs, can return more than six random characters, and\nreplace trailing X characters in prefix with random characters.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use.

      \n
      import { mkdtemp } from 'fs/promises';\n\ntry {\n  await mkdtemp(path.join(os.tmpdir(), 'foo-'));\n} catch (err) {\n  console.error(err);\n}\n
      \n

      The fsPromises.mkdtemp() method will append the six randomly selected\ncharacters directly to the prefix string. For instance, given a directory\n/tmp, if the intention is to create a temporary directory within /tmp, the\nprefix must end with a trailing platform-specific path separator\n(require('path').sep).

      " }, { "textRaw": "`fsPromises.open(path, flags[, mode])`", @@ -1221,9 +1361,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with a {FileHandle} object.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with a {FileHandle} object." }, "params": [ { @@ -1239,15 +1380,16 @@ "desc": "See [support of file system `flags`][]." }, { - "textRaw": "`mode` {string|integer} **Default:** `0o666` (readable and writable)", + "textRaw": "`mode` {string|integer} Sets the file mode (permission and sticky bits) if the file is created. **Default:** `0o666` (readable and writable)", "name": "mode", "type": "string|integer", - "default": "`0o666` (readable and writable)" + "default": "`0o666` (readable and writable)", + "desc": "Sets the file mode (permission and sticky bits) if the file is created." } ] } ], - "desc": "

      Asynchronous file open that returns a Promise that, when resolved, yields a\nFileHandle object. See open(2).

      \n

      mode sets the file mode (permission and sticky bits), but only if the file was\ncreated.

      \n

      Some characters (< > : \" / \\ | ? *) are reserved under Windows as documented\nby Naming Files, Paths, and Namespaces. Under NTFS, if the filename contains\na colon, Node.js will open a file system stream, as described by\nthis MSDN page.

      " + "desc": "

      Opens a <FileHandle>.

      \n

      Refer to the POSIX open(2) documentation for more detail.

      \n

      Some characters (< > : \" / \\ | ? *) are reserved under Windows as documented\nby Naming Files, Paths, and Namespaces. Under NTFS, if the filename contains\na colon, Node.js will open a file system stream, as described by\nthis MSDN page.

      " }, { "textRaw": "`fsPromises.opendir(path[, options])`", @@ -1259,7 +1401,10 @@ ], "changes": [ { - "version": "v12.16.0", + "version": [ + "v13.1.0", + "v12.16.0" + ], "pr-url": "https://github.com/nodejs/node/pull/30114", "description": "The `bufferSize` option was introduced." } @@ -1268,10 +1413,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise} containing {fs.Dir}", + "textRaw": "Returns: {Promise} Fulfills with an {fs.Dir}.", "name": "return", "type": "Promise", - "desc": "containing {fs.Dir}" + "desc": "Fulfills with an {fs.Dir}." }, "params": [ { @@ -1302,7 +1447,7 @@ ] } ], - "desc": "

      Asynchronously open a directory. See opendir(3).

      \n

      Creates an fs.Dir, which contains all further functions for reading from\nand cleaning up the directory.

      \n

      The encoding option sets the encoding for the path while opening the\ndirectory and subsequent read operations.

      \n

      Example using async iteration:

      \n
      const fs = require('fs');\n\nasync function print(path) {\n  const dir = await fs.promises.opendir(path);\n  for await (const dirent of dir) {\n    console.log(dirent.name);\n  }\n}\nprint('./').catch(console.error);\n
      " + "desc": "

      Asynchronously open a directory for iterative scanning. See the POSIX\nopendir(3) documentation for more detail.

      \n

      Creates an <fs.Dir>, which contains all further functions for reading from\nand cleaning up the directory.

      \n

      The encoding option sets the encoding for the path while opening the\ndirectory and subsequent read operations.

      \n

      Example using async iteration:

      \n
      import { opendir } from 'fs/promises';\n\ntry {\n  const dir = await opendir('./');\n  for await (const dirent of dir)\n    console.log(dirent.name);\n} catch (err) {\n  console.error(err);\n}\n
      \n

      When using the async iterator, the <fs.Dir> object will be automatically\nclosed after the iterator exits.

      " }, { "textRaw": "`fsPromises.readdir(path[, options])`", @@ -1323,9 +1468,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with an array of the names of the files in the directory excluding `'.'` and `'..'`.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with an array of the names of the files in the directory excluding `'.'` and `'..'`." }, "params": [ { @@ -1355,7 +1501,7 @@ ] } ], - "desc": "

      Reads the contents of a directory then resolves the Promise with an array\nof the names of the files in the directory excluding '.' and '..'.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe filenames. If the encoding is set to 'buffer', the filenames returned\nwill be passed as Buffer objects.

      \n

      If options.withFileTypes is set to true, the resolved array will contain\nfs.Dirent objects.

      \n
      const fs = require('fs');\n\nasync function print(path) {\n  const files = await fs.promises.readdir(path);\n  for (const file of files) {\n    console.log(file);\n  }\n}\nprint('./').catch(console.error);\n
      " + "desc": "

      Reads the contents of a directory.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe filenames. If the encoding is set to 'buffer', the filenames returned\nwill be passed as <Buffer> objects.

      \n

      If options.withFileTypes is set to true, the resolved array will contain\n<fs.Dirent> objects.

      \n
      import { readdir } from 'fs/promises';\n\ntry {\n  const files = await readdir(path);\n  for (const file of files)\n    console.log(file);\n} catch (err) {\n  console.error(err);\n}\n
      " }, { "textRaw": "`fsPromises.readFile(path[, options])`", @@ -1365,14 +1511,21 @@ "added": [ "v10.0.0" ], - "changes": [] + "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/35911", + "description": "The options argument may include an AbortSignal to abort an ongoing readFile request." + } + ] }, "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with the contents of the file.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with the contents of the file." }, "params": [ { @@ -1398,13 +1551,19 @@ "type": "string", "default": "`'r'`", "desc": "See [support of file system `flags`][]." + }, + { + "textRaw": "`signal` {AbortSignal} allows aborting an in-progress readFile", + "name": "signal", + "type": "AbortSignal", + "desc": "allows aborting an in-progress readFile" } ] } ] } ], - "desc": "

      Asynchronously reads the entire contents of a file.

      \n

      The Promise is resolved with the contents of the file. If no encoding is\nspecified (using options.encoding), the data is returned as a Buffer\nobject. Otherwise, the data will be a string.

      \n

      If options is a string, then it specifies the encoding.

      \n

      When the path is a directory, the behavior of fsPromises.readFile() is\nplatform-specific. On macOS, Linux, and Windows, the promise will be rejected\nwith an error. On FreeBSD, a representation of the directory's contents will be\nreturned.

      \n

      Any specified FileHandle has to support reading.

      " + "desc": "

      Asynchronously reads the entire contents of a file.

      \n

      If no encoding is specified (using options.encoding), the data is returned\nas a <Buffer> object. Otherwise, the data will be a string.

      \n

      If options is a string, then it specifies the encoding.

      \n

      When the path is a directory, the behavior of fsPromises.readFile() is\nplatform-specific. On macOS, Linux, and Windows, the promise will be rejected\nwith an error. On FreeBSD, a representation of the directory's contents will be\nreturned.

      \n

      It is possible to abort an ongoing readFile using an <AbortSignal>. If a\nrequest is aborted the promise returned is rejected with an AbortError:

      \n
      import { readFile } from 'fs/promises';\n\ntry {\n  const controller = new AbortController();\n  const { signal } = controller;\n  const promise = readFile(fileName, { signal });\n\n  // Abort the request before the promise settles.\n  controller.abort();\n\n  await promise;\n} catch (err) {\n  // When a request is aborted - err is an AbortError\n  console.error(err);\n}\n
      \n

      Aborting an ongoing request does not abort individual operating\nsystem requests but rather the internal buffering fs.readFile performs.

      \n

      Any specified <FileHandle> has to support reading.

      " }, { "textRaw": "`fsPromises.readlink(path[, options])`", @@ -1419,9 +1578,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with the `linkString` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with the `linkString` upon success." }, "params": [ { @@ -1445,7 +1605,7 @@ ] } ], - "desc": "

      Asynchronous readlink(2). The Promise is resolved with the linkString upon\nsuccess.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe link path returned. If the encoding is set to 'buffer', the link path\nreturned will be passed as a Buffer object.

      " + "desc": "

      Reads the contents of the symbolic link referred to by path. See the POSIX\nreadlink(2) documentation for more detail. The promise is resolved with the\nlinkString upon success.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe link path returned. If the encoding is set to 'buffer', the link path\nreturned will be passed as a <Buffer> object.

      " }, { "textRaw": "`fsPromises.realpath(path[, options])`", @@ -1460,9 +1620,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with the resolved path upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with the resolved path upon success." }, "params": [ { @@ -1486,7 +1647,7 @@ ] } ], - "desc": "

      Determines the actual location of path using the same semantics as the\nfs.realpath.native() function then resolves the Promise with the resolved\npath.

      \n

      Only paths that can be converted to UTF8 strings are supported.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe path. If the encoding is set to 'buffer', the path returned will be\npassed as a Buffer object.

      \n

      On Linux, when Node.js is linked against musl libc, the procfs file system must\nbe mounted on /proc in order for this function to work. Glibc does not have\nthis restriction.

      " + "desc": "

      Determines the actual location of path using the same semantics as the\nfs.realpath.native() function.

      \n

      Only paths that can be converted to UTF8 strings are supported.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe path. If the encoding is set to 'buffer', the path returned will be\npassed as a <Buffer> object.

      \n

      On Linux, when Node.js is linked against musl libc, the procfs file system must\nbe mounted on /proc in order for this function to work. Glibc does not have\nthis restriction.

      " }, { "textRaw": "`fsPromises.rename(oldPath, newPath)`", @@ -1501,9 +1662,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -1519,7 +1681,7 @@ ] } ], - "desc": "

      Renames oldPath to newPath and resolves the Promise with no arguments\nupon success.

      " + "desc": "

      Renames oldPath to newPath.

      " }, { "textRaw": "`fsPromises.rmdir(path[, options])`", @@ -1531,7 +1693,15 @@ ], "changes": [ { - "version": "v12.16.0", + "version": "v14.14.0", + "pr-url": "https://github.com/nodejs/node/pull/35579", + "description": "The `recursive` option is deprecated, use `fsPromises.rm` instead." + }, + { + "version": [ + "v13.3.0", + "v12.16.0" + ], "pr-url": "https://github.com/nodejs/node/pull/30644", "description": "The `maxBusyTries` option is renamed to `maxRetries`, and its default is 0. The `emfileWait` option has been removed, and `EMFILE` errors use the same retry logic as other errors. The `retryDelay` option is now supported. `ENFILE` errors are now retried." }, @@ -1542,14 +1712,13 @@ } ] }, - "stability": 1, - "stabilityText": "Recursive removal is experimental.", "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -1563,11 +1732,11 @@ "type": "Object", "options": [ { - "textRaw": "`maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` ms longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`. **Default:** `0`.", + "textRaw": "`maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js retries the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`. **Default:** `0`.", "name": "maxRetries", "type": "integer", "default": "`0`", - "desc": "If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` ms longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`." + "desc": "If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js retries the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`." }, { "textRaw": "`recursive` {boolean} If `true`, perform a recursive directory removal. In recursive mode, errors are not reported if `path` does not exist, and operations are retried on failure. **Default:** `false`.", @@ -1588,7 +1757,71 @@ ] } ], - "desc": "

      Removes the directory identified by path then resolves the Promise with\nno arguments upon success.

      \n

      Using fsPromises.rmdir() on a file (not a directory) results in the\nPromise being rejected with an ENOENT error on Windows and an ENOTDIR\nerror on POSIX.

      " + "desc": "

      Removes the directory identified by path.

      \n

      Using fsPromises.rmdir() on a file (not a directory) results in the\npromise being rejected with an ENOENT error on Windows and an ENOTDIR\nerror on POSIX.

      \n

      Setting recursive to true results in behavior similar to the Unix command\nrm -rf: an error will not be raised for paths that do not exist, and paths\nthat represent files will be deleted. The permissive behavior of the\nrecursive option is deprecated, ENOTDIR and ENOENT will be thrown in\nthe future.

      " + }, + { + "textRaw": "`fsPromises.rm(path[, options])`", + "type": "method", + "name": "rm", + "meta": { + "added": [ + "v14.14.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", + "name": "return", + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." + }, + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`force` {boolean} When `true`, exceptions will be ignored if `path` does not exist. **Default:** `false`.", + "name": "force", + "type": "boolean", + "default": "`false`", + "desc": "When `true`, exceptions will be ignored if `path` does not exist." + }, + { + "textRaw": "`maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`. **Default:** `0`.", + "name": "maxRetries", + "type": "integer", + "default": "`0`", + "desc": "If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`." + }, + { + "textRaw": "`recursive` {boolean} If `true`, perform a recursive directory removal. In recursive mode operations are retried on failure. **Default:** `false`.", + "name": "recursive", + "type": "boolean", + "default": "`false`", + "desc": "If `true`, perform a recursive directory removal. In recursive mode operations are retried on failure." + }, + { + "textRaw": "`retryDelay` {integer} The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`. **Default:** `100`.", + "name": "retryDelay", + "type": "integer", + "default": "`100`", + "desc": "The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`." + } + ] + } + ] + } + ], + "desc": "

      Removes files and directories (modeled on the standard POSIX rm utility).

      " }, { "textRaw": "`fsPromises.stat(path[, options])`", @@ -1609,9 +1842,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with the {fs.Stats} object for the given `path`.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with the {fs.Stats} object for the given `path`." }, "params": [ { @@ -1625,18 +1859,17 @@ "type": "Object", "options": [ { - "textRaw": "`bigint` {boolean} Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`. **Default:** `false`.", + "textRaw": "`bigint` {boolean} Whether the numeric values in the returned {fs.Stats} object should be `bigint`. **Default:** `false`.", "name": "bigint", "type": "boolean", "default": "`false`", - "desc": "Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`." + "desc": "Whether the numeric values in the returned {fs.Stats} object should be `bigint`." } ] } ] } - ], - "desc": "

      The Promise is resolved with the fs.Stats object for the given path.

      " + ] }, { "textRaw": "`fsPromises.symlink(target, path[, type])`", @@ -1651,9 +1884,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -1675,7 +1909,7 @@ ] } ], - "desc": "

      Creates a symbolic link then resolves the Promise with no arguments upon\nsuccess.

      \n

      The type argument is only used on Windows platforms and can be one of 'dir',\n'file', or 'junction'. Windows junction points require the destination path\nto be absolute. When using 'junction', the target argument will\nautomatically be normalized to absolute path.

      " + "desc": "

      Creates a symbolic link.

      \n

      The type argument is only used on Windows platforms and can be one of 'dir',\n'file', or 'junction'. Windows junction points require the destination path\nto be absolute. When using 'junction', the target argument will\nautomatically be normalized to absolute path.

      " }, { "textRaw": "`fsPromises.truncate(path[, len])`", @@ -1690,9 +1924,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -1709,7 +1944,7 @@ ] } ], - "desc": "

      Truncates the path then resolves the Promise with no arguments upon\nsuccess. The path must be a string or Buffer.

      " + "desc": "

      Truncates (shortens or extends the length) of the content at path to len\nbytes.

      " }, { "textRaw": "`fsPromises.unlink(path)`", @@ -1724,9 +1959,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -1737,7 +1973,7 @@ ] } ], - "desc": "

      Asynchronous unlink(2). The Promise is resolved with no arguments upon\nsuccess.

      " + "desc": "

      If path refers to a symbolic link, then the link is removed without affecting\nthe file or directory to which that link refers. If the path refers to a file\npath that is not a symbolic link, the file is deleted. See the POSIX unlink(2)\ndocumentation for more detail.

      " }, { "textRaw": "`fsPromises.utimes(path, atime, mtime)`", @@ -1752,9 +1988,10 @@ "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -1775,24 +2012,123 @@ ] } ], - "desc": "

      Change the file system timestamps of the object referenced by path then\nresolves the Promise with no arguments upon success.

      \n

      The atime and mtime arguments follow these rules:

      \n
        \n
      • Values can be either numbers representing Unix epoch time, Dates, or a\nnumeric string like '123456789.0'.
      • \n
      • If the value can not be converted to a number, or is NaN, Infinity or\n-Infinity, an Error will be thrown.
      • \n
      " + "desc": "

      Change the file system timestamps of the object referenced by path.

      \n

      The atime and mtime arguments follow these rules:

      \n
        \n
      • Values can be either numbers representing Unix epoch time, Dates, or a\nnumeric string like '123456789.0'.
      • \n
      • If the value can not be converted to a number, or is NaN, Infinity or\n-Infinity, an Error will be thrown.
      • \n
      " }, { - "textRaw": "`fsPromises.writeFile(file, data[, options])`", + "textRaw": "`fsPromises.watch(filename[, options])`", "type": "method", - "name": "writeFile", + "name": "watch", "meta": { "added": [ - "v10.0.0" + "v14.18.0" ], "changes": [] }, "signatures": [ { "return": { - "textRaw": "Returns: {Promise}", + "textRaw": "Returns: {AsyncIterator} of objects with the properties:", + "name": "return", + "type": "AsyncIterator", + "desc": "of objects with the properties:", + "options": [ + { + "textRaw": "`eventType` {string} The type of change", + "name": "eventType", + "type": "string", + "desc": "The type of change" + }, + { + "textRaw": "`filename` {string|Buffer} The name of the file changed.", + "name": "filename", + "type": "string|Buffer", + "desc": "The name of the file changed." + } + ] + }, + "params": [ + { + "textRaw": "`filename` {string|Buffer|URL}", + "name": "filename", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`persistent` {boolean} Indicates whether the process should continue to run as long as files are being watched. **Default:** `true`.", + "name": "persistent", + "type": "boolean", + "default": "`true`", + "desc": "Indicates whether the process should continue to run as long as files are being watched." + }, + { + "textRaw": "`recursive` {boolean} Indicates whether all subdirectories should be watched, or only the current directory. This applies when a directory is specified, and only on supported platforms (See [caveats][]). **Default:** `false`.", + "name": "recursive", + "type": "boolean", + "default": "`false`", + "desc": "Indicates whether all subdirectories should be watched, or only the current directory. This applies when a directory is specified, and only on supported platforms (See [caveats][])." + }, + { + "textRaw": "`encoding` {string} Specifies the character encoding to be used for the filename passed to the listener. **Default:** `'utf8'`.", + "name": "encoding", + "type": "string", + "default": "`'utf8'`", + "desc": "Specifies the character encoding to be used for the filename passed to the listener." + }, + { + "textRaw": "`signal` {AbortSignal} An {AbortSignal} used to signal when the watcher should stop.", + "name": "signal", + "type": "AbortSignal", + "desc": "An {AbortSignal} used to signal when the watcher should stop." + } + ] + } + ] + } + ], + "desc": "

      Returns an async iterator that watches for changes on filename, where filename\nis either a file or a directory.

      \n
      const { watch } = require('fs/promises');\n\nconst ac = new AbortController();\nconst { signal } = ac;\nsetTimeout(() => ac.abort(), 10000);\n\n(async () => {\n  try {\n    const watcher = watch(__filename, { signal });\n    for await (const event of watcher)\n      console.log(event);\n  } catch (err) {\n    if (err.name === 'AbortError')\n      return;\n    throw err;\n  }\n})();\n
      \n

      On most platforms, 'rename' is emitted whenever a filename appears or\ndisappears in the directory.

      \n

      All the caveats for fs.watch() also apply to fsPromises.watch().

      " + }, + { + "textRaw": "`fsPromises.writeFile(file, data[, options])`", + "type": "method", + "name": "writeFile", + "meta": { + "added": [ + "v10.0.0" + ], + "changes": [ + { + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/37490", + "description": "The `data` argument supports `AsyncIterable`, `Iterable` and `Stream`." + }, + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/35993", + "description": "The options argument may include an AbortSignal to abort an ongoing writeFile request." + }, + { + "version": "v14.12.0", + "pr-url": "https://github.com/nodejs/node/pull/34993", + "description": "The `data` parameter will stringify an object with an explicit `toString` function." + }, + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31030", + "description": "The `data` parameter won't coerce unsupported input to strings anymore." + } + ] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {Promise} Fulfills with `undefined` upon success.", "name": "return", - "type": "Promise" + "type": "Promise", + "desc": "Fulfills with `undefined` upon success." }, "params": [ { @@ -1802,9 +2138,9 @@ "desc": "filename or `FileHandle`" }, { - "textRaw": "`data` {string|Buffer|Uint8Array}", + "textRaw": "`data` {string|Buffer|TypedArray|DataView|Object|AsyncIterable|Iterable |Stream}", "name": "data", - "type": "string|Buffer|Uint8Array" + "type": "string|Buffer|TypedArray|DataView|Object|AsyncIterable|Iterable |Stream" }, { "textRaw": "`options` {Object|string}", @@ -1829,118 +2165,64 @@ "type": "string", "default": "`'w'`", "desc": "See [support of file system `flags`][]." + }, + { + "textRaw": "`signal` {AbortSignal} allows aborting an in-progress writeFile", + "name": "signal", + "type": "AbortSignal", + "desc": "allows aborting an in-progress writeFile" } ] } ] } ], - "desc": "

      Asynchronously writes data to a file, replacing the file if it already exists.\ndata can be a string or a buffer. The Promise will be resolved with no\narguments upon success.

      \n

      The encoding option is ignored if data is a buffer.

      \n

      If options is a string, then it specifies the encoding.

      \n

      Any specified FileHandle has to support writing.

      \n

      It is unsafe to use fsPromises.writeFile() multiple times on the same file\nwithout waiting for the Promise to be resolved (or rejected).

      " - } - ], - "type": "module", - "displayName": "`fs` Promises API" - }, - { - "textRaw": "FS constants", - "name": "fs_constants", - "desc": "

      The following constants are exported by fs.constants.

      \n

      Not every constant will be available on every operating system.

      \n

      To use more than one constant, use the bitwise OR | operator.

      \n

      Example:

      \n
      const fs = require('fs');\n\nconst {\n  O_RDWR,\n  O_CREAT,\n  O_EXCL\n} = fs.constants;\n\nfs.open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => {\n  // ...\n});\n
      ", - "modules": [ - { - "textRaw": "File access constants", - "name": "file_access_constants", - "desc": "

      The following constants are meant for use with fs.access().

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      F_OKFlag indicating that the file is visible to the calling process.\n This is useful for determining if a file exists, but says nothing\n about rwx permissions. Default if no mode is specified.
      R_OKFlag indicating that the file can be read by the calling process.
      W_OKFlag indicating that the file can be written by the calling\n process.
      X_OKFlag indicating that the file can be executed by the calling\n process. This has no effect on Windows\n (will behave like fs.constants.F_OK).
      ", - "type": "module", - "displayName": "File access constants" - }, - { - "textRaw": "File copy constants", - "name": "file_copy_constants", - "desc": "

      The following constants are meant for use with fs.copyFile().

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      COPYFILE_EXCLIf present, the copy operation will fail with an error if the\n destination path already exists.
      COPYFILE_FICLONEIf present, the copy operation will attempt to create a\n copy-on-write reflink. If the underlying platform does not support\n copy-on-write, then a fallback copy mechanism is used.
      COPYFILE_FICLONE_FORCEIf present, the copy operation will attempt to create a\n copy-on-write reflink. If the underlying platform does not support\n copy-on-write, then the operation will fail with an error.
      ", - "type": "module", - "displayName": "File copy constants" - }, - { - "textRaw": "File open constants", - "name": "file_open_constants", - "desc": "

      The following constants are meant for use with fs.open().

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      O_RDONLYFlag indicating to open a file for read-only access.
      O_WRONLYFlag indicating to open a file for write-only access.
      O_RDWRFlag indicating to open a file for read-write access.
      O_CREATFlag indicating to create the file if it does not already exist.
      O_EXCLFlag indicating that opening a file should fail if the\n O_CREAT flag is set and the file already exists.
      O_NOCTTYFlag indicating that if path identifies a terminal device, opening the\n path shall not cause that terminal to become the controlling terminal for\n the process (if the process does not already have one).
      O_TRUNCFlag indicating that if the file exists and is a regular file, and the\n file is opened successfully for write access, its length shall be truncated\n to zero.
      O_APPENDFlag indicating that data will be appended to the end of the file.
      O_DIRECTORYFlag indicating that the open should fail if the path is not a\n directory.
      O_NOATIMEFlag indicating reading accesses to the file system will no longer\n result in an update to the atime information associated with\n the file. This flag is available on Linux operating systems only.
      O_NOFOLLOWFlag indicating that the open should fail if the path is a symbolic\n link.
      O_SYNCFlag indicating that the file is opened for synchronized I/O with write\n operations waiting for file integrity.
      O_DSYNCFlag indicating that the file is opened for synchronized I/O with write\n operations waiting for data integrity.
      O_SYMLINKFlag indicating to open the symbolic link itself rather than the\n resource it is pointing to.
      O_DIRECTWhen set, an attempt will be made to minimize caching effects of file\n I/O.
      O_NONBLOCKFlag indicating to open the file in nonblocking mode when possible.
      UV_FS_O_FILEMAPWhen set, a memory file mapping is used to access the file. This flag\n is available on Windows operating systems only. On other operating systems,\n this flag is ignored.
      ", - "type": "module", - "displayName": "File open constants" - }, - { - "textRaw": "File type constants", - "name": "file_type_constants", - "desc": "

      The following constants are meant for use with the fs.Stats object's\nmode property for determining a file's type.

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      S_IFMTBit mask used to extract the file type code.
      S_IFREGFile type constant for a regular file.
      S_IFDIRFile type constant for a directory.
      S_IFCHRFile type constant for a character-oriented device file.
      S_IFBLKFile type constant for a block-oriented device file.
      S_IFIFOFile type constant for a FIFO/pipe.
      S_IFLNKFile type constant for a symbolic link.
      S_IFSOCKFile type constant for a socket.
      ", - "type": "module", - "displayName": "File type constants" - }, - { - "textRaw": "File mode constants", - "name": "file_mode_constants", - "desc": "

      The following constants are meant for use with the fs.Stats object's\nmode property for determining the access permissions for a file.

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      S_IRWXUFile mode indicating readable, writable, and executable by owner.
      S_IRUSRFile mode indicating readable by owner.
      S_IWUSRFile mode indicating writable by owner.
      S_IXUSRFile mode indicating executable by owner.
      S_IRWXGFile mode indicating readable, writable, and executable by group.
      S_IRGRPFile mode indicating readable by group.
      S_IWGRPFile mode indicating writable by group.
      S_IXGRPFile mode indicating executable by group.
      S_IRWXOFile mode indicating readable, writable, and executable by others.
      S_IROTHFile mode indicating readable by others.
      S_IWOTHFile mode indicating writable by others.
      S_IXOTHFile mode indicating executable by others.
      ", - "type": "module", - "displayName": "File mode constants" + "desc": "

      Asynchronously writes data to a file, replacing the file if it already exists.\ndata can be a string, a <Buffer>, or, an object with an own (not inherited)\ntoString function property.

      \n

      The encoding option is ignored if data is a buffer.

      \n

      If options is a string, then it specifies the encoding.

      \n

      The mode option only affects the newly created file. See fs.open()\nfor more details.

      \n

      Any specified <FileHandle> has to support writing.

      \n

      It is unsafe to use fsPromises.writeFile() multiple times on the same file\nwithout waiting for the promise to be settled.

      \n

      Similarly to fsPromises.readFile - fsPromises.writeFile is a convenience\nmethod that performs multiple write calls internally to write the buffer\npassed to it. For performance sensitive code consider using\nfs.createWriteStream().

      \n

      It is possible to use an <AbortSignal> to cancel an fsPromises.writeFile().\nCancelation is \"best effort\", and some amount of data is likely still\nto be written.

      \n
      import { writeFile } from 'fs/promises';\n\ntry {\n  const controller = new AbortController();\n  const { signal } = controller;\n  const data = new Uint8Array(Buffer.from('Hello Node.js'));\n  const promise = writeFile('message.txt', data, { signal });\n\n  // Abort the request before the promise settles.\n  controller.abort();\n\n  await promise;\n} catch (err) {\n  // When a request is aborted - err is an AbortError\n  console.error(err);\n}\n
      \n

      Aborting an ongoing request does not abort individual operating\nsystem requests but rather the internal buffering fs.writeFile performs.

      " } ], "type": "module", - "displayName": "FS constants" + "displayName": "Promises API" }, { - "textRaw": "File system flags", - "name": "file_system_flags", - "desc": "

      The following flags are available wherever the flag option takes a\nstring.

      \n
        \n
      • \n

        'a': Open file for appending.\nThe file is created if it does not exist.

        \n
      • \n
      • \n

        'ax': Like 'a' but fails if the path exists.

        \n
      • \n
      • \n

        'a+': Open file for reading and appending.\nThe file is created if it does not exist.

        \n
      • \n
      • \n

        'ax+': Like 'a+' but fails if the path exists.

        \n
      • \n
      • \n

        'as': Open file for appending in synchronous mode.\nThe file is created if it does not exist.

        \n
      • \n
      • \n

        'as+': Open file for reading and appending in synchronous mode.\nThe file is created if it does not exist.

        \n
      • \n
      • \n

        'r': Open file for reading.\nAn exception occurs if the file does not exist.

        \n
      • \n
      • \n

        'r+': Open file for reading and writing.\nAn exception occurs if the file does not exist.

        \n
      • \n
      • \n

        'rs+': Open file for reading and writing in synchronous mode. Instructs\nthe operating system to bypass the local file system cache.

        \n

        This is primarily useful for opening files on NFS mounts as it allows\nskipping the potentially stale local cache. It has a very real impact on\nI/O performance so using this flag is not recommended unless it is needed.

        \n

        This doesn't turn fs.open() or fsPromises.open() into a synchronous\nblocking call. If synchronous operation is desired, something like\nfs.openSync() should be used.

        \n
      • \n
      • \n

        'w': Open file for writing.\nThe file is created (if it does not exist) or truncated (if it exists).

        \n
      • \n
      • \n

        'wx': Like 'w' but fails if the path exists.

        \n
      • \n
      • \n

        'w+': Open file for reading and writing.\nThe file is created (if it does not exist) or truncated (if it exists).

        \n
      • \n
      • \n

        'wx+': Like 'w+' but fails if the path exists.

        \n
      • \n
      \n

      flag can also be a number as documented by open(2); commonly used constants\nare available from fs.constants. On Windows, flags are translated to\ntheir equivalent ones where applicable, e.g. O_WRONLY to FILE_GENERIC_WRITE,\nor O_EXCL|O_CREAT to CREATE_NEW, as accepted by CreateFileW.

      \n

      The exclusive flag 'x' (O_EXCL flag in open(2)) causes the operation to\nreturn an error if the path already exists. On POSIX, if the path is a symbolic\nlink, using O_EXCL returns an error even if the link is to a path that does\nnot exist. The exclusive flag may or may not work with network file systems.

      \n

      On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      \n

      Modifying a file rather than replacing it may require a flags mode of 'r+'\nrather than the default mode 'w'.

      \n

      The behavior of some flags are platform-specific. As such, opening a directory\non macOS and Linux with the 'a+' flag, as in the example below, will return an\nerror. In contrast, on Windows and FreeBSD, a file descriptor or a FileHandle\nwill be returned.

      \n
      // macOS and Linux\nfs.open('<directory>', 'a+', (err, fd) => {\n  // => [Error: EISDIR: illegal operation on a directory, open <directory>]\n});\n\n// Windows and FreeBSD\nfs.open('<directory>', 'a+', (err, fd) => {\n  // => null, <fd>\n});\n
      \n

      On Windows, opening an existing hidden file using the 'w' flag (either\nthrough fs.open() or fs.writeFile() or fsPromises.open()) will fail with\nEPERM. Existing hidden files can be opened for writing with the 'r+' flag.

      \n

      A call to fs.ftruncate() or filehandle.truncate() can be used to reset\nthe file contents.

      ", - "type": "module", - "displayName": "File system flags" - } - ], - "classes": [ - { - "textRaw": "Class: `fs.Dir`", - "type": "class", - "name": "fs.Dir", - "meta": { - "added": [ - "v12.12.0" - ], - "changes": [] - }, - "desc": "

      A class representing a directory stream.

      \n

      Created by fs.opendir(), fs.opendirSync(), or\nfsPromises.opendir().

      \n
      const fs = require('fs');\n\nasync function print(path) {\n  const dir = await fs.promises.opendir(path);\n  for await (const dirent of dir) {\n    console.log(dirent.name);\n  }\n}\nprint('./').catch(console.error);\n
      ", + "textRaw": "Callback API", + "name": "callback_api", + "desc": "

      The callback APIs perform all operations asynchronously, without blocking the\nevent loop, then invoke a callback function upon completion or error.

      \n

      The callback APIs use the underlying Node.js threadpool to perform file\nsystem operations off the event loop thread. These operations are not\nsynchronized or threadsafe. Care must be taken when performing multiple\nconcurrent modifications on the same file or data corruption may occur.

      ", "methods": [ { - "textRaw": "`dir.close()`", + "textRaw": "`fs.access(path[, mode], callback)`", "type": "method", - "name": "close", + "name": "access", "meta": { "added": [ - "v12.12.0" + "v0.11.15" ], - "changes": [] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {Promise}", - "name": "return", - "type": "Promise" + "changes": [ + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." }, - "params": [] - } - ], - "desc": "

      Asynchronously close the directory's underlying resource handle.\nSubsequent reads will result in errors.

      \n

      A Promise is returned that will be resolved after the resource has been\nclosed.

      " - }, - { - "textRaw": "`dir.close(callback)`", - "type": "method", - "name": "close", - "meta": { - "added": [ - "v12.12.0" - ], - "changes": [] + { + "version": "v6.3.0", + "pr-url": "https://github.com/nodejs/node/pull/6534", + "description": "The constants like `fs.R_OK`, etc which were present directly on `fs` were moved into `fs.constants` as a soft deprecation. Thus for Node.js `< v6.3.0` use `fs` to access those constants, or do something like `(fs.constants || fs).R_OK` to work with all versions." + } + ] }, "signatures": [ { "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`mode` {integer} **Default:** `fs.constants.F_OK`", + "name": "mode", + "type": "integer", + "default": "`fs.constants.F_OK`" + }, { "textRaw": "`callback` {Function}", "name": "callback", @@ -1956,61 +2238,135 @@ ] } ], - "desc": "

      Asynchronously close the directory's underlying resource handle.\nSubsequent reads will result in errors.

      \n

      The callback will be called after the resource handle has been closed.

      " + "desc": "

      Tests a user's permissions for the file or directory specified by path.\nThe mode argument is an optional integer that specifies the accessibility\nchecks to be performed. Check File access constants for possible values\nof mode. It is possible to create a mask consisting of the bitwise OR of\ntwo or more values (e.g. fs.constants.W_OK | fs.constants.R_OK).

      \n

      The final argument, callback, is a callback function that is invoked with\na possible error argument. If any of the accessibility checks fail, the error\nargument will be an Error object. The following examples check if\npackage.json exists, and if it is readable or writable.

      \n
      import { access, constants } from 'fs';\n\nconst file = 'package.json';\n\n// Check if the file exists in the current directory.\naccess(file, constants.F_OK, (err) => {\n  console.log(`${file} ${err ? 'does not exist' : 'exists'}`);\n});\n\n// Check if the file is readable.\naccess(file, constants.R_OK, (err) => {\n  console.log(`${file} ${err ? 'is not readable' : 'is readable'}`);\n});\n\n// Check if the file is writable.\naccess(file, constants.W_OK, (err) => {\n  console.log(`${file} ${err ? 'is not writable' : 'is writable'}`);\n});\n\n// Check if the file exists in the current directory, and if it is writable.\naccess(file, constants.F_OK | constants.W_OK, (err) => {\n  if (err) {\n    console.error(\n      `${file} ${err.code === 'ENOENT' ? 'does not exist' : 'is read-only'}`);\n  } else {\n    console.log(`${file} exists, and it is writable`);\n  }\n});\n
      \n

      Do not use fs.access() to check for the accessibility of a file before calling\nfs.open(), fs.readFile() or fs.writeFile(). Doing\nso introduces a race condition, since other processes may change the file's\nstate between the two calls. Instead, user code should open/read/write the\nfile directly and handle the error raised if the file is not accessible.

      \n

      write (NOT RECOMMENDED)

      \n
      import { access, open, close } from 'fs';\n\naccess('myfile', (err) => {\n  if (!err) {\n    console.error('myfile already exists');\n    return;\n  }\n\n  open('myfile', 'wx', (err, fd) => {\n    if (err) throw err;\n\n    try {\n      writeMyData(fd);\n    } finally {\n      close(fd, (err) => {\n        if (err) throw err;\n      });\n    }\n  });\n});\n
      \n

      write (RECOMMENDED)

      \n
      import { open, close } from 'fs';\n\nopen('myfile', 'wx', (err, fd) => {\n  if (err) {\n    if (err.code === 'EEXIST') {\n      console.error('myfile already exists');\n      return;\n    }\n\n    throw err;\n  }\n\n  try {\n    writeMyData(fd);\n  } finally {\n    close(fd, (err) => {\n      if (err) throw err;\n    });\n  }\n});\n
      \n

      read (NOT RECOMMENDED)

      \n
      import { access, open, close } from 'fs';\naccess('myfile', (err) => {\n  if (err) {\n    if (err.code === 'ENOENT') {\n      console.error('myfile does not exist');\n      return;\n    }\n\n    throw err;\n  }\n\n  open('myfile', 'r', (err, fd) => {\n    if (err) throw err;\n\n    try {\n      readMyData(fd);\n    } finally {\n      close(fd, (err) => {\n        if (err) throw err;\n      });\n    }\n  });\n});\n
      \n

      read (RECOMMENDED)

      \n
      import { open, close } from 'fs';\n\nopen('myfile', 'r', (err, fd) => {\n  if (err) {\n    if (err.code === 'ENOENT') {\n      console.error('myfile does not exist');\n      return;\n    }\n\n    throw err;\n  }\n\n  try {\n    readMyData(fd);\n  } finally {\n    close(fd, (err) => {\n      if (err) throw err;\n    });\n  }\n});\n
      \n

      The \"not recommended\" examples above check for accessibility and then use the\nfile; the \"recommended\" examples are better because they use the file directly\nand handle the error, if any.

      \n

      In general, check for the accessibility of a file only if the file will not be\nused directly, for example when its accessibility is a signal from another\nprocess.

      \n

      On Windows, access-control policies (ACLs) on a directory may limit access to\na file or directory. The fs.access() function, however, does not check the\nACL and therefore may report that a path is accessible even if the ACL restricts\nthe user from reading or writing to it.

      " }, { - "textRaw": "`dir.closeSync()`", + "textRaw": "`fs.appendFile(path, data[, options], callback)`", "type": "method", - "name": "closeSync", + "name": "appendFile", "meta": { "added": [ - "v12.12.0" + "v0.6.7" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7831", + "description": "The passed `options` object will never be modified." + }, + { + "version": "v5.0.0", + "pr-url": "https://github.com/nodejs/node/pull/3163", + "description": "The `file` parameter can be a file descriptor now." + } + ] }, "signatures": [ { - "params": [] + "params": [ + { + "textRaw": "`path` {string|Buffer|URL|number} filename or file descriptor", + "name": "path", + "type": "string|Buffer|URL|number", + "desc": "filename or file descriptor" + }, + { + "textRaw": "`data` {string|Buffer}", + "name": "data", + "type": "string|Buffer" + }, + { + "textRaw": "`options` {Object|string}", + "name": "options", + "type": "Object|string", + "options": [ + { + "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", + "name": "encoding", + "type": "string|null", + "default": "`'utf8'`" + }, + { + "textRaw": "`mode` {integer} **Default:** `0o666`", + "name": "mode", + "type": "integer", + "default": "`0o666`" + }, + { + "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'a'`.", + "name": "flag", + "type": "string", + "default": "`'a'`", + "desc": "See [support of file system `flags`][]." + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      Synchronously close the directory's underlying resource handle.\nSubsequent reads will result in errors.

      " + "desc": "

      Asynchronously append data to a file, creating the file if it does not yet\nexist. data can be a string or a <Buffer>.

      \n

      The mode option only affects the newly created file. See fs.open()\nfor more details.

      \n
      import { appendFile } from 'fs';\n\nappendFile('message.txt', 'data to append', (err) => {\n  if (err) throw err;\n  console.log('The \"data to append\" was appended to file!');\n});\n
      \n

      If options is a string, then it specifies the encoding:

      \n
      import { appendFile } from 'fs';\n\nappendFile('message.txt', 'data to append', 'utf8', callback);\n
      \n

      The path may be specified as a numeric file descriptor that has been opened\nfor appending (using fs.open() or fs.openSync()). The file descriptor will\nnot be closed automatically.

      \n
      import { open, close, appendFile } from 'fs';\n\nfunction closeFd(fd) {\n  close(fd, (err) => {\n    if (err) throw err;\n  });\n}\n\nopen('message.txt', 'a', (err, fd) => {\n  if (err) throw err;\n\n  try {\n    appendFile(fd, 'data to append', 'utf8', (err) => {\n      closeFd(fd);\n      if (err) throw err;\n    });\n  } catch (err) {\n    closeFd(fd);\n    throw err;\n  }\n});\n
      " }, { - "textRaw": "`dir.read()`", + "textRaw": "`fs.chmod(path, mode, callback)`", "type": "method", - "name": "read", + "name": "chmod", "meta": { "added": [ - "v12.12.0" + "v0.1.30" ], - "changes": [] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {Promise} containing {fs.Dirent|null}", - "name": "return", - "type": "Promise", - "desc": "containing {fs.Dirent|null}" + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." }, - "params": [] - } - ], - "desc": "

      Asynchronously read the next directory entry via readdir(3) as an\nfs.Dirent.

      \n

      After the read is completed, a Promise is returned that will be resolved with\nan fs.Dirent, or null if there are no more directory entries to read.

      \n

      Directory entries returned by this function are in no particular order as\nprovided by the operating system's underlying directory mechanisms.\nEntries added or removed while iterating over the directory may or may not be\nincluded in the iteration results.

      " - }, - { - "textRaw": "`dir.read(callback)`", - "type": "method", - "name": "read", - "meta": { - "added": [ - "v12.12.0" - ], - "changes": [] + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`mode` {string|integer}", + "name": "mode", + "type": "string|integer" + }, { "textRaw": "`callback` {Function}", "name": "callback", @@ -2020,6118 +2376,6579 @@ "textRaw": "`err` {Error}", "name": "err", "type": "Error" - }, - { - "textRaw": "`dirent` {fs.Dirent|null}", - "name": "dirent", - "type": "fs.Dirent|null" } ] } ] } ], - "desc": "

      Asynchronously read the next directory entry via readdir(3) as an\nfs.Dirent.

      \n

      After the read is completed, the callback will be called with an\nfs.Dirent, or null if there are no more directory entries to read.

      \n

      Directory entries returned by this function are in no particular order as\nprovided by the operating system's underlying directory mechanisms.\nEntries added or removed while iterating over the directory may or may not be\nincluded in the iteration results.

      " + "desc": "

      Asynchronously changes the permissions of a file. No arguments other than a\npossible exception are given to the completion callback.

      \n

      See the POSIX chmod(2) documentation for more detail.

      \n
      import { chmod } from 'fs';\n\nchmod('my_file.txt', 0o775, (err) => {\n  if (err) throw err;\n  console.log('The permissions for file \"my_file.txt\" have been changed!');\n});\n
      ", + "modules": [ + { + "textRaw": "File modes", + "name": "file_modes", + "desc": "

      The mode argument used in both the fs.chmod() and fs.chmodSync()\nmethods is a numeric bitmask created using a logical OR of the following\nconstants:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      ConstantOctalDescription
      fs.constants.S_IRUSR0o400read by owner
      fs.constants.S_IWUSR0o200write by owner
      fs.constants.S_IXUSR0o100execute/search by owner
      fs.constants.S_IRGRP0o40read by group
      fs.constants.S_IWGRP0o20write by group
      fs.constants.S_IXGRP0o10execute/search by group
      fs.constants.S_IROTH0o4read by others
      fs.constants.S_IWOTH0o2write by others
      fs.constants.S_IXOTH0o1execute/search by others
      \n

      An easier method of constructing the mode is to use a sequence of three\noctal digits (e.g. 765). The left-most digit (7 in the example), specifies\nthe permissions for the file owner. The middle digit (6 in the example),\nspecifies permissions for the group. The right-most digit (5 in the example),\nspecifies the permissions for others.

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      NumberDescription
      7read, write, and execute
      6read and write
      5read and execute
      4read only
      3write and execute
      2write only
      1execute only
      0no permission
      \n

      For example, the octal value 0o765 means:

      \n
        \n
      • The owner may read, write and execute the file.
      • \n
      • The group may read and write the file.
      • \n
      • Others may read and execute the file.
      • \n
      \n

      When using raw numbers where file modes are expected, any value larger than\n0o777 may result in platform-specific behaviors that are not supported to work\nconsistently. Therefore constants like S_ISVTX, S_ISGID or S_ISUID are not\nexposed in fs.constants.

      \n

      Caveats: on Windows only the write permission can be changed, and the\ndistinction among the permissions of group, owner or others is not\nimplemented.

      ", + "type": "module", + "displayName": "File modes" + } + ] }, { - "textRaw": "`dir.readSync()`", + "textRaw": "`fs.chown(path, uid, gid, callback)`", "type": "method", - "name": "readSync", + "name": "chown", "meta": { "added": [ - "v12.12.0" + "v0.1.97" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {fs.Dirent|null}", - "name": "return", - "type": "fs.Dirent|null" - }, - "params": [] - } - ], - "desc": "

      Synchronously read the next directory entry via readdir(3) as an\nfs.Dirent.

      \n

      If there are no more directory entries to read, null will be returned.

      \n

      Directory entries returned by this function are in no particular order as\nprovided by the operating system's underlying directory mechanisms.\nEntries added or removed while iterating over the directory may or may not be\nincluded in the iteration results.

      " - }, - { - "textRaw": "`dir[Symbol.asyncIterator]()`", - "type": "method", - "name": "[Symbol.asyncIterator]", - "meta": { - "added": [ - "v12.12.0" - ], - "changes": [] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {AsyncIterator} of {fs.Dirent}", - "name": "return", - "type": "AsyncIterator", - "desc": "of {fs.Dirent}" - }, - "params": [] - } - ], - "desc": "

      Asynchronously iterates over the directory via readdir(3) until all entries have\nbeen read.

      \n

      Entries returned by the async iterator are always an fs.Dirent.\nThe null case from dir.read() is handled internally.

      \n

      See fs.Dir for an example.

      \n

      Directory entries returned by this iterator are in no particular order as\nprovided by the operating system's underlying directory mechanisms.\nEntries added or removed while iterating over the directory may or may not be\nincluded in the iteration results.

      " - } - ], - "properties": [ - { - "textRaw": "`path` {string}", - "type": "string", - "name": "path", - "meta": { - "added": [ - "v12.12.0" - ], - "changes": [] - }, - "desc": "

      The read-only path of this directory as was provided to fs.opendir(),\nfs.opendirSync(), or fsPromises.opendir().

      " - } - ] - }, - { - "textRaw": "Class: `fs.Dirent`", - "type": "class", - "name": "fs.Dirent", - "meta": { - "added": [ - "v10.10.0" - ], - "changes": [] - }, - "desc": "

      A representation of a directory entry, which can be a file or a subdirectory\nwithin the directory, as returned by reading from an fs.Dir. The\ndirectory entry is a combination of the file name and file type pairs.

      \n

      Additionally, when fs.readdir() or fs.readdirSync() is called with\nthe withFileTypes option set to true, the resulting array is filled with\nfs.Dirent objects, rather than strings or Buffers.

      ", - "methods": [ - { - "textRaw": "`dirent.isBlockDevice()`", - "type": "method", - "name": "isBlockDevice", - "meta": { - "added": [ - "v10.10.0" - ], - "changes": [] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`uid` {integer}", + "name": "uid", + "type": "integer" + }, + { + "textRaw": "`gid` {integer}", + "name": "gid", + "type": "integer" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      Returns true if the fs.Dirent object describes a block device.

      " + "desc": "

      Asynchronously changes owner and group of a file. No arguments other than a\npossible exception are given to the completion callback.

      \n

      See the POSIX chown(2) documentation for more detail.

      " }, { - "textRaw": "`dirent.isCharacterDevice()`", + "textRaw": "`fs.close(fd[, callback])`", "type": "method", - "name": "isCharacterDevice", + "name": "close", "meta": { "added": [ - "v10.10.0" + "v0.0.2" ], - "changes": [] + "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/37174", + "description": "A default callback is now used if one is not provided." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      Returns true if the fs.Dirent object describes a character device.

      " + "desc": "

      Closes the file descriptor. No arguments other than a possible exception are\ngiven to the completion callback.

      \n

      Calling fs.close() on any file descriptor (fd) that is currently in use\nthrough any other fs operation may lead to undefined behavior.

      \n

      See the POSIX close(2) documentation for more detail.

      " }, { - "textRaw": "`dirent.isDirectory()`", + "textRaw": "`fs.copyFile(src, dest[, mode], callback)`", "type": "method", - "name": "isDirectory", + "name": "copyFile", "meta": { "added": [ - "v10.10.0" + "v8.5.0" ], - "changes": [] + "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/27044", + "description": "Changed 'flags' argument to 'mode' and imposed stricter type validation." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] + "params": [ + { + "textRaw": "`src` {string|Buffer|URL} source filename to copy", + "name": "src", + "type": "string|Buffer|URL", + "desc": "source filename to copy" + }, + { + "textRaw": "`dest` {string|Buffer|URL} destination filename of the copy operation", + "name": "dest", + "type": "string|Buffer|URL", + "desc": "destination filename of the copy operation" + }, + { + "textRaw": "`mode` {integer} modifiers for copy operation. **Default:** `0`.", + "name": "mode", + "type": "integer", + "default": "`0`", + "desc": "modifiers for copy operation." + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function" + } + ] } ], - "desc": "

      Returns true if the fs.Dirent object describes a file system\ndirectory.

      " + "desc": "

      Asynchronously copies src to dest. By default, dest is overwritten if it\nalready exists. No arguments other than a possible exception are given to the\ncallback function. Node.js makes no guarantees about the atomicity of the copy\noperation. If an error occurs after the destination file has been opened for\nwriting, Node.js will attempt to remove the destination.

      \n

      mode is an optional integer that specifies the behavior\nof the copy operation. It is possible to create a mask consisting of the bitwise\nOR of two or more values (e.g.\nfs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

      \n
        \n
      • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest already\nexists.
      • \n
      • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create a\ncopy-on-write reflink. If the platform does not support copy-on-write, then a\nfallback copy mechanism is used.
      • \n
      • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to\ncreate a copy-on-write reflink. If the platform does not support\ncopy-on-write, then the operation will fail.
      • \n
      \n
      import { copyFile, constants } from 'fs';\n\nfunction callback(err) {\n  if (err) throw err;\n  console.log('source.txt was copied to destination.txt');\n}\n\n// destination.txt will be created or overwritten by default.\ncopyFile('source.txt', 'destination.txt', callback);\n\n// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.\ncopyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL, callback);\n
      " }, { - "textRaw": "`dirent.isFIFO()`", + "textRaw": "`fs.createReadStream(path[, options])`", "type": "method", - "name": "isFIFO", + "name": "createReadStream", "meta": { "added": [ - "v10.10.0" + "v0.1.31" ], - "changes": [] + "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31408", + "description": "Change `emitClose` default to `true`." + }, + { + "version": [ + "v13.6.0", + "v12.17.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/29083", + "description": "The `fs` options allow overriding the used `fs` implementation." + }, + { + "version": "v12.10.0", + "pr-url": "https://github.com/nodejs/node/pull/29212", + "description": "Enable `emitClose` option." + }, + { + "version": "v11.0.0", + "pr-url": "https://github.com/nodejs/node/pull/19898", + "description": "Impose new restrictions on `start` and `end`, throwing more appropriate errors in cases when we cannot reasonably handle the input values." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7831", + "description": "The passed `options` object will never be modified." + }, + { + "version": "v2.3.0", + "pr-url": "https://github.com/nodejs/node/pull/1845", + "description": "The passed `options` object can be a string now." + } + ] }, "signatures": [ { "return": { - "textRaw": "Returns: {boolean}", + "textRaw": "Returns: {fs.ReadStream} See [Readable Stream][].", "name": "return", - "type": "boolean" + "type": "fs.ReadStream", + "desc": "See [Readable Stream][]." }, - "params": [] + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`flags` {string} See [support of file system `flags`][]. **Default:** `'r'`.", + "name": "flags", + "type": "string", + "default": "`'r'`", + "desc": "See [support of file system `flags`][]." + }, + { + "textRaw": "`encoding` {string} **Default:** `null`", + "name": "encoding", + "type": "string", + "default": "`null`" + }, + { + "textRaw": "`fd` {integer} **Default:** `null`", + "name": "fd", + "type": "integer", + "default": "`null`" + }, + { + "textRaw": "`mode` {integer} **Default:** `0o666`", + "name": "mode", + "type": "integer", + "default": "`0o666`" + }, + { + "textRaw": "`autoClose` {boolean} **Default:** `true`", + "name": "autoClose", + "type": "boolean", + "default": "`true`" + }, + { + "textRaw": "`emitClose` {boolean} **Default:** `true`", + "name": "emitClose", + "type": "boolean", + "default": "`true`" + }, + { + "textRaw": "`start` {integer}", + "name": "start", + "type": "integer" + }, + { + "textRaw": "`end` {integer} **Default:** `Infinity`", + "name": "end", + "type": "integer", + "default": "`Infinity`" + }, + { + "textRaw": "`highWaterMark` {integer} **Default:** `64 * 1024`", + "name": "highWaterMark", + "type": "integer", + "default": "`64 * 1024`" + }, + { + "textRaw": "`fs` {Object|null} **Default:** `null`", + "name": "fs", + "type": "Object|null", + "default": "`null`" + } + ] + } + ] } ], - "desc": "

      Returns true if the fs.Dirent object describes a first-in-first-out\n(FIFO) pipe.

      " + "desc": "

      Unlike the 16 kb default highWaterMark for a readable stream, the stream\nreturned by this method has a default highWaterMark of 64 kb.

      \n

      options can include start and end values to read a range of bytes from\nthe file instead of the entire file. Both start and end are inclusive and\nstart counting at 0, allowed values are in the\n[0, Number.MAX_SAFE_INTEGER] range. If fd is specified and start is\nomitted or undefined, fs.createReadStream() reads sequentially from the\ncurrent file position. The encoding can be any one of those accepted by\n<Buffer>.

      \n

      If fd is specified, ReadStream will ignore the path argument and will use\nthe specified file descriptor. This means that no 'open' event will be\nemitted. fd should be blocking; non-blocking fds should be passed to\n<net.Socket>.

      \n

      If fd points to a character device that only supports blocking reads\n(such as keyboard or sound card), read operations do not finish until data is\navailable. This can prevent the process from exiting and the stream from\nclosing naturally.

      \n

      By default, the stream will emit a 'close' event after it has been\ndestroyed, like most Readable streams. Set the emitClose option to\nfalse to change this behavior.

      \n

      By providing the fs option, it is possible to override the corresponding fs\nimplementations for open, read, and close. When providing the fs option,\noverrides for open, read, and close are required.

      \n
      import { createReadStream } from 'fs';\n\n// Create a stream from some character device.\nconst stream = createReadStream('/dev/input/event0');\nsetTimeout(() => {\n  stream.close(); // This may not close the stream.\n  // Artificially marking end-of-stream, as if the underlying resource had\n  // indicated end-of-file by itself, allows the stream to close.\n  // This does not cancel pending read operations, and if there is such an\n  // operation, the process may still not be able to exit successfully\n  // until it finishes.\n  stream.push(null);\n  stream.read(0);\n}, 100);\n
      \n

      If autoClose is false, then the file descriptor won't be closed, even if\nthere's an error. It is the application's responsibility to close it and make\nsure there's no file descriptor leak. If autoClose is set to true (default\nbehavior), on 'error' or 'end' the file descriptor will be closed\nautomatically.

      \n

      mode sets the file mode (permission and sticky bits), but only if the\nfile was created.

      \n

      An example to read the last 10 bytes of a file which is 100 bytes long:

      \n
      import { createReadStream } from 'fs';\n\ncreateReadStream('sample.txt', { start: 90, end: 99 });\n
      \n

      If options is a string, then it specifies the encoding.

      " }, { - "textRaw": "`dirent.isFile()`", + "textRaw": "`fs.createWriteStream(path[, options])`", "type": "method", - "name": "isFile", + "name": "createWriteStream", "meta": { "added": [ - "v10.10.0" + "v0.1.31" ], - "changes": [] + "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31408", + "description": "Change `emitClose` default to `true`." + }, + { + "version": [ + "v13.6.0", + "v12.17.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/29083", + "description": "The `fs` options allow overriding the used `fs` implementation." + }, + { + "version": "v12.10.0", + "pr-url": "https://github.com/nodejs/node/pull/29212", + "description": "Enable `emitClose` option." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7831", + "description": "The passed `options` object will never be modified." + }, + { + "version": "v5.5.0", + "pr-url": "https://github.com/nodejs/node/pull/3679", + "description": "The `autoClose` option is supported now." + }, + { + "version": "v2.3.0", + "pr-url": "https://github.com/nodejs/node/pull/1845", + "description": "The passed `options` object can be a string now." + } + ] }, "signatures": [ { "return": { - "textRaw": "Returns: {boolean}", + "textRaw": "Returns: {fs.WriteStream} See [Writable Stream][].", "name": "return", - "type": "boolean" + "type": "fs.WriteStream", + "desc": "See [Writable Stream][]." }, - "params": [] - } - ], - "desc": "

      Returns true if the fs.Dirent object describes a regular file.

      " - }, - { - "textRaw": "`dirent.isSocket()`", - "type": "method", - "name": "isSocket", - "meta": { - "added": [ - "v10.10.0" - ], - "changes": [] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`flags` {string} See [support of file system `flags`][]. **Default:** `'w'`.", + "name": "flags", + "type": "string", + "default": "`'w'`", + "desc": "See [support of file system `flags`][]." + }, + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + }, + { + "textRaw": "`fd` {integer} **Default:** `null`", + "name": "fd", + "type": "integer", + "default": "`null`" + }, + { + "textRaw": "`mode` {integer} **Default:** `0o666`", + "name": "mode", + "type": "integer", + "default": "`0o666`" + }, + { + "textRaw": "`autoClose` {boolean} **Default:** `true`", + "name": "autoClose", + "type": "boolean", + "default": "`true`" + }, + { + "textRaw": "`emitClose` {boolean} **Default:** `true`", + "name": "emitClose", + "type": "boolean", + "default": "`true`" + }, + { + "textRaw": "`start` {integer}", + "name": "start", + "type": "integer" + }, + { + "textRaw": "`fs` {Object|null} **Default:** `null`", + "name": "fs", + "type": "Object|null", + "default": "`null`" + } + ] + } + ] } ], - "desc": "

      Returns true if the fs.Dirent object describes a socket.

      " + "desc": "

      options may also include a start option to allow writing data at some\nposition past the beginning of the file, allowed values are in the\n[0, Number.MAX_SAFE_INTEGER] range. Modifying a file rather than replacing\nit may require the flags option to be set to r+ rather than the default w.\nThe encoding can be any one of those accepted by <Buffer>.

      \n

      If autoClose is set to true (default behavior) on 'error' or 'finish'\nthe file descriptor will be closed automatically. If autoClose is false,\nthen the file descriptor won't be closed, even if there's an error.\nIt is the application's responsibility to close it and make sure there's no\nfile descriptor leak.

      \n

      By default, the stream will emit a 'close' event after it has been\ndestroyed, like most Writable streams. Set the emitClose option to\nfalse to change this behavior.

      \n

      By providing the fs option it is possible to override the corresponding fs\nimplementations for open, write, writev and close. Overriding write()\nwithout writev() can reduce performance as some optimizations (_writev())\nwill be disabled. When providing the fs option, overrides for open,\nclose, and at least one of write and writev are required.

      \n

      Like <fs.ReadStream>, if fd is specified, <fs.WriteStream> will ignore the\npath argument and will use the specified file descriptor. This means that no\n'open' event will be emitted. fd should be blocking; non-blocking fds\nshould be passed to <net.Socket>.

      \n

      If options is a string, then it specifies the encoding.

      " }, { - "textRaw": "`dirent.isSymbolicLink()`", + "textRaw": "`fs.exists(path, callback)`", "type": "method", - "name": "isSymbolicLink", - "meta": { - "added": [ - "v10.10.0" - ], - "changes": [] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] - } - ], - "desc": "

      Returns true if the fs.Dirent object describes a symbolic link.

      " - } - ], - "properties": [ - { - "textRaw": "`name` {string|Buffer}", - "type": "string|Buffer", - "name": "name", + "name": "exists", "meta": { "added": [ - "v10.10.0" + "v0.0.2" ], - "changes": [] - }, - "desc": "

      The file name that this fs.Dirent object refers to. The type of this\nvalue is determined by the options.encoding passed to fs.readdir() or\nfs.readdirSync().

      " - } - ] - }, - { - "textRaw": "Class: `fs.FSWatcher`", - "type": "class", - "name": "fs.FSWatcher", - "meta": { - "added": [ - "v0.5.8" - ], - "changes": [] - }, - "desc": "\n

      A successful call to fs.watch() method will return a new fs.FSWatcher\nobject.

      \n

      All fs.FSWatcher objects emit a 'change' event whenever a specific watched\nfile is modified.

      ", - "events": [ - { - "textRaw": "Event: `'change'`", - "type": "event", - "name": "change", - "meta": { - "added": [ - "v0.5.8" + "deprecated": [ + "v1.0.0" ], - "changes": [] + "changes": [ + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] }, - "params": [ - { - "textRaw": "`eventType` {string} The type of change event that has occurred", - "name": "eventType", - "type": "string", - "desc": "The type of change event that has occurred" - }, + "stability": 0, + "stabilityText": "Deprecated: Use [`fs.stat()`][] or [`fs.access()`][] instead.", + "signatures": [ { - "textRaw": "`filename` {string|Buffer} The filename that changed (if relevant/available)", - "name": "filename", - "type": "string|Buffer", - "desc": "The filename that changed (if relevant/available)" + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`exists` {boolean}", + "name": "exists", + "type": "boolean" + } + ] + } + ] } ], - "desc": "

      Emitted when something changes in a watched directory or file.\nSee more details in fs.watch().

      \n

      The filename argument may not be provided depending on operating system\nsupport. If filename is provided, it will be provided as a Buffer if\nfs.watch() is called with its encoding option set to 'buffer', otherwise\nfilename will be a UTF-8 string.

      \n
      // Example when handled through fs.watch() listener\nfs.watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {\n  if (filename) {\n    console.log(filename);\n    // Prints: <Buffer ...>\n  }\n});\n
      " - }, - { - "textRaw": "Event: `'close'`", - "type": "event", - "name": "close", - "meta": { - "added": [ - "v10.0.0" - ], - "changes": [] - }, - "params": [], - "desc": "

      Emitted when the watcher stops watching for changes. The closed\nfs.FSWatcher object is no longer usable in the event handler.

      " + "desc": "

      Test whether or not the given path exists by checking with the file system.\nThen call the callback argument with either true or false:

      \n
      import { exists } from 'fs';\n\nexists('/etc/passwd', (e) => {\n  console.log(e ? 'it exists' : 'no passwd!');\n});\n
      \n

      The parameters for this callback are not consistent with other Node.js\ncallbacks. Normally, the first parameter to a Node.js callback is an err\nparameter, optionally followed by other parameters. The fs.exists() callback\nhas only one boolean parameter. This is one reason fs.access() is recommended\ninstead of fs.exists().

      \n

      Using fs.exists() to check for the existence of a file before calling\nfs.open(), fs.readFile() or fs.writeFile() is not recommended. Doing\nso introduces a race condition, since other processes may change the file's\nstate between the two calls. Instead, user code should open/read/write the\nfile directly and handle the error raised if the file does not exist.

      \n

      write (NOT RECOMMENDED)

      \n
      import { exists, open, close } from 'fs';\n\nexists('myfile', (e) => {\n  if (e) {\n    console.error('myfile already exists');\n  } else {\n    open('myfile', 'wx', (err, fd) => {\n      if (err) throw err;\n\n      try {\n        writeMyData(fd);\n      } finally {\n        close(fd, (err) => {\n          if (err) throw err;\n        });\n      }\n    });\n  }\n});\n
      \n

      write (RECOMMENDED)

      \n
      import { open, close } from 'fs';\nopen('myfile', 'wx', (err, fd) => {\n  if (err) {\n    if (err.code === 'EEXIST') {\n      console.error('myfile already exists');\n      return;\n    }\n\n    throw err;\n  }\n\n  try {\n    writeMyData(fd);\n  } finally {\n    close(fd, (err) => {\n      if (err) throw err;\n    });\n  }\n});\n
      \n

      read (NOT RECOMMENDED)

      \n
      import { open, close, exists } from 'fs';\n\nexists('myfile', (e) => {\n  if (e) {\n    open('myfile', 'r', (err, fd) => {\n      if (err) throw err;\n\n      try {\n        readMyData(fd);\n      } finally {\n        close(fd, (err) => {\n          if (err) throw err;\n        });\n      }\n    });\n  } else {\n    console.error('myfile does not exist');\n  }\n});\n
      \n

      read (RECOMMENDED)

      \n
      import { open, close } from 'fs';\n\nopen('myfile', 'r', (err, fd) => {\n  if (err) {\n    if (err.code === 'ENOENT') {\n      console.error('myfile does not exist');\n      return;\n    }\n\n    throw err;\n  }\n\n  try {\n    readMyData(fd);\n  } finally {\n    close(fd, (err) => {\n      if (err) throw err;\n    });\n  }\n});\n
      \n

      The \"not recommended\" examples above check for existence and then use the\nfile; the \"recommended\" examples are better because they use the file directly\nand handle the error, if any.

      \n

      In general, check for the existence of a file only if the file won’t be\nused directly, for example when its existence is a signal from another\nprocess.

      " }, { - "textRaw": "Event: `'error'`", - "type": "event", - "name": "error", + "textRaw": "`fs.fchmod(fd, mode, callback)`", + "type": "method", + "name": "fchmod", "meta": { "added": [ - "v0.5.8" + "v0.4.7" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, - "params": [ + "signatures": [ { - "textRaw": "`error` {Error}", - "name": "error", - "type": "Error" + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`mode` {string|integer}", + "name": "mode", + "type": "string|integer" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      Emitted when an error occurs while watching the file. The errored\nfs.FSWatcher object is no longer usable in the event handler.

      " - } - ], - "methods": [ + "desc": "

      Sets the permissions on the file. No arguments other than a possible exception\nare given to the completion callback.

      \n

      See the POSIX fchmod(2) documentation for more detail.

      " + }, { - "textRaw": "`watcher.close()`", + "textRaw": "`fs.fchown(fd, uid, gid, callback)`", "type": "method", - "name": "close", + "name": "fchown", "meta": { "added": [ - "v0.5.8" + "v0.4.7" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { - "params": [] + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`uid` {integer}", + "name": "uid", + "type": "integer" + }, + { + "textRaw": "`gid` {integer}", + "name": "gid", + "type": "integer" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      Stop watching for changes on the given fs.FSWatcher. Once stopped, the\nfs.FSWatcher object is no longer usable.

      " + "desc": "

      Sets the owner of the file. No arguments other than a possible exception are\ngiven to the completion callback.

      \n

      See the POSIX fchown(2) documentation for more detail.

      " }, { - "textRaw": "`watcher.ref()`", + "textRaw": "`fs.fdatasync(fd, callback)`", "type": "method", - "name": "ref", + "name": "fdatasync", "meta": { "added": [ - "v12.20.0" + "v0.1.96" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {fs.FSWatcher}", - "name": "return", - "type": "fs.FSWatcher" - }, - "params": [] + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      When called, requests that the Node.js event loop not exit so long as the\nFSWatcher is active. Calling watcher.ref() multiple times will have\nno effect.

      \n

      By default, all FSWatcher objects are \"ref'ed\", making it normally\nunnecessary to call watcher.ref() unless watcher.unref() had been\ncalled previously.

      " + "desc": "

      Forces all currently queued I/O operations associated with the file to the\noperating system's synchronized I/O completion state. Refer to the POSIX\nfdatasync(2) documentation for details. No arguments other than a possible\nexception are given to the completion callback.

      " }, { - "textRaw": "`watcher.unref()`", + "textRaw": "`fs.fstat(fd[, options], callback)`", "type": "method", - "name": "unref", + "name": "fstat", "meta": { "added": [ - "v12.20.0" + "v0.1.95" ], - "changes": [] + "changes": [ + { + "version": "v10.5.0", + "pr-url": "https://github.com/nodejs/node/pull/20220", + "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {fs.FSWatcher}", - "name": "return", - "type": "fs.FSWatcher" - }, - "params": [] - } + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`bigint` {boolean} Whether the numeric values in the returned {fs.Stats} object should be `bigint`. **Default:** `false`.", + "name": "bigint", + "type": "boolean", + "default": "`false`", + "desc": "Whether the numeric values in the returned {fs.Stats} object should be `bigint`." + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`stats` {fs.Stats}", + "name": "stats", + "type": "fs.Stats" + } + ] + } + ] + } ], - "desc": "

      When called, the active FSWatcher object will not require the Node.js\nevent loop to remain active. If there is no other activity keeping the\nevent loop running, the process may exit before the FSWatcher object's\ncallback is invoked. Calling watcher.unref() multiple times will have\nno effect.

      " - } - ] - }, - { - "textRaw": "Class: `fs.StatWatcher`", - "type": "class", - "name": "fs.StatWatcher", - "meta": { - "added": [ - "v12.20.0" - ], - "changes": [] - }, - "desc": "\n

      A successful call to fs.watchFile() method will return a new fs.StatWatcher\nobject.

      ", - "methods": [ + "desc": "

      Invokes the callback with the <fs.Stats> for the file descriptor.

      \n

      See the POSIX fstat(2) documentation for more detail.

      " + }, { - "textRaw": "`watcher.ref()`", + "textRaw": "`fs.fsync(fd, callback)`", "type": "method", - "name": "ref", + "name": "fsync", "meta": { "added": [ - "v12.20.0" + "v0.1.96" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {fs.StatWatcher}", - "name": "return", - "type": "fs.StatWatcher" - }, - "params": [] + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      When called, requests that the Node.js event loop not exit so long as the\nStatWatcher is active. Calling watcher.ref() multiple times will have\nno effect.

      \n

      By default, all StatWatcher objects are \"ref'ed\", making it normally\nunnecessary to call watcher.ref() unless watcher.unref() had been\ncalled previously.

      " + "desc": "

      Request that all data for the open file descriptor is flushed to the storage\ndevice. The specific implementation is operating system and device specific.\nRefer to the POSIX fsync(2) documentation for more detail. No arguments other\nthan a possible exception are given to the completion callback.

      " }, { - "textRaw": "`watcher.unref()`", + "textRaw": "`fs.ftruncate(fd[, len], callback)`", "type": "method", - "name": "unref", + "name": "ftruncate", "meta": { "added": [ - "v12.20.0" + "v0.8.6" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {fs.StatWatcher}", - "name": "return", - "type": "fs.StatWatcher" - }, - "params": [] + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`len` {integer} **Default:** `0`", + "name": "len", + "type": "integer", + "default": "`0`" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      When called, the active StatWatcher object will not require the Node.js\nevent loop to remain active. If there is no other activity keeping the\nevent loop running, the process may exit before the StatWatcher object's\ncallback is invoked. Calling watcher.unref() multiple times will have\nno effect.

      " - } - ] - }, - { - "textRaw": "Class: `fs.ReadStream`", - "type": "class", - "name": "fs.ReadStream", - "meta": { - "added": [ - "v0.1.93" - ], - "changes": [] - }, - "desc": "\n

      Instances of fs.ReadStream are created and returned using the\nfs.createReadStream() function.

      ", - "events": [ - { - "textRaw": "Event: `'close'`", - "type": "event", - "name": "close", - "meta": { - "added": [ - "v0.1.93" - ], - "changes": [] - }, - "params": [], - "desc": "

      Emitted when the fs.ReadStream's underlying file descriptor has been closed.

      " + "desc": "

      Truncates the file descriptor. No arguments other than a possible exception are\ngiven to the completion callback.

      \n

      See the POSIX ftruncate(2) documentation for more detail.

      \n

      If the file referred to by the file descriptor was larger than len bytes, only\nthe first len bytes will be retained in the file.

      \n

      For example, the following program retains only the first four bytes of the\nfile:

      \n
      import { open, close, ftruncate } from 'fs';\n\nfunction closeFd(fd) {\n  close(fd, (err) => {\n    if (err) throw err;\n  });\n}\n\nopen('temp.txt', 'r+', (err, fd) => {\n  if (err) throw err;\n\n  try {\n    ftruncate(fd, 4, (err) => {\n      closeFd(fd);\n      if (err) throw err;\n    });\n  } catch (err) {\n    closeFd(fd);\n    if (err) throw err;\n  }\n});\n
      \n

      If the file previously was shorter than len bytes, it is extended, and the\nextended part is filled with null bytes ('\\0'):

      \n

      If len is negative then 0 will be used.

      " }, { - "textRaw": "Event: `'open'`", - "type": "event", - "name": "open", + "textRaw": "`fs.futimes(fd, atime, mtime, callback)`", + "type": "method", + "name": "futimes", "meta": { "added": [ - "v0.1.93" + "v0.4.2" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + }, + { + "version": "v4.1.0", + "pr-url": "https://github.com/nodejs/node/pull/2387", + "description": "Numeric strings, `NaN` and `Infinity` are now allowed time specifiers." + } + ] }, - "params": [ + "signatures": [ { - "textRaw": "`fd` {integer} Integer file descriptor used by the `ReadStream`.", - "name": "fd", - "type": "integer", - "desc": "Integer file descriptor used by the `ReadStream`." + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`atime` {number|string|Date}", + "name": "atime", + "type": "number|string|Date" + }, + { + "textRaw": "`mtime` {number|string|Date}", + "name": "mtime", + "type": "number|string|Date" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      Emitted when the fs.ReadStream's file descriptor has been opened.

      " - }, - { - "textRaw": "Event: `'ready'`", - "type": "event", - "name": "ready", - "meta": { - "added": [ - "v9.11.0" - ], - "changes": [] - }, - "params": [], - "desc": "

      Emitted when the fs.ReadStream is ready to be used.

      \n

      Fires immediately after 'open'.

      " - } - ], - "properties": [ - { - "textRaw": "`bytesRead` {number}", - "type": "number", - "name": "bytesRead", - "meta": { - "added": [ - "v6.4.0" - ], - "changes": [] - }, - "desc": "

      The number of bytes that have been read so far.

      " - }, - { - "textRaw": "`path` {string|Buffer}", - "type": "string|Buffer", - "name": "path", - "meta": { - "added": [ - "v0.1.93" - ], - "changes": [] - }, - "desc": "

      The path to the file the stream is reading from as specified in the first\nargument to fs.createReadStream(). If path is passed as a string, then\nreadStream.path will be a string. If path is passed as a Buffer, then\nreadStream.path will be a Buffer.

      " + "desc": "

      Change the file system timestamps of the object referenced by the supplied file\ndescriptor. See fs.utimes().

      \n

      This function does not work on AIX versions before 7.1, it will return the\nerror UV_ENOSYS.

      " }, { - "textRaw": "`pending` {boolean}", - "type": "boolean", - "name": "pending", - "meta": { - "added": [ - "v11.2.0" - ], - "changes": [] - }, - "desc": "

      This property is true if the underlying file has not been opened yet,\ni.e. before the 'ready' event is emitted.

      " - } - ] - }, - { - "textRaw": "Class: `fs.Stats`", - "type": "class", - "name": "fs.Stats", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [ - { - "version": "v8.1.0", - "pr-url": "https://github.com/nodejs/node/pull/13173", - "description": "Added times as numbers." - } - ] - }, - "desc": "

      A fs.Stats object provides information about a file.

      \n

      Objects returned from fs.stat(), fs.lstat() and fs.fstat() and\ntheir synchronous counterparts are of this type.\nIf bigint in the options passed to those methods is true, the numeric values\nwill be bigint instead of number, and the object will contain additional\nnanosecond-precision properties suffixed with Ns.

      \n
      Stats {\n  dev: 2114,\n  ino: 48064969,\n  mode: 33188,\n  nlink: 1,\n  uid: 85,\n  gid: 100,\n  rdev: 0,\n  size: 527,\n  blksize: 4096,\n  blocks: 8,\n  atimeMs: 1318289051000.1,\n  mtimeMs: 1318289051000.1,\n  ctimeMs: 1318289051000.1,\n  birthtimeMs: 1318289051000.1,\n  atime: Mon, 10 Oct 2011 23:24:11 GMT,\n  mtime: Mon, 10 Oct 2011 23:24:11 GMT,\n  ctime: Mon, 10 Oct 2011 23:24:11 GMT,\n  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }\n
      \n

      bigint version:

      \n
      BigIntStats {\n  dev: 2114n,\n  ino: 48064969n,\n  mode: 33188n,\n  nlink: 1n,\n  uid: 85n,\n  gid: 100n,\n  rdev: 0n,\n  size: 527n,\n  blksize: 4096n,\n  blocks: 8n,\n  atimeMs: 1318289051000n,\n  mtimeMs: 1318289051000n,\n  ctimeMs: 1318289051000n,\n  birthtimeMs: 1318289051000n,\n  atimeNs: 1318289051000000000n,\n  mtimeNs: 1318289051000000000n,\n  ctimeNs: 1318289051000000000n,\n  birthtimeNs: 1318289051000000000n,\n  atime: Mon, 10 Oct 2011 23:24:11 GMT,\n  mtime: Mon, 10 Oct 2011 23:24:11 GMT,\n  ctime: Mon, 10 Oct 2011 23:24:11 GMT,\n  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }\n
      ", - "methods": [ - { - "textRaw": "`stats.isBlockDevice()`", + "textRaw": "`fs.lchmod(path, mode, callback)`", "type": "method", - "name": "isBlockDevice", + "name": "lchmod", "meta": { - "added": [ - "v0.1.10" + "deprecated": [ + "v0.4.7" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`mode` {integer}", + "name": "mode", + "type": "integer" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      Returns true if the fs.Stats object describes a block device.

      " + "desc": "

      Changes the permissions on a symbolic link. No arguments other than a possible\nexception are given to the completion callback.

      \n

      This method is only implemented on macOS.

      \n

      See the POSIX lchmod(2) documentation for more detail.

      " }, { - "textRaw": "`stats.isCharacterDevice()`", + "textRaw": "`fs.lchown(path, uid, gid, callback)`", "type": "method", - "name": "isCharacterDevice", + "name": "lchown", "meta": { - "added": [ - "v0.1.10" - ], - "changes": [] + "changes": [ + { + "version": "v10.6.0", + "pr-url": "https://github.com/nodejs/node/pull/21498", + "description": "This API is no longer deprecated." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + }, + { + "version": "v0.4.7", + "description": "Documentation-only deprecation." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`uid` {integer}", + "name": "uid", + "type": "integer" + }, + { + "textRaw": "`gid` {integer}", + "name": "gid", + "type": "integer" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      Returns true if the fs.Stats object describes a character device.

      " + "desc": "

      Set the owner of the symbolic link. No arguments other than a possible\nexception are given to the completion callback.

      \n

      See the POSIX lchown(2) documentation for more detail.

      " }, { - "textRaw": "`stats.isDirectory()`", + "textRaw": "`fs.lutimes(path, atime, mtime, callback)`", "type": "method", - "name": "isDirectory", + "name": "lutimes", "meta": { "added": [ - "v0.1.10" + "v14.5.0", + "v12.19.0" ], "changes": [] }, "signatures": [ { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`atime` {number|string|Date}", + "name": "atime", + "type": "number|string|Date" + }, + { + "textRaw": "`mtime` {number|string|Date}", + "name": "mtime", + "type": "number|string|Date" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      Returns true if the fs.Stats object describes a file system directory.

      " + "desc": "

      Changes the access and modification times of a file in the same way as\nfs.utimes(), with the difference that if the path refers to a symbolic\nlink, then the link is not dereferenced: instead, the timestamps of the\nsymbolic link itself are changed.

      \n

      No arguments other than a possible exception are given to the completion\ncallback.

      " }, { - "textRaw": "`stats.isFIFO()`", + "textRaw": "`fs.link(existingPath, newPath, callback)`", "type": "method", - "name": "isFIFO", + "name": "link", "meta": { "added": [ - "v0.1.10" + "v0.1.31" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `existingPath` and `newPath` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] + "params": [ + { + "textRaw": "`existingPath` {string|Buffer|URL}", + "name": "existingPath", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`newPath` {string|Buffer|URL}", + "name": "newPath", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      Returns true if the fs.Stats object describes a first-in-first-out (FIFO)\npipe.

      " + "desc": "

      Creates a new link from the existingPath to the newPath. See the POSIX\nlink(2) documentation for more detail. No arguments other than a possible\nexception are given to the completion callback.

      " }, { - "textRaw": "`stats.isFile()`", + "textRaw": "`fs.lstat(path[, options], callback)`", "type": "method", - "name": "isFile", + "name": "lstat", "meta": { "added": [ - "v0.1.10" + "v0.1.30" ], - "changes": [] + "changes": [ + { + "version": "v10.5.0", + "pr-url": "https://github.com/nodejs/node/pull/20220", + "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`bigint` {boolean} Whether the numeric values in the returned {fs.Stats} object should be `bigint`. **Default:** `false`.", + "name": "bigint", + "type": "boolean", + "default": "`false`", + "desc": "Whether the numeric values in the returned {fs.Stats} object should be `bigint`." + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`stats` {fs.Stats}", + "name": "stats", + "type": "fs.Stats" + } + ] + } + ] } ], - "desc": "

      Returns true if the fs.Stats object describes a regular file.

      " + "desc": "

      Retrieves the <fs.Stats> for the symbolic link referred to by the path.\nThe callback gets two arguments (err, stats) where stats is a <fs.Stats>\nobject. lstat() is identical to stat(), except that if path is a symbolic\nlink, then the link itself is stat-ed, not the file that it refers to.

      \n

      See the POSIX lstat(2) documentation for more details.

      " }, { - "textRaw": "`stats.isSocket()`", + "textRaw": "`fs.mkdir(path[, options], callback)`", "type": "method", - "name": "isSocket", + "name": "mkdir", "meta": { "added": [ - "v0.1.10" + "v0.1.8" ], - "changes": [] + "changes": [ + { + "version": [ + "v13.11.0", + "v12.17.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/31530", + "description": "In `recursive` mode, the callback now receives the first created path as an argument." + }, + { + "version": "v10.12.0", + "pr-url": "https://github.com/nodejs/node/pull/21875", + "description": "The second argument can now be an `options` object with `recursive` and `mode` properties." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {Object|integer}", + "name": "options", + "type": "Object|integer", + "options": [ + { + "textRaw": "`recursive` {boolean} **Default:** `false`", + "name": "recursive", + "type": "boolean", + "default": "`false`" + }, + { + "textRaw": "`mode` {string|integer} Not supported on Windows. **Default:** `0o777`.", + "name": "mode", + "type": "string|integer", + "default": "`0o777`", + "desc": "Not supported on Windows." + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] } ], - "desc": "

      Returns true if the fs.Stats object describes a socket.

      " + "desc": "

      Asynchronously creates a directory.

      \n

      The callback is given a possible exception and, if recursive is true, the\nfirst directory path created, (err, [path]).\npath can still be undefined when recursive is true, if no directory was\ncreated.

      \n

      The optional options argument can be an integer specifying mode (permission\nand sticky bits), or an object with a mode property and a recursive\nproperty indicating whether parent directories should be created. Calling\nfs.mkdir() when path is a directory that exists results in an error only\nwhen recursive is false.

      \n
      import { mkdir } from 'fs';\n\n// Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist.\nmkdir('/tmp/a/apple', { recursive: true }, (err) => {\n  if (err) throw err;\n});\n
      \n

      On Windows, using fs.mkdir() on the root directory even with recursion will\nresult in an error:

      \n
      import { mkdir } from 'fs';\n\nmkdir('/', { recursive: true }, (err) => {\n  // => [Error: EPERM: operation not permitted, mkdir 'C:\\']\n});\n
      \n

      See the POSIX mkdir(2) documentation for more details.

      " }, { - "textRaw": "`stats.isSymbolicLink()`", + "textRaw": "`fs.mkdtemp(prefix[, options], callback)`", "type": "method", - "name": "isSymbolicLink", + "name": "mkdtemp", "meta": { "added": [ - "v0.1.10" + "v5.10.0" ], - "changes": [] + "changes": [ + { + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/39028", + "description": "The `prefix` parameter now accepts an empty string." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + }, + { + "version": "v6.2.1", + "pr-url": "https://github.com/nodejs/node/pull/6828", + "description": "The `callback` parameter is optional now." + } + ] }, "signatures": [ { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [] - } - ], - "desc": "

      Returns true if the fs.Stats object describes a symbolic link.

      \n

      This method is only valid when using fs.lstat().

      " - } - ], - "properties": [ - { - "textRaw": "`dev` {number|bigint}", - "type": "number|bigint", - "name": "dev", - "desc": "

      The numeric identifier of the device containing the file.

      " - }, - { - "textRaw": "`ino` {number|bigint}", - "type": "number|bigint", - "name": "ino", - "desc": "

      The file system specific \"Inode\" number for the file.

      " - }, - { - "textRaw": "`mode` {number|bigint}", - "type": "number|bigint", - "name": "mode", - "desc": "

      A bit-field describing the file type and mode.

      " - }, - { - "textRaw": "`nlink` {number|bigint}", - "type": "number|bigint", - "name": "nlink", - "desc": "

      The number of hard-links that exist for the file.

      " - }, - { - "textRaw": "`uid` {number|bigint}", - "type": "number|bigint", - "name": "uid", - "desc": "

      The numeric user identifier of the user that owns the file (POSIX).

      " - }, - { - "textRaw": "`gid` {number|bigint}", - "type": "number|bigint", - "name": "gid", - "desc": "

      The numeric group identifier of the group that owns the file (POSIX).

      " - }, - { - "textRaw": "`rdev` {number|bigint}", - "type": "number|bigint", - "name": "rdev", - "desc": "

      A numeric device identifier if the file represents a device.

      " - }, - { - "textRaw": "`size` {number|bigint}", - "type": "number|bigint", - "name": "size", - "desc": "

      The size of the file in bytes.

      " - }, - { - "textRaw": "`blksize` {number|bigint}", - "type": "number|bigint", - "name": "blksize", - "desc": "

      The file system block size for i/o operations.

      " - }, - { - "textRaw": "`blocks` {number|bigint}", - "type": "number|bigint", - "name": "blocks", - "desc": "

      The number of blocks allocated for this file.

      " - }, - { - "textRaw": "`atimeMs` {number|bigint}", - "type": "number|bigint", - "name": "atimeMs", - "meta": { - "added": [ - "v8.1.0" - ], - "changes": [] - }, - "desc": "

      The timestamp indicating the last time this file was accessed expressed in\nmilliseconds since the POSIX Epoch.

      " - }, - { - "textRaw": "`mtimeMs` {number|bigint}", - "type": "number|bigint", - "name": "mtimeMs", - "meta": { - "added": [ - "v8.1.0" - ], - "changes": [] - }, - "desc": "

      The timestamp indicating the last time this file was modified expressed in\nmilliseconds since the POSIX Epoch.

      " - }, - { - "textRaw": "`ctimeMs` {number|bigint}", - "type": "number|bigint", - "name": "ctimeMs", - "meta": { - "added": [ - "v8.1.0" - ], - "changes": [] - }, - "desc": "

      The timestamp indicating the last time the file status was changed expressed\nin milliseconds since the POSIX Epoch.

      " + "params": [ + { + "textRaw": "`prefix` {string}", + "name": "prefix", + "type": "string" + }, + { + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`directory` {string}", + "name": "directory", + "type": "string" + } + ] + } + ] + } + ], + "desc": "

      Creates a unique temporary directory.

      \n

      Generates six random characters to be appended behind a required\nprefix to create a unique temporary directory. Due to platform\ninconsistencies, avoid trailing X characters in prefix. Some platforms,\nnotably the BSDs, can return more than six random characters, and replace\ntrailing X characters in prefix with random characters.

      \n

      The created directory path is passed as a string to the callback's second\nparameter.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use.

      \n
      import { mkdtemp } from 'fs';\n\nmkdtemp(path.join(os.tmpdir(), 'foo-'), (err, directory) => {\n  if (err) throw err;\n  console.log(directory);\n  // Prints: /tmp/foo-itXde2 or C:\\Users\\...\\AppData\\Local\\Temp\\foo-itXde2\n});\n
      \n

      The fs.mkdtemp() method will append the six randomly selected characters\ndirectly to the prefix string. For instance, given a directory /tmp, if the\nintention is to create a temporary directory within /tmp, the prefix\nmust end with a trailing platform-specific path separator\n(require('path').sep).

      \n
      import { tmpdir } from 'os';\nimport { mkdtemp } from 'fs';\n\n// The parent directory for the new temporary directory\nconst tmpDir = tmpdir();\n\n// This method is *INCORRECT*:\nmkdtemp(tmpDir, (err, directory) => {\n  if (err) throw err;\n  console.log(directory);\n  // Will print something similar to `/tmpabc123`.\n  // A new temporary directory is created at the file system root\n  // rather than *within* the /tmp directory.\n});\n\n// This method is *CORRECT*:\nimport { sep } from 'path';\nmkdtemp(`${tmpDir}${sep}`, (err, directory) => {\n  if (err) throw err;\n  console.log(directory);\n  // Will print something similar to `/tmp/abc123`.\n  // A new temporary directory is created within\n  // the /tmp directory.\n});\n
      " }, { - "textRaw": "`birthtimeMs` {number|bigint}", - "type": "number|bigint", - "name": "birthtimeMs", + "textRaw": "`fs.open(path[, flags[, mode]], callback)`", + "type": "method", + "name": "open", "meta": { "added": [ - "v8.1.0" + "v0.0.2" ], - "changes": [] + "changes": [ + { + "version": "v11.1.0", + "pr-url": "https://github.com/nodejs/node/pull/23767", + "description": "The `flags` argument is now optional and defaults to `'r'`." + }, + { + "version": "v9.9.0", + "pr-url": "https://github.com/nodejs/node/pull/18801", + "description": "The `as` and `as+` flags are supported now." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] }, - "desc": "

      The timestamp indicating the creation time of this file expressed in\nmilliseconds since the POSIX Epoch.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`flags` {string|number} See [support of file system `flags`][]. **Default:** `'r'`.", + "name": "flags", + "type": "string|number", + "default": "`'r'`", + "desc": "See [support of file system `flags`][]." + }, + { + "textRaw": "`mode` {string|integer} **Default:** `0o666` (readable and writable)", + "name": "mode", + "type": "string|integer", + "default": "`0o666` (readable and writable)" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + } + ] + } + ] + } + ], + "desc": "

      Asynchronous file open. See the POSIX open(2) documentation for more details.

      \n

      mode sets the file mode (permission and sticky bits), but only if the file was\ncreated. On Windows, only the write permission can be manipulated; see\nfs.chmod().

      \n

      The callback gets two arguments (err, fd).

      \n

      Some characters (< > : \" / \\ | ? *) are reserved under Windows as documented\nby Naming Files, Paths, and Namespaces. Under NTFS, if the filename contains\na colon, Node.js will open a file system stream, as described by\nthis MSDN page.

      \n

      Functions based on fs.open() exhibit this behavior as well:\nfs.writeFile(), fs.readFile(), etc.

      " }, { - "textRaw": "`atimeNs` {bigint}", - "type": "bigint", - "name": "atimeNs", + "textRaw": "`fs.opendir(path[, options], callback)`", + "type": "method", + "name": "opendir", "meta": { "added": [ - "v12.10.0" + "v12.12.0" ], - "changes": [] + "changes": [ + { + "version": [ + "v13.1.0", + "v12.16.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/30114", + "description": "The `bufferSize` option was introduced." + } + ] }, - "desc": "

      Only present when bigint: true is passed into the method that generates\nthe object.\nThe timestamp indicating the last time this file was accessed expressed in\nnanoseconds since the POSIX Epoch.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", + "name": "encoding", + "type": "string|null", + "default": "`'utf8'`" + }, + { + "textRaw": "`bufferSize` {number} Number of directory entries that are buffered internally when reading from the directory. Higher values lead to better performance but higher memory usage. **Default:** `32`", + "name": "bufferSize", + "type": "number", + "default": "`32`", + "desc": "Number of directory entries that are buffered internally when reading from the directory. Higher values lead to better performance but higher memory usage." + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`dir` {fs.Dir}", + "name": "dir", + "type": "fs.Dir" + } + ] + } + ] + } + ], + "desc": "

      Asynchronously open a directory. See the POSIX opendir(3) documentation for\nmore details.

      \n

      Creates an <fs.Dir>, which contains all further functions for reading from\nand cleaning up the directory.

      \n

      The encoding option sets the encoding for the path while opening the\ndirectory and subsequent read operations.

      " }, { - "textRaw": "`mtimeNs` {bigint}", - "type": "bigint", - "name": "mtimeNs", + "textRaw": "`fs.read(fd, buffer, offset, length, position, callback)`", + "type": "method", + "name": "read", "meta": { "added": [ - "v12.10.0" + "v0.0.2" ], - "changes": [] + "changes": [ + { + "version": "v10.10.0", + "pr-url": "https://github.com/nodejs/node/pull/22150", + "description": "The `buffer` parameter can now be any `TypedArray`, or a `DataView`." + }, + { + "version": "v7.4.0", + "pr-url": "https://github.com/nodejs/node/pull/10382", + "description": "The `buffer` parameter can now be a `Uint8Array`." + }, + { + "version": "v6.0.0", + "pr-url": "https://github.com/nodejs/node/pull/4518", + "description": "The `length` parameter can now be `0`." + } + ] }, - "desc": "

      Only present when bigint: true is passed into the method that generates\nthe object.\nThe timestamp indicating the last time this file was modified expressed in\nnanoseconds since the POSIX Epoch.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`buffer` {Buffer|TypedArray|DataView} The buffer that the data will be written to. **Default:** `Buffer.alloc(16384)`", + "name": "buffer", + "type": "Buffer|TypedArray|DataView", + "default": "`Buffer.alloc(16384)`", + "desc": "The buffer that the data will be written to." + }, + { + "textRaw": "`offset` {integer} The position in `buffer` to write the data to. **Default:** `0`", + "name": "offset", + "type": "integer", + "default": "`0`", + "desc": "The position in `buffer` to write the data to." + }, + { + "textRaw": "`length` {integer} The number of bytes to read. **Default:** `buffer.byteLength`", + "name": "length", + "type": "integer", + "default": "`buffer.byteLength`", + "desc": "The number of bytes to read." + }, + { + "textRaw": "`position` {integer|bigint} Specifies where to begin reading from in the file. If `position` is `null` or `-1 `, data will be read from the current file position, and the file position will be updated. If `position` is an integer, the file position will be unchanged.", + "name": "position", + "type": "integer|bigint", + "desc": "Specifies where to begin reading from in the file. If `position` is `null` or `-1 `, data will be read from the current file position, and the file position will be updated. If `position` is an integer, the file position will be unchanged." + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`bytesRead` {integer}", + "name": "bytesRead", + "type": "integer" + }, + { + "textRaw": "`buffer` {Buffer}", + "name": "buffer", + "type": "Buffer" + } + ] + } + ] + } + ], + "desc": "

      Read data from the file specified by fd.

      \n

      The callback is given the three arguments, (err, bytesRead, buffer).

      \n

      If the file is not modified concurrently, the end-of-file is reached when the\nnumber of bytes read is zero.

      \n

      If this method is invoked as its util.promisify()ed version, it returns\na promise for an Object with bytesRead and buffer properties.

      " }, { - "textRaw": "`ctimeNs` {bigint}", - "type": "bigint", - "name": "ctimeNs", + "textRaw": "`fs.read(fd, [options,] callback)`", + "type": "method", + "name": "read", "meta": { "added": [ - "v12.10.0" + "v13.11.0", + "v12.17.0" ], - "changes": [] + "changes": [ + { + "version": [ + "v13.11.0", + "v12.17.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/31402", + "description": "Options object can be passed in to make Buffer, offset, length and position optional." + } + ] }, - "desc": "

      Only present when bigint: true is passed into the method that generates\nthe object.\nThe timestamp indicating the last time the file status was changed expressed\nin nanoseconds since the POSIX Epoch.

      " - }, - { - "textRaw": "`birthtimeNs` {bigint}", - "type": "bigint", - "name": "birthtimeNs", - "meta": { - "added": [ - "v12.10.0" - ], - "changes": [] - }, - "desc": "

      Only present when bigint: true is passed into the method that generates\nthe object.\nThe timestamp indicating the creation time of this file expressed in\nnanoseconds since the POSIX Epoch.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`buffer` {Buffer|TypedArray|DataView} **Default:** `Buffer.alloc(16384)`", + "name": "buffer", + "type": "Buffer|TypedArray|DataView", + "default": "`Buffer.alloc(16384)`" + }, + { + "textRaw": "`offset` {integer} **Default:** `0`", + "name": "offset", + "type": "integer", + "default": "`0`" + }, + { + "textRaw": "`length` {integer} **Default:** `buffer.byteLength`", + "name": "length", + "type": "integer", + "default": "`buffer.byteLength`" + }, + { + "textRaw": "`position` {integer|bigint} **Default:** `null`", + "name": "position", + "type": "integer|bigint", + "default": "`null`" + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`bytesRead` {integer}", + "name": "bytesRead", + "type": "integer" + }, + { + "textRaw": "`buffer` {Buffer}", + "name": "buffer", + "type": "Buffer" + } + ] + } + ] + } + ], + "desc": "

      Similar to the fs.read() function, this version takes an optional\noptions object. If no options object is specified, it will default with the\nabove values.

      " }, { - "textRaw": "`atime` {Date}", - "type": "Date", - "name": "atime", + "textRaw": "`fs.readdir(path[, options], callback)`", + "type": "method", + "name": "readdir", "meta": { "added": [ - "v0.11.13" + "v0.1.8" ], - "changes": [] + "changes": [ + { + "version": "v10.10.0", + "pr-url": "https://github.com/nodejs/node/pull/22020", + "description": "New option `withFileTypes` was added." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + }, + { + "version": "v6.0.0", + "pr-url": "https://github.com/nodejs/node/pull/5616", + "description": "The `options` parameter was added." + } + ] }, - "desc": "

      The timestamp indicating the last time this file was accessed.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + }, + { + "textRaw": "`withFileTypes` {boolean} **Default:** `false`", + "name": "withFileTypes", + "type": "boolean", + "default": "`false`" + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`files` {string[]|Buffer[]|fs.Dirent[]}", + "name": "files", + "type": "string[]|Buffer[]|fs.Dirent[]" + } + ] + } + ] + } + ], + "desc": "

      Reads the contents of a directory. The callback gets two arguments (err, files)\nwhere files is an array of the names of the files in the directory excluding\n'.' and '..'.

      \n

      See the POSIX readdir(3) documentation for more details.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe filenames passed to the callback. If the encoding is set to 'buffer',\nthe filenames returned will be passed as <Buffer> objects.

      \n

      If options.withFileTypes is set to true, the files array will contain\n<fs.Dirent> objects.

      " }, { - "textRaw": "`mtime` {Date}", - "type": "Date", - "name": "mtime", + "textRaw": "`fs.readFile(path[, options], callback)`", + "type": "method", + "name": "readFile", "meta": { "added": [ - "v0.11.13" + "v0.1.29" ], - "changes": [] + "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/35911", + "description": "The options argument may include an AbortSignal to abort an ongoing readFile request." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + }, + { + "version": "v5.1.0", + "pr-url": "https://github.com/nodejs/node/pull/3740", + "description": "The `callback` will always be called with `null` as the `error` parameter in case of success." + }, + { + "version": "v5.0.0", + "pr-url": "https://github.com/nodejs/node/pull/3163", + "description": "The `path` parameter can be a file descriptor now." + } + ] }, - "desc": "

      The timestamp indicating the last time this file was modified.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`path` {string|Buffer|URL|integer} filename or file descriptor", + "name": "path", + "type": "string|Buffer|URL|integer", + "desc": "filename or file descriptor" + }, + { + "textRaw": "`options` {Object|string}", + "name": "options", + "type": "Object|string", + "options": [ + { + "textRaw": "`encoding` {string|null} **Default:** `null`", + "name": "encoding", + "type": "string|null", + "default": "`null`" + }, + { + "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'r'`.", + "name": "flag", + "type": "string", + "default": "`'r'`", + "desc": "See [support of file system `flags`][]." + }, + { + "textRaw": "`signal` {AbortSignal} allows aborting an in-progress readFile", + "name": "signal", + "type": "AbortSignal", + "desc": "allows aborting an in-progress readFile" + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`data` {string|Buffer}", + "name": "data", + "type": "string|Buffer" + } + ] + } + ] + } + ], + "desc": "

      Asynchronously reads the entire contents of a file.

      \n
      import { readFile } from 'fs';\n\nreadFile('/etc/passwd', (err, data) => {\n  if (err) throw err;\n  console.log(data);\n});\n
      \n

      The callback is passed two arguments (err, data), where data is the\ncontents of the file.

      \n

      If no encoding is specified, then the raw buffer is returned.

      \n

      If options is a string, then it specifies the encoding:

      \n
      import { readFile } from 'fs';\n\nreadFile('/etc/passwd', 'utf8', callback);\n
      \n

      When the path is a directory, the behavior of fs.readFile() and\nfs.readFileSync() is platform-specific. On macOS, Linux, and Windows, an\nerror will be returned. On FreeBSD, a representation of the directory's contents\nwill be returned.

      \n
      import { readFile } from 'fs';\n\n// macOS, Linux, and Windows\nreadFile('<directory>', (err, data) => {\n  // => [Error: EISDIR: illegal operation on a directory, read <directory>]\n});\n\n//  FreeBSD\nreadFile('<directory>', (err, data) => {\n  // => null, <data>\n});\n
      \n

      It is possible to abort an ongoing request using an AbortSignal. If a\nrequest is aborted the callback is called with an AbortError:

      \n
      import { readFile } from 'fs';\n\nconst controller = new AbortController();\nconst signal = controller.signal;\nreadFile(fileInfo[0].name, { signal }, (err, buf) => {\n  // ...\n});\n// When you want to abort the request\ncontroller.abort();\n
      \n

      The fs.readFile() function buffers the entire file. To minimize memory costs,\nwhen possible prefer streaming via fs.createReadStream().

      \n

      Aborting an ongoing request does not abort individual operating\nsystem requests but rather the internal buffering fs.readFile performs.

      ", + "modules": [ + { + "textRaw": "File descriptors", + "name": "file_descriptors", + "desc": "
        \n
      1. Any specified file descriptor has to support reading.
      2. \n
      3. If a file descriptor is specified as the path, it will not be closed\nautomatically.
      4. \n
      5. The reading will begin at the current position. For example, if the file\nalready had 'Hello World' and six bytes are read with the file descriptor,\nthe call to fs.readFile() with the same file descriptor, would give\n'World', rather than 'Hello World'.
      6. \n
      ", + "type": "module", + "displayName": "File descriptors" + }, + { + "textRaw": "Performance Considerations", + "name": "performance_considerations", + "desc": "

      The fs.readFile() method asynchronously reads the contents of a file into\nmemory one chunk at a time, allowing the event loop to turn between each chunk.\nThis allows the read operation to have less impact on other activity that may\nbe using the underlying libuv thread pool but means that it will take longer\nto read a complete file into memory.

      \n

      The additional read overhead can vary broadly on different systems and depends\non the type of file being read. If the file type is not a regular file (a pipe\nfor instance) and Node.js is unable to determine an actual file size, each read\noperation will load on 64kb of data. For regular files, each read will process\n512kb of data.

      \n

      For applications that require as-fast-as-possible reading of file contents, it\nis better to use fs.read() directly and for application code to manage\nreading the full contents of the file itself.

      \n

      The Node.js GitHub issue #25741 provides more information and a detailed\nanalysis on the performance of fs.readFile() for multiple file sizes in\ndifferent Node.js versions.

      ", + "type": "module", + "displayName": "Performance Considerations" + } + ] }, { - "textRaw": "`ctime` {Date}", - "type": "Date", - "name": "ctime", + "textRaw": "`fs.readlink(path[, options], callback)`", + "type": "method", + "name": "readlink", "meta": { "added": [ - "v0.11.13" + "v0.1.31" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, - "desc": "

      The timestamp indicating the last time the file status was changed.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`linkString` {string|Buffer}", + "name": "linkString", + "type": "string|Buffer" + } + ] + } + ] + } + ], + "desc": "

      Reads the contents of the symbolic link referred to by path. The callback gets\ntwo arguments (err, linkString).

      \n

      See the POSIX readlink(2) documentation for more details.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe link path passed to the callback. If the encoding is set to 'buffer',\nthe link path returned will be passed as a <Buffer> object.

      " }, { - "textRaw": "`birthtime` {Date}", - "type": "Date", - "name": "birthtime", + "textRaw": "`fs.readv(fd, buffers[, position], callback)`", + "type": "method", + "name": "readv", "meta": { "added": [ - "v0.11.13" + "v13.13.0", + "v12.17.0" ], "changes": [] }, - "desc": "

      The timestamp indicating the creation time of this file.

      " - } - ], - "modules": [ - { - "textRaw": "Stat time values", - "name": "stat_time_values", - "desc": "

      The atimeMs, mtimeMs, ctimeMs, birthtimeMs properties are\nnumeric values that hold the corresponding times in milliseconds. Their\nprecision is platform specific. When bigint: true is passed into the\nmethod that generates the object, the properties will be bigints,\notherwise they will be numbers.

      \n

      The atimeNs, mtimeNs, ctimeNs, birthtimeNs properties are\nbigints that hold the corresponding times in nanoseconds. They are\nonly present when bigint: true is passed into the method that generates\nthe object. Their precision is platform specific.

      \n

      atime, mtime, ctime, and birthtime are\nDate object alternate representations of the various times. The\nDate and number values are not connected. Assigning a new number value, or\nmutating the Date value, will not be reflected in the corresponding alternate\nrepresentation.

      \n

      The times in the stat object have the following semantics:

      \n
        \n
      • atime \"Access Time\": Time when file data last accessed. Changed\nby the mknod(2), utimes(2), and read(2) system calls.
      • \n
      • mtime \"Modified Time\": Time when file data last modified.\nChanged by the mknod(2), utimes(2), and write(2) system calls.
      • \n
      • ctime \"Change Time\": Time when file status was last changed\n(inode data modification). Changed by the chmod(2), chown(2),\nlink(2), mknod(2), rename(2), unlink(2), utimes(2),\nread(2), and write(2) system calls.
      • \n
      • birthtime \"Birth Time\": Time of file creation. Set once when the\nfile is created. On filesystems where birthtime is not available,\nthis field may instead hold either the ctime or\n1970-01-01T00:00Z (ie, Unix epoch timestamp 0). This value may be greater\nthan atime or mtime in this case. On Darwin and other FreeBSD variants,\nalso set if the atime is explicitly set to an earlier value than the current\nbirthtime using the utimes(2) system call.
      • \n
      \n

      Prior to Node.js 0.12, the ctime held the birthtime on Windows systems. As\nof 0.12, ctime is not \"creation time\", and on Unix systems, it never was.

      ", - "type": "module", - "displayName": "Stat time values" - } - ] - }, - { - "textRaw": "Class: `fs.WriteStream`", - "type": "class", - "name": "fs.WriteStream", - "meta": { - "added": [ - "v0.1.93" - ], - "changes": [] - }, - "desc": "\n

      Instances of fs.WriteStream are created and returned using the\nfs.createWriteStream() function.

      ", - "events": [ - { - "textRaw": "Event: `'close'`", - "type": "event", - "name": "close", - "meta": { - "added": [ - "v0.1.93" - ], - "changes": [] - }, - "params": [], - "desc": "

      Emitted when the WriteStream's underlying file descriptor has been closed.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`buffers` {ArrayBufferView[]}", + "name": "buffers", + "type": "ArrayBufferView[]" + }, + { + "textRaw": "`position` {integer}", + "name": "position", + "type": "integer" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`bytesRead` {integer}", + "name": "bytesRead", + "type": "integer" + }, + { + "textRaw": "`buffers` {ArrayBufferView[]}", + "name": "buffers", + "type": "ArrayBufferView[]" + } + ] + } + ] + } + ], + "desc": "

      Read from a file specified by fd and write to an array of ArrayBufferViews\nusing readv().

      \n

      position is the offset from the beginning of the file from where data\nshould be read. If typeof position !== 'number', the data will be read\nfrom the current position.

      \n

      The callback will be given three arguments: err, bytesRead, and\nbuffers. bytesRead is how many bytes were read from the file.

      \n

      If this method is invoked as its util.promisify()ed version, it returns\na promise for an Object with bytesRead and buffers properties.

      " }, { - "textRaw": "Event: `'open'`", - "type": "event", - "name": "open", + "textRaw": "`fs.realpath(path[, options], callback)`", + "type": "method", + "name": "realpath", "meta": { "added": [ - "v0.1.93" + "v0.1.31" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v8.0.0", + "pr-url": "https://github.com/nodejs/node/pull/13028", + "description": "Pipe/Socket resolve support was added." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + }, + { + "version": "v6.4.0", + "pr-url": "https://github.com/nodejs/node/pull/7899", + "description": "Calling `realpath` now works again for various edge cases on Windows." + }, + { + "version": "v6.0.0", + "pr-url": "https://github.com/nodejs/node/pull/3594", + "description": "The `cache` parameter was removed." + } + ] }, - "params": [ + "signatures": [ { - "textRaw": "`fd` {integer} Integer file descriptor used by the `WriteStream`.", - "name": "fd", - "type": "integer", - "desc": "Integer file descriptor used by the `WriteStream`." + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`resolvedPath` {string|Buffer}", + "name": "resolvedPath", + "type": "string|Buffer" + } + ] + } + ] } ], - "desc": "

      Emitted when the WriteStream's file is opened.

      " + "desc": "

      Asynchronously computes the canonical pathname by resolving ., .. and\nsymbolic links.

      \n

      A canonical pathname is not necessarily unique. Hard links and bind mounts can\nexpose a file system entity through many pathnames.

      \n

      This function behaves like realpath(3), with some exceptions:

      \n
        \n
      1. \n

        No case conversion is performed on case-insensitive file systems.

        \n
      2. \n
      3. \n

        The maximum number of symbolic links is platform-independent and generally\n(much) higher than what the native realpath(3) implementation supports.

        \n
      4. \n
      \n

      The callback gets two arguments (err, resolvedPath). May use process.cwd\nto resolve relative paths.

      \n

      Only paths that can be converted to UTF8 strings are supported.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe path passed to the callback. If the encoding is set to 'buffer',\nthe path returned will be passed as a <Buffer> object.

      \n

      If path resolves to a socket or a pipe, the function will return a system\ndependent name for that object.

      " }, { - "textRaw": "Event: `'ready'`", - "type": "event", - "name": "ready", + "textRaw": "`fs.realpath.native(path[, options], callback)`", + "type": "method", + "name": "native", "meta": { "added": [ - "v9.11.0" + "v9.2.0" ], "changes": [] }, - "params": [], - "desc": "

      Emitted when the fs.WriteStream is ready to be used.

      \n

      Fires immediately after 'open'.

      " - } - ], - "properties": [ + "signatures": [ + { + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`resolvedPath` {string|Buffer}", + "name": "resolvedPath", + "type": "string|Buffer" + } + ] + } + ] + } + ], + "desc": "

      Asynchronous realpath(3).

      \n

      The callback gets two arguments (err, resolvedPath).

      \n

      Only paths that can be converted to UTF8 strings are supported.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe path passed to the callback. If the encoding is set to 'buffer',\nthe path returned will be passed as a <Buffer> object.

      \n

      On Linux, when Node.js is linked against musl libc, the procfs file system must\nbe mounted on /proc in order for this function to work. Glibc does not have\nthis restriction.

      " + }, { - "textRaw": "`writeStream.bytesWritten`", - "name": "bytesWritten", + "textRaw": "`fs.rename(oldPath, newPath, callback)`", + "type": "method", + "name": "rename", "meta": { "added": [ - "v0.4.7" + "v0.0.2" ], - "changes": [] + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `oldPath` and `newPath` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, - "desc": "

      The number of bytes written so far. Does not include data that is still queued\nfor writing.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`oldPath` {string|Buffer|URL}", + "name": "oldPath", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`newPath` {string|Buffer|URL}", + "name": "newPath", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] + } + ], + "desc": "

      Asynchronously rename file at oldPath to the pathname provided\nas newPath. In the case that newPath already exists, it will\nbe overwritten. If there is a directory at newPath, an error will\nbe raised instead. No arguments other than a possible exception are\ngiven to the completion callback.

      \n

      See also: rename(2).

      \n
      import { rename } from 'fs';\n\nrename('oldFile.txt', 'newFile.txt', (err) => {\n  if (err) throw err;\n  console.log('Rename complete!');\n});\n
      " }, { - "textRaw": "`writeStream.path`", - "name": "path", + "textRaw": "`fs.rmdir(path[, options], callback)`", + "type": "method", + "name": "rmdir", "meta": { "added": [ - "v0.1.93" + "v0.0.2" ], - "changes": [] + "changes": [ + { + "version": "v14.14.0", + "pr-url": "https://github.com/nodejs/node/pull/35579", + "description": "The `recursive` option is deprecated, use `fs.rm` instead." + }, + { + "version": [ + "v13.3.0", + "v12.16.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/30644", + "description": "The `maxBusyTries` option is renamed to `maxRetries`, and its default is 0. The `emfileWait` option has been removed, and `EMFILE` errors use the same retry logic as other errors. The `retryDelay` option is now supported. `ENFILE` errors are now retried." + }, + { + "version": "v12.10.0", + "pr-url": "https://github.com/nodejs/node/pull/29168", + "description": "The `recursive`, `maxBusyTries`, and `emfileWait` options are now supported." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameters can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, - "desc": "

      The path to the file the stream is writing to as specified in the first\nargument to fs.createWriteStream(). If path is passed as a string, then\nwriteStream.path will be a string. If path is passed as a Buffer, then\nwriteStream.path will be a Buffer.

      " + "signatures": [ + { + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js retries the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`. **Default:** `0`.", + "name": "maxRetries", + "type": "integer", + "default": "`0`", + "desc": "If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js retries the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`." + }, + { + "textRaw": "`recursive` {boolean} If `true`, perform a recursive directory removal. In recursive mode, errors are not reported if `path` does not exist, and operations are retried on failure. **Default:** `false`.", + "name": "recursive", + "type": "boolean", + "default": "`false`", + "desc": "If `true`, perform a recursive directory removal. In recursive mode, errors are not reported if `path` does not exist, and operations are retried on failure." + }, + { + "textRaw": "`retryDelay` {integer} The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`. **Default:** `100`.", + "name": "retryDelay", + "type": "integer", + "default": "`100`", + "desc": "The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`." + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] + } + ], + "desc": "

      Asynchronous rmdir(2). No arguments other than a possible exception are given\nto the completion callback.

      \n

      Using fs.rmdir() on a file (not a directory) results in an ENOENT error on\nWindows and an ENOTDIR error on POSIX.

      \n

      Setting recursive to true results in behavior similar to the Unix command\nrm -rf: an error will not be raised for paths that do not exist, and paths\nthat represent files will be deleted. The permissive behavior of the\nrecursive option is deprecated, ENOTDIR and ENOENT will be thrown in\nthe future.

      " }, { - "textRaw": "`pending` {boolean}", - "type": "boolean", - "name": "pending", + "textRaw": "`fs.rm(path[, options], callback)`", + "type": "method", + "name": "rm", "meta": { "added": [ - "v11.2.0" + "v14.14.0" ], "changes": [] }, - "desc": "

      This property is true if the underlying file has not been opened yet,\ni.e. before the 'ready' event is emitted.

      " - } - ] - } - ], - "methods": [ - { - "textRaw": "`fs.access(path[, mode], callback)`", - "type": "method", - "name": "access", - "meta": { - "added": [ - "v0.11.15" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v6.3.0", - "pr-url": "https://github.com/nodejs/node/pull/6534", - "description": "The constants like `fs.R_OK`, etc which were present directly on `fs` were moved into `fs.constants` as a soft deprecation. Thus for Node.js `< v6.3.0` use `fs` to access those constants, or do something like `(fs.constants || fs).R_OK` to work with all versions." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`mode` {integer} **Default:** `fs.constants.F_OK`", - "name": "mode", - "type": "integer", - "default": "`fs.constants.F_OK`" - }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`force` {boolean} When `true`, exceptions will be ignored if `path` does not exist. **Default:** `false`.", + "name": "force", + "type": "boolean", + "default": "`false`", + "desc": "When `true`, exceptions will be ignored if `path` does not exist." + }, + { + "textRaw": "`maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`. **Default:** `0`.", + "name": "maxRetries", + "type": "integer", + "default": "`0`", + "desc": "If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`." + }, + { + "textRaw": "`recursive` {boolean} If `true`, perform a recursive removal. In recursive mode operations are retried on failure. **Default:** `false`.", + "name": "recursive", + "type": "boolean", + "default": "`false`", + "desc": "If `true`, perform a recursive removal. In recursive mode operations are retried on failure." + }, + { + "textRaw": "`retryDelay` {integer} The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`. **Default:** `100`.", + "name": "retryDelay", + "type": "integer", + "default": "`100`", + "desc": "The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`." + } + ] + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] } ] } - ] - } - ], - "desc": "

      Tests a user's permissions for the file or directory specified by path.\nThe mode argument is an optional integer that specifies the accessibility\nchecks to be performed. Check File access constants for possible values\nof mode. It is possible to create a mask consisting of the bitwise OR of\ntwo or more values (e.g. fs.constants.W_OK | fs.constants.R_OK).

      \n

      The final argument, callback, is a callback function that is invoked with\na possible error argument. If any of the accessibility checks fail, the error\nargument will be an Error object. The following examples check if\npackage.json exists, and if it is readable or writable.

      \n
      const file = 'package.json';\n\n// Check if the file exists in the current directory.\nfs.access(file, fs.constants.F_OK, (err) => {\n  console.log(`${file} ${err ? 'does not exist' : 'exists'}`);\n});\n\n// Check if the file is readable.\nfs.access(file, fs.constants.R_OK, (err) => {\n  console.log(`${file} ${err ? 'is not readable' : 'is readable'}`);\n});\n\n// Check if the file is writable.\nfs.access(file, fs.constants.W_OK, (err) => {\n  console.log(`${file} ${err ? 'is not writable' : 'is writable'}`);\n});\n\n// Check if the file exists in the current directory, and if it is writable.\nfs.access(file, fs.constants.F_OK | fs.constants.W_OK, (err) => {\n  if (err) {\n    console.error(\n      `${file} ${err.code === 'ENOENT' ? 'does not exist' : 'is read-only'}`);\n  } else {\n    console.log(`${file} exists, and it is writable`);\n  }\n});\n
      \n

      Do not use fs.access() to check for the accessibility of a file before calling\nfs.open(), fs.readFile() or fs.writeFile(). Doing\nso introduces a race condition, since other processes may change the file's\nstate between the two calls. Instead, user code should open/read/write the\nfile directly and handle the error raised if the file is not accessible.

      \n

      write (NOT RECOMMENDED)

      \n
      fs.access('myfile', (err) => {\n  if (!err) {\n    console.error('myfile already exists');\n    return;\n  }\n\n  fs.open('myfile', 'wx', (err, fd) => {\n    if (err) throw err;\n    writeMyData(fd);\n  });\n});\n
      \n

      write (RECOMMENDED)

      \n
      fs.open('myfile', 'wx', (err, fd) => {\n  if (err) {\n    if (err.code === 'EEXIST') {\n      console.error('myfile already exists');\n      return;\n    }\n\n    throw err;\n  }\n\n  writeMyData(fd);\n});\n
      \n

      read (NOT RECOMMENDED)

      \n
      fs.access('myfile', (err) => {\n  if (err) {\n    if (err.code === 'ENOENT') {\n      console.error('myfile does not exist');\n      return;\n    }\n\n    throw err;\n  }\n\n  fs.open('myfile', 'r', (err, fd) => {\n    if (err) throw err;\n    readMyData(fd);\n  });\n});\n
      \n

      read (RECOMMENDED)

      \n
      fs.open('myfile', 'r', (err, fd) => {\n  if (err) {\n    if (err.code === 'ENOENT') {\n      console.error('myfile does not exist');\n      return;\n    }\n\n    throw err;\n  }\n\n  readMyData(fd);\n});\n
      \n

      The \"not recommended\" examples above check for accessibility and then use the\nfile; the \"recommended\" examples are better because they use the file directly\nand handle the error, if any.

      \n

      In general, check for the accessibility of a file only if the file will not be\nused directly, for example when its accessibility is a signal from another\nprocess.

      \n

      On Windows, access-control policies (ACLs) on a directory may limit access to\na file or directory. The fs.access() function, however, does not check the\nACL and therefore may report that a path is accessible even if the ACL restricts\nthe user from reading or writing to it.

      " - }, - { - "textRaw": "`fs.accessSync(path[, mode])`", - "type": "method", - "name": "accessSync", - "meta": { - "added": [ - "v0.11.15" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ + ], + "desc": "

      Asynchronously removes files and directories (modeled on the standard POSIX rm\nutility). No arguments other than a possible exception are given to the\ncompletion callback.

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`mode` {integer} **Default:** `fs.constants.F_OK`", - "name": "mode", - "type": "integer", - "default": "`fs.constants.F_OK`" - } - ] - } - ], - "desc": "

      Synchronously tests a user's permissions for the file or directory specified\nby path. The mode argument is an optional integer that specifies the\naccessibility checks to be performed. Check File access constants for\npossible values of mode. It is possible to create a mask consisting of\nthe bitwise OR of two or more values\n(e.g. fs.constants.W_OK | fs.constants.R_OK).

      \n

      If any of the accessibility checks fail, an Error will be thrown. Otherwise,\nthe method will return undefined.

      \n
      try {\n  fs.accessSync('etc/passwd', fs.constants.R_OK | fs.constants.W_OK);\n  console.log('can read/write');\n} catch (err) {\n  console.error('no access!');\n}\n
      " - }, - { - "textRaw": "`fs.appendFile(path, data[, options], callback)`", - "type": "method", - "name": "appendFile", - "meta": { - "added": [ - "v0.6.7" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7831", - "description": "The passed `options` object will never be modified." + "textRaw": "`fs.stat(path[, options], callback)`", + "type": "method", + "name": "stat", + "meta": { + "added": [ + "v0.0.2" + ], + "changes": [ + { + "version": "v10.5.0", + "pr-url": "https://github.com/nodejs/node/pull/20220", + "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, - { - "version": "v5.0.0", - "pr-url": "https://github.com/nodejs/node/pull/3163", - "description": "The `file` parameter can be a file descriptor now." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL|number} filename or file descriptor", - "name": "path", - "type": "string|Buffer|URL|number", - "desc": "filename or file descriptor" - }, - { - "textRaw": "`data` {string|Buffer}", - "name": "data", - "type": "string|Buffer" - }, + "signatures": [ { - "textRaw": "`options` {Object|string}", - "name": "options", - "type": "Object|string", - "options": [ + "params": [ { - "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", - "name": "encoding", - "type": "string|null", - "default": "`'utf8'`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`mode` {integer} **Default:** `0o666`", - "name": "mode", - "type": "integer", - "default": "`0o666`" + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`bigint` {boolean} Whether the numeric values in the returned {fs.Stats} object should be `bigint`. **Default:** `false`.", + "name": "bigint", + "type": "boolean", + "default": "`false`", + "desc": "Whether the numeric values in the returned {fs.Stats} object should be `bigint`." + } + ] }, { - "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'a'`.", - "name": "flag", - "type": "string", - "default": "`'a'`", - "desc": "See [support of file system `flags`][]." - } - ] - }, - { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ - { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`stats` {fs.Stats}", + "name": "stats", + "type": "fs.Stats" + } + ] } ] } - ] - } - ], - "desc": "

      Asynchronously append data to a file, creating the file if it does not yet\nexist. data can be a string or a Buffer.

      \n
      fs.appendFile('message.txt', 'data to append', (err) => {\n  if (err) throw err;\n  console.log('The \"data to append\" was appended to file!');\n});\n
      \n

      If options is a string, then it specifies the encoding:

      \n
      fs.appendFile('message.txt', 'data to append', 'utf8', callback);\n
      \n

      The path may be specified as a numeric file descriptor that has been opened\nfor appending (using fs.open() or fs.openSync()). The file descriptor will\nnot be closed automatically.

      \n
      fs.open('message.txt', 'a', (err, fd) => {\n  if (err) throw err;\n  fs.appendFile(fd, 'data to append', 'utf8', (err) => {\n    fs.close(fd, (err) => {\n      if (err) throw err;\n    });\n    if (err) throw err;\n  });\n});\n
      " - }, - { - "textRaw": "`fs.appendFileSync(path, data[, options])`", - "type": "method", - "name": "appendFileSync", - "meta": { - "added": [ - "v0.6.7" - ], - "changes": [ - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7831", - "description": "The passed `options` object will never be modified." - }, - { - "version": "v5.0.0", - "pr-url": "https://github.com/nodejs/node/pull/3163", - "description": "The `file` parameter can be a file descriptor now." - } - ] - }, - "signatures": [ + ], + "desc": "

      Asynchronous stat(2). The callback gets two arguments (err, stats) where\nstats is an <fs.Stats> object.

      \n

      In case of an error, the err.code will be one of Common System Errors.

      \n

      Using fs.stat() to check for the existence of a file before calling\nfs.open(), fs.readFile() or fs.writeFile() is not recommended.\nInstead, user code should open/read/write the file directly and handle the\nerror raised if the file is not available.

      \n

      To check if a file exists without manipulating it afterwards, fs.access()\nis recommended.

      \n

      For example, given the following directory structure:

      \n
      - txtDir\n-- file.txt\n- app.js\n
      \n

      The next program will check for the stats of the given paths:

      \n
      import { stat } from 'fs';\n\nconst pathsToCheck = ['./txtDir', './txtDir/file.txt'];\n\nfor (let i = 0; i < pathsToCheck.length; i++) {\n  stat(pathsToCheck[i], (err, stats) => {\n    console.log(stats.isDirectory());\n    console.log(stats);\n  });\n}\n
      \n

      The resulting output will resemble:

      \n
      true\nStats {\n  dev: 16777220,\n  mode: 16877,\n  nlink: 3,\n  uid: 501,\n  gid: 20,\n  rdev: 0,\n  blksize: 4096,\n  ino: 14214262,\n  size: 96,\n  blocks: 0,\n  atimeMs: 1561174653071.963,\n  mtimeMs: 1561174614583.3518,\n  ctimeMs: 1561174626623.5366,\n  birthtimeMs: 1561174126937.2893,\n  atime: 2019-06-22T03:37:33.072Z,\n  mtime: 2019-06-22T03:36:54.583Z,\n  ctime: 2019-06-22T03:37:06.624Z,\n  birthtime: 2019-06-22T03:28:46.937Z\n}\nfalse\nStats {\n  dev: 16777220,\n  mode: 33188,\n  nlink: 1,\n  uid: 501,\n  gid: 20,\n  rdev: 0,\n  blksize: 4096,\n  ino: 14214074,\n  size: 8,\n  blocks: 8,\n  atimeMs: 1561174616618.8555,\n  mtimeMs: 1561174614584,\n  ctimeMs: 1561174614583.8145,\n  birthtimeMs: 1561174007710.7478,\n  atime: 2019-06-22T03:36:56.619Z,\n  mtime: 2019-06-22T03:36:54.584Z,\n  ctime: 2019-06-22T03:36:54.584Z,\n  birthtime: 2019-06-22T03:26:47.711Z\n}\n
      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL|number} filename or file descriptor", - "name": "path", - "type": "string|Buffer|URL|number", - "desc": "filename or file descriptor" - }, - { - "textRaw": "`data` {string|Buffer}", - "name": "data", - "type": "string|Buffer" - }, + "textRaw": "`fs.symlink(target, path[, type], callback)`", + "type": "method", + "name": "symlink", + "meta": { + "added": [ + "v0.1.31" + ], + "changes": [ + { + "version": "v12.0.0", + "pr-url": "https://github.com/nodejs/node/pull/23724", + "description": "If the `type` argument is left undefined, Node will autodetect `target` type and automatically select `dir` or `file`." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `target` and `path` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." + } + ] + }, + "signatures": [ { - "textRaw": "`options` {Object|string}", - "name": "options", - "type": "Object|string", - "options": [ + "params": [ { - "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", - "name": "encoding", - "type": "string|null", - "default": "`'utf8'`" + "textRaw": "`target` {string|Buffer|URL}", + "name": "target", + "type": "string|Buffer|URL" }, { - "textRaw": "`mode` {integer} **Default:** `0o666`", - "name": "mode", - "type": "integer", - "default": "`0o666`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'a'`.", - "name": "flag", - "type": "string", - "default": "`'a'`", - "desc": "See [support of file system `flags`][]." - } - ] - } - ] - } - ], - "desc": "

      Synchronously append data to a file, creating the file if it does not yet\nexist. data can be a string or a Buffer.

      \n
      try {\n  fs.appendFileSync('message.txt', 'data to append');\n  console.log('The \"data to append\" was appended to file!');\n} catch (err) {\n  /* Handle the error */\n}\n
      \n

      If options is a string, then it specifies the encoding:

      \n
      fs.appendFileSync('message.txt', 'data to append', 'utf8');\n
      \n

      The path may be specified as a numeric file descriptor that has been opened\nfor appending (using fs.open() or fs.openSync()). The file descriptor will\nnot be closed automatically.

      \n
      let fd;\n\ntry {\n  fd = fs.openSync('message.txt', 'a');\n  fs.appendFileSync(fd, 'data to append', 'utf8');\n} catch (err) {\n  /* Handle the error */\n} finally {\n  if (fd !== undefined)\n    fs.closeSync(fd);\n}\n
      " - }, - { - "textRaw": "`fs.chmod(path, mode, callback)`", - "type": "method", - "name": "chmod", - "meta": { - "added": [ - "v0.1.30" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`mode` {string|integer}", - "name": "mode", - "type": "string|integer" - }, - { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "textRaw": "`type` {string}", + "name": "type", + "type": "string" + }, { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] } ] } - ] - } - ], - "desc": "

      Asynchronously changes the permissions of a file. No arguments other than a\npossible exception are given to the completion callback.

      \n

      See also: chmod(2).

      \n
      fs.chmod('my_file.txt', 0o775, (err) => {\n  if (err) throw err;\n  console.log('The permissions for file \"my_file.txt\" have been changed!');\n});\n
      ", - "modules": [ - { - "textRaw": "File modes", - "name": "file_modes", - "desc": "

      The mode argument used in both the fs.chmod() and fs.chmodSync()\nmethods is a numeric bitmask created using a logical OR of the following\nconstants:

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      ConstantOctalDescription
      fs.constants.S_IRUSR0o400read by owner
      fs.constants.S_IWUSR0o200write by owner
      fs.constants.S_IXUSR0o100execute/search by owner
      fs.constants.S_IRGRP0o40read by group
      fs.constants.S_IWGRP0o20write by group
      fs.constants.S_IXGRP0o10execute/search by group
      fs.constants.S_IROTH0o4read by others
      fs.constants.S_IWOTH0o2write by others
      fs.constants.S_IXOTH0o1execute/search by others
      \n

      An easier method of constructing the mode is to use a sequence of three\noctal digits (e.g. 765). The left-most digit (7 in the example), specifies\nthe permissions for the file owner. The middle digit (6 in the example),\nspecifies permissions for the group. The right-most digit (5 in the example),\nspecifies the permissions for others.

      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
      NumberDescription
      7read, write, and execute
      6read and write
      5read and execute
      4read only
      3write and execute
      2write only
      1execute only
      0no permission
      \n

      For example, the octal value 0o765 means:

      \n
        \n
      • The owner may read, write and execute the file.
      • \n
      • The group may read and write the file.
      • \n
      • Others may read and execute the file.
      • \n
      \n

      When using raw numbers where file modes are expected, any value larger than\n0o777 may result in platform-specific behaviors that are not supported to work\nconsistently. Therefore constants like S_ISVTX, S_ISGID or S_ISUID are not\nexposed in fs.constants.

      \n

      Caveats: on Windows only the write permission can be changed, and the\ndistinction among the permissions of group, owner or others is not\nimplemented.

      ", - "type": "module", - "displayName": "File modes" - } - ] - }, - { - "textRaw": "`fs.chmodSync(path, mode)`", - "type": "method", - "name": "chmodSync", - "meta": { - "added": [ - "v0.6.7" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ + ], + "desc": "

      Creates the link called path pointing to target. No arguments other than a\npossible exception are given to the completion callback.

      \n

      See the POSIX symlink(2) documentation for more details.

      \n

      The type argument is only available on Windows and ignored on other platforms.\nIt can be set to 'dir', 'file', or 'junction'. If the type argument is\nnot set, Node.js will autodetect target type and use 'file' or 'dir'. If\nthe target does not exist, 'file' will be used. Windows junction points\nrequire the destination path to be absolute. When using 'junction', the\ntarget argument will automatically be normalized to absolute path.

      \n

      Relative targets are relative to the link’s parent directory.

      \n
      import { symlink } from 'fs';\n\nsymlink('./mew', './example/mewtwo', callback);\n
      \n

      The above example creates a symbolic link mewtwo in the example which points\nto mew in the same directory:

      \n
      $ tree example/\nexample/\n├── mew\n└── mewtwo -> ./mew\n
      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`mode` {string|integer}", - "name": "mode", - "type": "string|integer" - } - ] - } - ], - "desc": "

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.chmod().

      \n

      See also: chmod(2).

      " - }, - { - "textRaw": "`fs.chown(path, uid, gid, callback)`", - "type": "method", - "name": "chown", - "meta": { - "added": [ - "v0.1.97" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." + "textRaw": "`fs.truncate(path[, len], callback)`", + "type": "method", + "name": "truncate", + "meta": { + "added": [ + "v0.8.6" + ], + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`uid` {integer}", - "name": "uid", - "type": "integer" - }, - { - "textRaw": "`gid` {integer}", - "name": "gid", - "type": "integer" - }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`len` {integer} **Default:** `0`", + "name": "len", + "type": "integer", + "default": "`0`" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] } ] } - ] - } - ], - "desc": "

      Asynchronously changes owner and group of a file. No arguments other than a\npossible exception are given to the completion callback.

      \n

      See also: chown(2).

      " - }, - { - "textRaw": "`fs.chownSync(path, uid, gid)`", - "type": "method", - "name": "chownSync", - "meta": { - "added": [ - "v0.1.97" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ + ], + "desc": "

      Truncates the file. No arguments other than a possible exception are\ngiven to the completion callback. A file descriptor can also be passed as the\nfirst argument. In this case, fs.ftruncate() is called.

      \n
      import { truncate } from 'fs';\n// Assuming that 'path/file.txt' is a regular file.\ntruncate('path/file.txt', (err) => {\n  if (err) throw err;\n  console.log('path/file.txt was truncated');\n});\n
      \n
      const { truncate } = require('fs');\n// Assuming that 'path/file.txt' is a regular file.\ntruncate('path/file.txt', (err) => {\n  if (err) throw err;\n  console.log('path/file.txt was truncated');\n});\n
      \n

      Passing a file descriptor is deprecated and may result in an error being thrown\nin the future.

      \n

      See the POSIX truncate(2) documentation for more details.

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`uid` {integer}", - "name": "uid", - "type": "integer" - }, - { - "textRaw": "`gid` {integer}", - "name": "gid", - "type": "integer" - } - ] - } - ], - "desc": "

      Synchronously changes owner and group of a file. Returns undefined.\nThis is the synchronous version of fs.chown().

      \n

      See also: chown(2).

      " - }, - { - "textRaw": "`fs.close(fd, callback)`", - "type": "method", - "name": "close", - "meta": { - "added": [ - "v0.0.2" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + "textRaw": "`fs.unlink(path, callback)`", + "type": "method", + "name": "unlink", + "meta": { + "added": [ + "v0.0.2" + ], + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" - } - ] - } - ] - } - ], - "desc": "

      Asynchronous close(2). No arguments other than a possible exception are given\nto the completion callback.

      \n

      Calling fs.close() on any file descriptor (fd) that is currently in use\nthrough any other fs operation may lead to undefined behavior.

      " - }, - { - "textRaw": "`fs.closeSync(fd)`", - "type": "method", - "name": "closeSync", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - } - ] - } - ], - "desc": "

      Synchronous close(2). Returns undefined.

      \n

      Calling fs.closeSync() on any file descriptor (fd) that is currently in use\nthrough any other fs operation may lead to undefined behavior.

      " - }, - { - "textRaw": "`fs.copyFile(src, dest[, flags], callback)`", - "type": "method", - "name": "copyFile", - "meta": { - "added": [ - "v8.5.0" - ], - "changes": [ - { - "version": "v14.0.0", - "pr-url": "https://github.com/nodejs/node/pull/27044", - "description": "Changed 'flags' argument to 'mode' and imposed stricter type validation." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`src` {string|Buffer|URL} source filename to copy", - "name": "src", - "type": "string|Buffer|URL", - "desc": "source filename to copy" - }, - { - "textRaw": "`dest` {string|Buffer|URL} destination filename of the copy operation", - "name": "dest", - "type": "string|Buffer|URL", - "desc": "destination filename of the copy operation" - }, - { - "textRaw": "`flags` {number} modifiers for copy operation. **Default:** `0`.", - "name": "flags", - "type": "number", - "default": "`0`", - "desc": "modifiers for copy operation." - }, - { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function" - } - ] - } - ], - "desc": "

      Asynchronously copies src to dest. By default, dest is overwritten if it\nalready exists. No arguments other than a possible exception are given to the\ncallback function. Node.js makes no guarantees about the atomicity of the copy\noperation. If an error occurs after the destination file has been opened for\nwriting, Node.js will attempt to remove the destination.

      \n

      flags is an optional integer that specifies the behavior\nof the copy operation. It is possible to create a mask consisting of the bitwise\nOR of two or more values (e.g.\nfs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

      \n
        \n
      • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest already\nexists.
      • \n
      • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create a\ncopy-on-write reflink. If the platform does not support copy-on-write, then a\nfallback copy mechanism is used.
      • \n
      • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to\ncreate a copy-on-write reflink. If the platform does not support copy-on-write,\nthen the operation will fail.
      • \n
      \n
      const fs = require('fs');\n\n// destination.txt will be created or overwritten by default.\nfs.copyFile('source.txt', 'destination.txt', (err) => {\n  if (err) throw err;\n  console.log('source.txt was copied to destination.txt');\n});\n
      \n

      If the third argument is a number, then it specifies flags:

      \n
      const fs = require('fs');\nconst { COPYFILE_EXCL } = fs.constants;\n\n// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.\nfs.copyFile('source.txt', 'destination.txt', COPYFILE_EXCL, callback);\n
      " - }, - { - "textRaw": "`fs.copyFileSync(src, dest[, flags])`", - "type": "method", - "name": "copyFileSync", - "meta": { - "added": [ - "v8.5.0" - ], - "changes": [ - { - "version": "v14.0.0", - "pr-url": "https://github.com/nodejs/node/pull/27044", - "description": "Changed 'flags' argument to 'mode' and imposed stricter type validation." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`src` {string|Buffer|URL} source filename to copy", - "name": "src", - "type": "string|Buffer|URL", - "desc": "source filename to copy" - }, - { - "textRaw": "`dest` {string|Buffer|URL} destination filename of the copy operation", - "name": "dest", - "type": "string|Buffer|URL", - "desc": "destination filename of the copy operation" - }, - { - "textRaw": "`flags` {number} modifiers for copy operation. **Default:** `0`.", - "name": "flags", - "type": "number", - "default": "`0`", - "desc": "modifiers for copy operation." - } - ] - } - ], - "desc": "

      Synchronously copies src to dest. By default, dest is overwritten if it\nalready exists. Returns undefined. Node.js makes no guarantees about the\natomicity of the copy operation. If an error occurs after the destination file\nhas been opened for writing, Node.js will attempt to remove the destination.

      \n

      flags is an optional integer that specifies the behavior\nof the copy operation. It is possible to create a mask consisting of the bitwise\nOR of two or more values (e.g.\nfs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

      \n
        \n
      • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest already\nexists.
      • \n
      • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create a\ncopy-on-write reflink. If the platform does not support copy-on-write, then a\nfallback copy mechanism is used.
      • \n
      • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to\ncreate a copy-on-write reflink. If the platform does not support copy-on-write,\nthen the operation will fail.
      • \n
      \n
      const fs = require('fs');\n\n// destination.txt will be created or overwritten by default.\nfs.copyFileSync('source.txt', 'destination.txt');\nconsole.log('source.txt was copied to destination.txt');\n
      \n

      If the third argument is a number, then it specifies flags:

      \n
      const fs = require('fs');\nconst { COPYFILE_EXCL } = fs.constants;\n\n// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.\nfs.copyFileSync('source.txt', 'destination.txt', COPYFILE_EXCL);\n
      " - }, - { - "textRaw": "`fs.createReadStream(path[, options])`", - "type": "method", - "name": "createReadStream", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [ - { - "version": "v12.10.0", - "pr-url": "https://github.com/nodejs/node/pull/29212", - "description": "Enable `emitClose` option." - }, - { - "version": "v11.0.0", - "pr-url": "https://github.com/nodejs/node/pull/19898", - "description": "Impose new restrictions on `start` and `end`, throwing more appropriate errors in cases when we cannot reasonably handle the input values." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7831", - "description": "The passed `options` object will never be modified." - }, - { - "version": "v2.3.0", - "pr-url": "https://github.com/nodejs/node/pull/1845", - "description": "The passed `options` object can be a string now." - }, - { - "version": "v12.17.0", - "pr-url": "https://github.com/nodejs/node/pull/29083", - "description": "The `fs` options allow overriding the used `fs` implementation." - } - ] - }, - "signatures": [ + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] + } + ], + "desc": "

      Asynchronously removes a file or symbolic link. No arguments other than a\npossible exception are given to the completion callback.

      \n
      import { unlink } from 'fs';\n// Assuming that 'path/file.txt' is a regular file.\nunlink('path/file.txt', (err) => {\n  if (err) throw err;\n  console.log('path/file.txt was deleted');\n});\n
      \n

      fs.unlink() will not work on a directory, empty or otherwise. To remove a\ndirectory, use fs.rmdir().

      \n

      See the POSIX unlink(2) documentation for more details.

      " + }, { - "return": { - "textRaw": "Returns: {fs.ReadStream} See [Readable Stream][].", - "name": "return", - "type": "fs.ReadStream", - "desc": "See [Readable Stream][]." + "textRaw": "`fs.unwatchFile(filename[, listener])`", + "type": "method", + "name": "unwatchFile", + "meta": { + "added": [ + "v0.1.31" + ], + "changes": [] }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "signatures": [ { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ + "params": [ { - "textRaw": "`flags` {string} See [support of file system `flags`][]. **Default:** `'r'`.", - "name": "flags", - "type": "string", - "default": "`'r'`", - "desc": "See [support of file system `flags`][]." + "textRaw": "`filename` {string|Buffer|URL}", + "name": "filename", + "type": "string|Buffer|URL" }, { - "textRaw": "`encoding` {string} **Default:** `null`", - "name": "encoding", - "type": "string", - "default": "`null`" - }, + "textRaw": "`listener` {Function} Optional, a listener previously attached using `fs.watchFile()`", + "name": "listener", + "type": "Function", + "desc": "Optional, a listener previously attached using `fs.watchFile()`" + } + ] + } + ], + "desc": "

      Stop watching for changes on filename. If listener is specified, only that\nparticular listener is removed. Otherwise, all listeners are removed,\neffectively stopping watching of filename.

      \n

      Calling fs.unwatchFile() with a filename that is not being watched is a\nno-op, not an error.

      \n

      Using fs.watch() is more efficient than fs.watchFile() and\nfs.unwatchFile(). fs.watch() should be used instead of fs.watchFile()\nand fs.unwatchFile() when possible.

      " + }, + { + "textRaw": "`fs.utimes(path, atime, mtime, callback)`", + "type": "method", + "name": "utimes", + "meta": { + "added": [ + "v0.4.2" + ], + "changes": [ + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v8.0.0", + "pr-url": "https://github.com/nodejs/node/pull/11919", + "description": "`NaN`, `Infinity`, and `-Infinity` are no longer valid time specifiers." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + }, + { + "version": "v4.1.0", + "pr-url": "https://github.com/nodejs/node/pull/2387", + "description": "Numeric strings, `NaN` and `Infinity` are now allowed time specifiers." + } + ] + }, + "signatures": [ + { + "params": [ { - "textRaw": "`fd` {integer} **Default:** `null`", - "name": "fd", - "type": "integer", - "default": "`null`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`mode` {integer} **Default:** `0o666`", - "name": "mode", - "type": "integer", - "default": "`0o666`" + "textRaw": "`atime` {number|string|Date}", + "name": "atime", + "type": "number|string|Date" }, { - "textRaw": "`autoClose` {boolean} **Default:** `true`", - "name": "autoClose", - "type": "boolean", - "default": "`true`" + "textRaw": "`mtime` {number|string|Date}", + "name": "mtime", + "type": "number|string|Date" }, { - "textRaw": "`emitClose` {boolean} **Default:** `false`", - "name": "emitClose", - "type": "boolean", - "default": "`false`" + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] + } + ], + "desc": "

      Change the file system timestamps of the object referenced by path.

      \n

      The atime and mtime arguments follow these rules:

      \n
        \n
      • Values can be either numbers representing Unix epoch time in seconds,\nDates, or a numeric string like '123456789.0'.
      • \n
      • If the value can not be converted to a number, or is NaN, Infinity or\n-Infinity, an Error will be thrown.
      • \n
      " + }, + { + "textRaw": "`fs.watch(filename[, options][, listener])`", + "type": "method", + "name": "watch", + "meta": { + "added": [ + "v0.5.10" + ], + "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/37190", + "description": "Added support for closing the watcher with an AbortSignal." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `filename` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7831", + "description": "The passed `options` object will never be modified." + } + ] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {fs.FSWatcher}", + "name": "return", + "type": "fs.FSWatcher" + }, + "params": [ + { + "textRaw": "`filename` {string|Buffer|URL}", + "name": "filename", + "type": "string|Buffer|URL" }, { - "textRaw": "`start` {integer}", - "name": "start", - "type": "integer" + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`persistent` {boolean} Indicates whether the process should continue to run as long as files are being watched. **Default:** `true`.", + "name": "persistent", + "type": "boolean", + "default": "`true`", + "desc": "Indicates whether the process should continue to run as long as files are being watched." + }, + { + "textRaw": "`recursive` {boolean} Indicates whether all subdirectories should be watched, or only the current directory. This applies when a directory is specified, and only on supported platforms (See [caveats][]). **Default:** `false`.", + "name": "recursive", + "type": "boolean", + "default": "`false`", + "desc": "Indicates whether all subdirectories should be watched, or only the current directory. This applies when a directory is specified, and only on supported platforms (See [caveats][])." + }, + { + "textRaw": "`encoding` {string} Specifies the character encoding to be used for the filename passed to the listener. **Default:** `'utf8'`.", + "name": "encoding", + "type": "string", + "default": "`'utf8'`", + "desc": "Specifies the character encoding to be used for the filename passed to the listener." + }, + { + "textRaw": "`signal` {AbortSignal} allows closing the watcher with an AbortSignal.", + "name": "signal", + "type": "AbortSignal", + "desc": "allows closing the watcher with an AbortSignal." + } + ] }, { - "textRaw": "`end` {integer} **Default:** `Infinity`", - "name": "end", - "type": "integer", - "default": "`Infinity`" + "textRaw": "`listener` {Function|undefined} **Default:** `undefined`", + "name": "listener", + "type": "Function|undefined", + "default": "`undefined`", + "options": [ + { + "textRaw": "`eventType` {string}", + "name": "eventType", + "type": "string" + }, + { + "textRaw": "`filename` {string|Buffer}", + "name": "filename", + "type": "string|Buffer" + } + ] + } + ] + } + ], + "desc": "

      Watch for changes on filename, where filename is either a file or a\ndirectory.

      \n

      The second argument is optional. If options is provided as a string, it\nspecifies the encoding. Otherwise options should be passed as an object.

      \n

      The listener callback gets two arguments (eventType, filename). eventType\nis either 'rename' or 'change', and filename is the name of the file\nwhich triggered the event.

      \n

      On most platforms, 'rename' is emitted whenever a filename appears or\ndisappears in the directory.

      \n

      The listener callback is attached to the 'change' event fired by\n<fs.FSWatcher>, but it is not the same thing as the 'change' value of\neventType.

      \n

      If a signal is passed, aborting the corresponding AbortController will close\nthe returned <fs.FSWatcher>.

      ", + "miscs": [ + { + "textRaw": "Caveats", + "name": "Caveats", + "type": "misc", + "desc": "

      The fs.watch API is not 100% consistent across platforms, and is\nunavailable in some situations.

      \n

      The recursive option is only supported on macOS and Windows.\nAn ERR_FEATURE_UNAVAILABLE_ON_PLATFORM exception will be thrown\nwhen the option is used on a platform that does not support it.

      \n

      On Windows, no events will be emitted if the watched directory is moved or\nrenamed. An EPERM error is reported when the watched directory is deleted.

      ", + "miscs": [ + { + "textRaw": "Availability", + "name": "Availability", + "type": "misc", + "desc": "

      This feature depends on the underlying operating system providing a way\nto be notified of filesystem changes.

      \n
        \n
      • On Linux systems, this uses inotify(7).
      • \n
      • On BSD systems, this uses kqueue(2).
      • \n
      • On macOS, this uses kqueue(2) for files and FSEvents for\ndirectories.
      • \n
      • On SunOS systems (including Solaris and SmartOS), this uses event ports.
      • \n
      • On Windows systems, this feature depends on ReadDirectoryChangesW.
      • \n
      • On AIX systems, this feature depends on AHAFS, which must be enabled.
      • \n
      • On IBM i systems, this feature is not supported.
      • \n
      \n

      If the underlying functionality is not available for some reason, then\nfs.watch() will not be able to function and may throw an exception.\nFor example, watching files or directories can be unreliable, and in some\ncases impossible, on network file systems (NFS, SMB, etc) or host file systems\nwhen using virtualization software such as Vagrant or Docker.

      \n

      It is still possible to use fs.watchFile(), which uses stat polling, but\nthis method is slower and less reliable.

      " }, { - "textRaw": "`highWaterMark` {integer} **Default:** `64 * 1024`", - "name": "highWaterMark", - "type": "integer", - "default": "`64 * 1024`" + "textRaw": "Inodes", + "name": "Inodes", + "type": "misc", + "desc": "

      On Linux and macOS systems, fs.watch() resolves the path to an inode and\nwatches the inode. If the watched path is deleted and recreated, it is assigned\na new inode. The watch will emit an event for the delete but will continue\nwatching the original inode. Events for the new inode will not be emitted.\nThis is expected behavior.

      \n

      AIX files retain the same inode for the lifetime of a file. Saving and closing a\nwatched file on AIX will result in two notifications (one for adding new\ncontent, and one for truncation).

      " }, { - "textRaw": "`fs` {Object|null} **Default:** `null`", - "name": "fs", - "type": "Object|null", - "default": "`null`" + "textRaw": "Filename argument", + "name": "Filename argument", + "type": "misc", + "desc": "

      Providing filename argument in the callback is only supported on Linux,\nmacOS, Windows, and AIX. Even on supported platforms, filename is not always\nguaranteed to be provided. Therefore, don't assume that filename argument is\nalways provided in the callback, and have some fallback logic if it is null.

      \n
      import { watch } from 'fs';\nwatch('somedir', (eventType, filename) => {\n  console.log(`event type is: ${eventType}`);\n  if (filename) {\n    console.log(`filename provided: ${filename}`);\n  } else {\n    console.log('filename not provided');\n  }\n});\n
      " } ] } ] - } - ], - "desc": "

      Unlike the 16 kb default highWaterMark for a readable stream, the stream\nreturned by this method has a default highWaterMark of 64 kb.

      \n

      options can include start and end values to read a range of bytes from\nthe file instead of the entire file. Both start and end are inclusive and\nstart counting at 0, allowed values are in the\n[0, Number.MAX_SAFE_INTEGER] range. If fd is specified and start is\nomitted or undefined, fs.createReadStream() reads sequentially from the\ncurrent file position. The encoding can be any one of those accepted by\nBuffer.

      \n

      If fd is specified, ReadStream will ignore the path argument and will use\nthe specified file descriptor. This means that no 'open' event will be\nemitted. fd should be blocking; non-blocking fds should be passed to\nnet.Socket.

      \n

      If fd points to a character device that only supports blocking reads\n(such as keyboard or sound card), read operations do not finish until data is\navailable. This can prevent the process from exiting and the stream from\nclosing naturally.

      \n

      By default, the stream will not emit a 'close' event after it has been\ndestroyed. This is the opposite of the default for other Readable streams.\nSet the emitClose option to true to change this behavior.

      \n

      By providing the fs option, it is possible to override the corresponding fs\nimplementations for open, read, and close. When providing the fs option,\noverrides for open, read, and close are required.

      \n
      const fs = require('fs');\n// Create a stream from some character device.\nconst stream = fs.createReadStream('/dev/input/event0');\nsetTimeout(() => {\n  stream.close(); // This may not close the stream.\n  // Artificially marking end-of-stream, as if the underlying resource had\n  // indicated end-of-file by itself, allows the stream to close.\n  // This does not cancel pending read operations, and if there is such an\n  // operation, the process may still not be able to exit successfully\n  // until it finishes.\n  stream.push(null);\n  stream.read(0);\n}, 100);\n
      \n

      If autoClose is false, then the file descriptor won't be closed, even if\nthere's an error. It is the application's responsibility to close it and make\nsure there's no file descriptor leak. If autoClose is set to true (default\nbehavior), on 'error' or 'end' the file descriptor will be closed\nautomatically.

      \n

      mode sets the file mode (permission and sticky bits), but only if the\nfile was created.

      \n

      An example to read the last 10 bytes of a file which is 100 bytes long:

      \n
      fs.createReadStream('sample.txt', { start: 90, end: 99 });\n
      \n

      If options is a string, then it specifies the encoding.

      " - }, - { - "textRaw": "`fs.createWriteStream(path[, options])`", - "type": "method", - "name": "createWriteStream", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [ - { - "version": "v12.10.0", - "pr-url": "https://github.com/nodejs/node/pull/29212", - "description": "Enable `emitClose` option." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7831", - "description": "The passed `options` object will never be modified." - }, - { - "version": "v5.5.0", - "pr-url": "https://github.com/nodejs/node/pull/3679", - "description": "The `autoClose` option is supported now." - }, - { - "version": "v2.3.0", - "pr-url": "https://github.com/nodejs/node/pull/1845", - "description": "The passed `options` object can be a string now." - }, - { - "version": "v12.17.0", - "pr-url": "https://github.com/nodejs/node/pull/v12.17.0", - "description": "The `fs` options allow overriding the used `fs` implementation." - } - ] - }, - "signatures": [ + }, { - "return": { - "textRaw": "Returns: {fs.WriteStream} See [Writable Stream][].", - "name": "return", - "type": "fs.WriteStream", - "desc": "See [Writable Stream][]." + "textRaw": "`fs.watchFile(filename[, options], listener)`", + "type": "method", + "name": "watchFile", + "meta": { + "added": [ + "v0.1.31" + ], + "changes": [ + { + "version": "v10.5.0", + "pr-url": "https://github.com/nodejs/node/pull/20220", + "description": "The `bigint` option is now supported." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `filename` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] }, - "params": [ + "signatures": [ { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "return": { + "textRaw": "Returns: {fs.StatWatcher}", + "name": "return", + "type": "fs.StatWatcher" + }, + "params": [ + { + "textRaw": "`filename` {string|Buffer|URL}", + "name": "filename", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`bigint` {boolean} **Default:** `false`", + "name": "bigint", + "type": "boolean", + "default": "`false`" + }, + { + "textRaw": "`persistent` {boolean} **Default:** `true`", + "name": "persistent", + "type": "boolean", + "default": "`true`" + }, + { + "textRaw": "`interval` {integer} **Default:** `5007`", + "name": "interval", + "type": "integer", + "default": "`5007`" + } + ] + }, + { + "textRaw": "`listener` {Function}", + "name": "listener", + "type": "Function", + "options": [ + { + "textRaw": "`current` {fs.Stats}", + "name": "current", + "type": "fs.Stats" + }, + { + "textRaw": "`previous` {fs.Stats}", + "name": "previous", + "type": "fs.Stats" + } + ] + } + ] + } + ], + "desc": "

      Watch for changes on filename. The callback listener will be called each\ntime the file is accessed.

      \n

      The options argument may be omitted. If provided, it should be an object. The\noptions object may contain a boolean named persistent that indicates\nwhether the process should continue to run as long as files are being watched.\nThe options object may specify an interval property indicating how often the\ntarget should be polled in milliseconds.

      \n

      The listener gets two arguments the current stat object and the previous\nstat object:

      \n
      import { watchFile } from 'fs';\n\nwatchFile('message.text', (curr, prev) => {\n  console.log(`the current mtime is: ${curr.mtime}`);\n  console.log(`the previous mtime was: ${prev.mtime}`);\n});\n
      \n

      These stat objects are instances of fs.Stat. If the bigint option is true,\nthe numeric values in these objects are specified as BigInts.

      \n

      To be notified when the file was modified, not just accessed, it is necessary\nto compare curr.mtime and prev.mtime.

      \n

      When an fs.watchFile operation results in an ENOENT error, it\nwill invoke the listener once, with all the fields zeroed (or, for dates, the\nUnix Epoch). If the file is created later on, the listener will be called\nagain, with the latest stat objects. This is a change in functionality since\nv0.10.

      \n

      Using fs.watch() is more efficient than fs.watchFile and\nfs.unwatchFile. fs.watch should be used instead of fs.watchFile and\nfs.unwatchFile when possible.

      \n

      When a file being watched by fs.watchFile() disappears and reappears,\nthen the contents of previous in the second callback event (the file's\nreappearance) will be the same as the contents of previous in the first\ncallback event (its disappearance).

      \n

      This happens when:

      \n
        \n
      • the file is deleted, followed by a restore
      • \n
      • the file is renamed and then renamed a second time back to its original name
      • \n
      " + }, + { + "textRaw": "`fs.write(fd, buffer[, offset[, length[, position]]], callback)`", + "type": "method", + "name": "write", + "meta": { + "added": [ + "v0.0.2" + ], + "changes": [ + { + "version": "v14.12.0", + "pr-url": "https://github.com/nodejs/node/pull/34993", + "description": "The `buffer` parameter will stringify an object with an explicit `toString` function." + }, + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31030", + "description": "The `buffer` parameter won't coerce unsupported input to strings anymore." + }, + { + "version": "v10.10.0", + "pr-url": "https://github.com/nodejs/node/pull/22150", + "description": "The `buffer` parameter can now be any `TypedArray` or a `DataView`." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.4.0", + "pr-url": "https://github.com/nodejs/node/pull/10382", + "description": "The `buffer` parameter can now be a `Uint8Array`." + }, + { + "version": "v7.2.0", + "pr-url": "https://github.com/nodejs/node/pull/7856", + "description": "The `offset` and `length` parameters are optional now." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] + }, + "signatures": [ { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ - { - "textRaw": "`flags` {string} See [support of file system `flags`][]. **Default:** `'w'`.", - "name": "flags", - "type": "string", - "default": "`'w'`", - "desc": "See [support of file system `flags`][]." - }, - { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", - "name": "encoding", - "type": "string", - "default": "`'utf8'`" - }, + "params": [ { - "textRaw": "`fd` {integer} **Default:** `null`", + "textRaw": "`fd` {integer}", "name": "fd", - "type": "integer", - "default": "`null`" + "type": "integer" }, { - "textRaw": "`mode` {integer} **Default:** `0o666`", - "name": "mode", - "type": "integer", - "default": "`0o666`" + "textRaw": "`buffer` {Buffer|TypedArray|DataView|string|Object}", + "name": "buffer", + "type": "Buffer|TypedArray|DataView|string|Object" }, { - "textRaw": "`autoClose` {boolean} **Default:** `true`", - "name": "autoClose", - "type": "boolean", - "default": "`true`" + "textRaw": "`offset` {integer}", + "name": "offset", + "type": "integer" }, { - "textRaw": "`emitClose` {boolean} **Default:** `false`", - "name": "emitClose", - "type": "boolean", - "default": "`false`" + "textRaw": "`length` {integer}", + "name": "length", + "type": "integer" }, { - "textRaw": "`start` {integer}", - "name": "start", + "textRaw": "`position` {integer}", + "name": "position", "type": "integer" }, { - "textRaw": "`fs` {Object|null} **Default:** `null`", - "name": "fs", - "type": "Object|null", - "default": "`null`" - } - ] - } - ] - } - ], - "desc": "

      options may also include a start option to allow writing data at\nsome position past the beginning of the file, allowed values are in the\n[0, Number.MAX_SAFE_INTEGER] range. Modifying a file rather\nthan replacing it may require a flags mode of r+ rather than the\ndefault mode w. The encoding can be any one of those accepted by\nBuffer.

      \n

      If autoClose is set to true (default behavior) on 'error' or 'finish'\nthe file descriptor will be closed automatically. If autoClose is false,\nthen the file descriptor won't be closed, even if there's an error.\nIt is the application's responsibility to close it and make sure there's no\nfile descriptor leak.

      \n

      By default, the stream will not emit a 'close' event after it has been\ndestroyed. This is the opposite of the default for other Writable streams.\nSet the emitClose option to true to change this behavior.

      \n

      By providing the fs option it is possible to override the corresponding fs\nimplementations for open, write, writev and close. Overriding write()\nwithout writev() can reduce performance as some optimizations (_writev())\nwill be disabled. When providing the fs option, overrides for open,\nclose, and at least one of write and writev are required.

      \n

      Like ReadStream, if fd is specified, WriteStream will ignore the\npath argument and will use the specified file descriptor. This means that no\n'open' event will be emitted. fd should be blocking; non-blocking fds\nshould be passed to net.Socket.

      \n

      If options is a string, then it specifies the encoding.

      " - }, - { - "textRaw": "`fs.exists(path, callback)`", - "type": "method", - "name": "exists", - "meta": { - "added": [ - "v0.0.2" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ], - "deprecated": [ - "v1.0.0" - ] - }, - "stability": 0, - "stabilityText": "Deprecated: Use [`fs.stat()`][] or [`fs.access()`][] instead.", - "signatures": [ - { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ - { - "textRaw": "`exists` {boolean}", - "name": "exists", - "type": "boolean" + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`bytesWritten` {integer}", + "name": "bytesWritten", + "type": "integer" + }, + { + "textRaw": "`buffer` {Buffer|TypedArray|DataView}", + "name": "buffer", + "type": "Buffer|TypedArray|DataView" + } + ] } ] } - ] - } - ], - "desc": "

      Test whether or not the given path exists by checking with the file system.\nThen call the callback argument with either true or false:

      \n
      fs.exists('/etc/passwd', (exists) => {\n  console.log(exists ? 'it\\'s there' : 'no passwd!');\n});\n
      \n

      The parameters for this callback are not consistent with other Node.js\ncallbacks. Normally, the first parameter to a Node.js callback is an err\nparameter, optionally followed by other parameters. The fs.exists() callback\nhas only one boolean parameter. This is one reason fs.access() is recommended\ninstead of fs.exists().

      \n

      Using fs.exists() to check for the existence of a file before calling\nfs.open(), fs.readFile() or fs.writeFile() is not recommended. Doing\nso introduces a race condition, since other processes may change the file's\nstate between the two calls. Instead, user code should open/read/write the\nfile directly and handle the error raised if the file does not exist.

      \n

      write (NOT RECOMMENDED)

      \n
      fs.exists('myfile', (exists) => {\n  if (exists) {\n    console.error('myfile already exists');\n  } else {\n    fs.open('myfile', 'wx', (err, fd) => {\n      if (err) throw err;\n      writeMyData(fd);\n    });\n  }\n});\n
      \n

      write (RECOMMENDED)

      \n
      fs.open('myfile', 'wx', (err, fd) => {\n  if (err) {\n    if (err.code === 'EEXIST') {\n      console.error('myfile already exists');\n      return;\n    }\n\n    throw err;\n  }\n\n  writeMyData(fd);\n});\n
      \n

      read (NOT RECOMMENDED)

      \n
      fs.exists('myfile', (exists) => {\n  if (exists) {\n    fs.open('myfile', 'r', (err, fd) => {\n      if (err) throw err;\n      readMyData(fd);\n    });\n  } else {\n    console.error('myfile does not exist');\n  }\n});\n
      \n

      read (RECOMMENDED)

      \n
      fs.open('myfile', 'r', (err, fd) => {\n  if (err) {\n    if (err.code === 'ENOENT') {\n      console.error('myfile does not exist');\n      return;\n    }\n\n    throw err;\n  }\n\n  readMyData(fd);\n});\n
      \n

      The \"not recommended\" examples above check for existence and then use the\nfile; the \"recommended\" examples are better because they use the file directly\nand handle the error, if any.

      \n

      In general, check for the existence of a file only if the file won’t be\nused directly, for example when its existence is a signal from another\nprocess.

      " - }, - { - "textRaw": "`fs.existsSync(path)`", - "type": "method", - "name": "existsSync", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ + ], + "desc": "

      Write buffer to the file specified by fd. If buffer is a normal object, it\nmust have an own toString function property.

      \n

      offset determines the part of the buffer to be written, and length is\nan integer specifying the number of bytes to write.

      \n

      position refers to the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number', the data will be written\nat the current position. See pwrite(2).

      \n

      The callback will be given three arguments (err, bytesWritten, buffer) where\nbytesWritten specifies how many bytes were written from buffer.

      \n

      If this method is invoked as its util.promisify()ed version, it returns\na promise for an Object with bytesWritten and buffer properties.

      \n

      It is unsafe to use fs.write() multiple times on the same file without waiting\nfor the callback. For this scenario, fs.createWriteStream() is\nrecommended.

      \n

      On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      " + }, { - "return": { - "textRaw": "Returns: {boolean}", - "name": "return", - "type": "boolean" - }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - } - ] - } - ], - "desc": "

      Returns true if the path exists, false otherwise.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.exists().

      \n

      fs.exists() is deprecated, but fs.existsSync() is not. The callback\nparameter to fs.exists() accepts parameters that are inconsistent with other\nNode.js callbacks. fs.existsSync() does not use a callback.

      \n
      if (fs.existsSync('/etc/passwd')) {\n  console.log('The path exists.');\n}\n
      " - }, - { - "textRaw": "`fs.fchmod(fd, mode, callback)`", - "type": "method", - "name": "fchmod", - "meta": { - "added": [ - "v0.4.7" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + "textRaw": "`fs.write(fd, string[, position[, encoding]], callback)`", + "type": "method", + "name": "write", + "meta": { + "added": [ + "v0.11.5" + ], + "changes": [ + { + "version": "v14.12.0", + "pr-url": "https://github.com/nodejs/node/pull/34993", + "description": "The `string` parameter will stringify an object with an explicit `toString` function." + }, + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31030", + "description": "The `string` parameter won't coerce unsupported input to strings anymore." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.2.0", + "pr-url": "https://github.com/nodejs/node/pull/7856", + "description": "The `position` parameter is optional now." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + } + ] }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`mode` {string|integer}", - "name": "mode", - "type": "string|integer" - }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`string` {string|Object}", + "name": "string", + "type": "string|Object" + }, + { + "textRaw": "`position` {integer}", + "name": "position", + "type": "integer" + }, + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`written` {integer}", + "name": "written", + "type": "integer" + }, + { + "textRaw": "`string` {string}", + "name": "string", + "type": "string" + } + ] } ] } - ] - } - ], - "desc": "

      Asynchronous fchmod(2). No arguments other than a possible exception\nare given to the completion callback.

      " - }, - { - "textRaw": "`fs.fchmodSync(fd, mode)`", - "type": "method", - "name": "fchmodSync", - "meta": { - "added": [ - "v0.4.7" - ], - "changes": [] - }, - "signatures": [ + ], + "desc": "

      Write string to the file specified by fd. If string is not a string, or an\nobject with an own toString function property, then an exception is thrown.

      \n

      position refers to the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number' the data will be written at\nthe current position. See pwrite(2).

      \n

      encoding is the expected string encoding.

      \n

      The callback will receive the arguments (err, written, string) where written\nspecifies how many bytes the passed string required to be written. Bytes\nwritten is not necessarily the same as string characters written. See\nBuffer.byteLength.

      \n

      It is unsafe to use fs.write() multiple times on the same file without waiting\nfor the callback. For this scenario, fs.createWriteStream() is\nrecommended.

      \n

      On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      \n

      On Windows, if the file descriptor is connected to the console (e.g. fd == 1\nor stdout) a string containing non-ASCII characters will not be rendered\nproperly by default, regardless of the encoding used.\nIt is possible to configure the console to render UTF-8 properly by changing the\nactive codepage with the chcp 65001 command. See the chcp docs for more\ndetails.

      " + }, { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`mode` {string|integer}", - "name": "mode", - "type": "string|integer" - } - ] - } - ], - "desc": "

      Synchronous fchmod(2). Returns undefined.

      " - }, - { - "textRaw": "`fs.fchown(fd, uid, gid, callback)`", - "type": "method", - "name": "fchown", - "meta": { - "added": [ - "v0.4.7" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + "textRaw": "`fs.writeFile(file, data[, options], callback)`", + "type": "method", + "name": "writeFile", + "meta": { + "added": [ + "v0.1.29" + ], + "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/35993", + "description": "The options argument may include an AbortSignal to abort an ongoing writeFile request." + }, + { + "version": "v14.12.0", + "pr-url": "https://github.com/nodejs/node/pull/34993", + "description": "The `data` parameter will stringify an object with an explicit `toString` function." + }, + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31030", + "description": "The `data` parameter won't coerce unsupported input to strings anymore." + }, + { + "version": "v10.10.0", + "pr-url": "https://github.com/nodejs/node/pull/22150", + "description": "The `data` parameter can now be any `TypedArray` or a `DataView`." + }, + { + "version": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/12562", + "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + }, + { + "version": "v7.4.0", + "pr-url": "https://github.com/nodejs/node/pull/10382", + "description": "The `data` parameter can now be a `Uint8Array`." + }, + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7897", + "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + }, + { + "version": "v5.0.0", + "pr-url": "https://github.com/nodejs/node/pull/3163", + "description": "The `file` parameter can be a file descriptor now." + } + ] }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`uid` {integer}", - "name": "uid", - "type": "integer" - }, - { - "textRaw": "`gid` {integer}", - "name": "gid", - "type": "integer" - }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ + { + "textRaw": "`file` {string|Buffer|URL|integer} filename or file descriptor", + "name": "file", + "type": "string|Buffer|URL|integer", + "desc": "filename or file descriptor" + }, + { + "textRaw": "`data` {string|Buffer|TypedArray|DataView|Object}", + "name": "data", + "type": "string|Buffer|TypedArray|DataView|Object" + }, + { + "textRaw": "`options` {Object|string}", + "name": "options", + "type": "Object|string", + "options": [ + { + "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", + "name": "encoding", + "type": "string|null", + "default": "`'utf8'`" + }, + { + "textRaw": "`mode` {integer} **Default:** `0o666`", + "name": "mode", + "type": "integer", + "default": "`0o666`" + }, + { + "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'w'`.", + "name": "flag", + "type": "string", + "default": "`'w'`", + "desc": "See [support of file system `flags`][]." + }, + { + "textRaw": "`signal` {AbortSignal} allows aborting an in-progress writeFile", + "name": "signal", + "type": "AbortSignal", + "desc": "allows aborting an in-progress writeFile" + } + ] + }, { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] } ] } - ] - } - ], - "desc": "

      Asynchronous fchown(2). No arguments other than a possible exception are given\nto the completion callback.

      " - }, - { - "textRaw": "`fs.fchownSync(fd, uid, gid)`", - "type": "method", - "name": "fchownSync", - "meta": { - "added": [ - "v0.4.7" - ], - "changes": [] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`uid` {integer}", - "name": "uid", - "type": "integer" - }, + ], + "desc": "

      When file is a filename, asynchronously writes data to the file, replacing the\nfile if it already exists. data can be a string or a buffer.

      \n

      When file is a file descriptor, the behavior is similar to calling\nfs.write() directly (which is recommended). See the notes below on using\na file descriptor.

      \n

      The encoding option is ignored if data is a buffer.

      \n

      The mode option only affects the newly created file. See fs.open()\nfor more details.

      \n

      If data is a plain object, it must have an own (not inherited) toString\nfunction property.

      \n
      import { writeFile } from 'fs';\n\nconst data = new Uint8Array(Buffer.from('Hello Node.js'));\nwriteFile('message.txt', data, (err) => {\n  if (err) throw err;\n  console.log('The file has been saved!');\n});\n
      \n

      If options is a string, then it specifies the encoding:

      \n
      import { writeFile } from 'fs';\n\nwriteFile('message.txt', 'Hello Node.js', 'utf8', callback);\n
      \n

      It is unsafe to use fs.writeFile() multiple times on the same file without\nwaiting for the callback. For this scenario, fs.createWriteStream() is\nrecommended.

      \n

      Similarly to fs.readFile - fs.writeFile is a convenience method that\nperforms multiple write calls internally to write the buffer passed to it.\nFor performance sensitive code consider using fs.createWriteStream().

      \n

      It is possible to use an <AbortSignal> to cancel an fs.writeFile().\nCancelation is \"best effort\", and some amount of data is likely still\nto be written.

      \n
      import { writeFile } from 'fs';\n\nconst controller = new AbortController();\nconst { signal } = controller;\nconst data = new Uint8Array(Buffer.from('Hello Node.js'));\nwriteFile('message.txt', data, { signal }, (err) => {\n  // When a request is aborted - the callback is called with an AbortError\n});\n// When the request should be aborted\ncontroller.abort();\n
      \n

      Aborting an ongoing request does not abort individual operating\nsystem requests but rather the internal buffering fs.writeFile performs.

      ", + "modules": [ { - "textRaw": "`gid` {integer}", - "name": "gid", - "type": "integer" + "textRaw": "Using `fs.writeFile()` with file descriptors", + "name": "using_`fs.writefile()`_with_file_descriptors", + "desc": "

      When file is a file descriptor, the behavior is almost identical to directly\ncalling fs.write() like:

      \n
      import { write } from 'fs';\n\nwrite(fd, Buffer.from(data, options.encoding), callback);\n
      \n

      The difference from directly calling fs.write() is that under some unusual\nconditions, fs.write() might write only part of the buffer and need to be\nretried to write the remaining data, whereas fs.writeFile() retries until\nthe data is entirely written (or an error occurs).

      \n

      The implications of this are a common source of confusion. In\nthe file descriptor case, the file is not replaced! The data is not necessarily\nwritten to the beginning of the file, and the file's original data may remain\nbefore and/or after the newly written data.

      \n

      For example, if fs.writeFile() is called twice in a row, first to write the\nstring 'Hello', then to write the string ', World', the file would contain\n'Hello, World', and might contain some of the file's original data (depending\non the size of the original file, and the position of the file descriptor). If\na file name had been used instead of a descriptor, the file would be guaranteed\nto contain only ', World'.

      ", + "type": "module", + "displayName": "Using `fs.writeFile()` with file descriptors" } ] - } - ], - "desc": "

      Synchronous fchown(2). Returns undefined.

      " - }, - { - "textRaw": "`fs.fdatasync(fd, callback)`", - "type": "method", - "name": "fdatasync", - "meta": { - "added": [ - "v0.1.96" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ + }, { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, + "textRaw": "`fs.writev(fd, buffers[, position], callback)`", + "type": "method", + "name": "writev", + "meta": { + "added": [ + "v12.9.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`buffers` {ArrayBufferView[]}", + "name": "buffers", + "type": "ArrayBufferView[]" + }, + { + "textRaw": "`position` {integer}", + "name": "position", + "type": "integer" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`bytesWritten` {integer}", + "name": "bytesWritten", + "type": "integer" + }, + { + "textRaw": "`buffers` {ArrayBufferView[]}", + "name": "buffers", + "type": "ArrayBufferView[]" + } + ] } ] } - ] + ], + "desc": "

      Write an array of ArrayBufferViews to the file specified by fd using\nwritev().

      \n

      position is the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number', the data will be written\nat the current position.

      \n

      The callback will be given three arguments: err, bytesWritten, and\nbuffers. bytesWritten is how many bytes were written from buffers.

      \n

      If this method is util.promisify()ed, it returns a promise for an\nObject with bytesWritten and buffers properties.

      \n

      It is unsafe to use fs.writev() multiple times on the same file without\nwaiting for the callback. For this scenario, use fs.createWriteStream().

      \n

      On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      " } ], - "desc": "

      Asynchronous fdatasync(2). No arguments other than a possible exception are\ngiven to the completion callback.

      " + "type": "module", + "displayName": "Callback API" }, { - "textRaw": "`fs.fdatasyncSync(fd)`", - "type": "method", - "name": "fdatasyncSync", - "meta": { - "added": [ - "v0.1.96" - ], - "changes": [] - }, - "signatures": [ + "textRaw": "Synchronous API", + "name": "synchronous_api", + "desc": "

      The synchronous APIs perform all operations synchronously, blocking the\nevent loop until the operation completes or fails.

      ", + "methods": [ { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - } - ] - } - ], - "desc": "

      Synchronous fdatasync(2). Returns undefined.

      " - }, - { - "textRaw": "`fs.fstat(fd[, options], callback)`", - "type": "method", - "name": "fstat", - "meta": { - "added": [ - "v0.1.95" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + "textRaw": "`fs.accessSync(path[, mode])`", + "type": "method", + "name": "accessSync", + "meta": { + "added": [ + "v0.11.15" + ], + "changes": [ + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] }, - { - "version": "v10.5.0", - "pr-url": "https://github.com/nodejs/node/pull/20220", - "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, + "signatures": [ { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, { - "textRaw": "`bigint` {boolean} Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`. **Default:** `false`.", - "name": "bigint", - "type": "boolean", - "default": "`false`", - "desc": "Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`." + "textRaw": "`mode` {integer} **Default:** `fs.constants.F_OK`", + "name": "mode", + "type": "integer", + "default": "`fs.constants.F_OK`" } ] - }, + } + ], + "desc": "

      Synchronously tests a user's permissions for the file or directory specified\nby path. The mode argument is an optional integer that specifies the\naccessibility checks to be performed. Check File access constants for\npossible values of mode. It is possible to create a mask consisting of\nthe bitwise OR of two or more values\n(e.g. fs.constants.W_OK | fs.constants.R_OK).

      \n

      If any of the accessibility checks fail, an Error will be thrown. Otherwise,\nthe method will return undefined.

      \n
      import { accessSync, constants } from 'fs';\n\ntry {\n  accessSync('etc/passwd', constants.R_OK | constants.W_OK);\n  console.log('can read/write');\n} catch (err) {\n  console.error('no access!');\n}\n
      " + }, + { + "textRaw": "`fs.appendFileSync(path, data[, options])`", + "type": "method", + "name": "appendFileSync", + "meta": { + "added": [ + "v0.6.7" + ], + "changes": [ + { + "version": "v7.0.0", + "pr-url": "https://github.com/nodejs/node/pull/7831", + "description": "The passed `options` object will never be modified." + }, + { + "version": "v5.0.0", + "pr-url": "https://github.com/nodejs/node/pull/3163", + "description": "The `file` parameter can be a file descriptor now." + } + ] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`path` {string|Buffer|URL|number} filename or file descriptor", + "name": "path", + "type": "string|Buffer|URL|number", + "desc": "filename or file descriptor" + }, + { + "textRaw": "`data` {string|Buffer}", + "name": "data", + "type": "string|Buffer" }, { - "textRaw": "`stats` {fs.Stats}", - "name": "stats", - "type": "fs.Stats" + "textRaw": "`options` {Object|string}", + "name": "options", + "type": "Object|string", + "options": [ + { + "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", + "name": "encoding", + "type": "string|null", + "default": "`'utf8'`" + }, + { + "textRaw": "`mode` {integer} **Default:** `0o666`", + "name": "mode", + "type": "integer", + "default": "`0o666`" + }, + { + "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'a'`.", + "name": "flag", + "type": "string", + "default": "`'a'`", + "desc": "See [support of file system `flags`][]." + } + ] } ] } - ] - } - ], - "desc": "

      Asynchronous fstat(2). The callback gets two arguments (err, stats) where\nstats is an fs.Stats object. fstat() is identical to stat(),\nexcept that the file to be stat-ed is specified by the file descriptor fd.

      " - }, - { - "textRaw": "`fs.fstatSync(fd[, options])`", - "type": "method", - "name": "fstatSync", - "meta": { - "added": [ - "v0.1.95" - ], - "changes": [ - { - "version": "v10.5.0", - "pr-url": "https://github.com/nodejs/node/pull/20220", - "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." - } - ] - }, - "signatures": [ + ], + "desc": "

      Synchronously append data to a file, creating the file if it does not yet\nexist. data can be a string or a <Buffer>.

      \n

      The mode option only affects the newly created file. See fs.open()\nfor more details.

      \n
      import { appendFileSync } from 'fs';\n\ntry {\n  appendFileSync('message.txt', 'data to append');\n  console.log('The \"data to append\" was appended to file!');\n} catch (err) {\n  /* Handle the error */\n}\n
      \n

      If options is a string, then it specifies the encoding:

      \n
      import { appendFileSync } from 'fs';\n\nappendFileSync('message.txt', 'data to append', 'utf8');\n
      \n

      The path may be specified as a numeric file descriptor that has been opened\nfor appending (using fs.open() or fs.openSync()). The file descriptor will\nnot be closed automatically.

      \n
      import { openSync, closeSync, appendFileSync } from 'fs';\n\nlet fd;\n\ntry {\n  fd = openSync('message.txt', 'a');\n  appendFileSync(fd, 'data to append', 'utf8');\n} catch (err) {\n  /* Handle the error */\n} finally {\n  if (fd !== undefined)\n    closeSync(fd);\n}\n
      " + }, { - "return": { - "textRaw": "Returns: {fs.Stats}", - "name": "return", - "type": "fs.Stats" + "textRaw": "`fs.chmodSync(path, mode)`", + "type": "method", + "name": "chmodSync", + "meta": { + "added": [ + "v0.6.7" + ], + "changes": [ + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] }, - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, + "signatures": [ { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, { - "textRaw": "`bigint` {boolean} Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`. **Default:** `false`.", - "name": "bigint", - "type": "boolean", - "default": "`false`", - "desc": "Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`." + "textRaw": "`mode` {string|integer}", + "name": "mode", + "type": "string|integer" } ] } - ] - } - ], - "desc": "

      Synchronous fstat(2).

      " - }, - { - "textRaw": "`fs.fsync(fd, callback)`", - "type": "method", - "name": "fsync", - "meta": { - "added": [ - "v0.1.96" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ + ], + "desc": "

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.chmod().

      \n

      See the POSIX chmod(2) documentation for more detail.

      " + }, { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, + "textRaw": "`fs.chownSync(path, uid, gid)`", + "type": "method", + "name": "chownSync", + "meta": { + "added": [ + "v0.1.97" + ], + "changes": [ + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`uid` {integer}", + "name": "uid", + "type": "integer" + }, + { + "textRaw": "`gid` {integer}", + "name": "gid", + "type": "integer" } ] } - ] - } - ], - "desc": "

      Asynchronous fsync(2). No arguments other than a possible exception are given\nto the completion callback.

      " - }, - { - "textRaw": "`fs.fsyncSync(fd)`", - "type": "method", - "name": "fsyncSync", - "meta": { - "added": [ - "v0.1.96" - ], - "changes": [] - }, - "signatures": [ + ], + "desc": "

      Synchronously changes owner and group of a file. Returns undefined.\nThis is the synchronous version of fs.chown().

      \n

      See the POSIX chown(2) documentation for more detail.

      " + }, { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - } - ] - } - ], - "desc": "

      Synchronous fsync(2). Returns undefined.

      " - }, - { - "textRaw": "`fs.ftruncate(fd[, len], callback)`", - "type": "method", - "name": "ftruncate", - "meta": { - "added": [ - "v0.8.6" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + "textRaw": "`fs.closeSync(fd)`", + "type": "method", + "name": "closeSync", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [] }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`len` {integer} **Default:** `0`", - "name": "len", - "type": "integer", - "default": "`0`" - }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" } ] } - ] - } - ], - "desc": "

      Asynchronous ftruncate(2). No arguments other than a possible exception are\ngiven to the completion callback.

      \n

      If the file referred to by the file descriptor was larger than len bytes, only\nthe first len bytes will be retained in the file.

      \n

      For example, the following program retains only the first four bytes of the\nfile:

      \n
      console.log(fs.readFileSync('temp.txt', 'utf8'));\n// Prints: Node.js\n\n// get the file descriptor of the file to be truncated\nconst fd = fs.openSync('temp.txt', 'r+');\n\n// Truncate the file to first four bytes\nfs.ftruncate(fd, 4, (err) => {\n  assert.ifError(err);\n  console.log(fs.readFileSync('temp.txt', 'utf8'));\n});\n// Prints: Node\n
      \n

      If the file previously was shorter than len bytes, it is extended, and the\nextended part is filled with null bytes ('\\0'):

      \n
      console.log(fs.readFileSync('temp.txt', 'utf8'));\n// Prints: Node.js\n\n// get the file descriptor of the file to be truncated\nconst fd = fs.openSync('temp.txt', 'r+');\n\n// Truncate the file to 10 bytes, whereas the actual size is 7 bytes\nfs.ftruncate(fd, 10, (err) => {\n  assert.ifError(err);\n  console.log(fs.readFileSync('temp.txt'));\n});\n// Prints: <Buffer 4e 6f 64 65 2e 6a 73 00 00 00>\n// ('Node.js\\0\\0\\0' in UTF8)\n
      \n

      The last three bytes are null bytes ('\\0'), to compensate the over-truncation.

      " - }, - { - "textRaw": "`fs.ftruncateSync(fd[, len])`", - "type": "method", - "name": "ftruncateSync", - "meta": { - "added": [ - "v0.8.6" - ], - "changes": [] - }, - "signatures": [ + ], + "desc": "

      Closes the file descriptor. Returns undefined.

      \n

      Calling fs.closeSync() on any file descriptor (fd) that is currently in use\nthrough any other fs operation may lead to undefined behavior.

      \n

      See the POSIX close(2) documentation for more detail.

      " + }, { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`len` {integer} **Default:** `0`", - "name": "len", - "type": "integer", - "default": "`0`" - } - ] - } - ], - "desc": "

      Returns undefined.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.ftruncate().

      " - }, - { - "textRaw": "`fs.futimes(fd, atime, mtime, callback)`", - "type": "method", - "name": "futimes", - "meta": { - "added": [ - "v0.4.2" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + "textRaw": "`fs.copyFileSync(src, dest[, mode])`", + "type": "method", + "name": "copyFileSync", + "meta": { + "added": [ + "v8.5.0" + ], + "changes": [ + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/27044", + "description": "Changed 'flags' argument to 'mode' and imposed stricter type validation." + } + ] }, - { - "version": "v4.1.0", - "pr-url": "https://github.com/nodejs/node/pull/2387", - "description": "Numeric strings, `NaN` and `Infinity` are now allowed time specifiers." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`atime` {number|string|Date}", - "name": "atime", - "type": "number|string|Date" - }, - { - "textRaw": "`mtime` {number|string|Date}", - "name": "mtime", - "type": "number|string|Date" - }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`src` {string|Buffer|URL} source filename to copy", + "name": "src", + "type": "string|Buffer|URL", + "desc": "source filename to copy" + }, + { + "textRaw": "`dest` {string|Buffer|URL} destination filename of the copy operation", + "name": "dest", + "type": "string|Buffer|URL", + "desc": "destination filename of the copy operation" + }, + { + "textRaw": "`mode` {integer} modifiers for copy operation. **Default:** `0`.", + "name": "mode", + "type": "integer", + "default": "`0`", + "desc": "modifiers for copy operation." } ] } - ] - } - ], - "desc": "

      Change the file system timestamps of the object referenced by the supplied file\ndescriptor. See fs.utimes().

      \n

      This function does not work on AIX versions before 7.1, it will return the\nerror UV_ENOSYS.

      " - }, - { - "textRaw": "`fs.futimesSync(fd, atime, mtime)`", - "type": "method", - "name": "futimesSync", - "meta": { - "added": [ - "v0.4.2" - ], - "changes": [ - { - "version": "v4.1.0", - "pr-url": "https://github.com/nodejs/node/pull/2387", - "description": "Numeric strings, `NaN` and `Infinity` are now allowed time specifiers." - } - ] - }, - "signatures": [ + ], + "desc": "

      Synchronously copies src to dest. By default, dest is overwritten if it\nalready exists. Returns undefined. Node.js makes no guarantees about the\natomicity of the copy operation. If an error occurs after the destination file\nhas been opened for writing, Node.js will attempt to remove the destination.

      \n

      mode is an optional integer that specifies the behavior\nof the copy operation. It is possible to create a mask consisting of the bitwise\nOR of two or more values (e.g.\nfs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE).

      \n
        \n
      • fs.constants.COPYFILE_EXCL: The copy operation will fail if dest already\nexists.
      • \n
      • fs.constants.COPYFILE_FICLONE: The copy operation will attempt to create a\ncopy-on-write reflink. If the platform does not support copy-on-write, then a\nfallback copy mechanism is used.
      • \n
      • fs.constants.COPYFILE_FICLONE_FORCE: The copy operation will attempt to\ncreate a copy-on-write reflink. If the platform does not support\ncopy-on-write, then the operation will fail.
      • \n
      \n
      import { copyFileSync, constants } from 'fs';\n\n// destination.txt will be created or overwritten by default.\ncopyFileSync('source.txt', 'destination.txt');\nconsole.log('source.txt was copied to destination.txt');\n\n// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.\ncopyFileSync('source.txt', 'destination.txt', constants.COPYFILE_EXCL);\n
      " + }, { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`atime` {number|string|Date}", - "name": "atime", - "type": "number|string|Date" - }, - { - "textRaw": "`mtime` {number|string|Date}", - "name": "mtime", - "type": "number|string|Date" - } - ] - } - ], - "desc": "

      Synchronous version of fs.futimes(). Returns undefined.

      " - }, - { - "textRaw": "`fs.lchmod(path, mode, callback)`", - "type": "method", - "name": "lchmod", - "meta": { - "deprecated": [ - "v0.4.7" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." + "textRaw": "`fs.existsSync(path)`", + "type": "method", + "name": "existsSync", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [ + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`mode` {integer}", - "name": "mode", - "type": "integer" - }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" } ] } - ] - } - ], - "desc": "

      Asynchronous lchmod(2). No arguments other than a possible exception\nare given to the completion callback.

      \n

      Only available on macOS.

      " - }, - { - "textRaw": "`fs.lchmodSync(path, mode)`", - "type": "method", - "name": "lchmodSync", - "meta": { - "deprecated": [ - "v0.4.7" - ], - "changes": [] - }, - "signatures": [ + ], + "desc": "

      Returns true if the path exists, false otherwise.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.exists().

      \n

      fs.exists() is deprecated, but fs.existsSync() is not. The callback\nparameter to fs.exists() accepts parameters that are inconsistent with other\nNode.js callbacks. fs.existsSync() does not use a callback.

      \n
      import { existsSync } from 'fs';\n\nif (existsSync('/etc/passwd'))\n  console.log('The path exists.');\n
      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`mode` {integer}", - "name": "mode", - "type": "integer" - } - ] - } - ], - "desc": "

      Synchronous lchmod(2). Returns undefined.

      " - }, - { - "textRaw": "`fs.lchown(path, uid, gid, callback)`", - "type": "method", - "name": "lchown", - "meta": { - "changes": [ - { - "version": "v10.6.0", - "pr-url": "https://github.com/nodejs/node/pull/21498", - "description": "This API is no longer deprecated." - }, - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." + "textRaw": "`fs.fchmodSync(fd, mode)`", + "type": "method", + "name": "fchmodSync", + "meta": { + "added": [ + "v0.4.7" + ], + "changes": [] }, - { - "version": "v0.4.7", - "description": "Documentation-only deprecation." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`uid` {integer}", - "name": "uid", - "type": "integer" - }, - { - "textRaw": "`gid` {integer}", - "name": "gid", - "type": "integer" - }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`mode` {string|integer}", + "name": "mode", + "type": "string|integer" } ] } - ] - } - ], - "desc": "

      Asynchronous lchown(2). No arguments other than a possible exception are given\nto the completion callback.

      " - }, - { - "textRaw": "`fs.lchownSync(path, uid, gid)`", - "type": "method", - "name": "lchownSync", - "meta": { - "changes": [ - { - "version": "v10.6.0", - "pr-url": "https://github.com/nodejs/node/pull/21498", - "description": "This API is no longer deprecated." - }, - { - "version": "v0.4.7", - "description": "Documentation-only deprecation." - } - ] - }, - "signatures": [ + ], + "desc": "

      Sets the permissions on the file. Returns undefined.

      \n

      See the POSIX fchmod(2) documentation for more detail.

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`uid` {integer}", - "name": "uid", - "type": "integer" - }, + "textRaw": "`fs.fchownSync(fd, uid, gid)`", + "type": "method", + "name": "fchownSync", + "meta": { + "added": [ + "v0.4.7" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`gid` {integer}", - "name": "gid", - "type": "integer" + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`uid` {integer} The file's new owner's user id.", + "name": "uid", + "type": "integer", + "desc": "The file's new owner's user id." + }, + { + "textRaw": "`gid` {integer} The file's new group's group id.", + "name": "gid", + "type": "integer", + "desc": "The file's new group's group id." + } + ] } - ] - } - ], - "desc": "

      Synchronous lchown(2). Returns undefined.

      " - }, - { - "textRaw": "`fs.lutimes(path, atime, mtime, callback)`", - "type": "method", - "name": "lutimes", - "meta": { - "added": [ - "v12.19.0" - ], - "changes": [] - }, - "signatures": [ + ], + "desc": "

      Sets the owner of the file. Returns undefined.

      \n

      See the POSIX fchown(2) documentation for more detail.

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`atime` {number|string|Date}", - "name": "atime", - "type": "number|string|Date" - }, - { - "textRaw": "`mtime` {number|string|Date}", - "name": "mtime", - "type": "number|string|Date" - }, + "textRaw": "`fs.fdatasyncSync(fd)`", + "type": "method", + "name": "fdatasyncSync", + "meta": { + "added": [ + "v0.1.96" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" } ] } - ] - } - ], - "desc": "

      Changes the access and modification times of a file in the same way as\nfs.utimes(), with the difference that if the path refers to a symbolic\nlink, then the link is not dereferenced: instead, the timestamps of the\nsymbolic link itself are changed.

      \n

      No arguments other than a possible exception are given to the completion\ncallback.

      " - }, - { - "textRaw": "`fs.lutimesSync(path, atime, mtime)`", - "type": "method", - "name": "lutimesSync", - "meta": { - "added": [ - "v12.19.0" - ], - "changes": [] - }, - "signatures": [ + ], + "desc": "

      Forces all currently queued I/O operations associated with the file to the\noperating system's synchronized I/O completion state. Refer to the POSIX\nfdatasync(2) documentation for details. Returns undefined.

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`atime` {number|string|Date}", - "name": "atime", - "type": "number|string|Date" - }, + "textRaw": "`fs.fstatSync(fd[, options])`", + "type": "method", + "name": "fstatSync", + "meta": { + "added": [ + "v0.1.95" + ], + "changes": [ + { + "version": "v10.5.0", + "pr-url": "https://github.com/nodejs/node/pull/20220", + "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." + } + ] + }, + "signatures": [ { - "textRaw": "`mtime` {number|string|Date}", - "name": "mtime", - "type": "number|string|Date" + "return": { + "textRaw": "Returns: {fs.Stats}", + "name": "return", + "type": "fs.Stats" + }, + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`bigint` {boolean} Whether the numeric values in the returned {fs.Stats} object should be `bigint`. **Default:** `false`.", + "name": "bigint", + "type": "boolean", + "default": "`false`", + "desc": "Whether the numeric values in the returned {fs.Stats} object should be `bigint`." + } + ] + } + ] } - ] - } - ], - "desc": "

      Change the file system timestamps of the symbolic link referenced by path.\nReturns undefined, or throws an exception when parameters are incorrect or\nthe operation fails. This is the synchronous version of fs.lutimes().

      " - }, - { - "textRaw": "`fs.link(existingPath, newPath, callback)`", - "type": "method", - "name": "link", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `existingPath` and `newPath` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ + ], + "desc": "

      Retrieves the <fs.Stats> for the file descriptor.

      \n

      See the POSIX fstat(2) documentation for more detail.

      " + }, { - "params": [ - { - "textRaw": "`existingPath` {string|Buffer|URL}", - "name": "existingPath", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`newPath` {string|Buffer|URL}", - "name": "newPath", - "type": "string|Buffer|URL" - }, + "textRaw": "`fs.fsyncSync(fd)`", + "type": "method", + "name": "fsyncSync", + "meta": { + "added": [ + "v0.1.96" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" } ] } - ] - } - ], - "desc": "

      Asynchronous link(2). No arguments other than a possible exception are given to\nthe completion callback.

      " - }, - { - "textRaw": "`fs.linkSync(existingPath, newPath)`", - "type": "method", - "name": "linkSync", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `existingPath` and `newPath` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ + ], + "desc": "

      Request that all data for the open file descriptor is flushed to the storage\ndevice. The specific implementation is operating system and device specific.\nRefer to the POSIX fsync(2) documentation for more detail. Returns undefined.

      " + }, { - "params": [ - { - "textRaw": "`existingPath` {string|Buffer|URL}", - "name": "existingPath", - "type": "string|Buffer|URL" - }, + "textRaw": "`fs.ftruncateSync(fd[, len])`", + "type": "method", + "name": "ftruncateSync", + "meta": { + "added": [ + "v0.8.6" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`newPath` {string|Buffer|URL}", - "name": "newPath", - "type": "string|Buffer|URL" + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`len` {integer} **Default:** `0`", + "name": "len", + "type": "integer", + "default": "`0`" + } + ] } - ] - } - ], - "desc": "

      Synchronous link(2). Returns undefined.

      " - }, - { - "textRaw": "`fs.lstat(path[, options], callback)`", - "type": "method", - "name": "lstat", - "meta": { - "added": [ - "v0.1.30" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - }, - { - "version": "v10.5.0", - "pr-url": "https://github.com/nodejs/node/pull/20220", - "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." - } - ] - }, - "signatures": [ + ], + "desc": "

      Truncates the file descriptor. Returns undefined.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.ftruncate().

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "textRaw": "`fs.futimesSync(fd, atime, mtime)`", + "type": "method", + "name": "futimesSync", + "meta": { + "added": [ + "v0.4.2" + ], + "changes": [ + { + "version": "v4.1.0", + "pr-url": "https://github.com/nodejs/node/pull/2387", + "description": "Numeric strings, `NaN` and `Infinity` are now allowed time specifiers." + } + ] + }, + "signatures": [ { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`atime` {number|string|Date}", + "name": "atime", + "type": "number|string|Date" + }, { - "textRaw": "`bigint` {boolean} Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`. **Default:** `false`.", - "name": "bigint", - "type": "boolean", - "default": "`false`", - "desc": "Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`." + "textRaw": "`mtime` {number|string|Date}", + "name": "mtime", + "type": "number|string|Date" } ] - }, + } + ], + "desc": "

      Synchronous version of fs.futimes(). Returns undefined.

      " + }, + { + "textRaw": "`fs.lchmodSync(path, mode)`", + "type": "method", + "name": "lchmodSync", + "meta": { + "deprecated": [ + "v0.4.7" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`stats` {fs.Stats}", - "name": "stats", - "type": "fs.Stats" + "textRaw": "`mode` {integer}", + "name": "mode", + "type": "integer" } ] } - ] - } - ], - "desc": "

      Asynchronous lstat(2). The callback gets two arguments (err, stats) where\nstats is a fs.Stats object. lstat() is identical to stat(),\nexcept that if path is a symbolic link, then the link itself is stat-ed,\nnot the file that it refers to.

      " - }, - { - "textRaw": "`fs.lstatSync(path[, options])`", - "type": "method", - "name": "lstatSync", - "meta": { - "added": [ - "v0.1.30" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v10.5.0", - "pr-url": "https://github.com/nodejs/node/pull/20220", - "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." - } - ] - }, - "signatures": [ + ], + "desc": "

      Changes the permissions on a symbolic link. Returns undefined.

      \n

      This method is only implemented on macOS.

      \n

      See the POSIX lchmod(2) documentation for more detail.

      " + }, { - "return": { - "textRaw": "Returns: {fs.Stats}", - "name": "return", - "type": "fs.Stats" + "textRaw": "`fs.lchownSync(path, uid, gid)`", + "type": "method", + "name": "lchownSync", + "meta": { + "changes": [ + { + "version": "v10.6.0", + "pr-url": "https://github.com/nodejs/node/pull/21498", + "description": "This API is no longer deprecated." + }, + { + "version": "v0.4.7", + "description": "Documentation-only deprecation." + } + ] }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "signatures": [ { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`uid` {integer} The file's new owner's user id.", + "name": "uid", + "type": "integer", + "desc": "The file's new owner's user id." + }, { - "textRaw": "`bigint` {boolean} Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`. **Default:** `false`.", - "name": "bigint", - "type": "boolean", - "default": "`false`", - "desc": "Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`." + "textRaw": "`gid` {integer} The file's new group's group id.", + "name": "gid", + "type": "integer", + "desc": "The file's new group's group id." } ] } - ] - } - ], - "desc": "

      Synchronous lstat(2).

      " - }, - { - "textRaw": "`fs.mkdir(path[, options], callback)`", - "type": "method", - "name": "mkdir", - "meta": { - "added": [ - "v0.1.8" - ], - "changes": [ - { - "version": "v12.17.0", - "pr-url": "https://github.com/nodejs/node/pull/31530", - "description": "In `recursive` mode, the callback now receives the first created path as an argument." - }, - { - "version": "v10.12.0", - "pr-url": "https://github.com/nodejs/node/pull/21875", - "description": "The second argument can now be an `options` object with `recursive` and `mode` properties." - }, - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ + ], + "desc": "

      Set the owner for the path. Returns undefined.

      \n

      See the POSIX lchown(2) documentation for more details.

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "textRaw": "`fs.lutimesSync(path, atime, mtime)`", + "type": "method", + "name": "lutimesSync", + "meta": { + "added": [ + "v14.5.0", + "v12.19.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`options` {Object|integer}", - "name": "options", - "type": "Object|integer", - "options": [ + "params": [ + { + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, { - "textRaw": "`recursive` {boolean} **Default:** `false`", - "name": "recursive", - "type": "boolean", - "default": "`false`" + "textRaw": "`atime` {number|string|Date}", + "name": "atime", + "type": "number|string|Date" }, { - "textRaw": "`mode` {string|integer} Not supported on Windows. **Default:** `0o777`.", - "name": "mode", - "type": "string|integer", - "default": "`0o777`", - "desc": "Not supported on Windows." + "textRaw": "`mtime` {number|string|Date}", + "name": "mtime", + "type": "number|string|Date" } ] - }, + } + ], + "desc": "

      Change the file system timestamps of the symbolic link referenced by path.\nReturns undefined, or throws an exception when parameters are incorrect or\nthe operation fails. This is the synchronous version of fs.lutimes().

      " + }, + { + "textRaw": "`fs.linkSync(existingPath, newPath)`", + "type": "method", + "name": "linkSync", + "meta": { + "added": [ + "v0.1.31" + ], + "changes": [ + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `existingPath` and `newPath` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." + } + ] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`existingPath` {string|Buffer|URL}", + "name": "existingPath", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`newPath` {string|Buffer|URL}", + "name": "newPath", + "type": "string|Buffer|URL" } ] } - ] - } - ], - "desc": "

      Asynchronously creates a directory.

      \n

      The callback is given a possible exception and, if recursive is true, the\nfirst directory path created, (err, [path]).

      \n

      The optional options argument can be an integer specifying mode (permission\nand sticky bits), or an object with a mode property and a recursive\nproperty indicating whether parent directories should be created. Calling\nfs.mkdir() when path is a directory that exists results in an error only\nwhen recursive is false.

      \n
      // Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist.\nfs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {\n  if (err) throw err;\n});\n
      \n

      On Windows, using fs.mkdir() on the root directory even with recursion will\nresult in an error:

      \n
      fs.mkdir('/', { recursive: true }, (err) => {\n  // => [Error: EPERM: operation not permitted, mkdir 'C:\\']\n});\n
      \n

      See also: mkdir(2).

      " - }, - { - "textRaw": "`fs.mkdirSync(path[, options])`", - "type": "method", - "name": "mkdirSync", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [ - { - "version": "v12.17.0", - "pr-url": "https://github.com/nodejs/node/pull/31530", - "description": "In `recursive` mode, the first created path is returned now." - }, - { - "version": "v10.12.0", - "pr-url": "https://github.com/nodejs/node/pull/21875", - "description": "The second argument can now be an `options` object with `recursive` and `mode` properties." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ + ], + "desc": "

      Creates a new link from the existingPath to the newPath. See the POSIX\nlink(2) documentation for more detail. Returns undefined.

      " + }, { - "return": { - "textRaw": "Returns: {string|undefined}", - "name": "return", - "type": "string|undefined" + "textRaw": "`fs.lstatSync(path[, options])`", + "type": "method", + "name": "lstatSync", + "meta": { + "added": [ + "v0.1.30" + ], + "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/33716", + "description": "Accepts a `throwIfNoEntry` option to specify whether an exception should be thrown if the entry does not exist." + }, + { + "version": "v10.5.0", + "pr-url": "https://github.com/nodejs/node/pull/20220", + "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "signatures": [ { - "textRaw": "`options` {Object|integer}", - "name": "options", - "type": "Object|integer", - "options": [ + "return": { + "textRaw": "Returns: {fs.Stats}", + "name": "return", + "type": "fs.Stats" + }, + "params": [ { - "textRaw": "`recursive` {boolean} **Default:** `false`", - "name": "recursive", - "type": "boolean", - "default": "`false`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`mode` {string|integer} Not supported on Windows. **Default:** `0o777`.", - "name": "mode", - "type": "string|integer", - "default": "`0o777`", - "desc": "Not supported on Windows." + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`bigint` {boolean} Whether the numeric values in the returned {fs.Stats} object should be `bigint`. **Default:** `false`.", + "name": "bigint", + "type": "boolean", + "default": "`false`", + "desc": "Whether the numeric values in the returned {fs.Stats} object should be `bigint`." + }, + { + "textRaw": "`throwIfNoEntry` {boolean} Whether an exception will be thrown if no file system entry exists, rather than returning `undefined`. **Default:** `true`.", + "name": "throwIfNoEntry", + "type": "boolean", + "default": "`true`", + "desc": "Whether an exception will be thrown if no file system entry exists, rather than returning `undefined`." + } + ] } ] } - ] - } - ], - "desc": "

      Synchronously creates a directory. Returns undefined, or if recursive is\ntrue, the first directory path created.\nThis is the synchronous version of fs.mkdir().

      \n

      See also: mkdir(2).

      " - }, - { - "textRaw": "`fs.mkdtemp(prefix[, options], callback)`", - "type": "method", - "name": "mkdtemp", - "meta": { - "added": [ - "v5.10.0" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - }, - { - "version": "v6.2.1", - "pr-url": "https://github.com/nodejs/node/pull/6828", - "description": "The `callback` parameter is optional now." - } - ] - }, - "signatures": [ + ], + "desc": "

      Retrieves the <fs.Stats> for the symbolic link referred to by path.

      \n

      See the POSIX lstat(2) documentation for more details.

      " + }, { - "params": [ - { - "textRaw": "`prefix` {string}", - "name": "prefix", - "type": "string" - }, + "textRaw": "`fs.mkdirSync(path[, options])`", + "type": "method", + "name": "mkdirSync", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [ + { + "version": [ + "v13.11.0", + "v12.17.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/31530", + "description": "In `recursive` mode, the first created path is returned now." + }, + { + "version": "v10.12.0", + "pr-url": "https://github.com/nodejs/node/pull/21875", + "description": "The second argument can now be an `options` object with `recursive` and `mode` properties." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] + }, + "signatures": [ { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ + "return": { + "textRaw": "Returns: {string|undefined}", + "name": "return", + "type": "string|undefined" + }, + "params": [ { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", - "name": "encoding", - "type": "string", - "default": "`'utf8'`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {Object|integer}", + "name": "options", + "type": "Object|integer", + "options": [ + { + "textRaw": "`recursive` {boolean} **Default:** `false`", + "name": "recursive", + "type": "boolean", + "default": "`false`" + }, + { + "textRaw": "`mode` {string|integer} Not supported on Windows. **Default:** `0o777`.", + "name": "mode", + "type": "string|integer", + "default": "`0o777`", + "desc": "Not supported on Windows." + } + ] } ] - }, + } + ], + "desc": "

      Synchronously creates a directory. Returns undefined, or if recursive is\ntrue, the first directory path created.\nThis is the synchronous version of fs.mkdir().

      \n

      See the POSIX mkdir(2) documentation for more details.

      " + }, + { + "textRaw": "`fs.mkdtempSync(prefix[, options])`", + "type": "method", + "name": "mkdtempSync", + "meta": { + "added": [ + "v5.10.0" + ], + "changes": [ + { + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/39028", + "description": "The `prefix` parameter now accepts an empty string." + } + ] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "return": { + "textRaw": "Returns: {string}", + "name": "return", + "type": "string" + }, + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`prefix` {string}", + "name": "prefix", + "type": "string" }, { - "textRaw": "`directory` {string}", - "name": "directory", - "type": "string" + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + } + ] } ] } - ] - } - ], - "desc": "

      Creates a unique temporary directory.

      \n

      Generates six random characters to be appended behind a required\nprefix to create a unique temporary directory. Due to platform\ninconsistencies, avoid trailing X characters in prefix. Some platforms,\nnotably the BSDs, can return more than six random characters, and replace\ntrailing X characters in prefix with random characters.

      \n

      The created directory path is passed as a string to the callback's second\nparameter.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use.

      \n
      fs.mkdtemp(path.join(os.tmpdir(), 'foo-'), (err, directory) => {\n  if (err) throw err;\n  console.log(directory);\n  // Prints: /tmp/foo-itXde2 or C:\\Users\\...\\AppData\\Local\\Temp\\foo-itXde2\n});\n
      \n

      The fs.mkdtemp() method will append the six randomly selected characters\ndirectly to the prefix string. For instance, given a directory /tmp, if the\nintention is to create a temporary directory within /tmp, the prefix\nmust end with a trailing platform-specific path separator\n(require('path').sep).

      \n
      // The parent directory for the new temporary directory\nconst tmpDir = os.tmpdir();\n\n// This method is *INCORRECT*:\nfs.mkdtemp(tmpDir, (err, directory) => {\n  if (err) throw err;\n  console.log(directory);\n  // Will print something similar to `/tmpabc123`.\n  // A new temporary directory is created at the file system root\n  // rather than *within* the /tmp directory.\n});\n\n// This method is *CORRECT*:\nconst { sep } = require('path');\nfs.mkdtemp(`${tmpDir}${sep}`, (err, directory) => {\n  if (err) throw err;\n  console.log(directory);\n  // Will print something similar to `/tmp/abc123`.\n  // A new temporary directory is created within\n  // the /tmp directory.\n});\n
      " - }, - { - "textRaw": "`fs.mkdtempSync(prefix[, options])`", - "type": "method", - "name": "mkdtempSync", - "meta": { - "added": [ - "v5.10.0" - ], - "changes": [] - }, - "signatures": [ + ], + "desc": "

      Returns the created directory path.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.mkdtemp().

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use.

      " + }, { - "return": { - "textRaw": "Returns: {string}", - "name": "return", - "type": "string" + "textRaw": "`fs.opendirSync(path[, options])`", + "type": "method", + "name": "opendirSync", + "meta": { + "added": [ + "v12.12.0" + ], + "changes": [ + { + "version": [ + "v13.1.0", + "v12.16.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/30114", + "description": "The `bufferSize` option was introduced." + } + ] }, - "params": [ - { - "textRaw": "`prefix` {string}", - "name": "prefix", - "type": "string" - }, + "signatures": [ { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ + "return": { + "textRaw": "Returns: {fs.Dir}", + "name": "return", + "type": "fs.Dir" + }, + "params": [ { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", - "name": "encoding", - "type": "string", - "default": "`'utf8'`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", + "name": "encoding", + "type": "string|null", + "default": "`'utf8'`" + }, + { + "textRaw": "`bufferSize` {number} Number of directory entries that are buffered internally when reading from the directory. Higher values lead to better performance but higher memory usage. **Default:** `32`", + "name": "bufferSize", + "type": "number", + "default": "`32`", + "desc": "Number of directory entries that are buffered internally when reading from the directory. Higher values lead to better performance but higher memory usage." + } + ] } ] } - ] - } - ], - "desc": "

      Returns the created directory path.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.mkdtemp().

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use.

      " - }, - { - "textRaw": "`fs.open(path[, flags[, mode]], callback)`", - "type": "method", - "name": "open", - "meta": { - "added": [ - "v0.0.2" - ], - "changes": [ - { - "version": "v11.1.0", - "pr-url": "https://github.com/nodejs/node/pull/23767", - "description": "The `flags` argument is now optional and defaults to `'r'`." - }, - { - "version": "v9.9.0", - "pr-url": "https://github.com/nodejs/node/pull/18801", - "description": "The `as` and `as+` modes are supported now." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ + ], + "desc": "

      Synchronously open a directory. See opendir(3).

      \n

      Creates an <fs.Dir>, which contains all further functions for reading from\nand cleaning up the directory.

      \n

      The encoding option sets the encoding for the path while opening the\ndirectory and subsequent read operations.

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`flags` {string|number} See [support of file system `flags`][]. **Default:** `'r'`.", - "name": "flags", - "type": "string|number", - "default": "`'r'`", - "desc": "See [support of file system `flags`][]." - }, - { - "textRaw": "`mode` {string|integer} **Default:** `0o666` (readable and writable)", - "name": "mode", - "type": "string|integer", - "default": "`0o666` (readable and writable)" - }, + "textRaw": "`fs.openSync(path[, flags[, mode]])`", + "type": "method", + "name": "openSync", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [ + { + "version": "v11.1.0", + "pr-url": "https://github.com/nodejs/node/pull/23767", + "description": "The `flags` argument is now optional and defaults to `'r'`." + }, + { + "version": "v9.9.0", + "pr-url": "https://github.com/nodejs/node/pull/18801", + "description": "The `as` and `as+` flags are supported now." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "return": { + "textRaw": "Returns: {number}", + "name": "return", + "type": "number" + }, + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" + "textRaw": "`flags` {string|number} **Default:** `'r'`. See [support of file system `flags`][].", + "name": "flags", + "type": "string|number", + "default": "`'r'`. See [support of file system `flags`][]" + }, + { + "textRaw": "`mode` {string|integer} **Default:** `0o666`", + "name": "mode", + "type": "string|integer", + "default": "`0o666`" } ] } - ] - } - ], - "desc": "

      Asynchronous file open. See open(2).

      \n

      mode sets the file mode (permission and sticky bits), but only if the file was\ncreated. On Windows, only the write permission can be manipulated; see\nfs.chmod().

      \n

      The callback gets two arguments (err, fd).

      \n

      Some characters (< > : \" / \\ | ? *) are reserved under Windows as documented\nby Naming Files, Paths, and Namespaces. Under NTFS, if the filename contains\na colon, Node.js will open a file system stream, as described by\nthis MSDN page.

      \n

      Functions based on fs.open() exhibit this behavior as well:\nfs.writeFile(), fs.readFile(), etc.

      " - }, - { - "textRaw": "`fs.opendir(path[, options], callback)`", - "type": "method", - "name": "opendir", - "meta": { - "added": [ - "v12.12.0" - ], - "changes": [ - { - "version": "v12.16.0", - "pr-url": "https://github.com/nodejs/node/pull/30114", - "description": "The `bufferSize` option was introduced." - } - ] - }, - "signatures": [ + ], + "desc": "

      Returns an integer representing the file descriptor.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.open().

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "textRaw": "`fs.readdirSync(path[, options])`", + "type": "method", + "name": "readdirSync", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [ + { + "version": "v10.10.0", + "pr-url": "https://github.com/nodejs/node/pull/22020", + "description": "New option `withFileTypes` was added." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] + }, + "signatures": [ { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ + "return": { + "textRaw": "Returns: {string[]|Buffer[]|fs.Dirent[]}", + "name": "return", + "type": "string[]|Buffer[]|fs.Dirent[]" + }, + "params": [ { - "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", - "name": "encoding", - "type": "string|null", - "default": "`'utf8'`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`bufferSize` {number} Number of directory entries that are buffered internally when reading from the directory. Higher values lead to better performance but higher memory usage. **Default:** `32`", - "name": "bufferSize", - "type": "number", - "default": "`32`", - "desc": "Number of directory entries that are buffered internally when reading from the directory. Higher values lead to better performance but higher memory usage." + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + }, + { + "textRaw": "`withFileTypes` {boolean} **Default:** `false`", + "name": "withFileTypes", + "type": "boolean", + "default": "`false`" + } + ] } ] - }, + } + ], + "desc": "

      Reads the contents of the directory.

      \n

      See the POSIX readdir(3) documentation for more details.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe filenames returned. If the encoding is set to 'buffer',\nthe filenames returned will be passed as <Buffer> objects.

      \n

      If options.withFileTypes is set to true, the result will contain\n<fs.Dirent> objects.

      " + }, + { + "textRaw": "`fs.readFileSync(path[, options])`", + "type": "method", + "name": "readFileSync", + "meta": { + "added": [ + "v0.1.8" + ], + "changes": [ + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v5.0.0", + "pr-url": "https://github.com/nodejs/node/pull/3163", + "description": "The `path` parameter can be a file descriptor now." + } + ] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "return": { + "textRaw": "Returns: {string|Buffer}", + "name": "return", + "type": "string|Buffer" + }, + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`path` {string|Buffer|URL|integer} filename or file descriptor", + "name": "path", + "type": "string|Buffer|URL|integer", + "desc": "filename or file descriptor" }, { - "textRaw": "`dir` {fs.Dir}", - "name": "dir", - "type": "fs.Dir" + "textRaw": "`options` {Object|string}", + "name": "options", + "type": "Object|string", + "options": [ + { + "textRaw": "`encoding` {string|null} **Default:** `null`", + "name": "encoding", + "type": "string|null", + "default": "`null`" + }, + { + "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'r'`.", + "name": "flag", + "type": "string", + "default": "`'r'`", + "desc": "See [support of file system `flags`][]." + } + ] } ] } - ] - } - ], - "desc": "

      Asynchronously open a directory. See opendir(3).

      \n

      Creates an fs.Dir, which contains all further functions for reading from\nand cleaning up the directory.

      \n

      The encoding option sets the encoding for the path while opening the\ndirectory and subsequent read operations.

      " - }, - { - "textRaw": "`fs.opendirSync(path[, options])`", - "type": "method", - "name": "opendirSync", - "meta": { - "added": [ - "v12.12.0" - ], - "changes": [ - { - "version": "v12.16.0", - "pr-url": "https://github.com/nodejs/node/pull/30114", - "description": "The `bufferSize` option was introduced." - } - ] - }, - "signatures": [ + ], + "desc": "

      Returns the contents of the path.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.readFile().

      \n

      If the encoding option is specified then this function returns a\nstring. Otherwise it returns a buffer.

      \n

      Similar to fs.readFile(), when the path is a directory, the behavior of\nfs.readFileSync() is platform-specific.

      \n
      import { readFileSync } from 'fs';\n\n// macOS, Linux, and Windows\nreadFileSync('<directory>');\n// => [Error: EISDIR: illegal operation on a directory, read <directory>]\n\n//  FreeBSD\nreadFileSync('<directory>'); // => <data>\n
      " + }, { - "return": { - "textRaw": "Returns: {fs.Dir}", - "name": "return", - "type": "fs.Dir" + "textRaw": "`fs.readlinkSync(path[, options])`", + "type": "method", + "name": "readlinkSync", + "meta": { + "added": [ + "v0.1.31" + ], + "changes": [ + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "signatures": [ { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ + "return": { + "textRaw": "Returns: {string|Buffer}", + "name": "return", + "type": "string|Buffer" + }, + "params": [ { - "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", - "name": "encoding", - "type": "string|null", - "default": "`'utf8'`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`bufferSize` {number} Number of directory entries that are buffered internally when reading from the directory. Higher values lead to better performance but higher memory usage. **Default:** `32`", - "name": "bufferSize", - "type": "number", - "default": "`32`", - "desc": "Number of directory entries that are buffered internally when reading from the directory. Higher values lead to better performance but higher memory usage." + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + } + ] } ] } - ] - } - ], - "desc": "

      Synchronously open a directory. See opendir(3).

      \n

      Creates an fs.Dir, which contains all further functions for reading from\nand cleaning up the directory.

      \n

      The encoding option sets the encoding for the path while opening the\ndirectory and subsequent read operations.

      " - }, - { - "textRaw": "`fs.openSync(path[, flags, mode])`", - "type": "method", - "name": "openSync", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [ - { - "version": "v11.1.0", - "pr-url": "https://github.com/nodejs/node/pull/23767", - "description": "The `flags` argument is now optional and defaults to `'r'`." - }, - { - "version": "v9.9.0", - "pr-url": "https://github.com/nodejs/node/pull/18801", - "description": "The `as` and `as+` modes are supported now." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ + ], + "desc": "

      Returns the symbolic link's string value.

      \n

      See the POSIX readlink(2) documentation for more details.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe link path returned. If the encoding is set to 'buffer',\nthe link path returned will be passed as a <Buffer> object.

      " + }, { - "return": { - "textRaw": "Returns: {number}", - "name": "return", - "type": "number" - }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`flags` {string|number} **Default:** `'r'`. See [support of file system `flags`][].", - "name": "flags", - "type": "string|number", - "default": "`'r'`. See [support of file system `flags`][]" - }, - { - "textRaw": "`mode` {string|integer} **Default:** `0o666`", - "name": "mode", - "type": "string|integer", - "default": "`0o666`" - } - ] - } - ], - "desc": "

      Returns an integer representing the file descriptor.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.open().

      " - }, - { - "textRaw": "`fs.read(fd, buffer, offset, length, position, callback)`", - "type": "method", - "name": "read", - "meta": { - "added": [ - "v0.0.2" - ], - "changes": [ - { - "version": "v10.10.0", - "pr-url": "https://github.com/nodejs/node/pull/22150", - "description": "The `buffer` parameter can now be any `TypedArray`, or a `DataView`." - }, - { - "version": "v7.4.0", - "pr-url": "https://github.com/nodejs/node/pull/10382", - "description": "The `buffer` parameter can now be a `Uint8Array`." + "textRaw": "`fs.readSync(fd, buffer, offset, length, position)`", + "type": "method", + "name": "readSync", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [ + { + "version": "v10.10.0", + "pr-url": "https://github.com/nodejs/node/pull/22150", + "description": "The `buffer` parameter can now be any `TypedArray` or a `DataView`." + }, + { + "version": "v6.0.0", + "pr-url": "https://github.com/nodejs/node/pull/4518", + "description": "The `length` parameter can now be `0`." + } + ] }, - { - "version": "v6.0.0", - "pr-url": "https://github.com/nodejs/node/pull/4518", - "description": "The `length` parameter can now be `0`." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`buffer` {Buffer|TypedArray|DataView}", - "name": "buffer", - "type": "Buffer|TypedArray|DataView" - }, - { - "textRaw": "`offset` {integer}", - "name": "offset", - "type": "integer" - }, - { - "textRaw": "`length` {integer}", - "name": "length", - "type": "integer" - }, - { - "textRaw": "`position` {integer}", - "name": "position", - "type": "integer" - }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ - { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" - }, + "return": { + "textRaw": "Returns: {number}", + "name": "return", + "type": "number" + }, + "params": [ { - "textRaw": "`bytesRead` {integer}", - "name": "bytesRead", + "textRaw": "`fd` {integer}", + "name": "fd", "type": "integer" }, { - "textRaw": "`buffer` {Buffer}", - "name": "buffer", - "type": "Buffer" - } - ] - } - ] - } - ], - "desc": "

      Read data from the file specified by fd.

      \n

      buffer is the buffer that the data (read from the fd) will be written to.

      \n

      offset is the offset in the buffer to start writing at.

      \n

      length is an integer specifying the number of bytes to read.

      \n

      position is an argument specifying where to begin reading from in the file.\nIf position is null, data will be read from the current file position,\nand the file position will be updated.\nIf position is an integer, the file position will remain unchanged.

      \n

      The callback is given the three arguments, (err, bytesRead, buffer).

      \n

      If this method is invoked as its util.promisify()ed version, it returns\na Promise for an Object with bytesRead and buffer properties.

      " - }, - { - "textRaw": "`fs.read(fd, [options,] callback)`", - "type": "method", - "name": "read", - "meta": { - "added": [ - "v12.17.0" - ], - "changes": [ - { - "version": "v12.17.0", - "pr-url": "https://github.com/nodejs/node/pull/31402", - "description": "Options object can be passed in to make Buffer, offset, length and position optional" - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ - { - "textRaw": "`buffer` {Buffer|TypedArray|DataView} **Default:** `Buffer.alloc(16384)`", + "textRaw": "`buffer` {Buffer|TypedArray|DataView}", "name": "buffer", - "type": "Buffer|TypedArray|DataView", - "default": "`Buffer.alloc(16384)`" + "type": "Buffer|TypedArray|DataView" }, { - "textRaw": "`offset` {integer} **Default:** `0`", + "textRaw": "`offset` {integer}", "name": "offset", - "type": "integer", - "default": "`0`" + "type": "integer" }, { - "textRaw": "`length` {integer} **Default:** `buffer.length`", + "textRaw": "`length` {integer}", "name": "length", - "type": "integer", - "default": "`buffer.length`" + "type": "integer" }, { - "textRaw": "`position` {integer} **Default:** `null`", + "textRaw": "`position` {integer|bigint}", "name": "position", - "type": "integer", - "default": "`null`" + "type": "integer|bigint" } ] - }, + } + ], + "desc": "

      Returns the number of bytesRead.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.read().

      " + }, + { + "textRaw": "`fs.readSync(fd, buffer, [options])`", + "type": "method", + "name": "readSync", + "meta": { + "added": [ + "v13.13.0", + "v12.17.0" + ], + "changes": [ + { + "version": [ + "v13.13.0", + "v12.17.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/32460", + "description": "Options object can be passed in to make offset, length and position optional." + } + ] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ - { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" - }, + "return": { + "textRaw": "Returns: {number}", + "name": "return", + "type": "number" + }, + "params": [ { - "textRaw": "`bytesRead` {integer}", - "name": "bytesRead", + "textRaw": "`fd` {integer}", + "name": "fd", "type": "integer" }, { - "textRaw": "`buffer` {Buffer}", + "textRaw": "`buffer` {Buffer|TypedArray|DataView}", "name": "buffer", - "type": "Buffer" + "type": "Buffer|TypedArray|DataView" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`offset` {integer} **Default:** `0`", + "name": "offset", + "type": "integer", + "default": "`0`" + }, + { + "textRaw": "`length` {integer} **Default:** `buffer.byteLength`", + "name": "length", + "type": "integer", + "default": "`buffer.byteLength`" + }, + { + "textRaw": "`position` {integer|bigint} **Default:** `null`", + "name": "position", + "type": "integer|bigint", + "default": "`null`" + } + ] } ] } - ] - } - ], - "desc": "

      Similar to the above fs.read function, this version takes an optional options object.\nIf no options object is specified, it will default with the above values.

      " - }, - { - "textRaw": "`fs.readdir(path[, options], callback)`", - "type": "method", - "name": "readdir", - "meta": { - "added": [ - "v0.1.8" - ], - "changes": [ - { - "version": "v10.10.0", - "pr-url": "https://github.com/nodejs/node/pull/22020", - "description": "New option `withFileTypes` was added." - }, - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - }, - { - "version": "v6.0.0", - "pr-url": "https://github.com/nodejs/node/pull/5616", - "description": "The `options` parameter was added." - } - ] - }, - "signatures": [ + ], + "desc": "

      Returns the number of bytesRead.

      \n

      Similar to the above fs.readSync function, this version takes an optional options object.\nIf no options object is specified, it will default with the above values.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.read().

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "textRaw": "`fs.readvSync(fd, buffers[, position])`", + "type": "method", + "name": "readvSync", + "meta": { + "added": [ + "v13.13.0", + "v12.17.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ + "return": { + "textRaw": "Returns: {number} The number of bytes read.", + "name": "return", + "type": "number", + "desc": "The number of bytes read." + }, + "params": [ { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", - "name": "encoding", - "type": "string", - "default": "`'utf8'`" + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" }, { - "textRaw": "`withFileTypes` {boolean} **Default:** `false`", - "name": "withFileTypes", - "type": "boolean", - "default": "`false`" - } - ] - }, - { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ - { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`buffers` {ArrayBufferView[]}", + "name": "buffers", + "type": "ArrayBufferView[]" }, { - "textRaw": "`files` {string[]|Buffer[]|fs.Dirent[]}", - "name": "files", - "type": "string[]|Buffer[]|fs.Dirent[]" + "textRaw": "`position` {integer}", + "name": "position", + "type": "integer" } ] } - ] - } - ], - "desc": "

      Asynchronous readdir(3). Reads the contents of a directory.\nThe callback gets two arguments (err, files) where files is an array of\nthe names of the files in the directory excluding '.' and '..'.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe filenames passed to the callback. If the encoding is set to 'buffer',\nthe filenames returned will be passed as Buffer objects.

      \n

      If options.withFileTypes is set to true, the files array will contain\nfs.Dirent objects.

      " - }, - { - "textRaw": "`fs.readdirSync(path[, options])`", - "type": "method", - "name": "readdirSync", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [ - { - "version": "v10.10.0", - "pr-url": "https://github.com/nodejs/node/pull/22020", - "description": "New option `withFileTypes` was added." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ + ], + "desc": "

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.readv().

      " + }, { - "return": { - "textRaw": "Returns: {string[]|Buffer[]|fs.Dirent[]}", - "name": "return", - "type": "string[]|Buffer[]|fs.Dirent[]" + "textRaw": "`fs.realpathSync(path[, options])`", + "type": "method", + "name": "realpathSync", + "meta": { + "added": [ + "v0.1.31" + ], + "changes": [ + { + "version": "v8.0.0", + "pr-url": "https://github.com/nodejs/node/pull/13028", + "description": "Pipe/Socket resolve support was added." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v6.4.0", + "pr-url": "https://github.com/nodejs/node/pull/7899", + "description": "Calling `realpathSync` now works again for various edge cases on Windows." + }, + { + "version": "v6.0.0", + "pr-url": "https://github.com/nodejs/node/pull/3594", + "description": "The `cache` parameter was removed." + } + ] }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "signatures": [ { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ + "return": { + "textRaw": "Returns: {string|Buffer}", + "name": "return", + "type": "string|Buffer" + }, + "params": [ { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", - "name": "encoding", - "type": "string", - "default": "`'utf8'`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`withFileTypes` {boolean} **Default:** `false`", - "name": "withFileTypes", - "type": "boolean", - "default": "`false`" + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + } + ] } ] } - ] - } - ], - "desc": "

      Synchronous readdir(3).

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe filenames returned. If the encoding is set to 'buffer',\nthe filenames returned will be passed as Buffer objects.

      \n

      If options.withFileTypes is set to true, the result will contain\nfs.Dirent objects.

      " - }, - { - "textRaw": "`fs.readFile(path[, options], callback)`", - "type": "method", - "name": "readFile", - "meta": { - "added": [ - "v0.1.29" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - }, - { - "version": "v5.1.0", - "pr-url": "https://github.com/nodejs/node/pull/3740", - "description": "The `callback` will always be called with `null` as the `error` parameter in case of success." - }, - { - "version": "v5.0.0", - "pr-url": "https://github.com/nodejs/node/pull/3163", - "description": "The `path` parameter can be a file descriptor now." - } - ] - }, - "signatures": [ + ], + "desc": "

      Returns the resolved pathname.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.realpath().

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL|integer} filename or file descriptor", - "name": "path", - "type": "string|Buffer|URL|integer", - "desc": "filename or file descriptor" - }, + "textRaw": "`fs.realpathSync.native(path[, options])`", + "type": "method", + "name": "native", + "meta": { + "added": [ + "v9.2.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`options` {Object|string}", - "name": "options", - "type": "Object|string", - "options": [ + "return": { + "textRaw": "Returns: {string|Buffer}", + "name": "return", + "type": "string|Buffer" + }, + "params": [ { - "textRaw": "`encoding` {string|null} **Default:** `null`", - "name": "encoding", - "type": "string|null", - "default": "`null`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'r'`.", - "name": "flag", - "type": "string", - "default": "`'r'`", - "desc": "See [support of file system `flags`][]." + "textRaw": "`options` {string|Object}", + "name": "options", + "type": "string|Object", + "options": [ + { + "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "name": "encoding", + "type": "string", + "default": "`'utf8'`" + } + ] } ] - }, + } + ], + "desc": "

      Synchronous realpath(3).

      \n

      Only paths that can be converted to UTF8 strings are supported.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe path returned. If the encoding is set to 'buffer',\nthe path returned will be passed as a <Buffer> object.

      \n

      On Linux, when Node.js is linked against musl libc, the procfs file system must\nbe mounted on /proc in order for this function to work. Glibc does not have\nthis restriction.

      " + }, + { + "textRaw": "`fs.renameSync(oldPath, newPath)`", + "type": "method", + "name": "renameSync", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [ + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `oldPath` and `newPath` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." + } + ] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`oldPath` {string|Buffer|URL}", + "name": "oldPath", + "type": "string|Buffer|URL" }, { - "textRaw": "`data` {string|Buffer}", - "name": "data", - "type": "string|Buffer" + "textRaw": "`newPath` {string|Buffer|URL}", + "name": "newPath", + "type": "string|Buffer|URL" } ] } - ] - } - ], - "desc": "

      Asynchronously reads the entire contents of a file.

      \n
      fs.readFile('/etc/passwd', (err, data) => {\n  if (err) throw err;\n  console.log(data);\n});\n
      \n

      The callback is passed two arguments (err, data), where data is the\ncontents of the file.

      \n

      If no encoding is specified, then the raw buffer is returned.

      \n

      If options is a string, then it specifies the encoding:

      \n
      fs.readFile('/etc/passwd', 'utf8', callback);\n
      \n

      When the path is a directory, the behavior of fs.readFile() and\nfs.readFileSync() is platform-specific. On macOS, Linux, and Windows, an\nerror will be returned. On FreeBSD, a representation of the directory's contents\nwill be returned.

      \n
      // macOS, Linux, and Windows\nfs.readFile('<directory>', (err, data) => {\n  // => [Error: EISDIR: illegal operation on a directory, read <directory>]\n});\n\n//  FreeBSD\nfs.readFile('<directory>', (err, data) => {\n  // => null, <data>\n});\n
      \n

      The fs.readFile() function buffers the entire file. To minimize memory costs,\nwhen possible prefer streaming via fs.createReadStream().

      ", - "modules": [ - { - "textRaw": "File descriptors", - "name": "file_descriptors", - "desc": "
        \n
      1. Any specified file descriptor has to support reading.
      2. \n
      3. If a file descriptor is specified as the path, it will not be closed\nautomatically.
      4. \n
      5. The reading will begin at the current position. For example, if the file\nalready had 'Hello World' and six bytes are read with the file descriptor,\nthe call to fs.readFile() with the same file descriptor, would give\n'World', rather than 'Hello World'.
      6. \n
      ", - "type": "module", - "displayName": "File descriptors" - } - ] - }, - { - "textRaw": "`fs.readFileSync(path[, options])`", - "type": "method", - "name": "readFileSync", - "meta": { - "added": [ - "v0.1.8" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v5.0.0", - "pr-url": "https://github.com/nodejs/node/pull/3163", - "description": "The `path` parameter can be a file descriptor now." - } - ] - }, - "signatures": [ + ], + "desc": "

      Renames the file from oldPath to newPath. Returns undefined.

      \n

      See the POSIX rename(2) documentation for more details.

      " + }, { - "return": { - "textRaw": "Returns: {string|Buffer}", - "name": "return", - "type": "string|Buffer" + "textRaw": "`fs.rmdirSync(path[, options])`", + "type": "method", + "name": "rmdirSync", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [ + { + "version": "v14.14.0", + "pr-url": "https://github.com/nodejs/node/pull/35579", + "description": "The `recursive` option is deprecated, use `fs.rmSync` instead." + }, + { + "version": [ + "v13.3.0", + "v12.16.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/30644", + "description": "The `maxBusyTries` option is renamed to `maxRetries`, and its default is 0. The `emfileWait` option has been removed, and `EMFILE` errors use the same retry logic as other errors. The `retryDelay` option is now supported. `ENFILE` errors are now retried." + }, + { + "version": "v12.10.0", + "pr-url": "https://github.com/nodejs/node/pull/29168", + "description": "The `recursive`, `maxBusyTries`, and `emfileWait` options are now supported." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameters can be a WHATWG `URL` object using `file:` protocol." + } + ] }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL|integer} filename or file descriptor", - "name": "path", - "type": "string|Buffer|URL|integer", - "desc": "filename or file descriptor" - }, + "signatures": [ { - "textRaw": "`options` {Object|string}", - "name": "options", - "type": "Object|string", - "options": [ + "params": [ { - "textRaw": "`encoding` {string|null} **Default:** `null`", - "name": "encoding", - "type": "string|null", - "default": "`null`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'r'`.", - "name": "flag", - "type": "string", - "default": "`'r'`", - "desc": "See [support of file system `flags`][]." + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js retries the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`. **Default:** `0`.", + "name": "maxRetries", + "type": "integer", + "default": "`0`", + "desc": "If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js retries the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`." + }, + { + "textRaw": "`recursive` {boolean} If `true`, perform a recursive directory removal. In recursive mode, errors are not reported if `path` does not exist, and operations are retried on failure. **Default:** `false`.", + "name": "recursive", + "type": "boolean", + "default": "`false`", + "desc": "If `true`, perform a recursive directory removal. In recursive mode, errors are not reported if `path` does not exist, and operations are retried on failure." + }, + { + "textRaw": "`retryDelay` {integer} The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`. **Default:** `100`.", + "name": "retryDelay", + "type": "integer", + "default": "`100`", + "desc": "The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`." + } + ] } ] } - ] - } - ], - "desc": "

      Returns the contents of the path.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.readFile().

      \n

      If the encoding option is specified then this function returns a\nstring. Otherwise it returns a buffer.

      \n

      Similar to fs.readFile(), when the path is a directory, the behavior of\nfs.readFileSync() is platform-specific.

      \n
      // macOS, Linux, and Windows\nfs.readFileSync('<directory>');\n// => [Error: EISDIR: illegal operation on a directory, read <directory>]\n\n//  FreeBSD\nfs.readFileSync('<directory>'); // => <data>\n
      " - }, - { - "textRaw": "`fs.readlink(path[, options], callback)`", - "type": "method", - "name": "readlink", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ + ], + "desc": "

      Synchronous rmdir(2). Returns undefined.

      \n

      Using fs.rmdirSync() on a file (not a directory) results in an ENOENT error\non Windows and an ENOTDIR error on POSIX.

      \n

      Setting recursive to true results in behavior similar to the Unix command\nrm -rf: an error will not be raised for paths that do not exist, and paths\nthat represent files will be deleted. The permissive behavior of the\nrecursive option is deprecated, ENOTDIR and ENOENT will be thrown in\nthe future.

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ - { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", - "name": "encoding", - "type": "string", - "default": "`'utf8'`" - } - ] - }, + "textRaw": "`fs.rmSync(path[, options])`", + "type": "method", + "name": "rmSync", + "meta": { + "added": [ + "v14.14.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`linkString` {string|Buffer}", - "name": "linkString", - "type": "string|Buffer" + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`force` {boolean} When `true`, exceptions will be ignored if `path` does not exist. **Default:** `false`.", + "name": "force", + "type": "boolean", + "default": "`false`", + "desc": "When `true`, exceptions will be ignored if `path` does not exist." + }, + { + "textRaw": "`maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`. **Default:** `0`.", + "name": "maxRetries", + "type": "integer", + "default": "`0`", + "desc": "If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` milliseconds longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`." + }, + { + "textRaw": "`recursive` {boolean} If `true`, perform a recursive directory removal. In recursive mode operations are retried on failure. **Default:** `false`.", + "name": "recursive", + "type": "boolean", + "default": "`false`", + "desc": "If `true`, perform a recursive directory removal. In recursive mode operations are retried on failure." + }, + { + "textRaw": "`retryDelay` {integer} The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`. **Default:** `100`.", + "name": "retryDelay", + "type": "integer", + "default": "`100`", + "desc": "The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`." + } + ] } ] } - ] - } - ], - "desc": "

      Asynchronous readlink(2). The callback gets two arguments (err, linkString).

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe link path passed to the callback. If the encoding is set to 'buffer',\nthe link path returned will be passed as a Buffer object.

      " - }, - { - "textRaw": "`fs.readlinkSync(path[, options])`", - "type": "method", - "name": "readlinkSync", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ + ], + "desc": "

      Synchronously removes files and directories (modeled on the standard POSIX rm\nutility). Returns undefined.

      " + }, { - "return": { - "textRaw": "Returns: {string|Buffer}", - "name": "return", - "type": "string|Buffer" + "textRaw": "`fs.statSync(path[, options])`", + "type": "method", + "name": "statSync", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/33716", + "description": "Accepts a `throwIfNoEntry` option to specify whether an exception should be thrown if the entry does not exist." + }, + { + "version": "v10.5.0", + "pr-url": "https://github.com/nodejs/node/pull/20220", + "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "signatures": [ { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ + "return": { + "textRaw": "Returns: {fs.Stats}", + "name": "return", + "type": "fs.Stats" + }, + "params": [ { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", - "name": "encoding", - "type": "string", - "default": "`'utf8'`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" + }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`bigint` {boolean} Whether the numeric values in the returned {fs.Stats} object should be `bigint`. **Default:** `false`.", + "name": "bigint", + "type": "boolean", + "default": "`false`", + "desc": "Whether the numeric values in the returned {fs.Stats} object should be `bigint`." + }, + { + "textRaw": "`throwIfNoEntry` {boolean} Whether an exception will be thrown if no file system entry exists, rather than returning `undefined`. **Default:** `true`.", + "name": "throwIfNoEntry", + "type": "boolean", + "default": "`true`", + "desc": "Whether an exception will be thrown if no file system entry exists, rather than returning `undefined`." + } + ] } ] } - ] - } - ], - "desc": "

      Synchronous readlink(2). Returns the symbolic link's string value.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe link path returned. If the encoding is set to 'buffer',\nthe link path returned will be passed as a Buffer object.

      " - }, - { - "textRaw": "`fs.readSync(fd, buffer, offset, length, position)`", - "type": "method", - "name": "readSync", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [ - { - "version": "v10.10.0", - "pr-url": "https://github.com/nodejs/node/pull/22150", - "description": "The `buffer` parameter can now be any `TypedArray` or a `DataView`." - }, - { - "version": "v6.0.0", - "pr-url": "https://github.com/nodejs/node/pull/4518", - "description": "The `length` parameter can now be `0`." - } - ] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {number}", - "name": "return", - "type": "number" - }, - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`buffer` {Buffer|TypedArray|DataView}", - "name": "buffer", - "type": "Buffer|TypedArray|DataView" - }, - { - "textRaw": "`offset` {integer}", - "name": "offset", - "type": "integer" - }, - { - "textRaw": "`length` {integer}", - "name": "length", - "type": "integer" - }, - { - "textRaw": "`position` {integer}", - "name": "position", - "type": "integer" - } - ] - } - ], - "desc": "

      Returns the number of bytesRead.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.read().

      " - }, - { - "textRaw": "`fs.readSync(fd, buffer, [options])`", - "type": "method", - "name": "readSync", - "meta": { - "added": [ - "v12.17.0" - ], - "changes": [ - { - "version": "v12.17.0", - "pr-url": "https://github.com/nodejs/node/pull/32460", - "description": "Options object can be passed in to make offset, length and position optional" - } - ] - }, - "signatures": [ + ], + "desc": "

      Retrieves the <fs.Stats> for the path.

      " + }, { - "return": { - "textRaw": "Returns: {number}", - "name": "return", - "type": "number" + "textRaw": "`fs.symlinkSync(target, path[, type])`", + "type": "method", + "name": "symlinkSync", + "meta": { + "added": [ + "v0.1.31" + ], + "changes": [ + { + "version": "v12.0.0", + "pr-url": "https://github.com/nodejs/node/pull/23724", + "description": "If the `type` argument is left undefined, Node will autodetect `target` type and automatically select `dir` or `file`." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `target` and `path` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." + } + ] }, - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`buffer` {Buffer|TypedArray|DataView}", - "name": "buffer", - "type": "Buffer|TypedArray|DataView" - }, + "signatures": [ { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ + "params": [ { - "textRaw": "`offset` {integer} **Default:** `0`", - "name": "offset", - "type": "integer", - "default": "`0`" + "textRaw": "`target` {string|Buffer|URL}", + "name": "target", + "type": "string|Buffer|URL" }, { - "textRaw": "`length` {integer} **Default:** `buffer.length`", - "name": "length", - "type": "integer", - "default": "`buffer.length`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`position` {integer} **Default:** `null`", - "name": "position", - "type": "integer", - "default": "`null`" + "textRaw": "`type` {string}", + "name": "type", + "type": "string" } ] } - ] - } - ], - "desc": "

      Returns the number of bytesRead.

      \n

      Similar to the above fs.readSync function, this version takes an optional options object.\nIf no options object is specified, it will default with the above values.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.read().

      " - }, - { - "textRaw": "`fs.readv(fd, buffers[, position], callback)`", - "type": "method", - "name": "readv", - "meta": { - "added": [ - "v12.17.0" - ], - "changes": [] - }, - "signatures": [ + ], + "desc": "

      Returns undefined.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.symlink().

      " + }, { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`buffers` {ArrayBufferView[]}", - "name": "buffers", - "type": "ArrayBufferView[]" - }, - { - "textRaw": "`position` {integer}", - "name": "position", - "type": "integer" - }, + "textRaw": "`fs.truncateSync(path[, len])`", + "type": "method", + "name": "truncateSync", + "meta": { + "added": [ + "v0.8.6" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ - { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" - }, + "params": [ { - "textRaw": "`bytesRead` {integer}", - "name": "bytesRead", - "type": "integer" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`buffers` {ArrayBufferView[]}", - "name": "buffers", - "type": "ArrayBufferView[]" + "textRaw": "`len` {integer} **Default:** `0`", + "name": "len", + "type": "integer", + "default": "`0`" } ] } - ] - } - ], - "desc": "

      Read from a file specified by fd and write to an array of ArrayBufferViews\nusing readv().

      \n

      position is the offset from the beginning of the file from where data\nshould be read. If typeof position !== 'number', the data will be read\nfrom the current position.

      \n

      The callback will be given three arguments: err, bytesRead, and\nbuffers. bytesRead is how many bytes were read from the file.

      \n

      If this method is invoked as its util.promisify()ed version, it returns\na Promise for an Object with bytesRead and buffers properties.

      " - }, - { - "textRaw": "`fs.readvSync(fd, buffers[, position])`", - "type": "method", - "name": "readvSync", - "meta": { - "added": [ - "v12.17.0" - ], - "changes": [] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {number} The number of bytes read.", - "name": "return", - "type": "number", - "desc": "The number of bytes read." - }, - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`buffers` {ArrayBufferView[]}", - "name": "buffers", - "type": "ArrayBufferView[]" - }, - { - "textRaw": "`position` {integer}", - "name": "position", - "type": "integer" - } - ] - } - ], - "desc": "

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.readv().

      " - }, - { - "textRaw": "`fs.realpath(path[, options], callback)`", - "type": "method", - "name": "realpath", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v8.0.0", - "pr-url": "https://github.com/nodejs/node/pull/13028", - "description": "Pipe/Socket resolve support was added." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - }, - { - "version": "v6.4.0", - "pr-url": "https://github.com/nodejs/node/pull/7899", - "description": "Calling `realpath` now works again for various edge cases on Windows." - }, - { - "version": "v6.0.0", - "pr-url": "https://github.com/nodejs/node/pull/3594", - "description": "The `cache` parameter was removed." - } - ] - }, - "signatures": [ + ], + "desc": "

      Truncates the file. Returns undefined. A file descriptor can also be\npassed as the first argument. In this case, fs.ftruncateSync() is called.

      \n

      Passing a file descriptor is deprecated and may result in an error being thrown\nin the future.

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "textRaw": "`fs.unlinkSync(path)`", + "type": "method", + "name": "unlinkSync", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [ + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + } + ] + }, + "signatures": [ { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ + "params": [ { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", - "name": "encoding", - "type": "string", - "default": "`'utf8'`" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" } ] - }, + } + ], + "desc": "

      Synchronous unlink(2). Returns undefined.

      " + }, + { + "textRaw": "`fs.utimesSync(path, atime, mtime)`", + "type": "method", + "name": "utimesSync", + "meta": { + "added": [ + "v0.4.2" + ], + "changes": [ + { + "version": "v8.0.0", + "pr-url": "https://github.com/nodejs/node/pull/11919", + "description": "`NaN`, `Infinity`, and `-Infinity` are no longer valid time specifiers." + }, + { + "version": "v7.6.0", + "pr-url": "https://github.com/nodejs/node/pull/10739", + "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol." + }, + { + "version": "v4.1.0", + "pr-url": "https://github.com/nodejs/node/pull/2387", + "description": "Numeric strings, `NaN` and `Infinity` are now allowed time specifiers." + } + ] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`path` {string|Buffer|URL}", + "name": "path", + "type": "string|Buffer|URL" }, { - "textRaw": "`resolvedPath` {string|Buffer}", - "name": "resolvedPath", - "type": "string|Buffer" + "textRaw": "`atime` {number|string|Date}", + "name": "atime", + "type": "number|string|Date" + }, + { + "textRaw": "`mtime` {number|string|Date}", + "name": "mtime", + "type": "number|string|Date" } ] } - ] - } - ], - "desc": "

      Asynchronously computes the canonical pathname by resolving ., .. and\nsymbolic links.

      \n

      A canonical pathname is not necessarily unique. Hard links and bind mounts can\nexpose a file system entity through many pathnames.

      \n

      This function behaves like realpath(3), with some exceptions:

      \n
        \n
      1. \n

        No case conversion is performed on case-insensitive file systems.

        \n
      2. \n
      3. \n

        The maximum number of symbolic links is platform-independent and generally\n(much) higher than what the native realpath(3) implementation supports.

        \n
      4. \n
      \n

      The callback gets two arguments (err, resolvedPath). May use process.cwd\nto resolve relative paths.

      \n

      Only paths that can be converted to UTF8 strings are supported.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe path passed to the callback. If the encoding is set to 'buffer',\nthe path returned will be passed as a Buffer object.

      \n

      If path resolves to a socket or a pipe, the function will return a system\ndependent name for that object.

      " - }, - { - "textRaw": "`fs.realpath.native(path[, options], callback)`", - "type": "method", - "name": "native", - "meta": { - "added": [ - "v9.2.0" - ], - "changes": [] - }, - "signatures": [ + ], + "desc": "

      Returns undefined.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.utimes().

      " + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "textRaw": "`fs.writeFileSync(file, data[, options])`", + "type": "method", + "name": "writeFileSync", + "meta": { + "added": [ + "v0.1.29" + ], + "changes": [ + { + "version": "v14.12.0", + "pr-url": "https://github.com/nodejs/node/pull/34993", + "description": "The `data` parameter will stringify an object with an explicit `toString` function." + }, + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31030", + "description": "The `data` parameter won't coerce unsupported input to strings anymore." + }, + { + "version": "v10.10.0", + "pr-url": "https://github.com/nodejs/node/pull/22150", + "description": "The `data` parameter can now be any `TypedArray` or a `DataView`." + }, + { + "version": "v7.4.0", + "pr-url": "https://github.com/nodejs/node/pull/10382", + "description": "The `data` parameter can now be a `Uint8Array`." + }, + { + "version": "v5.0.0", + "pr-url": "https://github.com/nodejs/node/pull/3163", + "description": "The `file` parameter can be a file descriptor now." + } + ] + }, + "signatures": [ { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ + "params": [ { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", - "name": "encoding", - "type": "string", - "default": "`'utf8'`" + "textRaw": "`file` {string|Buffer|URL|integer} filename or file descriptor", + "name": "file", + "type": "string|Buffer|URL|integer", + "desc": "filename or file descriptor" + }, + { + "textRaw": "`data` {string|Buffer|TypedArray|DataView|Object}", + "name": "data", + "type": "string|Buffer|TypedArray|DataView|Object" + }, + { + "textRaw": "`options` {Object|string}", + "name": "options", + "type": "Object|string", + "options": [ + { + "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", + "name": "encoding", + "type": "string|null", + "default": "`'utf8'`" + }, + { + "textRaw": "`mode` {integer} **Default:** `0o666`", + "name": "mode", + "type": "integer", + "default": "`0o666`" + }, + { + "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'w'`.", + "name": "flag", + "type": "string", + "default": "`'w'`", + "desc": "See [support of file system `flags`][]." + } + ] } ] - }, + } + ], + "desc": "

      Returns undefined.

      \n

      If data is a plain object, it must have an own (not inherited) toString\nfunction property.

      \n

      The mode option only affects the newly created file. See fs.open()\nfor more details.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.writeFile().

      " + }, + { + "textRaw": "`fs.writeSync(fd, buffer[, offset[, length[, position]]])`", + "type": "method", + "name": "writeSync", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [ + { + "version": "v14.12.0", + "pr-url": "https://github.com/nodejs/node/pull/34993", + "description": "The `buffer` parameter will stringify an object with an explicit `toString` function." + }, + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31030", + "description": "The `buffer` parameter won't coerce unsupported input to strings anymore." + }, + { + "version": "v10.10.0", + "pr-url": "https://github.com/nodejs/node/pull/22150", + "description": "The `buffer` parameter can now be any `TypedArray` or a `DataView`." + }, + { + "version": "v7.4.0", + "pr-url": "https://github.com/nodejs/node/pull/10382", + "description": "The `buffer` parameter can now be a `Uint8Array`." + }, + { + "version": "v7.2.0", + "pr-url": "https://github.com/nodejs/node/pull/7856", + "description": "The `offset` and `length` parameters are optional now." + } + ] + }, + "signatures": [ { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "return": { + "textRaw": "Returns: {number} The number of bytes written.", + "name": "return", + "type": "number", + "desc": "The number of bytes written." + }, + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" }, { - "textRaw": "`resolvedPath` {string|Buffer}", - "name": "resolvedPath", - "type": "string|Buffer" + "textRaw": "`buffer` {Buffer|TypedArray|DataView|string|Object}", + "name": "buffer", + "type": "Buffer|TypedArray|DataView|string|Object" + }, + { + "textRaw": "`offset` {integer}", + "name": "offset", + "type": "integer" + }, + { + "textRaw": "`length` {integer}", + "name": "length", + "type": "integer" + }, + { + "textRaw": "`position` {integer}", + "name": "position", + "type": "integer" } ] } - ] - } - ], - "desc": "

      Asynchronous realpath(3).

      \n

      The callback gets two arguments (err, resolvedPath).

      \n

      Only paths that can be converted to UTF8 strings are supported.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe path passed to the callback. If the encoding is set to 'buffer',\nthe path returned will be passed as a Buffer object.

      \n

      On Linux, when Node.js is linked against musl libc, the procfs file system must\nbe mounted on /proc in order for this function to work. Glibc does not have\nthis restriction.

      " - }, - { - "textRaw": "`fs.realpathSync(path[, options])`", - "type": "method", - "name": "realpathSync", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [ - { - "version": "v8.0.0", - "pr-url": "https://github.com/nodejs/node/pull/13028", - "description": "Pipe/Socket resolve support was added." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v6.4.0", - "pr-url": "https://github.com/nodejs/node/pull/7899", - "description": "Calling `realpathSync` now works again for various edge cases on Windows." - }, - { - "version": "v6.0.0", - "pr-url": "https://github.com/nodejs/node/pull/3594", - "description": "The `cache` parameter was removed." - } - ] - }, - "signatures": [ + ], + "desc": "

      If buffer is a plain object, it must have an own (not inherited) toString\nfunction property.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.write(fd, buffer...).

      " + }, { - "return": { - "textRaw": "Returns: {string|Buffer}", - "name": "return", - "type": "string|Buffer" + "textRaw": "`fs.writeSync(fd, string[, position[, encoding]])`", + "type": "method", + "name": "writeSync", + "meta": { + "added": [ + "v0.11.5" + ], + "changes": [ + { + "version": "v14.12.0", + "pr-url": "https://github.com/nodejs/node/pull/34993", + "description": "The `string` parameter will stringify an object with an explicit `toString` function." + }, + { + "version": "v14.0.0", + "pr-url": "https://github.com/nodejs/node/pull/31030", + "description": "The `string` parameter won't coerce unsupported input to strings anymore." + }, + { + "version": "v7.2.0", + "pr-url": "https://github.com/nodejs/node/pull/7856", + "description": "The `position` parameter is optional now." + } + ] }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "signatures": [ { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ + "return": { + "textRaw": "Returns: {number} The number of bytes written.", + "name": "return", + "type": "number", + "desc": "The number of bytes written." + }, + "params": [ { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`string` {string|Object}", + "name": "string", + "type": "string|Object" + }, + { + "textRaw": "`position` {integer}", + "name": "position", + "type": "integer" + }, + { + "textRaw": "`encoding` {string}", "name": "encoding", - "type": "string", - "default": "`'utf8'`" + "type": "string" } ] } - ] - } - ], - "desc": "

      Returns the resolved pathname.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.realpath().

      " - }, - { - "textRaw": "`fs.realpathSync.native(path[, options])`", - "type": "method", - "name": "native", - "meta": { - "added": [ - "v9.2.0" - ], - "changes": [] - }, - "signatures": [ + ], + "desc": "

      If string is a plain object, it must have an own (not inherited) toString\nfunction property.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.write(fd, string...).

      " + }, { - "return": { - "textRaw": "Returns: {string|Buffer}", - "name": "return", - "type": "string|Buffer" + "textRaw": "`fs.writevSync(fd, buffers[, position])`", + "type": "method", + "name": "writevSync", + "meta": { + "added": [ + "v12.9.0" + ], + "changes": [] }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + "signatures": [ { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ + "return": { + "textRaw": "Returns: {number} The number of bytes written.", + "name": "return", + "type": "number", + "desc": "The number of bytes written." + }, + "params": [ + { + "textRaw": "`fd` {integer}", + "name": "fd", + "type": "integer" + }, + { + "textRaw": "`buffers` {ArrayBufferView[]}", + "name": "buffers", + "type": "ArrayBufferView[]" + }, { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", - "name": "encoding", - "type": "string", - "default": "`'utf8'`" + "textRaw": "`position` {integer}", + "name": "position", + "type": "integer" } ] } - ] + ], + "desc": "

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.writev().

      " } ], - "desc": "

      Synchronous realpath(3).

      \n

      Only paths that can be converted to UTF8 strings are supported.

      \n

      The optional options argument can be a string specifying an encoding, or an\nobject with an encoding property specifying the character encoding to use for\nthe path returned. If the encoding is set to 'buffer',\nthe path returned will be passed as a Buffer object.

      \n

      On Linux, when Node.js is linked against musl libc, the procfs file system must\nbe mounted on /proc in order for this function to work. Glibc does not have\nthis restriction.

      " + "type": "module", + "displayName": "Synchronous API" }, { - "textRaw": "`fs.rename(oldPath, newPath, callback)`", - "type": "method", - "name": "rename", - "meta": { - "added": [ - "v0.0.2" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `oldPath` and `newPath` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ + "textRaw": "Common Objects", + "name": "common_objects", + "desc": "

      The common objects are shared by all of the file system API variants\n(promise, callback, and synchronous).

      ", + "classes": [ { - "params": [ + "textRaw": "Class: `fs.Dir`", + "type": "class", + "name": "fs.Dir", + "meta": { + "added": [ + "v12.12.0" + ], + "changes": [] + }, + "desc": "

      A class representing a directory stream.

      \n

      Created by fs.opendir(), fs.opendirSync(), or\nfsPromises.opendir().

      \n
      import { opendir } from 'fs/promises';\n\ntry {\n  const dir = await opendir('./');\n  for await (const dirent of dir)\n    console.log(dirent.name);\n} catch (err) {\n  console.error(err);\n}\n
      \n

      When using the async iterator, the <fs.Dir> object will be automatically\nclosed after the iterator exits.

      ", + "methods": [ { - "textRaw": "`oldPath` {string|Buffer|URL}", - "name": "oldPath", - "type": "string|Buffer|URL" + "textRaw": "`dir.close()`", + "type": "method", + "name": "close", + "meta": { + "added": [ + "v12.12.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {Promise}", + "name": "return", + "type": "Promise" + }, + "params": [] + } + ], + "desc": "

      Asynchronously close the directory's underlying resource handle.\nSubsequent reads will result in errors.

      \n

      A promise is returned that will be resolved after the resource has been\nclosed.

      " }, { - "textRaw": "`newPath` {string|Buffer|URL}", - "name": "newPath", - "type": "string|Buffer|URL" + "textRaw": "`dir.close(callback)`", + "type": "method", + "name": "close", + "meta": { + "added": [ + "v12.12.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] + } + ], + "desc": "

      Asynchronously close the directory's underlying resource handle.\nSubsequent reads will result in errors.

      \n

      The callback will be called after the resource handle has been closed.

      " }, { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "textRaw": "`dir.closeSync()`", + "type": "method", + "name": "closeSync", + "meta": { + "added": [ + "v12.12.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "params": [] } - ] - } - ] - } - ], - "desc": "

      Asynchronously rename file at oldPath to the pathname provided\nas newPath. In the case that newPath already exists, it will\nbe overwritten. If there is a directory at newPath, an error will\nbe raised instead. No arguments other than a possible exception are\ngiven to the completion callback.

      \n

      See also: rename(2).

      \n
      fs.rename('oldFile.txt', 'newFile.txt', (err) => {\n  if (err) throw err;\n  console.log('Rename complete!');\n});\n
      " - }, - { - "textRaw": "`fs.renameSync(oldPath, newPath)`", - "type": "method", - "name": "renameSync", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `oldPath` and `newPath` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`oldPath` {string|Buffer|URL}", - "name": "oldPath", - "type": "string|Buffer|URL" + ], + "desc": "

      Synchronously close the directory's underlying resource handle.\nSubsequent reads will result in errors.

      " }, { - "textRaw": "`newPath` {string|Buffer|URL}", - "name": "newPath", - "type": "string|Buffer|URL" - } - ] - } - ], - "desc": "

      Synchronous rename(2). Returns undefined.

      " - }, - { - "textRaw": "`fs.rmdir(path[, options], callback)`", - "type": "method", - "name": "rmdir", - "meta": { - "added": [ - "v0.0.2" - ], - "changes": [ - { - "version": "v12.16.0", - "pr-url": "https://github.com/nodejs/node/pull/30644", - "description": "The `maxBusyTries` option is renamed to `maxRetries`, and its default is 0. The `emfileWait` option has been removed, and `EMFILE` errors use the same retry logic as other errors. The `retryDelay` option is now supported. `ENFILE` errors are now retried." - }, - { - "version": "v12.10.0", - "pr-url": "https://github.com/nodejs/node/pull/29168", - "description": "The `recursive`, `maxBusyTries`, and `emfileWait` options are now supported." - }, - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameters can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "stability": 1, - "stabilityText": "Recursive removal is experimental.", - "signatures": [ - { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" + "textRaw": "`dir.read()`", + "type": "method", + "name": "read", + "meta": { + "added": [ + "v12.12.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {Promise} containing {fs.Dirent|null}", + "name": "return", + "type": "Promise", + "desc": "containing {fs.Dirent|null}" + }, + "params": [] + } + ], + "desc": "

      Asynchronously read the next directory entry via readdir(3) as an\n<fs.Dirent>.

      \n

      A promise is returned that will be resolved with an <fs.Dirent>, or null\nif there are no more directory entries to read.

      \n

      Directory entries returned by this function are in no particular order as\nprovided by the operating system's underlying directory mechanisms.\nEntries added or removed while iterating over the directory might not be\nincluded in the iteration results.

      " }, { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ - { - "textRaw": "`maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` ms longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`. **Default:** `0`.", - "name": "maxRetries", - "type": "integer", - "default": "`0`", - "desc": "If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` ms longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`." - }, - { - "textRaw": "`recursive` {boolean} If `true`, perform a recursive directory removal. In recursive mode, errors are not reported if `path` does not exist, and operations are retried on failure. **Default:** `false`.", - "name": "recursive", - "type": "boolean", - "default": "`false`", - "desc": "If `true`, perform a recursive directory removal. In recursive mode, errors are not reported if `path` does not exist, and operations are retried on failure." - }, + "textRaw": "`dir.read(callback)`", + "type": "method", + "name": "read", + "meta": { + "added": [ + "v12.12.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`retryDelay` {integer} The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`. **Default:** `100`.", - "name": "retryDelay", - "type": "integer", - "default": "`100`", - "desc": "The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`." + "params": [ + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + }, + { + "textRaw": "`dirent` {fs.Dirent|null}", + "name": "dirent", + "type": "fs.Dirent|null" + } + ] + } + ] } - ] + ], + "desc": "

      Asynchronously read the next directory entry via readdir(3) as an\n<fs.Dirent>.

      \n

      After the read is completed, the callback will be called with an\n<fs.Dirent>, or null if there are no more directory entries to read.

      \n

      Directory entries returned by this function are in no particular order as\nprovided by the operating system's underlying directory mechanisms.\nEntries added or removed while iterating over the directory might not be\nincluded in the iteration results.

      " }, { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "textRaw": "`dir.readSync()`", + "type": "method", + "name": "readSync", + "meta": { + "added": [ + "v12.12.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "return": { + "textRaw": "Returns: {fs.Dirent|null}", + "name": "return", + "type": "fs.Dirent|null" + }, + "params": [] } - ] - } - ] - } - ], - "desc": "

      Asynchronous rmdir(2). No arguments other than a possible exception are given\nto the completion callback.

      \n

      Using fs.rmdir() on a file (not a directory) results in an ENOENT error on\nWindows and an ENOTDIR error on POSIX.

      " - }, - { - "textRaw": "`fs.rmdirSync(path[, options])`", - "type": "method", - "name": "rmdirSync", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [ - { - "version": "v12.16.0", - "pr-url": "https://github.com/nodejs/node/pull/30644", - "description": "The `maxBusyTries` option is renamed to `maxRetries`, and its default is 0. The `emfileWait` option has been removed, and `EMFILE` errors use the same retry logic as other errors. The `retryDelay` option is now supported. `ENFILE` errors are now retried." - }, - { - "version": "v12.10.0", - "pr-url": "https://github.com/nodejs/node/pull/29168", - "description": "The `recursive`, `maxBusyTries`, and `emfileWait` options are now supported." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameters can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "stability": 1, - "stabilityText": "Recursive removal is experimental.", - "signatures": [ - { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" + ], + "desc": "

      Synchronously read the next directory entry as an <fs.Dirent>. See the\nPOSIX readdir(3) documentation for more detail.

      \n

      If there are no more directory entries to read, null will be returned.

      \n

      Directory entries returned by this function are in no particular order as\nprovided by the operating system's underlying directory mechanisms.\nEntries added or removed while iterating over the directory might not be\nincluded in the iteration results.

      " }, { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ - { - "textRaw": "`maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` ms longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`. **Default:** `0`.", - "name": "maxRetries", - "type": "integer", - "default": "`0`", - "desc": "If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or `EPERM` error is encountered, Node.js will retry the operation with a linear backoff wait of `retryDelay` ms longer on each try. This option represents the number of retries. This option is ignored if the `recursive` option is not `true`." - }, - { - "textRaw": "`recursive` {boolean} If `true`, perform a recursive directory removal. In recursive mode, errors are not reported if `path` does not exist, and operations are retried on failure. **Default:** `false`.", - "name": "recursive", - "type": "boolean", - "default": "`false`", - "desc": "If `true`, perform a recursive directory removal. In recursive mode, errors are not reported if `path` does not exist, and operations are retried on failure." - }, + "textRaw": "`dir[Symbol.asyncIterator]()`", + "type": "method", + "name": "[Symbol.asyncIterator]", + "meta": { + "added": [ + "v12.12.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`retryDelay` {integer} The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`. **Default:** `100`.", - "name": "retryDelay", - "type": "integer", - "default": "`100`", - "desc": "The amount of time in milliseconds to wait between retries. This option is ignored if the `recursive` option is not `true`." + "return": { + "textRaw": "Returns: {AsyncIterator} of {fs.Dirent}", + "name": "return", + "type": "AsyncIterator", + "desc": "of {fs.Dirent}" + }, + "params": [] } - ] + ], + "desc": "

      Asynchronously iterates over the directory until all entries have\nbeen read. Refer to the POSIX readdir(3) documentation for more detail.

      \n

      Entries returned by the async iterator are always an <fs.Dirent>.\nThe null case from dir.read() is handled internally.

      \n

      See <fs.Dir> for an example.

      \n

      Directory entries returned by this iterator are in no particular order as\nprovided by the operating system's underlying directory mechanisms.\nEntries added or removed while iterating over the directory might not be\nincluded in the iteration results.

      " + } + ], + "properties": [ + { + "textRaw": "`path` {string}", + "type": "string", + "name": "path", + "meta": { + "added": [ + "v12.12.0" + ], + "changes": [] + }, + "desc": "

      The read-only path of this directory as was provided to fs.opendir(),\nfs.opendirSync(), or fsPromises.opendir().

      " } ] - } - ], - "desc": "

      Synchronous rmdir(2). Returns undefined.

      \n

      Using fs.rmdirSync() on a file (not a directory) results in an ENOENT error\non Windows and an ENOTDIR error on POSIX.

      " - }, - { - "textRaw": "`fs.stat(path[, options], callback)`", - "type": "method", - "name": "stat", - "meta": { - "added": [ - "v0.0.2" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - }, - { - "version": "v10.5.0", - "pr-url": "https://github.com/nodejs/node/pull/20220", - "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." - } - ] - }, - "signatures": [ + }, { - "params": [ + "textRaw": "Class: `fs.Dirent`", + "type": "class", + "name": "fs.Dirent", + "meta": { + "added": [ + "v10.10.0" + ], + "changes": [] + }, + "desc": "

      A representation of a directory entry, which can be a file or a subdirectory\nwithin the directory, as returned by reading from an <fs.Dir>. The\ndirectory entry is a combination of the file name and file type pairs.

      \n

      Additionally, when fs.readdir() or fs.readdirSync() is called with\nthe withFileTypes option set to true, the resulting array is filled with\n<fs.Dirent> objects, rather than strings or <Buffer>s.

      ", + "methods": [ { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" + "textRaw": "`dirent.isBlockDevice()`", + "type": "method", + "name": "isBlockDevice", + "meta": { + "added": [ + "v10.10.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] + } + ], + "desc": "

      Returns true if the <fs.Dirent> object describes a block device.

      " }, { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ + "textRaw": "`dirent.isCharacterDevice()`", + "type": "method", + "name": "isCharacterDevice", + "meta": { + "added": [ + "v10.10.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`bigint` {boolean} Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`. **Default:** `false`.", - "name": "bigint", - "type": "boolean", - "default": "`false`", - "desc": "Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`." + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] } - ] + ], + "desc": "

      Returns true if the <fs.Dirent> object describes a character device.

      " }, { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ - { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" - }, + "textRaw": "`dirent.isDirectory()`", + "type": "method", + "name": "isDirectory", + "meta": { + "added": [ + "v10.10.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`stats` {fs.Stats}", - "name": "stats", - "type": "fs.Stats" + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] } - ] - } - ] - } - ], - "desc": "

      Asynchronous stat(2). The callback gets two arguments (err, stats) where\nstats is an fs.Stats object.

      \n

      In case of an error, the err.code will be one of Common System Errors.

      \n

      Using fs.stat() to check for the existence of a file before calling\nfs.open(), fs.readFile() or fs.writeFile() is not recommended.\nInstead, user code should open/read/write the file directly and handle the\nerror raised if the file is not available.

      \n

      To check if a file exists without manipulating it afterwards, fs.access()\nis recommended.

      \n

      For example, given the following directory structure:

      \n
      - txtDir\n-- file.txt\n- app.js\n
      \n

      The next program will check for the stats of the given paths:

      \n
      const fs = require('fs');\n\nconst pathsToCheck = ['./txtDir', './txtDir/file.txt'];\n\nfor (let i = 0; i < pathsToCheck.length; i++) {\n  fs.stat(pathsToCheck[i], function(err, stats) {\n    console.log(stats.isDirectory());\n    console.log(stats);\n  });\n}\n
      \n

      The resulting output will resemble:

      \n
      true\nStats {\n  dev: 16777220,\n  mode: 16877,\n  nlink: 3,\n  uid: 501,\n  gid: 20,\n  rdev: 0,\n  blksize: 4096,\n  ino: 14214262,\n  size: 96,\n  blocks: 0,\n  atimeMs: 1561174653071.963,\n  mtimeMs: 1561174614583.3518,\n  ctimeMs: 1561174626623.5366,\n  birthtimeMs: 1561174126937.2893,\n  atime: 2019-06-22T03:37:33.072Z,\n  mtime: 2019-06-22T03:36:54.583Z,\n  ctime: 2019-06-22T03:37:06.624Z,\n  birthtime: 2019-06-22T03:28:46.937Z\n}\nfalse\nStats {\n  dev: 16777220,\n  mode: 33188,\n  nlink: 1,\n  uid: 501,\n  gid: 20,\n  rdev: 0,\n  blksize: 4096,\n  ino: 14214074,\n  size: 8,\n  blocks: 8,\n  atimeMs: 1561174616618.8555,\n  mtimeMs: 1561174614584,\n  ctimeMs: 1561174614583.8145,\n  birthtimeMs: 1561174007710.7478,\n  atime: 2019-06-22T03:36:56.619Z,\n  mtime: 2019-06-22T03:36:54.584Z,\n  ctime: 2019-06-22T03:36:54.584Z,\n  birthtime: 2019-06-22T03:26:47.711Z\n}\n
      " - }, - { - "textRaw": "`fs.statSync(path[, options])`", - "type": "method", - "name": "statSync", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v10.5.0", - "pr-url": "https://github.com/nodejs/node/pull/20220", - "description": "Accepts an additional `options` object to specify whether the numeric values returned should be bigint." - } - ] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {fs.Stats}", - "name": "return", - "type": "fs.Stats" - }, - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" + ], + "desc": "

      Returns true if the <fs.Dirent> object describes a file system\ndirectory.

      " }, { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ + "textRaw": "`dirent.isFIFO()`", + "type": "method", + "name": "isFIFO", + "meta": { + "added": [ + "v10.10.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`bigint` {boolean} Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`. **Default:** `false`.", - "name": "bigint", - "type": "boolean", - "default": "`false`", - "desc": "Whether the numeric values in the returned [`fs.Stats`][] object should be `bigint`." + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] } - ] - } - ] - } - ], - "desc": "

      Synchronous stat(2).

      " - }, - { - "textRaw": "`fs.symlink(target, path[, type], callback)`", - "type": "method", - "name": "symlink", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `target` and `path` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v12.0.0", - "pr-url": "https://github.com/nodejs/node/pull/23724", - "description": "If the `type` argument is left undefined, Node will autodetect `target` type and automatically select `dir` or `file`" - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`target` {string|Buffer|URL}", - "name": "target", - "type": "string|Buffer|URL" + ], + "desc": "

      Returns true if the <fs.Dirent> object describes a first-in-first-out\n(FIFO) pipe.

      " }, { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" + "textRaw": "`dirent.isFile()`", + "type": "method", + "name": "isFile", + "meta": { + "added": [ + "v10.10.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] + } + ], + "desc": "

      Returns true if the <fs.Dirent> object describes a regular file.

      " }, { - "textRaw": "`type` {string}", - "name": "type", - "type": "string" + "textRaw": "`dirent.isSocket()`", + "type": "method", + "name": "isSocket", + "meta": { + "added": [ + "v10.10.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] + } + ], + "desc": "

      Returns true if the <fs.Dirent> object describes a socket.

      " }, { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "textRaw": "`dirent.isSymbolicLink()`", + "type": "method", + "name": "isSymbolicLink", + "meta": { + "added": [ + "v10.10.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] } - ] + ], + "desc": "

      Returns true if the <fs.Dirent> object describes a symbolic link.

      " } - ] - } - ], - "desc": "

      Asynchronous symlink(2) which creates the link called path pointing to\ntarget. No arguments other than a possible exception are given to the\ncompletion callback.

      \n

      The type argument is only available on Windows and ignored on other platforms.\nIt can be set to 'dir', 'file', or 'junction'. If the type argument is\nnot set, Node.js will autodetect target type and use 'file' or 'dir'. If\nthe target does not exist, 'file' will be used. Windows junction points\nrequire the destination path to be absolute. When using 'junction', the\ntarget argument will automatically be normalized to absolute path.

      \n

      Relative targets are relative to the link’s parent directory.

      \n
      fs.symlink('./mew', './example/mewtwo', callback);\n
      \n

      The above example creates a symbolic link mewtwo in the example which points\nto mew in the same directory:

      \n
      $ tree example/\nexample/\n├── mew\n└── mewtwo -> ./mew\n
      " - }, - { - "textRaw": "`fs.symlinkSync(target, path[, type])`", - "type": "method", - "name": "symlinkSync", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `target` and `path` parameters can be WHATWG `URL` objects using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v12.0.0", - "pr-url": "https://github.com/nodejs/node/pull/23724", - "description": "If the `type` argument is left undefined, Node will autodetect `target` type and automatically select `dir` or `file`" - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`target` {string|Buffer|URL}", - "name": "target", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, + ], + "properties": [ { - "textRaw": "`type` {string}", - "name": "type", - "type": "string" + "textRaw": "`name` {string|Buffer}", + "type": "string|Buffer", + "name": "name", + "meta": { + "added": [ + "v10.10.0" + ], + "changes": [] + }, + "desc": "

      The file name that this <fs.Dirent> object refers to. The type of this\nvalue is determined by the options.encoding passed to fs.readdir() or\nfs.readdirSync().

      " } ] - } - ], - "desc": "

      Returns undefined.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.symlink().

      " - }, - { - "textRaw": "`fs.truncate(path[, len], callback)`", - "type": "method", - "name": "truncate", - "meta": { - "added": [ - "v0.8.6" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ + }, { - "params": [ + "textRaw": "Class: `fs.FSWatcher`", + "type": "class", + "name": "fs.FSWatcher", + "meta": { + "added": [ + "v0.5.8" + ], + "changes": [] + }, + "desc": "\n

      A successful call to fs.watch() method will return a new <fs.FSWatcher>\nobject.

      \n

      All <fs.FSWatcher> objects emit a 'change' event whenever a specific watched\nfile is modified.

      ", + "events": [ { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" + "textRaw": "Event: `'change'`", + "type": "event", + "name": "change", + "meta": { + "added": [ + "v0.5.8" + ], + "changes": [] + }, + "params": [ + { + "textRaw": "`eventType` {string} The type of change event that has occurred", + "name": "eventType", + "type": "string", + "desc": "The type of change event that has occurred" + }, + { + "textRaw": "`filename` {string|Buffer} The filename that changed (if relevant/available)", + "name": "filename", + "type": "string|Buffer", + "desc": "The filename that changed (if relevant/available)" + } + ], + "desc": "

      Emitted when something changes in a watched directory or file.\nSee more details in fs.watch().

      \n

      The filename argument may not be provided depending on operating system\nsupport. If filename is provided, it will be provided as a <Buffer> if\nfs.watch() is called with its encoding option set to 'buffer', otherwise\nfilename will be a UTF-8 string.

      \n
      import { watch } from 'fs';\n// Example when handled through fs.watch() listener\nwatch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {\n  if (filename) {\n    console.log(filename);\n    // Prints: <Buffer ...>\n  }\n});\n
      " }, { - "textRaw": "`len` {integer} **Default:** `0`", - "name": "len", - "type": "integer", - "default": "`0`" + "textRaw": "Event: `'close'`", + "type": "event", + "name": "close", + "meta": { + "added": [ + "v10.0.0" + ], + "changes": [] + }, + "params": [], + "desc": "

      Emitted when the watcher stops watching for changes. The closed\n<fs.FSWatcher> object is no longer usable in the event handler.

      " }, { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "textRaw": "Event: `'error'`", + "type": "event", + "name": "error", + "meta": { + "added": [ + "v0.5.8" + ], + "changes": [] + }, + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", + "textRaw": "`error` {Error}", + "name": "error", "type": "Error" } - ] - } - ] - } - ], - "desc": "

      Asynchronous truncate(2). No arguments other than a possible exception are\ngiven to the completion callback. A file descriptor can also be passed as the\nfirst argument. In this case, fs.ftruncate() is called.

      \n

      Passing a file descriptor is deprecated and may result in an error being thrown\nin the future.

      " - }, - { - "textRaw": "`fs.truncateSync(path[, len])`", - "type": "method", - "name": "truncateSync", - "meta": { - "added": [ - "v0.8.6" - ], - "changes": [] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`len` {integer} **Default:** `0`", - "name": "len", - "type": "integer", - "default": "`0`" + ], + "desc": "

      Emitted when an error occurs while watching the file. The errored\n<fs.FSWatcher> object is no longer usable in the event handler.

      " } - ] - } - ], - "desc": "

      Synchronous truncate(2). Returns undefined. A file descriptor can also be\npassed as the first argument. In this case, fs.ftruncateSync() is called.

      \n

      Passing a file descriptor is deprecated and may result in an error being thrown\nin the future.

      " - }, - { - "textRaw": "`fs.unlink(path, callback)`", - "type": "method", - "name": "unlink", - "meta": { - "added": [ - "v0.0.2" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ - { - "params": [ + ], + "methods": [ { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" + "textRaw": "`watcher.close()`", + "type": "method", + "name": "close", + "meta": { + "added": [ + "v0.5.8" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      Stop watching for changes on the given <fs.FSWatcher>. Once stopped, the\n<fs.FSWatcher> object is no longer usable.

      " }, { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "textRaw": "`watcher.ref()`", + "type": "method", + "name": "ref", + "meta": { + "added": [ + "v14.3.0", + "v12.20.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "return": { + "textRaw": "Returns: {fs.FSWatcher}", + "name": "return", + "type": "fs.FSWatcher" + }, + "params": [] } - ] - } - ] - } - ], - "desc": "

      Asynchronously removes a file or symbolic link. No arguments other than a\npossible exception are given to the completion callback.

      \n
      // Assuming that 'path/file.txt' is a regular file.\nfs.unlink('path/file.txt', (err) => {\n  if (err) throw err;\n  console.log('path/file.txt was deleted');\n});\n
      \n

      fs.unlink() will not work on a directory, empty or otherwise. To remove a\ndirectory, use fs.rmdir().

      \n

      See also: unlink(2).

      " - }, - { - "textRaw": "`fs.unlinkSync(path)`", - "type": "method", - "name": "unlinkSync", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ - { - "params": [ + ], + "desc": "

      When called, requests that the Node.js event loop not exit so long as the\n<fs.FSWatcher> is active. Calling watcher.ref() multiple times will have\nno effect.

      \n

      By default, all <fs.FSWatcher> objects are \"ref'ed\", making it normally\nunnecessary to call watcher.ref() unless watcher.unref() had been\ncalled previously.

      " + }, { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" + "textRaw": "`watcher.unref()`", + "type": "method", + "name": "unref", + "meta": { + "added": [ + "v14.3.0", + "v12.20.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {fs.FSWatcher}", + "name": "return", + "type": "fs.FSWatcher" + }, + "params": [] + } + ], + "desc": "

      When called, the active <fs.FSWatcher> object will not require the Node.js\nevent loop to remain active. If there is no other activity keeping the\nevent loop running, the process may exit before the <fs.FSWatcher> object's\ncallback is invoked. Calling watcher.unref() multiple times will have\nno effect.

      " } ] - } - ], - "desc": "

      Synchronous unlink(2). Returns undefined.

      " - }, - { - "textRaw": "`fs.unwatchFile(filename[, listener])`", - "type": "method", - "name": "unwatchFile", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [] - }, - "signatures": [ + }, { - "params": [ + "textRaw": "Class: `fs.StatWatcher`", + "type": "class", + "name": "fs.StatWatcher", + "meta": { + "added": [ + "v14.3.0", + "v12.20.0" + ], + "changes": [] + }, + "desc": "\n

      A successful call to fs.watchFile() method will return a new <fs.StatWatcher>\nobject.

      ", + "methods": [ { - "textRaw": "`filename` {string|Buffer|URL}", - "name": "filename", - "type": "string|Buffer|URL" + "textRaw": "`watcher.ref()`", + "type": "method", + "name": "ref", + "meta": { + "added": [ + "v14.3.0", + "v12.20.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {fs.StatWatcher}", + "name": "return", + "type": "fs.StatWatcher" + }, + "params": [] + } + ], + "desc": "

      When called, requests that the Node.js event loop not exit so long as the\n<fs.StatWatcher> is active. Calling watcher.ref() multiple times will have\nno effect.

      \n

      By default, all <fs.StatWatcher> objects are \"ref'ed\", making it normally\nunnecessary to call watcher.ref() unless watcher.unref() had been\ncalled previously.

      " }, { - "textRaw": "`listener` {Function} Optional, a listener previously attached using `fs.watchFile()`", - "name": "listener", - "type": "Function", - "desc": "Optional, a listener previously attached using `fs.watchFile()`" + "textRaw": "`watcher.unref()`", + "type": "method", + "name": "unref", + "meta": { + "added": [ + "v14.3.0", + "v12.20.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {fs.StatWatcher}", + "name": "return", + "type": "fs.StatWatcher" + }, + "params": [] + } + ], + "desc": "

      When called, the active <fs.StatWatcher> object will not require the Node.js\nevent loop to remain active. If there is no other activity keeping the\nevent loop running, the process may exit before the <fs.StatWatcher> object's\ncallback is invoked. Calling watcher.unref() multiple times will have\nno effect.

      " } ] - } - ], - "desc": "

      Stop watching for changes on filename. If listener is specified, only that\nparticular listener is removed. Otherwise, all listeners are removed,\neffectively stopping watching of filename.

      \n

      Calling fs.unwatchFile() with a filename that is not being watched is a\nno-op, not an error.

      \n

      Using fs.watch() is more efficient than fs.watchFile() and\nfs.unwatchFile(). fs.watch() should be used instead of fs.watchFile()\nand fs.unwatchFile() when possible.

      " - }, - { - "textRaw": "`fs.utimes(path, atime, mtime, callback)`", - "type": "method", - "name": "utimes", - "meta": { - "added": [ - "v0.4.2" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v8.0.0", - "pr-url": "https://github.com/nodejs/node/pull/11919", - "description": "`NaN`, `Infinity`, and `-Infinity` are no longer valid time specifiers." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - }, - { - "version": "v4.1.0", - "pr-url": "https://github.com/nodejs/node/pull/2387", - "description": "Numeric strings, `NaN` and `Infinity` are now allowed time specifiers." - } - ] - }, - "signatures": [ + }, { - "params": [ - { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" - }, - { - "textRaw": "`atime` {number|string|Date}", - "name": "atime", - "type": "number|string|Date" - }, + "textRaw": "Class: `fs.ReadStream`", + "type": "class", + "name": "fs.ReadStream", + "meta": { + "added": [ + "v0.1.93" + ], + "changes": [] + }, + "desc": "\n

      Instances of <fs.ReadStream> are created and returned using the\nfs.createReadStream() function.

      ", + "events": [ { - "textRaw": "`mtime` {number|string|Date}", - "name": "mtime", - "type": "number|string|Date" + "textRaw": "Event: `'close'`", + "type": "event", + "name": "close", + "meta": { + "added": [ + "v0.1.93" + ], + "changes": [] + }, + "params": [], + "desc": "

      Emitted when the <fs.ReadStream>'s underlying file descriptor has been closed.

      " }, { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "textRaw": "Event: `'open'`", + "type": "event", + "name": "open", + "meta": { + "added": [ + "v0.1.93" + ], + "changes": [] + }, + "params": [ { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "`fd` {integer} Integer file descriptor used by the {fs.ReadStream}.", + "name": "fd", + "type": "integer", + "desc": "Integer file descriptor used by the {fs.ReadStream}." } - ] + ], + "desc": "

      Emitted when the <fs.ReadStream>'s file descriptor has been opened.

      " + }, + { + "textRaw": "Event: `'ready'`", + "type": "event", + "name": "ready", + "meta": { + "added": [ + "v9.11.0" + ], + "changes": [] + }, + "params": [], + "desc": "

      Emitted when the <fs.ReadStream> is ready to be used.

      \n

      Fires immediately after 'open'.

      " } - ] - } - ], - "desc": "

      Change the file system timestamps of the object referenced by path.

      \n

      The atime and mtime arguments follow these rules:

      \n
        \n
      • Values can be either numbers representing Unix epoch time in seconds,\nDates, or a numeric string like '123456789.0'.
      • \n
      • If the value can not be converted to a number, or is NaN, Infinity or\n-Infinity, an Error will be thrown.
      • \n
      " - }, - { - "textRaw": "`fs.utimesSync(path, atime, mtime)`", - "type": "method", - "name": "utimesSync", - "meta": { - "added": [ - "v0.4.2" - ], - "changes": [ - { - "version": "v8.0.0", - "pr-url": "https://github.com/nodejs/node/pull/11919", - "description": "`NaN`, `Infinity`, and `-Infinity` are no longer valid time specifiers." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `path` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v4.1.0", - "pr-url": "https://github.com/nodejs/node/pull/2387", - "description": "Numeric strings, `NaN` and `Infinity` are now allowed time specifiers." - } - ] - }, - "signatures": [ - { - "params": [ + ], + "properties": [ { - "textRaw": "`path` {string|Buffer|URL}", - "name": "path", - "type": "string|Buffer|URL" + "textRaw": "`bytesRead` {number}", + "type": "number", + "name": "bytesRead", + "meta": { + "added": [ + "v6.4.0" + ], + "changes": [] + }, + "desc": "

      The number of bytes that have been read so far.

      " }, { - "textRaw": "`atime` {number|string|Date}", - "name": "atime", - "type": "number|string|Date" + "textRaw": "`path` {string|Buffer}", + "type": "string|Buffer", + "name": "path", + "meta": { + "added": [ + "v0.1.93" + ], + "changes": [] + }, + "desc": "

      The path to the file the stream is reading from as specified in the first\nargument to fs.createReadStream(). If path is passed as a string, then\nreadStream.path will be a string. If path is passed as a <Buffer>, then\nreadStream.path will be a <Buffer>.

      " }, { - "textRaw": "`mtime` {number|string|Date}", - "name": "mtime", - "type": "number|string|Date" + "textRaw": "`pending` {boolean}", + "type": "boolean", + "name": "pending", + "meta": { + "added": [ + "v11.2.0", + "v10.16.0" + ], + "changes": [] + }, + "desc": "

      This property is true if the underlying file has not been opened yet,\ni.e. before the 'ready' event is emitted.

      " } ] - } - ], - "desc": "

      Returns undefined.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.utimes().

      " - }, - { - "textRaw": "`fs.watch(filename[, options][, listener])`", - "type": "method", - "name": "watch", - "meta": { - "added": [ - "v0.5.10" - ], - "changes": [ - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `filename` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7831", - "description": "The passed `options` object will never be modified." - } - ] - }, - "signatures": [ + }, { - "return": { - "textRaw": "Returns: {fs.FSWatcher}", - "name": "return", - "type": "fs.FSWatcher" + "textRaw": "Class: `fs.Stats`", + "type": "class", + "name": "fs.Stats", + "meta": { + "added": [ + "v0.1.21" + ], + "changes": [ + { + "version": "v8.1.0", + "pr-url": "https://github.com/nodejs/node/pull/13173", + "description": "Added times as numbers." + } + ] }, - "params": [ + "desc": "

      A <fs.Stats> object provides information about a file.

      \n

      Objects returned from fs.stat(), fs.lstat() and fs.fstat() and\ntheir synchronous counterparts are of this type.\nIf bigint in the options passed to those methods is true, the numeric values\nwill be bigint instead of number, and the object will contain additional\nnanosecond-precision properties suffixed with Ns.

      \n
      Stats {\n  dev: 2114,\n  ino: 48064969,\n  mode: 33188,\n  nlink: 1,\n  uid: 85,\n  gid: 100,\n  rdev: 0,\n  size: 527,\n  blksize: 4096,\n  blocks: 8,\n  atimeMs: 1318289051000.1,\n  mtimeMs: 1318289051000.1,\n  ctimeMs: 1318289051000.1,\n  birthtimeMs: 1318289051000.1,\n  atime: Mon, 10 Oct 2011 23:24:11 GMT,\n  mtime: Mon, 10 Oct 2011 23:24:11 GMT,\n  ctime: Mon, 10 Oct 2011 23:24:11 GMT,\n  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }\n
      \n

      bigint version:

      \n
      BigIntStats {\n  dev: 2114n,\n  ino: 48064969n,\n  mode: 33188n,\n  nlink: 1n,\n  uid: 85n,\n  gid: 100n,\n  rdev: 0n,\n  size: 527n,\n  blksize: 4096n,\n  blocks: 8n,\n  atimeMs: 1318289051000n,\n  mtimeMs: 1318289051000n,\n  ctimeMs: 1318289051000n,\n  birthtimeMs: 1318289051000n,\n  atimeNs: 1318289051000000000n,\n  mtimeNs: 1318289051000000000n,\n  ctimeNs: 1318289051000000000n,\n  birthtimeNs: 1318289051000000000n,\n  atime: Mon, 10 Oct 2011 23:24:11 GMT,\n  mtime: Mon, 10 Oct 2011 23:24:11 GMT,\n  ctime: Mon, 10 Oct 2011 23:24:11 GMT,\n  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }\n
      ", + "methods": [ + { + "textRaw": "`stats.isBlockDevice()`", + "type": "method", + "name": "isBlockDevice", + "meta": { + "added": [ + "v0.1.10" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] + } + ], + "desc": "

      Returns true if the <fs.Stats> object describes a block device.

      " + }, { - "textRaw": "`filename` {string|Buffer|URL}", - "name": "filename", - "type": "string|Buffer|URL" + "textRaw": "`stats.isCharacterDevice()`", + "type": "method", + "name": "isCharacterDevice", + "meta": { + "added": [ + "v0.1.10" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] + } + ], + "desc": "

      Returns true if the <fs.Stats> object describes a character device.

      " }, { - "textRaw": "`options` {string|Object}", - "name": "options", - "type": "string|Object", - "options": [ + "textRaw": "`stats.isDirectory()`", + "type": "method", + "name": "isDirectory", + "meta": { + "added": [ + "v0.1.10" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`persistent` {boolean} Indicates whether the process should continue to run as long as files are being watched. **Default:** `true`.", - "name": "persistent", - "type": "boolean", - "default": "`true`", - "desc": "Indicates whether the process should continue to run as long as files are being watched." - }, + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] + } + ], + "desc": "

      Returns true if the <fs.Stats> object describes a file system directory.

      \n

      If the <fs.Stats> object was obtained from fs.lstat(), this method will\nalways return false. This is because fs.lstat() returns information\nabout a symbolic link itself and not the path it resolves to.

      " + }, + { + "textRaw": "`stats.isFIFO()`", + "type": "method", + "name": "isFIFO", + "meta": { + "added": [ + "v0.1.10" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`recursive` {boolean} Indicates whether all subdirectories should be watched, or only the current directory. This applies when a directory is specified, and only on supported platforms (See [Caveats][]). **Default:** `false`.", - "name": "recursive", - "type": "boolean", - "default": "`false`", - "desc": "Indicates whether all subdirectories should be watched, or only the current directory. This applies when a directory is specified, and only on supported platforms (See [Caveats][])." - }, + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] + } + ], + "desc": "

      Returns true if the <fs.Stats> object describes a first-in-first-out (FIFO)\npipe.

      " + }, + { + "textRaw": "`stats.isFile()`", + "type": "method", + "name": "isFile", + "meta": { + "added": [ + "v0.1.10" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`encoding` {string} Specifies the character encoding to be used for the filename passed to the listener. **Default:** `'utf8'`.", - "name": "encoding", - "type": "string", - "default": "`'utf8'`", - "desc": "Specifies the character encoding to be used for the filename passed to the listener." + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] } - ] + ], + "desc": "

      Returns true if the <fs.Stats> object describes a regular file.

      " }, { - "textRaw": "`listener` {Function|undefined} **Default:** `undefined`", - "name": "listener", - "type": "Function|undefined", - "default": "`undefined`", - "options": [ + "textRaw": "`stats.isSocket()`", + "type": "method", + "name": "isSocket", + "meta": { + "added": [ + "v0.1.10" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`eventType` {string}", - "name": "eventType", - "type": "string" - }, + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] + } + ], + "desc": "

      Returns true if the <fs.Stats> object describes a socket.

      " + }, + { + "textRaw": "`stats.isSymbolicLink()`", + "type": "method", + "name": "isSymbolicLink", + "meta": { + "added": [ + "v0.1.10" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`filename` {string|Buffer}", - "name": "filename", - "type": "string|Buffer" + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [] } - ] + ], + "desc": "

      Returns true if the <fs.Stats> object describes a symbolic link.

      \n

      This method is only valid when using fs.lstat().

      " } - ] - } - ], - "desc": "

      Watch for changes on filename, where filename is either a file or a\ndirectory.

      \n

      The second argument is optional. If options is provided as a string, it\nspecifies the encoding. Otherwise options should be passed as an object.

      \n

      The listener callback gets two arguments (eventType, filename). eventType\nis either 'rename' or 'change', and filename is the name of the file\nwhich triggered the event.

      \n

      On most platforms, 'rename' is emitted whenever a filename appears or\ndisappears in the directory.

      \n

      The listener callback is attached to the 'change' event fired by\nfs.FSWatcher, but it is not the same thing as the 'change' value of\neventType.

      ", - "miscs": [ - { - "textRaw": "Caveats", - "name": "Caveats", - "type": "misc", - "desc": "

      The fs.watch API is not 100% consistent across platforms, and is\nunavailable in some situations.

      \n

      The recursive option is only supported on macOS and Windows.

      \n

      On Windows, no events will be emitted if the watched directory is moved or\nrenamed. An EPERM error is reported when the watched directory is deleted.

      ", - "miscs": [ + ], + "properties": [ { - "textRaw": "Availability", - "name": "Availability", - "type": "misc", - "desc": "

      This feature depends on the underlying operating system providing a way\nto be notified of filesystem changes.

      \n
        \n
      • On Linux systems, this uses inotify(7).
      • \n
      • On BSD systems, this uses kqueue(2).
      • \n
      • On macOS, this uses kqueue(2) for files and FSEvents for\ndirectories.
      • \n
      • On SunOS systems (including Solaris and SmartOS), this uses event ports.
      • \n
      • On Windows systems, this feature depends on ReadDirectoryChangesW.
      • \n
      • On Aix systems, this feature depends on AHAFS, which must be enabled.
      • \n
      • On IBM i systems, this feature is not supported.
      • \n
      \n

      If the underlying functionality is not available for some reason, then\nfs.watch() will not be able to function and may thrown an exception.\nFor example, watching files or directories can be unreliable, and in some\ncases impossible, on network file systems (NFS, SMB, etc) or host file systems\nwhen using virtualization software such as Vagrant or Docker.

      \n

      It is still possible to use fs.watchFile(), which uses stat polling, but\nthis method is slower and less reliable.

      " + "textRaw": "`dev` {number|bigint}", + "type": "number|bigint", + "name": "dev", + "desc": "

      The numeric identifier of the device containing the file.

      " }, { - "textRaw": "Inodes", - "name": "Inodes", - "type": "misc", - "desc": "

      On Linux and macOS systems, fs.watch() resolves the path to an inode and\nwatches the inode. If the watched path is deleted and recreated, it is assigned\na new inode. The watch will emit an event for the delete but will continue\nwatching the original inode. Events for the new inode will not be emitted.\nThis is expected behavior.

      \n

      AIX files retain the same inode for the lifetime of a file. Saving and closing a\nwatched file on AIX will result in two notifications (one for adding new\ncontent, and one for truncation).

      " + "textRaw": "`ino` {number|bigint}", + "type": "number|bigint", + "name": "ino", + "desc": "

      The file system specific \"Inode\" number for the file.

      " }, { - "textRaw": "Filename argument", - "name": "Filename argument", - "type": "misc", - "desc": "

      Providing filename argument in the callback is only supported on Linux,\nmacOS, Windows, and AIX. Even on supported platforms, filename is not always\nguaranteed to be provided. Therefore, don't assume that filename argument is\nalways provided in the callback, and have some fallback logic if it is null.

      \n
      fs.watch('somedir', (eventType, filename) => {\n  console.log(`event type is: ${eventType}`);\n  if (filename) {\n    console.log(`filename provided: ${filename}`);\n  } else {\n    console.log('filename not provided');\n  }\n});\n
      " - } - ] - } - ] - }, - { - "textRaw": "`fs.watchFile(filename[, options], listener)`", - "type": "method", - "name": "watchFile", - "meta": { - "added": [ - "v0.1.31" - ], - "changes": [ - { - "version": "v10.5.0", - "pr-url": "https://github.com/nodejs/node/pull/20220", - "description": "The `bigint` option is now supported." - }, - { - "version": "v7.6.0", - "pr-url": "https://github.com/nodejs/node/pull/10739", - "description": "The `filename` parameter can be a WHATWG `URL` object using `file:` protocol. Support is currently still *experimental*." - } - ] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {fs.StatWatcher}", - "name": "return", - "type": "fs.StatWatcher" - }, - "params": [ + "textRaw": "`mode` {number|bigint}", + "type": "number|bigint", + "name": "mode", + "desc": "

      A bit-field describing the file type and mode.

      " + }, { - "textRaw": "`filename` {string|Buffer|URL}", - "name": "filename", - "type": "string|Buffer|URL" + "textRaw": "`nlink` {number|bigint}", + "type": "number|bigint", + "name": "nlink", + "desc": "

      The number of hard-links that exist for the file.

      " }, { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ - { - "textRaw": "`bigint` {boolean} **Default:** `false`", - "name": "bigint", - "type": "boolean", - "default": "`false`" - }, - { - "textRaw": "`persistent` {boolean} **Default:** `true`", - "name": "persistent", - "type": "boolean", - "default": "`true`" - }, - { - "textRaw": "`interval` {integer} **Default:** `5007`", - "name": "interval", - "type": "integer", - "default": "`5007`" - } - ] + "textRaw": "`uid` {number|bigint}", + "type": "number|bigint", + "name": "uid", + "desc": "

      The numeric user identifier of the user that owns the file (POSIX).

      " }, { - "textRaw": "`listener` {Function}", - "name": "listener", - "type": "Function", - "options": [ - { - "textRaw": "`current` {fs.Stats}", - "name": "current", - "type": "fs.Stats" - }, - { - "textRaw": "`previous` {fs.Stats}", - "name": "previous", - "type": "fs.Stats" - } - ] - } - ] - } - ], - "desc": "

      Watch for changes on filename. The callback listener will be called each\ntime the file is accessed.

      \n

      The options argument may be omitted. If provided, it should be an object. The\noptions object may contain a boolean named persistent that indicates\nwhether the process should continue to run as long as files are being watched.\nThe options object may specify an interval property indicating how often the\ntarget should be polled in milliseconds.

      \n

      The listener gets two arguments the current stat object and the previous\nstat object:

      \n
      fs.watchFile('message.text', (curr, prev) => {\n  console.log(`the current mtime is: ${curr.mtime}`);\n  console.log(`the previous mtime was: ${prev.mtime}`);\n});\n
      \n

      These stat objects are instances of fs.Stat. If the bigint option is true,\nthe numeric values in these objects are specified as BigInts.

      \n

      To be notified when the file was modified, not just accessed, it is necessary\nto compare curr.mtime and prev.mtime.

      \n

      When an fs.watchFile operation results in an ENOENT error, it\nwill invoke the listener once, with all the fields zeroed (or, for dates, the\nUnix Epoch). If the file is created later on, the listener will be called\nagain, with the latest stat objects. This is a change in functionality since\nv0.10.

      \n

      Using fs.watch() is more efficient than fs.watchFile and\nfs.unwatchFile. fs.watch should be used instead of fs.watchFile and\nfs.unwatchFile when possible.

      \n

      When a file being watched by fs.watchFile() disappears and reappears,\nthen the contents of previous in the second callback event (the file's\nreappearance) will be the same as the contents of previous in the first\ncallback event (its disappearance).

      \n

      This happens when:

      \n
        \n
      • the file is deleted, followed by a restore
      • \n
      • the file is renamed and then renamed a second time back to its original name
      • \n
      " - }, - { - "textRaw": "`fs.write(fd, buffer[, offset[, length[, position]]], callback)`", - "type": "method", - "name": "write", - "meta": { - "added": [ - "v0.0.2" - ], - "changes": [ - { - "version": "v10.10.0", - "pr-url": "https://github.com/nodejs/node/pull/22150", - "description": "The `buffer` parameter can now be any `TypedArray` or a `DataView`" - }, - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.4.0", - "pr-url": "https://github.com/nodejs/node/pull/10382", - "description": "The `buffer` parameter can now be a `Uint8Array`." - }, - { - "version": "v7.2.0", - "pr-url": "https://github.com/nodejs/node/pull/7856", - "description": "The `offset` and `length` parameters are optional now." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ - { - "params": [ + "textRaw": "`gid` {number|bigint}", + "type": "number|bigint", + "name": "gid", + "desc": "

      The numeric group identifier of the group that owns the file (POSIX).

      " + }, { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" + "textRaw": "`rdev` {number|bigint}", + "type": "number|bigint", + "name": "rdev", + "desc": "

      A numeric device identifier if the file represents a device.

      " }, { - "textRaw": "`buffer` {Buffer|TypedArray|DataView}", - "name": "buffer", - "type": "Buffer|TypedArray|DataView" + "textRaw": "`size` {number|bigint}", + "type": "number|bigint", + "name": "size", + "desc": "

      The size of the file in bytes.

      " }, { - "textRaw": "`offset` {integer}", - "name": "offset", - "type": "integer" + "textRaw": "`blksize` {number|bigint}", + "type": "number|bigint", + "name": "blksize", + "desc": "

      The file system block size for i/o operations.

      " }, { - "textRaw": "`length` {integer}", - "name": "length", - "type": "integer" + "textRaw": "`blocks` {number|bigint}", + "type": "number|bigint", + "name": "blocks", + "desc": "

      The number of blocks allocated for this file.

      " }, { - "textRaw": "`position` {integer}", - "name": "position", - "type": "integer" + "textRaw": "`atimeMs` {number|bigint}", + "type": "number|bigint", + "name": "atimeMs", + "meta": { + "added": [ + "v8.1.0" + ], + "changes": [] + }, + "desc": "

      The timestamp indicating the last time this file was accessed expressed in\nmilliseconds since the POSIX Epoch.

      " }, { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ - { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" - }, - { - "textRaw": "`bytesWritten` {integer}", - "name": "bytesWritten", - "type": "integer" - }, - { - "textRaw": "`buffer` {Buffer|TypedArray|DataView}", - "name": "buffer", - "type": "Buffer|TypedArray|DataView" - } - ] - } - ] - } - ], - "desc": "

      Write buffer to the file specified by fd.

      \n

      offset determines the part of the buffer to be written, and length is\nan integer specifying the number of bytes to write.

      \n

      position refers to the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number', the data will be written\nat the current position. See pwrite(2).

      \n

      The callback will be given three arguments (err, bytesWritten, buffer) where\nbytesWritten specifies how many bytes were written from buffer.

      \n

      If this method is invoked as its util.promisify()ed version, it returns\na Promise for an Object with bytesWritten and buffer properties.

      \n

      It is unsafe to use fs.write() multiple times on the same file without waiting\nfor the callback. For this scenario, fs.createWriteStream() is\nrecommended.

      \n

      On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      " - }, - { - "textRaw": "`fs.write(fd, string[, position[, encoding]], callback)`", - "type": "method", - "name": "write", - "meta": { - "added": [ - "v0.11.5" - ], - "changes": [ - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.2.0", - "pr-url": "https://github.com/nodejs/node/pull/7856", - "description": "The `position` parameter is optional now." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - } - ] - }, - "signatures": [ - { - "params": [ + "textRaw": "`mtimeMs` {number|bigint}", + "type": "number|bigint", + "name": "mtimeMs", + "meta": { + "added": [ + "v8.1.0" + ], + "changes": [] + }, + "desc": "

      The timestamp indicating the last time this file was modified expressed in\nmilliseconds since the POSIX Epoch.

      " + }, { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" + "textRaw": "`ctimeMs` {number|bigint}", + "type": "number|bigint", + "name": "ctimeMs", + "meta": { + "added": [ + "v8.1.0" + ], + "changes": [] + }, + "desc": "

      The timestamp indicating the last time the file status was changed expressed\nin milliseconds since the POSIX Epoch.

      " }, { - "textRaw": "`string` {string}", - "name": "string", - "type": "string" + "textRaw": "`birthtimeMs` {number|bigint}", + "type": "number|bigint", + "name": "birthtimeMs", + "meta": { + "added": [ + "v8.1.0" + ], + "changes": [] + }, + "desc": "

      The timestamp indicating the creation time of this file expressed in\nmilliseconds since the POSIX Epoch.

      " }, { - "textRaw": "`position` {integer}", - "name": "position", - "type": "integer" + "textRaw": "`atimeNs` {bigint}", + "type": "bigint", + "name": "atimeNs", + "meta": { + "added": [ + "v12.10.0" + ], + "changes": [] + }, + "desc": "

      Only present when bigint: true is passed into the method that generates\nthe object.\nThe timestamp indicating the last time this file was accessed expressed in\nnanoseconds since the POSIX Epoch.

      " }, { - "textRaw": "`encoding` {string} **Default:** `'utf8'`", - "name": "encoding", - "type": "string", - "default": "`'utf8'`" + "textRaw": "`mtimeNs` {bigint}", + "type": "bigint", + "name": "mtimeNs", + "meta": { + "added": [ + "v12.10.0" + ], + "changes": [] + }, + "desc": "

      Only present when bigint: true is passed into the method that generates\nthe object.\nThe timestamp indicating the last time this file was modified expressed in\nnanoseconds since the POSIX Epoch.

      " }, { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ - { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" - }, - { - "textRaw": "`written` {integer}", - "name": "written", - "type": "integer" - }, - { - "textRaw": "`string` {string}", - "name": "string", - "type": "string" - } - ] - } - ] - } - ], - "desc": "

      Write string to the file specified by fd. If string is not a string, then\nthe value will be coerced to one.

      \n

      position refers to the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number' the data will be written at\nthe current position. See pwrite(2).

      \n

      encoding is the expected string encoding.

      \n

      The callback will receive the arguments (err, written, string) where written\nspecifies how many bytes the passed string required to be written. Bytes\nwritten is not necessarily the same as string characters written. See\nBuffer.byteLength.

      \n

      It is unsafe to use fs.write() multiple times on the same file without waiting\nfor the callback. For this scenario, fs.createWriteStream() is\nrecommended.

      \n

      On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      \n

      On Windows, if the file descriptor is connected to the console (e.g. fd == 1\nor stdout) a string containing non-ASCII characters will not be rendered\nproperly by default, regardless of the encoding used.\nIt is possible to configure the console to render UTF-8 properly by changing the\nactive codepage with the chcp 65001 command. See the chcp docs for more\ndetails.

      " - }, - { - "textRaw": "`fs.writeFile(file, data[, options], callback)`", - "type": "method", - "name": "writeFile", - "meta": { - "added": [ - "v0.1.29" - ], - "changes": [ - { - "version": "v10.10.0", - "pr-url": "https://github.com/nodejs/node/pull/22150", - "description": "The `data` parameter can now be any `TypedArray` or a `DataView`." - }, - { - "version": "v10.0.0", - "pr-url": "https://github.com/nodejs/node/pull/12562", - "description": "The `callback` parameter is no longer optional. Not passing it will throw a `TypeError` at runtime." - }, - { - "version": "v7.4.0", - "pr-url": "https://github.com/nodejs/node/pull/10382", - "description": "The `data` parameter can now be a `Uint8Array`." - }, - { - "version": "v7.0.0", - "pr-url": "https://github.com/nodejs/node/pull/7897", - "description": "The `callback` parameter is no longer optional. Not passing it will emit a deprecation warning with id DEP0013." - }, - { - "version": "v5.0.0", - "pr-url": "https://github.com/nodejs/node/pull/3163", - "description": "The `file` parameter can be a file descriptor now." - } - ] - }, - "signatures": [ - { - "params": [ + "textRaw": "`ctimeNs` {bigint}", + "type": "bigint", + "name": "ctimeNs", + "meta": { + "added": [ + "v12.10.0" + ], + "changes": [] + }, + "desc": "

      Only present when bigint: true is passed into the method that generates\nthe object.\nThe timestamp indicating the last time the file status was changed expressed\nin nanoseconds since the POSIX Epoch.

      " + }, + { + "textRaw": "`birthtimeNs` {bigint}", + "type": "bigint", + "name": "birthtimeNs", + "meta": { + "added": [ + "v12.10.0" + ], + "changes": [] + }, + "desc": "

      Only present when bigint: true is passed into the method that generates\nthe object.\nThe timestamp indicating the creation time of this file expressed in\nnanoseconds since the POSIX Epoch.

      " + }, { - "textRaw": "`file` {string|Buffer|URL|integer} filename or file descriptor", - "name": "file", - "type": "string|Buffer|URL|integer", - "desc": "filename or file descriptor" + "textRaw": "`atime` {Date}", + "type": "Date", + "name": "atime", + "meta": { + "added": [ + "v0.11.13" + ], + "changes": [] + }, + "desc": "

      The timestamp indicating the last time this file was accessed.

      " }, { - "textRaw": "`data` {string|Buffer|TypedArray|DataView}", - "name": "data", - "type": "string|Buffer|TypedArray|DataView" + "textRaw": "`mtime` {Date}", + "type": "Date", + "name": "mtime", + "meta": { + "added": [ + "v0.11.13" + ], + "changes": [] + }, + "desc": "

      The timestamp indicating the last time this file was modified.

      " }, { - "textRaw": "`options` {Object|string}", - "name": "options", - "type": "Object|string", - "options": [ - { - "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", - "name": "encoding", - "type": "string|null", - "default": "`'utf8'`" - }, - { - "textRaw": "`mode` {integer} **Default:** `0o666`", - "name": "mode", - "type": "integer", - "default": "`0o666`" - }, - { - "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'w'`.", - "name": "flag", - "type": "string", - "default": "`'w'`", - "desc": "See [support of file system `flags`][]." - } - ] + "textRaw": "`ctime` {Date}", + "type": "Date", + "name": "ctime", + "meta": { + "added": [ + "v0.11.13" + ], + "changes": [] + }, + "desc": "

      The timestamp indicating the last time the file status was changed.

      " }, { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ - { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" - } - ] + "textRaw": "`birthtime` {Date}", + "type": "Date", + "name": "birthtime", + "meta": { + "added": [ + "v0.11.13" + ], + "changes": [] + }, + "desc": "

      The timestamp indicating the creation time of this file.

      " + } + ], + "modules": [ + { + "textRaw": "Stat time values", + "name": "stat_time_values", + "desc": "

      The atimeMs, mtimeMs, ctimeMs, birthtimeMs properties are\nnumeric values that hold the corresponding times in milliseconds. Their\nprecision is platform specific. When bigint: true is passed into the\nmethod that generates the object, the properties will be bigints,\notherwise they will be numbers.

      \n

      The atimeNs, mtimeNs, ctimeNs, birthtimeNs properties are\nbigints that hold the corresponding times in nanoseconds. They are\nonly present when bigint: true is passed into the method that generates\nthe object. Their precision is platform specific.

      \n

      atime, mtime, ctime, and birthtime are\nDate object alternate representations of the various times. The\nDate and number values are not connected. Assigning a new number value, or\nmutating the Date value, will not be reflected in the corresponding alternate\nrepresentation.

      \n

      The times in the stat object have the following semantics:

      \n
        \n
      • atime \"Access Time\": Time when file data last accessed. Changed\nby the mknod(2), utimes(2), and read(2) system calls.
      • \n
      • mtime \"Modified Time\": Time when file data last modified.\nChanged by the mknod(2), utimes(2), and write(2) system calls.
      • \n
      • ctime \"Change Time\": Time when file status was last changed\n(inode data modification). Changed by the chmod(2), chown(2),\nlink(2), mknod(2), rename(2), unlink(2), utimes(2),\nread(2), and write(2) system calls.
      • \n
      • birthtime \"Birth Time\": Time of file creation. Set once when the\nfile is created. On filesystems where birthtime is not available,\nthis field may instead hold either the ctime or\n1970-01-01T00:00Z (ie, Unix epoch timestamp 0). This value may be greater\nthan atime or mtime in this case. On Darwin and other FreeBSD variants,\nalso set if the atime is explicitly set to an earlier value than the current\nbirthtime using the utimes(2) system call.
      • \n
      \n

      Prior to Node.js 0.12, the ctime held the birthtime on Windows systems. As\nof 0.12, ctime is not \"creation time\", and on Unix systems, it never was.

      ", + "type": "module", + "displayName": "Stat time values" } ] - } - ], - "desc": "

      When file is a filename, asynchronously writes data to the file, replacing the\nfile if it already exists. data can be a string or a buffer.

      \n

      When file is a file descriptor, the behavior is similar to calling\nfs.write() directly (which is recommended). See the notes below on using\na file descriptor.

      \n

      The encoding option is ignored if data is a buffer.

      \n
      const data = new Uint8Array(Buffer.from('Hello Node.js'));\nfs.writeFile('message.txt', data, (err) => {\n  if (err) throw err;\n  console.log('The file has been saved!');\n});\n
      \n

      If options is a string, then it specifies the encoding:

      \n
      fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback);\n
      \n

      It is unsafe to use fs.writeFile() multiple times on the same file without\nwaiting for the callback. For this scenario, fs.createWriteStream() is\nrecommended.

      ", - "modules": [ + }, { - "textRaw": "Using `fs.writeFile()` with file descriptors", - "name": "using_`fs.writefile()`_with_file_descriptors", - "desc": "

      When file is a file descriptor, the behavior is almost identical to directly\ncalling fs.write() like:

      \n
      fs.write(fd, Buffer.from(data, options.encoding), callback);\n
      \n

      The difference from directly calling fs.write() is that under some unusual\nconditions, fs.write() may write only part of the buffer and will need to be\nretried to write the remaining data, whereas fs.writeFile() will retry until\nthe data is entirely written (or an error occurs).

      \n

      The implications of this are a common source of confusion. In\nthe file descriptor case, the file is not replaced! The data is not necessarily\nwritten to the beginning of the file, and the file's original data may remain\nbefore and/or after the newly written data.

      \n

      For example, if fs.writeFile() is called twice in a row, first to write the\nstring 'Hello', then to write the string ', World', the file would contain\n'Hello, World', and might contain some of the file's original data (depending\non the size of the original file, and the position of the file descriptor). If\na file name had been used instead of a descriptor, the file would be guaranteed\nto contain only ', World'.

      ", - "type": "module", - "displayName": "Using `fs.writeFile()` with file descriptors" - } - ] - }, - { - "textRaw": "`fs.writeFileSync(file, data[, options])`", - "type": "method", - "name": "writeFileSync", - "meta": { - "added": [ - "v0.1.29" - ], - "changes": [ - { - "version": "v10.10.0", - "pr-url": "https://github.com/nodejs/node/pull/22150", - "description": "The `data` parameter can now be any `TypedArray` or a `DataView`." - }, - { - "version": "v7.4.0", - "pr-url": "https://github.com/nodejs/node/pull/10382", - "description": "The `data` parameter can now be a `Uint8Array`." + "textRaw": "Class: `fs.WriteStream`", + "type": "class", + "name": "fs.WriteStream", + "meta": { + "added": [ + "v0.1.93" + ], + "changes": [] }, - { - "version": "v5.0.0", - "pr-url": "https://github.com/nodejs/node/pull/3163", - "description": "The `file` parameter can be a file descriptor now." - } - ] - }, - "signatures": [ - { - "params": [ - { - "textRaw": "`file` {string|Buffer|URL|integer} filename or file descriptor", - "name": "file", - "type": "string|Buffer|URL|integer", - "desc": "filename or file descriptor" - }, + "desc": "\n

      Instances of <fs.WriteStream> are created and returned using the\nfs.createWriteStream() function.

      ", + "events": [ { - "textRaw": "`data` {string|Buffer|TypedArray|DataView}", - "name": "data", - "type": "string|Buffer|TypedArray|DataView" + "textRaw": "Event: `'close'`", + "type": "event", + "name": "close", + "meta": { + "added": [ + "v0.1.93" + ], + "changes": [] + }, + "params": [], + "desc": "

      Emitted when the <fs.WriteStream>'s underlying file descriptor has been closed.

      " }, { - "textRaw": "`options` {Object|string}", - "name": "options", - "type": "Object|string", - "options": [ - { - "textRaw": "`encoding` {string|null} **Default:** `'utf8'`", - "name": "encoding", - "type": "string|null", - "default": "`'utf8'`" - }, + "textRaw": "Event: `'open'`", + "type": "event", + "name": "open", + "meta": { + "added": [ + "v0.1.93" + ], + "changes": [] + }, + "params": [ { - "textRaw": "`mode` {integer} **Default:** `0o666`", - "name": "mode", + "textRaw": "`fd` {integer} Integer file descriptor used by the {fs.WriteStream}.", + "name": "fd", "type": "integer", - "default": "`0o666`" - }, - { - "textRaw": "`flag` {string} See [support of file system `flags`][]. **Default:** `'w'`.", - "name": "flag", - "type": "string", - "default": "`'w'`", - "desc": "See [support of file system `flags`][]." + "desc": "Integer file descriptor used by the {fs.WriteStream}." } - ] - } - ] - } - ], - "desc": "

      Returns undefined.

      \n

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.writeFile().

      " - }, - { - "textRaw": "`fs.writeSync(fd, buffer[, offset[, length[, position]]])`", - "type": "method", - "name": "writeSync", - "meta": { - "added": [ - "v0.1.21" - ], - "changes": [ - { - "version": "v10.10.0", - "pr-url": "https://github.com/nodejs/node/pull/22150", - "description": "The `buffer` parameter can now be any `TypedArray` or a `DataView`." - }, - { - "version": "v7.4.0", - "pr-url": "https://github.com/nodejs/node/pull/10382", - "description": "The `buffer` parameter can now be a `Uint8Array`." - }, - { - "version": "v7.2.0", - "pr-url": "https://github.com/nodejs/node/pull/7856", - "description": "The `offset` and `length` parameters are optional now." - } - ] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {number} The number of bytes written.", - "name": "return", - "type": "number", - "desc": "The number of bytes written." - }, - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`buffer` {Buffer|TypedArray|DataView}", - "name": "buffer", - "type": "Buffer|TypedArray|DataView" - }, - { - "textRaw": "`offset` {integer}", - "name": "offset", - "type": "integer" - }, - { - "textRaw": "`length` {integer}", - "name": "length", - "type": "integer" + ], + "desc": "

      Emitted when the <fs.WriteStream>'s file is opened.

      " }, { - "textRaw": "`position` {integer}", - "name": "position", - "type": "integer" + "textRaw": "Event: `'ready'`", + "type": "event", + "name": "ready", + "meta": { + "added": [ + "v9.11.0" + ], + "changes": [] + }, + "params": [], + "desc": "

      Emitted when the <fs.WriteStream> is ready to be used.

      \n

      Fires immediately after 'open'.

      " } - ] - } - ], - "desc": "

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.write(fd, buffer...).

      " - }, - { - "textRaw": "`fs.writeSync(fd, string[, position[, encoding]])`", - "type": "method", - "name": "writeSync", - "meta": { - "added": [ - "v0.11.5" - ], - "changes": [ - { - "version": "v7.2.0", - "pr-url": "https://github.com/nodejs/node/pull/7856", - "description": "The `position` parameter is optional now." - } - ] - }, - "signatures": [ - { - "return": { - "textRaw": "Returns: {number} The number of bytes written.", - "name": "return", - "type": "number", - "desc": "The number of bytes written." - }, - "params": [ + ], + "properties": [ { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" + "textRaw": "`writeStream.bytesWritten`", + "name": "bytesWritten", + "meta": { + "added": [ + "v0.4.7" + ], + "changes": [] + }, + "desc": "

      The number of bytes written so far. Does not include data that is still queued\nfor writing.

      " }, { - "textRaw": "`string` {string}", - "name": "string", - "type": "string" + "textRaw": "`writeStream.path`", + "name": "path", + "meta": { + "added": [ + "v0.1.93" + ], + "changes": [] + }, + "desc": "

      The path to the file the stream is writing to as specified in the first\nargument to fs.createWriteStream(). If path is passed as a string, then\nwriteStream.path will be a string. If path is passed as a <Buffer>, then\nwriteStream.path will be a <Buffer>.

      " }, { - "textRaw": "`position` {integer}", - "name": "position", - "type": "integer" - }, + "textRaw": "`pending` {boolean}", + "type": "boolean", + "name": "pending", + "meta": { + "added": [ + "v11.2.0" + ], + "changes": [] + }, + "desc": "

      This property is true if the underlying file has not been opened yet,\ni.e. before the 'ready' event is emitted.

      " + } + ], + "methods": [ { - "textRaw": "`encoding` {string}", - "name": "encoding", - "type": "string" + "textRaw": "`writeStream.close([callback])`", + "type": "method", + "name": "close", + "meta": { + "added": [ + "v0.9.4" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function", + "options": [ + { + "textRaw": "`err` {Error}", + "name": "err", + "type": "Error" + } + ] + } + ] + } + ], + "desc": "

      Closes writeStream. Optionally accepts a\ncallback that will be executed once the writeStream\nis closed.

      " } ] } ], - "desc": "

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.write(fd, string...).

      " - }, - { - "textRaw": "`fs.writev(fd, buffers[, position], callback)`", - "type": "method", - "name": "writev", - "meta": { - "added": [ - "v12.9.0" - ], - "changes": [] - }, - "signatures": [ + "properties": [ { - "params": [ - { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" - }, - { - "textRaw": "`buffers` {ArrayBufferView[]}", - "name": "buffers", - "type": "ArrayBufferView[]" - }, - { - "textRaw": "`position` {integer}", - "name": "position", - "type": "integer" - }, - { - "textRaw": "`callback` {Function}", - "name": "callback", - "type": "Function", - "options": [ + "textRaw": "`constants` {Object}", + "type": "Object", + "name": "constants", + "desc": "

      Returns an object containing commonly used constants for file system\noperations.

      ", + "modules": [ + { + "textRaw": "FS constants", + "name": "fs_constants", + "desc": "

      The following constants are exported by fs.constants.

      \n

      Not every constant will be available on every operating system.

      \n

      To use more than one constant, use the bitwise OR | operator.

      \n

      Example:

      \n
      import { open, constants } from 'fs';\n\nconst {\n  O_RDWR,\n  O_CREAT,\n  O_EXCL\n} = constants;\n\nopen('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => {\n  // ...\n});\n
      ", + "modules": [ + { + "textRaw": "File access constants", + "name": "file_access_constants", + "desc": "

      The following constants are meant for use with fs.access().

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      F_OKFlag indicating that the file is visible to the calling process.\n This is useful for determining if a file exists, but says nothing\n about rwx permissions. Default if no mode is specified.
      R_OKFlag indicating that the file can be read by the calling process.
      W_OKFlag indicating that the file can be written by the calling\n process.
      X_OKFlag indicating that the file can be executed by the calling\n process. This has no effect on Windows\n (will behave like fs.constants.F_OK).
      ", + "type": "module", + "displayName": "File access constants" + }, { - "textRaw": "`err` {Error}", - "name": "err", - "type": "Error" + "textRaw": "File copy constants", + "name": "file_copy_constants", + "desc": "

      The following constants are meant for use with fs.copyFile().

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      COPYFILE_EXCLIf present, the copy operation will fail with an error if the\n destination path already exists.
      COPYFILE_FICLONEIf present, the copy operation will attempt to create a\n copy-on-write reflink. If the underlying platform does not support\n copy-on-write, then a fallback copy mechanism is used.
      COPYFILE_FICLONE_FORCEIf present, the copy operation will attempt to create a\n copy-on-write reflink. If the underlying platform does not support\n copy-on-write, then the operation will fail with an error.
      ", + "type": "module", + "displayName": "File copy constants" }, { - "textRaw": "`bytesWritten` {integer}", - "name": "bytesWritten", - "type": "integer" + "textRaw": "File open constants", + "name": "file_open_constants", + "desc": "

      The following constants are meant for use with fs.open().

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      O_RDONLYFlag indicating to open a file for read-only access.
      O_WRONLYFlag indicating to open a file for write-only access.
      O_RDWRFlag indicating to open a file for read-write access.
      O_CREATFlag indicating to create the file if it does not already exist.
      O_EXCLFlag indicating that opening a file should fail if the\n O_CREAT flag is set and the file already exists.
      O_NOCTTYFlag indicating that if path identifies a terminal device, opening the\n path shall not cause that terminal to become the controlling terminal for\n the process (if the process does not already have one).
      O_TRUNCFlag indicating that if the file exists and is a regular file, and the\n file is opened successfully for write access, its length shall be truncated\n to zero.
      O_APPENDFlag indicating that data will be appended to the end of the file.
      O_DIRECTORYFlag indicating that the open should fail if the path is not a\n directory.
      O_NOATIMEFlag indicating reading accesses to the file system will no longer\n result in an update to the atime information associated with\n the file. This flag is available on Linux operating systems only.
      O_NOFOLLOWFlag indicating that the open should fail if the path is a symbolic\n link.
      O_SYNCFlag indicating that the file is opened for synchronized I/O with write\n operations waiting for file integrity.
      O_DSYNCFlag indicating that the file is opened for synchronized I/O with write\n operations waiting for data integrity.
      O_SYMLINKFlag indicating to open the symbolic link itself rather than the\n resource it is pointing to.
      O_DIRECTWhen set, an attempt will be made to minimize caching effects of file\n I/O.
      O_NONBLOCKFlag indicating to open the file in nonblocking mode when possible.
      UV_FS_O_FILEMAPWhen set, a memory file mapping is used to access the file. This flag\n is available on Windows operating systems only. On other operating systems,\n this flag is ignored.
      ", + "type": "module", + "displayName": "File open constants" }, { - "textRaw": "`buffers` {ArrayBufferView[]}", - "name": "buffers", - "type": "ArrayBufferView[]" + "textRaw": "File type constants", + "name": "file_type_constants", + "desc": "

      The following constants are meant for use with the <fs.Stats> object's\nmode property for determining a file's type.

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      S_IFMTBit mask used to extract the file type code.
      S_IFREGFile type constant for a regular file.
      S_IFDIRFile type constant for a directory.
      S_IFCHRFile type constant for a character-oriented device file.
      S_IFBLKFile type constant for a block-oriented device file.
      S_IFIFOFile type constant for a FIFO/pipe.
      S_IFLNKFile type constant for a symbolic link.
      S_IFSOCKFile type constant for a socket.
      ", + "type": "module", + "displayName": "File type constants" + }, + { + "textRaw": "File mode constants", + "name": "file_mode_constants", + "desc": "

      The following constants are meant for use with the <fs.Stats> object's\nmode property for determining the access permissions for a file.

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      S_IRWXUFile mode indicating readable, writable, and executable by owner.
      S_IRUSRFile mode indicating readable by owner.
      S_IWUSRFile mode indicating writable by owner.
      S_IXUSRFile mode indicating executable by owner.
      S_IRWXGFile mode indicating readable, writable, and executable by group.
      S_IRGRPFile mode indicating readable by group.
      S_IWGRPFile mode indicating writable by group.
      S_IXGRPFile mode indicating executable by group.
      S_IRWXOFile mode indicating readable, writable, and executable by others.
      S_IROTHFile mode indicating readable by others.
      S_IWOTHFile mode indicating writable by others.
      S_IXOTHFile mode indicating executable by others.
      ", + "type": "module", + "displayName": "File mode constants" } - ] + ], + "type": "module", + "displayName": "FS constants" } ] } ], - "desc": "

      Write an array of ArrayBufferViews to the file specified by fd using\nwritev().

      \n

      position is the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number', the data will be written\nat the current position.

      \n

      The callback will be given three arguments: err, bytesWritten, and\nbuffers. bytesWritten is how many bytes were written from buffers.

      \n

      If this method is util.promisify()ed, it returns a Promise for an\nObject with bytesWritten and buffers properties.

      \n

      It is unsafe to use fs.writev() multiple times on the same file without\nwaiting for the callback. For this scenario, use fs.createWriteStream().

      \n

      On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      " + "type": "module", + "displayName": "Common Objects" }, { - "textRaw": "`fs.writevSync(fd, buffers[, position])`", - "type": "method", - "name": "writevSync", - "meta": { - "added": [ - "v12.9.0" - ], - "changes": [] - }, - "signatures": [ + "textRaw": "Notes", + "name": "notes", + "modules": [ { - "return": { - "textRaw": "Returns: {number} The number of bytes written.", - "name": "return", - "type": "number", - "desc": "The number of bytes written." - }, - "params": [ + "textRaw": "Ordering of callback and promise-based operations", + "name": "ordering_of_callback_and_promise-based_operations", + "desc": "

      Because they are executed asynchronously by the underlying thread pool,\nthere is no guaranteed ordering when using either the callback or\npromise-based methods.

      \n

      For example, the following is prone to error because the fs.stat()\noperation might complete before the fs.rename() operation:

      \n
      fs.rename('/tmp/hello', '/tmp/world', (err) => {\n  if (err) throw err;\n  console.log('renamed complete');\n});\nfs.stat('/tmp/world', (err, stats) => {\n  if (err) throw err;\n  console.log(`stats: ${JSON.stringify(stats)}`);\n});\n
      \n

      It is important to correctly order the operations by awaiting the results\nof one before invoking the other:

      \n
      import { rename, stat } from 'fs/promises';\n\nconst from = '/tmp/hello';\nconst to = '/tmp/world';\n\ntry {\n  await rename(from, to);\n  const stats = await stat(to);\n  console.log(`stats: ${JSON.stringify(stats)}`);\n} catch (error) {\n  console.error('there was an error:', error.message);\n}\n
      \n
      const { rename, stat } = require('fs/promises');\n\n(async function(from, to) {\n  try {\n    await rename(from, to);\n    const stats = await stat(to);\n    console.log(`stats: ${JSON.stringify(stats)}`);\n  } catch (error) {\n    console.error('there was an error:', error.message);\n  }\n})('/tmp/hello', '/tmp/world');\n
      \n

      Or, when using the callback APIs, move the fs.stat() call into the callback\nof the fs.rename() operation:

      \n
      import { rename, stat } from 'fs';\n\nrename('/tmp/hello', '/tmp/world', (err) => {\n  if (err) throw err;\n  stat('/tmp/world', (err, stats) => {\n    if (err) throw err;\n    console.log(`stats: ${JSON.stringify(stats)}`);\n  });\n});\n
      \n
      const { rename, stat } = require('fs/promises');\n\nrename('/tmp/hello', '/tmp/world', (err) => {\n  if (err) throw err;\n  stat('/tmp/world', (err, stats) => {\n    if (err) throw err;\n    console.log(`stats: ${JSON.stringify(stats)}`);\n  });\n});\n
      ", + "type": "module", + "displayName": "Ordering of callback and promise-based operations" + }, + { + "textRaw": "File paths", + "name": "file_paths", + "desc": "

      Most fs operations accept file paths that may be specified in the form of\na string, a <Buffer>, or a <URL> object using the file: protocol.

      ", + "modules": [ { - "textRaw": "`fd` {integer}", - "name": "fd", - "type": "integer" + "textRaw": "String paths", + "name": "string_paths", + "desc": "

      String form paths are interpreted as UTF-8 character sequences identifying\nthe absolute or relative filename. Relative paths will be resolved relative\nto the current working directory as determined by calling process.cwd().

      \n

      Example using an absolute path on POSIX:

      \n
      import { open } from 'fs/promises';\n\nlet fd;\ntry {\n  fd = await open('/open/some/file.txt', 'r');\n  // Do something with the file\n} finally {\n  await fd.close();\n}\n
      \n

      Example using a relative path on POSIX (relative to process.cwd()):

      \n
      import { open } from 'fs/promises';\n\nlet fd;\ntry {\n  fd = await open('file.txt', 'r');\n  // Do something with the file\n} finally {\n  await fd.close();\n}\n
      ", + "type": "module", + "displayName": "String paths" + }, + { + "textRaw": "File URL paths", + "name": "file_url_paths", + "meta": { + "added": [ + "v7.6.0" + ], + "changes": [] + }, + "desc": "

      For most fs module functions, the path or filename argument may be passed\nas a <URL> object using the file: protocol.

      \n
      import { readFileSync } from 'fs';\n\nreadFileSync(new URL('file:///tmp/hello'));\n
      \n

      file: URLs are always absolute paths.

      ", + "modules": [ + { + "textRaw": "Platform-specific considerations", + "name": "platform-specific_considerations", + "desc": "

      On Windows, file: <URL>s with a host name convert to UNC paths, while file:\n<URL>s with drive letters convert to local absolute paths. file: <URL>s\nwithout a host name nor a drive letter will result in an error:

      \n
      import { readFileSync } from 'fs';\n// On Windows :\n\n// - WHATWG file URLs with hostname convert to UNC path\n// file://hostname/p/a/t/h/file => \\\\hostname\\p\\a\\t\\h\\file\nreadFileSync(new URL('file://hostname/p/a/t/h/file'));\n\n// - WHATWG file URLs with drive letters convert to absolute path\n// file:///C:/tmp/hello => C:\\tmp\\hello\nreadFileSync(new URL('file:///C:/tmp/hello'));\n\n// - WHATWG file URLs without hostname must have a drive letters\nreadFileSync(new URL('file:///notdriveletter/p/a/t/h/file'));\nreadFileSync(new URL('file:///c/p/a/t/h/file'));\n// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute\n
      \n

      file: <URL>s with drive letters must use : as a separator just after\nthe drive letter. Using another separator will result in an error.

      \n

      On all other platforms, file: <URL>s with a host name are unsupported and\nwill result in an error:

      \n
      import { readFileSync } from 'fs';\n// On other platforms:\n\n// - WHATWG file URLs with hostname are unsupported\n// file://hostname/p/a/t/h/file => throw!\nreadFileSync(new URL('file://hostname/p/a/t/h/file'));\n// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute\n\n// - WHATWG file URLs convert to absolute path\n// file:///tmp/hello => /tmp/hello\nreadFileSync(new URL('file:///tmp/hello'));\n
      \n

      A file: <URL> having encoded slash characters will result in an error on all\nplatforms:

      \n
      import { readFileSync } from 'fs';\n\n// On Windows\nreadFileSync(new URL('file:///C:/p/a/t/h/%2F'));\nreadFileSync(new URL('file:///C:/p/a/t/h/%2f'));\n/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded\n\\ or / characters */\n\n// On POSIX\nreadFileSync(new URL('file:///p/a/t/h/%2F'));\nreadFileSync(new URL('file:///p/a/t/h/%2f'));\n/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded\n/ characters */\n
      \n

      On Windows, file: <URL>s having encoded backslash will result in an error:

      \n
      import { readFileSync } from 'fs';\n\n// On Windows\nreadFileSync(new URL('file:///C:/path/%5C'));\nreadFileSync(new URL('file:///C:/path/%5c'));\n/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded\n\\ or / characters */\n
      ", + "type": "module", + "displayName": "Platform-specific considerations" + } + ], + "type": "module", + "displayName": "File URL paths" }, { - "textRaw": "`buffers` {ArrayBufferView[]}", - "name": "buffers", - "type": "ArrayBufferView[]" + "textRaw": "Buffer paths", + "name": "buffer_paths", + "desc": "

      Paths specified using a <Buffer> are useful primarily on certain POSIX\noperating systems that treat file paths as opaque byte sequences. On such\nsystems, it is possible for a single file path to contain sub-sequences that\nuse multiple character encodings. As with string paths, <Buffer> paths may\nbe relative or absolute:

      \n

      Example using an absolute path on POSIX:

      \n
      import { open } from 'fs/promises';\n\nlet fd;\ntry {\n  fd = await open(Buffer.from('/open/some/file.txt'), 'r');\n  // Do something with the file\n} finally {\n  await fd.close();\n}\n
      ", + "type": "module", + "displayName": "Buffer paths" }, { - "textRaw": "`position` {integer}", - "name": "position", - "type": "integer" + "textRaw": "Per-drive working directories on Windows", + "name": "per-drive_working_directories_on_windows", + "desc": "

      On Windows, Node.js follows the concept of per-drive working directory. This\nbehavior can be observed when using a drive path without a backslash. For\nexample fs.readdirSync('C:\\\\') can potentially return a different result than\nfs.readdirSync('C:'). For more information, see\nthis MSDN page.

      ", + "type": "module", + "displayName": "Per-drive working directories on Windows" } - ] + ], + "type": "module", + "displayName": "File paths" + }, + { + "textRaw": "File descriptors", + "name": "file_descriptors", + "desc": "

      On POSIX systems, for every process, the kernel maintains a table of currently\nopen files and resources. Each open file is assigned a simple numeric\nidentifier called a file descriptor. At the system-level, all file system\noperations use these file descriptors to identify and track each specific\nfile. Windows systems use a different but conceptually similar mechanism for\ntracking resources. To simplify things for users, Node.js abstracts away the\ndifferences between operating systems and assigns all open files a numeric file\ndescriptor.

      \n

      The callback-based fs.open(), and synchronous fs.openSync() methods open a\nfile and allocate a new file descriptor. Once allocated, the file descriptor may\nbe used to read data from, write data to, or request information about the file.

      \n

      Operating systems limit the number of file descriptors that may be open\nat any given time so it is critical to close the descriptor when operations\nare completed. Failure to do so will result in a memory leak that will\neventually cause an application to crash.

      \n
      import { open, close, fstat } from 'fs';\n\nfunction closeFd(fd) {\n  close(fd, (err) => {\n    if (err) throw err;\n  });\n}\n\nopen('/open/some/file.txt', 'r', (err, fd) => {\n  if (err) throw err;\n  try {\n    fstat(fd, (err, stat) => {\n      if (err) {\n        closeFd(fd);\n        throw err;\n      }\n\n      // use stat\n\n      closeFd(fd);\n    });\n  } catch (err) {\n    closeFd(fd);\n    throw err;\n  }\n});\n
      \n

      The promise-based APIs use a <FileHandle> object in place of the numeric\nfile descriptor. These objects are better managed by the system to ensure\nthat resources are not leaked. However, it is still required that they are\nclosed when operations are completed:

      \n
      import { open } from 'fs/promises';\n\nlet file;\ntry {\n  file = await open('/open/some/file.txt', 'r');\n  const stat = await file.stat();\n  // use stat\n} finally {\n  await file.close();\n}\n
      ", + "type": "module", + "displayName": "File descriptors" + }, + { + "textRaw": "Threadpool usage", + "name": "threadpool_usage", + "desc": "

      All callback and promise-based file system APIs ( with the exception of\nfs.FSWatcher()) use libuv's threadpool. This can have surprising and negative\nperformance implications for some applications. See the\nUV_THREADPOOL_SIZE documentation for more information.

      ", + "type": "module", + "displayName": "Threadpool usage" + }, + { + "textRaw": "File system flags", + "name": "file_system_flags", + "desc": "

      The following flags are available wherever the flag option takes a\nstring.

      \n
        \n
      • \n

        'a': Open file for appending.\nThe file is created if it does not exist.

        \n
      • \n
      • \n

        'ax': Like 'a' but fails if the path exists.

        \n
      • \n
      • \n

        'a+': Open file for reading and appending.\nThe file is created if it does not exist.

        \n
      • \n
      • \n

        'ax+': Like 'a+' but fails if the path exists.

        \n
      • \n
      • \n

        'as': Open file for appending in synchronous mode.\nThe file is created if it does not exist.

        \n
      • \n
      • \n

        'as+': Open file for reading and appending in synchronous mode.\nThe file is created if it does not exist.

        \n
      • \n
      • \n

        'r': Open file for reading.\nAn exception occurs if the file does not exist.

        \n
      • \n
      • \n

        'r+': Open file for reading and writing.\nAn exception occurs if the file does not exist.

        \n
      • \n
      • \n

        'rs+': Open file for reading and writing in synchronous mode. Instructs\nthe operating system to bypass the local file system cache.

        \n

        This is primarily useful for opening files on NFS mounts as it allows\nskipping the potentially stale local cache. It has a very real impact on\nI/O performance so using this flag is not recommended unless it is needed.

        \n

        This doesn't turn fs.open() or fsPromises.open() into a synchronous\nblocking call. If synchronous operation is desired, something like\nfs.openSync() should be used.

        \n
      • \n
      • \n

        'w': Open file for writing.\nThe file is created (if it does not exist) or truncated (if it exists).

        \n
      • \n
      • \n

        'wx': Like 'w' but fails if the path exists.

        \n
      • \n
      • \n

        'w+': Open file for reading and writing.\nThe file is created (if it does not exist) or truncated (if it exists).

        \n
      • \n
      • \n

        'wx+': Like 'w+' but fails if the path exists.

        \n
      • \n
      \n

      flag can also be a number as documented by open(2); commonly used constants\nare available from fs.constants. On Windows, flags are translated to\ntheir equivalent ones where applicable, e.g. O_WRONLY to FILE_GENERIC_WRITE,\nor O_EXCL|O_CREAT to CREATE_NEW, as accepted by CreateFileW.

      \n

      The exclusive flag 'x' (O_EXCL flag in open(2)) causes the operation to\nreturn an error if the path already exists. On POSIX, if the path is a symbolic\nlink, using O_EXCL returns an error even if the link is to a path that does\nnot exist. The exclusive flag might not work with network file systems.

      \n

      On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.

      \n

      Modifying a file rather than replacing it may require the flag option to be\nset to 'r+' rather than the default 'w'.

      \n

      The behavior of some flags are platform-specific. As such, opening a directory\non macOS and Linux with the 'a+' flag, as in the example below, will return an\nerror. In contrast, on Windows and FreeBSD, a file descriptor or a FileHandle\nwill be returned.

      \n
      // macOS and Linux\nfs.open('<directory>', 'a+', (err, fd) => {\n  // => [Error: EISDIR: illegal operation on a directory, open <directory>]\n});\n\n// Windows and FreeBSD\nfs.open('<directory>', 'a+', (err, fd) => {\n  // => null, <fd>\n});\n
      \n

      On Windows, opening an existing hidden file using the 'w' flag (either\nthrough fs.open() or fs.writeFile() or fsPromises.open()) will fail with\nEPERM. Existing hidden files can be opened for writing with the 'r+' flag.

      \n

      A call to fs.ftruncate() or filehandle.truncate() can be used to reset\nthe file contents.

      ", + "type": "module", + "displayName": "File system flags" } ], - "desc": "

      For detailed information, see the documentation of the asynchronous version of\nthis API: fs.writev().

      " - } - ], - "properties": [ - { - "textRaw": "`constants` {Object}", - "type": "Object", - "name": "constants", - "desc": "

      Returns an object containing commonly used constants for file system\noperations. The specific constants currently defined are described in\nFS constants.

      " + "type": "module", + "displayName": "Notes" } ], "type": "module", diff --git a/doc/api/fs.md b/doc/api/fs.md index 778c6f3ff59630c0e3ed99ecdb1008334792cbd3..88cbbb4afbc1708ab4f50ace013a3436c77badfc 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -11,60 +11,51 @@ The `fs` module enables interacting with the file system in a way modeled on standard POSIX functions. -To use this module: +To use the promise-based APIs: -```js -const fs = require('fs'); +```mjs +import * as fs from 'fs/promises'; ``` -All file system operations have synchronous, callback, and promise-based -forms. +```cjs +const fs = require('fs/promises'); +``` -## Synchronous example +To use the callback and sync APIs: -The synchronous form blocks the Node.js event loop and further JavaScript -execution until the operation is complete. Exceptions are thrown immediately -and can be handled using `try…catch`, or can be allowed to bubble up. +```mjs +import * as fs from 'fs'; +``` -```js +```cjs const fs = require('fs'); - -try { - fs.unlinkSync('/tmp/hello'); - console.log('successfully deleted /tmp/hello'); -} catch (err) { - // handle the error -} ``` -## Callback example +All file system operations have synchronous, callback, and promise-based +forms, and are accessible using both CommonJS syntax and ES6 Modules (ESM). -The callback form takes a completion callback function as its last -argument and invokes the operation asynchronously. The arguments passed to -the completion callback depend on the method, but the first argument is always -reserved for an exception. If the operation is completed successfully, then -the first argument is `null` or `undefined`. +## Promise example -```js -const fs = require('fs'); +Promise-based operations return a promise that is fulfilled when the +asynchronous operation is complete. -fs.unlink('/tmp/hello', (err) => { - if (err) throw err; +```mjs +import { unlink } from 'fs/promises'; + +try { + await unlink('/tmp/hello'); console.log('successfully deleted /tmp/hello'); -}); +} catch (error) { + console.error('there was an error:', error.message); +} ``` -## Promise example - -Promise-based operations return a `Promise` that is resolved when the -asynchronous operation is complete. - -```js -const fs = require('fs').promises; +```cjs +const { unlink } = require('fs/promises'); (async function(path) { try { - await fs.unlink(path); + await unlink(path); console.log(`successfully deleted ${path}`); } catch (error) { console.error('there was an error:', error.message); @@ -72,1092 +63,1289 @@ const fs = require('fs').promises; })('/tmp/hello'); ``` -## Ordering of callback and promise-based operations +## Callback example -There is no guaranteed ordering when using either the callback or -promise-based methods. For example, the following is prone to error -because the `fs.stat()` operation might complete before the `fs.rename()` -operation: +The callback form takes a completion callback function as its last +argument and invokes the operation asynchronously. The arguments passed to +the completion callback depend on the method, but the first argument is always +reserved for an exception. If the operation is completed successfully, then +the first argument is `null` or `undefined`. -```js -fs.rename('/tmp/hello', '/tmp/world', (err) => { - if (err) throw err; - console.log('renamed complete'); -}); -fs.stat('/tmp/world', (err, stats) => { +```mjs +import { unlink } from 'fs'; + +unlink('/tmp/hello', (err) => { if (err) throw err; - console.log(`stats: ${JSON.stringify(stats)}`); + console.log('successfully deleted /tmp/hello'); }); ``` -To correctly order the operations, move the `fs.stat()` call into the callback -of the `fs.rename()` operation: +```cjs +const { unlink } = require('fs'); -```js -fs.rename('/tmp/hello', '/tmp/world', (err) => { +unlink('/tmp/hello', (err) => { if (err) throw err; - fs.stat('/tmp/world', (err, stats) => { - if (err) throw err; - console.log(`stats: ${JSON.stringify(stats)}`); - }); + console.log('successfully deleted /tmp/hello'); }); ``` -Or, use the promise-based API: - -```js -const fs = require('fs').promises; - -(async function(from, to) { - try { - await fs.rename(from, to); - const stats = await fs.stat(to); - console.log(`stats: ${JSON.stringify(stats)}`); - } catch (error) { - console.error('there was an error:', error.message); - } -})('/tmp/hello', '/tmp/world'); -``` - -## File paths - -Most `fs` operations accept filepaths that may be specified in the form of -a string, a [`Buffer`][], or a [`URL`][] object using the `file:` protocol. - -String form paths are interpreted as UTF-8 character sequences identifying -the absolute or relative filename. Relative paths will be resolved relative -to the current working directory as determined by calling `process.cwd()`. - -Example using an absolute path on POSIX: +The callback-based versions of the `fs` module APIs are preferable over +the use of the promise APIs when maximal performance (both in terms of +execution time and memory allocation are required). -```js -const fs = require('fs'); +## Synchronous example -fs.open('/open/some/file.txt', 'r', (err, fd) => { - if (err) throw err; - fs.close(fd, (err) => { - if (err) throw err; - }); -}); -``` +The synchronous APIs block the Node.js event loop and further JavaScript +execution until the operation is complete. Exceptions are thrown immediately +and can be handled using `try…catch`, or can be allowed to bubble up. -Example using a relative path on POSIX (relative to `process.cwd()`): +```mjs +import { unlinkSync } from 'fs'; -```js -fs.open('file.txt', 'r', (err, fd) => { - if (err) throw err; - fs.close(fd, (err) => { - if (err) throw err; - }); -}); +try { + unlinkSync('/tmp/hello'); + console.log('successfully deleted /tmp/hello'); +} catch (err) { + // handle the error +} ``` -Paths specified using a [`Buffer`][] are useful primarily on certain POSIX -operating systems that treat file paths as opaque byte sequences. On such -systems, it is possible for a single file path to contain sub-sequences that -use multiple character encodings. As with string paths, `Buffer` paths may -be relative or absolute: - -Example using an absolute path on POSIX: +```cjs +const { unlinkSync } = require('fs'); -```js -fs.open(Buffer.from('/open/some/file.txt'), 'r', (err, fd) => { - if (err) throw err; - fs.close(fd, (err) => { - if (err) throw err; - }); -}); +try { + unlinkSync('/tmp/hello'); + console.log('successfully deleted /tmp/hello'); +} catch (err) { + // handle the error +} ``` -On Windows, Node.js follows the concept of per-drive working directory. This -behavior can be observed when using a drive path without a backslash. For -example `fs.readdirSync('C:\\')` can potentially return a different result than -`fs.readdirSync('C:')`. For more information, see -[this MSDN page][MSDN-Rel-Path]. +## Promises API + + +The `fs/promises` API provides asynchronous file system methods that return +promises. + +The promise APIs use the underlying Node.js threadpool to perform file +system operations off the event loop thread. These operations are not +synchronized or threadsafe. Care must be taken when performing multiple +concurrent modifications on the same file or data corruption may occur. -### URL object support +### Class: `FileHandle` -For most `fs` module functions, the `path` or `filename` argument may be passed -as a WHATWG [`URL`][] object. Only [`URL`][] objects using the `file:` protocol -are supported. -```js -const fs = require('fs'); -const fileUrl = new URL('file:///tmp/hello'); +A {FileHandle} object is an object wrapper for a numeric file descriptor. -fs.readFileSync(fileUrl); -``` +Instances of the {FileHandle} object are created by the `fsPromises.open()` +method. -`file:` URLs are always absolute paths. +All {FileHandle} objects are {EventEmitter}s. -Using WHATWG [`URL`][] objects might introduce platform-specific behaviors. +If a {FileHandle} is not closed using the `filehandle.close()` method, it will +try to automatically close the file descriptor and emit a process warning, +helping to prevent memory leaks. Please do not rely on this behavior because +it can be unreliable and the file may not be closed. Instead, always explicitly +close {FileHandle}s. Node.js may change this behavior in the future. -On Windows, `file:` URLs with a host name convert to UNC paths, while `file:` -URLs with drive letters convert to local absolute paths. `file:` URLs without a -host name nor a drive letter will result in a throw: +#### `filehandle.appendFile(data[, options])` + -```js -// On Windows : +* `data` {string|Buffer|TypedArray|DataView} +* `options` {Object|string} + * `encoding` {string|null} **Default:** `'utf8'` +* Returns: {Promise} Fulfills with `undefined` upon success. -// - WHATWG file URLs with hostname convert to UNC path -// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file -fs.readFileSync(new URL('file://hostname/p/a/t/h/file')); +Alias of [`filehandle.writeFile()`][]. -// - WHATWG file URLs with drive letters convert to absolute path -// file:///C:/tmp/hello => C:\tmp\hello -fs.readFileSync(new URL('file:///C:/tmp/hello')); +When operating on file handles, the mode cannot be changed from what it was set +to with [`fsPromises.open()`][]. Therefore, this is equivalent to +[`filehandle.writeFile()`][]. -// - WHATWG file URLs without hostname must have a drive letters -fs.readFileSync(new URL('file:///notdriveletter/p/a/t/h/file')); -fs.readFileSync(new URL('file:///c/p/a/t/h/file')); -// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute -``` +#### `filehandle.chmod(mode)` + -`file:` URLs with drive letters must use `:` as a separator just after -the drive letter. Using another separator will result in a throw. +* `mode` {integer} the file mode bit mask. +* Returns: {Promise} Fulfills with `undefined` upon success. -On all other platforms, `file:` URLs with a host name are unsupported and will -result in a throw: +Modifies the permissions on the file. See chmod(2). -```js -// On other platforms: +#### `filehandle.chown(uid, gid)` + -// - WHATWG file URLs with hostname are unsupported -// file://hostname/p/a/t/h/file => throw! -fs.readFileSync(new URL('file://hostname/p/a/t/h/file')); -// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute +* `uid` {integer} The file's new owner's user id. +* `gid` {integer} The file's new group's group id. +* Returns: {Promise} Fulfills with `undefined` upon success. -// - WHATWG file URLs convert to absolute path -// file:///tmp/hello => /tmp/hello -fs.readFileSync(new URL('file:///tmp/hello')); -``` +Changes the ownership of the file. A wrapper for chown(2). -A `file:` URL having encoded slash characters will result in a throw on all -platforms: +#### `filehandle.close()` + -```js -// On Windows -fs.readFileSync(new URL('file:///C:/p/a/t/h/%2F')); -fs.readFileSync(new URL('file:///C:/p/a/t/h/%2f')); -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded -\ or / characters */ +* Returns: {Promise} Fulfills with `undefined` upon success. -// On POSIX -fs.readFileSync(new URL('file:///p/a/t/h/%2F')); -fs.readFileSync(new URL('file:///p/a/t/h/%2f')); -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded -/ characters */ -``` +Closes the file handle after waiting for any pending operation on the handle to +complete. -On Windows, `file:` URLs having encoded backslash will result in a throw: +```mjs +import { open } from 'fs/promises'; -```js -// On Windows -fs.readFileSync(new URL('file:///C:/path/%5C')); -fs.readFileSync(new URL('file:///C:/path/%5c')); -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded -\ or / characters */ +let filehandle; +try { + filehandle = await open('thefile.txt', 'r'); +} finally { + await filehandle?.close(); +} ``` -## File descriptors - -On POSIX systems, for every process, the kernel maintains a table of currently -open files and resources. Each open file is assigned a simple numeric -identifier called a *file descriptor*. At the system-level, all file system -operations use these file descriptors to identify and track each specific -file. Windows systems use a different but conceptually similar mechanism for -tracking resources. To simplify things for users, Node.js abstracts away the -specific differences between operating systems and assigns all open files a -numeric file descriptor. - -The `fs.open()` method is used to allocate a new file descriptor. Once -allocated, the file descriptor may be used to read data from, write data to, -or request information about the file. +#### `filehandle.datasync()` + -```js -fs.open('/open/some/file.txt', 'r', (err, fd) => { - if (err) throw err; - fs.fstat(fd, (err, stat) => { - if (err) throw err; - // use stat +* Returns: {Promise} Fulfills with `undefined` upon success. - // always close the file descriptor! - fs.close(fd, (err) => { - if (err) throw err; - }); - }); -}); -``` +Forces all currently queued I/O operations associated with the file to the +operating system's synchronized I/O completion state. Refer to the POSIX +fdatasync(2) documentation for details. -Most operating systems limit the number of file descriptors that may be open -at any given time so it is critical to close the descriptor when operations -are completed. Failure to do so will result in a memory leak that will -eventually cause an application to crash. +Unlike `filehandle.sync` this method does not flush modified metadata. -## Threadpool usage +#### `filehandle.fd` + -All file system APIs except `fs.FSWatcher()` and those that are explicitly -synchronous use libuv's threadpool, which can have surprising and negative -performance implications for some applications. See the -[`UV_THREADPOOL_SIZE`][] documentation for more information. +* {number} The numeric file descriptor managed by the {FileHandle} object. -## Class: `fs.Dir` +#### `filehandle.read(buffer, offset, length, position)` -A class representing a directory stream. +* `buffer` {Buffer|TypedArray|DataView} A buffer that will be filled with the + file data read. +* `offset` {integer} The location in the buffer at which to start filling. + **Default:** `0` +* `length` {integer} The number of bytes to read. **Default:** + `buffer.byteLength` +* `position` {integer} The location where to begin reading data from the + file. If `null`, data will be read from the current file position, and + the position will be updated. If `position` is an integer, the current + file position will remain unchanged. +* Returns: {Promise} Fulfills upon success with an object with two properties: + * `bytesRead` {integer} The number of bytes read + * `buffer` {Buffer|TypedArray|DataView} A reference to the passed in `buffer` + argument. -Created by [`fs.opendir()`][], [`fs.opendirSync()`][], or -[`fsPromises.opendir()`][]. +Reads data from the file and stores that in the given buffer. -```js -const fs = require('fs'); +If the file is not modified concurrently, the end-of-file is reached when the +number of bytes read is zero. -async function print(path) { - const dir = await fs.promises.opendir(path); - for await (const dirent of dir) { - console.log(dirent.name); - } -} -print('./').catch(console.error); -``` +#### `filehandle.read([options])` + +* `options` {Object} + * `buffer` {Buffer|TypedArray|DataView} A buffer that will be filled with the + file data read. **Default:** `Buffer.alloc(16384)` + * `offset` {integer} The location in the buffer at which to start filling. + **Default:** `0` + * `length` {integer} The number of bytes to read. **Default:** + `buffer.byteLength` + * `position` {integer} The location where to begin reading data from the + file. If `null`, data will be read from the current file position, and + the position will be updated. If `position` is an integer, the current + file position will remain unchanged. **Default:**: `null` +* Returns: {Promise} Fulfills upon success with an object with two properties: + * `bytesRead` {integer} The number of bytes read + * `buffer` {Buffer|TypedArray|DataView} A reference to the passed in `buffer` + argument. + +Reads data from the file and stores that in the given buffer. + +If the file is not modified concurrently, the end-of-file is reached when the +number of bytes read is zero. -### `dir.close()` +#### `filehandle.readFile(options)` -* Returns: {Promise} +* `options` {Object|string} + * `encoding` {string|null} **Default:** `null` + * `signal` {AbortSignal} allows aborting an in-progress readFile +* Returns: {Promise} Fulfills upon a successful read with the contents of the + file. If no encoding is specified (using `options.encoding`), the data is + returned as a {Buffer} object. Otherwise, the data will be a string. -Asynchronously close the directory's underlying resource handle. -Subsequent reads will result in errors. +Asynchronously reads the entire contents of a file. -A `Promise` is returned that will be resolved after the resource has been -closed. +If `options` is a string, then it specifies the `encoding`. + +The {FileHandle} has to support reading. -### `dir.close(callback)` +If one or more `filehandle.read()` calls are made on a file handle and then a +`filehandle.readFile()` call is made, the data will be read from the current +position till the end of the file. It doesn't always read from the beginning +of the file. + +#### `filehandle.readv(buffers[, position])` -* `callback` {Function} - * `err` {Error} - -Asynchronously close the directory's underlying resource handle. -Subsequent reads will result in errors. +* `buffers` {Buffer[]|TypedArray[]|DataView[]} +* `position` {integer} The offset from the beginning of the file where the data + should be read from. If `position` is not a `number`, the data will be read + from the current position. +* Returns: {Promise} Fulfills upon success an object containing two properties: + * `bytesRead` {integer} the number of bytes read + * `buffers` {Buffer[]|TypedArray[]|DataView[]} property containing + a reference to the `buffers` input. -The `callback` will be called after the resource handle has been closed. +Read from a file and write to an array of {ArrayBufferView}s -### `dir.closeSync()` +#### `filehandle.stat([options])` +added: v10.0.0 +changes: + - version: v10.5.0 + pr-url: https://github.com/nodejs/node/pull/20220 + description: Accepts an additional `options` object to specify whether + the numeric values returned should be bigint. +--> -Synchronously close the directory's underlying resource handle. -Subsequent reads will result in errors. +* `options` {Object} + * `bigint` {boolean} Whether the numeric values in the returned + {fs.Stats} object should be `bigint`. **Default:** `false`. +* Returns: {Promise} Fulfills with an {fs.Stats} for the file. -### `dir.path` +#### `filehandle.sync()` -* {string} +* Returns: {Promise} Fufills with `undefined` upon success. -The read-only path of this directory as was provided to [`fs.opendir()`][], -[`fs.opendirSync()`][], or [`fsPromises.opendir()`][]. +Request that all data for the open file descriptor is flushed to the storage +device. The specific implementation is operating system and device specific. +Refer to the POSIX fsync(2) documentation for more detail. -### `dir.read()` +#### `filehandle.truncate(len)` -* Returns: {Promise} containing {fs.Dirent|null} - -Asynchronously read the next directory entry via readdir(3) as an -[`fs.Dirent`][]. +* `len` {integer} **Default:** `0` +* Returns: {Promise} Fulfills with `undefined` upon success. -After the read is completed, a `Promise` is returned that will be resolved with -an [`fs.Dirent`][], or `null` if there are no more directory entries to read. +Truncates the file. -Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results. +If the file was larger than `len` bytes, only the first `len` bytes will be +retained in the file. -### `dir.read(callback)` - +The following example retains only the first four bytes of the file: -* `callback` {Function} - * `err` {Error} - * `dirent` {fs.Dirent|null} +```mjs +import { open } from 'fs/promises'; -Asynchronously read the next directory entry via readdir(3) as an -[`fs.Dirent`][]. +let filehandle = null; +try { + filehandle = await open('temp.txt', 'r+'); + await filehandle.truncate(4); +} finally { + await filehandle?.close(); +} +``` -After the read is completed, the `callback` will be called with an -[`fs.Dirent`][], or `null` if there are no more directory entries to read. +If the file previously was shorter than `len` bytes, it is extended, and the +extended part is filled with null bytes (`'\0'`): -Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results. +If `len` is negative then `0` will be used. -### `dir.readSync()` +#### `filehandle.utimes(atime, mtime)` -* Returns: {fs.Dirent|null} - -Synchronously read the next directory entry via readdir(3) as an -[`fs.Dirent`][]. +* `atime` {number|string|Date} +* `mtime` {number|string|Date} +* Returns: {Promise} -If there are no more directory entries to read, `null` will be returned. +Change the file system timestamps of the object referenced by the {FileHandle} +then resolves the promise with no arguments upon success. -Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results. +This function does not work on AIX versions before 7.1, it will reject the +promise with an error using code `UV_ENOSYS`. -### `dir[Symbol.asyncIterator]()` +#### `filehandle.write(buffer[, offset[, length[, position]]])` - -* Returns: {AsyncIterator} of {fs.Dirent} - -Asynchronously iterates over the directory via readdir(3) until all entries have -been read. +added: v10.0.0 +changes: + - version: v14.12.0 + pr-url: https://github.com/nodejs/node/pull/34993 + description: The `buffer` parameter will stringify an object with an + explicit `toString` function. + - version: v14.0.0 + pr-url: https://github.com/nodejs/node/pull/31030 + description: The `buffer` parameter won't coerce unsupported input to + buffers anymore. +--> + +* `buffer` {Buffer|TypedArray|DataView|string|Object} +* `offset` {integer} The start position from within `buffer` where the data + to write begins. **Default:** `0` +* `length` {integer} The number of bytes from `buffer` to write. **Default:** + `buffer.byteLength` +* `position` {integer} The offset from the beginning of the file where the + data from `buffer` should be written. If `position` is not a `number`, + the data will be written at the current position. See the POSIX pwrite(2) + documentation for more detail. +* Returns: {Promise} -Entries returned by the async iterator are always an [`fs.Dirent`][]. -The `null` case from `dir.read()` is handled internally. +Write `buffer` to the file. -See [`fs.Dir`][] for an example. +If `buffer` is a plain object, it must have an own (not inherited) `toString` +function property. -Directory entries returned by this iterator are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory may or may not be -included in the iteration results. +The promise is resolved with an object containing two properties: -## Class: `fs.Dirent` - +* `bytesWritten` {integer} the number of bytes written +* `buffer` {Buffer|TypedArray|DataView|string|Object} a reference to the + `buffer` written. -A representation of a directory entry, which can be a file or a subdirectory -within the directory, as returned by reading from an [`fs.Dir`][]. The -directory entry is a combination of the file name and file type pairs. +It is unsafe to use `filehandle.write()` multiple times on the same file +without waiting for the promise to be resolved (or rejected). For this +scenario, use [`fs.createWriteStream()`][]. -Additionally, when [`fs.readdir()`][] or [`fs.readdirSync()`][] is called with -the `withFileTypes` option set to `true`, the resulting array is filled with -`fs.Dirent` objects, rather than strings or `Buffers`. +On Linux, positional writes do not work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file. -### `dirent.isBlockDevice()` +#### `filehandle.write(string[, position[, encoding]])` -* Returns: {boolean} - -Returns `true` if the `fs.Dirent` object describes a block device. - -### `dirent.isCharacterDevice()` - +* `string` {string|Object} +* `position` {integer} The offset from the beginning of the file where the + data from `string` should be written. If `position` is not a `number` the + data will be written at the current position. See the POSIX pwrite(2) + documentation for more detail. +* `encoding` {string} The expected string encoding. **Default:** `'utf8'` +* Returns: {Promise} -* Returns: {boolean} +Write `string` to the file. If `string` is not a string, or an object with an +own `toString` function property, the promise is rejected with an error. -Returns `true` if the `fs.Dirent` object describes a character device. +The promise is resolved with an object containing two properties: -### `dirent.isDirectory()` - +* `bytesWritten` {integer} the number of bytes written +* `buffer` {string|Object} a reference to the `string` written. -* Returns: {boolean} +It is unsafe to use `filehandle.write()` multiple times on the same file +without waiting for the promise to be resolved (or rejected). For this +scenario, use [`fs.createWriteStream()`][]. -Returns `true` if the `fs.Dirent` object describes a file system -directory. +On Linux, positional writes do not work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file. -### `dirent.isFIFO()` +#### `filehandle.writeFile(data, options)` -* Returns: {boolean} +* `data` {string|Buffer|TypedArray|DataView|Object|AsyncIterable|Iterable + |Stream} +* `options` {Object|string} + * `encoding` {string|null} The expected character encoding when `data` is a + string. **Default:** `'utf8'` +* Returns: {Promise} -Returns `true` if the `fs.Dirent` object describes a first-in-first-out -(FIFO) pipe. +Asynchronously writes data to a file, replacing the file if it already exists. +`data` can be a string, a buffer, an {AsyncIterable} or {Iterable} object, or an +object with an own `toString` function +property. The promise is resolved with no arguments upon success. -### `dirent.isFile()` - +If `options` is a string, then it specifies the `encoding`. -* Returns: {boolean} +The {FileHandle} has to support writing. + +It is unsafe to use `filehandle.writeFile()` multiple times on the same file +without waiting for the promise to be resolved (or rejected). -Returns `true` if the `fs.Dirent` object describes a regular file. +If one or more `filehandle.write()` calls are made on a file handle and then a +`filehandle.writeFile()` call is made, the data will be written from the +current position till the end of the file. It doesn't always write from the +beginning of the file. -### `dirent.isSocket()` +#### `filehandle.writev(buffers[, position])` -* Returns: {boolean} +* `buffers` {Buffer[]|TypedArray[]|DataView[]} +* `position` {integer} The offset from the beginning of the file where the + data from `buffers` should be written. If `position` is not a `number`, + the data will be written at the current position. +* Returns: {Promise} -Returns `true` if the `fs.Dirent` object describes a socket. +Write an array of {ArrayBufferView}s to the file. -### `dirent.isSymbolicLink()` - +The promise is resolved with an object containing a two properties: -* Returns: {boolean} +* `bytesWritten` {integer} the number of bytes written +* `buffers` {Buffer[]|TypedArray[]|DataView[]} a reference to the `buffers` + input. + +It is unsafe to call `writev()` multiple times on the same file without waiting +for the promise to be resolved (or rejected). -Returns `true` if the `fs.Dirent` object describes a symbolic link. +On Linux, positional writes don't work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file. -### `dirent.name` +### `fsPromises.access(path[, mode])` -* {string|Buffer} +* `path` {string|Buffer|URL} +* `mode` {integer} **Default:** `fs.constants.F_OK` +* Returns: {Promise} Fulfills with `undefined` upon success. -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()`][]. +Tests a user's permissions for the file or directory specified by `path`. +The `mode` argument is an optional integer that specifies the accessibility +checks to be performed. Check [File access constants][] for possible values +of `mode`. It is possible to create a mask consisting of the bitwise OR of +two or more values (e.g. `fs.constants.W_OK | fs.constants.R_OK`). -## Class: `fs.FSWatcher` - +If the accessibility check is successful, the promise is resolved with no +value. If any of the accessibility checks fail, the promise is rejected +with an {Error} object. The following example checks if the file +`/etc/passwd` can be read and written by the current process. -* Extends {EventEmitter} +```mjs +import { access } from 'fs/promises'; +import { constants } from 'fs'; -A successful call to [`fs.watch()`][] method will return a new `fs.FSWatcher` -object. +try { + await access('/etc/passwd', constants.R_OK | constants.W_OK); + console.log('can access'); +} catch { + console.error('cannot access'); +} +``` -All `fs.FSWatcher` objects emit a `'change'` event whenever a specific watched -file is modified. +Using `fsPromises.access()` to check for the accessibility of a file before +calling `fsPromises.open()` is not recommended. Doing so introduces a race +condition, since other processes may change the file's state between the two +calls. Instead, user code should open/read/write the file directly and handle +the error raised if the file is not accessible. -### Event: `'change'` +### `fsPromises.appendFile(path, data[, options])` -* `eventType` {string} The type of change event that has occurred -* `filename` {string|Buffer} The filename that changed (if relevant/available) +* `path` {string|Buffer|URL|FileHandle} filename or {FileHandle} +* `data` {string|Buffer} +* `options` {Object|string} + * `encoding` {string|null} **Default:** `'utf8'` + * `mode` {integer} **Default:** `0o666` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'a'`. +* Returns: {Promise} Fulfills with `undefined` upon success. -Emitted when something changes in a watched directory or file. -See more details in [`fs.watch()`][]. +Asynchronously append data to a file, creating the file if it does not yet +exist. `data` can be a string or a {Buffer}. -The `filename` argument may not be provided depending on operating system -support. If `filename` is provided, it will be provided as a `Buffer` if -`fs.watch()` is called with its `encoding` option set to `'buffer'`, otherwise -`filename` will be a UTF-8 string. +If `options` is a string, then it specifies the `encoding`. -```js -// Example when handled through fs.watch() listener -fs.watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => { - if (filename) { - console.log(filename); - // Prints: - } -}); -``` +The `mode` option only affects the newly created file. See [`fs.open()`][] +for more details. + +The `path` may be specified as a {FileHandle} that has been opened +for appending (using `fsPromises.open()`). -### Event: `'close'` +### `fsPromises.chmod(path, mode)` -Emitted when the watcher stops watching for changes. The closed -`fs.FSWatcher` object is no longer usable in the event handler. +* `path` {string|Buffer|URL} +* `mode` {string|integer} +* Returns: {Promise} Fulfills with `undefined` upon success. -### Event: `'error'` +Changes the permissions of a file. + +### `fsPromises.chown(path, uid, gid)` -* `error` {Error} +* `path` {string|Buffer|URL} +* `uid` {integer} +* `gid` {integer} +* Returns: {Promise} Fulfills with `undefined` upon success. -Emitted when an error occurs while watching the file. The errored -`fs.FSWatcher` object is no longer usable in the event handler. +Changes the ownership of a file. -### `watcher.close()` +### `fsPromises.copyFile(src, dest[, mode])` -Stop watching for changes on the given `fs.FSWatcher`. Once stopped, the -`fs.FSWatcher` object is no longer usable. +* `src` {string|Buffer|URL} source filename to copy +* `dest` {string|Buffer|URL} destination filename of the copy operation +* `mode` {integer} Optional modifiers that specify the behavior of the copy + operation. It is possible to create a mask consisting of the bitwise OR of + two or more values (e.g. + `fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`) + **Default:** `0`. + * `fs.constants.COPYFILE_EXCL`: The copy operation will fail if `dest` + already exists. + * `fs.constants.COPYFILE_FICLONE`: The copy operation will attempt to create + a copy-on-write reflink. If the platform does not support copy-on-write, + then a fallback copy mechanism is used. + * `fs.constants.COPYFILE_FICLONE_FORCE`: The copy operation will attempt to + create a copy-on-write reflink. If the platform does not support + copy-on-write, then the operation will fail. +* Returns: {Promise} Fulfills with `undefined` upon success. -### `watcher.ref()` - +Asynchronously copies `src` to `dest`. By default, `dest` is overwritten if it +already exists. -* Returns: {fs.FSWatcher} +No guarantees are made about the atomicity of the copy operation. If an +error occurs after the destination file has been opened for writing, an attempt +will be made to remove the destination. -When called, requests that the Node.js event loop *not* exit so long as the -`FSWatcher` is active. Calling `watcher.ref()` multiple times will have -no effect. +```mjs +import { constants } from 'fs'; +import { copyFile } from 'fs/promises'; -By default, all `FSWatcher` objects are "ref'ed", making it normally -unnecessary to call `watcher.ref()` unless `watcher.unref()` had been -called previously. +try { + await copyFile('source.txt', 'destination.txt'); + console.log('source.txt was copied to destination.txt'); +} catch { + console.log('The file could not be copied'); +} + +// By using COPYFILE_EXCL, the operation will fail if destination.txt exists. +try { + await copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL); + console.log('source.txt was copied to destination.txt'); +} catch { + console.log('The file could not be copied'); +} +``` -### `watcher.unref()` +### `fsPromises.lchmod(path, mode)` -* Returns: {fs.FSWatcher} +* `path` {string|Buffer|URL} +* `mode` {integer} +* Returns: {Promise} Fulfills with `undefined` upon success. -When called, the active `FSWatcher` object will not require the Node.js -event loop to remain active. If there is no other activity keeping the -event loop running, the process may exit before the `FSWatcher` object's -callback is invoked. Calling `watcher.unref()` multiple times will have -no effect. +Changes the permissions on a symbolic link. + +This method is only implemented on macOS. -## Class: `fs.StatWatcher` +### `fsPromises.lchown(path, uid, gid)` -* Extends {EventEmitter} +* `path` {string|Buffer|URL} +* `uid` {integer} +* `gid` {integer} +* Returns: {Promise} Fulfills with `undefined` upon success. -A successful call to `fs.watchFile()` method will return a new `fs.StatWatcher` -object. +Changes the ownership on a symbolic link. -### `watcher.ref()` +### `fsPromises.lutimes(path, atime, mtime)` -* Returns: {fs.StatWatcher} - -When called, requests that the Node.js event loop *not* exit so long as the -`StatWatcher` is active. Calling `watcher.ref()` multiple times will have -no effect. +* `path` {string|Buffer|URL} +* `atime` {number|string|Date} +* `mtime` {number|string|Date} +* Returns: {Promise} Fulfills with `undefined` upon success. -By default, all `StatWatcher` objects are "ref'ed", making it normally -unnecessary to call `watcher.ref()` unless `watcher.unref()` had been -called previously. +Changes the access and modification times of a file in the same way as +[`fsPromises.utimes()`][], with the difference that if the path refers to a +symbolic link, then the link is not dereferenced: instead, the timestamps of +the symbolic link itself are changed. -### `watcher.unref()` +### `fsPromises.link(existingPath, newPath)` -* Returns: {fs.StatWatcher} +* `existingPath` {string|Buffer|URL} +* `newPath` {string|Buffer|URL} +* Returns: {Promise} Fulfills with `undefined` upon success. -When called, the active `StatWatcher` object will not require the Node.js -event loop to remain active. If there is no other activity keeping the -event loop running, the process may exit before the `StatWatcher` object's -callback is invoked. Calling `watcher.unref()` multiple times will have -no effect. +Creates a new link from the `existingPath` to the `newPath`. See the POSIX +link(2) documentation for more detail. -## Class: `fs.ReadStream` +### `fsPromises.lstat(path[, options])` -* Extends: {stream.Readable} +* `path` {string|Buffer|URL} +* `options` {Object} + * `bigint` {boolean} Whether the numeric values in the returned + {fs.Stats} object should be `bigint`. **Default:** `false`. +* Returns: {Promise} Fulfills with the {fs.Stats} object for the given + symbolic link `path`. -Instances of `fs.ReadStream` are created and returned using the -[`fs.createReadStream()`][] function. +Equivalent to [`fsPromises.stat()`][] unless `path` refers to a symbolic link, +in which case the link itself is stat-ed, not the file that it refers to. +Refer to the POSIX lstat(2) document for more detail. -### Event: `'close'` +### `fsPromises.mkdir(path[, options])` -Emitted when the `fs.ReadStream`'s underlying file descriptor has been closed. - -### Event: `'open'` - +* `path` {string|Buffer|URL} +* `options` {Object|integer} + * `recursive` {boolean} **Default:** `false` + * `mode` {string|integer} Not supported on Windows. **Default:** `0o777`. +* Returns: {Promise} Upon success, fulfills with `undefined` if `recursive` + is `false`, or the first directory path created if `recursive` is `true`. -* `fd` {integer} Integer file descriptor used by the `ReadStream`. +Asynchronously creates a directory. -Emitted when the `fs.ReadStream`'s file descriptor has been opened. +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 directories should be created. Calling +`fsPromises.mkdir()` when `path` is a directory that exists results in a +rejection only when `recursive` is false. -### Event: `'ready'` +### `fsPromises.mkdtemp(prefix[, options])` -Emitted when the `fs.ReadStream` is ready to be used. +* `prefix` {string} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {Promise} Fulfills with a string containing the filesystem path + of the newly created temporary directory. -Fires immediately after `'open'`. +Creates a unique temporary directory. A unique directory name is generated by +appending six random characters to the end of the provided `prefix`. Due to +platform inconsistencies, avoid trailing `X` characters in `prefix`. Some +platforms, notably the BSDs, can return more than six random characters, and +replace trailing `X` characters in `prefix` with random characters. -### `readStream.bytesRead` - +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use. -* {number} +```mjs +import { mkdtemp } from 'fs/promises'; -The number of bytes that have been read so far. +try { + await mkdtemp(path.join(os.tmpdir(), 'foo-')); +} catch (err) { + console.error(err); +} +``` + +The `fsPromises.mkdtemp()` method will append the six randomly selected +characters directly to the `prefix` string. For instance, given a directory +`/tmp`, if the intention is to create a temporary directory *within* `/tmp`, the +`prefix` must end with a trailing platform-specific path separator +(`require('path').sep`). -### `readStream.path` +### `fsPromises.open(path, flags[, mode])` -* {string|Buffer} - -The path to the file the stream is reading from as specified in the first -argument to `fs.createReadStream()`. If `path` is passed as a string, then -`readStream.path` will be a string. If `path` is passed as a `Buffer`, then -`readStream.path` will be a `Buffer`. +* `path` {string|Buffer|URL} +* `flags` {string|number} See [support of file system `flags`][]. + **Default:** `'r'`. +* `mode` {string|integer} Sets the file mode (permission and sticky bits) + if the file is created. **Default:** `0o666` (readable and writable) +* Returns: {Promise} Fulfills with a {FileHandle} object. -### `readStream.pending` - +Opens a {FileHandle}. -* {boolean} +Refer to the POSIX open(2) documentation for more detail. -This property is `true` if the underlying file has not been opened yet, -i.e. before the `'ready'` event is emitted. +Some characters (`< > : " / \ | ? *`) are reserved under Windows as documented +by [Naming Files, Paths, and Namespaces][]. Under NTFS, if the filename contains +a colon, Node.js will open a file system stream, as described by +[this MSDN page][MSDN-Using-Streams]. -## Class: `fs.Stats` +### `fsPromises.opendir(path[, options])` -A `fs.Stats` object provides information about a file. +* `path` {string|Buffer|URL} +* `options` {Object} + * `encoding` {string|null} **Default:** `'utf8'` + * `bufferSize` {number} Number of directory entries that are buffered + internally when reading from the directory. Higher values lead to better + performance but higher memory usage. **Default:** `32` +* Returns: {Promise} Fulfills with an {fs.Dir}. -Objects returned from [`fs.stat()`][], [`fs.lstat()`][] and [`fs.fstat()`][] and -their synchronous counterparts are of this type. -If `bigint` in the `options` passed to those methods is true, the numeric values -will be `bigint` instead of `number`, and the object will contain additional -nanosecond-precision properties suffixed with `Ns`. +Asynchronously open a directory for iterative scanning. See the POSIX +opendir(3) documentation for more detail. -```console -Stats { - dev: 2114, - ino: 48064969, - mode: 33188, - nlink: 1, - uid: 85, - gid: 100, - rdev: 0, - size: 527, - blksize: 4096, - blocks: 8, - atimeMs: 1318289051000.1, - mtimeMs: 1318289051000.1, - ctimeMs: 1318289051000.1, - birthtimeMs: 1318289051000.1, - atime: Mon, 10 Oct 2011 23:24:11 GMT, - mtime: Mon, 10 Oct 2011 23:24:11 GMT, - ctime: Mon, 10 Oct 2011 23:24:11 GMT, - birthtime: Mon, 10 Oct 2011 23:24:11 GMT } -``` +Creates an {fs.Dir}, which contains all further functions for reading from +and cleaning up the directory. -`bigint` version: +The `encoding` option sets the encoding for the `path` while opening the +directory and subsequent read operations. -```console -BigIntStats { - dev: 2114n, - ino: 48064969n, - mode: 33188n, - nlink: 1n, - uid: 85n, - gid: 100n, - rdev: 0n, - size: 527n, - blksize: 4096n, - blocks: 8n, - atimeMs: 1318289051000n, - mtimeMs: 1318289051000n, - ctimeMs: 1318289051000n, - birthtimeMs: 1318289051000n, - atimeNs: 1318289051000000000n, - mtimeNs: 1318289051000000000n, - ctimeNs: 1318289051000000000n, - birthtimeNs: 1318289051000000000n, - atime: Mon, 10 Oct 2011 23:24:11 GMT, - mtime: Mon, 10 Oct 2011 23:24:11 GMT, - ctime: Mon, 10 Oct 2011 23:24:11 GMT, - birthtime: Mon, 10 Oct 2011 23:24:11 GMT } +Example using async iteration: + +```mjs +import { opendir } from 'fs/promises'; + +try { + const dir = await opendir('./'); + for await (const dirent of dir) + console.log(dirent.name); +} catch (err) { + console.error(err); +} ``` -### `stats.isBlockDevice()` +When using the async iterator, the {fs.Dir} object will be automatically +closed after the iterator exits. + +### `fsPromises.readdir(path[, options])` -* Returns: {boolean} +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` + * `withFileTypes` {boolean} **Default:** `false` +* Returns: {Promise} Fulfills with an array of the names of the files in + the directory excluding `'.'` and `'..'`. -Returns `true` if the `fs.Stats` object describes a block device. +Reads the contents of a directory. -### `stats.isCharacterDevice()` - +The optional `options` argument can be a string specifying an encoding, or an +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. -* Returns: {boolean} +If `options.withFileTypes` is set to `true`, the resolved array will contain +{fs.Dirent} objects. + +```mjs +import { readdir } from 'fs/promises'; -Returns `true` if the `fs.Stats` object describes a character device. +try { + const files = await readdir(path); + for (const file of files) + console.log(file); +} catch (err) { + console.error(err); +} +``` -### `stats.isDirectory()` +### `fsPromises.readFile(path[, options])` -* Returns: {boolean} +* `path` {string|Buffer|URL|FileHandle} filename or `FileHandle` +* `options` {Object|string} + * `encoding` {string|null} **Default:** `null` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'r'`. + * `signal` {AbortSignal} allows aborting an in-progress readFile +* Returns: {Promise} Fulfills with the contents of the file. -Returns `true` if the `fs.Stats` object describes a file system directory. +Asynchronously reads the entire contents of a file. -### `stats.isFIFO()` - +If no encoding is specified (using `options.encoding`), the data is returned +as a {Buffer} object. Otherwise, the data will be a string. -* Returns: {boolean} +If `options` is a string, then it specifies the encoding. -Returns `true` if the `fs.Stats` object describes a first-in-first-out (FIFO) -pipe. +When the `path` is a directory, the behavior of `fsPromises.readFile()` is +platform-specific. On macOS, Linux, and Windows, the promise will be rejected +with an error. On FreeBSD, a representation of the directory's contents will be +returned. -### `stats.isFile()` - +It is possible to abort an ongoing `readFile` using an {AbortSignal}. If a +request is aborted the promise returned is rejected with an `AbortError`: -* Returns: {boolean} +```mjs +import { readFile } from 'fs/promises'; -Returns `true` if the `fs.Stats` object describes a regular file. +try { + const controller = new AbortController(); + const { signal } = controller; + const promise = readFile(fileName, { signal }); -### `stats.isSocket()` - + // Abort the request before the promise settles. + controller.abort(); -* Returns: {boolean} + await promise; +} catch (err) { + // When a request is aborted - err is an AbortError + console.error(err); +} +``` + +Aborting an ongoing request does not abort individual operating +system requests but rather the internal buffering `fs.readFile` performs. -Returns `true` if the `fs.Stats` object describes a socket. +Any specified {FileHandle} has to support reading. -### `stats.isSymbolicLink()` +### `fsPromises.readlink(path[, options])` +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {Promise} Fulfills with the `linkString` upon success. -* Returns: {boolean} +Reads the contents of the symbolic link referred to by `path`. See the POSIX +readlink(2) documentation for more detail. The promise is resolved with the +`linkString` upon success. -Returns `true` if the `fs.Stats` object describes a symbolic link. +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use for +the link path returned. If the `encoding` is set to `'buffer'`, the link path +returned will be passed as a {Buffer} object. -This method is only valid when using [`fs.lstat()`][]. +### `fsPromises.realpath(path[, options])` + -### `stats.dev` +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {Promise} Fulfills with the resolved path upon success. -* {number|bigint} +Determines the actual location of `path` using the same semantics as the +`fs.realpath.native()` function. -The numeric identifier of the device containing the file. +Only paths that can be converted to UTF8 strings are supported. -### `stats.ino` - -* {number|bigint} - -The file system specific "Inode" number for the file. - -### `stats.mode` - -* {number|bigint} - -A bit-field describing the file type and mode. - -### `stats.nlink` - -* {number|bigint} - -The number of hard-links that exist for the file. - -### `stats.uid` - -* {number|bigint} - -The numeric user identifier of the user that owns the file (POSIX). - -### `stats.gid` - -* {number|bigint} - -The numeric group identifier of the group that owns the file (POSIX). - -### `stats.rdev` - -* {number|bigint} - -A numeric device identifier if the file represents a device. +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use for +the path. If the `encoding` is set to `'buffer'`, the path returned will be +passed as a {Buffer} object. -### `stats.size` +On Linux, when Node.js is linked against musl libc, the procfs file system must +be mounted on `/proc` in order for this function to work. Glibc does not have +this restriction. -* {number|bigint} +### `fsPromises.rename(oldPath, newPath)` + -The size of the file in bytes. +* `oldPath` {string|Buffer|URL} +* `newPath` {string|Buffer|URL} +* Returns: {Promise} Fulfills with `undefined` upon success. -### `stats.blksize` +Renames `oldPath` to `newPath`. -* {number|bigint} +### `fsPromises.rmdir(path[, options])` + -The file system block size for i/o operations. +* `path` {string|Buffer|URL} +* `options` {Object} + * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or + `EPERM` error is encountered, Node.js retries the operation with a linear + backoff wait of `retryDelay` milliseconds longer on each try. This option + represents the number of retries. This option is ignored if the `recursive` + option is not `true`. **Default:** `0`. + * `recursive` {boolean} If `true`, perform a recursive directory removal. In + recursive mode, errors are not reported if `path` does not exist, and + operations are retried on failure. **Default:** `false`. + * `retryDelay` {integer} The amount of time in milliseconds to wait between + retries. This option is ignored if the `recursive` option is not `true`. + **Default:** `100`. +* Returns: {Promise} Fulfills with `undefined` upon success. -### `stats.blocks` +Removes the directory identified by `path`. -* {number|bigint} +Using `fsPromises.rmdir()` on a file (not a directory) results in the +promise being rejected with an `ENOENT` error on Windows and an `ENOTDIR` +error on POSIX. -The number of blocks allocated for this file. +Setting `recursive` to `true` results in behavior similar to the Unix command +`rm -rf`: an error will not be raised for paths that do not exist, and paths +that represent files will be deleted. The permissive behavior of the +`recursive` option is deprecated, `ENOTDIR` and `ENOENT` will be thrown in +the future. -### `stats.atimeMs` +### `fsPromises.rm(path[, options])` -* {number|bigint} +* `path` {string|Buffer|URL} +* `options` {Object} + * `force` {boolean} When `true`, exceptions will be ignored if `path` does + not exist. **Default:** `false`. + * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or + `EPERM` error is encountered, Node.js will retry the operation with a linear + backoff wait of `retryDelay` milliseconds longer on each try. This option + represents the number of retries. This option is ignored if the `recursive` + option is not `true`. **Default:** `0`. + * `recursive` {boolean} If `true`, perform a recursive directory removal. In + recursive mode operations are retried on failure. **Default:** `false`. + * `retryDelay` {integer} The amount of time in milliseconds to wait between + retries. This option is ignored if the `recursive` option is not `true`. + **Default:** `100`. +* Returns: {Promise} Fulfills with `undefined` upon success. -The timestamp indicating the last time this file was accessed expressed in -milliseconds since the POSIX Epoch. +Removes files and directories (modeled on the standard POSIX `rm` utility). -### `stats.mtimeMs` +### `fsPromises.stat(path[, options])` -* {number|bigint} - -The timestamp indicating the last time this file was modified expressed in -milliseconds since the POSIX Epoch. +* `path` {string|Buffer|URL} +* `options` {Object} + * `bigint` {boolean} Whether the numeric values in the returned + {fs.Stats} object should be `bigint`. **Default:** `false`. +* Returns: {Promise} Fulfills with the {fs.Stats} object for the + given `path`. -### `stats.ctimeMs` +### `fsPromises.symlink(target, path[, type])` -* {number|bigint} - -The timestamp indicating the last time the file status was changed expressed -in milliseconds since the POSIX Epoch. - -### `stats.birthtimeMs` - +* `target` {string|Buffer|URL} +* `path` {string|Buffer|URL} +* `type` {string} **Default:** `'file'` +* Returns: {Promise} Fulfills with `undefined` upon success. -* {number|bigint} +Creates a symbolic link. -The timestamp indicating the creation time of this file expressed in -milliseconds since the POSIX Epoch. +The `type` argument is only used on Windows platforms and can be one of `'dir'`, +`'file'`, or `'junction'`. Windows junction points require the destination path +to be absolute. When using `'junction'`, the `target` argument will +automatically be normalized to absolute path. -### `stats.atimeNs` +### `fsPromises.truncate(path[, len])` -* {bigint} +* `path` {string|Buffer|URL} +* `len` {integer} **Default:** `0` +* Returns: {Promise} Fulfills with `undefined` upon success. -Only present when `bigint: true` is passed into the method that generates -the object. -The timestamp indicating the last time this file was accessed expressed in -nanoseconds since the POSIX Epoch. +Truncates (shortens or extends the length) of the content at `path` to `len` +bytes. -### `stats.mtimeNs` +### `fsPromises.unlink(path)` -* {bigint} +* `path` {string|Buffer|URL} +* Returns: {Promise} Fulfills with `undefined` upon success. -Only present when `bigint: true` is passed into the method that generates -the object. -The timestamp indicating the last time this file was modified expressed in -nanoseconds since the POSIX Epoch. +If `path` refers to a symbolic link, then the link is removed without affecting +the file or directory to which that link refers. If the `path` refers to a file +path that is not a symbolic link, the file is deleted. See the POSIX unlink(2) +documentation for more detail. -### `stats.ctimeNs` +### `fsPromises.utimes(path, atime, mtime)` -* {bigint} - -Only present when `bigint: true` is passed into the method that generates -the object. -The timestamp indicating the last time the file status was changed expressed -in nanoseconds since the POSIX Epoch. +* `path` {string|Buffer|URL} +* `atime` {number|string|Date} +* `mtime` {number|string|Date} +* Returns: {Promise} Fulfills with `undefined` upon success. -### `stats.birthtimeNs` - +Change the file system timestamps of the object referenced by `path`. -* {bigint} +The `atime` and `mtime` arguments follow these rules: -Only present when `bigint: true` is passed into the method that generates -the object. -The timestamp indicating the creation time of this file expressed in -nanoseconds since the POSIX Epoch. +* Values can be either numbers representing Unix epoch time, `Date`s, or a + numeric string like `'123456789.0'`. +* If the value can not be converted to a number, or is `NaN`, `Infinity` or + `-Infinity`, an `Error` will be thrown. -### `stats.atime` +### `fsPromises.watch(filename[, options])` -* {Date} - -The timestamp indicating the last time this file was accessed. +* `filename` {string|Buffer|URL} +* `options` {string|Object} + * `persistent` {boolean} Indicates whether the process should continue to run + as long as files are being watched. **Default:** `true`. + * `recursive` {boolean} Indicates whether all subdirectories should be + watched, or only the current directory. This applies when a directory is + specified, and only on supported platforms (See [caveats][]). **Default:** + `false`. + * `encoding` {string} Specifies the character encoding to be used for the + filename passed to the listener. **Default:** `'utf8'`. + * `signal` {AbortSignal} An {AbortSignal} used to signal when the watcher + should stop. +* Returns: {AsyncIterator} of objects with the properties: + * `eventType` {string} The type of change + * `filename` {string|Buffer} The name of the file changed. -### `stats.mtime` - +Returns an async iterator that watches for changes on `filename`, where `filename` +is either a file or a directory. -* {Date} +```js +const { watch } = require('fs/promises'); -The timestamp indicating the last time this file was modified. +const ac = new AbortController(); +const { signal } = ac; +setTimeout(() => ac.abort(), 10000); -### `stats.ctime` - +(async () => { + try { + const watcher = watch(__filename, { signal }); + for await (const event of watcher) + console.log(event); + } catch (err) { + if (err.name === 'AbortError') + return; + throw err; + } +})(); +``` -* {Date} +On most platforms, `'rename'` is emitted whenever a filename appears or +disappears in the directory. -The timestamp indicating the last time the file status was changed. +All the [caveats][] for `fs.watch()` also apply to `fsPromises.watch()`. -### `stats.birthtime` +### `fsPromises.writeFile(file, data[, options])` -* {Date} +* `file` {string|Buffer|URL|FileHandle} filename or `FileHandle` +* `data` {string|Buffer|TypedArray|DataView|Object|AsyncIterable|Iterable + |Stream} +* `options` {Object|string} + * `encoding` {string|null} **Default:** `'utf8'` + * `mode` {integer} **Default:** `0o666` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'w'`. + * `signal` {AbortSignal} allows aborting an in-progress writeFile +* Returns: {Promise} Fulfills with `undefined` upon success. -The timestamp indicating the creation time of this file. +Asynchronously writes data to a file, replacing the file if it already exists. +`data` can be a string, a {Buffer}, or, an object with an own (not inherited) +`toString` function property. -### Stat time values +The `encoding` option is ignored if `data` is a buffer. -The `atimeMs`, `mtimeMs`, `ctimeMs`, `birthtimeMs` properties are -numeric values that hold the corresponding times in milliseconds. Their -precision is platform specific. When `bigint: true` is passed into the -method that generates the object, the properties will be [bigints][], -otherwise they will be [numbers][MDN-Number]. +If `options` is a string, then it specifies the encoding. -The `atimeNs`, `mtimeNs`, `ctimeNs`, `birthtimeNs` properties are -[bigints][] that hold the corresponding times in nanoseconds. They are -only present when `bigint: true` is passed into the method that generates -the object. Their precision is platform specific. +The `mode` option only affects the newly created file. See [`fs.open()`][] +for more details. -`atime`, `mtime`, `ctime`, and `birthtime` are -[`Date`][MDN-Date] object alternate representations of the various times. The -`Date` and number values are not connected. Assigning a new number value, or -mutating the `Date` value, will not be reflected in the corresponding alternate -representation. +Any specified {FileHandle} has to support writing. -The times in the stat object have the following semantics: +It is unsafe to use `fsPromises.writeFile()` multiple times on the same file +without waiting for the promise to be settled. -* `atime` "Access Time": Time when file data last accessed. Changed - by the mknod(2), utimes(2), and read(2) system calls. -* `mtime` "Modified Time": Time when file data last modified. - Changed by the mknod(2), utimes(2), and write(2) system calls. -* `ctime` "Change Time": Time when file status was last changed - (inode data modification). Changed by the chmod(2), chown(2), - link(2), mknod(2), rename(2), unlink(2), utimes(2), - read(2), and write(2) system calls. -* `birthtime` "Birth Time": Time of file creation. Set once when the - file is created. On filesystems where birthtime is not available, - this field may instead hold either the `ctime` or - `1970-01-01T00:00Z` (ie, Unix epoch timestamp `0`). This value may be greater - than `atime` or `mtime` in this case. On Darwin and other FreeBSD variants, - also set if the `atime` is explicitly set to an earlier value than the current - `birthtime` using the utimes(2) system call. +Similarly to `fsPromises.readFile` - `fsPromises.writeFile` is a convenience +method that performs multiple `write` calls internally to write the buffer +passed to it. For performance sensitive code consider using +[`fs.createWriteStream()`][]. -Prior to Node.js 0.12, the `ctime` held the `birthtime` on Windows systems. As -of 0.12, `ctime` is not "creation time", and on Unix systems, it never was. +It is possible to use an {AbortSignal} to cancel an `fsPromises.writeFile()`. +Cancelation is "best effort", and some amount of data is likely still +to be written. -## Class: `fs.WriteStream` - +```mjs +import { writeFile } from 'fs/promises'; -* Extends {stream.Writable} +try { + const controller = new AbortController(); + const { signal } = controller; + const data = new Uint8Array(Buffer.from('Hello Node.js')); + const promise = writeFile('message.txt', data, { signal }); -Instances of `fs.WriteStream` are created and returned using the -[`fs.createWriteStream()`][] function. + // Abort the request before the promise settles. + controller.abort(); -### Event: `'close'` - + await promise; +} catch (err) { + // When a request is aborted - err is an AbortError + console.error(err); +} +``` -Emitted when the `WriteStream`'s underlying file descriptor has been closed. +Aborting an ongoing request does not abort individual operating +system requests but rather the internal buffering `fs.writeFile` performs. -### Event: `'open'` - +## Callback API -* `fd` {integer} Integer file descriptor used by the `WriteStream`. +The callback APIs perform all operations asynchronously, without blocking the +event loop, then invoke a callback function upon completion or error. -Emitted when the `WriteStream`'s file is opened. +The callback APIs use the underlying Node.js threadpool to perform file +system operations off the event loop thread. These operations are not +synchronized or threadsafe. Care must be taken when performing multiple +concurrent modifications on the same file or data corruption may occur. -### Event: `'ready'` - - -Emitted when the `fs.WriteStream` is ready to be used. - -Fires immediately after `'open'`. - -### `writeStream.bytesWritten` - - -The number of bytes written so far. Does not include data that is still queued -for writing. - -### `writeStream.path` - - -The path to the file the stream is writing to as specified in the first -argument to [`fs.createWriteStream()`][]. If `path` is passed as a string, then -`writeStream.path` will be a string. If `path` is passed as a `Buffer`, then -`writeStream.path` will be a `Buffer`. - -### `writeStream.pending` - - -* {boolean} - -This property is `true` if the underlying file has not been opened yet, -i.e. before the `'ready'` event is emitted. - -## `fs.access(path[, mode], callback)` +### `fs.access(path[, mode], callback)` - -* `path` {string|Buffer|URL} -* `mode` {integer} **Default:** `fs.constants.F_OK` - -Synchronously tests a user's permissions for the file or directory specified -by `path`. The `mode` argument is an optional integer that specifies the -accessibility checks to be performed. Check [File access constants][] for -possible values of `mode`. It is possible to create a mask consisting of -the bitwise OR of two or more values -(e.g. `fs.constants.W_OK | fs.constants.R_OK`). - -If any of the accessibility checks fail, an `Error` will be thrown. Otherwise, -the method will return `undefined`. - -```js -try { - fs.accessSync('etc/passwd', fs.constants.R_OK | fs.constants.W_OK); - console.log('can read/write'); -} catch (err) { - console.error('no access!'); -} -``` - -## `fs.appendFile(path, data[, options], callback)` +### `fs.appendFile(path, data[, options], callback)` - -* `path` {string|Buffer|URL|number} filename or file descriptor -* `data` {string|Buffer} -* `options` {Object|string} - * `encoding` {string|null} **Default:** `'utf8'` - * `mode` {integer} **Default:** `0o666` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'a'`. - -Synchronously append data to a file, creating the file if it does not yet -exist. `data` can be a string or a [`Buffer`][]. - -```js -try { - fs.appendFileSync('message.txt', 'data to append'); - console.log('The "data to append" was appended to file!'); -} catch (err) { - /* Handle the error */ } -``` - -If `options` is a string, then it specifies the encoding: - -```js -fs.appendFileSync('message.txt', 'data to append', 'utf8'); -``` - -The `path` may be specified as a numeric file descriptor that has been opened -for appending (using `fs.open()` or `fs.openSync()`). The file descriptor will -not be closed automatically. -```js -let fd; +open('message.txt', 'a', (err, fd) => { + if (err) throw err; -try { - fd = fs.openSync('message.txt', 'a'); - fs.appendFileSync(fd, 'data to append', 'utf8'); -} catch (err) { - /* Handle the error */ -} finally { - if (fd !== undefined) - fs.closeSync(fd); -} + try { + appendFile(fd, 'data to append', 'utf8', (err) => { + closeFd(fd); + if (err) throw err; + }); + } catch (err) { + closeFd(fd); + throw err; + } +}); ``` -## `fs.chmod(path, mode, callback)` +### `fs.chmod(path, mode, callback)` - -* `path` {string|Buffer|URL} -* `mode` {string|integer} - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.chmod()`][]. - -See also: chmod(2). - -## `fs.chown(path, uid, gid, callback)` +### `fs.chown(path, uid, gid, callback)` - -* `path` {string|Buffer|URL} -* `uid` {integer} -* `gid` {integer} - -Synchronously changes owner and group of a file. Returns `undefined`. -This is the synchronous version of [`fs.chown()`][]. - -See also: chown(2). +See the POSIX chown(2) documentation for more detail. -## `fs.close(fd, callback)` +### `fs.close(fd[, callback])` - -* `fd` {integer} - -Synchronous close(2). Returns `undefined`. - -Calling `fs.closeSync()` on any file descriptor (`fd`) that is currently in use -through any other `fs` operation may lead to undefined behavior. - -## `fs.constants` - -* {Object} - -Returns an object containing commonly used constants for file system -operations. The specific constants currently defined are described in -[FS constants][]. +See the POSIX close(2) documentation for more detail. -## `fs.copyFile(src, dest[, flags], callback)` +### `fs.copyFile(src, dest[, mode], callback)` - -* `src` {string|Buffer|URL} source filename to copy -* `dest` {string|Buffer|URL} destination filename of the copy operation -* `flags` {number} modifiers for copy operation. **Default:** `0`. - -Synchronously copies `src` to `dest`. By default, `dest` is overwritten if it -already exists. Returns `undefined`. Node.js makes no guarantees about the -atomicity of the copy operation. If an error occurs after the destination file -has been opened for writing, Node.js will attempt to remove the destination. - -`flags` is an optional integer that specifies the behavior -of the copy operation. It is possible to create a mask consisting of the bitwise -OR of two or more values (e.g. -`fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`). - -* `fs.constants.COPYFILE_EXCL`: The copy operation will fail if `dest` already -exists. -* `fs.constants.COPYFILE_FICLONE`: The copy operation will attempt to create a -copy-on-write reflink. If the platform does not support copy-on-write, then a -fallback copy mechanism is used. -* `fs.constants.COPYFILE_FICLONE_FORCE`: The copy operation will attempt to -create a copy-on-write reflink. If the platform does not support copy-on-write, -then the operation will fail. - -```js -const fs = require('fs'); +} // destination.txt will be created or overwritten by default. -fs.copyFileSync('source.txt', 'destination.txt'); -console.log('source.txt was copied to destination.txt'); -``` - -If the third argument is a number, then it specifies `flags`: - -```js -const fs = require('fs'); -const { COPYFILE_EXCL } = fs.constants; +copyFile('source.txt', 'destination.txt', callback); // By using COPYFILE_EXCL, the operation will fail if destination.txt exists. -fs.copyFileSync('source.txt', 'destination.txt', COPYFILE_EXCL); +copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL, callback); ``` -## `fs.createReadStream(path[, options])` +### `fs.createReadStream(path[, options])` * `path` {string|Buffer|URL} * `options` {string|Object} * `flags` {string} See [support of file system `flags`][]. **Default:** - `'r'`. + `'r'`. * `encoding` {string} **Default:** `null` * `fd` {integer} **Default:** `null` * `mode` {integer} **Default:** `0o666` * `autoClose` {boolean} **Default:** `true` - * `emitClose` {boolean} **Default:** `false` + * `emitClose` {boolean} **Default:** `true` * `start` {integer} * `end` {integer} **Default:** `Infinity` * `highWaterMark` {integer} **Default:** `64 * 1024` @@ -1803,30 +1857,31 @@ start counting at 0, allowed values are in the [0, [`Number.MAX_SAFE_INTEGER`][]] range. If `fd` is specified and `start` is omitted or `undefined`, `fs.createReadStream()` reads sequentially from the current file position. The `encoding` can be any one of those accepted by -[`Buffer`][]. +{Buffer}. If `fd` is specified, `ReadStream` will ignore the `path` argument and will use the specified file descriptor. This means that no `'open'` event will be emitted. `fd` should be blocking; non-blocking `fd`s should be passed to -[`net.Socket`][]. +{net.Socket}. If `fd` points to a character device that only supports blocking reads (such as keyboard or sound card), read operations do not finish until data is available. This can prevent the process from exiting and the stream from closing naturally. -By default, the stream will not emit a `'close'` event after it has been -destroyed. This is the opposite of the default for other `Readable` streams. -Set the `emitClose` option to `true` to change this behavior. +By default, the stream will emit a `'close'` event after it has been +destroyed, like most `Readable` streams. Set the `emitClose` option to +`false` to change this behavior. By providing the `fs` option, it is possible to override the corresponding `fs` implementations for `open`, `read`, and `close`. When providing the `fs` option, overrides for `open`, `read`, and `close` are required. -```js -const fs = require('fs'); +```mjs +import { createReadStream } from 'fs'; + // Create a stream from some character device. -const stream = fs.createReadStream('/dev/input/event0'); +const stream = createReadStream('/dev/input/event0'); setTimeout(() => { stream.close(); // This may not close the stream. // Artificially marking end-of-stream, as if the underlying resource had @@ -1850,23 +1905,34 @@ file was created. An example to read the last 10 bytes of a file which is 100 bytes long: -```js -fs.createReadStream('sample.txt', { start: 90, end: 99 }); +```mjs +import { createReadStream } from 'fs'; + +createReadStream('sample.txt', { start: 90, end: 99 }); ``` If `options` is a string, then it specifies the encoding. -## `fs.createWriteStream(path[, options])` +### `fs.createWriteStream(path[, options])` * `path` {string|Buffer|URL} * `options` {string|Object} * `flags` {string} See [support of file system `flags`][]. **Default:** - `'w'`. + `'w'`. * `encoding` {string} **Default:** `'utf8'` * `fd` {integer} **Default:** `null` * `mode` {integer} **Default:** `0o666` * `autoClose` {boolean} **Default:** `true` - * `emitClose` {boolean} **Default:** `false` + * `emitClose` {boolean} **Default:** `true` * `start` {integer} * `fs` {Object|null} **Default:** `null` * Returns: {fs.WriteStream} See [Writable Stream][]. -`options` may also include a `start` option to allow writing data at -some position past the beginning of the file, allowed values are in the -[0, [`Number.MAX_SAFE_INTEGER`][]] range. Modifying a file rather -than replacing it may require a `flags` mode of `r+` rather than the -default mode `w`. The `encoding` can be any one of those accepted by -[`Buffer`][]. +`options` may also include a `start` option to allow writing data at some +position past the beginning of the file, allowed values are in the +[0, [`Number.MAX_SAFE_INTEGER`][]] range. Modifying a file rather than replacing +it may require the `flags` option to be set to `r+` rather than the default `w`. +The `encoding` can be any one of those accepted by {Buffer}. If `autoClose` is set to true (default behavior) on `'error'` or `'finish'` the file descriptor will be closed automatically. If `autoClose` is false, @@ -1908,9 +1969,9 @@ then the file descriptor won't be closed, even if there's an error. It is the application's responsibility to close it and make sure there's no file descriptor leak. -By default, the stream will not emit a `'close'` event after it has been -destroyed. This is the opposite of the default for other `Writable` streams. -Set the `emitClose` option to `true` to change this behavior. +By default, the stream will emit a `'close'` event after it has been +destroyed, like most `Writable` streams. Set the `emitClose` option to +`false` to change this behavior. By providing the `fs` option it is possible to override the corresponding `fs` implementations for `open`, `write`, `writev` and `close`. Overriding `write()` @@ -1918,22 +1979,22 @@ without `writev()` can reduce performance as some optimizations (`_writev()`) will be disabled. When providing the `fs` option, overrides for `open`, `close`, and at least one of `write` and `writev` are required. -Like [`ReadStream`][], if `fd` is specified, [`WriteStream`][] will ignore the +Like {fs.ReadStream}, if `fd` is specified, {fs.WriteStream} will ignore the `path` argument and will use the specified file descriptor. This means that no `'open'` event will be emitted. `fd` should be blocking; non-blocking `fd`s -should be passed to [`net.Socket`][]. +should be passed to {net.Socket}. If `options` is a string, then it specifies the encoding. -## `fs.exists(path, callback)` +### `fs.exists(path, callback)` > Stability: 0 - Deprecated: Use [`fs.stat()`][] or [`fs.access()`][] instead. @@ -1945,9 +2006,11 @@ deprecated: v1.0.0 Test whether or not the given path exists by checking with the file system. Then call the `callback` argument with either true or false: -```js -fs.exists('/etc/passwd', (exists) => { - console.log(exists ? 'it\'s there' : 'no passwd!'); +```mjs +import { exists } from 'fs'; + +exists('/etc/passwd', (e) => { + console.log(e ? 'it exists' : 'no passwd!'); }); ``` @@ -1965,14 +2028,23 @@ file directly and handle the error raised if the file does not exist. **write (NOT RECOMMENDED)** -```js -fs.exists('myfile', (exists) => { - if (exists) { +```mjs +import { exists, open, close } from 'fs'; + +exists('myfile', (e) => { + if (e) { console.error('myfile already exists'); } else { - fs.open('myfile', 'wx', (err, fd) => { + open('myfile', 'wx', (err, fd) => { if (err) throw err; - writeMyData(fd); + + try { + writeMyData(fd); + } finally { + close(fd, (err) => { + if (err) throw err; + }); + } }); } }); @@ -1980,8 +2052,9 @@ fs.exists('myfile', (exists) => { **write (RECOMMENDED)** -```js -fs.open('myfile', 'wx', (err, fd) => { +```mjs +import { open, close } from 'fs'; +open('myfile', 'wx', (err, fd) => { if (err) { if (err.code === 'EEXIST') { console.error('myfile already exists'); @@ -1991,18 +2064,33 @@ fs.open('myfile', 'wx', (err, fd) => { throw err; } - writeMyData(fd); + try { + writeMyData(fd); + } finally { + close(fd, (err) => { + if (err) throw err; + }); + } }); ``` **read (NOT RECOMMENDED)** -```js -fs.exists('myfile', (exists) => { - if (exists) { - fs.open('myfile', 'r', (err, fd) => { +```mjs +import { open, close, exists } from 'fs'; + +exists('myfile', (e) => { + if (e) { + open('myfile', 'r', (err, fd) => { if (err) throw err; - readMyData(fd); + + try { + readMyData(fd); + } finally { + close(fd, (err) => { + if (err) throw err; + }); + } }); } else { console.error('myfile does not exist'); @@ -2012,8 +2100,10 @@ fs.exists('myfile', (exists) => { **read (RECOMMENDED)** -```js -fs.open('myfile', 'r', (err, fd) => { +```mjs +import { open, close } from 'fs'; + +open('myfile', 'r', (err, fd) => { if (err) { if (err.code === 'ENOENT') { console.error('myfile does not exist'); @@ -2023,7 +2113,13 @@ fs.open('myfile', 'r', (err, fd) => { throw err; } - readMyData(fd); + try { + readMyData(fd); + } finally { + close(fd, (err) => { + if (err) throw err; + }); + } }); ``` @@ -2035,35 +2131,7 @@ In general, check for the existence of a file only if the file won’t be used directly, for example when its existence is a signal from another process. -## `fs.existsSync(path)` - - -* `path` {string|Buffer|URL} -* Returns: {boolean} - -Returns `true` if the path exists, `false` otherwise. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.exists()`][]. - -`fs.exists()` is deprecated, but `fs.existsSync()` is not. The `callback` -parameter to `fs.exists()` accepts parameters that are inconsistent with other -Node.js callbacks. `fs.existsSync()` does not use a callback. - -```js -if (fs.existsSync('/etc/passwd')) { - console.log('The path exists.'); -} -``` - -## `fs.fchmod(fd, mode, callback)` +### `fs.fchmod(fd, mode, callback)` - -* `fd` {integer} -* `mode` {string|integer} - -Synchronous fchmod(2). Returns `undefined`. +See the POSIX fchmod(2) documentation for more detail. -## `fs.fchown(fd, uid, gid, callback)` +### `fs.fchown(fd, uid, gid, callback)` - -* `fd` {integer} -* `uid` {integer} -* `gid` {integer} +Sets the owner of the file. No arguments other than a possible exception are +given to the completion callback. -Synchronous fchown(2). Returns `undefined`. +See the POSIX fchown(2) documentation for more detail. -## `fs.fdatasync(fd, callback)` +### `fs.fdatasync(fd, callback)` - -* `fd` {integer} - -Synchronous fdatasync(2). Returns `undefined`. +Forces all currently queued I/O operations associated with the file to the +operating system's synchronized I/O completion state. Refer to the POSIX +fdatasync(2) documentation for details. No arguments other than a possible +exception are given to the completion callback. -## `fs.fstat(fd[, options], callback)` +### `fs.fstat(fd[, options], callback)` * `fd` {integer} * `options` {Object} * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. + {fs.Stats} object should be `bigint`. **Default:** `false`. * `callback` {Function} * `err` {Error} * `stats` {fs.Stats} -Asynchronous fstat(2). The callback gets two arguments `(err, stats)` where -`stats` is an [`fs.Stats`][] object. `fstat()` is identical to [`stat()`][], -except that the file to be stat-ed is specified by the file descriptor `fd`. - -## `fs.fstatSync(fd[, options])` - - -* `fd` {integer} -* `options` {Object} - * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. -* Returns: {fs.Stats} +Invokes the callback with the {fs.Stats} for the file descriptor. -Synchronous fstat(2). +See the POSIX fstat(2) documentation for more detail. -## `fs.fsync(fd, callback)` +### `fs.fsync(fd, callback)` - -* `fd` {integer} - -Synchronous fsync(2). Returns `undefined`. +Request that all data for the open file descriptor is flushed to the storage +device. The specific implementation is operating system and device specific. +Refer to the POSIX fsync(2) documentation for more detail. No arguments other +than a possible exception are given to the completion callback. -## `fs.ftruncate(fd[, len], callback)` +### `fs.ftruncate(fd[, len], callback)` - -* `fd` {integer} -* `len` {integer} **Default:** `0` - -Returns `undefined`. +If `len` is negative then `0` will be used. -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.ftruncate()`][]. - -## `fs.futimes(fd, atime, mtime, callback)` +### `fs.futimes(fd, atime, mtime, callback)` - -* `fd` {integer} -* `atime` {number|string|Date} -* `mtime` {number|string|Date} - -Synchronous version of [`fs.futimes()`][]. Returns `undefined`. - -## `fs.lchmod(path, mode, callback)` +### `fs.lchmod(path, mode, callback)` - -* `path` {string|Buffer|URL} -* `mode` {integer} +This method is only implemented on macOS. -Synchronous lchmod(2). Returns `undefined`. +See the POSIX lchmod(2) documentation for more detail. -## `fs.lchown(path, uid, gid, callback)` +### `fs.lchown(path, uid, gid, callback)` - -* `path` {string|Buffer|URL} -* `uid` {integer} -* `gid` {integer} +Set the owner of the symbolic link. No arguments other than a possible +exception are given to the completion callback. -Synchronous lchown(2). Returns `undefined`. +See the POSIX lchown(2) documentation for more detail. -## `fs.lutimes(path, atime, mtime, callback)` +### `fs.lutimes(path, atime, mtime, callback)` * `path` {string|Buffer|URL} @@ -2456,20 +2421,7 @@ symbolic link itself are changed. No arguments other than a possible exception are given to the completion callback. -## `fs.lutimesSync(path, atime, mtime)` - - -* `path` {string|Buffer|URL} -* `atime` {number|string|Date} -* `mtime` {number|string|Date} - -Change the file system timestamps of the symbolic link referenced by `path`. -Returns `undefined`, or throws an exception when parameters are incorrect or -the operation fails. This is the synchronous version of [`fs.lutimes()`][]. - -## `fs.link(existingPath, newPath, callback)` +### `fs.link(existingPath, newPath, callback)` - -* `existingPath` {string|Buffer|URL} -* `newPath` {string|Buffer|URL} +Creates a new link from the `existingPath` to the `newPath`. See the POSIX +link(2) documentation for more detail. No arguments other than a possible +exception are given to the completion callback. -Synchronous link(2). Returns `undefined`. - -## `fs.lstat(path[, options], callback)` +### `fs.lstat(path[, options], callback)` * `path` {string|Buffer|URL} * `options` {Object} * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. + {fs.Stats} object should be `bigint`. **Default:** `false`. * `callback` {Function} * `err` {Error} * `stats` {fs.Stats} -Asynchronous lstat(2). The callback gets two arguments `(err, stats)` where -`stats` is a [`fs.Stats`][] object. `lstat()` is identical to `stat()`, -except that if `path` is a symbolic link, then the link itself is stat-ed, -not the file that it refers to. - -## `fs.lstatSync(path[, options])` - - -* `path` {string|Buffer|URL} -* `options` {Object} - * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. -* Returns: {fs.Stats} +Retrieves the {fs.Stats} for the symbolic link referred to by the path. +The callback gets two arguments `(err, stats)` where `stats` is a {fs.Stats} +object. `lstat()` is identical to `stat()`, except that if `path` is a symbolic +link, then the link itself is stat-ed, not the file that it refers to. -Synchronous lstat(2). +See the POSIX lstat(2) documentation for more details. -## `fs.mkdir(path[, options], callback)` +### `fs.mkdir(path[, options], callback)` - -* `path` {string|Buffer|URL} -* `options` {Object|integer} - * `recursive` {boolean} **Default:** `false` - * `mode` {string|integer} Not supported on Windows. **Default:** `0o777`. -* Returns: {string|undefined} - -Synchronously creates a directory. Returns `undefined`, or if `recursive` is -`true`, the first directory path created. -This is the synchronous version of [`fs.mkdir()`][]. - -See also: mkdir(2). - -## `fs.mkdtemp(prefix[, options], callback)` - - -* `prefix` {string} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {string} - -Returns the created directory path. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.mkdtemp()`][]. - -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use. - -## `fs.open(path[, flags[, mode]], callback)` +### `fs.open(path[, flags[, mode]], callback)` * `path` {string|Buffer|URL} @@ -2778,7 +2664,7 @@ changes: * `err` {Error} * `fd` {integer} -Asynchronous file open. See open(2). +Asynchronous file open. See the POSIX open(2) documentation for more details. `mode` sets the file mode (permission and sticky bits), but only if the file was created. On Windows, only the write permission can be manipulated; see @@ -2794,11 +2680,13 @@ a colon, Node.js will open a file system stream, as described by Functions based on `fs.open()` exhibit this behavior as well: `fs.writeFile()`, `fs.readFile()`, etc. -## `fs.opendir(path[, options], callback)` +### `fs.opendir(path[, options], callback)` @@ -2813,67 +2701,16 @@ changes: * `err` {Error} * `dir` {fs.Dir} -Asynchronously open a directory. See opendir(3). - -Creates an [`fs.Dir`][], which contains all further functions for reading from -and cleaning up the directory. - -The `encoding` option sets the encoding for the `path` while opening the -directory and subsequent read operations. - -## `fs.opendirSync(path[, options])` - - -* `path` {string|Buffer|URL} -* `options` {Object} - * `encoding` {string|null} **Default:** `'utf8'` - * `bufferSize` {number} Number of directory entries that are buffered - internally when reading from the directory. Higher values lead to better - performance but higher memory usage. **Default:** `32` -* Returns: {fs.Dir} - -Synchronously open a directory. See opendir(3). +Asynchronously open a directory. See the POSIX opendir(3) documentation for +more details. -Creates an [`fs.Dir`][], which contains all further functions for reading from +Creates an {fs.Dir}, which contains all further functions for reading from and cleaning up the directory. The `encoding` option sets the encoding for the `path` while opening the directory and subsequent read operations. -## `fs.openSync(path[, flags, mode])` - - -* `path` {string|Buffer|URL} -* `flags` {string|number} **Default:** `'r'`. - See [support of file system `flags`][]. -* `mode` {string|integer} **Default:** `0o666` -* Returns: {number} - -Returns an integer representing the file descriptor. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.open()`][]. - -## `fs.read(fd, buffer, offset, length, position, callback)` +### `fs.read(fd, buffer, offset, length, position, callback)` * `fd` {integer} -* `buffer` {Buffer|TypedArray|DataView} -* `offset` {integer} -* `length` {integer} -* `position` {integer} +* `buffer` {Buffer|TypedArray|DataView} The buffer that the data will be + written to. **Default:** `Buffer.alloc(16384)` +* `offset` {integer} The position in `buffer` to write the data to. **Default:** + `0` +* `length` {integer} The number of bytes to read. **Default:** + `buffer.byteLength` +* `position` {integer|bigint} Specifies where to begin reading from in the + file. If `position` is `null` or `-1 `, data will be read from the current + file position, and the file position will be updated. If `position` is an + integer, the file position will be unchanged. * `callback` {Function} * `err` {Error} * `bytesRead` {integer} @@ -2901,46 +2744,43 @@ changes: Read data from the file specified by `fd`. -`buffer` is the buffer that the data (read from the fd) will be written to. - -`offset` is the offset in the buffer to start writing at. - -`length` is an integer specifying the number of bytes to read. - -`position` is an argument specifying where to begin reading from in the file. -If `position` is `null`, data will be read from the current file position, -and the file position will be updated. -If `position` is an integer, the file position will remain unchanged. - The callback is given the three arguments, `(err, bytesRead, buffer)`. +If the file is not modified concurrently, the end-of-file is reached when the +number of bytes read is zero. + If this method is invoked as its [`util.promisify()`][]ed version, it returns -a `Promise` for an `Object` with `bytesRead` and `buffer` properties. +a promise for an `Object` with `bytesRead` and `buffer` properties. -## `fs.read(fd, [options,] callback)` +### `fs.read(fd, [options,] callback)` * `fd` {integer} * `options` {Object} * `buffer` {Buffer|TypedArray|DataView} **Default:** `Buffer.alloc(16384)` * `offset` {integer} **Default:** `0` - * `length` {integer} **Default:** `buffer.length` - * `position` {integer} **Default:** `null` + * `length` {integer} **Default:** `buffer.byteLength` + * `position` {integer|bigint} **Default:** `null` * `callback` {Function} * `err` {Error} * `bytesRead` {integer} * `buffer` {Buffer} -Similar to the above `fs.read` function, this version takes an optional `options` object. -If no `options` object is specified, it will default with the above values. +Similar to the [`fs.read()`][] function, this version takes an optional +`options` object. If no `options` object is specified, it will default with the +above values. -## `fs.readdir(path[, options], callback)` +### `fs.readdir(path[, options], callback)` - -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` - * `withFileTypes` {boolean} **Default:** `false` -* Returns: {string[]|Buffer[]|fs.Dirent[]} - -Synchronous readdir(3). - -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use for -the filenames returned. If the `encoding` is set to `'buffer'`, -the filenames returned will be passed as `Buffer` objects. - -If `options.withFileTypes` is set to `true`, the result will contain -[`fs.Dirent`][] objects. +{fs.Dirent} objects. -## `fs.readFile(path[, options], callback)` +### `fs.readFile(path[, options], callback)` - -* `path` {string|Buffer|URL|integer} filename or file descriptor -* `options` {Object|string} - * `encoding` {string|null} **Default:** `null` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'r'`. -* Returns: {string|Buffer} + already had `'Hello World`' and six bytes are read with the file descriptor, + the call to `fs.readFile()` with the same file descriptor, would give + `'World'`, rather than `'Hello World'`. -Returns the contents of the `path`. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.readFile()`][]. +#### Performance Considerations -If the `encoding` option is specified then this function returns a -string. Otherwise it returns a buffer. +The `fs.readFile()` method asynchronously reads the contents of a file into +memory one chunk at a time, allowing the event loop to turn between each chunk. +This allows the read operation to have less impact on other activity that may +be using the underlying libuv thread pool but means that it will take longer +to read a complete file into memory. -Similar to [`fs.readFile()`][], when the path is a directory, the behavior of -`fs.readFileSync()` is platform-specific. +The additional read overhead can vary broadly on different systems and depends +on the type of file being read. If the file type is not a regular file (a pipe +for instance) and Node.js is unable to determine an actual file size, each read +operation will load on 64kb of data. For regular files, each read will process +512kb of data. -```js -// macOS, Linux, and Windows -fs.readFileSync(''); -// => [Error: EISDIR: illegal operation on a directory, read ] +For applications that require as-fast-as-possible reading of file contents, it +is better to use `fs.read()` directly and for application code to manage +reading the full contents of the file itself. -// FreeBSD -fs.readFileSync(''); // => -``` +The Node.js GitHub issue [#25741][] provides more information and a detailed +analysis on the performance of `fs.readFile()` for multiple file sizes in +different Node.js versions. -## `fs.readlink(path[, options], callback)` +### `fs.readlink(path[, options], callback)` - -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {string|Buffer} +Reads the contents of the symbolic link referred to by `path`. The callback gets +two arguments `(err, linkString)`. -Synchronous readlink(2). Returns the symbolic link's string value. +See the POSIX readlink(2) documentation for more details. The optional `options` argument can be a string specifying an encoding, or an object with an `encoding` property specifying the character encoding to use for -the link path returned. If the `encoding` is set to `'buffer'`, -the link path returned will be passed as a `Buffer` object. - -## `fs.readSync(fd, buffer, offset, length, position)` - - -* `fd` {integer} -* `buffer` {Buffer|TypedArray|DataView} -* `offset` {integer} -* `length` {integer} -* `position` {integer} -* Returns: {number} - -Returns the number of `bytesRead`. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.read()`][]. - -## `fs.readSync(fd, buffer, [options])` - - -* `fd` {integer} -* `buffer` {Buffer|TypedArray|DataView} -* `options` {Object} - * `offset` {integer} **Default:** `0` - * `length` {integer} **Default:** `buffer.length` - * `position` {integer} **Default:** `null` -* Returns: {number} - -Returns the number of `bytesRead`. - -Similar to the above `fs.readSync` function, this version takes an optional `options` object. -If no `options` object is specified, it will default with the above values. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.read()`][]. +the link path passed to the callback. If the `encoding` is set to `'buffer'`, +the link path returned will be passed as a {Buffer} object. -## `fs.readv(fd, buffers[, position], callback)` +### `fs.readv(fd, buffers[, position], callback)` * `fd` {integer} @@ -3265,22 +3021,9 @@ The callback will be given three arguments: `err`, `bytesRead`, and `buffers`. `bytesRead` is how many bytes were read from the file. If this method is invoked as its [`util.promisify()`][]ed version, it returns -a `Promise` for an `Object` with `bytesRead` and `buffers` properties. - -## `fs.readvSync(fd, buffers[, position])` - - -* `fd` {integer} -* `buffers` {ArrayBufferView[]} -* `position` {integer} -* Returns: {number} The number of bytes read. +a promise for an `Object` with `bytesRead` and `buffers` properties. -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.readv()`][]. - -## `fs.realpath(path[, options], callback)` +### `fs.realpath(path[, options], callback)` @@ -3362,82 +3105,29 @@ Only paths that can be converted to UTF8 strings are supported. The optional `options` argument can be a string specifying an encoding, or an object with an `encoding` property specifying the character encoding to use for the path passed to the callback. If the `encoding` is set to `'buffer'`, -the path returned will be passed as a `Buffer` object. +the path returned will be passed as a {Buffer} object. On Linux, when Node.js is linked against musl libc, the procfs file system must be mounted on `/proc` in order for this function to work. Glibc does not have this restriction. -## `fs.realpathSync(path[, options])` +### `fs.rename(oldPath, newPath, callback)` - -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {string|Buffer} - -Returns the resolved pathname. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.realpath()`][]. - -## `fs.realpathSync.native(path[, options])` - - -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {string|Buffer} - -Synchronous realpath(3). - -Only paths that can be converted to UTF8 strings are supported. - -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use for -the path returned. If the `encoding` is set to `'buffer'`, -the path returned will be passed as a `Buffer` object. - -On Linux, when Node.js is linked against musl libc, the procfs file system must -be mounted on `/proc` in order for this function to work. Glibc does not have -this restriction. - -## `fs.rename(oldPath, newPath, callback)` - * `oldPath` {string|Buffer|URL} @@ -3453,34 +3143,25 @@ given to the completion callback. See also: rename(2). -```js -fs.rename('oldFile.txt', 'newFile.txt', (err) => { +```mjs +import { rename } from 'fs'; + +rename('oldFile.txt', 'newFile.txt', (err) => { if (err) throw err; console.log('Rename complete!'); }); ``` -## `fs.renameSync(oldPath, newPath)` - - -* `oldPath` {string|Buffer|URL} -* `newPath` {string|Buffer|URL} - -Synchronous rename(2). Returns `undefined`. - -## `fs.rmdir(path[, options], callback)` +### `fs.rmdir(path[, options], callback)` -> Stability: 1 - Recursive removal is experimental. - * `path` {string|Buffer|URL} * `options` {Object} * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or - `EPERM` error is encountered, Node.js will retry the operation with a linear - backoff wait of `retryDelay` ms longer on each try. This option represents the - number of retries. This option is ignored if the `recursive` option is not - `true`. **Default:** `0`. + `EPERM` error is encountered, Node.js retries the operation with a linear + backoff wait of `retryDelay` milliseconds longer on each try. This option + represents the number of retries. This option is ignored if the `recursive` + option is not `true`. **Default:** `0`. * `recursive` {boolean} If `true`, perform a recursive directory removal. In - recursive mode, errors are not reported if `path` does not exist, and - operations are retried on failure. **Default:** `false`. + recursive mode, errors are not reported if `path` does not exist, and + operations are retried on failure. **Default:** `false`. * `retryDelay` {integer} The amount of time in milliseconds to wait between - retries. This option is ignored if the `recursive` option is not `true`. - **Default:** `100`. + retries. This option is ignored if the `recursive` option is not `true`. + **Default:** `100`. * `callback` {Function} * `err` {Error} @@ -3529,52 +3208,46 @@ to the completion callback. Using `fs.rmdir()` on a file (not a directory) results in an `ENOENT` error on Windows and an `ENOTDIR` error on POSIX. -## `fs.rmdirSync(path[, options])` +Setting `recursive` to `true` results in behavior similar to the Unix command +`rm -rf`: an error will not be raised for paths that do not exist, and paths +that represent files will be deleted. The permissive behavior of the +`recursive` option is deprecated, `ENOTDIR` and `ENOENT` will be thrown in +the future. + +### `fs.rm(path[, options], callback)` -> Stability: 1 - Recursive removal is experimental. - * `path` {string|Buffer|URL} * `options` {Object} + * `force` {boolean} When `true`, exceptions will be ignored if `path` does + not exist. **Default:** `false`. * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or - `EPERM` error is encountered, Node.js will retry the operation with a linear - backoff wait of `retryDelay` ms longer on each try. This option represents the - number of retries. This option is ignored if the `recursive` option is not - `true`. **Default:** `0`. - * `recursive` {boolean} If `true`, perform a recursive directory removal. In - recursive mode, errors are not reported if `path` does not exist, and - operations are retried on failure. **Default:** `false`. + `EPERM` error is encountered, Node.js will retry the operation with a linear + backoff wait of `retryDelay` milliseconds longer on each try. This option + represents the number of retries. This option is ignored if the `recursive` + option is not `true`. **Default:** `0`. + * `recursive` {boolean} If `true`, perform a recursive removal. In + recursive mode operations are retried on failure. **Default:** `false`. * `retryDelay` {integer} The amount of time in milliseconds to wait between - retries. This option is ignored if the `recursive` option is not `true`. - **Default:** `100`. - -Synchronous rmdir(2). Returns `undefined`. + retries. This option is ignored if the `recursive` option is not `true`. + **Default:** `100`. +* `callback` {Function} + * `err` {Error} -Using `fs.rmdirSync()` on a file (not a directory) results in an `ENOENT` error -on Windows and an `ENOTDIR` error on POSIX. +Asynchronously removes files and directories (modeled on the standard POSIX `rm` +utility). No arguments other than a possible exception are given to the +completion callback. -## `fs.stat(path[, options], callback)` +### `fs.stat(path[, options], callback)` * `path` {string|Buffer|URL} * `options` {Object} * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. + {fs.Stats} object should be `bigint`. **Default:** `false`. * `callback` {Function} * `err` {Error} * `stats` {fs.Stats} Asynchronous stat(2). The callback gets two arguments `(err, stats)` where -`stats` is an [`fs.Stats`][] object. +`stats` is an {fs.Stats} object. In case of an error, the `err.code` will be one of [Common System Errors][]. @@ -3624,13 +3293,13 @@ For example, given the following directory structure: The next program will check for the stats of the given paths: -```js -const fs = require('fs'); +```mjs +import { stat } from 'fs'; const pathsToCheck = ['./txtDir', './txtDir/file.txt']; for (let i = 0; i < pathsToCheck.length; i++) { - fs.stat(pathsToCheck[i], function(err, stats) { + stat(pathsToCheck[i], (err, stats) => { console.log(stats.isDirectory()); console.log(stats); }); @@ -3684,41 +3353,19 @@ Stats { } ``` -## `fs.statSync(path[, options])` - - -* `path` {string|Buffer|URL} -* `options` {Object} - * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. -* Returns: {fs.Stats} - -Synchronous stat(2). - -## `fs.symlink(target, path[, type], callback)` +### `fs.symlink(target, path[, type], callback)` * `target` {string|Buffer|URL} @@ -3727,9 +3374,10 @@ changes: * `callback` {Function} * `err` {Error} -Asynchronous symlink(2) which creates the link called `path` pointing to -`target`. No arguments other than a possible exception are given to the -completion callback. +Creates the link called `path` pointing to `target`. No arguments other than a +possible exception are given to the completion callback. + +See the POSIX symlink(2) documentation for more details. The `type` argument is only available on Windows and ignored on other platforms. It can be set to `'dir'`, `'file'`, or `'junction'`. If the `type` argument is @@ -3740,8 +3388,10 @@ require the destination path to be absolute. When using `'junction'`, the Relative targets are relative to the link’s parent directory. -```js -fs.symlink('./mew', './example/mewtwo', callback); +```mjs +import { symlink } from 'fs'; + +symlink('./mew', './example/mewtwo', callback); ``` The above example creates a symbolic link `mewtwo` in the `example` which points @@ -3754,31 +3404,7 @@ example/ └── mewtwo -> ./mew ``` -## `fs.symlinkSync(target, path[, type])` - - -* `target` {string|Buffer|URL} -* `path` {string|Buffer|URL} -* `type` {string} - -Returns `undefined`. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.symlink()`][]. - -## `fs.truncate(path[, len], callback)` +### `fs.truncate(path[, len], callback)` - -* `path` {string|Buffer|URL} -* `len` {integer} **Default:** `0` +```mjs +import { truncate } from 'fs'; +// Assuming that 'path/file.txt' is a regular file. +truncate('path/file.txt', (err) => { + if (err) throw err; + console.log('path/file.txt was truncated'); +}); +``` -Synchronous truncate(2). Returns `undefined`. A file descriptor can also be -passed as the first argument. In this case, `fs.ftruncateSync()` is called. +```cjs +const { truncate } = require('fs'); +// Assuming that 'path/file.txt' is a regular file. +truncate('path/file.txt', (err) => { + if (err) throw err; + console.log('path/file.txt was truncated'); +}); +``` Passing a file descriptor is deprecated and may result in an error being thrown in the future. -## `fs.unlink(path, callback)` +See the POSIX truncate(2) documentation for more details. + +### `fs.unlink(path, callback)` - -* `path` {string|Buffer|URL} - -Synchronous unlink(2). Returns `undefined`. +See the POSIX unlink(2) documentation for more details. -## `fs.unwatchFile(filename[, listener])` +### `fs.unwatchFile(filename[, listener])` @@ -3890,7 +3509,7 @@ Using [`fs.watch()`][] is more efficient than `fs.watchFile()` and `fs.unwatchFile()`. `fs.watch()` should be used instead of `fs.watchFile()` and `fs.unwatchFile()` when possible. -## `fs.utimes(path, atime, mtime, callback)` +### `fs.utimes(path, atime, mtime, callback)` - -* `path` {string|Buffer|URL} -* `atime` {number|string|Date} -* `mtime` {number|string|Date} - -Returns `undefined`. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.utimes()`][]. - -## `fs.watch(filename[, options][, listener])` +### `fs.watch(filename[, options][, listener])` @@ -4011,11 +3610,13 @@ The `fs.watch` API is not 100% consistent across platforms, and is unavailable in some situations. The recursive option is only supported on macOS and Windows. +An `ERR_FEATURE_UNAVAILABLE_ON_PLATFORM` exception will be thrown +when the option is used on a platform that does not support it. On Windows, no events will be emitted if the watched directory is moved or renamed. An `EPERM` error is reported when the watched directory is deleted. -#### Availability +##### Availability @@ -4028,11 +3629,11 @@ to be notified of filesystem changes. directories. * On SunOS systems (including Solaris and SmartOS), this uses [`event ports`][]. * On Windows systems, this feature depends on [`ReadDirectoryChangesW`][]. -* On Aix systems, this feature depends on [`AHAFS`][], which must be enabled. +* On AIX systems, this feature depends on [`AHAFS`][], which must be enabled. * On IBM i systems, this feature is not supported. If the underlying functionality is not available for some reason, then -`fs.watch()` will not be able to function and may thrown an exception. +`fs.watch()` will not be able to function and may throw an exception. For example, watching files or directories can be unreliable, and in some cases impossible, on network file systems (NFS, SMB, etc) or host file systems when using virtualization software such as Vagrant or Docker. @@ -4040,7 +3641,7 @@ when using virtualization software such as Vagrant or Docker. It is still possible to use `fs.watchFile()`, which uses stat polling, but this method is slower and less reliable. -#### Inodes +##### Inodes @@ -4054,7 +3655,7 @@ AIX files retain the same inode for the lifetime of a file. Saving and closing a watched file on AIX will result in two notifications (one for adding new content, and one for truncation). -#### Filename argument +##### Filename argument @@ -4063,8 +3664,9 @@ macOS, Windows, and AIX. Even on supported platforms, `filename` is not always guaranteed to be provided. Therefore, don't assume that `filename` argument is always provided in the callback, and have some fallback logic if it is `null`. -```js -fs.watch('somedir', (eventType, filename) => { +```mjs +import { watch } from 'fs'; +watch('somedir', (eventType, filename) => { console.log(`event type is: ${eventType}`); if (filename) { console.log(`filename provided: ${filename}`); @@ -4074,7 +3676,7 @@ fs.watch('somedir', (eventType, filename) => { }); ``` -## `fs.watchFile(filename[, options], listener)` +### `fs.watchFile(filename[, options], listener)` * `filename` {string|Buffer|URL} @@ -4109,8 +3711,10 @@ target should be polled in milliseconds. The `listener` gets two arguments the current stat object and the previous stat object: -```js -fs.watchFile('message.text', (curr, prev) => { +```mjs +import { watchFile } from 'fs'; + +watchFile('message.text', (curr, prev) => { console.log(`the current mtime is: ${curr.mtime}`); console.log(`the previous mtime was: ${prev.mtime}`); }); @@ -4142,14 +3746,22 @@ This happens when: * the file is deleted, followed by a restore * the file is renamed and then renamed a second time back to its original name -## `fs.write(fd, buffer[, offset[, length[, position]]], callback)` +### `fs.write(fd, buffer[, offset[, length[, position]]], callback)` * `fd` {integer} -* `buffer` {Buffer|TypedArray|DataView} +* `buffer` {Buffer|TypedArray|DataView|string|Object} * `offset` {integer} * `length` {integer} * `position` {integer} @@ -4176,7 +3788,8 @@ changes: * `bytesWritten` {integer} * `buffer` {Buffer|TypedArray|DataView} -Write `buffer` to the file specified by `fd`. +Write `buffer` to the file specified by `fd`. If `buffer` is a normal object, it +must have an own `toString` function property. `offset` determines the part of the buffer to be written, and `length` is an integer specifying the number of bytes to write. @@ -4189,7 +3802,7 @@ The callback will be given three arguments `(err, bytesWritten, buffer)` where `bytesWritten` specifies how many _bytes_ were written from `buffer`. If this method is invoked as its [`util.promisify()`][]ed version, it returns -a `Promise` for an `Object` with `bytesWritten` and `buffer` properties. +a promise for an `Object` with `bytesWritten` and `buffer` properties. It is unsafe to use `fs.write()` multiple times on the same file without waiting for the callback. For this scenario, [`fs.createWriteStream()`][] is @@ -4199,10 +3812,18 @@ On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file. -## `fs.write(fd, string[, position[, encoding]], callback)` +### `fs.write(fd, string[, position[, encoding]], callback)` * `fd` {integer} -* `string` {string} +* `string` {string|Object} * `position` {integer} * `encoding` {string} **Default:** `'utf8'` * `callback` {Function} @@ -4225,8 +3846,8 @@ changes: * `written` {integer} * `string` {string} -Write `string` to the file specified by `fd`. If `string` is not a string, then -the value will be coerced to one. +Write `string` to the file specified by `fd`. If `string` is not a string, or an +object with an own `toString` function property, then an exception is thrown. `position` refers to the offset from the beginning of the file where this data should be written. If `typeof position !== 'number'` the data will be written at @@ -4254,10 +3875,22 @@ It is possible to configure the console to render UTF-8 properly by changing the active codepage with the `chcp 65001` command. See the [chcp][] docs for more details. -## `fs.writeFile(file, data[, options], callback)` +### `fs.writeFile(file, data[, options], callback)` * `file` {string|Buffer|URL|integer} filename or file descriptor -* `data` {string|Buffer|TypedArray|DataView} +* `data` {string|Buffer|TypedArray|DataView|Object} * `options` {Object|string} * `encoding` {string|null} **Default:** `'utf8'` * `mode` {integer} **Default:** `0o666` * `flag` {string} See [support of file system `flags`][]. **Default:** `'w'`. + * `signal` {AbortSignal} allows aborting an in-progress writeFile * `callback` {Function} * `err` {Error} When `file` is a filename, asynchronously writes data to the file, replacing the -file if it already exists. `data` can be a string or a buffer. +file if it already exists. `data` can be a string or a buffer. When `file` is a file descriptor, the behavior is similar to calling `fs.write()` directly (which is recommended). See the notes below on using @@ -4296,9 +3930,17 @@ a file descriptor. The `encoding` option is ignored if `data` is a buffer. -```js +The `mode` option only affects the newly created file. See [`fs.open()`][] +for more details. + +If `data` is a plain object, it must have an own (not inherited) `toString` +function property. + +```mjs +import { writeFile } from 'fs'; + const data = new Uint8Array(Buffer.from('Hello Node.js')); -fs.writeFile('message.txt', data, (err) => { +writeFile('message.txt', data, (err) => { if (err) throw err; console.log('The file has been saved!'); }); @@ -4306,26 +3948,54 @@ fs.writeFile('message.txt', data, (err) => { If `options` is a string, then it specifies the encoding: -```js -fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback); +```mjs +import { writeFile } from 'fs'; + +writeFile('message.txt', 'Hello Node.js', 'utf8', callback); ``` It is unsafe to use `fs.writeFile()` multiple times on the same file without waiting for the callback. For this scenario, [`fs.createWriteStream()`][] is recommended. -### Using `fs.writeFile()` with file descriptors +Similarly to `fs.readFile` - `fs.writeFile` is a convenience method that +performs multiple `write` calls internally to write the buffer passed to it. +For performance sensitive code consider using [`fs.createWriteStream()`][]. + +It is possible to use an {AbortSignal} to cancel an `fs.writeFile()`. +Cancelation is "best effort", and some amount of data is likely still +to be written. + +```mjs +import { writeFile } from 'fs'; + +const controller = new AbortController(); +const { signal } = controller; +const data = new Uint8Array(Buffer.from('Hello Node.js')); +writeFile('message.txt', data, { signal }, (err) => { + // When a request is aborted - the callback is called with an AbortError +}); +// When the request should be aborted +controller.abort(); +``` + +Aborting an ongoing request does not abort individual operating +system requests but rather the internal buffering `fs.writeFile` performs. + +#### Using `fs.writeFile()` with file descriptors When `file` is a file descriptor, the behavior is almost identical to directly calling `fs.write()` like: -```js -fs.write(fd, Buffer.from(data, options.encoding), callback); +```mjs +import { write } from 'fs'; + +write(fd, Buffer.from(data, options.encoding), callback); ``` The difference from directly calling `fs.write()` is that under some unusual -conditions, `fs.write()` may write only part of the buffer and will need to be -retried to write the remaining data, whereas `fs.writeFile()` will retry until +conditions, `fs.write()` might write only part of the buffer and need to be +retried to write the remaining data, whereas `fs.writeFile()` retries until the data is entirely written (or an error occurs). The implications of this are a common source of confusion. In @@ -4340,90 +4010,18 @@ on the size of the original file, and the position of the file descriptor). If a file name had been used instead of a descriptor, the file would be guaranteed to contain only `', World'`. -## `fs.writeFileSync(file, data[, options])` +### `fs.writev(fd, buffers[, position], callback)` -* `file` {string|Buffer|URL|integer} filename or file descriptor -* `data` {string|Buffer|TypedArray|DataView} -* `options` {Object|string} - * `encoding` {string|null} **Default:** `'utf8'` - * `mode` {integer} **Default:** `0o666` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'w'`. - -Returns `undefined`. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.writeFile()`][]. - -## `fs.writeSync(fd, buffer[, offset[, length[, position]]])` - - -* `fd` {integer} -* `buffer` {Buffer|TypedArray|DataView} -* `offset` {integer} -* `length` {integer} -* `position` {integer} -* Returns: {number} The number of bytes written. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.write(fd, buffer...)`][]. - -## `fs.writeSync(fd, string[, position[, encoding]])` - - -* `fd` {integer} -* `string` {string} -* `position` {integer} -* `encoding` {string} -* Returns: {number} The number of bytes written. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.write(fd, string...)`][]. - -## `fs.writev(fd, buffers[, position], callback)` - - -* `fd` {integer} -* `buffers` {ArrayBufferView[]} -* `position` {integer} -* `callback` {Function} - * `err` {Error} - * `bytesWritten` {integer} - * `buffers` {ArrayBufferView[]} +* `fd` {integer} +* `buffers` {ArrayBufferView[]} +* `position` {integer} +* `callback` {Function} + * `err` {Error} + * `bytesWritten` {integer} + * `buffers` {ArrayBufferView[]} Write an array of `ArrayBufferView`s to the file specified by `fd` using `writev()`. @@ -4435,7 +4033,7 @@ at the current position. The callback will be given three arguments: `err`, `bytesWritten`, and `buffers`. `bytesWritten` is how many bytes were written from `buffers`. -If this method is [`util.promisify()`][]ed, it returns a `Promise` for an +If this method is [`util.promisify()`][]ed, it returns a promise for an `Object` with `bytesWritten` and `buffers` properties. It is unsafe to use `fs.writev()` multiple times on the same file without @@ -4445,215 +4043,272 @@ On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file. -## `fs.writevSync(fd, buffers[, position])` - - -* `fd` {integer} -* `buffers` {ArrayBufferView[]} -* `position` {integer} -* Returns: {number} The number of bytes written. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.writev()`][]. - -## `fs` Promises API +## Synchronous API -The `fs.promises` API provides an alternative set of asynchronous file system -methods that return `Promise` objects rather than using callbacks. The -API is accessible via `require('fs').promises`. +The synchronous APIs perform all operations synchronously, blocking the +event loop until the operation completes or fails. -### Class: `FileHandle` +### `fs.accessSync(path[, mode])` -A `FileHandle` object is a wrapper for a numeric file descriptor. -Instances of `FileHandle` are distinct from numeric file descriptors -in that they provide an object oriented API for working with files. +* `path` {string|Buffer|URL} +* `mode` {integer} **Default:** `fs.constants.F_OK` + +Synchronously tests a user's permissions for the file or directory specified +by `path`. The `mode` argument is an optional integer that specifies the +accessibility checks to be performed. Check [File access constants][] for +possible values of `mode`. It is possible to create a mask consisting of +the bitwise OR of two or more values +(e.g. `fs.constants.W_OK | fs.constants.R_OK`). -If a `FileHandle` is not closed using the -`filehandle.close()` method, it might automatically close the file descriptor -and will emit a process warning, thereby helping to prevent memory leaks. -Please do not rely on this behavior because it is unreliable and -the file may not be closed. Instead, always explicitly close `FileHandle`s. -Node.js may change this behavior in the future. +If any of the accessibility checks fail, an `Error` will be thrown. Otherwise, +the method will return `undefined`. -Instances of the `FileHandle` object are created internally by the -`fsPromises.open()` method. +```mjs +import { accessSync, constants } from 'fs'; -Unlike the callback-based API (`fs.fstat()`, `fs.fchown()`, `fs.fchmod()`, and -so on), a numeric file descriptor is not used by the promise-based API. Instead, -the promise-based API uses the `FileHandle` class in order to help avoid -accidental leaking of unclosed file descriptors after a `Promise` is resolved or -rejected. +try { + accessSync('etc/passwd', constants.R_OK | constants.W_OK); + console.log('can read/write'); +} catch (err) { + console.error('no access!'); +} +``` -#### `filehandle.appendFile(data, options)` +### `fs.appendFileSync(path, data[, options])` +* `path` {string|Buffer|URL|number} filename or file descriptor * `data` {string|Buffer} * `options` {Object|string} * `encoding` {string|null} **Default:** `'utf8'` -* Returns: {Promise} - -Alias of [`filehandle.writeFile()`][]. + * `mode` {integer} **Default:** `0o666` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'a'`. -When operating on file handles, the mode cannot be changed from what it was set -to with [`fsPromises.open()`][]. Therefore, this is equivalent to -[`filehandle.writeFile()`][]. +Synchronously append data to a file, creating the file if it does not yet +exist. `data` can be a string or a {Buffer}. -#### `filehandle.chmod(mode)` - +The `mode` option only affects the newly created file. See [`fs.open()`][] +for more details. -* `mode` {integer} -* Returns: {Promise} +```mjs +import { appendFileSync } from 'fs'; -Modifies the permissions on the file. The `Promise` is resolved with no -arguments upon success. +try { + appendFileSync('message.txt', 'data to append'); + console.log('The "data to append" was appended to file!'); +} catch (err) { + /* Handle the error */ +} +``` -#### `filehandle.chown(uid, gid)` - +If `options` is a string, then it specifies the encoding: -* `uid` {integer} -* `gid` {integer} -* Returns: {Promise} +```mjs +import { appendFileSync } from 'fs'; -Changes the ownership of the file then resolves the `Promise` with no arguments -upon success. +appendFileSync('message.txt', 'data to append', 'utf8'); +``` -#### `filehandle.close()` - +The `path` may be specified as a numeric file descriptor that has been opened +for appending (using `fs.open()` or `fs.openSync()`). The file descriptor will +not be closed automatically. -* Returns: {Promise} A `Promise` that will be resolved once the underlying - file descriptor is closed, or will be rejected if an error occurs while - closing. +```mjs +import { openSync, closeSync, appendFileSync } from 'fs'; -Closes the file descriptor. +let fd; -```js -const fsPromises = require('fs').promises; -async function openAndClose() { - let filehandle; - try { - filehandle = await fsPromises.open('thefile.txt', 'r'); - } finally { - if (filehandle !== undefined) - await filehandle.close(); - } +try { + fd = openSync('message.txt', 'a'); + appendFileSync(fd, 'data to append', 'utf8'); +} catch (err) { + /* Handle the error */ +} finally { + if (fd !== undefined) + closeSync(fd); } ``` -#### `filehandle.datasync()` +### `fs.chmodSync(path, mode)` -* Returns: {Promise} +* `path` {string|Buffer|URL} +* `mode` {string|integer} -Asynchronous fdatasync(2). The `Promise` is resolved with no arguments upon -success. +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.chmod()`][]. -#### `filehandle.fd` +See the POSIX chmod(2) documentation for more detail. + +### `fs.chownSync(path, uid, gid)` -* {number} The numeric file descriptor managed by the `FileHandle` object. +* `path` {string|Buffer|URL} +* `uid` {integer} +* `gid` {integer} -#### `filehandle.read(buffer, offset, length, position)` +Synchronously changes owner and group of a file. Returns `undefined`. +This is the synchronous version of [`fs.chown()`][]. + +See the POSIX chown(2) documentation for more detail. + +### `fs.closeSync(fd)` -* `buffer` {Buffer|Uint8Array} -* `offset` {integer} -* `length` {integer} -* `position` {integer} -* Returns: {Promise} +* `fd` {integer} + +Closes the file descriptor. Returns `undefined`. + +Calling `fs.closeSync()` on any file descriptor (`fd`) that is currently in use +through any other `fs` operation may lead to undefined behavior. + +See the POSIX close(2) documentation for more detail. + +### `fs.copyFileSync(src, dest[, mode])` + -Read data from the file. +* `src` {string|Buffer|URL} source filename to copy +* `dest` {string|Buffer|URL} destination filename of the copy operation +* `mode` {integer} modifiers for copy operation. **Default:** `0`. -`buffer` is the buffer that the data will be written to. +Synchronously copies `src` to `dest`. By default, `dest` is overwritten if it +already exists. Returns `undefined`. Node.js makes no guarantees about the +atomicity of the copy operation. If an error occurs after the destination file +has been opened for writing, Node.js will attempt to remove the destination. -`offset` is the offset in the buffer to start writing at. +`mode` is an optional integer that specifies the behavior +of the copy operation. It is possible to create a mask consisting of the bitwise +OR of two or more values (e.g. +`fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`). -`length` is an integer specifying the number of bytes to read. +* `fs.constants.COPYFILE_EXCL`: The copy operation will fail if `dest` already + exists. +* `fs.constants.COPYFILE_FICLONE`: The copy operation will attempt to create a + copy-on-write reflink. If the platform does not support copy-on-write, then a + fallback copy mechanism is used. +* `fs.constants.COPYFILE_FICLONE_FORCE`: The copy operation will attempt to + create a copy-on-write reflink. If the platform does not support + copy-on-write, then the operation will fail. -`position` is an argument specifying where to begin reading from in the file. -If `position` is `null`, data will be read from the current file position, -and the file position will be updated. -If `position` is an integer, the file position will remain unchanged. +```mjs +import { copyFileSync, constants } from 'fs'; -Following successful read, the `Promise` is resolved with an object with a -`bytesRead` property specifying the number of bytes read, and a `buffer` -property that is a reference to the passed in `buffer` argument. +// destination.txt will be created or overwritten by default. +copyFileSync('source.txt', 'destination.txt'); +console.log('source.txt was copied to destination.txt'); -#### `filehandle.read(options)` - -* `options` {Object} - * `buffer` {Buffer|Uint8Array} **Default:** `Buffer.alloc(16384)` - * `offset` {integer} **Default:** `0` - * `length` {integer} **Default:** `buffer.length` - * `position` {integer} **Default:** `null` -* Returns: {Promise} +// By using COPYFILE_EXCL, the operation will fail if destination.txt exists. +copyFileSync('source.txt', 'destination.txt', constants.COPYFILE_EXCL); +``` -#### `filehandle.readFile(options)` +### `fs.existsSync(path)` -* `options` {Object|string} - * `encoding` {string|null} **Default:** `null` -* Returns: {Promise} +* `path` {string|Buffer|URL} +* Returns: {boolean} -Asynchronously reads the entire contents of a file. +Returns `true` if the path exists, `false` otherwise. -The `Promise` is resolved with the contents of the file. If no encoding is -specified (using `options.encoding`), the data is returned as a `Buffer` -object. Otherwise, the data will be a string. +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.exists()`][]. -If `options` is a string, then it specifies the encoding. +`fs.exists()` is deprecated, but `fs.existsSync()` is not. The `callback` +parameter to `fs.exists()` accepts parameters that are inconsistent with other +Node.js callbacks. `fs.existsSync()` does not use a callback. -The `FileHandle` has to support reading. +```mjs +import { existsSync } from 'fs'; -If one or more `filehandle.read()` calls are made on a file handle and then a -`filehandle.readFile()` call is made, the data will be read from the current -position till the end of the file. It doesn't always read from the beginning -of the file. +if (existsSync('/etc/passwd')) + console.log('The path exists.'); +``` -#### `filehandle.readv(buffers[, position])` +### `fs.fchmodSync(fd, mode)` -* `buffers` {ArrayBufferView[]} -* `position` {integer} -* Returns: {Promise} +* `fd` {integer} +* `mode` {string|integer} -Read from a file and write to an array of `ArrayBufferView`s +Sets the permissions on the file. Returns `undefined`. -The `Promise` is resolved with an object containing a `bytesRead` property -identifying the number of bytes read, and a `buffers` property containing -a reference to the `buffers` input. +See the POSIX fchmod(2) documentation for more detail. -`position` is the offset from the beginning of the file where this data -should be read from. If `typeof position !== 'number'`, the data will be read -from the current position. +### `fs.fchownSync(fd, uid, gid)` + -#### `filehandle.stat([options])` +* `fd` {integer} +* `uid` {integer} The file's new owner's user id. +* `gid` {integer} The file's new group's group id. + +Sets the owner of the file. Returns `undefined`. + +See the POSIX fchown(2) documentation for more detail. + +### `fs.fdatasyncSync(fd)` + +* `fd` {integer} + +Forces all currently queued I/O operations associated with the file to the +operating system's synchronized I/O completion state. Refer to the POSIX +fdatasync(2) documentation for details. Returns `undefined`. + +### `fs.fstatSync(fd[, options])` + +* `fd` {integer} * `options` {Object} * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. -* Returns: {Promise} + {fs.Stats} object should be `bigint`. **Default:** `false`. +* Returns: {fs.Stats} -Retrieves the [`fs.Stats`][] for the file. +Retrieves the {fs.Stats} for the file descriptor. -#### `filehandle.sync()` +See the POSIX fstat(2) documentation for more detail. + +### `fs.fsyncSync(fd)` -* Returns: {Promise} +* `fd` {integer} -Asynchronous fsync(2). The `Promise` is resolved with no arguments upon -success. +Request that all data for the open file descriptor is flushed to the storage +device. The specific implementation is operating system and device specific. +Refer to the POSIX fsync(2) documentation for more detail. Returns `undefined`. -#### `filehandle.truncate(len)` +### `fs.ftruncateSync(fd[, len])` +* `fd` {integer} * `len` {integer} **Default:** `0` -* Returns: {Promise} -Truncates the file then resolves the `Promise` with no arguments upon success. +Truncates the file descriptor. Returns `undefined`. -If the file was larger than `len` bytes, only the first `len` bytes will be -retained in the file. +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.ftruncate()`][]. -For example, the following program retains only the first four bytes of the -file: +### `fs.futimesSync(fd, atime, mtime)` + -```js -const fs = require('fs'); -const fsPromises = fs.promises; +* `fd` {integer} +* `atime` {number|string|Date} +* `mtime` {number|string|Date} -console.log(fs.readFileSync('temp.txt', 'utf8')); -// Prints: Node.js +Synchronous version of [`fs.futimes()`][]. Returns `undefined`. -async function doTruncate() { - let filehandle = null; - try { - filehandle = await fsPromises.open('temp.txt', 'r+'); - await filehandle.truncate(4); - } finally { - if (filehandle) { - // Close the file if it is opened. - await filehandle.close(); - } - } - console.log(fs.readFileSync('temp.txt', 'utf8')); // Prints: Node -} +### `fs.lchmodSync(path, mode)` + -doTruncate().catch(console.error); -``` +* `path` {string|Buffer|URL} +* `mode` {integer} -If the file previously was shorter than `len` bytes, it is extended, and the -extended part is filled with null bytes (`'\0'`): +Changes the permissions on a symbolic link. Returns `undefined`. -```js -const fs = require('fs'); -const fsPromises = fs.promises; +This method is only implemented on macOS. -console.log(fs.readFileSync('temp.txt', 'utf8')); -// Prints: Node.js +See the POSIX lchmod(2) documentation for more detail. -async function doTruncate() { - let filehandle = null; - try { - filehandle = await fsPromises.open('temp.txt', 'r+'); - await filehandle.truncate(10); - } finally { - if (filehandle) { - // Close the file if it is opened. - await filehandle.close(); - } - } - console.log(fs.readFileSync('temp.txt', 'utf8')); // Prints Node.js\0\0\0 -} +### `fs.lchownSync(path, uid, gid)` + -doTruncate().catch(console.error); -``` +* `path` {string|Buffer|URL} +* `uid` {integer} The file's new owner's user id. +* `gid` {integer} The file's new group's group id. -The last three bytes are null bytes (`'\0'`), to compensate the over-truncation. +Set the owner for the path. Returns `undefined`. -#### `filehandle.utimes(atime, mtime)` +See the POSIX lchown(2) documentation for more details. + +### `fs.lutimesSync(path, atime, mtime)` +* `path` {string|Buffer|URL} * `atime` {number|string|Date} * `mtime` {number|string|Date} -* Returns: {Promise} -Change the file system timestamps of the object referenced by the `FileHandle` -then resolves the `Promise` with no arguments upon success. - -This function does not work on AIX versions before 7.1, it will resolve the -`Promise` with an error using code `UV_ENOSYS`. +Change the file system timestamps of the symbolic link referenced by `path`. +Returns `undefined`, or throws an exception when parameters are incorrect or +the operation fails. This is the synchronous version of [`fs.lutimes()`][]. -#### `filehandle.write(buffer[, offset[, length[, position]]])` +### `fs.linkSync(existingPath, newPath)` -* `buffer` {Buffer|Uint8Array} -* `offset` {integer} -* `length` {integer} -* `position` {integer} -* Returns: {Promise} - -Write `buffer` to the file. +* `existingPath` {string|Buffer|URL} +* `newPath` {string|Buffer|URL} -The `Promise` is resolved with an object containing a `bytesWritten` property -identifying the number of bytes written, and a `buffer` property containing -a reference to the `buffer` written. +Creates a new link from the `existingPath` to the `newPath`. See the POSIX +link(2) documentation for more detail. Returns `undefined`. -`offset` determines the part of the buffer to be written, and `length` is -an integer specifying the number of bytes to write. +### `fs.lstatSync(path[, options])` + -`position` refers to the offset from the beginning of the file where this data -should be written. If `typeof position !== 'number'`, the data will be written -at the current position. See pwrite(2). +* `path` {string|Buffer|URL} +* `options` {Object} + * `bigint` {boolean} Whether the numeric values in the returned + {fs.Stats} object should be `bigint`. **Default:** `false`. + * `throwIfNoEntry` {boolean} Whether an exception will be thrown + if no file system entry exists, rather than returning `undefined`. + **Default:** `true`. +* Returns: {fs.Stats} -It is unsafe to use `filehandle.write()` multiple times on the same file -without waiting for the `Promise` to be resolved (or rejected). For this -scenario, use [`fs.createWriteStream()`][]. +Retrieves the {fs.Stats} for the symbolic link referred to by `path`. -On Linux, positional writes do not work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file. +See the POSIX lstat(2) documentation for more details. -#### `filehandle.write(string[, position[, encoding]])` +### `fs.mkdirSync(path[, options])` -* `string` {string} -* `position` {integer} -* `encoding` {string} **Default:** `'utf8'` -* Returns: {Promise} +* `path` {string|Buffer|URL} +* `options` {Object|integer} + * `recursive` {boolean} **Default:** `false` + * `mode` {string|integer} Not supported on Windows. **Default:** `0o777`. +* Returns: {string|undefined} -Write `string` to the file. If `string` is not a string, then -the value will be coerced to one. +Synchronously creates a directory. Returns `undefined`, or if `recursive` is +`true`, the first directory path created. +This is the synchronous version of [`fs.mkdir()`][]. -The `Promise` is resolved with an object containing a `bytesWritten` property -identifying the number of bytes written, and a `buffer` property containing -a reference to the `string` written. +See the POSIX mkdir(2) documentation for more details. -`position` refers to the offset from the beginning of the file where this data -should be written. If the type of `position` is not a `number` the data -will be written at the current position. See pwrite(2). +### `fs.mkdtempSync(prefix[, options])` + -`encoding` is the expected string encoding. +* `prefix` {string} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {string} -It is unsafe to use `filehandle.write()` multiple times on the same file -without waiting for the `Promise` to be resolved (or rejected). For this -scenario, use [`fs.createWriteStream()`][]. +Returns the created directory path. -On Linux, positional writes do not work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file. +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.mkdtemp()`][]. -#### `filehandle.writeFile(data, options)` +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use. + +### `fs.opendirSync(path[, options])` -* `data` {string|Buffer|Uint8Array} -* `options` {Object|string} +* `path` {string|Buffer|URL} +* `options` {Object} * `encoding` {string|null} **Default:** `'utf8'` -* Returns: {Promise} + * `bufferSize` {number} Number of directory entries that are buffered + internally when reading from the directory. Higher values lead to better + performance but higher memory usage. **Default:** `32` +* Returns: {fs.Dir} -Asynchronously writes data to a file, replacing the file if it already exists. -`data` can be a string or a buffer. The `Promise` will be resolved with no -arguments upon success. +Synchronously open a directory. See opendir(3). -The `encoding` option is ignored if `data` is a buffer. +Creates an {fs.Dir}, which contains all further functions for reading from +and cleaning up the directory. -If `options` is a string, then it specifies the encoding. +The `encoding` option sets the encoding for the `path` while opening the +directory and subsequent read operations. -The `FileHandle` has to support writing. +### `fs.openSync(path[, flags[, mode]])` + -It is unsafe to use `filehandle.writeFile()` multiple times on the same file -without waiting for the `Promise` to be resolved (or rejected). +* `path` {string|Buffer|URL} +* `flags` {string|number} **Default:** `'r'`. + See [support of file system `flags`][]. +* `mode` {string|integer} **Default:** `0o666` +* Returns: {number} -If one or more `filehandle.write()` calls are made on a file handle and then a -`filehandle.writeFile()` call is made, the data will be written from the -current position till the end of the file. It doesn't always write from the -beginning of the file. +Returns an integer representing the file descriptor. -#### `filehandle.writev(buffers[, position])` +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.open()`][]. + +### `fs.readdirSync(path[, options])` -* `buffers` {ArrayBufferView[]} -* `position` {integer} -* Returns: {Promise} - -Write an array of `ArrayBufferView`s to the file. +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` + * `withFileTypes` {boolean} **Default:** `false` +* Returns: {string[]|Buffer[]|fs.Dirent[]} -The `Promise` is resolved with an object containing a `bytesWritten` property -identifying the number of bytes written, and a `buffers` property containing -a reference to the `buffers` input. +Reads the contents of the directory. -`position` is the offset from the beginning of the file where this data -should be written. If `typeof position !== 'number'`, the data will be written -at the current position. +See the POSIX readdir(3) documentation for more details. -It is unsafe to call `writev()` multiple times on the same file without waiting -for the previous operation to complete. +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use for +the filenames returned. If the `encoding` is set to `'buffer'`, +the filenames returned will be passed as {Buffer} objects. -On Linux, positional writes don't work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file. +If `options.withFileTypes` is set to `true`, the result will contain +{fs.Dirent} objects. -### `fsPromises.access(path[, mode])` +### `fs.readFileSync(path[, options])` -* `path` {string|Buffer|URL} -* `mode` {integer} **Default:** `fs.constants.F_OK` -* Returns: {Promise} - -Tests a user's permissions for the file or directory specified by `path`. -The `mode` argument is an optional integer that specifies the accessibility -checks to be performed. Check [File access constants][] for possible values -of `mode`. It is possible to create a mask consisting of the bitwise OR of -two or more values (e.g. `fs.constants.W_OK | fs.constants.R_OK`). - -If the accessibility check is successful, the `Promise` is resolved with no -value. If any of the accessibility checks fail, the `Promise` is rejected -with an `Error` object. The following example checks if the file -`/etc/passwd` can be read and written by the current process. - -```js -const fs = require('fs'); -const fsPromises = fs.promises; +* `path` {string|Buffer|URL|integer} filename or file descriptor +* `options` {Object|string} + * `encoding` {string|null} **Default:** `null` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'r'`. +* Returns: {string|Buffer} -fsPromises.access('/etc/passwd', fs.constants.R_OK | fs.constants.W_OK) - .then(() => console.log('can access')) - .catch(() => console.error('cannot access')); -``` +Returns the contents of the `path`. -Using `fsPromises.access()` to check for the accessibility of a file before -calling `fsPromises.open()` is not recommended. Doing so introduces a race -condition, since other processes may change the file's state between the two -calls. Instead, user code should open/read/write the file directly and handle -the error raised if the file is not accessible. +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.readFile()`][]. -### `fsPromises.appendFile(path, data[, options])` - +If the `encoding` option is specified then this function returns a +string. Otherwise it returns a buffer. -* `path` {string|Buffer|URL|FileHandle} filename or `FileHandle` -* `data` {string|Buffer} -* `options` {Object|string} - * `encoding` {string|null} **Default:** `'utf8'` - * `mode` {integer} **Default:** `0o666` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'a'`. -* Returns: {Promise} +Similar to [`fs.readFile()`][], when the path is a directory, the behavior of +`fs.readFileSync()` is platform-specific. -Asynchronously append data to a file, creating the file if it does not yet -exist. `data` can be a string or a [`Buffer`][]. The `Promise` will be -resolved with no arguments upon success. +```mjs +import { readFileSync } from 'fs'; -If `options` is a string, then it specifies the encoding. +// macOS, Linux, and Windows +readFileSync(''); +// => [Error: EISDIR: illegal operation on a directory, read ] -The `path` may be specified as a `FileHandle` that has been opened -for appending (using `fsPromises.open()`). +// FreeBSD +readFileSync(''); // => +``` -### `fsPromises.chmod(path, mode)` +### `fs.readlinkSync(path[, options])` * `path` {string|Buffer|URL} -* `mode` {string|integer} -* Returns: {Promise} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {string|Buffer} -Changes the permissions of a file then resolves the `Promise` with no -arguments upon succces. +Returns the symbolic link's string value. -### `fsPromises.chown(path, uid, gid)` +See the POSIX readlink(2) documentation for more details. + +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use for +the link path returned. If the `encoding` is set to `'buffer'`, +the link path returned will be passed as a {Buffer} object. + +### `fs.readSync(fd, buffer, offset, length, position)` -* `path` {string|Buffer|URL} -* `uid` {integer} -* `gid` {integer} -* Returns: {Promise} +* `fd` {integer} +* `buffer` {Buffer|TypedArray|DataView} +* `offset` {integer} +* `length` {integer} +* `position` {integer|bigint} +* Returns: {number} + +Returns the number of `bytesRead`. -Changes the ownership of a file then resolves the `Promise` with no arguments -upon success. +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.read()`][]. -### `fsPromises.copyFile(src, dest[, flags])` +### `fs.readSync(fd, buffer, [options])` -* `src` {string|Buffer|URL} source filename to copy -* `dest` {string|Buffer|URL} destination filename of the copy operation -* `flags` {number} modifiers for copy operation. **Default:** `0`. -* Returns: {Promise} +* `fd` {integer} +* `buffer` {Buffer|TypedArray|DataView} +* `options` {Object} + * `offset` {integer} **Default:** `0` + * `length` {integer} **Default:** `buffer.byteLength` + * `position` {integer|bigint} **Default:** `null` +* Returns: {number} -Asynchronously copies `src` to `dest`. By default, `dest` is overwritten if it -already exists. The `Promise` will be resolved with no arguments upon success. +Returns the number of `bytesRead`. -Node.js makes no guarantees about the atomicity of the copy operation. If an -error occurs after the destination file has been opened for writing, Node.js -will attempt to remove the destination. +Similar to the above `fs.readSync` function, this version takes an optional `options` object. +If no `options` object is specified, it will default with the above values. -`flags` is an optional integer that specifies the behavior -of the copy operation. It is possible to create a mask consisting of the bitwise -OR of two or more values (e.g. -`fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`). +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.read()`][]. -* `fs.constants.COPYFILE_EXCL`: The copy operation will fail if `dest` already -exists. -* `fs.constants.COPYFILE_FICLONE`: The copy operation will attempt to create a -copy-on-write reflink. If the platform does not support copy-on-write, then a -fallback copy mechanism is used. -* `fs.constants.COPYFILE_FICLONE_FORCE`: The copy operation will attempt to -create a copy-on-write reflink. If the platform does not support copy-on-write, -then the operation will fail. +### `fs.readvSync(fd, buffers[, position])` + -```js -const fsPromises = require('fs').promises; +* `fd` {integer} +* `buffers` {ArrayBufferView[]} +* `position` {integer} +* Returns: {number} The number of bytes read. -// destination.txt will be created or overwritten by default. -fsPromises.copyFile('source.txt', 'destination.txt') - .then(() => console.log('source.txt was copied to destination.txt')) - .catch(() => console.log('The file could not be copied')); -``` +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.readv()`][]. -If the third argument is a number, then it specifies `flags`: +### `fs.realpathSync(path[, options])` + -```js -const fs = require('fs'); -const fsPromises = fs.promises; -const { COPYFILE_EXCL } = fs.constants; +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {string|Buffer} -// By using COPYFILE_EXCL, the operation will fail if destination.txt exists. -fsPromises.copyFile('source.txt', 'destination.txt', COPYFILE_EXCL) - .then(() => console.log('source.txt was copied to destination.txt')) - .catch(() => console.log('The file could not be copied')); -``` +Returns the resolved pathname. -### `fsPromises.lchmod(path, mode)` +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.realpath()`][]. + +### `fs.realpathSync.native(path[, options])` * `path` {string|Buffer|URL} -* `mode` {integer} -* Returns: {Promise} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {string|Buffer} -Changes the permissions on a symbolic link then resolves the `Promise` with -no arguments upon success. This method is only implemented on macOS. +Synchronous realpath(3). -### `fsPromises.lchown(path, uid, gid)` +Only paths that can be converted to UTF8 strings are supported. + +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use for +the path returned. If the `encoding` is set to `'buffer'`, +the path returned will be passed as a {Buffer} object. + +On Linux, when Node.js is linked against musl libc, the procfs file system must +be mounted on `/proc` in order for this function to work. Glibc does not have +this restriction. + +### `fs.renameSync(oldPath, newPath)` -* `path` {string|Buffer|URL} -* `uid` {integer} -* `gid` {integer} -* Returns: {Promise} +* `oldPath` {string|Buffer|URL} +* `newPath` {string|Buffer|URL} -Changes the ownership on a symbolic link then resolves the `Promise` with -no arguments upon success. +Renames the file from `oldPath` to `newPath`. Returns `undefined`. -### `fsPromises.lutimes(path, atime, mtime)` +See the POSIX rename(2) documentation for more details. + +### `fs.rmdirSync(path[, options])` * `path` {string|Buffer|URL} -* `atime` {number|string|Date} -* `mtime` {number|string|Date} -* Returns: {Promise} +* `options` {Object} + * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or + `EPERM` error is encountered, Node.js retries the operation with a linear + backoff wait of `retryDelay` milliseconds longer on each try. This option + represents the number of retries. This option is ignored if the `recursive` + option is not `true`. **Default:** `0`. + * `recursive` {boolean} If `true`, perform a recursive directory removal. In + recursive mode, errors are not reported if `path` does not exist, and + operations are retried on failure. **Default:** `false`. + * `retryDelay` {integer} The amount of time in milliseconds to wait between + retries. This option is ignored if the `recursive` option is not `true`. + **Default:** `100`. -Changes the access and modification times of a file in the same way as -[`fsPromises.utimes()`][], with the difference that if the path refers to a -symbolic link, then the link is not dereferenced: instead, the timestamps of -the symbolic link itself are changed. +Synchronous rmdir(2). Returns `undefined`. + +Using `fs.rmdirSync()` on a file (not a directory) results in an `ENOENT` error +on Windows and an `ENOTDIR` error on POSIX. -Upon success, the `Promise` is resolved without arguments. +Setting `recursive` to `true` results in behavior similar to the Unix command +`rm -rf`: an error will not be raised for paths that do not exist, and paths +that represent files will be deleted. The permissive behavior of the +`recursive` option is deprecated, `ENOTDIR` and `ENOENT` will be thrown in +the future. -### `fsPromises.link(existingPath, newPath)` +### `fs.rmSync(path[, options])` -* `existingPath` {string|Buffer|URL} -* `newPath` {string|Buffer|URL} -* Returns: {Promise} +* `path` {string|Buffer|URL} +* `options` {Object} + * `force` {boolean} When `true`, exceptions will be ignored if `path` does + not exist. **Default:** `false`. + * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or + `EPERM` error is encountered, Node.js will retry the operation with a linear + backoff wait of `retryDelay` milliseconds longer on each try. This option + represents the number of retries. This option is ignored if the `recursive` + option is not `true`. **Default:** `0`. + * `recursive` {boolean} If `true`, perform a recursive directory removal. In + recursive mode operations are retried on failure. **Default:** `false`. + * `retryDelay` {integer} The amount of time in milliseconds to wait between + retries. This option is ignored if the `recursive` option is not `true`. + **Default:** `100`. -Asynchronous link(2). The `Promise` is resolved with no arguments upon success. +Synchronously removes files and directories (modeled on the standard POSIX `rm` +utility). Returns `undefined`. -### `fsPromises.lstat(path[, options])` +### `fs.statSync(path[, options])` * `path` {string|Buffer|URL} * `options` {Object} * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. -* Returns: {Promise} + {fs.Stats} object should be `bigint`. **Default:** `false`. + * `throwIfNoEntry` {boolean} Whether an exception will be thrown + if no file system entry exists, rather than returning `undefined`. + **Default:** `true`. +* Returns: {fs.Stats} -Asynchronous lstat(2). The `Promise` is resolved with the [`fs.Stats`][] object -for the given symbolic link `path`. +Retrieves the {fs.Stats} for the path. -### `fsPromises.mkdir(path[, options])` +### `fs.symlinkSync(target, path[, type])` - +added: v0.1.31 +changes: + - version: v12.0.0 + pr-url: https://github.com/nodejs/node/pull/23724 + description: If the `type` argument is left undefined, Node will autodetect + `target` type and automatically select `dir` or `file`. + - version: v7.6.0 + pr-url: https://github.com/nodejs/node/pull/10739 + description: The `target` and `path` parameters can be WHATWG `URL` objects + using `file:` protocol. Support is currently still + *experimental*. +--> + +* `target` {string|Buffer|URL} * `path` {string|Buffer|URL} -* `options` {Object|integer} - * `recursive` {boolean} **Default:** `false` - * `mode` {string|integer} Not supported on Windows. **Default:** `0o777`. -* Returns: {Promise} +* `type` {string} -Asynchronously creates a directory then resolves the `Promise` with either no -arguments, or the first directory path created if `recursive` is `true`. +Returns `undefined`. -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 directories should be created. Calling -`fsPromises.mkdir()` when `path` is a directory that exists results in a -rejection only when `recursive` is false. +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.symlink()`][]. -### `fsPromises.mkdtemp(prefix[, options])` +### `fs.truncateSync(path[, len])` -* `prefix` {string} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {Promise} +* `path` {string|Buffer|URL} +* `len` {integer} **Default:** `0` -Creates a unique temporary directory and resolves the `Promise` with the created -directory path. A unique directory name is generated by appending six random -characters to the end of the provided `prefix`. Due to platform -inconsistencies, avoid trailing `X` characters in `prefix`. Some platforms, -notably the BSDs, can return more than six random characters, and replace -trailing `X` characters in `prefix` with random characters. +Truncates the file. Returns `undefined`. A file descriptor can also be +passed as the first argument. In this case, `fs.ftruncateSync()` is called. -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use. +Passing a file descriptor is deprecated and may result in an error being thrown +in the future. -```js -fsPromises.mkdtemp(path.join(os.tmpdir(), 'foo-')) - .catch(console.error); -``` +### `fs.unlinkSync(path)` + -The `fsPromises.mkdtemp()` method will append the six randomly selected -characters directly to the `prefix` string. For instance, given a directory -`/tmp`, if the intention is to create a temporary directory *within* `/tmp`, the -`prefix` must end with a trailing platform-specific path separator -(`require('path').sep`). +* `path` {string|Buffer|URL} -### `fsPromises.open(path, flags[, mode])` +Synchronous unlink(2). Returns `undefined`. + +### `fs.utimesSync(path, atime, mtime)` + +* `path` {string|Buffer|URL} +* `atime` {number|string|Date} +* `mtime` {number|string|Date} + +Returns `undefined`. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.utimes()`][]. + +### `fs.writeFileSync(file, data[, options])` + + +* `file` {string|Buffer|URL|integer} filename or file descriptor +* `data` {string|Buffer|TypedArray|DataView|Object} +* `options` {Object|string} + * `encoding` {string|null} **Default:** `'utf8'` + * `mode` {integer} **Default:** `0o666` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'w'`. + +Returns `undefined`. + +If `data` is a plain object, it must have an own (not inherited) `toString` +function property. + +The `mode` option only affects the newly created file. See [`fs.open()`][] +for more details. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.writeFile()`][]. + +### `fs.writeSync(fd, buffer[, offset[, length[, position]]])` + + +* `fd` {integer} +* `buffer` {Buffer|TypedArray|DataView|string|Object} +* `offset` {integer} +* `length` {integer} +* `position` {integer} +* Returns: {number} The number of bytes written. + +If `buffer` is a plain object, it must have an own (not inherited) `toString` +function property. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.write(fd, buffer...)`][]. + +### `fs.writeSync(fd, string[, position[, encoding]])` + + +* `fd` {integer} +* `string` {string|Object} +* `position` {integer} +* `encoding` {string} +* Returns: {number} The number of bytes written. + +If `string` is a plain object, it must have an own (not inherited) `toString` +function property. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.write(fd, string...)`][]. + +### `fs.writevSync(fd, buffers[, position])` + + +* `fd` {integer} +* `buffers` {ArrayBufferView[]} +* `position` {integer} +* Returns: {number} The number of bytes written. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.writev()`][]. + +## Common Objects + +The common objects are shared by all of the file system API variants +(promise, callback, and synchronous). + +### Class: `fs.Dir` + + +A class representing a directory stream. + +Created by [`fs.opendir()`][], [`fs.opendirSync()`][], or +[`fsPromises.opendir()`][]. + +```mjs +import { opendir } from 'fs/promises'; + +try { + const dir = await opendir('./'); + for await (const dirent of dir) + console.log(dirent.name); +} catch (err) { + console.error(err); +} +``` + +When using the async iterator, the {fs.Dir} object will be automatically +closed after the iterator exits. + +#### `dir.close()` + + +* Returns: {Promise} + +Asynchronously close the directory's underlying resource handle. +Subsequent reads will result in errors. + +A promise is returned that will be resolved after the resource has been +closed. + +#### `dir.close(callback)` + + +* `callback` {Function} + * `err` {Error} + +Asynchronously close the directory's underlying resource handle. +Subsequent reads will result in errors. + +The `callback` will be called after the resource handle has been closed. + +#### `dir.closeSync()` + + +Synchronously close the directory's underlying resource handle. +Subsequent reads will result in errors. + +#### `dir.path` + + +* {string} + +The read-only path of this directory as was provided to [`fs.opendir()`][], +[`fs.opendirSync()`][], or [`fsPromises.opendir()`][]. + +#### `dir.read()` + + +* Returns: {Promise} containing {fs.Dirent|null} + +Asynchronously read the next directory entry via readdir(3) as an +{fs.Dirent}. + +A promise is returned that will be resolved with an {fs.Dirent}, or `null` +if there are no more directory entries to read. + +Directory entries returned by this function are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results. + +#### `dir.read(callback)` + -* `path` {string|Buffer|URL} -* `flags` {string|number} See [support of file system `flags`][]. - **Default:** `'r'`. -* `mode` {string|integer} **Default:** `0o666` (readable and writable) -* Returns: {Promise} +* `callback` {Function} + * `err` {Error} + * `dirent` {fs.Dirent|null} + +Asynchronously read the next directory entry via readdir(3) as an +{fs.Dirent}. + +After the read is completed, the `callback` will be called with an +{fs.Dirent}, or `null` if there are no more directory entries to read. + +Directory entries returned by this function are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results. + +#### `dir.readSync()` + + +* Returns: {fs.Dirent|null} + +Synchronously read the next directory entry as an {fs.Dirent}. See the +POSIX readdir(3) documentation for more detail. + +If there are no more directory entries to read, `null` will be returned. + +Directory entries returned by this function are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results. + +#### `dir[Symbol.asyncIterator]()` + + +* Returns: {AsyncIterator} of {fs.Dirent} + +Asynchronously iterates over the directory until all entries have +been read. Refer to the POSIX readdir(3) documentation for more detail. + +Entries returned by the async iterator are always an {fs.Dirent}. +The `null` case from `dir.read()` is handled internally. + +See {fs.Dir} for an example. + +Directory entries returned by this iterator are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results. + +### Class: `fs.Dirent` + + +A representation of a directory entry, which can be a file or a subdirectory +within the directory, as returned by reading from an {fs.Dir}. The +directory entry is a combination of the file name and file type pairs. + +Additionally, when [`fs.readdir()`][] or [`fs.readdirSync()`][] is called with +the `withFileTypes` option set to `true`, the resulting array is filled with +{fs.Dirent} objects, rather than strings or {Buffer}s. + +#### `dirent.isBlockDevice()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a block device. + +#### `dirent.isCharacterDevice()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a character device. + +#### `dirent.isDirectory()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a file system +directory. + +#### `dirent.isFIFO()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a first-in-first-out +(FIFO) pipe. + +#### `dirent.isFile()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a regular file. + +#### `dirent.isSocket()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a socket. + +#### `dirent.isSymbolicLink()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a symbolic link. + +#### `dirent.name` + + +* {string|Buffer} + +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()`][]. + +### Class: `fs.FSWatcher` + + +* Extends {EventEmitter} + +A successful call to [`fs.watch()`][] method will return a new {fs.FSWatcher} +object. + +All {fs.FSWatcher} objects emit a `'change'` event whenever a specific watched +file is modified. + +#### Event: `'change'` + + +* `eventType` {string} The type of change event that has occurred +* `filename` {string|Buffer} The filename that changed (if relevant/available) + +Emitted when something changes in a watched directory or file. +See more details in [`fs.watch()`][]. + +The `filename` argument may not be provided depending on operating system +support. If `filename` is provided, it will be provided as a {Buffer} if +`fs.watch()` is called with its `encoding` option set to `'buffer'`, otherwise +`filename` will be a UTF-8 string. + +```mjs +import { watch } from 'fs'; +// Example when handled through fs.watch() listener +watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => { + if (filename) { + console.log(filename); + // Prints: + } +}); +``` + +#### Event: `'close'` + + +Emitted when the watcher stops watching for changes. The closed +{fs.FSWatcher} object is no longer usable in the event handler. + +#### Event: `'error'` + + +* `error` {Error} + +Emitted when an error occurs while watching the file. The errored +{fs.FSWatcher} object is no longer usable in the event handler. + +#### `watcher.close()` + + +Stop watching for changes on the given {fs.FSWatcher}. Once stopped, the +{fs.FSWatcher} object is no longer usable. + +#### `watcher.ref()` + + +* Returns: {fs.FSWatcher} + +When called, requests that the Node.js event loop *not* exit so long as the +{fs.FSWatcher} is active. Calling `watcher.ref()` multiple times will have +no effect. + +By default, all {fs.FSWatcher} objects are "ref'ed", making it normally +unnecessary to call `watcher.ref()` unless `watcher.unref()` had been +called previously. + +#### `watcher.unref()` + + +* Returns: {fs.FSWatcher} + +When called, the active {fs.FSWatcher} object will not require the Node.js +event loop to remain active. If there is no other activity keeping the +event loop running, the process may exit before the {fs.FSWatcher} object's +callback is invoked. Calling `watcher.unref()` multiple times will have +no effect. + +### Class: `fs.StatWatcher` + + +* Extends {EventEmitter} + +A successful call to `fs.watchFile()` method will return a new {fs.StatWatcher} +object. + +#### `watcher.ref()` + + +* Returns: {fs.StatWatcher} + +When called, requests that the Node.js event loop *not* exit so long as the +{fs.StatWatcher} is active. Calling `watcher.ref()` multiple times will have +no effect. + +By default, all {fs.StatWatcher} objects are "ref'ed", making it normally +unnecessary to call `watcher.ref()` unless `watcher.unref()` had been +called previously. + +#### `watcher.unref()` + + +* Returns: {fs.StatWatcher} + +When called, the active {fs.StatWatcher} object will not require the Node.js +event loop to remain active. If there is no other activity keeping the +event loop running, the process may exit before the {fs.StatWatcher} object's +callback is invoked. Calling `watcher.unref()` multiple times will have +no effect. + +### Class: `fs.ReadStream` + + +* Extends: {stream.Readable} + +Instances of {fs.ReadStream} are created and returned using the +[`fs.createReadStream()`][] function. + +#### Event: `'close'` + + +Emitted when the {fs.ReadStream}'s underlying file descriptor has been closed. + +#### Event: `'open'` + + +* `fd` {integer} Integer file descriptor used by the {fs.ReadStream}. + +Emitted when the {fs.ReadStream}'s file descriptor has been opened. + +#### Event: `'ready'` + + +Emitted when the {fs.ReadStream} is ready to be used. + +Fires immediately after `'open'`. + +#### `readStream.bytesRead` + + +* {number} + +The number of bytes that have been read so far. + +#### `readStream.path` + + +* {string|Buffer} + +The path to the file the stream is reading from as specified in the first +argument to `fs.createReadStream()`. If `path` is passed as a string, then +`readStream.path` will be a string. If `path` is passed as a {Buffer}, then +`readStream.path` will be a {Buffer}. + +#### `readStream.pending` + + +* {boolean} + +This property is `true` if the underlying file has not been opened yet, +i.e. before the `'ready'` event is emitted. + +### Class: `fs.Stats` + + +A {fs.Stats} object provides information about a file. + +Objects returned from [`fs.stat()`][], [`fs.lstat()`][] and [`fs.fstat()`][] and +their synchronous counterparts are of this type. +If `bigint` in the `options` passed to those methods is true, the numeric values +will be `bigint` instead of `number`, and the object will contain additional +nanosecond-precision properties suffixed with `Ns`. + +```console +Stats { + dev: 2114, + ino: 48064969, + mode: 33188, + nlink: 1, + uid: 85, + gid: 100, + rdev: 0, + size: 527, + blksize: 4096, + blocks: 8, + atimeMs: 1318289051000.1, + mtimeMs: 1318289051000.1, + ctimeMs: 1318289051000.1, + birthtimeMs: 1318289051000.1, + atime: Mon, 10 Oct 2011 23:24:11 GMT, + mtime: Mon, 10 Oct 2011 23:24:11 GMT, + ctime: Mon, 10 Oct 2011 23:24:11 GMT, + birthtime: Mon, 10 Oct 2011 23:24:11 GMT } +``` + +`bigint` version: + +```console +BigIntStats { + dev: 2114n, + ino: 48064969n, + mode: 33188n, + nlink: 1n, + uid: 85n, + gid: 100n, + rdev: 0n, + size: 527n, + blksize: 4096n, + blocks: 8n, + atimeMs: 1318289051000n, + mtimeMs: 1318289051000n, + ctimeMs: 1318289051000n, + birthtimeMs: 1318289051000n, + atimeNs: 1318289051000000000n, + mtimeNs: 1318289051000000000n, + ctimeNs: 1318289051000000000n, + birthtimeNs: 1318289051000000000n, + atime: Mon, 10 Oct 2011 23:24:11 GMT, + mtime: Mon, 10 Oct 2011 23:24:11 GMT, + ctime: Mon, 10 Oct 2011 23:24:11 GMT, + birthtime: Mon, 10 Oct 2011 23:24:11 GMT } +``` + +#### `stats.isBlockDevice()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Stats} object describes a block device. + +#### `stats.isCharacterDevice()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Stats} object describes a character device. + +#### `stats.isDirectory()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Stats} object describes a file system directory. + +If the {fs.Stats} object was obtained from [`fs.lstat()`][], this method will +always return `false`. This is because [`fs.lstat()`][] returns information +about a symbolic link itself and not the path it resolves to. + +#### `stats.isFIFO()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Stats} object describes a first-in-first-out (FIFO) +pipe. + +#### `stats.isFile()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Stats} object describes a regular file. + +#### `stats.isSocket()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Stats} object describes a socket. + +#### `stats.isSymbolicLink()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Stats} object describes a symbolic link. + +This method is only valid when using [`fs.lstat()`][]. + +#### `stats.dev` + +* {number|bigint} + +The numeric identifier of the device containing the file. + +#### `stats.ino` + +* {number|bigint} + +The file system specific "Inode" number for the file. + +#### `stats.mode` + +* {number|bigint} + +A bit-field describing the file type and mode. + +#### `stats.nlink` + +* {number|bigint} + +The number of hard-links that exist for the file. + +#### `stats.uid` + +* {number|bigint} + +The numeric user identifier of the user that owns the file (POSIX). + +#### `stats.gid` + +* {number|bigint} + +The numeric group identifier of the group that owns the file (POSIX). + +#### `stats.rdev` + +* {number|bigint} + +A numeric device identifier if the file represents a device. + +#### `stats.size` + +* {number|bigint} + +The size of the file in bytes. + +#### `stats.blksize` + +* {number|bigint} + +The file system block size for i/o operations. -Asynchronous file open that returns a `Promise` that, when resolved, yields a -`FileHandle` object. See open(2). +#### `stats.blocks` -`mode` sets the file mode (permission and sticky bits), but only if the file was -created. +* {number|bigint} -Some characters (`< > : " / \ | ? *`) are reserved under Windows as documented -by [Naming Files, Paths, and Namespaces][]. Under NTFS, if the filename contains -a colon, Node.js will open a file system stream, as described by -[this MSDN page][MSDN-Using-Streams]. +The number of blocks allocated for this file. -### `fsPromises.opendir(path[, options])` +#### `stats.atimeMs` -* `path` {string|Buffer|URL} -* `options` {Object} - * `encoding` {string|null} **Default:** `'utf8'` - * `bufferSize` {number} Number of directory entries that are buffered - internally when reading from the directory. Higher values lead to better - performance but higher memory usage. **Default:** `32` -* Returns: {Promise} containing {fs.Dir} +* {number|bigint} -Asynchronously open a directory. See opendir(3). +The timestamp indicating the last time this file was accessed expressed in +milliseconds since the POSIX Epoch. -Creates an [`fs.Dir`][], which contains all further functions for reading from -and cleaning up the directory. +#### `stats.mtimeMs` + -The `encoding` option sets the encoding for the `path` while opening the -directory and subsequent read operations. +* {number|bigint} -Example using async iteration: +The timestamp indicating the last time this file was modified expressed in +milliseconds since the POSIX Epoch. -```js -const fs = require('fs'); +#### `stats.ctimeMs` + -async function print(path) { - const dir = await fs.promises.opendir(path); - for await (const dirent of dir) { - console.log(dirent.name); - } -} -print('./').catch(console.error); -``` +* {number|bigint} -### `fsPromises.readdir(path[, options])` +The timestamp indicating the last time the file status was changed expressed +in milliseconds since the POSIX Epoch. + +#### `stats.birthtimeMs` -* `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 -of the names of the files in the directory excluding `'.'` and `'..'`. +* {number|bigint} -The optional `options` argument can be a string specifying an encoding, or an -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. +The timestamp indicating the creation time of this file expressed in +milliseconds since the POSIX Epoch. -If `options.withFileTypes` is set to `true`, the resolved array will contain -[`fs.Dirent`][] objects. +#### `stats.atimeNs` + -```js -const fs = require('fs'); +* {bigint} -async function print(path) { - const files = await fs.promises.readdir(path); - for (const file of files) { - console.log(file); - } -} -print('./').catch(console.error); -``` +Only present when `bigint: true` is passed into the method that generates +the object. +The timestamp indicating the last time this file was accessed expressed in +nanoseconds since the POSIX Epoch. -### `fsPromises.readFile(path[, options])` +#### `stats.mtimeNs` -* `path` {string|Buffer|URL|FileHandle} filename or `FileHandle` -* `options` {Object|string} - * `encoding` {string|null} **Default:** `null` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'r'`. -* Returns: {Promise} - -Asynchronously reads the entire contents of a file. +* {bigint} -The `Promise` is resolved with the contents of the file. If no encoding is -specified (using `options.encoding`), the data is returned as a `Buffer` -object. Otherwise, the data will be a string. +Only present when `bigint: true` is passed into the method that generates +the object. +The timestamp indicating the last time this file was modified expressed in +nanoseconds since the POSIX Epoch. -If `options` is a string, then it specifies the encoding. +#### `stats.ctimeNs` + -When the `path` is a directory, the behavior of `fsPromises.readFile()` is -platform-specific. On macOS, Linux, and Windows, the promise will be rejected -with an error. On FreeBSD, a representation of the directory's contents will be -returned. +* {bigint} -Any specified `FileHandle` has to support reading. +Only present when `bigint: true` is passed into the method that generates +the object. +The timestamp indicating the last time the file status was changed expressed +in nanoseconds since the POSIX Epoch. -### `fsPromises.readlink(path[, options])` +#### `stats.birthtimeNs` -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {Promise} - -Asynchronous readlink(2). The `Promise` is resolved with the `linkString` upon -success. +* {bigint} -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use for -the link path returned. If the `encoding` is set to `'buffer'`, the link path -returned will be passed as a `Buffer` object. +Only present when `bigint: true` is passed into the method that generates +the object. +The timestamp indicating the creation time of this file expressed in +nanoseconds since the POSIX Epoch. -### `fsPromises.realpath(path[, options])` +#### `stats.atime` -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {Promise} +* {Date} -Determines the actual location of `path` using the same semantics as the -`fs.realpath.native()` function then resolves the `Promise` with the resolved -path. +The timestamp indicating the last time this file was accessed. -Only paths that can be converted to UTF8 strings are supported. +#### `stats.mtime` + -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use for -the path. If the `encoding` is set to `'buffer'`, the path returned will be -passed as a `Buffer` object. +* {Date} -On Linux, when Node.js is linked against musl libc, the procfs file system must -be mounted on `/proc` in order for this function to work. Glibc does not have -this restriction. +The timestamp indicating the last time this file was modified. -### `fsPromises.rename(oldPath, newPath)` +#### `stats.ctime` -* `oldPath` {string|Buffer|URL} -* `newPath` {string|Buffer|URL} -* Returns: {Promise} +* {Date} -Renames `oldPath` to `newPath` and resolves the `Promise` with no arguments -upon success. +The timestamp indicating the last time the file status was changed. -### `fsPromises.rmdir(path[, options])` +#### `stats.birthtime` -> Stability: 1 - Recursive removal is experimental. +* {Date} -* `path` {string|Buffer|URL} -* `options` {Object} - * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or - `EPERM` error is encountered, Node.js will retry the operation with a linear - backoff wait of `retryDelay` ms longer on each try. This option represents the - number of retries. This option is ignored if the `recursive` option is not - `true`. **Default:** `0`. - * `recursive` {boolean} If `true`, perform a recursive directory removal. In - recursive mode, errors are not reported if `path` does not exist, and - operations are retried on failure. **Default:** `false`. - * `retryDelay` {integer} The amount of time in milliseconds to wait between - retries. This option is ignored if the `recursive` option is not `true`. - **Default:** `100`. -* Returns: {Promise} +The timestamp indicating the creation time of this file. -Removes the directory identified by `path` then resolves the `Promise` with -no arguments upon success. +#### Stat time values -Using `fsPromises.rmdir()` on a file (not a directory) results in the -`Promise` being rejected with an `ENOENT` error on Windows and an `ENOTDIR` -error on POSIX. +The `atimeMs`, `mtimeMs`, `ctimeMs`, `birthtimeMs` properties are +numeric values that hold the corresponding times in milliseconds. Their +precision is platform specific. When `bigint: true` is passed into the +method that generates the object, the properties will be [bigints][], +otherwise they will be [numbers][MDN-Number]. -### `fsPromises.stat(path[, options])` - +The `atimeNs`, `mtimeNs`, `ctimeNs`, `birthtimeNs` properties are +[bigints][] that hold the corresponding times in nanoseconds. They are +only present when `bigint: true` is passed into the method that generates +the object. Their precision is platform specific. -* `path` {string|Buffer|URL} -* `options` {Object} - * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. -* Returns: {Promise} +`atime`, `mtime`, `ctime`, and `birthtime` are +[`Date`][MDN-Date] object alternate representations of the various times. The +`Date` and number values are not connected. Assigning a new number value, or +mutating the `Date` value, will not be reflected in the corresponding alternate +representation. -The `Promise` is resolved with the [`fs.Stats`][] object for the given `path`. +The times in the stat object have the following semantics: -### `fsPromises.symlink(target, path[, type])` +* `atime` "Access Time": Time when file data last accessed. Changed + by the mknod(2), utimes(2), and read(2) system calls. +* `mtime` "Modified Time": Time when file data last modified. + Changed by the mknod(2), utimes(2), and write(2) system calls. +* `ctime` "Change Time": Time when file status was last changed + (inode data modification). Changed by the chmod(2), chown(2), + link(2), mknod(2), rename(2), unlink(2), utimes(2), + read(2), and write(2) system calls. +* `birthtime` "Birth Time": Time of file creation. Set once when the + file is created. On filesystems where birthtime is not available, + this field may instead hold either the `ctime` or + `1970-01-01T00:00Z` (ie, Unix epoch timestamp `0`). This value may be greater + than `atime` or `mtime` in this case. On Darwin and other FreeBSD variants, + also set if the `atime` is explicitly set to an earlier value than the current + `birthtime` using the utimes(2) system call. + +Prior to Node.js 0.12, the `ctime` held the `birthtime` on Windows systems. As +of 0.12, `ctime` is not "creation time", and on Unix systems, it never was. + +### Class: `fs.WriteStream` -* `target` {string|Buffer|URL} -* `path` {string|Buffer|URL} -* `type` {string} **Default:** `'file'` -* Returns: {Promise} - -Creates a symbolic link then resolves the `Promise` with no arguments upon -success. +* Extends {stream.Writable} -The `type` argument is only used on Windows platforms and can be one of `'dir'`, -`'file'`, or `'junction'`. Windows junction points require the destination path -to be absolute. When using `'junction'`, the `target` argument will -automatically be normalized to absolute path. +Instances of {fs.WriteStream} are created and returned using the +[`fs.createWriteStream()`][] function. -### `fsPromises.truncate(path[, len])` +#### Event: `'close'` -* `path` {string|Buffer|URL} -* `len` {integer} **Default:** `0` -* Returns: {Promise} +Emitted when the {fs.WriteStream}'s underlying file descriptor has been closed. + +#### Event: `'open'` + -Truncates the `path` then resolves the `Promise` with no arguments upon -success. The `path` *must* be a string or `Buffer`. +* `fd` {integer} Integer file descriptor used by the {fs.WriteStream}. -### `fsPromises.unlink(path)` +Emitted when the {fs.WriteStream}'s file is opened. + +#### Event: `'ready'` -* `path` {string|Buffer|URL} -* Returns: {Promise} +Emitted when the {fs.WriteStream} is ready to be used. -Asynchronous unlink(2). The `Promise` is resolved with no arguments upon -success. +Fires immediately after `'open'`. -### `fsPromises.utimes(path, atime, mtime)` +#### `writeStream.bytesWritten` -* `path` {string|Buffer|URL} -* `atime` {number|string|Date} -* `mtime` {number|string|Date} -* Returns: {Promise} +The number of bytes written so far. Does not include data that is still queued +for writing. -Change the file system timestamps of the object referenced by `path` then -resolves the `Promise` with no arguments upon success. +#### `writeStream.close([callback])` + -The `atime` and `mtime` arguments follow these rules: +* `callback` {Function} + * `err` {Error} -* Values can be either numbers representing Unix epoch time, `Date`s, or a - numeric string like `'123456789.0'`. -* If the value can not be converted to a number, or is `NaN`, `Infinity` or - `-Infinity`, an `Error` will be thrown. +Closes `writeStream`. Optionally accepts a +callback that will be executed once the `writeStream` +is closed. -### `fsPromises.writeFile(file, data[, options])` +#### `writeStream.path` -* `file` {string|Buffer|URL|FileHandle} filename or `FileHandle` -* `data` {string|Buffer|Uint8Array} -* `options` {Object|string} - * `encoding` {string|null} **Default:** `'utf8'` - * `mode` {integer} **Default:** `0o666` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'w'`. -* Returns: {Promise} +The path to the file the stream is writing to as specified in the first +argument to [`fs.createWriteStream()`][]. If `path` is passed as a string, then +`writeStream.path` will be a string. If `path` is passed as a {Buffer}, then +`writeStream.path` will be a {Buffer}. -Asynchronously writes data to a file, replacing the file if it already exists. -`data` can be a string or a buffer. The `Promise` will be resolved with no -arguments upon success. +#### `writeStream.pending` + -The `encoding` option is ignored if `data` is a buffer. +* {boolean} -If `options` is a string, then it specifies the encoding. +This property is `true` if the underlying file has not been opened yet, +i.e. before the `'ready'` event is emitted. -Any specified `FileHandle` has to support writing. +### `fs.constants` -It is unsafe to use `fsPromises.writeFile()` multiple times on the same file -without waiting for the `Promise` to be resolved (or rejected). +* {Object} + +Returns an object containing commonly used constants for file system +operations. -## FS constants +#### FS constants The following constants are exported by `fs.constants`. @@ -5486,21 +6009,21 @@ To use more than one constant, use the bitwise OR `|` operator. Example: -```js -const fs = require('fs'); +```mjs +import { open, constants } from 'fs'; const { O_RDWR, O_CREAT, O_EXCL -} = fs.constants; +} = constants; -fs.open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => { +open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => { // ... }); ``` -### File access constants +##### File access constants The following constants are meant for use with [`fs.access()`][]. @@ -5532,7 +6055,7 @@ The following constants are meant for use with [`fs.access()`][]. -### File copy constants +##### File copy constants The following constants are meant for use with [`fs.copyFile()`][]. @@ -5560,7 +6083,7 @@ The following constants are meant for use with [`fs.copyFile()`][]. -### File open constants +##### File open constants The following constants are meant for use with `fs.open()`. @@ -5654,9 +6177,9 @@ The following constants are meant for use with `fs.open()`. -### File type constants +##### File type constants -The following constants are meant for use with the [`fs.Stats`][] object's +The following constants are meant for use with the {fs.Stats} object's `mode` property for determining a file's type. @@ -5698,9 +6221,9 @@ The following constants are meant for use with the [`fs.Stats`][] object's
      -### File mode constants +##### File mode constants -The following constants are meant for use with the [`fs.Stats`][] object's +The following constants are meant for use with the {fs.Stats} object's `mode` property for determining the access permissions for a file. @@ -5758,7 +6281,321 @@ The following constants are meant for use with the [`fs.Stats`][] object's
      -## File system flags +## Notes + +### Ordering of callback and promise-based operations + +Because they are executed asynchronously by the underlying thread pool, +there is no guaranteed ordering when using either the callback or +promise-based methods. + +For example, the following is prone to error because the `fs.stat()` +operation might complete before the `fs.rename()` operation: + +```js +fs.rename('/tmp/hello', '/tmp/world', (err) => { + if (err) throw err; + console.log('renamed complete'); +}); +fs.stat('/tmp/world', (err, stats) => { + if (err) throw err; + console.log(`stats: ${JSON.stringify(stats)}`); +}); +``` + +It is important to correctly order the operations by awaiting the results +of one before invoking the other: + +```mjs +import { rename, stat } from 'fs/promises'; + +const from = '/tmp/hello'; +const to = '/tmp/world'; + +try { + await rename(from, to); + const stats = await stat(to); + console.log(`stats: ${JSON.stringify(stats)}`); +} catch (error) { + console.error('there was an error:', error.message); +} +``` + +```cjs +const { rename, stat } = require('fs/promises'); + +(async function(from, to) { + try { + await rename(from, to); + const stats = await stat(to); + console.log(`stats: ${JSON.stringify(stats)}`); + } catch (error) { + console.error('there was an error:', error.message); + } +})('/tmp/hello', '/tmp/world'); +``` + +Or, when using the callback APIs, move the `fs.stat()` call into the callback +of the `fs.rename()` operation: + +```mjs +import { rename, stat } from 'fs'; + +rename('/tmp/hello', '/tmp/world', (err) => { + if (err) throw err; + stat('/tmp/world', (err, stats) => { + if (err) throw err; + console.log(`stats: ${JSON.stringify(stats)}`); + }); +}); +``` + +```cjs +const { rename, stat } = require('fs/promises'); + +rename('/tmp/hello', '/tmp/world', (err) => { + if (err) throw err; + stat('/tmp/world', (err, stats) => { + if (err) throw err; + console.log(`stats: ${JSON.stringify(stats)}`); + }); +}); +``` + +### File paths + +Most `fs` operations accept file paths that may be specified in the form of +a string, a {Buffer}, or a {URL} object using the `file:` protocol. + +#### String paths + +String form paths are interpreted as UTF-8 character sequences identifying +the absolute or relative filename. Relative paths will be resolved relative +to the current working directory as determined by calling `process.cwd()`. + +Example using an absolute path on POSIX: + +```mjs +import { open } from 'fs/promises'; + +let fd; +try { + fd = await open('/open/some/file.txt', 'r'); + // Do something with the file +} finally { + await fd.close(); +} +``` + +Example using a relative path on POSIX (relative to `process.cwd()`): + +```mjs +import { open } from 'fs/promises'; + +let fd; +try { + fd = await open('file.txt', 'r'); + // Do something with the file +} finally { + await fd.close(); +} +``` + +#### File URL paths + +For most `fs` module functions, the `path` or `filename` argument may be passed +as a {URL} object using the `file:` protocol. + +```mjs +import { readFileSync } from 'fs'; + +readFileSync(new URL('file:///tmp/hello')); +``` + +`file:` URLs are always absolute paths. + +##### Platform-specific considerations + +On Windows, `file:` {URL}s with a host name convert to UNC paths, while `file:` +{URL}s with drive letters convert to local absolute paths. `file:` {URL}s +without a host name nor a drive letter will result in an error: + +```mjs +import { readFileSync } from 'fs'; +// On Windows : + +// - WHATWG file URLs with hostname convert to UNC path +// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file +readFileSync(new URL('file://hostname/p/a/t/h/file')); + +// - WHATWG file URLs with drive letters convert to absolute path +// file:///C:/tmp/hello => C:\tmp\hello +readFileSync(new URL('file:///C:/tmp/hello')); + +// - WHATWG file URLs without hostname must have a drive letters +readFileSync(new URL('file:///notdriveletter/p/a/t/h/file')); +readFileSync(new URL('file:///c/p/a/t/h/file')); +// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute +``` + +`file:` {URL}s with drive letters must use `:` as a separator just after +the drive letter. Using another separator will result in an error. + +On all other platforms, `file:` {URL}s with a host name are unsupported and +will result in an error: + +```mjs +import { readFileSync } from 'fs'; +// On other platforms: + +// - WHATWG file URLs with hostname are unsupported +// file://hostname/p/a/t/h/file => throw! +readFileSync(new URL('file://hostname/p/a/t/h/file')); +// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute + +// - WHATWG file URLs convert to absolute path +// file:///tmp/hello => /tmp/hello +readFileSync(new URL('file:///tmp/hello')); +``` + +A `file:` {URL} having encoded slash characters will result in an error on all +platforms: + +```mjs +import { readFileSync } from 'fs'; + +// On Windows +readFileSync(new URL('file:///C:/p/a/t/h/%2F')); +readFileSync(new URL('file:///C:/p/a/t/h/%2f')); +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded +\ or / characters */ + +// On POSIX +readFileSync(new URL('file:///p/a/t/h/%2F')); +readFileSync(new URL('file:///p/a/t/h/%2f')); +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded +/ characters */ +``` + +On Windows, `file:` {URL}s having encoded backslash will result in an error: + +```mjs +import { readFileSync } from 'fs'; + +// On Windows +readFileSync(new URL('file:///C:/path/%5C')); +readFileSync(new URL('file:///C:/path/%5c')); +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded +\ or / characters */ +``` + +#### Buffer paths + +Paths specified using a {Buffer} are useful primarily on certain POSIX +operating systems that treat file paths as opaque byte sequences. On such +systems, it is possible for a single file path to contain sub-sequences that +use multiple character encodings. As with string paths, {Buffer} paths may +be relative or absolute: + +Example using an absolute path on POSIX: + +```mjs +import { open } from 'fs/promises'; + +let fd; +try { + fd = await open(Buffer.from('/open/some/file.txt'), 'r'); + // Do something with the file +} finally { + await fd.close(); +} +``` + +#### Per-drive working directories on Windows + +On Windows, Node.js follows the concept of per-drive working directory. This +behavior can be observed when using a drive path without a backslash. For +example `fs.readdirSync('C:\\')` can potentially return a different result than +`fs.readdirSync('C:')`. For more information, see +[this MSDN page][MSDN-Rel-Path]. + +### File descriptors + +On POSIX systems, for every process, the kernel maintains a table of currently +open files and resources. Each open file is assigned a simple numeric +identifier called a *file descriptor*. At the system-level, all file system +operations use these file descriptors to identify and track each specific +file. Windows systems use a different but conceptually similar mechanism for +tracking resources. To simplify things for users, Node.js abstracts away the +differences between operating systems and assigns all open files a numeric file +descriptor. + +The callback-based `fs.open()`, and synchronous `fs.openSync()` methods open a +file and allocate a new file descriptor. Once allocated, the file descriptor may +be used to read data from, write data to, or request information about the file. + +Operating systems limit the number of file descriptors that may be open +at any given time so it is critical to close the descriptor when operations +are completed. Failure to do so will result in a memory leak that will +eventually cause an application to crash. + +```mjs +import { open, close, fstat } from 'fs'; + +function closeFd(fd) { + close(fd, (err) => { + if (err) throw err; + }); +} + +open('/open/some/file.txt', 'r', (err, fd) => { + if (err) throw err; + try { + fstat(fd, (err, stat) => { + if (err) { + closeFd(fd); + throw err; + } + + // use stat + + closeFd(fd); + }); + } catch (err) { + closeFd(fd); + throw err; + } +}); +``` + +The promise-based APIs use a {FileHandle} object in place of the numeric +file descriptor. These objects are better managed by the system to ensure +that resources are not leaked. However, it is still required that they are +closed when operations are completed: + +```mjs +import { open } from 'fs/promises'; + +let file; +try { + file = await open('/open/some/file.txt', 'r'); + const stat = await file.stat(); + // use stat +} finally { + await file.close(); +} +``` + +### Threadpool usage + +All callback and promise-based file system APIs ( with the exception of +`fs.FSWatcher()`) use libuv's threadpool. This can have surprising and negative +performance implications for some applications. See the +[`UV_THREADPOOL_SIZE`][] documentation for more information. + +### File system flags The following flags are available wherever the `flag` option takes a string. @@ -5802,7 +6639,7 @@ string. * `'wx'`: Like `'w'` but fails if the path exists. * `'w+'`: Open file for reading and writing. -The file is created (if it does not exist) or truncated (if it exists). + The file is created (if it does not exist) or truncated (if it exists). * `'wx+'`: Like `'w+'` but fails if the path exists. @@ -5814,14 +6651,14 @@ or `O_EXCL|O_CREAT` to `CREATE_NEW`, as accepted by `CreateFileW`. The exclusive flag `'x'` (`O_EXCL` flag in open(2)) causes the operation to return an error if the path already exists. On POSIX, if the path is a symbolic link, using `O_EXCL` returns an error even if the link is to a path that does -not exist. The exclusive flag may or may not work with network file systems. +not exist. The exclusive flag might not work with network file systems. On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file. -Modifying a file rather than replacing it may require a flags mode of `'r+'` -rather than the default mode `'w'`. +Modifying a file rather than replacing it may require the `flag` option to be +set to `'r+'` rather than the default `'w'`. The behavior of some flags are platform-specific. As such, opening a directory on macOS and Linux with the `'a+'` flag, as in the example below, will return an @@ -5847,30 +6684,31 @@ through `fs.open()` or `fs.writeFile()` or `fsPromises.open()`) will fail with A call to `fs.ftruncate()` or `filehandle.truncate()` can be used to reset the file contents. -[`AHAFS`]: https://www.ibm.com/developerworks/aix/library/au-aix_event_infrastructure/ -[`Buffer.byteLength`]: buffer.html#buffer_static_method_buffer_bytelength_string_encoding -[`Buffer`]: buffer.html#buffer_buffer +[#25741]: https://github.com/nodejs/node/issues/25741 +[Common System Errors]: errors.md#errors_common_system_errors +[File access constants]: #fs_file_access_constants +[MDN-Date]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date +[MDN-Number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type +[MSDN-Rel-Path]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#fully-qualified-vs-relative-paths +[MSDN-Using-Streams]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/using-streams +[Naming Files, Paths, and Namespaces]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file +[Readable Stream]: stream.md#stream_class_stream_readable +[Writable Stream]: stream.md#stream_class_stream_writable +[`AHAFS`]: https://developer.ibm.com/articles/au-aix_event_infrastructure/ +[`Buffer.byteLength`]: buffer.md#buffer_static_method_buffer_bytelength_string_encoding [`FSEvents`]: https://developer.apple.com/documentation/coreservices/file_system_events [`Number.MAX_SAFE_INTEGER`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER [`ReadDirectoryChangesW`]: https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-readdirectorychangesw -[`ReadStream`]: #fs_class_fs_readstream -[Readable Stream]: stream.html#stream_class_stream_readable -[`URL`]: url.html#url_the_whatwg_url_api -[`UV_THREADPOOL_SIZE`]: cli.html#cli_uv_threadpool_size_size -[`WriteStream`]: #fs_class_fs_writestream +[`UV_THREADPOOL_SIZE`]: cli.md#cli_uv_threadpool_size_size [`event ports`]: https://illumos.org/man/port_create [`filehandle.writeFile()`]: #fs_filehandle_writefile_data_options -[`fs.Dir`]: #fs_class_fs_dir -[`fs.Dirent`]: #fs_class_fs_dirent -[`fs.FSWatcher`]: #fs_class_fs_fswatcher -[`fs.Stats`]: #fs_class_fs_stats [`fs.access()`]: #fs_fs_access_path_mode_callback [`fs.chmod()`]: #fs_fs_chmod_path_mode_callback [`fs.chown()`]: #fs_fs_chown_path_uid_gid_callback -[`fs.copyFile()`]: #fs_fs_copyfile_src_dest_flags_callback +[`fs.copyFile()`]: #fs_fs_copyfile_src_dest_mode_callback [`fs.createReadStream()`]: #fs_fs_createreadstream_path_options [`fs.createWriteStream()`]: #fs_fs_createwritestream_path_options -[`fs.exists()`]: fs.html#fs_fs_exists_path_callback +[`fs.exists()`]: #fs_fs_exists_path_callback [`fs.fstat()`]: #fs_fs_fstat_fd_options_callback [`fs.ftruncate()`]: #fs_fs_ftruncate_fd_len_callback [`fs.futimes()`]: #fs_fs_futimes_fd_atime_mtime_callback @@ -5899,23 +6737,13 @@ the file contents. [`fs.writev()`]: #fs_fs_writev_fd_buffers_position_callback [`fsPromises.open()`]: #fs_fspromises_open_path_flags_mode [`fsPromises.opendir()`]: #fs_fspromises_opendir_path_options +[`fsPromises.stat()`]: #fs_fspromises_stat_path_options [`fsPromises.utimes()`]: #fs_fspromises_utimes_path_atime_mtime [`inotify(7)`]: https://man7.org/linux/man-pages/man7/inotify.7.html [`kqueue(2)`]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 -[`net.Socket`]: net.html#net_class_net_socket -[`stat()`]: fs.html#fs_fs_stat_path_options_callback -[`util.promisify()`]: util.html#util_util_promisify_original -[Caveats]: #fs_caveats -[Common System Errors]: errors.html#errors_common_system_errors -[FS constants]: #fs_fs_constants_1 -[File access constants]: #fs_file_access_constants -[MDN-Date]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date -[MDN-Number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type -[MSDN-Rel-Path]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#fully-qualified-vs-relative-paths -[MSDN-Using-Streams]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/using-streams -[Naming Files, Paths, and Namespaces]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file +[`util.promisify()`]: util.md#util_util_promisify_original [bigints]: https://tc39.github.io/proposal-bigint +[caveats]: #fs_caveats [chcp]: https://ss64.com/nt/chcp.html [inode]: https://en.wikipedia.org/wiki/Inode [support of file system `flags`]: #fs_file_system_flags -[Writable Stream]: #stream_class_stream_writable diff --git a/doc/api/globals.html b/doc/api/globals.html index 31bf6997f2e0dcc3d0521631b9254cd9e663e8ba..8a421b021946cf8feb83469e4e015a8601054777 100644 --- a/doc/api/globals.html +++ b/doc/api/globals.html @@ -1,10 +1,10 @@ - + - - Global objects | Node.js v12.22.7 Documentation + + Global objects | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      - +
      -

      Global objects#

      +

      Global objects#

      These objects are available in all modules. The following variables may appear @@ -172,7 +198,97 @@ to be global but are not. They exist only in the scope of modules, see the

      The objects listed here are specific to Node.js. There are built-in objects that are part of the JavaScript language itself, which are also globally accessible.

      -

      Class: Buffer#

      +

      Class: AbortController#

      + +

      Stability: 1 - Experimental

      + +

      A utility class used to signal cancelation in selected Promise-based APIs. +The API is based on the Web API AbortController.

      +

      To use, launch Node.js using the --experimental-abortcontroller flag.

      +
      const ac = new AbortController();
      +
      +ac.signal.addEventListener('abort', () => console.log('Aborted!'),
      +                           { once: true });
      +
      +ac.abort();
      +
      +console.log(ac.signal.aborted);  // Prints True
      +

      abortController.abort()#

      + +

      Triggers the abort signal, causing the abortController.signal to emit +the 'abort' event.

      +

      abortController.signal#

      + + +

      Class: AbortSignal#

      + + +

      The AbortSignal is used to notify observers when the +abortController.abort() method is called.

      +
      Static method: AbortSignal.abort()#
      + + +

      Returns a new already aborted AbortSignal.

      +
      Event: 'abort'#
      + +

      The 'abort' event is emitted when the abortController.abort() method +is called. The callback is invoked with a single object argument with a +single type property set to 'abort':

      +
      const ac = new AbortController();
      +
      +// Use either the onabort property...
      +ac.signal.onabort = () => console.log('aborted!');
      +
      +// Or the EventTarget API...
      +ac.signal.addEventListener('abort', (event) => {
      +  console.log(event.type);  // Prints 'abort'
      +}, { once: true });
      +
      +ac.abort();
      +

      The AbortController with which the AbortSignal is associated will only +ever trigger the 'abort' event once. We recommended that code check +that the abortSignal.aborted attribute is false before adding an 'abort' +event listener.

      +

      Any event listeners attached to the AbortSignal should use the +{ once: true } option (or, if using the EventEmitter APIs to attach a +listener, use the once() method) to ensure that the event listener is +removed as soon as the 'abort' event is handled. Failure to do so may +result in memory leaks.

      +
      abortSignal.aborted#
      + +
        +
      • Type: <boolean> True after the AbortController has been aborted.
      • +
      +
      abortSignal.onabort#
      + + +

      An optional callback function that may be set by user code to be notified +when the abortController.abort() function has been called.

      +

      Class: Buffer#

      @@ -181,29 +297,29 @@ accessible.

    • <Function>
    • Used to handle binary data. See the buffer section.

      -

      __dirname#

      +

      __dirname#

      This variable may appear to be global but is not. See __dirname.

      -

      __filename#

      +

      __filename#

      This variable may appear to be global but is not. See __filename.

      -

      clearImmediate(immediateObject)#

      +

      clearImmediate(immediateObject)#

      clearImmediate is described in the timers section.

      -

      clearInterval(intervalObject)#

      +

      clearInterval(intervalObject)#

      clearInterval is described in the timers section.

      -

      clearTimeout(timeoutObject)#

      +

      clearTimeout(timeoutObject)#

      clearTimeout is described in the timers section.

      -

      console#

      +

      console#

      @@ -212,9 +328,9 @@ accessible.

    • <Object>
    • Used to print to stdout and stderr. See the console section.

      -

      exports#

      +

      exports#

      This variable may appear to be global but is not. See exports.

      -

      global#

      +

      global#

      @@ -226,9 +342,9 @@ accessible.

      within the browser var something will define a new global variable. In Node.js this is different. The top-level scope is not the global scope; var something inside a Node.js module will be local to that module.

      -

      module#

      +

      module#

      This variable may appear to be global but is not. See module.

      -

      process#

      +

      process#

      @@ -237,7 +353,7 @@ Node.js this is different. The top-level scope is not the global scope;
    • <Object>
    • The process object. See the process object section.

      -

      queueMicrotask(callback)#

      +

      queueMicrotask(callback)#

      @@ -257,64 +373,64 @@ within each turn of the Node.js event loop.

      // `process.nextTick()` here would result in the 'load' event always emitting // before any other promise jobs. -DataHandler.prototype.load = async function load(key) { - const hit = this._cache.get(url); +DataHandler.prototype.load = async function load(key) { + const hit = this._cache.get(key); if (hit !== undefined) { - queueMicrotask(() => { - this.emit('load', hit); + queueMicrotask(() => { + this.emit('load', hit); }); return; } - const data = await fetchData(key); - this._cache.set(url, data); - this.emit('load', data); + const data = await fetchData(key); + this._cache.set(key, data); + this.emit('load', data); };
      -

      require()#

      +

      require()#

      This variable may appear to be global but is not. See require().

      -

      setImmediate(callback[, ...args])#

      +

      setImmediate(callback[, ...args])#

      setImmediate is described in the timers section.

      -

      setInterval(callback, delay[, ...args])#

      +

      setInterval(callback, delay[, ...args])#

      setInterval is described in the timers section.

      -

      setTimeout(callback, delay[, ...args])#

      +

      setTimeout(callback, delay[, ...args])#

      setTimeout is described in the timers section.

      -

      TextDecoder#

      +

      TextDecoder#

      The WHATWG TextDecoder class. See the TextDecoder section.

      -

      TextEncoder#

      +

      TextEncoder#

      The WHATWG TextEncoder class. See the TextEncoder section.

      -

      URL#

      +

      URL#

      The WHATWG URL class. See the URL section.

      -

      URLSearchParams#

      +

      URLSearchParams#

      The WHATWG URLSearchParams class. See the URLSearchParams section.

      -

      WebAssembly#

      +

      WebAssembly#

      @@ -324,10 +440,46 @@ DataHandler.prototype.load = async

      The object that acts as the namespace for all W3C WebAssembly related functionality. See the -Mozilla Developer Network for usage and compatibility.

      +Mozilla Developer Network for usage and compatibility.

      + diff --git a/doc/api/globals.json b/doc/api/globals.json index 63d679c31e6b93cb9fe0e7827696b40024c62160..566fb87c3479a4245818644052ea3570799e95b2 100644 --- a/doc/api/globals.json +++ b/doc/api/globals.json @@ -3,6 +3,131 @@ "source": "doc/api/globals.md", "introduced_in": "v0.10.0", "globals": [ + { + "textRaw": "Class: `AbortController`", + "type": "global", + "name": "AbortController", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "stability": 1, + "stabilityText": "Experimental", + "desc": "

      A utility class used to signal cancelation in selected Promise-based APIs.\nThe API is based on the Web API AbortController.

      \n

      To use, launch Node.js using the --experimental-abortcontroller flag.

      \n
      const ac = new AbortController();\n\nac.signal.addEventListener('abort', () => console.log('Aborted!'),\n                           { once: true });\n\nac.abort();\n\nconsole.log(ac.signal.aborted);  // Prints True\n
      ", + "methods": [ + { + "textRaw": "`abortController.abort()`", + "type": "method", + "name": "abort", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      Triggers the abort signal, causing the abortController.signal to emit\nthe 'abort' event.

      " + } + ], + "properties": [ + { + "textRaw": "`signal` Type: {AbortSignal}", + "type": "AbortSignal", + "name": "Type", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + } + } + ], + "classes": [ + { + "textRaw": "Class: `AbortSignal`", + "type": "class", + "name": "AbortSignal", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "desc": "\n

      The AbortSignal is used to notify observers when the\nabortController.abort() method is called.

      ", + "classMethods": [ + { + "textRaw": "Static method: `AbortSignal.abort()`", + "type": "classMethod", + "name": "abort", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {AbortSignal}", + "name": "return", + "type": "AbortSignal" + }, + "params": [] + } + ], + "desc": "

      Returns a new already aborted AbortSignal.

      " + } + ], + "events": [ + { + "textRaw": "Event: `'abort'`", + "type": "event", + "name": "abort", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "params": [], + "desc": "

      The 'abort' event is emitted when the abortController.abort() method\nis called. The callback is invoked with a single object argument with a\nsingle type property set to 'abort':

      \n
      const ac = new AbortController();\n\n// Use either the onabort property...\nac.signal.onabort = () => console.log('aborted!');\n\n// Or the EventTarget API...\nac.signal.addEventListener('abort', (event) => {\n  console.log(event.type);  // Prints 'abort'\n}, { once: true });\n\nac.abort();\n
      \n

      The AbortController with which the AbortSignal is associated will only\never trigger the 'abort' event once. We recommended that code check\nthat the abortSignal.aborted attribute is false before adding an 'abort'\nevent listener.

      \n

      Any event listeners attached to the AbortSignal should use the\n{ once: true } option (or, if using the EventEmitter APIs to attach a\nlistener, use the once() method) to ensure that the event listener is\nremoved as soon as the 'abort' event is handled. Failure to do so may\nresult in memory leaks.

      " + } + ], + "properties": [ + { + "textRaw": "`aborted` Type: {boolean} True after the `AbortController` has been aborted.", + "type": "boolean", + "name": "Type", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "desc": "True after the `AbortController` has been aborted." + }, + { + "textRaw": "`onabort` Type: {Function}", + "type": "Function", + "name": "Type", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "desc": "

      An optional callback function that may be set by user code to be notified\nwhen the abortController.abort() function has been called.

      " + } + ] + } + ] + }, { "textRaw": "Class: `Buffer`", "type": "global", @@ -97,7 +222,7 @@ ], "changes": [] }, - "desc": "\n

      The queueMicrotask() method queues a microtask to invoke callback. If\ncallback throws an exception, the process object 'uncaughtException'\nevent will be emitted.

      \n

      The microtask queue is managed by V8 and may be used in a similar manner to\nthe process.nextTick() queue, which is managed by Node.js. The\nprocess.nextTick() queue is always processed before the microtask queue\nwithin each turn of the Node.js event loop.

      \n
      // Here, `queueMicrotask()` is used to ensure the 'load' event is always\n// emitted asynchronously, and therefore consistently. Using\n// `process.nextTick()` here would result in the 'load' event always emitting\n// before any other promise jobs.\n\nDataHandler.prototype.load = async function load(key) {\n  const hit = this._cache.get(url);\n  if (hit !== undefined) {\n    queueMicrotask(() => {\n      this.emit('load', hit);\n    });\n    return;\n  }\n\n  const data = await fetchData(key);\n  this._cache.set(url, data);\n  this.emit('load', data);\n};\n
      " + "desc": "\n

      The queueMicrotask() method queues a microtask to invoke callback. If\ncallback throws an exception, the process object 'uncaughtException'\nevent will be emitted.

      \n

      The microtask queue is managed by V8 and may be used in a similar manner to\nthe process.nextTick() queue, which is managed by Node.js. The\nprocess.nextTick() queue is always processed before the microtask queue\nwithin each turn of the Node.js event loop.

      \n
      // Here, `queueMicrotask()` is used to ensure the 'load' event is always\n// emitted asynchronously, and therefore consistently. Using\n// `process.nextTick()` here would result in the 'load' event always emitting\n// before any other promise jobs.\n\nDataHandler.prototype.load = async function load(key) {\n  const hit = this._cache.get(key);\n  if (hit !== undefined) {\n    queueMicrotask(() => {\n      this.emit('load', hit);\n    });\n    return;\n  }\n\n  const data = await fetchData(key);\n  this._cache.set(key, data);\n  this.emit('load', data);\n};\n
      " }, { "textRaw": "`setImmediate(callback[, ...args])`", @@ -217,6 +342,131 @@ "type": "misc", "desc": "

      These objects are available in all modules. The following variables may appear\nto be global but are not. They exist only in the scope of modules, see the\nmodule system documentation:

      \n\n

      The objects listed here are specific to Node.js. There are built-in objects\nthat are part of the JavaScript language itself, which are also globally\naccessible.

      ", "globals": [ + { + "textRaw": "Class: `AbortController`", + "type": "global", + "name": "AbortController", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "stability": 1, + "stabilityText": "Experimental", + "desc": "

      A utility class used to signal cancelation in selected Promise-based APIs.\nThe API is based on the Web API AbortController.

      \n

      To use, launch Node.js using the --experimental-abortcontroller flag.

      \n
      const ac = new AbortController();\n\nac.signal.addEventListener('abort', () => console.log('Aborted!'),\n                           { once: true });\n\nac.abort();\n\nconsole.log(ac.signal.aborted);  // Prints True\n
      ", + "methods": [ + { + "textRaw": "`abortController.abort()`", + "type": "method", + "name": "abort", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      Triggers the abort signal, causing the abortController.signal to emit\nthe 'abort' event.

      " + } + ], + "properties": [ + { + "textRaw": "`signal` Type: {AbortSignal}", + "type": "AbortSignal", + "name": "Type", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + } + } + ], + "classes": [ + { + "textRaw": "Class: `AbortSignal`", + "type": "class", + "name": "AbortSignal", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "desc": "\n

      The AbortSignal is used to notify observers when the\nabortController.abort() method is called.

      ", + "classMethods": [ + { + "textRaw": "Static method: `AbortSignal.abort()`", + "type": "classMethod", + "name": "abort", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {AbortSignal}", + "name": "return", + "type": "AbortSignal" + }, + "params": [] + } + ], + "desc": "

      Returns a new already aborted AbortSignal.

      " + } + ], + "events": [ + { + "textRaw": "Event: `'abort'`", + "type": "event", + "name": "abort", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "params": [], + "desc": "

      The 'abort' event is emitted when the abortController.abort() method\nis called. The callback is invoked with a single object argument with a\nsingle type property set to 'abort':

      \n
      const ac = new AbortController();\n\n// Use either the onabort property...\nac.signal.onabort = () => console.log('aborted!');\n\n// Or the EventTarget API...\nac.signal.addEventListener('abort', (event) => {\n  console.log(event.type);  // Prints 'abort'\n}, { once: true });\n\nac.abort();\n
      \n

      The AbortController with which the AbortSignal is associated will only\never trigger the 'abort' event once. We recommended that code check\nthat the abortSignal.aborted attribute is false before adding an 'abort'\nevent listener.

      \n

      Any event listeners attached to the AbortSignal should use the\n{ once: true } option (or, if using the EventEmitter APIs to attach a\nlistener, use the once() method) to ensure that the event listener is\nremoved as soon as the 'abort' event is handled. Failure to do so may\nresult in memory leaks.

      " + } + ], + "properties": [ + { + "textRaw": "`aborted` Type: {boolean} True after the `AbortController` has been aborted.", + "type": "boolean", + "name": "Type", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "desc": "True after the `AbortController` has been aborted." + }, + { + "textRaw": "`onabort` Type: {Function}", + "type": "Function", + "name": "Type", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "desc": "

      An optional callback function that may be set by user code to be notified\nwhen the abortController.abort() function has been called.

      " + } + ] + } + ] + }, { "textRaw": "Class: `Buffer`", "type": "global", @@ -311,7 +561,7 @@ ], "changes": [] }, - "desc": "\n

      The queueMicrotask() method queues a microtask to invoke callback. If\ncallback throws an exception, the process object 'uncaughtException'\nevent will be emitted.

      \n

      The microtask queue is managed by V8 and may be used in a similar manner to\nthe process.nextTick() queue, which is managed by Node.js. The\nprocess.nextTick() queue is always processed before the microtask queue\nwithin each turn of the Node.js event loop.

      \n
      // Here, `queueMicrotask()` is used to ensure the 'load' event is always\n// emitted asynchronously, and therefore consistently. Using\n// `process.nextTick()` here would result in the 'load' event always emitting\n// before any other promise jobs.\n\nDataHandler.prototype.load = async function load(key) {\n  const hit = this._cache.get(url);\n  if (hit !== undefined) {\n    queueMicrotask(() => {\n      this.emit('load', hit);\n    });\n    return;\n  }\n\n  const data = await fetchData(key);\n  this._cache.set(url, data);\n  this.emit('load', data);\n};\n
      " + "desc": "\n

      The queueMicrotask() method queues a microtask to invoke callback. If\ncallback throws an exception, the process object 'uncaughtException'\nevent will be emitted.

      \n

      The microtask queue is managed by V8 and may be used in a similar manner to\nthe process.nextTick() queue, which is managed by Node.js. The\nprocess.nextTick() queue is always processed before the microtask queue\nwithin each turn of the Node.js event loop.

      \n
      // Here, `queueMicrotask()` is used to ensure the 'load' event is always\n// emitted asynchronously, and therefore consistently. Using\n// `process.nextTick()` here would result in the 'load' event always emitting\n// before any other promise jobs.\n\nDataHandler.prototype.load = async function load(key) {\n  const hit = this._cache.get(key);\n  if (hit !== undefined) {\n    queueMicrotask(() => {\n      this.emit('load', hit);\n    });\n    return;\n  }\n\n  const data = await fetchData(key);\n  this._cache.set(key, data);\n  this.emit('load', data);\n};\n
      " }, { "textRaw": "`setImmediate(callback[, ...args])`", diff --git a/doc/api/globals.md b/doc/api/globals.md index 4e2e362bcdeb5bca2125cf0ff6eafc03d74b60ea..a824f50899bd975ef60e0730c46f7ce61e91126e 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -17,6 +17,116 @@ The objects listed here are specific to Node.js. There are [built-in objects][] that are part of the JavaScript language itself, which are also globally accessible. +## Class: `AbortController` + + +> Stability: 1 - Experimental + + + +A utility class used to signal cancelation in selected `Promise`-based APIs. +The API is based on the Web API [`AbortController`][]. + +To use, launch Node.js using the `--experimental-abortcontroller` flag. + +```js +const ac = new AbortController(); + +ac.signal.addEventListener('abort', () => console.log('Aborted!'), + { once: true }); + +ac.abort(); + +console.log(ac.signal.aborted); // Prints True +``` + +### `abortController.abort()` + + +Triggers the abort signal, causing the `abortController.signal` to emit +the `'abort'` event. + +### `abortController.signal` + + +* Type: {AbortSignal} + +### Class: `AbortSignal` + + +* Extends: {EventTarget} + +The `AbortSignal` is used to notify observers when the +`abortController.abort()` method is called. + +#### Static method: `AbortSignal.abort()` + + +* Returns: {AbortSignal} + +Returns a new already aborted `AbortSignal`. + +#### Event: `'abort'` + + +The `'abort'` event is emitted when the `abortController.abort()` method +is called. The callback is invoked with a single object argument with a +single `type` property set to `'abort'`: + +```js +const ac = new AbortController(); + +// Use either the onabort property... +ac.signal.onabort = () => console.log('aborted!'); + +// Or the EventTarget API... +ac.signal.addEventListener('abort', (event) => { + console.log(event.type); // Prints 'abort' +}, { once: true }); + +ac.abort(); +``` + +The `AbortController` with which the `AbortSignal` is associated will only +ever trigger the `'abort'` event once. We recommended that code check +that the `abortSignal.aborted` attribute is `false` before adding an `'abort'` +event listener. + +Any event listeners attached to the `AbortSignal` should use the +`{ once: true }` option (or, if using the `EventEmitter` APIs to attach a +listener, use the `once()` method) to ensure that the event listener is +removed as soon as the `'abort'` event is handled. Failure to do so may +result in memory leaks. + +#### `abortSignal.aborted` + + +* Type: {boolean} True after the `AbortController` has been aborted. + +#### `abortSignal.onabort` + + +* Type: {Function} + +An optional callback function that may be set by user code to be notified +when the `abortController.abort()` function has been called. + ## Class: `Buffer` true + err.code; // --> 'ERR_INVALID_HTTP_TOKEN' + err.message; // --> 'Header name must be a valid HTTP token [""]' +}
      +

      http.validateHeaderValue(name, value)#

      + + +

      Performs the low-level validations on the provided value that are done when +res.setHeader(name, value) is called.

      +

      Passing illegal value as value will result in a TypeError being thrown.

      +
        +
      • Undefined value error is identified by code: 'ERR_HTTP_INVALID_HEADER_VALUE'.
      • +
      • Invalid value character error is identified by code: 'ERR_INVALID_CHAR'.
      • +
      +

      It is not necessary to use this method before passing headers to an HTTP request +or response. The HTTP module will automatically validate such headers.

      +

      Examples:

      +
      const { validateHeaderValue } = require('http');
      +
      +try {
      +  validateHeaderValue('x-my-header', undefined);
      +} catch (err) {
      +  err instanceof TypeError; // --> true
      +  err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'; // --> true
      +  err.message; // --> 'Invalid value "undefined" for header "x-my-header"'
      +}
      +
      +try {
      +  validateHeaderValue('x-my-header', 'oʊmɪɡə');
      +} catch (err) {
      +  err instanceof TypeError; // --> true
      +  err.code === 'ERR_INVALID_CHAR'; // --> true
      +  err.message; // --> 'Invalid character in header content ["x-my-header"]'
      +}
      + diff --git a/doc/api/http.json b/doc/api/http.json index 8b6ec78f45c0e47717bf99e7642ee1ecaa5cbf7d..4d7a943a63d7754c7dedcc2d7c35a5a93f323280 100644 --- a/doc/api/http.json +++ b/doc/api/http.json @@ -8,7 +8,7 @@ "introduced_in": "v0.10.0", "stability": 2, "stabilityText": "Stable", - "desc": "

      Source Code: lib/http.js

      \n

      To use the HTTP server and client one must require('http').

      \n

      The HTTP interfaces in Node.js are designed to support many features\nof the protocol which have been traditionally difficult to use.\nIn particular, large, possibly chunk-encoded, messages. The interface is\ncareful to never buffer entire requests or responses, so the\nuser is able to stream data.

      \n

      HTTP message headers are represented by an object like this:

      \n\n
      { 'content-length': '123',\n  'content-type': 'text/plain',\n  'connection': 'keep-alive',\n  'host': 'mysite.com',\n  'accept': '*/*' }\n
      \n

      Keys are lowercased. Values are not modified.

      \n

      In order to support the full spectrum of possible HTTP applications, the Node.js\nHTTP API is very low-level. It deals with stream handling and message\nparsing only. It parses a message into headers and body but it does not\nparse the actual headers or the body.

      \n

      See message.headers for details on how duplicate headers are handled.

      \n

      The raw headers as they were received are retained in the rawHeaders\nproperty, which is an array of [key, value, key2, value2, ...]. For\nexample, the previous message header object might have a rawHeaders\nlist like the following:

      \n\n
      [ 'ConTent-Length', '123456',\n  'content-LENGTH', '123',\n  'content-type', 'text/plain',\n  'CONNECTION', 'keep-alive',\n  'Host', 'mysite.com',\n  'accepT', '*/*' ]\n
      ", + "desc": "

      Source Code: lib/http.js

      \n

      To use the HTTP server and client one must require('http').

      \n

      The HTTP interfaces in Node.js are designed to support many features\nof the protocol which have been traditionally difficult to use.\nIn particular, large, possibly chunk-encoded, messages. The interface is\ncareful to never buffer entire requests or responses, so the\nuser is able to stream data.

      \n

      HTTP message headers are represented by an object like this:

      \n\n
      { 'content-length': '123',\n  'content-type': 'text/plain',\n  'connection': 'keep-alive',\n  'host': 'mysite.com',\n  'accept': '*/*' }\n
      \n

      Keys are lowercased. Values are not modified.

      \n

      In order to support the full spectrum of possible HTTP applications, the Node.js\nHTTP API is very low-level. It deals with stream handling and message\nparsing only. It parses a message into headers and body but it does not\nparse the actual headers or the body.

      \n

      See message.headers for details on how duplicate headers are handled.

      \n

      The raw headers as they were received are retained in the rawHeaders\nproperty, which is an array of [key, value, key2, value2, ...]. For\nexample, the previous message header object might have a rawHeaders\nlist like the following:

      \n\n
      [ 'ConTent-Length', '123456',\n  'content-LENGTH', '123',\n  'content-type', 'text/plain',\n  'CONNECTION', 'keep-alive',\n  'Host', 'mysite.com',\n  'accepT', '*/*' ]\n
      ", "classes": [ { "textRaw": "Class: `http.Agent`", @@ -123,7 +123,7 @@ "params": [] } ], - "desc": "

      Destroy any sockets that are currently in use by the agent.

      \n

      It is usually not necessary to do this. However, if using an\nagent with keepAlive enabled, then it is best to explicitly shut down\nthe agent when it will no longer be used. Otherwise,\nsockets may hang open for quite a long time before the server\nterminates them.

      " + "desc": "

      Destroy any sockets that are currently in use by the agent.

      \n

      It is usually not necessary to do this. However, if using an\nagent with keepAlive enabled, then it is best to explicitly shut down\nthe agent when it is no longer needed. Otherwise,\nsockets might stay open for quite a long time before the server\nterminates them.

      " }, { "textRaw": "`agent.getName(options)`", @@ -224,7 +224,7 @@ "name": "maxTotalSockets", "meta": { "added": [ - "v12.19.0" + "v14.5.0" ], "changes": [] }, @@ -272,18 +272,18 @@ "desc": "Keep sockets around even when there are no outstanding requests, so they can be used for future requests without having to reestablish a TCP connection. Not to be confused with the `keep-alive` value of the `Connection` header. The `Connection: keep-alive` header is always sent when using an agent except when the `Connection` header is explicitly specified or when the `keepAlive` and `maxSockets` options are respectively set to `false` and `Infinity`, in which case `Connection: close` will be used." }, { - "textRaw": "`keepAliveMsecs` {number} When using the `keepAlive` option, specifies the [initial delay](net.html#net_socket_setkeepalive_enable_initialdelay) for TCP Keep-Alive packets. Ignored when the `keepAlive` option is `false` or `undefined`. **Default:** `1000`.", + "textRaw": "`keepAliveMsecs` {number} When using the `keepAlive` option, specifies the [initial delay](net.md#net_socket_setkeepalive_enable_initialdelay) for TCP Keep-Alive packets. Ignored when the `keepAlive` option is `false` or `undefined`. **Default:** `1000`.", "name": "keepAliveMsecs", "type": "number", "default": "`1000`", - "desc": "When using the `keepAlive` option, specifies the [initial delay](net.html#net_socket_setkeepalive_enable_initialdelay) for TCP Keep-Alive packets. Ignored when the `keepAlive` option is `false` or `undefined`." + "desc": "When using the `keepAlive` option, specifies the [initial delay](net.md#net_socket_setkeepalive_enable_initialdelay) for TCP Keep-Alive packets. Ignored when the `keepAlive` option is `false` or `undefined`." }, { - "textRaw": "`maxSockets` {number} Maximum number of sockets to allow per host. Each request will use a new socket until the maximum is reached. **Default:** `Infinity`.", + "textRaw": "`maxSockets` {number} Maximum number of sockets to allow per host. If the same host opens multiple concurrent connections, each request will use new socket until the `maxSockets` value is reached. If the host attempts to open more connections than `maxSockets`, the additional requests will enter into a pending request queue, and will enter active connection state when an existing connection terminates. This makes sure there are at most `maxSockets` active connections at any point in time, from a given host. **Default:** `Infinity`.", "name": "maxSockets", "type": "number", "default": "`Infinity`", - "desc": "Maximum number of sockets to allow per host. Each request will use a new socket until the maximum is reached." + "desc": "Maximum number of sockets to allow per host. If the same host opens multiple concurrent connections, each request will use new socket until the `maxSockets` value is reached. If the host attempts to open more connections than `maxSockets`, the additional requests will enter into a pending request queue, and will enter active connection state when an existing connection terminates. This makes sure there are at most `maxSockets` active connections at any point in time, from a given host." }, { "textRaw": "`maxTotalSockets` {number} Maximum number of sockets allowed for all hosts in total. Each request will use a new socket until the maximum is reached. **Default:** `Infinity`.", @@ -300,10 +300,10 @@ "desc": "Maximum number of sockets to leave open in a free state. Only relevant if `keepAlive` is set to `true`." }, { - "textRaw": "`scheduling` {string} Scheduling strategy to apply when picking the next free socket to use. It can be `'fifo'` or `'lifo'`. The main difference between the two scheduling strategies is that `'lifo'` selects the most recently used socket, while `'fifo'` selects the least recently used socket. In case of a low rate of request per second, the `'lifo'` scheduling will lower the risk of picking a socket that might have been closed by the server due to inactivity. In case of a high rate of request per second, the `'fifo'` scheduling will maximize the number of open sockets, while the `'lifo'` scheduling will keep it as low as possible. **Default:** `'fifo'`.", + "textRaw": "`scheduling` {string} Scheduling strategy to apply when picking the next free socket to use. It can be `'fifo'` or `'lifo'`. The main difference between the two scheduling strategies is that `'lifo'` selects the most recently used socket, while `'fifo'` selects the least recently used socket. In case of a low rate of request per second, the `'lifo'` scheduling will lower the risk of picking a socket that might have been closed by the server due to inactivity. In case of a high rate of request per second, the `'fifo'` scheduling will maximize the number of open sockets, while the `'lifo'` scheduling will keep it as low as possible. **Default:** `'lifo'`.", "name": "scheduling", "type": "string", - "default": "`'fifo'`", + "default": "`'lifo'`", "desc": "Scheduling strategy to apply when picking the next free socket to use. It can be `'fifo'` or `'lifo'`. The main difference between the two scheduling strategies is that `'lifo'` selects the most recently used socket, while `'fifo'` selects the least recently used socket. In case of a low rate of request per second, the `'lifo'` scheduling will lower the risk of picking a socket that might have been closed by the server due to inactivity. In case of a high rate of request per second, the `'fifo'` scheduling will maximize the number of open sockets, while the `'lifo'` scheduling will keep it as low as possible." }, { @@ -532,8 +532,13 @@ "added": [ "v0.3.8" ], + "deprecated": [ + "v14.1.0" + ], "changes": [] }, + "stability": 0, + "stabilityText": "Deprecated: Use [`request.destroy()`][] instead.", "signatures": [ { "params": [] @@ -585,6 +590,55 @@ ], "desc": "

      Finishes sending the request. If any parts of the body are\nunsent, it will flush them to the stream. If the request is\nchunked, this will send the terminating '0\\r\\n\\r\\n'.

      \n

      If data is specified, it is equivalent to calling\nrequest.write(data, encoding) followed by request.end(callback).

      \n

      If callback is specified, it will be called when the request stream\nis finished.

      " }, + { + "textRaw": "`request.destroy([error])`", + "type": "method", + "name": "destroy", + "meta": { + "added": [ + "v0.3.0" + ], + "changes": [ + { + "version": "v14.5.0", + "pr-url": "https://github.com/nodejs/node/pull/32789", + "description": "The function returns `this` for consistency with other Readable streams." + } + ] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {this}", + "name": "return", + "type": "this" + }, + "params": [ + { + "textRaw": "`error` {Error} Optional, an error to emit with `'error'` event.", + "name": "error", + "type": "Error", + "desc": "Optional, an error to emit with `'error'` event." + } + ] + } + ], + "desc": "

      Destroy the request. Optionally emit an 'error' event,\nand emit a 'close' event. Calling this will cause remaining data\nin the response to be dropped and the socket to be destroyed.

      \n

      See writable.destroy() for further details.

      ", + "properties": [ + { + "textRaw": "`destroyed` {boolean}", + "type": "boolean", + "name": "destroyed", + "meta": { + "added": [ + "v14.1.0" + ], + "changes": [] + }, + "desc": "

      Is true after request.destroy() has been called.

      \n

      See writable.destroyed for further details.

      " + } + ] + }, { "textRaw": "`request.flushHeaders()`", "type": "method", @@ -630,6 +684,28 @@ ], "desc": "

      Reads out a header on the request. The name is case-insensitive.\nThe type of the return value depends on the arguments provided to\nrequest.setHeader().

      \n
      request.setHeader('content-type', 'text/html');\nrequest.setHeader('Content-Length', Buffer.byteLength(body));\nrequest.setHeader('Cookie', ['type=ninja', 'language=javascript']);\nconst contentType = request.getHeader('Content-Type');\n// 'contentType' is 'text/html'\nconst contentLength = request.getHeader('Content-Length');\n// 'contentLength' is of type number\nconst cookie = request.getHeader('Cookie');\n// 'cookie' is of type string[]\n
      " }, + { + "textRaw": "`request.getRawHeaderNames()`", + "type": "method", + "name": "getRawHeaderNames", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {string[]}", + "name": "return", + "type": "string[]" + }, + "params": [] + } + ], + "desc": "

      Returns an array containing the unique names of the current outgoing raw\nheaders. Header names are returned with their exact casing being set.

      \n
      request.setHeader('Foo', 'bar');\nrequest.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);\n\nconst headerNames = request.getRawHeaderNames();\n// headerNames === ['Foo', 'Set-Cookie']\n
      " + }, { "textRaw": "`request.removeHeader(name)`", "type": "method", @@ -809,7 +885,7 @@ ] } ], - "desc": "

      Sends a chunk of the body. By calling this method\nmany times, a request body can be sent to a\nserver. In that case, it is suggested to use the\n['Transfer-Encoding', 'chunked'] header line when\ncreating the request.

      \n

      The encoding argument is optional and only applies when chunk is a string.\nDefaults to 'utf8'.

      \n

      The callback argument is optional and will be called when this chunk of data\nis flushed, but only if the chunk is non-empty.

      \n

      Returns true if the entire data was flushed successfully to the kernel\nbuffer. Returns false if all or part of the data was queued in user memory.\n'drain' will be emitted when the buffer is free again.

      \n

      When write function is called with empty string or buffer, it does\nnothing and waits for more input.

      " + "desc": "

      Sends a chunk of the body. This method can be called multiple times. If no\nContent-Length is set, data will automatically be encoded in HTTP Chunked\ntransfer encoding, so that server knows when the data ends. The\nTransfer-Encoding: chunked header is added. Calling request.end()\nis necessary to finish sending the request.

      \n

      The encoding argument is optional and only applies when chunk is a string.\nDefaults to 'utf8'.

      \n

      The callback argument is optional and will be called when this chunk of data\nis flushed, but only if the chunk is non-empty.

      \n

      Returns true if the entire data was flushed successfully to the kernel\nbuffer. Returns false if all or part of the data was queued in user memory.\n'drain' will be emitted when the buffer is free again.

      \n

      When write function is called with empty string or buffer, it does\nnothing and waits for more input.

      " } ], "properties": [ @@ -839,8 +915,13 @@ "added": [ "v0.3.0" ], + "deprecated": [ + "v13.0.0" + ], "changes": [] }, + "stability": 0, + "stabilityText": "Deprecated. Use [`request.socket`][].", "desc": "

      See request.socket.

      " }, { @@ -852,6 +933,7 @@ "v0.0.1" ], "deprecated": [ + "v13.4.0", "v12.16.0" ], "changes": [] @@ -897,7 +979,7 @@ "name": "host", "meta": { "added": [ - "v12.19.0" + "v14.5.0" ], "changes": [] }, @@ -909,7 +991,7 @@ "name": "protocol", "meta": { "added": [ - "v12.19.0" + "v14.5.0" ], "changes": [] }, @@ -921,6 +1003,7 @@ "name": "reusedSocket", "meta": { "added": [ + "v13.0.0", "v12.16.0" ], "changes": [] @@ -938,7 +1021,7 @@ ], "changes": [] }, - "desc": "

      Reference to the underlying socket. Usually users will not want to access\nthis property. In particular, the socket will not emit 'readable' events\nbecause of how the protocol parser attaches to the socket. The socket\nmay also be accessed via request.connection.

      \n
      const http = require('http');\nconst options = {\n  host: 'www.google.com',\n};\nconst req = http.get(options);\nreq.end();\nreq.once('response', (res) => {\n  const ip = req.socket.localAddress;\n  const port = req.socket.localPort;\n  console.log(`Your IP address is ${ip} and your source port is ${port}.`);\n  // Consume response object\n});\n
      \n

      This property is guaranteed to be an instance of the <net.Socket> class,\na subclass of <stream.Duplex>, unless the user specified a socket\ntype other than <net.Socket>.

      " + "desc": "

      Reference to the underlying socket. Usually users will not want to access\nthis property. In particular, the socket will not emit 'readable' events\nbecause of how the protocol parser attaches to the socket.

      \n
      const http = require('http');\nconst options = {\n  host: 'www.google.com',\n};\nconst req = http.get(options);\nreq.end();\nreq.once('response', (res) => {\n  const ip = req.socket.localAddress;\n  const port = req.socket.localPort;\n  console.log(`Your IP address is ${ip} and your source port is ${port}.`);\n  // Consume response object\n});\n
      \n

      This property is guaranteed to be an instance of the <net.Socket> class,\na subclass of <stream.Duplex>, unless the user specified a socket\ntype other than <net.Socket>.

      " }, { "textRaw": "`writableEnded` {boolean}", @@ -1036,9 +1119,9 @@ ], "changes": [ { - "version": "v6.0.0", - "pr-url": "https://github.com/nodejs/node/pull/4557", - "description": "The default action of calling `.destroy()` on the `socket` will no longer take place if there are listeners attached for `'clientError'`." + "version": "v12.0.0", + "pr-url": "https://github.com/nodejs/node/pull/25605", + "description": "The default behavior will return a 431 Request Header Fields Too Large if a HPE_HEADER_OVERFLOW error occurs." }, { "version": "v9.4.0", @@ -1046,9 +1129,9 @@ "description": "The `rawPacket` is the current buffer that just parsed. Adding this buffer to the error object of `'clientError'` event is to make it possible that developers can log the broken packet." }, { - "version": "v12.0.0", - "pr-url": "https://github.com/nodejs/node/pull/25605", - "description": "The default behavior will return a 431 Request Header Fields Too Large if a HPE_HEADER_OVERFLOW error occurs." + "version": "v6.0.0", + "pr-url": "https://github.com/nodejs/node/pull/4557", + "description": "The default action of calling `.destroy()` on the `socket` will no longer take place if there are listeners attached for `'clientError'`." } ] }, @@ -1128,7 +1211,7 @@ "type": "stream.Duplex" } ], - "desc": "

      This event is emitted when a new TCP stream is established. socket is\ntypically an object of type net.Socket. Usually users will not want to\naccess this event. In particular, the socket will not emit 'readable' events\nbecause of how the protocol parser attaches to the socket. The socket can\nalso be accessed at request.connection.

      \n

      This event can also be explicitly emitted by users to inject connections\ninto the HTTP server. In that case, any Duplex stream can be passed.

      \n

      If socket.setTimeout() is called here, the timeout will be replaced with\nserver.keepAliveTimeout when the socket has served a request (if\nserver.keepAliveTimeout is non-zero).

      \n

      This event is guaranteed to be passed an instance of the <net.Socket> class,\na subclass of <stream.Duplex>, unless the user specifies a socket\ntype other than <net.Socket>.

      " + "desc": "

      This event is emitted when a new TCP stream is established. socket is\ntypically an object of type net.Socket. Usually users will not want to\naccess this event. In particular, the socket will not emit 'readable' events\nbecause of how the protocol parser attaches to the socket. The socket can\nalso be accessed at request.socket.

      \n

      This event can also be explicitly emitted by users to inject connections\ninto the HTTP server. In that case, any Duplex stream can be passed.

      \n

      If socket.setTimeout() is called here, the timeout will be replaced with\nserver.keepAliveTimeout when the socket has served a request (if\nserver.keepAliveTimeout is non-zero).

      \n

      This event is guaranteed to be passed an instance of the <net.Socket> class,\na subclass of <stream.Duplex>, unless the user specifies a socket\ntype other than <net.Socket>.

      " }, { "textRaw": "Event: `'request'`", @@ -1165,7 +1248,7 @@ "changes": [ { "version": "v10.0.0", - "pr-url": "v10.0.0", + "pr-url": "https://github.com/nodejs/node/pull/19981", "description": "Not listening to this event no longer causes the socket to be destroyed if a client sends an Upgrade header." } ] @@ -1236,7 +1319,13 @@ "added": [ "v0.9.12" ], - "changes": [] + "changes": [ + { + "version": "v13.0.0", + "pr-url": "https://github.com/nodejs/node/pull/27558", + "description": "The default timeout changed from 120s to 0 (no timeout)." + } + ] }, "signatures": [ { @@ -1247,10 +1336,10 @@ }, "params": [ { - "textRaw": "`msecs` {number} **Default:** `120000` (2 minutes)", + "textRaw": "`msecs` {number} **Default:** 0 (no timeout)", "name": "msecs", "type": "number", - "default": "`120000` (2 minutes)" + "default": "0 (no timeout)" }, { "textRaw": "`callback` {Function}", @@ -1260,7 +1349,7 @@ ] } ], - "desc": "

      Sets the timeout value for sockets, and emits a 'timeout' event on\nthe Server object, passing the socket as an argument, if a timeout\noccurs.

      \n

      If there is a 'timeout' event listener on the Server object, then it\nwill be called with the timed-out socket as an argument.

      \n

      By default, the Server's timeout value is 2 minutes, and sockets are\ndestroyed automatically if they time out. However, if a callback is assigned\nto the Server's 'timeout' event, timeouts must be handled explicitly.

      \n

      To change the default timeout use the --http-server-default-timeout\nflag.

      " + "desc": "

      Sets the timeout value for sockets, and emits a 'timeout' event on\nthe Server object, passing the socket as an argument, if a timeout\noccurs.

      \n

      If there is a 'timeout' event listener on the Server object, then it\nwill be called with the timed-out socket as an argument.

      \n

      By default, the Server does not timeout sockets. However, if a callback\nis assigned to the Server's 'timeout' event, timeouts must be handled\nexplicitly.

      " } ], "properties": [ @@ -1270,12 +1359,13 @@ "name": "headersTimeout", "meta": { "added": [ - "v11.3.0" + "v11.3.0", + "v10.14.0" ], "changes": [] }, "default": "`60000`", - "desc": "

      Limit the amount of time the parser will wait to receive the complete HTTP\nheaders.

      \n

      In case of inactivity, the rules defined in server.timeout apply. However,\nthat inactivity based timeout would still allow the connection to be kept open\nif the headers are being sent very slowly (by default, up to a byte per 2\nminutes). In order to prevent this, whenever header data arrives an additional\ncheck is made that more than server.headersTimeout milliseconds has not\npassed since the connection was established. If the check fails, a 'timeout'\nevent is emitted on the server object, and (by default) the socket is destroyed.\nSee server.timeout for more information on how timeout behavior can be\ncustomized.

      \n

      A value of 0 will disable the HTTP headers timeout check.

      " + "desc": "

      Limit the amount of time the parser will wait to receive the complete HTTP\nheaders.

      \n

      In case of inactivity, the rules defined in server.timeout apply. However,\nthat inactivity based timeout would still allow the connection to be kept open\nif the headers are being sent very slowly (by default, up to a byte per 2\nminutes). In order to prevent this, whenever header data arrives an additional\ncheck is made that more than server.headersTimeout milliseconds has not\npassed since the connection was established. If the check fails, a 'timeout'\nevent is emitted on the server object, and (by default) the socket is destroyed.\nSee server.timeout for more information on how timeout behavior can be\ncustomized.

      " }, { "textRaw": "`listening` {boolean} Indicates whether or not the server is listening for connections.", @@ -1303,17 +1393,36 @@ "desc": "

      Limits maximum incoming headers count. If set to 0, no limit will be applied.

      " }, { - "textRaw": "`timeout` {number} Timeout in milliseconds. **Default:** `120000` (2 minutes).", + "textRaw": "`requestTimeout` {number} **Default:** `0`", + "type": "number", + "name": "requestTimeout", + "meta": { + "added": [ + "v14.11.0" + ], + "changes": [] + }, + "default": "`0`", + "desc": "

      Sets the timeout value in milliseconds for receiving the entire request from\nthe client.

      \n

      If the timeout expires, the server responds with status 408 without\nforwarding the request to the request listener and then closes the connection.

      \n

      It must be set to a non-zero value (e.g. 120 seconds) to protect against\npotential Denial-of-Service attacks in case the server is deployed without a\nreverse proxy in front.

      " + }, + { + "textRaw": "`timeout` {number} Timeout in milliseconds. **Default:** 0 (no timeout)", "type": "number", "name": "timeout", "meta": { "added": [ "v0.9.12" ], - "changes": [] + "changes": [ + { + "version": "v13.0.0", + "pr-url": "https://github.com/nodejs/node/pull/27558", + "description": "The default timeout changed from 120s to 0 (no timeout)." + } + ] }, - "default": "`120000` (2 minutes)", - "desc": "

      The number of milliseconds of inactivity before a socket is presumed\nto have timed out.

      \n

      A value of 0 will disable the timeout behavior on incoming connections.

      \n

      The socket timeout logic is set up on connection, so changing this\nvalue only affects new connections to the server, not any existing connections.

      \n

      To change the default timeout use the --http-server-default-timeout\nflag.

      ", + "default": "0 (no timeout)", + "desc": "

      The number of milliseconds of inactivity before a socket is presumed\nto have timed out.

      \n

      A value of 0 will disable the timeout behavior on incoming connections.

      \n

      The socket timeout logic is set up on connection, so changing this\nvalue only affects new connections to the server, not any existing connections.

      ", "shortDesc": "Timeout in milliseconds." }, { @@ -1355,7 +1464,7 @@ "changes": [] }, "params": [], - "desc": "

      Indicates that the the response is completed, or its underlying connection was\nterminated prematurely (before the response completion).

      " + "desc": "

      Indicates that the response is completed, or its underlying connection was\nterminated prematurely (before the response completion).

      " }, { "textRaw": "Event: `'finish'`", @@ -1401,6 +1510,7 @@ "name": "cork", "meta": { "added": [ + "v13.2.0", "v12.16.0" ], "changes": [] @@ -1608,6 +1718,11 @@ }, "signatures": [ { + "return": { + "textRaw": "Returns: {http.ServerResponse}", + "name": "return", + "type": "http.ServerResponse" + }, "params": [ { "textRaw": "`name` {string}", @@ -1622,7 +1737,7 @@ ] } ], - "desc": "

      Sets a single header value for implicit headers. If this header already exists\nin the to-be-sent headers, its value will be replaced. Use an array of strings\nhere to send multiple headers with the same name. Non-string values will be\nstored without modification. Therefore, response.getHeader() may return\nnon-string values. However, the non-string values will be converted to strings\nfor network transmission.

      \n
      response.setHeader('Content-Type', 'text/html');\n
      \n

      or

      \n
      response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);\n
      \n

      Attempting to set a header field name or value that contains invalid characters\nwill result in a TypeError being thrown.

      \n

      When headers have been set with response.setHeader(), they will be merged\nwith any headers passed to response.writeHead(), with the headers passed\nto response.writeHead() given precedence.

      \n
      // Returns content-type = text/plain\nconst server = http.createServer((req, res) => {\n  res.setHeader('Content-Type', 'text/html');\n  res.setHeader('X-Foo', 'bar');\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end('ok');\n});\n
      \n

      If response.writeHead() method is called and this method has not been\ncalled, it will directly write the supplied header values onto the network\nchannel without caching internally, and the response.getHeader() on the\nheader will not yield the expected result. If progressive population of headers\nis desired with potential future retrieval and modification, use\nresponse.setHeader() instead of response.writeHead().

      " + "desc": "

      Returns the response object.

      \n

      Sets a single header value for implicit headers. If this header already exists\nin the to-be-sent headers, its value will be replaced. Use an array of strings\nhere to send multiple headers with the same name. Non-string values will be\nstored without modification. Therefore, response.getHeader() may return\nnon-string values. However, the non-string values will be converted to strings\nfor network transmission. The same response object is returned to the caller,\nto enable call chaining.

      \n
      response.setHeader('Content-Type', 'text/html');\n
      \n

      or

      \n
      response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);\n
      \n

      Attempting to set a header field name or value that contains invalid characters\nwill result in a TypeError being thrown.

      \n

      When headers have been set with response.setHeader(), they will be merged\nwith any headers passed to response.writeHead(), with the headers passed\nto response.writeHead() given precedence.

      \n
      // Returns content-type = text/plain\nconst server = http.createServer((req, res) => {\n  res.setHeader('Content-Type', 'text/html');\n  res.setHeader('X-Foo', 'bar');\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end('ok');\n});\n
      \n

      If response.writeHead() method is called and this method has not been\ncalled, it will directly write the supplied header values onto the network\nchannel without caching internally, and the response.getHeader() on the\nheader will not yield the expected result. If progressive population of headers\nis desired with potential future retrieval and modification, use\nresponse.setHeader() instead of response.writeHead().

      " }, { "textRaw": "`response.setTimeout(msecs[, callback])`", @@ -1663,6 +1778,7 @@ "name": "uncork", "meta": { "added": [ + "v13.2.0", "v12.16.0" ], "changes": [] @@ -1740,12 +1856,23 @@ ], "changes": [ { - "version": "v11.10.0", + "version": "v14.14.0", + "pr-url": "https://github.com/nodejs/node/pull/35274", + "description": "Allow passing headers as an array." + }, + { + "version": [ + "v11.10.0", + "v10.17.0" + ], "pr-url": "https://github.com/nodejs/node/pull/25974", "description": "Return `this` from `writeHead()` to allow chaining with `end()`." }, { - "version": "v5.11.0, v4.4.5", + "version": [ + "v5.11.0", + "v4.4.5" + ], "pr-url": "https://github.com/nodejs/node/pull/6291", "description": "A `RangeError` is thrown if `statusCode` is not a number in the range `[100, 999]`." } @@ -1770,14 +1897,14 @@ "type": "string" }, { - "textRaw": "`headers` {Object}", + "textRaw": "`headers` {Object|Array}", "name": "headers", - "type": "Object" + "type": "Object|Array" } ] } ], - "desc": "

      Sends a response header to the request. The status code is a 3-digit HTTP\nstatus code, like 404. The last argument, headers, are the response headers.\nOptionally one can give a human-readable statusMessage as the second\nargument.

      \n

      Returns a reference to the ServerResponse, so that calls can be chained.

      \n
      const body = 'hello world';\nresponse\n  .writeHead(200, {\n    'Content-Length': Buffer.byteLength(body),\n    'Content-Type': 'text/plain'\n  })\n  .end(body);\n
      \n

      This method must only be called once on a message and it must\nbe called before response.end() is called.

      \n

      If response.write() or response.end() are called before calling\nthis, the implicit/mutable headers will be calculated and call this function.

      \n

      When headers have been set with response.setHeader(), they will be merged\nwith any headers passed to response.writeHead(), with the headers passed\nto response.writeHead() given precedence.

      \n

      If this method is called and response.setHeader() has not been called,\nit will directly write the supplied header values onto the network channel\nwithout caching internally, and the response.getHeader() on the header\nwill not yield the expected result. If progressive population of headers is\ndesired with potential future retrieval and modification, use\nresponse.setHeader() instead.

      \n
      // Returns content-type = text/plain\nconst server = http.createServer((req, res) => {\n  res.setHeader('Content-Type', 'text/html');\n  res.setHeader('X-Foo', 'bar');\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end('ok');\n});\n
      \n

      Content-Length is given in bytes, not characters. Use\nBuffer.byteLength() to determine the length of the body in bytes. Node.js\ndoes not check whether Content-Length and the length of the body which has\nbeen transmitted are equal or not.

      \n

      Attempting to set a header field name or value that contains invalid characters\nwill result in a TypeError being thrown.

      " + "desc": "

      Sends a response header to the request. The status code is a 3-digit HTTP\nstatus code, like 404. The last argument, headers, are the response headers.\nOptionally one can give a human-readable statusMessage as the second\nargument.

      \n

      headers may be an Array where the keys and values are in the same list.\nIt is not a list of tuples. So, the even-numbered offsets are key values,\nand the odd-numbered offsets are the associated values. The array is in the same\nformat as request.rawHeaders.

      \n

      Returns a reference to the ServerResponse, so that calls can be chained.

      \n
      const body = 'hello world';\nresponse\n  .writeHead(200, {\n    'Content-Length': Buffer.byteLength(body),\n    'Content-Type': 'text/plain'\n  })\n  .end(body);\n
      \n

      This method must only be called once on a message and it must\nbe called before response.end() is called.

      \n

      If response.write() or response.end() are called before calling\nthis, the implicit/mutable headers will be calculated and call this function.

      \n

      When headers have been set with response.setHeader(), they will be merged\nwith any headers passed to response.writeHead(), with the headers passed\nto response.writeHead() given precedence.

      \n

      If this method is called and response.setHeader() has not been called,\nit will directly write the supplied header values onto the network channel\nwithout caching internally, and the response.getHeader() on the header\nwill not yield the expected result. If progressive population of headers is\ndesired with potential future retrieval and modification, use\nresponse.setHeader() instead.

      \n
      // Returns content-type = text/plain\nconst server = http.createServer((req, res) => {\n  res.setHeader('Content-Type', 'text/html');\n  res.setHeader('X-Foo', 'bar');\n  res.writeHead(200, { 'Content-Type': 'text/plain' });\n  res.end('ok');\n});\n
      \n

      Content-Length is given in bytes, not characters. Use\nBuffer.byteLength() to determine the length of the body in bytes. Node.js\ndoes not check whether Content-Length and the length of the body which has\nbeen transmitted are equal or not.

      \n

      Attempting to set a header field name or value that contains invalid characters\nwill result in a TypeError being thrown.

      " }, { "textRaw": "`response.writeProcessing()`", @@ -1806,8 +1933,13 @@ "added": [ "v0.3.0" ], + "deprecated": [ + "v13.0.0" + ], "changes": [] }, + "stability": 0, + "stabilityText": "Deprecated. Use [`response.socket`][].", "desc": "

      See response.socket.

      " }, { @@ -1819,6 +1951,7 @@ "v0.0.2" ], "deprecated": [ + "v13.4.0", "v12.16.0" ], "changes": [] @@ -1861,7 +1994,7 @@ ], "changes": [] }, - "desc": "

      Reference to the underlying socket. Usually users will not want to access\nthis property. In particular, the socket will not emit 'readable' events\nbecause of how the protocol parser attaches to the socket. After\nresponse.end(), the property is nulled. The socket may also be accessed\nvia response.connection.

      \n
      const http = require('http');\nconst server = http.createServer((req, res) => {\n  const ip = res.socket.remoteAddress;\n  const port = res.socket.remotePort;\n  res.end(`Your IP address is ${ip} and your source port is ${port}.`);\n}).listen(3000);\n
      \n

      This property is guaranteed to be an instance of the <net.Socket> class,\na subclass of <stream.Duplex>, unless the user specified a socket\ntype other than <net.Socket>.

      " + "desc": "

      Reference to the underlying socket. Usually users will not want to access\nthis property. In particular, the socket will not emit 'readable' events\nbecause of how the protocol parser attaches to the socket. After\nresponse.end(), the property is nulled.

      \n
      const http = require('http');\nconst server = http.createServer((req, res) => {\n  const ip = res.socket.remoteAddress;\n  const port = res.socket.remotePort;\n  res.end(`Your IP address is ${ip} and your source port is ${port}.`);\n}).listen(3000);\n
      \n

      This property is guaranteed to be an instance of the <net.Socket> class,\na subclass of <stream.Duplex>, unless the user specified a socket\ntype other than <net.Socket>.

      " }, { "textRaw": "`statusCode` {number} **Default:** `200`", @@ -1924,7 +2057,10 @@ ], "changes": [ { - "version": "v12.16.0", + "version": [ + "v13.1.0", + "v12.16.0" + ], "pr-url": "https://github.com/nodejs/node/pull/30135", "description": "The `readableHighWaterMark` value mirrors that of the socket." } @@ -2116,7 +2252,7 @@ ], "changes": [ { - "version": "v12.19.0", + "version": "v14.5.0", "pr-url": "https://github.com/nodejs/node/pull/32789", "description": "The function returns `this` for consistency with other Readable streams." } @@ -2171,128 +2307,708 @@ ] } ], - "desc": "

      Calls message.connection.setTimeout(msecs, callback).

      " + "desc": "

      Calls message.socket.setTimeout(msecs, callback).

      " } ] - } - ], - "properties": [ - { - "textRaw": "`METHODS` {string[]}", - "type": "string[]", - "name": "METHODS", - "meta": { - "added": [ - "v0.11.8" - ], - "changes": [] - }, - "desc": "

      A list of the HTTP methods that are supported by the parser.

      " - }, - { - "textRaw": "`STATUS_CODES` {Object}", - "type": "Object", - "name": "STATUS_CODES", - "meta": { - "added": [ - "v0.1.22" - ], - "changes": [] - }, - "desc": "

      A collection of all the standard HTTP response status codes, and the\nshort description of each. For example, http.STATUS_CODES[404] === 'Not Found'.

      " - }, - { - "textRaw": "`globalAgent` {http.Agent}", - "type": "http.Agent", - "name": "globalAgent", - "meta": { - "added": [ - "v0.5.9" - ], - "changes": [] - }, - "desc": "

      Global instance of Agent which is used as the default for all HTTP client\nrequests.

      " }, { - "textRaw": "`maxHeaderSize` {number}", - "type": "number", - "name": "maxHeaderSize", + "textRaw": "Class: `http.OutgoingMessage`", + "type": "class", + "name": "http.OutgoingMessage", "meta": { "added": [ - "v11.6.0" + "v0.1.17" ], "changes": [] }, - "desc": "

      Read-only property specifying the maximum allowed size of HTTP headers in bytes.\nDefaults to 8KB. Configurable using the --max-http-header-size CLI option.

      " - } - ], - "methods": [ - { - "textRaw": "`http.createServer([options][, requestListener])`", - "type": "method", - "name": "createServer", - "meta": { - "added": [ - "v0.1.13" - ], - "changes": [ - { - "version": "v12.15.0", - "pr-url": "https://github.com/nodejs/node/pull/31448", - "description": "The `insecureHTTPParser` option is supported now." + "desc": "\n

      This class serves as the parent class of http.ClientRequest\nand http.ServerResponse. It is an abstract of outgoing message from\nthe perspective of the participants of HTTP transaction.

      ", + "events": [ + { + "textRaw": "Event: `drain`", + "type": "event", + "name": "drain`", + "meta": { + "added": [ + "v0.3.6" + ], + "changes": [] }, - { - "version": "v9.6.0, v8.12.0", - "pr-url": "https://github.com/nodejs/node/pull/15752", - "description": "The `options` argument is supported now." - } - ] - }, - "signatures": [ + "params": [], + "desc": "

      Emitted when the buffer of the message is free again.

      " + }, { - "return": { - "textRaw": "Returns: {http.Server}", - "name": "return", - "type": "http.Server" + "textRaw": "Event: `finish`", + "type": "event", + "name": "finish`", + "meta": { + "added": [ + "v0.1.17" + ], + "changes": [] }, - "params": [ + "params": [], + "desc": "

      Emitted when the transmission is finished successfully.

      " + }, + { + "textRaw": "Event: `prefinish`", + "type": "event", + "name": "prefinish`", + "meta": { + "added": [ + "v0.11.6" + ], + "changes": [] + }, + "params": [], + "desc": "

      Emitted when outgoingMessage.end was called.\nWhen the event is emitted, all data has been processed but not necessarily\ncompletely flushed.

      " + } + ], + "methods": [ + { + "textRaw": "`outgoingMessage.addTrailers(headers)`", + "type": "method", + "name": "addTrailers", + "meta": { + "added": [ + "v0.3.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`options` {Object}", - "name": "options", - "type": "Object", - "options": [ - { - "textRaw": "`IncomingMessage` {http.IncomingMessage} Specifies the `IncomingMessage` class to be used. Useful for extending the original `IncomingMessage`. **Default:** `IncomingMessage`.", - "name": "IncomingMessage", - "type": "http.IncomingMessage", - "default": "`IncomingMessage`", - "desc": "Specifies the `IncomingMessage` class to be used. Useful for extending the original `IncomingMessage`." - }, - { - "textRaw": "`ServerResponse` {http.ServerResponse} Specifies the `ServerResponse` class to be used. Useful for extending the original `ServerResponse`. **Default:** `ServerResponse`.", - "name": "ServerResponse", - "type": "http.ServerResponse", - "default": "`ServerResponse`", - "desc": "Specifies the `ServerResponse` class to be used. Useful for extending the original `ServerResponse`." - }, + "params": [ { - "textRaw": "`insecureHTTPParser` {boolean} Use an insecure HTTP parser that accepts invalid HTTP headers when `true`. Using the insecure parser should be avoided. See [`--insecure-http-parser`][] for more information. **Default:** `false`", - "name": "insecureHTTPParser", - "type": "boolean", - "default": "`false`", - "desc": "Use an insecure HTTP parser that accepts invalid HTTP headers when `true`. Using the insecure parser should be avoided. See [`--insecure-http-parser`][] for more information." + "textRaw": "`headers` {Object}", + "name": "headers", + "type": "Object" } ] - }, + } + ], + "desc": "

      Adds HTTP trailers (headers but at the end of the message) to the message.

      \n

      Trailers are only be emitted if the message is chunked encoded. If not,\nthe trailer will be silently discarded.

      \n

      HTTP requires the Trailer header to be sent to emit trailers,\nwith a list of header fields in its value, e.g.

      \n
      message.writeHead(200, { 'Content-Type': 'text/plain',\n                         'Trailer': 'Content-MD5' });\nmessage.write(fileData);\nmessage.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' });\nmessage.end();\n
      \n

      Attempting to set a header field name or value that contains invalid characters\nwill result in a TypeError being thrown.

      " + }, + { + "textRaw": "`outgoingMessage.cork()`", + "type": "method", + "name": "cork", + "meta": { + "added": [ + "v14.0.0" + ], + "changes": [] + }, + "signatures": [ { - "textRaw": "`requestListener` {Function}", - "name": "requestListener", - "type": "Function" + "params": [] } - ] - } - ], - "desc": "

      Returns a new instance of http.Server.

      \n

      The requestListener is a function which is automatically\nadded to the 'request' event.

      " + ], + "desc": "

      See writable.cork().

      " + }, + { + "textRaw": "`outgoingMessage.destroy([error])`", + "type": "method", + "name": "destroy", + "meta": { + "added": [ + "v0.3.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {this}", + "name": "return", + "type": "this" + }, + "params": [ + { + "textRaw": "`error` {Error} Optional, an error to emit with `error` event", + "name": "error", + "type": "Error", + "desc": "Optional, an error to emit with `error` event" + } + ] + } + ], + "desc": "

      Destroys the message. Once a socket is associated with the message\nand is connected, that socket will be destroyed as well.

      " + }, + { + "textRaw": "`outgoingMessage.end(chunk[, encoding][, callback])`", + "type": "method", + "name": "end", + "meta": { + "added": [ + "v0.1.90" + ], + "changes": [ + { + "version": "v0.11.6", + "description": "add `callback` argument." + } + ] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {this}", + "name": "return", + "type": "this" + }, + "params": [ + { + "textRaw": "`chunk` {string | Buffer}", + "name": "chunk", + "type": "string | Buffer" + }, + { + "textRaw": "`encoding` {string} Optional, **Default**: `utf-8`", + "name": "encoding", + "type": "string", + "desc": "Optional, **Default**: `utf-8`" + }, + { + "textRaw": "`callback` {Function} Optional", + "name": "callback", + "type": "Function", + "desc": "Optional" + } + ] + } + ], + "desc": "

      Finishes the outgoing message. If any parts of the body are unsent, it will\nflush them to the underlying system. If the message is chunked, it will\nsend the terminating chunk 0\\r\\n\\r\\n, and send the trailer (if any).

      \n

      If chunk is specified, it is equivalent to call\noutgoingMessage.write(chunk, encoding), followed by\noutgoingMessage.end(callback).

      \n

      If callback is provided, it will be called when the message is finished.\n(equivalent to the callback to event finish)

      " + }, + { + "textRaw": "`outgoingMessage.flushHeaders()`", + "type": "method", + "name": "flushHeaders", + "meta": { + "added": [ + "v1.6.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      Compulsorily flushes the message headers

      \n

      For efficiency reason, Node.js normally buffers the message headers\nuntil outgoingMessage.end() is called or the first chunk of message data\nis written. It then tries to pack the headers and data into a single TCP\npacket.

      \n

      It is usually desired (it saves a TCP round-trip), but not when the first\ndata is not sent until possibly much later. outgoingMessage.flushHeaders()\nbypasses the optimization and kickstarts the request.

      " + }, + { + "textRaw": "`outgoingMessage.getHeader(name)`", + "type": "method", + "name": "getHeader", + "meta": { + "added": [ + "v0.4.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns {string | undefined}", + "name": "return", + "type": "string | undefined" + }, + "params": [ + { + "textRaw": "`name` {string} Name of header", + "name": "name", + "type": "string", + "desc": "Name of header" + } + ] + } + ], + "desc": "

      Gets the value of HTTP header with the given name. If such a name doesn't\nexist in message, it will be undefined.

      " + }, + { + "textRaw": "`outgoingMessage.getHeaderNames()`", + "type": "method", + "name": "getHeaderNames", + "meta": { + "added": [ + "v8.0.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns {string[]}", + "name": "return", + "type": "string[]" + }, + "params": [] + } + ], + "desc": "

      Returns an array of names of headers of the outgoing outgoingMessage. All\nnames are lowercase.

      " + }, + { + "textRaw": "`outgoingMessage.getHeaders()`", + "type": "method", + "name": "getHeaders", + "meta": { + "added": [ + "v8.0.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {Object}", + "name": "return", + "type": "Object" + }, + "params": [] + } + ], + "desc": "

      Returns a shallow copy of the current outgoing headers. Since a shallow\ncopy is used, array values may be mutated without additional calls to\nvarious header-related HTTP module methods. The keys of the returned\nobject are the header names and the values are the respective header\nvalues. All header names are lowercase.

      \n

      The object returned by the outgoingMessage.getHeaders() method does\nnot prototypically inherit from the JavaScript Object. This means that\ntypical Object methods such as obj.toString(), obj.hasOwnProperty(),\nand others are not defined and will not work.

      \n
      outgoingMessage.setHeader('Foo', 'bar');\noutgoingMessage.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);\n\nconst headers = outgoingMessage.getHeaders();\n// headers === { foo: 'bar', 'set-cookie': ['foo=bar', 'bar=baz'] }\n
      " + }, + { + "textRaw": "`outgoingMessage.hasHeader(name)`", + "type": "method", + "name": "hasHeader", + "meta": { + "added": [ + "v8.0.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [ + { + "textRaw": "`name` {string}", + "name": "name", + "type": "string" + } + ] + } + ], + "desc": "

      Returns true if the header identified by name is currently set in the\noutgoing headers. The header name is case-insensitive.

      \n
      const hasContentType = outgoingMessage.hasHeader('content-type');\n
      " + }, + { + "textRaw": "`outgoingMessage.pipe()`", + "type": "method", + "name": "pipe", + "meta": { + "added": [ + "v9.0.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      Overrides the pipe method of legacy Stream which is the parent class of\nhttp.outgoingMessage.

      \n

      Since OutgoingMessage should be a write-only stream,\ncall this function will throw an Error. Thus, it disabled the pipe method\nit inherits from Stream.

      \n

      The User should not call this function directly.

      " + }, + { + "textRaw": "`outgoingMessage.removeHeader()`", + "type": "method", + "name": "removeHeader", + "meta": { + "added": [ + "v0.4.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      Removes a header that is queued for implicit sending.

      \n
      outgoingMessage.removeHeader('Content-Encoding');\n
      " + }, + { + "textRaw": "`outgoingMessage.setHeader(name, value)`", + "type": "method", + "name": "setHeader", + "meta": { + "added": [ + "v0.4.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {this}", + "name": "return", + "type": "this" + }, + "params": [ + { + "textRaw": "`name` {string} Header name", + "name": "name", + "type": "string", + "desc": "Header name" + }, + { + "textRaw": "`value` {string} Header value", + "name": "value", + "type": "string", + "desc": "Header value" + } + ] + } + ], + "desc": "

      Sets a single header value for the header object.

      " + }, + { + "textRaw": "`outgoingMessage.setTimeout(msesc[, callback])`", + "type": "method", + "name": "setTimeout", + "meta": { + "added": [ + "v0.9.12" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`msesc` {number}", + "name": "msesc", + "type": "number" + }, + { + "textRaw": "`callback` {Function} Optional function to be called when a timeout", + "name": "callback", + "type": "Function", + "desc": "Optional function to be called when a timeout" + } + ] + } + ], + "desc": "

      occurs, Same as binding to the timeout event.

      \n\n

      Once a socket is associated with the message and is connected,\nsocket.setTimeout() will be called with msecs as the first parameter.

      " + }, + { + "textRaw": "`outgoingMessage.uncork()`", + "type": "method", + "name": "uncork", + "meta": { + "added": [ + "v14.0.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [] + } + ], + "desc": "

      See writable.uncork()

      " + }, + { + "textRaw": "`outgoingMessage.write(chunk[, encoding][, callback])`", + "type": "method", + "name": "write", + "meta": { + "added": [ + "v0.1.29" + ], + "changes": [ + { + "version": "v0.11.6", + "description": "add `callback` argument." + } + ] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [ + { + "textRaw": "`chunk` {string | Buffer}", + "name": "chunk", + "type": "string | Buffer" + }, + { + "textRaw": "`encoding` {string} **Default**: `utf-8`", + "name": "encoding", + "type": "string", + "desc": "**Default**: `utf-8`" + }, + { + "textRaw": "`callback` {Function}", + "name": "callback", + "type": "Function" + } + ] + } + ], + "desc": "

      If this method is called and the header is not sent, it will call\nthis._implicitHeader to flush implicit header.\nIf the message should not have a body (indicated by this._hasBody),\nthe call is ignored and chunk will not be sent. It could be useful\nwhen handling a particular message which must not include a body.\ne.g. response to HEAD request, 204 and 304 response.

      \n

      chunk can be a string or a buffer. When chunk is a string, the\nencoding parameter specifies how to encode chunk into a byte stream.\ncallback will be called when the chunk is flushed.

      \n

      If the message is transferred in chucked encoding\n(indicated by this.chunkedEncoding), chunk will be flushed as\none chunk among a stream of chunks. Otherwise, it will be flushed as the\nbody of message.

      \n

      This method handles the raw body of the HTTP message and has nothing to do\nwith higher-level multi-part body encodings that may be used.

      \n

      If it is the first call to this method of a message, it will send the\nbuffered header first, then flush the chunk as described above.

      \n

      The second and successive calls to this method will assume the data\nwill be streamed and send the new data separately. It means that the response\nis buffered up to the first chunk of the body.

      \n

      Returns true if the entire data was flushed successfully to the kernel\nbuffer. Returns false if all or part of the data was queued in the user\nmemory. Event drain will be emitted when the buffer is free again.

      " + } + ], + "properties": [ + { + "textRaw": "`outgoingMessage.connection`", + "name": "connection", + "meta": { + "added": [ + "v0.3.0" + ], + "deprecated": [ + "v14.17.1" + ], + "changes": [] + }, + "stability": 0, + "stabilityText": "Deprecated: Use [`outgoingMessage.socket`][] instead.", + "desc": "

      Aliases of outgoingMessage.socket

      " + }, + { + "textRaw": "`headersSent` {boolean}", + "type": "boolean", + "name": "headersSent", + "meta": { + "added": [ + "v0.9.3" + ], + "changes": [] + }, + "desc": "

      Read-only. true if the headers were sent, otherwise false.

      " + }, + { + "textRaw": "`socket` {stream.Duplex}", + "type": "stream.Duplex", + "name": "socket", + "meta": { + "added": [ + "v0.3.0" + ], + "changes": [] + }, + "desc": "

      Reference to the underlying socket. Usually, users will not want to access\nthis property.

      \n

      After calling outgoingMessage.end(), this property will be nulled.

      " + }, + { + "textRaw": "`writableCorked` {number}", + "type": "number", + "name": "writableCorked", + "meta": { + "added": [ + "v14.0.0" + ], + "changes": [] + }, + "desc": "

      This outgoingMessage.writableCorked will return the time how many\noutgoingMessage.cork() have been called.

      " + }, + { + "textRaw": "`writableEnded` {boolean}", + "type": "boolean", + "name": "writableEnded", + "meta": { + "added": [ + "v13.0.0" + ], + "changes": [] + }, + "desc": "

      Readonly, true if outgoingMessage.end() has been called. Noted that\nthis property does not reflect whether the data has been flush. For that\npurpose, use message.writableFinished instead.

      " + }, + { + "textRaw": "`writableFinished` {boolean}", + "type": "boolean", + "name": "writableFinished", + "meta": { + "added": [ + "v13.0.0" + ], + "changes": [] + }, + "desc": "

      Readonly. true if all data has been flushed to the underlying system.

      " + }, + { + "textRaw": "`writableHighWaterMark` {number}", + "type": "number", + "name": "writableHighWaterMark", + "meta": { + "added": [ + "v13.0.0" + ], + "changes": [] + }, + "desc": "

      This outgoingMessage.writableHighWaterMark will be the highWaterMark of\nunderlying socket if socket exists. Else, it would be the default\nhighWaterMark.

      \n

      highWaterMark is the maximum amount of data that can be potentially\nbuffered by the socket.

      " + }, + { + "textRaw": "`writableLength` {number}", + "type": "number", + "name": "writableLength", + "meta": { + "added": [ + "v13.0.0" + ], + "changes": [] + }, + "desc": "

      Readonly, This outgoingMessage.writableLength contains the number of\nbytes (or objects) in the buffer ready to send.

      " + }, + { + "textRaw": "`writableObjectMode` {boolean}", + "type": "boolean", + "name": "writableObjectMode", + "meta": { + "added": [ + "v13.0.0" + ], + "changes": [] + }, + "desc": "

      Readonly, always returns false.

      " + } + ] + } + ], + "properties": [ + { + "textRaw": "`METHODS` {string[]}", + "type": "string[]", + "name": "METHODS", + "meta": { + "added": [ + "v0.11.8" + ], + "changes": [] + }, + "desc": "

      A list of the HTTP methods that are supported by the parser.

      " + }, + { + "textRaw": "`STATUS_CODES` {Object}", + "type": "Object", + "name": "STATUS_CODES", + "meta": { + "added": [ + "v0.1.22" + ], + "changes": [] + }, + "desc": "

      A collection of all the standard HTTP response status codes, and the\nshort description of each. For example, http.STATUS_CODES[404] === 'Not Found'.

      " + }, + { + "textRaw": "`globalAgent` {http.Agent}", + "type": "http.Agent", + "name": "globalAgent", + "meta": { + "added": [ + "v0.5.9" + ], + "changes": [] + }, + "desc": "

      Global instance of Agent which is used as the default for all HTTP client\nrequests.

      " + }, + { + "textRaw": "`maxHeaderSize` {number}", + "type": "number", + "name": "maxHeaderSize", + "meta": { + "added": [ + "v11.6.0", + "v10.15.0" + ], + "changes": [] + }, + "desc": "

      Read-only property specifying the maximum allowed size of HTTP headers in bytes.\nDefaults to 8KB. Configurable using the --max-http-header-size CLI option.

      \n

      This can be overridden for servers and client requests by passing the\nmaxHeaderSize option.

      " + } + ], + "methods": [ + { + "textRaw": "`http.createServer([options][, requestListener])`", + "type": "method", + "name": "createServer", + "meta": { + "added": [ + "v0.1.13" + ], + "changes": [ + { + "version": [ + "v13.8.0", + "v12.15.0", + "v10.19.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/31448", + "description": "The `insecureHTTPParser` option is supported now." + }, + { + "version": "v13.3.0", + "pr-url": "https://github.com/nodejs/node/pull/30570", + "description": "The `maxHeaderSize` option is supported now." + }, + { + "version": [ + "v9.6.0", + "v8.12.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/15752", + "description": "The `options` argument is supported now." + } + ] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {http.Server}", + "name": "return", + "type": "http.Server" + }, + "params": [ + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`IncomingMessage` {http.IncomingMessage} Specifies the `IncomingMessage` class to be used. Useful for extending the original `IncomingMessage`. **Default:** `IncomingMessage`.", + "name": "IncomingMessage", + "type": "http.IncomingMessage", + "default": "`IncomingMessage`", + "desc": "Specifies the `IncomingMessage` class to be used. Useful for extending the original `IncomingMessage`." + }, + { + "textRaw": "`ServerResponse` {http.ServerResponse} Specifies the `ServerResponse` class to be used. Useful for extending the original `ServerResponse`. **Default:** `ServerResponse`.", + "name": "ServerResponse", + "type": "http.ServerResponse", + "default": "`ServerResponse`", + "desc": "Specifies the `ServerResponse` class to be used. Useful for extending the original `ServerResponse`." + }, + { + "textRaw": "`insecureHTTPParser` {boolean} Use an insecure HTTP parser that accepts invalid HTTP headers when `true`. Using the insecure parser should be avoided. See [`--insecure-http-parser`][] for more information. **Default:** `false`", + "name": "insecureHTTPParser", + "type": "boolean", + "default": "`false`", + "desc": "Use an insecure HTTP parser that accepts invalid HTTP headers when `true`. Using the insecure parser should be avoided. See [`--insecure-http-parser`][] for more information." + }, + { + "textRaw": "`maxHeaderSize` {number} Optionally overrides the value of [`--max-http-header-size`][] for requests received by this server, i.e. the maximum length of request headers in bytes. **Default:** 16384 (16KB).", + "name": "maxHeaderSize", + "type": "number", + "default": "16384 (16KB)", + "desc": "Optionally overrides the value of [`--max-http-header-size`][] for requests received by this server, i.e. the maximum length of request headers in bytes." + } + ] + }, + { + "textRaw": "`requestListener` {Function}", + "name": "requestListener", + "type": "Function" + } + ] + } + ], + "desc": "

      Returns a new instance of http.Server.

      \n

      The requestListener is a function which is automatically\nadded to the 'request' event.

      \n
      const http = require('http');\n\n// Create a local server to receive data from\nconst server = http.createServer((req, res) => {\n  res.writeHead(200, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify({\n    data: 'Hello World!'\n  }));\n});\n\nserver.listen(8000);\n
      \n
      const http = require('http');\n\n// Create a local server to receive data from\nconst server = http.createServer();\n\n// Listen to the request event\nserver.on('request', (request, res) => {\n  res.writeHead(200, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify({\n    data: 'Hello World!'\n  }));\n});\n\nserver.listen(8000);\n
      " }, { "textRaw": "`http.get(options[, callback])`", @@ -2342,7 +3058,7 @@ ] } ], - "desc": "

      Since most requests are GET requests without bodies, Node.js provides this\nconvenience method. The only difference between this method and\nhttp.request() is that it sets the method to GET and calls req.end()\nautomatically. The callback must take care to consume the response\ndata for reasons stated in http.ClientRequest section.

      \n

      The callback is invoked with a single argument that is an instance of\nhttp.IncomingMessage.

      \n

      JSON fetching example:

      \n
      http.get('http://nodejs.org/dist/index.json', (res) => {\n  const { statusCode } = res;\n  const contentType = res.headers['content-type'];\n\n  let error;\n  // Any 2xx status code signals a successful response but\n  // here we're only checking for 200.\n  if (statusCode !== 200) {\n    error = new Error('Request Failed.\\n' +\n                      `Status Code: ${statusCode}`);\n  } else if (!/^application\\/json/.test(contentType)) {\n    error = new Error('Invalid content-type.\\n' +\n                      `Expected application/json but received ${contentType}`);\n  }\n  if (error) {\n    console.error(error.message);\n    // Consume response data to free up memory\n    res.resume();\n    return;\n  }\n\n  res.setEncoding('utf8');\n  let rawData = '';\n  res.on('data', (chunk) => { rawData += chunk; });\n  res.on('end', () => {\n    try {\n      const parsedData = JSON.parse(rawData);\n      console.log(parsedData);\n    } catch (e) {\n      console.error(e.message);\n    }\n  });\n}).on('error', (e) => {\n  console.error(`Got error: ${e.message}`);\n});\n
      " + "desc": "

      Since most requests are GET requests without bodies, Node.js provides this\nconvenience method. The only difference between this method and\nhttp.request() is that it sets the method to GET and calls req.end()\nautomatically. The callback must take care to consume the response\ndata for reasons stated in http.ClientRequest section.

      \n

      The callback is invoked with a single argument that is an instance of\nhttp.IncomingMessage.

      \n

      JSON fetching example:

      \n
      http.get('http://localhost:8000/', (res) => {\n  const { statusCode } = res;\n  const contentType = res.headers['content-type'];\n\n  let error;\n  // Any 2xx status code signals a successful response but\n  // here we're only checking for 200.\n  if (statusCode !== 200) {\n    error = new Error('Request Failed.\\n' +\n                      `Status Code: ${statusCode}`);\n  } else if (!/^application\\/json/.test(contentType)) {\n    error = new Error('Invalid content-type.\\n' +\n                      `Expected application/json but received ${contentType}`);\n  }\n  if (error) {\n    console.error(error.message);\n    // Consume response data to free up memory\n    res.resume();\n    return;\n  }\n\n  res.setEncoding('utf8');\n  let rawData = '';\n  res.on('data', (chunk) => { rawData += chunk; });\n  res.on('end', () => {\n    try {\n      const parsedData = JSON.parse(rawData);\n      console.log(parsedData);\n    } catch (e) {\n      console.error(e.message);\n    }\n  });\n}).on('error', (e) => {\n  console.error(`Got error: ${e.message}`);\n});\n\n// Create a local server to receive data from\nconst server = http.createServer((req, res) => {\n  res.writeHead(200, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify({\n    data: 'Hello World!'\n  }));\n});\n\nserver.listen(8000);\n
      " }, { "textRaw": "`http.get(url[, options][, callback])`", @@ -2392,7 +3108,7 @@ ] } ], - "desc": "

      Since most requests are GET requests without bodies, Node.js provides this\nconvenience method. The only difference between this method and\nhttp.request() is that it sets the method to GET and calls req.end()\nautomatically. The callback must take care to consume the response\ndata for reasons stated in http.ClientRequest section.

      \n

      The callback is invoked with a single argument that is an instance of\nhttp.IncomingMessage.

      \n

      JSON fetching example:

      \n
      http.get('http://nodejs.org/dist/index.json', (res) => {\n  const { statusCode } = res;\n  const contentType = res.headers['content-type'];\n\n  let error;\n  // Any 2xx status code signals a successful response but\n  // here we're only checking for 200.\n  if (statusCode !== 200) {\n    error = new Error('Request Failed.\\n' +\n                      `Status Code: ${statusCode}`);\n  } else if (!/^application\\/json/.test(contentType)) {\n    error = new Error('Invalid content-type.\\n' +\n                      `Expected application/json but received ${contentType}`);\n  }\n  if (error) {\n    console.error(error.message);\n    // Consume response data to free up memory\n    res.resume();\n    return;\n  }\n\n  res.setEncoding('utf8');\n  let rawData = '';\n  res.on('data', (chunk) => { rawData += chunk; });\n  res.on('end', () => {\n    try {\n      const parsedData = JSON.parse(rawData);\n      console.log(parsedData);\n    } catch (e) {\n      console.error(e.message);\n    }\n  });\n}).on('error', (e) => {\n  console.error(`Got error: ${e.message}`);\n});\n
      " + "desc": "

      Since most requests are GET requests without bodies, Node.js provides this\nconvenience method. The only difference between this method and\nhttp.request() is that it sets the method to GET and calls req.end()\nautomatically. The callback must take care to consume the response\ndata for reasons stated in http.ClientRequest section.

      \n

      The callback is invoked with a single argument that is an instance of\nhttp.IncomingMessage.

      \n

      JSON fetching example:

      \n
      http.get('http://localhost:8000/', (res) => {\n  const { statusCode } = res;\n  const contentType = res.headers['content-type'];\n\n  let error;\n  // Any 2xx status code signals a successful response but\n  // here we're only checking for 200.\n  if (statusCode !== 200) {\n    error = new Error('Request Failed.\\n' +\n                      `Status Code: ${statusCode}`);\n  } else if (!/^application\\/json/.test(contentType)) {\n    error = new Error('Invalid content-type.\\n' +\n                      `Expected application/json but received ${contentType}`);\n  }\n  if (error) {\n    console.error(error.message);\n    // Consume response data to free up memory\n    res.resume();\n    return;\n  }\n\n  res.setEncoding('utf8');\n  let rawData = '';\n  res.on('data', (chunk) => { rawData += chunk; });\n  res.on('end', () => {\n    try {\n      const parsedData = JSON.parse(rawData);\n      console.log(parsedData);\n    } catch (e) {\n      console.error(e.message);\n    }\n  });\n}).on('error', (e) => {\n  console.error(`Got error: ${e.message}`);\n});\n\n// Create a local server to receive data from\nconst server = http.createServer((req, res) => {\n  res.writeHead(200, { 'Content-Type': 'application/json' });\n  res.end(JSON.stringify({\n    data: 'Hello World!'\n  }));\n});\n\nserver.listen(8000);\n
      " }, { "textRaw": "`http.request(options[, callback])`", @@ -2404,10 +3120,29 @@ ], "changes": [ { - "version": "v12.15.0", + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/39310", + "description": "When using a `URL` object parsed username and password will now be properly URI decoded." + }, + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/36048", + "description": "It is possible to abort a request with an AbortSignal." + }, + { + "version": [ + "v13.8.0", + "v12.15.0", + "v10.19.0" + ], "pr-url": "https://github.com/nodejs/node/pull/31448", "description": "The `insecureHTTPParser` option is supported now." }, + { + "version": "v13.3.0", + "pr-url": "https://github.com/nodejs/node/pull/30570", + "description": "The `maxHeaderSize` option is supported now." + }, { "version": "v10.9.0", "pr-url": "https://github.com/nodejs/node/pull/21616", @@ -2492,6 +3227,12 @@ "type": "Object", "desc": "An object containing request headers." }, + { + "textRaw": "`hints` {number} Optional [`dns.lookup()` hints][].", + "name": "hints", + "type": "number", + "desc": "Optional [`dns.lookup()` hints][]." + }, { "textRaw": "`host` {string} A domain name or IP address of the server to issue the request to. **Default:** `'localhost'`.", "name": "host", @@ -2518,6 +3259,12 @@ "type": "string", "desc": "Local interface to bind for network connections." }, + { + "textRaw": "`localPort` {number} Local port to connect from.", + "name": "localPort", + "type": "number", + "desc": "Local port to connect from." + }, { "textRaw": "`lookup` {Function} Custom lookup function. **Default:** [`dns.lookup()`][].", "name": "lookup", @@ -2525,6 +3272,13 @@ "default": "[`dns.lookup()`][]", "desc": "Custom lookup function." }, + { + "textRaw": "`maxHeaderSize` {number} Optionally overrides the value of [`--max-http-header-size`][] for requests received from the server, i.e. the maximum length of response headers in bytes. **Default:** 16384 (16KB).", + "name": "maxHeaderSize", + "type": "number", + "default": "16384 (16KB)", + "desc": "Optionally overrides the value of [`--max-http-header-size`][] for requests received from the server, i.e. the maximum length of response headers in bytes." + }, { "textRaw": "`method` {string} A string specifying the HTTP request method. **Default:** `'GET'`.", "name": "method", @@ -2570,6 +3324,12 @@ "name": "timeout", "type": "number", "desc": ": A number specifying the socket timeout in milliseconds. This will set the timeout before the socket is connected." + }, + { + "textRaw": "`signal` {AbortSignal}: An AbortSignal that may be used to abort an ongoing request.", + "name": "signal", + "type": "AbortSignal", + "desc": ": An AbortSignal that may be used to abort an ongoing request." } ] }, @@ -2581,7 +3341,7 @@ ] } ], - "desc": "

      Node.js maintains several connections per server to make HTTP requests.\nThis function allows one to transparently issue requests.

      \n

      url can be a string or a URL object. If url is a\nstring, it is automatically parsed with new URL(). If it is a URL\nobject, it will be automatically converted to an ordinary options object.

      \n

      If both url and options are specified, the objects are merged, with the\noptions properties taking precedence.

      \n

      The optional callback parameter will be added as a one-time listener for\nthe 'response' event.

      \n

      http.request() returns an instance of the http.ClientRequest\nclass. The ClientRequest instance is a writable stream. If one needs to\nupload a file with a POST request, then write to the ClientRequest object.

      \n
      const postData = querystring.stringify({\n  'msg': 'Hello World!'\n});\n\nconst options = {\n  hostname: 'www.google.com',\n  port: 80,\n  path: '/upload',\n  method: 'POST',\n  headers: {\n    'Content-Type': 'application/x-www-form-urlencoded',\n    'Content-Length': Buffer.byteLength(postData)\n  }\n};\n\nconst req = http.request(options, (res) => {\n  console.log(`STATUS: ${res.statusCode}`);\n  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);\n  res.setEncoding('utf8');\n  res.on('data', (chunk) => {\n    console.log(`BODY: ${chunk}`);\n  });\n  res.on('end', () => {\n    console.log('No more data in response.');\n  });\n});\n\nreq.on('error', (e) => {\n  console.error(`problem with request: ${e.message}`);\n});\n\n// Write data to request body\nreq.write(postData);\nreq.end();\n
      \n

      In the example req.end() was called. With http.request() one\nmust always call req.end() to signify the end of the request -\neven if there is no data being written to the request body.

      \n

      If any error is encountered during the request (be that with DNS resolution,\nTCP level errors, or actual HTTP parse errors) an 'error' event is emitted\non the returned request object. As with all 'error' events, if no listeners\nare registered the error will be thrown.

      \n

      There are a few special headers that should be noted.

      \n
        \n
      • \n

        Sending a 'Connection: keep-alive' will notify Node.js that the connection to\nthe server should be persisted until the next request.

        \n
      • \n
      • \n

        Sending a 'Content-Length' header will disable the default chunked encoding.

        \n
      • \n
      • \n

        Sending an 'Expect' header will immediately send the request headers.\nUsually, when sending 'Expect: 100-continue', both a timeout and a listener\nfor the 'continue' event should be set. See RFC 2616 Section 8.2.3 for more\ninformation.

        \n
      • \n
      • \n

        Sending an Authorization header will override using the auth option\nto compute basic authentication.

        \n
      • \n
      \n

      Example using a URL as options:

      \n
      const options = new URL('http://abc:xyz@example.com');\n\nconst req = http.request(options, (res) => {\n  // ...\n});\n
      \n

      In a successful request, the following events will be emitted in the following\norder:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object\n('data' will not be emitted at all if the response body is empty, for\ninstance, in most redirects)
        • \n
        • 'end' on the res object
        • \n
        \n
      • \n
      • 'close'
      • \n
      \n

      In the case of a connection error, the following events will be emitted:

      \n
        \n
      • 'socket'
      • \n
      • 'error'
      • \n
      • 'close'
      • \n
      \n

      If req.abort() is called before the connection succeeds, the following events\nwill be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • (req.abort() called here)
      • \n
      • 'abort'
      • \n
      • 'error' with an error with message 'Error: socket hang up' and code\n'ECONNRESET'
      • \n
      • 'close'
      • \n
      \n

      If req.abort() is called after the response is received, the following events\nwill be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object
        • \n
        \n
      • \n
      • (req.abort() called here)
      • \n
      • 'abort'
      • \n
      • 'aborted' on the res object
      • \n
      • 'close'
      • \n
      • 'end' on the res object
      • \n
      • 'close' on the res object
      • \n
      \n

      Setting the timeout option or using the setTimeout() function will\nnot abort the request or do anything besides add a 'timeout' event.

      " + "desc": "

      Node.js maintains several connections per server to make HTTP requests.\nThis function allows one to transparently issue requests.

      \n

      url can be a string or a URL object. If url is a\nstring, it is automatically parsed with new URL(). If it is a URL\nobject, it will be automatically converted to an ordinary options object.

      \n

      If both url and options are specified, the objects are merged, with the\noptions properties taking precedence.

      \n

      The optional callback parameter will be added as a one-time listener for\nthe 'response' event.

      \n

      http.request() returns an instance of the http.ClientRequest\nclass. The ClientRequest instance is a writable stream. If one needs to\nupload a file with a POST request, then write to the ClientRequest object.

      \n
      const http = require('http');\n\nconst postData = JSON.stringify({\n  'msg': 'Hello World!'\n});\n\nconst options = {\n  hostname: 'www.google.com',\n  port: 80,\n  path: '/upload',\n  method: 'POST',\n  headers: {\n    'Content-Type': 'application/json',\n    'Content-Length': Buffer.byteLength(postData)\n  }\n};\n\nconst req = http.request(options, (res) => {\n  console.log(`STATUS: ${res.statusCode}`);\n  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);\n  res.setEncoding('utf8');\n  res.on('data', (chunk) => {\n    console.log(`BODY: ${chunk}`);\n  });\n  res.on('end', () => {\n    console.log('No more data in response.');\n  });\n});\n\nreq.on('error', (e) => {\n  console.error(`problem with request: ${e.message}`);\n});\n\n// Write data to request body\nreq.write(postData);\nreq.end();\n
      \n

      In the example req.end() was called. With http.request() one\nmust always call req.end() to signify the end of the request -\neven if there is no data being written to the request body.

      \n

      If any error is encountered during the request (be that with DNS resolution,\nTCP level errors, or actual HTTP parse errors) an 'error' event is emitted\non the returned request object. As with all 'error' events, if no listeners\nare registered the error will be thrown.

      \n

      There are a few special headers that should be noted.

      \n
        \n
      • \n

        Sending a 'Connection: keep-alive' will notify Node.js that the connection to\nthe server should be persisted until the next request.

        \n
      • \n
      • \n

        Sending a 'Content-Length' header will disable the default chunked encoding.

        \n
      • \n
      • \n

        Sending an 'Expect' header will immediately send the request headers.\nUsually, when sending 'Expect: 100-continue', both a timeout and a listener\nfor the 'continue' event should be set. See RFC 2616 Section 8.2.3 for more\ninformation.

        \n
      • \n
      • \n

        Sending an Authorization header will override using the auth option\nto compute basic authentication.

        \n
      • \n
      \n

      Example using a URL as options:

      \n
      const options = new URL('http://abc:xyz@example.com');\n\nconst req = http.request(options, (res) => {\n  // ...\n});\n
      \n

      In a successful request, the following events will be emitted in the following\norder:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object\n('data' will not be emitted at all if the response body is empty, for\ninstance, in most redirects)
        • \n
        • 'end' on the res object
        • \n
        \n
      • \n
      • 'close'
      • \n
      \n

      In the case of a connection error, the following events will be emitted:

      \n
        \n
      • 'socket'
      • \n
      • 'error'
      • \n
      • 'close'
      • \n
      \n

      In the case of a premature connection close before the response is received,\nthe following events will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • 'error' with an error with message 'Error: socket hang up' and code\n'ECONNRESET'
      • \n
      • 'close'
      • \n
      \n

      In the case of a premature connection close after the response is received,\nthe following events will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object
        • \n
        \n
      • \n
      • (connection closed here)
      • \n
      • 'aborted' on the res object
      • \n
      • 'close'
      • \n
      • 'close' on the res object
      • \n
      \n

      If req.destroy() is called before a socket is assigned, the following\nevents will be emitted in the following order:

      \n
        \n
      • (req.destroy() called here)
      • \n
      • 'error' with an error with message 'Error: socket hang up' and code\n'ECONNRESET'
      • \n
      • 'close'
      • \n
      \n

      If req.destroy() is called before the connection succeeds, the following\nevents will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • (req.destroy() called here)
      • \n
      • 'error' with an error with message 'Error: socket hang up' and code\n'ECONNRESET'
      • \n
      • 'close'
      • \n
      \n

      If req.destroy() is called after the response is received, the following\nevents will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object
        • \n
        \n
      • \n
      • (req.destroy() called here)
      • \n
      • 'aborted' on the res object
      • \n
      • 'close'
      • \n
      • 'close' on the res object
      • \n
      \n

      If req.abort() is called before a socket is assigned, the following\nevents will be emitted in the following order:

      \n
        \n
      • (req.abort() called here)
      • \n
      • 'abort'
      • \n
      • 'close'
      • \n
      \n

      If req.abort() is called before the connection succeeds, the following\nevents will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • (req.abort() called here)
      • \n
      • 'abort'
      • \n
      • 'error' with an error with message 'Error: socket hang up' and code\n'ECONNRESET'
      • \n
      • 'close'
      • \n
      \n

      If req.abort() is called after the response is received, the following\nevents will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object
        • \n
        \n
      • \n
      • (req.abort() called here)
      • \n
      • 'abort'
      • \n
      • 'aborted' on the res object
      • \n
      • 'close'
      • \n
      • 'close' on the res object
      • \n
      \n

      Setting the timeout option or using the setTimeout() function will\nnot abort the request or do anything besides add a 'timeout' event.

      \n

      Passing an AbortSignal and then calling abort on the corresponding\nAbortController will behave the same way as calling .destroy() on the\nrequest itself.

      " }, { "textRaw": "`http.request(url[, options][, callback])`", @@ -2593,10 +3353,29 @@ ], "changes": [ { - "version": "v12.15.0", + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/39310", + "description": "When using a `URL` object parsed username and password will now be properly URI decoded." + }, + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/36048", + "description": "It is possible to abort a request with an AbortSignal." + }, + { + "version": [ + "v13.8.0", + "v12.15.0", + "v10.19.0" + ], "pr-url": "https://github.com/nodejs/node/pull/31448", "description": "The `insecureHTTPParser` option is supported now." }, + { + "version": "v13.3.0", + "pr-url": "https://github.com/nodejs/node/pull/30570", + "description": "The `maxHeaderSize` option is supported now." + }, { "version": "v10.9.0", "pr-url": "https://github.com/nodejs/node/pull/21616", @@ -2681,6 +3460,12 @@ "type": "Object", "desc": "An object containing request headers." }, + { + "textRaw": "`hints` {number} Optional [`dns.lookup()` hints][].", + "name": "hints", + "type": "number", + "desc": "Optional [`dns.lookup()` hints][]." + }, { "textRaw": "`host` {string} A domain name or IP address of the server to issue the request to. **Default:** `'localhost'`.", "name": "host", @@ -2707,6 +3492,12 @@ "type": "string", "desc": "Local interface to bind for network connections." }, + { + "textRaw": "`localPort` {number} Local port to connect from.", + "name": "localPort", + "type": "number", + "desc": "Local port to connect from." + }, { "textRaw": "`lookup` {Function} Custom lookup function. **Default:** [`dns.lookup()`][].", "name": "lookup", @@ -2714,6 +3505,13 @@ "default": "[`dns.lookup()`][]", "desc": "Custom lookup function." }, + { + "textRaw": "`maxHeaderSize` {number} Optionally overrides the value of [`--max-http-header-size`][] for requests received from the server, i.e. the maximum length of response headers in bytes. **Default:** 16384 (16KB).", + "name": "maxHeaderSize", + "type": "number", + "default": "16384 (16KB)", + "desc": "Optionally overrides the value of [`--max-http-header-size`][] for requests received from the server, i.e. the maximum length of response headers in bytes." + }, { "textRaw": "`method` {string} A string specifying the HTTP request method. **Default:** `'GET'`.", "name": "method", @@ -2759,6 +3557,12 @@ "name": "timeout", "type": "number", "desc": ": A number specifying the socket timeout in milliseconds. This will set the timeout before the socket is connected." + }, + { + "textRaw": "`signal` {AbortSignal}: An AbortSignal that may be used to abort an ongoing request.", + "name": "signal", + "type": "AbortSignal", + "desc": ": An AbortSignal that may be used to abort an ongoing request." } ] }, @@ -2770,7 +3574,58 @@ ] } ], - "desc": "

      Node.js maintains several connections per server to make HTTP requests.\nThis function allows one to transparently issue requests.

      \n

      url can be a string or a URL object. If url is a\nstring, it is automatically parsed with new URL(). If it is a URL\nobject, it will be automatically converted to an ordinary options object.

      \n

      If both url and options are specified, the objects are merged, with the\noptions properties taking precedence.

      \n

      The optional callback parameter will be added as a one-time listener for\nthe 'response' event.

      \n

      http.request() returns an instance of the http.ClientRequest\nclass. The ClientRequest instance is a writable stream. If one needs to\nupload a file with a POST request, then write to the ClientRequest object.

      \n
      const postData = querystring.stringify({\n  'msg': 'Hello World!'\n});\n\nconst options = {\n  hostname: 'www.google.com',\n  port: 80,\n  path: '/upload',\n  method: 'POST',\n  headers: {\n    'Content-Type': 'application/x-www-form-urlencoded',\n    'Content-Length': Buffer.byteLength(postData)\n  }\n};\n\nconst req = http.request(options, (res) => {\n  console.log(`STATUS: ${res.statusCode}`);\n  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);\n  res.setEncoding('utf8');\n  res.on('data', (chunk) => {\n    console.log(`BODY: ${chunk}`);\n  });\n  res.on('end', () => {\n    console.log('No more data in response.');\n  });\n});\n\nreq.on('error', (e) => {\n  console.error(`problem with request: ${e.message}`);\n});\n\n// Write data to request body\nreq.write(postData);\nreq.end();\n
      \n

      In the example req.end() was called. With http.request() one\nmust always call req.end() to signify the end of the request -\neven if there is no data being written to the request body.

      \n

      If any error is encountered during the request (be that with DNS resolution,\nTCP level errors, or actual HTTP parse errors) an 'error' event is emitted\non the returned request object. As with all 'error' events, if no listeners\nare registered the error will be thrown.

      \n

      There are a few special headers that should be noted.

      \n
        \n
      • \n

        Sending a 'Connection: keep-alive' will notify Node.js that the connection to\nthe server should be persisted until the next request.

        \n
      • \n
      • \n

        Sending a 'Content-Length' header will disable the default chunked encoding.

        \n
      • \n
      • \n

        Sending an 'Expect' header will immediately send the request headers.\nUsually, when sending 'Expect: 100-continue', both a timeout and a listener\nfor the 'continue' event should be set. See RFC 2616 Section 8.2.3 for more\ninformation.

        \n
      • \n
      • \n

        Sending an Authorization header will override using the auth option\nto compute basic authentication.

        \n
      • \n
      \n

      Example using a URL as options:

      \n
      const options = new URL('http://abc:xyz@example.com');\n\nconst req = http.request(options, (res) => {\n  // ...\n});\n
      \n

      In a successful request, the following events will be emitted in the following\norder:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object\n('data' will not be emitted at all if the response body is empty, for\ninstance, in most redirects)
        • \n
        • 'end' on the res object
        • \n
        \n
      • \n
      • 'close'
      • \n
      \n

      In the case of a connection error, the following events will be emitted:

      \n
        \n
      • 'socket'
      • \n
      • 'error'
      • \n
      • 'close'
      • \n
      \n

      If req.abort() is called before the connection succeeds, the following events\nwill be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • (req.abort() called here)
      • \n
      • 'abort'
      • \n
      • 'error' with an error with message 'Error: socket hang up' and code\n'ECONNRESET'
      • \n
      • 'close'
      • \n
      \n

      If req.abort() is called after the response is received, the following events\nwill be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object
        • \n
        \n
      • \n
      • (req.abort() called here)
      • \n
      • 'abort'
      • \n
      • 'aborted' on the res object
      • \n
      • 'close'
      • \n
      • 'end' on the res object
      • \n
      • 'close' on the res object
      • \n
      \n

      Setting the timeout option or using the setTimeout() function will\nnot abort the request or do anything besides add a 'timeout' event.

      " + "desc": "

      Node.js maintains several connections per server to make HTTP requests.\nThis function allows one to transparently issue requests.

      \n

      url can be a string or a URL object. If url is a\nstring, it is automatically parsed with new URL(). If it is a URL\nobject, it will be automatically converted to an ordinary options object.

      \n

      If both url and options are specified, the objects are merged, with the\noptions properties taking precedence.

      \n

      The optional callback parameter will be added as a one-time listener for\nthe 'response' event.

      \n

      http.request() returns an instance of the http.ClientRequest\nclass. The ClientRequest instance is a writable stream. If one needs to\nupload a file with a POST request, then write to the ClientRequest object.

      \n
      const http = require('http');\n\nconst postData = JSON.stringify({\n  'msg': 'Hello World!'\n});\n\nconst options = {\n  hostname: 'www.google.com',\n  port: 80,\n  path: '/upload',\n  method: 'POST',\n  headers: {\n    'Content-Type': 'application/json',\n    'Content-Length': Buffer.byteLength(postData)\n  }\n};\n\nconst req = http.request(options, (res) => {\n  console.log(`STATUS: ${res.statusCode}`);\n  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);\n  res.setEncoding('utf8');\n  res.on('data', (chunk) => {\n    console.log(`BODY: ${chunk}`);\n  });\n  res.on('end', () => {\n    console.log('No more data in response.');\n  });\n});\n\nreq.on('error', (e) => {\n  console.error(`problem with request: ${e.message}`);\n});\n\n// Write data to request body\nreq.write(postData);\nreq.end();\n
      \n

      In the example req.end() was called. With http.request() one\nmust always call req.end() to signify the end of the request -\neven if there is no data being written to the request body.

      \n

      If any error is encountered during the request (be that with DNS resolution,\nTCP level errors, or actual HTTP parse errors) an 'error' event is emitted\non the returned request object. As with all 'error' events, if no listeners\nare registered the error will be thrown.

      \n

      There are a few special headers that should be noted.

      \n
        \n
      • \n

        Sending a 'Connection: keep-alive' will notify Node.js that the connection to\nthe server should be persisted until the next request.

        \n
      • \n
      • \n

        Sending a 'Content-Length' header will disable the default chunked encoding.

        \n
      • \n
      • \n

        Sending an 'Expect' header will immediately send the request headers.\nUsually, when sending 'Expect: 100-continue', both a timeout and a listener\nfor the 'continue' event should be set. See RFC 2616 Section 8.2.3 for more\ninformation.

        \n
      • \n
      • \n

        Sending an Authorization header will override using the auth option\nto compute basic authentication.

        \n
      • \n
      \n

      Example using a URL as options:

      \n
      const options = new URL('http://abc:xyz@example.com');\n\nconst req = http.request(options, (res) => {\n  // ...\n});\n
      \n

      In a successful request, the following events will be emitted in the following\norder:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object\n('data' will not be emitted at all if the response body is empty, for\ninstance, in most redirects)
        • \n
        • 'end' on the res object
        • \n
        \n
      • \n
      • 'close'
      • \n
      \n

      In the case of a connection error, the following events will be emitted:

      \n
        \n
      • 'socket'
      • \n
      • 'error'
      • \n
      • 'close'
      • \n
      \n

      In the case of a premature connection close before the response is received,\nthe following events will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • 'error' with an error with message 'Error: socket hang up' and code\n'ECONNRESET'
      • \n
      • 'close'
      • \n
      \n

      In the case of a premature connection close after the response is received,\nthe following events will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object
        • \n
        \n
      • \n
      • (connection closed here)
      • \n
      • 'aborted' on the res object
      • \n
      • 'close'
      • \n
      • 'close' on the res object
      • \n
      \n

      If req.destroy() is called before a socket is assigned, the following\nevents will be emitted in the following order:

      \n
        \n
      • (req.destroy() called here)
      • \n
      • 'error' with an error with message 'Error: socket hang up' and code\n'ECONNRESET'
      • \n
      • 'close'
      • \n
      \n

      If req.destroy() is called before the connection succeeds, the following\nevents will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • (req.destroy() called here)
      • \n
      • 'error' with an error with message 'Error: socket hang up' and code\n'ECONNRESET'
      • \n
      • 'close'
      • \n
      \n

      If req.destroy() is called after the response is received, the following\nevents will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object
        • \n
        \n
      • \n
      • (req.destroy() called here)
      • \n
      • 'aborted' on the res object
      • \n
      • 'close'
      • \n
      • 'close' on the res object
      • \n
      \n

      If req.abort() is called before a socket is assigned, the following\nevents will be emitted in the following order:

      \n
        \n
      • (req.abort() called here)
      • \n
      • 'abort'
      • \n
      • 'close'
      • \n
      \n

      If req.abort() is called before the connection succeeds, the following\nevents will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • (req.abort() called here)
      • \n
      • 'abort'
      • \n
      • 'error' with an error with message 'Error: socket hang up' and code\n'ECONNRESET'
      • \n
      • 'close'
      • \n
      \n

      If req.abort() is called after the response is received, the following\nevents will be emitted in the following order:

      \n
        \n
      • 'socket'
      • \n
      • 'response'\n
          \n
        • 'data' any number of times, on the res object
        • \n
        \n
      • \n
      • (req.abort() called here)
      • \n
      • 'abort'
      • \n
      • 'aborted' on the res object
      • \n
      • 'close'
      • \n
      • 'close' on the res object
      • \n
      \n

      Setting the timeout option or using the setTimeout() function will\nnot abort the request or do anything besides add a 'timeout' event.

      \n

      Passing an AbortSignal and then calling abort on the corresponding\nAbortController will behave the same way as calling .destroy() on the\nrequest itself.

      " + }, + { + "textRaw": "`http.validateHeaderName(name)`", + "type": "method", + "name": "validateHeaderName", + "meta": { + "added": [ + "v14.3.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`name` {string}", + "name": "name", + "type": "string" + } + ] + } + ], + "desc": "

      Performs the low-level validations on the provided name that are done when\nres.setHeader(name, value) is called.

      \n

      Passing illegal value as name will result in a TypeError being thrown,\nidentified by code: 'ERR_INVALID_HTTP_TOKEN'.

      \n

      It is not necessary to use this method before passing headers to an HTTP request\nor response. The HTTP module will automatically validate such headers.\nExamples:

      \n

      Example:

      \n
      const { validateHeaderName } = require('http');\n\ntry {\n  validateHeaderName('');\n} catch (err) {\n  err instanceof TypeError; // --> true\n  err.code; // --> 'ERR_INVALID_HTTP_TOKEN'\n  err.message; // --> 'Header name must be a valid HTTP token [\"\"]'\n}\n
      " + }, + { + "textRaw": "`http.validateHeaderValue(name, value)`", + "type": "method", + "name": "validateHeaderValue", + "meta": { + "added": [ + "v14.3.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`name` {string}", + "name": "name", + "type": "string" + }, + { + "textRaw": "`value` {any}", + "name": "value", + "type": "any" + } + ] + } + ], + "desc": "

      Performs the low-level validations on the provided value that are done when\nres.setHeader(name, value) is called.

      \n

      Passing illegal value as value will result in a TypeError being thrown.

      \n
        \n
      • Undefined value error is identified by code: 'ERR_HTTP_INVALID_HEADER_VALUE'.
      • \n
      • Invalid value character error is identified by code: 'ERR_INVALID_CHAR'.
      • \n
      \n

      It is not necessary to use this method before passing headers to an HTTP request\nor response. The HTTP module will automatically validate such headers.

      \n

      Examples:

      \n
      const { validateHeaderValue } = require('http');\n\ntry {\n  validateHeaderValue('x-my-header', undefined);\n} catch (err) {\n  err instanceof TypeError; // --> true\n  err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'; // --> true\n  err.message; // --> 'Invalid value \"undefined\" for header \"x-my-header\"'\n}\n\ntry {\n  validateHeaderValue('x-my-header', 'oʊmɪɡə');\n} catch (err) {\n  err instanceof TypeError; // --> true\n  err.code === 'ERR_INVALID_CHAR'; // --> true\n  err.message; // --> 'Invalid character in header content [\"x-my-header\"]'\n}\n
      " } ], "type": "module", diff --git a/doc/api/http.md b/doc/api/http.md index ff33288e7292082d0eb09a12592d3c425c506c93..5f6d3804eedcf5c9f2f2ebf85bdca7bade6fd9f3 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -113,10 +113,13 @@ http.get({ * {number} @@ -604,8 +613,11 @@ server.listen(1337, '127.0.0.1', () => { ### `request.abort()` +> Stability: 0 - Deprecated: Use [`request.destroy()`][] instead. + Marks the request as aborting. Calling this will cause remaining data in the response to be dropped and the socket to be destroyed. @@ -626,8 +638,11 @@ been aborted. ### `request.connection` +> Stability: 0 - Deprecated. Use [`request.socket`][]. + * {stream.Duplex} See [`request.socket`][]. @@ -656,10 +671,42 @@ If `data` is specified, it is equivalent to calling If `callback` is specified, it will be called when the request stream is finished. +### `request.destroy([error])` + + +* `error` {Error} Optional, an error to emit with `'error'` event. +* Returns: {this} + +Destroy the request. Optionally emit an `'error'` event, +and emit a `'close'` event. Calling this will cause remaining data +in the response to be dropped and the socket to be destroyed. + +See [`writable.destroy()`][] for further details. + +#### `request.destroyed` + + +* {boolean} + +Is `true` after [`request.destroy()`][] has been called. + +See [`writable.destroyed`][] for further details. + ### `request.finished` > Stability: 0 - Deprecated. Use [`request.writableEnded`][]. @@ -709,6 +756,24 @@ const cookie = request.getHeader('Cookie'); // 'cookie' is of type string[] ``` +### `request.getRawHeaderNames()` + + +* Returns: {string[]} + +Returns an array containing the unique names of the current outgoing raw +headers. Header names are returned with their exact casing being set. + +```js +request.setHeader('Foo', 'bar'); +request.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']); + +const headerNames = request.getRawHeaderNames(); +// headerNames === ['Foo', 'Set-Cookie'] +``` + ### `request.maxHeadersCount` * {number} **Default:** `2000` @@ -731,14 +796,14 @@ added: v0.1.97 ### `request.host` * {string} The request host. ### `request.protocol` * {string} The request protocol. @@ -757,9 +822,10 @@ request.removeHeader('Content-Type'); ``` ### `request.reusedSocket` - * {boolean} Whether the request is send through a reused socket. @@ -884,8 +950,7 @@ added: v0.3.0 Reference to the underlying socket. Usually users will not want to access this property. In particular, the socket will not emit `'readable'` events -because of how the protocol parser attaches to the socket. The `socket` -may also be accessed via `request.connection`. +because of how the protocol parser attaches to the socket. ```js const http = require('http'); @@ -937,11 +1002,11 @@ added: v0.1.29 * `callback` {Function} * Returns: {boolean} -Sends a chunk of the body. By calling this method -many times, a request body can be sent to a -server. In that case, it is suggested to use the -`['Transfer-Encoding', 'chunked']` header line when -creating the request. +Sends a chunk of the body. This method can be called multiple times. If no +`Content-Length` is set, data will automatically be encoded in HTTP Chunked +transfer encoding, so that server knows when the data ends. The +`Transfer-Encoding: chunked` header is added. Calling [`request.end()`][] +is necessary to finish sending the request. The `encoding` argument is optional and only applies when `chunk` is a string. Defaults to `'utf8'`. @@ -1002,20 +1067,20 @@ not be emitted. * `exception` {Error} @@ -1115,7 +1180,7 @@ This event is emitted when a new TCP stream is established. `socket` is typically an object of type [`net.Socket`][]. Usually users will not want to access this event. In particular, the socket will not emit `'readable'` events because of how the protocol parser attaches to the socket. The `socket` can -also be accessed at `request.connection`. +also be accessed at `request.socket`. This event can also be explicitly emitted by users to inject connections into the HTTP server. In that case, any [`Duplex`][] stream can be passed. @@ -1144,7 +1209,7 @@ per connection (in the case of HTTP Keep-Alive connections). added: v0.1.94 changes: - version: v10.0.0 - pr-url: v10.0.0 + pr-url: https://github.com/nodejs/node/pull/19981 description: Not listening to this event no longer causes the socket to be destroyed if a client sends an Upgrade header. --> @@ -1176,7 +1241,9 @@ Stops the server from accepting new connections. See [`net.Server.close()`][]. ### `server.headersTimeout` * {number} **Default:** `60000` @@ -1194,8 +1261,6 @@ event is emitted on the server object, and (by default) the socket is destroyed. See [`server.timeout`][] for more information on how timeout behavior can be customized. -A value of `0` will disable the HTTP headers timeout check. - ### `server.listen()` Starts the HTTP server listening for connections. @@ -1217,12 +1282,33 @@ added: v0.7.0 Limits maximum incoming headers count. If set to 0, no limit will be applied. +### `server.requestTimeout` + + +* {number} **Default:** `0` + +Sets the timeout value in milliseconds for receiving the entire request from +the client. + +If the timeout expires, the server responds with status 408 without +forwarding the request to the request listener and then closes the connection. + +It must be set to a non-zero value (e.g. 120 seconds) to protect against +potential Denial-of-Service attacks in case the server is deployed without a +reverse proxy in front. + ### `server.setTimeout([msecs][, callback])` -* `msecs` {number} **Default:** `120000` (2 minutes) +* `msecs` {number} **Default:** 0 (no timeout) * `callback` {Function} * Returns: {http.Server} @@ -1233,19 +1319,20 @@ occurs. If there is a `'timeout'` event listener on the Server object, then it will be called with the timed-out socket as an argument. -By default, the Server's timeout value is 2 minutes, and sockets are -destroyed automatically if they time out. However, if a callback is assigned -to the Server's `'timeout'` event, timeouts must be handled explicitly. - -To change the default timeout use the [`--http-server-default-timeout`][] -flag. +By default, the Server does not timeout sockets. However, if a callback +is assigned to the Server's `'timeout'` event, timeouts must be handled +explicitly. ### `server.timeout` -* {number} Timeout in milliseconds. **Default:** `120000` (2 minutes). +* {number} Timeout in milliseconds. **Default:** 0 (no timeout) The number of milliseconds of inactivity before a socket is presumed to have timed out. @@ -1255,9 +1342,6 @@ A value of `0` will disable the timeout behavior on incoming connections. The socket timeout logic is set up on connection, so changing this value only affects new connections to the server, not any existing connections. -To change the default timeout use the [`--http-server-default-timeout`][] -flag. - ### `server.keepAliveTimeout` -Indicates that the the response is completed, or its underlying connection was +Indicates that the response is completed, or its underlying connection was terminated prematurely (before the response completion). ### Event: `'finish'` @@ -1338,15 +1422,20 @@ will result in a [`TypeError`][] being thrown. ### `response.connection` +> Stability: 0 - Deprecated. Use [`response.socket`][]. + * {stream.Duplex} See [`response.socket`][]. ### `response.cork()` See [`writable.cork()`][]. @@ -1378,7 +1467,9 @@ is finished. ### `response.finished` > Stability: 0 - Deprecated. Use [`response.writableEnded`][]. @@ -1520,13 +1611,17 @@ added: v0.4.0 * `name` {string} * `value` {any} +* Returns: {http.ServerResponse} + +Returns the response object. Sets a single header value for implicit headers. If this header already exists in the to-be-sent headers, its value will be replaced. Use an array of strings here to send multiple headers with the same name. Non-string values will be stored without modification. Therefore, [`response.getHeader()`][] may return non-string values. However, the non-string values will be converted to strings -for network transmission. +for network transmission. The same response object is returned to the caller, +to enable call chaining. ```js response.setHeader('Content-Type', 'text/html'); @@ -1590,8 +1685,7 @@ added: v0.3.0 Reference to the underlying socket. Usually users will not want to access this property. In particular, the socket will not emit `'readable'` events because of how the protocol parser attaches to the socket. After -`response.end()`, the property is nulled. The `socket` may also be accessed -via `response.connection`. +`response.end()`, the property is nulled. ```js const http = require('http'); @@ -1645,7 +1739,9 @@ status message which was sent out. ### `response.uncork()` See [`writable.uncork()`][]. @@ -1721,11 +1817,18 @@ the request body should be sent. See the [`'checkContinue'`][] event on @@ -1868,7 +1978,7 @@ const req = http.request({ + +* Extends: {Stream} + +This class serves as the parent class of [`http.ClientRequest`][] +and [`http.ServerResponse`][]. It is an abstract of outgoing message from +the perspective of the participants of HTTP transaction. + +### Event: `drain` + + +Emitted when the buffer of the message is free again. + +### Event: `finish` + + +Emitted when the transmission is finished successfully. + +### Event: `prefinish` + + +Emitted when `outgoingMessage.end` was called. +When the event is emitted, all data has been processed but not necessarily +completely flushed. + +### `outgoingMessage.addTrailers(headers)` + + +* `headers` {Object} + +Adds HTTP trailers (headers but at the end of the message) to the message. + +Trailers are **only** be emitted if the message is chunked encoded. If not, +the trailer will be silently discarded. + +HTTP requires the `Trailer` header to be sent to emit trailers, +with a list of header fields in its value, e.g. + +```js +message.writeHead(200, { 'Content-Type': 'text/plain', + 'Trailer': 'Content-MD5' }); +message.write(fileData); +message.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' }); +message.end(); +``` + +Attempting to set a header field name or value that contains invalid characters +will result in a `TypeError` being thrown. + +### `outgoingMessage.connection` + + +> Stability: 0 - Deprecated: Use [`outgoingMessage.socket`][] instead. + +Aliases of `outgoingMessage.socket` +### `outgoingMessage.cork()` + + +See [`writable.cork()`][]. + +### `outgoingMessage.destroy([error])` + + +* `error` {Error} Optional, an error to emit with `error` event +* Returns: {this} + +Destroys the message. Once a socket is associated with the message +and is connected, that socket will be destroyed as well. + +### `outgoingMessage.end(chunk[, encoding][, callback])` + + +* `chunk` {string | Buffer} +* `encoding` {string} Optional, **Default**: `utf-8` +* `callback` {Function} Optional +* Returns: {this} + +Finishes the outgoing message. If any parts of the body are unsent, it will +flush them to the underlying system. If the message is chunked, it will +send the terminating chunk `0\r\n\r\n`, and send the trailer (if any). + +If `chunk` is specified, it is equivalent to call +`outgoingMessage.write(chunk, encoding)`, followed by +`outgoingMessage.end(callback)`. + +If `callback` is provided, it will be called when the message is finished. +(equivalent to the callback to event `finish`) + +### `outgoingMessage.flushHeaders()` + + +Compulsorily flushes the message headers + +For efficiency reason, Node.js normally buffers the message headers +until `outgoingMessage.end()` is called or the first chunk of message data +is written. It then tries to pack the headers and data into a single TCP +packet. + +It is usually desired (it saves a TCP round-trip), but not when the first +data is not sent until possibly much later. `outgoingMessage.flushHeaders()` +bypasses the optimization and kickstarts the request. + +### `outgoingMessage.getHeader(name)` + + +* `name` {string} Name of header +* Returns {string | undefined} + +Gets the value of HTTP header with the given name. If such a name doesn't +exist in message, it will be `undefined`. + +### `outgoingMessage.getHeaderNames()` + + +* Returns {string[]} + +Returns an array of names of headers of the outgoing outgoingMessage. All +names are lowercase. + +### `outgoingMessage.getHeaders()` + + +* Returns: {Object} + +Returns a shallow copy of the current outgoing headers. Since a shallow +copy is used, array values may be mutated without additional calls to +various header-related HTTP module methods. The keys of the returned +object are the header names and the values are the respective header +values. All header names are lowercase. + +The object returned by the `outgoingMessage.getHeaders()` method does +not prototypically inherit from the JavaScript Object. This means that +typical Object methods such as `obj.toString()`, `obj.hasOwnProperty()`, +and others are not defined and will not work. + +```js +outgoingMessage.setHeader('Foo', 'bar'); +outgoingMessage.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']); + +const headers = outgoingMessage.getHeaders(); +// headers === { foo: 'bar', 'set-cookie': ['foo=bar', 'bar=baz'] } +``` + +### `outgoingMessage.hasHeader(name)` + + +* `name` {string} +* Returns {boolean} + +Returns `true` if the header identified by `name` is currently set in the +outgoing headers. The header name is case-insensitive. + +```js +const hasContentType = outgoingMessage.hasHeader('content-type'); +``` + +### `outgoingMessage.headersSent` + + +* {boolean} + +Read-only. `true` if the headers were sent, otherwise `false`. + +### `outgoingMessage.pipe()` + + +Overrides the pipe method of legacy `Stream` which is the parent class of +`http.outgoingMessage`. + +Since `OutgoingMessage` should be a write-only stream, +call this function will throw an `Error`. Thus, it disabled the pipe method +it inherits from `Stream`. + +The User should not call this function directly. + +### `outgoingMessage.removeHeader()` + + +Removes a header that is queued for implicit sending. + +```js +outgoingMessage.removeHeader('Content-Encoding'); +``` + +### `outgoingMessage.setHeader(name, value)` + + +* `name` {string} Header name +* `value` {string} Header value +* Returns: {this} + +Sets a single header value for the header object. + +### `outgoingMessage.setTimeout(msesc[, callback])` + + +* `msesc` {number} +* `callback` {Function} Optional function to be called when a timeout +occurs, Same as binding to the `timeout` event. +* Returns: {this} + +Once a socket is associated with the message and is connected, +[`socket.setTimeout()`][] will be called with `msecs` as the first parameter. + +### `outgoingMessage.socket` + + +* {stream.Duplex} + +Reference to the underlying socket. Usually, users will not want to access +this property. + +After calling `outgoingMessage.end()`, this property will be nulled. + +### `outgoingMessage.uncork()` + + +See [`writable.uncork()`][] + +### `outgoingMessage.writableCorked` + + +* {number} + +This `outgoingMessage.writableCorked` will return the time how many +`outgoingMessage.cork()` have been called. + +### `outgoingMessage.writableEnded` + + +* {boolean} + +Readonly, `true` if `outgoingMessage.end()` has been called. Noted that +this property does not reflect whether the data has been flush. For that +purpose, use `message.writableFinished` instead. + +### `outgoingMessage.writableFinished` + + +* {boolean} + +Readonly. `true` if all data has been flushed to the underlying system. + +### `outgoingMessage.writableHighWaterMark` + + +* {number} + +This `outgoingMessage.writableHighWaterMark` will be the `highWaterMark` of +underlying socket if socket exists. Else, it would be the default +`highWaterMark`. + +`highWaterMark` is the maximum amount of data that can be potentially +buffered by the socket. + +### `outgoingMessage.writableLength` + + +* {number} + +Readonly, This `outgoingMessage.writableLength` contains the number of +bytes (or objects) in the buffer ready to send. + +### `outgoingMessage.writableObjectMode` + + +* {boolean} + +Readonly, always returns `false`. + +### `outgoingMessage.write(chunk[, encoding][, callback])` + + +* `chunk` {string | Buffer} +* `encoding` {string} **Default**: `utf-8` +* `callback` {Function} +* Returns {boolean} + +If this method is called and the header is not sent, it will call +`this._implicitHeader` to flush implicit header. +If the message should not have a body (indicated by `this._hasBody`), +the call is ignored and `chunk` will not be sent. It could be useful +when handling a particular message which must not include a body. +e.g. response to `HEAD` request, `204` and `304` response. + +`chunk` can be a string or a buffer. When `chunk` is a string, the +`encoding` parameter specifies how to encode `chunk` into a byte stream. +`callback` will be called when the `chunk` is flushed. + +If the message is transferred in chucked encoding +(indicated by `this.chunkedEncoding`), `chunk` will be flushed as +one chunk among a stream of chunks. Otherwise, it will be flushed as the +body of message. + +This method handles the raw body of the HTTP message and has nothing to do +with higher-level multi-part body encodings that may be used. + +If it is the first call to this method of a message, it will send the +buffered header first, then flush the `chunk` as described above. + +The second and successive calls to this method will assume the data +will be streamed and send the new data separately. It means that the response +is buffered up to the first chunk of the body. + +Returns `true` if the entire data was flushed successfully to the kernel +buffer. Returns `false` if all or part of the data was queued in the user +memory. Event `drain` will be emitted when the buffer is free again. + ## `http.METHODS` @@ -2123,6 +2613,10 @@ changes: invalid HTTP headers when `true`. Using the insecure parser should be avoided. See [`--insecure-http-parser`][] for more information. **Default:** `false` + * `maxHeaderSize` {number} Optionally overrides the value of + [`--max-http-header-size`][] for requests received by this server, i.e. + the maximum length of request headers in bytes. + **Default:** 16384 (16KB). * `requestListener` {Function} * Returns: {http.Server} @@ -2132,6 +2626,37 @@ Returns a new instance of [`http.Server`][]. The `requestListener` is a function which is automatically added to the [`'request'`][] event. +```cjs +const http = require('http'); + +// Create a local server to receive data from +const server = http.createServer((req, res) => { + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ + data: 'Hello World!' + })); +}); + +server.listen(8000); +``` + +```cjs +const http = require('http'); + +// Create a local server to receive data from +const server = http.createServer(); + +// Listen to the request event +server.on('request', (request, res) => { + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ + data: 'Hello World!' + })); +}); + +server.listen(8000); +``` + ## `http.get(options[, callback])` ## `http.get(url[, options][, callback])` * {number} @@ -2222,14 +2759,30 @@ added: v11.6.0 Read-only property specifying the maximum allowed size of HTTP headers in bytes. Defaults to 8KB. Configurable using the [`--max-http-header-size`][] CLI option. +This can be overridden for servers and client requests by passing the +`maxHeaderSize` option. + ## `http.request(options[, callback])` ## `http.request(url[, options][, callback])` + +* `name` {string} + +Performs the low-level validations on the provided `name` that are done when +`res.setHeader(name, value)` is called. + +Passing illegal value as `name` will result in a [`TypeError`][] being thrown, +identified by `code: 'ERR_INVALID_HTTP_TOKEN'`. + +It is not necessary to use this method before passing headers to an HTTP request +or response. The HTTP module will automatically validate such headers. +Examples: + +Example: +```js +const { validateHeaderName } = require('http'); + +try { + validateHeaderName(''); +} catch (err) { + err instanceof TypeError; // --> true + err.code; // --> 'ERR_INVALID_HTTP_TOKEN' + err.message; // --> 'Header name must be a valid HTTP token [""]' +} +``` + +## `http.validateHeaderValue(name, value)` + + +* `name` {string} +* `value` {any} + +Performs the low-level validations on the provided `value` that are done when +`res.setHeader(name, value)` is called. + +Passing illegal value as `value` will result in a [`TypeError`][] being thrown. +* Undefined value error is identified by `code: 'ERR_HTTP_INVALID_HEADER_VALUE'`. +* Invalid value character error is identified by `code: 'ERR_INVALID_CHAR'`. + +It is not necessary to use this method before passing headers to an HTTP request +or response. The HTTP module will automatically validate such headers. + +Examples: + +```js +const { validateHeaderValue } = require('http'); + +try { + validateHeaderValue('x-my-header', undefined); +} catch (err) { + err instanceof TypeError; // --> true + err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'; // --> true + err.message; // --> 'Invalid value "undefined" for header "x-my-header"' +} + +try { + validateHeaderValue('x-my-header', 'oʊmɪɡə'); +} catch (err) { + err instanceof TypeError; // --> true + err.code === 'ERR_INVALID_CHAR'; // --> true + err.message; // --> 'Invalid character in header content ["x-my-header"]' +} +``` + [`'checkContinue'`]: #http_event_checkcontinue +[`'finish'`]: #http_event_finish [`'request'`]: #http_event_request [`'response'`]: #http_event_response [`'upgrade'`]: #http_event_upgrade +[`--insecure-http-parser`]: cli.md#cli_insecure_http_parser +[`--max-http-header-size`]: cli.md#cli_max_http_header_size_size [`Agent`]: #http_class_http_agent -[`Buffer.byteLength()`]: buffer.html#buffer_static_method_buffer_bytelength_string_encoding -[`Duplex`]: stream.html#stream_class_stream_duplex -[`TypeError`]: errors.html#errors_class_typeerror -[`URL`]: url.html#url_the_whatwg_url_api +[`Buffer.byteLength()`]: buffer.md#buffer_static_method_buffer_bytelength_string_encoding +[`Duplex`]: stream.md#stream_class_stream_duplex +[`HPE_HEADER_OVERFLOW`]: errors.md#errors_hpe_header_overflow +[`TypeError`]: errors.md#errors_class_typeerror +[`URL`]: url.md#url_the_whatwg_url_api [`agent.createConnection()`]: #http_agent_createconnection_options_callback [`agent.getName()`]: #http_agent_getname_options [`destroy()`]: #http_agent_destroy -[`dns.lookup()`]: dns.html#dns_dns_lookup_hostname_options_callback -[`'finish'`]: #http_event_finish +[`dns.lookup()`]: dns.md#dns_dns_lookup_hostname_options_callback +[`dns.lookup()` hints]: dns.md#dns_supported_getaddrinfo_flags [`getHeader(name)`]: #http_request_getheader_name [`http.Agent`]: #http_class_http_agent [`http.ClientRequest`]: #http_class_http_clientrequest [`http.IncomingMessage`]: #http_class_http_incomingmessage +[`http.ServerResponse`]: #http_class_http_serverresponse [`http.Server`]: #http_class_http_server [`http.get()`]: #http_http_get_options_callback [`http.globalAgent`]: #http_http_globalagent [`http.request()`]: #http_http_request_options_callback [`message.headers`]: #http_message_headers -[`net.Server.close()`]: net.html#net_server_close_callback -[`net.Server`]: net.html#net_class_net_server -[`net.Socket`]: net.html#net_class_net_socket -[`net.createConnection()`]: net.html#net_net_createconnection_options_connectlistener -[`new URL()`]: url.html#url_new_url_input_base +[`net.Server.close()`]: net.md#net_server_close_callback +[`net.Server`]: net.md#net_class_net_server +[`net.Socket`]: net.md#net_class_net_socket +[`net.createConnection()`]: net.md#net_net_createconnection_options_connectlistener +[`new URL()`]: url.md#url_new_url_input_base +[`outgoingMessage.socket`]: #http_outgoingmessage_socket [`removeHeader(name)`]: #http_request_removeheader_name +[`request.destroy()`]: #http_request_destroy_error [`request.end()`]: #http_request_end_data_encoding_callback [`request.flushHeaders()`]: #http_request_flushheaders [`request.getHeader()`]: #http_request_getheader_name [`request.setHeader()`]: #http_request_setheader_name_value [`request.setTimeout()`]: #http_request_settimeout_timeout_callback -[`request.socket.getPeerCertificate()`]: tls.html#tls_tlssocket_getpeercertificate_detailed +[`request.socket.getPeerCertificate()`]: tls.md#tls_tlssocket_getpeercertificate_detailed [`request.socket`]: #http_request_socket -[`request.writableFinished`]: #http_request_writablefinished [`request.writableEnded`]: #http_request_writableended +[`request.writableFinished`]: #http_request_writablefinished [`request.write(data, encoding)`]: #http_request_write_chunk_encoding_callback [`response.end()`]: #http_response_end_data_encoding_callback [`response.getHeader()`]: #http_response_getheader_name [`response.setHeader()`]: #http_response_setheader_name_value [`response.socket`]: #http_response_socket -[`response.writableFinished`]: #http_response_writablefinished [`response.writableEnded`]: #http_response_writableended +[`response.writableFinished`]: #http_response_writablefinished [`response.write()`]: #http_response_write_chunk_encoding_callback [`response.write(data, encoding)`]: #http_response_write_chunk_encoding_callback [`response.writeContinue()`]: #http_response_writecontinue [`response.writeHead()`]: #http_response_writehead_statuscode_statusmessage_headers -[`server.listen()`]: net.html#net_server_listen +[`server.listen()`]: net.md#net_server_listen [`server.timeout`]: #http_server_timeout [`setHeader(name, value)`]: #http_request_setheader_name_value -[`socket.connect()`]: net.html#net_socket_connect_options_connectlistener -[`socket.setKeepAlive()`]: net.html#net_socket_setkeepalive_enable_initialdelay -[`socket.setNoDelay()`]: net.html#net_socket_setnodelay_nodelay -[`socket.setTimeout()`]: net.html#net_socket_settimeout_timeout_callback -[`socket.unref()`]: net.html#net_socket_unref -[`url.parse()`]: url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost -[`HPE_HEADER_OVERFLOW`]: errors.html#errors_hpe_header_overflow -[`writable.cork()`]: stream.html#stream_writable_cork -[`writable.uncork()`]: stream.html#stream_writable_uncork +[`socket.connect()`]: net.md#net_socket_connect_options_connectlistener +[`socket.setKeepAlive()`]: net.md#net_socket_setkeepalive_enable_initialdelay +[`socket.setNoDelay()`]: net.md#net_socket_setnodelay_nodelay +[`socket.setTimeout()`]: net.md#net_socket_settimeout_timeout_callback +[`socket.unref()`]: net.md#net_socket_unref +[`url.parse()`]: url.md#url_url_parse_urlstring_parsequerystring_slashesdenotehost +[`writable.cork()`]: stream.md#stream_writable_cork +[`writable.destroy()`]: stream.md#stream_writable_destroy_error +[`writable.destroyed`]: stream.md#stream_writable_destroyed +[`writable.uncork()`]: stream.md#stream_writable_uncork diff --git a/doc/api/http2.html b/doc/api/http2.html index 66231b1a71b5bf9b3fa37d56f90ea283ef2cbd8d..befa53bc99b134276e651862ea4c4ae50cb5128d 100644 --- a/doc/api/http2.html +++ b/doc/api/http2.html @@ -1,10 +1,10 @@ - + - - HTTP/2 | Node.js v12.22.7 Documentation + + HTTP/2 | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      -
      -

      Table of Contents

      - - -
      +
      -

      HTTP/2#

      +

      HTTP/2#

      + diff --git a/doc/api/module.json b/doc/api/module.json index e24be3c6a9ddd75dca65d8e5fdcef17583e599f2..846798fcd64aaecf08d1e3df972b8402d4f344b9 100644 --- a/doc/api/module.json +++ b/doc/api/module.json @@ -5,7 +5,13 @@ { "textRaw": "Modules: `module` API", "name": "modules:_`module`_api", - "introduced_in": "v0.3.7", + "introduced_in": "v12.20.0", + "meta": { + "added": [ + "v0.3.7" + ], + "changes": [] + }, "modules": [ { "textRaw": "The `Module` object", @@ -24,7 +30,7 @@ ], "changes": [] }, - "desc": "

      A list of the names of all modules provided by Node.js. Can be used to verify\nif a module is maintained by a third party or not.

      \n

      module in this context isn't the same object that's provided\nby the module wrapper. To access it, require the Module module:

      \n
      // module.mjs\n// In an ECMAScript module\nimport { builtinModules as builtin } from 'module';\n
      \n
      // module.cjs\n// In a CommonJS module\nconst builtin = require('module').builtinModules;\n
      " + "desc": "

      A list of the names of all modules provided by Node.js. Can be used to verify\nif a module is maintained by a third party or not.

      \n

      module in this context isn't the same object that's provided\nby the module wrapper. To access it, require the Module module:

      \n
      // module.mjs\n// In an ECMAScript module\nimport { builtinModules as builtin } from 'module';\n
      \n
      // module.cjs\n// In a CommonJS module\nconst builtin = require('module').builtinModules;\n
      " } ], "methods": [ @@ -56,7 +62,7 @@ ] } ], - "desc": "
      import { createRequire } from 'module';\nconst require = createRequire(import.meta.url);\n\n// sibling-module.js is a CommonJS module.\nconst siblingModule = require('./sibling-module');\n
      " + "desc": "
      import { createRequire } from 'module';\nconst require = createRequire(import.meta.url);\n\n// sibling-module.js is a CommonJS module.\nconst siblingModule = require('./sibling-module');\n
      " }, { "textRaw": "`module.createRequireFromPath(filename)`", @@ -108,7 +114,7 @@ "params": [] } ], - "desc": "

      The module.syncBuiltinESMExports() method updates all the live bindings for\nbuiltin ES Modules to match the properties of the CommonJS exports. It\ndoes not add or remove exported names from the ES Modules.

      \n
      const fs = require('fs');\nconst { syncBuiltinESMExports } = require('module');\n\nfs.readFile = null;\n\ndelete fs.readFileSync;\n\nfs.newAPI = function newAPI() {\n  // ...\n};\n\nsyncBuiltinESMExports();\n\nimport('fs').then((esmFS) => {\n  assert.strictEqual(esmFS.readFile, null);\n  assert.strictEqual('readFileSync' in fs, true);\n  assert.strictEqual(esmFS.newAPI, undefined);\n});\n
      " + "desc": "

      The module.syncBuiltinESMExports() method updates all the live bindings for\nbuiltin ES Modules to match the properties of the CommonJS exports. It\ndoes not add or remove exported names from the ES Modules.

      \n
      const fs = require('fs');\nconst assert = require('assert');\nconst { syncBuiltinESMExports } = require('module');\n\nfs.readFile = newAPI;\n\ndelete fs.readFileSync;\n\nfunction newAPI() {\n  // ...\n}\n\nfs.newAPI = newAPI;\n\nsyncBuiltinESMExports();\n\nimport('fs').then((esmFS) => {\n  // It syncs the existing readFile property with the new value\n  assert.strictEqual(esmFS.readFile, newAPI);\n  // readFileSync has been deleted from the required fs\n  assert.strictEqual('readFileSync' in fs, false);\n  // syncBuiltinESMExports() does not remove readFileSync from esmFS\n  assert.strictEqual('readFileSync' in esmFS, true);\n  // syncBuiltinESMExports() does not add names\n  assert.strictEqual(esmFS.newAPI, undefined);\n});\n
      " } ], "type": "module", @@ -126,10 +132,10 @@ }, "stability": 1, "stabilityText": "Experimental", - "desc": "

      Helpers for interacting with the source map cache. This cache is\npopulated when source map parsing is enabled and\nsource map include directives are found in a modules' footer.

      \n

      To enable source map parsing, Node.js must be run with the flag\n--enable-source-maps, or with code coverage enabled by setting\nNODE_V8_COVERAGE=dir.

      \n
      // module.mjs\n// In an ECMAScript module\nimport { findSourceMap, SourceMap } from 'module';\n
      \n
      // module.cjs\n// In a CommonJS module\nconst { findSourceMap, SourceMap } = require('module');\n
      ", + "desc": "

      Helpers for interacting with the source map cache. This cache is\npopulated when source map parsing is enabled and\nsource map include directives are found in a modules' footer.

      \n

      To enable source map parsing, Node.js must be run with the flag\n--enable-source-maps, or with code coverage enabled by setting\nNODE_V8_COVERAGE=dir.

      \n
      // module.mjs\n// In an ECMAScript module\nimport { findSourceMap, SourceMap } from 'module';\n
      \n
      // module.cjs\n// In a CommonJS module\nconst { findSourceMap, SourceMap } = require('module');\n
      \n\n

      ", "methods": [ { - "textRaw": "`module.findSourceMap(path[, error])`", + "textRaw": "`module.findSourceMap(path)`", "type": "method", "name": "findSourceMap", "meta": { @@ -151,16 +157,11 @@ "textRaw": "`path` {string}", "name": "path", "type": "string" - }, - { - "textRaw": "`error` {Error}", - "name": "error", - "type": "Error" } ] } ], - "desc": "

      path is the resolved path for the file for which a corresponding source map\nshould be fetched.

      \n

      The error instance should be passed as the second parameter to findSourceMap\nin exceptional flows, such as when an overridden\nError.prepareStackTrace(error, trace) is invoked. Modules are not added to\nthe module cache until they are successfully loaded. In these cases, source maps\nare associated with the error instance along with the path.

      " + "desc": "

      path is the resolved path for the file for which a corresponding source map\nshould be fetched.

      " } ], "classes": [ @@ -209,7 +210,7 @@ ] } ], - "desc": "

      Given a line number and column number in the generated source file, returns\nan object representing the position in the original file. The object returned\nconsists of the following keys:

      \n" + "desc": "

      Given a line number and column number in the generated source file, returns\nan object representing the position in the original file. The object returned\nconsists of the following keys:

      \n" } ], "signatures": [ diff --git a/doc/api/module.md b/doc/api/module.md index d0d454ba69714957ef50162a35b4c62483396ace..65744b68d95a8e694e69e354acf89a9dd19ee41c 100644 --- a/doc/api/module.md +++ b/doc/api/module.md @@ -1,6 +1,9 @@ # Modules: `module` API - + + ## The `Module` object @@ -26,13 +29,13 @@ if a module is maintained by a third party or not. `module` in this context isn't the same object that's provided by the [module wrapper][]. To access it, require the `Module` module: -```js +```mjs // module.mjs // In an ECMAScript module import { builtinModules as builtin } from 'module'; ``` -```js +```cjs // module.cjs // In a CommonJS module const builtin = require('module').builtinModules; @@ -48,7 +51,7 @@ added: v12.2.0 string. * Returns: {require} Require function -```js +```mjs import { createRequire } from 'module'; const require = createRequire(import.meta.url); @@ -87,21 +90,29 @@ does not add or remove exported names from the [ES Modules][]. ```js const fs = require('fs'); +const assert = require('assert'); const { syncBuiltinESMExports } = require('module'); -fs.readFile = null; +fs.readFile = newAPI; delete fs.readFileSync; -fs.newAPI = function newAPI() { +function newAPI() { // ... -}; +} + +fs.newAPI = newAPI; syncBuiltinESMExports(); import('fs').then((esmFS) => { - assert.strictEqual(esmFS.readFile, null); - assert.strictEqual('readFileSync' in fs, true); + // It syncs the existing readFile property with the new value + assert.strictEqual(esmFS.readFile, newAPI); + // readFileSync has been deleted from the required fs + assert.strictEqual('readFileSync' in fs, false); + // syncBuiltinESMExports() does not remove readFileSync from esmFS + assert.strictEqual('readFileSync' in esmFS, true); + // syncBuiltinESMExports() does not add names assert.strictEqual(esmFS.newAPI, undefined); }); ``` @@ -123,19 +134,22 @@ To enable source map parsing, Node.js must be run with the flag [`--enable-source-maps`][], or with code coverage enabled by setting [`NODE_V8_COVERAGE=dir`][]. -```js +```mjs // module.mjs // In an ECMAScript module import { findSourceMap, SourceMap } from 'module'; ``` -```js +```cjs // module.cjs // In a CommonJS module const { findSourceMap, SourceMap } = require('module'); ``` -### `module.findSourceMap(path[, error])` + + +### `module.findSourceMap(path)` + * `path` {string} -* `error` {Error} * Returns: {module.SourceMap} `path` is the resolved path for the file for which a corresponding source map should be fetched. -The `error` instance should be passed as the second parameter to `findSourceMap` -in exceptional flows, such as when an overridden -[`Error.prepareStackTrace(error, trace)`][] is invoked. Modules are not added to -the module cache until they are successfully loaded. In these cases, source maps -are associated with the `error` instance along with the `path`. - ### Class: `module.SourceMap` +
      const assert = require('assert');
      +const realFs = require('fs');
      +
      +const fakeFs = {};
      +require.cache.fs = { exports: fakeFs };
      +
      +assert.strictEqual(require('fs'), fakeFs);
      +assert.strictEqual(require('node:fs'), realFs);
      +
      require.extensions#
      @@ -695,14 +731,14 @@ going to receive the native module anymore. Use with care!

      Instruct require on how to handle certain file extensions.

      Process files with the extension .sjs as .js:

      -
      require.extensions['.sjs'] = require.extensions['.js'];
      +
      require.extensions['.sjs'] = require.extensions['.js'];

      Deprecated. In the past, this list has been used to load non-JavaScript modules into Node.js by compiling them on-demand. However, in practice, there are much better ways to do this, such as loading modules via some other Node.js program, or compiling them to JavaScript ahead of time.

      Avoid using require.extensions. Use could cause subtle bugs and resolving the extensions gets slower with each registered extension.

      -

      require.main#

      +
      require.main#
      @@ -713,10 +749,10 @@ extensions gets slower with each registered extension.

      process launched. See "Accessing the main module".

      In entry.js script:

      -
      console.log(require.main);
      +
      console.log(require.main);
      node entry.js
      -
      Module {
      +
      Module {
         id: '.',
         path: '/absolute/path/to',
         exports: {},
      @@ -729,7 +765,7 @@ See "Accessing the main module"
            '/absolute/path/node_modules',
            '/absolute/node_modules',
            '/node_modules' ] }
      -

      require.resolve(request[, options])#

      +
      require.resolve(request[, options])#
      // addon.c
      -#include "addon.h"
      +#include "addon.h"
       
      -#define NAPI_CALL(env, call)                                      \
      +#define NAPI_CALL(env, call)                                      \
         do {                                                            \
           napi_status status = (call);                                  \
      -    if (status != napi_ok) {                                      \
      +    if (status != napi_ok) {                                      \
             const napi_extended_error_info* error_info = NULL;          \
             napi_get_last_error_info((env), &error_info);               \
             bool is_pending;                                            \
             napi_is_exception_pending((env), &is_pending);              \
      -      if (!is_pending) {                                          \
      +      if (!is_pending) {                                          \
               const char* message = (error_info->error_message == NULL) \
      -            ? "empty error message"                               \
      +            ? "empty error message"                               \
                   : error_info->error_message;                          \
               napi_throw_error((env), NULL, message);                   \
               return NULL;                                              \
      @@ -770,13 +798,13 @@ addon is loaded into a Node.js environment.

      } \ } while(0)
      -static napi_value -DoSomethingUseful(napi_env env, napi_callback_info info) { +static napi_value +DoSomethingUseful(napi_env env, napi_callback_info info) { // Do something useful. return NULL; } -napi_value create_addon(napi_env env) { +napi_value create_addon(napi_env env) { napi_value result; NAPI_CALL(env, napi_create_object(env, &result)); @@ -796,8 +824,8 @@ addon is loaded into a Node.js environment.

      return result; }
      // addon_node.c
      -#include <node_api.h>
      -#include "addon.h"
      +#include <node_api.h>
      +#include "addon.h"
       
       NAPI_MODULE_INIT() {
         // This function body is expected to return a `napi_value`.
      @@ -805,7 +833,7 @@ NAPI_MODULE_INIT() {
         // the body, as they are provided by the definition of `NAPI_MODULE_INIT()`.
         return create_addon(env);
       }
      -

      Environment life cycle APIs#

      +

      Environment life cycle APIs#

      Section 8.7 of the ECMAScript Language Specification defines the concept of an "Agent" as a self-contained environment in which JavaScript code runs. Multiple such Agents may be started and terminated either concurrently or in @@ -824,19 +852,19 @@ multiple threads.

      Native addons may need to allocate global state which they use during their entire life cycle such that the state must be unique to each instance of the addon.

      -

      To this end, N-API provides a way to allocate data such that its life cycle is -tied to the life cycle of the Agent.

      -

      napi_set_instance_data#

      +

      To this end, Node-API provides a way to allocate data such that its life cycle +is tied to the life cycle of the Agent.

      +

      napi_set_instance_data#

      -
      napi_status napi_set_instance_data(napi_env env,
      -                                   void* data,
      +
      napi_status napi_set_instance_data(napi_env env,
      +                                   void* data,
                                          napi_finalize finalize_cb,
      -                                   void* finalize_hint);
      + void* finalize_hint)
      ;
        -
      • [in] env: The environment that the N-API call is invoked under.
      • +
      • [in] env: The environment that the Node-API call is invoked under.
      • [in] data: The data item to make available to bindings of this instance.
      • [in] finalize_cb: The function to call when the environment is being torn down. The function receives data so that it might free it. @@ -850,15 +878,15 @@ be retrieved using napi_get_instance_data(). Any existing data asso the currently running Agent which was set by means of a previous call to napi_set_instance_data() will be overwritten. If a finalize_cb was provided by the previous call, it will not be called.

        -

        napi_get_instance_data#

        +

        napi_get_instance_data#

        -
        napi_status napi_get_instance_data(napi_env env,
        -                                   void** data);
        +
        napi_status napi_get_instance_data(napi_env env,
        +                                   void** data);
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [out] data: The data item that was previously associated with the currently running Agent by a call to napi_set_instance_data().
        @@ -866,18 +894,18 @@ running Agent by a call to napi_set_instance_data().
      • This API retrieves data that was previously associated with the currently running Agent via napi_set_instance_data(). If no data is set, the call will succeed and data will be set to NULL.

        -

        Basic N-API data types#

        -

        N-API exposes the following fundamental datatypes as abstractions that are +

      Basic Node-API data types#

      +

      Node-API exposes the following fundamental datatypes as abstractions that are consumed by the various APIs. These APIs should be treated as opaque, -introspectable only with other N-API calls.

      -

      napi_status#

      +introspectable only with other Node-API calls.

      +

      napi_status#

      -

      Integral status code indicating the success or failure of a N-API call. +

      Integral status code indicating the success or failure of a Node-API call. Currently, the following status codes are supported.

      -
      typedef enum {
      +
      typedef enum {
         napi_ok,
         napi_invalid_arg,
         napi_object_expected,
      @@ -899,18 +927,19 @@ Currently, the following status codes are supported.

      napi_date_expected, napi_arraybuffer_expected, napi_detachable_arraybuffer_expected, + napi_would_deadlock, /* unused */ } napi_status;

      If additional information is required upon an API returning a failed status, it can be obtained by calling napi_get_last_error_info.

      -

      napi_extended_error_info#

      +

      napi_extended_error_info#

      typedef struct {
      -  const char* error_message;
      -  void* engine_reserved;
      -  uint32_t engine_error_code;
      +  const char* error_message;
      +  void* engine_reserved;
      +  uint32_t engine_error_code;
         napi_status error_code;
       } napi_extended_error_info;
        @@ -920,24 +949,24 @@ the error. not implemented for any VM.
      • engine_error_code: VM-specific error code. This is currently not implemented for any VM.
      • -
      • error_code: The N-API status code that originated with the last error.
      • +
      • error_code: The Node-API status code that originated with the last error.

      See the Error handling section for additional information.

      -

      napi_env#

      -

      napi_env is used to represent a context that the underlying N-API +

      napi_env#

      +

      napi_env is used to represent a context that the underlying Node-API implementation can use to persist VM-specific state. This structure is passed to native functions when they're invoked, and it must be passed back when -making N-API calls. Specifically, the same napi_env that was passed in when +making Node-API calls. Specifically, the same napi_env that was passed in when the initial native function was called must be passed to any subsequent -nested N-API calls. Caching the napi_env for the purpose of general reuse, +nested Node-API calls. Caching the napi_env for the purpose of general reuse, and passing the napi_env between instances of the same addon running on different Worker threads is not allowed. The napi_env becomes invalid when an instance of a native addon is unloaded. Notification of this event is delivered through the callbacks given to napi_add_env_cleanup_hook and napi_set_instance_data.

      -

      napi_value#

      +

      napi_value#

      This is an opaque pointer that is used to represent a JavaScript value.

      -

      napi_threadsafe_function#

      +

      napi_threadsafe_function#

      Error handling#

      +

      Node-API uses both return values and JavaScript exceptions for error handling. The following sections explain the approach for each case.

      -

      Return values#

      -

      All of the N-API functions share the same error handling pattern. The +

      Return values#

      +

      All of the Node-API functions share the same error handling pattern. The return type of all API functions is napi_status.

      The return value will be napi_ok if the request was successful and no uncaught JavaScript exception was thrown. If an error occurred AND @@ -1171,30 +1200,30 @@ The format of the napi_extended_error_info structure is as follows: N-API version: 1

      typedef struct napi_extended_error_info {
      -  const char* error_message;
      -  void* engine_reserved;
      -  uint32_t engine_error_code;
      +  const char* error_message;
      +  void* engine_reserved;
      +  uint32_t engine_error_code;
         napi_status error_code;
       };
      • error_message: Textual representation of the error that occurred.
      • engine_reserved: Opaque handle reserved for engine use only.
      • engine_error_code: VM specific error code.
      • -
      • error_code: n-api status code for the last error.
      • +
      • error_code: Node-API status code for the last error.

      napi_get_last_error_info returns the information for the last -N-API call that was made.

      +Node-API call that was made.

      Do not rely on the content or format of any of the extended information as it is not subject to SemVer and may change at any time. It is intended only for logging purposes.

      -

      napi_get_last_error_info#

      +
      napi_get_last_error_info#
      -
      napi_status
      -napi_get_last_error_info(napi_env env,
      -                         const napi_extended_error_info** result);
      +
      napi_status
      +napi_get_last_error_info(napi_env env,
      +                         const napi_extended_error_info** result);
      • [in] env: The environment that the API is invoked under.
      • [out] result: The napi_extended_error_info structure with more @@ -1204,13 +1233,13 @@ information about the error.
      • This API retrieves a napi_extended_error_info structure with information about the last error that occurred.

        The content of the napi_extended_error_info returned is only valid up until -an n-api function is called on the same env.

        +a Node-API function is called on the same env.

        Do not rely on the content or format of any of the extended information as it is not subject to SemVer and may change at any time. It is intended only for logging purposes.

        This API can be called even if there is a pending JavaScript exception.

        -

        Exceptions#

        -

        Any N-API function call may result in a pending JavaScript exception. This is +

        Exceptions#

        +

        Any Node-API function call may result in a pending JavaScript exception. This is the case for any of the API functions, even those that may not cause the execution of JavaScript.

        If the napi_status returned by a function is napi_ok then no @@ -1219,10 +1248,10 @@ exception is pending and no additional action is required. If the napi_pending_exception, in order to try to recover and continue instead of simply returning immediately, napi_is_exception_pending must be called in order to determine if an exception is pending or not.

        -

        In many cases when an N-API function is called and an exception is +

        In many cases when a Node-API function is called and an exception is already pending, the function will return immediately with a napi_status of napi_pending_exception. However, this is not the case -for all functions. N-API allows a subset of the functions to be +for all functions. Node-API allows a subset of the functions to be called to allow for some minimal cleanup before returning to JavaScript. In that case, napi_status will reflect the status for the function. It will not reflect previous pending exceptions. To avoid confusion, check @@ -1231,7 +1260,7 @@ the error status after every function call.

        The first approach is to do any appropriate cleanup and then return so that execution will return to JavaScript. As part of the transition back to JavaScript, the exception will be thrown at the point in the JavaScript -code where the native method was invoked. The behavior of most N-API calls +code where the native method was invoked. The behavior of most Node-API calls is unspecified while an exception is pending, and many will simply return napi_pending_exception, so do as little as possible and then return to JavaScript where the exception can be handled.

        @@ -1244,7 +1273,7 @@ clear the exception. On success, result will contain the handle to the last JavaScript Object thrown. If it is determined, after retrieving the exception, the exception cannot be handled after all it can be re-thrown it with napi_throw where error is the -JavaScript Error object to be thrown.

        +JavaScript value to be thrown.

        The following utility functions are also available in case native code needs to throw an exception or determine if a napi_value is an instance of a JavaScript Error object: napi_throw_error, @@ -1260,7 +1289,7 @@ generated internally. The goal is for applications to use these error codes for all error checking. The associated error messages will remain, but will only be meant to be used for logging and display with the expectation that the message can change without -SemVer applying. In order to support this model with N-API, both +SemVer applying. In order to support this model with Node-API, both in internal functionality and for module specific functionality (as its good practice), the throw_ and create_ functions take an optional code parameter which is the string for the code @@ -1272,26 +1301,26 @@ the name associated with the error is also updated to be:

        and code is the code that was provided. For example, if the code is 'ERR_ERROR_1' and a TypeError is being created the name will be:

        TypeError [ERR_ERROR_1]
        -

        napi_throw#

        +
        napi_throw#
        -
        NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error);
        +
        NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error);
        • [in] env: The environment that the API is invoked under.
        • [in] error: The JavaScript value to be thrown.

        Returns napi_ok if the API succeeded.

        This API throws the JavaScript value provided.

        -

        napi_throw_error#

        +
        napi_throw_error#
        -
        NAPI_EXTERN napi_status napi_throw_error(napi_env env,
        -                                         const char* code,
        -                                         const char* msg);
        +
        NAPI_EXTERN napi_status napi_throw_error(napi_env env,
        +                                         const char* code,
        +                                         const char* msg);
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional error code to be set on the error.
        • @@ -1299,14 +1328,14 @@ is 'ERR_ERROR_1' and a TypeError is being created the

        Returns napi_ok if the API succeeded.

        This API throws a JavaScript Error with the text provided.

        -

        napi_throw_type_error#

        +
        napi_throw_type_error#
        -
        NAPI_EXTERN napi_status napi_throw_type_error(napi_env env,
        -                                              const char* code,
        -                                              const char* msg);
        +
        NAPI_EXTERN napi_status napi_throw_type_error(napi_env env,
        +                                              const char* code,
        +                                              const char* msg);
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional error code to be set on the error.
        • @@ -1314,14 +1343,14 @@ is 'ERR_ERROR_1' and a TypeError is being created the

        Returns napi_ok if the API succeeded.

        This API throws a JavaScript TypeError with the text provided.

        -

        napi_throw_range_error#

        +
        napi_throw_range_error#
        -
        NAPI_EXTERN napi_status napi_throw_range_error(napi_env env,
        -                                               const char* code,
        -                                               const char* msg);
        +
        NAPI_EXTERN napi_status napi_throw_range_error(napi_env env,
        +                                               const char* code,
        +                                               const char* msg);
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional error code to be set on the error.
        • @@ -1329,14 +1358,14 @@ is 'ERR_ERROR_1' and a TypeError is being created the

        Returns napi_ok if the API succeeded.

        This API throws a JavaScript RangeError with the text provided.

        -

        napi_is_error#

        +
        napi_is_error#
        -
        NAPI_EXTERN napi_status napi_is_error(napi_env env,
        +
        NAPI_EXTERN napi_status napi_is_error(napi_env env,
                                               napi_value value,
        -                                      bool* result);
        + bool* result)
        ;
        • [in] env: The environment that the API is invoked under.
        • [in] value: The napi_value to be checked.
        • @@ -1345,112 +1374,112 @@ an error, false otherwise.

        Returns napi_ok if the API succeeded.

        This API queries a napi_value to check if it represents an error object.

        -

        napi_create_error#

        +
        napi_create_error#
        -
        NAPI_EXTERN napi_status napi_create_error(napi_env env,
        +
        NAPI_EXTERN napi_status napi_create_error(napi_env env,
                                                   napi_value code,
                                                   napi_value msg,
        -                                          napi_value* result);
        + napi_value* result)
        ;
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional napi_value with the string for the error code to be associated with the error.
        • -
        • [in] msg: napi_value that references a JavaScript String to be used as +
        • [in] msg: napi_value that references a JavaScript string to be used as the message for the Error.
        • [out] result: napi_value representing the error created.

        Returns napi_ok if the API succeeded.

        This API returns a JavaScript Error with the text provided.

        -

        napi_create_type_error#

        +
        napi_create_type_error#
        -
        NAPI_EXTERN napi_status napi_create_type_error(napi_env env,
        +
        NAPI_EXTERN napi_status napi_create_type_error(napi_env env,
                                                        napi_value code,
                                                        napi_value msg,
        -                                               napi_value* result);
        + napi_value* result)
        ;
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional napi_value with the string for the error code to be associated with the error.
        • -
        • [in] msg: napi_value that references a JavaScript String to be used as +
        • [in] msg: napi_value that references a JavaScript string to be used as the message for the Error.
        • [out] result: napi_value representing the error created.

        Returns napi_ok if the API succeeded.

        This API returns a JavaScript TypeError with the text provided.

        -

        napi_create_range_error#

        +
        napi_create_range_error#
        -
        NAPI_EXTERN napi_status napi_create_range_error(napi_env env,
        +
        NAPI_EXTERN napi_status napi_create_range_error(napi_env env,
                                                         napi_value code,
                                                         napi_value msg,
        -                                                napi_value* result);
        + napi_value* result)
        ;
        • [in] env: The environment that the API is invoked under.
        • [in] code: Optional napi_value with the string for the error code to be associated with the error.
        • -
        • [in] msg: napi_value that references a JavaScript String to be used as +
        • [in] msg: napi_value that references a JavaScript string to be used as the message for the Error.
        • [out] result: napi_value representing the error created.

        Returns napi_ok if the API succeeded.

        This API returns a JavaScript RangeError with the text provided.

        -

        napi_get_and_clear_last_exception#

        +
        napi_get_and_clear_last_exception#
        -
        napi_status napi_get_and_clear_last_exception(napi_env env,
        -                                              napi_value* result);
        +
        napi_status napi_get_and_clear_last_exception(napi_env env,
        +                                              napi_value* result);
        • [in] env: The environment that the API is invoked under.
        • [out] result: The exception if one is pending, NULL otherwise.

        Returns napi_ok if the API succeeded.

        This API can be called even if there is a pending JavaScript exception.

        -

        napi_is_exception_pending#

        +
        napi_is_exception_pending#
        -
        napi_status napi_is_exception_pending(napi_env env, bool* result);
        +
        napi_status napi_is_exception_pending(napi_env env, bool* result);
        • [in] env: The environment that the API is invoked under.
        • [out] result: Boolean value that is set to true if an exception is pending.

        Returns napi_ok if the API succeeded.

        This API can be called even if there is a pending JavaScript exception.

        -

        napi_fatal_exception#

        +
        napi_fatal_exception#
        -
        napi_status napi_fatal_exception(napi_env env, napi_value err);
        +
        napi_status napi_fatal_exception(napi_env env, napi_value err);
        • [in] env: The environment that the API is invoked under.
        • [in] err: The error that is passed to 'uncaughtException'.

        Trigger an 'uncaughtException' in JavaScript. Useful if an async callback throws an exception with no way to recover.

        -

        Fatal errors#

        +

        Fatal errors#

        In the event of an unrecoverable error in a native module, a fatal error can be thrown to immediately terminate the process.

        -

        napi_fatal_error#

        +
        napi_fatal_error#
        -
        NAPI_NO_RETURN void napi_fatal_error(const char* location,
        -                                                 size_t location_len,
        -                                                 const char* message,
        -                                                 size_t message_len);
        +
        NAPI_NO_RETURN void napi_fatal_error(const char* location,
        +                                     size_t location_len,
        +                                     const char* message,
        +                                     size_t message_len);
        • [in] location: Optional location at which the error occurred.
        • [in] location_len: The length of the location in bytes, or @@ -1461,8 +1490,8 @@ if it is null-terminated.

        The function call does not return, the process will be terminated.

        This API can be called even if there is a pending JavaScript exception.

        -

        Object lifetime management#

        -

        As N-API calls are made, handles to objects in the heap for the underlying +

        Object lifetime management#

        +

        As Node-API calls are made, handles to objects in the heap for the underlying VM may be returned as napi_values. These handles must hold the objects 'live' until they are no longer required by the native code, otherwise the objects could be collected before the native code was @@ -1474,13 +1503,13 @@ remain valid and the objects associated with these handles will be held live for the lifespan of the native method call.

        In many cases, however, it is necessary that the handles remain valid for either a shorter or longer lifespan than that of the native method. -The sections which follow describe the N-API functions that can be used +The sections which follow describe the Node-API functions that can be used to change the handle lifespan from the default.

        -

        Making handle lifespan shorter than that of the native method#

        +

        Making handle lifespan shorter than that of the native method#

        It is often necessary to make the lifespan of handles shorter than the lifespan of a native method. For example, consider a native method that has a loop which iterates through the elements in a large array:

        -
        for (int i = 0; i < 1000000; i++) {
        +
        for (int i = 0; i < 1000000; i++) {
           napi_value result;
           napi_status status = napi_get_element(env, object, i, &result);
           if (status != napi_ok) {
        @@ -1492,12 +1521,12 @@ that has a loop which iterates through the elements in a large array:

        substantial resources. In addition, even though the native code could only use the most recent handle, all of the associated objects would also be kept alive since they all share the same scope.

        -

        To handle this case, N-API provides the ability to establish a new 'scope' to +

        To handle this case, Node-API provides the ability to establish a new 'scope' to which newly created handles will be associated. Once those handles are no longer required, the scope can be 'closed' and any handles associated with the scope are invalidated. The methods available to open/close scopes are napi_open_handle_scope and napi_close_handle_scope.

        -

        N-API only supports a single nested hierarchy of scopes. There is only one +

        Node-API only supports a single nested hierarchy of scopes. There is only one active scope at any time, and all new handles will be associated with that scope while it is active. Scopes must be closed in the reverse order from which they are opened. In addition, all scopes created within a native method @@ -1505,7 +1534,7 @@ must be closed before returning from that method.

        Taking the earlier example, adding calls to napi_open_handle_scope and napi_close_handle_scope would ensure that at most a single handle is valid throughout the execution of the loop:

        -
        for (int i = 0; i < 1000000; i++) {
        +
        for (int i = 0; i < 1000000; i++) {
           napi_handle_scope scope;
           napi_status status = napi_open_handle_scope(env, &scope);
           if (status != napi_ok) {
        @@ -1523,8 +1552,8 @@ is valid throughout the execution of the loop:

        } }

        When nesting scopes, there are cases where a handle from an -inner scope needs to live beyond the lifespan of that scope. N-API supports an -'escapable scope' in order to support this case. An escapable scope +inner scope needs to live beyond the lifespan of that scope. Node-API supports +an 'escapable scope' in order to support this case. An escapable scope allows one handle to be 'promoted' so that it 'escapes' the current scope and the lifespan of the handle changes from the current scope to that of the outer scope.

        @@ -1533,26 +1562,26 @@ scope to that of the outer scope.

        napi_close_escapable_handle_scope.

        The request to promote a handle is made through napi_escape_handle which can only be called once.

        -

        napi_open_handle_scope#

        +
        napi_open_handle_scope#
        -
        NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env,
        -                                               napi_handle_scope* result);
        +
        NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env,
        +                                               napi_handle_scope* result);
        • [in] env: The environment that the API is invoked under.
        • [out] result: napi_value representing the new scope.

        Returns napi_ok if the API succeeded.

        This API opens a new scope.

        -

        napi_close_handle_scope#

        +
        napi_close_handle_scope#
        -
        NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env,
        -                                                napi_handle_scope scope);
        +
        NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env,
        +                                                napi_handle_scope scope);
        • [in] env: The environment that the API is invoked under.
        • [in] scope: napi_value representing the scope to be closed.
        • @@ -1561,14 +1590,14 @@ can only be called once.

          This API closes the scope passed in. Scopes must be closed in the reverse order from which they were created.

          This API can be called even if there is a pending JavaScript exception.

          -

          napi_open_escapable_handle_scope#

          +
          napi_open_escapable_handle_scope#
          -
          NAPI_EXTERN napi_status
          -    napi_open_escapable_handle_scope(napi_env env,
          -                                     napi_handle_scope* result);
          +
          NAPI_EXTERN napi_status
          +    napi_open_escapable_handle_scope(napi_env env,
          +                                     napi_handle_scope* result);
          • [in] env: The environment that the API is invoked under.
          • [out] result: napi_value representing the new scope.
          • @@ -1576,14 +1605,14 @@ reverse order from which they were created.

            Returns napi_ok if the API succeeded.

            This API opens a new scope from which one object can be promoted to the outer scope.

            -

            napi_close_escapable_handle_scope#

            +
            napi_close_escapable_handle_scope#
            -
            NAPI_EXTERN napi_status
            -    napi_close_escapable_handle_scope(napi_env env,
            -                                      napi_handle_scope scope);
            +
            NAPI_EXTERN napi_status
            +    napi_close_escapable_handle_scope(napi_env env,
            +                                      napi_handle_scope scope);
            • [in] env: The environment that the API is invoked under.
            • [in] scope: napi_value representing the scope to be closed.
            • @@ -1592,15 +1621,15 @@ to the outer scope.

              This API closes the scope passed in. Scopes must be closed in the reverse order from which they were created.

              This API can be called even if there is a pending JavaScript exception.

              -

              napi_escape_handle#

              +
              napi_escape_handle#
              -
              napi_status napi_escape_handle(napi_env env,
              +
              napi_status napi_escape_handle(napi_env env,
                                              napi_escapable_handle_scope scope,
                                              napi_value escapee,
              -                               napi_value* result);
              + napi_value* result)
              ;
              • [in] env: The environment that the API is invoked under.
              • [in] scope: napi_value representing the current scope.
              • @@ -1614,7 +1643,7 @@ in the outer scope. for the lifetime of the outer scope. It can only be called once per scope. If it is called more than once an error will be returned.

                This API can be called even if there is a pending JavaScript exception.

                -

                References to objects with a lifespan longer than that of the native method#

                +

                References to objects with a lifespan longer than that of the native method#

                In some cases an addon will need to be able to create and reference objects with a lifespan longer than that of a single native method invocation. For example, to create a constructor and later use that constructor @@ -1624,7 +1653,7 @@ would not be possible with a normal handle returned as a napi_value described in the earlier section. The lifespan of a normal handle is managed by scopes and all scopes must be closed before the end of a native method.

                -

                N-API provides methods to create persistent references to an object. +

                Node-API provides methods to create persistent references to an object. Each persistent reference has an associated count with a value of 0 or higher. The count determines if the reference will keep the corresponding object live. References with a count of 0 do not @@ -1638,24 +1667,24 @@ for a reference is 0, all subsequent calls to get the object associated with the reference napi_get_reference_value will return NULL for the returned napi_value. An attempt to call napi_reference_ref for a reference whose object has been collected -will result in an error.

                +results in an error.

                References must be deleted once they are no longer required by the addon. When -a reference is deleted it will no longer prevent the corresponding object from -being collected. Failure to delete a persistent reference will result in +a reference is deleted, it will no longer prevent the corresponding object from +being collected. Failure to delete a persistent reference results in a 'memory leak' with both the native memory for the persistent reference and the corresponding object on the heap being retained forever.

                There can be multiple persistent references created which refer to the same object, each of which will either keep the object live or not based on its individual count.

                -

                napi_create_reference#

                +
                napi_create_reference#
                -
                NAPI_EXTERN napi_status napi_create_reference(napi_env env,
                +
                NAPI_EXTERN napi_status napi_create_reference(napi_env env,
                                                               napi_value value,
                -                                              uint32_t initial_refcount,
                -                                              napi_ref* result);
                + uint32_t initial_refcount, + napi_ref* result)
                ;
                • [in] env: The environment that the API is invoked under.
                • [in] value: napi_value representing the Object to which we want a @@ -1666,12 +1695,12 @@ reference.
                • Returns napi_ok if the API succeeded.

                  This API create a new reference with the specified reference count to the Object passed in.

                  -

                  napi_delete_reference#

                  +
                  napi_delete_reference#
                  -
                  NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref);
                  +
                  NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref);
                  • [in] env: The environment that the API is invoked under.
                  • [in] ref: napi_ref to be deleted.
                  • @@ -1679,14 +1708,14 @@ to the Object passed in.

                    Returns napi_ok if the API succeeded.

                    This API deletes the reference passed in.

                    This API can be called even if there is a pending JavaScript exception.

                    -

                    napi_reference_ref#

                    +
                    napi_reference_ref#
                    -
                    NAPI_EXTERN napi_status napi_reference_ref(napi_env env,
                    +
                    NAPI_EXTERN napi_status napi_reference_ref(napi_env env,
                                                                napi_ref ref,
                    -                                           uint32_t* result);
                    + uint32_t* result)
                    ;
                    • [in] env: The environment that the API is invoked under.
                    • [in] ref: napi_ref for which the reference count will be incremented.
                    • @@ -1695,14 +1724,14 @@ to the Object passed in.

                      Returns napi_ok if the API succeeded.

                      This API increments the reference count for the reference passed in and returns the resulting reference count.

                      -

                      napi_reference_unref#

                      +
                      napi_reference_unref#
                      -
                      NAPI_EXTERN napi_status napi_reference_unref(napi_env env,
                      +
                      NAPI_EXTERN napi_status napi_reference_unref(napi_env env,
                                                                    napi_ref ref,
                      -                                             uint32_t* result);
                      + uint32_t* result)
                      ;
                      • [in] env: The environment that the API is invoked under.
                      • [in] ref: napi_ref for which the reference count will be decremented.
                      • @@ -1711,14 +1740,14 @@ passed in and returns the resulting reference count.

                        Returns napi_ok if the API succeeded.

                        This API decrements the reference count for the reference passed in and returns the resulting reference count.

                        -

                        napi_get_reference_value#

                        +
                        napi_get_reference_value#
                        -
                        NAPI_EXTERN napi_status napi_get_reference_value(napi_env env,
                        +
                        NAPI_EXTERN napi_status napi_get_reference_value(napi_env env,
                                                                          napi_ref ref,
                        -                                                 napi_value* result);
                        + napi_value* result)
                        ;

                        the napi_value passed in or out of these methods is a handle to the object to which the reference is related.

                          @@ -1731,21 +1760,21 @@ object to which the reference is related.

                          If still valid, this API returns the napi_value representing the JavaScript Object associated with the napi_ref. Otherwise, result will be NULL.

                          -

                          Cleanup on exit of the current Node.js instance#

                          +

                          Cleanup on exit of the current Node.js instance#

                          While a Node.js process typically releases all its resources when exiting, embedders of Node.js, or future Worker support, may require addons to register clean-up hooks that will be run once the current Node.js instance exits.

                          -

                          N-API provides functions for registering and un-registering such callbacks. +

                          Node-API provides functions for registering and un-registering such callbacks. When those callbacks are run, all resources that are being held by the addon should be freed up.

                          -

                          napi_add_env_cleanup_hook#

                          +
                          napi_add_env_cleanup_hook#
                          -
                          NODE_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env,
                          -                                                  void (*fun)(void* arg),
                          -                                                  void* arg);
                          +
                          NODE_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env,
                          +                                                  void (*fun)(void* arg),
                          +                                                  void* arg);

                          Registers fun as a function to be run with the arg parameter once the current Node.js environment exits.

                          A function can safely be specified multiple times with different @@ -1758,37 +1787,37 @@ will be called first.

                          Typically, that happens when the resource for which this hook was added is being torn down anyway.

                          For asynchronous cleanup, napi_add_async_cleanup_hook is available.

                          -

                          napi_remove_env_cleanup_hook#

                          +
                          napi_remove_env_cleanup_hook#
                          -
                          NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env,
                          -                                                     void (*fun)(void* arg),
                          -                                                     void* arg);
                          +
                          NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env,
                          +                                                     void (*fun)(void* arg),
                          +                                                     void* arg);

                          Unregisters fun as a function to be run with the arg parameter once the current Node.js environment exits. Both the argument and the function value need to be exact matches.

                          The function must have originally been registered with napi_add_env_cleanup_hook, otherwise the process will abort.

                          -

                          napi_add_async_cleanup_hook#

                          +
                          napi_add_async_cleanup_hook#
                          -
                          NAPI_EXTERN napi_status napi_add_async_cleanup_hook(
                          +
                          NAPI_EXTERN napi_status napi_add_async_cleanup_hook(
                               napi_env env,
                               napi_async_cleanup_hook hook,
                          -    void* arg,
                          -    napi_async_cleanup_hook_handle* remove_handle);
                          + void* arg, + napi_async_cleanup_hook_handle* remove_handle)
                          ;

        Module registration#

        +

        Node-API modules are registered in a manner similar to other modules except that instead of using the NODE_MODULE macro the following is used:

        NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
        -

        The next difference is the signature for the Init method. For a N-API +

        The next difference is the signature for the Init method. For a Node-API module it is as follows:

        -
        napi_value Init(napi_env env, napi_value exports);
        +
        napi_value Init(napi_env env, napi_value exports);

        The return value from Init is treated as the exports object for the module. The Init method is passed an empty object via the exports parameter as a convenience. If Init returns NULL, the parameter passed as exports is -exported by the module. N-API modules cannot modify the module object but can -specify anything as the exports property of the module.

        +exported by the module. Node-API modules cannot modify the module object but +can specify anything as the exports property of the module.

        To add the method hello as a function so that it can be called as a method provided by the addon:

        -
        napi_value Init(napi_env env, napi_value exports) {
        +
        napi_value Init(napi_env env, napi_value exports) {
           napi_status status;
           napi_property_descriptor desc = {
             "hello",
        @@ -1860,7 +1889,7 @@ provided by the addon:

        return exports; }

        To set a function to be returned by the require() for the addon:

        -
        napi_value Init(napi_env env, napi_value exports) {
        +
        napi_value Init(napi_env env, napi_value exports) {
           napi_value method;
           napi_status status;
           status = napi_create_function(env, "exports", NAPI_AUTO_LENGTH, Method, NULL, &method);
        @@ -1870,7 +1899,7 @@ provided by the addon:

        To define a class so that new instances can be created (often used with Object wrap):

        // NOTE: partial example, not all referenced code is included
        -napi_value Init(napi_env env, napi_value exports) {
        +napi_value Init(napi_env env, napi_value exports) {
           napi_status status;
           napi_property_descriptor properties[] = {
             { "value", NULL, NULL, GetValue, SetValue, NULL, napi_writable | napi_configurable, NULL },
        @@ -1891,8 +1920,8 @@ provided by the addon:

        return exports; }
        -

        If the module will be loaded multiple times during the lifetime of the Node.js -process, use the NAPI_MODULE_INIT macro to initialize the module:

        +

        You can also use the NAPI_MODULE_INIT macro, which acts as a shorthand +for NAPI_MODULE and defining an Init function:

        NAPI_MODULE_INIT() {
           napi_value answer;
           napi_status result;
        @@ -1905,41 +1934,38 @@ process, use the NAPI_MODULE_INIT macro to initialize the module:return exports;
         }
        -

        This macro includes NAPI_MODULE, and declares an Init function with a -special name and with visibility beyond the addon. This will allow Node.js to -initialize the module even if it is loaded multiple times.

        -

        There are a few design considerations when declaring a module that may be loaded -multiple times. The documentation of context-aware addons provides more -details.

        +

        All Node-API addons are context-aware, meaning they may be loaded multiple +times. There are a few design considerations when declaring such a module. +The documentation on context-aware addons provides more details.

        The variables env and exports will be available inside the function body following the macro invocation.

        For more details on setting properties on objects, see the section on Working with JavaScript properties.

        For more details on building addon modules in general, refer to the existing API.

        -

        Working with JavaScript values#

        -

        N-API exposes a set of APIs to create all types of JavaScript values. +

        Working with JavaScript values#

        +

        Node-API exposes a set of APIs to create all types of JavaScript values. Some of these types are documented under Section 6 of the ECMAScript Language Specification.

        Fundamentally, these APIs are used to do one of the following:

        1. Create a new JavaScript object
        2. -
        3. Convert from a primitive C type to an N-API value
        4. -
        5. Convert from N-API value to a primitive C type
        6. +
        7. Convert from a primitive C type to a Node-API value
        8. +
        9. Convert from Node-API value to a primitive C type
        10. Get global instances including undefined and null
        -

        N-API values are represented by the type napi_value. -Any N-API call that requires a JavaScript value takes in a napi_value. +

        Node-API values are represented by the type napi_value. +Any Node-API call that requires a JavaScript value takes in a napi_value. In some cases, the API does check the type of the napi_value up-front. However, for better performance, it's better for the caller to make sure that the napi_value in question is of the JavaScript type expected by the API.

        -

        Enum types#

        -

        napi_key_collection_mode#

        +

        Enum types#

        +
        napi_key_collection_mode#
        -
        typedef enum {
        +
        typedef enum {
           napi_key_include_prototypes,
           napi_key_own_only
         } napi_key_collection_mode;
        @@ -1948,12 +1974,12 @@ the napi_value in question is of the JavaScript type expected by th

        napi_key_own_only limits the collected properties to the given object only. napi_key_include_prototypes will include all keys of the objects's prototype chain as well.

        -

        napi_key_filter#

        +
        napi_key_filter#
        -
        typedef enum {
        +
        typedef enum {
           napi_key_all_properties = 0,
           napi_key_writable = 1,
           napi_key_enumerable = 1 << 1,
        @@ -1962,20 +1988,20 @@ of the objects's prototype chain as well.

        napi_key_skip_symbols = 1 << 4 } napi_key_filter;

        Property filter bits. They can be or'ed to build a composite filter.

        -

        napi_key_conversion#

        +
        napi_key_conversion#
        -
        typedef enum {
        +
        typedef enum {
           napi_key_keep_numbers,
           napi_key_numbers_to_strings
         } napi_key_conversion;

        napi_key_numbers_to_strings will convert integer indices to strings. napi_key_keep_numbers will return numbers for integer indices.

        -

        napi_valuetype#

        -
        typedef enum {
        +
        napi_valuetype#
        +
        typedef enum {
           // ES6 types (corresponds to typeof)
           napi_undefined,
           napi_null,
        @@ -1994,8 +2020,8 @@ In addition to types in that section, napi_valuetype can also repre
         Functions and Objects with external data.

        A JavaScript value of type napi_external appears in JavaScript as a plain object such that no properties can be set on it, and no prototype.

        -

        napi_typedarray_type#

        -
        typedef enum {
        +
        napi_typedarray_type#
        +
        typedef enum {
           napi_int8_array,
           napi_uint8_array,
           napi_uint8_clamped_array,
        @@ -2011,36 +2037,36 @@ object such that no properties can be set on it, and no prototype.

        This represents the underlying binary scalar datatype of the TypedArray. Elements of this enum correspond to Section 22.2 of the ECMAScript Language Specification.

        -

        Object creation functions#

        -

        napi_create_array#

        +

        Object creation functions#

        +
        napi_create_array#
        -
        napi_status napi_create_array(napi_env env, napi_value* result)
        +
        napi_status napi_create_array(napi_env env, napi_value* result)
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [out] result: A napi_value representing a JavaScript Array.

        Returns napi_ok if the API succeeded.

        -

        This API returns an N-API value corresponding to a JavaScript Array type. +

        This API returns a Node-API value corresponding to a JavaScript Array type. JavaScript arrays are described in Section 22.1 of the ECMAScript Language Specification.

        -

        napi_create_array_with_length#

        +
        napi_create_array_with_length#
        -
        napi_status napi_create_array_with_length(napi_env env,
        -                                          size_t length,
        -                                          napi_value* result)
        +
        napi_status napi_create_array_with_length(napi_env env,
        +                                          size_t length,
        +                                          napi_value* result)
        • [in] env: The environment that the API is invoked under.
        • [in] length: The initial length of the Array.
        • [out] result: A napi_value representing a JavaScript Array.

        Returns napi_ok if the API succeeded.

        -

        This API returns an N-API value corresponding to a JavaScript Array type. +

        This API returns a Node-API value corresponding to a JavaScript Array type. The Array's length property is set to the passed-in length parameter. However, the underlying buffer is not guaranteed to be pre-allocated by the VM when the array is created. That behavior is left to the underlying VM @@ -2049,15 +2075,15 @@ directly read and/or written via C, consider using napi_create_external_arraybuffer.

        JavaScript arrays are described in Section 22.1 of the ECMAScript Language Specification.

        -

        napi_create_arraybuffer#

        +
        napi_create_arraybuffer#
        -
        napi_status napi_create_arraybuffer(napi_env env,
        -                                    size_t byte_length,
        -                                    void** data,
        -                                    napi_value* result)
        +
        napi_status napi_create_arraybuffer(napi_env env,
        +                                    size_t byte_length,
        +                                    void** data,
        +                                    napi_value* result)
        • [in] env: The environment that the API is invoked under.
        • [in] length: The length in bytes of the array buffer to create.
        • @@ -2065,7 +2091,7 @@ directly read and/or written via C, consider using
        • [out] result: A napi_value representing a JavaScript ArrayBuffer.

        Returns napi_ok if the API succeeded.

        -

        This API returns an N-API value corresponding to a JavaScript ArrayBuffer. +

        This API returns a Node-API value corresponding to a JavaScript ArrayBuffer. ArrayBuffers are used to represent fixed-length binary data buffers. They are normally used as a backing-buffer for TypedArray objects. The ArrayBuffer allocated will have an underlying byte buffer whose size is @@ -2076,15 +2102,15 @@ written to directly from native code. To write to this buffer from JavaScript, a typed array or DataView object would need to be created.

        JavaScript ArrayBuffer objects are described in Section 24.1 of the ECMAScript Language Specification.

        -

        napi_create_buffer#

        +
        napi_create_buffer#
        -
        napi_status napi_create_buffer(napi_env env,
        -                               size_t size,
        -                               void** data,
        -                               napi_value* result)
        +
        napi_status napi_create_buffer(napi_env env,
        +                               size_t size,
        +                               void** data,
        +                               napi_value* result)
        • [in] env: The environment that the API is invoked under.
        • [in] size: Size in bytes of the underlying buffer.
        • @@ -2094,16 +2120,16 @@ a typed array or DataView object would need to be created.

          Returns napi_ok if the API succeeded.

          This API allocates a node::Buffer object. While this is still a fully-supported data structure, in most cases using a TypedArray will suffice.

          -

          napi_create_buffer_copy#

          +
          napi_create_buffer_copy#
          -
          napi_status napi_create_buffer_copy(napi_env env,
          -                                    size_t length,
          -                                    const void* data,
          -                                    void** result_data,
          -                                    napi_value* result)
          +
          napi_status napi_create_buffer_copy(napi_env env,
          +                                    size_t length,
          +                                    const void* data,
          +                                    void** result_data,
          +                                    napi_value* result)
          • [in] env: The environment that the API is invoked under.
          • [in] size: Size in bytes of the input buffer (should be the same as the size @@ -2116,14 +2142,14 @@ of the new buffer).
          • This API allocates a node::Buffer object and initializes it with data copied from the passed-in buffer. While this is still a fully-supported data structure, in most cases using a TypedArray will suffice.

            -

            napi_create_date#

            +
            napi_create_date#
            -
            napi_status napi_create_date(napi_env env,
            -                             double time,
            -                             napi_value* result);
            +
            napi_status napi_create_date(napi_env env,
            +                             double time,
            +                             napi_value* result);
            • [in] env: The environment that the API is invoked under.
            • [in] time: ECMAScript time value in milliseconds since 01 January, 1970 UTC.
            • @@ -2135,16 +2161,16 @@ ECMAScript aligns with POSIX time specification.

              This API allocates a JavaScript Date object.

              JavaScript Date objects are described in Section 20.3 of the ECMAScript Language Specification.

              -

              napi_create_external#

              +
              napi_create_external#
              -
              napi_status napi_create_external(napi_env env,
              -                                 void* data,
              +
              napi_status napi_create_external(napi_env env,
              +                                 void* data,
                                                napi_finalize finalize_cb,
              -                                 void* finalize_hint,
              -                                 napi_value* result)
              + void* finalize_hint, + napi_value* result)
              • [in] env: The environment that the API is invoked under.
              • [in] data: Raw pointer to the external data.
              • @@ -2169,18 +2195,18 @@ object just created is ready for garbage collection. It is similar to

                The created value is not an object, and therefore does not support additional properties. It is considered a distinct value type: calling napi_typeof() with an external value yields napi_external.

                -

                napi_create_external_arraybuffer#

                +
                napi_create_external_arraybuffer#
                -
                napi_status
                -napi_create_external_arraybuffer(napi_env env,
                -                                 void* external_data,
                -                                 size_t byte_length,
                +
                napi_status
                +napi_create_external_arraybuffer(napi_env env,
                +                                 void* external_data,
                +                                 size_t byte_length,
                                                  napi_finalize finalize_cb,
                -                                 void* finalize_hint,
                -                                 napi_value* result)
                + void* finalize_hint, + napi_value* result)
                • [in] env: The environment that the API is invoked under.
                • [in] external_data: Pointer to the underlying byte buffer of the @@ -2193,7 +2219,7 @@ collection.
                • [out] result: A napi_value representing a JavaScript ArrayBuffer.

                Returns napi_ok if the API succeeded.

                -

                This API returns an N-API value corresponding to a JavaScript ArrayBuffer. +

                This API returns a Node-API value corresponding to a JavaScript ArrayBuffer. The underlying byte buffer of the ArrayBuffer is externally allocated and managed. The caller must ensure that the byte buffer remains valid until the finalize callback is called.

                @@ -2207,17 +2233,17 @@ object just created is ready for garbage collection. It is similar to

              JavaScript ArrayBuffers are described in Section 24.1 of the ECMAScript Language Specification.

              -

              napi_create_external_buffer#

              +
              napi_create_external_buffer#
              -
              napi_status napi_create_external_buffer(napi_env env,
              -                                        size_t length,
              -                                        void* data,
              +
              napi_status napi_create_external_buffer(napi_env env,
              +                                        size_t length,
              +                                        void* data,
                                                       napi_finalize finalize_cb,
              -                                        void* finalize_hint,
              -                                        napi_value* result)
              + void* finalize_hint, + napi_value* result)
              • [in] env: The environment that the API is invoked under.
              • [in] length: Size in bytes of the input buffer (should be the same as the @@ -2242,12 +2268,12 @@ object just created is ready for garbage collection. It is similar to
              • the object created by the API can be used with napi_wrap().

              For Node.js >=4 Buffers are Uint8Arrays.

              -

              napi_create_object#

              +
              napi_create_object#
              -
              napi_status napi_create_object(napi_env env, napi_value* result)
              +
              napi_status napi_create_object(napi_env env, napi_value* result)
              • [in] env: The environment that the API is invoked under.
              • [out] result: A napi_value representing a JavaScript Object.
              • @@ -2257,35 +2283,35 @@ object just created is ready for garbage collection. It is similar to It is the equivalent of doing new Object() in JavaScript.

                The JavaScript Object type is described in Section 6.1.7 of the ECMAScript Language Specification.

                -

                napi_create_symbol#

                +
                napi_create_symbol#
                -
                napi_status napi_create_symbol(napi_env env,
                +
                napi_status napi_create_symbol(napi_env env,
                                                napi_value description,
                -                               napi_value* result)
                + napi_value* result)
                • [in] env: The environment that the API is invoked under.
                • [in] description: Optional napi_value which refers to a JavaScript -String to be set as the description for the symbol.
                • -
                • [out] result: A napi_value representing a JavaScript Symbol.
                • +string to be set as the description for the symbol. +
                • [out] result: A napi_value representing a JavaScript symbol.

                Returns napi_ok if the API succeeded.

                -

                This API creates a JavaScript Symbol object from a UTF8-encoded C string.

                -

                The JavaScript Symbol type is described in Section 19.4 +

                This API creates a JavaScript symbol value from a UTF8-encoded C string.

                +

                The JavaScript symbol type is described in Section 19.4 of the ECMAScript Language Specification.

                -

                napi_create_typedarray#

                +
                napi_create_typedarray#
                -
                napi_status napi_create_typedarray(napi_env env,
                +
                napi_status napi_create_typedarray(napi_env env,
                                                    napi_typedarray_type type,
                -                                   size_t length,
                +                                   size_t length,
                                                    napi_value arraybuffer,
                -                                   size_t byte_offset,
                -                                   napi_value* result)
                + size_t byte_offset, + napi_value* result)
                • [in] env: The environment that the API is invoked under.
                • [in] type: Scalar datatype of the elements within the TypedArray.
                • @@ -2305,16 +2331,16 @@ be <= the size in bytes of the array passed in. If not, a RangeError< is raised.

                  JavaScript TypedArray objects are described in Section 22.2 of the ECMAScript Language Specification.

                  -

                  napi_create_dataview#

                  +
                  napi_create_dataview#
                  -
                  napi_status napi_create_dataview(napi_env env,
                  -                                 size_t byte_length,
                  +
                  napi_status napi_create_dataview(napi_env env,
                  +                                 size_t byte_length,
                                                    napi_value arraybuffer,
                  -                                 size_t byte_offset,
                  -                                 napi_value* result)
                  + size_t byte_offset, + napi_value* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] length: Number of elements in the DataView.
                  • @@ -2332,82 +2358,82 @@ size in bytes of the array passed in. If not, a RangeError exceptio raised.

                    JavaScript DataView objects are described in Section 24.3 of the ECMAScript Language Specification.

                    -

                    Functions to convert from C types to N-API#

                    -

                    napi_create_int32#

                    +

                    Functions to convert from C types to Node-API#

                    +
                    napi_create_int32#
                    -
                    napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)
                    +
                    napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)
                    • [in] env: The environment that the API is invoked under.
                    • [in] value: Integer value to be represented in JavaScript.
                    • -
                    • [out] result: A napi_value representing a JavaScript Number.
                    • +
                    • [out] result: A napi_value representing a JavaScript number.

                    Returns napi_ok if the API succeeded.

                    This API is used to convert from the C int32_t type to the JavaScript -Number type.

                    -

                    The JavaScript Number type is described in +number type.

                    +

                    The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification.

                    -

                    napi_create_uint32#

                    +
                    napi_create_uint32#
                    -
                    napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)
                    +
                    napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)
                    • [in] env: The environment that the API is invoked under.
                    • [in] value: Unsigned integer value to be represented in JavaScript.
                    • -
                    • [out] result: A napi_value representing a JavaScript Number.
                    • +
                    • [out] result: A napi_value representing a JavaScript number.

                    Returns napi_ok if the API succeeded.

                    This API is used to convert from the C uint32_t type to the JavaScript -Number type.

                    -

                    The JavaScript Number type is described in +number type.

                    +

                    The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification.

                    -

                    napi_create_int64#

                    +
                    napi_create_int64#
                    -
                    napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)
                    +
                    napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)
                    • [in] env: The environment that the API is invoked under.
                    • [in] value: Integer value to be represented in JavaScript.
                    • -
                    • [out] result: A napi_value representing a JavaScript Number.
                    • +
                    • [out] result: A napi_value representing a JavaScript number.

                    Returns napi_ok if the API succeeded.

                    This API is used to convert from the C int64_t type to the JavaScript -Number type.

                    -

                    The JavaScript Number type is described in Section 6.1.6 +number type.

                    +

                    The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification. Note the complete range of int64_t cannot be represented with full precision in JavaScript. Integer values outside the range of Number.MIN_SAFE_INTEGER -(2**53 - 1) - Number.MAX_SAFE_INTEGER (2**53 - 1) will lose precision.

                    -

                    napi_create_double#

                    +
                    napi_create_double#
                    -
                    napi_status napi_create_double(napi_env env, double value, napi_value* result)
                    +
                    napi_status napi_create_double(napi_env env, double value, napi_value* result)
                    • [in] env: The environment that the API is invoked under.
                    • [in] value: Double-precision value to be represented in JavaScript.
                    • -
                    • [out] result: A napi_value representing a JavaScript Number.
                    • +
                    • [out] result: A napi_value representing a JavaScript number.

                    Returns napi_ok if the API succeeded.

                    This API is used to convert from the C double type to the JavaScript -Number type.

                    -

                    The JavaScript Number type is described in +number type.

                    +

                    The JavaScript number type is described in Section 6.1.6 of the ECMAScript Language Specification.

                    -

                    napi_create_bigint_int64#

                    +
                    napi_create_bigint_int64#
                    -
                    napi_status napi_create_bigint_int64(napi_env env,
                    -                                     int64_t value,
                    -                                     napi_value* result);
                    +
                    napi_status napi_create_bigint_int64(napi_env env,
                    +                                     int64_t value,
                    +                                     napi_value* result);
                    • [in] env: The environment that the API is invoked under.
                    • [in] value: Integer value to be represented in JavaScript.
                    • @@ -2415,14 +2441,14 @@ outside the range of # +
                      napi_create_bigint_uint64#
                      -
                      napi_status napi_create_bigint_uint64(napi_env env,
                      -                                      uint64_t value,
                      -                                      napi_value* result);
                      +
                      napi_status napi_create_bigint_uint64(napi_env env,
                      +                                      uint64_t value,
                      +                                      napi_value* result);
                      • [in] env: The environment that the API is invoked under.
                      • [in] value: Unsigned integer value to be represented in JavaScript.
                      • @@ -2430,16 +2456,16 @@ outside the range of # +
                        napi_create_bigint_words#
                        -
                        napi_status napi_create_bigint_words(napi_env env,
                        -                                     int sign_bit,
                        -                                     size_t word_count,
                        -                                     const uint64_t* words,
                        -                                     napi_value* result);
                        +
                        napi_status napi_create_bigint_words(napi_env env,
                        +                                     int sign_bit,
                        +                                     size_t word_count,
                        +                                     const uint64_t* words,
                        +                                     napi_value* result);
                        • [in] env: The environment that the API is invoked under.
                        • [in] sign_bit: Determines if the resulting BigInt will be positive or @@ -2453,78 +2479,78 @@ negative.
                        • value.

                          The resulting BigInt is calculated as: (–1)sign_bit (words[0] × (264)0 + words[1] × (264)1 + …)

                          -

                          napi_create_string_latin1#

                          +
                          napi_create_string_latin1#
                          -
                          napi_status napi_create_string_latin1(napi_env env,
                          -                                      const char* str,
                          -                                      size_t length,
                          -                                      napi_value* result);
                          +
                          napi_status napi_create_string_latin1(napi_env env,
                          +                                      const char* str,
                          +                                      size_t length,
                          +                                      napi_value* result);
                          • [in] env: The environment that the API is invoked under.
                          • [in] str: Character buffer representing an ISO-8859-1-encoded string.
                          • [in] length: The length of the string in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.
                          • -
                          • [out] result: A napi_value representing a JavaScript String.
                          • +
                          • [out] result: A napi_value representing a JavaScript string.

                          Returns napi_ok if the API succeeded.

                          -

                          This API creates a JavaScript String object from an ISO-8859-1-encoded C +

                          This API creates a JavaScript string value from an ISO-8859-1-encoded C string. The native string is copied.

                          -

                          The JavaScript String type is described in +

                          The JavaScript string type is described in Section 6.1.4 of the ECMAScript Language Specification.

                          -

                          napi_create_string_utf16#

                          +
                          napi_create_string_utf16#
                          -
                          napi_status napi_create_string_utf16(napi_env env,
                          -                                     const char16_t* str,
                          -                                     size_t length,
                          -                                     napi_value* result)
                          +
                          napi_status napi_create_string_utf16(napi_env env,
                          +                                     const char16_t* str,
                          +                                     size_t length,
                          +                                     napi_value* result)
                          • [in] env: The environment that the API is invoked under.
                          • [in] str: Character buffer representing a UTF16-LE-encoded string.
                          • [in] length: The length of the string in two-byte code units, or NAPI_AUTO_LENGTH if it is null-terminated.
                          • -
                          • [out] result: A napi_value representing a JavaScript String.
                          • +
                          • [out] result: A napi_value representing a JavaScript string.

                          Returns napi_ok if the API succeeded.

                          -

                          This API creates a JavaScript String object from a UTF16-LE-encoded C string. +

                          This API creates a JavaScript string value from a UTF16-LE-encoded C string. The native string is copied.

                          -

                          The JavaScript String type is described in +

                          The JavaScript string type is described in Section 6.1.4 of the ECMAScript Language Specification.

                          -

                          napi_create_string_utf8#

                          +
                          napi_create_string_utf8#
                          -
                          napi_status napi_create_string_utf8(napi_env env,
                          -                                    const char* str,
                          -                                    size_t length,
                          -                                    napi_value* result)
                          +
                          napi_status napi_create_string_utf8(napi_env env,
                          +                                    const char* str,
                          +                                    size_t length,
                          +                                    napi_value* result)
                          • [in] env: The environment that the API is invoked under.
                          • [in] str: Character buffer representing a UTF8-encoded string.
                          • [in] length: The length of the string in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.
                          • -
                          • [out] result: A napi_value representing a JavaScript String.
                          • +
                          • [out] result: A napi_value representing a JavaScript string.

                          Returns napi_ok if the API succeeded.

                          -

                          This API creates a JavaScript String object from a UTF8-encoded C string. +

                          This API creates a JavaScript string value from a UTF8-encoded C string. The native string is copied.

                          -

                          The JavaScript String type is described in +

                          The JavaScript string type is described in Section 6.1.4 of the ECMAScript Language Specification.

                          -

                          Functions to convert from N-API to C types#

                          -

                          napi_get_array_length#

                          +

                          Functions to convert from Node-API to C types#

                          +
                          napi_get_array_length#
                          -
                          napi_status napi_get_array_length(napi_env env,
                          +
                          napi_status napi_get_array_length(napi_env env,
                                                             napi_value value,
                          -                                  uint32_t* result)
                          + uint32_t* result)
                          • [in] env: The environment that the API is invoked under.
                          • [in] value: napi_value representing the JavaScript Array whose length is @@ -2535,15 +2561,15 @@ being queried.
                          • This API returns the length of an array.

                            Array length is described in Section 22.1.4.1 of the ECMAScript Language Specification.

                            -

                            napi_get_arraybuffer_info#

                            +
                            napi_get_arraybuffer_info#
                            -
                            napi_status napi_get_arraybuffer_info(napi_env env,
                            +
                            napi_status napi_get_arraybuffer_info(napi_env env,
                                                                   napi_value arraybuffer,
                            -                                      void** data,
                            -                                      size_t* byte_length)
                            + void** data, + size_t* byte_length)
                            • [in] env: The environment that the API is invoked under.
                            • [in] arraybuffer: napi_value representing the ArrayBuffer being queried.
                            • @@ -2561,15 +2587,15 @@ possible safe way to use this API is in conjunction with lifetime of the ArrayBuffer. It's also safe to use the returned data buffer within the same callback as long as there are no calls to other APIs that might trigger a GC.

                              -

                              napi_get_buffer_info#

                              +
                              napi_get_buffer_info#
                              -
                              napi_status napi_get_buffer_info(napi_env env,
                              +
                              napi_status napi_get_buffer_info(napi_env env,
                                                                napi_value value,
                              -                                 void** data,
                              -                                 size_t* length)
                              + void** data, + size_t* length)
                              • [in] env: The environment that the API is invoked under.
                              • [in] value: napi_value representing the node::Buffer being queried.
                              • @@ -2582,14 +2608,14 @@ If length is 0, this may be NULL or any other pointer and it's length.

                                Warning: Use caution while using this API since the underlying data buffer's lifetime is not guaranteed if it's managed by the VM.

                                -

                                napi_get_prototype#

                                +
                                napi_get_prototype#
                                -
                                napi_status napi_get_prototype(napi_env env,
                                +
                                napi_status napi_get_prototype(napi_env env,
                                                                napi_value object,
                                -                               napi_value* result)
                                + napi_value* result)
                                • [in] env: The environment that the API is invoked under.
                                • [in] object: napi_value representing JavaScript Object whose prototype @@ -2598,18 +2624,18 @@ not the same as the function's prototype property).
                                • [out] result: napi_value representing prototype of the given object.

                                Returns napi_ok if the API succeeded.

                                -

                                napi_get_typedarray_info#

                                +
                                napi_get_typedarray_info#
                                -
                                napi_status napi_get_typedarray_info(napi_env env,
                                +
                                napi_status napi_get_typedarray_info(napi_env env,
                                                                      napi_value typedarray,
                                                                      napi_typedarray_type* type,
                                -                                     size_t* length,
                                -                                     void** data,
                                +                                     size_t* length,
                                +                                     void** data,
                                                                      napi_value* arraybuffer,
                                -                                     size_t* byte_offset)
                                + size_t* byte_offset)
                                • [in] env: The environment that the API is invoked under.
                                • [in] typedarray: napi_value representing the TypedArray whose @@ -2631,22 +2657,22 @@ in the array. Therefore, the first byte of the native array would be at

                                  This API returns various properties of a typed array.

                                  Warning: Use caution while using this API since the underlying data buffer is managed by the VM.

                                  -

                                  napi_get_dataview_info#

                                  +
                                  napi_get_dataview_info#
                                  -
                                  napi_status napi_get_dataview_info(napi_env env,
                                  +
                                  napi_status napi_get_dataview_info(napi_env env,
                                                                      napi_value dataview,
                                  -                                   size_t* byte_length,
                                  -                                   void** data,
                                  +                                   size_t* byte_length,
                                  +                                   void** data,
                                                                      napi_value* arraybuffer,
                                  -                                   size_t* byte_offset)
                                  + size_t* byte_offset)
                                  • [in] env: The environment that the API is invoked under.
                                  • [in] dataview: napi_value representing the DataView whose properties to query.
                                  • -
                                  • [out] byte_length: Number of bytes in the DataView.
                                  • +
                                  • [out] byte_length: Number of bytes in the DataView.
                                  • [out] data: The data buffer underlying the DataView. If byte_length is 0, this may be NULL or any other pointer value.
                                  • [out] arraybuffer: ArrayBuffer underlying the DataView.
                                  • @@ -2655,14 +2681,14 @@ to start projecting the DataView.

                                  Returns napi_ok if the API succeeded.

                                  This API returns various properties of a DataView.

                                  -

                                  napi_get_date_value#

                                  +
                                  napi_get_date_value#
                                  -
                                  napi_status napi_get_date_value(napi_env env,
                                  +
                                  napi_status napi_get_date_value(napi_env env,
                                                                   napi_value value,
                                  -                                double* result)
                                  + double* result)
                                  • [in] env: The environment that the API is invoked under.
                                  • [in] value: napi_value representing a JavaScript Date.
                                  • @@ -2675,12 +2701,12 @@ ECMAScript aligns with POSIX time specification.

                                    in it returns napi_date_expected.

                                    This API returns the C double primitive of time value for the given JavaScript Date.

                                    -

                                    napi_get_value_bool#

                                    +
                                    napi_get_value_bool#
                                    -
                                    napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result)
                                    +
                                    napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result)
                                    • [in] env: The environment that the API is invoked under.
                                    • [in] value: napi_value representing JavaScript Boolean.
                                    • @@ -2691,33 +2717,33 @@ in it returns napi_date_expected.

                                      passed in it returns napi_boolean_expected.

                                      This API returns the C boolean primitive equivalent of the given JavaScript Boolean.

                                      -

                                      napi_get_value_double#

                                      +
                                      napi_get_value_double#
                                      -
                                      napi_status napi_get_value_double(napi_env env,
                                      +
                                      napi_status napi_get_value_double(napi_env env,
                                                                         napi_value value,
                                      -                                  double* result)
                                      + double* result)
                                      • [in] env: The environment that the API is invoked under.
                                      • -
                                      • [in] value: napi_value representing JavaScript Number.
                                      • +
                                      • [in] value: napi_value representing JavaScript number.
                                      • [out] result: C double primitive equivalent of the given JavaScript -Number.
                                      • +number.

                                      Returns napi_ok if the API succeeded. If a non-number napi_value is passed in it returns napi_number_expected.

                                      This API returns the C double primitive equivalent of the given JavaScript -Number.

                                      -

                                      napi_get_value_bigint_int64#

                                      +number.

                                      +
                                      napi_get_value_bigint_int64#
                                      -
                                      napi_status napi_get_value_bigint_int64(napi_env env,
                                      +
                                      napi_status napi_get_value_bigint_int64(napi_env env,
                                                                               napi_value value,
                                      -                                        int64_t* result,
                                      -                                        bool* lossless);
                                      + int64_t* result, + bool* lossless)
                                      ;
                                      • [in] env: The environment that the API is invoked under
                                      • [in] value: napi_value representing JavaScript BigInt.
                                      • @@ -2730,15 +2756,15 @@ losslessly. returns napi_bigint_expected.

                                        This API returns the C int64_t primitive equivalent of the given JavaScript BigInt. If needed it will truncate the value, setting lossless to false.

                                        -

                                        napi_get_value_bigint_uint64#

                                        +
                                        napi_get_value_bigint_uint64#
                                        -
                                        napi_status napi_get_value_bigint_uint64(napi_env env,
                                        +
                                        napi_status napi_get_value_bigint_uint64(napi_env env,
                                                                                 napi_value value,
                                        -                                        uint64_t* result,
                                        -                                        bool* lossless);
                                        + uint64_t* result, + bool* lossless)
                                        ;
                                        • [in] env: The environment that the API is invoked under.
                                        • [in] value: napi_value representing JavaScript BigInt.
                                        • @@ -2751,16 +2777,16 @@ losslessly. returns napi_bigint_expected.

                                          This API returns the C uint64_t primitive equivalent of the given JavaScript BigInt. If needed it will truncate the value, setting lossless to false.

                                          -

                                          napi_get_value_bigint_words#

                                          +
                                          napi_get_value_bigint_words#
                                          -
                                          napi_status napi_get_value_bigint_words(napi_env env,
                                          +
                                          napi_status napi_get_value_bigint_words(napi_env env,
                                                                                   napi_value value,
                                          -                                        int* sign_bit,
                                          -                                        size_t* word_count,
                                          -                                        uint64_t* words);
                                          + int* sign_bit, + size_t* word_count, + uint64_t* words)
                                          ;
                                          • [in] env: The environment that the API is invoked under.
                                          • [in] value: napi_value representing JavaScript BigInt.
                                          • @@ -2775,14 +2801,14 @@ would be needed to store this BigInt.

                                            This API converts a single BigInt value into a sign bit, 64-bit little-endian array, and the number of elements in the array. sign_bit and words may be both set to NULL, in order to get only word_count.

                                            -

                                            napi_get_value_external#

                                            +
                                            napi_get_value_external#
                                            -
                                            napi_status napi_get_value_external(napi_env env,
                                            +
                                            napi_status napi_get_value_external(napi_env env,
                                                                                 napi_value value,
                                            -                                    void** result)
                                            + void** result)
                                            • [in] env: The environment that the API is invoked under.
                                            • [in] value: napi_value representing JavaScript external value.
                                            • @@ -2792,133 +2818,136 @@ both set to NULL, in order to get only word_count.

                                              passed in it returns napi_invalid_arg.

                                              This API retrieves the external data pointer that was previously passed to napi_create_external().

                                              -

                                              napi_get_value_int32#

                                              +
                                              napi_get_value_int32#
                                              -
                                              napi_status napi_get_value_int32(napi_env env,
                                              +
                                              napi_status napi_get_value_int32(napi_env env,
                                                                                napi_value value,
                                              -                                 int32_t* result)
                                              + int32_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • -
                                              • [in] value: napi_value representing JavaScript Number.
                                              • +
                                              • [in] value: napi_value representing JavaScript number.
                                              • [out] result: C int32 primitive equivalent of the given JavaScript -Number.
                                              • +number.

                                              Returns napi_ok if the API succeeded. If a non-number napi_value is passed in napi_number_expected.

                                              This API returns the C int32 primitive equivalent -of the given JavaScript Number.

                                              +of the given JavaScript number.

                                              If the number exceeds the range of the 32 bit integer, then the result is truncated to the equivalent of the bottom 32 bits. This can result in a large positive number becoming a negative number if the value is > 231 - 1.

                                              Non-finite number values (NaN, +Infinity, or -Infinity) set the result to zero.

                                              -

                                              napi_get_value_int64#

                                              +
                                              napi_get_value_int64#
                                              -
                                              napi_status napi_get_value_int64(napi_env env,
                                              +
                                              napi_status napi_get_value_int64(napi_env env,
                                                                                napi_value value,
                                              -                                 int64_t* result)
                                              + int64_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • -
                                              • [in] value: napi_value representing JavaScript Number.
                                              • +
                                              • [in] value: napi_value representing JavaScript number.
                                              • [out] result: C int64 primitive equivalent of the given JavaScript -Number.
                                              • +number.

                                              Returns napi_ok if the API succeeded. If a non-number napi_value is passed in it returns napi_number_expected.

                                              This API returns the C int64 primitive equivalent of the given JavaScript -Number.

                                              -

                                              Number values outside the range of Number.MIN_SAFE_INTEGER +number.

                                              +

                                              number values outside the range of Number.MIN_SAFE_INTEGER -(2**53 - 1) - Number.MAX_SAFE_INTEGER (2**53 - 1) will lose precision.

                                              Non-finite number values (NaN, +Infinity, or -Infinity) set the result to zero.

                                              -

                                              napi_get_value_string_latin1#

                                              +
                                              napi_get_value_string_latin1#
                                              -
                                              napi_status napi_get_value_string_latin1(napi_env env,
                                              +
                                              napi_status napi_get_value_string_latin1(napi_env env,
                                                                                        napi_value value,
                                              -                                         char* buf,
                                              -                                         size_t bufsize,
                                              -                                         size_t* result)
                                              + char* buf, + size_t bufsize, + size_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • [in] value: napi_value representing JavaScript string.
                                              • [in] buf: Buffer to write the ISO-8859-1-encoded string into. If NULL is -passed in, the length of the string (in bytes) is returned.
                                              • +passed in, the length of the string in bytes and excluding the null terminator +is returned in result.
                                              • [in] bufsize: Size of the destination buffer. When this value is -insufficient, the returned string will be truncated.
                                              • +insufficient, the returned string is truncated and null-terminated.
                                              • [out] result: Number of bytes copied into the buffer, excluding the null terminator.
                                              -

                                              Returns napi_ok if the API succeeded. If a non-String napi_value +

                                              Returns napi_ok if the API succeeded. If a non-string napi_value is passed in it returns napi_string_expected.

                                              This API returns the ISO-8859-1-encoded string corresponding the value passed in.

                                              -

                                              napi_get_value_string_utf8#

                                              +
                                              napi_get_value_string_utf8#
                                              -
                                              napi_status napi_get_value_string_utf8(napi_env env,
                                              +
                                              napi_status napi_get_value_string_utf8(napi_env env,
                                                                                      napi_value value,
                                              -                                       char* buf,
                                              -                                       size_t bufsize,
                                              -                                       size_t* result)
                                              + char* buf, + size_t bufsize, + size_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • [in] value: napi_value representing JavaScript string.
                                              • [in] buf: Buffer to write the UTF8-encoded string into. If NULL is passed -in, the length of the string (in bytes) is returned.
                                              • +in, the length of the string in bytes and excluding the null terminator is +returned in result.
                                              • [in] bufsize: Size of the destination buffer. When this value is -insufficient, the returned string will be truncated.
                                              • +insufficient, the returned string is truncated and null-terminated.
                                              • [out] result: Number of bytes copied into the buffer, excluding the null terminator.
                                              -

                                              Returns napi_ok if the API succeeded. If a non-String napi_value +

                                              Returns napi_ok if the API succeeded. If a non-string napi_value is passed in it returns napi_string_expected.

                                              This API returns the UTF8-encoded string corresponding the value passed in.

                                              -

                                              napi_get_value_string_utf16#

                                              +
                                              napi_get_value_string_utf16#
                                              -
                                              napi_status napi_get_value_string_utf16(napi_env env,
                                              +
                                              napi_status napi_get_value_string_utf16(napi_env env,
                                                                                       napi_value value,
                                              -                                        char16_t* buf,
                                              -                                        size_t bufsize,
                                              -                                        size_t* result)
                                              + char16_t* buf, + size_t bufsize, + size_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • [in] value: napi_value representing JavaScript string.
                                              • [in] buf: Buffer to write the UTF16-LE-encoded string into. If NULL is -passed in, the length of the string (in 2-byte code units) is returned.
                                              • +passed in, the length of the string in 2-byte code units and excluding the +null terminator is returned.
                                              • [in] bufsize: Size of the destination buffer. When this value is -insufficient, the returned string will be truncated.
                                              • +insufficient, the returned string is truncated and null-terminated.
                                              • [out] result: Number of 2-byte code units copied into the buffer, excluding the null terminator.
                                              -

                                              Returns napi_ok if the API succeeded. If a non-String napi_value +

                                              Returns napi_ok if the API succeeded. If a non-string napi_value is passed in it returns napi_string_expected.

                                              This API returns the UTF16-encoded string corresponding the value passed in.

                                              -

                                              napi_get_value_uint32#

                                              +
                                              napi_get_value_uint32#
                                              -
                                              napi_status napi_get_value_uint32(napi_env env,
                                              +
                                              napi_status napi_get_value_uint32(napi_env env,
                                                                                 napi_value value,
                                              -                                  uint32_t* result)
                                              + uint32_t* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • -
                                              • [in] value: napi_value representing JavaScript Number.
                                              • +
                                              • [in] value: napi_value representing JavaScript number.
                                              • [out] result: C primitive equivalent of the given napi_value as a uint32_t.
                                              @@ -2926,13 +2955,13 @@ is passed in it returns napi_string_expected.

                                              is passed in it returns napi_number_expected.

                                              This API returns the C primitive equivalent of the given napi_value as a uint32_t.

                                              -

                                              Functions to get global instances#

                                              -

                                              napi_get_boolean#

                                              +

                                              Functions to get global instances#

                                              +
                                              napi_get_boolean#
                                              -
                                              napi_status napi_get_boolean(napi_env env, bool value, napi_value* result)
                                              +
                                              napi_status napi_get_boolean(napi_env env, bool value, napi_value* result)
                                              • [in] env: The environment that the API is invoked under.
                                              • [in] value: The value of the boolean to retrieve.
                                              • @@ -2942,61 +2971,61 @@ retrieve.

                                                Returns napi_ok if the API succeeded.

                                                This API is used to return the JavaScript singleton object that is used to represent the given boolean value.

                                                -

                                                napi_get_global#

                                                +
                                                napi_get_global#
                                                -
                                                napi_status napi_get_global(napi_env env, napi_value* result)
                                                +
                                                napi_status napi_get_global(napi_env env, napi_value* result)
                                                • [in] env: The environment that the API is invoked under.
                                                • [out] result: napi_value representing JavaScript global object.

                                                Returns napi_ok if the API succeeded.

                                                This API returns the global object.

                                                -

                                                napi_get_null#

                                                +
                                                napi_get_null#
                                                -
                                                napi_status napi_get_null(napi_env env, napi_value* result)
                                                +
                                                napi_status napi_get_null(napi_env env, napi_value* result)
                                                • [in] env: The environment that the API is invoked under.
                                                • [out] result: napi_value representing JavaScript null object.

                                                Returns napi_ok if the API succeeded.

                                                This API returns the null object.

                                                -

                                                napi_get_undefined#

                                                +
                                                napi_get_undefined#
                                                -
                                                napi_status napi_get_undefined(napi_env env, napi_value* result)
                                                +
                                                napi_status napi_get_undefined(napi_env env, napi_value* result)
                                                • [in] env: The environment that the API is invoked under.
                                                • [out] result: napi_value representing JavaScript Undefined value.

                                                Returns napi_ok if the API succeeded.

                                                This API returns the Undefined object.

                                                -

                                                Working with JavaScript values and abstract operations#

                                                -

                                                N-API exposes a set of APIs to perform some abstract operations on JavaScript +

        Working with JavaScript values and abstract operations#

        +

        Node-API exposes a set of APIs to perform some abstract operations on JavaScript values. Some of these operations are documented under Section 7 of the ECMAScript Language Specification.

        These APIs support doing one of the following:

          -
        1. Coerce JavaScript values to specific JavaScript types (such as Number or -String).
        2. +
        3. Coerce JavaScript values to specific JavaScript types (such as number or +string).
        4. Check the type of a JavaScript value.
        5. Check for equality between two JavaScript values.
        -

        napi_coerce_to_bool#

        +

        napi_coerce_to_bool#

        -
        napi_status napi_coerce_to_bool(napi_env env,
        +
        napi_status napi_coerce_to_bool(napi_env env,
                                         napi_value value,
        -                                napi_value* result)
        + napi_value* result)
        • [in] env: The environment that the API is invoked under.
        • [in] value: The JavaScript value to coerce.
        • @@ -3006,31 +3035,31 @@ of the ECMAScript Language Specificati

          This API implements the abstract operation ToBoolean() as defined in Section 7.1.2 of the ECMAScript Language Specification. This API can be re-entrant if getters are defined on the passed-in Object.

          -

          napi_coerce_to_number#

          +

          napi_coerce_to_number#

          -
          napi_status napi_coerce_to_number(napi_env env,
          +
          napi_status napi_coerce_to_number(napi_env env,
                                             napi_value value,
          -                                  napi_value* result)
          + napi_value* result)
          • [in] env: The environment that the API is invoked under.
          • [in] value: The JavaScript value to coerce.
          • -
          • [out] result: napi_value representing the coerced JavaScript Number.
          • +
          • [out] result: napi_value representing the coerced JavaScript number.

          Returns napi_ok if the API succeeded.

          This API implements the abstract operation ToNumber() as defined in Section 7.1.3 of the ECMAScript Language Specification. This API can be re-entrant if getters are defined on the passed-in Object.

          -

          napi_coerce_to_object#

          +

          napi_coerce_to_object#

          -
          napi_status napi_coerce_to_object(napi_env env,
          +
          napi_status napi_coerce_to_object(napi_env env,
                                             napi_value value,
          -                                  napi_value* result)
          + napi_value* result)
          • [in] env: The environment that the API is invoked under.
          • [in] value: The JavaScript value to coerce.
          • @@ -3040,29 +3069,29 @@ This API can be re-entrant if getters are defined on the passed-in Object<

            This API implements the abstract operation ToObject() as defined in Section 7.1.13 of the ECMAScript Language Specification. This API can be re-entrant if getters are defined on the passed-in Object.

            -

            napi_coerce_to_string#

            +

            napi_coerce_to_string#

            -
            napi_status napi_coerce_to_string(napi_env env,
            +
            napi_status napi_coerce_to_string(napi_env env,
                                               napi_value value,
            -                                  napi_value* result)
            + napi_value* result)
            • [in] env: The environment that the API is invoked under.
            • [in] value: The JavaScript value to coerce.
            • -
            • [out] result: napi_value representing the coerced JavaScript String.
            • +
            • [out] result: napi_value representing the coerced JavaScript string.

            Returns napi_ok if the API succeeded.

            This API implements the abstract operation ToString() as defined in Section 7.1.13 of the ECMAScript Language Specification. This API can be re-entrant if getters are defined on the passed-in Object.

            -

            napi_typeof#

            +

            napi_typeof#

            -
            napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result)
            +
            napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result)
            • [in] env: The environment that the API is invoked under.
            • [in] value: The JavaScript value whose type to query.
            • @@ -3082,15 +3111,15 @@ Specification. However, there are some differences:

              object.

              If value has a type that is invalid, an error is returned.

              -

              napi_instanceof#

              +

              napi_instanceof#

              -
              napi_status napi_instanceof(napi_env env,
              +
              napi_status napi_instanceof(napi_env env,
                                           napi_value object,
                                           napi_value constructor,
              -                            bool* result)
              + bool* result)
              • [in] env: The environment that the API is invoked under.
              • [in] object: The JavaScript value to check.
              • @@ -3102,12 +3131,12 @@ is true.

                Returns napi_ok if the API succeeded.

                This API represents invoking the instanceof Operator on the object as defined in Section 12.10.4 of the ECMAScript Language Specification.

                -

                napi_is_array#

                +

                napi_is_array#

                -
                napi_status napi_is_array(napi_env env, napi_value value, bool* result)
                +
                napi_status napi_is_array(napi_env env, napi_value value, bool* result)
                • [in] env: The environment that the API is invoked under.
                • [in] value: The JavaScript value to check.
                • @@ -3116,12 +3145,12 @@ defined in Sect

                  Returns napi_ok if the API succeeded.

                  This API represents invoking the IsArray operation on the object as defined in Section 7.2.2 of the ECMAScript Language Specification.

                  -

                  napi_is_arraybuffer#

                  +

                  napi_is_arraybuffer#

                  -
                  napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -3129,12 +3158,12 @@ as defined in Section 7.2.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is an array buffer.

                  -

                  napi_is_buffer#

                  +

                  napi_is_buffer#

                  -
                  napi_status napi_is_buffer(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_buffer(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -3143,12 +3172,12 @@ object.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is a buffer.

                  -

                  napi_is_date#

                  +

                  napi_is_date#

                  -
                  napi_status napi_is_date(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_date(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -3157,12 +3186,12 @@ object.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is a date.

                  -

                  napi_is_error#

                  +

                  napi_is_error#

                  -
                  napi_status napi_is_error(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_error(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -3170,12 +3199,12 @@ object.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is an Error.

                  -

                  napi_is_typedarray#

                  +

                  napi_is_typedarray#

                  -
                  napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -3183,12 +3212,12 @@ object.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is a typed array.

                  -

                  napi_is_dataview#

                  +

                  napi_is_dataview#

                  -
                  napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
                  +
                  napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] value: The JavaScript value to check.
                  • @@ -3196,15 +3225,15 @@ object.

                  Returns napi_ok if the API succeeded.

                  This API checks if the Object passed in is a DataView.

                  -

                  napi_strict_equals#

                  +

                  napi_strict_equals#

                  -
                  napi_status napi_strict_equals(napi_env env,
                  +
                  napi_status napi_strict_equals(napi_env env,
                                                  napi_value lhs,
                                                  napi_value rhs,
                  -                               bool* result)
                  + bool* result)
                  • [in] env: The environment that the API is invoked under.
                  • [in] lhs: The JavaScript value to check.
                  • @@ -3214,13 +3243,13 @@ object.

                    Returns napi_ok if the API succeeded.

                    This API represents the invocation of the Strict Equality algorithm as defined in Section 7.2.14 of the ECMAScript Language Specification.

                    -

                    napi_detach_arraybuffer#

                    +

                    napi_detach_arraybuffer#

                    -
                    napi_status napi_detach_arraybuffer(napi_env env,
                    -                                    napi_value arraybuffer)
                    +
                    napi_status napi_detach_arraybuffer(napi_env env,
                    +                                    napi_value arraybuffer)
                    • [in] env: The environment that the API is invoked under.
                    • [in] arraybuffer: The JavaScript ArrayBuffer to be detached.
                    • @@ -3233,14 +3262,14 @@ detachable. For example, V8 requires that the ArrayBuffer be extern that is, created with napi_create_external_arraybuffer.

                      This API represents the invocation of the ArrayBuffer detach operation as defined in Section 24.1.1.3 of the ECMAScript Language Specification.

                      -

                      napi_is_detached_arraybuffer#

                      +

                      napi_is_detached_arraybuffer#

                      -
                      napi_status napi_is_detached_arraybuffer(napi_env env,
                      +
                      napi_status napi_is_detached_arraybuffer(napi_env env,
                                                                napi_value arraybuffer,
                      -                                         bool* result)
                      + bool* result)

        Working with JavaScript properties#

        +

        Node-API exposes a set of APIs to get and set properties on JavaScript objects. Some of these types are documented under Section 7 of the ECMAScript Language Specification.

        Properties in JavaScript are represented as a tuple of a key and a value. -Fundamentally, all property keys in N-API can be represented in one of the +Fundamentally, all property keys in Node-API can be represented in one of the following forms:

        • Named: a simple UTF8-encoded string
        • Integer-Indexed: an index value represented by uint32_t
        • -
        • JavaScript value: these are represented in N-API by napi_value. This can -be a napi_value representing a String, Number, or Symbol.
        • +
        • JavaScript value: these are represented in Node-API by napi_value. This can +be a napi_value representing a string, number, or symbol.
        -

        N-API values are represented by the type napi_value. -Any N-API call that requires a JavaScript value takes in a napi_value. +

        Node-API values are represented by the type napi_value. +Any Node-API call that requires a JavaScript value takes in a napi_value. However, it's the caller's responsibility to make sure that the napi_value in question is of the JavaScript type expected by the API.

        The APIs documented in this section provide a simple interface to @@ -3273,8 +3302,8 @@ get and set properties on arbitrary JavaScript objects represented by napi_value.

        For instance, consider the following JavaScript code snippet:

        const obj = {};
        -obj.myProp = 123;
        -

        The equivalent can be done using N-API values with the following snippet:

        +obj.myProp = 123;
        +

        The equivalent can be done using Node-API values with the following snippet:

        napi_status status = napi_generic_failure;
         
         // const obj = {}
        @@ -3293,7 +3322,7 @@ status = napi_set_named_property(env, obj, "myProp"
         
        const arr = [];
         arr[123] = 'hello';
        -

        The equivalent can be done using N-API values with the following snippet:

        +

        The equivalent can be done using Node-API values with the following snippet:

        napi_status status = napi_generic_failure;
         
         // const arr = [];
        @@ -3312,7 +3341,7 @@ status = napi_set_element(env, arr, 123, value)
         Consider the following JavaScript snippet:

        const arr = [];
         const value = arr[123];
        -

        The following is the approximate equivalent of the N-API counterpart:

        +

        The following is the approximate equivalent of the Node-API counterpart:

        napi_status status = napi_generic_failure;
         
         // const arr = []
        @@ -3326,11 +3355,11 @@ status = napi_get_element(env, arr, 123, &
         

        Finally, multiple properties can also be defined on an object for performance reasons. Consider the following JavaScript:

        const obj = {};
        -Object.defineProperties(obj, {
        +Object.defineProperties(obj, {
           'foo': { value: 123, writable: true, configurable: true, enumerable: true },
           'bar': { value: 456, writable: true, configurable: true, enumerable: true }
         });
        -

        The following is the approximate equivalent of the N-API counterpart:

        +

        The following is the approximate equivalent of the Node-API counterpart:

        napi_status status = napi_status_generic_failure;
         
         // const obj = {};
        @@ -3355,18 +3384,18 @@ status = napi_define_properties(env,
                                         sizeof(descriptors) / sizeof(descriptors[0]),
                                         descriptors);
         if (status != napi_ok) return status;
        -

        Structures#

        -

        napi_property_attributes#

        +

        Structures#

        +
        napi_property_attributes#
        -
        typedef enum {
        +
        typedef enum {
           napi_default = 0,
           napi_writable = 1 << 0,
           napi_enumerable = 1 << 1,
        @@ -3380,7 +3409,7 @@ status = napi_define_properties(env,
           napi_default_method = napi_writable | napi_configurable,
         
           // Default for object properties, like in JS obj[prop].
        -  napi_default_property = napi_writable |
        +  napi_default_jsproperty = napi_writable |
                                   napi_enumerable |
                                   napi_configurable,
         } napi_property_attributes;
        @@ -3399,15 +3428,15 @@ property is read only, not enumerable and not configurable.
      • napi_static: The property will be defined as a static property on a class as opposed to an instance property, which is the default. This is used only by napi_define_class. It is ignored by napi_define_properties.
      • -
      • napi_default_method: The property is configureable, writeable but not -enumerable like a method in a JS class.
      • -
      • napi_default_property: The property is writable, enumerable and configurable -like a property set via JS code obj.key = value.
      • +
      • napi_default_method: Like a method in a JS class, the property is +configurable and writeable, but not enumerable.
      • +
      • napi_default_jsproperty: Like a property set via assignment in JavaScript, +the property is writable, enumerable, and configurable.
      -

      napi_property_descriptor#

      +
      napi_property_descriptor#
      typedef struct {
         // One of utf8name or name should be NULL.
      -  const char* utf8name;
      +  const char* utf8name;
         napi_value name;
       
         napi_callback method;
      @@ -3416,10 +3445,10 @@ like a property set via JS code obj.key = value.
         napi_value value;
       
         napi_property_attributes attributes;
      -  void* data;
      +  void* data;
       } napi_property_descriptor;
        -
      • utf8name: Optional String describing the key for the property, +
      • utf8name: Optional string describing the key for the property, encoded as UTF8. One of utf8name or name must be provided for the property.
      • name: Optional napi_value that points to a JavaScript string or symbol @@ -3432,12 +3461,12 @@ property is a data property. If this is passed in, set getter, value and method to NULL (since these members won't be used). The given function is called implicitly by the runtime when the property is accessed from JavaScript code (or if a get on the property is -performed using a N-API call). napi_callback provides more details.
      • +performed using a Node-API call). napi_callback provides more details.
      • setter: A function to call when a set access of the property is performed. If this is passed in, set value and method to NULL (since these members won't be used). The given function is called implicitly by the runtime when the property is set from JavaScript code (or if a set on the property is -performed using a N-API call). napi_callback provides more details.
      • +performed using a Node-API call). napi_callback provides more details.
      • method: Set this to make the property descriptor object's value property to be a JavaScript function represented by method. If this is passed in, set value, getter and setter to NULL (since these members @@ -3447,17 +3476,17 @@ won't be used). napi_callback pr
      • data: The callback data passed into method, getter and setter if this function is invoked.
      -

      Functions#

      -

      napi_get_property_names#

      +

      Functions#

      +
      napi_get_property_names#
      -
      napi_status napi_get_property_names(napi_env env,
      +
      napi_status napi_get_property_names(napi_env env,
                                           napi_value object,
      -                                    napi_value* result);
      + napi_value* result)
      ;
        -
      • [in] env: The environment that the N-API call is invoked under.
      • +
      • [in] env: The environment that the Node-API call is invoked under.
      • [in] object: The object from which to retrieve the properties.
      • [out] result: A napi_value representing an array of JavaScript values that represent the property names of the object. The API can be used to @@ -3468,9 +3497,9 @@ and napi_get_element.
      • This API returns the names of the enumerable properties of object as an array of strings. The properties of object whose key is a symbol will not be included.

        -

        napi_get_all_property_names#

        +
        napi_get_all_property_names#
        napi_get_all_property_names(napi_env env,
        @@ -3480,81 +3509,81 @@ included.

        napi_key_conversion key_conversion, napi_value* result);
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object from which to retrieve the properties.
        • [in] key_mode: Whether to retrieve prototype properties as well.
        • [in] key_filter: Which properties to retrieve (enumerable/readable/writable).
        • [in] key_conversion: Whether to convert numbered property keys to strings.
        • [out] result: A napi_value representing an array of JavaScript values -that represent the property names of the object. napi_get_array_length and -napi_get_element can be used to iterate over result.
        • +that represent the property names of the object. napi_get_array_length +and napi_get_element can be used to iterate over result.

        Returns napi_ok if the API succeeded.

        This API returns an array containing the names of the available properties of this object.

        -

        napi_set_property#

        +
        napi_set_property#
        -
        napi_status napi_set_property(napi_env env,
        +
        napi_status napi_set_property(napi_env env,
                                       napi_value object,
                                       napi_value key,
        -                              napi_value value);
        + napi_value value)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object on which to set the property.
        • [in] key: The name of the property to set.
        • [in] value: The property value.

        Returns napi_ok if the API succeeded.

        This API set a property on the Object passed in.

        -

        napi_get_property#

        +
        napi_get_property#
        -
        napi_status napi_get_property(napi_env env,
        +
        napi_status napi_get_property(napi_env env,
                                       napi_value object,
                                       napi_value key,
        -                              napi_value* result);
        + napi_value* result)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object from which to retrieve the property.
        • [in] key: The name of the property to retrieve.
        • [out] result: The value of the property.

        Returns napi_ok if the API succeeded.

        This API gets the requested property from the Object passed in.

        -

        napi_has_property#

        +
        napi_has_property#
        -
        napi_status napi_has_property(napi_env env,
        +
        napi_status napi_has_property(napi_env env,
                                       napi_value object,
                                       napi_value key,
        -                              bool* result);
        + bool* result)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object to query.
        • [in] key: The name of the property whose existence to check.
        • [out] result: Whether the property exists on the object or not.

        Returns napi_ok if the API succeeded.

        This API checks if the Object passed in has the named property.

        -

        napi_delete_property#

        +
        napi_delete_property#
        -
        napi_status napi_delete_property(napi_env env,
        +
        napi_status napi_delete_property(napi_env env,
                                          napi_value object,
                                          napi_value key,
        -                                 bool* result);
        + bool* result)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object to query.
        • [in] key: The name of the property to delete.
        • [out] result: Whether the property deletion succeeded or not. result can @@ -3562,36 +3591,36 @@ optionally be ignored by passing NULL.

        Returns napi_ok if the API succeeded.

        This API attempts to delete the key own property from object.

        -

        napi_has_own_property#

        +
        napi_has_own_property#
        -
        napi_status napi_has_own_property(napi_env env,
        +
        napi_status napi_has_own_property(napi_env env,
                                           napi_value object,
                                           napi_value key,
        -                                  bool* result);
        + bool* result)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object to query.
        • [in] key: The name of the own property whose existence to check.
        • [out] result: Whether the own property exists on the object or not.

        Returns napi_ok if the API succeeded.

        This API checks if the Object passed in has the named own property. key must -be a string or a Symbol, or an error will be thrown. N-API will not perform -any conversion between data types.

        -

        napi_set_named_property#

        +be a string or a symbol, or an error will be thrown. Node-API will not +perform any conversion between data types.

        +
        napi_set_named_property#
        -
        napi_status napi_set_named_property(napi_env env,
        +
        napi_status napi_set_named_property(napi_env env,
                                             napi_value object,
        -                                    const char* utf8Name,
        -                                    napi_value value);
        + const char* utf8Name, + napi_value value)
        ;
          -
        • [in] env: The environment that the N-API call is invoked under.
        • +
        • [in] env: The environment that the Node-API call is invoked under.
        • [in] object: The object on which to set the property.
        • [in] utf8Name: The name of the property to set.
        • [in] value: The property value.
        • @@ -3599,17 +3628,17 @@ any conversion between data types.

          Returns napi_ok if the API succeeded.

          This method is equivalent to calling napi_set_property with a napi_value created from the string passed in as utf8Name.

          -

          napi_get_named_property#

          +
          napi_get_named_property#
          -
          napi_status napi_get_named_property(napi_env env,
          +
          napi_status napi_get_named_property(napi_env env,
                                               napi_value object,
          -                                    const char* utf8Name,
          -                                    napi_value* result);
          + const char* utf8Name, + napi_value* result)
          ;
            -
          • [in] env: The environment that the N-API call is invoked under.
          • +
          • [in] env: The environment that the Node-API call is invoked under.
          • [in] object: The object from which to retrieve the property.
          • [in] utf8Name: The name of the property to get.
          • [out] result: The value of the property.
          • @@ -3617,17 +3646,17 @@ created from the string passed in as utf8Name.

            Returns napi_ok if the API succeeded.

            This method is equivalent to calling napi_get_property with a napi_value created from the string passed in as utf8Name.

            -

            napi_has_named_property#

            +
            napi_has_named_property#
            -
            napi_status napi_has_named_property(napi_env env,
            +
            napi_status napi_has_named_property(napi_env env,
                                                 napi_value object,
            -                                    const char* utf8Name,
            -                                    bool* result);
            + const char* utf8Name, + bool* result)
            ;
              -
            • [in] env: The environment that the N-API call is invoked under.
            • +
            • [in] env: The environment that the Node-API call is invoked under.
            • [in] object: The object to query.
            • [in] utf8Name: The name of the property whose existence to check.
            • [out] result: Whether the property exists on the object or not.
            • @@ -3635,51 +3664,51 @@ created from the string passed in as utf8Name.

              Returns napi_ok if the API succeeded.

              This method is equivalent to calling napi_has_property with a napi_value created from the string passed in as utf8Name.

              -

              napi_set_element#

              +
              napi_set_element#
              -
              napi_status napi_set_element(napi_env env,
              +
              napi_status napi_set_element(napi_env env,
                                            napi_value object,
              -                             uint32_t index,
              -                             napi_value value);
              + uint32_t index, + napi_value value)
              ;
                -
              • [in] env: The environment that the N-API call is invoked under.
              • +
              • [in] env: The environment that the Node-API call is invoked under.
              • [in] object: The object from which to set the properties.
              • [in] index: The index of the property to set.
              • [in] value: The property value.

              Returns napi_ok if the API succeeded.

              This API sets and element on the Object passed in.

              -

              napi_get_element#

              +
              napi_get_element#
              -
              napi_status napi_get_element(napi_env env,
              +
              napi_status napi_get_element(napi_env env,
                                            napi_value object,
              -                             uint32_t index,
              -                             napi_value* result);
              + uint32_t index, + napi_value* result)
              ;
                -
              • [in] env: The environment that the N-API call is invoked under.
              • +
              • [in] env: The environment that the Node-API call is invoked under.
              • [in] object: The object from which to retrieve the property.
              • [in] index: The index of the property to get.
              • [out] result: The value of the property.

              Returns napi_ok if the API succeeded.

              This API gets the element at the requested index.

              -

              napi_has_element#

              +
              napi_has_element#
              -
              napi_status napi_has_element(napi_env env,
              +
              napi_status napi_has_element(napi_env env,
                                            napi_value object,
              -                             uint32_t index,
              -                             bool* result);
              + uint32_t index, + bool* result)
              ;
                -
              • [in] env: The environment that the N-API call is invoked under.
              • +
              • [in] env: The environment that the Node-API call is invoked under.
              • [in] object: The object to query.
              • [in] index: The index of the property whose existence to check.
              • [out] result: Whether the property exists on the object or not.
              • @@ -3687,17 +3716,17 @@ created from the string passed in as utf8Name.

                Returns napi_ok if the API succeeded.

                This API returns if the Object passed in has an element at the requested index.

                -

                napi_delete_element#

                +
                napi_delete_element#
                -
                napi_status napi_delete_element(napi_env env,
                +
                napi_status napi_delete_element(napi_env env,
                                                 napi_value object,
                -                                uint32_t index,
                -                                bool* result);
                + uint32_t index, + bool* result)
                ;
                  -
                • [in] env: The environment that the N-API call is invoked under.
                • +
                • [in] env: The environment that the Node-API call is invoked under.
                • [in] object: The object to query.
                • [in] index: The index of the property to delete.
                • [out] result: Whether the element deletion succeeded or not. result can @@ -3705,17 +3734,17 @@ optionally be ignored by passing NULL.

                Returns napi_ok if the API succeeded.

                This API attempts to delete the specified index from object.

                -

                napi_define_properties#

                +
                napi_define_properties#
                -
                napi_status napi_define_properties(napi_env env,
                +
                napi_status napi_define_properties(napi_env env,
                                                    napi_value object,
                -                                   size_t property_count,
                -                                   const napi_property_descriptor* properties);
                + size_t property_count, + const napi_property_descriptor* properties)
                ;
                  -
                • [in] env: The environment that the N-API call is invoked under.
                • +
                • [in] env: The environment that the Node-API call is invoked under.
                • [in] object: The object from which to retrieve the properties.
                • [in] property_count: The number of elements in the properties array.
                • [in] properties: The array of property descriptors.
                • @@ -3727,15 +3756,15 @@ object. The properties are defined using property descriptors (see this API will set the properties on the object one at a time, as defined by DefineOwnProperty() (described in Section 9.1.6 of the ECMA-262 specification).

                  -

                  napi_object_freeze#

                  +
                  napi_object_freeze#
                  -
                  napi_status napi_object_freeze(napi_env env,
                  -                               napi_value object);
                  +
                  napi_status napi_object_freeze(napi_env env,
                  +                               napi_value object);
                    -
                  • [in] env: The environment that the N-API call is invoked under.
                  • +
                  • [in] env: The environment that the Node-API call is invoked under.
                  • [in] object: The object to freeze.

                  Returns napi_ok if the API succeeded.

                  @@ -3746,15 +3775,15 @@ properties, and prevents the values of existing properties from being changed. It also prevents the object's prototype from being changed. This is described in Section 19.1.2.6 of the ECMA-262 specification.

                  -

                  napi_object_seal#

                  +
                  napi_object_seal#
                  -
                  napi_status napi_object_seal(napi_env env,
                  -                             napi_value object);
                  +
                  napi_status napi_object_seal(napi_env env,
                  +                             napi_value object);
                    -
                  • [in] env: The environment that the N-API call is invoked under.
                  • +
                  • [in] env: The environment that the Node-API call is invoked under.
                  • [in] object: The object to seal.

                  Returns napi_ok if the API succeeded.

                  @@ -3762,9 +3791,9 @@ ECMA-262 specification.

                  added to it, as well as marking all existing properties as non-configurable. This is described in Section 19.1.2.20 of the ECMA-262 specification.

                  -

                  Working with JavaScript functions#

                  -

                  N-API provides a set of APIs that allow JavaScript code to -call back into native code. N-API APIs that support calling back +

                  Working with JavaScript functions#

                  +

                  Node-API provides a set of APIs that allow JavaScript code to +call back into native code. Node-APIs that support calling back into native code take in a callback functions represented by the napi_callback type. When the JavaScript VM calls back to native code, the napi_callback function provided is invoked. The APIs @@ -3775,7 +3804,7 @@ following:

                • Get the arguments passed into the callback.
                • Return a napi_value back from the callback.
                -

                Additionally, N-API provides a set of functions which allow calling +

                Additionally, Node-API provides a set of functions which allow calling JavaScript functions from native code. One can either call a function like a regular JavaScript function call, or as a constructor function.

                @@ -3783,20 +3812,20 @@ function.

                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#

                +

                napi_call_function#

                -
                NAPI_EXTERN napi_status napi_call_function(napi_env env,
                +
                NAPI_EXTERN napi_status napi_call_function(napi_env env,
                                                            napi_value recv,
                                                            napi_value func,
                -                                           size_t argc,
                +                                           size_t argc,
                                                            const napi_value* argv,
                -                                           napi_value* result);
                + napi_value* result)
                ;
                • [in] env: The environment that the API is invoked under.
                • -
                • [in] recv: The this object passed to the called function.
                • +
                • [in] recv: The this value passed to the called function.
                • [in] func: napi_value representing the JavaScript function to be invoked.
                • [in] argc: The count of elements in the argv array.
                • [in] argv: Array of napi_values representing JavaScript values passed in @@ -3810,7 +3839,7 @@ native code into JavaScript. For the special case of calling into JavaS after an async operation, see napi_make_callback.

                  A sample use case might look as follows. Consider the following JavaScript snippet:

                  -
                  function AddTwo(num) {
                  +
                  function AddTwo(num) {
                     return num + 2;
                   }

                  Then, the above function can be invoked from a native add-on using the @@ -3828,7 +3857,7 @@ status = napi_create_int32(env, 1337, &arg if (status != napi_ok) return; napi_value* argv = &arg; -size_t argc = 1; +size_t argc = 1; // AddTwo(arg); napi_value return_val; @@ -3836,20 +3865,20 @@ status = napi_call_function(env, global, add_two, argc, argv, &return_val); if (status != napi_ok) return; // Convert the result back to a native type -int32_t result; +int32_t result; status = napi_get_value_int32(env, return_val, &result); if (status != napi_ok) return;

                  -

                  napi_create_function#

                  +

                  napi_create_function#

                  -
                  napi_status napi_create_function(napi_env env,
                  -                                 const char* utf8name,
                  -                                 size_t length,
                  +
                  napi_status napi_create_function(napi_env env,
                  +                                 const char* utf8name,
                  +                                 size_t length,
                                                    napi_callback cb,
                  -                                 void* data,
                  -                                 napi_value* result);
                  + void* data, + napi_value* result)
                  ;
                  • [in] env: The environment that the API is invoked under.
                  • [in] utf8Name: The name of the function encoded as UTF8. This is visible @@ -3873,12 +3902,12 @@ to JavaScript, in order for the function to be accessible from script.

                    In order to expose a function as part of the add-on's module exports, set the newly created function on the exports object. A sample module might look as follows:

                    -
                    napi_value SayHello(napi_env env, napi_callback_info info) {
                    +
                    napi_value SayHello(napi_env env, napi_callback_info info) {
                       printf("Hello\n");
                       return NULL;
                     }
                     
                    -napi_value Init(napi_env env, napi_value exports) {
                    +napi_value Init(napi_env env, napi_value exports) {
                       napi_status status;
                     
                       napi_value fn;
                    @@ -3894,7 +3923,7 @@ object. A sample module might look as follows:

                    NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)

                    Given the above code, the add-on can be used from JavaScript as follows:

                    const myaddon = require('./addon');
                    -myaddon.sayHello();
                    +myaddon.sayHello();

                    The string passed to require() is the name of the target in binding.gyp responsible for creating the .node file.

                    Any non-NULL data which is passed to this API via the data parameter can @@ -3903,22 +3932,22 @@ be associated with the resulting JavaScript function (which is returned in the passing both the JavaScript function and the data to napi_add_finalizer.

                    JavaScript Functions are described in Section 19.2 of the ECMAScript Language Specification.

                    -

                    napi_get_cb_info#

                    +

                    napi_get_cb_info#

                    -
                    napi_status napi_get_cb_info(napi_env env,
                    +
                    napi_status napi_get_cb_info(napi_env env,
                                                  napi_callback_info cbinfo,
                    -                             size_t* argc,
                    +                             size_t* argc,
                                                  napi_value* argv,
                                                  napi_value* thisArg,
                    -                             void** data)
                    + void** data)
                    • [in] env: The environment that the API is invoked under.
                    • [in] cbinfo: The callback info passed into the callback function.
                    • -
                    • [in-out] argc: Specifies the size of the provided argv array and receives -the actual count of arguments.
                    • +
                    • [in-out] argc: Specifies the length of the provided argv array and +receives the actual count of arguments.
                    • [out] argv: Buffer to which the napi_value representing the arguments are copied. If there are more arguments than the provided count, only the requested number of arguments are copied. If there are fewer arguments @@ -3930,14 +3959,14 @@ that represent undefined.
                    • Returns napi_ok if the API succeeded.

                      This method is used within a callback function to retrieve details about the call like the arguments and the this pointer from a given callback info.

                      -

                      napi_get_new_target#

                      +

                      napi_get_new_target#

                      -
                      napi_status napi_get_new_target(napi_env env,
                      +
                      napi_status napi_get_new_target(napi_env env,
                                                       napi_callback_info cbinfo,
                      -                                napi_value* result)
                      + napi_value* result)
                      • [in] env: The environment that the API is invoked under.
                      • [in] cbinfo: The callback info passed into the callback function.
                      • @@ -3946,16 +3975,16 @@ call like the arguments and the this pointer from a given callback

                        Returns napi_ok if the API succeeded.

                        This API returns the new.target of the constructor call. If the current callback is not a constructor call, the result is NULL.

                        -

                        napi_new_instance#

                        +

                        napi_new_instance#

                        -
                        napi_status napi_new_instance(napi_env env,
                        +
                        napi_status napi_new_instance(napi_env env,
                                                       napi_value cons,
                        -                              size_t argc,
                        +                              size_t argc,
                                                       napi_value* argv,
                        -                              napi_value* result)
                        + napi_value* result)
                        • [in] env: The environment that the API is invoked under.
                        • [in] cons: napi_value representing the JavaScript function to be invoked @@ -3969,13 +3998,13 @@ which in this case is the constructed object.
                        • This method is used to instantiate a new JavaScript value using a given napi_value that represents the constructor for the object. For example, consider the following snippet:

                          -
                          function MyObject(param) {
                          -  this.param = param;
                          +
                          function MyObject(param) {
                          +  this.param = param;
                           }
                           
                           const arg = 'hello';
                          -const value = new MyObject(arg);
                          -

                          The following can be approximated in N-API using the following snippet:

                          +const value = new MyObject(arg);
                          +

                          The following can be approximated in Node-API using the following snippet:

                          // Get the constructor function MyObject
                           napi_value global, constructor, arg, value;
                           napi_status status = napi_get_global(env, &global);
                          @@ -3989,13 +4018,13 @@ status = napi_create_string_utf8(env, "hello",
                           if (status != napi_ok) return;
                           
                           napi_value* argv = &arg;
                          -size_t argc = 1;
                          +size_t argc = 1;
                           
                           // const value = new MyObject(arg)
                           status = napi_new_instance(env, constructor, argc, argv, &value);

                          Returns napi_ok if the API succeeded.

                          -

                          Object wrap#

                          -

                          N-API offers a way to "wrap" C++ classes and instances so that the class +

                          Object wrap#

                          +

                          Node-API offers a way to "wrap" C++ classes and instances so that the class constructor and methods can be called from JavaScript.

                          1. The napi_define_class API defines a JavaScript class with constructor, @@ -4016,7 +4045,7 @@ reference to the class constructor for later instanceof checks.

                            napi_value MyClass_constructor = NULL;
                             status = napi_get_reference_value(env, MyClass::es_constructor, &MyClass_constructor);
                             assert(napi_ok == status);
                            -bool is_instance = false;
                            +bool is_instance = false;
                             status = napi_instanceof(env, es_this, MyClass_constructor, &is_instance);
                             assert(napi_ok == status);
                             if (is_instance) {
                            @@ -4034,10 +4063,10 @@ cases there is a chance that they may be unwrapped incorrectly.

                            // `openDatabase()` returns a JavaScript object that wraps a native database // handle. -const dbHandle = myAddon.openDatabase(); +const dbHandle = myAddon.openDatabase(); // `query()` returns a JavaScript object that wraps a native query handle. -const queryHandle = myAddon.query(dbHandle, 'Gimme ALL the things!'); +const queryHandle = myAddon.query(dbHandle, 'Gimme ALL the things!'); // There is an accidental error in the line below. The first parameter to // `myAddon.queryHasRecords()` should be the database handle (`dbHandle`), not @@ -4046,7 +4075,7 @@ cases there is a chance that they may be unwrapped incorrectly.

                            // // myAddon.queryHasRecords(dbHandle, queryHandle) // -while (myAddon.queryHasRecords(queryHandle, dbHandle)) { +while (myAddon.queryHasRecords(queryHandle, dbHandle)) { // retrieve records }

                            In the above example myAddon.queryHasRecords() is a method that accepts two @@ -4070,8 +4099,8 @@ set to the prototype of the constructor for query handle instances. In this case, the database handle instance can appear as a query handle instance, and it will pass the napi_instanceof() test for a query handle instance, while still containing a pointer to a database handle.

                            -

                            To this end, N-API provides type-tagging capabilities.

                            -

                            A type tag is a 128-bit integer unique to the addon. N-API provides the +

                            To this end, Node-API provides type-tagging capabilities.

                            +

                            A type tag is a 128-bit integer unique to the addon. Node-API provides the napi_type_tag structure for storing a type tag. When such a value is passed along with a JavaScript object stored in a napi_value to napi_type_tag_object(), the JavaScript object will be "marked" with the @@ -4098,8 +4127,8 @@ illustrates the use of napi_type_tag_object() and 0x9c73317f9fad44a3, 0x93c3920bf3b0ad6a }; -static napi_value -openDatabase(napi_env env, napi_callback_info info) { +static napi_value +openDatabase(napi_env env, napi_callback_info info) { napi_status status; napi_value result; @@ -4125,12 +4154,12 @@ illustrates the use of napi_type_tag_object() and // we can use `napi_check_object_type_tag()` to ensure that it is indeed such a // handle. -static napi_value -query(napi_env env, napi_callback_info info) { +static napi_value +query(napi_env env, napi_callback_info info) { napi_status status; - size_t argc = 2; + size_t argc = 2; napi_value argv[2]; - bool is_db_handle; + bool is_db_handle; status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL); if (status != napi_ok) return NULL; @@ -4149,29 +4178,30 @@ illustrates the use of napi_type_tag_object() and return NULL; } } -

                            napi_define_class#

                            +

                            napi_define_class#

                            -
                            napi_status napi_define_class(napi_env env,
                            -                              const char* utf8name,
                            -                              size_t length,
                            +
                            napi_status napi_define_class(napi_env env,
                            +                              const char* utf8name,
                            +                              size_t length,
                                                           napi_callback constructor,
                            -                              void* data,
                            -                              size_t property_count,
                            +                              void* data,
                            +                              size_t property_count,
                                                           const napi_property_descriptor* properties,
                            -                              napi_value* result);
                            + napi_value* result)
                            ;
                            • [in] env: The environment that the API is invoked under.
                            • -
                            • [in] utf8name: Name of the JavaScript constructor function; this is -not required to be the same as the C++ class name, though it is recommended -for clarity.
                            • +
                            • [in] utf8name: Name of the JavaScript constructor function; When wrapping a +C++ class, we recommend for clarity that this name be the same as that of +the C++ class.
                            • [in] length: The length of the utf8name in bytes, or NAPI_AUTO_LENGTH if it is null-terminated.
                            • [in] constructor: Callback function that handles constructing instances -of the class. This should be a static method on the class, not an actual -C++ constructor function. napi_callback provides more details.
                            • +of the class. When wrapping a C++ class, this method must be a static member +with the napi_callback signature. A C++ class constructor cannot be +used. napi_callback provides more details.
                            • [in] data: Optional data to be passed to the constructor callback as the data property of the callback info.
                            • [in] property_count: Number of items in the properties array argument.
                            • @@ -4182,42 +4212,48 @@ See napi_property_descriptor. the class.

                            Returns napi_ok if the API succeeded.

                            -

                            Defines a JavaScript class that corresponds to a C++ class, including:

                            -
                              -
                            • A JavaScript constructor function that has the class name and invokes the -provided C++ constructor callback.
                            • -
                            • Properties on the constructor function corresponding to static data -properties, accessors, and methods of the C++ class (defined by -property descriptors with the napi_static attribute).
                            • -
                            • Properties on the constructor function's prototype object corresponding to -non-static data properties, accessors, and methods of the C++ class -(defined by property descriptors without the napi_static attribute).
                            • -
                            -

                            The C++ constructor callback should be a static method on the class that calls -the actual class constructor, then wraps the new C++ instance in a JavaScript -object, and returns the wrapper object. See napi_wrap() for details.

                            +

                            Defines a JavaScript class, including:

                            +
                              +
                            • A JavaScript constructor function that has the class name. When wrapping a +corresponding C++ class, the callback passed via constructor can be used to +instantiate a new C++ class instance, which can then be placed inside the +JavaScript object instance being constructed using napi_wrap.
                            • +
                            • Properties on the constructor function whose implementation can call +corresponding static data properties, accessors, and methods of the C++ +class (defined by property descriptors with the napi_static attribute).
                            • +
                            • Properties on the constructor function's prototype object. When wrapping a +C++ class, non-static data properties, accessors, and methods of the C++ +class can be called from the static functions given in the property +descriptors without the napi_static attribute after retrieving the C++ class +instance placed inside the JavaScript object instance by using +napi_unwrap.
                            • +
                            +

                            When wrapping a C++ class, the C++ constructor callback passed via constructor +should be a static method on the class that calls the actual class constructor, +then wraps the new C++ instance in a JavaScript object, and returns the wrapper +object. See napi_wrap for details.

                            The JavaScript constructor function returned from napi_define_class is -often saved and used later, to construct new instances of the class from native -code, and/or check whether provided values are instances of the class. In that -case, to prevent the function value from being garbage-collected, create a -persistent reference to it using napi_create_reference and ensure the -reference count is kept >= 1.

                            +often saved and used later to construct new instances of the class from native +code, and/or to check whether provided values are instances of the class. In +that case, to prevent the function value from being garbage-collected, a +strong persistent reference to it can be created using +napi_create_reference, ensuring that the reference count is kept >= 1.

                            Any non-NULL data which is passed to this API via the data parameter or via the data field of the napi_property_descriptor array items can be associated with the resulting JavaScript constructor (which is returned in the result parameter) and freed whenever the class is garbage-collected by passing both the JavaScript function and the data to napi_add_finalizer.

                            -

                            napi_wrap#

                            +

                            napi_wrap#

                            -
                            napi_status napi_wrap(napi_env env,
                            +
                            napi_status napi_wrap(napi_env env,
                                                   napi_value js_object,
                            -                      void* native_object,
                            +                      void* native_object,
                                                   napi_finalize finalize_cb,
                            -                      void* finalize_hint,
                            -                      napi_ref* result);
                            + void* finalize_hint, + napi_ref* result)
                            ;
                            • [in] env: The environment that the API is invoked under.
                            • [in] js_object: The JavaScript object that will be the wrapper for the @@ -4255,14 +4291,14 @@ required in order to enable correct disposal of the reference.

                              Calling napi_wrap() a second time on an object will return an error. To associate another native instance with the object, use napi_remove_wrap() first.

                              -

                              napi_unwrap#

                              +

                              napi_unwrap#

                              -
                              napi_status napi_unwrap(napi_env env,
                              +
                              napi_status napi_unwrap(napi_env env,
                                                       napi_value js_object,
                              -                        void** result);
                              + void** result)
                              ;
                              • [in] env: The environment that the API is invoked under.
                              • [in] js_object: The object associated with the native instance.
                              • @@ -4276,14 +4312,14 @@ corresponding napi_callback is invoked. If the callback is for an i method or accessor, then the this argument to the callback is the wrapper object; the wrapped C++ instance that is the target of the call can be obtained then by calling napi_unwrap() on the wrapper object.

                                -

                                napi_remove_wrap#

                                +

                                napi_remove_wrap#

                                -
                                napi_status napi_remove_wrap(napi_env env,
                                +
                                napi_status napi_remove_wrap(napi_env env,
                                                              napi_value js_object,
                                -                             void** result);
                                + void** result)
                                ;
                                • [in] env: The environment that the API is invoked under.
                                • [in] js_object: The object associated with the native instance.
                                • @@ -4294,14 +4330,14 @@ then by calling napi_unwrap() on the wrapper object.

                                  object js_object using napi_wrap() and removes the wrapping. If a finalize callback was associated with the wrapping, it will no longer be called when the JavaScript object becomes garbage-collected.

                                  -

                                  napi_type_tag_object#

                                  +

                                  napi_type_tag_object#

                                  -
                                  napi_status napi_type_tag_object(napi_env env,
                                  +
                                  napi_status napi_type_tag_object(napi_env env,
                                                                    napi_value js_object,
                                  -                                 const napi_type_tag* type_tag);
                                  + const napi_type_tag* type_tag)
                                  ;
                                  • [in] env: The environment that the API is invoked under.
                                  • [in] js_object: The JavaScript object to be marked.
                                  • @@ -4314,15 +4350,15 @@ attached to the object with one owned by the addon to ensure that the object has the right type.

                                    If the object already has an associated type tag, this API will return napi_invalid_arg.

                                    -

                                    napi_check_object_type_tag#

                                    +

                                    napi_check_object_type_tag#

                                    -
                                    napi_status napi_check_object_type_tag(napi_env env,
                                    +
                                    napi_status napi_check_object_type_tag(napi_env env,
                                                                            napi_value js_object,
                                                                            const napi_type_tag* type_tag,
                                    -                                       bool* result);
                                    + bool* result)
                                    ;
                                    • [in] env: The environment that the API is invoked under.
                                    • [in] js_object: The JavaScript object whose type tag to examine.
                                    • @@ -4335,17 +4371,17 @@ object. false is also returned if no type tag was found on the obje js_object. If no tag is found on js_object or, if a tag is found but it does not match type_tag, then result is set to false. If a tag is found and it matches type_tag, then result is set to true.

                                      -

                                      napi_add_finalizer#

                                      +

                                      napi_add_finalizer#

                                      -
                                      napi_status napi_add_finalizer(napi_env env,
                                      +
                                      napi_status napi_add_finalizer(napi_env env,
                                                                      napi_value js_object,
                                      -                               void* native_object,
                                      +                               void* native_object,
                                                                      napi_finalize finalize_cb,
                                      -                               void* finalize_hint,
                                      -                               napi_ref* result);
                                      + 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 @@ -4375,45 +4411,45 @@ attach each of them to the JavaScript object, and
                                      • 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#

                                        +

                          Simple asynchronous operations#

                          Addon modules often need to leverage async helpers from libuv as part of their implementation. This allows them to schedule work to be executed asynchronously so that their methods can return in advance of the work being completed. This allows them to avoid blocking overall execution of the Node.js application.

                          -

                          N-API provides an ABI-stable interface for these +

                          Node-API provides an ABI-stable interface for these supporting functions which covers the most common asynchronous use cases.

                          -

                          N-API defines the napi_async_work structure which is used to manage +

                          Node-API defines the napi_async_work structure which is used to manage asynchronous workers. Instances are created/deleted with napi_create_async_work and napi_delete_async_work.

                          The execute and complete callbacks are functions that will be invoked when the executor is ready to execute and when it completes its task respectively.

                          -

                          The execute function should avoid making any N-API calls +

                          The execute function should avoid making any Node-API calls that could result in the execution of JavaScript or interaction with -JavaScript objects. Most often, any code that needs to make N-API +JavaScript objects. Most often, any code that needs to make Node-API calls should be made in complete callback instead. Avoid using the napi_env parameter in the execute callback as it will likely execute JavaScript.

                          These functions implement the following interfaces:

                          -
                          typedef void (*napi_async_execute_callback)(napi_env env,
                          -                                            void* data);
                          -typedef void (*napi_async_complete_callback)(napi_env env,
                          +
                          typedef void (*napi_async_execute_callback)(napi_env env,
                          +                                            void* data);
                          +typedef void (*napi_async_complete_callback)(napi_env env,
                                                                        napi_status status,
                          -                                             void* data);
                          + void* data)
                          ;

                          When these methods are invoked, the data parameter passed will be the addon-provided void* data that was passed into the napi_create_async_work call.

                          Once created the async worker can be queued for execution using the napi_queue_async_work function:

                          -
                          napi_status napi_queue_async_work(napi_env env,
                          -                                  napi_async_work work);
                          +
                          napi_status napi_queue_async_work(napi_env env,
                          +                                  napi_async_work work);

                          napi_cancel_async_work can be used if the work needs to be cancelled before the work has started execution.

                          After calling napi_cancel_async_work, the complete callback will be invoked with a status value of napi_cancelled. The work should not be deleted before the complete callback invocation, even when it was cancelled.

                          -

                          napi_create_async_work#

                          +

                          napi_create_async_work#

                          -
                          NAPI_EXTERN napi_status
                          -napi_call_threadsafe_function(napi_threadsafe_function func,
                          -                              void* data,
                          -                              napi_threadsafe_function_call_mode is_blocking);
                          +
                          NAPI_EXTERN napi_status
                          +napi_call_threadsafe_function(napi_threadsafe_function func,
                          +                              void* data,
                          +                              napi_threadsafe_function_call_mode is_blocking);
                          • [in] func: The asynchronous thread-safe JavaScript function to invoke.
                          • [in] data: Data to send into JavaScript via the callback call_js_cb @@ -5046,17 +5109,20 @@ indicate that the call should block if the queue is full or napi_tsfn_nonblocking to indicate that the call should return immediately with a status of napi_queue_full whenever the queue is full.
                          +

                          This API should not be called with napi_tsfn_blocking from a JavaScript +thread, because, if the queue is full, it may cause the JavaScript thread to +deadlock.

                          This API will return napi_closing if napi_release_threadsafe_function() was called with abort set to napi_tsfn_abort from any thread. The value is only added to the queue if the API returns napi_ok.

                          This API may be called from any thread which makes use of func.

                          -

                          napi_acquire_threadsafe_function#

                          +

                          napi_acquire_threadsafe_function#

                          -
                          NAPI_EXTERN napi_status
                          -napi_acquire_threadsafe_function(napi_threadsafe_function func);
                          +
                          NAPI_EXTERN napi_status
                          +napi_acquire_threadsafe_function(napi_threadsafe_function func);
                          • [in] func: The asynchronous thread-safe JavaScript function to start making use of.
                          • @@ -5066,14 +5132,14 @@ function APIs to indicate that it will be making use of func. This func from being destroyed when all other threads have stopped making use of it.

                            This API may be called from any thread which will start making use of func.

                            -

                            napi_release_threadsafe_function#

                            +

                            napi_release_threadsafe_function#

                            -
                            NAPI_EXTERN napi_status
                            -napi_release_threadsafe_function(napi_threadsafe_function func,
                            -                                 napi_threadsafe_function_release_mode mode);
                            +
                            NAPI_EXTERN napi_status
                            +napi_release_threadsafe_function(napi_threadsafe_function func,
                            +                                 napi_threadsafe_function_release_mode mode);
                            • [in] func: The asynchronous thread-safe JavaScript function whose reference count to decrement.
                            • @@ -5089,13 +5155,13 @@ values will be placed in the queue. to any thread-safe APIs after having called this API has undefined results, as func may have been destroyed.

                              This API may be called from any thread which will stop making use of func.

                              -

                              napi_ref_threadsafe_function#

                              +

                              napi_ref_threadsafe_function#

                              -
                              NAPI_EXTERN napi_status
                              -napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func);
                              +
                              NAPI_EXTERN napi_status
                              +napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func);
                              • [in] env: The environment that the API is invoked under.
                              • [in] func: The thread-safe function to reference.
                              • @@ -5108,13 +5174,13 @@ able to be destroyed nor does napi_ref_threadsafe_function prevent being destroyed. napi_acquire_threadsafe_function and napi_release_threadsafe_function are available for that purpose.

                                This API may only be called from the main thread.

                                -

                                napi_unref_threadsafe_function#

                                +

                                napi_unref_threadsafe_function#

                                -
                                NAPI_EXTERN napi_status
                                -napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func);
                                +
                                NAPI_EXTERN napi_status
                                +napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func);
                                • [in] env: The environment that the API is invoked under.
                                • [in] func: The thread-safe function to unreference.
                                • @@ -5123,14 +5189,14 @@ being destroyed. napi_acquire_threadsafe_function and may exit before func is destroyed. Similar to uv_unref it is also idempotent.

                                  This API may only be called from the main thread.

                                  -

                                  Miscellaneous utilities#

                                  -

                                  node_api_get_module_file_name#

                                  +

                          Miscellaneous utilities#

                          +

                          node_api_get_module_file_name#

                          Stability: 1 - Experimental

                          -
                          NAPI_EXTERN napi_status
                          -node_api_get_module_file_name(napi_env env, const char** result);
                          +
                          NAPI_EXTERN napi_status
                          +node_api_get_module_file_name(napi_env env, const char** result);
                           
                          • [in] env: The environment that the API is invoked under.
                          • @@ -5140,10 +5206,46 @@ file system it will start with file://. The string is null-terminat owned by env and must thus not be modified or freed.

                          result may be an empty string if the add-on loading process fails to establish -the add-on's file name during loading.

                          +the add-on's file name during loading.

                          + diff --git a/doc/api/n-api.json b/doc/api/n-api.json index e7e626e223156d54f7f1ab1e8db33e031794ce3f..83dfab4745646b4fa8a2ac4005588aa1c3a6a14f 100644 --- a/doc/api/n-api.json +++ b/doc/api/n-api.json @@ -6,25 +6,25 @@ "stabilityText": "Stable", "miscs": [ { - "textRaw": "N-API", - "name": "N-API", + "textRaw": "Node-API", + "name": "Node-API", "introduced_in": "v8.0.0", "type": "misc", "stability": 2, "stabilityText": "Stable", - "desc": "

                          N-API (pronounced N as in the letter, followed by API)\nis an API for building native Addons. It is independent from\nthe underlying JavaScript runtime (for example, V8) and is maintained as part of\nNode.js itself. This API will be Application Binary Interface (ABI) stable\nacross versions of Node.js. It is intended to insulate Addons from\nchanges in the underlying JavaScript engine and allow modules\ncompiled for one major version to run on later major versions of Node.js without\nrecompilation. The ABI Stability guide provides a more in-depth explanation.

                          \n

                          Addons are built/packaged with the same approach/tools outlined in the section\ntitled C++ Addons. The only difference is the set of APIs that are used by\nthe native code. Instead of using the V8 or Native Abstractions for Node.js\nAPIs, the functions available in the N-API are used.

                          \n

                          APIs exposed by N-API are generally used to create and manipulate\nJavaScript values. Concepts and operations generally map to ideas specified\nin the ECMA-262 Language Specification. The APIs have the following\nproperties:

                          \n
                            \n
                          • All N-API calls return a status code of type napi_status. This\nstatus indicates whether the API call succeeded or failed.
                          • \n
                          • The API's return value is passed via an out parameter.
                          • \n
                          • All JavaScript values are abstracted behind an opaque type named\nnapi_value.
                          • \n
                          • In case of an error status code, additional information can be obtained\nusing napi_get_last_error_info. More information can be found in the error\nhandling section Error handling.
                          • \n
                          \n

                          The N-API is a C API that ensures ABI stability across Node.js versions\nand different compiler levels. A C++ API can be easier to use.\nTo support using C++, the project maintains a\nC++ wrapper module called node-addon-api.\nThis wrapper provides an inlineable C++ API. Binaries built\nwith node-addon-api will depend on the symbols for the N-API C-based\nfunctions exported by Node.js. node-addon-api is a more\nefficient way to write code that calls N-API. Take, for example, the\nfollowing node-addon-api code. The first section shows the\nnode-addon-api code and the second section shows what actually gets\nused in the addon.

                          \n
                          Object obj = Object::New(env);\nobj[\"foo\"] = String::New(env, \"bar\");\n
                          \n
                          napi_status status;\nnapi_value object, string;\nstatus = napi_create_object(env, &object);\nif (status != napi_ok) {\n  napi_throw_error(env, ...);\n  return;\n}\n\nstatus = napi_create_string_utf8(env, \"bar\", NAPI_AUTO_LENGTH, &string);\nif (status != napi_ok) {\n  napi_throw_error(env, ...);\n  return;\n}\n\nstatus = napi_set_named_property(env, object, \"foo\", string);\nif (status != napi_ok) {\n  napi_throw_error(env, ...);\n  return;\n}\n
                          \n

                          The end result is that the addon only uses the exported C APIs. As a result,\nit still gets the benefits of the ABI stability provided by the C API.

                          \n

                          When using node-addon-api instead of the C APIs, start with the API docs\nfor node-addon-api.

                          \n

                          The N-API Resource offers an\nexcellent orientation and tips for developers just getting started with N-API\nand node-addon-api.

                          ", + "desc": "

                          Node-API (formerly N-API) is an API for building native Addons. It is\nindependent from the underlying JavaScript runtime (for example, V8) and is\nmaintained as part of Node.js itself. This API will be Application Binary\nInterface (ABI) stable across versions of Node.js. It is intended to insulate\naddons from changes in the underlying JavaScript engine and allow modules\ncompiled for one major version to run on later major versions of Node.js without\nrecompilation. The ABI Stability guide provides a more in-depth explanation.

                          \n

                          Addons are built/packaged with the same approach/tools outlined in the section\ntitled C++ Addons. The only difference is the set of APIs that are used by\nthe native code. Instead of using the V8 or Native Abstractions for Node.js\nAPIs, the functions available in Node-API are used.

                          \n

                          APIs exposed by Node-API are generally used to create and manipulate\nJavaScript values. Concepts and operations generally map to ideas specified\nin the ECMA-262 Language Specification. The APIs have the following\nproperties:

                          \n
                            \n
                          • All Node-API calls return a status code of type napi_status. This\nstatus indicates whether the API call succeeded or failed.
                          • \n
                          • The API's return value is passed via an out parameter.
                          • \n
                          • All JavaScript values are abstracted behind an opaque type named\nnapi_value.
                          • \n
                          • In case of an error status code, additional information can be obtained\nusing napi_get_last_error_info. More information can be found in the error\nhandling section Error handling.
                          • \n
                          \n

                          Node-API is a C API that ensures ABI stability across Node.js versions\nand different compiler levels. A C++ API can be easier to use.\nTo support using C++, the project maintains a\nC++ wrapper module called node-addon-api.\nThis wrapper provides an inlineable C++ API. Binaries built\nwith node-addon-api will depend on the symbols for the Node-API C-based\nfunctions exported by Node.js. node-addon-api is a more\nefficient way to write code that calls Node-API. Take, for example, the\nfollowing node-addon-api code. The first section shows the\nnode-addon-api code and the second section shows what actually gets\nused in the addon.

                          \n
                          Object obj = Object::New(env);\nobj[\"foo\"] = String::New(env, \"bar\");\n
                          \n
                          napi_status status;\nnapi_value object, string;\nstatus = napi_create_object(env, &object);\nif (status != napi_ok) {\n  napi_throw_error(env, ...);\n  return;\n}\n\nstatus = napi_create_string_utf8(env, \"bar\", NAPI_AUTO_LENGTH, &string);\nif (status != napi_ok) {\n  napi_throw_error(env, ...);\n  return;\n}\n\nstatus = napi_set_named_property(env, object, \"foo\", string);\nif (status != napi_ok) {\n  napi_throw_error(env, ...);\n  return;\n}\n
                          \n

                          The end result is that the addon only uses the exported C APIs. As a result,\nit still gets the benefits of the ABI stability provided by the C API.

                          \n

                          When using node-addon-api instead of the C APIs, start with the API docs\nfor node-addon-api.

                          \n

                          The Node-API Resource offers\nan excellent orientation and tips for developers just getting started with\nNode-API and node-addon-api.

                          ", "miscs": [ { "textRaw": "Implications of ABI stability", "name": "implications_of_abi_stability", - "desc": "

                          Although N-API provides an ABI stability guarantee, other parts of Node.js do\nnot, and any external libraries used from the addon may not. In particular,\nnone of the following APIs provide an ABI stability guarantee across major\nversions:

                          \n
                            \n
                          • \n

                            the Node.js C++ APIs available via any of

                            \n
                            #include <node.h>\n#include <node_buffer.h>\n#include <node_version.h>\n#include <node_object_wrap.h>\n
                            \n
                          • \n
                          • \n

                            the libuv APIs which are also included with Node.js and available via

                            \n
                            #include <uv.h>\n
                            \n
                          • \n
                          • \n

                            the V8 API available via

                            \n
                            #include <v8.h>\n
                            \n
                          • \n
                          \n

                          Thus, for an addon to remain ABI-compatible across Node.js major versions, it\nmust use N-API exclusively by restricting itself to using

                          \n
                          #include <node_api.h>\n
                          \n

                          and by checking, for all external libraries that it uses, that the external\nlibrary makes ABI stability guarantees similar to N-API.

                          ", + "desc": "

                          Although Node-API provides an ABI stability guarantee, other parts of Node.js do\nnot, and any external libraries used from the addon may not. In particular,\nnone of the following APIs provide an ABI stability guarantee across major\nversions:

                          \n
                            \n
                          • \n

                            the Node.js C++ APIs available via any of

                            \n
                            #include <node.h>\n#include <node_buffer.h>\n#include <node_version.h>\n#include <node_object_wrap.h>\n
                            \n
                          • \n
                          • \n

                            the libuv APIs which are also included with Node.js and available via

                            \n
                            #include <uv.h>\n
                            \n
                          • \n
                          • \n

                            the V8 API available via

                            \n
                            #include <v8.h>\n
                            \n
                          • \n
                          \n

                          Thus, for an addon to remain ABI-compatible across Node.js major versions, it\nmust use Node-API exclusively by restricting itself to using

                          \n
                          #include <node_api.h>\n
                          \n

                          and by checking, for all external libraries that it uses, that the external\nlibrary makes ABI stability guarantees similar to Node-API.

                          ", "type": "misc", "displayName": "Implications of ABI stability" }, { "textRaw": "Building", "name": "building", - "desc": "

                          Unlike modules written in JavaScript, developing and deploying Node.js\nnative addons using N-API requires an additional set of tools. Besides the\nbasic tools required to develop for Node.js, the native addon developer\nrequires a toolchain that can compile C and C++ code into a binary. In\naddition, depending upon how the native addon is deployed, the user of\nthe native addon will also need to have a C/C++ toolchain installed.

                          \n

                          For Linux developers, the necessary C/C++ toolchain packages are readily\navailable. GCC is widely used in the Node.js community to build and\ntest across a variety of platforms. For many developers, the LLVM\ncompiler infrastructure is also a good choice.

                          \n

                          For Mac developers, Xcode offers all the required compiler tools.\nHowever, it is not necessary to install the entire Xcode IDE. The following\ncommand installs the necessary toolchain:

                          \n
                          xcode-select --install\n
                          \n

                          For Windows developers, Visual Studio offers all the required compiler\ntools. However, it is not necessary to install the entire Visual Studio\nIDE. The following command installs the necessary toolchain:

                          \n
                          npm install --global windows-build-tools\n
                          \n

                          The sections below describe the additional tools available for developing\nand deploying Node.js native addons.

                          ", + "desc": "

                          Unlike modules written in JavaScript, developing and deploying Node.js\nnative addons using Node-API requires an additional set of tools. Besides the\nbasic tools required to develop for Node.js, the native addon developer\nrequires a toolchain that can compile C and C++ code into a binary. In\naddition, depending upon how the native addon is deployed, the user of\nthe native addon will also need to have a C/C++ toolchain installed.

                          \n

                          For Linux developers, the necessary C/C++ toolchain packages are readily\navailable. GCC is widely used in the Node.js community to build and\ntest across a variety of platforms. For many developers, the LLVM\ncompiler infrastructure is also a good choice.

                          \n

                          For Mac developers, Xcode offers all the required compiler tools.\nHowever, it is not necessary to install the entire Xcode IDE. The following\ncommand installs the necessary toolchain:

                          \n
                          xcode-select --install\n
                          \n

                          For Windows developers, Visual Studio offers all the required compiler\ntools. However, it is not necessary to install the entire Visual Studio\nIDE. The following command installs the necessary toolchain:

                          \n
                          npm install --global windows-build-tools\n
                          \n

                          The sections below describe the additional tools available for developing\nand deploying Node.js native addons.

                          ", "modules": [ { "textRaw": "Build tools", @@ -34,7 +34,7 @@ { "textRaw": "node-gyp", "name": "node-gyp", - "desc": "

                          node-gyp is a build system based on Google's GYP tool and comes\nbundled with npm. GYP, and therefore node-gyp, requires that Python be\ninstalled.

                          \n

                          Historically, node-gyp has been the tool of choice for building native\naddons. It has widespread adoption and documentation. However, some\ndevelopers have run into limitations in node-gyp.

                          ", + "desc": "

                          node-gyp is a build system based on the gyp-next fork of\nGoogle's GYP tool and comes bundled with npm. GYP, and therefore node-gyp,\nrequires that Python be installed.

                          \n

                          Historically, node-gyp has been the tool of choice for building native\naddons. It has widespread adoption and documentation. However, some\ndevelopers have run into limitations in node-gyp.

                          ", "type": "module", "displayName": "node-gyp" } @@ -86,35 +86,36 @@ { "textRaw": "Usage", "name": "usage", - "desc": "

                          In order to use the N-API functions, include the file node_api.h which is\nlocated in the src directory in the node development tree:

                          \n
                          #include <node_api.h>\n
                          \n

                          This will opt into the default NAPI_VERSION for the given release of Node.js.\nIn order to ensure compatibility with specific versions of N-API, the version\ncan be specified explicitly when including the header:

                          \n
                          #define NAPI_VERSION 3\n#include <node_api.h>\n
                          \n

                          This restricts the N-API surface to just the functionality that was available in\nthe specified (and earlier) versions.

                          \n

                          Some of the N-API surface is experimental and requires explicit opt-in:

                          \n
                          #define NAPI_EXPERIMENTAL\n#include <node_api.h>\n
                          \n

                          In this case the entire API surface, including any experimental APIs, will be\navailable to the module code.

                          ", + "desc": "

                          In order to use the Node-API functions, include the file node_api.h which\nis located in the src directory in the node development tree:

                          \n
                          #include <node_api.h>\n
                          \n

                          This will opt into the default NAPI_VERSION for the given release of Node.js.\nIn order to ensure compatibility with specific versions of Node-API, the version\ncan be specified explicitly when including the header:

                          \n
                          #define NAPI_VERSION 3\n#include <node_api.h>\n
                          \n

                          This restricts the Node-API surface to just the functionality that was available\nin the specified (and earlier) versions.

                          \n

                          Some of the Node-API surface is experimental and requires explicit opt-in:

                          \n
                          #define NAPI_EXPERIMENTAL\n#include <node_api.h>\n
                          \n

                          In this case the entire API surface, including any experimental APIs, will be\navailable to the module code.

                          ", "type": "misc", "displayName": "Usage" }, { - "textRaw": "N-API version matrix", - "name": "n-api_version_matrix", - "desc": "

                          N-API versions are additive and versioned independently from Node.js.\nVersion 4 is an extension to version 3 in that it has all of the APIs\nfrom version 3 with some additions. This means that it is not necessary\nto recompile for new versions of Node.js which are\nlisted as supporting a later version.

                          \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
                          123456
                          v6.xv6.14.2*
                          v8.xv8.0.0*v8.10.0*v8.11.2v8.16.0
                          v9.xv9.0.0*v9.3.0*v9.11.0*
                          v10.xv10.0.0v10.0.0v10.0.0v10.16.0v10.17.0v10.20.0
                          v11.xv11.0.0v11.0.0v11.0.0v11.8.0
                          v12.xv12.0.0v12.0.0v12.0.0v12.0.0v12.11.0v12.17.0
                          v13.xv13.0.0v13.0.0v13.0.0v13.0.0v13.0.0
                          v14.xv14.0.0v14.0.0v14.0.0v14.0.0v14.0.0v14.0.0
                          \n

                          * Indicates that the N-API version was released as experimental

                          \n

                          Each API documented for N-API will have a header named added in:, and APIs\nwhich are stable will have the additional header N-API version:.\nAPIs are directly usable when using a Node.js version which supports\nthe N-API version shown in N-API version: or higher.\nWhen using a Node.js version that does not support the\nN-API version: listed or if there is no N-API version: listed,\nthen the API will only be available if\n#define NAPI_EXPERIMENTAL precedes the inclusion of node_api.h\nor js_native_api.h. If an API appears not to be available on\na version of Node.js which is later than the one shown in added in: then\nthis is most likely the reason for the apparent absence.

                          \n

                          The N-APIs associated strictly with accessing ECMAScript features from native\ncode can be found separately in js_native_api.h and js_native_api_types.h.\nThe APIs defined in these headers are included in node_api.h and\nnode_api_types.h. The headers are structured in this way in order to allow\nimplementations of N-API outside of Node.js. For those implementations the\nNode.js specific APIs may not be applicable.

                          \n

                          The Node.js-specific parts of an addon can be separated from the code that\nexposes the actual functionality to the JavaScript environment so that the\nlatter may be used with multiple implementations of N-API. In the example below,\naddon.c and addon.h refer only to js_native_api.h. This ensures that\naddon.c can be reused to compile against either the Node.js implementation of\nN-API or any implementation of N-API outside of Node.js.

                          \n

                          addon_node.c is a separate file that contains the Node.js specific entry point\nto the addon and which instantiates the addon by calling into addon.c when the\naddon is loaded into a Node.js environment.

                          \n
                          // addon.h\n#ifndef _ADDON_H_\n#define _ADDON_H_\n#include <js_native_api.h>\nnapi_value create_addon(napi_env env);\n#endif  // _ADDON_H_\n
                          \n
                          // addon.c\n#include \"addon.h\"\n\n#define NAPI_CALL(env, call)                                      \\\n  do {                                                            \\\n    napi_status status = (call);                                  \\\n    if (status != napi_ok) {                                      \\\n      const napi_extended_error_info* error_info = NULL;          \\\n      napi_get_last_error_info((env), &error_info);               \\\n      bool is_pending;                                            \\\n      napi_is_exception_pending((env), &is_pending);              \\\n      if (!is_pending) {                                          \\\n        const char* message = (error_info->error_message == NULL) \\\n            ? \"empty error message\"                               \\\n            : error_info->error_message;                          \\\n        napi_throw_error((env), NULL, message);                   \\\n        return NULL;                                              \\\n      }                                                           \\\n    }                                                             \\\n  } while(0)\n\nstatic napi_value\nDoSomethingUseful(napi_env env, napi_callback_info info) {\n  // Do something useful.\n  return NULL;\n}\n\nnapi_value create_addon(napi_env env) {\n  napi_value result;\n  NAPI_CALL(env, napi_create_object(env, &result));\n\n  napi_value exported_function;\n  NAPI_CALL(env, napi_create_function(env,\n                                      \"doSomethingUseful\",\n                                      NAPI_AUTO_LENGTH,\n                                      DoSomethingUseful,\n                                      NULL,\n                                      &exported_function));\n\n  NAPI_CALL(env, napi_set_named_property(env,\n                                         result,\n                                         \"doSomethingUseful\",\n                                         exported_function));\n\n  return result;\n}\n
                          \n
                          // addon_node.c\n#include <node_api.h>\n#include \"addon.h\"\n\nNAPI_MODULE_INIT() {\n  // This function body is expected to return a `napi_value`.\n  // The variables `napi_env env` and `napi_value exports` may be used within\n  // the body, as they are provided by the definition of `NAPI_MODULE_INIT()`.\n  return create_addon(env);\n}\n
                          ", + "textRaw": "Node-API version matrix", + "name": "node-api_version_matrix", + "desc": "

                          Node-API versions are additive and versioned independently from Node.js.\nVersion 4 is an extension to version 3 in that it has all of the APIs\nfrom version 3 with some additions. This means that it is not necessary\nto recompile for new versions of Node.js which are\nlisted as supporting a later version.

                          \n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
                          123
                          v6.xv6.14.2*
                          v8.xv8.6.0**v8.10.0*v8.11.2
                          v9.xv9.0.0*v9.3.0*v9.11.0*
                          ≥ v10.xall releasesall releasesall releases
                          \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
                          45678
                          v10.xv10.16.0v10.17.0v10.20.0v10.23.0
                          v11.xv11.8.0
                          v12.xv12.0.0v12.11.0v12.17.0v12.19.0v12.22.0
                          v13.xv13.0.0v13.0.0
                          v14.xv14.0.0v14.0.0v14.0.0v14.12.0v14.17.0
                          v15.xv15.0.0v15.0.0v15.0.0v15.0.0v15.12.0
                          v16.xv16.0.0v16.0.0v16.0.0v16.0.0v16.0.0
                          \n

                          * Node-API was experimental.

                          \n

                          ** Node.js 8.0.0 included Node-API as experimental. It was released as\nNode-API version 1 but continued to evolve until Node.js 8.6.0. The API is\ndifferent in versions prior to Node.js 8.6.0. We recommend Node-API version 3 or\nlater.

                          \n

                          Each API documented for Node-API will have a header named added in:, and APIs\nwhich are stable will have the additional header Node-API version:.\nAPIs are directly usable when using a Node.js version which supports\nthe Node-API version shown in Node-API version: or higher.\nWhen using a Node.js version that does not support the\nNode-API version: listed or if there is no Node-API version: listed,\nthen the API will only be available if\n#define NAPI_EXPERIMENTAL precedes the inclusion of node_api.h\nor js_native_api.h. If an API appears not to be available on\na version of Node.js which is later than the one shown in added in: then\nthis is most likely the reason for the apparent absence.

                          \n

                          The Node-APIs associated strictly with accessing ECMAScript features from native\ncode can be found separately in js_native_api.h and js_native_api_types.h.\nThe APIs defined in these headers are included in node_api.h and\nnode_api_types.h. The headers are structured in this way in order to allow\nimplementations of Node-API outside of Node.js. For those implementations the\nNode.js specific APIs may not be applicable.

                          \n

                          The Node.js-specific parts of an addon can be separated from the code that\nexposes the actual functionality to the JavaScript environment so that the\nlatter may be used with multiple implementations of Node-API. In the example\nbelow, addon.c and addon.h refer only to js_native_api.h. This ensures\nthat addon.c can be reused to compile against either the Node.js\nimplementation of Node-API or any implementation of Node-API outside of Node.js.

                          \n

                          addon_node.c is a separate file that contains the Node.js specific entry point\nto the addon and which instantiates the addon by calling into addon.c when the\naddon is loaded into a Node.js environment.

                          \n
                          // addon.h\n#ifndef _ADDON_H_\n#define _ADDON_H_\n#include <js_native_api.h>\nnapi_value create_addon(napi_env env);\n#endif  // _ADDON_H_\n
                          \n
                          // addon.c\n#include \"addon.h\"\n\n#define NAPI_CALL(env, call)                                      \\\n  do {                                                            \\\n    napi_status status = (call);                                  \\\n    if (status != napi_ok) {                                      \\\n      const napi_extended_error_info* error_info = NULL;          \\\n      napi_get_last_error_info((env), &error_info);               \\\n      bool is_pending;                                            \\\n      napi_is_exception_pending((env), &is_pending);              \\\n      if (!is_pending) {                                          \\\n        const char* message = (error_info->error_message == NULL) \\\n            ? \"empty error message\"                               \\\n            : error_info->error_message;                          \\\n        napi_throw_error((env), NULL, message);                   \\\n        return NULL;                                              \\\n      }                                                           \\\n    }                                                             \\\n  } while(0)\n\nstatic napi_value\nDoSomethingUseful(napi_env env, napi_callback_info info) {\n  // Do something useful.\n  return NULL;\n}\n\nnapi_value create_addon(napi_env env) {\n  napi_value result;\n  NAPI_CALL(env, napi_create_object(env, &result));\n\n  napi_value exported_function;\n  NAPI_CALL(env, napi_create_function(env,\n                                      \"doSomethingUseful\",\n                                      NAPI_AUTO_LENGTH,\n                                      DoSomethingUseful,\n                                      NULL,\n                                      &exported_function));\n\n  NAPI_CALL(env, napi_set_named_property(env,\n                                         result,\n                                         \"doSomethingUseful\",\n                                         exported_function));\n\n  return result;\n}\n
                          \n
                          // addon_node.c\n#include <node_api.h>\n#include \"addon.h\"\n\nNAPI_MODULE_INIT() {\n  // This function body is expected to return a `napi_value`.\n  // The variables `napi_env env` and `napi_value exports` may be used within\n  // the body, as they are provided by the definition of `NAPI_MODULE_INIT()`.\n  return create_addon(env);\n}\n
                          ", "type": "misc", - "displayName": "N-API version matrix" + "displayName": "Node-API version matrix" }, { "textRaw": "Environment life cycle APIs", "name": "environment_life_cycle_apis", - "desc": "

                          Section 8.7 of the ECMAScript Language Specification defines the concept\nof an \"Agent\" as a self-contained environment in which JavaScript code runs.\nMultiple such Agents may be started and terminated either concurrently or in\nsequence by the process.

                          \n

                          A Node.js environment corresponds to an ECMAScript Agent. In the main process,\nan environment is created at startup, and additional environments can be created\non separate threads to serve as worker threads. When Node.js is embedded in\nanother application, the main thread of the application may also construct and\ndestroy a Node.js environment multiple times during the life cycle of the\napplication process such that each Node.js environment created by the\napplication may, in turn, during its life cycle create and destroy additional\nenvironments as worker threads.

                          \n

                          From the perspective of a native addon this means that the bindings it provides\nmay be called multiple times, from multiple contexts, and even concurrently from\nmultiple threads.

                          \n

                          Native addons may need to allocate global state which they use during\ntheir entire life cycle such that the state must be unique to each instance of\nthe addon.

                          \n

                          To this end, N-API provides a way to allocate data such that its life cycle is\ntied to the life cycle of the Agent.

                          ", + "desc": "

                          Section 8.7 of the ECMAScript Language Specification defines the concept\nof an \"Agent\" as a self-contained environment in which JavaScript code runs.\nMultiple such Agents may be started and terminated either concurrently or in\nsequence by the process.

                          \n

                          A Node.js environment corresponds to an ECMAScript Agent. In the main process,\nan environment is created at startup, and additional environments can be created\non separate threads to serve as worker threads. When Node.js is embedded in\nanother application, the main thread of the application may also construct and\ndestroy a Node.js environment multiple times during the life cycle of the\napplication process such that each Node.js environment created by the\napplication may, in turn, during its life cycle create and destroy additional\nenvironments as worker threads.

                          \n

                          From the perspective of a native addon this means that the bindings it provides\nmay be called multiple times, from multiple contexts, and even concurrently from\nmultiple threads.

                          \n

                          Native addons may need to allocate global state which they use during\ntheir entire life cycle such that the state must be unique to each instance of\nthe addon.

                          \n

                          To this end, Node-API provides a way to allocate data such that its life cycle\nis tied to the life cycle of the Agent.

                          ", "modules": [ { "textRaw": "napi_set_instance_data", "name": "napi_set_instance_data", "meta": { "added": [ - "v12.8.0" + "v12.8.0", + "v10.20.0" ], "napiVersion": [ 6 ], "changes": [] }, - "desc": "
                          napi_status napi_set_instance_data(napi_env env,\n                                   void* data,\n                                   napi_finalize finalize_cb,\n                                   void* finalize_hint);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] data: The data item to make available to bindings of this instance.
                          • \n
                          • [in] finalize_cb: The function to call when the environment is being torn\ndown. The function receives data so that it might free it.\nnapi_finalize provides more details.
                          • \n
                          • [in] finalize_hint: Optional hint to pass to the finalize callback during\ncollection.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API associates data with the currently running Agent. data can later\nbe retrieved using napi_get_instance_data(). Any existing data associated with\nthe currently running Agent which was set by means of a previous call to\nnapi_set_instance_data() will be overwritten. If a finalize_cb was provided\nby the previous call, it will not be called.

                          ", + "desc": "
                          napi_status napi_set_instance_data(napi_env env,\n                                   void* data,\n                                   napi_finalize finalize_cb,\n                                   void* finalize_hint);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] data: The data item to make available to bindings of this instance.
                          • \n
                          • [in] finalize_cb: The function to call when the environment is being torn\ndown. The function receives data so that it might free it.\nnapi_finalize provides more details.
                          • \n
                          • [in] finalize_hint: Optional hint to pass to the finalize callback during\ncollection.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API associates data with the currently running Agent. data can later\nbe retrieved using napi_get_instance_data(). Any existing data associated with\nthe currently running Agent which was set by means of a previous call to\nnapi_set_instance_data() will be overwritten. If a finalize_cb was provided\nby the previous call, it will not be called.

                          ", "type": "module", "displayName": "napi_set_instance_data" }, @@ -123,14 +124,15 @@ "name": "napi_get_instance_data", "meta": { "added": [ - "v12.8.0" + "v12.8.0", + "v10.20.0" ], "napiVersion": [ 6 ], "changes": [] }, - "desc": "
                          napi_status napi_get_instance_data(napi_env env,\n                                   void** data);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [out] data: The data item that was previously associated with the currently\nrunning Agent by a call to napi_set_instance_data().
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API retrieves data that was previously associated with the currently\nrunning Agent via napi_set_instance_data(). If no data is set, the call will\nsucceed and data will be set to NULL.

                          ", + "desc": "
                          napi_status napi_get_instance_data(napi_env env,\n                                   void** data);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [out] data: The data item that was previously associated with the currently\nrunning Agent by a call to napi_set_instance_data().
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API retrieves data that was previously associated with the currently\nrunning Agent via napi_set_instance_data(). If no data is set, the call will\nsucceed and data will be set to NULL.

                          ", "type": "module", "displayName": "napi_get_instance_data" } @@ -139,9 +141,9 @@ "displayName": "Environment life cycle APIs" }, { - "textRaw": "Basic N-API data types", - "name": "basic_n-api_data_types", - "desc": "

                          N-API exposes the following fundamental datatypes as abstractions that are\nconsumed by the various APIs. These APIs should be treated as opaque,\nintrospectable only with other N-API calls.

                          ", + "textRaw": "Basic Node-API data types", + "name": "basic_node-api_data_types", + "desc": "

                          Node-API exposes the following fundamental datatypes as abstractions that are\nconsumed by the various APIs. These APIs should be treated as opaque,\nintrospectable only with other Node-API calls.

                          ", "modules": [ { "textRaw": "napi_status", @@ -155,7 +157,7 @@ ], "changes": [] }, - "desc": "

                          Integral status code indicating the success or failure of a N-API call.\nCurrently, the following status codes are supported.

                          \n
                          typedef enum {\n  napi_ok,\n  napi_invalid_arg,\n  napi_object_expected,\n  napi_string_expected,\n  napi_name_expected,\n  napi_function_expected,\n  napi_number_expected,\n  napi_boolean_expected,\n  napi_array_expected,\n  napi_generic_failure,\n  napi_pending_exception,\n  napi_cancelled,\n  napi_escape_called_twice,\n  napi_handle_scope_mismatch,\n  napi_callback_scope_mismatch,\n  napi_queue_full,\n  napi_closing,\n  napi_bigint_expected,\n  napi_date_expected,\n  napi_arraybuffer_expected,\n  napi_detachable_arraybuffer_expected,\n} napi_status;\n
                          \n

                          If additional information is required upon an API returning a failed status,\nit can be obtained by calling napi_get_last_error_info.

                          ", + "desc": "

                          Integral status code indicating the success or failure of a Node-API call.\nCurrently, the following status codes are supported.

                          \n
                          typedef enum {\n  napi_ok,\n  napi_invalid_arg,\n  napi_object_expected,\n  napi_string_expected,\n  napi_name_expected,\n  napi_function_expected,\n  napi_number_expected,\n  napi_boolean_expected,\n  napi_array_expected,\n  napi_generic_failure,\n  napi_pending_exception,\n  napi_cancelled,\n  napi_escape_called_twice,\n  napi_handle_scope_mismatch,\n  napi_callback_scope_mismatch,\n  napi_queue_full,\n  napi_closing,\n  napi_bigint_expected,\n  napi_date_expected,\n  napi_arraybuffer_expected,\n  napi_detachable_arraybuffer_expected,\n  napi_would_deadlock,  /* unused */\n} napi_status;\n
                          \n

                          If additional information is required upon an API returning a failed status,\nit can be obtained by calling napi_get_last_error_info.

                          ", "type": "module", "displayName": "napi_status" }, @@ -171,14 +173,14 @@ ], "changes": [] }, - "desc": "
                          typedef struct {\n  const char* error_message;\n  void* engine_reserved;\n  uint32_t engine_error_code;\n  napi_status error_code;\n} napi_extended_error_info;\n
                          \n
                            \n
                          • error_message: UTF8-encoded string containing a VM-neutral description of\nthe error.
                          • \n
                          • engine_reserved: Reserved for VM-specific error details. This is currently\nnot implemented for any VM.
                          • \n
                          • engine_error_code: VM-specific error code. This is currently\nnot implemented for any VM.
                          • \n
                          • error_code: The N-API status code that originated with the last error.
                          • \n
                          \n

                          See the Error handling section for additional information.

                          ", + "desc": "
                          typedef struct {\n  const char* error_message;\n  void* engine_reserved;\n  uint32_t engine_error_code;\n  napi_status error_code;\n} napi_extended_error_info;\n
                          \n
                            \n
                          • error_message: UTF8-encoded string containing a VM-neutral description of\nthe error.
                          • \n
                          • engine_reserved: Reserved for VM-specific error details. This is currently\nnot implemented for any VM.
                          • \n
                          • engine_error_code: VM-specific error code. This is currently\nnot implemented for any VM.
                          • \n
                          • error_code: The Node-API status code that originated with the last error.
                          • \n
                          \n

                          See the Error handling section for additional information.

                          ", "type": "module", "displayName": "napi_extended_error_info" }, { "textRaw": "napi_env", "name": "napi_env", - "desc": "

                          napi_env is used to represent a context that the underlying N-API\nimplementation can use to persist VM-specific state. This structure is passed\nto native functions when they're invoked, and it must be passed back when\nmaking N-API calls. Specifically, the same napi_env that was passed in when\nthe initial native function was called must be passed to any subsequent\nnested N-API calls. Caching the napi_env for the purpose of general reuse,\nand passing the napi_env between instances of the same addon running on\ndifferent Worker threads is not allowed. The napi_env becomes invalid\nwhen an instance of a native addon is unloaded. Notification of this event is\ndelivered through the callbacks given to napi_add_env_cleanup_hook and\nnapi_set_instance_data.

                          ", + "desc": "

                          napi_env is used to represent a context that the underlying Node-API\nimplementation can use to persist VM-specific state. This structure is passed\nto native functions when they're invoked, and it must be passed back when\nmaking Node-API calls. Specifically, the same napi_env that was passed in when\nthe initial native function was called must be passed to any subsequent\nnested Node-API calls. Caching the napi_env for the purpose of general reuse,\nand passing the napi_env between instances of the same addon running on\ndifferent Worker threads is not allowed. The napi_env becomes invalid\nwhen an instance of a native addon is unloaded. Notification of this event is\ndelivered through the callbacks given to napi_add_env_cleanup_hook and\nnapi_set_instance_data.

                          ", "type": "module", "displayName": "napi_env" }, @@ -238,13 +240,13 @@ "displayName": "napi_threadsafe_function_call_mode" }, { - "textRaw": "N-API memory management types", - "name": "n-api_memory_management_types", + "textRaw": "Node-API memory management types", + "name": "node-api_memory_management_types", "modules": [ { "textRaw": "napi_handle_scope", "name": "napi_handle_scope", - "desc": "

                          This is an abstraction used to control and modify the lifetime of objects\ncreated within a particular scope. In general, N-API values are created within\nthe context of a handle scope. When a native method is called from\nJavaScript, a default handle scope will exist. If the user does not explicitly\ncreate a new handle scope, N-API values will be created in the default handle\nscope. For any invocations of code outside the execution of a native method\n(for instance, during a libuv callback invocation), the module is required to\ncreate a scope before invoking any functions that can result in the creation\nof JavaScript values.

                          \n

                          Handle scopes are created using napi_open_handle_scope and are destroyed\nusing napi_close_handle_scope. Closing the scope can indicate to the GC\nthat all napi_values created during the lifetime of the handle scope are no\nlonger referenced from the current stack frame.

                          \n

                          For more details, review the Object lifetime management.

                          ", + "desc": "

                          This is an abstraction used to control and modify the lifetime of objects\ncreated within a particular scope. In general, Node-API values are created\nwithin the context of a handle scope. When a native method is called from\nJavaScript, a default handle scope will exist. If the user does not explicitly\ncreate a new handle scope, Node-API values will be created in the default handle\nscope. For any invocations of code outside the execution of a native method\n(for instance, during a libuv callback invocation), the module is required to\ncreate a scope before invoking any functions that can result in the creation\nof JavaScript values.

                          \n

                          Handle scopes are created using napi_open_handle_scope and are destroyed\nusing napi_close_handle_scope. Closing the scope can indicate to the GC\nthat all napi_values created during the lifetime of the handle scope are no\nlonger referenced from the current stack frame.

                          \n

                          For more details, review the Object lifetime management.

                          ", "type": "module", "displayName": "napi_handle_scope" }, @@ -285,6 +287,7 @@ "name": "napi_type_tag", "meta": { "added": [ + "v14.8.0", "v12.19.0" ], "napiVersion": [ @@ -301,7 +304,7 @@ "name": "napi_async_cleanup_hook_handle", "meta": { "added": [ - "v12.19.0" + "v14.10.0" ], "changes": [] }, @@ -311,11 +314,11 @@ } ], "type": "module", - "displayName": "N-API memory management types" + "displayName": "Node-API memory management types" }, { - "textRaw": "N-API callback types", - "name": "n-api_callback_types", + "textRaw": "Node-API callback types", + "name": "node-api_callback_types", "modules": [ { "textRaw": "napi_callback_info", @@ -345,7 +348,7 @@ ], "changes": [] }, - "desc": "

                          Function pointer type for user-provided native functions which are to be\nexposed to JavaScript via N-API. Callback functions should satisfy the\nfollowing signature:

                          \n
                          typedef napi_value (*napi_callback)(napi_env, napi_callback_info);\n
                          \n

                          Unless for reasons discussed in Object Lifetime Management, creating a\nhandle and/or callback scope inside a napi_callback is not necessary.

                          ", + "desc": "

                          Function pointer type for user-provided native functions which are to be\nexposed to JavaScript via Node-API. Callback functions should satisfy the\nfollowing signature:

                          \n
                          typedef napi_value (*napi_callback)(napi_env, napi_callback_info);\n
                          \n

                          Unless for reasons discussed in Object Lifetime Management, creating a\nhandle and/or callback scope inside a napi_callback is not necessary.

                          ", "type": "module", "displayName": "napi_callback" }, @@ -377,7 +380,7 @@ ], "changes": [] }, - "desc": "

                          Function pointer used with functions that support asynchronous\noperations. Callback functions must satisfy the following signature:

                          \n
                          typedef void (*napi_async_execute_callback)(napi_env env, void* data);\n
                          \n

                          Implementations of this function must avoid making N-API calls that execute\nJavaScript or interact with JavaScript objects. N-API calls should be in the\nnapi_async_complete_callback instead. Do not use the napi_env parameter as\nit will likely result in execution of JavaScript.

                          ", + "desc": "

                          Function pointer used with functions that support asynchronous\noperations. Callback functions must satisfy the following signature:

                          \n
                          typedef void (*napi_async_execute_callback)(napi_env env, void* data);\n
                          \n

                          Implementations of this function must avoid making Node-API calls that execute\nJavaScript or interact with JavaScript objects. Node-API calls should be in the\nnapi_async_complete_callback instead. Do not use the napi_env parameter as\nit will likely result in execution of JavaScript.

                          ", "type": "module", "displayName": "napi_async_execute_callback" }, @@ -409,7 +412,7 @@ ], "changes": [] }, - "desc": "

                          Function pointer used with asynchronous thread-safe function calls. The callback\nwill be called on the main thread. Its purpose is to use a data item arriving\nvia the queue from one of the secondary threads to construct the parameters\nnecessary for a call into JavaScript, usually via napi_call_function, and then\nmake the call into JavaScript.

                          \n

                          The data arriving from the secondary thread via the queue is given in the data\nparameter and the JavaScript function to call is given in the js_callback\nparameter.

                          \n

                          N-API sets up the environment prior to calling this callback, so it is\nsufficient to call the JavaScript function via napi_call_function rather than\nvia napi_make_callback.

                          \n

                          Callback functions must satisfy the following signature:

                          \n
                          typedef void (*napi_threadsafe_function_call_js)(napi_env env,\n                                                 napi_value js_callback,\n                                                 void* context,\n                                                 void* data);\n
                          \n
                            \n
                          • [in] env: The environment to use for API calls, or NULL if the thread-safe\nfunction is being torn down and data may need to be freed.
                          • \n
                          • [in] js_callback: The JavaScript function to call, or NULL if the\nthread-safe function is being torn down and data may need to be freed. It\nmay also be NULL if the thread-safe function was created without\njs_callback.
                          • \n
                          • [in] context: The optional data with which the thread-safe function was\ncreated.
                          • \n
                          • [in] data: Data created by the secondary thread. It is the responsibility of\nthe callback to convert this native data to JavaScript values (with N-API\nfunctions) that can be passed as parameters when js_callback is invoked.\nThis pointer is managed entirely by the threads and this callback. Thus this\ncallback should free the data.
                          • \n
                          \n

                          Unless for reasons discussed in Object Lifetime Management, creating a\nhandle and/or callback scope inside the function body is not necessary.

                          ", + "desc": "

                          Function pointer used with asynchronous thread-safe function calls. The callback\nwill be called on the main thread. Its purpose is to use a data item arriving\nvia the queue from one of the secondary threads to construct the parameters\nnecessary for a call into JavaScript, usually via napi_call_function, and then\nmake the call into JavaScript.

                          \n

                          The data arriving from the secondary thread via the queue is given in the data\nparameter and the JavaScript function to call is given in the js_callback\nparameter.

                          \n

                          Node-API sets up the environment prior to calling this callback, so it is\nsufficient to call the JavaScript function via napi_call_function rather than\nvia napi_make_callback.

                          \n

                          Callback functions must satisfy the following signature:

                          \n
                          typedef void (*napi_threadsafe_function_call_js)(napi_env env,\n                                                 napi_value js_callback,\n                                                 void* context,\n                                                 void* data);\n
                          \n
                            \n
                          • [in] env: The environment to use for API calls, or NULL if the thread-safe\nfunction is being torn down and data may need to be freed.
                          • \n
                          • [in] js_callback: The JavaScript function to call, or NULL if the\nthread-safe function is being torn down and data may need to be freed. It\nmay also be NULL if the thread-safe function was created without\njs_callback.
                          • \n
                          • [in] context: The optional data with which the thread-safe function was\ncreated.
                          • \n
                          • [in] data: Data created by the secondary thread. It is the responsibility of\nthe callback to convert this native data to JavaScript values (with Node-API\nfunctions) that can be passed as parameters when js_callback is invoked.\nThis pointer is managed entirely by the threads and this callback. Thus this\ncallback should free the data.
                          • \n
                          \n

                          Unless for reasons discussed in Object Lifetime Management, creating a\nhandle and/or callback scope inside the function body is not necessary.

                          ", "type": "module", "displayName": "napi_threadsafe_function_call_js" }, @@ -418,7 +421,7 @@ "name": "napi_async_cleanup_hook", "meta": { "added": [ - "v12.19.0" + "v14.10.0" ], "changes": [] }, @@ -428,16 +431,16 @@ } ], "type": "module", - "displayName": "N-API callback types" + "displayName": "Node-API callback types" } ], "type": "misc", - "displayName": "Basic N-API data types" + "displayName": "Basic Node-API data types" }, { "textRaw": "Error handling", "name": "error_handling", - "desc": "

                          N-API uses both return values and JavaScript exceptions for error handling.\nThe following sections explain the approach for each case.

                          ", + "desc": "

                          Node-API uses both return values and JavaScript exceptions for error handling.\nThe following sections explain the approach for each case.

                          ", "modules": [ { "textRaw": "Return values", @@ -451,7 +454,7 @@ ], "changes": [] }, - "desc": "

                          All of the N-API functions share the same error handling pattern. The\nreturn type of all API functions is napi_status.

                          \n

                          The return value will be napi_ok if the request was successful and\nno uncaught JavaScript exception was thrown. If an error occurred AND\nan exception was thrown, the napi_status value for the error\nwill be returned. If an exception was thrown, and no error occurred,\nnapi_pending_exception will be returned.

                          \n

                          In cases where a return value other than napi_ok or\nnapi_pending_exception is returned, napi_is_exception_pending\nmust be called to check if an exception is pending.\nSee the section on exceptions for more details.

                          \n

                          The full set of possible napi_status values is defined\nin napi_api_types.h.

                          \n

                          The napi_status return value provides a VM-independent representation of\nthe error which occurred. In some cases it is useful to be able to get\nmore detailed information, including a string representing the error as well as\nVM (engine)-specific information.

                          \n

                          In order to retrieve this information napi_get_last_error_info\nis provided which returns a napi_extended_error_info structure.\nThe format of the napi_extended_error_info structure is as follows:

                          \n
                          typedef struct napi_extended_error_info {\n  const char* error_message;\n  void* engine_reserved;\n  uint32_t engine_error_code;\n  napi_status error_code;\n};\n
                          \n
                            \n
                          • error_message: Textual representation of the error that occurred.
                          • \n
                          • engine_reserved: Opaque handle reserved for engine use only.
                          • \n
                          • engine_error_code: VM specific error code.
                          • \n
                          • error_code: n-api status code for the last error.
                          • \n
                          \n

                          napi_get_last_error_info returns the information for the last\nN-API call that was made.

                          \n

                          Do not rely on the content or format of any of the extended information as it\nis not subject to SemVer and may change at any time. It is intended only for\nlogging purposes.

                          ", + "desc": "

                          All of the Node-API functions share the same error handling pattern. The\nreturn type of all API functions is napi_status.

                          \n

                          The return value will be napi_ok if the request was successful and\nno uncaught JavaScript exception was thrown. If an error occurred AND\nan exception was thrown, the napi_status value for the error\nwill be returned. If an exception was thrown, and no error occurred,\nnapi_pending_exception will be returned.

                          \n

                          In cases where a return value other than napi_ok or\nnapi_pending_exception is returned, napi_is_exception_pending\nmust be called to check if an exception is pending.\nSee the section on exceptions for more details.

                          \n

                          The full set of possible napi_status values is defined\nin napi_api_types.h.

                          \n

                          The napi_status return value provides a VM-independent representation of\nthe error which occurred. In some cases it is useful to be able to get\nmore detailed information, including a string representing the error as well as\nVM (engine)-specific information.

                          \n

                          In order to retrieve this information napi_get_last_error_info\nis provided which returns a napi_extended_error_info structure.\nThe format of the napi_extended_error_info structure is as follows:

                          \n
                          typedef struct napi_extended_error_info {\n  const char* error_message;\n  void* engine_reserved;\n  uint32_t engine_error_code;\n  napi_status error_code;\n};\n
                          \n
                            \n
                          • error_message: Textual representation of the error that occurred.
                          • \n
                          • engine_reserved: Opaque handle reserved for engine use only.
                          • \n
                          • engine_error_code: VM specific error code.
                          • \n
                          • error_code: Node-API status code for the last error.
                          • \n
                          \n

                          napi_get_last_error_info returns the information for the last\nNode-API call that was made.

                          \n

                          Do not rely on the content or format of any of the extended information as it\nis not subject to SemVer and may change at any time. It is intended only for\nlogging purposes.

                          ", "modules": [ { "textRaw": "napi_get_last_error_info", @@ -465,7 +468,7 @@ ], "changes": [] }, - "desc": "
                          napi_status\nnapi_get_last_error_info(napi_env env,\n                         const napi_extended_error_info** result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [out] result: The napi_extended_error_info structure with more\ninformation about the error.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API retrieves a napi_extended_error_info structure with information\nabout the last error that occurred.

                          \n

                          The content of the napi_extended_error_info returned is only valid up until\nan n-api function is called on the same env.

                          \n

                          Do not rely on the content or format of any of the extended information as it\nis not subject to SemVer and may change at any time. It is intended only for\nlogging purposes.

                          \n

                          This API can be called even if there is a pending JavaScript exception.

                          ", + "desc": "
                          napi_status\nnapi_get_last_error_info(napi_env env,\n                         const napi_extended_error_info** result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [out] result: The napi_extended_error_info structure with more\ninformation about the error.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API retrieves a napi_extended_error_info structure with information\nabout the last error that occurred.

                          \n

                          The content of the napi_extended_error_info returned is only valid up until\na Node-API function is called on the same env.

                          \n

                          Do not rely on the content or format of any of the extended information as it\nis not subject to SemVer and may change at any time. It is intended only for\nlogging purposes.

                          \n

                          This API can be called even if there is a pending JavaScript exception.

                          ", "type": "module", "displayName": "napi_get_last_error_info" } @@ -476,7 +479,7 @@ { "textRaw": "Exceptions", "name": "exceptions", - "desc": "

                          Any N-API function call may result in a pending JavaScript exception. This is\nthe case for any of the API functions, even those that may not cause the\nexecution of JavaScript.

                          \n

                          If the napi_status returned by a function is napi_ok then no\nexception is pending and no additional action is required. If the\nnapi_status returned is anything other than napi_ok or\nnapi_pending_exception, in order to try to recover and continue\ninstead of simply returning immediately, napi_is_exception_pending\nmust be called in order to determine if an exception is pending or not.

                          \n

                          In many cases when an N-API function is called and an exception is\nalready pending, the function will return immediately with a\nnapi_status of napi_pending_exception. However, this is not the case\nfor all functions. N-API allows a subset of the functions to be\ncalled to allow for some minimal cleanup before returning to JavaScript.\nIn that case, napi_status will reflect the status for the function. It\nwill not reflect previous pending exceptions. To avoid confusion, check\nthe error status after every function call.

                          \n

                          When an exception is pending one of two approaches can be employed.

                          \n

                          The first approach is to do any appropriate cleanup and then return so that\nexecution will return to JavaScript. As part of the transition back to\nJavaScript, the exception will be thrown at the point in the JavaScript\ncode where the native method was invoked. The behavior of most N-API calls\nis unspecified while an exception is pending, and many will simply return\nnapi_pending_exception, so do as little as possible and then return to\nJavaScript where the exception can be handled.

                          \n

                          The second approach is to try to handle the exception. There will be cases\nwhere the native code can catch the exception, take the appropriate action,\nand then continue. This is only recommended in specific cases\nwhere it is known that the exception can be safely handled. In these\ncases napi_get_and_clear_last_exception can be used to get and\nclear the exception. On success, result will contain the handle to\nthe last JavaScript Object thrown. If it is determined, after\nretrieving the exception, the exception cannot be handled after all\nit can be re-thrown it with napi_throw where error is the\nJavaScript Error object to be thrown.

                          \n

                          The following utility functions are also available in case native code\nneeds to throw an exception or determine if a napi_value is an instance\nof a JavaScript Error object: napi_throw_error,\nnapi_throw_type_error, napi_throw_range_error and\nnapi_is_error.

                          \n

                          The following utility functions are also available in case native\ncode needs to create an Error object: napi_create_error,\nnapi_create_type_error, and napi_create_range_error,\nwhere result is the napi_value that refers to the newly created\nJavaScript Error object.

                          \n

                          The Node.js project is adding error codes to all of the errors\ngenerated internally. The goal is for applications to use these\nerror codes for all error checking. The associated error messages\nwill remain, but will only be meant to be used for logging and\ndisplay with the expectation that the message can change without\nSemVer applying. In order to support this model with N-API, both\nin internal functionality and for module specific functionality\n(as its good practice), the throw_ and create_ functions\ntake an optional code parameter which is the string for the code\nto be added to the error object. If the optional parameter is NULL\nthen no code will be associated with the error. If a code is provided,\nthe name associated with the error is also updated to be:

                          \n
                          originalName [code]\n
                          \n

                          where originalName is the original name associated with the error\nand code is the code that was provided. For example, if the code\nis 'ERR_ERROR_1' and a TypeError is being created the name will be:

                          \n
                          TypeError [ERR_ERROR_1]\n
                          ", + "desc": "

                          Any Node-API function call may result in a pending JavaScript exception. This is\nthe case for any of the API functions, even those that may not cause the\nexecution of JavaScript.

                          \n

                          If the napi_status returned by a function is napi_ok then no\nexception is pending and no additional action is required. If the\nnapi_status returned is anything other than napi_ok or\nnapi_pending_exception, in order to try to recover and continue\ninstead of simply returning immediately, napi_is_exception_pending\nmust be called in order to determine if an exception is pending or not.

                          \n

                          In many cases when a Node-API function is called and an exception is\nalready pending, the function will return immediately with a\nnapi_status of napi_pending_exception. However, this is not the case\nfor all functions. Node-API allows a subset of the functions to be\ncalled to allow for some minimal cleanup before returning to JavaScript.\nIn that case, napi_status will reflect the status for the function. It\nwill not reflect previous pending exceptions. To avoid confusion, check\nthe error status after every function call.

                          \n

                          When an exception is pending one of two approaches can be employed.

                          \n

                          The first approach is to do any appropriate cleanup and then return so that\nexecution will return to JavaScript. As part of the transition back to\nJavaScript, the exception will be thrown at the point in the JavaScript\ncode where the native method was invoked. The behavior of most Node-API calls\nis unspecified while an exception is pending, and many will simply return\nnapi_pending_exception, so do as little as possible and then return to\nJavaScript where the exception can be handled.

                          \n

                          The second approach is to try to handle the exception. There will be cases\nwhere the native code can catch the exception, take the appropriate action,\nand then continue. This is only recommended in specific cases\nwhere it is known that the exception can be safely handled. In these\ncases napi_get_and_clear_last_exception can be used to get and\nclear the exception. On success, result will contain the handle to\nthe last JavaScript Object thrown. If it is determined, after\nretrieving the exception, the exception cannot be handled after all\nit can be re-thrown it with napi_throw where error is the\nJavaScript value to be thrown.

                          \n

                          The following utility functions are also available in case native code\nneeds to throw an exception or determine if a napi_value is an instance\nof a JavaScript Error object: napi_throw_error,\nnapi_throw_type_error, napi_throw_range_error and\nnapi_is_error.

                          \n

                          The following utility functions are also available in case native\ncode needs to create an Error object: napi_create_error,\nnapi_create_type_error, and napi_create_range_error,\nwhere result is the napi_value that refers to the newly created\nJavaScript Error object.

                          \n

                          The Node.js project is adding error codes to all of the errors\ngenerated internally. The goal is for applications to use these\nerror codes for all error checking. The associated error messages\nwill remain, but will only be meant to be used for logging and\ndisplay with the expectation that the message can change without\nSemVer applying. In order to support this model with Node-API, both\nin internal functionality and for module specific functionality\n(as its good practice), the throw_ and create_ functions\ntake an optional code parameter which is the string for the code\nto be added to the error object. If the optional parameter is NULL\nthen no code will be associated with the error. If a code is provided,\nthe name associated with the error is also updated to be:

                          \n
                          originalName [code]\n
                          \n

                          where originalName is the original name associated with the error\nand code is the code that was provided. For example, if the code\nis 'ERR_ERROR_1' and a TypeError is being created the name will be:

                          \n
                          TypeError [ERR_ERROR_1]\n
                          ", "modules": [ { "textRaw": "napi_throw", @@ -570,7 +573,7 @@ ], "changes": [] }, - "desc": "
                          NAPI_EXTERN napi_status napi_create_error(napi_env env,\n                                          napi_value code,\n                                          napi_value msg,\n                                          napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] code: Optional napi_value with the string for the error code to be\nassociated with the error.
                          • \n
                          • [in] msg: napi_value that references a JavaScript String to be used as\nthe message for the Error.
                          • \n
                          • [out] result: napi_value representing the error created.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns a JavaScript Error with the text provided.

                          ", + "desc": "
                          NAPI_EXTERN napi_status napi_create_error(napi_env env,\n                                          napi_value code,\n                                          napi_value msg,\n                                          napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] code: Optional napi_value with the string for the error code to be\nassociated with the error.
                          • \n
                          • [in] msg: napi_value that references a JavaScript string to be used as\nthe message for the Error.
                          • \n
                          • [out] result: napi_value representing the error created.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns a JavaScript Error with the text provided.

                          ", "type": "module", "displayName": "napi_create_error" }, @@ -586,7 +589,7 @@ ], "changes": [] }, - "desc": "
                          NAPI_EXTERN napi_status napi_create_type_error(napi_env env,\n                                               napi_value code,\n                                               napi_value msg,\n                                               napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] code: Optional napi_value with the string for the error code to be\nassociated with the error.
                          • \n
                          • [in] msg: napi_value that references a JavaScript String to be used as\nthe message for the Error.
                          • \n
                          • [out] result: napi_value representing the error created.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns a JavaScript TypeError with the text provided.

                          ", + "desc": "
                          NAPI_EXTERN napi_status napi_create_type_error(napi_env env,\n                                               napi_value code,\n                                               napi_value msg,\n                                               napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] code: Optional napi_value with the string for the error code to be\nassociated with the error.
                          • \n
                          • [in] msg: napi_value that references a JavaScript string to be used as\nthe message for the Error.
                          • \n
                          • [out] result: napi_value representing the error created.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns a JavaScript TypeError with the text provided.

                          ", "type": "module", "displayName": "napi_create_type_error" }, @@ -602,7 +605,7 @@ ], "changes": [] }, - "desc": "
                          NAPI_EXTERN napi_status napi_create_range_error(napi_env env,\n                                                napi_value code,\n                                                napi_value msg,\n                                                napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] code: Optional napi_value with the string for the error code to be\nassociated with the error.
                          • \n
                          • [in] msg: napi_value that references a JavaScript String to be used as\nthe message for the Error.
                          • \n
                          • [out] result: napi_value representing the error created.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns a JavaScript RangeError with the text provided.

                          ", + "desc": "
                          NAPI_EXTERN napi_status napi_create_range_error(napi_env env,\n                                                napi_value code,\n                                                napi_value msg,\n                                                napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] code: Optional napi_value with the string for the error code to be\nassociated with the error.
                          • \n
                          • [in] msg: napi_value that references a JavaScript string to be used as\nthe message for the Error.
                          • \n
                          • [out] result: napi_value representing the error created.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns a JavaScript RangeError with the text provided.

                          ", "type": "module", "displayName": "napi_create_range_error" }, @@ -675,7 +678,7 @@ ], "changes": [] }, - "desc": "
                          NAPI_NO_RETURN void napi_fatal_error(const char* location,\n                                                 size_t location_len,\n                                                 const char* message,\n                                                 size_t message_len);\n
                          \n
                            \n
                          • [in] location: Optional location at which the error occurred.
                          • \n
                          • [in] location_len: The length of the location in bytes, or\nNAPI_AUTO_LENGTH if it is null-terminated.
                          • \n
                          • [in] message: The message associated with the error.
                          • \n
                          • [in] message_len: The length of the message in bytes, or NAPI_AUTO_LENGTH\nif it is null-terminated.
                          • \n
                          \n

                          The function call does not return, the process will be terminated.

                          \n

                          This API can be called even if there is a pending JavaScript exception.

                          ", + "desc": "
                          NAPI_NO_RETURN void napi_fatal_error(const char* location,\n                                     size_t location_len,\n                                     const char* message,\n                                     size_t message_len);\n
                          \n
                            \n
                          • [in] location: Optional location at which the error occurred.
                          • \n
                          • [in] location_len: The length of the location in bytes, or\nNAPI_AUTO_LENGTH if it is null-terminated.
                          • \n
                          • [in] message: The message associated with the error.
                          • \n
                          • [in] message_len: The length of the message in bytes, or NAPI_AUTO_LENGTH\nif it is null-terminated.
                          • \n
                          \n

                          The function call does not return, the process will be terminated.

                          \n

                          This API can be called even if there is a pending JavaScript exception.

                          ", "type": "module", "displayName": "napi_fatal_error" } @@ -690,12 +693,12 @@ { "textRaw": "Object lifetime management", "name": "object_lifetime_management", - "desc": "

                          As N-API calls are made, handles to objects in the heap for the underlying\nVM may be returned as napi_values. These handles must hold the\nobjects 'live' until they are no longer required by the native code,\notherwise the objects could be collected before the native code was\nfinished using them.

                          \n

                          As object handles are returned they are associated with a\n'scope'. The lifespan for the default scope is tied to the lifespan\nof the native method call. The result is that, by default, handles\nremain valid and the objects associated with these handles will be\nheld live for the lifespan of the native method call.

                          \n

                          In many cases, however, it is necessary that the handles remain valid for\neither a shorter or longer lifespan than that of the native method.\nThe sections which follow describe the N-API functions that can be used\nto change the handle lifespan from the default.

                          ", + "desc": "

                          As Node-API calls are made, handles to objects in the heap for the underlying\nVM may be returned as napi_values. These handles must hold the\nobjects 'live' until they are no longer required by the native code,\notherwise the objects could be collected before the native code was\nfinished using them.

                          \n

                          As object handles are returned they are associated with a\n'scope'. The lifespan for the default scope is tied to the lifespan\nof the native method call. The result is that, by default, handles\nremain valid and the objects associated with these handles will be\nheld live for the lifespan of the native method call.

                          \n

                          In many cases, however, it is necessary that the handles remain valid for\neither a shorter or longer lifespan than that of the native method.\nThe sections which follow describe the Node-API functions that can be used\nto change the handle lifespan from the default.

                          ", "modules": [ { "textRaw": "Making handle lifespan shorter than that of the native method", "name": "making_handle_lifespan_shorter_than_that_of_the_native_method", - "desc": "

                          It is often necessary to make the lifespan of handles shorter than\nthe lifespan of a native method. For example, consider a native method\nthat has a loop which iterates through the elements in a large array:

                          \n
                          for (int i = 0; i < 1000000; i++) {\n  napi_value result;\n  napi_status status = napi_get_element(env, object, i, &result);\n  if (status != napi_ok) {\n    break;\n  }\n  // do something with element\n}\n
                          \n

                          This would result in a large number of handles being created, consuming\nsubstantial resources. In addition, even though the native code could only\nuse the most recent handle, all of the associated objects would also be\nkept alive since they all share the same scope.

                          \n

                          To handle this case, N-API provides the ability to establish a new 'scope' to\nwhich newly created handles will be associated. Once those handles\nare no longer required, the scope can be 'closed' and any handles associated\nwith the scope are invalidated. The methods available to open/close scopes are\nnapi_open_handle_scope and napi_close_handle_scope.

                          \n

                          N-API only supports a single nested hierarchy of scopes. There is only one\nactive scope at any time, and all new handles will be associated with that\nscope while it is active. Scopes must be closed in the reverse order from\nwhich they are opened. In addition, all scopes created within a native method\nmust be closed before returning from that method.

                          \n

                          Taking the earlier example, adding calls to napi_open_handle_scope and\nnapi_close_handle_scope would ensure that at most a single handle\nis valid throughout the execution of the loop:

                          \n
                          for (int i = 0; i < 1000000; i++) {\n  napi_handle_scope scope;\n  napi_status status = napi_open_handle_scope(env, &scope);\n  if (status != napi_ok) {\n    break;\n  }\n  napi_value result;\n  status = napi_get_element(env, object, i, &result);\n  if (status != napi_ok) {\n    break;\n  }\n  // do something with element\n  status = napi_close_handle_scope(env, scope);\n  if (status != napi_ok) {\n    break;\n  }\n}\n
                          \n

                          When nesting scopes, there are cases where a handle from an\ninner scope needs to live beyond the lifespan of that scope. N-API supports an\n'escapable scope' in order to support this case. An escapable scope\nallows one handle to be 'promoted' so that it 'escapes' the\ncurrent scope and the lifespan of the handle changes from the current\nscope to that of the outer scope.

                          \n

                          The methods available to open/close escapable scopes are\nnapi_open_escapable_handle_scope and\nnapi_close_escapable_handle_scope.

                          \n

                          The request to promote a handle is made through napi_escape_handle which\ncan only be called once.

                          ", + "desc": "

                          It is often necessary to make the lifespan of handles shorter than\nthe lifespan of a native method. For example, consider a native method\nthat has a loop which iterates through the elements in a large array:

                          \n
                          for (int i = 0; i < 1000000; i++) {\n  napi_value result;\n  napi_status status = napi_get_element(env, object, i, &result);\n  if (status != napi_ok) {\n    break;\n  }\n  // do something with element\n}\n
                          \n

                          This would result in a large number of handles being created, consuming\nsubstantial resources. In addition, even though the native code could only\nuse the most recent handle, all of the associated objects would also be\nkept alive since they all share the same scope.

                          \n

                          To handle this case, Node-API provides the ability to establish a new 'scope' to\nwhich newly created handles will be associated. Once those handles\nare no longer required, the scope can be 'closed' and any handles associated\nwith the scope are invalidated. The methods available to open/close scopes are\nnapi_open_handle_scope and napi_close_handle_scope.

                          \n

                          Node-API only supports a single nested hierarchy of scopes. There is only one\nactive scope at any time, and all new handles will be associated with that\nscope while it is active. Scopes must be closed in the reverse order from\nwhich they are opened. In addition, all scopes created within a native method\nmust be closed before returning from that method.

                          \n

                          Taking the earlier example, adding calls to napi_open_handle_scope and\nnapi_close_handle_scope would ensure that at most a single handle\nis valid throughout the execution of the loop:

                          \n
                          for (int i = 0; i < 1000000; i++) {\n  napi_handle_scope scope;\n  napi_status status = napi_open_handle_scope(env, &scope);\n  if (status != napi_ok) {\n    break;\n  }\n  napi_value result;\n  status = napi_get_element(env, object, i, &result);\n  if (status != napi_ok) {\n    break;\n  }\n  // do something with element\n  status = napi_close_handle_scope(env, scope);\n  if (status != napi_ok) {\n    break;\n  }\n}\n
                          \n

                          When nesting scopes, there are cases where a handle from an\ninner scope needs to live beyond the lifespan of that scope. Node-API supports\nan 'escapable scope' in order to support this case. An escapable scope\nallows one handle to be 'promoted' so that it 'escapes' the\ncurrent scope and the lifespan of the handle changes from the current\nscope to that of the outer scope.

                          \n

                          The methods available to open/close escapable scopes are\nnapi_open_escapable_handle_scope and\nnapi_close_escapable_handle_scope.

                          \n

                          The request to promote a handle is made through napi_escape_handle which\ncan only be called once.

                          ", "modules": [ { "textRaw": "napi_open_handle_scope", @@ -784,7 +787,7 @@ { "textRaw": "References to objects with a lifespan longer than that of the native method", "name": "references_to_objects_with_a_lifespan_longer_than_that_of_the_native_method", - "desc": "

                          In some cases an addon will need to be able to create and reference objects\nwith a lifespan longer than that of a single native method invocation. For\nexample, to create a constructor and later use that constructor\nin a request to creates instances, it must be possible to reference\nthe constructor object across many different instance creation requests. This\nwould not be possible with a normal handle returned as a napi_value as\ndescribed in the earlier section. The lifespan of a normal handle is\nmanaged by scopes and all scopes must be closed before the end of a native\nmethod.

                          \n

                          N-API provides methods to create persistent references to an object.\nEach persistent reference has an associated count with a value of 0\nor higher. The count determines if the reference will keep\nthe corresponding object live. References with a count of 0 do not\nprevent the object from being collected and are often called 'weak'\nreferences. Any count greater than 0 will prevent the object\nfrom being collected.

                          \n

                          References can be created with an initial reference count. The count can\nthen be modified through napi_reference_ref and\nnapi_reference_unref. If an object is collected while the count\nfor a reference is 0, all subsequent calls to\nget the object associated with the reference napi_get_reference_value\nwill return NULL for the returned napi_value. An attempt to call\nnapi_reference_ref for a reference whose object has been collected\nwill result in an error.

                          \n

                          References must be deleted once they are no longer required by the addon. When\na reference is deleted it will no longer prevent the corresponding object from\nbeing collected. Failure to delete a persistent reference will result in\na 'memory leak' with both the native memory for the persistent reference and\nthe corresponding object on the heap being retained forever.

                          \n

                          There can be multiple persistent references created which refer to the same\nobject, each of which will either keep the object live or not based on its\nindividual count.

                          ", + "desc": "

                          In some cases an addon will need to be able to create and reference objects\nwith a lifespan longer than that of a single native method invocation. For\nexample, to create a constructor and later use that constructor\nin a request to creates instances, it must be possible to reference\nthe constructor object across many different instance creation requests. This\nwould not be possible with a normal handle returned as a napi_value as\ndescribed in the earlier section. The lifespan of a normal handle is\nmanaged by scopes and all scopes must be closed before the end of a native\nmethod.

                          \n

                          Node-API provides methods to create persistent references to an object.\nEach persistent reference has an associated count with a value of 0\nor higher. The count determines if the reference will keep\nthe corresponding object live. References with a count of 0 do not\nprevent the object from being collected and are often called 'weak'\nreferences. Any count greater than 0 will prevent the object\nfrom being collected.

                          \n

                          References can be created with an initial reference count. The count can\nthen be modified through napi_reference_ref and\nnapi_reference_unref. If an object is collected while the count\nfor a reference is 0, all subsequent calls to\nget the object associated with the reference napi_get_reference_value\nwill return NULL for the returned napi_value. An attempt to call\nnapi_reference_ref for a reference whose object has been collected\nresults in an error.

                          \n

                          References must be deleted once they are no longer required by the addon. When\na reference is deleted, it will no longer prevent the corresponding object from\nbeing collected. Failure to delete a persistent reference results in\na 'memory leak' with both the native memory for the persistent reference and\nthe corresponding object on the heap being retained forever.

                          \n

                          There can be multiple persistent references created which refer to the same\nobject, each of which will either keep the object live or not based on its\nindividual count.

                          ", "modules": [ { "textRaw": "napi_create_reference", @@ -873,7 +876,7 @@ { "textRaw": "Cleanup on exit of the current Node.js instance", "name": "cleanup_on_exit_of_the_current_node.js_instance", - "desc": "

                          While a Node.js process typically releases all its resources when exiting,\nembedders of Node.js, or future Worker support, may require addons to register\nclean-up hooks that will be run once the current Node.js instance exits.

                          \n

                          N-API provides functions for registering and un-registering such callbacks.\nWhen those callbacks are run, all resources that are being held by the addon\nshould be freed up.

                          ", + "desc": "

                          While a Node.js process typically releases all its resources when exiting,\nembedders of Node.js, or future Worker support, may require addons to register\nclean-up hooks that will be run once the current Node.js instance exits.

                          \n

                          Node-API provides functions for registering and un-registering such callbacks.\nWhen those callbacks are run, all resources that are being held by the addon\nshould be freed up.

                          ", "modules": [ { "textRaw": "napi_add_env_cleanup_hook", @@ -912,17 +915,18 @@ "name": "napi_add_async_cleanup_hook", "meta": { "added": [ + "v14.8.0", "v12.19.0" ], + "napiVersion": [ + 8 + ], "changes": [ { - "version": "v12.19.0", + "version": "v14.10.0", "pr-url": "https://github.com/nodejs/node/pull/34819", "description": "Changed signature of the `hook` callback." } - ], - "napiVersion": [ - 8 ] }, "desc": "
                          NAPI_EXTERN napi_status napi_add_async_cleanup_hook(\n    napi_env env,\n    napi_async_cleanup_hook hook,\n    void* arg,\n    napi_async_cleanup_hook_handle* remove_handle);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] hook: The function pointer to call at environment teardown.
                          • \n
                          • [in] arg: The pointer to pass to hook when it gets called.
                          • \n
                          • [out] remove_handle: Optional handle that refers to the asynchronous cleanup\nhook.
                          • \n
                          \n

                          Registers hook, which is a function of type napi_async_cleanup_hook, as\na function to be run with the remove_handle and arg parameters once the\ncurrent Node.js environment exits.

                          \n

                          Unlike napi_add_env_cleanup_hook, the hook is allowed to be asynchronous.

                          \n

                          Otherwise, behavior generally matches that of napi_add_env_cleanup_hook.

                          \n

                          If remove_handle is not NULL, an opaque value will be stored in it\nthat must later be passed to napi_remove_async_cleanup_hook,\nregardless of whether the hook has already been invoked.\nTypically, that happens when the resource for which this hook was added\nis being torn down anyway.

                          ", @@ -934,11 +938,11 @@ "name": "napi_remove_async_cleanup_hook", "meta": { "added": [ - "v12.19.0" + "v14.8.0" ], "changes": [ { - "version": "v12.19.0", + "version": "v14.10.0", "pr-url": "https://github.com/nodejs/node/pull/34819", "description": "Removed `env` parameter." } @@ -959,14 +963,14 @@ { "textRaw": "Module registration", "name": "module_registration", - "desc": "

                          N-API modules are registered in a manner similar to other modules\nexcept that instead of using the NODE_MODULE macro the following\nis used:

                          \n
                          NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)\n
                          \n

                          The next difference is the signature for the Init method. For a N-API\nmodule it is as follows:

                          \n
                          napi_value Init(napi_env env, napi_value exports);\n
                          \n

                          The return value from Init is treated as the exports object for the module.\nThe Init method is passed an empty object via the exports parameter as a\nconvenience. If Init returns NULL, the parameter passed as exports is\nexported by the module. N-API modules cannot modify the module object but can\nspecify anything as the exports property of the module.

                          \n

                          To add the method hello as a function so that it can be called as a method\nprovided by the addon:

                          \n
                          napi_value Init(napi_env env, napi_value exports) {\n  napi_status status;\n  napi_property_descriptor desc = {\n    \"hello\",\n    NULL,\n    Method,\n    NULL,\n    NULL,\n    NULL,\n    napi_writable | napi_enumerable | napi_configurable,\n    NULL\n  };\n  status = napi_define_properties(env, exports, 1, &desc);\n  if (status != napi_ok) return NULL;\n  return exports;\n}\n
                          \n

                          To set a function to be returned by the require() for the addon:

                          \n
                          napi_value Init(napi_env env, napi_value exports) {\n  napi_value method;\n  napi_status status;\n  status = napi_create_function(env, \"exports\", NAPI_AUTO_LENGTH, Method, NULL, &method);\n  if (status != napi_ok) return NULL;\n  return method;\n}\n
                          \n

                          To define a class so that new instances can be created (often used with\nObject wrap):

                          \n
                          // NOTE: partial example, not all referenced code is included\nnapi_value Init(napi_env env, napi_value exports) {\n  napi_status status;\n  napi_property_descriptor properties[] = {\n    { \"value\", NULL, NULL, GetValue, SetValue, NULL, napi_writable | napi_configurable, NULL },\n    DECLARE_NAPI_METHOD(\"plusOne\", PlusOne),\n    DECLARE_NAPI_METHOD(\"multiply\", Multiply),\n  };\n\n  napi_value cons;\n  status =\n      napi_define_class(env, \"MyObject\", New, NULL, 3, properties, &cons);\n  if (status != napi_ok) return NULL;\n\n  status = napi_create_reference(env, cons, 1, &constructor);\n  if (status != napi_ok) return NULL;\n\n  status = napi_set_named_property(env, exports, \"MyObject\", cons);\n  if (status != napi_ok) return NULL;\n\n  return exports;\n}\n
                          \n

                          If the module will be loaded multiple times during the lifetime of the Node.js\nprocess, use the NAPI_MODULE_INIT macro to initialize the module:

                          \n
                          NAPI_MODULE_INIT() {\n  napi_value answer;\n  napi_status result;\n\n  status = napi_create_int64(env, 42, &answer);\n  if (status != napi_ok) return NULL;\n\n  status = napi_set_named_property(env, exports, \"answer\", answer);\n  if (status != napi_ok) return NULL;\n\n  return exports;\n}\n
                          \n

                          This macro includes NAPI_MODULE, and declares an Init function with a\nspecial name and with visibility beyond the addon. This will allow Node.js to\ninitialize the module even if it is loaded multiple times.

                          \n

                          There are a few design considerations when declaring a module that may be loaded\nmultiple times. The documentation of context-aware addons provides more\ndetails.

                          \n

                          The variables env and exports will be available inside the function body\nfollowing the macro invocation.

                          \n

                          For more details on setting properties on objects, see the section on\nWorking with JavaScript properties.

                          \n

                          For more details on building addon modules in general, refer to the existing\nAPI.

                          ", + "desc": "

                          Node-API modules are registered in a manner similar to other modules\nexcept that instead of using the NODE_MODULE macro the following\nis used:

                          \n
                          NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)\n
                          \n

                          The next difference is the signature for the Init method. For a Node-API\nmodule it is as follows:

                          \n
                          napi_value Init(napi_env env, napi_value exports);\n
                          \n

                          The return value from Init is treated as the exports object for the module.\nThe Init method is passed an empty object via the exports parameter as a\nconvenience. If Init returns NULL, the parameter passed as exports is\nexported by the module. Node-API modules cannot modify the module object but\ncan specify anything as the exports property of the module.

                          \n

                          To add the method hello as a function so that it can be called as a method\nprovided by the addon:

                          \n
                          napi_value Init(napi_env env, napi_value exports) {\n  napi_status status;\n  napi_property_descriptor desc = {\n    \"hello\",\n    NULL,\n    Method,\n    NULL,\n    NULL,\n    NULL,\n    napi_writable | napi_enumerable | napi_configurable,\n    NULL\n  };\n  status = napi_define_properties(env, exports, 1, &desc);\n  if (status != napi_ok) return NULL;\n  return exports;\n}\n
                          \n

                          To set a function to be returned by the require() for the addon:

                          \n
                          napi_value Init(napi_env env, napi_value exports) {\n  napi_value method;\n  napi_status status;\n  status = napi_create_function(env, \"exports\", NAPI_AUTO_LENGTH, Method, NULL, &method);\n  if (status != napi_ok) return NULL;\n  return method;\n}\n
                          \n

                          To define a class so that new instances can be created (often used with\nObject wrap):

                          \n
                          // NOTE: partial example, not all referenced code is included\nnapi_value Init(napi_env env, napi_value exports) {\n  napi_status status;\n  napi_property_descriptor properties[] = {\n    { \"value\", NULL, NULL, GetValue, SetValue, NULL, napi_writable | napi_configurable, NULL },\n    DECLARE_NAPI_METHOD(\"plusOne\", PlusOne),\n    DECLARE_NAPI_METHOD(\"multiply\", Multiply),\n  };\n\n  napi_value cons;\n  status =\n      napi_define_class(env, \"MyObject\", New, NULL, 3, properties, &cons);\n  if (status != napi_ok) return NULL;\n\n  status = napi_create_reference(env, cons, 1, &constructor);\n  if (status != napi_ok) return NULL;\n\n  status = napi_set_named_property(env, exports, \"MyObject\", cons);\n  if (status != napi_ok) return NULL;\n\n  return exports;\n}\n
                          \n

                          You can also use the NAPI_MODULE_INIT macro, which acts as a shorthand\nfor NAPI_MODULE and defining an Init function:

                          \n
                          NAPI_MODULE_INIT() {\n  napi_value answer;\n  napi_status result;\n\n  status = napi_create_int64(env, 42, &answer);\n  if (status != napi_ok) return NULL;\n\n  status = napi_set_named_property(env, exports, \"answer\", answer);\n  if (status != napi_ok) return NULL;\n\n  return exports;\n}\n
                          \n

                          All Node-API addons are context-aware, meaning they may be loaded multiple\ntimes. There are a few design considerations when declaring such a module.\nThe documentation on context-aware addons provides more details.

                          \n

                          The variables env and exports will be available inside the function body\nfollowing the macro invocation.

                          \n

                          For more details on setting properties on objects, see the section on\nWorking with JavaScript properties.

                          \n

                          For more details on building addon modules in general, refer to the existing\nAPI.

                          ", "type": "misc", "displayName": "Module registration" }, { "textRaw": "Working with JavaScript values", "name": "working_with_javascript_values", - "desc": "

                          N-API exposes a set of APIs to create all types of JavaScript values.\nSome of these types are documented under Section 6\nof the ECMAScript Language Specification.

                          \n

                          Fundamentally, these APIs are used to do one of the following:

                          \n
                            \n
                          1. Create a new JavaScript object
                          2. \n
                          3. Convert from a primitive C type to an N-API value
                          4. \n
                          5. Convert from N-API value to a primitive C type
                          6. \n
                          7. Get global instances including undefined and null
                          8. \n
                          \n

                          N-API values are represented by the type napi_value.\nAny N-API call that requires a JavaScript value takes in a napi_value.\nIn some cases, the API does check the type of the napi_value up-front.\nHowever, for better performance, it's better for the caller to make sure that\nthe napi_value in question is of the JavaScript type expected by the API.

                          ", + "desc": "

                          Node-API exposes a set of APIs to create all types of JavaScript values.\nSome of these types are documented under Section 6\nof the ECMAScript Language Specification.

                          \n

                          Fundamentally, these APIs are used to do one of the following:

                          \n
                            \n
                          1. Create a new JavaScript object
                          2. \n
                          3. Convert from a primitive C type to a Node-API value
                          4. \n
                          5. Convert from Node-API value to a primitive C type
                          6. \n
                          7. Get global instances including undefined and null
                          8. \n
                          \n

                          Node-API values are represented by the type napi_value.\nAny Node-API call that requires a JavaScript value takes in a napi_value.\nIn some cases, the API does check the type of the napi_value up-front.\nHowever, for better performance, it's better for the caller to make sure that\nthe napi_value in question is of the JavaScript type expected by the API.

                          ", "modules": [ { "textRaw": "Enum types", @@ -977,7 +981,8 @@ "name": "napi_key_collection_mode", "meta": { "added": [ - "v12.17.0" + "v13.7.0", + "v10.20.0" ], "napiVersion": [ 6 @@ -993,7 +998,8 @@ "name": "napi_key_filter", "meta": { "added": [ - "v12.17.0" + "v13.7.0", + "v10.20.0" ], "napiVersion": [ 6 @@ -1009,7 +1015,8 @@ "name": "napi_key_conversion", "meta": { "added": [ - "v12.17.0" + "v13.7.0", + "v10.20.0" ], "napiVersion": [ 6 @@ -1054,7 +1061,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_create_array(napi_env env, napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [out] result: A napi_value representing a JavaScript Array.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns an N-API value corresponding to a JavaScript Array type.\nJavaScript arrays are described in\nSection 22.1 of the ECMAScript Language Specification.

                          ", + "desc": "
                          napi_status napi_create_array(napi_env env, napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [out] result: A napi_value representing a JavaScript Array.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns a Node-API value corresponding to a JavaScript Array type.\nJavaScript arrays are described in\nSection 22.1 of the ECMAScript Language Specification.

                          ", "type": "module", "displayName": "napi_create_array" }, @@ -1070,7 +1077,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_create_array_with_length(napi_env env,\n                                          size_t length,\n                                          napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] length: The initial length of the Array.
                          • \n
                          • [out] result: A napi_value representing a JavaScript Array.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns an N-API value corresponding to a JavaScript Array type.\nThe Array's length property is set to the passed-in length parameter.\nHowever, the underlying buffer is not guaranteed to be pre-allocated by the VM\nwhen the array is created. That behavior is left to the underlying VM\nimplementation. If the buffer must be a contiguous block of memory that can be\ndirectly read and/or written via C, consider using\nnapi_create_external_arraybuffer.

                          \n

                          JavaScript arrays are described in\nSection 22.1 of the ECMAScript Language Specification.

                          ", + "desc": "
                          napi_status napi_create_array_with_length(napi_env env,\n                                          size_t length,\n                                          napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] length: The initial length of the Array.
                          • \n
                          • [out] result: A napi_value representing a JavaScript Array.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns a Node-API value corresponding to a JavaScript Array type.\nThe Array's length property is set to the passed-in length parameter.\nHowever, the underlying buffer is not guaranteed to be pre-allocated by the VM\nwhen the array is created. That behavior is left to the underlying VM\nimplementation. If the buffer must be a contiguous block of memory that can be\ndirectly read and/or written via C, consider using\nnapi_create_external_arraybuffer.

                          \n

                          JavaScript arrays are described in\nSection 22.1 of the ECMAScript Language Specification.

                          ", "type": "module", "displayName": "napi_create_array_with_length" }, @@ -1086,7 +1093,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_create_arraybuffer(napi_env env,\n                                    size_t byte_length,\n                                    void** data,\n                                    napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] length: The length in bytes of the array buffer to create.
                          • \n
                          • [out] data: Pointer to the underlying byte buffer of the ArrayBuffer.
                          • \n
                          • [out] result: A napi_value representing a JavaScript ArrayBuffer.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns an N-API value corresponding to a JavaScript ArrayBuffer.\nArrayBuffers are used to represent fixed-length binary data buffers. They are\nnormally used as a backing-buffer for TypedArray objects.\nThe ArrayBuffer allocated will have an underlying byte buffer whose size is\ndetermined by the length parameter that's passed in.\nThe underlying buffer is optionally returned back to the caller in case the\ncaller wants to directly manipulate the buffer. This buffer can only be\nwritten to directly from native code. To write to this buffer from JavaScript,\na typed array or DataView object would need to be created.

                          \n

                          JavaScript ArrayBuffer objects are described in\nSection 24.1 of the ECMAScript Language Specification.

                          ", + "desc": "
                          napi_status napi_create_arraybuffer(napi_env env,\n                                    size_t byte_length,\n                                    void** data,\n                                    napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] length: The length in bytes of the array buffer to create.
                          • \n
                          • [out] data: Pointer to the underlying byte buffer of the ArrayBuffer.
                          • \n
                          • [out] result: A napi_value representing a JavaScript ArrayBuffer.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns a Node-API value corresponding to a JavaScript ArrayBuffer.\nArrayBuffers are used to represent fixed-length binary data buffers. They are\nnormally used as a backing-buffer for TypedArray objects.\nThe ArrayBuffer allocated will have an underlying byte buffer whose size is\ndetermined by the length parameter that's passed in.\nThe underlying buffer is optionally returned back to the caller in case the\ncaller wants to directly manipulate the buffer. This buffer can only be\nwritten to directly from native code. To write to this buffer from JavaScript,\na typed array or DataView object would need to be created.

                          \n

                          JavaScript ArrayBuffer objects are described in\nSection 24.1 of the ECMAScript Language Specification.

                          ", "type": "module", "displayName": "napi_create_arraybuffer" }, @@ -1127,7 +1134,8 @@ "name": "napi_create_date", "meta": { "added": [ - "v11.11.0" + "v11.11.0", + "v10.17.0" ], "napiVersion": [ 5 @@ -1166,7 +1174,7 @@ ], "changes": [] }, - "desc": "
                          napi_status\nnapi_create_external_arraybuffer(napi_env env,\n                                 void* external_data,\n                                 size_t byte_length,\n                                 napi_finalize finalize_cb,\n                                 void* finalize_hint,\n                                 napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] external_data: Pointer to the underlying byte buffer of the\nArrayBuffer.
                          • \n
                          • [in] byte_length: The length in bytes of the underlying buffer.
                          • \n
                          • [in] finalize_cb: Optional callback to call when the ArrayBuffer is being\ncollected. napi_finalize provides more details.
                          • \n
                          • [in] finalize_hint: Optional hint to pass to the finalize callback during\ncollection.
                          • \n
                          • [out] result: A napi_value representing a JavaScript ArrayBuffer.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns an N-API value corresponding to a JavaScript ArrayBuffer.\nThe underlying byte buffer of the ArrayBuffer is externally allocated and\nmanaged. The caller must ensure that the byte buffer remains valid until the\nfinalize callback is called.

                          \n

                          The API adds a napi_finalize callback which will be called when the JavaScript\nobject just created is ready for garbage collection. It is similar to\nnapi_wrap() except that:

                          \n
                            \n
                          • the native data cannot be retrieved later using napi_unwrap(),
                          • \n
                          • nor can it be removed later using napi_remove_wrap(), and
                          • \n
                          • the object created by the API can be used with napi_wrap().
                          • \n
                          \n

                          JavaScript ArrayBuffers are described in\nSection 24.1 of the ECMAScript Language Specification.

                          ", + "desc": "
                          napi_status\nnapi_create_external_arraybuffer(napi_env env,\n                                 void* external_data,\n                                 size_t byte_length,\n                                 napi_finalize finalize_cb,\n                                 void* finalize_hint,\n                                 napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] external_data: Pointer to the underlying byte buffer of the\nArrayBuffer.
                          • \n
                          • [in] byte_length: The length in bytes of the underlying buffer.
                          • \n
                          • [in] finalize_cb: Optional callback to call when the ArrayBuffer is being\ncollected. napi_finalize provides more details.
                          • \n
                          • [in] finalize_hint: Optional hint to pass to the finalize callback during\ncollection.
                          • \n
                          • [out] result: A napi_value representing a JavaScript ArrayBuffer.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns a Node-API value corresponding to a JavaScript ArrayBuffer.\nThe underlying byte buffer of the ArrayBuffer is externally allocated and\nmanaged. The caller must ensure that the byte buffer remains valid until the\nfinalize callback is called.

                          \n

                          The API adds a napi_finalize callback which will be called when the JavaScript\nobject just created is ready for garbage collection. It is similar to\nnapi_wrap() except that:

                          \n
                            \n
                          • the native data cannot be retrieved later using napi_unwrap(),
                          • \n
                          • nor can it be removed later using napi_remove_wrap(), and
                          • \n
                          • the object created by the API can be used with napi_wrap().
                          • \n
                          \n

                          JavaScript ArrayBuffers are described in\nSection 24.1 of the ECMAScript Language Specification.

                          ", "type": "module", "displayName": "napi_create_external_arraybuffer" }, @@ -1214,7 +1222,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_create_symbol(napi_env env,\n                               napi_value description,\n                               napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] description: Optional napi_value which refers to a JavaScript\nString to be set as the description for the symbol.
                          • \n
                          • [out] result: A napi_value representing a JavaScript Symbol.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API creates a JavaScript Symbol object from a UTF8-encoded C string.

                          \n

                          The JavaScript Symbol type is described in Section 19.4\nof the ECMAScript Language Specification.

                          ", + "desc": "
                          napi_status napi_create_symbol(napi_env env,\n                               napi_value description,\n                               napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] description: Optional napi_value which refers to a JavaScript\nstring to be set as the description for the symbol.
                          • \n
                          • [out] result: A napi_value representing a JavaScript symbol.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API creates a JavaScript symbol value from a UTF8-encoded C string.

                          \n

                          The JavaScript symbol type is described in Section 19.4\nof the ECMAScript Language Specification.

                          ", "type": "module", "displayName": "napi_create_symbol" }, @@ -1255,8 +1263,8 @@ "displayName": "Object creation functions" }, { - "textRaw": "Functions to convert from C types to N-API", - "name": "functions_to_convert_from_c_types_to_n-api", + "textRaw": "Functions to convert from C types to Node-API", + "name": "functions_to_convert_from_c_types_to_node-api", "modules": [ { "textRaw": "napi_create_int32", @@ -1270,7 +1278,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: Integer value to be represented in JavaScript.
                          • \n
                          • [out] result: A napi_value representing a JavaScript Number.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API is used to convert from the C int32_t type to the JavaScript\nNumber type.

                          \n

                          The JavaScript Number type is described in\nSection 6.1.6 of the ECMAScript Language Specification.

                          ", + "desc": "
                          napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: Integer value to be represented in JavaScript.
                          • \n
                          • [out] result: A napi_value representing a JavaScript number.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API is used to convert from the C int32_t type to the JavaScript\nnumber type.

                          \n

                          The JavaScript number type is described in\nSection 6.1.6 of the ECMAScript Language Specification.

                          ", "type": "module", "displayName": "napi_create_int32" }, @@ -1286,7 +1294,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: Unsigned integer value to be represented in JavaScript.
                          • \n
                          • [out] result: A napi_value representing a JavaScript Number.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API is used to convert from the C uint32_t type to the JavaScript\nNumber type.

                          \n

                          The JavaScript Number type is described in\nSection 6.1.6 of the ECMAScript Language Specification.

                          ", + "desc": "
                          napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: Unsigned integer value to be represented in JavaScript.
                          • \n
                          • [out] result: A napi_value representing a JavaScript number.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API is used to convert from the C uint32_t type to the JavaScript\nnumber type.

                          \n

                          The JavaScript number type is described in\nSection 6.1.6 of the ECMAScript Language Specification.

                          ", "type": "module", "displayName": "napi_create_uint32" }, @@ -1302,7 +1310,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: Integer value to be represented in JavaScript.
                          • \n
                          • [out] result: A napi_value representing a JavaScript Number.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API is used to convert from the C int64_t type to the JavaScript\nNumber type.

                          \n

                          The JavaScript Number type is described in Section 6.1.6\nof the ECMAScript Language Specification. Note the complete range of int64_t\ncannot be represented with full precision in JavaScript. Integer values\noutside the range of Number.MIN_SAFE_INTEGER -(2**53 - 1) -\nNumber.MAX_SAFE_INTEGER (2**53 - 1) will lose precision.

                          ", + "desc": "
                          napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: Integer value to be represented in JavaScript.
                          • \n
                          • [out] result: A napi_value representing a JavaScript number.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API is used to convert from the C int64_t type to the JavaScript\nnumber type.

                          \n

                          The JavaScript number type is described in Section 6.1.6\nof the ECMAScript Language Specification. Note the complete range of int64_t\ncannot be represented with full precision in JavaScript. Integer values\noutside the range of Number.MIN_SAFE_INTEGER -(2**53 - 1) -\nNumber.MAX_SAFE_INTEGER (2**53 - 1) will lose precision.

                          ", "type": "module", "displayName": "napi_create_int64" }, @@ -1318,7 +1326,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_create_double(napi_env env, double value, napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: Double-precision value to be represented in JavaScript.
                          • \n
                          • [out] result: A napi_value representing a JavaScript Number.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API is used to convert from the C double type to the JavaScript\nNumber type.

                          \n

                          The JavaScript Number type is described in\nSection 6.1.6 of the ECMAScript Language Specification.

                          ", + "desc": "
                          napi_status napi_create_double(napi_env env, double value, napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: Double-precision value to be represented in JavaScript.
                          • \n
                          • [out] result: A napi_value representing a JavaScript number.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API is used to convert from the C double type to the JavaScript\nnumber type.

                          \n

                          The JavaScript number type is described in\nSection 6.1.6 of the ECMAScript Language Specification.

                          ", "type": "module", "displayName": "napi_create_double" }, @@ -1382,7 +1390,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_create_string_latin1(napi_env env,\n                                      const char* str,\n                                      size_t length,\n                                      napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] str: Character buffer representing an ISO-8859-1-encoded string.
                          • \n
                          • [in] length: The length of the string in bytes, or NAPI_AUTO_LENGTH if it\nis null-terminated.
                          • \n
                          • [out] result: A napi_value representing a JavaScript String.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API creates a JavaScript String object from an ISO-8859-1-encoded C\nstring. The native string is copied.

                          \n

                          The JavaScript String type is described in\nSection 6.1.4 of the ECMAScript Language Specification.

                          ", + "desc": "
                          napi_status napi_create_string_latin1(napi_env env,\n                                      const char* str,\n                                      size_t length,\n                                      napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] str: Character buffer representing an ISO-8859-1-encoded string.
                          • \n
                          • [in] length: The length of the string in bytes, or NAPI_AUTO_LENGTH if it\nis null-terminated.
                          • \n
                          • [out] result: A napi_value representing a JavaScript string.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API creates a JavaScript string value from an ISO-8859-1-encoded C\nstring. The native string is copied.

                          \n

                          The JavaScript string type is described in\nSection 6.1.4 of the ECMAScript Language Specification.

                          ", "type": "module", "displayName": "napi_create_string_latin1" }, @@ -1398,7 +1406,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_create_string_utf16(napi_env env,\n                                     const char16_t* str,\n                                     size_t length,\n                                     napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] str: Character buffer representing a UTF16-LE-encoded string.
                          • \n
                          • [in] length: The length of the string in two-byte code units, or\nNAPI_AUTO_LENGTH if it is null-terminated.
                          • \n
                          • [out] result: A napi_value representing a JavaScript String.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API creates a JavaScript String object from a UTF16-LE-encoded C string.\nThe native string is copied.

                          \n

                          The JavaScript String type is described in\nSection 6.1.4 of the ECMAScript Language Specification.

                          ", + "desc": "
                          napi_status napi_create_string_utf16(napi_env env,\n                                     const char16_t* str,\n                                     size_t length,\n                                     napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] str: Character buffer representing a UTF16-LE-encoded string.
                          • \n
                          • [in] length: The length of the string in two-byte code units, or\nNAPI_AUTO_LENGTH if it is null-terminated.
                          • \n
                          • [out] result: A napi_value representing a JavaScript string.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API creates a JavaScript string value from a UTF16-LE-encoded C string.\nThe native string is copied.

                          \n

                          The JavaScript string type is described in\nSection 6.1.4 of the ECMAScript Language Specification.

                          ", "type": "module", "displayName": "napi_create_string_utf16" }, @@ -1414,17 +1422,17 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_create_string_utf8(napi_env env,\n                                    const char* str,\n                                    size_t length,\n                                    napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] str: Character buffer representing a UTF8-encoded string.
                          • \n
                          • [in] length: The length of the string in bytes, or NAPI_AUTO_LENGTH if it\nis null-terminated.
                          • \n
                          • [out] result: A napi_value representing a JavaScript String.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API creates a JavaScript String object from a UTF8-encoded C string.\nThe native string is copied.

                          \n

                          The JavaScript String type is described in\nSection 6.1.4 of the ECMAScript Language Specification.

                          ", + "desc": "
                          napi_status napi_create_string_utf8(napi_env env,\n                                    const char* str,\n                                    size_t length,\n                                    napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] str: Character buffer representing a UTF8-encoded string.
                          • \n
                          • [in] length: The length of the string in bytes, or NAPI_AUTO_LENGTH if it\nis null-terminated.
                          • \n
                          • [out] result: A napi_value representing a JavaScript string.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API creates a JavaScript string value from a UTF8-encoded C string.\nThe native string is copied.

                          \n

                          The JavaScript string type is described in\nSection 6.1.4 of the ECMAScript Language Specification.

                          ", "type": "module", "displayName": "napi_create_string_utf8" } ], "type": "module", - "displayName": "Functions to convert from C types to N-API" + "displayName": "Functions to convert from C types to Node-API" }, { - "textRaw": "Functions to convert from N-API to C types", - "name": "functions_to_convert_from_n-api_to_c_types", + "textRaw": "Functions to convert from Node-API to C types", + "name": "functions_to_convert_from_node-api_to_c_types", "modules": [ { "textRaw": "napi_get_array_length", @@ -1518,7 +1526,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_dataview_info(napi_env env,\n                                   napi_value dataview,\n                                   size_t* byte_length,\n                                   void** data,\n                                   napi_value* arraybuffer,\n                                   size_t* byte_offset)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] dataview: napi_value representing the DataView whose\nproperties to query.
                          • \n
                          • [out] byte_length: Number of bytes in the DataView.
                          • \n
                          • [out] data: The data buffer underlying the DataView.\nIf byte_length is 0, this may be NULL or any other pointer value.
                          • \n
                          • [out] arraybuffer: ArrayBuffer underlying the DataView.
                          • \n
                          • [out] byte_offset: The byte offset within the data buffer from which\nto start projecting the DataView.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns various properties of a DataView.

                          ", + "desc": "
                          napi_status napi_get_dataview_info(napi_env env,\n                                   napi_value dataview,\n                                   size_t* byte_length,\n                                   void** data,\n                                   napi_value* arraybuffer,\n                                   size_t* byte_offset)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] dataview: napi_value representing the DataView whose\nproperties to query.
                          • \n
                          • [out] byte_length: Number of bytes in the DataView.
                          • \n
                          • [out] data: The data buffer underlying the DataView.\nIf byte_length is 0, this may be NULL or any other pointer value.
                          • \n
                          • [out] arraybuffer: ArrayBuffer underlying the DataView.
                          • \n
                          • [out] byte_offset: The byte offset within the data buffer from which\nto start projecting the DataView.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns various properties of a DataView.

                          ", "type": "module", "displayName": "napi_get_dataview_info" }, @@ -1527,7 +1535,8 @@ "name": "napi_get_date_value", "meta": { "added": [ - "v11.11.0" + "v11.11.0", + "v10.17.0" ], "napiVersion": [ 5 @@ -1566,7 +1575,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_value_double(napi_env env,\n                                  napi_value value,\n                                  double* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript Number.
                          • \n
                          • [out] result: C double primitive equivalent of the given JavaScript\nNumber.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-number napi_value is passed\nin it returns napi_number_expected.

                          \n

                          This API returns the C double primitive equivalent of the given JavaScript\nNumber.

                          ", + "desc": "
                          napi_status napi_get_value_double(napi_env env,\n                                  napi_value value,\n                                  double* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript number.
                          • \n
                          • [out] result: C double primitive equivalent of the given JavaScript\nnumber.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-number napi_value is passed\nin it returns napi_number_expected.

                          \n

                          This API returns the C double primitive equivalent of the given JavaScript\nnumber.

                          ", "type": "module", "displayName": "napi_get_value_double" }, @@ -1646,7 +1655,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_value_int32(napi_env env,\n                                 napi_value value,\n                                 int32_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript Number.
                          • \n
                          • [out] result: C int32 primitive equivalent of the given JavaScript\nNumber.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-number napi_value\nis passed in napi_number_expected.

                          \n

                          This API returns the C int32 primitive equivalent\nof the given JavaScript Number.

                          \n

                          If the number exceeds the range of the 32 bit integer, then the result is\ntruncated to the equivalent of the bottom 32 bits. This can result in a large\npositive number becoming a negative number if the value is > 231 - 1.

                          \n

                          Non-finite number values (NaN, +Infinity, or -Infinity) set the\nresult to zero.

                          ", + "desc": "
                          napi_status napi_get_value_int32(napi_env env,\n                                 napi_value value,\n                                 int32_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript number.
                          • \n
                          • [out] result: C int32 primitive equivalent of the given JavaScript\nnumber.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-number napi_value\nis passed in napi_number_expected.

                          \n

                          This API returns the C int32 primitive equivalent\nof the given JavaScript number.

                          \n

                          If the number exceeds the range of the 32 bit integer, then the result is\ntruncated to the equivalent of the bottom 32 bits. This can result in a large\npositive number becoming a negative number if the value is > 231 - 1.

                          \n

                          Non-finite number values (NaN, +Infinity, or -Infinity) set the\nresult to zero.

                          ", "type": "module", "displayName": "napi_get_value_int32" }, @@ -1662,7 +1671,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_value_int64(napi_env env,\n                                 napi_value value,\n                                 int64_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript Number.
                          • \n
                          • [out] result: C int64 primitive equivalent of the given JavaScript\nNumber.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-number napi_value\nis passed in it returns napi_number_expected.

                          \n

                          This API returns the C int64 primitive equivalent of the given JavaScript\nNumber.

                          \n

                          Number values outside the range of Number.MIN_SAFE_INTEGER\n-(2**53 - 1) - Number.MAX_SAFE_INTEGER (2**53 - 1) will lose\nprecision.

                          \n

                          Non-finite number values (NaN, +Infinity, or -Infinity) set the\nresult to zero.

                          ", + "desc": "
                          napi_status napi_get_value_int64(napi_env env,\n                                 napi_value value,\n                                 int64_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript number.
                          • \n
                          • [out] result: C int64 primitive equivalent of the given JavaScript\nnumber.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-number napi_value\nis passed in it returns napi_number_expected.

                          \n

                          This API returns the C int64 primitive equivalent of the given JavaScript\nnumber.

                          \n

                          number values outside the range of Number.MIN_SAFE_INTEGER\n-(2**53 - 1) - Number.MAX_SAFE_INTEGER (2**53 - 1) will lose\nprecision.

                          \n

                          Non-finite number values (NaN, +Infinity, or -Infinity) set the\nresult to zero.

                          ", "type": "module", "displayName": "napi_get_value_int64" }, @@ -1678,7 +1687,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_value_string_latin1(napi_env env,\n                                         napi_value value,\n                                         char* buf,\n                                         size_t bufsize,\n                                         size_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript string.
                          • \n
                          • [in] buf: Buffer to write the ISO-8859-1-encoded string into. If NULL is\npassed in, the length of the string (in bytes) is returned.
                          • \n
                          • [in] bufsize: Size of the destination buffer. When this value is\ninsufficient, the returned string will be truncated.
                          • \n
                          • [out] result: Number of bytes copied into the buffer, excluding the null\nterminator.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-String napi_value\nis passed in it returns napi_string_expected.

                          \n

                          This API returns the ISO-8859-1-encoded string corresponding the value passed\nin.

                          ", + "desc": "
                          napi_status napi_get_value_string_latin1(napi_env env,\n                                         napi_value value,\n                                         char* buf,\n                                         size_t bufsize,\n                                         size_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript string.
                          • \n
                          • [in] buf: Buffer to write the ISO-8859-1-encoded string into. If NULL is\npassed in, the length of the string in bytes and excluding the null terminator\nis returned in result.
                          • \n
                          • [in] bufsize: Size of the destination buffer. When this value is\ninsufficient, the returned string is truncated and null-terminated.
                          • \n
                          • [out] result: Number of bytes copied into the buffer, excluding the null\nterminator.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-string napi_value\nis passed in it returns napi_string_expected.

                          \n

                          This API returns the ISO-8859-1-encoded string corresponding the value passed\nin.

                          ", "type": "module", "displayName": "napi_get_value_string_latin1" }, @@ -1694,7 +1703,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_value_string_utf8(napi_env env,\n                                       napi_value value,\n                                       char* buf,\n                                       size_t bufsize,\n                                       size_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript string.
                          • \n
                          • [in] buf: Buffer to write the UTF8-encoded string into. If NULL is passed\nin, the length of the string (in bytes) is returned.
                          • \n
                          • [in] bufsize: Size of the destination buffer. When this value is\ninsufficient, the returned string will be truncated.
                          • \n
                          • [out] result: Number of bytes copied into the buffer, excluding the null\nterminator.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-String napi_value\nis passed in it returns napi_string_expected.

                          \n

                          This API returns the UTF8-encoded string corresponding the value passed in.

                          ", + "desc": "
                          napi_status napi_get_value_string_utf8(napi_env env,\n                                       napi_value value,\n                                       char* buf,\n                                       size_t bufsize,\n                                       size_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript string.
                          • \n
                          • [in] buf: Buffer to write the UTF8-encoded string into. If NULL is passed\nin, the length of the string in bytes and excluding the null terminator is\nreturned in result.
                          • \n
                          • [in] bufsize: Size of the destination buffer. When this value is\ninsufficient, the returned string is truncated and null-terminated.
                          • \n
                          • [out] result: Number of bytes copied into the buffer, excluding the null\nterminator.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-string napi_value\nis passed in it returns napi_string_expected.

                          \n

                          This API returns the UTF8-encoded string corresponding the value passed in.

                          ", "type": "module", "displayName": "napi_get_value_string_utf8" }, @@ -1710,7 +1719,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_value_string_utf16(napi_env env,\n                                        napi_value value,\n                                        char16_t* buf,\n                                        size_t bufsize,\n                                        size_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript string.
                          • \n
                          • [in] buf: Buffer to write the UTF16-LE-encoded string into. If NULL is\npassed in, the length of the string (in 2-byte code units) is returned.
                          • \n
                          • [in] bufsize: Size of the destination buffer. When this value is\ninsufficient, the returned string will be truncated.
                          • \n
                          • [out] result: Number of 2-byte code units copied into the buffer, excluding\nthe null terminator.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-String napi_value\nis passed in it returns napi_string_expected.

                          \n

                          This API returns the UTF16-encoded string corresponding the value passed in.

                          ", + "desc": "
                          napi_status napi_get_value_string_utf16(napi_env env,\n                                        napi_value value,\n                                        char16_t* buf,\n                                        size_t bufsize,\n                                        size_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript string.
                          • \n
                          • [in] buf: Buffer to write the UTF16-LE-encoded string into. If NULL is\npassed in, the length of the string in 2-byte code units and excluding the\nnull terminator is returned.
                          • \n
                          • [in] bufsize: Size of the destination buffer. When this value is\ninsufficient, the returned string is truncated and null-terminated.
                          • \n
                          • [out] result: Number of 2-byte code units copied into the buffer, excluding\nthe null terminator.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-string napi_value\nis passed in it returns napi_string_expected.

                          \n

                          This API returns the UTF16-encoded string corresponding the value passed in.

                          ", "type": "module", "displayName": "napi_get_value_string_utf16" }, @@ -1726,13 +1735,13 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_value_uint32(napi_env env,\n                                  napi_value value,\n                                  uint32_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript Number.
                          • \n
                          • [out] result: C primitive equivalent of the given napi_value as a\nuint32_t.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-number napi_value\nis passed in it returns napi_number_expected.

                          \n

                          This API returns the C primitive equivalent of the given napi_value as a\nuint32_t.

                          ", + "desc": "
                          napi_status napi_get_value_uint32(napi_env env,\n                                  napi_value value,\n                                  uint32_t* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: napi_value representing JavaScript number.
                          • \n
                          • [out] result: C primitive equivalent of the given napi_value as a\nuint32_t.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded. If a non-number napi_value\nis passed in it returns napi_number_expected.

                          \n

                          This API returns the C primitive equivalent of the given napi_value as a\nuint32_t.

                          ", "type": "module", "displayName": "napi_get_value_uint32" } ], "type": "module", - "displayName": "Functions to convert from N-API to C types" + "displayName": "Functions to convert from Node-API to C types" }, { "textRaw": "Functions to get global instances", @@ -1813,7 +1822,7 @@ { "textRaw": "Working with JavaScript values and abstract operations", "name": "working_with_javascript_values_and_abstract_operations", - "desc": "

                          N-API exposes a set of APIs to perform some abstract operations on JavaScript\nvalues. Some of these operations are documented under Section 7\nof the ECMAScript Language Specification.

                          \n

                          These APIs support doing one of the following:

                          \n
                            \n
                          1. Coerce JavaScript values to specific JavaScript types (such as Number or\nString).
                          2. \n
                          3. Check the type of a JavaScript value.
                          4. \n
                          5. Check for equality between two JavaScript values.
                          6. \n
                          ", + "desc": "

                          Node-API exposes a set of APIs to perform some abstract operations on JavaScript\nvalues. Some of these operations are documented under Section 7\nof the ECMAScript Language Specification.

                          \n

                          These APIs support doing one of the following:

                          \n
                            \n
                          1. Coerce JavaScript values to specific JavaScript types (such as number or\nstring).
                          2. \n
                          3. Check the type of a JavaScript value.
                          4. \n
                          5. Check for equality between two JavaScript values.
                          6. \n
                          ", "modules": [ { "textRaw": "napi_coerce_to_bool", @@ -1843,7 +1852,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_coerce_to_number(napi_env env,\n                                  napi_value value,\n                                  napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: The JavaScript value to coerce.
                          • \n
                          • [out] result: napi_value representing the coerced JavaScript Number.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API implements the abstract operation ToNumber() as defined in\nSection 7.1.3 of the ECMAScript Language Specification.\nThis API can be re-entrant if getters are defined on the passed-in Object.

                          ", + "desc": "
                          napi_status napi_coerce_to_number(napi_env env,\n                                  napi_value value,\n                                  napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: The JavaScript value to coerce.
                          • \n
                          • [out] result: napi_value representing the coerced JavaScript number.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API implements the abstract operation ToNumber() as defined in\nSection 7.1.3 of the ECMAScript Language Specification.\nThis API can be re-entrant if getters are defined on the passed-in Object.

                          ", "type": "module", "displayName": "napi_coerce_to_number" }, @@ -1875,7 +1884,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_coerce_to_string(napi_env env,\n                                  napi_value value,\n                                  napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: The JavaScript value to coerce.
                          • \n
                          • [out] result: napi_value representing the coerced JavaScript String.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API implements the abstract operation ToString() as defined in\nSection 7.1.13 of the ECMAScript Language Specification.\nThis API can be re-entrant if getters are defined on the passed-in Object.

                          ", + "desc": "
                          napi_status napi_coerce_to_string(napi_env env,\n                                  napi_value value,\n                                  napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] value: The JavaScript value to coerce.
                          • \n
                          • [out] result: napi_value representing the coerced JavaScript string.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API implements the abstract operation ToString() as defined in\nSection 7.1.13 of the ECMAScript Language Specification.\nThis API can be re-entrant if getters are defined on the passed-in Object.

                          ", "type": "module", "displayName": "napi_coerce_to_string" }, @@ -1964,7 +1973,8 @@ "name": "napi_is_date", "meta": { "added": [ - "v11.11.0" + "v11.11.0", + "v10.17.0" ], "napiVersion": [ 5 @@ -2044,7 +2054,9 @@ "name": "napi_detach_arraybuffer", "meta": { "added": [ - "v12.16.0" + "v13.0.0", + "v12.16.0", + "v10.22.0" ], "napiVersion": [ 7 @@ -2060,7 +2072,9 @@ "name": "napi_is_detached_arraybuffer", "meta": { "added": [ - "v12.16.0" + "v13.3.0", + "v12.16.0", + "v10.22.0" ], "napiVersion": [ 7 @@ -2078,7 +2092,7 @@ { "textRaw": "Working with JavaScript properties", "name": "working_with_javascript_properties", - "desc": "

                          N-API exposes a set of APIs to get and set properties on JavaScript\nobjects. Some of these types are documented under Section 7 of the\nECMAScript Language Specification.

                          \n

                          Properties in JavaScript are represented as a tuple of a key and a value.\nFundamentally, all property keys in N-API can be represented in one of the\nfollowing forms:

                          \n
                            \n
                          • Named: a simple UTF8-encoded string
                          • \n
                          • Integer-Indexed: an index value represented by uint32_t
                          • \n
                          • JavaScript value: these are represented in N-API by napi_value. This can\nbe a napi_value representing a String, Number, or Symbol.
                          • \n
                          \n

                          N-API values are represented by the type napi_value.\nAny N-API call that requires a JavaScript value takes in a napi_value.\nHowever, it's the caller's responsibility to make sure that the\nnapi_value in question is of the JavaScript type expected by the API.

                          \n

                          The APIs documented in this section provide a simple interface to\nget and set properties on arbitrary JavaScript objects represented by\nnapi_value.

                          \n

                          For instance, consider the following JavaScript code snippet:

                          \n
                          const obj = {};\nobj.myProp = 123;\n
                          \n

                          The equivalent can be done using N-API values with the following snippet:

                          \n
                          napi_status status = napi_generic_failure;\n\n// const obj = {}\nnapi_value obj, value;\nstatus = napi_create_object(env, &obj);\nif (status != napi_ok) return status;\n\n// Create a napi_value for 123\nstatus = napi_create_int32(env, 123, &value);\nif (status != napi_ok) return status;\n\n// obj.myProp = 123\nstatus = napi_set_named_property(env, obj, \"myProp\", value);\nif (status != napi_ok) return status;\n
                          \n

                          Indexed properties can be set in a similar manner. Consider the following\nJavaScript snippet:

                          \n
                          const arr = [];\narr[123] = 'hello';\n
                          \n

                          The equivalent can be done using N-API values with the following snippet:

                          \n
                          napi_status status = napi_generic_failure;\n\n// const arr = [];\nnapi_value arr, value;\nstatus = napi_create_array(env, &arr);\nif (status != napi_ok) return status;\n\n// Create a napi_value for 'hello'\nstatus = napi_create_string_utf8(env, \"hello\", NAPI_AUTO_LENGTH, &value);\nif (status != napi_ok) return status;\n\n// arr[123] = 'hello';\nstatus = napi_set_element(env, arr, 123, value);\nif (status != napi_ok) return status;\n
                          \n

                          Properties can be retrieved using the APIs described in this section.\nConsider the following JavaScript snippet:

                          \n
                          const arr = [];\nconst value = arr[123];\n
                          \n

                          The following is the approximate equivalent of the N-API counterpart:

                          \n
                          napi_status status = napi_generic_failure;\n\n// const arr = []\nnapi_value arr, value;\nstatus = napi_create_array(env, &arr);\nif (status != napi_ok) return status;\n\n// const value = arr[123]\nstatus = napi_get_element(env, arr, 123, &value);\nif (status != napi_ok) return status;\n
                          \n

                          Finally, multiple properties can also be defined on an object for performance\nreasons. Consider the following JavaScript:

                          \n
                          const obj = {};\nObject.defineProperties(obj, {\n  'foo': { value: 123, writable: true, configurable: true, enumerable: true },\n  'bar': { value: 456, writable: true, configurable: true, enumerable: true }\n});\n
                          \n

                          The following is the approximate equivalent of the N-API counterpart:

                          \n
                          napi_status status = napi_status_generic_failure;\n\n// const obj = {};\nnapi_value obj;\nstatus = napi_create_object(env, &obj);\nif (status != napi_ok) return status;\n\n// Create napi_values for 123 and 456\nnapi_value fooValue, barValue;\nstatus = napi_create_int32(env, 123, &fooValue);\nif (status != napi_ok) return status;\nstatus = napi_create_int32(env, 456, &barValue);\nif (status != napi_ok) return status;\n\n// Set the properties\nnapi_property_descriptor descriptors[] = {\n  { \"foo\", NULL, NULL, NULL, NULL, fooValue, napi_writable | napi_configurable, NULL },\n  { \"bar\", NULL, NULL, NULL, NULL, barValue, napi_writable | napi_configurable, NULL }\n}\nstatus = napi_define_properties(env,\n                                obj,\n                                sizeof(descriptors) / sizeof(descriptors[0]),\n                                descriptors);\nif (status != napi_ok) return status;\n
                          ", + "desc": "

                          Node-API exposes a set of APIs to get and set properties on JavaScript\nobjects. Some of these types are documented under Section 7 of the\nECMAScript Language Specification.

                          \n

                          Properties in JavaScript are represented as a tuple of a key and a value.\nFundamentally, all property keys in Node-API can be represented in one of the\nfollowing forms:

                          \n
                            \n
                          • Named: a simple UTF8-encoded string
                          • \n
                          • Integer-Indexed: an index value represented by uint32_t
                          • \n
                          • JavaScript value: these are represented in Node-API by napi_value. This can\nbe a napi_value representing a string, number, or symbol.
                          • \n
                          \n

                          Node-API values are represented by the type napi_value.\nAny Node-API call that requires a JavaScript value takes in a napi_value.\nHowever, it's the caller's responsibility to make sure that the\nnapi_value in question is of the JavaScript type expected by the API.

                          \n

                          The APIs documented in this section provide a simple interface to\nget and set properties on arbitrary JavaScript objects represented by\nnapi_value.

                          \n

                          For instance, consider the following JavaScript code snippet:

                          \n
                          const obj = {};\nobj.myProp = 123;\n
                          \n

                          The equivalent can be done using Node-API values with the following snippet:

                          \n
                          napi_status status = napi_generic_failure;\n\n// const obj = {}\nnapi_value obj, value;\nstatus = napi_create_object(env, &obj);\nif (status != napi_ok) return status;\n\n// Create a napi_value for 123\nstatus = napi_create_int32(env, 123, &value);\nif (status != napi_ok) return status;\n\n// obj.myProp = 123\nstatus = napi_set_named_property(env, obj, \"myProp\", value);\nif (status != napi_ok) return status;\n
                          \n

                          Indexed properties can be set in a similar manner. Consider the following\nJavaScript snippet:

                          \n
                          const arr = [];\narr[123] = 'hello';\n
                          \n

                          The equivalent can be done using Node-API values with the following snippet:

                          \n
                          napi_status status = napi_generic_failure;\n\n// const arr = [];\nnapi_value arr, value;\nstatus = napi_create_array(env, &arr);\nif (status != napi_ok) return status;\n\n// Create a napi_value for 'hello'\nstatus = napi_create_string_utf8(env, \"hello\", NAPI_AUTO_LENGTH, &value);\nif (status != napi_ok) return status;\n\n// arr[123] = 'hello';\nstatus = napi_set_element(env, arr, 123, value);\nif (status != napi_ok) return status;\n
                          \n

                          Properties can be retrieved using the APIs described in this section.\nConsider the following JavaScript snippet:

                          \n
                          const arr = [];\nconst value = arr[123];\n
                          \n

                          The following is the approximate equivalent of the Node-API counterpart:

                          \n
                          napi_status status = napi_generic_failure;\n\n// const arr = []\nnapi_value arr, value;\nstatus = napi_create_array(env, &arr);\nif (status != napi_ok) return status;\n\n// const value = arr[123]\nstatus = napi_get_element(env, arr, 123, &value);\nif (status != napi_ok) return status;\n
                          \n

                          Finally, multiple properties can also be defined on an object for performance\nreasons. Consider the following JavaScript:

                          \n
                          const obj = {};\nObject.defineProperties(obj, {\n  'foo': { value: 123, writable: true, configurable: true, enumerable: true },\n  'bar': { value: 456, writable: true, configurable: true, enumerable: true }\n});\n
                          \n

                          The following is the approximate equivalent of the Node-API counterpart:

                          \n
                          napi_status status = napi_status_generic_failure;\n\n// const obj = {};\nnapi_value obj;\nstatus = napi_create_object(env, &obj);\nif (status != napi_ok) return status;\n\n// Create napi_values for 123 and 456\nnapi_value fooValue, barValue;\nstatus = napi_create_int32(env, 123, &fooValue);\nif (status != napi_ok) return status;\nstatus = napi_create_int32(env, 456, &barValue);\nif (status != napi_ok) return status;\n\n// Set the properties\nnapi_property_descriptor descriptors[] = {\n  { \"foo\", NULL, NULL, NULL, NULL, fooValue, napi_writable | napi_configurable, NULL },\n  { \"bar\", NULL, NULL, NULL, NULL, barValue, napi_writable | napi_configurable, NULL }\n}\nstatus = napi_define_properties(env,\n                                obj,\n                                sizeof(descriptors) / sizeof(descriptors[0]),\n                                descriptors);\nif (status != napi_ok) return status;\n
                          ", "modules": [ { "textRaw": "Structures", @@ -2090,20 +2104,20 @@ "meta": { "changes": [ { - "version": "v12.20.0", + "version": "v14.12.0", "pr-url": "https://github.com/nodejs/node/pull/35214", - "description": "added `napi_default_method` and `napi_default_property`" + "description": "added `napi_default_method` and `napi_default_property`." } ] }, - "desc": "
                          typedef enum {\n  napi_default = 0,\n  napi_writable = 1 << 0,\n  napi_enumerable = 1 << 1,\n  napi_configurable = 1 << 2,\n\n  // Used with napi_define_class to distinguish static properties\n  // from instance properties. Ignored by napi_define_properties.\n  napi_static = 1 << 10,\n\n  // Default for class methods.\n  napi_default_method = napi_writable | napi_configurable,\n\n  // Default for object properties, like in JS obj[prop].\n  napi_default_property = napi_writable |\n                          napi_enumerable |\n                          napi_configurable,\n} napi_property_attributes;\n
                          \n

                          napi_property_attributes are flags used to control the behavior of properties\nset on a JavaScript object. Other than napi_static they correspond to the\nattributes listed in Section 6.1.7.1\nof the ECMAScript Language Specification.\nThey can be one or more of the following bitflags:

                          \n
                            \n
                          • napi_default: No explicit attributes are set on the property. By default, a\nproperty is read only, not enumerable and not configurable.
                          • \n
                          • napi_writable: The property is writable.
                          • \n
                          • napi_enumerable: The property is enumerable.
                          • \n
                          • napi_configurable: The property is configurable as defined in\nSection 6.1.7.1 of the ECMAScript Language Specification.
                          • \n
                          • napi_static: The property will be defined as a static property on a class as\nopposed to an instance property, which is the default. This is used only by\nnapi_define_class. It is ignored by napi_define_properties.
                          • \n
                          • napi_default_method: The property is configureable, writeable but not\nenumerable like a method in a JS class.
                          • \n
                          • napi_default_property: The property is writable, enumerable and configurable\nlike a property set via JS code obj.key = value.
                          • \n
                          ", + "desc": "
                          typedef enum {\n  napi_default = 0,\n  napi_writable = 1 << 0,\n  napi_enumerable = 1 << 1,\n  napi_configurable = 1 << 2,\n\n  // Used with napi_define_class to distinguish static properties\n  // from instance properties. Ignored by napi_define_properties.\n  napi_static = 1 << 10,\n\n  // Default for class methods.\n  napi_default_method = napi_writable | napi_configurable,\n\n  // Default for object properties, like in JS obj[prop].\n  napi_default_jsproperty = napi_writable |\n                          napi_enumerable |\n                          napi_configurable,\n} napi_property_attributes;\n
                          \n

                          napi_property_attributes are flags used to control the behavior of properties\nset on a JavaScript object. Other than napi_static they correspond to the\nattributes listed in Section 6.1.7.1\nof the ECMAScript Language Specification.\nThey can be one or more of the following bitflags:

                          \n
                            \n
                          • napi_default: No explicit attributes are set on the property. By default, a\nproperty is read only, not enumerable and not configurable.
                          • \n
                          • napi_writable: The property is writable.
                          • \n
                          • napi_enumerable: The property is enumerable.
                          • \n
                          • napi_configurable: The property is configurable as defined in\nSection 6.1.7.1 of the ECMAScript Language Specification.
                          • \n
                          • napi_static: The property will be defined as a static property on a class as\nopposed to an instance property, which is the default. This is used only by\nnapi_define_class. It is ignored by napi_define_properties.
                          • \n
                          • napi_default_method: Like a method in a JS class, the property is\nconfigurable and writeable, but not enumerable.
                          • \n
                          • napi_default_jsproperty: Like a property set via assignment in JavaScript,\nthe property is writable, enumerable, and configurable.
                          • \n
                          ", "type": "module", "displayName": "napi_property_attributes" }, { "textRaw": "napi_property_descriptor", "name": "napi_property_descriptor", - "desc": "
                          typedef struct {\n  // One of utf8name or name should be NULL.\n  const char* utf8name;\n  napi_value name;\n\n  napi_callback method;\n  napi_callback getter;\n  napi_callback setter;\n  napi_value value;\n\n  napi_property_attributes attributes;\n  void* data;\n} napi_property_descriptor;\n
                          \n
                            \n
                          • utf8name: Optional String describing the key for the property,\nencoded as UTF8. One of utf8name or name must be provided for the\nproperty.
                          • \n
                          • name: Optional napi_value that points to a JavaScript string or symbol\nto be used as the key for the property. One of utf8name or name must\nbe provided for the property.
                          • \n
                          • value: The value that's retrieved by a get access of the property if the\nproperty is a data property. If this is passed in, set getter, setter,\nmethod and data to NULL (since these members won't be used).
                          • \n
                          • getter: A function to call when a get access of the property is performed.\nIf this is passed in, set value and method to NULL (since these members\nwon't be used). The given function is called implicitly by the runtime when\nthe property is accessed from JavaScript code (or if a get on the property is\nperformed using a N-API call). napi_callback provides more details.
                          • \n
                          • setter: A function to call when a set access of the property is performed.\nIf this is passed in, set value and method to NULL (since these members\nwon't be used). The given function is called implicitly by the runtime when\nthe property is set from JavaScript code (or if a set on the property is\nperformed using a N-API call). napi_callback provides more details.
                          • \n
                          • method: Set this to make the property descriptor object's value\nproperty to be a JavaScript function represented by method. If this is\npassed in, set value, getter and setter to NULL (since these members\nwon't be used). napi_callback provides more details.
                          • \n
                          • attributes: The attributes associated with the particular property. See\nnapi_property_attributes.
                          • \n
                          • data: The callback data passed into method, getter and setter if this\nfunction is invoked.
                          • \n
                          ", + "desc": "
                          typedef struct {\n  // One of utf8name or name should be NULL.\n  const char* utf8name;\n  napi_value name;\n\n  napi_callback method;\n  napi_callback getter;\n  napi_callback setter;\n  napi_value value;\n\n  napi_property_attributes attributes;\n  void* data;\n} napi_property_descriptor;\n
                          \n
                            \n
                          • utf8name: Optional string describing the key for the property,\nencoded as UTF8. One of utf8name or name must be provided for the\nproperty.
                          • \n
                          • name: Optional napi_value that points to a JavaScript string or symbol\nto be used as the key for the property. One of utf8name or name must\nbe provided for the property.
                          • \n
                          • value: The value that's retrieved by a get access of the property if the\nproperty is a data property. If this is passed in, set getter, setter,\nmethod and data to NULL (since these members won't be used).
                          • \n
                          • getter: A function to call when a get access of the property is performed.\nIf this is passed in, set value and method to NULL (since these members\nwon't be used). The given function is called implicitly by the runtime when\nthe property is accessed from JavaScript code (or if a get on the property is\nperformed using a Node-API call). napi_callback provides more details.
                          • \n
                          • setter: A function to call when a set access of the property is performed.\nIf this is passed in, set value and method to NULL (since these members\nwon't be used). The given function is called implicitly by the runtime when\nthe property is set from JavaScript code (or if a set on the property is\nperformed using a Node-API call). napi_callback provides more details.
                          • \n
                          • method: Set this to make the property descriptor object's value\nproperty to be a JavaScript function represented by method. If this is\npassed in, set value, getter and setter to NULL (since these members\nwon't be used). napi_callback provides more details.
                          • \n
                          • attributes: The attributes associated with the particular property. See\nnapi_property_attributes.
                          • \n
                          • data: The callback data passed into method, getter and setter if this\nfunction is invoked.
                          • \n
                          ", "type": "module", "displayName": "napi_property_descriptor" } @@ -2127,7 +2141,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_property_names(napi_env env,\n                                    napi_value object,\n                                    napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the properties.
                          • \n
                          • [out] result: A napi_value representing an array of JavaScript values\nthat represent the property names of the object. The API can be used to\niterate over result using napi_get_array_length\nand napi_get_element.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns the names of the enumerable properties of object as an array\nof strings. The properties of object whose key is a symbol will not be\nincluded.

                          ", + "desc": "
                          napi_status napi_get_property_names(napi_env env,\n                                    napi_value object,\n                                    napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the properties.
                          • \n
                          • [out] result: A napi_value representing an array of JavaScript values\nthat represent the property names of the object. The API can be used to\niterate over result using napi_get_array_length\nand napi_get_element.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns the names of the enumerable properties of object as an array\nof strings. The properties of object whose key is a symbol will not be\nincluded.

                          ", "type": "module", "displayName": "napi_get_property_names" }, @@ -2136,14 +2150,15 @@ "name": "napi_get_all_property_names", "meta": { "added": [ - "v12.17.0" + "v13.7.0", + "v10.20.0" ], "napiVersion": [ 6 ], "changes": [] }, - "desc": "
                          napi_get_all_property_names(napi_env env,\n                            napi_value object,\n                            napi_key_collection_mode key_mode,\n                            napi_key_filter key_filter,\n                            napi_key_conversion key_conversion,\n                            napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the properties.
                          • \n
                          • [in] key_mode: Whether to retrieve prototype properties as well.
                          • \n
                          • [in] key_filter: Which properties to retrieve\n(enumerable/readable/writable).
                          • \n
                          • [in] key_conversion: Whether to convert numbered property keys to strings.
                          • \n
                          • [out] result: A napi_value representing an array of JavaScript values\nthat represent the property names of the object. napi_get_array_length and\nnapi_get_element can be used to iterate over result.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns an array containing the names of the available properties\nof this object.

                          ", + "desc": "
                          napi_get_all_property_names(napi_env env,\n                            napi_value object,\n                            napi_key_collection_mode key_mode,\n                            napi_key_filter key_filter,\n                            napi_key_conversion key_conversion,\n                            napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the properties.
                          • \n
                          • [in] key_mode: Whether to retrieve prototype properties as well.
                          • \n
                          • [in] key_filter: Which properties to retrieve\n(enumerable/readable/writable).
                          • \n
                          • [in] key_conversion: Whether to convert numbered property keys to strings.
                          • \n
                          • [out] result: A napi_value representing an array of JavaScript values\nthat represent the property names of the object. napi_get_array_length\nand napi_get_element can be used to iterate over result.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns an array containing the names of the available properties\nof this object.

                          ", "type": "module", "displayName": "napi_get_all_property_names" }, @@ -2159,7 +2174,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_set_property(napi_env env,\n                              napi_value object,\n                              napi_value key,\n                              napi_value value);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object on which to set the property.
                          • \n
                          • [in] key: The name of the property to set.
                          • \n
                          • [in] value: The property value.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API set a property on the Object passed in.

                          ", + "desc": "
                          napi_status napi_set_property(napi_env env,\n                              napi_value object,\n                              napi_value key,\n                              napi_value value);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object on which to set the property.
                          • \n
                          • [in] key: The name of the property to set.
                          • \n
                          • [in] value: The property value.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API set a property on the Object passed in.

                          ", "type": "module", "displayName": "napi_set_property" }, @@ -2175,7 +2190,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_property(napi_env env,\n                              napi_value object,\n                              napi_value key,\n                              napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the property.
                          • \n
                          • [in] key: The name of the property to retrieve.
                          • \n
                          • [out] result: The value of the property.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API gets the requested property from the Object passed in.

                          ", + "desc": "
                          napi_status napi_get_property(napi_env env,\n                              napi_value object,\n                              napi_value key,\n                              napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the property.
                          • \n
                          • [in] key: The name of the property to retrieve.
                          • \n
                          • [out] result: The value of the property.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API gets the requested property from the Object passed in.

                          ", "type": "module", "displayName": "napi_get_property" }, @@ -2191,7 +2206,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_has_property(napi_env env,\n                              napi_value object,\n                              napi_value key,\n                              bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] key: The name of the property whose existence to check.
                          • \n
                          • [out] result: Whether the property exists on the object or not.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API checks if the Object passed in has the named property.

                          ", + "desc": "
                          napi_status napi_has_property(napi_env env,\n                              napi_value object,\n                              napi_value key,\n                              bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] key: The name of the property whose existence to check.
                          • \n
                          • [out] result: Whether the property exists on the object or not.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API checks if the Object passed in has the named property.

                          ", "type": "module", "displayName": "napi_has_property" }, @@ -2207,7 +2222,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_delete_property(napi_env env,\n                                 napi_value object,\n                                 napi_value key,\n                                 bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] key: The name of the property to delete.
                          • \n
                          • [out] result: Whether the property deletion succeeded or not. result can\noptionally be ignored by passing NULL.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API attempts to delete the key own property from object.

                          ", + "desc": "
                          napi_status napi_delete_property(napi_env env,\n                                 napi_value object,\n                                 napi_value key,\n                                 bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] key: The name of the property to delete.
                          • \n
                          • [out] result: Whether the property deletion succeeded or not. result can\noptionally be ignored by passing NULL.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API attempts to delete the key own property from object.

                          ", "type": "module", "displayName": "napi_delete_property" }, @@ -2223,7 +2238,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_has_own_property(napi_env env,\n                                  napi_value object,\n                                  napi_value key,\n                                  bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] key: The name of the own property whose existence to check.
                          • \n
                          • [out] result: Whether the own property exists on the object or not.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API checks if the Object passed in has the named own property. key must\nbe a string or a Symbol, or an error will be thrown. N-API will not perform\nany conversion between data types.

                          ", + "desc": "
                          napi_status napi_has_own_property(napi_env env,\n                                  napi_value object,\n                                  napi_value key,\n                                  bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] key: The name of the own property whose existence to check.
                          • \n
                          • [out] result: Whether the own property exists on the object or not.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API checks if the Object passed in has the named own property. key must\nbe a string or a symbol, or an error will be thrown. Node-API will not\nperform any conversion between data types.

                          ", "type": "module", "displayName": "napi_has_own_property" }, @@ -2239,7 +2254,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_set_named_property(napi_env env,\n                                    napi_value object,\n                                    const char* utf8Name,\n                                    napi_value value);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object on which to set the property.
                          • \n
                          • [in] utf8Name: The name of the property to set.
                          • \n
                          • [in] value: The property value.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method is equivalent to calling napi_set_property with a napi_value\ncreated from the string passed in as utf8Name.

                          ", + "desc": "
                          napi_status napi_set_named_property(napi_env env,\n                                    napi_value object,\n                                    const char* utf8Name,\n                                    napi_value value);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object on which to set the property.
                          • \n
                          • [in] utf8Name: The name of the property to set.
                          • \n
                          • [in] value: The property value.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method is equivalent to calling napi_set_property with a napi_value\ncreated from the string passed in as utf8Name.

                          ", "type": "module", "displayName": "napi_set_named_property" }, @@ -2255,7 +2270,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_named_property(napi_env env,\n                                    napi_value object,\n                                    const char* utf8Name,\n                                    napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the property.
                          • \n
                          • [in] utf8Name: The name of the property to get.
                          • \n
                          • [out] result: The value of the property.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method is equivalent to calling napi_get_property with a napi_value\ncreated from the string passed in as utf8Name.

                          ", + "desc": "
                          napi_status napi_get_named_property(napi_env env,\n                                    napi_value object,\n                                    const char* utf8Name,\n                                    napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the property.
                          • \n
                          • [in] utf8Name: The name of the property to get.
                          • \n
                          • [out] result: The value of the property.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method is equivalent to calling napi_get_property with a napi_value\ncreated from the string passed in as utf8Name.

                          ", "type": "module", "displayName": "napi_get_named_property" }, @@ -2271,7 +2286,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_has_named_property(napi_env env,\n                                    napi_value object,\n                                    const char* utf8Name,\n                                    bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] utf8Name: The name of the property whose existence to check.
                          • \n
                          • [out] result: Whether the property exists on the object or not.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method is equivalent to calling napi_has_property with a napi_value\ncreated from the string passed in as utf8Name.

                          ", + "desc": "
                          napi_status napi_has_named_property(napi_env env,\n                                    napi_value object,\n                                    const char* utf8Name,\n                                    bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] utf8Name: The name of the property whose existence to check.
                          • \n
                          • [out] result: Whether the property exists on the object or not.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method is equivalent to calling napi_has_property with a napi_value\ncreated from the string passed in as utf8Name.

                          ", "type": "module", "displayName": "napi_has_named_property" }, @@ -2287,7 +2302,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_set_element(napi_env env,\n                             napi_value object,\n                             uint32_t index,\n                             napi_value value);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object from which to set the properties.
                          • \n
                          • [in] index: The index of the property to set.
                          • \n
                          • [in] value: The property value.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API sets and element on the Object passed in.

                          ", + "desc": "
                          napi_status napi_set_element(napi_env env,\n                             napi_value object,\n                             uint32_t index,\n                             napi_value value);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object from which to set the properties.
                          • \n
                          • [in] index: The index of the property to set.
                          • \n
                          • [in] value: The property value.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API sets and element on the Object passed in.

                          ", "type": "module", "displayName": "napi_set_element" }, @@ -2303,7 +2318,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_element(napi_env env,\n                             napi_value object,\n                             uint32_t index,\n                             napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the property.
                          • \n
                          • [in] index: The index of the property to get.
                          • \n
                          • [out] result: The value of the property.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API gets the element at the requested index.

                          ", + "desc": "
                          napi_status napi_get_element(napi_env env,\n                             napi_value object,\n                             uint32_t index,\n                             napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the property.
                          • \n
                          • [in] index: The index of the property to get.
                          • \n
                          • [out] result: The value of the property.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API gets the element at the requested index.

                          ", "type": "module", "displayName": "napi_get_element" }, @@ -2319,7 +2334,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_has_element(napi_env env,\n                             napi_value object,\n                             uint32_t index,\n                             bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] index: The index of the property whose existence to check.
                          • \n
                          • [out] result: Whether the property exists on the object or not.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns if the Object passed in has an element at the\nrequested index.

                          ", + "desc": "
                          napi_status napi_has_element(napi_env env,\n                             napi_value object,\n                             uint32_t index,\n                             bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] index: The index of the property whose existence to check.
                          • \n
                          • [out] result: Whether the property exists on the object or not.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns if the Object passed in has an element at the\nrequested index.

                          ", "type": "module", "displayName": "napi_has_element" }, @@ -2335,7 +2350,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_delete_element(napi_env env,\n                                napi_value object,\n                                uint32_t index,\n                                bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] index: The index of the property to delete.
                          • \n
                          • [out] result: Whether the element deletion succeeded or not. result can\noptionally be ignored by passing NULL.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API attempts to delete the specified index from object.

                          ", + "desc": "
                          napi_status napi_delete_element(napi_env env,\n                                napi_value object,\n                                uint32_t index,\n                                bool* result);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object to query.
                          • \n
                          • [in] index: The index of the property to delete.
                          • \n
                          • [out] result: Whether the element deletion succeeded or not. result can\noptionally be ignored by passing NULL.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API attempts to delete the specified index from object.

                          ", "type": "module", "displayName": "napi_delete_element" }, @@ -2351,7 +2366,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_define_properties(napi_env env,\n                                   napi_value object,\n                                   size_t property_count,\n                                   const napi_property_descriptor* properties);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the properties.
                          • \n
                          • [in] property_count: The number of elements in the properties array.
                          • \n
                          • [in] properties: The array of property descriptors.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method allows the efficient definition of multiple properties on a given\nobject. The properties are defined using property descriptors (see\nnapi_property_descriptor). Given an array of such property descriptors,\nthis API will set the properties on the object one at a time, as defined by\nDefineOwnProperty() (described in Section 9.1.6 of the ECMA-262\nspecification).

                          ", + "desc": "
                          napi_status napi_define_properties(napi_env env,\n                                   napi_value object,\n                                   size_t property_count,\n                                   const napi_property_descriptor* properties);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object from which to retrieve the properties.
                          • \n
                          • [in] property_count: The number of elements in the properties array.
                          • \n
                          • [in] properties: The array of property descriptors.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method allows the efficient definition of multiple properties on a given\nobject. The properties are defined using property descriptors (see\nnapi_property_descriptor). Given an array of such property descriptors,\nthis API will set the properties on the object one at a time, as defined by\nDefineOwnProperty() (described in Section 9.1.6 of the ECMA-262\nspecification).

                          ", "type": "module", "displayName": "napi_define_properties" }, @@ -2360,6 +2375,7 @@ "name": "napi_object_freeze", "meta": { "added": [ + "v14.14.0", "v12.20.0" ], "napiVersion": [ @@ -2367,7 +2383,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_object_freeze(napi_env env,\n                               napi_value object);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object to freeze.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method freezes a given object. This prevents new properties from\nbeing added to it, existing properties from being removed, prevents\nchanging the enumerability, configurability, or writability of existing\nproperties, and prevents the values of existing properties from being changed.\nIt also prevents the object's prototype from being changed. This is described\nin Section 19.1.2.6 of the\nECMA-262 specification.

                          ", + "desc": "
                          napi_status napi_object_freeze(napi_env env,\n                               napi_value object);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object to freeze.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method freezes a given object. This prevents new properties from\nbeing added to it, existing properties from being removed, prevents\nchanging the enumerability, configurability, or writability of existing\nproperties, and prevents the values of existing properties from being changed.\nIt also prevents the object's prototype from being changed. This is described\nin Section 19.1.2.6 of the\nECMA-262 specification.

                          ", "type": "module", "displayName": "napi_object_freeze" }, @@ -2376,6 +2392,7 @@ "name": "napi_object_seal", "meta": { "added": [ + "v14.14.0", "v12.20.0" ], "napiVersion": [ @@ -2383,7 +2400,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_object_seal(napi_env env,\n                             napi_value object);\n
                          \n
                            \n
                          • [in] env: The environment that the N-API call is invoked under.
                          • \n
                          • [in] object: The object to seal.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method seals a given object. This prevents new properties from being\nadded to it, as well as marking all existing properties as non-configurable.\nThis is described in Section 19.1.2.20\nof the ECMA-262 specification.

                          ", + "desc": "
                          napi_status napi_object_seal(napi_env env,\n                             napi_value object);\n
                          \n
                            \n
                          • [in] env: The environment that the Node-API call is invoked under.
                          • \n
                          • [in] object: The object to seal.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method seals a given object. This prevents new properties from being\nadded to it, as well as marking all existing properties as non-configurable.\nThis is described in Section 19.1.2.20\nof the ECMA-262 specification.

                          ", "type": "module", "displayName": "napi_object_seal" } @@ -2398,7 +2415,7 @@ { "textRaw": "Working with JavaScript functions", "name": "working_with_javascript_functions", - "desc": "

                          N-API provides a set of APIs that allow JavaScript code to\ncall back into native code. N-API APIs that support calling back\ninto native code take in a callback functions represented by\nthe napi_callback type. When the JavaScript VM calls back to\nnative code, the napi_callback function provided is invoked. The APIs\ndocumented in this section allow the callback function to do the\nfollowing:

                          \n
                            \n
                          • Get information about the context in which the callback was invoked.
                          • \n
                          • Get the arguments passed into the callback.
                          • \n
                          • Return a napi_value back from the callback.
                          • \n
                          \n

                          Additionally, N-API provides a set of functions which allow calling\nJavaScript functions from native code. One can either call a function\nlike a regular JavaScript function call, or as a constructor\nfunction.

                          \n

                          Any non-NULL data which is passed to this API via the data field of the\nnapi_property_descriptor items can be associated with object and freed\nwhenever object is garbage-collected by passing both object and the data to\nnapi_add_finalizer.

                          ", + "desc": "

                          Node-API provides a set of APIs that allow JavaScript code to\ncall back into native code. Node-APIs that support calling back\ninto native code take in a callback functions represented by\nthe napi_callback type. When the JavaScript VM calls back to\nnative code, the napi_callback function provided is invoked. The APIs\ndocumented in this section allow the callback function to do the\nfollowing:

                          \n
                            \n
                          • Get information about the context in which the callback was invoked.
                          • \n
                          • Get the arguments passed into the callback.
                          • \n
                          • Return a napi_value back from the callback.
                          • \n
                          \n

                          Additionally, Node-API provides a set of functions which allow calling\nJavaScript functions from native code. One can either call a function\nlike a regular JavaScript function call, or as a constructor\nfunction.

                          \n

                          Any non-NULL data which is passed to this API via the data field of the\nnapi_property_descriptor items can be associated with object and freed\nwhenever object is garbage-collected by passing both object and the data to\nnapi_add_finalizer.

                          ", "modules": [ { "textRaw": "napi_call_function", @@ -2412,7 +2429,7 @@ ], "changes": [] }, - "desc": "
                          NAPI_EXTERN napi_status napi_call_function(napi_env env,\n                                           napi_value recv,\n                                           napi_value func,\n                                           size_t argc,\n                                           const napi_value* argv,\n                                           napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] recv: The this object passed to the called function.
                          • \n
                          • [in] func: napi_value representing the JavaScript function to be invoked.
                          • \n
                          • [in] argc: The count of elements in the argv array.
                          • \n
                          • [in] argv: Array of napi_values representing JavaScript values passed in\nas arguments to the function.
                          • \n
                          • [out] result: napi_value representing the JavaScript object returned.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method allows a JavaScript function object to be called from a native\nadd-on. This is the primary mechanism of calling back from the add-on's\nnative code into JavaScript. For the special case of calling into JavaScript\nafter an async operation, see napi_make_callback.

                          \n

                          A sample use case might look as follows. Consider the following JavaScript\nsnippet:

                          \n
                          function AddTwo(num) {\n  return num + 2;\n}\n
                          \n

                          Then, the above function can be invoked from a native add-on using the\nfollowing code:

                          \n
                          // Get the function named \"AddTwo\" on the global object\nnapi_value global, add_two, arg;\nnapi_status status = napi_get_global(env, &global);\nif (status != napi_ok) return;\n\nstatus = napi_get_named_property(env, global, \"AddTwo\", &add_two);\nif (status != napi_ok) return;\n\n// const arg = 1337\nstatus = napi_create_int32(env, 1337, &arg);\nif (status != napi_ok) return;\n\nnapi_value* argv = &arg;\nsize_t argc = 1;\n\n// AddTwo(arg);\nnapi_value return_val;\nstatus = napi_call_function(env, global, add_two, argc, argv, &return_val);\nif (status != napi_ok) return;\n\n// Convert the result back to a native type\nint32_t result;\nstatus = napi_get_value_int32(env, return_val, &result);\nif (status != napi_ok) return;\n
                          ", + "desc": "
                          NAPI_EXTERN napi_status napi_call_function(napi_env env,\n                                           napi_value recv,\n                                           napi_value func,\n                                           size_t argc,\n                                           const napi_value* argv,\n                                           napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] recv: The this value passed to the called function.
                          • \n
                          • [in] func: napi_value representing the JavaScript function to be invoked.
                          • \n
                          • [in] argc: The count of elements in the argv array.
                          • \n
                          • [in] argv: Array of napi_values representing JavaScript values passed in\nas arguments to the function.
                          • \n
                          • [out] result: napi_value representing the JavaScript object returned.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method allows a JavaScript function object to be called from a native\nadd-on. This is the primary mechanism of calling back from the add-on's\nnative code into JavaScript. For the special case of calling into JavaScript\nafter an async operation, see napi_make_callback.

                          \n

                          A sample use case might look as follows. Consider the following JavaScript\nsnippet:

                          \n
                          function AddTwo(num) {\n  return num + 2;\n}\n
                          \n

                          Then, the above function can be invoked from a native add-on using the\nfollowing code:

                          \n
                          // Get the function named \"AddTwo\" on the global object\nnapi_value global, add_two, arg;\nnapi_status status = napi_get_global(env, &global);\nif (status != napi_ok) return;\n\nstatus = napi_get_named_property(env, global, \"AddTwo\", &add_two);\nif (status != napi_ok) return;\n\n// const arg = 1337\nstatus = napi_create_int32(env, 1337, &arg);\nif (status != napi_ok) return;\n\nnapi_value* argv = &arg;\nsize_t argc = 1;\n\n// AddTwo(arg);\nnapi_value return_val;\nstatus = napi_call_function(env, global, add_two, argc, argv, &return_val);\nif (status != napi_ok) return;\n\n// Convert the result back to a native type\nint32_t result;\nstatus = napi_get_value_int32(env, return_val, &result);\nif (status != napi_ok) return;\n
                          ", "type": "module", "displayName": "napi_call_function" }, @@ -2444,7 +2461,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_cb_info(napi_env env,\n                             napi_callback_info cbinfo,\n                             size_t* argc,\n                             napi_value* argv,\n                             napi_value* thisArg,\n                             void** data)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] cbinfo: The callback info passed into the callback function.
                          • \n
                          • [in-out] argc: Specifies the size of the provided argv array and receives\nthe actual count of arguments.
                          • \n
                          • [out] argv: Buffer to which the napi_value representing the arguments are\ncopied. If there are more arguments than the provided count, only the\nrequested number of arguments are copied. If there are fewer arguments\nprovided than claimed, the rest of argv is filled with napi_value values\nthat represent undefined.
                          • \n
                          • [out] this: Receives the JavaScript this argument for the call.
                          • \n
                          • [out] data: Receives the data pointer for the callback.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method is used within a callback function to retrieve details about the\ncall like the arguments and the this pointer from a given callback info.

                          ", + "desc": "
                          napi_status napi_get_cb_info(napi_env env,\n                             napi_callback_info cbinfo,\n                             size_t* argc,\n                             napi_value* argv,\n                             napi_value* thisArg,\n                             void** data)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] cbinfo: The callback info passed into the callback function.
                          • \n
                          • [in-out] argc: Specifies the length of the provided argv array and\nreceives the actual count of arguments.
                          • \n
                          • [out] argv: Buffer to which the napi_value representing the arguments are\ncopied. If there are more arguments than the provided count, only the\nrequested number of arguments are copied. If there are fewer arguments\nprovided than claimed, the rest of argv is filled with napi_value values\nthat represent undefined.
                          • \n
                          • [out] this: Receives the JavaScript this argument for the call.
                          • \n
                          • [out] data: Receives the data pointer for the callback.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method is used within a callback function to retrieve details about the\ncall like the arguments and the this pointer from a given callback info.

                          ", "type": "module", "displayName": "napi_get_cb_info" }, @@ -2476,7 +2493,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_new_instance(napi_env env,\n                              napi_value cons,\n                              size_t argc,\n                              napi_value* argv,\n                              napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] cons: napi_value representing the JavaScript function to be invoked\nas a constructor.
                          • \n
                          • [in] argc: The count of elements in the argv array.
                          • \n
                          • [in] argv: Array of JavaScript values as napi_value representing the\narguments to the constructor.
                          • \n
                          • [out] result: napi_value representing the JavaScript object returned,\nwhich in this case is the constructed object.
                          • \n
                          \n

                          This method is used to instantiate a new JavaScript value using a given\nnapi_value that represents the constructor for the object. For example,\nconsider the following snippet:

                          \n
                          function MyObject(param) {\n  this.param = param;\n}\n\nconst arg = 'hello';\nconst value = new MyObject(arg);\n
                          \n

                          The following can be approximated in N-API using the following snippet:

                          \n
                          // Get the constructor function MyObject\nnapi_value global, constructor, arg, value;\nnapi_status status = napi_get_global(env, &global);\nif (status != napi_ok) return;\n\nstatus = napi_get_named_property(env, global, \"MyObject\", &constructor);\nif (status != napi_ok) return;\n\n// const arg = \"hello\"\nstatus = napi_create_string_utf8(env, \"hello\", NAPI_AUTO_LENGTH, &arg);\nif (status != napi_ok) return;\n\nnapi_value* argv = &arg;\nsize_t argc = 1;\n\n// const value = new MyObject(arg)\nstatus = napi_new_instance(env, constructor, argc, argv, &value);\n
                          \n

                          Returns napi_ok if the API succeeded.

                          ", + "desc": "
                          napi_status napi_new_instance(napi_env env,\n                              napi_value cons,\n                              size_t argc,\n                              napi_value* argv,\n                              napi_value* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] cons: napi_value representing the JavaScript function to be invoked\nas a constructor.
                          • \n
                          • [in] argc: The count of elements in the argv array.
                          • \n
                          • [in] argv: Array of JavaScript values as napi_value representing the\narguments to the constructor.
                          • \n
                          • [out] result: napi_value representing the JavaScript object returned,\nwhich in this case is the constructed object.
                          • \n
                          \n

                          This method is used to instantiate a new JavaScript value using a given\nnapi_value that represents the constructor for the object. For example,\nconsider the following snippet:

                          \n
                          function MyObject(param) {\n  this.param = param;\n}\n\nconst arg = 'hello';\nconst value = new MyObject(arg);\n
                          \n

                          The following can be approximated in Node-API using the following snippet:

                          \n
                          // Get the constructor function MyObject\nnapi_value global, constructor, arg, value;\nnapi_status status = napi_get_global(env, &global);\nif (status != napi_ok) return;\n\nstatus = napi_get_named_property(env, global, \"MyObject\", &constructor);\nif (status != napi_ok) return;\n\n// const arg = \"hello\"\nstatus = napi_create_string_utf8(env, \"hello\", NAPI_AUTO_LENGTH, &arg);\nif (status != napi_ok) return;\n\nnapi_value* argv = &arg;\nsize_t argc = 1;\n\n// const value = new MyObject(arg)\nstatus = napi_new_instance(env, constructor, argc, argv, &value);\n
                          \n

                          Returns napi_ok if the API succeeded.

                          ", "type": "module", "displayName": "napi_new_instance" } @@ -2487,7 +2504,7 @@ { "textRaw": "Object wrap", "name": "object_wrap", - "desc": "

                          N-API offers a way to \"wrap\" C++ classes and instances so that the class\nconstructor and methods can be called from JavaScript.

                          \n
                            \n
                          1. The napi_define_class API defines a JavaScript class with constructor,\nstatic properties and methods, and instance properties and methods that\ncorrespond to the C++ class.
                          2. \n
                          3. When JavaScript code invokes the constructor, the constructor callback\nuses napi_wrap to wrap a new C++ instance in a JavaScript object,\nthen returns the wrapper object.
                          4. \n
                          5. When JavaScript code invokes a method or property accessor on the class,\nthe corresponding napi_callback C++ function is invoked. For an instance\ncallback, napi_unwrap obtains the C++ instance that is the target of\nthe call.
                          6. \n
                          \n

                          For wrapped objects it may be difficult to distinguish between a function\ncalled on a class prototype and a function called on an instance of a class.\nA common pattern used to address this problem is to save a persistent\nreference to the class constructor for later instanceof checks.

                          \n
                          napi_value MyClass_constructor = NULL;\nstatus = napi_get_reference_value(env, MyClass::es_constructor, &MyClass_constructor);\nassert(napi_ok == status);\nbool is_instance = false;\nstatus = napi_instanceof(env, es_this, MyClass_constructor, &is_instance);\nassert(napi_ok == status);\nif (is_instance) {\n  // napi_unwrap() ...\n} else {\n  // otherwise...\n}\n
                          \n

                          The reference must be freed once it is no longer needed.

                          \n

                          There are occasions where napi_instanceof() is insufficient for ensuring that\na JavaScript object is a wrapper for a certain native type. This is the case\nespecially when wrapped JavaScript objects are passed back into the addon via\nstatic methods rather than as the this value of prototype methods. In such\ncases there is a chance that they may be unwrapped incorrectly.

                          \n
                          const myAddon = require('./build/Release/my_addon.node');\n\n// `openDatabase()` returns a JavaScript object that wraps a native database\n// handle.\nconst dbHandle = myAddon.openDatabase();\n\n// `query()` returns a JavaScript object that wraps a native query handle.\nconst queryHandle = myAddon.query(dbHandle, 'Gimme ALL the things!');\n\n// There is an accidental error in the line below. The first parameter to\n// `myAddon.queryHasRecords()` should be the database handle (`dbHandle`), not\n// the query handle (`query`), so the correct condition for the while-loop\n// should be\n//\n// myAddon.queryHasRecords(dbHandle, queryHandle)\n//\nwhile (myAddon.queryHasRecords(queryHandle, dbHandle)) {\n  // retrieve records\n}\n
                          \n

                          In the above example myAddon.queryHasRecords() is a method that accepts two\narguments. The first is a database handle and the second is a query handle.\nInternally, it unwraps the first argument and casts the resulting pointer to a\nnative database handle. It then unwraps the second argument and casts the\nresulting pointer to a query handle. If the arguments are passed in the wrong\norder, the casts will work, however, there is a good chance that the underlying\ndatabase operation will fail, or will even cause an invalid memory access.

                          \n

                          To ensure that the pointer retrieved from the first argument is indeed a pointer\nto a database handle and, similarly, that the pointer retrieved from the second\nargument is indeed a pointer to a query handle, the implementation of\nqueryHasRecords() has to perform a type validation. Retaining the JavaScript\nclass constructor from which the database handle was instantiated and the\nconstructor from which the query handle was instantiated in napi_refs can\nhelp, because napi_instanceof() can then be used to ensure that the instances\npassed into queryHashRecords() are indeed of the correct type.

                          \n

                          Unfortunately, napi_instanceof() does not protect against prototype\nmanipulation. For example, the prototype of the database handle instance can be\nset to the prototype of the constructor for query handle instances. In this\ncase, the database handle instance can appear as a query handle instance, and it\nwill pass the napi_instanceof() test for a query handle instance, while still\ncontaining a pointer to a database handle.

                          \n

                          To this end, N-API provides type-tagging capabilities.

                          \n

                          A type tag is a 128-bit integer unique to the addon. N-API provides the\nnapi_type_tag structure for storing a type tag. When such a value is passed\nalong with a JavaScript object stored in a napi_value to\nnapi_type_tag_object(), the JavaScript object will be \"marked\" with the\ntype tag. The \"mark\" is invisible on the JavaScript side. When a JavaScript\nobject arrives into a native binding, napi_check_object_type_tag() can be used\nalong with the original type tag to determine whether the JavaScript object was\npreviously \"marked\" with the type tag. This creates a type-checking capability\nof a higher fidelity than napi_instanceof() can provide, because such type-\ntagging survives prototype manipulation and addon unloading/reloading.

                          \n

                          Continuing the above example, the following skeleton addon implementation\nillustrates the use of napi_type_tag_object() and\nnapi_check_object_type_tag().

                          \n
                          // This value is the type tag for a database handle. The command\n//\n//   uuidgen | sed -r -e 's/-//g' -e 's/(.{16})(.*)/0x\\1, 0x\\2/'\n//\n// can be used to obtain the two values with which to initialize the structure.\nstatic const napi_type_tag DatabaseHandleTypeTag = {\n  0x1edf75a38336451d, 0xa5ed9ce2e4c00c38\n};\n\n// This value is the type tag for a query handle.\nstatic const napi_type_tag QueryHandleTypeTag = {\n  0x9c73317f9fad44a3, 0x93c3920bf3b0ad6a\n};\n\nstatic napi_value\nopenDatabase(napi_env env, napi_callback_info info) {\n  napi_status status;\n  napi_value result;\n\n  // Perform the underlying action which results in a database handle.\n  DatabaseHandle* dbHandle = open_database();\n\n  // Create a new, empty JS object.\n  status = napi_create_object(env, &result);\n  if (status != napi_ok) return NULL;\n\n  // Tag the object to indicate that it holds a pointer to a `DatabaseHandle`.\n  status = napi_type_tag_object(env, result, &DatabaseHandleTypeTag);\n  if (status != napi_ok) return NULL;\n\n  // Store the pointer to the `DatabaseHandle` structure inside the JS object.\n  status = napi_wrap(env, result, dbHandle, NULL, NULL, NULL);\n  if (status != napi_ok) return NULL;\n\n  return result;\n}\n\n// Later when we receive a JavaScript object purporting to be a database handle\n// we can use `napi_check_object_type_tag()` to ensure that it is indeed such a\n// handle.\n\nstatic napi_value\nquery(napi_env env, napi_callback_info info) {\n  napi_status status;\n  size_t argc = 2;\n  napi_value argv[2];\n  bool is_db_handle;\n\n  status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);\n  if (status != napi_ok) return NULL;\n\n  // Check that the object passed as the first parameter has the previously\n  // applied tag.\n  status = napi_check_object_type_tag(env,\n                                      argv[0],\n                                      &DatabaseHandleTypeTag,\n                                      &is_db_handle);\n  if (status != napi_ok) return NULL;\n\n  // Throw a `TypeError` if it doesn't.\n  if (!is_db_handle) {\n    // Throw a TypeError.\n    return NULL;\n  }\n}\n
                          ", + "desc": "

                          Node-API offers a way to \"wrap\" C++ classes and instances so that the class\nconstructor and methods can be called from JavaScript.

                          \n
                            \n
                          1. The napi_define_class API defines a JavaScript class with constructor,\nstatic properties and methods, and instance properties and methods that\ncorrespond to the C++ class.
                          2. \n
                          3. When JavaScript code invokes the constructor, the constructor callback\nuses napi_wrap to wrap a new C++ instance in a JavaScript object,\nthen returns the wrapper object.
                          4. \n
                          5. When JavaScript code invokes a method or property accessor on the class,\nthe corresponding napi_callback C++ function is invoked. For an instance\ncallback, napi_unwrap obtains the C++ instance that is the target of\nthe call.
                          6. \n
                          \n

                          For wrapped objects it may be difficult to distinguish between a function\ncalled on a class prototype and a function called on an instance of a class.\nA common pattern used to address this problem is to save a persistent\nreference to the class constructor for later instanceof checks.

                          \n
                          napi_value MyClass_constructor = NULL;\nstatus = napi_get_reference_value(env, MyClass::es_constructor, &MyClass_constructor);\nassert(napi_ok == status);\nbool is_instance = false;\nstatus = napi_instanceof(env, es_this, MyClass_constructor, &is_instance);\nassert(napi_ok == status);\nif (is_instance) {\n  // napi_unwrap() ...\n} else {\n  // otherwise...\n}\n
                          \n

                          The reference must be freed once it is no longer needed.

                          \n

                          There are occasions where napi_instanceof() is insufficient for ensuring that\na JavaScript object is a wrapper for a certain native type. This is the case\nespecially when wrapped JavaScript objects are passed back into the addon via\nstatic methods rather than as the this value of prototype methods. In such\ncases there is a chance that they may be unwrapped incorrectly.

                          \n
                          const myAddon = require('./build/Release/my_addon.node');\n\n// `openDatabase()` returns a JavaScript object that wraps a native database\n// handle.\nconst dbHandle = myAddon.openDatabase();\n\n// `query()` returns a JavaScript object that wraps a native query handle.\nconst queryHandle = myAddon.query(dbHandle, 'Gimme ALL the things!');\n\n// There is an accidental error in the line below. The first parameter to\n// `myAddon.queryHasRecords()` should be the database handle (`dbHandle`), not\n// the query handle (`query`), so the correct condition for the while-loop\n// should be\n//\n// myAddon.queryHasRecords(dbHandle, queryHandle)\n//\nwhile (myAddon.queryHasRecords(queryHandle, dbHandle)) {\n  // retrieve records\n}\n
                          \n

                          In the above example myAddon.queryHasRecords() is a method that accepts two\narguments. The first is a database handle and the second is a query handle.\nInternally, it unwraps the first argument and casts the resulting pointer to a\nnative database handle. It then unwraps the second argument and casts the\nresulting pointer to a query handle. If the arguments are passed in the wrong\norder, the casts will work, however, there is a good chance that the underlying\ndatabase operation will fail, or will even cause an invalid memory access.

                          \n

                          To ensure that the pointer retrieved from the first argument is indeed a pointer\nto a database handle and, similarly, that the pointer retrieved from the second\nargument is indeed a pointer to a query handle, the implementation of\nqueryHasRecords() has to perform a type validation. Retaining the JavaScript\nclass constructor from which the database handle was instantiated and the\nconstructor from which the query handle was instantiated in napi_refs can\nhelp, because napi_instanceof() can then be used to ensure that the instances\npassed into queryHashRecords() are indeed of the correct type.

                          \n

                          Unfortunately, napi_instanceof() does not protect against prototype\nmanipulation. For example, the prototype of the database handle instance can be\nset to the prototype of the constructor for query handle instances. In this\ncase, the database handle instance can appear as a query handle instance, and it\nwill pass the napi_instanceof() test for a query handle instance, while still\ncontaining a pointer to a database handle.

                          \n

                          To this end, Node-API provides type-tagging capabilities.

                          \n

                          A type tag is a 128-bit integer unique to the addon. Node-API provides the\nnapi_type_tag structure for storing a type tag. When such a value is passed\nalong with a JavaScript object stored in a napi_value to\nnapi_type_tag_object(), the JavaScript object will be \"marked\" with the\ntype tag. The \"mark\" is invisible on the JavaScript side. When a JavaScript\nobject arrives into a native binding, napi_check_object_type_tag() can be used\nalong with the original type tag to determine whether the JavaScript object was\npreviously \"marked\" with the type tag. This creates a type-checking capability\nof a higher fidelity than napi_instanceof() can provide, because such type-\ntagging survives prototype manipulation and addon unloading/reloading.

                          \n

                          Continuing the above example, the following skeleton addon implementation\nillustrates the use of napi_type_tag_object() and\nnapi_check_object_type_tag().

                          \n
                          // This value is the type tag for a database handle. The command\n//\n//   uuidgen | sed -r -e 's/-//g' -e 's/(.{16})(.*)/0x\\1, 0x\\2/'\n//\n// can be used to obtain the two values with which to initialize the structure.\nstatic const napi_type_tag DatabaseHandleTypeTag = {\n  0x1edf75a38336451d, 0xa5ed9ce2e4c00c38\n};\n\n// This value is the type tag for a query handle.\nstatic const napi_type_tag QueryHandleTypeTag = {\n  0x9c73317f9fad44a3, 0x93c3920bf3b0ad6a\n};\n\nstatic napi_value\nopenDatabase(napi_env env, napi_callback_info info) {\n  napi_status status;\n  napi_value result;\n\n  // Perform the underlying action which results in a database handle.\n  DatabaseHandle* dbHandle = open_database();\n\n  // Create a new, empty JS object.\n  status = napi_create_object(env, &result);\n  if (status != napi_ok) return NULL;\n\n  // Tag the object to indicate that it holds a pointer to a `DatabaseHandle`.\n  status = napi_type_tag_object(env, result, &DatabaseHandleTypeTag);\n  if (status != napi_ok) return NULL;\n\n  // Store the pointer to the `DatabaseHandle` structure inside the JS object.\n  status = napi_wrap(env, result, dbHandle, NULL, NULL, NULL);\n  if (status != napi_ok) return NULL;\n\n  return result;\n}\n\n// Later when we receive a JavaScript object purporting to be a database handle\n// we can use `napi_check_object_type_tag()` to ensure that it is indeed such a\n// handle.\n\nstatic napi_value\nquery(napi_env env, napi_callback_info info) {\n  napi_status status;\n  size_t argc = 2;\n  napi_value argv[2];\n  bool is_db_handle;\n\n  status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);\n  if (status != napi_ok) return NULL;\n\n  // Check that the object passed as the first parameter has the previously\n  // applied tag.\n  status = napi_check_object_type_tag(env,\n                                      argv[0],\n                                      &DatabaseHandleTypeTag,\n                                      &is_db_handle);\n  if (status != napi_ok) return NULL;\n\n  // Throw a `TypeError` if it doesn't.\n  if (!is_db_handle) {\n    // Throw a TypeError.\n    return NULL;\n  }\n}\n
                          ", "modules": [ { "textRaw": "napi_define_class", @@ -2501,7 +2518,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_define_class(napi_env env,\n                              const char* utf8name,\n                              size_t length,\n                              napi_callback constructor,\n                              void* data,\n                              size_t property_count,\n                              const napi_property_descriptor* properties,\n                              napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] utf8name: Name of the JavaScript constructor function; this is\nnot required to be the same as the C++ class name, though it is recommended\nfor clarity.
                          • \n
                          • [in] length: The length of the utf8name in bytes, or NAPI_AUTO_LENGTH\nif it is null-terminated.
                          • \n
                          • [in] constructor: Callback function that handles constructing instances\nof the class. This should be a static method on the class, not an actual\nC++ constructor function. napi_callback provides more details.
                          • \n
                          • [in] data: Optional data to be passed to the constructor callback as\nthe data property of the callback info.
                          • \n
                          • [in] property_count: Number of items in the properties array argument.
                          • \n
                          • [in] properties: Array of property descriptors describing static and\ninstance data properties, accessors, and methods on the class\nSee napi_property_descriptor.
                          • \n
                          • [out] result: A napi_value representing the constructor function for\nthe class.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          Defines a JavaScript class that corresponds to a C++ class, including:

                          \n
                            \n
                          • A JavaScript constructor function that has the class name and invokes the\nprovided C++ constructor callback.
                          • \n
                          • Properties on the constructor function corresponding to static data\nproperties, accessors, and methods of the C++ class (defined by\nproperty descriptors with the napi_static attribute).
                          • \n
                          • Properties on the constructor function's prototype object corresponding to\nnon-static data properties, accessors, and methods of the C++ class\n(defined by property descriptors without the napi_static attribute).
                          • \n
                          \n

                          The C++ constructor callback should be a static method on the class that calls\nthe actual class constructor, then wraps the new C++ instance in a JavaScript\nobject, and returns the wrapper object. See napi_wrap() for details.

                          \n

                          The JavaScript constructor function returned from napi_define_class is\noften saved and used later, to construct new instances of the class from native\ncode, and/or check whether provided values are instances of the class. In that\ncase, to prevent the function value from being garbage-collected, create a\npersistent reference to it using napi_create_reference and ensure the\nreference count is kept >= 1.

                          \n

                          Any non-NULL data which is passed to this API via the data parameter or via\nthe data field of the napi_property_descriptor array items can be associated\nwith the resulting JavaScript constructor (which is returned in the result\nparameter) and freed whenever the class is garbage-collected by passing both\nthe JavaScript function and the data to napi_add_finalizer.

                          ", + "desc": "
                          napi_status napi_define_class(napi_env env,\n                              const char* utf8name,\n                              size_t length,\n                              napi_callback constructor,\n                              void* data,\n                              size_t property_count,\n                              const napi_property_descriptor* properties,\n                              napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] utf8name: Name of the JavaScript constructor function; When wrapping a\nC++ class, we recommend for clarity that this name be the same as that of\nthe C++ class.
                          • \n
                          • [in] length: The length of the utf8name in bytes, or NAPI_AUTO_LENGTH\nif it is null-terminated.
                          • \n
                          • [in] constructor: Callback function that handles constructing instances\nof the class. When wrapping a C++ class, this method must be a static member\nwith the napi_callback signature. A C++ class constructor cannot be\nused. napi_callback provides more details.
                          • \n
                          • [in] data: Optional data to be passed to the constructor callback as\nthe data property of the callback info.
                          • \n
                          • [in] property_count: Number of items in the properties array argument.
                          • \n
                          • [in] properties: Array of property descriptors describing static and\ninstance data properties, accessors, and methods on the class\nSee napi_property_descriptor.
                          • \n
                          • [out] result: A napi_value representing the constructor function for\nthe class.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          Defines a JavaScript class, including:

                          \n
                            \n
                          • A JavaScript constructor function that has the class name. When wrapping a\ncorresponding C++ class, the callback passed via constructor can be used to\ninstantiate a new C++ class instance, which can then be placed inside the\nJavaScript object instance being constructed using napi_wrap.
                          • \n
                          • Properties on the constructor function whose implementation can call\ncorresponding static data properties, accessors, and methods of the C++\nclass (defined by property descriptors with the napi_static attribute).
                          • \n
                          • Properties on the constructor function's prototype object. When wrapping a\nC++ class, non-static data properties, accessors, and methods of the C++\nclass can be called from the static functions given in the property\ndescriptors without the napi_static attribute after retrieving the C++ class\ninstance placed inside the JavaScript object instance by using\nnapi_unwrap.
                          • \n
                          \n

                          When wrapping a C++ class, the C++ constructor callback passed via constructor\nshould be a static method on the class that calls the actual class constructor,\nthen wraps the new C++ instance in a JavaScript object, and returns the wrapper\nobject. See napi_wrap for details.

                          \n

                          The JavaScript constructor function returned from napi_define_class is\noften saved and used later to construct new instances of the class from native\ncode, and/or to check whether provided values are instances of the class. In\nthat case, to prevent the function value from being garbage-collected, a\nstrong persistent reference to it can be created using\nnapi_create_reference, ensuring that the reference count is kept >= 1.

                          \n

                          Any non-NULL data which is passed to this API via the data parameter or via\nthe data field of the napi_property_descriptor array items can be associated\nwith the resulting JavaScript constructor (which is returned in the result\nparameter) and freed whenever the class is garbage-collected by passing both\nthe JavaScript function and the data to napi_add_finalizer.

                          ", "type": "module", "displayName": "napi_define_class" }, @@ -2558,6 +2575,7 @@ "name": "napi_type_tag_object", "meta": { "added": [ + "v14.8.0", "v12.19.0" ], "napiVersion": [ @@ -2574,6 +2592,7 @@ "name": "napi_check_object_type_tag", "meta": { "added": [ + "v14.8.0", "v12.19.0" ], "napiVersion": [ @@ -2608,7 +2627,7 @@ { "textRaw": "Simple asynchronous operations", "name": "simple_asynchronous_operations", - "desc": "

                          Addon modules often need to leverage async helpers from libuv as part of their\nimplementation. This allows them to schedule work to be executed asynchronously\nso that their methods can return in advance of the work being completed. This\nallows them to avoid blocking overall execution of the Node.js application.

                          \n

                          N-API provides an ABI-stable interface for these\nsupporting functions which covers the most common asynchronous use cases.

                          \n

                          N-API defines the napi_async_work structure which is used to manage\nasynchronous workers. Instances are created/deleted with\nnapi_create_async_work and napi_delete_async_work.

                          \n

                          The execute and complete callbacks are functions that will be\ninvoked when the executor is ready to execute and when it completes its\ntask respectively.

                          \n

                          The execute function should avoid making any N-API calls\nthat could result in the execution of JavaScript or interaction with\nJavaScript objects. Most often, any code that needs to make N-API\ncalls should be made in complete callback instead.\nAvoid using the napi_env parameter in the execute callback as\nit will likely execute JavaScript.

                          \n

                          These functions implement the following interfaces:

                          \n
                          typedef void (*napi_async_execute_callback)(napi_env env,\n                                            void* data);\ntypedef void (*napi_async_complete_callback)(napi_env env,\n                                             napi_status status,\n                                             void* data);\n
                          \n

                          When these methods are invoked, the data parameter passed will be the\naddon-provided void* data that was passed into the\nnapi_create_async_work call.

                          \n

                          Once created the async worker can be queued\nfor execution using the napi_queue_async_work function:

                          \n
                          napi_status napi_queue_async_work(napi_env env,\n                                  napi_async_work work);\n
                          \n

                          napi_cancel_async_work can be used if the work needs\nto be cancelled before the work has started execution.

                          \n

                          After calling napi_cancel_async_work, the complete callback\nwill be invoked with a status value of napi_cancelled.\nThe work should not be deleted before the complete\ncallback invocation, even when it was cancelled.

                          ", + "desc": "

                          Addon modules often need to leverage async helpers from libuv as part of their\nimplementation. This allows them to schedule work to be executed asynchronously\nso that their methods can return in advance of the work being completed. This\nallows them to avoid blocking overall execution of the Node.js application.

                          \n

                          Node-API provides an ABI-stable interface for these\nsupporting functions which covers the most common asynchronous use cases.

                          \n

                          Node-API defines the napi_async_work structure which is used to manage\nasynchronous workers. Instances are created/deleted with\nnapi_create_async_work and napi_delete_async_work.

                          \n

                          The execute and complete callbacks are functions that will be\ninvoked when the executor is ready to execute and when it completes its\ntask respectively.

                          \n

                          The execute function should avoid making any Node-API calls\nthat could result in the execution of JavaScript or interaction with\nJavaScript objects. Most often, any code that needs to make Node-API\ncalls should be made in complete callback instead.\nAvoid using the napi_env parameter in the execute callback as\nit will likely execute JavaScript.

                          \n

                          These functions implement the following interfaces:

                          \n
                          typedef void (*napi_async_execute_callback)(napi_env env,\n                                            void* data);\ntypedef void (*napi_async_complete_callback)(napi_env env,\n                                             napi_status status,\n                                             void* data);\n
                          \n

                          When these methods are invoked, the data parameter passed will be the\naddon-provided void* data that was passed into the\nnapi_create_async_work call.

                          \n

                          Once created the async worker can be queued\nfor execution using the napi_queue_async_work function:

                          \n
                          napi_status napi_queue_async_work(napi_env env,\n                                  napi_async_work work);\n
                          \n

                          napi_cancel_async_work can be used if the work needs\nto be cancelled before the work has started execution.

                          \n

                          After calling napi_cancel_async_work, the complete callback\nwill be invoked with a status value of napi_cancelled.\nThe work should not be deleted before the complete\ncallback invocation, even when it was cancelled.

                          ", "modules": [ { "textRaw": "napi_create_async_work", @@ -2701,7 +2720,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_async_init(napi_env env,\n                            napi_value async_resource,\n                            napi_value async_resource_name,\n                            napi_async_context* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] async_resource: Object associated with the async work\nthat will be passed to possible async_hooks init hooks.\nIn order to retain ABI compatibility with previous versions,\npassing NULL for async_resource will not result in an error, however,\nthis will result incorrect operation of async hooks for the\nnapi_async_context created. Potential issues include\nloss of async context when using the AsyncLocalStorage API.
                          • \n
                          • [in] async_resource_name: Identifier for the kind of resource\nthat is being provided for diagnostic information exposed by the\nasync_hooks API.
                          • \n
                          • [out] result: The initialized async context.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          ", + "desc": "
                          napi_status napi_async_init(napi_env env,\n                            napi_value async_resource,\n                            napi_value async_resource_name,\n                            napi_async_context* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] async_resource: Object associated with the async work\nthat will be passed to possible async_hooks init hooks and can be\naccessed by async_hooks.executionAsyncResource().
                          • \n
                          • [in] async_resource_name: Identifier for the kind of resource that is being\nprovided for diagnostic information exposed by the async_hooks API.
                          • \n
                          • [out] result: The initialized async context.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          The async_resource object needs to be kept alive until\nnapi_async_destroy to keep async_hooks related API acts correctly. In\norder to retain ABI compatibility with previous versions, napi_async_contexts\nare not maintaining the strong reference to the async_resource objects to\navoid introducing causing memory leaks. However, if the async_resource is\ngarbage collected by JavaScript engine before the napi_async_context was\ndestroyed by napi_async_destroy, calling napi_async_context related APIs\nlike napi_open_callback_scope and napi_make_callback can cause\nproblems like loss of async context when using the AsyncLocalStoage API.

                          \n

                          In order to retain ABI compatibility with previous versions, passing NULL\nfor async_resource does not result in an error. However, this is not\nrecommended as this will result poor results with async_hooks\ninit hooks and async_hooks.executionAsyncResource() as the resource is\nnow required by the underlying async_hooks implementation in order to provide\nthe linkage between async callbacks.

                          ", "type": "module", "displayName": "napi_async_init" }, @@ -2734,11 +2753,12 @@ "changes": [ { "version": "v8.6.0", + "pr-url": "https://github.com/nodejs/node/pull/15189", "description": "Added `async_context` parameter." } ] }, - "desc": "
                          NAPI_EXTERN napi_status napi_make_callback(napi_env env,\n                                           napi_async_context async_context,\n                                           napi_value recv,\n                                           napi_value func,\n                                           size_t argc,\n                                           const napi_value* argv,\n                                           napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] async_context: Context for the async operation that is\ninvoking the callback. This should normally be a value previously\nobtained from napi_async_init. However NULL is also allowed,\nwhich indicates the current async context (if any) is to be used\nfor the callback.
                          • \n
                          • [in] recv: The this object passed to the called function.
                          • \n
                          • [in] func: napi_value representing the JavaScript function to be invoked.
                          • \n
                          • [in] argc: The count of elements in the argv array.
                          • \n
                          • [in] argv: Array of JavaScript values as napi_value representing the\narguments to the function.
                          • \n
                          • [out] result: napi_value representing the JavaScript object returned.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method allows a JavaScript function object to be called from a native\nadd-on. This API is similar to napi_call_function. However, it is used to call\nfrom native code back into JavaScript after returning from an async\noperation (when there is no other script on the stack). It is a fairly simple\nwrapper around node::MakeCallback.

                          \n

                          Note it is not necessary to use napi_make_callback from within a\nnapi_async_complete_callback; in that situation the callback's async\ncontext has already been set up, so a direct call to napi_call_function\nis sufficient and appropriate. Use of the napi_make_callback function\nmay be required when implementing custom async behavior that does not use\nnapi_create_async_work.

                          \n

                          Any process.nextTicks or Promises scheduled on the microtask queue by\nJavaScript during the callback are ran before returning back to C/C++.

                          ", + "desc": "
                          NAPI_EXTERN napi_status napi_make_callback(napi_env env,\n                                           napi_async_context async_context,\n                                           napi_value recv,\n                                           napi_value func,\n                                           size_t argc,\n                                           const napi_value* argv,\n                                           napi_value* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] async_context: Context for the async operation that is\ninvoking the callback. This should normally be a value previously\nobtained from napi_async_init.\nIn order to retain ABI compatibility with previous versions, passing NULL\nfor async_context does not result in an error. However, this results\nin incorrect operation of async hooks. Potential issues include loss of\nasync context when using the AsyncLocalStorage API.
                          • \n
                          • [in] recv: The this value passed to the called function.
                          • \n
                          • [in] func: napi_value representing the JavaScript function to be invoked.
                          • \n
                          • [in] argc: The count of elements in the argv array.
                          • \n
                          • [in] argv: Array of JavaScript values as napi_value representing the\narguments to the function.
                          • \n
                          • [out] result: napi_value representing the JavaScript object returned.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This method allows a JavaScript function object to be called from a native\nadd-on. This API is similar to napi_call_function. However, it is used to call\nfrom native code back into JavaScript after returning from an async\noperation (when there is no other script on the stack). It is a fairly simple\nwrapper around node::MakeCallback.

                          \n

                          Note it is not necessary to use napi_make_callback from within a\nnapi_async_complete_callback; in that situation the callback's async\ncontext has already been set up, so a direct call to napi_call_function\nis sufficient and appropriate. Use of the napi_make_callback function\nmay be required when implementing custom async behavior that does not use\nnapi_create_async_work.

                          \n

                          Any process.nextTicks or Promises scheduled on the microtask queue by\nJavaScript during the callback are ran before returning back to C/C++.

                          ", "type": "module", "displayName": "napi_make_callback" }, @@ -2754,7 +2774,7 @@ ], "changes": [] }, - "desc": "
                          NAPI_EXTERN napi_status napi_open_callback_scope(napi_env env,\n                                                 napi_value resource_object,\n                                                 napi_async_context context,\n                                                 napi_callback_scope* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] resource_object: An object associated with the async work\nthat will be passed to possible async_hooks init hooks.
                          • \n
                          • [in] context: Context for the async operation that is invoking the callback.\nThis should be a value previously obtained from napi_async_init.
                          • \n
                          • [out] result: The newly created scope.
                          • \n
                          \n

                          There are cases (for example, resolving promises) where it is\nnecessary to have the equivalent of the scope associated with a callback\nin place when making certain N-API calls. If there is no other script on\nthe stack the napi_open_callback_scope and\nnapi_close_callback_scope functions can be used to open/close\nthe required scope.

                          ", + "desc": "
                          NAPI_EXTERN napi_status napi_open_callback_scope(napi_env env,\n                                                 napi_value resource_object,\n                                                 napi_async_context context,\n                                                 napi_callback_scope* result)\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [in] resource_object: An object associated with the async work\nthat will be passed to possible async_hooks init hooks. This\nparameter has been deprecated and is ignored at runtime. Use the\nasync_resource parameter in napi_async_init instead.
                          • \n
                          • [in] context: Context for the async operation that is invoking the callback.\nThis should be a value previously obtained from napi_async_init.
                          • \n
                          • [out] result: The newly created scope.
                          • \n
                          \n

                          There are cases (for example, resolving promises) where it is\nnecessary to have the equivalent of the scope associated with a callback\nin place when making certain Node-API calls. If there is no other script on\nthe stack the napi_open_callback_scope and\nnapi_close_callback_scope functions can be used to open/close\nthe required scope.

                          ", "type": "module", "displayName": "napi_open_callback_scope" }, @@ -2810,7 +2830,7 @@ ], "changes": [] }, - "desc": "
                          napi_status napi_get_version(napi_env env,\n                             uint32_t* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [out] result: The highest version of N-API supported.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns the highest N-API version supported by the\nNode.js runtime. N-API is planned to be additive such that\nnewer releases of Node.js may support additional API functions.\nIn order to allow an addon to use a newer function when running with\nversions of Node.js that support it, while providing\nfallback behavior when running with Node.js versions that don't\nsupport it:

                          \n
                            \n
                          • Call napi_get_version() to determine if the API is available.
                          • \n
                          • If available, dynamically load a pointer to the function using uv_dlsym().
                          • \n
                          • Use the dynamically loaded pointer to invoke the function.
                          • \n
                          • If the function is not available, provide an alternate implementation\nthat does not use the function.
                          • \n
                          ", + "desc": "
                          napi_status napi_get_version(napi_env env,\n                             uint32_t* result);\n
                          \n
                            \n
                          • [in] env: The environment that the API is invoked under.
                          • \n
                          • [out] result: The highest version of Node-API supported.
                          • \n
                          \n

                          Returns napi_ok if the API succeeded.

                          \n

                          This API returns the highest Node-API version supported by the\nNode.js runtime. Node-API is planned to be additive such that\nnewer releases of Node.js may support additional API functions.\nIn order to allow an addon to use a newer function when running with\nversions of Node.js that support it, while providing\nfallback behavior when running with Node.js versions that don't\nsupport it:

                          \n
                            \n
                          • Call napi_get_version() to determine if the API is available.
                          • \n
                          • If available, dynamically load a pointer to the function using uv_dlsym().
                          • \n
                          • Use the dynamically loaded pointer to invoke the function.
                          • \n
                          • If the function is not available, provide an alternate implementation\nthat does not use the function.
                          • \n
                          ", "type": "module", "displayName": "napi_get_version" } @@ -2845,7 +2865,7 @@ { "textRaw": "Promises", "name": "promises", - "desc": "

                          N-API provides facilities for creating Promise objects as described in\nSection 25.4 of the ECMA specification. It implements promises as a pair of\nobjects. When a promise is created by napi_create_promise(), a \"deferred\"\nobject is created and returned alongside the Promise. The deferred object is\nbound to the created Promise and is the only means to resolve or reject the\nPromise using napi_resolve_deferred() or napi_reject_deferred(). The\ndeferred object that is created by napi_create_promise() is freed by\nnapi_resolve_deferred() or napi_reject_deferred(). The Promise object may\nbe returned to JavaScript where it can be used in the usual fashion.

                          \n

                          For example, to create a promise and pass it to an asynchronous worker:

                          \n
                          napi_deferred deferred;\nnapi_value promise;\nnapi_status status;\n\n// Create the promise.\nstatus = napi_create_promise(env, &deferred, &promise);\nif (status != napi_ok) return NULL;\n\n// Pass the deferred to a function that performs an asynchronous action.\ndo_something_asynchronous(deferred);\n\n// Return the promise to JS\nreturn promise;\n
                          \n

                          The above function do_something_asynchronous() would perform its asynchronous\naction and then it would resolve or reject the deferred, thereby concluding the\npromise and freeing the deferred:

                          \n
                          napi_deferred deferred;\nnapi_value undefined;\nnapi_status status;\n\n// Create a value with which to conclude the deferred.\nstatus = napi_get_undefined(env, &undefined);\nif (status != napi_ok) return NULL;\n\n// Resolve or reject the promise associated with the deferred depending on\n// whether the asynchronous action succeeded.\nif (asynchronous_action_succeeded) {\n  status = napi_resolve_deferred(env, deferred, undefined);\n} else {\n  status = napi_reject_deferred(env, deferred, undefined);\n}\nif (status != napi_ok) return NULL;\n\n// At this point the deferred has been freed, so we should assign NULL to it.\ndeferred = NULL;\n
                          ", + "desc": "

                          Node-API provides facilities for creating Promise objects as described in\nSection 25.4 of the ECMA specification. It implements promises as a pair of\nobjects. When a promise is created by napi_create_promise(), a \"deferred\"\nobject is created and returned alongside the Promise. The deferred object is\nbound to the created Promise and is the only means to resolve or reject the\nPromise using napi_resolve_deferred() or napi_reject_deferred(). The\ndeferred object that is created by napi_create_promise() is freed by\nnapi_resolve_deferred() or napi_reject_deferred(). The Promise object may\nbe returned to JavaScript where it can be used in the usual fashion.

                          \n

                          For example, to create a promise and pass it to an asynchronous worker:

                          \n
                          napi_deferred deferred;\nnapi_value promise;\nnapi_status status;\n\n// Create the promise.\nstatus = napi_create_promise(env, &deferred, &promise);\nif (status != napi_ok) return NULL;\n\n// Pass the deferred to a function that performs an asynchronous action.\ndo_something_asynchronous(deferred);\n\n// Return the promise to JS\nreturn promise;\n
                          \n

                          The above function do_something_asynchronous() would perform its asynchronous\naction and then it would resolve or reject the deferred, thereby concluding the\npromise and freeing the deferred:

                          \n
                          napi_deferred deferred;\nnapi_value undefined;\nnapi_status status;\n\n// Create a value with which to conclude the deferred.\nstatus = napi_get_undefined(env, &undefined);\nif (status != napi_ok) return NULL;\n\n// Resolve or reject the promise associated with the deferred depending on\n// whether the asynchronous action succeeded.\nif (asynchronous_action_succeeded) {\n  status = napi_resolve_deferred(env, deferred, undefined);\n} else {\n  status = napi_reject_deferred(env, deferred, undefined);\n}\nif (status != napi_ok) return NULL;\n\n// At this point the deferred has been freed, so we should assign NULL to it.\ndeferred = NULL;\n
                          ", "modules": [ { "textRaw": "napi_create_promise", @@ -2918,7 +2938,7 @@ { "textRaw": "Script execution", "name": "script_execution", - "desc": "

                          N-API provides an API for executing a string containing JavaScript using the\nunderlying JavaScript engine.

                          ", + "desc": "

                          Node-API provides an API for executing a string containing JavaScript using the\nunderlying JavaScript engine.

                          ", "modules": [ { "textRaw": "napi_run_script", @@ -2943,15 +2963,15 @@ { "textRaw": "libuv event loop", "name": "libuv_event_loop", - "desc": "

                          N-API provides a function for getting the current event loop associated with\na specific napi_env.

                          ", + "desc": "

                          Node-API provides a function for getting the current event loop associated with\na specific napi_env.

                          ", "modules": [ { "textRaw": "napi_get_uv_event_loop", "name": "napi_get_uv_event_loop", "meta": { "added": [ - "v8.10.0", - "v9.3.0" + "v9.3.0", + "v8.10.0" ], "napiVersion": [ 2 @@ -2969,12 +2989,12 @@ { "textRaw": "Asynchronous thread-safe function calls", "name": "asynchronous_thread-safe_function_calls", - "desc": "

                          JavaScript functions can normally only be called from a native addon's main\nthread. If an addon creates additional threads, then N-API functions that\nrequire a napi_env, napi_value, or napi_ref must not be called from those\nthreads.

                          \n

                          When an addon has additional threads and JavaScript functions need to be invoked\nbased on the processing completed by those threads, those threads must\ncommunicate with the addon's main thread so that the main thread can invoke the\nJavaScript function on their behalf. The thread-safe function APIs provide an\neasy way to do this.

                          \n

                          These APIs provide the type napi_threadsafe_function as well as APIs to\ncreate, destroy, and call objects of this type.\nnapi_create_threadsafe_function() creates a persistent reference to a\nnapi_value that holds a JavaScript function which can be called from multiple\nthreads. The calls happen asynchronously. This means that values with which the\nJavaScript callback is to be called will be placed in a queue, and, for each\nvalue in the queue, a call will eventually be made to the JavaScript function.

                          \n

                          Upon creation of a napi_threadsafe_function a napi_finalize callback can be\nprovided. This callback will be invoked on the main thread when the thread-safe\nfunction is about to be destroyed. It receives the context and the finalize data\ngiven during construction, and provides an opportunity for cleaning up after the\nthreads e.g. by calling uv_thread_join(). Aside from the main loop thread,\nno threads should be using the thread-safe function after the finalize callback\ncompletes.

                          \n

                          The context given during the call to napi_create_threadsafe_function() can\nbe retrieved from any thread with a call to\nnapi_get_threadsafe_function_context().

                          ", + "desc": "

                          JavaScript functions can normally only be called from a native addon's main\nthread. If an addon creates additional threads, then Node-API functions that\nrequire a napi_env, napi_value, or napi_ref must not be called from those\nthreads.

                          \n

                          When an addon has additional threads and JavaScript functions need to be invoked\nbased on the processing completed by those threads, those threads must\ncommunicate with the addon's main thread so that the main thread can invoke the\nJavaScript function on their behalf. The thread-safe function APIs provide an\neasy way to do this.

                          \n

                          These APIs provide the type napi_threadsafe_function as well as APIs to\ncreate, destroy, and call objects of this type.\nnapi_create_threadsafe_function() creates a persistent reference to a\nnapi_value that holds a JavaScript function which can be called from multiple\nthreads. The calls happen asynchronously. This means that values with which the\nJavaScript callback is to be called will be placed in a queue, and, for each\nvalue in the queue, a call will eventually be made to the JavaScript function.

                          \n

                          Upon creation of a napi_threadsafe_function a napi_finalize callback can be\nprovided. This callback will be invoked on the main thread when the thread-safe\nfunction is about to be destroyed. It receives the context and the finalize data\ngiven during construction, and provides an opportunity for cleaning up after the\nthreads e.g. by calling uv_thread_join(). Aside from the main loop thread,\nno threads should be using the thread-safe function after the finalize callback\ncompletes.

                          \n

                          The context given during the call to napi_create_threadsafe_function() can\nbe retrieved from any thread with a call to\nnapi_get_threadsafe_function_context().

                          ", "modules": [ { "textRaw": "Calling a thread-safe function", "name": "calling_a_thread-safe_function", - "desc": "

                          napi_call_threadsafe_function() can be used for initiating a call into\nJavaScript. napi_call_threadsafe_function() accepts a parameter which controls\nwhether the API behaves blockingly. If set to napi_tsfn_nonblocking, the API\nbehaves non-blockingly, returning napi_queue_full if the queue was full,\npreventing data from being successfully added to the queue. If set to\nnapi_tsfn_blocking, the API blocks until space becomes available in the queue.\nnapi_call_threadsafe_function() never blocks if the thread-safe function was\ncreated with a maximum queue size of 0.

                          \n

                          The actual call into JavaScript is controlled by the callback given via the\ncall_js_cb parameter. call_js_cb is invoked on the main thread once for each\nvalue that was placed into the queue by a successful call to\nnapi_call_threadsafe_function(). If such a callback is not given, a default\ncallback will be used, and the resulting JavaScript call will have no arguments.\nThe call_js_cb callback receives the JavaScript function to call as a\nnapi_value in its parameters, as well as the void* context pointer used when\ncreating the napi_threadsafe_function, and the next data pointer that was\ncreated by one of the secondary threads. The callback can then use an API such\nas napi_call_function() to call into JavaScript.

                          \n

                          The callback may also be invoked with env and call_js_cb both set to NULL\nto indicate that calls into JavaScript are no longer possible, while items\nremain in the queue that may need to be freed. This normally occurs when the\nNode.js process exits while there is a thread-safe function still active.

                          \n

                          It is not necessary to call into JavaScript via napi_make_callback() because\nN-API runs call_js_cb in a context appropriate for callbacks.

                          ", + "desc": "

                          napi_call_threadsafe_function() can be used for initiating a call into\nJavaScript. napi_call_threadsafe_function() accepts a parameter which controls\nwhether the API behaves blockingly. If set to napi_tsfn_nonblocking, the API\nbehaves non-blockingly, returning napi_queue_full if the queue was full,\npreventing data from being successfully added to the queue. If set to\nnapi_tsfn_blocking, the API blocks until space becomes available in the queue.\nnapi_call_threadsafe_function() never blocks if the thread-safe function was\ncreated with a maximum queue size of 0.

                          \n

                          napi_call_threadsafe_function() should not be called with napi_tsfn_blocking\nfrom a JavaScript thread, because, if the queue is full, it may cause the\nJavaScript thread to deadlock.

                          \n

                          The actual call into JavaScript is controlled by the callback given via the\ncall_js_cb parameter. call_js_cb is invoked on the main thread once for each\nvalue that was placed into the queue by a successful call to\nnapi_call_threadsafe_function(). If such a callback is not given, a default\ncallback will be used, and the resulting JavaScript call will have no arguments.\nThe call_js_cb callback receives the JavaScript function to call as a\nnapi_value in its parameters, as well as the void* context pointer used when\ncreating the napi_threadsafe_function, and the next data pointer that was\ncreated by one of the secondary threads. The callback can then use an API such\nas napi_call_function() to call into JavaScript.

                          \n

                          The callback may also be invoked with env and call_js_cb both set to NULL\nto indicate that calls into JavaScript are no longer possible, while items\nremain in the queue that may need to be freed. This normally occurs when the\nNode.js process exits while there is a thread-safe function still active.

                          \n

                          It is not necessary to call into JavaScript via napi_make_callback() because\nNode-API runs call_js_cb in a context appropriate for callbacks.

                          ", "type": "module", "displayName": "Calling a thread-safe function" }, @@ -3004,7 +3024,10 @@ ], "changes": [ { - "version": "v12.6.0", + "version": [ + "v12.6.0", + "v10.17.0" + ], "pr-url": "https://github.com/nodejs/node/pull/27791", "description": "Made `func` parameter optional with custom `call_js_cb`." } @@ -3040,9 +3063,20 @@ "napiVersion": [ 4 ], - "changes": [] + "changes": [ + { + "version": "v14.5.0", + "pr-url": "https://github.com/nodejs/node/pull/33453", + "description": "Support for `napi_would_deadlock` has been reverted." + }, + { + "version": "v14.1.0", + "pr-url": "https://github.com/nodejs/node/pull/32689", + "description": "Return `napi_would_deadlock` when called with `napi_tsfn_blocking` from the main thread or a worker thread and the queue is full." + } + ] }, - "desc": "
                          NAPI_EXTERN napi_status\nnapi_call_threadsafe_function(napi_threadsafe_function func,\n                              void* data,\n                              napi_threadsafe_function_call_mode is_blocking);\n
                          \n
                            \n
                          • [in] func: The asynchronous thread-safe JavaScript function to invoke.
                          • \n
                          • [in] data: Data to send into JavaScript via the callback call_js_cb\nprovided during the creation of the thread-safe JavaScript function.
                          • \n
                          • [in] is_blocking: Flag whose value can be either napi_tsfn_blocking to\nindicate that the call should block if the queue is full or\nnapi_tsfn_nonblocking to indicate that the call should return immediately\nwith a status of napi_queue_full whenever the queue is full.
                          • \n
                          \n

                          This API will return napi_closing if napi_release_threadsafe_function() was\ncalled with abort set to napi_tsfn_abort from any thread. The value is only\nadded to the queue if the API returns napi_ok.

                          \n

                          This API may be called from any thread which makes use of func.

                          ", + "desc": "
                          NAPI_EXTERN napi_status\nnapi_call_threadsafe_function(napi_threadsafe_function func,\n                              void* data,\n                              napi_threadsafe_function_call_mode is_blocking);\n
                          \n
                            \n
                          • [in] func: The asynchronous thread-safe JavaScript function to invoke.
                          • \n
                          • [in] data: Data to send into JavaScript via the callback call_js_cb\nprovided during the creation of the thread-safe JavaScript function.
                          • \n
                          • [in] is_blocking: Flag whose value can be either napi_tsfn_blocking to\nindicate that the call should block if the queue is full or\nnapi_tsfn_nonblocking to indicate that the call should return immediately\nwith a status of napi_queue_full whenever the queue is full.
                          • \n
                          \n

                          This API should not be called with napi_tsfn_blocking from a JavaScript\nthread, because, if the queue is full, it may cause the JavaScript thread to\ndeadlock.

                          \n

                          This API will return napi_closing if napi_release_threadsafe_function() was\ncalled with abort set to napi_tsfn_abort from any thread. The value is only\nadded to the queue if the API returns napi_ok.

                          \n

                          This API may be called from any thread which makes use of func.

                          ", "type": "module", "displayName": "napi_call_threadsafe_function" }, @@ -3119,7 +3153,7 @@ "name": "miscellaneous_utilities", "meta": { "added": [ - "v12.22.0" + "v14.18.0" ], "changes": [] }, @@ -3134,7 +3168,7 @@ "name": "node_api_get_module_file_name", "meta": { "added": [ - "v12.22.0" + "v14.18.0" ], "changes": [] }, diff --git a/doc/api/n-api.md b/doc/api/n-api.md index a55bffd3fab47838bda1222469239224e0eadaed..2dc473dca16513a3c5b56124776b890699803df7 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -1,30 +1,29 @@ -# N-API +# Node-API > Stability: 2 - Stable -N-API (pronounced N as in the letter, followed by API) -is an API for building native Addons. It is independent from -the underlying JavaScript runtime (for example, V8) and is maintained as part of -Node.js itself. This API will be Application Binary Interface (ABI) stable -across versions of Node.js. It is intended to insulate Addons from -changes in the underlying JavaScript engine and allow modules +Node-API (formerly N-API) is an API for building native Addons. It is +independent from the underlying JavaScript runtime (for example, V8) and is +maintained as part of Node.js itself. This API will be Application Binary +Interface (ABI) stable across versions of Node.js. It is intended to insulate +addons from changes in the underlying JavaScript engine and allow modules compiled for one major version to run on later major versions of Node.js without recompilation. The [ABI Stability][] guide provides a more in-depth explanation. Addons are built/packaged with the same approach/tools outlined in the section titled [C++ Addons][]. The only difference is the set of APIs that are used by the native code. Instead of using the V8 or [Native Abstractions for Node.js][] -APIs, the functions available in the N-API are used. +APIs, the functions available in Node-API are used. -APIs exposed by N-API are generally used to create and manipulate +APIs exposed by Node-API are generally used to create and manipulate JavaScript values. Concepts and operations generally map to ideas specified in the ECMA-262 Language Specification. The APIs have the following properties: -* All N-API calls return a status code of type `napi_status`. This +* All Node-API calls return a status code of type `napi_status`. This status indicates whether the API call succeeded or failed. * The API's return value is passed via an out parameter. * All JavaScript values are abstracted behind an opaque type named @@ -33,14 +32,14 @@ properties: using `napi_get_last_error_info`. More information can be found in the error handling section [Error handling][]. -The N-API is a C API that ensures ABI stability across Node.js versions +Node-API is a C API that ensures ABI stability across Node.js versions and different compiler levels. A C++ API can be easier to use. To support using C++, the project maintains a C++ wrapper module called [`node-addon-api`][]. This wrapper provides an inlineable C++ API. Binaries built -with `node-addon-api` will depend on the symbols for the N-API C-based +with `node-addon-api` will depend on the symbols for the Node-API C-based functions exported by Node.js. `node-addon-api` is a more -efficient way to write code that calls N-API. Take, for example, the +efficient way to write code that calls Node-API. Take, for example, the following `node-addon-api` code. The first section shows the `node-addon-api` code and the second section shows what actually gets used in the addon. @@ -78,13 +77,13 @@ it still gets the benefits of the ABI stability provided by the C API. When using `node-addon-api` instead of the C APIs, start with the API [docs][] for `node-addon-api`. -The [N-API Resource](https://nodejs.github.io/node-addon-examples/) offers an -excellent orientation and tips for developers just getting started with N-API -and `node-addon-api`. +The [Node-API Resource](https://nodejs.github.io/node-addon-examples/) offers +an excellent orientation and tips for developers just getting started with +Node-API and `node-addon-api`. ## Implications of ABI stability -Although N-API provides an ABI stability guarantee, other parts of Node.js do +Although Node-API provides an ABI stability guarantee, other parts of Node.js do not, and any external libraries used from the addon may not. In particular, none of the following APIs provide an ABI stability guarantee across major versions: @@ -111,19 +110,19 @@ versions: ``` Thus, for an addon to remain ABI-compatible across Node.js major versions, it -must use N-API exclusively by restricting itself to using +must use Node-API exclusively by restricting itself to using ```c #include ``` and by checking, for all external libraries that it uses, that the external -library makes ABI stability guarantees similar to N-API. +library makes ABI stability guarantees similar to Node-API. ## Building Unlike modules written in JavaScript, developing and deploying Node.js -native addons using N-API requires an additional set of tools. Besides the +native addons using Node-API requires an additional set of tools. Besides the basic tools required to develop for Node.js, the native addon developer requires a toolchain that can compile C and C++ code into a binary. In addition, depending upon how the native addon is deployed, the *user* of @@ -161,9 +160,9 @@ the native addon. #### node-gyp -[node-gyp][] is a build system based on Google's [GYP][] tool and comes -bundled with npm. GYP, and therefore node-gyp, requires that Python be -installed. +[node-gyp][] is a build system based on the [gyp-next][] fork of +Google's [GYP][] tool and comes bundled with npm. GYP, and therefore node-gyp, +requires that Python be installed. Historically, node-gyp has been the tool of choice for building native addons. It has widespread adoption and documentation. However, some @@ -207,15 +206,15 @@ available to the module user when the native module is installed. ## Usage -In order to use the N-API functions, include the file [`node_api.h`][] which is -located in the src directory in the node development tree: +In order to use the Node-API functions, include the file [`node_api.h`][] which +is located in the src directory in the node development tree: ```c #include ``` This will opt into the default `NAPI_VERSION` for the given release of Node.js. -In order to ensure compatibility with specific versions of N-API, the version +In order to ensure compatibility with specific versions of Node-API, the version can be specified explicitly when including the header: ```c @@ -223,10 +222,10 @@ can be specified explicitly when including the header: #include ``` -This restricts the N-API surface to just the functionality that was available in -the specified (and earlier) versions. +This restricts the Node-API surface to just the functionality that was available +in the specified (and earlier) versions. -Some of the N-API surface is experimental and requires explicit opt-in: +Some of the Node-API surface is experimental and requires explicit opt-in: ```c #define NAPI_EXPERIMENTAL @@ -236,52 +235,149 @@ Some of the N-API surface is experimental and requires explicit opt-in: In this case the entire API surface, including any experimental APIs, will be available to the module code. -## N-API version matrix +## Node-API version matrix -N-API versions are additive and versioned independently from Node.js. +Node-API versions are additive and versioned independently from Node.js. Version 4 is an extension to version 3 in that it has all of the APIs from version 3 with some additions. This means that it is not necessary to recompile for new versions of Node.js which are listed as supporting a later version. -| | 1 | 2 | 3 | 4 | 5 | 6 | -|-------|---------|----------|----------|----------|-----------|-----------| -| v6.x | | | v6.14.2* | | | | -| v8.x | v8.0.0* | v8.10.0* | v8.11.2 | v8.16.0 | | | -| v9.x | v9.0.0* | v9.3.0* | v9.11.0* | | | | -| v10.x | v10.0.0 | v10.0.0 | v10.0.0 | v10.16.0 | v10.17.0 | v10.20.0 | -| v11.x | v11.0.0 | v11.0.0 | v11.0.0 | v11.8.0 | | | -| v12.x | v12.0.0 | v12.0.0 | v12.0.0 | v12.0.0 | v12.11.0 | v12.17.0 | -| v13.x | v13.0.0 | v13.0.0 | v13.0.0 | v13.0.0 | v13.0.0 | | -| v14.x | v14.0.0 | v14.0.0 | v14.0.0 | v14.0.0 | v14.0.0 | v14.0.0 | - -\* Indicates that the N-API version was released as experimental - -Each API documented for N-API will have a header named `added in:`, and APIs -which are stable will have the additional header `N-API version:`. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                          123
                          v6.xv6.14.2*
                          v8.xv8.6.0**v8.10.0*v8.11.2
                          v9.xv9.0.0*v9.3.0*v9.11.0*
                          ≥ v10.xall releasesall releasesall releases
                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                          45678
                          v10.xv10.16.0v10.17.0v10.20.0v10.23.0
                          v11.xv11.8.0
                          v12.xv12.0.0v12.11.0v12.17.0v12.19.0v12.22.0
                          v13.xv13.0.0v13.0.0
                          v14.xv14.0.0v14.0.0v14.0.0v14.12.0v14.17.0
                          v15.xv15.0.0v15.0.0v15.0.0v15.0.0v15.12.0
                          v16.xv16.0.0v16.0.0v16.0.0v16.0.0v16.0.0
                          + +\* Node-API was experimental. + +\*\* Node.js 8.0.0 included Node-API as experimental. It was released as +Node-API version 1 but continued to evolve until Node.js 8.6.0. The API is +different in versions prior to Node.js 8.6.0. We recommend Node-API version 3 or +later. + +Each API documented for Node-API will have a header named `added in:`, and APIs +which are stable will have the additional header `Node-API version:`. APIs are directly usable when using a Node.js version which supports -the N-API version shown in `N-API version:` or higher. +the Node-API version shown in `Node-API version:` or higher. When using a Node.js version that does not support the -`N-API version:` listed or if there is no `N-API version:` listed, +`Node-API version:` listed or if there is no `Node-API version:` listed, then the API will only be available if `#define NAPI_EXPERIMENTAL` precedes the inclusion of `node_api.h` or `js_native_api.h`. If an API appears not to be available on a version of Node.js which is later than the one shown in `added in:` then this is most likely the reason for the apparent absence. -The N-APIs associated strictly with accessing ECMAScript features from native +The Node-APIs associated strictly with accessing ECMAScript features from native code can be found separately in `js_native_api.h` and `js_native_api_types.h`. The APIs defined in these headers are included in `node_api.h` and `node_api_types.h`. The headers are structured in this way in order to allow -implementations of N-API outside of Node.js. For those implementations the +implementations of Node-API outside of Node.js. For those implementations the Node.js specific APIs may not be applicable. The Node.js-specific parts of an addon can be separated from the code that exposes the actual functionality to the JavaScript environment so that the -latter may be used with multiple implementations of N-API. In the example below, -`addon.c` and `addon.h` refer only to `js_native_api.h`. This ensures that -`addon.c` can be reused to compile against either the Node.js implementation of -N-API or any implementation of N-API outside of Node.js. +latter may be used with multiple implementations of Node-API. In the example +below, `addon.c` and `addon.h` refer only to `js_native_api.h`. This ensures +that `addon.c` can be reused to compile against either the Node.js +implementation of Node-API or any implementation of Node-API outside of Node.js. `addon_node.c` is a separate file that contains the Node.js specific entry point to the addon and which instantiates the addon by calling into `addon.c` when the @@ -382,12 +478,14 @@ Native addons may need to allocate global state which they use during their entire life cycle such that the state must be unique to each instance of the addon. -To this end, N-API provides a way to allocate data such that its life cycle is -tied to the life cycle of the Agent. +To this end, Node-API provides a way to allocate data such that its life cycle +is tied to the life cycle of the Agent. ### napi_set_instance_data @@ -398,7 +496,7 @@ napi_status napi_set_instance_data(napi_env env, void* finalize_hint); ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[in] data`: The data item to make available to bindings of this instance. * `[in] finalize_cb`: The function to call when the environment is being torn down. The function receives `data` so that it might free it. @@ -416,7 +514,9 @@ by the previous call, it will not be called. ### napi_get_instance_data @@ -425,7 +525,7 @@ napi_status napi_get_instance_data(napi_env env, void** data); ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[out] data`: The data item that was previously associated with the currently running Agent by a call to `napi_set_instance_data()`. @@ -435,18 +535,18 @@ This API retrieves data that was previously associated with the currently running Agent via `napi_set_instance_data()`. If no data is set, the call will succeed and `data` will be set to `NULL`. -## Basic N-API data types +## Basic Node-API data types -N-API exposes the following fundamental datatypes as abstractions that are +Node-API exposes the following fundamental datatypes as abstractions that are consumed by the various APIs. These APIs should be treated as opaque, -introspectable only with other N-API calls. +introspectable only with other Node-API calls. ### napi_status -Integral status code indicating the success or failure of a N-API call. +Integral status code indicating the success or failure of a Node-API call. Currently, the following status codes are supported. ```c @@ -472,6 +572,7 @@ typedef enum { napi_date_expected, napi_arraybuffer_expected, napi_detachable_arraybuffer_expected, + napi_would_deadlock, /* unused */ } napi_status; ``` @@ -499,18 +600,18 @@ typedef struct { not implemented for any VM. * `engine_error_code`: VM-specific error code. This is currently not implemented for any VM. -* `error_code`: The N-API status code that originated with the last error. +* `error_code`: The Node-API status code that originated with the last error. See the [Error handling][] section for additional information. ### napi_env -`napi_env` is used to represent a context that the underlying N-API +`napi_env` is used to represent a context that the underlying Node-API implementation can use to persist VM-specific state. This structure is passed to native functions when they're invoked, and it must be passed back when -making N-API calls. Specifically, the same `napi_env` that was passed in when +making Node-API calls. Specifically, the same `napi_env` that was passed in when the initial native function was called must be passed to any subsequent -nested N-API calls. Caching the `napi_env` for the purpose of general reuse, +nested Node-API calls. Caching the `napi_env` for the purpose of general reuse, and passing the `napi_env` between instances of the same addon running on different [`Worker`][] threads is not allowed. The `napi_env` becomes invalid when an instance of a native addon is unloaded. Notification of this event is @@ -566,14 +667,14 @@ typedef enum { } napi_threadsafe_function_call_mode; ``` -### N-API memory management types +### Node-API memory management types #### napi_handle_scope This is an abstraction used to control and modify the lifetime of objects -created within a particular scope. In general, N-API values are created within -the context of a handle scope. When a native method is called from +created within a particular scope. In general, Node-API values are created +within the context of a handle scope. When a native method is called from JavaScript, a default handle scope will exist. If the user does not explicitly -create a new handle scope, N-API values will be created in the default handle +create a new handle scope, Node-API values will be created in the default handle scope. For any invocations of code outside the execution of a native method (for instance, during a libuv callback invocation), the module is required to create a scope before invoking any functions that can result in the creation @@ -607,7 +708,9 @@ For more details, review the [Object lifetime management][]. #### napi_type_tag @@ -629,14 +732,14 @@ typedef struct { #### napi_async_cleanup_hook_handle An opaque value returned by [`napi_add_async_cleanup_hook`][]. It must be passed to [`napi_remove_async_cleanup_hook`][] when the chain of asynchronous cleanup events completes. -### N-API callback types +### Node-API callback types #### napi_callback_info Function pointer type for user-provided native functions which are to be -exposed to JavaScript via N-API. Callback functions should satisfy the +exposed to JavaScript via Node-API. Callback functions should satisfy the following signature: ```c @@ -696,8 +799,8 @@ operations. Callback functions must satisfy the following signature: typedef void (*napi_async_execute_callback)(napi_env env, void* data); ``` -Implementations of this function must avoid making N-API calls that execute -JavaScript or interact with JavaScript objects. N-API calls should be in the +Implementations of this function must avoid making Node-API calls that execute +JavaScript or interact with JavaScript objects. Node-API calls should be in the `napi_async_complete_callback` instead. Do not use the `napi_env` parameter as it will likely result in execution of JavaScript. @@ -734,7 +837,7 @@ The data arriving from the secondary thread via the queue is given in the `data` parameter and the JavaScript function to call is given in the `js_callback` parameter. -N-API sets up the environment prior to calling this callback, so it is +Node-API sets up the environment prior to calling this callback, so it is sufficient to call the JavaScript function via `napi_call_function` rather than via `napi_make_callback`. @@ -756,7 +859,7 @@ typedef void (*napi_threadsafe_function_call_js)(napi_env env, * `[in] context`: The optional data with which the thread-safe function was created. * `[in] data`: Data created by the secondary thread. It is the responsibility of - the callback to convert this native data to JavaScript values (with N-API + the callback to convert this native data to JavaScript values (with Node-API functions) that can be passed as parameters when `js_callback` is invoked. This pointer is managed entirely by the threads and this callback. Thus this callback should free the data. @@ -766,7 +869,7 @@ handle and/or callback scope inside the function body is not necessary. #### napi_async_cleanup_hook Function pointer used with [`napi_add_async_cleanup_hook`][]. It will be called @@ -780,8 +883,8 @@ typedef void (*napi_async_cleanup_hook)(napi_async_cleanup_hook_handle handle, ``` * `[in] handle`: The handle that must be passed to -[`napi_remove_async_cleanup_hook`][] after completion of the asynchronous -cleanup. + [`napi_remove_async_cleanup_hook`][] after completion of the asynchronous + cleanup. * `[in] data`: The data that was passed to [`napi_add_async_cleanup_hook`][]. The body of the function should initiate the asynchronous cleanup actions at the @@ -790,12 +893,12 @@ end of which `handle` must be passed in a call to ## Error handling -N-API uses both return values and JavaScript exceptions for error handling. +Node-API uses both return values and JavaScript exceptions for error handling. The following sections explain the approach for each case. ### Return values -All of the N-API functions share the same error handling pattern. The +All of the Node-API functions share the same error handling pattern. The return type of all API functions is `napi_status`. The return value will be `napi_ok` if the request was successful and @@ -838,10 +941,10 @@ typedef struct napi_extended_error_info { * `error_message`: Textual representation of the error that occurred. * `engine_reserved`: Opaque handle reserved for engine use only. * `engine_error_code`: VM specific error code. -* `error_code`: n-api status code for the last error. +* `error_code`: Node-API status code for the last error. [`napi_get_last_error_info`][] returns the information for the last -N-API call that was made. +Node-API call that was made. Do not rely on the content or format of any of the extended information as it is not subject to SemVer and may change at any time. It is intended only for @@ -861,7 +964,7 @@ napi_get_last_error_info(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[out] result`: The `napi_extended_error_info` structure with more -information about the error. + information about the error. Returns `napi_ok` if the API succeeded. @@ -869,7 +972,7 @@ This API retrieves a `napi_extended_error_info` structure with information about the last error that occurred. The content of the `napi_extended_error_info` returned is only valid up until -an n-api function is called on the same `env`. +a Node-API function is called on the same `env`. Do not rely on the content or format of any of the extended information as it is not subject to SemVer and may change at any time. It is intended only for @@ -879,7 +982,7 @@ This API can be called even if there is a pending JavaScript exception. ### Exceptions -Any N-API function call may result in a pending JavaScript exception. This is +Any Node-API function call may result in a pending JavaScript exception. This is the case for any of the API functions, even those that may not cause the execution of JavaScript. @@ -890,10 +993,10 @@ exception is pending and no additional action is required. If the instead of simply returning immediately, [`napi_is_exception_pending`][] must be called in order to determine if an exception is pending or not. -In many cases when an N-API function is called and an exception is +In many cases when a Node-API function is called and an exception is already pending, the function will return immediately with a `napi_status` of `napi_pending_exception`. However, this is not the case -for all functions. N-API allows a subset of the functions to be +for all functions. Node-API allows a subset of the functions to be called to allow for some minimal cleanup before returning to JavaScript. In that case, `napi_status` will reflect the status for the function. It will not reflect previous pending exceptions. To avoid confusion, check @@ -904,7 +1007,7 @@ When an exception is pending one of two approaches can be employed. The first approach is to do any appropriate cleanup and then return so that execution will return to JavaScript. As part of the transition back to JavaScript, the exception will be thrown at the point in the JavaScript -code where the native method was invoked. The behavior of most N-API calls +code where the native method was invoked. The behavior of most Node-API calls is unspecified while an exception is pending, and many will simply return `napi_pending_exception`, so do as little as possible and then return to JavaScript where the exception can be handled. @@ -918,7 +1021,7 @@ clear the exception. On success, result will contain the handle to the last JavaScript `Object` thrown. If it is determined, after retrieving the exception, the exception cannot be handled after all it can be re-thrown it with [`napi_throw`][] where error is the -JavaScript `Error` object to be thrown. +JavaScript value to be thrown. The following utility functions are also available in case native code needs to throw an exception or determine if a `napi_value` is an instance @@ -937,7 +1040,7 @@ generated internally. The goal is for applications to use these error codes for all error checking. The associated error messages will remain, but will only be meant to be used for logging and display with the expectation that the message can change without -SemVer applying. In order to support this model with N-API, both +SemVer applying. In order to support this model with Node-API, both in internal functionality and for module specific functionality (as its good practice), the `throw_` and `create_` functions take an optional code parameter which is the string for the code @@ -1071,7 +1174,7 @@ NAPI_EXTERN napi_status napi_create_error(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[in] code`: Optional `napi_value` with the string for the error code to be associated with the error. -* `[in] msg`: `napi_value` that references a JavaScript `String` to be used as +* `[in] msg`: `napi_value` that references a JavaScript `string` to be used as the message for the `Error`. * `[out] result`: `napi_value` representing the error created. @@ -1095,7 +1198,7 @@ NAPI_EXTERN napi_status napi_create_type_error(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[in] code`: Optional `napi_value` with the string for the error code to be associated with the error. -* `[in] msg`: `napi_value` that references a JavaScript `String` to be used as +* `[in] msg`: `napi_value` that references a JavaScript `string` to be used as the message for the `Error`. * `[out] result`: `napi_value` representing the error created. @@ -1119,7 +1222,7 @@ NAPI_EXTERN napi_status napi_create_range_error(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[in] code`: Optional `napi_value` with the string for the error code to be associated with the error. -* `[in] msg`: `napi_value` that references a JavaScript `String` to be used as +* `[in] msg`: `napi_value` that references a JavaScript `string` to be used as the message for the `Error`. * `[out] result`: `napi_value` representing the error created. @@ -1191,9 +1294,9 @@ napiVersion: 1 ```c NAPI_NO_RETURN void napi_fatal_error(const char* location, - size_t location_len, - const char* message, - size_t message_len); + size_t location_len, + const char* message, + size_t message_len); ``` * `[in] location`: Optional location at which the error occurred. @@ -1209,7 +1312,7 @@ This API can be called even if there is a pending JavaScript exception. ## Object lifetime management -As N-API calls are made, handles to objects in the heap for the underlying +As Node-API calls are made, handles to objects in the heap for the underlying VM may be returned as `napi_values`. These handles must hold the objects 'live' until they are no longer required by the native code, otherwise the objects could be collected before the native code was @@ -1223,7 +1326,7 @@ held live for the lifespan of the native method call. In many cases, however, it is necessary that the handles remain valid for either a shorter or longer lifespan than that of the native method. -The sections which follow describe the N-API functions that can be used +The sections which follow describe the Node-API functions that can be used to change the handle lifespan from the default. ### Making handle lifespan shorter than that of the native method @@ -1247,13 +1350,13 @@ substantial resources. In addition, even though the native code could only use the most recent handle, all of the associated objects would also be kept alive since they all share the same scope. -To handle this case, N-API provides the ability to establish a new 'scope' to +To handle this case, Node-API provides the ability to establish a new 'scope' to which newly created handles will be associated. Once those handles are no longer required, the scope can be 'closed' and any handles associated with the scope are invalidated. The methods available to open/close scopes are [`napi_open_handle_scope`][] and [`napi_close_handle_scope`][]. -N-API only supports a single nested hierarchy of scopes. There is only one +Node-API only supports a single nested hierarchy of scopes. There is only one active scope at any time, and all new handles will be associated with that scope while it is active. Scopes must be closed in the reverse order from which they are opened. In addition, all scopes created within a native method @@ -1284,8 +1387,8 @@ for (int i = 0; i < 1000000; i++) { ``` When nesting scopes, there are cases where a handle from an -inner scope needs to live beyond the lifespan of that scope. N-API supports an -'escapable scope' in order to support this case. An escapable scope +inner scope needs to live beyond the lifespan of that scope. Node-API supports +an 'escapable scope' in order to support this case. An escapable scope allows one handle to be 'promoted' so that it 'escapes' the current scope and the lifespan of the handle changes from the current scope to that of the outer scope. @@ -1418,7 +1521,7 @@ described in the earlier section. The lifespan of a normal handle is managed by scopes and all scopes must be closed before the end of a native method. -N-API provides methods to create persistent references to an object. +Node-API provides methods to create persistent references to an object. Each persistent reference has an associated count with a value of 0 or higher. The count determines if the reference will keep the corresponding object live. References with a count of 0 do not @@ -1433,11 +1536,11 @@ for a reference is 0, all subsequent calls to get the object associated with the reference [`napi_get_reference_value`][] will return `NULL` for the returned `napi_value`. An attempt to call [`napi_reference_ref`][] for a reference whose object has been collected -will result in an error. +results in an error. References must be deleted once they are no longer required by the addon. When -a reference is deleted it will no longer prevent the corresponding object from -being collected. Failure to delete a persistent reference will result in +a reference is deleted, it will no longer prevent the corresponding object from +being collected. Failure to delete a persistent reference results in a 'memory leak' with both the native memory for the persistent reference and the corresponding object on the heap being retained forever. @@ -1562,7 +1665,7 @@ While a Node.js process typically releases all its resources when exiting, embedders of Node.js, or future Worker support, may require addons to register clean-up hooks that will be run once the current Node.js instance exits. -N-API provides functions for registering and un-registering such callbacks. +Node-API provides functions for registering and un-registering such callbacks. When those callbacks are run, all resources that are being held by the addon should be freed up. @@ -1616,12 +1719,14 @@ with `napi_add_env_cleanup_hook`, otherwise the process will abort. #### napi_add_async_cleanup_hook ```c @@ -1636,7 +1741,7 @@ NAPI_EXTERN napi_status napi_add_async_cleanup_hook( * `[in] hook`: The function pointer to call at environment teardown. * `[in] arg`: The pointer to pass to `hook` when it gets called. * `[out] remove_handle`: Optional handle that refers to the asynchronous cleanup -hook. + hook. Registers `hook`, which is a function of type [`napi_async_cleanup_hook`][], as a function to be run with the `remove_handle` and `arg` parameters once the @@ -1654,9 +1759,9 @@ is being torn down anyway. #### napi_remove_async_cleanup_hook @@ -1667,7 +1772,7 @@ NAPI_EXTERN napi_status napi_remove_async_cleanup_hook( ``` * `[in] remove_handle`: The handle to an asynchronous cleanup hook that was -created with [`napi_add_async_cleanup_hook`][]. + created with [`napi_add_async_cleanup_hook`][]. Unregisters the cleanup hook corresponding to `remove_handle`. This will prevent the hook from being executed, unless it has already started executing. @@ -1675,7 +1780,7 @@ This must be called on any `napi_async_cleanup_hook_handle` value obtained from [`napi_add_async_cleanup_hook`][]. ## Module registration -N-API modules are registered in a manner similar to other modules +Node-API modules are registered in a manner similar to other modules except that instead of using the `NODE_MODULE` macro the following is used: @@ -1683,7 +1788,7 @@ is used: NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) ``` -The next difference is the signature for the `Init` method. For a N-API +The next difference is the signature for the `Init` method. For a Node-API module it is as follows: ```c @@ -1693,8 +1798,8 @@ napi_value Init(napi_env env, napi_value exports); The return value from `Init` is treated as the `exports` object for the module. The `Init` method is passed an empty object via the `exports` parameter as a convenience. If `Init` returns `NULL`, the parameter passed as `exports` is -exported by the module. N-API modules cannot modify the `module` object but can -specify anything as the `exports` property of the module. +exported by the module. Node-API modules cannot modify the `module` object but +can specify anything as the `exports` property of the module. To add the method `hello` as a function so that it can be called as a method provided by the addon: @@ -1758,8 +1863,8 @@ napi_value Init(napi_env env, napi_value exports) { } ``` -If the module will be loaded multiple times during the lifetime of the Node.js -process, use the `NAPI_MODULE_INIT` macro to initialize the module: +You can also use the `NAPI_MODULE_INIT` macro, which acts as a shorthand +for `NAPI_MODULE` and defining an `Init` function: ```c NAPI_MODULE_INIT() { @@ -1776,13 +1881,9 @@ NAPI_MODULE_INIT() { } ``` -This macro includes `NAPI_MODULE`, and declares an `Init` function with a -special name and with visibility beyond the addon. This will allow Node.js to -initialize the module even if it is loaded multiple times. - -There are a few design considerations when declaring a module that may be loaded -multiple times. The documentation of [context-aware addons][] provides more -details. +All Node-API addons are context-aware, meaning they may be loaded multiple +times. There are a few design considerations when declaring such a module. +The documentation on [context-aware addons][] provides more details. The variables `env` and `exports` will be available inside the function body following the macro invocation. @@ -1794,19 +1895,19 @@ For more details on building addon modules in general, refer to the existing API. ## Working with JavaScript values -N-API exposes a set of APIs to create all types of JavaScript values. +Node-API exposes a set of APIs to create all types of JavaScript values. Some of these types are documented under [Section 6][] of the [ECMAScript Language Specification][]. Fundamentally, these APIs are used to do one of the following: 1. Create a new JavaScript object -2. Convert from a primitive C type to an N-API value -3. Convert from N-API value to a primitive C type +2. Convert from a primitive C type to a Node-API value +3. Convert from Node-API value to a primitive C type 4. Get global instances including `undefined` and `null` -N-API values are represented by the type `napi_value`. -Any N-API call that requires a JavaScript value takes in a `napi_value`. +Node-API values are represented by the type `napi_value`. +Any Node-API call that requires a JavaScript value takes in a `napi_value`. In some cases, the API does check the type of the `napi_value` up-front. However, for better performance, it's better for the caller to make sure that the `napi_value` in question is of the JavaScript type expected by the API. @@ -1814,7 +1915,9 @@ the `napi_value` in question is of the JavaScript type expected by the API. ### Enum types #### napi_key_collection_mode @@ -1835,7 +1938,9 @@ of the objects's prototype chain as well. #### napi_key_filter @@ -1854,7 +1959,9 @@ Property filter bits. They can be or'ed to build a composite filter. #### napi_key_conversion @@ -1928,12 +2035,12 @@ napiVersion: 1 napi_status napi_create_array(napi_env env, napi_value* result) ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[out] result`: A `napi_value` representing a JavaScript `Array`. Returns `napi_ok` if the API succeeded. -This API returns an N-API value corresponding to a JavaScript `Array` type. +This API returns a Node-API value corresponding to a JavaScript `Array` type. JavaScript arrays are described in [Section 22.1][] of the ECMAScript Language Specification. @@ -1955,7 +2062,7 @@ napi_status napi_create_array_with_length(napi_env env, Returns `napi_ok` if the API succeeded. -This API returns an N-API value corresponding to a JavaScript `Array` type. +This API returns a Node-API value corresponding to a JavaScript `Array` type. The `Array`'s length property is set to the passed-in length parameter. However, the underlying buffer is not guaranteed to be pre-allocated by the VM when the array is created. That behavior is left to the underlying VM @@ -1986,7 +2093,7 @@ napi_status napi_create_arraybuffer(napi_env env, Returns `napi_ok` if the API succeeded. -This API returns an N-API value corresponding to a JavaScript `ArrayBuffer`. +This API returns a Node-API value corresponding to a JavaScript `ArrayBuffer`. `ArrayBuffer`s are used to represent fixed-length binary data buffers. They are normally used as a backing-buffer for `TypedArray` objects. The `ArrayBuffer` allocated will have an underlying byte buffer whose size is @@ -2051,7 +2158,9 @@ structure, in most cases using a `TypedArray` will suffice. #### napi_create_date @@ -2143,7 +2252,7 @@ napi_create_external_arraybuffer(napi_env env, Returns `napi_ok` if the API succeeded. -This API returns an N-API value corresponding to a JavaScript `ArrayBuffer`. +This API returns a Node-API value corresponding to a JavaScript `ArrayBuffer`. The underlying byte buffer of the `ArrayBuffer` is externally allocated and managed. The caller must ensure that the byte buffer remains valid until the finalize callback is called. @@ -2235,14 +2344,14 @@ napi_status napi_create_symbol(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[in] description`: Optional `napi_value` which refers to a JavaScript - `String` to be set as the description for the symbol. -* `[out] result`: A `napi_value` representing a JavaScript `Symbol`. + `string` to be set as the description for the symbol. +* `[out] result`: A `napi_value` representing a JavaScript `symbol`. Returns `napi_ok` if the API succeeded. -This API creates a JavaScript `Symbol` object from a UTF8-encoded C string. +This API creates a JavaScript `symbol` value from a UTF8-encoded C string. -The JavaScript `Symbol` type is described in [Section 19.4][] +The JavaScript `symbol` type is described in [Section 19.4][] of the ECMAScript Language Specification. #### napi_create_typedarray @@ -2316,7 +2425,7 @@ raised. JavaScript `DataView` objects are described in [Section 24.3][] of the ECMAScript Language Specification. -### Functions to convert from C types to N-API +### Functions to convert from C types to Node-API #### napi_create_int32 @@ -2790,15 +2901,15 @@ napi_status napi_get_value_double(napi_env env, ``` * `[in] env`: The environment that the API is invoked under. -* `[in] value`: `napi_value` representing JavaScript `Number`. +* `[in] value`: `napi_value` representing JavaScript `number`. * `[out] result`: C double primitive equivalent of the given JavaScript - `Number`. + `number`. Returns `napi_ok` if the API succeeded. If a non-number `napi_value` is passed in it returns `napi_number_expected`. This API returns the C double primitive equivalent of the given JavaScript -`Number`. +`number`. #### napi_get_value_bigint_int64 @@ -3452,7 +3568,10 @@ defined in [Section 7.2.14][] of the ECMAScript Language Specification. ### napi_detach_arraybuffer @@ -3477,7 +3596,10 @@ defined in [Section 24.1.1.3][] of the ECMAScript Language Specification. ### napi_is_detached_arraybuffer @@ -3501,21 +3623,21 @@ Specification. ## Working with JavaScript properties -N-API exposes a set of APIs to get and set properties on JavaScript +Node-API exposes a set of APIs to get and set properties on JavaScript objects. Some of these types are documented under [Section 7][] of the [ECMAScript Language Specification][]. Properties in JavaScript are represented as a tuple of a key and a value. -Fundamentally, all property keys in N-API can be represented in one of the +Fundamentally, all property keys in Node-API can be represented in one of the following forms: * Named: a simple UTF8-encoded string * Integer-Indexed: an index value represented by `uint32_t` -* JavaScript value: these are represented in N-API by `napi_value`. This can - be a `napi_value` representing a `String`, `Number`, or `Symbol`. +* JavaScript value: these are represented in Node-API by `napi_value`. This can + be a `napi_value` representing a `string`, `number`, or `symbol`. -N-API values are represented by the type `napi_value`. -Any N-API call that requires a JavaScript value takes in a `napi_value`. +Node-API values are represented by the type `napi_value`. +Any Node-API call that requires a JavaScript value takes in a `napi_value`. However, it's the caller's responsibility to make sure that the `napi_value` in question is of the JavaScript type expected by the API. @@ -3530,7 +3652,7 @@ const obj = {}; obj.myProp = 123; ``` -The equivalent can be done using N-API values with the following snippet: +The equivalent can be done using Node-API values with the following snippet: ```c napi_status status = napi_generic_failure; @@ -3557,7 +3679,7 @@ const arr = []; arr[123] = 'hello'; ``` -The equivalent can be done using N-API values with the following snippet: +The equivalent can be done using Node-API values with the following snippet: ```c napi_status status = napi_generic_failure; @@ -3584,7 +3706,7 @@ const arr = []; const value = arr[123]; ``` -The following is the approximate equivalent of the N-API counterpart: +The following is the approximate equivalent of the Node-API counterpart: ```c napi_status status = napi_generic_failure; @@ -3610,7 +3732,7 @@ Object.defineProperties(obj, { }); ``` -The following is the approximate equivalent of the N-API counterpart: +The following is the approximate equivalent of the Node-API counterpart: ```c napi_status status = napi_status_generic_failure; @@ -3643,9 +3765,9 @@ if (status != napi_ok) return status; #### napi_property_attributes ```c @@ -3663,7 +3785,7 @@ typedef enum { napi_default_method = napi_writable | napi_configurable, // Default for object properties, like in JS obj[prop]. - napi_default_property = napi_writable | + napi_default_jsproperty = napi_writable | napi_enumerable | napi_configurable, } napi_property_attributes; @@ -3684,10 +3806,10 @@ They can be one or more of the following bitflags: * `napi_static`: The property will be defined as a static property on a class as opposed to an instance property, which is the default. This is used only by [`napi_define_class`][]. It is ignored by `napi_define_properties`. -* `napi_default_method`: The property is configureable, writeable but not - enumerable like a method in a JS class. -* `napi_default_property`: The property is writable, enumerable and configurable - like a property set via JS code `obj.key = value`. +* `napi_default_method`: Like a method in a JS class, the property is + configurable and writeable, but not enumerable. +* `napi_default_jsproperty`: Like a property set via assignment in JavaScript, + the property is writable, enumerable, and configurable. #### napi_property_descriptor @@ -3707,7 +3829,7 @@ typedef struct { } napi_property_descriptor; ``` -* `utf8name`: Optional `String` describing the key for the property, +* `utf8name`: Optional string describing the key for the property, encoded as UTF8. One of `utf8name` or `name` must be provided for the property. * `name`: Optional `napi_value` that points to a JavaScript string or symbol @@ -3720,12 +3842,12 @@ typedef struct { If this is passed in, set `value` and `method` to `NULL` (since these members won't be used). The given function is called implicitly by the runtime when the property is accessed from JavaScript code (or if a get on the property is - performed using a N-API call). [`napi_callback`][] provides more details. + performed using a Node-API call). [`napi_callback`][] provides more details. * `setter`: A function to call when a set access of the property is performed. If this is passed in, set `value` and `method` to `NULL` (since these members won't be used). The given function is called implicitly by the runtime when the property is set from JavaScript code (or if a set on the property is - performed using a N-API call). [`napi_callback`][] provides more details. + performed using a Node-API call). [`napi_callback`][] provides more details. * `method`: Set this to make the property descriptor object's `value` property to be a JavaScript function represented by `method`. If this is passed in, set `value`, `getter` and `setter` to `NULL` (since these members @@ -3748,7 +3870,7 @@ napi_status napi_get_property_names(napi_env env, napi_value* result); ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[in] object`: The object from which to retrieve the properties. * `[out] result`: A `napi_value` representing an array of JavaScript values that represent the property names of the object. The API can be used to @@ -3763,7 +3885,9 @@ included. #### napi_get_all_property_names @@ -3776,15 +3900,15 @@ napi_get_all_property_names(napi_env env, napi_value* result); ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[in] object`: The object from which to retrieve the properties. * `[in] key_mode`: Whether to retrieve prototype properties as well. * `[in] key_filter`: Which properties to retrieve -(enumerable/readable/writable). + (enumerable/readable/writable). * `[in] key_conversion`: Whether to convert numbered property keys to strings. * `[out] result`: A `napi_value` representing an array of JavaScript values -that represent the property names of the object. [`napi_get_array_length`][] and -[`napi_get_element`][] can be used to iterate over `result`. + that represent the property names of the object. [`napi_get_array_length`][] + and [`napi_get_element`][] can be used to iterate over `result`. Returns `napi_ok` if the API succeeded. @@ -3804,7 +3928,7 @@ napi_status napi_set_property(napi_env env, napi_value value); ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[in] object`: The object on which to set the property. * `[in] key`: The name of the property to set. * `[in] value`: The property value. @@ -3826,7 +3950,7 @@ napi_status napi_get_property(napi_env env, napi_value* result); ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[in] object`: The object from which to retrieve the property. * `[in] key`: The name of the property to retrieve. * `[out] result`: The value of the property. @@ -3848,7 +3972,7 @@ napi_status napi_has_property(napi_env env, bool* result); ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[in] object`: The object to query. * `[in] key`: The name of the property whose existence to check. * `[out] result`: Whether the property exists on the object or not. @@ -3870,7 +3994,7 @@ napi_status napi_delete_property(napi_env env, bool* result); ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[in] object`: The object to query. * `[in] key`: The name of the property to delete. * `[out] result`: Whether the property deletion succeeded or not. `result` can @@ -3893,7 +4017,7 @@ napi_status napi_has_own_property(napi_env env, bool* result); ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[in] object`: The object to query. * `[in] key`: The name of the own property whose existence to check. * `[out] result`: Whether the own property exists on the object or not. @@ -3901,8 +4025,8 @@ napi_status napi_has_own_property(napi_env env, Returns `napi_ok` if the API succeeded. This API checks if the `Object` passed in has the named own property. `key` must -be a string or a `Symbol`, or an error will be thrown. N-API will not perform -any conversion between data types. +be a `string` or a `symbol`, or an error will be thrown. Node-API will not +perform any conversion between data types. #### napi_set_named_property @@ -4101,7 +4227,7 @@ napi_status napi_object_freeze(napi_env env, napi_value object); ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[in] object`: The object to freeze. Returns `napi_ok` if the API succeeded. @@ -4116,7 +4242,9 @@ ECMA-262 specification. #### napi_object_seal @@ -4125,7 +4253,7 @@ napi_status napi_object_seal(napi_env env, napi_value object); ``` -* `[in] env`: The environment that the N-API call is invoked under. +* `[in] env`: The environment that the Node-API call is invoked under. * `[in] object`: The object to seal. Returns `napi_ok` if the API succeeded. @@ -4137,8 +4265,8 @@ of the ECMA-262 specification. ## Working with JavaScript functions -N-API provides a set of APIs that allow JavaScript code to -call back into native code. N-API APIs that support calling back +Node-API provides a set of APIs that allow JavaScript code to +call back into native code. Node-APIs that support calling back into native code take in a callback functions represented by the `napi_callback` type. When the JavaScript VM calls back to native code, the `napi_callback` function provided is invoked. The APIs @@ -4149,7 +4277,7 @@ following: * Get the arguments passed into the callback. * Return a `napi_value` back from the callback. -Additionally, N-API provides a set of functions which allow calling +Additionally, Node-API provides a set of functions which allow calling JavaScript functions from native code. One can either call a function like a regular JavaScript function call, or as a constructor function. @@ -4175,7 +4303,7 @@ NAPI_EXTERN napi_status napi_call_function(napi_env env, ``` * `[in] env`: The environment that the API is invoked under. -* `[in] recv`: The `this` object passed to the called function. +* `[in] recv`: The `this` value passed to the called function. * `[in] func`: `napi_value` representing the JavaScript function to be invoked. * `[in] argc`: The count of elements in the `argv` array. * `[in] argv`: Array of `napi_values` representing JavaScript values passed in @@ -4326,8 +4454,8 @@ napi_status napi_get_cb_info(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[in] cbinfo`: The callback info passed into the callback function. -* `[in-out] argc`: Specifies the size of the provided `argv` array and receives - the actual count of arguments. +* `[in-out] argc`: Specifies the length of the provided `argv` array and + receives the actual count of arguments. * `[out] argv`: Buffer to which the `napi_value` representing the arguments are copied. If there are more arguments than the provided count, only the requested number of arguments are copied. If there are fewer arguments @@ -4398,7 +4526,7 @@ const arg = 'hello'; const value = new MyObject(arg); ``` -The following can be approximated in N-API using the following snippet: +The following can be approximated in Node-API using the following snippet: ```c // Get the constructor function MyObject @@ -4424,7 +4552,7 @@ Returns `napi_ok` if the API succeeded. ## Object wrap -N-API offers a way to "wrap" C++ classes and instances so that the class +Node-API offers a way to "wrap" C++ classes and instances so that the class constructor and methods can be called from JavaScript. 1. The [`napi_define_class`][] API defines a JavaScript class with constructor, @@ -4511,9 +4639,9 @@ case, the database handle instance can appear as a query handle instance, and it will pass the `napi_instanceof()` test for a query handle instance, while still containing a pointer to a database handle. -To this end, N-API provides type-tagging capabilities. +To this end, Node-API provides type-tagging capabilities. -A type tag is a 128-bit integer unique to the addon. N-API provides the +A type tag is a 128-bit integer unique to the addon. Node-API provides the `napi_type_tag` structure for storing a type tag. When such a value is passed along with a JavaScript object stored in a `napi_value` to `napi_type_tag_object()`, the JavaScript object will be "marked" with the @@ -4614,14 +4742,15 @@ napi_status napi_define_class(napi_env env, ``` * `[in] env`: The environment that the API is invoked under. -* `[in] utf8name`: Name of the JavaScript constructor function; this is - not required to be the same as the C++ class name, though it is recommended - for clarity. +* `[in] utf8name`: Name of the JavaScript constructor function; When wrapping a + C++ class, we recommend for clarity that this name be the same as that of + the C++ class. * `[in] length`: The length of the `utf8name` in bytes, or `NAPI_AUTO_LENGTH` if it is null-terminated. * `[in] constructor`: Callback function that handles constructing instances - of the class. This should be a static method on the class, not an actual - C++ constructor function. [`napi_callback`][] provides more details. + of the class. When wrapping a C++ class, this method must be a static member + with the [`napi_callback`][] signature. A C++ class constructor cannot be + used. [`napi_callback`][] provides more details. * `[in] data`: Optional data to be passed to the constructor callback as the `data` property of the callback info. * `[in] property_count`: Number of items in the `properties` array argument. @@ -4633,27 +4762,33 @@ napi_status napi_define_class(napi_env env, Returns `napi_ok` if the API succeeded. -Defines a JavaScript class that corresponds to a C++ class, including: - -* A JavaScript constructor function that has the class name and invokes the - provided C++ constructor callback. -* Properties on the constructor function corresponding to _static_ data - properties, accessors, and methods of the C++ class (defined by - property descriptors with the `napi_static` attribute). -* Properties on the constructor function's `prototype` object corresponding to - _non-static_ data properties, accessors, and methods of the C++ class - (defined by property descriptors without the `napi_static` attribute). - -The C++ constructor callback should be a static method on the class that calls -the actual class constructor, then wraps the new C++ instance in a JavaScript -object, and returns the wrapper object. See `napi_wrap()` for details. +Defines a JavaScript class, including: + +* A JavaScript constructor function that has the class name. When wrapping a + corresponding C++ class, the callback passed via `constructor` can be used to + instantiate a new C++ class instance, which can then be placed inside the + JavaScript object instance being constructed using [`napi_wrap`][]. +* Properties on the constructor function whose implementation can call + corresponding _static_ data properties, accessors, and methods of the C++ + class (defined by property descriptors with the `napi_static` attribute). +* Properties on the constructor function's `prototype` object. When wrapping a + C++ class, _non-static_ data properties, accessors, and methods of the C++ + class can be called from the static functions given in the property + descriptors without the `napi_static` attribute after retrieving the C++ class + instance placed inside the JavaScript object instance by using + [`napi_unwrap`][]. + +When wrapping a C++ class, the C++ constructor callback passed via `constructor` +should be a static method on the class that calls the actual class constructor, +then wraps the new C++ instance in a JavaScript object, and returns the wrapper +object. See [`napi_wrap`][] for details. The JavaScript constructor function returned from [`napi_define_class`][] is -often saved and used later, to construct new instances of the class from native -code, and/or check whether provided values are instances of the class. In that -case, to prevent the function value from being garbage-collected, create a -persistent reference to it using [`napi_create_reference`][] and ensure the -reference count is kept >= 1. +often saved and used later to construct new instances of the class from native +code, and/or to check whether provided values are instances of the class. In +that case, to prevent the function value from being garbage-collected, a +strong persistent reference to it can be created using +[`napi_create_reference`][], ensuring that the reference count is kept >= 1. Any non-`NULL` data which is passed to this API via the `data` parameter or via the `data` field of the `napi_property_descriptor` array items can be associated @@ -4771,7 +4906,9 @@ JavaScript object becomes garbage-collected. ### napi_type_tag_object @@ -4797,7 +4934,9 @@ If the object already has an associated type tag, this API will return ### napi_check_object_type_tag @@ -4812,7 +4951,7 @@ napi_status napi_check_object_type_tag(napi_env env, * `[in] js_object`: The JavaScript object whose type tag to examine. * `[in] type_tag`: The tag with which to compare any tag found on the object. * `[out] result`: Whether the type tag given matched the type tag on the -object. `false` is also returned if no type tag was found on the object. + object. `false` is also returned if no type tag was found on the object. Returns `napi_ok` if the API succeeded. @@ -4874,10 +5013,10 @@ implementation. This allows them to schedule work to be executed asynchronously so that their methods can return in advance of the work being completed. This allows them to avoid blocking overall execution of the Node.js application. -N-API provides an ABI-stable interface for these +Node-API provides an ABI-stable interface for these supporting functions which covers the most common asynchronous use cases. -N-API defines the `napi_async_work` structure which is used to manage +Node-API defines the `napi_async_work` structure which is used to manage asynchronous workers. Instances are created/deleted with [`napi_create_async_work`][] and [`napi_delete_async_work`][]. @@ -4885,9 +5024,9 @@ The `execute` and `complete` callbacks are functions that will be invoked when the executor is ready to execute and when it completes its task respectively. -The `execute` function should avoid making any N-API calls +The `execute` function should avoid making any Node-API calls that could result in the execution of JavaScript or interaction with -JavaScript objects. Most often, any code that needs to make N-API +JavaScript objects. Most often, any code that needs to make Node-API calls should be made in `complete` callback instead. Avoid using the `napi_env` parameter in the execute callback as it will likely execute JavaScript. @@ -5059,19 +5198,31 @@ napi_status napi_async_init(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[in] async_resource`: Object associated with the async work - that will be passed to possible `async_hooks` [`init` hooks][]. - In order to retain ABI compatibility with previous versions, - passing `NULL` for `async_resource` will not result in an error, however, - this will result incorrect operation of async hooks for the - napi_async_context created. Potential issues include - loss of async context when using the AsyncLocalStorage API. -* `[in] async_resource_name`: Identifier for the kind of resource - that is being provided for diagnostic information exposed by the - `async_hooks` API. + that will be passed to possible `async_hooks` [`init` hooks][] and can be + accessed by [`async_hooks.executionAsyncResource()`][]. +* `[in] async_resource_name`: Identifier for the kind of resource that is being + provided for diagnostic information exposed by the `async_hooks` API. * `[out] result`: The initialized async context. Returns `napi_ok` if the API succeeded. +The `async_resource` object needs to be kept alive until +[`napi_async_destroy`][] to keep `async_hooks` related API acts correctly. In +order to retain ABI compatibility with previous versions, `napi_async_context`s +are not maintaining the strong reference to the `async_resource` objects to +avoid introducing causing memory leaks. However, if the `async_resource` is +garbage collected by JavaScript engine before the `napi_async_context` was +destroyed by `napi_async_destroy`, calling `napi_async_context` related APIs +like [`napi_open_callback_scope`][] and [`napi_make_callback`][] can cause +problems like loss of async context when using the `AsyncLocalStoage` API. + +In order to retain ABI compatibility with previous versions, passing `NULL` +for `async_resource` does not result in an error. However, this is not +recommended as this will result poor results with `async_hooks` +[`init` hooks][] and `async_hooks.executionAsyncResource()` as the resource is +now required by the underlying `async_hooks` implementation in order to provide +the linkage between async callbacks. + ### napi_async_destroy @@ -5112,10 +5264,12 @@ NAPI_EXTERN napi_status napi_make_callback(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[in] async_context`: Context for the async operation that is invoking the callback. This should normally be a value previously - obtained from [`napi_async_init`][]. However `NULL` is also allowed, - which indicates the current async context (if any) is to be used - for the callback. -* `[in] recv`: The `this` object passed to the called function. + obtained from [`napi_async_init`][]. + In order to retain ABI compatibility with previous versions, passing `NULL` + for `async_context` does not result in an error. However, this results + in incorrect operation of async hooks. Potential issues include loss of + async context when using the `AsyncLocalStorage` API. +* `[in] recv`: The `this` value passed to the called function. * `[in] func`: `napi_value` representing the JavaScript function to be invoked. * `[in] argc`: The count of elements in the `argv` array. * `[in] argv`: Array of JavaScript values as `napi_value` representing the @@ -5155,14 +5309,16 @@ NAPI_EXTERN napi_status napi_open_callback_scope(napi_env env, * `[in] env`: The environment that the API is invoked under. * `[in] resource_object`: An object associated with the async work - that will be passed to possible `async_hooks` [`init` hooks][]. + that will be passed to possible `async_hooks` [`init` hooks][]. This + parameter has been deprecated and is ignored at runtime. Use the + `async_resource` parameter in [`napi_async_init`][] instead. * `[in] context`: Context for the async operation that is invoking the callback. This should be a value previously obtained from [`napi_async_init`][]. * `[out] result`: The newly created scope. There are cases (for example, resolving promises) where it is necessary to have the equivalent of the scope associated with a callback -in place when making certain N-API calls. If there is no other script on +in place when making certain Node-API calls. If there is no other script on the stack the [`napi_open_callback_scope`][] and [`napi_close_callback_scope`][] functions can be used to open/close the required scope. @@ -5226,12 +5382,12 @@ napi_status napi_get_version(napi_env env, ``` * `[in] env`: The environment that the API is invoked under. -* `[out] result`: The highest version of N-API supported. +* `[out] result`: The highest version of Node-API supported. Returns `napi_ok` if the API succeeded. -This API returns the highest N-API version supported by the -Node.js runtime. N-API is planned to be additive such that +This API returns the highest Node-API version supported by the +Node.js runtime. Node-API is planned to be additive such that newer releases of Node.js may support additional API functions. In order to allow an addon to use a newer function when running with versions of Node.js that support it, while providing @@ -5273,7 +5429,7 @@ often than it would otherwise. ## Promises -N-API provides facilities for creating `Promise` objects as described in +Node-API provides facilities for creating `Promise` objects as described in [Section 25.4][] of the ECMA specification. It implements promises as a pair of objects. When a promise is created by `napi_create_promise()`, a "deferred" object is created and returned alongside the `Promise`. The deferred object is @@ -5418,7 +5574,7 @@ napi_status napi_is_promise(napi_env env, ## Script execution -N-API provides an API for executing a string containing JavaScript using the +Node-API provides an API for executing a string containing JavaScript using the underlying JavaScript engine. ### napi_run_script @@ -5452,14 +5608,14 @@ the following caveats: ## libuv event loop -N-API provides a function for getting the current event loop associated with +Node-API provides a function for getting the current event loop associated with a specific `napi_env`. ### napi_get_uv_event_loop @@ -5474,7 +5630,7 @@ NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env, ## Asynchronous thread-safe function calls JavaScript functions can normally only be called from a native addon's main -thread. If an addon creates additional threads, then N-API functions that +thread. If an addon creates additional threads, then Node-API functions that require a `napi_env`, `napi_value`, or `napi_ref` must not be called from those threads. @@ -5515,6 +5671,10 @@ preventing data from being successfully added to the queue. If set to `napi_call_threadsafe_function()` never blocks if the thread-safe function was created with a maximum queue size of 0. +`napi_call_threadsafe_function()` should not be called with `napi_tsfn_blocking` +from a JavaScript thread, because, if the queue is full, it may cause the +JavaScript thread to deadlock. + The actual call into JavaScript is controlled by the callback given via the `call_js_cb` parameter. `call_js_cb` is invoked on the main thread once for each value that was placed into the queue by a successful call to @@ -5532,7 +5692,7 @@ remain in the queue that may need to be freed. This normally occurs when the Node.js process exits while there is a thread-safe function still active. It is not necessary to call into JavaScript via `napi_make_callback()` because -N-API runs `call_js_cb` in a context appropriate for callbacks. +Node-API runs `call_js_cb` in a context appropriate for callbacks. ### Reference counting of thread-safe functions @@ -5597,7 +5757,9 @@ being destroyed. added: v10.6.0 napiVersion: 4 changes: - - version: v12.6.0 + - version: + - v12.6.0 + - v10.17.0 pr-url: https://github.com/nodejs/node/pull/27791 description: Made `func` parameter optional with custom `call_js_cb`. --> @@ -5664,6 +5826,15 @@ This API may be called from any thread which makes use of `func`. ```c @@ -5681,6 +5852,10 @@ napi_call_threadsafe_function(napi_threadsafe_function func, `napi_tsfn_nonblocking` to indicate that the call should return immediately with a status of `napi_queue_full` whenever the queue is full. +This API should not be called with `napi_tsfn_blocking` from a JavaScript +thread, because, if the queue is full, it may cause the JavaScript thread to +deadlock. + This API will return `napi_closing` if `napi_release_threadsafe_function()` was called with `abort` set to `napi_tsfn_abort` from any thread. The value is only added to the queue if the API returns `napi_ok`. @@ -5790,7 +5965,7 @@ This API may only be called from the main thread. ## node_api_get_module_file_name > Stability: 1 - Experimental @@ -5812,9 +5987,9 @@ the add-on's file name during loading. [ABI Stability]: https://nodejs.org/en/docs/guides/abi-stability/ [AppVeyor]: https://www.appveyor.com -[C++ Addons]: addons.html -[CMake.js]: https://github.com/cmake-js/cmake-js +[C++ Addons]: addons.md [CMake]: https://cmake.org +[CMake.js]: https://github.com/cmake-js/cmake-js [ECMAScript Language Specification]: https://tc39.github.io/ecma262/ [Error handling]: #n_api_error_handling [GCC]: https://gcc.gnu.org @@ -5829,42 +6004,44 @@ the add-on's file name during loading. [Section 19.2]: https://tc39.github.io/ecma262/#sec-function-objects [Section 19.4]: https://tc39.github.io/ecma262/#sec-symbol-objects [Section 20.3]: https://tc39.github.io/ecma262/#sec-date-objects -[Section 22.1.4.1]: https://tc39.github.io/ecma262/#sec-properties-of-array-instances-length [Section 22.1]: https://tc39.github.io/ecma262/#sec-array-objects +[Section 22.1.4.1]: https://tc39.github.io/ecma262/#sec-properties-of-array-instances-length [Section 22.2]: https://tc39.github.io/ecma262/#sec-typedarray-objects [Section 24.1]: https://tc39.github.io/ecma262/#sec-arraybuffer-objects +[Section 24.1.1.2]: https://tc39.es/ecma262/#sec-isdetachedbuffer [Section 24.1.1.3]: https://tc39.es/ecma262/#sec-detacharraybuffer [Section 24.3]: https://tc39.github.io/ecma262/#sec-dataview-objects [Section 25.4]: https://tc39.github.io/ecma262/#sec-promise-objects +[Section 6]: https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values +[Section 6.1]: https://tc39.github.io/ecma262/#sec-ecmascript-language-types [Section 6.1.4]: https://tc39.github.io/ecma262/#sec-ecmascript-language-types-string-type [Section 6.1.6]: https://tc39.github.io/ecma262/#sec-ecmascript-language-types-number-type -[Section 6.1.7.1]: https://tc39.github.io/ecma262/#table-2 [Section 6.1.7]: https://tc39.github.io/ecma262/#sec-object-type -[Section 6.1]: https://tc39.github.io/ecma262/#sec-ecmascript-language-types -[Section 6]: https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values +[Section 6.1.7.1]: https://tc39.github.io/ecma262/#table-2 +[Section 7]: https://tc39.github.io/ecma262/#sec-abstract-operations [Section 7.1.13]: https://tc39.github.io/ecma262/#sec-toobject [Section 7.1.2]: https://tc39.github.io/ecma262/#sec-toboolean [Section 7.1.3]: https://tc39.github.io/ecma262/#sec-tonumber [Section 7.2.14]: https://tc39.github.io/ecma262/#sec-strict-equality-comparison [Section 7.2.2]: https://tc39.github.io/ecma262/#sec-isarray -[Section 7]: https://tc39.github.io/ecma262/#sec-abstract-operations [Section 8.7]: https://tc39.es/ecma262/#sec-agents [Section 9.1.6]: https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc -[Section 24.1.1.2]: https://tc39.es/ecma262/#sec-isdetachedbuffer [Travis CI]: https://travis-ci.org [Visual Studio]: https://visualstudio.microsoft.com [Working with JavaScript properties]: #n_api_working_with_javascript_properties [Xcode]: https://developer.apple.com/xcode/ [`Number.MAX_SAFE_INTEGER`]: https://tc39.github.io/ecma262/#sec-number.max_safe_integer [`Number.MIN_SAFE_INTEGER`]: https://tc39.github.io/ecma262/#sec-number.min_safe_integer -[`Worker`]: worker_threads.html#worker_threads_class_worker -[`global`]: globals.html#globals_global -[`init` hooks]: async_hooks.html#async_hooks_init_asyncid_type_triggerasyncid_resource +[`Worker`]: worker_threads.md#worker_threads_class_worker +[`async_hooks.executionAsyncResource()`]: async_hooks.md#async_hooks_async_hooks_executionasyncresource +[`global`]: globals.md#globals_global +[`init` hooks]: async_hooks.md#async_hooks_init_asyncid_type_triggerasyncid_resource [`napi_add_async_cleanup_hook`]: #n_api_napi_add_async_cleanup_hook [`napi_add_env_cleanup_hook`]: #n_api_napi_add_env_cleanup_hook [`napi_add_finalizer`]: #n_api_napi_add_finalizer [`napi_async_cleanup_hook`]: #n_api_napi_async_cleanup_hook [`napi_async_complete_callback`]: #n_api_napi_async_complete_callback +[`napi_async_destroy`]: #n_api_napi_async_destroy [`napi_async_init`]: #n_api_napi_async_init [`napi_callback`]: #n_api_napi_callback [`napi_cancel_async_work`]: #n_api_napi_cancel_async_work @@ -5914,15 +6091,16 @@ the add-on's file name during loading. [`napi_unwrap`]: #n_api_napi_unwrap [`napi_wrap`]: #n_api_napi_wrap [`node-addon-api`]: https://github.com/nodejs/node-addon-api -[`node_api.h`]: https://github.com/nodejs/node/blob/master/src/node_api.h -[`process.release`]: process.html#process_process_release +[`node_api.h`]: https://github.com/nodejs/node/blob/HEAD/src/node_api.h +[`process.release`]: process.md#process_process_release [`uv_ref`]: https://docs.libuv.org/en/v1.x/handle.html#c.uv_ref [`uv_unref`]: https://docs.libuv.org/en/v1.x/handle.html#c.uv_unref -[async_hooks `type`]: async_hooks.html#async_hooks_type -[context-aware addons]: addons.html#addons_context_aware_addons +[async_hooks `type`]: async_hooks.md#async_hooks_type +[context-aware addons]: addons.md#addons_context_aware_addons [docs]: https://github.com/nodejs/node-addon-api#api-documentation -[global scope]: globals.html -[module scope]: modules.html#modules_the_module_scope +[global scope]: globals.md +[gyp-next]: https://github.com/nodejs/gyp-next +[module scope]: modules.md#modules_the_module_scope [node-gyp]: https://github.com/nodejs/node-gyp [node-pre-gyp]: https://github.com/mapbox/node-pre-gyp [prebuild]: https://github.com/prebuild/prebuild diff --git a/doc/api/net.html b/doc/api/net.html index 72255febf5a41adfedfca8b4bdcb0b9850c9a63b..cee3e68f8b93b2728b3407f1457fb22de0dd5bf8 100644 --- a/doc/api/net.html +++ b/doc/api/net.html @@ -1,10 +1,10 @@ - + - - Net | Node.js v12.22.7 Documentation + + Net | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
                        • Assertion testing
                        • Async hooks
                        • Buffer
                        • -
                        • C++ Addons
                        • -
                        • C/C++ Addons with N-API
                        • -
                        • C++ Embedder API
                        • -
                        • Child Processes
                        • +
                        • C++ addons
                        • +
                        • C/C++ addons with Node-API
                        • +
                        • C++ embedder API
                        • +
                        • Child processes
                        • Cluster
                        • -
                        • Command line options
                        • +
                        • Command-line options
                        • Console
                        • Crypto
                        • Debugger
                        • Deprecated APIs
                        • +
                        • Diagnostics Channel
                        • DNS
                        • Domain
                        • Errors
                        • @@ -86,7 +87,20 @@
                        -

                        Net#

                        +

                        Net#

                        Stability: 2 - Stable

                        -

                        Source Code: lib/net.js

                        +

                        Source Code: lib/net.js

                        The net module provides an asynchronous network API for creating stream-based TCP or IPC servers (net.createServer()) and clients (net.createConnection()).

                        It can be accessed using:

                        const net = require('net');
                        -

                        IPC support#

                        +

                        IPC support#

                        The net module supports IPC with named pipes on Windows, and Unix domain sockets on other operating systems.

                        -

                        Identifying paths for IPC connections#

                        +

                        Identifying paths for IPC connections#

                        net.connect(), net.createConnection(), server.listen() and socket.connect() take a path parameter to identify IPC endpoints.

                        On Unix, the local domain is also known as the Unix domain. The path is a @@ -263,9 +295,128 @@ Unlike Unix domain sockets, Windows will close and remove the pipe when the owning process exits.

                        JavaScript string escaping requires paths to be specified with extra backslash escaping such as:

                        -
                        net.createServer().listen(
                        -  path.join('\\\\?\\pipe', process.cwd(), 'myctl'));
                        -

                        Class: net.Server#

                        +
                        net.createServer().listen(
                        +  path.join('\\\\?\\pipe', process.cwd(), 'myctl'));
                        +

                        Class: net.BlockList#

                        + +

                        The BlockList object can be used with some network APIs to specify rules for +disabling inbound or outbound access to specific IP addresses, IP ranges, or +IP subnets.

                        +

                        blockList.addAddress(address[, type])#

                        + + +

                        Adds a rule to block the given IP address.

                        +

                        blockList.addRange(start, end[, type])#

                        + + +

                        Adds a rule to block a range of IP addresses from start (inclusive) to +end (inclusive).

                        +

                        blockList.addSubnet(net, prefix[, type])#

                        + +
                          +
                        • net <string> | <net.SocketAddress> The network IPv4 or IPv6 address.
                        • +
                        • prefix <number> The number of CIDR prefix bits. For IPv4, this +must be a value between 0 and 32. For IPv6, this must be between +0 and 128.
                        • +
                        • type <string> Either 'ipv4' or 'ipv6'. Default: 'ipv4'.
                        • +
                        +

                        Adds a rule to block a range of IP addresses specified as a subnet mask.

                        +

                        blockList.check(address[, type])#

                        + + +

                        Returns true if the given IP address matches any of the rules added to the +BlockList.

                        +
                        const blockList = new net.BlockList();
                        +blockList.addAddress('123.123.123.123');
                        +blockList.addRange('10.0.0.1', '10.0.0.10');
                        +blockList.addSubnet('8592:757c:efae:4e45::', 64, 'ipv6');
                        +
                        +console.log(blockList.check('123.123.123.123'));  // Prints: true
                        +console.log(blockList.check('10.0.0.3'));  // Prints: true
                        +console.log(blockList.check('222.111.111.222'));  // Prints: false
                        +
                        +// IPv6 notation for IPv4 addresses works:
                        +console.log(blockList.check('::ffff:7b7b:7b7b', 'ipv6')); // Prints: true
                        +console.log(blockList.check('::ffff:123.123.123.123', 'ipv6')); // Prints: true
                        +

                        blockList.rules#

                        + + +

                        The list of rules added to the blocklist.

                        +

                        Class: net.SocketAddress#

                        + +

                        new net.SocketAddress([options])#

                        + +
                          +
                        • options <Object> +
                            +
                          • address <string> The network address as either an IPv4 or IPv6 string. +Default: '127.0.0.1' if family is 'ipv4'; '::' if family is +'ipv6'.
                          • +
                          • family <string> One of either 'ipv4' or 'ipv6'. **Default**: 'ipv4'`.
                          • +
                          • flowlabel <number> An IPv6 flow-label used only if family is 'ipv6'.
                          • +
                          • port <number> An IP port.
                          • +
                          +
                        • +
                        +

                        socketaddress.address#

                        + + +

                        socketaddress.family#

                        + +
                          +
                        • Type <string> Either 'ipv4' or 'ipv6'.
                        • +
                        +

                        socketaddress.flowlabel#

                        + + +

                        socketaddress.port#

                        + + +

                        Class: net.Server#

                        @@ -273,7 +424,7 @@ escaping such as:

                      • Extends: <EventEmitter>

                      This class is used to create a TCP or IPC server.

                      -

                      new net.Server([options][, connectionListener])#

                      +

                      new net.Server([options][, connectionListener])#

                      net.Server is an EventEmitter with the following events:

                      -

                      Event: 'close'#

                      +

                      Event: 'close'#

                      Emitted when the server closes. If connections exist, this event is not emitted until all connections are ended.

                      -

                      Event: 'connection'#

                      +

                      Event: 'connection'#

                      @@ -297,7 +448,7 @@ event is not emitted until all connections are ended.

                    Emitted when a new connection is made. socket is an instance of net.Socket.

                    -

                    Event: 'error'#

                    +

                    Event: 'error'#

                    @@ -308,12 +459,12 @@ event is not emitted until all connections are ended.

                    event will not be emitted directly following this event unless server.close() is manually called. See the example in discussion of server.listen().

                    -

                    Event: 'listening'#

                    +

                    Event: 'listening'#

                    Emitted when the server has been bound after calling server.listen().

                    -

                    server.address()#

                    +

                    server.address()#

                    @@ -326,20 +477,20 @@ as reported by the operating system if listening on an IP socket { port: 12346, family: 'IPv4', address: '127.0.0.1' }.

                    For a server listening on a pipe or Unix domain socket, the name is returned as a string.

                    -
                    const server = net.createServer((socket) => {
                    -  socket.end('goodbye\n');
                    -}).on('error', (err) => {
                    +
                    const server = net.createServer((socket) => {
                    +  socket.end('goodbye\n');
                    +}).on('error', (err) => {
                       // Handle errors here.
                       throw err;
                     });
                     
                     // Grab an arbitrary unused port.
                    -server.listen(() => {
                    -  console.log('opened server on', server.address());
                    +server.listen(() => {
                    +  console.log('opened server on', server.address());
                     });

                    server.address() returns null before the 'listening' event has been emitted or after calling server.close().

                    -

                    server.close([callback])#

                    +

                    server.close([callback])#

                    @@ -353,7 +504,7 @@ when all connections are ended and the server emits a callback
                    will be called once the 'close' event occurs. Unlike that event, it will be called with an Error as its only argument if the server was not open when it was closed.

                    -

                    server.connections#

                    +

                    server.connections#

                    @@ -365,7 +516,7 @@ was not open when it was closed.

                    This becomes null when sending a socket to a child with child_process.fork(). To poll forks and get current number of active connections, use asynchronous server.getConnections() instead.

                    -

                    server.getConnections(callback)#

                    +

                    server.getConnections(callback)#

                    @@ -376,10 +527,11 @@ connections, use asynchronous Asynchronously get the number of concurrent connections on the server. Works when sockets were sent to forks.

                    Callback should take two arguments err and count.

                    -

                    server.listen()#

                    +

                    server.listen()#

                    Start a server listening for connections. A net.Server can be a TCP or an IPC server depending on what it listens to.

                    Possible signatures:

                    + +

                    This function is asynchronous. When the server starts listening, the 'listening' event will be emitted. The last parameter callback will be added as a listener for the 'listening' event.

                    @@ -407,16 +560,16 @@ called. Otherwise, an ERR_SERVER_ALREADY_LISTEN error will be throw This happens when another server is already listening on the requested port/path/handle. One way to handle this would be to retry after a certain amount of time:

                    -
                    server.on('error', (e) => {
                    -  if (e.code === 'EADDRINUSE') {
                    -    console.log('Address in use, retrying...');
                    +
                    server.on('error', (e) => {
                    +  if (e.code === 'EADDRINUSE') {
                    +    console.log('Address in use, retrying...');
                         setTimeout(() => {
                    -      server.close();
                    -      server.listen(PORT, HOST);
                    +      server.close();
                    +      server.listen(PORT, HOST);
                         }, 1000);
                       }
                     });
                    -

                    server.listen(handle[, backlog][, callback])#

                    +
                    server.listen(handle[, backlog][, callback])#
                    @@ -432,7 +585,7 @@ already been bound to a port, a Unix domain socket, or a Windows named pipe.

                    underlying _handle member), or an object with an fd member that is a valid file descriptor.

                    Listening on a file descriptor is not supported on Windows.

                    -

                    server.listen(options[, callback])#

                    +
                    server.listen(options[, callback])#
                    • enable <boolean> Default: false
                    • @@ -995,7 +1160,14 @@ delay before the first keepalive probe is sent on an idle socket.

                      data packet received and the first keepalive probe. Setting 0 for initialDelay will leave the value unchanged from the default (or previous) setting.

                      -

                      socket.setNoDelay([noDelay])#

                      +

                      Enabling the keep-alive functionality will set the following socket options:

                      +
                        +
                      • SO_KEEPALIVE=1
                      • +
                      • TCP_KEEPIDLE=initialDelay
                      • +
                      • TCP_KEEPCNT=10
                      • +
                      • TCP_KEEPINTVL=1
                      • +
                      +

                      socket.setNoDelay([noDelay])#

                      @@ -1010,7 +1182,7 @@ to optimize throughput at the expense of latency.

                      Passing true for noDelay or not passing an argument will disable Nagle's algorithm for the socket. Passing false for noDelay will enable Nagle's algorithm.

                      -

                      socket.setTimeout(timeout[, callback])#

                      +

                      socket.setTimeout(timeout[, callback])#

                      @@ -1024,15 +1196,24 @@ the socket. By default net.Socket do not have a timeout.

                      When an idle timeout is triggered the socket will receive a 'timeout' event but the connection will not be severed. The user must manually call socket.end() or socket.destroy() to end the connection.

                      -
                      socket.setTimeout(3000);
                      -socket.on('timeout', () => {
                      -  console.log('socket timeout');
                      -  socket.end();
                      +
                      socket.setTimeout(3000);
                      +socket.on('timeout', () => {
                      +  console.log('socket timeout');
                      +  socket.end();
                       });

                      If timeout is 0, then the existing idle timeout is disabled.

                      The optional callback parameter will be added as a one-time listener for the 'timeout' event.

                      -

                      socket.unref()#

                      +

                      socket.timeout#

                      + + +

                      The socket timeout in milliseconds as set by socket.setTimeout(). +It is undefined if a timeout has not been set.

                      +

                      socket.unref()#

                      @@ -1042,7 +1223,7 @@ socket.on('timeout', # +

                      socket.write(data[, encoding][, callback])#

                      @@ -1061,7 +1242,21 @@ buffer. Returns false if all or part of the data was queued in user written out, which may not be immediately.

                      See Writable stream write() method for more information.

                      -

                      net.connect()#

                      +

                      socket.readyState#

                      + + +

                      This property represents the state of the connection as a string.

                      +
                        +
                      • If the stream is connecting socket.readyState is opening.
                      • +
                      • If the stream is readable and writable, it is open.
                      • +
                      • If the stream is readable and not writable, it is readOnly.
                      • +
                      • If the stream is not readable and writable, it is writeOnly.
                      • +
                      +

                      net.connect()#

                      Aliases to net.createConnection().

                      Possible signatures:

                      @@ -1072,7 +1267,7 @@ connections.
                    • net.connect(port[, host][, connectListener]) for TCP connections.
                    -

                    net.connect(options[, connectListener])#

                    +

                    net.connect(options[, connectListener])#

                    @@ -1083,7 +1278,7 @@ for TCP connections.

                  Alias to net.createConnection(options[, connectListener]).

                  -

                  net.connect(path[, connectListener])#

                  +

                  net.connect(path[, connectListener])#

                  @@ -1094,7 +1289,7 @@ for TCP connections.

                Alias to net.createConnection(path[, connectListener]).

                -

                net.connect(port[, host][, connectListener])#

                +

                net.connect(port[, host][, connectListener])#

                @@ -1106,7 +1301,7 @@ for TCP connections.

              Alias to net.createConnection(port[, host][, connectListener]).

              -

              net.createConnection()#

              +

              net.createConnection()#

              A factory function, which creates a new net.Socket, immediately initiates connection with socket.connect(), then returns the net.Socket that starts the connection.

              @@ -1122,7 +1317,7 @@ for IPC connections. for TCP connections.

            The net.connect() function is an alias to this function.

            -

            net.createConnection(options[, connectListener])#

            +

            net.createConnection(options[, connectListener])#

            @@ -1148,21 +1343,21 @@ it starts the connection.

            Following is an example of a client of the echo server described in the net.createServer() section:

            const net = require('net');
            -const client = net.createConnection({ port: 8124 }, () => {
            +const client = net.createConnection({ port: 8124 }, () => {
               // 'connect' listener.
            -  console.log('connected to server!');
            -  client.write('world!\r\n');
            +  console.log('connected to server!');
            +  client.write('world!\r\n');
             });
            -client.on('data', (data) => {
            -  console.log(data.toString());
            -  client.end();
            +client.on('data', (data) => {
            +  console.log(data.toString());
            +  client.end();
             });
            -client.on('end', () => {
            -  console.log('disconnected from server');
            +client.on('end', () => {
            +  console.log('disconnected from server');
             });

            To connect on the socket /tmp/echo.sock:

            -
            const client = net.createConnection({ path: '/tmp/echo.sock' });
            -

            net.createConnection(path[, connectListener])#

            +
            const client = net.createConnection({ path: '/tmp/echo.sock' });
            +

            net.createConnection(path[, connectListener])#

            @@ -1181,7 +1376,7 @@ See Identifying paths for I immediately initiates connection with socket.connect(path[, connectListener]), then returns the net.Socket that starts the connection.

            -

            net.createConnection(port[, host][, connectListener])#

            +

            net.createConnection(port[, host][, connectListener])#

            @@ -1202,15 +1397,16 @@ then returns the net.Socket that starts the connection.

            immediately initiates connection with socket.connect(port[, host][, connectListener]), then returns the net.Socket that starts the connection.

            -

            net.createServer([options][, connectionListener])#

            +

            net.createServer([options][, connectionListener])#

            • options <Object>
                -
              • allowHalfOpen <boolean> Indicates whether half-opened TCP -connections are allowed. Default: false.
              • +
              • allowHalfOpen <boolean> If set to false, then the socket will +automatically end the writable side when the readable side ends. +Default: false.
              • pauseOnConnect <boolean> Indicates whether the socket should be paused on incoming connections. Default: false.
              @@ -1221,10 +1417,12 @@ paused on incoming connections. Default: false.

              Creates a new TCP or IPC server.

              If allowHalfOpen is set to true, when the other end of the socket -sends a FIN packet, the server will only send a FIN packet back when -socket.end() is explicitly called, until then the connection is -half-closed (non-readable but still writable). See 'end' event -and RFC 1122 (section 4.2.2.13) for more information.

              +signals the end of transmission, the server will only send back the end of +transmission when socket.end() is explicitly called. For example, in the +context of TCP, when a FIN packed is received, a FIN packed is sent +back only when socket.end() is explicitly called. Until then the +connection is half-closed (non-readable but still writable). See 'end' +event and RFC 1122 (section 4.2.2.13) for more information.

              If pauseOnConnect is set to true, then the socket associated with each incoming connection will be paused, and no data will be read from its handle. This allows connections to be passed between processes without any data being @@ -1235,30 +1433,30 @@ read by the original process. To begin reading data from a paused socket, call

              Here is an example of an TCP echo server which listens for connections on port 8124:

              const net = require('net');
              -const server = net.createServer((c) => {
              +const server = net.createServer((c) => {
                 // 'connection' listener.
              -  console.log('client connected');
              -  c.on('end', () => {
              -    console.log('client disconnected');
              +  console.log('client connected');
              +  c.on('end', () => {
              +    console.log('client disconnected');
                 });
              -  c.write('hello\r\n');
              -  c.pipe(c);
              +  c.write('hello\r\n');
              +  c.pipe(c);
               });
              -server.on('error', (err) => {
              +server.on('error', (err) => {
                 throw err;
               });
              -server.listen(8124, () => {
              -  console.log('server bound');
              +server.listen(8124, () => {
              +  console.log('server bound');
               });

              Test this by using telnet:

              -
              $ telnet localhost 8124
              +
              $ telnet localhost 8124

              To listen on the socket /tmp/echo.sock:

              -
              server.listen('/tmp/echo.sock', () => {
              -  console.log('server bound');
              +
              server.listen('/tmp/echo.sock', () => {
              +  console.log('server bound');
               });

              Use nc to connect to a Unix domain socket server:

              -
              $ nc -U /tmp/echo.sock
              -

              net.isIP(input)#

              +
              $ nc -U /tmp/echo.sock
              +

            net.isIP(input)#

            @@ -1269,7 +1467,7 @@ server.listen(8124, Tests if input is an IP address. Returns 0 for invalid strings, returns 4 for IP version 4 addresses, and returns 6 for IP version 6 addresses.

            -

            net.isIPv4(input)#

            +

            net.isIPv4(input)#

            @@ -1278,7 +1476,7 @@ addresses.

          • Returns: <boolean>

          Returns true if input is a version 4 IP address, otherwise returns false.

          -

          net.isIPv6(input)#

          +

          net.isIPv6(input)#

          @@ -1286,10 +1484,46 @@ addresses.

        • input <string>
        • Returns: <boolean>
        -

        Returns true if input is a version 6 IP address, otherwise returns false.

        +

        Returns true if input is a version 6 IP address, otherwise returns false.

        + diff --git a/doc/api/net.json b/doc/api/net.json index 6a857b6bd4605a5d39a90c4ab25595bbeb185015..818e5cfc72cb3c2e16be1d85d554fadbf81b981d 100644 --- a/doc/api/net.json +++ b/doc/api/net.json @@ -6,7 +6,7 @@ "textRaw": "Net", "name": "net", "introduced_in": "v0.10.0", - "desc": "\n
        \n

        Stability: 2 - Stable

        \n
        \n

        Source Code: lib/net.js

        \n

        The net module provides an asynchronous network API for creating stream-based\nTCP or IPC servers (net.createServer()) and clients\n(net.createConnection()).

        \n

        It can be accessed using:

        \n
        const net = require('net');\n
        ", + "desc": "\n
        \n

        Stability: 2 - Stable

        \n
        \n

        Source Code: lib/net.js

        \n

        The net module provides an asynchronous network API for creating stream-based\nTCP or IPC servers (net.createServer()) and clients\n(net.createConnection()).

        \n

        It can be accessed using:

        \n
        const net = require('net');\n
        ", "modules": [ { "textRaw": "IPC support", @@ -26,6 +26,270 @@ } ], "classes": [ + { + "textRaw": "Class: `net.BlockList`", + "type": "class", + "name": "net.BlockList", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "desc": "

        The BlockList object can be used with some network APIs to specify rules for\ndisabling inbound or outbound access to specific IP addresses, IP ranges, or\nIP subnets.

        ", + "methods": [ + { + "textRaw": "`blockList.addAddress(address[, type])`", + "type": "method", + "name": "addAddress", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`address` {string|net.SocketAddress} An IPv4 or IPv6 address.", + "name": "address", + "type": "string|net.SocketAddress", + "desc": "An IPv4 or IPv6 address." + }, + { + "textRaw": "`type` {string} Either `'ipv4'` or `'ipv6'`. **Default:** `'ipv4'`.", + "name": "type", + "type": "string", + "default": "`'ipv4'`", + "desc": "Either `'ipv4'` or `'ipv6'`." + } + ] + } + ], + "desc": "

        Adds a rule to block the given IP address.

        " + }, + { + "textRaw": "`blockList.addRange(start, end[, type])`", + "type": "method", + "name": "addRange", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`start` {string|net.SocketAddress} The starting IPv4 or IPv6 address in the range.", + "name": "start", + "type": "string|net.SocketAddress", + "desc": "The starting IPv4 or IPv6 address in the range." + }, + { + "textRaw": "`end` {string|net.SocketAddress} The ending IPv4 or IPv6 address in the range.", + "name": "end", + "type": "string|net.SocketAddress", + "desc": "The ending IPv4 or IPv6 address in the range." + }, + { + "textRaw": "`type` {string} Either `'ipv4'` or `'ipv6'`. **Default:** `'ipv4'`.", + "name": "type", + "type": "string", + "default": "`'ipv4'`", + "desc": "Either `'ipv4'` or `'ipv6'`." + } + ] + } + ], + "desc": "

        Adds a rule to block a range of IP addresses from start (inclusive) to\nend (inclusive).

        " + }, + { + "textRaw": "`blockList.addSubnet(net, prefix[, type])`", + "type": "method", + "name": "addSubnet", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "signatures": [ + { + "params": [ + { + "textRaw": "`net` {string|net.SocketAddress} The network IPv4 or IPv6 address.", + "name": "net", + "type": "string|net.SocketAddress", + "desc": "The network IPv4 or IPv6 address." + }, + { + "textRaw": "`prefix` {number} The number of CIDR prefix bits. For IPv4, this must be a value between `0` and `32`. For IPv6, this must be between `0` and `128`.", + "name": "prefix", + "type": "number", + "desc": "The number of CIDR prefix bits. For IPv4, this must be a value between `0` and `32`. For IPv6, this must be between `0` and `128`." + }, + { + "textRaw": "`type` {string} Either `'ipv4'` or `'ipv6'`. **Default**: `'ipv4'`.", + "name": "type", + "type": "string", + "desc": "Either `'ipv4'` or `'ipv6'`. **Default**: `'ipv4'`." + } + ] + } + ], + "desc": "

        Adds a rule to block a range of IP addresses specified as a subnet mask.

        " + }, + { + "textRaw": "`blockList.check(address[, type])`", + "type": "method", + "name": "check", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {boolean}", + "name": "return", + "type": "boolean" + }, + "params": [ + { + "textRaw": "`address` {string|net.SocketAddress} The IP address to check", + "name": "address", + "type": "string|net.SocketAddress", + "desc": "The IP address to check" + }, + { + "textRaw": "`type` {string} Either `'ipv4'` or `'ipv6'`. **Default:** `'ipv4'`.", + "name": "type", + "type": "string", + "default": "`'ipv4'`", + "desc": "Either `'ipv4'` or `'ipv6'`." + } + ] + } + ], + "desc": "

        Returns true if the given IP address matches any of the rules added to the\nBlockList.

        \n
        const blockList = new net.BlockList();\nblockList.addAddress('123.123.123.123');\nblockList.addRange('10.0.0.1', '10.0.0.10');\nblockList.addSubnet('8592:757c:efae:4e45::', 64, 'ipv6');\n\nconsole.log(blockList.check('123.123.123.123'));  // Prints: true\nconsole.log(blockList.check('10.0.0.3'));  // Prints: true\nconsole.log(blockList.check('222.111.111.222'));  // Prints: false\n\n// IPv6 notation for IPv4 addresses works:\nconsole.log(blockList.check('::ffff:7b7b:7b7b', 'ipv6')); // Prints: true\nconsole.log(blockList.check('::ffff:123.123.123.123', 'ipv6')); // Prints: true\n
        " + } + ], + "properties": [ + { + "textRaw": "`rules` Type: {string[]}", + "type": "string[]", + "name": "Type", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "desc": "

        The list of rules added to the blocklist.

        " + } + ] + }, + { + "textRaw": "Class: `net.SocketAddress`", + "type": "class", + "name": "net.SocketAddress", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "properties": [ + { + "textRaw": "`address` Type {string}", + "type": "string", + "name": "Type", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "desc": "Either `'ipv4'` or `'ipv6'`." + }, + { + "textRaw": "`family` Type {string} Either `'ipv4'` or `'ipv6'`.", + "type": "string", + "name": "Type", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "desc": "Either `'ipv4'` or `'ipv6'`." + }, + { + "textRaw": "`flowlabel` Type {number}", + "type": "number", + "name": "Type", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + } + }, + { + "textRaw": "`port` Type {number}", + "type": "number", + "name": "Type", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + } + } + ], + "signatures": [ + { + "params": [ + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`address` {string} The network address as either an IPv4 or IPv6 string. **Default**: `'127.0.0.1'` if `family` is `'ipv4'`; `'::'` if `family` is `'ipv6'`.", + "name": "address", + "type": "string", + "desc": "The network address as either an IPv4 or IPv6 string. **Default**: `'127.0.0.1'` if `family` is `'ipv4'`; `'::'` if `family` is `'ipv6'`." + }, + { + "textRaw": "`family` {string} One of either `'ipv4'` or 'ipv6'`. **Default**: `'ipv4'`.", + "name": "family", + "type": "string", + "desc": "One of either `'ipv4'` or 'ipv6'`. **Default**: `'ipv4'`." + }, + { + "textRaw": "`flowlabel` {number} An IPv6 flow-label used only if `family` is `'ipv6'`.", + "name": "flowlabel", + "type": "number", + "desc": "An IPv6 flow-label used only if `family` is `'ipv6'`." + }, + { + "textRaw": "`port` {number} An IP port.", + "name": "port", + "type": "number", + "desc": "An IP port." + } + ] + } + ] + } + ] + }, { "textRaw": "Class: `net.Server`", "type": "class", @@ -191,7 +455,7 @@ "params": [] } ], - "desc": "

        Start a server listening for connections. A net.Server can be a TCP or\nan IPC server depending on what it listens to.

        \n

        Possible signatures:

        \n\n

        This function is asynchronous. When the server starts listening, the\n'listening' event will be emitted. The last parameter callback\nwill be added as a listener for the 'listening' event.

        \n

        All listen() methods can take a backlog parameter to specify the maximum\nlength of the queue of pending connections. The actual length will be determined\nby the OS through sysctl settings such as tcp_max_syn_backlog and somaxconn\non Linux. The default value of this parameter is 511 (not 512).

        \n

        All net.Socket are set to SO_REUSEADDR (see socket(7) for\ndetails).

        \n

        The server.listen() method can be called again if and only if there was an\nerror during the first server.listen() call or server.close() has been\ncalled. Otherwise, an ERR_SERVER_ALREADY_LISTEN error will be thrown.

        \n

        One of the most common errors raised when listening is EADDRINUSE.\nThis happens when another server is already listening on the requested\nport/path/handle. One way to handle this would be to retry\nafter a certain amount of time:

        \n
        server.on('error', (e) => {\n  if (e.code === 'EADDRINUSE') {\n    console.log('Address in use, retrying...');\n    setTimeout(() => {\n      server.close();\n      server.listen(PORT, HOST);\n    }, 1000);\n  }\n});\n
        ", + "desc": "

        Start a server listening for connections. A net.Server can be a TCP or\nan IPC server depending on what it listens to.

        \n

        Possible signatures:

        \n\n\n\n

        This function is asynchronous. When the server starts listening, the\n'listening' event will be emitted. The last parameter callback\nwill be added as a listener for the 'listening' event.

        \n

        All listen() methods can take a backlog parameter to specify the maximum\nlength of the queue of pending connections. The actual length will be determined\nby the OS through sysctl settings such as tcp_max_syn_backlog and somaxconn\non Linux. The default value of this parameter is 511 (not 512).

        \n

        All net.Socket are set to SO_REUSEADDR (see socket(7) for\ndetails).

        \n

        The server.listen() method can be called again if and only if there was an\nerror during the first server.listen() call or server.close() has been\ncalled. Otherwise, an ERR_SERVER_ALREADY_LISTEN error will be thrown.

        \n

        One of the most common errors raised when listening is EADDRINUSE.\nThis happens when another server is already listening on the requested\nport/path/handle. One way to handle this would be to retry\nafter a certain amount of time:

        \n
        server.on('error', (e) => {\n  if (e.code === 'EADDRINUSE') {\n    console.log('Address in use, retrying...');\n    setTimeout(() => {\n      server.close();\n      server.listen(PORT, HOST);\n    }, 1000);\n  }\n});\n
        ", "methods": [ { "textRaw": "`server.listen(handle[, backlog][, callback])`", @@ -322,7 +586,7 @@ ] } ], - "desc": "

        If port is specified, it behaves the same as\n\nserver.listen([port[, host[, backlog]]][, callback]).\nOtherwise, if path is specified, it behaves the same as\nserver.listen(path[, backlog][, callback]).\nIf none of them is specified, an error will be thrown.

        \n

        If exclusive is false (default), then cluster workers will use the same\nunderlying handle, allowing connection handling duties to be shared. When\nexclusive is true, the handle is not shared, and attempted port sharing\nresults in an error. An example which listens on an exclusive port is\nshown below.

        \n
        server.listen({\n  host: 'localhost',\n  port: 80,\n  exclusive: true\n});\n
        \n

        Starting an IPC server as root may cause the server path to be inaccessible for\nunprivileged users. Using readableAll and writableAll will make the server\naccessible for all users.

        " + "desc": "\n

        If port is specified, it behaves the same as\n\nserver.listen([port[, host[, backlog]]][, callback]).\nOtherwise, if path is specified, it behaves the same as\nserver.listen(path[, backlog][, callback]).\nIf none of them is specified, an error will be thrown.

        \n\n

        If exclusive is false (default), then cluster workers will use the same\nunderlying handle, allowing connection handling duties to be shared. When\nexclusive is true, the handle is not shared, and attempted port sharing\nresults in an error. An example which listens on an exclusive port is\nshown below.

        \n
        server.listen({\n  host: 'localhost',\n  port: 80,\n  exclusive: true\n});\n
        \n

        Starting an IPC server as root may cause the server path to be inaccessible for\nunprivileged users. Using readableAll and writableAll will make the server\naccessible for all users.

        " }, { "textRaw": "`server.listen(path[, backlog][, callback])`", @@ -612,7 +876,7 @@ "changes": [] }, "params": [], - "desc": "

        Emitted when the other end of the socket sends a FIN packet, thus ending the\nreadable side of the socket.

        \n

        By default (allowHalfOpen is false) the socket will send a FIN packet\nback and destroy its file descriptor once it has written out its pending\nwrite queue. However, if allowHalfOpen is set to true, the socket will\nnot automatically end() its writable side, allowing the\nuser to write arbitrary amounts of data. The user must call\nend() explicitly to close the connection (i.e. sending a\nFIN packet back).

        " + "desc": "

        Emitted when the other end of the socket signals the end of transmission, thus\nending the readable side of the socket.

        \n

        By default (allowHalfOpen is false) the socket will send an end of\ntransmission packet back and destroy its file descriptor once it has written out\nits pending write queue. However, if allowHalfOpen is set to true, the\nsocket will not automatically end() its writable side,\nallowing the user to write arbitrary amounts of data. The user must call\nend() explicitly to close the connection (i.e. sending a\nFIN packet back).

        " }, { "textRaw": "Event: `'error'`", @@ -1001,7 +1265,16 @@ "added": [ "v0.1.92" ], - "changes": [] + "changes": [ + { + "version": [ + "v13.12.0", + "v12.17.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/32204", + "description": "New defaults for `TCP_KEEPCNT` and `TCP_KEEPINTVL` socket options were added." + } + ] }, "signatures": [ { @@ -1027,7 +1300,7 @@ ] } ], - "desc": "

        Enable/disable keep-alive functionality, and optionally set the initial\ndelay before the first keepalive probe is sent on an idle socket.

        \n

        Set initialDelay (in milliseconds) to set the delay between the last\ndata packet received and the first keepalive probe. Setting 0 for\ninitialDelay will leave the value unchanged from the default\n(or previous) setting.

        " + "desc": "

        Enable/disable keep-alive functionality, and optionally set the initial\ndelay before the first keepalive probe is sent on an idle socket.

        \n

        Set initialDelay (in milliseconds) to set the delay between the last\ndata packet received and the first keepalive probe. Setting 0 for\ninitialDelay will leave the value unchanged from the default\n(or previous) setting.

        \n

        Enabling the keep-alive functionality will set the following socket options:

        \n
          \n
        • SO_KEEPALIVE=1
        • \n
        • TCP_KEEPIDLE=initialDelay
        • \n
        • TCP_KEEPCNT=10
        • \n
        • TCP_KEEPINTVL=1
        • \n
        " }, { "textRaw": "`socket.setNoDelay([noDelay])`", @@ -1166,8 +1439,13 @@ "added": [ "v0.3.8" ], + "deprecated": [ + "v14.6.0" + ], "changes": [] }, + "stability": 0, + "stabilityText": "Deprecated: Use [`writable.writableLength`][] instead.", "desc": "

        This property shows the number of characters buffered for writing. The buffer\nmay contain strings whose length after encoding is not yet known. So this number\nis only an approximation of the number of bytes in the buffer.

        \n

        net.Socket has the property that socket.write() always works. This is to\nhelp users get up and running quickly. The computer cannot always keep up\nwith the amount of data that is written to a socket. The network connection\nsimply might be too slow. Node.js will internally queue up the data written to a\nsocket and send it out over the wire when it is possible.

        \n

        The consequence of this internal buffering is that memory may grow.\nUsers who experience large or growing bufferSize should attempt to\n\"throttle\" the data flows in their program with\nsocket.pause() and socket.resume().

        " }, { @@ -1243,7 +1521,8 @@ "name": "pending", "meta": { "added": [ - "v11.2.0" + "v11.2.0", + "v10.16.0" ], "changes": [] }, @@ -1284,6 +1563,30 @@ "changes": [] }, "desc": "

        The numeric representation of the remote port. For example, 80 or 21.

        " + }, + { + "textRaw": "`timeout` {number|undefined}", + "type": "number|undefined", + "name": "timeout", + "meta": { + "added": [ + "v10.7.0" + ], + "changes": [] + }, + "desc": "

        The socket timeout in milliseconds as set by socket.setTimeout().\nIt is undefined if a timeout has not been set.

        " + }, + { + "textRaw": "`readyState` {string}", + "type": "string", + "name": "readyState", + "meta": { + "added": [ + "v0.5.0" + ], + "changes": [] + }, + "desc": "

        This property represents the state of the connection as a string.

        \n
          \n
        • If the stream is connecting socket.readyState is opening.
        • \n
        • If the stream is readable and writable, it is open.
        • \n
        • If the stream is readable and not writable, it is readOnly.
        • \n
        • If the stream is not readable and writable, it is writeOnly.
        • \n
        " } ], "signatures": [ @@ -1307,11 +1610,11 @@ "desc": "If specified, wrap around an existing socket with the given file descriptor, otherwise a new socket will be created." }, { - "textRaw": "`allowHalfOpen` {boolean} Indicates whether half-opened TCP connections are allowed. See [`net.createServer()`][] and the [`'end'`][] event for details. **Default:** `false`.", + "textRaw": "`allowHalfOpen` {boolean} If set to `false`, then the socket will automatically end the writable side when the readable side ends. See [`net.createServer()`][] and the [`'end'`][] event for details. **Default:** `false`.", "name": "allowHalfOpen", "type": "boolean", "default": "`false`", - "desc": "Indicates whether half-opened TCP connections are allowed. See [`net.createServer()`][] and the [`'end'`][] event for details." + "desc": "If set to `false`, then the socket will automatically end the writable side when the readable side ends. See [`net.createServer()`][] and the [`'end'`][] event for details." }, { "textRaw": "`readable` {boolean} Allow reads on the socket when an `fd` is passed, otherwise ignored. **Default:** `false`.", @@ -1605,11 +1908,11 @@ "type": "Object", "options": [ { - "textRaw": "`allowHalfOpen` {boolean} Indicates whether half-opened TCP connections are allowed. **Default:** `false`.", + "textRaw": "`allowHalfOpen` {boolean} If set to `false`, then the socket will automatically end the writable side when the readable side ends. **Default:** `false`.", "name": "allowHalfOpen", "type": "boolean", "default": "`false`", - "desc": "Indicates whether half-opened TCP connections are allowed." + "desc": "If set to `false`, then the socket will automatically end the writable side when the readable side ends." }, { "textRaw": "`pauseOnConnect` {boolean} Indicates whether the socket should be paused on incoming connections. **Default:** `false`.", @@ -1629,7 +1932,7 @@ ] } ], - "desc": "

        Creates a new TCP or IPC server.

        \n

        If allowHalfOpen is set to true, when the other end of the socket\nsends a FIN packet, the server will only send a FIN packet back when\nsocket.end() is explicitly called, until then the connection is\nhalf-closed (non-readable but still writable). See 'end' event\nand RFC 1122 (section 4.2.2.13) for more information.

        \n

        If pauseOnConnect is set to true, then the socket associated with each\nincoming connection will be paused, and no data will be read from its handle.\nThis allows connections to be passed between processes without any data being\nread by the original process. To begin reading data from a paused socket, call\nsocket.resume().

        \n

        The server can be a TCP server or an IPC server, depending on what it\nlisten() to.

        \n

        Here is an example of an TCP echo server which listens for connections\non port 8124:

        \n
        const net = require('net');\nconst server = net.createServer((c) => {\n  // 'connection' listener.\n  console.log('client connected');\n  c.on('end', () => {\n    console.log('client disconnected');\n  });\n  c.write('hello\\r\\n');\n  c.pipe(c);\n});\nserver.on('error', (err) => {\n  throw err;\n});\nserver.listen(8124, () => {\n  console.log('server bound');\n});\n
        \n

        Test this by using telnet:

        \n
        $ telnet localhost 8124\n
        \n

        To listen on the socket /tmp/echo.sock:

        \n
        server.listen('/tmp/echo.sock', () => {\n  console.log('server bound');\n});\n
        \n

        Use nc to connect to a Unix domain socket server:

        \n
        $ nc -U /tmp/echo.sock\n
        " + "desc": "

        Creates a new TCP or IPC server.

        \n

        If allowHalfOpen is set to true, when the other end of the socket\nsignals the end of transmission, the server will only send back the end of\ntransmission when socket.end() is explicitly called. For example, in the\ncontext of TCP, when a FIN packed is received, a FIN packed is sent\nback only when socket.end() is explicitly called. Until then the\nconnection is half-closed (non-readable but still writable). See 'end'\nevent and RFC 1122 (section 4.2.2.13) for more information.

        \n

        If pauseOnConnect is set to true, then the socket associated with each\nincoming connection will be paused, and no data will be read from its handle.\nThis allows connections to be passed between processes without any data being\nread by the original process. To begin reading data from a paused socket, call\nsocket.resume().

        \n

        The server can be a TCP server or an IPC server, depending on what it\nlisten() to.

        \n

        Here is an example of an TCP echo server which listens for connections\non port 8124:

        \n
        const net = require('net');\nconst server = net.createServer((c) => {\n  // 'connection' listener.\n  console.log('client connected');\n  c.on('end', () => {\n    console.log('client disconnected');\n  });\n  c.write('hello\\r\\n');\n  c.pipe(c);\n});\nserver.on('error', (err) => {\n  throw err;\n});\nserver.listen(8124, () => {\n  console.log('server bound');\n});\n
        \n

        Test this by using telnet:

        \n
        $ telnet localhost 8124\n
        \n

        To listen on the socket /tmp/echo.sock:

        \n
        server.listen('/tmp/echo.sock', () => {\n  console.log('server bound');\n});\n
        \n

        Use nc to connect to a Unix domain socket server:

        \n
        $ nc -U /tmp/echo.sock\n
        " }, { "textRaw": "`net.isIP(input)`", diff --git a/doc/api/net.md b/doc/api/net.md index 956bed6c706a8a47903d1a634df17d480f2d4de6..abf57a570c30cb1bcddb338647d22152fec9d7ff 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -55,6 +55,132 @@ net.createServer().listen( path.join('\\\\?\\pipe', process.cwd(), 'myctl')); ``` +## Class: `net.BlockList` + + +The `BlockList` object can be used with some network APIs to specify rules for +disabling inbound or outbound access to specific IP addresses, IP ranges, or +IP subnets. + +### `blockList.addAddress(address[, type])` + + +* `address` {string|net.SocketAddress} An IPv4 or IPv6 address. +* `type` {string} Either `'ipv4'` or `'ipv6'`. **Default:** `'ipv4'`. + +Adds a rule to block the given IP address. + +### `blockList.addRange(start, end[, type])` + + +* `start` {string|net.SocketAddress} The starting IPv4 or IPv6 address in the + range. +* `end` {string|net.SocketAddress} The ending IPv4 or IPv6 address in the range. +* `type` {string} Either `'ipv4'` or `'ipv6'`. **Default:** `'ipv4'`. + +Adds a rule to block a range of IP addresses from `start` (inclusive) to +`end` (inclusive). + +### `blockList.addSubnet(net, prefix[, type])` + + +* `net` {string|net.SocketAddress} The network IPv4 or IPv6 address. +* `prefix` {number} The number of CIDR prefix bits. For IPv4, this + must be a value between `0` and `32`. For IPv6, this must be between + `0` and `128`. +* `type` {string} Either `'ipv4'` or `'ipv6'`. **Default**: `'ipv4'`. + +Adds a rule to block a range of IP addresses specified as a subnet mask. + +### `blockList.check(address[, type])` + + +* `address` {string|net.SocketAddress} The IP address to check +* `type` {string} Either `'ipv4'` or `'ipv6'`. **Default:** `'ipv4'`. +* Returns: {boolean} + +Returns `true` if the given IP address matches any of the rules added to the +`BlockList`. + +```js +const blockList = new net.BlockList(); +blockList.addAddress('123.123.123.123'); +blockList.addRange('10.0.0.1', '10.0.0.10'); +blockList.addSubnet('8592:757c:efae:4e45::', 64, 'ipv6'); + +console.log(blockList.check('123.123.123.123')); // Prints: true +console.log(blockList.check('10.0.0.3')); // Prints: true +console.log(blockList.check('222.111.111.222')); // Prints: false + +// IPv6 notation for IPv4 addresses works: +console.log(blockList.check('::ffff:7b7b:7b7b', 'ipv6')); // Prints: true +console.log(blockList.check('::ffff:123.123.123.123', 'ipv6')); // Prints: true +``` + +### `blockList.rules` + + +* Type: {string[]} + +The list of rules added to the blocklist. + +## Class: `net.SocketAddress` + +### `new net.SocketAddress([options])` + + +* `options` {Object} + * `address` {string} The network address as either an IPv4 or IPv6 string. + **Default**: `'127.0.0.1'` if `family` is `'ipv4'`; `'::'` if `family` is + `'ipv6'`. + * `family` {string} One of either `'ipv4'` or 'ipv6'`. **Default**: `'ipv4'`. + * `flowlabel` {number} An IPv6 flow-label used only if `family` is `'ipv6'`. + * `port` {number} An IP port. + +### `socketaddress.address` + + +* Type {string} + +### `socketaddress.family` + + +* Type {string} Either `'ipv4'` or `'ipv6'`. + +### `socketaddress.flowlabel` + + +* Type {number} + +### `socketaddress.port` + + +* Type {number} + ## Class: `net.Server` * [`server.listen(handle[, backlog][, callback])`][`server.listen(handle)`] * [`server.listen(options[, callback])`][`server.listen(options)`] * [`server.listen(path[, backlog][, callback])`][`server.listen(path)`] @@ -201,6 +328,7 @@ Possible signatures: * server.listen([port[, host[, backlog]]][, callback]) for TCP servers + This function is asynchronous. When the server starts listening, the [`'listening'`][] event will be emitted. The last parameter `callback` @@ -282,12 +410,14 @@ changes: functions. * Returns: {net.Server} + If `port` is specified, it behaves the same as server.listen([port[, host[, backlog]]][, callback]). Otherwise, if `path` is specified, it behaves the same as [`server.listen(path[, backlog][, callback])`][`server.listen(path)`]. If none of them is specified, an error will be thrown. + If `exclusive` is `false` (default), then cluster workers will use the same underlying handle, allowing connection handling duties to be shared. When @@ -415,9 +545,10 @@ added: v0.3.4 * `options` {Object} Available options are: * `fd` {number} If specified, wrap around an existing socket with the given file descriptor, otherwise a new socket will be created. - * `allowHalfOpen` {boolean} Indicates whether half-opened TCP connections - are allowed. See [`net.createServer()`][] and the [`'end'`][] event - for details. **Default:** `false`. + * `allowHalfOpen` {boolean} If set to `false`, then the socket will + automatically end the writable side when the readable side ends. See + [`net.createServer()`][] and the [`'end'`][] event for details. **Default:** + `false`. * `readable` {boolean} Allow reads on the socket when an `fd` is passed, otherwise ignored. **Default:** `false`. * `writable` {boolean} Allow writes on the socket when an `fd` is passed, @@ -474,14 +605,14 @@ See also: the return values of `socket.write()`. added: v0.1.90 --> -Emitted when the other end of the socket sends a FIN packet, thus ending the -readable side of the socket. +Emitted when the other end of the socket signals the end of transmission, thus +ending the readable side of the socket. -By default (`allowHalfOpen` is `false`) the socket will send a FIN packet -back and destroy its file descriptor once it has written out its pending -write queue. However, if `allowHalfOpen` is set to `true`, the socket will -not automatically [`end()`][`socket.end()`] its writable side, allowing the -user to write arbitrary amounts of data. The user must call +By default (`allowHalfOpen` is `false`) the socket will send an end of +transmission packet back and destroy its file descriptor once it has written out +its pending write queue. However, if `allowHalfOpen` is set to `true`, the +socket will not automatically [`end()`][`socket.end()`] its writable side, +allowing the user to write arbitrary amounts of data. The user must call [`end()`][`socket.end()`] explicitly to close the connection (i.e. sending a FIN packet back). @@ -545,8 +676,12 @@ socket as reported by the operating system: ### `socket.bufferSize` +> Stability: 0 - Deprecated: Use [`writable.writableLength`][] instead. + * {integer} This property shows the number of characters buffered for writing. The buffer @@ -793,7 +928,9 @@ Useful to throttle back an upload. ### `socket.pending` * {boolean} @@ -862,6 +999,12 @@ Set the encoding for the socket as a [Readable Stream][]. See ### `socket.setKeepAlive([enable][, initialDelay])` * `enable` {boolean} **Default:** `false` @@ -876,6 +1019,12 @@ data packet received and the first keepalive probe. Setting `0` for `initialDelay` will leave the value unchanged from the default (or previous) setting. +Enabling the keep-alive functionality will set the following socket options: +* `SO_KEEPALIVE=1` +* `TCP_KEEPIDLE=initialDelay` +* `TCP_KEEPCNT=10` +* `TCP_KEEPINTVL=1` + ### `socket.setNoDelay([noDelay])` + +* {number|undefined} + +The socket timeout in milliseconds as set by [`socket.setTimeout()`][]. +It is `undefined` if a timeout has not been set. + ### `socket.unref()` + +* {string} + +This property represents the state of the connection as a string. + +* If the stream is connecting `socket.readyState` is `opening`. +* If the stream is readable and writable, it is `open`. +* If the stream is readable and not writable, it is `readOnly`. +* If the stream is not readable and writable, it is `writeOnly`. + ## `net.connect()` Aliases to @@ -1127,8 +1300,9 @@ added: v0.5.0 --> * `options` {Object} - * `allowHalfOpen` {boolean} Indicates whether half-opened TCP - connections are allowed. **Default:** `false`. + * `allowHalfOpen` {boolean} If set to `false`, then the socket will + automatically end the writable side when the readable side ends. + **Default:** `false`. * `pauseOnConnect` {boolean} Indicates whether the socket should be paused on incoming connections. **Default:** `false`. * `connectionListener` {Function} Automatically set as a listener for the @@ -1138,10 +1312,12 @@ added: v0.5.0 Creates a new TCP or [IPC][] server. If `allowHalfOpen` is set to `true`, when the other end of the socket -sends a FIN packet, the server will only send a FIN packet back when -[`socket.end()`][] is explicitly called, until then the connection is -half-closed (non-readable but still writable). See [`'end'`][] event -and [RFC 1122][half-closed] (section 4.2.2.13) for more information. +signals the end of transmission, the server will only send back the end of +transmission when [`socket.end()`][] is explicitly called. For example, in the +context of TCP, when a FIN packed is received, a FIN packed is sent +back only when [`socket.end()`][] is explicitly called. Until then the +connection is half-closed (non-readable but still writable). See [`'end'`][] +event and [RFC 1122][half-closed] (section 4.2.2.13) for more information. If `pauseOnConnect` is set to `true`, then the socket associated with each incoming connection will be paused, and no data will be read from its handle. @@ -1228,7 +1404,7 @@ Returns `true` if input is a version 6 IP address, otherwise returns `false`. [IPC]: #net_ipc_support [Identifying paths for IPC connections]: #net_identifying_paths_for_ipc_connections -[Readable Stream]: stream.html#stream_class_stream_readable +[Readable Stream]: stream.md#stream_class_stream_readable [`'close'`]: #net_event_close [`'connect'`]: #net_event_connect [`'connection'`]: #net_event_connection @@ -1238,10 +1414,10 @@ Returns `true` if input is a version 6 IP address, otherwise returns `false`. [`'error'`]: #net_event_error_1 [`'listening'`]: #net_event_listening [`'timeout'`]: #net_event_timeout -[`EventEmitter`]: events.html#events_class_eventemitter -[`child_process.fork()`]: child_process.html#child_process_child_process_fork_modulepath_args_options -[`dns.lookup()` hints]: dns.html#dns_supported_getaddrinfo_flags -[`dns.lookup()`]: dns.html#dns_dns_lookup_hostname_options_callback +[`EventEmitter`]: events.md#events_class_eventemitter +[`child_process.fork()`]: child_process.md#child_process_child_process_fork_modulepath_args_options +[`dns.lookup()`]: dns.md#dns_dns_lookup_hostname_options_callback +[`dns.lookup()` hints]: dns.md#dns_supported_getaddrinfo_flags [`net.Server`]: #net_class_net_server [`net.Socket`]: #net_class_net_socket [`net.connect()`]: #net_net_connect @@ -1254,7 +1430,7 @@ Returns `true` if input is a version 6 IP address, otherwise returns `false`. [`net.createConnection(port, host)`]: #net_net_createconnection_port_host_connectlistener [`net.createServer()`]: #net_net_createserver_options_connectionlistener [`new net.Socket(options)`]: #net_new_net_socket_options -[`readable.setEncoding()`]: stream.html#stream_readable_setencoding_encoding +[`readable.setEncoding()`]: stream.md#stream_readable_setencoding_encoding [`server.close()`]: #net_server_close_callback [`server.getConnections()`]: #net_server_getconnections_callback [`server.listen()`]: #net_server_listen @@ -1274,10 +1450,11 @@ Returns `true` if input is a version 6 IP address, otherwise returns `false`. [`socket.setEncoding()`]: #net_socket_setencoding_encoding [`socket.setTimeout()`]: #net_socket_settimeout_timeout_callback [`socket.setTimeout(timeout)`]: #net_socket_settimeout_timeout_callback -[`writable.destroyed`]: stream.html#stream_writable_destroyed -[`writable.destroy()`]: stream.html#stream_writable_destroy_error -[`writable.end()`]: stream.html#stream_writable_end_chunk_encoding_callback +[`writable.destroy()`]: stream.md#stream_writable_destroy_error +[`writable.destroyed`]: stream.md#stream_writable_destroyed +[`writable.end()`]: stream.md#stream_writable_end_chunk_encoding_callback +[`writable.writableLength`]: stream.md#stream_writable_writablelength [half-closed]: https://tools.ietf.org/html/rfc1122 -[stream_writable_write]: stream.html#stream_writable_write_chunk_encoding_callback +[stream_writable_write]: stream.md#stream_writable_write_chunk_encoding_callback [unspecified IPv4 address]: https://en.wikipedia.org/wiki/0.0.0.0 [unspecified IPv6 address]: https://en.wikipedia.org/wiki/IPv6_address#Unspecified_address diff --git a/doc/api/os.html b/doc/api/os.html index e3ad9211ebfa5d1ed545250536c431e5ff795262..93f8d7aac849714d9330910b8c339bc228cd3ac8 100644 --- a/doc/api/os.html +++ b/doc/api/os.html @@ -1,10 +1,10 @@ - + - - OS | Node.js v12.22.7 Documentation + + OS | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
      • Assertion testing
      • Async hooks
      • Buffer
      • -
      • C++ Addons
      • -
      • C/C++ Addons with N-API
      • -
      • C++ Embedder API
      • -
      • Child Processes
      • +
      • C++ addons
      • +
      • C/C++ addons with Node-API
      • +
      • C++ embedder API
      • +
      • Child processes
      • Cluster
      • -
      • Command line options
      • +
      • Command-line options
      • Console
      • Crypto
      • Debugger
      • Deprecated APIs
      • +
      • Diagnostics Channel
      • DNS
      • Domain
      • Errors
      • @@ -86,7 +87,20 @@
        -

        Node.js v12.22.7 Documentation

        +
        +

        Node.js v14.18.3 documentation

        + +

        -
        -

        Table of Contents

        -
        +
      -

      OS#

      +

      OS#

      Stability: 2 - Stable

      -

      Source Code: lib/os.js

      +

      Source Code: lib/os.js

      The os module provides operating system-related utility methods and properties. It can be accessed using:

      const os = require('os');
      -

      os.EOL#

      +

      os.EOL#

      @@ -188,7 +201,7 @@ properties. It can be accessed using:

    • \n on POSIX
    • \r\n on Windows
    • -

      os.arch()#

      +

      os.arch()#

      @@ -199,7 +212,7 @@ properties. It can be accessed using:

      compiled. Possible values are 'arm', 'arm64', 'ia32', 'mips', 'mipsel', 'ppc', 'ppc64', 's390', 's390x', 'x32', and 'x64'.

      The return value is equivalent to process.arch.

      -

      os.constants#

      +

      os.constants#

      @@ -209,7 +222,7 @@ compiled. Possible values are 'arm', 'arm64', 'i

      Contains commonly used operating system-specific constants for error codes, process signals, and so on. The specific constants defined are described in OS constants.

      -

      os.cpus()#

      +

      os.cpus()#

      @@ -276,11 +289,23 @@ process signals, and so on. The specific constants defined are described in idle: 1070905480, irq: 20 } - } + }, ]

      nice values are POSIX-only. On Windows, the nice values of all processors are always 0.

      -

      os.endianness()#

      +

      os.devNull#

      + + +

      The platform-specific file path of the null device.

      +
        +
      • \\.\nul on Windows
      • +
      • /dev/null on POSIX
      • +
      +

      os.endianness()#

      @@ -290,7 +315,7 @@ are always 0.

      Returns a string identifying the endianness of the CPU for which the Node.js binary was compiled.

      Possible values are 'BE' for big endian and 'LE' for little endian.

      -

      os.freemem()#

      +

      os.freemem()#

      @@ -298,7 +323,7 @@ binary was compiled.

    • Returns: <integer>
    • Returns the amount of free system memory in bytes as an integer.

      -

      os.getPriority([pid])#

      +

      os.getPriority([pid])#

      @@ -309,7 +334,7 @@ binary was compiled.

      Returns the scheduling priority for the process specified by pid. If pid is not provided or is 0, the priority of the current process is returned.

      -

      os.homedir()#

      +

      os.homedir()#

      @@ -321,7 +346,7 @@ not provided or is 0, the priority of the current process is return uses the effective UID to look up the user's home directory.

      On Windows, it uses the USERPROFILE environment variable if defined. Otherwise it uses the path to the profile directory of the current user.

      -

      os.hostname()#

      +

      os.hostname()#

      @@ -329,7 +354,7 @@ Otherwise it uses the path to the profile directory of the current user.

    • Returns: <string>
    • Returns the host name of the operating system as a string.

      -

      os.loadavg()#

      +

      os.loadavg()#

      @@ -341,7 +366,7 @@ Otherwise it uses the path to the profile directory of the current user.

      system and expressed as a fractional number.

      The load average is a Unix-specific concept. On Windows, the return value is always [0, 0, 0].

      -

      os.networkInterfaces()#

      +

      os.networkInterfaces()#

      @@ -407,7 +432,7 @@ to null. } ] }
      -

      os.platform()#

      +

      os.platform()#

      @@ -419,8 +444,8 @@ at compile time. Possible values are 'aix', 'darwin', 'linux', 'openbsd', 'sunos', and 'win32'.

      The return value is equivalent to process.platform.

      The value 'android' may also be returned if Node.js is built on the Android -operating system. Android support is experimental.

      -

      os.release()#

      +operating system. Android support is experimental.

      +

      os.release()#

      @@ -431,7 +456,7 @@ operating system. uname(3). On Windows, GetVersionExW() is used. See https://en.wikipedia.org/wiki/Uname#Examples for more information.

      -

      os.setPriority([pid, ]priority)#

      +

      os.setPriority([pid, ]priority)#

      @@ -451,13 +476,13 @@ confusion, set priority to one of the priority constants.

      On Windows, setting priority to PRIORITY_HIGHEST requires elevated user privileges. Otherwise the set priority will be silently reduced to PRIORITY_HIGH.

      -

      os.tmpdir()#

      +

      os.tmpdir()#

      os.totalmem()#

      @@ -476,7 +501,7 @@ string.

    • Returns: <integer>
    • Returns the total amount of system memory in bytes as an integer.

      -

      os.type()#

      +

      os.type()#

      @@ -487,7 +512,7 @@ string.

      returns 'Linux' on Linux, 'Darwin' on macOS, and 'Windows_NT' on Windows.

      See https://en.wikipedia.org/wiki/Uname#Examples for additional information about the output of running uname(3) on various operating systems.

      -

      os.uptime()#

      +

      os.uptime()#

      + diff --git a/doc/api/os.json b/doc/api/os.json index a01b4b97be60a9f927bc9abea7d72597a1977da9..74342810c5a682026345cb4db6d7d37dc7a11cd2 100644 --- a/doc/api/os.json +++ b/doc/api/os.json @@ -8,7 +8,7 @@ "introduced_in": "v0.10.0", "stability": 2, "stabilityText": "Stable", - "desc": "

      Source Code: lib/os.js

      \n

      The os module provides operating system-related utility methods and\nproperties. It can be accessed using:

      \n
      const os = require('os');\n
      ", + "desc": "

      Source Code: lib/os.js

      \n

      The os module provides operating system-related utility methods and\nproperties. It can be accessed using:

      \n
      const os = require('os');\n
      ", "properties": [ { "textRaw": "`EOL` {string}", @@ -33,6 +33,18 @@ "changes": [] }, "desc": "

      Contains commonly used operating system-specific constants for error codes,\nprocess signals, and so on. The specific constants defined are described in\nOS constants.

      " + }, + { + "textRaw": "`devNull` {string}", + "type": "string", + "name": "devNull", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "desc": "

      The platform-specific file path of the null device.

      \n
        \n
      • \\\\.\\nul on Windows
      • \n
      • /dev/null on POSIX
      • \n
      " } ], "methods": [ @@ -78,7 +90,7 @@ "params": [] } ], - "desc": "

      Returns an array of objects containing information about each logical CPU core.

      \n

      The properties included on each object include:

      \n
        \n
      • model <string>
      • \n
      • speed <number> (in MHz)
      • \n
      • times <Object>\n
          \n
        • user <number> The number of milliseconds the CPU has spent in user mode.
        • \n
        • nice <number> The number of milliseconds the CPU has spent in nice mode.
        • \n
        • sys <number> The number of milliseconds the CPU has spent in sys mode.
        • \n
        • idle <number> The number of milliseconds the CPU has spent in idle mode.
        • \n
        • irq <number> The number of milliseconds the CPU has spent in irq mode.
        • \n
        \n
      • \n
      \n\n
      [\n  {\n    model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times: {\n      user: 252020,\n      nice: 0,\n      sys: 30340,\n      idle: 1070356870,\n      irq: 0\n    }\n  },\n  {\n    model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times: {\n      user: 306960,\n      nice: 0,\n      sys: 26980,\n      idle: 1071569080,\n      irq: 0\n    }\n  },\n  {\n    model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times: {\n      user: 248450,\n      nice: 0,\n      sys: 21750,\n      idle: 1070919370,\n      irq: 0\n    }\n  },\n  {\n    model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times: {\n      user: 256880,\n      nice: 0,\n      sys: 19430,\n      idle: 1070905480,\n      irq: 20\n    }\n  }\n]\n
      \n

      nice values are POSIX-only. On Windows, the nice values of all processors\nare always 0.

      " + "desc": "

      Returns an array of objects containing information about each logical CPU core.

      \n

      The properties included on each object include:

      \n
        \n
      • model <string>
      • \n
      • speed <number> (in MHz)
      • \n
      • times <Object>\n
          \n
        • user <number> The number of milliseconds the CPU has spent in user mode.
        • \n
        • nice <number> The number of milliseconds the CPU has spent in nice mode.
        • \n
        • sys <number> The number of milliseconds the CPU has spent in sys mode.
        • \n
        • idle <number> The number of milliseconds the CPU has spent in idle mode.
        • \n
        • irq <number> The number of milliseconds the CPU has spent in irq mode.
        • \n
        \n
      • \n
      \n\n
      [\n  {\n    model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times: {\n      user: 252020,\n      nice: 0,\n      sys: 30340,\n      idle: 1070356870,\n      irq: 0\n    }\n  },\n  {\n    model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times: {\n      user: 306960,\n      nice: 0,\n      sys: 26980,\n      idle: 1071569080,\n      irq: 0\n    }\n  },\n  {\n    model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times: {\n      user: 248450,\n      nice: 0,\n      sys: 21750,\n      idle: 1070919370,\n      irq: 0\n    }\n  },\n  {\n    model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times: {\n      user: 256880,\n      nice: 0,\n      sys: 19430,\n      idle: 1070905480,\n      irq: 20\n    }\n  },\n]\n
      \n

      nice values are POSIX-only. On Windows, the nice values of all processors\nare always 0.

      " }, { "textRaw": "`os.endianness()`", @@ -261,7 +273,7 @@ "params": [] } ], - "desc": "

      Returns a string identifying the operating system platform. The value is set\nat compile time. Possible values are 'aix', 'darwin', 'freebsd',\n'linux', 'openbsd', 'sunos', and 'win32'.

      \n

      The return value is equivalent to process.platform.

      \n

      The value 'android' may also be returned if Node.js is built on the Android\noperating system. Android support is experimental.

      " + "desc": "

      Returns a string identifying the operating system platform. The value is set\nat compile time. Possible values are 'aix', 'darwin', 'freebsd',\n'linux', 'openbsd', 'sunos', and 'win32'.

      \n

      The return value is equivalent to process.platform.

      \n

      The value 'android' may also be returned if Node.js is built on the Android\noperating system. Android support is experimental.

      " }, { "textRaw": "`os.release()`", @@ -327,7 +339,7 @@ { "version": "v2.0.0", "pr-url": "https://github.com/nodejs/node/pull/747", - "description": "This function is now cross-platform consistent and no longer returns a path with a trailing slash on any platform" + "description": "This function is now cross-platform consistent and no longer returns a path with a trailing slash on any platform." } ] }, @@ -458,7 +470,7 @@ "name": "version", "meta": { "added": [ - "v12.17.0" + "v13.11.0" ], "changes": [] }, @@ -493,7 +505,7 @@ } ] }, - "desc": "

      The following signal constants are exported by os.constants.signals.

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      SIGHUPSent to indicate when a controlling terminal is closed or a parent\n process exits.
      SIGINTSent to indicate when a user wishes to interrupt a process\n ((Ctrl+C)).
      SIGQUITSent to indicate when a user wishes to terminate a process and perform a\n core dump.
      SIGILLSent to a process to notify that it has attempted to perform an illegal,\n malformed, unknown, or privileged instruction.
      SIGTRAPSent to a process when an exception has occurred.
      SIGABRTSent to a process to request that it abort.
      SIGIOTSynonym for SIGABRT
      SIGBUSSent to a process to notify that it has caused a bus error.
      SIGFPESent to a process to notify that it has performed an illegal arithmetic\n operation.
      SIGKILLSent to a process to terminate it immediately.
      SIGUSR1 SIGUSR2Sent to a process to identify user-defined conditions.
      SIGSEGVSent to a process to notify of a segmentation fault.
      SIGPIPESent to a process when it has attempted to write to a disconnected\n pipe.
      SIGALRMSent to a process when a system timer elapses.
      SIGTERMSent to a process to request termination.
      SIGCHLDSent to a process when a child process terminates.
      SIGSTKFLTSent to a process to indicate a stack fault on a coprocessor.
      SIGCONTSent to instruct the operating system to continue a paused process.
      SIGSTOPSent to instruct the operating system to halt a process.
      SIGTSTPSent to a process to request it to stop.
      SIGBREAKSent to indicate when a user wishes to interrupt a process.
      SIGTTINSent to a process when it reads from the TTY while in the\n background.
      SIGTTOUSent to a process when it writes to the TTY while in the\n background.
      SIGURGSent to a process when a socket has urgent data to read.
      SIGXCPUSent to a process when it has exceeded its limit on CPU usage.
      SIGXFSZSent to a process when it grows a file larger than the maximum\n allowed.
      SIGVTALRMSent to a process when a virtual timer has elapsed.
      SIGPROFSent to a process when a system timer has elapsed.
      SIGWINCHSent to a process when the controlling terminal has changed its\n size.
      SIGIOSent to a process when I/O is available.
      SIGPOLLSynonym for SIGIO
      SIGLOSTSent to a process when a file lock has been lost.
      SIGPWRSent to a process to notify of a power failure.
      SIGINFOSynonym for SIGPWR
      SIGSYSSent to a process to notify of a bad argument.
      SIGUNUSEDSynonym for SIGSYS
      ", + "desc": "

      The following signal constants are exported by os.constants.signals.

      \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ConstantDescription
      SIGHUPSent to indicate when a controlling terminal is closed or a parent\n process exits.
      SIGINTSent to indicate when a user wishes to interrupt a process\n (Ctrl+C).
      SIGQUITSent to indicate when a user wishes to terminate a process and perform a\n core dump.
      SIGILLSent to a process to notify that it has attempted to perform an illegal,\n malformed, unknown, or privileged instruction.
      SIGTRAPSent to a process when an exception has occurred.
      SIGABRTSent to a process to request that it abort.
      SIGIOTSynonym for SIGABRT
      SIGBUSSent to a process to notify that it has caused a bus error.
      SIGFPESent to a process to notify that it has performed an illegal arithmetic\n operation.
      SIGKILLSent to a process to terminate it immediately.
      SIGUSR1 SIGUSR2Sent to a process to identify user-defined conditions.
      SIGSEGVSent to a process to notify of a segmentation fault.
      SIGPIPESent to a process when it has attempted to write to a disconnected\n pipe.
      SIGALRMSent to a process when a system timer elapses.
      SIGTERMSent to a process to request termination.
      SIGCHLDSent to a process when a child process terminates.
      SIGSTKFLTSent to a process to indicate a stack fault on a coprocessor.
      SIGCONTSent to instruct the operating system to continue a paused process.
      SIGSTOPSent to instruct the operating system to halt a process.
      SIGTSTPSent to a process to request it to stop.
      SIGBREAKSent to indicate when a user wishes to interrupt a process.
      SIGTTINSent to a process when it reads from the TTY while in the\n background.
      SIGTTOUSent to a process when it writes to the TTY while in the\n background.
      SIGURGSent to a process when a socket has urgent data to read.
      SIGXCPUSent to a process when it has exceeded its limit on CPU usage.
      SIGXFSZSent to a process when it grows a file larger than the maximum\n allowed.
      SIGVTALRMSent to a process when a virtual timer has elapsed.
      SIGPROFSent to a process when a system timer has elapsed.
      SIGWINCHSent to a process when the controlling terminal has changed its\n size.
      SIGIOSent to a process when I/O is available.
      SIGPOLLSynonym for SIGIO
      SIGLOSTSent to a process when a file lock has been lost.
      SIGPWRSent to a process to notify of a power failure.
      SIGINFOSynonym for SIGPWR
      SIGSYSSent to a process to notify of a bad argument.
      SIGUNUSEDSynonym for SIGSYS
      ", "type": "module", "displayName": "Signal constants" }, diff --git a/doc/api/os.md b/doc/api/os.md index 4bde3f6dc27847ded810986101c68af1c9e17ef3..f9812d4a8490b4f4fad4471e4b38bf6133b14ad7 100644 --- a/doc/api/os.md +++ b/doc/api/os.md @@ -115,13 +115,25 @@ The properties included on each object include: idle: 1070905480, irq: 20 } - } + }, ] ``` `nice` values are POSIX-only. On Windows, the `nice` values of all processors are always 0. +## `os.devNull` + + +* {string} + +The platform-specific file path of the null device. + +* `\\.\nul` on Windows +* `/dev/null` on POSIX + ## `os.endianness()` * Returns: {string} @@ -393,7 +405,7 @@ Throws a [`SystemError`][] if a user has no `username` or `homedir`. ## `os.version()` * Returns {string} @@ -434,7 +446,7 @@ The following signal constants are exported by `os.constants.signals`. SIGINT Sent to indicate when a user wishes to interrupt a process - ((Ctrl+C)). + (Ctrl+C). SIGQUIT @@ -1267,9 +1279,9 @@ The following process scheduling constants are exported by -[`SystemError`]: errors.html#errors_class_systemerror -[`process.arch`]: process.html#process_process_arch -[`process.platform`]: process.html#process_process_platform -[`uname(3)`]: https://linux.die.net/man/3/uname -[Android building]: https://github.com/nodejs/node/blob/master/BUILDING.md#androidandroid-based-devices-eg-firefox-os +[Android building]: https://github.com/nodejs/node/blob/HEAD/BUILDING.md#androidandroid-based-devices-eg-firefox-os [EUID]: https://en.wikipedia.org/wiki/User_identifier#Effective_user_ID +[`SystemError`]: errors.md#errors_class_systemerror +[`process.arch`]: process.md#process_process_arch +[`process.platform`]: process.md#process_process_platform +[`uname(3)`]: https://linux.die.net/man/3/uname diff --git a/doc/api/packages.html b/doc/api/packages.html index c44228be6ee74d00525bda5314f0abd68a37754b..84639599e1ec354ba54f48f10540988ef753e2d1 100644 --- a/doc/api/packages.html +++ b/doc/api/packages.html @@ -1,10 +1,10 @@ - + - - Modules: Packages | Node.js v12.22.7 Documentation + + Modules: Packages | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      - +
      -

      Modules: Packages#

      +

      Modules: Packages#

      + -

      Introduction#

      +

      Introduction#

      A package is a folder tree described by a package.json file. The package consists of the folder containing the package.json file and all subfolders until the next folder containing another package.json file, or a folder named node_modules.

      This page provides guidance for package authors writing package.json files along with a reference for the package.json fields defined by Node.js.

      -

      Determining module system#

      +

      Determining module system#

      Node.js will treat the following as ES modules when passed to node as the initial input, or when referenced by import statements within ES module code:

        @@ -225,7 +248,7 @@ all sources are CommonJS. Being explicit about the type of the pack future-proof the package in case the default type of Node.js ever changes, and it will also make things easier for build tools and loaders to determine how the files in the package should be interpreted.

        -

        package.json and file extensions#

        +

        package.json and file extensions#

        Within a package, the package.json "type" field defines how Node.js should interpret .js files. If a package.json file does not have a "type" field, .js files are treated as CommonJS.

        @@ -272,7 +295,10 @@ extension (since both .js and .cjs files are treated a "commonjs" package).

      -

      --input-type flag#

      +

      --input-type flag#

      +

      Strings passed in as an argument to --eval (or -e), or piped to node via STDIN, are treated as ES modules when the --input-type=module flag is set.

      @@ -282,7 +308,7 @@ is set.

      For completeness there is also --input-type=commonjs, for explicitly running string input as CommonJS. This is the default behavior if --input-type is unspecified.

      -

      Package entry points#

      +

      Package entry points#

      In a package’s package.json file, two fields can define entry points for a package: "main" and "exports". The "main" field is supported in all versions of Node.js, but its capabilities are limited: it only defines @@ -312,46 +338,46 @@ previously supported entry point is exported. It is best to explicitly specify entry points so that the package’s public API is well-defined. For example, a project that previous exported main, lib, feature, and the package.json could use the following package.exports:

      -
      {
      -  "name": "my-mod",
      -  "exports": {
      -    ".": "./lib/index.js",
      -    "./lib": "./lib/index.js",
      -    "./lib/index": "./lib/index.js",
      -    "./lib/index.js": "./lib/index.js",
      -    "./feature": "./feature/index.js",
      -    "./feature/index.js": "./feature/index.js",
      -    "./package.json": "./package.json"
      -  }
      -}
      +
      {
      +  "name": "my-mod",
      +  "exports": {
      +    ".": "./lib/index.js",
      +    "./lib": "./lib/index.js",
      +    "./lib/index": "./lib/index.js",
      +    "./lib/index.js": "./lib/index.js",
      +    "./feature": "./feature/index.js",
      +    "./feature/index.js": "./feature/index.js",
      +    "./package.json": "./package.json"
      +  }
      +}

      Alternatively a project could choose to export entire folders:

      -
      {
      -  "name": "my-mod",
      -  "exports": {
      -    ".": "./lib/index.js",
      -    "./lib": "./lib/index.js",
      -    "./lib/*": "./lib/*.js",
      -    "./feature": "./feature/index.js",
      -    "./feature/*": "./feature/*.js",
      -    "./package.json": "./package.json"
      -  }
      -}
      +
      {
      +  "name": "my-mod",
      +  "exports": {
      +    ".": "./lib/index.js",
      +    "./lib": "./lib/index.js",
      +    "./lib/*": "./lib/*.js",
      +    "./feature": "./feature/index.js",
      +    "./feature/*": "./feature/*.js",
      +    "./package.json": "./package.json"
      +  }
      +}

      As a last resort, package encapsulation can be disabled entirely by creating an export for the root of the package "./*": "./*". This exposes every file in the package at the cost of disabling the encapsulation and potential tooling benefits this provides. As the ES Module loader in Node.js enforces the use of -the full specifier path, exporting the root rather than being explicit +the full specifier path, exporting the root rather than being explicit about entry is less expressive than either of the prior examples. Not only is encapsulation lost but module consumers are unable to import feature from 'my-mod/feature' as they need to provide the full path import feature from 'my-mod/feature/index.js.

      -

      Main entry point export#

      +

      Main entry point export#

      To set the main entry point for a package, it is advisable to define both "exports" and "main" in the package’s package.json file:

      -
      {
      -  "main": "./main.js",
      -  "exports": "./main.js"
      -}
      +
      {
      +  "main": "./main.js",
      +  "exports": "./main.js"
      +}

      When the "exports" field is defined, all subpaths of the package are encapsulated and no longer available to importers. For example, require('pkg/subpath.js') throws an ERR_PACKAGE_PATH_NOT_EXPORTED @@ -361,26 +387,30 @@ about package interfaces for tools and when handling semver upgrades for a package. It is not a strong encapsulation since a direct require of any absolute subpath of the package such as require('/path/to/node_modules/pkg/subpath.js') will still load subpath.js.

      -

      Subpath exports#

      -

      Stability: 1 - Experimental

      +

      Subpath exports#

      +

      When using the "exports" field, custom subpaths can be defined along with the main entry point by treating the main entry point as the "." subpath:

      -
      {
      -  "main": "./main.js",
      -  "exports": {
      -    ".": "./main.js",
      -    "./submodule": "./src/submodule.js"
      -  }
      -}
      +
      {
      +  "main": "./main.js",
      +  "exports": {
      +    ".": "./main.js",
      +    "./submodule": "./src/submodule.js"
      +  }
      +}

      Now only the defined subpath in "exports" can be imported by a consumer:

      import submodule from 'es-module-package/submodule';
       // Loads ./node_modules/es-module-package/src/submodule.js

      While other subpaths will error:

      import submodule from 'es-module-package/private-module.js';
       // Throws ERR_PACKAGE_PATH_NOT_EXPORTED
      -

      Subpath imports#

      -

      Stability: 1 - Experimental

      +

      Subpath imports#

      +

      In addition to the "exports" field, it is possible to define internal package import maps that only apply to import specifiers from within the package itself.

      @@ -389,17 +419,17 @@ disambiguated from package specifiers.

      For example, the imports field can be used to gain the benefits of conditional exports for internal modules:

      // package.json
      -{
      -  "imports": {
      -    "#dep": {
      -      "node": "dep-node-native",
      -      "default": "./dep-polyfill.js"
      -    }
      -  },
      -  "dependencies": {
      -    "dep-node-native": "^1.0.0"
      -  }
      -}
      +{ + "imports": { + "#dep": { + "node": "dep-node-native", + "default": "./dep-polyfill.js" + } + }, + "dependencies": { + "dep-node-native": "^1.0.0" + } +}

      where import '#dep' does not get the resolution of the external package dep-node-native (including its exports in turn), and instead gets the local file ./dep-polyfill.js relative to the package in other environments.

      @@ -407,22 +437,26 @@ file ./dep-polyfill.js relative to the package in other environment packages.

      The resolution rules for the imports field are otherwise analogous to the exports field.

      -

      Subpath patterns#

      -

      Stability: 1 - Experimental

      +

      Subpath patterns#

      +

      For packages with a small number of exports or imports, we recommend explicitly listing each exports subpath entry. But for packages that have large numbers of subpaths, this might cause package.json bloat and maintenance issues.

      For these use cases, subpath export patterns can be used instead:

      // ./node_modules/es-module-package/package.json
      -{
      -  "exports": {
      -    "./features/*": "./src/features/*.js"
      -  },
      -  "imports": {
      -    "#internal/*": "./src/internal/*.js"
      -  }
      -}
      +{ + "exports": { + "./features/*": "./src/features/*.js" + }, + "imports": { + "#internal/*": "./src/internal/*.js" + } +}
      +

      * maps expose nested subpaths as it is a string replacement syntax +only.

      The left hand matching pattern must always end in *. All instances of * on the right hand side will then be replaced with this value, including if it contains any / separators.

      @@ -442,37 +476,62 @@ patterns since the individual exports for a package can be determined by treating the right hand side target pattern as a ** glob against the list of files within the package. Because node_modules paths are forbidden in exports targets, this expansion is dependent on only the files of the package itself.

      -

      Exports sugar#

      -

      Stability: 1 - Experimental

      +

      To exclude private subfolders from patterns, null targets can be used:

      +
      // ./node_modules/es-module-package/package.json
      +{
      +  "exports": {
      +    "./features/*": "./src/features/*.js",
      +    "./features/private-internal/*": null
      +  }
      +}
      +
      import featureInternal from 'es-module-package/features/private-internal/m';
      +// Throws: ERR_PACKAGE_PATH_NOT_EXPORTED
      +
      +import featureX from 'es-module-package/features/x';
      +// Loads ./node_modules/es-module-package/src/features/x.js
      +

      Exports sugar#

      +

      If the "." export is the only export, the "exports" field provides sugar for this case being the direct "exports" field value.

      If the "." export has a fallback array or string value, then the "exports" field can be set to this value directly.

      -
      {
      -  "exports": {
      -    ".": "./main.js"
      -  }
      -}
      +
      {
      +  "exports": {
      +    ".": "./main.js"
      +  }
      +}

      can be written:

      -
      {
      -  "exports": "./main.js"
      -}
      -

      Conditional exports#

      -

      Stability: 1 - Experimental

      +
      {
      +  "exports": "./main.js"
      +}
      +

      Conditional exports#

      +

      Conditional exports provide a way to map to different paths depending on certain conditions. They are supported for both CommonJS and ES module imports.

      For example, a package that wants to provide different ES module exports for require() and import can be written:

      // package.json
      -{
      -  "main": "./main-require.cjs",
      -  "exports": {
      -    "import": "./main-module.js",
      -    "require": "./main-require.cjs"
      -  },
      -  "type": "module"
      -}
      -

      Node.js supports the following conditions out of the box:

      +{ + "main": "./main-require.cjs", + "exports": { + "import": "./main-module.js", + "require": "./main-require.cjs" + }, + "type": "module" +}
      +

      Node.js implements the following conditions:

      • "import" - matches when the package is loaded via import or import(), or via any top-level import or resolve operation by the @@ -494,23 +553,19 @@ or ES module file. This condition should always come last.
      • matching, earlier entries have higher priority and take precedence over later entries. The general rule is that conditions should be from most specific to least specific in object order.

        -

        Other conditions such as "browser", "electron", "deno", "react-native", -etc., are unknown to Node.js, and thus ignored. Runtimes or tools other than -Node.js can use them at their discretion. Further restrictions, definitions, or -guidance on condition names might occur in the future.

        Using the "import" and "require" conditions can lead to some hazards, which are further explained in the dual CommonJS/ES module packages section.

        Conditional exports can also be extended to exports subpaths, for example:

        -
        {
        -  "main": "./main.js",
        -  "exports": {
        -    ".": "./main.js",
        -    "./feature": {
        -      "node": "./feature-node.js",
        -      "default": "./feature.js"
        -    }
        -  }
        -}
        +
        {
        +  "main": "./main.js",
        +  "exports": {
        +    ".": "./main.js",
        +    "./feature": {
        +      "node": "./feature-node.js",
        +      "default": "./feature.js"
        +    }
        +  }
        +}

        Defines a package where require('pkg/feature') and import 'pkg/feature' could provide different implementations between Node.js and other JS environments.

        @@ -521,26 +576,28 @@ these JS environments from having to pretend to be existing environments in order to support packages with conditional exports. For this reason, using "node" and "default" condition branches is usually preferable to using "node" and "browser" condition branches.

        -

        Nested conditions#

        -

        Stability: 1 - Experimental

        +

        Nested conditions#

        In addition to direct mappings, Node.js also supports nested condition objects.

        For example, to define a package that only has dual mode entry points for use in Node.js but not the browser:

        -
        {
        -  "main": "./main.js",
        -  "exports": {
        -    "node": {
        -      "import": "./feature-node.mjs",
        -      "require": "./feature-node.cjs"
        -    },
        -    "default": "./feature.mjs",
        -  }
        -}
        +
        {
        +  "main": "./main.js",
        +  "exports": {
        +    "node": {
        +      "import": "./feature-node.mjs",
        +      "require": "./feature-node.cjs"
        +    },
        +    "default": "./feature.mjs",
        +  }
        +}

        Conditions continue to be matched in order as with flat conditions. If a nested conditional does not have any mapping it will continue checking the remaining conditions of the parent condition. In this way nested conditions behave analogously to nested JavaScript if statements.

        -

        Resolving user conditions#

        +

        Resolving user conditions#

        +

        When running Node.js, custom user conditions can be added with the --conditions flag:

        node --conditions=development main.js
        @@ -548,18 +605,68 @@ conditions behave analogously to nested JavaScript if statements."node"
        , "default", "import", and "require" conditions as appropriate.

        Any number of custom conditions can be set with repeat flags.

        -

        Self-referencing a package using its name#

        +

        Conditions Definitions#

        +

        The "import", "require", "node" and "default" conditions are defined +and implemented in Node.js core, +as specified above.

        +

        Other condition strings are unknown to Node.js and thus ignored by default. +Runtimes or tools other than Node.js can use them at their discretion.

        +

        These user conditions can be enabled in Node.js via the --conditions +flag.

        +

        The following condition definitions are currently endorsed by Node.js:

        +
          +
        • "browser" - any environment which implements a standard subset of global +browser APIs available from JavaScript in web browsers, including the DOM +APIs.
        • +
        • "development" - can be used to define a development-only environment +entry point. Must always be mutually exclusive with "production".
        • +
        • "production" - can be used to define a production environment entry +point. Must always be mutually exclusive with "development".
        • +
        +

        The above user conditions can be enabled in Node.js via the --conditions +flag.

        +

        Platform specific conditions such as "deno", "electron", or "react-native" +may be used, but while there remain no implementation or integration intent +from these platforms, the above are not explicitly endorsed by Node.js.

        +

        New conditions definitions may be added to this list by creating a pull request +to the Node.js documentation for this section. The requirements for listing +a new condition definition here are that:

        +
          +
        • The definition should be clear and unambiguous for all implementers.
        • +
        • The use case for why the condition is needed should be clearly justified.
        • +
        • There should exist sufficient existing implementation usage.
        • +
        • The condition name should not conflict with another condition definition or +condition in wide usage.
        • +
        • The listing of the condition definition should provide a coordination +benefit to the ecosystem that wouldn't otherwise be possible. For example, +this would not necessarily be the case for company-specific or +application-specific conditions.
        • +
        +

        The above definitions may be moved to a dedicated conditions registry in due +course.

        +

        Self-referencing a package using its name#

        +

        Within a package, the values defined in the package’s package.json "exports" field can be referenced via the package’s name. For example, assuming the package.json is:

        // package.json
        -{
        -  "name": "a-package",
        -  "exports": {
        -    ".": "./main.mjs",
        -    "./foo": "./foo.js"
        -  }
        -}
        +{ + "name": "a-package", + "exports": { + ".": "./main.mjs", + "./foo": "./foo.js" + } +}

        Then any module in that package can reference an export in the package itself:

        // ./a-module.mjs
         import { something } from 'a-package'; // Imports "something" from ./main.mjs.
        @@ -575,9 +682,22 @@ error:

        import { another } from 'a-package/m.mjs';

        Self-referencing is also available when using require, both in an ES module, and in a CommonJS one. For example, this code will also work:

        -
        // ./a-module.js
        +
        // ./a-module.js
         const { something } = require('a-package/foo'); // Loads from ./foo.js.
        -

        Dual CommonJS/ES module packages#

        +

        Finally, self-referencing also works with scoped packages. For example, this +code will also work:

        +
        // package.json
        +{
        +  "name": "@my/package",
        +  "exports": "./index.js"
        +}
        + +
        // ./index.js
        +module.exports = 42;
        // ./other.js +console.log(require('@my/package'));
        +
        $ node other.js
        +42
        +

      Dual CommonJS/ES module packages#

      Prior to the introduction of support for ES modules in Node.js, it was a common pattern for package authors to include both CommonJS and ES module JavaScript sources in their package, with package.json "main" specifying the @@ -593,7 +713,7 @@ exports). Unlike in the scenario where "module" is only used by or ES module files are transpiled into CommonJS on the fly before evaluation by Node.js, the files referenced by the ES module entry point are evaluated as ES modules.

      -

      Dual package hazard#

      +

      Dual package hazard#

      When an application is using a package that provides both CommonJS and ES module sources, there is a risk of certain bugs if both versions of the package get loaded. This potential comes from the fact that the pkgInstance created by @@ -613,7 +733,7 @@ the other. This differs from how import and require st all-CommonJS or all-ES module environments, respectively, and therefore is surprising to users. It also differs from the behavior users are familiar with when using transpilation via tools like Babel or esm.

      -

      Writing dual packages while avoiding or minimizing hazards#

      +

      Writing dual packages while avoiding or minimizing hazards#

      First, the hazard described in the previous section occurs when a package contains both CommonJS and ES module sources and both sources are provided for use in Node.js, either via separate main entry points or exported paths. A @@ -641,30 +761,30 @@ than import pkg from 'pkg'; pkg.name. browsers.

    • The hazards described in the previous section are avoided or minimized.
    • -

      Approach #1: Use an ES module wrapper#

      +
      Approach #1: Use an ES module wrapper#

      Write the package in CommonJS or transpile ES module sources into CommonJS, and create an ES module wrapper file that defines the named exports. Using Conditional exports, the ES module wrapper is used for import and the CommonJS entry point for require.

      // ./node_modules/pkg/package.json
      -{
      -  "type": "module",
      -  "main": "./index.cjs",
      -  "exports": {
      -    "import": "./wrapper.mjs",
      -    "require": "./index.cjs"
      -  }
      -}
      +{ + "type": "module", + "main": "./index.cjs", + "exports": { + "import": "./wrapper.mjs", + "require": "./index.cjs" + } +}

      The preceding example uses explicit extensions .mjs and .cjs. If your files use the .js extension, "type": "module" will cause such files to be treated as ES modules, just as "type": "commonjs" would cause them to be treated as CommonJS. -See Enabling.

      -
      // ./node_modules/pkg/index.cjs
      -exports.name = 'value';
      +See Enabling.

      +
      // ./node_modules/pkg/index.cjs
      +exports.name = 'value';
      // ./node_modules/pkg/wrapper.mjs
       import cjsModule from './index.cjs';
      -export const name = cjsModule.name;
      +export const name = cjsModule.name;

      In this example, the name from import { name } from 'pkg' is the same singleton as the name from const { name } = require('pkg'). Therefore === returns true when comparing the two names and the divergent specifier hazard @@ -675,7 +795,7 @@ or if support in the wrapper for the import pkg from 'pkg' pattern then the wrapper would instead be written to export the default optionally along with any named exports as well:

      import cjsModule from './index.cjs';
      -export const name = cjsModule.name;
      +export const name = cjsModule.name;
       export default cjsModule;

      This approach is appropriate for any of the following use cases:

        @@ -699,26 +819,26 @@ application, such as by dependencies; or if the CommonJS version can be loaded but doesn’t affect the ES module version (for example, because the package is stateless):

        // ./node_modules/pkg/package.json
        -{
        -  "type": "module",
        -  "main": "./index.cjs",
        -  "exports": {
        -    ".": "./index.cjs",
        -    "./module": "./wrapper.mjs"
        -  }
        -}
        -

        Approach #2: Isolate state#

        +{ + "type": "module", + "main": "./index.cjs", + "exports": { + ".": "./index.cjs", + "./module": "./wrapper.mjs" + } +}
        +
        Approach #2: Isolate state#

        A package.json file can define the separate CommonJS and ES module entry points directly:

        // ./node_modules/pkg/package.json
        -{
        -  "type": "module",
        -  "main": "./index.cjs",
        -  "exports": {
        -    "import": "./index.mjs",
        -    "require": "./index.cjs"
        -  }
        -}
        +{ + "type": "module", + "main": "./index.cjs", + "exports": { + "import": "./index.mjs", + "require": "./index.cjs" + } +}

        This can be done if both the CommonJS and ES module versions of the package are equivalent, for example because one is the transpiled output of the other; and the package’s management of state is carefully isolated (or the package is @@ -738,8 +858,8 @@ CommonJS and ES module instances of the package:

        If possible, contain all state within an instantiated object. JavaScript’s Date, for example, needs to be instantiated to contain state; if it were a package, it would be used like this:

        -
        import Date from 'date';
        -const someDate = new Date();
        +
        import Date from 'date';
        +const someDate = new Date();
         // someDate contains state; Date does not

        The new keyword isn’t required; a package’s function can return a new object, or modify a passed-in object, to keep the state external to the @@ -749,9 +869,9 @@ package.

        Isolate the state in one or more CommonJS files that are shared between the CommonJS and ES module versions of the package. For example, if the CommonJS and ES module entry points are index.cjs and index.mjs, respectively:

        -
        // ./node_modules/pkg/index.cjs
        +
        // ./node_modules/pkg/index.cjs
         const state = require('./state.cjs');
        -module.exports.state = state;
        +module.exports.state = state;
        // ./node_modules/pkg/index.mjs
         import state from './state.cjs';
         export {
        @@ -781,15 +901,15 @@ execution between the CommonJS and ES module versions of a package.

        conditional exports for consumers could be to add an export, e.g. "./module", to point to an all-ES module-syntax version of the package:

        // ./node_modules/pkg/package.json
        -{
        -  "type": "module",
        -  "main": "./index.cjs",
        -  "exports": {
        -    ".": "./index.cjs",
        -    "./module": "./index.mjs"
        -  }
        -}
        -

        Node.js package.json field definitions#

        +{ + "type": "module", + "main": "./index.cjs", + "exports": { + ".": "./index.cjs", + "./module": "./index.mjs" + } +}
        +

      Node.js package.json field definitions#

      This section describes the fields used by the Node.js runtime. Other tools (such as npm) use additional fields which are ignored by Node.js and not documented here.

      @@ -797,44 +917,60 @@ additional fields which are ignored by Node.js and not documented here.

      • "name" - Relevant when using named imports within a package. Also used by package managers as the name of the package.
      • +
      • "main" - The default module when loading the package, if exports is not +specified, and in versions of Node.js prior to the introduction of exports.
      • "type" - The package type determining whether to load .js files as CommonJS or ES modules.
      • "exports" - Package exports and conditional exports. When present, limits which submodules can be loaded from within the package.
      • -
      • "main" - The default module when loading the package, if exports is not -specified, and in versions of Node.js prior to the introduction of exports.
      • "imports" - Package imports, for use by modules within the package itself.
      -

      "name"#

      +

      "name"#

      -
      {
      -  "name": "package-name"
      -}
      +
      {
      +  "name": "package-name"
      +}

      The "name" field defines your package’s name. Publishing to the npm registry requires a name that satisfies certain requirements.

      The "name" field can be used in addition to the "exports" field to self-reference a package using its name.

      -

      "type"#

      +

      "main"#

      + + +
      {
      +  "main": "./main.js"
      +}
      +

      The "main" field defines the script that is used when the package directory +is loaded via require(). Its value +is a path.

      +
      require('./path/to/directory'); // This resolves to ./path/to/directory/main.js.
      +

      When a package has an "exports" field, this will take precedence over the +"main" field when importing the package by name.

      +

      "type"#

      + diff --git a/doc/api/packages.json b/doc/api/packages.json index 0056e8765732d1d25a795a62a1e678293a659852..50a7c1a84580d40638562654a34ee2c32d300cb4 100644 --- a/doc/api/packages.json +++ b/doc/api/packages.json @@ -1,20 +1,27 @@ { "type": "module", "source": "doc/api/packages.md", + "introduced_in": "v12.20.0", "meta": { "changes": [ { - "version": "v12.20.0", + "version": [ + "v14.13.0" + ], "pr-url": "https://github.com/nodejs/node/pull/34718", "description": "Add support for `\"exports\"` patterns." }, { - "version": "v12.19.0", + "version": [ + "v14.6.0", + "v12.19.0" + ], "pr-url": "https://github.com/nodejs/node/pull/34117", "description": "Add package `\"imports\"` field." }, { "version": [ + "v13.7.0", "v12.16.0" ], "pr-url": "https://github.com/nodejs/node/pull/31001", @@ -22,6 +29,7 @@ }, { "version": [ + "v13.6.0", "v12.16.0" ], "pr-url": "https://github.com/nodejs/node/pull/31002", @@ -43,21 +51,28 @@ { "textRaw": "Modules: Packages", "name": "Modules: Packages", + "introduced_in": "v12.20.0", "type": "misc", "meta": { "changes": [ { - "version": "v12.20.0", + "version": [ + "v14.13.0" + ], "pr-url": "https://github.com/nodejs/node/pull/34718", "description": "Add support for `\"exports\"` patterns." }, { - "version": "v12.19.0", + "version": [ + "v14.6.0", + "v12.19.0" + ], "pr-url": "https://github.com/nodejs/node/pull/34117", "description": "Add package `\"imports\"` field." }, { "version": [ + "v13.7.0", "v12.16.0" ], "pr-url": "https://github.com/nodejs/node/pull/31001", @@ -65,6 +80,7 @@ }, { "version": [ + "v13.6.0", "v12.16.0" ], "pr-url": "https://github.com/nodejs/node/pull/31002", @@ -105,6 +121,12 @@ { "textRaw": "`--input-type` flag", "name": "`--input-type`_flag", + "meta": { + "added": [ + "v12.0.0" + ], + "changes": [] + }, "desc": "

      Strings passed in as an argument to --eval (or -e), or piped to node via\nSTDIN, are treated as ES modules when the --input-type=module flag\nis set.

      \n
      node --input-type=module --eval \"import { sep } from 'path'; console.log(sep);\"\n\necho \"import { sep } from 'path'; console.log(sep);\" | node --input-type=module\n
      \n

      For completeness there is also --input-type=commonjs, for explicitly running\nstring input as CommonJS. This is the default behavior if --input-type is\nunspecified.

      ", "type": "module", "displayName": "`--input-type` flag" @@ -116,7 +138,7 @@ { "textRaw": "Package entry points", "name": "package_entry_points", - "desc": "

      In a package’s package.json file, two fields can define entry points for a\npackage: \"main\" and \"exports\". The \"main\" field is supported\nin all versions of Node.js, but its capabilities are limited: it only defines\nthe main entry point of the package.

      \n

      The \"exports\" field provides an alternative to \"main\" where the\npackage main entry point can be defined while also encapsulating the package,\npreventing any other entry points besides those defined in \"exports\".\nThis encapsulation allows module authors to define a public interface for\ntheir package.

      \n

      If both \"exports\" and \"main\" are defined, the \"exports\" field\ntakes precedence over \"main\". \"exports\" are not specific to ES\nmodules or CommonJS; \"main\" is overridden by \"exports\" if it\nexists. As such \"main\" cannot be used as a fallback for CommonJS but it\ncan be used as a fallback for legacy versions of Node.js that do not support the\n\"exports\" field.

      \n

      Conditional exports can be used within \"exports\" to define different\npackage entry points per environment, including whether the package is\nreferenced via require or via import. For more information about supporting\nboth CommonJS and ES Modules in a single package please consult\nthe dual CommonJS/ES module packages section.

      \n

      Warning: Introducing the \"exports\" field prevents consumers of a\npackage from using any entry points that are not defined, including the\npackage.json (e.g. require('your-package/package.json'). This will\nlikely be a breaking change.

      \n

      To make the introduction of \"exports\" non-breaking, ensure that every\npreviously supported entry point is exported. It is best to explicitly specify\nentry points so that the package’s public API is well-defined. For example,\na project that previous exported main, lib,\nfeature, and the package.json could use the following package.exports:

      \n
      {\n  \"name\": \"my-mod\",\n  \"exports\": {\n    \".\": \"./lib/index.js\",\n    \"./lib\": \"./lib/index.js\",\n    \"./lib/index\": \"./lib/index.js\",\n    \"./lib/index.js\": \"./lib/index.js\",\n    \"./feature\": \"./feature/index.js\",\n    \"./feature/index.js\": \"./feature/index.js\",\n    \"./package.json\": \"./package.json\"\n  }\n}\n
      \n

      Alternatively a project could choose to export entire folders:

      \n
      {\n  \"name\": \"my-mod\",\n  \"exports\": {\n    \".\": \"./lib/index.js\",\n    \"./lib\": \"./lib/index.js\",\n    \"./lib/*\": \"./lib/*.js\",\n    \"./feature\": \"./feature/index.js\",\n    \"./feature/*\": \"./feature/*.js\",\n    \"./package.json\": \"./package.json\"\n  }\n}\n
      \n

      As a last resort, package encapsulation can be disabled entirely by creating an\nexport for the root of the package \"./*\": \"./*\". This exposes every file\nin the package at the cost of disabling the encapsulation and potential tooling\nbenefits this provides. As the ES Module loader in Node.js enforces the use of\nthe full specifier path, exporting the root rather than being explicit\nabout entry is less expressive than either of the prior examples. Not only\nis encapsulation lost but module consumers are unable to\nimport feature from 'my-mod/feature' as they need to provide the full\npath import feature from 'my-mod/feature/index.js.

      ", + "desc": "

      In a package’s package.json file, two fields can define entry points for a\npackage: \"main\" and \"exports\". The \"main\" field is supported\nin all versions of Node.js, but its capabilities are limited: it only defines\nthe main entry point of the package.

      \n

      The \"exports\" field provides an alternative to \"main\" where the\npackage main entry point can be defined while also encapsulating the package,\npreventing any other entry points besides those defined in \"exports\".\nThis encapsulation allows module authors to define a public interface for\ntheir package.

      \n

      If both \"exports\" and \"main\" are defined, the \"exports\" field\ntakes precedence over \"main\". \"exports\" are not specific to ES\nmodules or CommonJS; \"main\" is overridden by \"exports\" if it\nexists. As such \"main\" cannot be used as a fallback for CommonJS but it\ncan be used as a fallback for legacy versions of Node.js that do not support the\n\"exports\" field.

      \n

      Conditional exports can be used within \"exports\" to define different\npackage entry points per environment, including whether the package is\nreferenced via require or via import. For more information about supporting\nboth CommonJS and ES Modules in a single package please consult\nthe dual CommonJS/ES module packages section.

      \n

      Warning: Introducing the \"exports\" field prevents consumers of a\npackage from using any entry points that are not defined, including the\npackage.json (e.g. require('your-package/package.json'). This will\nlikely be a breaking change.

      \n

      To make the introduction of \"exports\" non-breaking, ensure that every\npreviously supported entry point is exported. It is best to explicitly specify\nentry points so that the package’s public API is well-defined. For example,\na project that previous exported main, lib,\nfeature, and the package.json could use the following package.exports:

      \n
      {\n  \"name\": \"my-mod\",\n  \"exports\": {\n    \".\": \"./lib/index.js\",\n    \"./lib\": \"./lib/index.js\",\n    \"./lib/index\": \"./lib/index.js\",\n    \"./lib/index.js\": \"./lib/index.js\",\n    \"./feature\": \"./feature/index.js\",\n    \"./feature/index.js\": \"./feature/index.js\",\n    \"./package.json\": \"./package.json\"\n  }\n}\n
      \n

      Alternatively a project could choose to export entire folders:

      \n
      {\n  \"name\": \"my-mod\",\n  \"exports\": {\n    \".\": \"./lib/index.js\",\n    \"./lib\": \"./lib/index.js\",\n    \"./lib/*\": \"./lib/*.js\",\n    \"./feature\": \"./feature/index.js\",\n    \"./feature/*\": \"./feature/*.js\",\n    \"./package.json\": \"./package.json\"\n  }\n}\n
      \n

      As a last resort, package encapsulation can be disabled entirely by creating an\nexport for the root of the package \"./*\": \"./*\". This exposes every file\nin the package at the cost of disabling the encapsulation and potential tooling\nbenefits this provides. As the ES Module loader in Node.js enforces the use of\nthe full specifier path, exporting the root rather than being explicit\nabout entry is less expressive than either of the prior examples. Not only\nis encapsulation lost but module consumers are unable to\nimport feature from 'my-mod/feature' as they need to provide the full\npath import feature from 'my-mod/feature/index.js.

      ", "modules": [ { "textRaw": "Main entry point export", @@ -128,8 +150,12 @@ { "textRaw": "Subpath exports", "name": "subpath_exports", - "stability": 1, - "stabilityText": "Experimental", + "meta": { + "added": [ + "v12.7.0" + ], + "changes": [] + }, "desc": "

      When using the \"exports\" field, custom subpaths can be defined along\nwith the main entry point by treating the main entry point as the\n\".\" subpath:

      \n
      {\n  \"main\": \"./main.js\",\n  \"exports\": {\n    \".\": \"./main.js\",\n    \"./submodule\": \"./src/submodule.js\"\n  }\n}\n
      \n

      Now only the defined subpath in \"exports\" can be imported by a consumer:

      \n
      import submodule from 'es-module-package/submodule';\n// Loads ./node_modules/es-module-package/src/submodule.js\n
      \n

      While other subpaths will error:

      \n
      import submodule from 'es-module-package/private-module.js';\n// Throws ERR_PACKAGE_PATH_NOT_EXPORTED\n
      ", "type": "module", "displayName": "Subpath exports" @@ -137,8 +163,13 @@ { "textRaw": "Subpath imports", "name": "subpath_imports", - "stability": 1, - "stabilityText": "Experimental", + "meta": { + "added": [ + "v14.6.0", + "v12.19.0" + ], + "changes": [] + }, "desc": "

      In addition to the \"exports\" field, it is possible to define internal\npackage import maps that only apply to import specifiers from within the package\nitself.

      \n

      Entries in the imports field must always start with # to ensure they are\ndisambiguated from package specifiers.

      \n

      For example, the imports field can be used to gain the benefits of conditional\nexports for internal modules:

      \n
      // package.json\n{\n  \"imports\": {\n    \"#dep\": {\n      \"node\": \"dep-node-native\",\n      \"default\": \"./dep-polyfill.js\"\n    }\n  },\n  \"dependencies\": {\n    \"dep-node-native\": \"^1.0.0\"\n  }\n}\n
      \n

      where import '#dep' does not get the resolution of the external package\ndep-node-native (including its exports in turn), and instead gets the local\nfile ./dep-polyfill.js relative to the package in other environments.

      \n

      Unlike the \"exports\" field, the \"imports\" field permits mapping to external\npackages.

      \n

      The resolution rules for the imports field are otherwise\nanalogous to the exports field.

      ", "type": "module", "displayName": "Subpath imports" @@ -146,17 +177,26 @@ { "textRaw": "Subpath patterns", "name": "subpath_patterns", - "stability": 1, - "stabilityText": "Experimental", - "desc": "

      For packages with a small number of exports or imports, we recommend\nexplicitly listing each exports subpath entry. But for packages that have\nlarge numbers of subpaths, this might cause package.json bloat and\nmaintenance issues.

      \n

      For these use cases, subpath export patterns can be used instead:

      \n
      // ./node_modules/es-module-package/package.json\n{\n  \"exports\": {\n    \"./features/*\": \"./src/features/*.js\"\n  },\n  \"imports\": {\n    \"#internal/*\": \"./src/internal/*.js\"\n  }\n}\n
      \n

      The left hand matching pattern must always end in *. All instances of * on\nthe right hand side will then be replaced with this value, including if it\ncontains any / separators.

      \n
      import featureX from 'es-module-package/features/x';\n// Loads ./node_modules/es-module-package/src/features/x.js\n\nimport featureY from 'es-module-package/features/y/y';\n// Loads ./node_modules/es-module-package/src/features/y/y.js\n\nimport internalZ from '#internal/z';\n// Loads ./node_modules/es-module-package/src/internal/z.js\n
      \n

      This is a direct static replacement without any special handling for file\nextensions. In the previous example, pkg/features/x.json would be resolved to\n./src/features/x.json.js in the mapping.

      \n

      The property of exports being statically enumerable is maintained with exports\npatterns since the individual exports for a package can be determined by\ntreating the right hand side target pattern as a ** glob against the list of\nfiles within the package. Because node_modules paths are forbidden in exports\ntargets, this expansion is dependent on only the files of the package itself.

      ", + "meta": { + "added": [ + "v14.13.0", + "v12.20.0" + ], + "changes": [] + }, + "desc": "

      For packages with a small number of exports or imports, we recommend\nexplicitly listing each exports subpath entry. But for packages that have\nlarge numbers of subpaths, this might cause package.json bloat and\nmaintenance issues.

      \n

      For these use cases, subpath export patterns can be used instead:

      \n
      // ./node_modules/es-module-package/package.json\n{\n  \"exports\": {\n    \"./features/*\": \"./src/features/*.js\"\n  },\n  \"imports\": {\n    \"#internal/*\": \"./src/internal/*.js\"\n  }\n}\n
      \n

      * maps expose nested subpaths as it is a string replacement syntax\nonly.

      \n

      The left hand matching pattern must always end in *. All instances of * on\nthe right hand side will then be replaced with this value, including if it\ncontains any / separators.

      \n
      import featureX from 'es-module-package/features/x';\n// Loads ./node_modules/es-module-package/src/features/x.js\n\nimport featureY from 'es-module-package/features/y/y';\n// Loads ./node_modules/es-module-package/src/features/y/y.js\n\nimport internalZ from '#internal/z';\n// Loads ./node_modules/es-module-package/src/internal/z.js\n
      \n

      This is a direct static replacement without any special handling for file\nextensions. In the previous example, pkg/features/x.json would be resolved to\n./src/features/x.json.js in the mapping.

      \n

      The property of exports being statically enumerable is maintained with exports\npatterns since the individual exports for a package can be determined by\ntreating the right hand side target pattern as a ** glob against the list of\nfiles within the package. Because node_modules paths are forbidden in exports\ntargets, this expansion is dependent on only the files of the package itself.

      \n

      To exclude private subfolders from patterns, null targets can be used:

      \n
      // ./node_modules/es-module-package/package.json\n{\n  \"exports\": {\n    \"./features/*\": \"./src/features/*.js\",\n    \"./features/private-internal/*\": null\n  }\n}\n
      \n
      import featureInternal from 'es-module-package/features/private-internal/m';\n// Throws: ERR_PACKAGE_PATH_NOT_EXPORTED\n\nimport featureX from 'es-module-package/features/x';\n// Loads ./node_modules/es-module-package/src/features/x.js\n
      ", "type": "module", "displayName": "Subpath patterns" }, { "textRaw": "Exports sugar", "name": "exports_sugar", - "stability": 1, - "stabilityText": "Experimental", + "meta": { + "added": [ + "v12.11.0" + ], + "changes": [] + }, "desc": "

      If the \".\" export is the only export, the \"exports\" field provides sugar\nfor this case being the direct \"exports\" field value.

      \n

      If the \".\" export has a fallback array or string value, then the\n\"exports\" field can be set to this value directly.

      \n
      {\n  \"exports\": {\n    \".\": \"./main.js\"\n  }\n}\n
      \n

      can be written:

      \n
      {\n  \"exports\": \"./main.js\"\n}\n
      ", "type": "module", "displayName": "Exports sugar" @@ -164,17 +204,29 @@ { "textRaw": "Conditional exports", "name": "conditional_exports", - "stability": 1, - "stabilityText": "Experimental", - "desc": "

      Conditional exports provide a way to map to different paths depending on\ncertain conditions. They are supported for both CommonJS and ES module imports.

      \n

      For example, a package that wants to provide different ES module exports for\nrequire() and import can be written:

      \n
      // package.json\n{\n  \"main\": \"./main-require.cjs\",\n  \"exports\": {\n    \"import\": \"./main-module.js\",\n    \"require\": \"./main-require.cjs\"\n  },\n  \"type\": \"module\"\n}\n
      \n

      Node.js supports the following conditions out of the box:

      \n
        \n
      • \"import\" - matches when the package is loaded via import or\nimport(), or via any top-level import or resolve operation by the\nECMAScript module loader. Applies regardless of the module format of the\ntarget file. Always mutually exclusive with \"require\".
      • \n
      • \"require\" - matches when the package is loaded via require(). The\nreferenced file should be loadable with require() although the condition\nmatches regardless of the module format of the target file. Expected\nformats include CommonJS, JSON, and native addons but not ES modules as\nrequire() doesn't support them. Always mutually exclusive with\n\"import\".
      • \n
      • \"node\" - matches for any Node.js environment. Can be a CommonJS or ES\nmodule file. This condition should always come after \"import\" or\n\"require\".
      • \n
      • \"default\" - the generic fallback that always matches. Can be a CommonJS\nor ES module file. This condition should always come last.
      • \n
      \n

      Within the \"exports\" object, key order is significant. During condition\nmatching, earlier entries have higher priority and take precedence over later\nentries. The general rule is that conditions should be from most specific to\nleast specific in object order.

      \n

      Other conditions such as \"browser\", \"electron\", \"deno\", \"react-native\",\netc., are unknown to Node.js, and thus ignored. Runtimes or tools other than\nNode.js can use them at their discretion. Further restrictions, definitions, or\nguidance on condition names might occur in the future.

      \n

      Using the \"import\" and \"require\" conditions can lead to some hazards,\nwhich are further explained in the dual CommonJS/ES module packages section.

      \n

      Conditional exports can also be extended to exports subpaths, for example:

      \n
      {\n  \"main\": \"./main.js\",\n  \"exports\": {\n    \".\": \"./main.js\",\n    \"./feature\": {\n      \"node\": \"./feature-node.js\",\n      \"default\": \"./feature.js\"\n    }\n  }\n}\n
      \n

      Defines a package where require('pkg/feature') and import 'pkg/feature'\ncould provide different implementations between Node.js and other JS\nenvironments.

      \n

      When using environment branches, always include a \"default\" condition where\npossible. Providing a \"default\" condition ensures that any unknown JS\nenvironments are able to use this universal implementation, which helps avoid\nthese JS environments from having to pretend to be existing environments in\norder to support packages with conditional exports. For this reason, using\n\"node\" and \"default\" condition branches is usually preferable to using\n\"node\" and \"browser\" condition branches.

      ", + "meta": { + "added": [ + "v13.2.0", + "v12.16.0" + ], + "changes": [ + { + "version": [ + "v13.7.0", + "v12.16.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/31001", + "description": "Unflag conditional exports." + } + ] + }, + "desc": "

      Conditional exports provide a way to map to different paths depending on\ncertain conditions. They are supported for both CommonJS and ES module imports.

      \n

      For example, a package that wants to provide different ES module exports for\nrequire() and import can be written:

      \n
      // package.json\n{\n  \"main\": \"./main-require.cjs\",\n  \"exports\": {\n    \"import\": \"./main-module.js\",\n    \"require\": \"./main-require.cjs\"\n  },\n  \"type\": \"module\"\n}\n
      \n

      Node.js implements the following conditions:

      \n
        \n
      • \"import\" - matches when the package is loaded via import or\nimport(), or via any top-level import or resolve operation by the\nECMAScript module loader. Applies regardless of the module format of the\ntarget file. Always mutually exclusive with \"require\".
      • \n
      • \"require\" - matches when the package is loaded via require(). The\nreferenced file should be loadable with require() although the condition\nmatches regardless of the module format of the target file. Expected\nformats include CommonJS, JSON, and native addons but not ES modules as\nrequire() doesn't support them. Always mutually exclusive with\n\"import\".
      • \n
      • \"node\" - matches for any Node.js environment. Can be a CommonJS or ES\nmodule file. This condition should always come after \"import\" or\n\"require\".
      • \n
      • \"default\" - the generic fallback that always matches. Can be a CommonJS\nor ES module file. This condition should always come last.
      • \n
      \n

      Within the \"exports\" object, key order is significant. During condition\nmatching, earlier entries have higher priority and take precedence over later\nentries. The general rule is that conditions should be from most specific to\nleast specific in object order.

      \n

      Using the \"import\" and \"require\" conditions can lead to some hazards,\nwhich are further explained in the dual CommonJS/ES module packages section.

      \n

      Conditional exports can also be extended to exports subpaths, for example:

      \n
      {\n  \"main\": \"./main.js\",\n  \"exports\": {\n    \".\": \"./main.js\",\n    \"./feature\": {\n      \"node\": \"./feature-node.js\",\n      \"default\": \"./feature.js\"\n    }\n  }\n}\n
      \n

      Defines a package where require('pkg/feature') and import 'pkg/feature'\ncould provide different implementations between Node.js and other JS\nenvironments.

      \n

      When using environment branches, always include a \"default\" condition where\npossible. Providing a \"default\" condition ensures that any unknown JS\nenvironments are able to use this universal implementation, which helps avoid\nthese JS environments from having to pretend to be existing environments in\norder to support packages with conditional exports. For this reason, using\n\"node\" and \"default\" condition branches is usually preferable to using\n\"node\" and \"browser\" condition branches.

      ", "type": "module", "displayName": "Conditional exports" }, { "textRaw": "Nested conditions", "name": "nested_conditions", - "stability": 1, - "stabilityText": "Experimental", "desc": "

      In addition to direct mappings, Node.js also supports nested condition objects.

      \n

      For example, to define a package that only has dual mode entry points for\nuse in Node.js but not the browser:

      \n
      {\n  \"main\": \"./main.js\",\n  \"exports\": {\n    \"node\": {\n      \"import\": \"./feature-node.mjs\",\n      \"require\": \"./feature-node.cjs\"\n    },\n    \"default\": \"./feature.mjs\",\n  }\n}\n
      \n

      Conditions continue to be matched in order as with flat conditions. If\na nested conditional does not have any mapping it will continue checking\nthe remaining conditions of the parent condition. In this way nested\nconditions behave analogously to nested JavaScript if statements.

      ", "type": "module", "displayName": "Nested conditions" @@ -182,14 +234,44 @@ { "textRaw": "Resolving user conditions", "name": "resolving_user_conditions", + "meta": { + "added": [ + "v14.9.0", + "v12.19.0" + ], + "changes": [] + }, "desc": "

      When running Node.js, custom user conditions can be added with the\n--conditions flag:

      \n
      node --conditions=development main.js\n
      \n

      which would then resolve the \"development\" condition in package imports and\nexports, while resolving the existing \"node\", \"default\", \"import\", and\n\"require\" conditions as appropriate.

      \n

      Any number of custom conditions can be set with repeat flags.

      ", "type": "module", "displayName": "Resolving user conditions" }, + { + "textRaw": "Conditions Definitions", + "name": "conditions_definitions", + "desc": "

      The \"import\", \"require\", \"node\" and \"default\" conditions are defined\nand implemented in Node.js core,\nas specified above.

      \n

      Other condition strings are unknown to Node.js and thus ignored by default.\nRuntimes or tools other than Node.js can use them at their discretion.

      \n

      These user conditions can be enabled in Node.js via the --conditions\nflag.

      \n

      The following condition definitions are currently endorsed by Node.js:

      \n
        \n
      • \"browser\" - any environment which implements a standard subset of global\nbrowser APIs available from JavaScript in web browsers, including the DOM\nAPIs.
      • \n
      • \"development\" - can be used to define a development-only environment\nentry point. Must always be mutually exclusive with \"production\".
      • \n
      • \"production\" - can be used to define a production environment entry\npoint. Must always be mutually exclusive with \"development\".
      • \n
      \n

      The above user conditions can be enabled in Node.js via the --conditions\nflag.

      \n

      Platform specific conditions such as \"deno\", \"electron\", or \"react-native\"\nmay be used, but while there remain no implementation or integration intent\nfrom these platforms, the above are not explicitly endorsed by Node.js.

      \n

      New conditions definitions may be added to this list by creating a pull request\nto the Node.js documentation for this section. The requirements for listing\na new condition definition here are that:

      \n
        \n
      • The definition should be clear and unambiguous for all implementers.
      • \n
      • The use case for why the condition is needed should be clearly justified.
      • \n
      • There should exist sufficient existing implementation usage.
      • \n
      • The condition name should not conflict with another condition definition or\ncondition in wide usage.
      • \n
      • The listing of the condition definition should provide a coordination\nbenefit to the ecosystem that wouldn't otherwise be possible. For example,\nthis would not necessarily be the case for company-specific or\napplication-specific conditions.
      • \n
      \n

      The above definitions may be moved to a dedicated conditions registry in due\ncourse.

      ", + "type": "module", + "displayName": "Conditions Definitions" + }, { "textRaw": "Self-referencing a package using its name", "name": "self-referencing_a_package_using_its_name", - "desc": "

      Within a package, the values defined in the package’s\npackage.json \"exports\" field can be referenced via the package’s name.\nFor example, assuming the package.json is:

      \n
      // package.json\n{\n  \"name\": \"a-package\",\n  \"exports\": {\n    \".\": \"./main.mjs\",\n    \"./foo\": \"./foo.js\"\n  }\n}\n
      \n

      Then any module in that package can reference an export in the package itself:

      \n
      // ./a-module.mjs\nimport { something } from 'a-package'; // Imports \"something\" from ./main.mjs.\n
      \n

      Self-referencing is available only if package.json has \"exports\", and\nwill allow importing only what that \"exports\" (in the package.json)\nallows. So the code below, given the previous package, will generate a runtime\nerror:

      \n
      // ./another-module.mjs\n\n// Imports \"another\" from ./m.mjs. Fails because\n// the \"package.json\" \"exports\" field\n// does not provide an export named \"./m.mjs\".\nimport { another } from 'a-package/m.mjs';\n
      \n

      Self-referencing is also available when using require, both in an ES module,\nand in a CommonJS one. For example, this code will also work:

      \n
      // ./a-module.js\nconst { something } = require('a-package/foo'); // Loads from ./foo.js.\n
      ", + "meta": { + "added": [ + "v13.1.0", + "v12.16.0" + ], + "changes": [ + { + "version": [ + "v13.6.0", + "v12.16.0" + ], + "pr-url": "https://github.com/nodejs/node/pull/31002", + "description": "Unflag self-referencing a package using its name." + } + ] + }, + "desc": "

      Within a package, the values defined in the package’s\npackage.json \"exports\" field can be referenced via the package’s name.\nFor example, assuming the package.json is:

      \n
      // package.json\n{\n  \"name\": \"a-package\",\n  \"exports\": {\n    \".\": \"./main.mjs\",\n    \"./foo\": \"./foo.js\"\n  }\n}\n
      \n

      Then any module in that package can reference an export in the package itself:

      \n
      // ./a-module.mjs\nimport { something } from 'a-package'; // Imports \"something\" from ./main.mjs.\n
      \n

      Self-referencing is available only if package.json has \"exports\", and\nwill allow importing only what that \"exports\" (in the package.json)\nallows. So the code below, given the previous package, will generate a runtime\nerror:

      \n
      // ./another-module.mjs\n\n// Imports \"another\" from ./m.mjs. Fails because\n// the \"package.json\" \"exports\" field\n// does not provide an export named \"./m.mjs\".\nimport { another } from 'a-package/m.mjs';\n
      \n

      Self-referencing is also available when using require, both in an ES module,\nand in a CommonJS one. For example, this code will also work:

      \n
      // ./a-module.js\nconst { something } = require('a-package/foo'); // Loads from ./foo.js.\n
      \n

      Finally, self-referencing also works with scoped packages. For example, this\ncode will also work:

      \n
      // package.json\n{\n  \"name\": \"@my/package\",\n  \"exports\": \"./index.js\"\n}\n
      \n
      // ./index.js\nmodule.exports = 42;\n
      \n
      // ./other.js\nconsole.log(require('@my/package'));\n
      \n
      $ node other.js\n42\n
      ", "type": "module", "displayName": "Self-referencing a package using its name" } @@ -217,14 +299,14 @@ { "textRaw": "Approach #1: Use an ES module wrapper", "name": "approach_#1:_use_an_es_module_wrapper", - "desc": "

      Write the package in CommonJS or transpile ES module sources into CommonJS, and\ncreate an ES module wrapper file that defines the named exports. Using\nConditional exports, the ES module wrapper is used for import and the\nCommonJS entry point for require.

      \n
      // ./node_modules/pkg/package.json\n{\n  \"type\": \"module\",\n  \"main\": \"./index.cjs\",\n  \"exports\": {\n    \"import\": \"./wrapper.mjs\",\n    \"require\": \"./index.cjs\"\n  }\n}\n
      \n

      The preceding example uses explicit extensions .mjs and .cjs.\nIf your files use the .js extension, \"type\": \"module\" will cause such files\nto be treated as ES modules, just as \"type\": \"commonjs\" would cause them\nto be treated as CommonJS.\nSee Enabling.

      \n
      // ./node_modules/pkg/index.cjs\nexports.name = 'value';\n
      \n
      // ./node_modules/pkg/wrapper.mjs\nimport cjsModule from './index.cjs';\nexport const name = cjsModule.name;\n
      \n

      In this example, the name from import { name } from 'pkg' is the same\nsingleton as the name from const { name } = require('pkg'). Therefore ===\nreturns true when comparing the two names and the divergent specifier hazard\nis avoided.

      \n

      If the module is not simply a list of named exports, but rather contains a\nunique function or object export like module.exports = function () { ... },\nor if support in the wrapper for the import pkg from 'pkg' pattern is desired,\nthen the wrapper would instead be written to export the default optionally\nalong with any named exports as well:

      \n
      import cjsModule from './index.cjs';\nexport const name = cjsModule.name;\nexport default cjsModule;\n
      \n

      This approach is appropriate for any of the following use cases:

      \n
        \n
      • The package is currently written in CommonJS and the author would prefer not\nto refactor it into ES module syntax, but wishes to provide named exports for\nES module consumers.
      • \n
      • The package has other packages that depend on it, and the end user might\ninstall both this package and those other packages. For example a utilities\npackage is used directly in an application, and a utilities-plus package\nadds a few more functions to utilities. Because the wrapper exports\nunderlying CommonJS files, it doesn’t matter if utilities-plus is written in\nCommonJS or ES module syntax; it will work either way.
      • \n
      • The package stores internal state, and the package author would prefer not to\nrefactor the package to isolate its state management. See the next section.
      • \n
      \n

      A variant of this approach not requiring conditional exports for consumers could\nbe to add an export, e.g. \"./module\", to point to an all-ES module-syntax\nversion of the package. This could be used via import 'pkg/module' by users\nwho are certain that the CommonJS version will not be loaded anywhere in the\napplication, such as by dependencies; or if the CommonJS version can be loaded\nbut doesn’t affect the ES module version (for example, because the package is\nstateless):

      \n
      // ./node_modules/pkg/package.json\n{\n  \"type\": \"module\",\n  \"main\": \"./index.cjs\",\n  \"exports\": {\n    \".\": \"./index.cjs\",\n    \"./module\": \"./wrapper.mjs\"\n  }\n}\n
      ", + "desc": "

      Write the package in CommonJS or transpile ES module sources into CommonJS, and\ncreate an ES module wrapper file that defines the named exports. Using\nConditional exports, the ES module wrapper is used for import and the\nCommonJS entry point for require.

      \n
      // ./node_modules/pkg/package.json\n{\n  \"type\": \"module\",\n  \"main\": \"./index.cjs\",\n  \"exports\": {\n    \"import\": \"./wrapper.mjs\",\n    \"require\": \"./index.cjs\"\n  }\n}\n
      \n

      The preceding example uses explicit extensions .mjs and .cjs.\nIf your files use the .js extension, \"type\": \"module\" will cause such files\nto be treated as ES modules, just as \"type\": \"commonjs\" would cause them\nto be treated as CommonJS.\nSee Enabling.

      \n
      // ./node_modules/pkg/index.cjs\nexports.name = 'value';\n
      \n
      // ./node_modules/pkg/wrapper.mjs\nimport cjsModule from './index.cjs';\nexport const name = cjsModule.name;\n
      \n

      In this example, the name from import { name } from 'pkg' is the same\nsingleton as the name from const { name } = require('pkg'). Therefore ===\nreturns true when comparing the two names and the divergent specifier hazard\nis avoided.

      \n

      If the module is not simply a list of named exports, but rather contains a\nunique function or object export like module.exports = function () { ... },\nor if support in the wrapper for the import pkg from 'pkg' pattern is desired,\nthen the wrapper would instead be written to export the default optionally\nalong with any named exports as well:

      \n
      import cjsModule from './index.cjs';\nexport const name = cjsModule.name;\nexport default cjsModule;\n
      \n

      This approach is appropriate for any of the following use cases:

      \n
        \n
      • The package is currently written in CommonJS and the author would prefer not\nto refactor it into ES module syntax, but wishes to provide named exports for\nES module consumers.
      • \n
      • The package has other packages that depend on it, and the end user might\ninstall both this package and those other packages. For example a utilities\npackage is used directly in an application, and a utilities-plus package\nadds a few more functions to utilities. Because the wrapper exports\nunderlying CommonJS files, it doesn’t matter if utilities-plus is written in\nCommonJS or ES module syntax; it will work either way.
      • \n
      • The package stores internal state, and the package author would prefer not to\nrefactor the package to isolate its state management. See the next section.
      • \n
      \n

      A variant of this approach not requiring conditional exports for consumers could\nbe to add an export, e.g. \"./module\", to point to an all-ES module-syntax\nversion of the package. This could be used via import 'pkg/module' by users\nwho are certain that the CommonJS version will not be loaded anywhere in the\napplication, such as by dependencies; or if the CommonJS version can be loaded\nbut doesn’t affect the ES module version (for example, because the package is\nstateless):

      \n
      // ./node_modules/pkg/package.json\n{\n  \"type\": \"module\",\n  \"main\": \"./index.cjs\",\n  \"exports\": {\n    \".\": \"./index.cjs\",\n    \"./module\": \"./wrapper.mjs\"\n  }\n}\n
      ", "type": "module", "displayName": "Approach #1: Use an ES module wrapper" }, { "textRaw": "Approach #2: Isolate state", "name": "approach_#2:_isolate_state", - "desc": "

      A package.json file can define the separate CommonJS and ES module entry\npoints directly:

      \n
      // ./node_modules/pkg/package.json\n{\n  \"type\": \"module\",\n  \"main\": \"./index.cjs\",\n  \"exports\": {\n    \"import\": \"./index.mjs\",\n    \"require\": \"./index.cjs\"\n  }\n}\n
      \n

      This can be done if both the CommonJS and ES module versions of the package are\nequivalent, for example because one is the transpiled output of the other; and\nthe package’s management of state is carefully isolated (or the package is\nstateless).

      \n

      The reason that state is an issue is because both the CommonJS and ES module\nversions of the package might get used within an application; for example, the\nuser’s application code could import the ES module version while a dependency\nrequires the CommonJS version. If that were to occur, two copies of the\npackage would be loaded in memory and therefore two separate states would be\npresent. This would likely cause hard-to-troubleshoot bugs.

      \n

      Aside from writing a stateless package (if JavaScript’s Math were a package,\nfor example, it would be stateless as all of its methods are static), there are\nsome ways to isolate state so that it’s shared between the potentially loaded\nCommonJS and ES module instances of the package:

      \n
        \n
      1. \n

        If possible, contain all state within an instantiated object. JavaScript’s\nDate, for example, needs to be instantiated to contain state; if it were a\npackage, it would be used like this:

        \n
        import Date from 'date';\nconst someDate = new Date();\n// someDate contains state; Date does not\n
        \n

        The new keyword isn’t required; a package’s function can return a new\nobject, or modify a passed-in object, to keep the state external to the\npackage.

        \n
      2. \n
      3. \n

        Isolate the state in one or more CommonJS files that are shared between the\nCommonJS and ES module versions of the package. For example, if the CommonJS\nand ES module entry points are index.cjs and index.mjs, respectively:

        \n
        // ./node_modules/pkg/index.cjs\nconst state = require('./state.cjs');\nmodule.exports.state = state;\n
        \n
        // ./node_modules/pkg/index.mjs\nimport state from './state.cjs';\nexport {\n  state\n};\n
        \n

        Even if pkg is used via both require and import in an application (for\nexample, via import in application code and via require by a dependency)\neach reference of pkg will contain the same state; and modifying that\nstate from either module system will apply to both.

        \n
      4. \n
      \n

      Any plugins that attach to the package’s singleton would need to separately\nattach to both the CommonJS and ES module singletons.

      \n

      This approach is appropriate for any of the following use cases:

      \n
        \n
      • The package is currently written in ES module syntax and the package author\nwants that version to be used wherever such syntax is supported.
      • \n
      • The package is stateless or its state can be isolated without too much\ndifficulty.
      • \n
      • The package is unlikely to have other public packages that depend on it, or if\nit does, the package is stateless or has state that need not be shared between\ndependencies or with the overall application.
      • \n
      \n

      Even with isolated state, there is still the cost of possible extra code\nexecution between the CommonJS and ES module versions of a package.

      \n

      As with the previous approach, a variant of this approach not requiring\nconditional exports for consumers could be to add an export, e.g.\n\"./module\", to point to an all-ES module-syntax version of the package:

      \n
      // ./node_modules/pkg/package.json\n{\n  \"type\": \"module\",\n  \"main\": \"./index.cjs\",\n  \"exports\": {\n    \".\": \"./index.cjs\",\n    \"./module\": \"./index.mjs\"\n  }\n}\n
      ", + "desc": "

      A package.json file can define the separate CommonJS and ES module entry\npoints directly:

      \n
      // ./node_modules/pkg/package.json\n{\n  \"type\": \"module\",\n  \"main\": \"./index.cjs\",\n  \"exports\": {\n    \"import\": \"./index.mjs\",\n    \"require\": \"./index.cjs\"\n  }\n}\n
      \n

      This can be done if both the CommonJS and ES module versions of the package are\nequivalent, for example because one is the transpiled output of the other; and\nthe package’s management of state is carefully isolated (or the package is\nstateless).

      \n

      The reason that state is an issue is because both the CommonJS and ES module\nversions of the package might get used within an application; for example, the\nuser’s application code could import the ES module version while a dependency\nrequires the CommonJS version. If that were to occur, two copies of the\npackage would be loaded in memory and therefore two separate states would be\npresent. This would likely cause hard-to-troubleshoot bugs.

      \n

      Aside from writing a stateless package (if JavaScript’s Math were a package,\nfor example, it would be stateless as all of its methods are static), there are\nsome ways to isolate state so that it’s shared between the potentially loaded\nCommonJS and ES module instances of the package:

      \n
        \n
      1. \n

        If possible, contain all state within an instantiated object. JavaScript’s\nDate, for example, needs to be instantiated to contain state; if it were a\npackage, it would be used like this:

        \n
        import Date from 'date';\nconst someDate = new Date();\n// someDate contains state; Date does not\n
        \n

        The new keyword isn’t required; a package’s function can return a new\nobject, or modify a passed-in object, to keep the state external to the\npackage.

        \n
      2. \n
      3. \n

        Isolate the state in one or more CommonJS files that are shared between the\nCommonJS and ES module versions of the package. For example, if the CommonJS\nand ES module entry points are index.cjs and index.mjs, respectively:

        \n
        // ./node_modules/pkg/index.cjs\nconst state = require('./state.cjs');\nmodule.exports.state = state;\n
        \n
        // ./node_modules/pkg/index.mjs\nimport state from './state.cjs';\nexport {\n  state\n};\n
        \n

        Even if pkg is used via both require and import in an application (for\nexample, via import in application code and via require by a dependency)\neach reference of pkg will contain the same state; and modifying that\nstate from either module system will apply to both.

        \n
      4. \n
      \n

      Any plugins that attach to the package’s singleton would need to separately\nattach to both the CommonJS and ES module singletons.

      \n

      This approach is appropriate for any of the following use cases:

      \n
        \n
      • The package is currently written in ES module syntax and the package author\nwants that version to be used wherever such syntax is supported.
      • \n
      • The package is stateless or its state can be isolated without too much\ndifficulty.
      • \n
      • The package is unlikely to have other public packages that depend on it, or if\nit does, the package is stateless or has state that need not be shared between\ndependencies or with the overall application.
      • \n
      \n

      Even with isolated state, there is still the cost of possible extra code\nexecution between the CommonJS and ES module versions of a package.

      \n

      As with the previous approach, a variant of this approach not requiring\nconditional exports for consumers could be to add an export, e.g.\n\"./module\", to point to an all-ES module-syntax version of the package:

      \n
      // ./node_modules/pkg/package.json\n{\n  \"type\": \"module\",\n  \"main\": \"./index.cjs\",\n  \"exports\": {\n    \".\": \"./index.cjs\",\n    \"./module\": \"./index.mjs\"\n  }\n}\n
      ", "type": "module", "displayName": "Approach #2: Isolate state" } @@ -239,18 +321,20 @@ { "textRaw": "Node.js `package.json` field definitions", "name": "node.js_`package.json`_field_definitions", - "desc": "

      This section describes the fields used by the Node.js runtime. Other tools (such\nas npm) use\nadditional fields which are ignored by Node.js and not documented here.

      \n

      The following fields in package.json files are used in Node.js:

      \n
        \n
      • \"name\" - Relevant when using named imports within a package. Also used\nby package managers as the name of the package.
      • \n
      • \"type\" - The package type determining whether to load .js files as\nCommonJS or ES modules.
      • \n
      • \"exports\" - Package exports and conditional exports. When present,\nlimits which submodules can be loaded from within the package.
      • \n
      • \"main\" - The default module when loading the package, if exports is not\nspecified, and in versions of Node.js prior to the introduction of exports.
      • \n
      • \"imports\" - Package imports, for use by modules within the package\nitself.
      • \n
      ", + "desc": "

      This section describes the fields used by the Node.js runtime. Other tools (such\nas npm) use\nadditional fields which are ignored by Node.js and not documented here.

      \n

      The following fields in package.json files are used in Node.js:

      \n
        \n
      • \"name\" - Relevant when using named imports within a package. Also used\nby package managers as the name of the package.
      • \n
      • \"main\" - The default module when loading the package, if exports is not\nspecified, and in versions of Node.js prior to the introduction of exports.
      • \n
      • \"type\" - The package type determining whether to load .js files as\nCommonJS or ES modules.
      • \n
      • \"exports\" - Package exports and conditional exports. When present,\nlimits which submodules can be loaded from within the package.
      • \n
      • \"imports\" - Package imports, for use by modules within the package\nitself.
      • \n
      ", "modules": [ { "textRaw": "`\"name\"`", "name": "`\"name\"`", "meta": { "added": [ + "v13.1.0", "v12.16.0" ], "changes": [ { "version": [ + "v13.6.0", "v12.16.0" ], "pr-url": "https://github.com/nodejs/node/pull/31002", @@ -262,6 +346,19 @@ "type": "module", "displayName": "`\"name\"`" }, + { + "textRaw": "`\"main\"`", + "name": "`\"main\"`", + "meta": { + "added": [ + "v0.4.0" + ], + "changes": [] + }, + "desc": "\n
      {\n  \"main\": \"./main.js\"\n}\n
      \n

      The \"main\" field defines the script that is used when the package directory\nis loaded via require(). Its value\nis a path.

      \n
      require('./path/to/directory'); // This resolves to ./path/to/directory/main.js.\n
      \n

      When a package has an \"exports\" field, this will take precedence over the\n\"main\" field when importing the package by name.

      ", + "type": "module", + "displayName": "`\"main\"`" + }, { "textRaw": "`\"type\"`", "name": "`\"type\"`", @@ -272,6 +369,7 @@ "changes": [ { "version": [ + "v13.2.0", "v12.17.0" ], "pr-url": "https://github.com/nodejs/node/pull/29866", @@ -293,31 +391,35 @@ "changes": [ { "version": [ - "v12.16.0" + "v14.13.0", + "v12.20.0" ], - "pr-url": "https://github.com/nodejs/node/pull/29978", - "description": "Implement conditional exports." + "pr-url": "https://github.com/nodejs/node/pull/34718", + "description": "Add support for `\"exports\"` patterns." }, { "version": [ + "v13.7.0", "v12.16.0" ], - "pr-url": "https://github.com/nodejs/node/pull/31001", - "description": "Remove the `--experimental-conditional-exports` option." + "pr-url": "https://github.com/nodejs/node/pull/31008", + "description": "Implement logical conditional exports ordering." }, { "version": [ + "v13.7.0", "v12.16.0" ], - "pr-url": "https://github.com/nodejs/node/pull/31008", - "description": "Implement logical conditional exports ordering." + "pr-url": "https://github.com/nodejs/node/pull/31001", + "description": "Remove the `--experimental-conditional-exports` option." }, { "version": [ - "v12.20.0" + "v13.2.0", + "v12.16.0" ], - "pr-url": "https://github.com/nodejs/node/pull/34718", - "description": "Add support for `\"exports\"` patterns." + "pr-url": "https://github.com/nodejs/node/pull/29978", + "description": "Implement conditional exports." } ] }, @@ -325,30 +427,16 @@ "type": "module", "displayName": "`\"exports\"`" }, - { - "textRaw": "`\"main\"`", - "name": "`\"main\"`", - "meta": { - "added": [ - "v0.4.0" - ], - "changes": [] - }, - "desc": "\n
      {\n  \"main\": \"./main.js\"\n}\n
      \n

      The \"main\" field defines the script that is used when the package directory\nis loaded via require(). Its value\nis interpreted as a path.

      \n
      require('./path/to/directory'); // This resolves to ./path/to/directory/main.js.\n
      \n

      When a package has an \"exports\" field, this will take precedence over the\n\"main\" field when importing the package by name.

      ", - "type": "module", - "displayName": "`\"main\"`" - }, { "textRaw": "`\"imports\"`", "name": "`\"imports\"`", "meta": { "added": [ + "v14.6.0", "v12.19.0" ], "changes": [] }, - "stability": 1, - "stabilityText": "Experimental", "desc": "\n
      // package.json\n{\n  \"imports\": {\n    \"#dep\": {\n      \"node\": \"dep-node-native\",\n      \"default\": \"./dep-polyfill.js\"\n    }\n  },\n  \"dependencies\": {\n    \"dep-node-native\": \"^1.0.0\"\n  }\n}\n
      \n

      Entries in the imports field must be strings starting with #.

      \n

      Import maps permit mapping to external packages.

      \n

      This field defines subpath imports for the current package.

      ", "type": "module", "displayName": "`\"imports\"`" diff --git a/doc/api/packages.md b/doc/api/packages.md index 216f6f5ba8d830453397c4bb5536bd982c023229..739db6d273e46edcd7ee9876553539eb38a17a9d 100644 --- a/doc/api/packages.md +++ b/doc/api/packages.md @@ -1,19 +1,25 @@ # Modules: Packages + Strings passed in as an argument to `--eval` (or `-e`), or piped to `node` via `STDIN`, are treated as [ES modules][] when the `--input-type=module` flag @@ -248,8 +257,9 @@ absolute subpath of the package such as `require('/path/to/node_modules/pkg/subpath.js')` will still load `subpath.js`. ### Subpath exports - -> Stability: 1 - Experimental + When using the [`"exports"`][] field, custom subpaths can be defined along with the main entry point by treating the main entry point as the @@ -280,8 +290,11 @@ import submodule from 'es-module-package/private-module.js'; ``` ### Subpath imports - -> Stability: 1 - Experimental + In addition to the [`"exports"`][] field, it is possible to define internal package import maps that only apply to import specifiers from within the package @@ -319,8 +332,11 @@ The resolution rules for the imports field are otherwise analogous to the exports field. ### Subpath patterns - -> Stability: 1 - Experimental + For packages with a small number of exports or imports, we recommend explicitly listing each exports subpath entry. But for packages that have @@ -341,6 +357,9 @@ For these use cases, subpath export patterns can be used instead: } ``` +**`*` maps expose nested subpaths as it is a string replacement syntax +only.** + The left hand matching pattern must always end in `*`. All instances of `*` on the right hand side will then be replaced with this value, including if it contains any `/` separators. @@ -366,9 +385,30 @@ treating the right hand side target pattern as a `**` glob against the list of files within the package. Because `node_modules` paths are forbidden in exports targets, this expansion is dependent on only the files of the package itself. -### Exports sugar +To exclude private subfolders from patterns, `null` targets can be used: -> Stability: 1 - Experimental +```json +// ./node_modules/es-module-package/package.json +{ + "exports": { + "./features/*": "./src/features/*.js", + "./features/private-internal/*": null + } +} +``` + +```js +import featureInternal from 'es-module-package/features/private-internal/m'; +// Throws: ERR_PACKAGE_PATH_NOT_EXPORTED + +import featureX from 'es-module-package/features/x'; +// Loads ./node_modules/es-module-package/src/features/x.js +``` + +### Exports sugar + If the `"."` export is the only export, the [`"exports"`][] field provides sugar for this case being the direct [`"exports"`][] field value. @@ -393,8 +433,17 @@ can be written: ``` ### Conditional exports - -> Stability: 1 - Experimental + Conditional exports provide a way to map to different paths depending on certain conditions. They are supported for both CommonJS and ES module imports. @@ -414,7 +463,7 @@ For example, a package that wants to provide different ES module exports for } ``` -Node.js supports the following conditions out of the box: +Node.js implements the following conditions: * `"import"` - matches when the package is loaded via `import` or `import()`, or via any top-level import or resolve operation by the @@ -437,11 +486,6 @@ matching, earlier entries have higher priority and take precedence over later entries. _The general rule is that conditions should be from most specific to least specific in object order_. -Other conditions such as `"browser"`, `"electron"`, `"deno"`, `"react-native"`, -etc., are unknown to Node.js, and thus ignored. Runtimes or tools other than -Node.js can use them at their discretion. Further restrictions, definitions, or -guidance on condition names might occur in the future. - Using the `"import"` and `"require"` conditions can lead to some hazards, which are further explained in [the dual CommonJS/ES module packages section][]. @@ -474,8 +518,6 @@ order to support packages with conditional exports. For this reason, using ### Nested conditions -> Stability: 1 - Experimental - In addition to direct mappings, Node.js also supports nested condition objects. For example, to define a package that only has dual mode entry points for @@ -500,6 +542,11 @@ the remaining conditions of the parent condition. In this way nested conditions behave analogously to nested JavaScript `if` statements. ### Resolving user conditions + When running Node.js, custom user conditions can be added with the `--conditions` flag: @@ -514,7 +561,64 @@ exports, while resolving the existing `"node"`, `"default"`, `"import"`, and Any number of custom conditions can be set with repeat flags. +### Conditions Definitions + +The `"import"`, `"require"`, `"node"` and `"default"` conditions are defined +and implemented in Node.js core, +[as specified above](#packages_conditional_exports). + +Other condition strings are unknown to Node.js and thus ignored by default. +Runtimes or tools other than Node.js can use them at their discretion. + +These user conditions can be enabled in Node.js via the [`--conditions` +flag](#packages_resolving_user_conditions). + +The following condition definitions are currently endorsed by Node.js: + +* `"browser"` - any environment which implements a standard subset of global + browser APIs available from JavaScript in web browsers, including the DOM + APIs. +* `"development"` - can be used to define a development-only environment + entry point. _Must always be mutually exclusive with `"production"`._ +* `"production"` - can be used to define a production environment entry + point. _Must always be mutually exclusive with `"development"`._ + +The above user conditions can be enabled in Node.js via the [`--conditions` +flag](#packages_resolving_user_conditions). + +Platform specific conditions such as `"deno"`, `"electron"`, or `"react-native"` +may be used, but while there remain no implementation or integration intent +from these platforms, the above are not explicitly endorsed by Node.js. + +New conditions definitions may be added to this list by creating a pull request +to the [Node.js documentation for this section][]. The requirements for listing +a new condition definition here are that: + +* The definition should be clear and unambiguous for all implementers. +* The use case for why the condition is needed should be clearly justified. +* There should exist sufficient existing implementation usage. +* The condition name should not conflict with another condition definition or + condition in wide usage. +* The listing of the condition definition should provide a coordination + benefit to the ecosystem that wouldn't otherwise be possible. For example, + this would not necessarily be the case for company-specific or + application-specific conditions. + +The above definitions may be moved to a dedicated conditions registry in due +course. + ### Self-referencing a package using its name + Within a package, the values defined in the package’s `package.json` [`"exports"`][] field can be referenced via the package’s name. @@ -555,11 +659,37 @@ import { another } from 'a-package/m.mjs'; Self-referencing is also available when using `require`, both in an ES module, and in a CommonJS one. For example, this code will also work: -```js +```cjs // ./a-module.js const { something } = require('a-package/foo'); // Loads from ./foo.js. ``` +Finally, self-referencing also works with scoped packages. For example, this +code will also work: + +```json +// package.json +{ + "name": "@my/package", + "exports": "./index.js" +} +``` + +```cjs +// ./index.js +module.exports = 42; +``` + +```cjs +// ./other.js +console.log(require('@my/package')); +``` + +```console +$ node other.js +42 +``` + ## Dual CommonJS/ES module packages Prior to the introduction of support for ES modules in Node.js, it was a common @@ -656,9 +786,9 @@ The preceding example uses explicit extensions `.mjs` and `.cjs`. If your files use the `.js` extension, `"type": "module"` will cause such files to be treated as ES modules, just as `"type": "commonjs"` would cause them to be treated as CommonJS. -See [Enabling](#esm_enabling). +See [Enabling](esm.md#esm_enabling). -```js +```cjs // ./node_modules/pkg/index.cjs exports.name = 'value'; ``` @@ -771,7 +901,7 @@ CommonJS and ES module instances of the package: CommonJS and ES module versions of the package. For example, if the CommonJS and ES module entry points are `index.cjs` and `index.mjs`, respectively: - ```js + ```cjs // ./node_modules/pkg/index.cjs const state = require('./state.cjs'); module.exports.state = state; @@ -831,21 +961,23 @@ The following fields in `package.json` files are used in Node.js: * [`"name"`][] - Relevant when using named imports within a package. Also used by package managers as the name of the package. +* [`"main"`][] - The default module when loading the package, if exports is not + specified, and in versions of Node.js prior to the introduction of exports. * [`"type"`][] - The package type determining whether to load `.js` files as CommonJS or ES modules. * [`"exports"`][] - Package exports and conditional exports. When present, limits which submodules can be loaded from within the package. -* [`"main"`][] - The default module when loading the package, if exports is not - specified, and in versions of Node.js prior to the introduction of exports. * [`"imports"`][] - Package imports, for use by modules within the package itself. ### `"name"` + +* Type: {string} + +```json +{ + "main": "./main.js" +} +``` + +The `"main"` field defines the script that is used when the [package directory +is loaded via `require()`](modules.md#modules_folders_as_modules). Its value +is a path. + +```cjs +require('./path/to/directory'); // This resolves to ./path/to/directory/main.js. +``` + +When a package has an [`"exports"`][] field, this will take precedence over the +`"main"` field when importing the package by name. + ### `"type"` * Type: {Object} | {string} | {string[]} @@ -960,37 +1121,13 @@ referenced via `require` or via `import`. All paths defined in the `"exports"` must be relative file URLs starting with `./`. -### `"main"` - - -* Type: {string} - -```json -{ - "main": "./main.js" -} -``` - -The `"main"` field defines the script that is used when the [package directory -is loaded via `require()`](modules.html#modules_folders_as_modules). Its value -is interpreted as a path. - -```js -require('./path/to/directory'); // This resolves to ./path/to/directory/main.js. -``` - -When a package has an [`"exports"`][] field, this will take precedence over the -`"main"` field when importing the package by name. - ### `"imports"` -> Stability: 1 - Experimental - * Type: {Object} ```json @@ -1015,21 +1152,22 @@ Import maps permit mapping to external packages. This field defines [subpath imports][] for the current package. [Babel]: https://babeljs.io/ +[CommonJS]: modules.md [Conditional exports]: #packages_conditional_exports -[CommonJS]: modules.html -[`ERR_PACKAGE_PATH_NOT_EXPORTED`]: errors.html#errors_err_package_path_not_exported -[ES modules]: esm.html -[ES module]: esm.html -[`esm`]: https://github.com/standard-things/esm#readme +[ES module]: esm.md +[ES modules]: esm.md +[Node.js documentation for this section]: https://github.com/nodejs/node/blob/HEAD/doc/api/packages.md#conditions-definitions [`"exports"`]: #packages_exports +[`"imports"`]: #packages_imports [`"main"`]: #packages_main [`"name"`]: #packages_name -[`"imports"`]: #packages_imports [`"type"`]: #packages_type -[entry points]: #packages_package_entry_points +[`ERR_PACKAGE_PATH_NOT_EXPORTED`]: errors.md#errors_err_package_path_not_exported +[`esm`]: https://github.com/standard-things/esm#readme [`package.json`]: #packages_node_js_package_json_field_definitions +[entry points]: #packages_package_entry_points [self-reference]: #packages_self_referencing_a_package_using_its_name [subpath exports]: #packages_subpath_exports [subpath imports]: #packages_subpath_imports -[the full specifier path]: esm.md#esm_mandatory_file_extensions [the dual CommonJS/ES module packages section]: #packages_dual_commonjs_es_module_packages +[the full specifier path]: esm.md#esm_mandatory_file_extensions diff --git a/doc/api/path.html b/doc/api/path.html index 27b53d417a9ac93e7a44b20d058d3c0418c36256..cf6a71c97a8deb47b82e956e9d3dd2a9d6eae05f 100644 --- a/doc/api/path.html +++ b/doc/api/path.html @@ -1,10 +1,10 @@ - + - - Path | Node.js v12.22.7 Documentation + + Path | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      -
      -

      Table of Contents

      -
      +
      -

      Path#

      +

      Path#

      Stability: 2 - Stable

      -

      Source Code: lib/path.js

      +

      Source Code: lib/path.js

      The path module provides utilities for working with file and directory paths. It can be accessed using:

      const path = require('path');
      -

      Windows vs. POSIX#

      +

      Windows vs. POSIX#

      The default operation of the path module varies based on the operating system on which a Node.js application is running. Specifically, when running on a Windows operating system, the path module will assume that Windows-style paths are being used.

      So using path.basename() might yield different results on POSIX and Windows:

      On POSIX:

      -
      path.basename('C:\\temp\\myfile.html');
      +
      path.basename('C:\\temp\\myfile.html');
       // Returns: 'C:\\temp\\myfile.html'

      On Windows:

      -
      path.basename('C:\\temp\\myfile.html');
      +
      path.basename('C:\\temp\\myfile.html');
       // Returns: 'myfile.html'

      To achieve consistent results when working with Windows file paths on any operating system, use path.win32:

      On POSIX and Windows:

      -
      path.win32.basename('C:\\temp\\myfile.html');
      +
      path.win32.basename('C:\\temp\\myfile.html');
       // Returns: 'myfile.html'

      To achieve consistent results when working with POSIX file paths on any operating system, use path.posix:

      On POSIX and Windows:

      -
      path.posix.basename('/tmp/myfile.html');
      +
      path.posix.basename('/tmp/myfile.html');
       // Returns: 'myfile.html'

      On Windows Node.js follows the concept of per-drive working directory. This behavior can be observed when using a drive path without a backslash. For example, path.resolve('C:\\') can potentially return a different result than path.resolve('C:'). For more information, see this MSDN page.

      -

      path.basename(path[, ext])#

      +

      path.basename(path[, ext])#

      • <Object>
      • @@ -805,7 +869,25 @@ process.argv.forEach((val, Child Process documentation), the process.channel property is a reference to the IPC channel. If no IPC channel exists, this property is undefined.

        -

        process.chdir(directory)#

        +

        process.channel.ref()#

        + +

        This method makes the IPC channel keep the event loop of the process +running if .unref() has been called before.

        +

        Typically, this is managed through the number of 'disconnect' and 'message' +listeners on the process object. However, this method can be used to +explicitly request a specific behavior.

        +

        process.channel.unref()#

        + +

        This method makes the IPC channel not keep the event loop of the process +running, and lets it finish even while the channel is open.

        +

        Typically, this is managed through the number of 'disconnect' and 'message' +listeners on the process object. However, this method can be used to +explicitly request a specific behavior.

        +

      process.chdir(directory)#

      @@ -815,15 +897,15 @@ property is undefined.

      The process.chdir() method changes the current working directory of the Node.js process or throws an exception if doing so fails (for instance, if the specified directory does not exist).

      -
      console.log(`Starting directory: ${process.cwd()}`);
      +
      console.log(`Starting directory: ${process.cwd()}`);
       try {
      -  process.chdir('/tmp');
      -  console.log(`New directory: ${process.cwd()}`);
      +  process.chdir('/tmp');
      +  console.log(`New directory: ${process.cwd()}`);
       } catch (err) {
      -  console.error(`chdir: ${err}`);
      +  console.error(`chdir: ${err}`);
       }

      This feature is not available in Worker threads.

      -

      process.config#

      +

      process.config#

      @@ -864,7 +946,7 @@ running the ./configure script.

      The process.config property is not read-only and there are existing modules in the ecosystem that are known to extend, modify, or entirely replace the value of process.config.

      -

      process.connected#

      +

      process.connected#

      @@ -877,7 +959,7 @@ and Cluster documentation), the process.connect process.disconnect() is called.

      Once process.connected is false, it is no longer possible to send messages over the IPC channel using process.send().

      -

      process.cpuUsage([previousValue])#

      +

      process.cpuUsage([previousValue])#

      @@ -898,16 +980,16 @@ spent in user and system code respectively, and may end up being greater than actual elapsed time if multiple CPU cores are performing work for this process.

      The result of a previous call to process.cpuUsage() can be passed as the argument to the function, to get a diff reading.

      -
      const startUsage = process.cpuUsage();
      +
      const startUsage = process.cpuUsage();
       // { user: 38579, system: 6986 }
       
       // spin the CPU for 500 milliseconds
      -const now = Date.now();
      -while (Date.now() - now < 500);
      +const now = Date.now();
      +while (Date.now() - now < 500);
       
      -console.log(process.cpuUsage(startUsage));
      +console.log(process.cpuUsage(startUsage));
       // { user: 514883, system: 11226 }
      -

      process.cwd()#

      +

      process.cwd()#

      @@ -916,8 +998,8 @@ argument to the function, to get a diff reading.

      The process.cwd() method returns the current working directory of the Node.js process.

      -
      console.log(`Current directory: ${process.cwd()}`);
      -

      process.debugPort#

      +
      console.log(`Current directory: ${process.cwd()}`);
      +

      process.debugPort#

      @@ -925,8 +1007,8 @@ process.

    • <number>
    • The port used by the Node.js debugger when enabled.

      -
      process.debugPort = 5858;
      -

      process.disconnect()#

      +
      process.debugPort = 5858;
      +

      process.disconnect()#

      @@ -938,7 +1020,7 @@ once there are no other connections keeping it alive.

      ChildProcess.disconnect() from the parent process.

      If the Node.js process was not spawned with an IPC channel, process.disconnect() will be undefined.

      -

      process.dlopen(module, filename[, flags])#

      +

      process.dlopen(module, filename[, flags])#

      -

      Stability: 1 - Experimental

      If true, a diagnostic report is generated on fatal errors, such as out of memory errors or failed C++ assertions.

      -
      console.log(`Report on fatal error: ${process.report.reportOnFatalError}`);
      -

      process.report.reportOnSignal#

      +
      console.log(`Report on fatal error: ${process.report.reportOnFatalError}`);
      +

      process.report.reportOnSignal#

      @@ -429,8 +502,8 @@ stream as a string. This method allows asynchronous iteration of readline.Interface will always consume the input stream fully.

      Performance is not on par with the traditional 'line' event API. Use 'line' instead for performance-sensitive applications.

      -
      async function processLineByLine() {
      -  const rl = readline.createInterface({
      +
      async function processLineByLine() {
      +  const rl = readline.createInterface({
           // ...
         });
       
      @@ -439,12 +512,23 @@ instead for performance-sensitive applications.

      // `line`. } }
      -

      rl.line#

      +

      readline.createInterface() will start to consume the input stream once +invoked. Having asynchronous operations between interface creation and +asynchronous iteration may result in missed lines.

      +

      rl.line#

      The current input data being processed by node.

      This can be used when collecting input from a TTY stream to retrieve the @@ -456,17 +540,17 @@ unintended consequences if rl.cursor is not also controlled.

      If not using a TTY stream for input, use the 'line' event.

      One possible use case would be as follows:

      const values = ['lorem ipsum', 'dolor sit amet'];
      -const rl = readline.createInterface(process.stdin);
      -const showResults = debounce(() => {
      -  console.log(
      +const rl = readline.createInterface(process.stdin);
      +const showResults = debounce(() => {
      +  console.log(
           '\n',
      -    values.filter((val) => val.startsWith(rl.line)).join(' ')
      +    values.filter((val) => val.startsWith(rl.line)).join(' ')
         );
       }, 300);
      -process.stdin.on('keypress', (c, k) => {
      -  showResults();
      +process.stdin.on('keypress', (c, k) => {
      +  showResults();
       });
      -

      rl.cursor#

      +

      rl.cursor#

      @@ -478,9 +562,9 @@ process.stdin.on('keypress', # +

      rl.getCursorPos()#

      • Returns: <Object> @@ -493,7 +577,7 @@ as well as the column where the terminal caret will be rendered.

        Returns the real position of the cursor in relation to the input prompt + string. Long input (wrapping) strings, as well as multiple line prompts are included in the calculations.

        -

        readline.clearLine(stream, dir[, callback])#

        +

      readline.clearLine(stream, dir[, callback])#

      + diff --git a/doc/api/readline.json b/doc/api/readline.json index edd7985fe929dcb73a6cec14815da88b729a0f5a..1276c5179ca9e011860b72a1e464b4fa023ca4c6 100644 --- a/doc/api/readline.json +++ b/doc/api/readline.json @@ -8,7 +8,7 @@ "introduced_in": "v0.10.0", "stability": 2, "stabilityText": "Stable", - "desc": "

      Source Code: lib/readline.js

      \n

      The readline module provides an interface for reading data from a Readable\nstream (such as process.stdin) one line at a time. It can be accessed\nusing:

      \n
      const readline = require('readline');\n
      \n

      The following simple example illustrates the basic use of the readline module.

      \n
      const readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nrl.question('What do you think of Node.js? ', (answer) => {\n  // TODO: Log the answer in a database\n  console.log(`Thank you for your valuable feedback: ${answer}`);\n\n  rl.close();\n});\n
      \n

      Once this code is invoked, the Node.js application will not terminate until the\nreadline.Interface is closed because the interface waits for data to be\nreceived on the input stream.

      ", + "desc": "

      Source Code: lib/readline.js

      \n

      The readline module provides an interface for reading data from a Readable\nstream (such as process.stdin) one line at a time. It can be accessed\nusing:

      \n
      const readline = require('readline');\n
      \n

      The following simple example illustrates the basic use of the readline module.

      \n
      const readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nrl.question('What do you think of Node.js? ', (answer) => {\n  // TODO: Log the answer in a database\n  console.log(`Thank you for your valuable feedback: ${answer}`);\n\n  rl.close();\n});\n
      \n

      Once this code is invoked, the Node.js application will not terminate until the\nreadline.Interface is closed because the interface waits for data to be\nreceived on the input stream.

      ", "classes": [ { "textRaw": "Class: `Interface`", @@ -33,7 +33,7 @@ "changes": [] }, "params": [], - "desc": "

      The 'close' event is emitted when one of the following occur:

      \n
        \n
      • The rl.close() method is called and the readline.Interface instance has\nrelinquished control over the input and output streams;
      • \n
      • The input stream receives its 'end' event;
      • \n
      • The input stream receives <ctrl>-D to signal end-of-transmission (EOT);
      • \n
      • The input stream receives <ctrl>-C to signal SIGINT and there is no\n'SIGINT' event listener registered on the readline.Interface instance.
      • \n
      \n

      The listener function is called without passing any arguments.

      \n

      The readline.Interface instance is finished once the 'close' event is\nemitted.

      " + "desc": "

      The 'close' event is emitted when one of the following occur:

      \n
        \n
      • The rl.close() method is called and the readline.Interface instance has\nrelinquished control over the input and output streams;
      • \n
      • The input stream receives its 'end' event;
      • \n
      • The input stream receives Ctrl+D to signal\nend-of-transmission (EOT);
      • \n
      • The input stream receives Ctrl+C to signal SIGINT\nand there is no 'SIGINT' event listener registered on the\nreadline.Interface instance.
      • \n
      \n

      The listener function is called without passing any arguments.

      \n

      The readline.Interface instance is finished once the 'close' event is\nemitted.

      " }, { "textRaw": "Event: `'line'`", @@ -46,7 +46,20 @@ "changes": [] }, "params": [], - "desc": "

      The 'line' event is emitted whenever the input stream receives an\nend-of-line input (\\n, \\r, or \\r\\n). This usually occurs when the user\npresses the <Enter>, or <Return> keys.

      \n

      The listener function is called with a string containing the single line of\nreceived input.

      \n
      rl.on('line', (input) => {\n  console.log(`Received: ${input}`);\n});\n
      " + "desc": "

      The 'line' event is emitted whenever the input stream receives an\nend-of-line input (\\n, \\r, or \\r\\n). This usually occurs when the user\npresses Enter or Return.

      \n

      The listener function is called with a string containing the single line of\nreceived input.

      \n
      rl.on('line', (input) => {\n  console.log(`Received: ${input}`);\n});\n
      " + }, + { + "textRaw": "Event: `'history'`", + "type": "event", + "name": "history", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "params": [], + "desc": "

      The 'history' event is emitted whenever the history array has changed.

      \n

      The listener function is called with an array containing the history array.\nIt will reflect all changes, added lines and removed lines due to\nhistorySize and removeHistoryDuplicates.

      \n

      The primary purpose is to allow a listener to persist the history.\nIt is also possible for the listener to change the history object. This\ncould be useful to prevent certain lines to be added to the history, like\na password.

      \n
      rl.on('history', (history) => {\n  console.log(`Received: ${history}`);\n});\n
      " }, { "textRaw": "Event: `'pause'`", @@ -59,7 +72,7 @@ "changes": [] }, "params": [], - "desc": "

      The 'pause' event is emitted when one of the following occur:

      \n
        \n
      • The input stream is paused.
      • \n
      • The input stream is not paused and receives the 'SIGCONT' event. (See\nevents 'SIGTSTP' and 'SIGCONT'.)
      • \n
      \n

      The listener function is called without passing any arguments.

      \n
      rl.on('pause', () => {\n  console.log('Readline paused.');\n});\n
      " + "desc": "

      The 'pause' event is emitted when one of the following occur:

      \n
        \n
      • The input stream is paused.
      • \n
      • The input stream is not paused and receives the 'SIGCONT' event. (See\nevents 'SIGTSTP' and 'SIGCONT'.)
      • \n
      \n

      The listener function is called without passing any arguments.

      \n
      rl.on('pause', () => {\n  console.log('Readline paused.');\n});\n
      " }, { "textRaw": "Event: `'resume'`", @@ -85,7 +98,7 @@ "changes": [] }, "params": [], - "desc": "

      The 'SIGCONT' event is emitted when a Node.js process previously moved into\nthe background using <ctrl>-Z (i.e. SIGTSTP) is then brought back to the\nforeground using fg(1p).

      \n

      If the input stream was paused before the SIGTSTP request, this event will\nnot be emitted.

      \n

      The listener function is invoked without passing any arguments.

      \n
      rl.on('SIGCONT', () => {\n  // `prompt` will automatically resume the stream\n  rl.prompt();\n});\n
      \n

      The 'SIGCONT' event is not supported on Windows.

      " + "desc": "

      The 'SIGCONT' event is emitted when a Node.js process previously moved into\nthe background using Ctrl+Z (i.e. SIGTSTP) is then\nbrought back to the foreground using fg(1p).

      \n

      If the input stream was paused before the SIGTSTP request, this event will\nnot be emitted.

      \n

      The listener function is invoked without passing any arguments.

      \n
      rl.on('SIGCONT', () => {\n  // `prompt` will automatically resume the stream\n  rl.prompt();\n});\n
      \n

      The 'SIGCONT' event is not supported on Windows.

      " }, { "textRaw": "Event: `'SIGINT'`", @@ -98,7 +111,7 @@ "changes": [] }, "params": [], - "desc": "

      The 'SIGINT' event is emitted whenever the input stream receives a\n<ctrl>-C input, known typically as SIGINT. If there are no 'SIGINT' event\nlisteners registered when the input stream receives a SIGINT, the 'pause'\nevent will be emitted.

      \n

      The listener function is invoked without passing any arguments.

      \n
      rl.on('SIGINT', () => {\n  rl.question('Are you sure you want to exit? ', (answer) => {\n    if (answer.match(/^y(es)?$/i)) rl.pause();\n  });\n});\n
      " + "desc": "

      The 'SIGINT' event is emitted whenever the input stream receives a\nCtrl+C input, known typically as SIGINT. If there are no 'SIGINT'\nevent listeners registered when the input stream receives a SIGINT, the\n'pause' event will be emitted.

      \n

      The listener function is invoked without passing any arguments.

      \n
      rl.on('SIGINT', () => {\n  rl.question('Are you sure you want to exit? ', (answer) => {\n    if (answer.match(/^y(es)?$/i)) rl.pause();\n  });\n});\n
      " }, { "textRaw": "Event: `'SIGTSTP'`", @@ -111,7 +124,7 @@ "changes": [] }, "params": [], - "desc": "

      The 'SIGTSTP' event is emitted when the input stream receives a <ctrl>-Z\ninput, typically known as SIGTSTP. If there are no 'SIGTSTP' event listeners\nregistered when the input stream receives a SIGTSTP, the Node.js process\nwill be sent to the background.

      \n

      When the program is resumed using fg(1p), the 'pause' and 'SIGCONT' events\nwill be emitted. These can be used to resume the input stream.

      \n

      The 'pause' and 'SIGCONT' events will not be emitted if the input was\npaused before the process was sent to the background.

      \n

      The listener function is invoked without passing any arguments.

      \n
      rl.on('SIGTSTP', () => {\n  // This will override SIGTSTP and prevent the program from going to the\n  // background.\n  console.log('Caught SIGTSTP.');\n});\n
      \n

      The 'SIGTSTP' event is not supported on Windows.

      " + "desc": "

      The 'SIGTSTP' event is emitted when the input stream receives a\nCtrl+Z input, typically known as SIGTSTP. If there are\nno 'SIGTSTP' event listeners registered when the input stream receives a\nSIGTSTP, the Node.js process will be sent to the background.

      \n

      When the program is resumed using fg(1p), the 'pause' and 'SIGCONT' events\nwill be emitted. These can be used to resume the input stream.

      \n

      The 'pause' and 'SIGCONT' events will not be emitted if the input was\npaused before the process was sent to the background.

      \n

      The listener function is invoked without passing any arguments.

      \n
      rl.on('SIGTSTP', () => {\n  // This will override SIGTSTP and prevent the program from going to the\n  // background.\n  console.log('Caught SIGTSTP.');\n});\n
      \n

      The 'SIGTSTP' event is not supported on Windows.

      " } ], "methods": [ @@ -174,7 +187,7 @@ "desc": "

      The rl.prompt() method writes the readline.Interface instances configured\nprompt to a new line in output in order to provide a user with a new\nlocation at which to provide input.

      \n

      When called, rl.prompt() will resume the input stream if it has been\npaused.

      \n

      If the readline.Interface was created with output set to null or\nundefined the prompt is not written.

      " }, { - "textRaw": "`rl.question(query, callback)`", + "textRaw": "`rl.question(query[, options], callback)`", "type": "method", "name": "question", "meta": { @@ -192,6 +205,19 @@ "type": "string", "desc": "A statement or query to write to `output`, prepended to the prompt." }, + { + "textRaw": "`options` {Object}", + "name": "options", + "type": "Object", + "options": [ + { + "textRaw": "`signal` {AbortSignal} Optionally allows the `question()` to be canceled using an `AbortController`.", + "name": "signal", + "type": "AbortSignal", + "desc": "Optionally allows the `question()` to be canceled using an `AbortController`." + } + ] + }, { "textRaw": "`callback` {Function} A callback function that is invoked with the user's input in response to the `query`.", "name": "callback", @@ -201,7 +227,7 @@ ] } ], - "desc": "

      The rl.question() method displays the query by writing it to the output,\nwaits for user input to be provided on input, then invokes the callback\nfunction passing the provided input as the first argument.

      \n

      When called, rl.question() will resume the input stream if it has been\npaused.

      \n

      If the readline.Interface was created with output set to null or\nundefined the query is not written.

      \n

      Example usage:

      \n
      rl.question('What is your favorite food? ', (answer) => {\n  console.log(`Oh, so your favorite food is ${answer}`);\n});\n
      \n

      The callback function passed to rl.question() does not follow the typical\npattern of accepting an Error object or null as the first argument.\nThe callback is called with the provided answer as the only argument.

      " + "desc": "

      The rl.question() method displays the query by writing it to the output,\nwaits for user input to be provided on input, then invokes the callback\nfunction passing the provided input as the first argument.

      \n

      When called, rl.question() will resume the input stream if it has been\npaused.

      \n

      If the readline.Interface was created with output set to null or\nundefined the query is not written.

      \n

      The callback function passed to rl.question() does not follow the typical\npattern of accepting an Error object or null as the first argument.\nThe callback is called with the provided answer as the only argument.

      \n

      Example usage:

      \n
      rl.question('What is your favorite food? ', (answer) => {\n  console.log(`Oh, so your favorite food is ${answer}`);\n});\n
      \n

      Using an AbortController to cancel a question.

      \n
      const ac = new AbortController();\nconst signal = ac.signal;\n\nrl.question('What is your favorite food? ', { signal }, (answer) => {\n  console.log(`Oh, so your favorite food is ${answer}`);\n});\n\nsignal.addEventListener('abort', () => {\n  console.log('The food question timed out');\n}, { once: true });\n\nsetTimeout(() => ac.abort(), 10000);\n
      \n

      If this method is invoked as it's util.promisify()ed version, it returns a\nPromise that fulfills with the answer. If the question is canceled using\nan AbortController it will reject with an AbortError.

      \n
      const util = require('util');\nconst question = util.promisify(rl.question).bind(rl);\n\nasync function questionExample() {\n  try {\n    const answer = await question('What is you favorite food? ');\n    console.log(`Oh, so your favorite food is ${answer}`);\n  } catch (err) {\n    console.error('Question rejected', err);\n  }\n}\nquestionExample();\n
      " }, { "textRaw": "`rl.resume()`", @@ -243,6 +269,29 @@ ], "desc": "

      The rl.setPrompt() method sets the prompt that will be written to output\nwhenever rl.prompt() is called.

      " }, + { + "textRaw": "`rl.getPrompt()`", + "type": "method", + "name": "getPrompt", + "meta": { + "added": [ + "v14.17.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {string} the current prompt string", + "name": "return", + "type": "string", + "desc": "the current prompt string" + }, + "params": [] + } + ], + "desc": "

      The rl.getPrompt() method returns the current prompt used by rl.prompt().

      " + }, { "textRaw": "`rl.write(data[, key])`", "type": "method", @@ -267,22 +316,22 @@ "type": "Object", "options": [ { - "textRaw": "`ctrl` {boolean} `true` to indicate the `` key.", + "textRaw": "`ctrl` {boolean} `true` to indicate the Ctrl key.", "name": "ctrl", "type": "boolean", - "desc": "`true` to indicate the `` key." + "desc": "`true` to indicate the Ctrl key." }, { - "textRaw": "`meta` {boolean} `true` to indicate the `` key.", + "textRaw": "`meta` {boolean} `true` to indicate the Meta key.", "name": "meta", "type": "boolean", - "desc": "`true` to indicate the `` key." + "desc": "`true` to indicate the Meta key." }, { - "textRaw": "`shift` {boolean} `true` to indicate the `` key.", + "textRaw": "`shift` {boolean} `true` to indicate the Shift key.", "name": "shift", "type": "boolean", - "desc": "`true` to indicate the `` key." + "desc": "`true` to indicate the Shift key." }, { "textRaw": "`name` {string} The name of the a key.", @@ -295,7 +344,7 @@ ] } ], - "desc": "

      The rl.write() method will write either data or a key sequence identified\nby key to the output. The key argument is supported only if output is\na TTY text terminal. See TTY keybindings for a list of key\ncombinations.

      \n

      If key is specified, data is ignored.

      \n

      When called, rl.write() will resume the input stream if it has been\npaused.

      \n

      If the readline.Interface was created with output set to null or\nundefined the data and key are not written.

      \n
      rl.write('Delete this!');\n// Simulate Ctrl+u to delete the line written previously\nrl.write(null, { ctrl: true, name: 'u' });\n
      \n

      The rl.write() method will write the data to the readline Interface's\ninput as if it were provided by the user.

      " + "desc": "

      The rl.write() method will write either data or a key sequence identified\nby key to the output. The key argument is supported only if output is\na TTY text terminal. See TTY keybindings for a list of key\ncombinations.

      \n

      If key is specified, data is ignored.

      \n

      When called, rl.write() will resume the input stream if it has been\npaused.

      \n

      If the readline.Interface was created with output set to null or\nundefined the data and key are not written.

      \n
      rl.write('Delete this!');\n// Simulate Ctrl+U to delete the line written previously\nrl.write(null, { ctrl: true, name: 'u' });\n
      \n

      The rl.write() method will write the data to the readline Interface's\ninput as if it were provided by the user.

      " }, { "textRaw": "`rl[Symbol.asyncIterator]()`", @@ -303,11 +352,15 @@ "name": "[Symbol.asyncIterator]", "meta": { "added": [ - "v11.4.0" + "v11.4.0", + "v10.16.0" ], "changes": [ { - "version": "v11.14.0", + "version": [ + "v11.14.0", + "v10.17.0" + ], "pr-url": "https://github.com/nodejs/node/pull/26989", "description": "Symbol.asyncIterator support is no longer experimental." } @@ -323,7 +376,7 @@ "params": [] } ], - "desc": "

      Create an AsyncIterator object that iterates through each line in the input\nstream as a string. This method allows asynchronous iteration of\nreadline.Interface objects through for await...of loops.

      \n

      Errors in the input stream are not forwarded.

      \n

      If the loop is terminated with break, throw, or return,\nrl.close() will be called. In other words, iterating over a\nreadline.Interface will always consume the input stream fully.

      \n

      Performance is not on par with the traditional 'line' event API. Use 'line'\ninstead for performance-sensitive applications.

      \n
      async function processLineByLine() {\n  const rl = readline.createInterface({\n    // ...\n  });\n\n  for await (const line of rl) {\n    // Each line in the readline input will be successively available here as\n    // `line`.\n  }\n}\n
      " + "desc": "

      Create an AsyncIterator object that iterates through each line in the input\nstream as a string. This method allows asynchronous iteration of\nreadline.Interface objects through for await...of loops.

      \n

      Errors in the input stream are not forwarded.

      \n

      If the loop is terminated with break, throw, or return,\nrl.close() will be called. In other words, iterating over a\nreadline.Interface will always consume the input stream fully.

      \n

      Performance is not on par with the traditional 'line' event API. Use 'line'\ninstead for performance-sensitive applications.

      \n
      async function processLineByLine() {\n  const rl = readline.createInterface({\n    // ...\n  });\n\n  for await (const line of rl) {\n    // Each line in the readline input will be successively available here as\n    // `line`.\n  }\n}\n
      \n

      readline.createInterface() will start to consume the input stream once\ninvoked. Having asynchronous operations between interface creation and\nasynchronous iteration may result in missed lines.

      " }, { "textRaw": "`rl.getCursorPos()`", @@ -331,6 +384,7 @@ "name": "getCursorPos", "meta": { "added": [ + "v13.5.0", "v12.16.0" ], "changes": [] @@ -364,14 +418,20 @@ ], "properties": [ { - "textRaw": "`line` {string|undefined}", - "type": "string|undefined", + "textRaw": "`line` {string}", + "type": "string", "name": "line", "meta": { "added": [ "v0.1.98" ], - "changes": [] + "changes": [ + { + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/33676", + "description": "Value will always be a string, never undefined." + } + ] }, "desc": "

      The current input data being processed by node.

      \n

      This can be used when collecting input from a TTY stream to retrieve the\ncurrent value that has been processed thus far, prior to the line event\nbeing emitted. Once the line event has been emitted, this property will\nbe an empty string.

      \n

      Be aware that modifying the value during the instance runtime may have\nunintended consequences if rl.cursor is not also controlled.

      \n

      If not using a TTY stream for input, use the 'line' event.

      \n

      One possible use case would be as follows:

      \n
      const values = ['lorem ipsum', 'dolor sit amet'];\nconst rl = readline.createInterface(process.stdin);\nconst showResults = debounce(() => {\n  console.log(\n    '\\n',\n    values.filter((val) => val.startsWith(rl.line)).join(' ')\n  );\n}, 300);\nprocess.stdin.on('keypress', (c, k) => {\n  showResults();\n});\n
      " }, @@ -505,7 +565,25 @@ ], "changes": [ { - "version": "v8.3.0, 6.11.4", + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/37932", + "description": "The `signal` option is supported now." + }, + { + "version": "v14.18.0", + "pr-url": "https://github.com/nodejs/node/pull/33662", + "description": "The `history` option is supported now." + }, + { + "version": "v13.9.0", + "pr-url": "https://github.com/nodejs/node/pull/31318", + "description": "The `tabSize` option is supported now." + }, + { + "version": [ + "v8.3.0", + "v6.11.4" + ], "pr-url": "https://github.com/nodejs/node/pull/13497", "description": "Remove max limit of `crlfDelay` option." }, @@ -528,6 +606,11 @@ }, "signatures": [ { + "return": { + "textRaw": "Returns: {readline.Interface}", + "name": "return", + "type": "readline.Interface" + }, "params": [ { "textRaw": "`options` {Object}", @@ -559,6 +642,13 @@ "default": "checking `isTTY` on the `output` stream upon instantiation", "desc": "`true` if the `input` and `output` streams should be treated like a TTY, and have ANSI/VT100 escape codes written to it." }, + { + "textRaw": "`history` {string[]} Initial list of history lines. This option makes sense only if `terminal` is set to `true` by the user or by an internal `output` check, otherwise the history caching mechanism is not initialized at all. **Default:** `[]`.", + "name": "history", + "type": "string[]", + "default": "`[]`", + "desc": "Initial list of history lines. This option makes sense only if `terminal` is set to `true` by the user or by an internal `output` check, otherwise the history caching mechanism is not initialized at all." + }, { "textRaw": "`historySize` {number} Maximum number of history lines retained. To disable the history set this value to `0`. This option makes sense only if `terminal` is set to `true` by the user or by an internal `output` check, otherwise the history caching mechanism is not initialized at all. **Default:** `30`.", "name": "historySize", @@ -566,6 +656,13 @@ "default": "`30`", "desc": "Maximum number of history lines retained. To disable the history set this value to `0`. This option makes sense only if `terminal` is set to `true` by the user or by an internal `output` check, otherwise the history caching mechanism is not initialized at all." }, + { + "textRaw": "`removeHistoryDuplicates` {boolean} If `true`, when a new input line added to the history list duplicates an older one, this removes the older line from the list. **Default:** `false`.", + "name": "removeHistoryDuplicates", + "type": "boolean", + "default": "`false`", + "desc": "If `true`, when a new input line added to the history list duplicates an older one, this removes the older line from the list." + }, { "textRaw": "`prompt` {string} The prompt string to use. **Default:** `'> '`.", "name": "prompt", @@ -580,26 +677,32 @@ "default": "`100`", "desc": "If the delay between `\\r` and `\\n` exceeds `crlfDelay` milliseconds, both `\\r` and `\\n` will be treated as separate end-of-line input. `crlfDelay` will be coerced to a number no less than `100`. It can be set to `Infinity`, in which case `\\r` followed by `\\n` will always be considered a single newline (which may be reasonable for [reading files][] with `\\r\\n` line delimiter)." }, - { - "textRaw": "`removeHistoryDuplicates` {boolean} If `true`, when a new input line added to the history list duplicates an older one, this removes the older line from the list. **Default:** `false`.", - "name": "removeHistoryDuplicates", - "type": "boolean", - "default": "`false`", - "desc": "If `true`, when a new input line added to the history list duplicates an older one, this removes the older line from the list." - }, { "textRaw": "`escapeCodeTimeout` {number} The duration `readline` will wait for a character (when reading an ambiguous key sequence in milliseconds one that can both form a complete key sequence using the input read so far and can take additional input to complete a longer key sequence). **Default:** `500`.", "name": "escapeCodeTimeout", "type": "number", "default": "`500`", "desc": "The duration `readline` will wait for a character (when reading an ambiguous key sequence in milliseconds one that can both form a complete key sequence using the input read so far and can take additional input to complete a longer key sequence)." + }, + { + "textRaw": "`tabSize` {integer} The number of spaces a tab is equal to (minimum 1). **Default:** `8`.", + "name": "tabSize", + "type": "integer", + "default": "`8`", + "desc": "The number of spaces a tab is equal to (minimum 1)." + }, + { + "textRaw": "`signal` {AbortSignal} Allows closing the interface using an AbortSignal. Aborting the signal will internally call `close` on the interface.", + "name": "signal", + "type": "AbortSignal", + "desc": "Allows closing the interface using an AbortSignal. Aborting the signal will internally call `close` on the interface." } ] } ] } ], - "desc": "

      The readline.createInterface() method creates a new readline.Interface\ninstance.

      \n
      const readline = require('readline');\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n
      \n

      Once the readline.Interface instance is created, the most common case is to\nlisten for the 'line' event:

      \n
      rl.on('line', (line) => {\n  console.log(`Received: ${line}`);\n});\n
      \n

      If terminal is true for this instance then the output stream will get\nthe best compatibility if it defines an output.columns property and emits\na 'resize' event on the output if or when the columns ever change\n(process.stdout does this automatically when it is a TTY).

      ", + "desc": "

      The readline.createInterface() method creates a new readline.Interface\ninstance.

      \n
      const readline = require('readline');\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n
      \n

      Once the readline.Interface instance is created, the most common case is to\nlisten for the 'line' event:

      \n
      rl.on('line', (line) => {\n  console.log(`Received: ${line}`);\n});\n
      \n

      If terminal is true for this instance then the output stream will get\nthe best compatibility if it defines an output.columns property and emits\na 'resize' event on the output if or when the columns ever change\n(process.stdout does this automatically when it is a TTY).

      \n

      When creating a readline.Interface using stdin as input, the program\nwill not terminate until it receives EOF (Ctrl+D on\nLinux/macOS, Ctrl+Z followed by Return on\nWindows).\nIf you want your application to exit without waiting for user input, you can\nunref() the standard input stream:

      \n
      process.stdin.unref();\n
      ", "modules": [ { "textRaw": "Use of the `completer` function", @@ -745,7 +848,7 @@ { "textRaw": "TTY keybindings", "name": "tty_keybindings", - "desc": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      KeybindingsDescriptionNotes
      ctrl + shift + backspaceDelete line leftDoesn't work on Linux, Mac and Windows
      ctrl + shift + deleteDelete line rightDoesn't work on Mac
      ctrl + cEmit SIGINT or close the readline instance
      ctrl + hDelete left
      ctrl + dDelete right or close the readline instance in case the current line is empty / EOFDoesn't work on Windows
      ctrl + uDelete from the current position to the line start
      ctrl + kDelete from the current position to the end of line
      ctrl + aGo to start of line
      ctrl + eGo to to end of line
      ctrl + bBack one character
      ctrl + fForward one character
      ctrl + lClear screen
      ctrl + nNext history item
      ctrl + pPrevious history item
      ctrl + zMoves running process into background. Type\n fg and press enter\n to return.Doesn't work on Windows
      ctrl + w or ctrl\n + backspaceDelete backward to a word boundaryctrl + backspace Doesn't\n work on Linux, Mac and Windows
      ctrl + deleteDelete forward to a word boundaryDoesn't work on Mac
      ctrl + left or\n meta + bWord leftctrl + left Doesn't work\n on Mac
      ctrl + right or\n meta + fWord rightctrl + right Doesn't work\n on Mac
      meta + d or meta\n + deleteDelete word rightmeta + delete Doesn't work\n on windows
      meta + backspaceDelete word leftDoesn't work on Mac
      ", + "desc": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      KeybindingsDescriptionNotes
      Ctrl+Shift+BackspaceDelete line leftDoesn't work on Linux, Mac and Windows
      Ctrl+Shift+DeleteDelete line rightDoesn't work on Mac
      Ctrl+CEmit SIGINT or close the readline instance
      Ctrl+HDelete left
      Ctrl+DDelete right or close the readline instance in case the current line is empty / EOFDoesn't work on Windows
      Ctrl+UDelete from the current position to the line start
      Ctrl+KDelete from the current position to the end of line
      Ctrl+AGo to start of line
      Ctrl+EGo to to end of line
      Ctrl+BBack one character
      Ctrl+FForward one character
      Ctrl+LClear screen
      Ctrl+NNext history item
      Ctrl+PPrevious history item
      Ctrl+ZMoves running process into background. Type\n fg and press Enter\n to return.Doesn't work on Windows
      Ctrl+W or Ctrl\n +BackspaceDelete backward to a word boundaryCtrl+Backspace Doesn't\n work on Linux, Mac and Windows
      Ctrl+DeleteDelete forward to a word boundaryDoesn't work on Mac
      Ctrl+Left arrow or\n Meta+BWord leftCtrl+Left arrow Doesn't work\n on Mac
      Ctrl+Right arrow or\n Meta+FWord rightCtrl+Right arrow Doesn't work\n on Mac
      Meta+D or Meta\n +DeleteDelete word rightMeta+Delete Doesn't work\n on windows
      Meta+BackspaceDelete word leftDoesn't work on Mac
      ", "type": "module", "displayName": "TTY keybindings" } diff --git a/doc/api/readline.md b/doc/api/readline.md index c5829bf746629f085701fd6fa9b151e91d8f0945..e78310fcfc97e7d7aa2a381f614d274d8540b724 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -59,9 +59,11 @@ The `'close'` event is emitted when one of the following occur: * The `rl.close()` method is called and the `readline.Interface` instance has relinquished control over the `input` and `output` streams; * The `input` stream receives its `'end'` event; -* The `input` stream receives `-D` to signal end-of-transmission (EOT); -* The `input` stream receives `-C` to signal `SIGINT` and there is no - `'SIGINT'` event listener registered on the `readline.Interface` instance. +* The `input` stream receives Ctrl+D to signal + end-of-transmission (EOT); +* The `input` stream receives Ctrl+C to signal `SIGINT` + and there is no `'SIGINT'` event listener registered on the + `readline.Interface` instance. The listener function is called without passing any arguments. @@ -75,7 +77,7 @@ added: v0.1.98 The `'line'` event is emitted whenever the `input` stream receives an end-of-line input (`\n`, `\r`, or `\r\n`). This usually occurs when the user -presses the ``, or `` keys. +presses Enter or Return. The listener function is called with a string containing the single line of received input. @@ -86,6 +88,28 @@ rl.on('line', (input) => { }); ``` +### Event: `'history'` + + +The `'history'` event is emitted whenever the history array has changed. + +The listener function is called with an array containing the history array. +It will reflect all changes, added lines and removed lines due to +`historySize` and `removeHistoryDuplicates`. + +The primary purpose is to allow a listener to persist the history. +It is also possible for the listener to change the history object. This +could be useful to prevent certain lines to be added to the history, like +a password. + +```js +rl.on('history', (history) => { + console.log(`Received: ${history}`); +}); +``` + ### Event: `'pause'` The `'SIGCONT'` event is emitted when a Node.js process previously moved into -the background using `-Z` (i.e. `SIGTSTP`) is then brought back to the -foreground using fg(1p). +the background using Ctrl+Z (i.e. `SIGTSTP`) is then +brought back to the foreground using fg(1p). If the `input` stream was paused *before* the `SIGTSTP` request, this event will not be emitted. @@ -149,9 +173,9 @@ added: v0.3.0 --> The `'SIGINT'` event is emitted whenever the `input` stream receives a -`-C` input, known typically as `SIGINT`. If there are no `'SIGINT'` event -listeners registered when the `input` stream receives a `SIGINT`, the `'pause'` -event will be emitted. +Ctrl+C input, known typically as `SIGINT`. If there are no `'SIGINT'` +event listeners registered when the `input` stream receives a `SIGINT`, the +`'pause'` event will be emitted. The listener function is invoked without passing any arguments. @@ -168,10 +192,10 @@ rl.on('SIGINT', () => { added: v0.7.5 --> -The `'SIGTSTP'` event is emitted when the `input` stream receives a `-Z` -input, typically known as `SIGTSTP`. If there are no `'SIGTSTP'` event listeners -registered when the `input` stream receives a `SIGTSTP`, the Node.js process -will be sent to the background. +The `'SIGTSTP'` event is emitted when the `input` stream receives a +Ctrl+Z input, typically known as `SIGTSTP`. If there are +no `'SIGTSTP'` event listeners registered when the `input` stream receives a +`SIGTSTP`, the Node.js process will be sent to the background. When the program is resumed using fg(1p), the `'pause'` and `'SIGCONT'` events will be emitted. These can be used to resume the `input` stream. @@ -232,13 +256,16 @@ paused. If the `readline.Interface` was created with `output` set to `null` or `undefined` the prompt is not written. -### `rl.question(query, callback)` +### `rl.question(query[, options], callback)` * `query` {string} A statement or query to write to `output`, prepended to the prompt. +* `options` {Object} + * `signal` {AbortSignal} Optionally allows the `question()` to be canceled + using an `AbortController`. * `callback` {Function} A callback function that is invoked with the user's input in response to the `query`. @@ -252,6 +279,10 @@ paused. If the `readline.Interface` was created with `output` set to `null` or `undefined` the `query` is not written. +The `callback` function passed to `rl.question()` does not follow the typical +pattern of accepting an `Error` object or `null` as the first argument. +The `callback` is called with the provided answer as the only argument. + Example usage: ```js @@ -260,9 +291,41 @@ rl.question('What is your favorite food? ', (answer) => { }); ``` -The `callback` function passed to `rl.question()` does not follow the typical -pattern of accepting an `Error` object or `null` as the first argument. -The `callback` is called with the provided answer as the only argument. +Using an `AbortController` to cancel a question. + +```js +const ac = new AbortController(); +const signal = ac.signal; + +rl.question('What is your favorite food? ', { signal }, (answer) => { + console.log(`Oh, so your favorite food is ${answer}`); +}); + +signal.addEventListener('abort', () => { + console.log('The food question timed out'); +}, { once: true }); + +setTimeout(() => ac.abort(), 10000); +``` + +If this method is invoked as it's util.promisify()ed version, it returns a +Promise that fulfills with the answer. If the question is canceled using +an `AbortController` it will reject with an `AbortError`. + +```js +const util = require('util'); +const question = util.promisify(rl.question).bind(rl); + +async function questionExample() { + try { + const answer = await question('What is you favorite food? '); + console.log(`Oh, so your favorite food is ${answer}`); + } catch (err) { + console.error('Question rejected', err); + } +} +questionExample(); +``` ### `rl.resume()` + +* Returns: {string} the current prompt string + +The `rl.getPrompt()` method returns the current prompt used by `rl.prompt()`. + ### `rl.write(data[, key])` @@ -352,12 +428,20 @@ async function processLineByLine() { } ``` -### rl.line +`readline.createInterface()` will start to consume the input stream once +invoked. Having asynchronous operations between interface creation and +asynchronous iteration may result in missed lines. + +### `rl.line` -* {string|undefined} +* {string} The current input data being processed by node. @@ -387,7 +471,7 @@ process.stdin.on('keypress', (c, k) => { }); ``` -### rl.cursor +### `rl.cursor` @@ -403,7 +487,9 @@ as well as the column where the terminal caret will be rendered. ### `rl.getCursorPos()` * Returns: {Object} @@ -458,7 +544,18 @@ the current position of the cursor down. + diff --git a/doc/api/repl.json b/doc/api/repl.json index 9eff9448adbea947ea5c43fa356aac990b6209e3..1dda9f31ca7f321bf8f5eefef0a252a330d297ad 100644 --- a/doc/api/repl.json +++ b/doc/api/repl.json @@ -8,7 +8,7 @@ "introduced_in": "v0.10.0", "stability": 2, "stabilityText": "Stable", - "desc": "

      Source Code: lib/repl.js

      \n

      The repl module provides a Read-Eval-Print-Loop (REPL) implementation that\nis available both as a standalone program or includible in other applications.\nIt can be accessed using:

      \n
      const repl = require('repl');\n
      ", + "desc": "

      Source Code: lib/repl.js

      \n

      The repl module provides a Read-Eval-Print-Loop (REPL) implementation that\nis available both as a standalone program or includible in other applications.\nIt can be accessed using:

      \n
      const repl = require('repl');\n
      ", "modules": [ { "textRaw": "Design and features", @@ -18,7 +18,7 @@ { "textRaw": "Commands and special keys", "name": "commands_and_special_keys", - "desc": "

      The following special commands are supported by all REPL instances:

      \n
        \n
      • .break: When in the process of inputting a multi-line expression, entering\nthe .break command (or pressing the <ctrl>-C key combination) will abort\nfurther input or processing of that expression.
      • \n
      • .clear: Resets the REPL context to an empty object and clears any\nmulti-line expression being input.
      • \n
      • .exit: Close the I/O stream, causing the REPL to exit.
      • \n
      • .help: Show this list of special commands.
      • \n
      • .save: Save the current REPL session to a file:\n> .save ./file/to/save.js
      • \n
      • .load: Load a file into the current REPL session.\n> .load ./file/to/load.js
      • \n
      • .editor: Enter editor mode (<ctrl>-D to finish, <ctrl>-C to cancel).
      • \n
      \n
      > .editor\n// Entering editor mode (^D to finish, ^C to cancel)\nfunction welcome(name) {\n  return `Hello ${name}!`;\n}\n\nwelcome('Node.js User');\n\n// ^D\n'Hello Node.js User!'\n>\n
      \n

      The following key combinations in the REPL have these special effects:

      \n
        \n
      • <ctrl>-C: When pressed once, has the same effect as the .break command.\nWhen pressed twice on a blank line, has the same effect as the .exit\ncommand.
      • \n
      • <ctrl>-D: Has the same effect as the .exit command.
      • \n
      • <tab>: When pressed on a blank line, displays global and local (scope)\nvariables. When pressed while entering other input, displays relevant\nautocompletion options.
      • \n
      \n

      For key bindings related to the reverse-i-search, see reverse-i-search.\nFor all other key bindings, see TTY keybindings.

      ", + "desc": "

      The following special commands are supported by all REPL instances:

      \n
        \n
      • .break: When in the process of inputting a multi-line expression, enter\nthe .break command (or press Ctrl+C) to abort\nfurther input or processing of that expression.
      • \n
      • .clear: Resets the REPL context to an empty object and clears any\nmulti-line expression being input.
      • \n
      • .exit: Close the I/O stream, causing the REPL to exit.
      • \n
      • .help: Show this list of special commands.
      • \n
      • .save: Save the current REPL session to a file:\n> .save ./file/to/save.js
      • \n
      • .load: Load a file into the current REPL session.\n> .load ./file/to/load.js
      • \n
      • .editor: Enter editor mode (Ctrl+D to finish,\nCtrl+C to cancel).
      • \n
      \n
      > .editor\n// Entering editor mode (^D to finish, ^C to cancel)\nfunction welcome(name) {\n  return `Hello ${name}!`;\n}\n\nwelcome('Node.js User');\n\n// ^D\n'Hello Node.js User!'\n>\n
      \n

      The following key combinations in the REPL have these special effects:

      \n
        \n
      • Ctrl+C: When pressed once, has the same effect as the\n.break command.\nWhen pressed twice on a blank line, has the same effect as the .exit\ncommand.
      • \n
      • Ctrl+D: Has the same effect as the .exit command.
      • \n
      • Tab: When pressed on a blank line, displays global and local (scope)\nvariables. When pressed while entering other input, displays relevant\nautocompletion options.
      • \n
      \n

      For key bindings related to the reverse-i-search, see reverse-i-search.\nFor all other key bindings, see TTY keybindings.

      ", "type": "module", "displayName": "Commands and special keys" }, @@ -60,7 +60,7 @@ } ] }, - "desc": "

      The REPL uses the domain module to catch all uncaught exceptions for that\nREPL session.

      \n

      This use of the domain module in the REPL has these side effects:

      \n\n

      As standalone program:

      \n
      process.on('uncaughtException', () => console.log('Uncaught'));\n\nthrow new Error('foobar');\n// Uncaught\n
      \n

      When used in another application:

      \n
      process.on('uncaughtException', () => console.log('Uncaught'));\n// TypeError [ERR_INVALID_REPL_INPUT]: Listeners for `uncaughtException`\n// cannot be used in the REPL\n\nthrow new Error('foobar');\n// Thrown:\n// Error: foobar\n
      ", + "desc": "

      The REPL uses the domain module to catch all uncaught exceptions for that\nREPL session.

      \n

      This use of the domain module in the REPL has these side effects:

      \n", "type": "module", "displayName": "Global uncaught exceptions" }, @@ -83,7 +83,7 @@ { "textRaw": "`await` keyword", "name": "`await`_keyword", - "desc": "

      With the --experimental-repl-await command line option specified,\nexperimental support for the await keyword is enabled.

      \n
      > await Promise.resolve(123)\n123\n> await Promise.reject(new Error('REPL await'))\nError: REPL await\n    at repl:1:45\n> const timeout = util.promisify(setTimeout);\nundefined\n> const old = Date.now(); await timeout(1000); console.log(Date.now() - old);\n1002\nundefined\n
      ", + "desc": "

      With the --experimental-repl-await command-line option specified,\nexperimental support for the await keyword is enabled.

      \n
      > await Promise.resolve(123)\n123\n> await Promise.reject(new Error('REPL await'))\nError: REPL await\n    at repl:1:45\n> const timeout = util.promisify(setTimeout);\nundefined\n> const old = Date.now(); await timeout(1000); console.log(Date.now() - old);\n1002\nundefined\n
      \n

      One known limitation of using the await keyword in the REPL is that\nit will invalidate the lexical scoping of the const and let\nkeywords.

      \n

      For example:

      \n
      > const m = await Promise.resolve(123)\nundefined\n> m\n123\n> const m = await Promise.resolve(234)\nundefined\n> m\n234\n
      ", "type": "module", "displayName": "`await` keyword" } @@ -96,11 +96,11 @@ "name": "reverse-i-search", "meta": { "added": [ - "v12.17.0" + "v13.6.0" ], "changes": [] }, - "desc": "

      The REPL supports bi-directional reverse-i-search similar to ZSH. It is\ntriggered with <ctrl> + R to search backward and <ctrl> + S to search\nforward.

      \n

      Duplicated history entires will be skipped.

      \n

      Entries are accepted as soon as any button is pressed that doesn't correspond\nwith the reverse search. Cancelling is possible by pressing escape or\n<ctrl> + C.

      \n

      Changing the direction immediately searches for the next entry in the expected\ndirection from the current position on.

      ", + "desc": "

      The REPL supports bi-directional reverse-i-search similar to ZSH. It is\ntriggered with Ctrl+R to search backward and\nCtrl+S to search\nforwards.

      \n

      Duplicated history entries will be skipped.

      \n

      Entries are accepted as soon as any key is pressed that doesn't correspond\nwith the reverse search. Cancelling is possible by pressing Esc or\nCtrl+C.

      \n

      Changing the direction immediately searches for the next entry in the expected\ndirection from the current position on.

      ", "type": "module", "displayName": "Reverse-i-search" }, @@ -112,7 +112,7 @@ { "textRaw": "Recoverable errors", "name": "recoverable_errors", - "desc": "

      As a user is typing input into the REPL prompt, pressing the <enter> key will\nsend the current line of input to the eval function. In order to support\nmulti-line input, the eval function can return an instance of repl.Recoverable\nto the provided callback function:

      \n
      function myEval(cmd, context, filename, callback) {\n  let result;\n  try {\n    result = vm.runInThisContext(cmd);\n  } catch (e) {\n    if (isRecoverableError(e)) {\n      return callback(new repl.Recoverable(e));\n    }\n  }\n  callback(null, result);\n}\n\nfunction isRecoverableError(error) {\n  if (error.name === 'SyntaxError') {\n    return /^(Unexpected end of input|Unexpected token)/.test(error.message);\n  }\n  return false;\n}\n
      ", + "desc": "

      At the REPL prompt, pressing Enter sends the current line of input to\nthe eval function. In order to support multi-line input, the eval function\ncan return an instance of repl.Recoverable to the provided callback function:

      \n
      function myEval(cmd, context, filename, callback) {\n  let result;\n  try {\n    result = vm.runInThisContext(cmd);\n  } catch (e) {\n    if (isRecoverableError(e)) {\n      return callback(new repl.Recoverable(e));\n    }\n  }\n  callback(null, result);\n}\n\nfunction isRecoverableError(error) {\n  if (error.name === 'SyntaxError') {\n    return /^(Unexpected end of input|Unexpected token)/.test(error.message);\n  }\n  return false;\n}\n
      ", "type": "module", "displayName": "Recoverable errors" } @@ -193,7 +193,7 @@ "changes": [] }, "params": [], - "desc": "

      The 'exit' event is emitted when the REPL is exited either by receiving the\n.exit command as input, the user pressing <ctrl>-C twice to signal SIGINT,\nor by pressing <ctrl>-D to signal 'end' on the input stream. The listener\ncallback is invoked without any arguments.

      \n
      replServer.on('exit', () => {\n  console.log('Received \"exit\" event from repl!');\n  process.exit();\n});\n
      " + "desc": "

      The 'exit' event is emitted when the REPL is exited either by receiving the\n.exit command as input, the user pressing Ctrl+C twice\nto signal SIGINT,\nor by pressing Ctrl+D to signal 'end' on the input\nstream. The listener\ncallback is invoked without any arguments.

      \n
      replServer.on('exit', () => {\n  console.log('Received \"exit\" event from repl!');\n  process.exit();\n});\n
      " }, { "textRaw": "Event: `'reset'`", @@ -360,11 +360,25 @@ ] } ], - "desc": "

      Initializes a history log file for the REPL instance. When executing the\nNode.js binary and using the command line REPL, a history file is initialized\nby default. However, this is not the case when creating a REPL\nprogrammatically. Use this method to initialize a history log file when working\nwith REPL instances programmatically.

      " + "desc": "

      Initializes a history log file for the REPL instance. When executing the\nNode.js binary and using the command-line REPL, a history file is initialized\nby default. However, this is not the case when creating a REPL\nprogrammatically. Use this method to initialize a history log file when working\nwith REPL instances programmatically.

      " } ] } ], + "properties": [ + { + "textRaw": "`builtinModules` {string[]}", + "type": "string[]", + "name": "builtinModules", + "meta": { + "added": [ + "v14.5.0" + ], + "changes": [] + }, + "desc": "

      A list of the names of all Node.js modules, e.g., 'http'.

      " + } + ], "methods": [ { "textRaw": "`repl.start([options])`", @@ -376,7 +390,7 @@ ], "changes": [ { - "version": "v12.17.0", + "version": "v13.4.0", "pr-url": "https://github.com/nodejs/node/pull/30811", "description": "The `preview` option is now available." }, @@ -503,11 +517,11 @@ ] }, { - "textRaw": "`breakEvalOnSigint` {boolean} Stop evaluating the current piece of code when `SIGINT` is received, such as when `Ctrl+C` is pressed. This cannot be used together with a custom `eval` function. **Default:** `false`.", + "textRaw": "`breakEvalOnSigint` {boolean} Stop evaluating the current piece of code when `SIGINT` is received, such as when Ctrl+C is pressed. This cannot be used together with a custom `eval` function. **Default:** `false`.", "name": "breakEvalOnSigint", "type": "boolean", "default": "`false`", - "desc": "Stop evaluating the current piece of code when `SIGINT` is received, such as when `Ctrl+C` is pressed. This cannot be used together with a custom `eval` function." + "desc": "Stop evaluating the current piece of code when `SIGINT` is received, such as when Ctrl+C is pressed. This cannot be used together with a custom `eval` function." }, { "textRaw": "`preview` {boolean} Defines if the repl prints autocomplete and output previews or not. **Default:** `true` with the default eval function and `false` in case a custom eval function is used. If `terminal` is falsy, then there are no previews and the value of `preview` has no effect.", diff --git a/doc/api/repl.md b/doc/api/repl.md index 3ab7cefec280d2e87a50d1eff8aa017cdb7a0079..bc2d74edde15731a1ebed33210efe741a2bb9a6a 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -34,8 +34,8 @@ feature set. The following special commands are supported by all REPL instances: -* `.break`: When in the process of inputting a multi-line expression, entering - the `.break` command (or pressing the `-C` key combination) will abort +* `.break`: When in the process of inputting a multi-line expression, enter + the `.break` command (or press Ctrl+C) to abort further input or processing of that expression. * `.clear`: Resets the REPL `context` to an empty object and clears any multi-line expression being input. @@ -45,7 +45,8 @@ The following special commands are supported by all REPL instances: `> .save ./file/to/save.js` * `.load`: Load a file into the current REPL session. `> .load ./file/to/load.js` -* `.editor`: Enter editor mode (`-D` to finish, `-C` to cancel). +* `.editor`: Enter editor mode (Ctrl+D to finish, + Ctrl+C to cancel). ```console > .editor @@ -63,11 +64,12 @@ welcome('Node.js User'); The following key combinations in the REPL have these special effects: -* `-C`: When pressed once, has the same effect as the `.break` command. +* Ctrl+C: When pressed once, has the same effect as the + `.break` command. When pressed twice on a blank line, has the same effect as the `.exit` command. -* `-D`: Has the same effect as the `.exit` command. -* ``: When pressed on a blank line, displays global and local (scope) +* Ctrl+D: Has the same effect as the `.exit` command. +* Tab: When pressed on a blank line, displays global and local (scope) variables. When pressed while entering other input, displays relevant autocompletion options. @@ -161,30 +163,21 @@ This use of the [`domain`][] module in the REPL has these side effects: * Uncaught exceptions only emit the [`'uncaughtException'`][] event in the standalone REPL. Adding a listener for this event in a REPL within - another Node.js program throws [`ERR_INVALID_REPL_INPUT`][]. -* Trying to use [`process.setUncaughtExceptionCaptureCallback()`][] throws - an [`ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE`][] error. + another Node.js program results in [`ERR_INVALID_REPL_INPUT`][]. -As standalone program: + ```js + const r = repl.start(); -```js -process.on('uncaughtException', () => console.log('Uncaught')); + r.write('process.on("uncaughtException", () => console.log("Foobar"));\n'); + // Output stream includes: + // TypeError [ERR_INVALID_REPL_INPUT]: Listeners for `uncaughtException` + // cannot be used in the REPL -throw new Error('foobar'); -// Uncaught -``` - -When used in another application: - -```js -process.on('uncaughtException', () => console.log('Uncaught')); -// TypeError [ERR_INVALID_REPL_INPUT]: Listeners for `uncaughtException` -// cannot be used in the REPL + r.close(); + ``` -throw new Error('foobar'); -// Thrown: -// Error: foobar -``` +* Trying to use [`process.setUncaughtExceptionCaptureCallback()`][] throws + an [`ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE`][] error. #### Assignment of the `_` (underscore) variable The REPL supports bi-directional reverse-i-search similar to [ZSH][]. It is -triggered with ` + R` to search backward and ` + S` to search -forward. +triggered with Ctrl+R to search backward and +Ctrl+S to search +forwards. -Duplicated history entires will be skipped. +Duplicated history entries will be skipped. -Entries are accepted as soon as any button is pressed that doesn't correspond -with the reverse search. Cancelling is possible by pressing `escape` or -` + C`. +Entries are accepted as soon as any key is pressed that doesn't correspond +with the reverse search. Cancelling is possible by pressing Esc or +Ctrl+C. Changing the direction immediately searches for the next entry in the expected direction from the current position on. @@ -282,10 +293,9 @@ repl.start({ prompt: '> ', eval: myEval }); #### Recoverable errors -As a user is typing input into the REPL prompt, pressing the `` key will -send the current line of input to the `eval` function. In order to support -multi-line input, the eval function can return an instance of `repl.Recoverable` -to the provided callback function: +At the REPL prompt, pressing Enter sends the current line of input to +the `eval` function. In order to support multi-line input, the `eval` function +can return an instance of `repl.Recoverable` to the provided callback function: ```js function myEval(cmd, context, filename, callback) { @@ -379,8 +389,10 @@ added: v0.7.7 --> The `'exit'` event is emitted when the REPL is exited either by receiving the -`.exit` command as input, the user pressing `-C` twice to signal `SIGINT`, -or by pressing `-D` to signal `'end'` on the input stream. The listener +`.exit` command as input, the user pressing Ctrl+C twice +to signal `SIGINT`, +or by pressing Ctrl+D to signal `'end'` on the input +stream. The listener callback is invoked without any arguments. ```js @@ -537,16 +549,25 @@ added: v11.10.0 * `repl` {repl.REPLServer} Initializes a history log file for the REPL instance. When executing the -Node.js binary and using the command line REPL, a history file is initialized +Node.js binary and using the command-line REPL, a history file is initialized by default. However, this is not the case when creating a REPL programmatically. Use this method to initialize a history log file when working with REPL instances programmatically. +## `repl.builtinModules` + + +* {string[]} + +A list of the names of all Node.js modules, e.g., `'http'`. + ## `repl.start([options])` + diff --git a/doc/api/report.json b/doc/api/report.json index 51a3497657bd972550c01605574280d85cc35275..5938154ecd7054b3919bad3083b5d75da096304c 100644 --- a/doc/api/report.json +++ b/doc/api/report.json @@ -12,12 +12,12 @@ "type": "misc", "stability": 2, "stabilityText": "Stable", - "desc": "

      Delivers a JSON-formatted diagnostic summary, written to a file.

      \n

      The report is intended for development, test and production use, to capture\nand preserve information for problem determination. It includes JavaScript\nand native stack traces, heap statistics, platform information, resource\nusage etc. With the report option enabled, diagnostic reports can be triggered\non unhandled exceptions, fatal errors and user signals, in addition to\ntriggering programmatically through API calls.

      \n

      A complete example report that was generated on an uncaught exception\nis provided below for reference.

      \n
      {\n  \"header\": {\n    \"reportVersion\": 1,\n    \"event\": \"exception\",\n    \"trigger\": \"Exception\",\n    \"filename\": \"report.20181221.005011.8974.0.001.json\",\n    \"dumpEventTime\": \"2018-12-21T00:50:11Z\",\n    \"dumpEventTimeStamp\": \"1545371411331\",\n    \"processId\": 8974,\n    \"cwd\": \"/home/nodeuser/project/node\",\n    \"commandLine\": [\n      \"/home/nodeuser/project/node/out/Release/node\",\n      \"--report-uncaught-exception\",\n      \"/home/nodeuser/project/node/test/report/test-exception.js\",\n      \"child\"\n    ],\n    \"nodejsVersion\": \"v12.0.0-pre\",\n    \"glibcVersionRuntime\": \"2.17\",\n    \"glibcVersionCompiler\": \"2.17\",\n    \"wordSize\": \"64 bit\",\n    \"arch\": \"x64\",\n    \"platform\": \"linux\",\n    \"componentVersions\": {\n      \"node\": \"12.0.0-pre\",\n      \"v8\": \"7.1.302.28-node.5\",\n      \"uv\": \"1.24.1\",\n      \"zlib\": \"1.2.11\",\n      \"ares\": \"1.15.0\",\n      \"modules\": \"68\",\n      \"nghttp2\": \"1.34.0\",\n      \"napi\": \"3\",\n      \"llhttp\": \"1.0.1\",\n      \"http_parser\": \"2.8.0\",\n      \"openssl\": \"1.1.0j\"\n    },\n    \"release\": {\n      \"name\": \"node\"\n    },\n    \"osName\": \"Linux\",\n    \"osRelease\": \"3.10.0-862.el7.x86_64\",\n    \"osVersion\": \"#1 SMP Wed Mar 21 18:14:51 EDT 2018\",\n    \"osMachine\": \"x86_64\",\n    \"cpus\": [\n      {\n        \"model\": \"Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz\",\n        \"speed\": 2700,\n        \"user\": 88902660,\n        \"nice\": 0,\n        \"sys\": 50902570,\n        \"idle\": 241732220,\n        \"irq\": 0\n      },\n      {\n        \"model\": \"Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz\",\n        \"speed\": 2700,\n        \"user\": 88902660,\n        \"nice\": 0,\n        \"sys\": 50902570,\n        \"idle\": 241732220,\n        \"irq\": 0\n      }\n    ],\n    \"networkInterfaces\": [\n      {\n        \"name\": \"en0\",\n        \"internal\": false,\n        \"mac\": \"13:10:de:ad:be:ef\",\n        \"address\": \"10.0.0.37\",\n        \"netmask\": \"255.255.255.0\",\n        \"family\": \"IPv4\"\n      }\n    ],\n    \"host\": \"test_machine\"\n  },\n  \"javascriptStack\": {\n    \"message\": \"Error: *** test-exception.js: throwing uncaught Error\",\n    \"stack\": [\n      \"at myException (/home/nodeuser/project/node/test/report/test-exception.js:9:11)\",\n      \"at Object.<anonymous> (/home/nodeuser/project/node/test/report/test-exception.js:12:3)\",\n      \"at Module._compile (internal/modules/cjs/loader.js:718:30)\",\n      \"at Object.Module._extensions..js (internal/modules/cjs/loader.js:729:10)\",\n      \"at Module.load (internal/modules/cjs/loader.js:617:32)\",\n      \"at tryModuleLoad (internal/modules/cjs/loader.js:560:12)\",\n      \"at Function.Module._load (internal/modules/cjs/loader.js:552:3)\",\n      \"at Function.Module.runMain (internal/modules/cjs/loader.js:771:12)\",\n      \"at executeUserCode (internal/bootstrap/node.js:332:15)\"\n    ]\n  },\n  \"nativeStack\": [\n    {\n      \"pc\": \"0x000055b57f07a9ef\",\n      \"symbol\": \"report::GetNodeReport(v8::Isolate*, node::Environment*, char const*, char const*, v8::Local<v8::String>, std::ostream&) [./node]\"\n    },\n    {\n      \"pc\": \"0x000055b57f07cf03\",\n      \"symbol\": \"report::GetReport(v8::FunctionCallbackInfo<v8::Value> const&) [./node]\"\n    },\n    {\n      \"pc\": \"0x000055b57f1bccfd\",\n      \"symbol\": \" [./node]\"\n    },\n    {\n      \"pc\": \"0x000055b57f1be048\",\n      \"symbol\": \"v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [./node]\"\n    },\n    {\n      \"pc\": \"0x000055b57feeda0e\",\n      \"symbol\": \" [./node]\"\n    }\n  ],\n  \"javascriptHeap\": {\n    \"totalMemory\": 6127616,\n    \"totalCommittedMemory\": 4357352,\n    \"usedMemory\": 3221136,\n    \"availableMemory\": 1521370240,\n    \"memoryLimit\": 1526909922,\n    \"heapSpaces\": {\n      \"read_only_space\": {\n        \"memorySize\": 524288,\n        \"committedMemory\": 39208,\n        \"capacity\": 515584,\n        \"used\": 30504,\n        \"available\": 485080\n      },\n      \"new_space\": {\n        \"memorySize\": 2097152,\n        \"committedMemory\": 2019312,\n        \"capacity\": 1031168,\n        \"used\": 985496,\n        \"available\": 45672\n      },\n      \"old_space\": {\n        \"memorySize\": 2273280,\n        \"committedMemory\": 1769008,\n        \"capacity\": 1974640,\n        \"used\": 1725488,\n        \"available\": 249152\n      },\n      \"code_space\": {\n        \"memorySize\": 696320,\n        \"committedMemory\": 184896,\n        \"capacity\": 152128,\n        \"used\": 152128,\n        \"available\": 0\n      },\n      \"map_space\": {\n        \"memorySize\": 536576,\n        \"committedMemory\": 344928,\n        \"capacity\": 327520,\n        \"used\": 327520,\n        \"available\": 0\n      },\n      \"large_object_space\": {\n        \"memorySize\": 0,\n        \"committedMemory\": 0,\n        \"capacity\": 1520590336,\n        \"used\": 0,\n        \"available\": 1520590336\n      },\n      \"new_large_object_space\": {\n        \"memorySize\": 0,\n        \"committedMemory\": 0,\n        \"capacity\": 0,\n        \"used\": 0,\n        \"available\": 0\n      }\n    }\n  },\n  \"resourceUsage\": {\n    \"userCpuSeconds\": 0.069595,\n    \"kernelCpuSeconds\": 0.019163,\n    \"cpuConsumptionPercent\": 0.000000,\n    \"maxRss\": 18079744,\n    \"pageFaults\": {\n      \"IORequired\": 0,\n      \"IONotRequired\": 4610\n    },\n    \"fsActivity\": {\n      \"reads\": 0,\n      \"writes\": 0\n    }\n  },\n  \"uvthreadResourceUsage\": {\n    \"userCpuSeconds\": 0.068457,\n    \"kernelCpuSeconds\": 0.019127,\n    \"cpuConsumptionPercent\": 0.000000,\n    \"fsActivity\": {\n      \"reads\": 0,\n      \"writes\": 0\n    }\n  },\n  \"libuv\": [\n    {\n      \"type\": \"async\",\n      \"is_active\": true,\n      \"is_referenced\": false,\n      \"address\": \"0x0000000102910900\",\n      \"details\": \"\"\n    },\n    {\n      \"type\": \"timer\",\n      \"is_active\": false,\n      \"is_referenced\": false,\n      \"address\": \"0x00007fff5fbfeab0\",\n      \"repeat\": 0,\n      \"firesInMsFromNow\": 94403548320796,\n      \"expired\": true\n    },\n    {\n      \"type\": \"check\",\n      \"is_active\": true,\n      \"is_referenced\": false,\n      \"address\": \"0x00007fff5fbfeb48\"\n    },\n    {\n      \"type\": \"idle\",\n      \"is_active\": false,\n      \"is_referenced\": true,\n      \"address\": \"0x00007fff5fbfebc0\"\n    },\n    {\n      \"type\": \"prepare\",\n      \"is_active\": false,\n      \"is_referenced\": false,\n      \"address\": \"0x00007fff5fbfec38\"\n    },\n    {\n      \"type\": \"check\",\n      \"is_active\": false,\n      \"is_referenced\": false,\n      \"address\": \"0x00007fff5fbfecb0\"\n    },\n    {\n      \"type\": \"async\",\n      \"is_active\": true,\n      \"is_referenced\": false,\n      \"address\": \"0x000000010188f2e0\"\n    },\n    {\n      \"type\": \"tty\",\n      \"is_active\": false,\n      \"is_referenced\": true,\n      \"address\": \"0x000055b581db0e18\",\n      \"width\": 204,\n      \"height\": 55,\n      \"fd\": 17,\n      \"writeQueueSize\": 0,\n      \"readable\": true,\n      \"writable\": true\n    },\n    {\n      \"type\": \"signal\",\n      \"is_active\": true,\n      \"is_referenced\": false,\n      \"address\": \"0x000055b581d80010\",\n      \"signum\": 28,\n      \"signal\": \"SIGWINCH\"\n    },\n    {\n      \"type\": \"tty\",\n      \"is_active\": true,\n      \"is_referenced\": true,\n      \"address\": \"0x000055b581df59f8\",\n      \"width\": 204,\n      \"height\": 55,\n      \"fd\": 19,\n      \"writeQueueSize\": 0,\n      \"readable\": true,\n      \"writable\": true\n    },\n    {\n      \"type\": \"loop\",\n      \"is_active\": true,\n      \"address\": \"0x000055fc7b2cb180\"\n    }\n  ],\n  \"workers\": [],\n  \"environmentVariables\": {\n    \"REMOTEHOST\": \"REMOVED\",\n    \"MANPATH\": \"/opt/rh/devtoolset-3/root/usr/share/man:\",\n    \"XDG_SESSION_ID\": \"66126\",\n    \"HOSTNAME\": \"test_machine\",\n    \"HOST\": \"test_machine\",\n    \"TERM\": \"xterm-256color\",\n    \"SHELL\": \"/bin/csh\",\n    \"SSH_CLIENT\": \"REMOVED\",\n    \"PERL5LIB\": \"/opt/rh/devtoolset-3/root//usr/lib64/perl5/vendor_perl:/opt/rh/devtoolset-3/root/usr/lib/perl5:/opt/rh/devtoolset-3/root//usr/share/perl5/vendor_perl\",\n    \"OLDPWD\": \"/home/nodeuser/project/node/src\",\n    \"JAVACONFDIRS\": \"/opt/rh/devtoolset-3/root/etc/java:/etc/java\",\n    \"SSH_TTY\": \"/dev/pts/0\",\n    \"PCP_DIR\": \"/opt/rh/devtoolset-3/root\",\n    \"GROUP\": \"normaluser\",\n    \"USER\": \"nodeuser\",\n    \"LD_LIBRARY_PATH\": \"/opt/rh/devtoolset-3/root/usr/lib64:/opt/rh/devtoolset-3/root/usr/lib\",\n    \"HOSTTYPE\": \"x86_64-linux\",\n    \"XDG_CONFIG_DIRS\": \"/opt/rh/devtoolset-3/root/etc/xdg:/etc/xdg\",\n    \"MAIL\": \"/var/spool/mail/nodeuser\",\n    \"PATH\": \"/home/nodeuser/project/node:/opt/rh/devtoolset-3/root/usr/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin\",\n    \"PWD\": \"/home/nodeuser/project/node\",\n    \"LANG\": \"en_US.UTF-8\",\n    \"PS1\": \"\\\\u@\\\\h : \\\\[\\\\e[31m\\\\]\\\\w\\\\[\\\\e[m\\\\] >  \",\n    \"SHLVL\": \"2\",\n    \"HOME\": \"/home/nodeuser\",\n    \"OSTYPE\": \"linux\",\n    \"VENDOR\": \"unknown\",\n    \"PYTHONPATH\": \"/opt/rh/devtoolset-3/root/usr/lib64/python2.7/site-packages:/opt/rh/devtoolset-3/root/usr/lib/python2.7/site-packages\",\n    \"MACHTYPE\": \"x86_64\",\n    \"LOGNAME\": \"nodeuser\",\n    \"XDG_DATA_DIRS\": \"/opt/rh/devtoolset-3/root/usr/share:/usr/local/share:/usr/share\",\n    \"LESSOPEN\": \"||/usr/bin/lesspipe.sh %s\",\n    \"INFOPATH\": \"/opt/rh/devtoolset-3/root/usr/share/info\",\n    \"XDG_RUNTIME_DIR\": \"/run/user/50141\",\n    \"_\": \"./node\"\n  },\n  \"userLimits\": {\n    \"core_file_size_blocks\": {\n      \"soft\": \"\",\n      \"hard\": \"unlimited\"\n    },\n    \"data_seg_size_kbytes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    },\n    \"file_size_blocks\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    },\n    \"max_locked_memory_bytes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": 65536\n    },\n    \"max_memory_size_kbytes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    },\n    \"open_files\": {\n      \"soft\": \"unlimited\",\n      \"hard\": 4096\n    },\n    \"stack_size_bytes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    },\n    \"cpu_time_seconds\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    },\n    \"max_user_processes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": 4127290\n    },\n    \"virtual_memory_kbytes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    }\n  },\n  \"sharedObjects\": [\n    \"/lib64/libdl.so.2\",\n    \"/lib64/librt.so.1\",\n    \"/lib64/libstdc++.so.6\",\n    \"/lib64/libm.so.6\",\n    \"/lib64/libgcc_s.so.1\",\n    \"/lib64/libpthread.so.0\",\n    \"/lib64/libc.so.6\",\n    \"/lib64/ld-linux-x86-64.so.2\"\n  ]\n}\n
      ", + "desc": "

      Delivers a JSON-formatted diagnostic summary, written to a file.

      \n

      The report is intended for development, test and production use, to capture\nand preserve information for problem determination. It includes JavaScript\nand native stack traces, heap statistics, platform information, resource\nusage etc. With the report option enabled, diagnostic reports can be triggered\non unhandled exceptions, fatal errors and user signals, in addition to\ntriggering programmatically through API calls.

      \n

      A complete example report that was generated on an uncaught exception\nis provided below for reference.

      \n
      {\n  \"header\": {\n    \"reportVersion\": 1,\n    \"event\": \"exception\",\n    \"trigger\": \"Exception\",\n    \"filename\": \"report.20181221.005011.8974.0.001.json\",\n    \"dumpEventTime\": \"2018-12-21T00:50:11Z\",\n    \"dumpEventTimeStamp\": \"1545371411331\",\n    \"processId\": 8974,\n    \"cwd\": \"/home/nodeuser/project/node\",\n    \"commandLine\": [\n      \"/home/nodeuser/project/node/out/Release/node\",\n      \"--report-uncaught-exception\",\n      \"/home/nodeuser/project/node/test/report/test-exception.js\",\n      \"child\"\n    ],\n    \"nodejsVersion\": \"v12.0.0-pre\",\n    \"glibcVersionRuntime\": \"2.17\",\n    \"glibcVersionCompiler\": \"2.17\",\n    \"wordSize\": \"64 bit\",\n    \"arch\": \"x64\",\n    \"platform\": \"linux\",\n    \"componentVersions\": {\n      \"node\": \"12.0.0-pre\",\n      \"v8\": \"7.1.302.28-node.5\",\n      \"uv\": \"1.24.1\",\n      \"zlib\": \"1.2.11\",\n      \"ares\": \"1.15.0\",\n      \"modules\": \"68\",\n      \"nghttp2\": \"1.34.0\",\n      \"napi\": \"3\",\n      \"llhttp\": \"1.0.1\",\n      \"openssl\": \"1.1.0j\"\n    },\n    \"release\": {\n      \"name\": \"node\"\n    },\n    \"osName\": \"Linux\",\n    \"osRelease\": \"3.10.0-862.el7.x86_64\",\n    \"osVersion\": \"#1 SMP Wed Mar 21 18:14:51 EDT 2018\",\n    \"osMachine\": \"x86_64\",\n    \"cpus\": [\n      {\n        \"model\": \"Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz\",\n        \"speed\": 2700,\n        \"user\": 88902660,\n        \"nice\": 0,\n        \"sys\": 50902570,\n        \"idle\": 241732220,\n        \"irq\": 0\n      },\n      {\n        \"model\": \"Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz\",\n        \"speed\": 2700,\n        \"user\": 88902660,\n        \"nice\": 0,\n        \"sys\": 50902570,\n        \"idle\": 241732220,\n        \"irq\": 0\n      }\n    ],\n    \"networkInterfaces\": [\n      {\n        \"name\": \"en0\",\n        \"internal\": false,\n        \"mac\": \"13:10:de:ad:be:ef\",\n        \"address\": \"10.0.0.37\",\n        \"netmask\": \"255.255.255.0\",\n        \"family\": \"IPv4\"\n      }\n    ],\n    \"host\": \"test_machine\"\n  },\n  \"javascriptStack\": {\n    \"message\": \"Error: *** test-exception.js: throwing uncaught Error\",\n    \"stack\": [\n      \"at myException (/home/nodeuser/project/node/test/report/test-exception.js:9:11)\",\n      \"at Object.<anonymous> (/home/nodeuser/project/node/test/report/test-exception.js:12:3)\",\n      \"at Module._compile (internal/modules/cjs/loader.js:718:30)\",\n      \"at Object.Module._extensions..js (internal/modules/cjs/loader.js:729:10)\",\n      \"at Module.load (internal/modules/cjs/loader.js:617:32)\",\n      \"at tryModuleLoad (internal/modules/cjs/loader.js:560:12)\",\n      \"at Function.Module._load (internal/modules/cjs/loader.js:552:3)\",\n      \"at Function.Module.runMain (internal/modules/cjs/loader.js:771:12)\",\n      \"at executeUserCode (internal/bootstrap/node.js:332:15)\"\n    ]\n  },\n  \"nativeStack\": [\n    {\n      \"pc\": \"0x000055b57f07a9ef\",\n      \"symbol\": \"report::GetNodeReport(v8::Isolate*, node::Environment*, char const*, char const*, v8::Local<v8::String>, std::ostream&) [./node]\"\n    },\n    {\n      \"pc\": \"0x000055b57f07cf03\",\n      \"symbol\": \"report::GetReport(v8::FunctionCallbackInfo<v8::Value> const&) [./node]\"\n    },\n    {\n      \"pc\": \"0x000055b57f1bccfd\",\n      \"symbol\": \" [./node]\"\n    },\n    {\n      \"pc\": \"0x000055b57f1be048\",\n      \"symbol\": \"v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [./node]\"\n    },\n    {\n      \"pc\": \"0x000055b57feeda0e\",\n      \"symbol\": \" [./node]\"\n    }\n  ],\n  \"javascriptHeap\": {\n    \"totalMemory\": 6127616,\n    \"totalCommittedMemory\": 4357352,\n    \"usedMemory\": 3221136,\n    \"availableMemory\": 1521370240,\n    \"memoryLimit\": 1526909922,\n    \"heapSpaces\": {\n      \"read_only_space\": {\n        \"memorySize\": 524288,\n        \"committedMemory\": 39208,\n        \"capacity\": 515584,\n        \"used\": 30504,\n        \"available\": 485080\n      },\n      \"new_space\": {\n        \"memorySize\": 2097152,\n        \"committedMemory\": 2019312,\n        \"capacity\": 1031168,\n        \"used\": 985496,\n        \"available\": 45672\n      },\n      \"old_space\": {\n        \"memorySize\": 2273280,\n        \"committedMemory\": 1769008,\n        \"capacity\": 1974640,\n        \"used\": 1725488,\n        \"available\": 249152\n      },\n      \"code_space\": {\n        \"memorySize\": 696320,\n        \"committedMemory\": 184896,\n        \"capacity\": 152128,\n        \"used\": 152128,\n        \"available\": 0\n      },\n      \"map_space\": {\n        \"memorySize\": 536576,\n        \"committedMemory\": 344928,\n        \"capacity\": 327520,\n        \"used\": 327520,\n        \"available\": 0\n      },\n      \"large_object_space\": {\n        \"memorySize\": 0,\n        \"committedMemory\": 0,\n        \"capacity\": 1520590336,\n        \"used\": 0,\n        \"available\": 1520590336\n      },\n      \"new_large_object_space\": {\n        \"memorySize\": 0,\n        \"committedMemory\": 0,\n        \"capacity\": 0,\n        \"used\": 0,\n        \"available\": 0\n      }\n    }\n  },\n  \"resourceUsage\": {\n    \"userCpuSeconds\": 0.069595,\n    \"kernelCpuSeconds\": 0.019163,\n    \"cpuConsumptionPercent\": 0.000000,\n    \"maxRss\": 18079744,\n    \"pageFaults\": {\n      \"IORequired\": 0,\n      \"IONotRequired\": 4610\n    },\n    \"fsActivity\": {\n      \"reads\": 0,\n      \"writes\": 0\n    }\n  },\n  \"uvthreadResourceUsage\": {\n    \"userCpuSeconds\": 0.068457,\n    \"kernelCpuSeconds\": 0.019127,\n    \"cpuConsumptionPercent\": 0.000000,\n    \"fsActivity\": {\n      \"reads\": 0,\n      \"writes\": 0\n    }\n  },\n  \"libuv\": [\n    {\n      \"type\": \"async\",\n      \"is_active\": true,\n      \"is_referenced\": false,\n      \"address\": \"0x0000000102910900\",\n      \"details\": \"\"\n    },\n    {\n      \"type\": \"timer\",\n      \"is_active\": false,\n      \"is_referenced\": false,\n      \"address\": \"0x00007fff5fbfeab0\",\n      \"repeat\": 0,\n      \"firesInMsFromNow\": 94403548320796,\n      \"expired\": true\n    },\n    {\n      \"type\": \"check\",\n      \"is_active\": true,\n      \"is_referenced\": false,\n      \"address\": \"0x00007fff5fbfeb48\"\n    },\n    {\n      \"type\": \"idle\",\n      \"is_active\": false,\n      \"is_referenced\": true,\n      \"address\": \"0x00007fff5fbfebc0\"\n    },\n    {\n      \"type\": \"prepare\",\n      \"is_active\": false,\n      \"is_referenced\": false,\n      \"address\": \"0x00007fff5fbfec38\"\n    },\n    {\n      \"type\": \"check\",\n      \"is_active\": false,\n      \"is_referenced\": false,\n      \"address\": \"0x00007fff5fbfecb0\"\n    },\n    {\n      \"type\": \"async\",\n      \"is_active\": true,\n      \"is_referenced\": false,\n      \"address\": \"0x000000010188f2e0\"\n    },\n    {\n      \"type\": \"tty\",\n      \"is_active\": false,\n      \"is_referenced\": true,\n      \"address\": \"0x000055b581db0e18\",\n      \"width\": 204,\n      \"height\": 55,\n      \"fd\": 17,\n      \"writeQueueSize\": 0,\n      \"readable\": true,\n      \"writable\": true\n    },\n    {\n      \"type\": \"signal\",\n      \"is_active\": true,\n      \"is_referenced\": false,\n      \"address\": \"0x000055b581d80010\",\n      \"signum\": 28,\n      \"signal\": \"SIGWINCH\"\n    },\n    {\n      \"type\": \"tty\",\n      \"is_active\": true,\n      \"is_referenced\": true,\n      \"address\": \"0x000055b581df59f8\",\n      \"width\": 204,\n      \"height\": 55,\n      \"fd\": 19,\n      \"writeQueueSize\": 0,\n      \"readable\": true,\n      \"writable\": true\n    },\n    {\n      \"type\": \"loop\",\n      \"is_active\": true,\n      \"address\": \"0x000055fc7b2cb180\",\n      \"loopIdleTimeSeconds\": 22644.8\n    }\n  ],\n  \"workers\": [],\n  \"environmentVariables\": {\n    \"REMOTEHOST\": \"REMOVED\",\n    \"MANPATH\": \"/opt/rh/devtoolset-3/root/usr/share/man:\",\n    \"XDG_SESSION_ID\": \"66126\",\n    \"HOSTNAME\": \"test_machine\",\n    \"HOST\": \"test_machine\",\n    \"TERM\": \"xterm-256color\",\n    \"SHELL\": \"/bin/csh\",\n    \"SSH_CLIENT\": \"REMOVED\",\n    \"PERL5LIB\": \"/opt/rh/devtoolset-3/root//usr/lib64/perl5/vendor_perl:/opt/rh/devtoolset-3/root/usr/lib/perl5:/opt/rh/devtoolset-3/root//usr/share/perl5/vendor_perl\",\n    \"OLDPWD\": \"/home/nodeuser/project/node/src\",\n    \"JAVACONFDIRS\": \"/opt/rh/devtoolset-3/root/etc/java:/etc/java\",\n    \"SSH_TTY\": \"/dev/pts/0\",\n    \"PCP_DIR\": \"/opt/rh/devtoolset-3/root\",\n    \"GROUP\": \"normaluser\",\n    \"USER\": \"nodeuser\",\n    \"LD_LIBRARY_PATH\": \"/opt/rh/devtoolset-3/root/usr/lib64:/opt/rh/devtoolset-3/root/usr/lib\",\n    \"HOSTTYPE\": \"x86_64-linux\",\n    \"XDG_CONFIG_DIRS\": \"/opt/rh/devtoolset-3/root/etc/xdg:/etc/xdg\",\n    \"MAIL\": \"/var/spool/mail/nodeuser\",\n    \"PATH\": \"/home/nodeuser/project/node:/opt/rh/devtoolset-3/root/usr/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin\",\n    \"PWD\": \"/home/nodeuser/project/node\",\n    \"LANG\": \"en_US.UTF-8\",\n    \"PS1\": \"\\\\u@\\\\h : \\\\[\\\\e[31m\\\\]\\\\w\\\\[\\\\e[m\\\\] >  \",\n    \"SHLVL\": \"2\",\n    \"HOME\": \"/home/nodeuser\",\n    \"OSTYPE\": \"linux\",\n    \"VENDOR\": \"unknown\",\n    \"PYTHONPATH\": \"/opt/rh/devtoolset-3/root/usr/lib64/python2.7/site-packages:/opt/rh/devtoolset-3/root/usr/lib/python2.7/site-packages\",\n    \"MACHTYPE\": \"x86_64\",\n    \"LOGNAME\": \"nodeuser\",\n    \"XDG_DATA_DIRS\": \"/opt/rh/devtoolset-3/root/usr/share:/usr/local/share:/usr/share\",\n    \"LESSOPEN\": \"||/usr/bin/lesspipe.sh %s\",\n    \"INFOPATH\": \"/opt/rh/devtoolset-3/root/usr/share/info\",\n    \"XDG_RUNTIME_DIR\": \"/run/user/50141\",\n    \"_\": \"./node\"\n  },\n  \"userLimits\": {\n    \"core_file_size_blocks\": {\n      \"soft\": \"\",\n      \"hard\": \"unlimited\"\n    },\n    \"data_seg_size_kbytes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    },\n    \"file_size_blocks\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    },\n    \"max_locked_memory_bytes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": 65536\n    },\n    \"max_memory_size_kbytes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    },\n    \"open_files\": {\n      \"soft\": \"unlimited\",\n      \"hard\": 4096\n    },\n    \"stack_size_bytes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    },\n    \"cpu_time_seconds\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    },\n    \"max_user_processes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": 4127290\n    },\n    \"virtual_memory_kbytes\": {\n      \"soft\": \"unlimited\",\n      \"hard\": \"unlimited\"\n    }\n  },\n  \"sharedObjects\": [\n    \"/lib64/libdl.so.2\",\n    \"/lib64/librt.so.1\",\n    \"/lib64/libstdc++.so.6\",\n    \"/lib64/libm.so.6\",\n    \"/lib64/libgcc_s.so.1\",\n    \"/lib64/libpthread.so.0\",\n    \"/lib64/libc.so.6\",\n    \"/lib64/ld-linux-x86-64.so.2\"\n  ]\n}\n
      ", "miscs": [ { "textRaw": "Usage", "name": "usage", - "desc": "
      node --report-uncaught-exception --report-on-signal \\\n--report-on-fatalerror app.js\n
      \n
        \n
      • \n

        --report-uncaught-exception Enables report to be generated on\nun-caught exceptions. Useful when inspecting JavaScript stack in conjunction\nwith native stack and other runtime environment data.

        \n
      • \n
      • \n

        --report-on-signal Enables report to be generated upon receiving\nthe specified (or predefined) signal to the running Node.js process. (See below\non how to modify the signal that triggers the report.) Default signal is SIGUSR2.\nUseful when a report needs to be triggered from another program.\nApplication monitors may leverage this feature to collect report at regular\nintervals and plot rich set of internal runtime data to their views.

        \n
      • \n
      \n

      Signal based report generation is not supported in Windows.

      \n

      Under normal circumstances, there is no need to modify the report triggering\nsignal. However, if SIGUSR2 is already used for other purposes, then this\nflag helps to change the signal for report generation and preserve the original\nmeaning of SIGUSR2 for the said purposes.

      \n
        \n
      • \n

        --report-on-fatalerror Enables the report to be triggered on\nfatal errors (internal errors within the Node.js runtime, such as out of memory)\nthat leads to termination of the application. Useful to inspect various\ndiagnostic data elements such as heap, stack, event loop state, resource\nconsumption etc. to reason about the fatal error.

        \n
      • \n
      • \n

        --report-compact Write reports in a compact format, single-line JSON, more\neasily consumable by log processing systems than the default multi-line format\ndesigned for human consumption.

        \n
      • \n
      • \n

        --report-directory Location at which the report will be\ngenerated.

        \n
      • \n
      • \n

        --report-filename Name of the file to which the report will be\nwritten.

        \n
      • \n
      • \n

        --report-signal Sets or resets the signal for report generation\n(not supported on Windows). Default signal is SIGUSR2.

        \n
      • \n
      \n

      A report can also be triggered via an API call from a JavaScript application:

      \n
      process.report.writeReport();\n
      \n

      This function takes an optional additional argument filename, which is\nthe name of a file into which the report is written.

      \n
      process.report.writeReport('./foo.json');\n
      \n

      This function takes an optional additional argument err which is an Error\nobject that will be used as the context for the JavaScript stack printed in the\nreport. When using report to handle errors in a callback or an exception\nhandler, this allows the report to include the location of the original error as\nwell as where it was handled.

      \n
      try {\n  process.chdir('/non-existent-path');\n} catch (err) {\n  process.report.writeReport(err);\n}\n// Any other code\n
      \n

      If both filename and error object are passed to writeReport() the\nerror object must be the second parameter.

      \n
      try {\n  process.chdir('/non-existent-path');\n} catch (err) {\n  process.report.writeReport(filename, err);\n}\n// Any other code\n
      \n

      The content of the diagnostic report can be returned as a JavaScript Object\nvia an API call from a JavaScript application:

      \n
      const report = process.report.getReport();\nconsole.log(typeof report === 'object'); // true\n\n// Similar to process.report.writeReport() output\nconsole.log(JSON.stringify(report, null, 2));\n
      \n

      This function takes an optional additional argument err, which is an Error\nobject that will be used as the context for the JavaScript stack printed in the\nreport.

      \n
      const report = process.report.getReport(new Error('custom error'));\nconsole.log(typeof report === 'object'); // true\n
      \n

      The API versions are useful when inspecting the runtime state from within\nthe application, in expectation of self-adjusting the resource consumption,\nload balancing, monitoring etc.

      \n

      The content of the report consists of a header section containing the event\ntype, date, time, PID and Node.js version, sections containing JavaScript and\nnative stack traces, a section containing V8 heap information, a section\ncontaining libuv handle information and an OS platform information section\nshowing CPU and memory usage and system limits. An example report can be\ntriggered using the Node.js REPL:

      \n
      $ node\n> process.report.writeReport();\nWriting Node.js report to file: report.20181126.091102.8480.0.001.json\nNode.js report completed\n>\n
      \n

      When a report is written, start and end messages are issued to stderr\nand the filename of the report is returned to the caller. The default filename\nincludes the date, time, PID and a sequence number. The sequence number helps\nin associating the report dump with the runtime state if generated multiple\ntimes for the same Node.js process.

      ", + "desc": "
      node --report-uncaught-exception --report-on-signal \\\n--report-on-fatalerror app.js\n
      \n
        \n
      • \n

        --report-uncaught-exception Enables report to be generated on\nun-caught exceptions. Useful when inspecting JavaScript stack in conjunction\nwith native stack and other runtime environment data.

        \n
      • \n
      • \n

        --report-on-signal Enables report to be generated upon receiving\nthe specified (or predefined) signal to the running Node.js process. (See\nbelow on how to modify the signal that triggers the report.) Default signal is\nSIGUSR2. Useful when a report needs to be triggered from another program.\nApplication monitors may leverage this feature to collect report at regular\nintervals and plot rich set of internal runtime data to their views.

        \n
      • \n
      \n

      Signal based report generation is not supported in Windows.

      \n

      Under normal circumstances, there is no need to modify the report triggering\nsignal. However, if SIGUSR2 is already used for other purposes, then this\nflag helps to change the signal for report generation and preserve the original\nmeaning of SIGUSR2 for the said purposes.

      \n
        \n
      • \n

        --report-on-fatalerror Enables the report to be triggered on fatal errors\n(internal errors within the Node.js runtime, such as out of memory)\nthat leads to termination of the application. Useful to inspect various\ndiagnostic data elements such as heap, stack, event loop state, resource\nconsumption etc. to reason about the fatal error.

        \n
      • \n
      • \n

        --report-compact Write reports in a compact format, single-line JSON, more\neasily consumable by log processing systems than the default multi-line format\ndesigned for human consumption.

        \n
      • \n
      • \n

        --report-directory Location at which the report will be\ngenerated.

        \n
      • \n
      • \n

        --report-filename Name of the file to which the report will be\nwritten.

        \n
      • \n
      • \n

        --report-signal Sets or resets the signal for report generation\n(not supported on Windows). Default signal is SIGUSR2.

        \n
      • \n
      \n

      A report can also be triggered via an API call from a JavaScript application:

      \n
      process.report.writeReport();\n
      \n

      This function takes an optional additional argument filename, which is\nthe name of a file into which the report is written.

      \n
      process.report.writeReport('./foo.json');\n
      \n

      This function takes an optional additional argument err which is an Error\nobject that will be used as the context for the JavaScript stack printed in the\nreport. When using report to handle errors in a callback or an exception\nhandler, this allows the report to include the location of the original error as\nwell as where it was handled.

      \n
      try {\n  process.chdir('/non-existent-path');\n} catch (err) {\n  process.report.writeReport(err);\n}\n// Any other code\n
      \n

      If both filename and error object are passed to writeReport() the\nerror object must be the second parameter.

      \n
      try {\n  process.chdir('/non-existent-path');\n} catch (err) {\n  process.report.writeReport(filename, err);\n}\n// Any other code\n
      \n

      The content of the diagnostic report can be returned as a JavaScript Object\nvia an API call from a JavaScript application:

      \n
      const report = process.report.getReport();\nconsole.log(typeof report === 'object'); // true\n\n// Similar to process.report.writeReport() output\nconsole.log(JSON.stringify(report, null, 2));\n
      \n

      This function takes an optional additional argument err, which is an Error\nobject that will be used as the context for the JavaScript stack printed in the\nreport.

      \n
      const report = process.report.getReport(new Error('custom error'));\nconsole.log(typeof report === 'object'); // true\n
      \n

      The API versions are useful when inspecting the runtime state from within\nthe application, in expectation of self-adjusting the resource consumption,\nload balancing, monitoring etc.

      \n

      The content of the report consists of a header section containing the event\ntype, date, time, PID and Node.js version, sections containing JavaScript and\nnative stack traces, a section containing V8 heap information, a section\ncontaining libuv handle information and an OS platform information section\nshowing CPU and memory usage and system limits. An example report can be\ntriggered using the Node.js REPL:

      \n
      $ node\n> process.report.writeReport();\nWriting Node.js report to file: report.20181126.091102.8480.0.001.json\nNode.js report completed\n>\n
      \n

      When a report is written, start and end messages are issued to stderr\nand the filename of the report is returned to the caller. The default filename\nincludes the date, time, PID and a sequence number. The sequence number helps\nin associating the report dump with the runtime state if generated multiple\ntimes for the same Node.js process.

      ", "type": "misc", "displayName": "Usage" }, @@ -34,7 +34,10 @@ "meta": { "changes": [ { - "version": "v12.16.2", + "version": [ + "v13.9.0", + "v12.16.2" + ], "pr-url": "https://github.com/nodejs/node/pull/31386", "description": "Workers are now included in the report." } diff --git a/doc/api/report.md b/doc/api/report.md index da96ba28cb29bcbaa7159af0a106b2080114d033..accf3ca21044fd970ae3c337e43da740e8895974 100644 --- a/doc/api/report.md +++ b/doc/api/report.md @@ -52,7 +52,6 @@ is provided below for reference. "nghttp2": "1.34.0", "napi": "3", "llhttp": "1.0.1", - "http_parser": "2.8.0", "openssl": "1.1.0j" }, "release": { @@ -293,7 +292,8 @@ is provided below for reference. { "type": "loop", "is_active": true, - "address": "0x000055fc7b2cb180" + "address": "0x000055fc7b2cb180", + "loopIdleTimeSeconds": 22644.8 } ], "workers": [], @@ -397,15 +397,15 @@ node --report-uncaught-exception --report-on-signal \ ``` * `--report-uncaught-exception` Enables report to be generated on -un-caught exceptions. Useful when inspecting JavaScript stack in conjunction -with native stack and other runtime environment data. + un-caught exceptions. Useful when inspecting JavaScript stack in conjunction + with native stack and other runtime environment data. * `--report-on-signal` Enables report to be generated upon receiving -the specified (or predefined) signal to the running Node.js process. (See below -on how to modify the signal that triggers the report.) Default signal is `SIGUSR2`. -Useful when a report needs to be triggered from another program. -Application monitors may leverage this feature to collect report at regular -intervals and plot rich set of internal runtime data to their views. + the specified (or predefined) signal to the running Node.js process. (See + below on how to modify the signal that triggers the report.) Default signal is + `SIGUSR2`. Useful when a report needs to be triggered from another program. + Application monitors may leverage this feature to collect report at regular + intervals and plot rich set of internal runtime data to their views. Signal based report generation is not supported in Windows. @@ -414,24 +414,24 @@ signal. However, if `SIGUSR2` is already used for other purposes, then this flag helps to change the signal for report generation and preserve the original meaning of `SIGUSR2` for the said purposes. -* `--report-on-fatalerror` Enables the report to be triggered on -fatal errors (internal errors within the Node.js runtime, such as out of memory) -that leads to termination of the application. Useful to inspect various -diagnostic data elements such as heap, stack, event loop state, resource -consumption etc. to reason about the fatal error. +* `--report-on-fatalerror` Enables the report to be triggered on fatal errors + (internal errors within the Node.js runtime, such as out of memory) + that leads to termination of the application. Useful to inspect various + diagnostic data elements such as heap, stack, event loop state, resource + consumption etc. to reason about the fatal error. * `--report-compact` Write reports in a compact format, single-line JSON, more -easily consumable by log processing systems than the default multi-line format -designed for human consumption. + easily consumable by log processing systems than the default multi-line format + designed for human consumption. * `--report-directory` Location at which the report will be -generated. + generated. * `--report-filename` Name of the file to which the report will be -written. + written. * `--report-signal` Sets or resets the signal for report generation -(not supported on Windows). Default signal is `SIGUSR2`. + (not supported on Windows). Default signal is `SIGUSR2`. A report can also be triggered via an API call from a JavaScript application: @@ -581,7 +581,9 @@ Specific API documentation can be found under ## Interaction with workers @@ -597,5 +599,5 @@ The thread which is generating the report will wait for the reports from Worker threads to finish. However, the latency for this will usually be low, as both running JavaScript and the event loop are interrupted to generate the report. -[`process API documentation`]: process.html -[`Worker`]: worker_threads.html +[`Worker`]: worker_threads.md +[`process API documentation`]: process.md diff --git a/doc/api/stream.html b/doc/api/stream.html index fb8d33a0ed8ee12769c51537f1c2858edecf3638..408ac9f09ea8b4eebebdbc22cff578a9cc541892 100644 --- a/doc/api/stream.html +++ b/doc/api/stream.html @@ -1,10 +1,10 @@ - + - - Stream | Node.js v12.22.7 Documentation + + Stream | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      + diff --git a/doc/api/url.json b/doc/api/url.json index f7df7e6bf0454b757344c090bc5605c9d79312ac..e1aaeb273991a2d2846074c32ad29bad6790d823 100644 --- a/doc/api/url.json +++ b/doc/api/url.json @@ -8,12 +8,21 @@ "introduced_in": "v0.10.0", "stability": 2, "stabilityText": "Stable", - "desc": "

      Source Code: lib/url.js

      \n

      The url module provides utilities for URL resolution and parsing. It can be\naccessed using:

      \n
      const url = require('url');\n
      ", + "desc": "

      Source Code: lib/url.js

      \n

      The url module provides utilities for URL resolution and parsing. It can be\naccessed using:

      \n
      const url = require('url');\n
      ", "modules": [ { "textRaw": "URL strings and URL objects", "name": "url_strings_and_url_objects", - "desc": "

      A URL string is a structured string containing multiple meaningful components.\nWhen parsed, a URL object is returned containing properties for each of these\ncomponents.

      \n

      The url module provides two APIs for working with URLs: a legacy API that is\nNode.js specific, and a newer API that implements the same\nWHATWG URL Standard used by web browsers.

      \n

      A comparison between the WHATWG and Legacy APIs is provided below. Above the URL\n'http://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash', properties\nof an object returned by the legacy url.parse() are shown. Below it are\nproperties of a WHATWG URL object.

      \n

      WHATWG URL's origin property includes protocol and host, but not\nusername or password.

      \n
      ┌────────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                              href                                              │\n├──────────┬──┬─────────────────────┬────────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │          host          │           path            │ hash  │\n│          │  │                     ├─────────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │    hostname     │ port │ pathname │     search     │       │\n│          │  │                     │                 │      │          ├─┬──────────────┤       │\n│          │  │                     │                 │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.example.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │    hostname     │ port │          │                │       │\n│          │  │          │          ├─────────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │          host          │          │                │       │\n├──────────┴──┼──────────┴──────────┼────────────────────────┤          │                │       │\n│   origin    │                     │         origin         │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴────────────────────────┴──────────┴────────────────┴───────┤\n│                                              href                                              │\n└────────────────────────────────────────────────────────────────────────────────────────────────┘\n(All spaces in the \"\" line should be ignored. They are purely for formatting.)\n
      \n

      Parsing the URL string using the WHATWG API:

      \n
      const myURL =\n  new URL('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');\n
      \n

      Parsing the URL string using the Legacy API:

      \n
      const url = require('url');\nconst myURL =\n  url.parse('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');\n
      ", + "desc": "

      A URL string is a structured string containing multiple meaningful components.\nWhen parsed, a URL object is returned containing properties for each of these\ncomponents.

      \n

      The url module provides two APIs for working with URLs: a legacy API that is\nNode.js specific, and a newer API that implements the same\nWHATWG URL Standard used by web browsers.

      \n

      A comparison between the WHATWG and Legacy APIs is provided below. Above the URL\n'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash', properties\nof an object returned by the legacy url.parse() are shown. Below it are\nproperties of a WHATWG URL object.

      \n

      WHATWG URL's origin property includes protocol and host, but not\nusername or password.

      \n
      ┌────────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                              href                                              │\n├──────────┬──┬─────────────────────┬────────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │          host          │           path            │ hash  │\n│          │  │                     ├─────────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │    hostname     │ port │ pathname │     search     │       │\n│          │  │                     │                 │      │          ├─┬──────────────┤       │\n│          │  │                     │                 │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.example.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │    hostname     │ port │          │                │       │\n│          │  │          │          ├─────────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │          host          │          │                │       │\n├──────────┴──┼──────────┴──────────┼────────────────────────┤          │                │       │\n│   origin    │                     │         origin         │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴────────────────────────┴──────────┴────────────────┴───────┤\n│                                              href                                              │\n└────────────────────────────────────────────────────────────────────────────────────────────────┘\n(All spaces in the \"\" line should be ignored. They are purely for formatting.)\n
      \n

      Parsing the URL string using the WHATWG API:

      \n
      const myURL =\n  new URL('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');\n
      \n

      Parsing the URL string using the Legacy API:

      \n
      const url = require('url');\nconst myURL =\n  url.parse('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');\n
      ", + "modules": [ + { + "textRaw": "Constructing a URL from component parts and getting the constructed string", + "name": "constructing_a_url_from_component_parts_and_getting_the_constructed_string", + "desc": "

      It is possible to construct a WHATWG URL from component parts using either the\nproperty setters or a template literal string:

      \n
      const myURL = new URL('https://example.org');\nmyURL.pathname = '/a/b/c';\nmyURL.search = '?d=e';\nmyURL.hash = '#fgh';\n
      \n
      const pathname = '/a/b/c';\nconst search = '?d=e';\nconst hash = '#fgh';\nconst myURL = new URL(`https://example.org${pathname}${search}${hash}`);\n
      \n

      To get the constructed URL string, use the href property accessor:

      \n
      console.log(myURL.href);\n
      ", + "type": "module", + "displayName": "Constructing a URL from component parts and getting the constructed string" + } + ], "type": "module", "displayName": "URL strings and URL objects" }, @@ -56,7 +65,7 @@ "textRaw": "`hostname` {string}", "type": "string", "name": "hostname", - "desc": "

      Gets and sets the host name portion of the URL. The key difference between\nurl.host and url.hostname is that url.hostname does not include the\nport.

      \n
      const myURL = new URL('https://example.org:81/foo');\nconsole.log(myURL.hostname);\n// Prints example.org\n\nmyURL.hostname = 'example.com:82';\nconsole.log(myURL.href);\n// Prints https://example.com:81/foo\n
      \n

      Invalid host name values assigned to the hostname property are ignored.

      " + "desc": "

      Gets and sets the host name portion of the URL. The key difference between\nurl.host and url.hostname is that url.hostname does not include the\nport.

      \n
      const myURL = new URL('https://example.org:81/foo');\nconsole.log(myURL.hostname);\n// Prints example.org\n\n// Setting the hostname does not change the port\nmyURL.hostname = 'example.com:82';\nconsole.log(myURL.href);\n// Prints https://example.com:81/foo\n\n// Use myURL.host to change the hostname and port\nmyURL.host = 'example.org:82';\nconsole.log(myURL.href);\n// Prints https://example.org:82/foo\n
      \n

      Invalid host name values assigned to the hostname property are ignored.

      " }, { "textRaw": "`href` {string}", @@ -153,7 +162,7 @@ "params": [] } ], - "desc": "

      The toJSON() method on the URL object returns the serialized URL. The\nvalue returned is equivalent to that of url.href and\nurl.toString().

      \n

      This method is automatically called when an URL object is serialized\nwith JSON.stringify().

      \n
      const myURLs = [\n  new URL('https://www.example.com'),\n  new URL('https://test.example.org')\n];\nconsole.log(JSON.stringify(myURLs));\n// Prints [\"https://www.example.com/\",\"https://test.example.org/\"]\n
      " + "desc": "

      The toJSON() method on the URL object returns the serialized URL. The\nvalue returned is equivalent to that of url.href and\nurl.toString().

      \n

      This method is automatically called when an URL object is serialized\nwith JSON.stringify().

      \n
      const myURLs = [\n  new URL('https://www.example.com'),\n  new URL('https://test.example.org'),\n];\nconsole.log(JSON.stringify(myURLs));\n// Prints [\"https://www.example.com/\",\"https://test.example.org/\"]\n
      " } ], "signatures": [ @@ -482,7 +491,7 @@ "desc": "An iterable object whose elements are key-value pairs" } ], - "desc": "

      Instantiate a new URLSearchParams object with an iterable map in a way that\nis similar to Map's constructor. iterable can be an Array or any\niterable object. That means iterable can be another URLSearchParams, in\nwhich case the constructor will simply create a clone of the provided\nURLSearchParams. Elements of iterable are key-value pairs, and can\nthemselves be any iterable object.

      \n

      Duplicate keys are allowed.

      \n
      let params;\n\n// Using an array\nparams = new URLSearchParams([\n  ['user', 'abc'],\n  ['query', 'first'],\n  ['query', 'second']\n]);\nconsole.log(params.toString());\n// Prints 'user=abc&query=first&query=second'\n\n// Using a Map object\nconst map = new Map();\nmap.set('user', 'abc');\nmap.set('query', 'xyz');\nparams = new URLSearchParams(map);\nconsole.log(params.toString());\n// Prints 'user=abc&query=xyz'\n\n// Using a generator function\nfunction* getQueryPairs() {\n  yield ['user', 'abc'];\n  yield ['query', 'first'];\n  yield ['query', 'second'];\n}\nparams = new URLSearchParams(getQueryPairs());\nconsole.log(params.toString());\n// Prints 'user=abc&query=first&query=second'\n\n// Each key-value pair must have exactly two elements\nnew URLSearchParams([\n  ['user', 'abc', 'error']\n]);\n// Throws TypeError [ERR_INVALID_TUPLE]:\n//        Each query pair must be an iterable [name, value] tuple\n
      " + "desc": "

      Instantiate a new URLSearchParams object with an iterable map in a way that\nis similar to Map's constructor. iterable can be an Array or any\niterable object. That means iterable can be another URLSearchParams, in\nwhich case the constructor will simply create a clone of the provided\nURLSearchParams. Elements of iterable are key-value pairs, and can\nthemselves be any iterable object.

      \n

      Duplicate keys are allowed.

      \n
      let params;\n\n// Using an array\nparams = new URLSearchParams([\n  ['user', 'abc'],\n  ['query', 'first'],\n  ['query', 'second'],\n]);\nconsole.log(params.toString());\n// Prints 'user=abc&query=first&query=second'\n\n// Using a Map object\nconst map = new Map();\nmap.set('user', 'abc');\nmap.set('query', 'xyz');\nparams = new URLSearchParams(map);\nconsole.log(params.toString());\n// Prints 'user=abc&query=xyz'\n\n// Using a generator function\nfunction* getQueryPairs() {\n  yield ['user', 'abc'];\n  yield ['query', 'first'];\n  yield ['query', 'second'];\n}\nparams = new URLSearchParams(getQueryPairs());\nconsole.log(params.toString());\n// Prints 'user=abc&query=first&query=second'\n\n// Each key-value pair must have exactly two elements\nnew URLSearchParams([\n  ['user', 'abc', 'error'],\n]);\n// Throws TypeError [ERR_INVALID_TUPLE]:\n//        Each query pair must be an iterable [name, value] tuple\n
      " } ] } @@ -515,7 +524,7 @@ ] } ], - "desc": "

      Returns the Punycode ASCII serialization of the domain. If domain is an\ninvalid domain, the empty string is returned.

      \n

      It performs the inverse operation to url.domainToUnicode().

      \n
      const url = require('url');\nconsole.log(url.domainToASCII('español.com'));\n// Prints xn--espaol-zwa.com\nconsole.log(url.domainToASCII('中文.com'));\n// Prints xn--fiq228c.com\nconsole.log(url.domainToASCII('xn--iñvalid.com'));\n// Prints an empty string\n
      " + "desc": "

      Returns the Punycode ASCII serialization of the domain. If domain is an\ninvalid domain, the empty string is returned.

      \n

      It performs the inverse operation to url.domainToUnicode().

      \n

      This feature is only available if the node executable was compiled with\nICU enabled. If not, the domain names are passed through unchanged.

      \n
      const url = require('url');\nconsole.log(url.domainToASCII('español.com'));\n// Prints xn--espaol-zwa.com\nconsole.log(url.domainToASCII('中文.com'));\n// Prints xn--fiq228c.com\nconsole.log(url.domainToASCII('xn--iñvalid.com'));\n// Prints an empty string\n
      " }, { "textRaw": "`url.domainToUnicode(domain)`", @@ -544,7 +553,7 @@ ] } ], - "desc": "

      Returns the Unicode serialization of the domain. If domain is an invalid\ndomain, the empty string is returned.

      \n

      It performs the inverse operation to url.domainToASCII().

      \n
      const url = require('url');\nconsole.log(url.domainToUnicode('xn--espaol-zwa.com'));\n// Prints español.com\nconsole.log(url.domainToUnicode('xn--fiq228c.com'));\n// Prints 中文.com\nconsole.log(url.domainToUnicode('xn--iñvalid.com'));\n// Prints an empty string\n
      " + "desc": "

      Returns the Unicode serialization of the domain. If domain is an invalid\ndomain, the empty string is returned.

      \n

      It performs the inverse operation to url.domainToASCII().

      \n

      This feature is only available if the node executable was compiled with\nICU enabled. If not, the domain names are passed through unchanged.

      \n
      const url = require('url');\nconsole.log(url.domainToUnicode('xn--espaol-zwa.com'));\n// Prints español.com\nconsole.log(url.domainToUnicode('xn--fiq228c.com'));\n// Prints 中文.com\nconsole.log(url.domainToUnicode('xn--iñvalid.com'));\n// Prints an empty string\n
      " }, { "textRaw": "`url.fileURLToPath(url)`", @@ -574,7 +583,7 @@ ] } ], - "desc": "

      This function ensures the correct decodings of percent-encoded characters as\nwell as ensuring a cross-platform valid absolute path string.

      \n
      new URL('file:///C:/path/').pathname;    // Incorrect: /C:/path/\nfileURLToPath('file:///C:/path/');       // Correct:   C:\\path\\ (Windows)\n\nnew URL('file://nas/foo.txt').pathname;  // Incorrect: /foo.txt\nfileURLToPath('file://nas/foo.txt');     // Correct:   \\\\nas\\foo.txt (Windows)\n\nnew URL('file:///你好.txt').pathname;    // Incorrect: /%E4%BD%A0%E5%A5%BD.txt\nfileURLToPath('file:///你好.txt');       // Correct:   /你好.txt (POSIX)\n\nnew URL('file:///hello world').pathname; // Incorrect: /hello%20world\nfileURLToPath('file:///hello world');    // Correct:   /hello world (POSIX)\n
      " + "desc": "

      This function ensures the correct decodings of percent-encoded characters as\nwell as ensuring a cross-platform valid absolute path string.

      \n
      import { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\n\nnew URL('file:///C:/path/').pathname;      // Incorrect: /C:/path/\nfileURLToPath('file:///C:/path/');         // Correct:   C:\\path\\ (Windows)\n\nnew URL('file://nas/foo.txt').pathname;    // Incorrect: /foo.txt\nfileURLToPath('file://nas/foo.txt');       // Correct:   \\\\nas\\foo.txt (Windows)\n\nnew URL('file:///你好.txt').pathname;      // Incorrect: /%E4%BD%A0%E5%A5%BD.txt\nfileURLToPath('file:///你好.txt');         // Correct:   /你好.txt (POSIX)\n\nnew URL('file:///hello world').pathname;   // Incorrect: /hello%20world\nfileURLToPath('file:///hello world');      // Correct:   /hello world (POSIX)\n
      \n
      const { fileURLToPath } = require('url');\nnew URL('file:///C:/path/').pathname;      // Incorrect: /C:/path/\nfileURLToPath('file:///C:/path/');         // Correct:   C:\\path\\ (Windows)\n\nnew URL('file://nas/foo.txt').pathname;    // Incorrect: /foo.txt\nfileURLToPath('file://nas/foo.txt');       // Correct:   \\\\nas\\foo.txt (Windows)\n\nnew URL('file:///你好.txt').pathname;      // Incorrect: /%E4%BD%A0%E5%A5%BD.txt\nfileURLToPath('file:///你好.txt');         // Correct:   /你好.txt (POSIX)\n\nnew URL('file:///hello world').pathname;   // Incorrect: /hello%20world\nfileURLToPath('file:///hello world');      // Correct:   /hello world (POSIX)\n
      " }, { "textRaw": "`url.format(URL[, options])`", @@ -638,7 +647,7 @@ ] } ], - "desc": "

      Returns a customizable serialization of a URL String representation of a\nWHATWG URL object.

      \n

      The URL object has both a toString() method and href property that return\nstring serializations of the URL. These are not, however, customizable in\nany way. The url.format(URL[, options]) method allows for basic customization\nof the output.

      \n
      const myURL = new URL('https://a:b@測試?abc#foo');\n\nconsole.log(myURL.href);\n// Prints https://a:b@xn--g6w251d/?abc#foo\n\nconsole.log(myURL.toString());\n// Prints https://a:b@xn--g6w251d/?abc#foo\n\nconsole.log(url.format(myURL, { fragment: false, unicode: true, auth: false }));\n// Prints 'https://測試/?abc'\n
      " + "desc": "

      Returns a customizable serialization of a URL String representation of a\nWHATWG URL object.

      \n

      The URL object has both a toString() method and href property that return\nstring serializations of the URL. These are not, however, customizable in\nany way. The url.format(URL[, options]) method allows for basic customization\nof the output.

      \n
      import url from 'url';\nconst myURL = new URL('https://a:b@測試?abc#foo');\n\nconsole.log(myURL.href);\n// Prints https://a:b@xn--g6w251d/?abc#foo\n\nconsole.log(myURL.toString());\n// Prints https://a:b@xn--g6w251d/?abc#foo\n\nconsole.log(url.format(myURL, { fragment: false, unicode: true, auth: false }));\n// Prints 'https://測試/?abc'\n
      \n
      const url = require('url');\nconst myURL = new URL('https://a:b@測試?abc#foo');\n\nconsole.log(myURL.href);\n// Prints https://a:b@xn--g6w251d/?abc#foo\n\nconsole.log(myURL.toString());\n// Prints https://a:b@xn--g6w251d/?abc#foo\n\nconsole.log(url.format(myURL, { fragment: false, unicode: true, auth: false }));\n// Prints 'https://測試/?abc'\n
      " }, { "textRaw": "`url.pathToFileURL(path)`", @@ -668,7 +677,93 @@ ] } ], - "desc": "

      This function ensures that path is resolved absolutely, and that the URL\ncontrol characters are correctly encoded when converting into a File URL.

      \n
      new URL(__filename);                // Incorrect: throws (POSIX)\nnew URL(__filename);                // Incorrect: C:\\... (Windows)\npathToFileURL(__filename);          // Correct:   file:///... (POSIX)\npathToFileURL(__filename);          // Correct:   file:///C:/... (Windows)\n\nnew URL('/foo#1', 'file:');         // Incorrect: file:///foo#1\npathToFileURL('/foo#1');            // Correct:   file:///foo%231 (POSIX)\n\nnew URL('/some/path%.c', 'file:'); // Incorrect: file:///some/path%.c\npathToFileURL('/some/path%.c');    // Correct:   file:///some/path%25.c (POSIX)\n
      " + "desc": "

      This function ensures that path is resolved absolutely, and that the URL\ncontrol characters are correctly encoded when converting into a File URL.

      \n
      import { pathToFileURL } from 'url';\n\nnew URL('/foo#1', 'file:');           // Incorrect: file:///foo#1\npathToFileURL('/foo#1');              // Correct:   file:///foo%231 (POSIX)\n\nnew URL('/some/path%.c', 'file:');    // Incorrect: file:///some/path%.c\npathToFileURL('/some/path%.c');       // Correct:   file:///some/path%25.c (POSIX)\n
      \n
      const { pathToFileURL } = require('url');\nnew URL(__filename);                  // Incorrect: throws (POSIX)\nnew URL(__filename);                  // Incorrect: C:\\... (Windows)\npathToFileURL(__filename);            // Correct:   file:///... (POSIX)\npathToFileURL(__filename);            // Correct:   file:///C:/... (Windows)\n\nnew URL('/foo#1', 'file:');           // Incorrect: file:///foo#1\npathToFileURL('/foo#1');              // Correct:   file:///foo%231 (POSIX)\n\nnew URL('/some/path%.c', 'file:');    // Incorrect: file:///some/path%.c\npathToFileURL('/some/path%.c');       // Correct:   file:///some/path%25.c (POSIX)\n
      " + }, + { + "textRaw": "`url.urlToHttpOptions(url)`", + "type": "method", + "name": "urlToHttpOptions", + "meta": { + "added": [ + "v14.18.0" + ], + "changes": [] + }, + "signatures": [ + { + "return": { + "textRaw": "Returns: {Object} Options object", + "name": "return", + "type": "Object", + "desc": "Options object", + "options": [ + { + "textRaw": "`protocol` {string} Protocol to use.", + "name": "protocol", + "type": "string", + "desc": "Protocol to use." + }, + { + "textRaw": "`hostname` {string} A domain name or IP address of the server to issue the request to.", + "name": "hostname", + "type": "string", + "desc": "A domain name or IP address of the server to issue the request to." + }, + { + "textRaw": "`hash` {string} The fragment portion of the URL.", + "name": "hash", + "type": "string", + "desc": "The fragment portion of the URL." + }, + { + "textRaw": "`search` {string} The serialized query portion of the URL.", + "name": "search", + "type": "string", + "desc": "The serialized query portion of the URL." + }, + { + "textRaw": "`pathname` {string} The path portion of the URL.", + "name": "pathname", + "type": "string", + "desc": "The path portion of the URL." + }, + { + "textRaw": "`path` {string} Request path. Should include query string if any. E.G. `'/index.html?page=12'`. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future.", + "name": "path", + "type": "string", + "desc": "Request path. Should include query string if any. E.G. `'/index.html?page=12'`. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future." + }, + { + "textRaw": "`href` {string} The serialized URL.", + "name": "href", + "type": "string", + "desc": "The serialized URL." + }, + { + "textRaw": "`port` {number} Port of remote server.", + "name": "port", + "type": "number", + "desc": "Port of remote server." + }, + { + "textRaw": "`auth` {string} Basic authentication i.e. `'user:password'` to compute an Authorization header.", + "name": "auth", + "type": "string", + "desc": "Basic authentication i.e. `'user:password'` to compute an Authorization header." + } + ] + }, + "params": [ + { + "textRaw": "`url` {URL} The [WHATWG URL][] object to convert to an options object.", + "name": "url", + "type": "URL", + "desc": "The [WHATWG URL][] object to convert to an options object." + } + ] + } + ], + "desc": "

      This utility function converts a URL object into an ordinary options object as\nexpected by the http.request() and https.request() APIs.

      \n
      const { urlToHttpOptions } = require('url');\nconst myURL = new URL('https://a:b@測試?abc#foo');\n\nconsole.log(urlToHttpOptions(myUrl));\n/**\n{\n  protocol: 'https:',\n  hostname: 'xn--g6w251d',\n  hash: '#foo',\n  search: '?abc',\n  pathname: '/',\n  path: '/?abc',\n  href: 'https://a:b@xn--g6w251d/?abc#foo',\n  auth: 'a:b'\n}\n*/\n
      " } ], "type": "module", @@ -678,17 +773,32 @@ "textRaw": "Legacy URL API", "name": "legacy_url_api", "meta": { - "deprecated": [ - "v11.0.0" - ], - "changes": [] + "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/37784", + "description": "Deprecation revoked. Status changed to \"Legacy\"." + }, + { + "version": "v11.0.0", + "pr-url": "https://github.com/nodejs/node/pull/22715", + "description": "This API is deprecated." + } + ] }, + "stability": 3, + "stabilityText": "Legacy: Use the WHATWG URL API instead.", "modules": [ { "textRaw": "Legacy `urlObject`", "name": "legacy_`urlobject`", "meta": { "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/37784", + "description": "Deprecation revoked. Status changed to \"Legacy\"." + }, { "version": "v11.0.0", "pr-url": "https://github.com/nodejs/node/pull/22715", @@ -696,8 +806,8 @@ } ] }, - "stability": 0, - "stabilityText": "Deprecated: Use the WHATWG URL API instead.", + "stability": 3, + "stabilityText": "Legacy: Use the WHATWG URL API instead.", "desc": "

      The legacy urlObject (require('url').Url) is created and returned by the\nurl.parse() function.

      ", "properties": [ { @@ -775,6 +885,11 @@ "v0.1.25" ], "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/37784", + "description": "Deprecation revoked. Status changed to \"Legacy\"." + }, { "version": "v11.0.0", "pr-url": "https://github.com/nodejs/node/pull/22715", @@ -787,8 +902,8 @@ } ] }, - "stability": 0, - "stabilityText": "Deprecated: Use the WHATWG URL API instead.", + "stability": 3, + "stabilityText": "Legacy: Use the WHATWG URL API instead.", "signatures": [ { "params": [ @@ -801,7 +916,7 @@ ] } ], - "desc": "

      The url.format() method returns a formatted URL string derived from\nurlObject.

      \n
      url.format({\n  protocol: 'https',\n  hostname: 'example.com',\n  pathname: '/some/path',\n  query: {\n    page: 1,\n    format: 'json'\n  }\n});\n\n// => 'https://example.com/some/path?page=1&format=json'\n
      \n

      If urlObject is not an object or a string, url.format() will throw a\nTypeError.

      \n

      The formatting process operates as follows:

      \n
        \n
      • A new empty string result is created.
      • \n
      • If urlObject.protocol is a string, it is appended as-is to result.
      • \n
      • Otherwise, if urlObject.protocol is not undefined and is not a string, an\nError is thrown.
      • \n
      • For all string values of urlObject.protocol that do not end with an ASCII\ncolon (:) character, the literal string : will be appended to result.
      • \n
      • If either of the following conditions is true, then the literal string //\nwill be appended to result:\n
          \n
        • urlObject.slashes property is true;
        • \n
        • urlObject.protocol begins with http, https, ftp, gopher, or\nfile;
        • \n
        \n
      • \n
      • If the value of the urlObject.auth property is truthy, and either\nurlObject.host or urlObject.hostname are not undefined, the value of\nurlObject.auth will be coerced into a string and appended to result\nfollowed by the literal string @.
      • \n
      • If the urlObject.host property is undefined then:\n
          \n
        • If the urlObject.hostname is a string, it is appended to result.
        • \n
        • Otherwise, if urlObject.hostname is not undefined and is not a string,\nan Error is thrown.
        • \n
        • If the urlObject.port property value is truthy, and urlObject.hostname\nis not undefined:\n
            \n
          • The literal string : is appended to result, and
          • \n
          • The value of urlObject.port is coerced to a string and appended to\nresult.
          • \n
          \n
        • \n
        \n
      • \n
      • Otherwise, if the urlObject.host property value is truthy, the value of\nurlObject.host is coerced to a string and appended to result.
      • \n
      • If the urlObject.pathname property is a string that is not an empty string:\n
          \n
        • If the urlObject.pathname does not start with an ASCII forward slash\n(/), then the literal string '/' is appended to result.
        • \n
        • The value of urlObject.pathname is appended to result.
        • \n
        \n
      • \n
      • Otherwise, if urlObject.pathname is not undefined and is not a string, an\nError is thrown.
      • \n
      • If the urlObject.search property is undefined and if the urlObject.query\nproperty is an Object, the literal string ? is appended to result\nfollowed by the output of calling the querystring module's stringify()\nmethod passing the value of urlObject.query.
      • \n
      • Otherwise, if urlObject.search is a string:\n
          \n
        • If the value of urlObject.search does not start with the ASCII question\nmark (?) character, the literal string ? is appended to result.
        • \n
        • The value of urlObject.search is appended to result.
        • \n
        \n
      • \n
      • Otherwise, if urlObject.search is not undefined and is not a string, an\nError is thrown.
      • \n
      • If the urlObject.hash property is a string:\n
          \n
        • If the value of urlObject.hash does not start with the ASCII hash (#)\ncharacter, the literal string # is appended to result.
        • \n
        • The value of urlObject.hash is appended to result.
        • \n
        \n
      • \n
      • Otherwise, if the urlObject.hash property is not undefined and is not a\nstring, an Error is thrown.
      • \n
      • result is returned.
      • \n
      " + "desc": "

      The url.format() method returns a formatted URL string derived from\nurlObject.

      \n
      const url = require('url');\nurl.format({\n  protocol: 'https',\n  hostname: 'example.com',\n  pathname: '/some/path',\n  query: {\n    page: 1,\n    format: 'json'\n  }\n});\n\n// => 'https://example.com/some/path?page=1&format=json'\n
      \n

      If urlObject is not an object or a string, url.format() will throw a\nTypeError.

      \n

      The formatting process operates as follows:

      \n
        \n
      • A new empty string result is created.
      • \n
      • If urlObject.protocol is a string, it is appended as-is to result.
      • \n
      • Otherwise, if urlObject.protocol is not undefined and is not a string, an\nError is thrown.
      • \n
      • For all string values of urlObject.protocol that do not end with an ASCII\ncolon (:) character, the literal string : will be appended to result.
      • \n
      • If either of the following conditions is true, then the literal string //\nwill be appended to result:\n
          \n
        • urlObject.slashes property is true;
        • \n
        • urlObject.protocol begins with http, https, ftp, gopher, or\nfile;
        • \n
        \n
      • \n
      • If the value of the urlObject.auth property is truthy, and either\nurlObject.host or urlObject.hostname are not undefined, the value of\nurlObject.auth will be coerced into a string and appended to result\nfollowed by the literal string @.
      • \n
      • If the urlObject.host property is undefined then:\n
          \n
        • If the urlObject.hostname is a string, it is appended to result.
        • \n
        • Otherwise, if urlObject.hostname is not undefined and is not a string,\nan Error is thrown.
        • \n
        • If the urlObject.port property value is truthy, and urlObject.hostname\nis not undefined:\n
            \n
          • The literal string : is appended to result, and
          • \n
          • The value of urlObject.port is coerced to a string and appended to\nresult.
          • \n
          \n
        • \n
        \n
      • \n
      • Otherwise, if the urlObject.host property value is truthy, the value of\nurlObject.host is coerced to a string and appended to result.
      • \n
      • If the urlObject.pathname property is a string that is not an empty string:\n
          \n
        • If the urlObject.pathname does not start with an ASCII forward slash\n(/), then the literal string '/' is appended to result.
        • \n
        • The value of urlObject.pathname is appended to result.
        • \n
        \n
      • \n
      • Otherwise, if urlObject.pathname is not undefined and is not a string, an\nError is thrown.
      • \n
      • If the urlObject.search property is undefined and if the urlObject.query\nproperty is an Object, the literal string ? is appended to result\nfollowed by the output of calling the querystring module's stringify()\nmethod passing the value of urlObject.query.
      • \n
      • Otherwise, if urlObject.search is a string:\n
          \n
        • If the value of urlObject.search does not start with the ASCII question\nmark (?) character, the literal string ? is appended to result.
        • \n
        • The value of urlObject.search is appended to result.
        • \n
        \n
      • \n
      • Otherwise, if urlObject.search is not undefined and is not a string, an\nError is thrown.
      • \n
      • If the urlObject.hash property is a string:\n
          \n
        • If the value of urlObject.hash does not start with the ASCII hash (#)\ncharacter, the literal string # is appended to result.
        • \n
        • The value of urlObject.hash is appended to result.
        • \n
        \n
      • \n
      • Otherwise, if the urlObject.hash property is not undefined and is not a\nstring, an Error is thrown.
      • \n
      • result is returned.
      • \n
      " }, { "textRaw": "`url.parse(urlString[, parseQueryString[, slashesDenoteHost]])`", @@ -812,6 +927,11 @@ "v0.1.25" ], "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/37784", + "description": "Deprecation revoked. Status changed to \"Legacy\"." + }, { "version": "v11.14.0", "pr-url": "https://github.com/nodejs/node/pull/26941", @@ -829,8 +949,8 @@ } ] }, - "stability": 0, - "stabilityText": "Deprecated: Use the WHATWG URL API instead.", + "stability": 3, + "stabilityText": "Legacy: Use the WHATWG URL API instead.", "signatures": [ { "params": [ @@ -868,6 +988,11 @@ "v0.1.25" ], "changes": [ + { + "version": "v14.17.0", + "pr-url": "https://github.com/nodejs/node/pull/37784", + "description": "Deprecation revoked. Status changed to \"Legacy\"." + }, { "version": "v11.0.0", "pr-url": "https://github.com/nodejs/node/pull/22715", @@ -879,7 +1004,10 @@ "description": "The `auth` fields are now kept intact when `from` and `to` refer to the same host." }, { - "version": "v6.5.0, v4.6.2", + "version": [ + "v6.5.0", + "v4.6.2" + ], "pr-url": "https://github.com/nodejs/node/pull/8214", "description": "The `port` field is copied correctly now." }, @@ -890,8 +1018,8 @@ } ] }, - "stability": 0, - "stabilityText": "Deprecated: Use the WHATWG URL API instead.", + "stability": 3, + "stabilityText": "Legacy: Use the WHATWG URL API instead.", "signatures": [ { "params": [ @@ -910,7 +1038,7 @@ ] } ], - "desc": "

      The url.resolve() method resolves a target URL relative to a base URL in a\nmanner similar to that of a Web browser resolving an anchor tag HREF.

      \n
      const url = require('url');\nurl.resolve('/one/two/three', 'four');         // '/one/two/four'\nurl.resolve('http://example.com/', '/one');    // 'http://example.com/one'\nurl.resolve('http://example.com/one', '/two'); // 'http://example.com/two'\n
      \n

      " + "desc": "

      The url.resolve() method resolves a target URL relative to a base URL in a\nmanner similar to that of a Web browser resolving an anchor tag HREF.

      \n
      const url = require('url');\nurl.resolve('/one/two/three', 'four');         // '/one/two/four'\nurl.resolve('http://example.com/', '/one');    // 'http://example.com/one'\nurl.resolve('http://example.com/one', '/two'); // 'http://example.com/two'\n
      \n

      You can achieve the same result using the WHATWG URL API:

      \n
      function resolve(from, to) {\n  const resolvedUrl = new URL(to, new URL(from, 'resolve://'));\n  if (resolvedUrl.protocol === 'resolve:') {\n    // `from` is a relative URL.\n    const { pathname, search, hash } = resolvedUrl;\n    return pathname + search + hash;\n  }\n  return resolvedUrl.toString();\n}\n\nresolve('/one/two/three', 'four');         // '/one/two/four'\nresolve('http://example.com/', '/one');    // 'http://example.com/one'\nresolve('http://example.com/one', '/two'); // 'http://example.com/two'\n
      \n

      " } ], "type": "module", diff --git a/doc/api/url.md b/doc/api/url.md index 55919241b90e0b2384ae912678e99f47ae4d2c4f..980a77836bcbcf04035708baddecd7933aaa83dd 100644 --- a/doc/api/url.md +++ b/doc/api/url.md @@ -24,7 +24,7 @@ Node.js specific, and a newer API that implements the same [WHATWG URL Standard][] used by web browsers. A comparison between the WHATWG and Legacy APIs is provided below. Above the URL -`'http://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'`, properties +`'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'`, properties of an object returned by the legacy `url.parse()` are shown. Below it are properties of a WHATWG `URL` object. @@ -67,6 +67,31 @@ const myURL = url.parse('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'); ``` +### Constructing a URL from component parts and getting the constructed string + +It is possible to construct a WHATWG URL from component parts using either the +property setters or a template literal string: + +```js +const myURL = new URL('https://example.org'); +myURL.pathname = '/a/b/c'; +myURL.search = '?d=e'; +myURL.hash = '#fgh'; +``` + +```js +const pathname = '/a/b/c'; +const search = '?d=e'; +const hash = '#fgh'; +const myURL = new URL(`https://example.org${pathname}${search}${hash}`); +``` + +To get the constructed URL string, use the `href` property accessor: + +```js +console.log(myURL.href); +``` + ## The WHATWG URL API ### Class: `URL` @@ -210,9 +235,15 @@ const myURL = new URL('https://example.org:81/foo'); console.log(myURL.hostname); // Prints example.org +// Setting the hostname does not change the port myURL.hostname = 'example.com:82'; console.log(myURL.href); // Prints https://example.com:81/foo + +// Use myURL.host to change the hostname and port +myURL.host = 'example.org:82'; +console.log(myURL.href); +// Prints https://example.org:82/foo ``` Invalid host name values assigned to the `hostname` property are ignored. @@ -542,7 +573,7 @@ with [`JSON.stringify()`][]. ```js const myURLs = [ new URL('https://www.example.com'), - new URL('https://test.example.org') + new URL('https://test.example.org'), ]; console.log(JSON.stringify(myURLs)); // Prints ["https://www.example.com/","https://test.example.org/"] @@ -679,7 +710,7 @@ let params; params = new URLSearchParams([ ['user', 'abc'], ['query', 'first'], - ['query', 'second'] + ['query', 'second'], ]); console.log(params.toString()); // Prints 'user=abc&query=first&query=second' @@ -704,7 +735,7 @@ console.log(params.toString()); // Each key-value pair must have exactly two elements new URLSearchParams([ - ['user', 'abc', 'error'] + ['user', 'abc', 'error'], ]); // Throws TypeError [ERR_INVALID_TUPLE]: // Each query pair must be an iterable [name, value] tuple @@ -882,6 +913,9 @@ invalid domain, the empty string is returned. It performs the inverse operation to [`url.domainToUnicode()`][]. +This feature is only available if the `node` executable was compiled with +[ICU][] enabled. If not, the domain names are passed through unchanged. + ```js const url = require('url'); console.log(url.domainToASCII('español.com')); @@ -907,6 +941,9 @@ domain, the empty string is returned. It performs the inverse operation to [`url.domainToASCII()`][]. +This feature is only available if the `node` executable was compiled with +[ICU][] enabled. If not, the domain names are passed through unchanged. + ```js const url = require('url'); console.log(url.domainToUnicode('xn--espaol-zwa.com')); @@ -928,18 +965,37 @@ added: v10.12.0 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) +```mjs +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); + +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) +``` + +```cjs +const { fileURLToPath } = require('url'); +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://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:///你好.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) +new URL('file:///hello world').pathname; // Incorrect: /hello%20world +fileURLToPath('file:///hello world'); // Correct: /hello world (POSIX) ``` ### `url.format(URL[, options])` @@ -968,7 +1024,22 @@ string serializations of the URL. These are not, however, customizable in any way. The `url.format(URL[, options])` method allows for basic customization of the output. -```js +```mjs +import url from 'url'; +const myURL = new URL('https://a:b@測試?abc#foo'); + +console.log(myURL.href); +// Prints https://a:b@xn--g6w251d/?abc#foo + +console.log(myURL.toString()); +// Prints https://a:b@xn--g6w251d/?abc#foo + +console.log(url.format(myURL, { fragment: false, unicode: true, auth: false })); +// Prints 'https://測試/?abc' +``` + +```cjs +const url = require('url'); const myURL = new URL('https://a:b@測試?abc#foo'); console.log(myURL.href); @@ -992,33 +1063,99 @@ added: v10.12.0 This function ensures that `path` is resolved absolutely, and that the URL control characters are correctly encoded when converting into a File URL. -```js -new URL(__filename); // Incorrect: throws (POSIX) -new URL(__filename); // Incorrect: C:\... (Windows) -pathToFileURL(__filename); // Correct: file:///... (POSIX) -pathToFileURL(__filename); // Correct: file:///C:/... (Windows) +```mjs +import { pathToFileURL } from 'url'; + +new URL('/foo#1', 'file:'); // Incorrect: file:///foo#1 +pathToFileURL('/foo#1'); // Correct: file:///foo%231 (POSIX) + +new URL('/some/path%.c', 'file:'); // Incorrect: file:///some/path%.c +pathToFileURL('/some/path%.c'); // Correct: file:///some/path%25.c (POSIX) +``` + +```cjs +const { pathToFileURL } = require('url'); +new URL(__filename); // Incorrect: throws (POSIX) +new URL(__filename); // Incorrect: C:\... (Windows) +pathToFileURL(__filename); // Correct: file:///... (POSIX) +pathToFileURL(__filename); // Correct: file:///C:/... (Windows) -new URL('/foo#1', 'file:'); // Incorrect: file:///foo#1 -pathToFileURL('/foo#1'); // Correct: file:///foo%231 (POSIX) +new URL('/foo#1', 'file:'); // Incorrect: file:///foo#1 +pathToFileURL('/foo#1'); // Correct: file:///foo%231 (POSIX) + +new URL('/some/path%.c', 'file:'); // Incorrect: file:///some/path%.c +pathToFileURL('/some/path%.c'); // Correct: file:///some/path%25.c (POSIX) +``` + +### `url.urlToHttpOptions(url)` + + +* `url` {URL} The [WHATWG URL][] object to convert to an options object. +* Returns: {Object} Options object + * `protocol` {string} Protocol to use. + * `hostname` {string} A domain name or IP address of the server to issue the + request to. + * `hash` {string} The fragment portion of the URL. + * `search` {string} The serialized query portion of the URL. + * `pathname` {string} The path portion of the URL. + * `path` {string} Request path. Should include query string if any. + E.G. `'/index.html?page=12'`. An exception is thrown when the request path + contains illegal characters. Currently, only spaces are rejected but that + may change in the future. + * `href` {string} The serialized URL. + * `port` {number} Port of remote server. + * `auth` {string} Basic authentication i.e. `'user:password'` to compute an + Authorization header. + +This utility function converts a URL object into an ordinary options object as +expected by the [`http.request()`][] and [`https.request()`][] APIs. + +```js +const { urlToHttpOptions } = require('url'); +const myURL = new URL('https://a:b@測試?abc#foo'); -new URL('/some/path%.c', 'file:'); // Incorrect: file:///some/path%.c -pathToFileURL('/some/path%.c'); // Correct: file:///some/path%25.c (POSIX) +console.log(urlToHttpOptions(myUrl)); +/** +{ + protocol: 'https:', + hostname: 'xn--g6w251d', + hash: '#foo', + search: '?abc', + pathname: '/', + path: '/?abc', + href: 'https://a:b@xn--g6w251d/?abc#foo', + auth: 'a:b' +} +*/ ``` ## Legacy URL API +> Stability: 3 - Legacy: Use the WHATWG URL API instead. + ### Legacy `urlObject` -> Stability: 0 - Deprecated: Use the WHATWG URL API instead. +> Stability: 3 - Legacy: Use the WHATWG URL API instead. The legacy `urlObject` (`require('url').Url`) is created and returned by the `url.parse()` function. @@ -1124,6 +1261,9 @@ forward-slash characters (`/`) are required following the colon in the -> Stability: 0 - Deprecated: Use the WHATWG URL API instead. +> Stability: 3 - Legacy: Use the WHATWG URL API instead. * `urlObject` {Object|string} A URL object (as returned by `url.parse()` or constructed otherwise). If a string, it is converted to an object by passing @@ -1145,6 +1285,7 @@ The `url.format()` method returns a formatted URL string derived from `urlObject`. ```js +const url = require('url'); url.format({ protocol: 'https', hostname: 'example.com', @@ -1217,6 +1358,9 @@ The formatting process operates as follows: -> Stability: 0 - Deprecated: Use the WHATWG URL API instead. +> Stability: 3 - Legacy: Use the WHATWG URL API instead. * `urlString` {string} The URL string to parse. * `parseQueryString` {boolean} If `true`, the `query` property will always @@ -1261,6 +1405,9 @@ incorrect handling of usernames and passwords have been identified. -> Stability: 0 - Deprecated: Use the WHATWG URL API instead. +> Stability: 3 - Legacy: Use the WHATWG URL API instead. * `from` {string} The Base URL being resolved against. * `to` {string} The HREF URL being resolved. @@ -1292,6 +1441,24 @@ url.resolve('http://example.com/', '/one'); // 'http://example.com/one' url.resolve('http://example.com/one', '/two'); // 'http://example.com/two' ``` +You can achieve the same result using the WHATWG URL API: + +```js +function resolve(from, to) { + const resolvedUrl = new URL(to, new URL(from, 'resolve://')); + if (resolvedUrl.protocol === 'resolve:') { + // `from` is a relative URL. + const { pathname, search, hash } = resolvedUrl; + return pathname + search + hash; + } + return resolvedUrl.toString(); +} + +resolve('/one/two/three', 'four'); // '/one/two/four' +resolve('http://example.com/', '/one'); // 'http://example.com/one' +resolve('http://example.com/one', '/two'); // 'http://example.com/two' +``` + ## Percent-encoding in URLs @@ -1352,14 +1519,20 @@ console.log(myURL.origin); // Prints https://xn--1xa.example.com ``` -[`Error`]: errors.html#errors_class_error +[ICU]: intl.md#intl_options_for_building_node_js +[Punycode]: https://tools.ietf.org/html/rfc5891#section-4.4 +[WHATWG URL]: #url_the_whatwg_url_api +[WHATWG URL Standard]: https://url.spec.whatwg.org/ +[`Error`]: errors.md#errors_class_error [`JSON.stringify()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify [`Map`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map -[`TypeError`]: errors.html#errors_class_typeerror +[`TypeError`]: errors.md#errors_class_typeerror [`URLSearchParams`]: #url_class_urlsearchparams [`array.toString()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString +[`http.request()`]: http.md#http_http_request_options_callback +[`https.request()`]: https.md#https_https_request_options_callback [`new URL()`]: #url_new_url_input_base -[`querystring`]: querystring.html +[`querystring`]: querystring.md [`require('url').format()`]: #url_url_format_url_options [`url.domainToASCII()`]: #url_url_domaintoascii_domain [`url.domainToUnicode()`]: #url_url_domaintounicode_domain @@ -1371,10 +1544,6 @@ console.log(myURL.origin); [`url.toString()`]: #url_url_tostring [`urlSearchParams.entries()`]: #url_urlsearchparams_entries [`urlSearchParams@@iterator()`]: #url_urlsearchparams_symbol_iterator -[ICU]: intl.html#intl_options_for_building_node_js -[Punycode]: https://tools.ietf.org/html/rfc5891#section-4.4 -[WHATWG URL Standard]: https://url.spec.whatwg.org/ -[WHATWG URL]: #url_the_whatwg_url_api [examples of parsed URLs]: https://url.spec.whatwg.org/#example-url-parsing [host name spoofing]: https://hackerone.com/reports/678487 [legacy `urlObject`]: #url_legacy_urlobject diff --git a/doc/api/util.html b/doc/api/util.html index 1720ee3a512654db17e369e971d2abc85bebbe4f..0f7606f2c72768df88a5ba821f3bba3f3e86627f 100644 --- a/doc/api/util.html +++ b/doc/api/util.html @@ -1,10 +1,10 @@ - + - - Util | Node.js v12.22.7 Documentation + + Util | Node.js v14.18.3 Documentation @@ -27,16 +27,17 @@
    • Assertion testing
    • Async hooks
    • Buffer
    • -
    • C++ Addons
    • -
    • C/C++ Addons with N-API
    • -
    • C++ Embedder API
    • -
    • Child Processes
    • +
    • C++ addons
    • +
    • C/C++ addons with Node-API
    • +
    • C++ embedder API
    • +
    • Child processes
    • Cluster
    • -
    • Command line options
    • +
    • Command-line options
    • Console
    • Crypto
    • Debugger
    • Deprecated APIs
    • +
    • Diagnostics Channel
    • DNS
    • Domain
    • Errors
    • @@ -86,7 +87,20 @@
      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      - +
      -

      Util#

      +

      Util#

      Stability: 2 - Stable

      -

      Source Code: lib/util.js

      +

      Source Code: lib/util.js

      The util module supports the needs of Node.js internal APIs. Many of the utilities are useful for application and module developers as well. To access it:

      const util = require('util');
      -

      util.callbackify(original)#

      +

      util.callbackify(original)#

      @@ -275,14 +294,14 @@ first argument will be the rejection reason (or null if the P resolved), and the second argument will be the resolved value.

      const util = require('util');
       
      -async function fn() {
      +async function fn() {
         return 'hello world';
       }
      -const callbackFunction = util.callbackify(fn);
      +const callbackFunction = util.callbackify(fn);
       
      -callbackFunction((err, ret) => {
      +callbackFunction((err, ret) => {
         if (err) throw err;
      -  console.log(ret);
      +  console.log(ret);
       });

      Will print:

      hello world
      @@ -293,17 +312,17 @@ event, and if not handled will exit.

      wrapped function rejects a Promise with a falsy value as a reason, the value is wrapped in an Error with the original value stored in a field named reason.

      -
      function fn() {
      -  return Promise.reject(null);
      +
      function fn() {
      +  return Promise.reject(null);
       }
      -const callbackFunction = util.callbackify(fn);
      +const callbackFunction = util.callbackify(fn);
       
      -callbackFunction((err, ret) => {
      +callbackFunction((err, ret) => {
         // When the Promise was rejected with `null` it is wrapped with an Error and
         // the original value is stored in `reason`.
      -  err && err.hasOwnProperty('reason') && err.reason === null;  // true
      +  err && err.hasOwnProperty('reason') && err.reason === null;  // true
       });
      -

      util.debuglog(section[, callback])#

      +

      util.debuglog(section[, callback])#

      @@ -320,9 +339,9 @@ environment variable. If the section name appears within the value environment variable, then the returned function operates similar to console.error(). If not, then the returned function is a no-op.

      const util = require('util');
      -const debuglog = util.debuglog('foo');
      +const debuglog = util.debuglog('foo');
       
      -debuglog('hello from foo [%d]', 123);
      +debuglog('hello from foo [%d]', 123);

      If this program is run with NODE_DEBUG=foo in the environment, then it will output something like:

      FOO 3245: hello from foo [123]
      @@ -330,9 +349,9 @@ it will output something like:

      environment variable set, then it will not print anything.

      The section supports wildcard also:

      const util = require('util');
      -const debuglog = util.debuglog('foo-bar');
      +const debuglog = util.debuglog('foo-bar');
       
      -debuglog('hi there, it\'s foo-bar [%d]', 2333);
      +debuglog('hi there, it\'s foo-bar [%d]', 2333);

      if it is run with NODE_DEBUG=foo* in the environment, then it will output something like:

      FOO-BAR 3257: hi there, it's foo-bar [2333]
      @@ -342,12 +361,38 @@ environment variable: NODE_DEBUG=fs,net,tls.

      with a different function that doesn't have any initialization or unnecessary wrapping.

      const util = require('util');
      -let debuglog = util.debuglog('internals', (debug) => {
      +let debuglog = util.debuglog('internals', (debug) => {
         // Replace with a logging function that optimizes out
         // testing if the section is enabled
         debuglog = debug;
       });
      -

      util.deprecate(fn, msg[, code])#

      +

      debuglog().enabled#

      + + +

      The util.debuglog().enabled getter is used to create a test that can be used +in conditionals based on the existence of the NODE_DEBUG environment variable. +If the section name appears within the value of that environment variable, +then the returned value will be true. If not, then the returned value will be +false.

      +
      const util = require('util');
      +const enabled = util.debuglog('foo').enabled;
      +if (enabled) {
      +  console.log('hello from foo [%d]', 123);
      +}
      +

      If this program is run with NODE_DEBUG=foo in the environment, then it will +output something like:

      +
      hello from foo [123]
      +

      util.debug(section)#

      + +

      Alias for util.debuglog. Usage allows for readability of that doesn't imply +logging when only using util.debuglog().enabled.

      +

      util.deprecate(fn, msg[, code])#

      +

      Stability: 3 - Legacy: Use ES2015 class syntax and extends keyword instead.

      • constructor <Function>
      • superConstructor <Function>
      • @@ -533,53 +594,55 @@ prototype of constructor will be set to a new object created from As an additional convenience, superConstructor will be accessible through the constructor.super_ property.

        const util = require('util');
        -const EventEmitter = require('events');
        +const EventEmitter = require('events');
         
        -function MyStream() {
        -  EventEmitter.call(this);
        +function MyStream() {
        +  EventEmitter.call(this);
         }
         
        -util.inherits(MyStream, EventEmitter);
        +util.inherits(MyStream, EventEmitter);
         
        -MyStream.prototype.write = function(data) {
        -  this.emit('data', data);
        +MyStream.prototype.write = function(data) {
        +  this.emit('data', data);
         };
         
        -const stream = new MyStream();
        +const stream = new MyStream();
         
        -console.log(stream instanceof EventEmitter); // true
        -console.log(MyStream.super_ === EventEmitter); // true
        +console.log(stream instanceof EventEmitter); // true
        +console.log(MyStream.super_ === EventEmitter); // true
         
        -stream.on('data', (data) => {
        -  console.log(`Received data: "${data}"`);
        +stream.on('data', (data) => {
        +  console.log(`Received data: "${data}"`);
         });
        -stream.write('It works!'); // Received data: "It works!"
        +stream.write('It works!'); // Received data: "It works!"

        ES6 example using class and extends:

        -
        const EventEmitter = require('events');
        +
        const EventEmitter = require('events');
         
        -class MyStream extends EventEmitter {
        -  write(data) {
        -    this.emit('data', data);
        +class MyStream extends EventEmitter {
        +  write(data) {
        +    this.emit('data', data);
           }
         }
         
        -const stream = new MyStream();
        +const stream = new MyStream();
         
        -stream.on('data', (data) => {
        -  console.log(`Received data: "${data}"`);
        +stream.on('data', (data) => {
        +  console.log(`Received data: "${data}"`);
         });
        -stream.write('With ES6');
        -

        util.inspect(object[, options])#

        -

        util.inspect(object[, showHidden[, depth[, colors]]])#

        +stream.write('With ES6');
        +

      util.inspect(object[, options])#

      +

      util.inspect(object[, showHidden[, depth[, colors]]])#

      -

      Node.js v12.22.7 Documentation

      +
      +

      Node.js v14.18.3 documentation

      + +

      - +
      -

      Stream[src]#

      +

      Stream[src]#

      Stability: 2 - Stable

      -

      Source Code: lib/stream.js

      +

      Source Code: lib/stream.js

      A stream is an abstract interface for working with streaming data in Node.js. The stream module provides an API for implementing the stream interface.

      There are many stream objects provided by Node.js. For instance, a @@ -297,11 +313,11 @@ are both stream instances.

      const stream = require('stream');

      The stream module is useful for creating new types of stream instances. It is usually not necessary to use the stream module to consume streams.

      -

      Organization of this document#

      +

      Organization of this document#

      This document contains two primary sections and a third section for notes. The first section explains how to use existing streams within an application. The second section explains how to create new types of streams.

      -

      Types of streams#

      +

      Types of streams#

      There are four fundamental stream types within Node.js:

      • Writable: streams to which data can be written (for example, @@ -314,9 +330,9 @@ second section explains how to create new types of streams.

        is written and read (for example, zlib.createDeflate()).

      Additionally, this module includes the utility functions -stream.pipeline(), stream.finished() and +stream.pipeline(), stream.finished() and stream.Readable.from().

      -

      Object mode#

      +

      Object mode#

      All streams created by Node.js APIs operate exclusively on strings and Buffer (or Uint8Array) objects. It is possible, however, for stream implementations to work with other types of JavaScript values (with the exception of null, @@ -325,11 +341,10 @@ operate in "object mode".

      Stream instances are switched into object mode using the objectMode option when the stream is created. Attempting to switch an existing stream into object mode is not safe.

      -

      Buffering#

      +

      Buffering#

      Both Writable and Readable streams will store data in an internal -buffer that can be retrieved using writable.writableBuffer or -readable.readableBuffer, respectively.

      +buffer.

      The amount of data potentially buffered depends on the highWaterMark option passed into the stream's constructor. For normal streams, the highWaterMark option specifies a total number of bytes. For streams operating @@ -365,43 +380,47 @@ consumption of data received from the socket and whose Writableto the socket. Because data may be written to the socket at a faster or slower rate than data is received, each side should operate (and buffer) independently of the other.

      -

      API for stream consumers#

      +

      The mechanics of the internal buffering are an internal implementation detail +and may be changed at any time. However, for certain advanced implementations, +the internal buffers can be retrieved using writable.writableBuffer or +readable.readableBuffer. Use of these undocumented properties is discouraged.

      +

      API for stream consumers#

      Almost all Node.js applications, no matter how simple, use streams in some manner. The following is an example of using streams in a Node.js application that implements an HTTP server:

      const http = require('http');
       
      -const server = http.createServer((req, res) => {
      +const server = http.createServer((req, res) => {
         // `req` is an http.IncomingMessage, which is a readable stream.
         // `res` is an http.ServerResponse, which is a writable stream.
       
         let body = '';
         // Get the data as utf8 strings.
         // If an encoding is not set, Buffer objects will be received.
      -  req.setEncoding('utf8');
      +  req.setEncoding('utf8');
       
         // Readable streams emit 'data' events once a listener is added.
      -  req.on('data', (chunk) => {
      +  req.on('data', (chunk) => {
           body += chunk;
         });
       
         // The 'end' event indicates that the entire body has been received.
      -  req.on('end', () => {
      +  req.on('end', () => {
           try {
      -      const data = JSON.parse(body);
      +      const data = JSON.parse(body);
             // Write back something interesting to the user:
      -      res.write(typeof data);
      -      res.end();
      +      res.write(typeof data);
      +      res.end();
           } catch (er) {
             // uh oh! bad json!
      -      res.statusCode = 400;
      -      return res.end(`error: ${er.message}`);
      +      res.statusCode = 400;
      +      return res.end(`error: ${er.message}`);
           }
         });
       });
       
      -server.listen(1337);
      +server.listen(1337);
       
       // $ curl localhost:1337 -d "{}"
       // object
      @@ -423,7 +442,7 @@ are not required to implement the stream interfaces directly and will generally
       have no reason to call require('stream').

      Developers wishing to implement new types of streams should refer to the section API for stream implementers.

      -

      Writable streams#

      +

      Writable streams#

      Writable streams are an abstraction for a destination to which data is written.

      Examples of Writable streams include:

      @@ -444,16 +463,16 @@ written.

      While specific instances of Writable streams may differ in various ways, all Writable streams follow the same fundamental usage pattern as illustrated in the example below:

      -
      const myStream = getWritableStreamSomehow();
      -myStream.write('some data');
      -myStream.write('some more data');
      -myStream.end('done writing data');
      -

      Class: stream.Writable#

      +
      const myStream = getWritableStreamSomehow();
      +myStream.write('some data');
      +myStream.write('some more data');
      +myStream.end('done writing data');
      +
      Class: stream.Writable#
      -
      Event: 'close'#
      +
      Event: 'close'#
      • error <Error> Optional, an error to emit with 'error' event.
      • @@ -596,10 +625,32 @@ an ERR_STREAM_DESTROYED error. This is a destructive and immediate way to destroy a stream. Previous calls to write() may not have drained, and may trigger an ERR_STREAM_DESTROYED error. Use end() instead of destroy if data should flush before close, or wait for -the 'drain' event before destroying the stream. -Implementors should not override this method, +the 'drain' event before destroying the stream.

        + +
        const { Writable } = require('stream');
        +
        +const myStream = new Writable();
        +
        +const fooErr = new Error('foo error');
        +myStream.destroy(fooErr);
        +myStream.on('error', (fooErr) => console.error(fooErr.message)); // foo error
        const { Writable } = require('stream'); + +const myStream = new Writable(); + +myStream.destroy(); +myStream.on('error', function wontHappen() {});
        +
        const { Writable } = require('stream');
        +
        +const myStream = new Writable();
        +myStream.destroy();
        +
        +myStream.write('foo', (error) => console.error(error.code));
        +// ERR_STREAM_DESTROYED
        +

        Once destroy() has been called any further calls will be a no-op and no +further errors except from _destroy() may be emitted as 'error'.

        +

        Implementors should not override this method, but instead implement writable._destroy().

        -
        writable.destroyed#
        +
        writable.destroyed#
        @@ -607,11 +658,20 @@ but instead implement writ
      • <boolean>

      Is true after writable.destroy() has been called.

      -
      writable.end([chunk[, encoding]][, callback])#
      +
      const { Writable } = require('stream');
      +
      +const myStream = new Writable();
      +
      +console.log(myStream.destroyed); // false
      +myStream.destroy();
      +console.log(myStream.destroyed); // true
      +
      writable.end([chunk[, encoding]][, callback])#
      • error <Error> Error which will be passed as payload in 'error' event
      • @@ -1086,10 +1165,12 @@ called and readableFlowing is not true.

        Destroy the stream. Optionally emit an 'error' event, and emit a 'close' event (unless emitClose is set to false). After this call, the readable stream will release any internal resources and subsequent calls to push() -will be ignored. -Implementors should not override this method, but instead implement +will be ignored.

        +

        Once destroy() has been called any further calls will be a no-op and no +further errors except from _destroy() may be emitted as 'error'.

        +

        Implementors should not override this method, but instead implement readable._destroy().

        -
        readable.destroyed#
        +
        readable.destroyed#
        @@ -1097,7 +1178,7 @@ Implementors should not override this method, but instead implement
      • <boolean>

      Is true after readable.destroy() has been called.

      -
      readable.isPaused()#
      +
      readable.isPaused()#
      @@ -1108,14 +1189,14 @@ Implementors should not override this method, but instead implement Readable. This is used primarily by the mechanism that underlies the readable.pipe() method. In most typical cases, there will be no reason to use this method directly.

      -
      const readable = new stream.Readable();
      +
      const readable = new stream.Readable();
       
      -readable.isPaused(); // === false
      -readable.pause();
      -readable.isPaused(); // === true
      -readable.resume();
      -readable.isPaused(); // === false
      -
      readable.pause()#
      +readable.isPaused(); // === false +readable.pause(); +readable.isPaused(); // === true +readable.resume(); +readable.isPaused(); // === false
      +
      readable.pause()#
      @@ -1125,19 +1206,19 @@ readable.isPaused(); // === false

      The readable.pause() method will cause a stream in flowing mode to stop emitting 'data' events, switching out of flowing mode. Any data that becomes available will remain in the internal buffer.

      -
      const readable = getReadableStreamSomehow();
      -readable.on('data', (chunk) => {
      -  console.log(`Received ${chunk.length} bytes of data.`);
      -  readable.pause();
      -  console.log('There will be no additional data for 1 second.');
      +
      const readable = getReadableStreamSomehow();
      +readable.on('data', (chunk) => {
      +  console.log(`Received ${chunk.length} bytes of data.`);
      +  readable.pause();
      +  console.log('There will be no additional data for 1 second.');
         setTimeout(() => {
      -    console.log('Now data will start flowing again.');
      -    readable.resume();
      +    console.log('Now data will start flowing again.');
      +    readable.resume();
         }, 1000);
       });

      The readable.pause() method has no effect if there is a 'readable' event listener.

      -
      readable.pipe(destination[, options])#
      +
      readable.pipe(destination[, options])#
      @@ -1159,26 +1240,26 @@ so that the destination Writable stream is not overwhelmed by a fas

      The following example pipes all of the data from the readable into a file named file.txt:

      const fs = require('fs');
      -const readable = getReadableStreamSomehow();
      -const writable = fs.createWriteStream('file.txt');
      +const readable = getReadableStreamSomehow();
      +const writable = fs.createWriteStream('file.txt');
       // All the data from readable goes into 'file.txt'.
      -readable.pipe(writable);
      +readable.pipe(writable);

      It is possible to attach multiple Writable streams to a single Readable stream.

      The readable.pipe() method returns a reference to the destination stream making it possible to set up chains of piped streams:

      const fs = require('fs');
      -const r = fs.createReadStream('file.txt');
      -const z = zlib.createGzip();
      -const w = fs.createWriteStream('file.txt.gz');
      -r.pipe(z).pipe(w);
      +const r = fs.createReadStream('file.txt'); +const z = zlib.createGzip(); +const w = fs.createWriteStream('file.txt.gz'); +r.pipe(z).pipe(w);

      By default, stream.end() is called on the destination Writable stream when the source Readable stream emits 'end', so that the destination is no longer writable. To disable this default behavior, the end option can be passed as false, causing the destination stream to remain open:

      -
      reader.pipe(writer, { end: false });
      -reader.on('end', () => {
      -  writer.end('Goodbye\n');
      +
      reader.pipe(writer, { end: false });
      +reader.on('end', () => {
      +  writer.end('Goodbye\n');
       });

      One important caveat is that if the Readable stream emits an error during processing, the Writable destination is not closed automatically. If an @@ -1186,7 +1267,7 @@ error occurs, it will be necessary to manually close each stream in ord to prevent memory leaks.

      The process.stderr and process.stdout Writable streams are never closed until the Node.js process exits, regardless of the specified options.

      -
      readable.read([size])#
      +
      readable.read([size])#
      @@ -1205,25 +1286,25 @@ the stream has ended, in which case all of the data remaining in the internal buffer will be returned.

      If the size argument is not specified, all of the data contained in the internal buffer will be returned.

      -

      The size argument must be less than or equal to 1 GB.

      +

      The size argument must be less than or equal to 1 GiB.

      The readable.read() method should only be called on Readable streams operating in paused mode. In flowing mode, readable.read() is called automatically until the internal buffer is fully drained.

      -
      const readable = getReadableStreamSomehow();
      +
      const readable = getReadableStreamSomehow();
       
       // 'readable' may be triggered multiple times as data is buffered in
      -readable.on('readable', () => {
      +readable.on('readable', () => {
         let chunk;
      -  console.log('Stream is readable (new data received in buffer)');
      +  console.log('Stream is readable (new data received in buffer)');
         // Use a loop to make sure we read all currently available data
      -  while (null !== (chunk = readable.read())) {
      -    console.log(`Read ${chunk.length} bytes of data...`);
      +  while (null !== (chunk = readable.read())) {
      +    console.log(`Read ${chunk.length} bytes of data...`);
         }
       });
       
       // 'end' will be triggered once when there is no more data available
      -readable.on('end', () => {
      -  console.log('Reached end of stream.');
      +readable.on('end', () => {
      +  console.log('Reached end of stream.');
       });

      Each call to readable.read() returns a chunk of data, or null. The chunks are not concatenated. A while loop is necessary to consume all data @@ -1236,15 +1317,15 @@ emitted when there is no more data to come.

      to collect chunks across multiple 'readable' events:

      const chunks = [];
       
      -readable.on('readable', () => {
      +readable.on('readable', () => {
         let chunk;
      -  while (null !== (chunk = readable.read())) {
      -    chunks.push(chunk);
      +  while (null !== (chunk = readable.read())) {
      +    chunks.push(chunk);
         }
       });
       
      -readable.on('end', () => {
      -  const content = chunks.join('');
      +readable.on('end', () => {
      +  const content = chunks.join('');
       });

      A Readable stream in object mode will always return a single item from a call to readable.read(size), regardless of the value of the @@ -1253,15 +1334,26 @@ a call to readable.read(size)< also be emitted.

      Calling stream.read([size]) after the 'end' event has been emitted will return null. No runtime error will be raised.

      -
      readable.readable#
      +
      readable.readable#
      -

      Is true if it is safe to call readable.read().

      -
      readable.readableEncoding#
      +

      Is true if it is safe to call readable.read(), which means +the stream has not been destroyed or emitted 'error' or 'end'.

      +
      readable.readableDidRead#
      + + +

      Allows determining if the stream has been or is about to be read. +Returns true if 'data', 'end', 'error' or 'close' has been +emitted.

      +
      readable.readableEncoding#
      @@ -1270,7 +1362,7 @@ been emitted will return null. No runtime error will be raised.

      Getter for the property encoding of a given Readable stream. The encoding property can be set using the readable.setEncoding() method.

      -
      readable.readableEnded#
      +
      readable.readableEnded#
      @@ -1278,7 +1370,7 @@ property can be set using the <boolean>

      Becomes true when 'end' event is emitted.

      -
      readable.readableFlowing#
      +
      readable.readableFlowing#
      @@ -1287,7 +1379,7 @@ property can be set using the

      This property reflects the current state of a Readable stream as described in the Three states section.

      -
      readable.readableHighWaterMark#
      +
      readable.readableHighWaterMark#
      @@ -1296,7 +1388,7 @@ in the Three states section.

      Returns the value of highWaterMark passed when constructing this Readable.

      -
      readable.readableLength#
      +
      readable.readableLength#
      @@ -1306,7 +1398,7 @@ in the Three states section.

      This property contains the number of bytes (or objects) in the queue ready to be read. The value provides introspection data regarding the status of the highWaterMark.

      -
      readable.readableObjectMode#
      +
      readable.readableObjectMode#
      @@ -1314,7 +1406,7 @@ the status of the highWaterMark.

    • <boolean>
    • Getter for the property objectMode of a given Readable stream.

      -
      readable.resume()#
      +
      readable.resume()#
      • error <Error>
      • @@ -1572,9 +1672,23 @@ Implementors should not override this method, but instead implement readable._destroy(). The default implementation of _destroy() for Transform also emit 'close' unless emitClose is set in false.

        -

        stream.finished(stream[, options], callback)#

        +

        Once destroy() has been called, any further calls will be a no-op and no +further errors except from _destroy() may be emitted as 'error'.

        +

        stream.finished(stream[, options], callback)#

        • stream <Stream> A readable and/or writable stream.
        • @@ -1599,56 +1713,86 @@ listeners. or has experienced an error or a premature close event.

          const { finished } = require('stream');
           
          -const rs = fs.createReadStream('archive.tar');
          +const rs = fs.createReadStream('archive.tar');
           
          -finished(rs, (err) => {
          +finished(rs, (err) => {
             if (err) {
          -    console.error('Stream failed.', err);
          +    console.error('Stream failed.', err);
             } else {
          -    console.log('Stream is done reading.');
          +    console.log('Stream is done reading.');
             }
           });
           
          -rs.resume(); // Drain the stream.
          +rs.resume(); // Drain the stream.

      Especially useful in error handling scenarios where a stream is destroyed prematurely (like an aborted HTTP request), and will not emit 'end' or 'finish'.

      The finished API is promisify-able as well;

      -
      const finished = util.promisify(stream.finished);
      +
      const finished = util.promisify(stream.finished);
       
      -const rs = fs.createReadStream('archive.tar');
      +const rs = fs.createReadStream('archive.tar');
       
      -async function run() {
      -  await finished(rs);
      -  console.log('Stream is done reading.');
      +async function run() {
      +  await finished(rs);
      +  console.log('Stream is done reading.');
       }
       
      -run().catch(console.error);
      -rs.resume(); // Drain the stream.
      +run().catch(console.error); +rs.resume(); // Drain the stream.

      stream.finished() leaves dangling event listeners (in particular 'error', 'end', 'finish' and 'close') after callback has been invoked. The reason for this is so that unexpected 'error' events (due to incorrect stream implementations) do not cause unexpected crashes. If this is unwanted behavior then the returned cleanup function needs to be invoked in the callback:

      -
      const cleanup = finished(rs, (err) => {
      -  cleanup();
      +
      const cleanup = finished(rs, (err) => {
      +  cleanup();
         // ...
       });
      -

      stream.pipeline(...streams, callback)#

      +

      stream.pipeline(source[, ...transforms], destination, callback)#

      +

      stream.pipeline(streams, callback)#

      -

      A module method to pipe between streams forwarding errors and properly cleaning -up and provide a callback when the pipeline is complete.

      +

      A module method to pipe between streams and generators forwarding errors and +properly cleaning up and provide a callback when the pipeline is complete.

      const { pipeline } = require('stream');
       const fs = require('fs');
       const zlib = require('zlib');
      @@ -1658,31 +1802,50 @@ up and provide a callback when the pipeline is complete.

      // A pipeline to gzip a potentially huge tar file efficiently: -pipeline( - fs.createReadStream('archive.tar'), - zlib.createGzip(), - fs.createWriteStream('archive.tar.gz'), +pipeline( + fs.createReadStream('archive.tar'), + zlib.createGzip(), + fs.createWriteStream('archive.tar.gz'), (err) => { if (err) { - console.error('Pipeline failed.', err); + console.error('Pipeline failed.', err); } else { - console.log('Pipeline succeeded.'); + console.log('Pipeline succeeded.'); } } );

      The pipeline API is promisify-able as well:

      -
      const pipeline = util.promisify(stream.pipeline);
      +
      const pipeline = util.promisify(stream.pipeline);
       
      -async function run() {
      -  await pipeline(
      -    fs.createReadStream('archive.tar'),
      -    zlib.createGzip(),
      -    fs.createWriteStream('archive.tar.gz')
      +async function run() {
      +  await pipeline(
      +    fs.createReadStream('archive.tar'),
      +    zlib.createGzip(),
      +    fs.createWriteStream('archive.tar.gz')
      +  );
      +  console.log('Pipeline succeeded.');
      +}
      +
      +run().catch(console.error);
      +

      The pipeline API also supports async generators:

      +
      const pipeline = util.promisify(stream.pipeline);
      +const fs = require('fs');
      +
      +async function run() {
      +  await pipeline(
      +    fs.createReadStream('lowercase.txt'),
      +    async function* (source) {
      +      source.setEncoding('utf8');  // Work with strings rather than `Buffer`s.
      +      for await (const chunk of source) {
      +        yield chunk.toUpperCase();
      +      }
      +    },
      +    fs.createWriteStream('uppercase.txt')
         );
      -  console.log('Pipeline succeeded.');
      +  console.log('Pipeline succeeded.');
       }
       
      -run().catch(console.error);
      +run().catch(console.error);

      stream.pipeline() will call stream.destroy(err) on all streams except:

      • Readable streams which have emitted 'end' or 'close'.
      • @@ -1691,7 +1854,7 @@ run().catch(console.error);

      stream.pipeline() leaves dangling event listeners on the streams after the callback has been invoked. In the case of reuse of streams after failure, this can cause event listener leaks and swallowed errors.

      -

      stream.Readable.from(iterable, [options])#

      +

      stream.Readable.from(iterable, [options])#

      @@ -1705,22 +1868,22 @@ this is explicitly opted out by setting options.objectMode to Returns: <stream.Readable>

      A utility method for creating readable streams out of iterators.

      -
      const { Readable } = require('stream');
      +
      const { Readable } = require('stream');
       
      -async function * generate() {
      +async function * generate() {
         yield 'hello';
         yield 'streams';
       }
       
      -const readable = Readable.from(generate());
      +const readable = Readable.from(generate());
       
      -readable.on('data', (chunk) => {
      -  console.log(chunk);
      +readable.on('data', (chunk) => {
      +  console.log(chunk);
       });

      Calling Readable.from(string) or Readable.from(buffer) will not have the strings or buffers be iterated to match the other streams semantics for performance reasons.

      -

      API for stream implementers#

      +

      API for stream implementers#

      The stream module API has been designed to make it possible to easily implement streams using JavaScript's prototypal inheritance model.

      @@ -1729,15 +1892,11 @@ of the four basic stream classes (stream.Writable, stream.Rea stream.Duplex, or stream.Transform), making sure they call the appropriate parent class constructor:

      -
      const { Writable } = require('stream');
      -
      -class MyWritable extends Writable {
      -  constructor({ highWaterMark, ...options }) {
      -    super({
      -      highWaterMark,
      -      autoDestroy: true,
      -      emitClose: true
      -    });
      +
      const { Writable } = require('stream');
      +
      +class MyWritable extends Writable {
      +  constructor({ highWaterMark, ...options }) {
      +    super({ highWaterMark });
           // ...
         }
       }
      @@ -1790,7 +1949,7 @@ as 'error', 'data', 'end', 'finish' Doing so can break current and future stream invariants leading to behavior and/or compatibility issues with other streams, stream utilities, and user expectations.

      -

      Simplified construction#

      +

      Simplified construction#

      @@ -1798,24 +1957,26 @@ expectations.

      inheritance. This can be accomplished by directly creating instances of the stream.Writable, stream.Readable, stream.Duplex or stream.Transform objects and passing appropriate methods as constructor options.

      -
      const { Writable } = require('stream');
      +
      const { Writable } = require('stream');
       
      -const myWritable = new Writable({
      -  write(chunk, encoding, callback) {
      +const myWritable = new Writable({
      +  write(chunk, encoding, callback) {
           // ...
         }
       });
      -

      Implementing a writable stream#

      +

      Implementing a writable stream#

      The stream.Writable class is extended to implement a Writable stream.

      Custom Writable streams must call the new stream.Writable([options]) constructor and implement the writable._write() and/or writable._writev() method.

      -

      new stream.Writable([options])#

      +
      new stream.Writable([options])#

      tls.connect(path[, options][, callback])#

      @@ -1529,7 +1566,7 @@ socket.on('end', ()

      Same as tls.connect() except that path can be provided as an argument instead of an option.

      A path option, if specified, will take precedence over the path argument.

      -

      tls.connect(port[, host][, options][, callback])#

      +

      tls.connect(port[, host][, options][, callback])#

      @@ -1544,7 +1581,7 @@ as an argument instead of an option.

      as arguments instead of options.

      A port or host option, if specified, will take precedence over any port or host argument.

      -

      tls.createSecureContext([options])#

      +

      tls.createSecureContext([options])#

      -

      Legacy urlObject#

      +

      Stability: 3 - Legacy: Use the WHATWG URL API instead.

      +

      Legacy urlObject#

      -

      Stability: 0 - Deprecated: Use the WHATWG URL API instead.

      +

      Stability: 3 - Legacy: Use the WHATWG URL API instead.

      The legacy urlObject (require('url').Url) is created and returned by the url.parse() function.

      -

      urlObject.auth#

      +
      urlObject.auth#

      The auth property is the username and password portion of the URL, also referred to as userinfo. This string subset follows the protocol and double slashes (if present) and precedes the host component, delimited by @. The string is either the username, or it is the username and password separated by :.

      For example: 'user:pass'.

      -

      urlObject.hash#

      +
      urlObject.hash#

      The hash property is the fragment identifier portion of the URL including the leading # character.

      For example: '#hash'.

      -

      urlObject.host#

      +
      urlObject.host#

      The host property is the full lower-cased host portion of the URL, including the port if specified.

      For example: 'sub.example.com:8080'.

      -

      urlObject.hostname#

      +
      urlObject.hostname#

      The hostname property is the lower-cased host name portion of the host component without the port included.

      For example: 'sub.example.com'.

      -

      urlObject.href#

      +
      urlObject.href#

      The href property is the full URL string that was parsed with both the protocol and host components converted to lower-case.

      For example: 'http://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'.

      -

      urlObject.path#

      +
      urlObject.path#

      The path property is a concatenation of the pathname and search components.

      For example: '/p/a/t/h?query=string'.

      No decoding of the path is performed.

      -

      urlObject.pathname#

      +
      urlObject.pathname#

      The pathname property consists of the entire path section of the URL. This is everything following the host (including the port) and before the start of the query or hash components, delimited by either the ASCII question mark (?) or hash (#) characters.

      For example: '/p/a/t/h'.

      No decoding of the path string is performed.

      -

      urlObject.port#

      +
      urlObject.port#

      The port property is the numeric port portion of the host component.

      For example: '8080'.

      -

      urlObject.protocol#

      +
      urlObject.protocol#

      The protocol property identifies the URL's lower-cased protocol scheme.

      For example: 'http:'.

      -

      urlObject.query#

      +
      urlObject.query#

      The query property is either the query string without the leading ASCII question mark (?), or an object returned by the querystring module's parse() method. Whether the query property is a string or object is @@ -1096,20 +1226,22 @@ determined by the parseQueryString argument passed to url.par

      For example: 'query=string' or {'query': 'string'}.

      If returned as a string, no decoding of the query string is performed. If returned as an object, both keys and values are decoded.

      -

      urlObject.search#

      +
      urlObject.search#

      The search property consists of the entire "query string" portion of the URL, including the leading ASCII question mark (?) character.

      For example: '?query=string'.

      No decoding of the query string is performed.

      -

      urlObject.slashes#

      +
      urlObject.slashes#

      The slashes property is a boolean with a value of true if two ASCII forward-slash characters (/) are required following the colon in the protocol.

      -

      url.format(urlObject)#

      +

      url.format(urlObject)#

      -

      Stability: 0 - Deprecated: Use the WHATWG URL API instead.

      +

      Stability: 3 - Legacy: Use the WHATWG URL API instead.

      • urlObject <Object> | <string> A URL object (as returned by url.parse() or constructed otherwise). If a string, it is converted to an object by passing @@ -1127,7 +1259,8 @@ it to url.parse().

      The url.format() method returns a formatted URL string derived from urlObject.

      -
      url.format({
      +
      const url = require('url');
      +url.format({
         protocol: 'https',
         hostname: 'example.com',
         pathname: '/some/path',
      @@ -1210,11 +1343,13 @@ character, the literal string # is appended to result.
       string, an Error is thrown.
       
    • result is returned.
    • -

      url.parse(urlString[, parseQueryString[, slashesDenoteHost]])#

      +

      url.parse(urlString[, parseQueryString[, slashesDenoteHost]])#

      -

      Stability: 0 - Deprecated: Use the WHATWG URL API instead.

      +

      Stability: 3 - Legacy: Use the WHATWG URL API instead.

      • urlString <string> The URL string to parse.
      • parseQueryString <boolean> If true, the query property will always @@ -1248,25 +1383,27 @@ use the WHATWG URL API. Because the url.parse() method lenient, non-standard algorithm for parsing URL strings, security issues can be introduced. Specifically, issues with host name spoofing and incorrect handling of usernames and passwords have been identified.

        -

        url.resolve(from, to)#

        +

        url.resolve(from, to)#

        -

        Stability: 0 - Deprecated: Use the WHATWG URL API instead.

        +

        Stability: 3 - Legacy: Use the WHATWG URL API instead.

        • from <string> The Base URL being resolved against.
        • to <string> The HREF URL being resolved.
        • @@ -1274,22 +1411,36 @@ incorrect handling of usernames and passwords have been identified.

          The url.resolve() method resolves a target URL relative to a base URL in a manner similar to that of a Web browser resolving an anchor tag HREF.

          const url = require('url');
          -url.resolve('/one/two/three', 'four');         // '/one/two/four'
          -url.resolve('http://example.com/', '/one');    // 'http://example.com/one'
          -url.resolve('http://example.com/one', '/two'); // 'http://example.com/two'
          +url.resolve('/one/two/three', 'four'); // '/one/two/four' +url.resolve('http://example.com/', '/one'); // 'http://example.com/one' +url.resolve('http://example.com/one', '/two'); // 'http://example.com/two'
      +

      You can achieve the same result using the WHATWG URL API:

      +
      function resolve(from, to) {
      +  const resolvedUrl = new URL(to, new URL(from, 'resolve://'));
      +  if (resolvedUrl.protocol === 'resolve:') {
      +    // `from` is a relative URL.
      +    const { pathname, search, hash } = resolvedUrl;
      +    return pathname + search + hash;
      +  }
      +  return resolvedUrl.toString();
      +}
      +
      +resolve('/one/two/three', 'four');         // '/one/two/four'
      +resolve('http://example.com/', '/one');    // 'http://example.com/one'
      +resolve('http://example.com/one', '/two'); // 'http://example.com/two'

      -

      Percent-encoding in URLs#

      +

      Percent-encoding in URLs#

      URLs are permitted to only contain a certain range of characters. Any character falling outside of that range must be encoded. How such characters are encoded, and which characters to encode depends entirely on where the character is located within the structure of the URL.

      -

      Legacy API#

      +

      Legacy API#

      Within the Legacy API, spaces (' ') and the following characters will be automatically escaped in the properties of URL objects:

      < > " ` \r \n \t { } | \ ^ '

      For example, the ASCII space character (' ') is encoded as %20. The ASCII forward slash (/) character is encoded as %3C.

      -

      WHATWG API#

      +

      WHATWG API#

      The WHATWG URL Standard uses a more selective and fine grained approach to selecting encoded characters than that used by the Legacy API.

      The WHATWG algorithm defines four "percent-encode sets" that describe ranges @@ -1322,14 +1473,50 @@ specific conditions, in addition to all other cases.

      When non-ASCII characters appear within a host name, the host name is encoded using the Punycode algorithm. Note, however, that a host name may contain both Punycode encoded and percent-encoded characters:

      -
      const myURL = new URL('https://%CF%80.example.com/foo');
      -console.log(myURL.href);
      +
      const myURL = new URL('https://%CF%80.example.com/foo');
      +console.log(myURL.href);
       // Prints https://xn--1xa.example.com/foo
      -console.log(myURL.origin);
      -// Prints https://xn--1xa.example.com
      +console.log(myURL.origin); +// Prints https://xn--1xa.example.com