diff --git a/.eslintignore b/.eslintignore index 80959ce611ee58..bdfdfaeab2388d 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,9 +1,7 @@ node_modules -lib/internal/v8.js lib/internal/v8_prof_polyfill.js lib/punycode.js test/addons/??_* -test/es-module/test-esm-dynamic-import.js test/fixtures test/message/esm_display_syntax_error.mjs tools/icu diff --git a/.eslintrc.js b/.eslintrc.js index 23ddc3c95cd39d..6dda76cb4ea985 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -58,6 +58,18 @@ module.exports = { 'arrow-spacing': ['error', { before: true, after: true }], 'block-spacing': 'error', 'brace-style': ['error', '1tbs', { allowSingleLine: true }], + 'capitalized-comments': ['error', 'always', { + line: { + // Ignore all lines that have less characters than 62 and all lines that + // start with something that looks like a variable name or code. + ignorePattern: '^.{0,62}$|^ [a-z]+ ?[0-9A-Z_.(/=:-]', + ignoreInlineComments: true, + ignoreConsecutiveComments: true + }, + block: { + ignorePattern: '.*' + } + }], 'comma-dangle': ['error', 'only-multiline'], 'comma-spacing': 'error', 'comma-style': 'error', diff --git a/CHANGELOG.md b/CHANGELOG.md index ec9307646c0bc2..29a5158bd74fc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,8 @@ release. -11.4.0
+11.5.0
+11.4.0
11.3.0
11.2.0
11.1.0
diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index d270903c2eadc3..193591381a108a 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -72,8 +72,7 @@ issues and pull requests can always be re-opened if necessary. A pull request is _author ready_ when: * There is a CI run in progress or completed. -* There are at least two Collaborator approvals, or at least one approval if the - pull request is older than 7 days. +* There is at least one Collaborator approval. * There are no outstanding review comments. Please always add the `author ready` label to the pull request in that case. @@ -147,56 +146,54 @@ the TSC meeting agenda. ### Waiting for Approvals -Before landing pull requests, sufficient time should be left for input -from other Collaborators. In general, leave at least 48 hours to account for -international time differences and work schedules. However, certain types of -pull requests can be fast-tracked and may be landed after a shorter delay. For -example: +Before landing pull requests, allow 48 hours for input from other Collaborators. +Certain types of pull requests can be fast-tracked and may land after a shorter +delay. For example: * Focused changes that affect only documentation and/or the test suite: - * `code-and-learn` tasks typically fall into this category. + * `code-and-learn` tasks often fall into this category. * `good-first-issue` pull requests may also be suitable. * Changes that fix regressions: * Regressions that break the workflow (red CI or broken compilation). * Regressions that happen right before a release, or reported soon after. -When a pull request is deemed suitable to be fast-tracked, label it with -`fast-track` and add a comment that collaborators may upvote. Please mention any -Collaborators that previously approved the pull request. If someone disagrees -with the fast-tracking request, remove the label and leave a comment indicating -why the pull request should not be fast-tracked. The pull request can be landed -once two or more Collaborators approve both the pull request and the -fast-tracking request, and the necessary CI testing is done. A request to -fast-track a PR made by a different Collaborator than the pull-request author -counts as a fast-track approval. +To propose fast-tracking a pull request, apply the `fast-track` label. Then add +a comment that Collaborators may upvote. + +If someone disagrees with the fast-tracking request, remove the label. Do not +fast-track the pull request in that case. + +The pull request may be fast-tracked if two Collaborators approve the +fast-tracking request. To land, the pull request itself still needs two +Collaborator approvals and a passing CI. + +Collaborators may request fast-tracking of pull requests they did not author. +In that case only, the request itself is also one fast-track approval. Upvote +the comment anyway to avoid any doubt. ### Testing and CI -All bugfixes require a test case which demonstrates the defect. The -test should *fail* before the change, and *pass* after the change. +All fixes must have a test case which demonstrates the defect. The test should +fail before the change, and pass after the change. -All pull requests that modify executable code should also include a test case -and must be subjected to continuous integration tests on the -[project CI server](https://ci.nodejs.org/). The pull request should have a CI -status indicator. +All pull requests must pass continuous integration tests on the +[project CI server](https://ci.nodejs.org/). -Do not land any Pull Requests without passing (green or yellow) CI runs. If you -believe any failed (red or grey) CI sub-tasks are unrelated to the change in the -Pull Request, use "Resume Build" in the left navigation of the relevant -`node-test-pull-request` job. It will create a new `node-test-pull-request` run -that preserves all the green results from the current job but re-runs everything -else. +Do not land any pull requests without passing (green or yellow) CI runs. If +there are CI failures unrelated to the change in the pull request, try "Resume +Build". It is in the left navigation of the relevant `node-test-pull-request` +job. It will preserve all the green results from the current job but re-run +everything else. #### Useful CI Jobs * [`node-test-pull-request`](https://ci.nodejs.org/job/node-test-pull-request/) -is the standard CI run we do to check Pull Requests. It triggers -`node-test-commit`, which runs the `build-ci` and `test-ci` targets on all -supported platforms. +is the CI job to test pull requests. It runs the `build-ci` and `test-ci` +targets on all supported platforms. * [`node-test-pull-request-lite-pipeline`](https://ci.nodejs.org/job/node-test-pull-request-lite-pipeline/) -only runs the linter job, as well as the tests on LinuxONE, which is very fast. -This is useful for changes that only affect comments or documentation. +runs the linter job. It also runs the tests on a very fast host. This is useful +for changes that only affect comments or documentation. * [`citgm-smoker`](https://ci.nodejs.org/job/citgm-smoker/) uses [`CitGM`](https://github.com/nodejs/citgm) to allow you to run @@ -205,69 +202,43 @@ useful to check whether a change will cause breakage in the ecosystem. To test Node.js ABI changes you can run [`citgm-abi-smoker`](https://ci.nodejs.org/job/citgm-abi-smoker/). * [`node-stress-single-test`](https://ci.nodejs.org/job/node-stress-single-test/) -is designed to allow one to run a group of tests over and over on a specific -platform to confirm that the test is reliable. +can run a group of tests over and over on a specific platform. Use it to check +that the tests are reliable. * [`node-test-commit-v8-linux`](https://ci.nodejs.org/job/node-test-commit-v8-linux/) -is designed to allow validation of changes to the copy of V8 in the Node.js -tree by running the standard V8 tests. It should be run whenever the -level of V8 within Node.js is updated or new patches are floated on V8. +runs the standard V8 tests. Run it when updating V8 in Node.js or floating new +patches on V8. * [`node-test-commit-custom-suites`](https://ci.nodejs.org/job/node-test-commit-custom-suites/) -can be used to customize what tests are run and with what parameters. For -example, it can be used to execute tests which are not executed in a typical -`node-test-commit` run (such as tests in the `internet` or `pummel` -directories). It can also be used to make sure tests pass when provided with a -flag not typically used in other CI test runs (such as `--worker`). +enables customization of test suites and parameters. It can execute test suites +not used in other CI test runs (such as tests in the `internet` or `pummel` +directories). It can also make sure tests pass when provided with a flag not +used in other CI test runs (such as `--worker`). ### Internal vs. Public API -Due to the nature of the JavaScript language, it can often be difficult to -establish a clear distinction between which parts of the Node.js implementation -represent the public API Node.js users should assume to be stable and which -are part of the internal implementation details of Node.js itself. A rule of -thumb is to base the determination off what functionality is actually -documented in the official Node.js API documentation. However, it has been -repeatedly demonstrated that either the documentation does not completely cover -implemented behavior or that Node.js users have come to rely heavily on -undocumented aspects of the Node.js implementation. - -The following general rules should be followed to determine which aspects of the -Node.js API are internal: - -- All functionality exposed via `process.binding(...)` is internal. -- All functionality implemented in `lib/internal/**/*.js` is internal unless it - is re-exported by code in `lib/*.js` or documented as part of the Node.js - Public API. -- Any object property or method whose key is a non-exported `Symbol` is an - internal property. -- Any object property or method whose key begins with the underscore `_` prefix - is internal unless it is documented as part of the Node.js Public API. -- Any object, property, method, argument, behavior, or event not documented in - the Node.js documentation is internal. -- Any native C/C++ APIs/ABIs exported by the Node.js `*.h` header files that - are hidden behind the `NODE_WANT_INTERNALS` flag are internal. - -Exceptions can be made if use or behavior of a given internal API can be -demonstrated to be sufficiently relied upon by the Node.js ecosystem such that -any changes would cause too much breakage. The threshold for what qualifies as -too much breakage is to be decided on a case-by-case basis by the TSC. - -If it is determined that a currently undocumented object, property, method, -argument, or event *should* be documented, then a pull request adding the -documentation is required in order for it to be considered part of the public -API. - -Making a determination about whether something *should* be documented can be -difficult and will need to be handled on a case-by-case basis. For instance, if -one documented API cannot be used successfully without the use of a second -*currently undocumented* API, then the second API *should* be documented. If -using an API in a manner currently undocumented achieves a particular useful -result, a decision will need to be made whether or not that falls within the -supported scope of that API; and if it does, it should be documented. - -See [Breaking Changes to Internal Elements](#breaking-changes-to-internal-elements) -on how to handle those types of changes. +All functionality in the official Node.js documentation is part of the public +API. Any undocumented object, property, method, argument, behavior, or event is +internal. There are exceptions to this rule. Node.js users have come to rely on +some undocumented behaviors. Collaborators treat many of those undocumented +behaviors as public. + +All undocumented functionality exposed via `process.binding(...)` is internal. + +All undocumented functionality in `lib/internal/**/*.js` is internal. It is +public, though, if it is re-exported by code in `lib/*.js`. + +Non-exported `Symbol` properties and methods are internal. + +Any undocumented object property or method that begins with `_` is internal. + +Any native C/C++ APIs/ABIs requiring the `NODE_WANT_INTERNALS` flag are +internal. + +Sometimes, there is disagreement about whether functionality is internal or +public. In those cases, the TSC makes a determination. + +For undocumented APIs that are public, open a pull request documenting the API. ### Breaking Changes diff --git a/LICENSE b/LICENSE index 59958b20e24a06..acb8712a8f7e29 100644 --- a/LICENSE +++ b/LICENSE @@ -76,7 +76,7 @@ The externally maintained libraries used by Node.js are: - c-ares, located at deps/cares, is licensed as follows: """ - Copyright (c) 2007 - 2016, Daniel Stenberg with many contributors, see AUTHORS + Copyright (c) 2007 - 2018, Daniel Stenberg with many contributors, see AUTHORS file. Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/Makefile b/Makefile index 6dfc1de6af5833..3cbf6118a91e96 100644 --- a/Makefile +++ b/Makefile @@ -1263,10 +1263,14 @@ tools/.cpplintstamp: $(LINT_CPP_FILES) @$(PYTHON) tools/check-imports.py @touch $@ -lint-addon-docs: test/addons/.docbuildstamp +.PHONY: lint-addon-docs +lint-addon-docs: tools/.doclintstamp + +tools/.doclintstamp: test/addons/.docbuildstamp @echo "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" @@ -1286,7 +1290,7 @@ ifneq ("","$(wildcard tools/pip/site-packages)") lint-py: PYTHONPATH=tools/pip $(PYTHON) -m flake8 . \ --count --show-source --statistics --select=E901,E999,F821,F822,F823 \ - --exclude=.git,deps,lib,src,tools/*_macros.py,tools/gyp,tools/jinja2,tools/pip + --exclude=.git,deps,lib,src,tools/*_macros.py,tools/gyp,tools/inspector_protocol,tools/jinja2,tools/markupsafe,tools/pip else lint-py: @echo "Python linting with flake8 is not avalible" diff --git a/README.md b/README.md index 1835c51cc6e252..34d65f8f1f7a41 100644 --- a/README.md +++ b/README.md @@ -50,11 +50,10 @@ If you didn't find an answer in the resources above, try these unofficial resources: * [Questions tagged 'node.js' on StackOverflow][] -* [#node.js channel on chat.freenode.net][]. See for more - information. +* [#node.js channel on chat.freenode.net][] * [Node.js Discord Community](https://discordapp.com/invite/v7rrPdE) -* [Node.js Slack Community](https://node-js.slack.com/): Visit - [nodeslackers.com](http://www.nodeslackers.com/) to register. +* [Node.js Slack Community](https://node-js.slack.com/) + * To register: [nodeslackers.com](http://www.nodeslackers.com/) GitHub issues are for tracking enhancements and bugs, not general support. @@ -552,11 +551,14 @@ GPG keys used to sign Node.js releases: `DD8F2338BAE7501E3DD5AC78C273792F7D83545D` * **Ruben Bridgewater** <ruben@bridgewater.de> `A48C2BEE680E841632CD4E44F07496B3EB3C1762` +* **Shelley Vohr** <shelley.vohr@gmail.com> +`B9E2F5981AA6E0CD28160D9FF13993A75599653C` To import the full set of trusted release keys: ```shell gpg --keyserver pool.sks-keyservers.net --recv-keys 4ED778F539E3634C779C87C6D7062848A1AB005C +gpg --keyserver pool.sks-keyservers.net --recv-keys B9E2F5981AA6E0CD28160D9FF13993A75599653C gpg --keyserver pool.sks-keyservers.net --recv-keys 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 gpg --keyserver pool.sks-keyservers.net --recv-keys B9AE9905FFD7803F25714661B63B535A4C206CA9 gpg --keyserver pool.sks-keyservers.net --recv-keys 77984A986EBC2AA786BC0F66B01FBB92821C587A diff --git a/benchmark/_cli.js b/benchmark/_cli.js index 4d92b05b1b82b4..0c39c0b1931f48 100644 --- a/benchmark/_cli.js +++ b/benchmark/_cli.js @@ -49,7 +49,7 @@ function CLI(usage, settings) { this.optional[currentOptional] = true; mode = 'both'; } else { - // expect the next value to be option related (either -- or the value) + // Expect the next value to be option related (either -- or the value) mode = 'option'; } } else if (mode === 'option') { diff --git a/benchmark/child_process/child-process-exec-stdout.js b/benchmark/child_process/child-process-exec-stdout.js index 88c02533f605c2..a1dc4aa04c72a9 100644 --- a/benchmark/child_process/child-process-exec-stdout.js +++ b/benchmark/child_process/child-process-exec-stdout.js @@ -31,7 +31,7 @@ function childProcessExecStdout({ dur, len }) { try { execSync(`taskkill /f /t /pid ${child.pid}`); } catch { - // this is a best effort kill. stderr is piped to parent for tracing. + // This is a best effort kill. stderr is piped to parent for tracing. } } else { child.kill(); diff --git a/benchmark/common.js b/benchmark/common.js index d5e0494c16e826..521a145997a8a4 100644 --- a/benchmark/common.js +++ b/benchmark/common.js @@ -146,7 +146,7 @@ Benchmark.prototype._run = function() { (function recursive(queueIndex) { const config = self.queue[queueIndex]; - // set NODE_RUN_BENCHMARK_FN to indicate that the child shouldn't construct + // Set NODE_RUN_BENCHMARK_FN to indicate that the child shouldn't construct // a configuration queue, but just execute the benchmark function. const childEnv = Object.assign({}, process.env); childEnv.NODE_RUN_BENCHMARK_FN = ''; @@ -187,7 +187,7 @@ Benchmark.prototype.start = function() { }; Benchmark.prototype.end = function(operations) { - // get elapsed time now and do error checking later for accuracy. + // Get elapsed time now and do error checking later for accuracy. const elapsed = process.hrtime(this._time); if (!this._started) { diff --git a/benchmark/crypto/cipher-stream.js b/benchmark/crypto/cipher-stream.js index 9f986dfb36b60d..c9989d32dcd20a 100644 --- a/benchmark/crypto/cipher-stream.js +++ b/benchmark/crypto/cipher-stream.js @@ -58,7 +58,7 @@ function main({ api, cipher, type, len, writes }) { const fn = api === 'stream' ? streamWrite : legacyWrite; - // write data as fast as possible to alice, and have bob decrypt. + // Write data as fast as possible to alice, and have bob decrypt. // use old API for comparison to v0.8 bench.start(); fn(alice_cipher, bob_cipher, message, encoding, writes); diff --git a/benchmark/dgram/array-vs-concat.js b/benchmark/dgram/array-vs-concat.js index a7843a9c7f7c28..c73c9538589540 100644 --- a/benchmark/dgram/array-vs-concat.js +++ b/benchmark/dgram/array-vs-concat.js @@ -1,4 +1,4 @@ -// test UDP send throughput with the multi buffer API against Buffer.concat +// Test UDP send throughput with the multi buffer API against Buffer.concat 'use strict'; const common = require('../common.js'); diff --git a/benchmark/dgram/offset-length.js b/benchmark/dgram/offset-length.js index 8a2df9ac67c1b6..7c78765cee0d09 100644 --- a/benchmark/dgram/offset-length.js +++ b/benchmark/dgram/offset-length.js @@ -1,4 +1,4 @@ -// test UDP send/recv throughput with the "old" offset/length API +// Test UDP send/recv throughput with the "old" offset/length API 'use strict'; const common = require('../common.js'); diff --git a/benchmark/napi/function_call/index.js b/benchmark/napi/function_call/index.js index 59063e500f7a84..e7d9fe46e54636 100644 --- a/benchmark/napi/function_call/index.js +++ b/benchmark/napi/function_call/index.js @@ -7,7 +7,7 @@ const assert = require('assert'); const common = require('../../common.js'); -// this fails when we try to open with a different version of node, +// This fails when we try to open with a different version of node, // which is quite common for benchmarks. so in that case, just // abort quietly. diff --git a/benchmark/net/net-wrap-js-stream-passthrough.js b/benchmark/net/net-wrap-js-stream-passthrough.js index c4d11fa56c7411..0e76281b25e927 100644 --- a/benchmark/net/net-wrap-js-stream-passthrough.js +++ b/benchmark/net/net-wrap-js-stream-passthrough.js @@ -1,4 +1,4 @@ -// test the speed of .pipe() with JSStream wrapping for PassThrough streams +// Test the speed of .pipe() with JSStream wrapping for PassThrough streams 'use strict'; const common = require('../common.js'); diff --git a/configure.py b/configure.py index 1bef01baef5fbc..ca870824248532 100755 --- a/configure.py +++ b/configure.py @@ -655,8 +655,8 @@ def try_check_compiler(cc, lang): values = (proc.communicate()[0].split() + ['0'] * 7)[0:7] is_clang = values[0] == '1' - gcc_version = tuple(values[1:1+3]) - clang_version = tuple(values[4:4+3]) + gcc_version = tuple(map(int, values[1:1+3])) + clang_version = tuple(map(int, values[4:4+3])) if is_clang else None return (True, is_clang, clang_version, gcc_version) @@ -753,6 +753,8 @@ def check_compiler(o): ok, is_clang, clang_version, gcc_version = try_check_compiler(CXX, 'c++') if not ok: warn('failed to autodetect C++ compiler version (CXX=%s)' % CXX) + elif sys.platform.startswith('aix') and gcc_version < (6, 3, 0): + warn('C++ compiler too old, need g++ 6.3.0 (CXX=%s)' % CXX) elif clang_version < (3, 4, 2) if is_clang else gcc_version < (4, 9, 4): warn('C++ compiler too old, need g++ 4.9.4 or clang++ 3.4.2 (CXX=%s)' % CXX) @@ -921,8 +923,7 @@ def gcc_version_ge(version_checked): for compiler in [(CC, 'c'), (CXX, 'c++')]: ok, is_clang, clang_version, compiler_version = \ try_check_compiler(compiler[0], compiler[1]) - compiler_version_num = tuple(map(int, compiler_version)) - if is_clang or compiler_version_num < version_checked: + if is_clang or compiler_version < version_checked: return False return True diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md index ad7a94736ff540..587a74c3d06caa 100644 --- a/doc/api/async_hooks.md +++ b/doc/api/async_hooks.md @@ -61,12 +61,12 @@ asyncHook.disable(); // resource referenced by "asyncId" may not have been populated. function init(asyncId, type, triggerAsyncId, resource) { } -// before is called just before the resource's callback is called. It can be +// 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). function before(asyncId) { } -// after is called just after the resource's callback has finished. +// After is called just after the resource's callback has finished. function after(asyncId) { } // destroy is called when an AsyncWrap instance is destroyed. @@ -159,7 +159,7 @@ const fs = require('fs'); const util = require('util'); function debug(...args) { - // use a function like this one when debugging inside an AsyncHooks callback + // Use a function like this one when debugging inside an AsyncHooks callback fs.writeFileSync('log.out', `${util.format(...args)}\n`, { flag: 'a' }); } ``` diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 3e1de25f750feb..736ac360c903d7 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -772,7 +772,7 @@ const uncompressedKey = ECDH.convertKey(compressedKey, 'hex', 'uncompressed'); -// the converted key and the uncompressed public key should be the same +// The converted key and the uncompressed public key should be the same console.log(uncompressedKey === ecdh.getPublicKey('hex')); ``` diff --git a/doc/api/domain.md b/doc/api/domain.md index eec763600e228f..3a1027f07b8afa 100644 --- a/doc/api/domain.md +++ b/doc/api/domain.md @@ -143,7 +143,7 @@ if (cluster.isMaster) { // a new worker. cluster.worker.disconnect(); - // try to send an error to the request that triggered the problem + // Try to send an error to the request that triggered the problem res.statusCode = 500; res.setHeader('content-type', 'text/plain'); res.end('Oops, there was a problem!\n'); diff --git a/doc/api/errors.md b/doc/api/errors.md index 1c16e05de84ac2..05ecad70214fb4 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -371,7 +371,7 @@ range, or outside the set of options for a given function parameter. ```js require('net').connect(-1); -// throws "RangeError: "port" option should be >= 0 and < 65536: -1" +// Throws "RangeError: "port" option should be >= 0 and < 65536: -1" ``` Node.js will generate and throw `RangeError` instances *immediately* as a form @@ -388,7 +388,7 @@ will do so. ```js doesNotExist; -// throws ReferenceError, doesNotExist is not a variable in this program. +// Throws ReferenceError, doesNotExist is not a variable in this program. ``` Unless an application is dynamically generating and running code, diff --git a/doc/api/events.md b/doc/api/events.md index aafdbcf735bee5..4fcaeb3211c4f2 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -638,14 +638,14 @@ emitter.once('log', () => console.log('log once')); const listeners = emitter.rawListeners('log'); const logFnWrapper = listeners[0]; -// logs "log once" to the console and does not unbind the `once` event +// 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 +// Will return a new Array with a single function bound by `.on()` above const newListeners = emitter.rawListeners('log'); // logs "log persistently" twice diff --git a/doc/api/fs.md b/doc/api/fs.md index fcd42fd19af1cd..01d537d8e3b40d 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1926,7 +1926,7 @@ console.log(fs.readFileSync('temp.txt', 'utf8')); // get the file descriptor of the file to be truncated const fd = fs.openSync('temp.txt', 'r+'); -// truncate the file to 10 bytes, whereas the actual size is 7 bytes +// Truncate the file to 10 bytes, whereas the actual size is 7 bytes fs.ftruncate(fd, 10, (err) => { assert.ifError(err); console.log(fs.readFileSync('temp.txt')); diff --git a/doc/api/http.md b/doc/api/http.md index aaeb9403ff499b..63f4c58a85d9bd 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -129,6 +129,8 @@ added: v0.3.4 * `timeout` {number} Socket timeout in milliseconds. This will set the timeout after the socket is connected. +`options` in [`socket.connect()`][] are also supported. + The default [`http.globalAgent`][] that is used by [`http.request()`][] has all of these values set to their respective defaults. @@ -2075,9 +2077,9 @@ will be emitted in the following order: * `'socket'` * (`req.abort()` called here) * `'abort'` -* `'close'` * `'error'` with an error with message `'Error: socket hang up'` and code `'ECONNRESET'` +* `'close'` If `req.abort()` is called after the response is received, the following events will be emitted in the following order: @@ -2087,10 +2089,10 @@ will be emitted in the following order: * `'data'` any number of times, on the `res` object * (`req.abort()` called here) * `'abort'` +* `'aborted'` on the `res` object * `'close'` - * `'aborted'` on the `res` object - * `'end'` on the `res` object - * `'close'` on the `res` object +* `'end'` on the `res` object +* `'close'` on the `res` object Note that setting the `timeout` option or using the `setTimeout()` function will not abort the request or do anything besides add a `'timeout'` event. @@ -2139,6 +2141,7 @@ not abort the request or do anything besides add a `'timeout'` event. [`server.listen()`]: net.html#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 diff --git a/doc/api/modules.md b/doc/api/modules.md index 28a13fb36dc4b9..5292d2389760bd 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -49,7 +49,7 @@ console.log(`The area of mySquare is ${mySquare.area()}`); The `square` module is defined in `square.js`: ```js -// assigning to exports will not modify module, must use module.exports +// Assigning to exports will not modify module, must use module.exports module.exports = class Square { constructor(width) { this.width = width; diff --git a/doc/api/process.md b/doc/api/process.md index 64d93a87603ef6..818bb6ed4ab73c 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -286,7 +286,7 @@ The listener function is called with the following arguments: ```js process.on('unhandledRejection', (reason, p) => { console.log('Unhandled Rejection at:', p, 'reason:', reason); - // application specific logging, throwing an error, or other logic here + // Application specific logging, throwing an error, or other logic here }); somePromise.then((res) => { diff --git a/doc/api/stream.md b/doc/api/stream.md index 5441cb03724d05..c1f23adae5a30b 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -131,7 +131,7 @@ const server = http.createServer((req, res) => { body += chunk; }); - // the 'end' event indicates that the entire body has been received + // The 'end' event indicates that the entire body has been received req.on('end', () => { try { const data = JSON.parse(body); diff --git a/doc/api/tls.md b/doc/api/tls.md index 89f0021d740111..d16af379e12f82 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -1054,6 +1054,9 @@ argument. * `maxArrayLength` {integer} Specifies the maximum number of `Array`, [`TypedArray`][], [`WeakMap`][] and [`WeakSet`][] elements to include when formatting. Set to `null` or `Infinity` to show all elements. Set to `0` or @@ -454,6 +453,11 @@ changes: of an object and Set and Map entries will be sorted in the returned string. If set to `true` the [default sort][] is going to be used. If set to a function, it is used as a [compare function][]. + * `getters` {boolean|string} If set to `true`, getters are going to be + inspected as well. If set to `'get'` only getters without setter are going + to be inspected. If set to `'set'` only getters having a corresponding + setter are going to be inspected. This might cause side effects depending on + the getter function. **Default:** `false`. * Returns: {string} The representation of passed object The `util.inspect()` method returns a string representation of `object` that is diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index 0fc133376d35d4..d6c396d3ac69dd 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -109,7 +109,7 @@ const { MessageChannel } = require('worker_threads'); const { port1, port2 } = new MessageChannel(); port1.on('message', (message) => console.log('received', message)); port2.postMessage({ foo: 'bar' }); -// prints: received { foo: 'bar' } from the `port1.on('message')` listener +// Prints: received { foo: 'bar' } from the `port1.on('message')` listener ``` ## Class: MessagePort @@ -125,7 +125,7 @@ structured data, memory regions and other `MessagePort`s between different [`Worker`][]s. With the exception of `MessagePort`s being [`EventEmitter`][]s rather -than `EventTarget`s, this implementation matches [browser `MessagePort`][]s. +than [`EventTarget`][]s, this implementation matches [browser `MessagePort`][]s. ### Event: 'close' +* Extends: {EventEmitter} + The `Worker` class represents an independent JavaScript execution thread. Most Node.js APIs are available inside of it. @@ -306,10 +308,10 @@ if (isMainThread) { * `filename` {string} The path to the Worker’s main script. Must be either an absolute path or a relative path (i.e. relative to the current working directory) starting with `./` or `../`. - If `options.eval` is true, this is a string containing JavaScript code rather - than a path. + If `options.eval` is `true`, this is a string containing JavaScript code + rather than a path. * `options` {Object} - * `eval` {boolean} If true, interpret the first argument to the constructor + * `eval` {boolean} If `true`, interpret the first argument to the constructor as a script that is executed once the worker is online. * `workerData` {any} Any JavaScript value that will be cloned and made available as [`require('worker_threads').workerData`][]. The cloning will @@ -462,6 +464,7 @@ active handle in the event system. If the worker is already `unref()`ed calling [`Buffer`]: buffer.html [`EventEmitter`]: events.html +[`EventTarget`]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget [`MessagePort`]: #worker_threads_class_messageport [`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer [`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array diff --git a/doc/changelogs/CHANGELOG_V11.md b/doc/changelogs/CHANGELOG_V11.md index 3e0553fa837345..bbb8610acd43c6 100644 --- a/doc/changelogs/CHANGELOG_V11.md +++ b/doc/changelogs/CHANGELOG_V11.md @@ -9,6 +9,7 @@ +11.5.0
11.4.0
11.3.0
11.2.0
@@ -31,6 +32,106 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + +## 2018-12-18, Version 11.5.0 (Current), @BethGriggs + +### Notable Changes + +* **tls**: + * support "BEGIN TRUSTED CERTIFICATE" for ca: (Sam Roberts) [#24733](https://github.com/nodejs/node/pull/24733) +* **util**: + * add inspection getter option (Ruben Bridgewater) [#24852](https://github.com/nodejs/node/pull/24852) + +### Commits + * [[`bf4faf3ffc`](https://github.com/nodejs/node/commit/bf4faf3ffc)] - **assert,util**: harden comparison (Ruben Bridgewater) [#24831](https://github.com/nodejs/node/pull/24831) + * [[`302081bafc`](https://github.com/nodejs/node/commit/302081bafc)] - **build**: make lint-addon-docs run only if needed (Daniel Bevenius) [#24993](https://github.com/nodejs/node/pull/24993) + * [[`cc8a805e31`](https://github.com/nodejs/node/commit/cc8a805e31)] - **build**: fix compiler version detection (Richard Lau) [#24879](https://github.com/nodejs/node/pull/24879) + * [[`bde5df20d6`](https://github.com/nodejs/node/commit/bde5df20d6)] - **doc**: fix node.1 --http-parser sort order (cjihrig) [#25045](https://github.com/nodejs/node/pull/25045) + * [[`a9f239fb60`](https://github.com/nodejs/node/commit/a9f239fb60)] - **doc**: add EventTarget link to worker\_threads (Azard) [#25058](https://github.com/nodejs/node/pull/25058) + * [[`00ce972305`](https://github.com/nodejs/node/commit/00ce972305)] - **doc**: make README formatting more consistent (wenjun ye) [#25003](https://github.com/nodejs/node/pull/25003) + * [[`dbdea36190`](https://github.com/nodejs/node/commit/dbdea36190)] - **doc**: add codebytere's info to release team (Shelley Vohr) [#25022](https://github.com/nodejs/node/pull/25022) + * [[`877f8a0094`](https://github.com/nodejs/node/commit/877f8a0094)] - **doc**: revise internal vs. public API in Collaborator Guide (Rich Trott) [#24975](https://github.com/nodejs/node/pull/24975) + * [[`f0bcacdcc6`](https://github.com/nodejs/node/commit/f0bcacdcc6)] - **doc**: update a link of npm repository (Daijiro Wachi) [#24969](https://github.com/nodejs/node/pull/24969) + * [[`1e096291d6`](https://github.com/nodejs/node/commit/1e096291d6)] - **doc**: fix author-ready conflict (Ruben Bridgewater) [#25015](https://github.com/nodejs/node/pull/25015) + * [[`b2e6cbddd8`](https://github.com/nodejs/node/commit/b2e6cbddd8)] - **doc**: update Useful CI Jobs section of Collaborator Guide (Rich Trott) [#24916](https://github.com/nodejs/node/pull/24916) + * [[`9bfbb6822b`](https://github.com/nodejs/node/commit/9bfbb6822b)] - **doc**: add class worker documentation (yoshimoto koki) [#24849](https://github.com/nodejs/node/pull/24849) + * [[`0220cd3260`](https://github.com/nodejs/node/commit/0220cd3260)] - **doc**: remove bad link to irc info (Richard Lau) [#24967](https://github.com/nodejs/node/pull/24967) + * [[`a6a3829962`](https://github.com/nodejs/node/commit/a6a3829962)] - **doc**: simplify author ready (Ruben Bridgewater) [#24893](https://github.com/nodejs/node/pull/24893) + * [[`cda1da9200`](https://github.com/nodejs/node/commit/cda1da9200)] - **doc**: update "Testing and CI" in Collaborator Guide (Rich Trott) [#24884](https://github.com/nodejs/node/pull/24884) + * [[`81dce68a9d`](https://github.com/nodejs/node/commit/81dce68a9d)] - **doc**: update http doc for new Agent()/support options in socket.connect() (Beni von Cheni) [#24846](https://github.com/nodejs/node/pull/24846) + * [[`643ca14d2c`](https://github.com/nodejs/node/commit/643ca14d2c)] - **doc**: fix order of events when request is aborted (Luigi Pinca) [#24779](https://github.com/nodejs/node/pull/24779) + * [[`c300aaa208`](https://github.com/nodejs/node/commit/c300aaa208)] - **doc**: update LICENSE file (Anna Henningsen) [#24898](https://github.com/nodejs/node/pull/24898) + * [[`c4f3cf9759`](https://github.com/nodejs/node/commit/c4f3cf9759)] - **doc**: revise Waiting for Approvals documentation (Rich Trott) [#24845](https://github.com/nodejs/node/pull/24845) + * [[`56b2a7274c`](https://github.com/nodejs/node/commit/56b2a7274c)] - **inspector**: split the HostPort being used and the one parsed from CLI (Joyee Cheung) [#24772](https://github.com/nodejs/node/pull/24772) + * [[`2456a545a6`](https://github.com/nodejs/node/commit/2456a545a6)] - **lib**: ensure readable stream flows to end (Mikko Rantanen) [#24918](https://github.com/nodejs/node/pull/24918) + * [[`79c52a9f88`](https://github.com/nodejs/node/commit/79c52a9f88)] - **lib**: improve error creation performance (Ruben Bridgewater) [#24747](https://github.com/nodejs/node/pull/24747) + * [[`25dae6cffd`](https://github.com/nodejs/node/commit/25dae6cffd)] - **module**: use validateString in modules/esm (ZYSzys) [#24868](https://github.com/nodejs/node/pull/24868) + * [[`2a11e6aaf3`](https://github.com/nodejs/node/commit/2a11e6aaf3)] - **module**: use validateString in modules/cjs (ZYSzys) [#24863](https://github.com/nodejs/node/pull/24863) + * [[`f4d5c358d9`](https://github.com/nodejs/node/commit/f4d5c358d9)] - **net**: use strict comparisons for fd (cjihrig) [#25014](https://github.com/nodejs/node/pull/25014) + * [[`5f60ed7647`](https://github.com/nodejs/node/commit/5f60ed7647)] - **path**: replace assertPath() with validator (cjihrig) [#24840](https://github.com/nodejs/node/pull/24840) + * [[`f43f45a26c`](https://github.com/nodejs/node/commit/f43f45a26c)] - **process**: properly close file descriptor on exit (Ruben Bridgewater) [#24972](https://github.com/nodejs/node/pull/24972) + * [[`8b109f05d9`](https://github.com/nodejs/node/commit/8b109f05d9)] - **process**: simplify check in previousValueIsValid() (cjihrig) [#24836](https://github.com/nodejs/node/pull/24836) + * [[`2e94f3b798`](https://github.com/nodejs/node/commit/2e94f3b798)] - **querystring**: remove eslint-disable (cjihrig) [#24995](https://github.com/nodejs/node/pull/24995) + * [[`5f8950b652`](https://github.com/nodejs/node/commit/5f8950b652)] - **src**: emit 'params' instead of 'data' for NodeTracing.dataCollected (Kelvin Jin) [#24949](https://github.com/nodejs/node/pull/24949) + * [[`d0270f3a5c`](https://github.com/nodejs/node/commit/d0270f3a5c)] - **src**: add GetLoadedLibraries routine (Gireesh Punathil) [#24825](https://github.com/nodejs/node/pull/24825) + * [[`f8547019c7`](https://github.com/nodejs/node/commit/f8547019c7)] - **src**: include node\_internals.h in node\_metadata.cc (Daniel Bevenius) [#24933](https://github.com/nodejs/node/pull/24933) + * [[`5a1289d128`](https://github.com/nodejs/node/commit/5a1289d128)] - **src**: create env-\>inspector\_console\_api\_object earlier (Joyee Cheung) [#24906](https://github.com/nodejs/node/pull/24906) + * [[`d7605725df`](https://github.com/nodejs/node/commit/d7605725df)] - **src**: remove use of CallOnForegroundThread() (cjihrig) [#24925](https://github.com/nodejs/node/pull/24925) + * [[`08c6b2126c`](https://github.com/nodejs/node/commit/08c6b2126c)] - **src**: use Local version of ToBoolean() (cjihrig) [#24924](https://github.com/nodejs/node/pull/24924) + * [[`5206f3add5`](https://github.com/nodejs/node/commit/5206f3add5)] - **src**: do not alias new and old signal masks (Sam Roberts) [#24810](https://github.com/nodejs/node/pull/24810) + * [[`94d02cabb9`](https://github.com/nodejs/node/commit/94d02cabb9)] - **src**: fix warning for potential snprintf truncation (Sam Roberts) [#24810](https://github.com/nodejs/node/pull/24810) + * [[`9b000e5088`](https://github.com/nodejs/node/commit/9b000e5088)] - **src**: remove finalized\_ member from Hash class (Daniel Bevenius) [#24822](https://github.com/nodejs/node/pull/24822) + * [[`90d481ea45`](https://github.com/nodejs/node/commit/90d481ea45)] - **src**: remove unused env variables in node\_util (Daniel Bevenius) [#24820](https://github.com/nodejs/node/pull/24820) + * [[`d449c36500`](https://github.com/nodejs/node/commit/d449c36500)] - **stream**: re-use existing `once()` implementation (Anna Henningsen) [#24991](https://github.com/nodejs/node/pull/24991) + * [[`39af61faa2`](https://github.com/nodejs/node/commit/39af61faa2)] - **stream**: fix end-of-stream for HTTP/2 (Anna Henningsen) [#24926](https://github.com/nodejs/node/pull/24926) + * [[`4f0d17b019`](https://github.com/nodejs/node/commit/4f0d17b019)] - **test**: remove unnecessary linter comment (cjihrig) [#25013](https://github.com/nodejs/node/pull/25013) + * [[`ab1801b8ad`](https://github.com/nodejs/node/commit/ab1801b8ad)] - **test**: use global.gc() instead of gc() (cjihrig) [#25012](https://github.com/nodejs/node/pull/25012) + * [[`ddff644172`](https://github.com/nodejs/node/commit/ddff644172)] - **test**: run eslint on test file and fix errors (Ruben Bridgewater) [#25009](https://github.com/nodejs/node/pull/25009) + * [[`110fd39dfe`](https://github.com/nodejs/node/commit/110fd39dfe)] - **test**: remove dead code (Ruben Bridgewater) [#25009](https://github.com/nodejs/node/pull/25009) + * [[`e04e85460f`](https://github.com/nodejs/node/commit/e04e85460f)] - **test**: use blocks instead of async IIFE (Anna Henningsen) [#24989](https://github.com/nodejs/node/pull/24989) + * [[`eb9e6e6576`](https://github.com/nodejs/node/commit/eb9e6e6576)] - **test**: adding history regression test case (Anto Aravinth) [#24843](https://github.com/nodejs/node/pull/24843) + * [[`ac919efbaf`](https://github.com/nodejs/node/commit/ac919efbaf)] - **test**: mark test-child-process-execfile flaky (Rich Trott) [#25051](https://github.com/nodejs/node/pull/25051) + * [[`1e3fb0ae03`](https://github.com/nodejs/node/commit/1e3fb0ae03)] - **test**: mark test-child-process-exit-code flaky (Rich Trott) [#25050](https://github.com/nodejs/node/pull/25050) + * [[`7e0dbc6e01`](https://github.com/nodejs/node/commit/7e0dbc6e01)] - **test**: improve WPT runner name matching (Joyee Cheung) [#24826](https://github.com/nodejs/node/pull/24826) + * [[`da984be0a3`](https://github.com/nodejs/node/commit/da984be0a3)] - **test**: remove reference to whatwg in file names under test/wpt (Joyee Cheung) [#24826](https://github.com/nodejs/node/pull/24826) + * [[`282589456c`](https://github.com/nodejs/node/commit/282589456c)] - **test**: mark test-worker-memory flaky on Windows CI (Rich Trott) [#25042](https://github.com/nodejs/node/pull/25042) + * [[`9bd42671c9`](https://github.com/nodejs/node/commit/9bd42671c9)] - **test**: mark test-cli-node-options flaky on arm (Rich Trott) [#25032](https://github.com/nodejs/node/pull/25032) + * [[`a4ef54a0a6`](https://github.com/nodejs/node/commit/a4ef54a0a6)] - **test**: mark test-child-process-execsync flaky on AIX (Rich Trott) [#25031](https://github.com/nodejs/node/pull/25031) + * [[`900a412f3f`](https://github.com/nodejs/node/commit/900a412f3f)] - **test**: increase error information in test-cli-syntax-\* (Rich Trott) [#25021](https://github.com/nodejs/node/pull/25021) + * [[`d5b0ce15d3`](https://github.com/nodejs/node/commit/d5b0ce15d3)] - **test**: refactor test-enable-in-init (Mitch Hankins) [#24976](https://github.com/nodejs/node/pull/24976) + * [[`649a7289dc`](https://github.com/nodejs/node/commit/649a7289dc)] - **test**: from functools import reduce in test/testpy/\_\_init\_\_.py (cclauss) [#24954](https://github.com/nodejs/node/pull/24954) + * [[`d366676cc5`](https://github.com/nodejs/node/commit/d366676cc5)] - **test**: split test-cli-syntax into multiple tests (Rich Trott) [#24922](https://github.com/nodejs/node/pull/24922) + * [[`e61bbda85d`](https://github.com/nodejs/node/commit/e61bbda85d)] - **test**: improve internet/test-dns (Ilarion Halushka) [#24927](https://github.com/nodejs/node/pull/24927) + * [[`016e35210c`](https://github.com/nodejs/node/commit/016e35210c)] - **(SEMVER-MINOR)** **test**: test TLS client authentication (Sam Roberts) [#24733](https://github.com/nodejs/node/pull/24733) + * [[`e050a5756f`](https://github.com/nodejs/node/commit/e050a5756f)] - **test**: replace callback with arrows (Shubham Urkade) [#24866](https://github.com/nodejs/node/pull/24866) + * [[`22b6befa14`](https://github.com/nodejs/node/commit/22b6befa14)] - **test**: mark test-cli-syntax as flaky/unreliable (Rich Trott) [#24957](https://github.com/nodejs/node/pull/24957) + * [[`56fd127ef0`](https://github.com/nodejs/node/commit/56fd127ef0)] - **test**: do not lint macros files (again) (cclauss) [#24886](https://github.com/nodejs/node/pull/24886) + * [[`bc71e9e0d6`](https://github.com/nodejs/node/commit/bc71e9e0d6)] - **test**: prepare test/pseudo-tty/testcfg.py Python 3 (cclauss) [#24887](https://github.com/nodejs/node/pull/24887) + * [[`f41443cc5c`](https://github.com/nodejs/node/commit/f41443cc5c)] - **test**: move test-cli-syntax to sequential (Rich Trott) [#24907](https://github.com/nodejs/node/pull/24907) + * [[`592bad1b0b`](https://github.com/nodejs/node/commit/592bad1b0b)] - **test**: move http2 test to parallel (Rich Trott) [#24877](https://github.com/nodejs/node/pull/24877) + * [[`91ce957037`](https://github.com/nodejs/node/commit/91ce957037)] - **test**: make http2 timeout test robust (Rich Trott) [#24877](https://github.com/nodejs/node/pull/24877) + * [[`3d87688fba`](https://github.com/nodejs/node/commit/3d87688fba)] - **test**: fix wrong parameter (zhmushan) [#24844](https://github.com/nodejs/node/pull/24844) + * [[`6db760c231`](https://github.com/nodejs/node/commit/6db760c231)] - **test**: improve test-net-socket-timeout (Rich Trott) [#24859](https://github.com/nodejs/node/pull/24859) + * [[`526ff1d1d2`](https://github.com/nodejs/node/commit/526ff1d1d2)] - **test**: prepare test/pseudo-tty/testcfg.py for Python 3 (cclauss) [#24791](https://github.com/nodejs/node/pull/24791) + * [[`a5c57861a9`](https://github.com/nodejs/node/commit/a5c57861a9)] - **test**: refactor test-fs-write-file-sync.js (cjihrig) [#24834](https://github.com/nodejs/node/pull/24834) + * [[`a5c8af7af4`](https://github.com/nodejs/node/commit/a5c8af7af4)] - **test**: prepare test/message/testcfg.py for Python 3 (cclauss) [#24793](https://github.com/nodejs/node/pull/24793) + * [[`390e050ae0`](https://github.com/nodejs/node/commit/390e050ae0)] - **(SEMVER-MINOR)** **tls**: support "BEGIN TRUSTED CERTIFICATE" for ca: (Sam Roberts) [#24733](https://github.com/nodejs/node/pull/24733) + * [[`16a75beffc`](https://github.com/nodejs/node/commit/16a75beffc)] - **tools**: prepare ./tools/compress\_json.py for Python 3 (cclauss) [#24889](https://github.com/nodejs/node/pull/24889) + * [[`b60808a2da`](https://github.com/nodejs/node/commit/b60808a2da)] - **tools**: prepare tools/testp.py for Python 3 (cclauss) [#24890](https://github.com/nodejs/node/pull/24890) + * [[`1f61c89a7f`](https://github.com/nodejs/node/commit/1f61c89a7f)] - **tools**: prepare tools/icu/icutrim.py for Python 3 (cclauss) [#24888](https://github.com/nodejs/node/pull/24888) + * [[`e140d41789`](https://github.com/nodejs/node/commit/e140d41789)] - **tools**: capitalize sentences (Ruben Bridgewater) [#24808](https://github.com/nodejs/node/pull/24808) + * [[`ad6104dbac`](https://github.com/nodejs/node/commit/ad6104dbac)] - **tools**: update ESLint to 5.10.0 (cjihrig) [#24903](https://github.com/nodejs/node/pull/24903) + * [[`ac46e27714`](https://github.com/nodejs/node/commit/ac46e27714)] - **tools**: do not lint tools/inspector\_protocol or tools/markupsafe (cclauss) [#24882](https://github.com/nodejs/node/pull/24882) + * [[`c3dda00e48`](https://github.com/nodejs/node/commit/c3dda00e48)] - **tools**: prepare tools/js2c.py for Python 3 (cclauss) [#24798](https://github.com/nodejs/node/pull/24798) + * [[`7cac76cdd5`](https://github.com/nodejs/node/commit/7cac76cdd5)] - **tools**: prepare tools/specialize\_node\_d.py for Python 3 (cclauss) [#24797](https://github.com/nodejs/node/pull/24797) + * [[`15632c3867`](https://github.com/nodejs/node/commit/15632c3867)] - **tools**: prepare tools/test.py for Python 3 (cclauss) [#24799](https://github.com/nodejs/node/pull/24799) + * [[`022599c0e1`](https://github.com/nodejs/node/commit/022599c0e1)] - **tools**: prepare tools/genv8constants.py for Python 3 (cclauss) [#24801](https://github.com/nodejs/node/pull/24801) + * [[`e7b77ead74`](https://github.com/nodejs/node/commit/e7b77ead74)] - **url**: remove an eslint-disable comment (cjihrig) [#24995](https://github.com/nodejs/node/pull/24995) + * [[`59317470e3`](https://github.com/nodejs/node/commit/59317470e3)] - **util**: inspect all prototypes (Ruben Bridgewater) [#24974](https://github.com/nodejs/node/pull/24974) + * [[`a1f0da1d40`](https://github.com/nodejs/node/commit/a1f0da1d40)] - **util**: remove todo (Ruben Bridgewater) [#24982](https://github.com/nodejs/node/pull/24982) + * [[`117e99121c`](https://github.com/nodejs/node/commit/117e99121c)] - **(SEMVER-MINOR)** **util**: add inspection getter option (Ruben Bridgewater) [#24852](https://github.com/nodejs/node/pull/24852) + * [[`331f6044b9`](https://github.com/nodejs/node/commit/331f6044b9)] - **worker**: drain messages from internal message port (Yael Hermon) [#24932](https://github.com/nodejs/node/pull/24932) + ## 2018-12-07, Version 11.4.0 (Current), @BridgeAR diff --git a/doc/guides/maintaining-npm.md b/doc/guides/maintaining-npm.md index 6017e78fded70a..67a4a9fcff6fd3 100644 --- a/doc/guides/maintaining-npm.md +++ b/doc/guides/maintaining-npm.md @@ -17,7 +17,7 @@ changes can be reviewed and landed via the normal consensus seeking process. ## Step 1: Clone npm ```console -$ git clone https://github.com/npm/npm.git +$ git clone https://github.com/npm/cli.git npm $ cd npm ``` diff --git a/doc/node.1 b/doc/node.1 index 7695c2011e309e..47d06233baa516 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -97,18 +97,18 @@ Enable experimental ES module support in VM module. .It Fl -experimental-worker Enable experimental worker threads using worker_threads module. . -.It Fl -http-parser Ns = Ns Ar library -Chooses an HTTP parser library. Available values are -.Sy llhttp -or -.Sy legacy . -. .It Fl -force-fips Force FIPS-compliant crypto on startup (Cannot be disabled from script code). Same requirements as .Fl -enable-fips . . +.It Fl -http-parser Ns = Ns Ar library +Chooses an HTTP parser library. Available values are +.Sy llhttp +or +.Sy legacy . +. .It Fl -icu-data-dir Ns = Ns Ar file Specify ICU data load path. Overrides diff --git a/doc/onboarding.md b/doc/onboarding.md index 133680a8cfb93a..5938803e531c95 100644 --- a/doc/onboarding.md +++ b/doc/onboarding.md @@ -96,11 +96,7 @@ onboarding session. `semver-major` label * When adding a `semver-*` label, add a comment explaining why you're adding it. Do it right away so you don't forget! - * Please add the `author-ready` label for PRs where: - * the CI has been started (not necessarily finished), - * no outstanding review comments exist and - * at least two Collaborators approved the PR (one Collaborator approval is - enough if the pull request has been open for more than 7 days). + * Please add the [`author-ready`][] label for PRs, if applicable. * See [Who to CC in the issue tracker][who-to-cc]. * This will come more naturally over time @@ -245,6 +241,7 @@ needs to be pointed out separately during the onboarding. the [summit](https://github.com/nodejs/summit) repository for details. [Code of Conduct]: https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md +[`author-ready`]: https://github.com/nodejs/node/blob/master/COLLABORATOR_GUIDE.md#author-ready-pull-requests [`core-validate-commit`]: https://github.com/nodejs/core-validate-commit [`git-node`]: https://github.com/nodejs/node-core-utils/blob/master/docs/git-node.md [`node-core-utils`]: https://github.com/nodejs/node-core-utils diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 97c5ab604ff821..e3d307133864f4 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -50,7 +50,7 @@ function Agent(options) { this.options = util._extend({}, options); - // don't confuse net and make it think that we're connecting to a pipe + // Don't confuse net and make it think that we're connecting to a pipe this.options.path = null; this.requests = {}; this.sockets = {}; diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index 04a36d2be2fde3..7395a02f331af0 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -387,7 +387,7 @@ function _storeHeader(firstLine, headers) { this._header = header + CRLF; this._headerSent = false; - // wait until the first body chunk, or close(), is sent to flush, + // Wait until the first body chunk, or close(), is sent to flush, // UNLESS we're sending Expect: 100-continue. if (state.expect) this._send(''); } @@ -445,7 +445,13 @@ function matchHeader(self, state, field, value) { function validateHeaderName(name) { if (typeof name !== 'string' || !name || !checkIsHttpToken(name)) { + // Reducing the limit improves the performance significantly. We do not + // lose the stack frames due to the `captureStackTrace()` function that is + // called later. + const tmpLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; const err = new ERR_INVALID_HTTP_TOKEN('Header name', name); + Error.stackTraceLimit = tmpLimit; Error.captureStackTrace(err, validateHeaderName); throw err; } @@ -453,12 +459,18 @@ function validateHeaderName(name) { function validateHeaderValue(name, value) { let err; + // Reducing the limit improves the performance significantly. We do not loose + // the stack frames due to the `captureStackTrace()` function that is called + // later. + const tmpLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; if (value === undefined) { err = new ERR_HTTP_INVALID_HEADER_VALUE(value, name); } else if (checkInvalidHeaderChar(value)) { debug('Header "%s" contains invalid characters', name); err = new ERR_INVALID_CHAR('header content', name); } + Error.stackTraceLimit = tmpLimit; if (err !== undefined) { Error.captureStackTrace(err, validateHeaderValue); throw err; diff --git a/lib/_http_server.js b/lib/_http_server.js index d54dcba7fcf55b..1dc44a4ce4c8b3 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -261,7 +261,7 @@ function writeHead(statusCode, reason, obj) { this._hasBody = false; } - // don't keep alive connections where the client expects 100 Continue + // Don't keep alive connections where the client expects 100 Continue // but we sent a final status; they may put extra bytes on the wire. if (this._expect_continue && !this._sent100) { this.shouldKeepAlive = false; diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 47dbae31b5f2c1..297c8190c2b36f 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -85,7 +85,7 @@ function ReadableState(options, stream, isDuplex) { if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; - // the point at which it stops calling _read() to fill the buffer + // The point at which it stops calling _read() to fill the buffer // Note: 0 is a valid value, means "don't call _read preemptively ever" this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex); @@ -102,7 +102,7 @@ function ReadableState(options, stream, isDuplex) { this.endEmitted = false; this.reading = false; - // a flag to be able to tell if the event 'readable'/'data' is emitted + // A flag to be able to tell if the event 'readable'/'data' is emitted // immediately, or on a later tick. We set this to true at first, because // any actions that shouldn't happen until "later" should generally also // not happen before the first read call. @@ -130,7 +130,7 @@ function ReadableState(options, stream, isDuplex) { // Everything else in the universe uses 'utf8', though. this.defaultEncoding = options.defaultEncoding || 'utf8'; - // the number of writers that are awaiting a drain event in .pipe()s + // The number of writers that are awaiting a drain event in .pipe()s this.awaitDrain = 0; // if true, a maybeReadMore has been scheduled @@ -373,7 +373,7 @@ function howMuchToRead(n, state) { return state.length; } -// you can override either this method, or the async _read(n) below. +// You can override either this method, or the async _read(n) below. Readable.prototype.read = function(n) { debug('read', n); n = parseInt(n, 10); @@ -435,13 +435,13 @@ Readable.prototype.read = function(n) { var doRead = state.needReadable; debug('need readable', doRead); - // if we currently have less than the highWaterMark, then also read some + // If we currently have less than the highWaterMark, then also read some if (state.length === 0 || state.length - n < state.highWaterMark) { doRead = true; debug('length less than watermark', doRead); } - // however, if we've ended, then there's no point, and if we're already + // However, if we've ended, then there's no point, and if we're already // reading, then it's unnecessary. if (state.ended || state.reading) { doRead = false; @@ -450,7 +450,7 @@ Readable.prototype.read = function(n) { debug('do read'); state.reading = true; state.sync = true; - // if the length is currently zero, then we *need* a readable event. + // If the length is currently zero, then we *need* a readable event. if (state.length === 0) state.needReadable = true; // call internal read method @@ -553,7 +553,7 @@ function emitReadable_(stream) { } -// at this point, the user has presumably seen the 'readable' event, +// At this point, the user has presumably seen the 'readable' event, // and called read() to consume some data. that may have triggered // in turn another _read(n) call, in which case reading = true if // it's in progress. @@ -567,21 +567,43 @@ function maybeReadMore(stream, state) { } function maybeReadMore_(stream, state) { - var len = state.length; + // Attempt to read more data if we should. + // + // The conditions for reading more data are (one of): + // - Not enough data buffered (state.length < state.highWaterMark). The loop + // is responsible for filling the buffer with enough data if such data + // is available. If highWaterMark is 0 and we are not in the flowing mode + // we should _not_ attempt to buffer any extra data. We'll get more data + // when the stream consumer calls read() instead. + // - No data in the buffer, and the stream is in flowing mode. In this mode + // the loop below is responsible for ensuring read() is called. Failing to + // call read here would abort the flow and there's no other mechanism for + // continuing the flow if the stream consumer has just subscribed to the + // 'data' event. + // + // In addition to the above conditions to keep reading data, the following + // conditions prevent the data from being read: + // - The stream has ended (state.ended). + // - There is already a pending 'read' operation (state.reading). This is a + // case where the the stream has called the implementation defined _read() + // method, but they are processing the call asynchronously and have _not_ + // called push() with new data. In this case we skip performing more + // read()s. The execution ends in this method again after the _read() ends + // up calling push() with more data. while (!state.reading && !state.ended && - state.length < state.highWaterMark) { + (state.length < state.highWaterMark || + (state.flowing && state.length === 0))) { + const len = state.length; debug('maybeReadMore read 0'); stream.read(0); if (len === state.length) // didn't get any data, stop spinning. break; - else - len = state.length; } state.readingMore = false; } -// abstract method. to be overridden in specific implementation classes. +// Abstract method. to be overridden in specific implementation classes. // call cb(er, data) where data is <= n in length. // for virtual (non-string, non-buffer) streams, "length" is somewhat // arbitrary, and perhaps not very meaningful. diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js index 679f79b80dfb35..af7f5347a52110 100644 --- a/lib/_stream_transform.js +++ b/lib/_stream_transform.js @@ -116,10 +116,10 @@ function Transform(options) { writeencoding: null }; - // start out asking for a readable event once data is transformed. + // Start out asking for a readable event once data is transformed. this._readableState.needReadable = true; - // we have implemented the _read method, and done the other things + // We have implemented the _read method, and done the other things // that Readable wants before the first _read call, so unset the // sync guard flag. this._readableState.sync = false; diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 022dcffdd78e28..0b013a01dd6196 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -90,7 +90,7 @@ function WritableState(options, stream, isDuplex) { // has it been destroyed this.destroyed = false; - // should we decode strings into buffers before passing to _write? + // Should we decode strings into buffers before passing to _write? // this is here so that some node-core streams can optimize string // handling at a lower level. var noDecode = options.decodeStrings === false; @@ -112,13 +112,13 @@ function WritableState(options, stream, isDuplex) { // when true all writes will be buffered until .uncork() call this.corked = 0; - // a flag to be able to tell if the onwrite cb is called immediately, + // A flag to be able to tell if the onwrite cb is called immediately, // or on a later tick. We set this to true at first, because any // actions that shouldn't happen until "later" should generally also // not happen before the first write call. this.sync = true; - // a flag to know if we're processing previously buffered items, which + // A flag to know if we're processing previously buffered items, which // may call the _write() callback in the same tick, so that we don't // end up in an overlapped onwrite situation. this.bufferProcessing = false; @@ -126,7 +126,7 @@ function WritableState(options, stream, isDuplex) { // the callback that's passed to _write(chunk,cb) this.onwrite = onwrite.bind(undefined, stream); - // the callback that the user supplies to write(chunk,encoding,cb) + // The callback that the user supplies to write(chunk,encoding,cb) this.writecb = null; // the amount that is being written when _write is called. @@ -139,7 +139,7 @@ function WritableState(options, stream, isDuplex) { // this must be 0 before 'finish' can be emitted this.pendingcb = 0; - // emit prefinish if the only thing we're waiting for is _write cbs + // Emit prefinish if the only thing we're waiting for is _write cbs // This is relevant for synchronous Transform streams this.prefinished = false; @@ -376,7 +376,7 @@ function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { state.length += len; var ret = state.length < state.highWaterMark; - // we must ensure that previous needDrain will not be reset to false. + // We must ensure that previous needDrain will not be reset to false. if (!ret) state.needDrain = true; diff --git a/lib/buffer.js b/lib/buffer.js index ac5e19c40819c1..b032736f509e5c 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -916,7 +916,7 @@ Buffer.prototype.write = function write(string, offset, length, encoding) { if (string.length > 0 && (length < 0 || offset < 0)) throw new ERR_BUFFER_OUT_OF_BOUNDS(); } else { - // if someone is still calling the obsolete form of write(), tell them. + // If someone is still calling the obsolete form of write(), tell them. // we don't want eg buf.write("foo", "utf8", 10) to silently turn into // buf.write("foo", "utf8"), so we can't ignore extra args throw new ERR_NO_LONGER_SUPPORTED( diff --git a/lib/console.js b/lib/console.js index 29d551549ddfa9..570515aefe0b62 100644 --- a/lib/console.js +++ b/lib/console.js @@ -171,7 +171,7 @@ function write(ignoreErrors, stream, string, errorhandler, groupIndent) { stream.write(string, errorhandler); } catch (e) { - // console is a debugging utility, so it swallowing errors is not desirable + // Console is a debugging utility, so it swallowing errors is not desirable // even in edge cases such as low stack space. if (isStackOverflowError(e)) throw e; diff --git a/lib/dgram.js b/lib/dgram.js index 55662313d640cd..27c38191735f38 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -312,7 +312,7 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) { }; -// thin wrapper around `send`, here for compatibility with dgram_legacy.js +// Thin wrapper around `send`, here for compatibility with dgram_legacy.js Socket.prototype.sendto = function(buffer, offset, length, diff --git a/lib/domain.js b/lib/domain.js index e8ae3ff1003486..899978cf7069d2 100644 --- a/lib/domain.js +++ b/lib/domain.js @@ -35,7 +35,7 @@ const { } = require('internal/errors').codes; const { createHook } = require('async_hooks'); -// overwrite process.domain with a getter/setter that will allow for more +// Overwrite process.domain with a getter/setter that will allow for more // effective optimizations var _domain = [null]; Object.defineProperty(process, 'domain', { diff --git a/lib/fs.js b/lib/fs.js index d8582786f174b0..5a951d1f767640 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1421,7 +1421,7 @@ function realpathSync(p, options) { let pos; // the partial path so far, including a trailing slash if any let current; - // the partial path without a trailing slash (except when pointing at a root) + // The partial path without a trailing slash (except when pointing at a root) let base; // the partial path scanned in the previous round, with slash let previous; @@ -1438,7 +1438,7 @@ function realpathSync(p, options) { knownHard[base] = true; } - // walk down the path, swapping out linked path parts for their real + // Walk down the path, swapping out linked path parts for their real // values // NB: p.length changes. while (pos < p.length) { @@ -1561,7 +1561,7 @@ function realpath(p, options, callback) { let pos; // the partial path so far, including a trailing slash if any let current; - // the partial path without a trailing slash (except when pointing at a root) + // The partial path without a trailing slash (except when pointing at a root) let base; // the partial path scanned in the previous round, with slash let previous; @@ -1580,7 +1580,7 @@ function realpath(p, options, callback) { process.nextTick(LOOP); } - // walk down the path, swapping out linked path parts for their real + // Walk down the path, swapping out linked path parts for their real // values function LOOP() { // stop if scanned past end of path diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index 2562a76cd9be0d..b6f9ca96296adb 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -62,7 +62,7 @@ let HTTPParser; const MAX_HANDLE_RETRANSMISSIONS = 3; -// this object contain function to convert TCP objects to native handle objects +// This object contain function to convert TCP objects to native handle objects // and back again. const handleConversion = { 'net.Native': { @@ -117,7 +117,7 @@ const handleConversion = { var handle = socket._handle; - // remove handle from socket object, it will be closed when the socket + // Remove handle from socket object, it will be closed when the socket // will be sent if (!options.keepOpen) { handle.onread = nop; @@ -166,7 +166,7 @@ const handleConversion = { writable: true }); - // if the socket was created by net.Server we will track the socket + // If the socket was created by net.Server we will track the socket if (message.key) { // add socket to connections list @@ -663,7 +663,7 @@ function setupChannel(target, channel) { // package messages with a handle object if (handle) { - // this message will be handled by an internalMessage event handler + // This message will be handled by an internalMessage event handler message = { cmd: 'NODE_HANDLE', type: null, @@ -768,7 +768,7 @@ function setupChannel(target, channel) { return channel.writeQueueSize < (65536 * 2); }; - // connected will be set to false immediately when a disconnect() is + // Connected will be set to false immediately when a disconnect() is // requested, even though the channel might still be alive internally to // process queued messages. The three states are distinguished as follows: // - disconnect() never requested: channel is not null and connected diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js new file mode 100644 index 00000000000000..d3c5ed74367b8a --- /dev/null +++ b/lib/internal/console/constructor.js @@ -0,0 +1,518 @@ +'use strict'; + +// The Console constructor is not actually used to construct the global +// console. It's exported for backwards compatibility. + +const { trace } = internalBinding('trace_events'); +const { + isStackOverflowError, + codes: { + ERR_CONSOLE_WRITABLE_STREAM, + ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, + }, +} = require('internal/errors'); +const { previewEntries } = internalBinding('util'); +const { Buffer: { isBuffer } } = require('buffer'); +const util = require('util'); +const { + isTypedArray, isSet, isMap, isSetIterator, isMapIterator, +} = util.types; +const kCounts = Symbol('counts'); + +const kTraceConsoleCategory = 'node,node.console'; +const kTraceCount = 'C'.charCodeAt(0); +const kTraceBegin = 'b'.charCodeAt(0); +const kTraceEnd = 'e'.charCodeAt(0); +const kTraceInstant = 'n'.charCodeAt(0); + +const { + keys: ObjectKeys, + values: ObjectValues, +} = Object; +const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); + +const { + isArray: ArrayIsArray, + from: ArrayFrom, +} = Array; + +// Lazy loaded for startup performance. +let cliTable; + +// Track amount of indentation required via `console.group()`. +const kGroupIndent = Symbol('kGroupIndent'); +const kFormatForStderr = Symbol('kFormatForStderr'); +const kFormatForStdout = Symbol('kFormatForStdout'); +const kGetInspectOptions = Symbol('kGetInspectOptions'); +const kColorMode = Symbol('kColorMode'); +const kIsConsole = Symbol('kIsConsole'); +const kWriteToConsole = Symbol('kWriteToConsole'); +const kBindProperties = Symbol('kBindProperties'); +const kBindStreamsEager = Symbol('kBindStreamsEager'); +const kBindStreamsLazy = Symbol('kBindStreamsLazy'); +const kUseStdout = Symbol('kUseStdout'); +const kUseStderr = Symbol('kUseStderr'); + +function Console(options /* or: stdout, stderr, ignoreErrors = true */) { + // We have to test new.target here to see if this function is called + // with new, because we need to define a custom instanceof to accommodate + // the global console. + if (!new.target) { + return new Console(...arguments); + } + + if (!options || typeof options.write === 'function') { + options = { + stdout: options, + stderr: arguments[1], + ignoreErrors: arguments[2] + }; + } + + const { + stdout, + stderr = stdout, + ignoreErrors = true, + colorMode = 'auto' + } = options; + + if (!stdout || typeof stdout.write !== 'function') { + throw new ERR_CONSOLE_WRITABLE_STREAM('stdout'); + } + if (!stderr || typeof stderr.write !== 'function') { + throw new ERR_CONSOLE_WRITABLE_STREAM('stderr'); + } + + if (typeof colorMode !== 'boolean' && colorMode !== 'auto') + throw new ERR_INVALID_ARG_VALUE('colorMode', colorMode); + + // bind the prototype functions to this Console instance + var keys = Object.keys(Console.prototype); + for (var v = 0; v < keys.length; v++) { + var k = keys[v]; + // We have to bind the methods grabbed from the instance instead of from + // the prototype so that users extending the Console can override them + // from the prototype chain of the subclass. + this[k] = this[k].bind(this); + } + + this[kBindStreamsEager](stdout, stderr); + this[kBindProperties](ignoreErrors, colorMode); +} + +const consolePropAttributes = { + writable: true, + enumerable: false, + configurable: true +}; + +// Fixup global.console instanceof global.console.Console +Object.defineProperty(Console, Symbol.hasInstance, { + value(instance) { + return instance[kIsConsole]; + } +}); + +// Eager version for the Console constructor +Console.prototype[kBindStreamsEager] = function(stdout, stderr) { + Object.defineProperties(this, { + '_stdout': { ...consolePropAttributes, value: stdout }, + '_stderr': { ...consolePropAttributes, value: stderr } + }); +}; + +// Lazily load the stdout and stderr from an object so we don't +// create the stdio streams when they are not even accessed +Console.prototype[kBindStreamsLazy] = function(object) { + let stdout; + let stderr; + Object.defineProperties(this, { + '_stdout': { + enumerable: false, + configurable: true, + get() { + if (!stdout) stdout = object.stdout; + return stdout; + }, + set(value) { stdout = value; } + }, + '_stderr': { + enumerable: false, + configurable: true, + get() { + if (!stderr) { stderr = object.stderr; } + return stderr; + }, + set(value) { stderr = value; } + } + }); +}; + +Console.prototype[kBindProperties] = function(ignoreErrors, colorMode) { + Object.defineProperties(this, { + '_stdoutErrorHandler': { + ...consolePropAttributes, + value: createWriteErrorHandler(this, kUseStdout) + }, + '_stderrErrorHandler': { + ...consolePropAttributes, + value: createWriteErrorHandler(this, kUseStderr) + }, + '_ignoreErrors': { + ...consolePropAttributes, + value: Boolean(ignoreErrors) + }, + '_times': { ...consolePropAttributes, value: new Map() } + }); + + // TODO(joyeecheung): use consolePropAttributes for these + // Corresponds to https://console.spec.whatwg.org/#count-map + this[kCounts] = new Map(); + this[kColorMode] = colorMode; + this[kIsConsole] = true; + this[kGroupIndent] = ''; +}; + +// Make a function that can serve as the callback passed to `stream.write()`. +function createWriteErrorHandler(instance, streamSymbol) { + return (err) => { + // This conditional evaluates to true if and only if there was an error + // that was not already emitted (which happens when the _write callback + // is invoked asynchronously). + const stream = streamSymbol === kUseStdout ? + instance._stdout : instance._stderr; + if (err !== null && !stream._writableState.errorEmitted) { + // If there was an error, it will be emitted on `stream` as + // an `error` event. Adding a `once` listener will keep that error + // from becoming an uncaught exception, but since the handler is + // removed after the event, non-console.* writes won't be affected. + // we are only adding noop if there is no one else listening for 'error' + if (stream.listenerCount('error') === 0) { + stream.on('error', noop); + } + } + }; +} + +Console.prototype[kWriteToConsole] = function(streamSymbol, string) { + const ignoreErrors = this._ignoreErrors; + const groupIndent = this[kGroupIndent]; + + const useStdout = streamSymbol === kUseStdout; + const stream = useStdout ? this._stdout : this._stderr; + const errorHandler = useStdout ? + this._stdoutErrorHandler : this._stderrErrorHandler; + + if (groupIndent.length !== 0) { + if (string.indexOf('\n') !== -1) { + string = string.replace(/\n/g, `\n${groupIndent}`); + } + string = groupIndent + string; + } + string += '\n'; + + if (ignoreErrors === false) return stream.write(string); + + // There may be an error occurring synchronously (e.g. for files or TTYs + // on POSIX systems) or asynchronously (e.g. pipes on POSIX systems), so + // handle both situations. + try { + // Add and later remove a noop error handler to catch synchronous errors. + stream.once('error', noop); + + stream.write(string, errorHandler); + } catch (e) { + // Console is a debugging utility, so it swallowing errors is not desirable + // even in edge cases such as low stack space. + if (isStackOverflowError(e)) + throw e; + // Sorry, there's no proper way to pass along the error here. + } finally { + stream.removeListener('error', noop); + } +}; + +const kColorInspectOptions = { colors: true }; +const kNoColorInspectOptions = {}; +Console.prototype[kGetInspectOptions] = function(stream) { + let color = this[kColorMode]; + if (color === 'auto') { + color = stream.isTTY && ( + typeof stream.getColorDepth === 'function' ? + stream.getColorDepth() > 2 : true); + } + + return color ? kColorInspectOptions : kNoColorInspectOptions; +}; + +Console.prototype[kFormatForStdout] = function(args) { + const opts = this[kGetInspectOptions](this._stdout); + return util.formatWithOptions(opts, ...args); +}; + +Console.prototype[kFormatForStderr] = function(args) { + const opts = this[kGetInspectOptions](this._stderr); + return util.formatWithOptions(opts, ...args); +}; + +Console.prototype.log = function log(...args) { + this[kWriteToConsole](kUseStdout, this[kFormatForStdout](args)); +}; + +Console.prototype.debug = Console.prototype.log; +Console.prototype.info = Console.prototype.log; +Console.prototype.dirxml = Console.prototype.log; + +Console.prototype.warn = function warn(...args) { + this[kWriteToConsole](kUseStderr, this[kFormatForStderr](args)); +}; + +Console.prototype.error = Console.prototype.warn; + +Console.prototype.dir = function dir(object, options) { + options = Object.assign({ + customInspect: false + }, this[kGetInspectOptions](this._stdout), options); + this[kWriteToConsole](kUseStdout, util.inspect(object, options)); +}; + +Console.prototype.time = function time(label = 'default') { + // Coerces everything other than Symbol to a string + label = `${label}`; + if (this._times.has(label)) { + process.emitWarning(`Label '${label}' already exists for console.time()`); + return; + } + trace(kTraceBegin, kTraceConsoleCategory, `time::${label}`, 0); + this._times.set(label, process.hrtime()); +}; + +Console.prototype.timeEnd = function timeEnd(label = 'default') { + // Coerces everything other than Symbol to a string + label = `${label}`; + const hasWarned = timeLogImpl(this, 'timeEnd', label); + trace(kTraceEnd, kTraceConsoleCategory, `time::${label}`, 0); + if (!hasWarned) { + this._times.delete(label); + } +}; + +Console.prototype.timeLog = function timeLog(label = 'default', ...data) { + // Coerces everything other than Symbol to a string + label = `${label}`; + timeLogImpl(this, 'timeLog', label, data); + trace(kTraceInstant, kTraceConsoleCategory, `time::${label}`, 0); +}; + +// Returns true if label was not found +function timeLogImpl(self, name, label, data) { + const time = self._times.get(label); + if (!time) { + process.emitWarning(`No such label '${label}' for console.${name}()`); + return true; + } + const duration = process.hrtime(time); + const ms = duration[0] * 1000 + duration[1] / 1e6; + if (data === undefined) { + self.log('%s: %sms', label, ms.toFixed(3)); + } else { + self.log('%s: %sms', label, ms.toFixed(3), ...data); + } + return false; +} + +Console.prototype.trace = function trace(...args) { + const err = { + name: 'Trace', + message: this[kFormatForStderr](args) + }; + Error.captureStackTrace(err, trace); + this.error(err.stack); +}; + +Console.prototype.assert = function assert(expression, ...args) { + if (!expression) { + args[0] = `Assertion failed${args.length === 0 ? '' : `: ${args[0]}`}`; + this.warn(...args); // the arguments will be formatted in warn() again + } +}; + +// Defined by: https://console.spec.whatwg.org/#clear +Console.prototype.clear = function clear() { + // It only makes sense to clear if _stdout is a TTY. + // Otherwise, do nothing. + if (this._stdout.isTTY) { + // The require is here intentionally to avoid readline being + // required too early when console is first loaded. + const { cursorTo, clearScreenDown } = require('readline'); + cursorTo(this._stdout, 0, 0); + clearScreenDown(this._stdout); + } +}; + +// Defined by: https://console.spec.whatwg.org/#count +Console.prototype.count = function count(label = 'default') { + // Ensures that label is a string, and only things that can be + // coerced to strings. e.g. Symbol is not allowed + label = `${label}`; + const counts = this[kCounts]; + let count = counts.get(label); + if (count === undefined) + count = 1; + else + count++; + counts.set(label, count); + trace(kTraceCount, kTraceConsoleCategory, `count::${label}`, 0, count); + this.log(`${label}: ${count}`); +}; + +// Defined by: https://console.spec.whatwg.org/#countreset +Console.prototype.countReset = function countReset(label = 'default') { + const counts = this[kCounts]; + if (!counts.has(label)) { + process.emitWarning(`Count for '${label}' does not exist`); + return; + } + trace(kTraceCount, kTraceConsoleCategory, `count::${label}`, 0, 0); + counts.delete(`${label}`); +}; + +Console.prototype.group = function group(...data) { + if (data.length > 0) { + this.log(...data); + } + this[kGroupIndent] += ' '; +}; +Console.prototype.groupCollapsed = Console.prototype.group; + +Console.prototype.groupEnd = function groupEnd() { + this[kGroupIndent] = + this[kGroupIndent].slice(0, this[kGroupIndent].length - 2); +}; + +const keyKey = 'Key'; +const valuesKey = 'Values'; +const indexKey = '(index)'; +const iterKey = '(iteration index)'; + +const isArray = (v) => ArrayIsArray(v) || isTypedArray(v) || isBuffer(v); + +// https://console.spec.whatwg.org/#table +Console.prototype.table = function(tabularData, properties) { + if (properties !== undefined && !ArrayIsArray(properties)) + throw new ERR_INVALID_ARG_TYPE('properties', 'Array', properties); + + if (tabularData === null || typeof tabularData !== 'object') + return this.log(tabularData); + + if (cliTable === undefined) cliTable = require('internal/cli_table'); + const final = (k, v) => this.log(cliTable(k, v)); + + const inspect = (v) => { + const opt = { depth: 0, maxArrayLength: 3 }; + if (v !== null && typeof v === 'object' && + !isArray(v) && ObjectKeys(v).length > 2) + opt.depth = -1; + Object.assign(opt, this[kGetInspectOptions](this._stdout)); + return util.inspect(v, opt); + }; + const getIndexArray = (length) => ArrayFrom({ length }, (_, i) => inspect(i)); + + const mapIter = isMapIterator(tabularData); + let isKeyValue = false; + let i = 0; + if (mapIter) { + const res = previewEntries(tabularData, true); + tabularData = res[0]; + isKeyValue = res[1]; + } + + if (isKeyValue || isMap(tabularData)) { + const keys = []; + const values = []; + let length = 0; + if (mapIter) { + for (; i < tabularData.length / 2; ++i) { + keys.push(inspect(tabularData[i * 2])); + values.push(inspect(tabularData[i * 2 + 1])); + length++; + } + } else { + for (const [k, v] of tabularData) { + keys.push(inspect(k)); + values.push(inspect(v)); + length++; + } + } + return final([ + iterKey, keyKey, valuesKey + ], [ + getIndexArray(length), + keys, + values, + ]); + } + + const setIter = isSetIterator(tabularData); + if (setIter) + tabularData = previewEntries(tabularData); + + const setlike = setIter || (mapIter && !isKeyValue) || isSet(tabularData); + if (setlike) { + const values = []; + let length = 0; + for (const v of tabularData) { + values.push(inspect(v)); + length++; + } + return final([setlike ? iterKey : indexKey, valuesKey], [ + getIndexArray(length), + values, + ]); + } + + const map = {}; + let hasPrimitives = false; + const valuesKeyArray = []; + const indexKeyArray = ObjectKeys(tabularData); + + for (; i < indexKeyArray.length; i++) { + const item = tabularData[indexKeyArray[i]]; + const primitive = item === null || + (typeof item !== 'function' && typeof item !== 'object'); + if (properties === undefined && primitive) { + hasPrimitives = true; + valuesKeyArray[i] = inspect(item); + } else { + const keys = properties || ObjectKeys(item); + for (const key of keys) { + if (map[key] === undefined) + map[key] = []; + if ((primitive && properties) || !hasOwnProperty(item, key)) + map[key][i] = ''; + else + map[key][i] = item == null ? item : inspect(item[key]); + } + } + } + + const keys = ObjectKeys(map); + const values = ObjectValues(map); + if (hasPrimitives) { + keys.push(valuesKey); + values.push(valuesKeyArray); + } + keys.unshift(indexKey); + values.unshift(indexKeyArray); + + return final(keys, values); +}; + +function noop() {} + +module.exports = { + Console, + kBindStreamsLazy, + kBindProperties +}; diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 0ed23a943805a8..04c68c2af21874 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -261,10 +261,16 @@ function uvException(ctx) { message += ` -> '${dest}'`; } + // Reducing the limit improves the performance significantly. We do not loose + // the stack frames due to the `captureStackTrace()` function that is called + // later. + const tmpLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; // Pass the message to the constructor instead of setting it on the object // to make sure it is the same as the one created in C++ // eslint-disable-next-line no-restricted-syntax const err = new Error(message); + Error.stackTraceLimit = tmpLimit; for (const prop of Object.keys(ctx)) { if (prop === 'message' || prop === 'path' || prop === 'dest') { @@ -307,8 +313,14 @@ function uvExceptionWithHostPort(err, syscall, address, port) { details = ` ${address}`; } + // Reducing the limit improves the performance significantly. We do not loose + // the stack frames due to the `captureStackTrace()` function that is called + // later. + const tmpLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; // eslint-disable-next-line no-restricted-syntax const ex = new Error(`${message}${details}`); + Error.stackTraceLimit = tmpLimit; ex.code = code; ex.errno = code; ex.syscall = syscall; @@ -377,9 +389,15 @@ function exceptionWithHostPort(err, syscall, address, port, additional) { details += ` - Local (${additional})`; } + // Reducing the limit improves the performance significantly. We do not loose + // the stack frames due to the `captureStackTrace()` function that is called + // later. + const tmpLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; // eslint-disable-next-line no-restricted-syntax const ex = new Error(`${syscall} ${code}${details}`); // TODO(joyeecheung): errno is supposed to err, like in uvException + Error.stackTraceLimit = tmpLimit; ex.code = ex.errno = code; ex.syscall = syscall; ex.address = address; @@ -410,9 +428,15 @@ function dnsException(code, syscall, hostname) { } } const message = `${syscall} ${code}${hostname ? ` ${hostname}` : ''}`; + // Reducing the limit improves the performance significantly. We do not loose + // the stack frames due to the `captureStackTrace()` function that is called + // later. + const tmpLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; // eslint-disable-next-line no-restricted-syntax const ex = new Error(message); // TODO(joyeecheung): errno is supposed to be a number / err, like in + Error.stackTraceLimit = tmpLimit; // uvException. ex.errno = code; ex.code = code; diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 0df13354acc628..4db4fb536c0b6a 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -190,16 +190,19 @@ function nullCheck(path, propName, throwError = true) { const pathIsUint8Array = isUint8Array(path); // We can only perform meaningful checks on strings and Uint8Arrays. - if (!pathIsString && !pathIsUint8Array) { + if (!pathIsString && !pathIsUint8Array || + pathIsString && path.indexOf('\u0000') === -1 || + pathIsUint8Array && path.indexOf(0) === -1) { return; } - if (pathIsString && path.indexOf('\u0000') === -1) { - return; - } else if (pathIsUint8Array && path.indexOf(0) === -1) { - return; + // Reducing the limit improves the performance significantly. We do not loose + // the stack frames due to the `captureStackTrace()` function that is called + // later. + const tmpLimit = Error.stackTraceLimit; + if (throwError) { + Error.stackTraceLimit = 0; } - const err = new ERR_INVALID_ARG_VALUE( propName, path, @@ -207,6 +210,7 @@ function nullCheck(path, propName, throwError = true) { ); if (throwError) { + Error.stackTraceLimit = tmpLimit; Error.captureStackTrace(err, nullCheck); throw err; } diff --git a/lib/internal/http2/compat.js b/lib/internal/http2/compat.js index adf6b1da628881..1783a48ada814c 100644 --- a/lib/internal/http2/compat.js +++ b/lib/internal/http2/compat.js @@ -231,7 +231,7 @@ function onStreamCloseRequest() { state.closed = true; req.push(null); - // if the user didn't interact with incoming data and didn't pipe it, + // If the user didn't interact with incoming data and didn't pipe it, // dump it for compatibility with http1 if (!state.didRead && !req._readableState.resumeScheduled) req.resume(); diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 80bcef5fa21633..6ce426a207a488 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -266,7 +266,7 @@ function onSessionHeaders(handle, id, cat, flags, headers) { if (stream === undefined) { if (session.closed) { - // we are not accepting any new streams at this point. This callback + // We are not accepting any new streams at this point. This callback // should not be invoked at this point in time, but just in case it is, // refuse the stream using an RST_STREAM and destroy the handle. handle.rstStream(NGHTTP2_REFUSED_STREAM); @@ -1112,7 +1112,7 @@ class Http2Session extends EventEmitter { return this[kState].goawayLastStreamID || 0; } - // true if the Http2Session is waiting for a settings acknowledgement + // True if the Http2Session is waiting for a settings acknowledgement get pendingSettingsAck() { return this[kState].pendingAck > 0; } @@ -2235,7 +2235,7 @@ class ServerHttp2Stream extends Http2Stream { this[kSession].remoteSettings.enablePush; } - // create a push stream, call the given callback with the created + // Create a push stream, call the given callback with the created // Http2Stream for the push stream. pushStream(headers, options, callback) { if (!this.pushAllowed) diff --git a/lib/internal/http2/util.js b/lib/internal/http2/util.js index 9dc8be6e83ddeb..f62d936025229f 100644 --- a/lib/internal/http2/util.js +++ b/lib/internal/http2/util.js @@ -290,7 +290,7 @@ function getDefaultSettings() { return holder; } -// remote is a boolean. true to fetch remote settings, false to fetch local. +// Remote is a boolean. true to fetch remote settings, false to fetch local. // this is only called internally function getSettings(session, remote) { if (remote) diff --git a/lib/internal/modules/cjs/helpers.js b/lib/internal/modules/cjs/helpers.js index b08e97b29c5c8d..2c856a99c6b8fd 100644 --- a/lib/internal/modules/cjs/helpers.js +++ b/lib/internal/modules/cjs/helpers.js @@ -1,6 +1,6 @@ 'use strict'; -const { ERR_INVALID_ARG_TYPE } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const { CHAR_LINE_FEED, @@ -26,18 +26,14 @@ function makeRequireFunction(mod) { } function resolve(request, options) { - if (typeof request !== 'string') { - throw new ERR_INVALID_ARG_TYPE('request', 'string', request); - } + validateString(request, 'request'); return Module._resolveFilename(request, mod, false, options); } require.resolve = resolve; function paths(request) { - if (typeof request !== 'string') { - throw new ERR_INVALID_ARG_TYPE('request', 'string', request); - } + validateString(request, 'request'); return Module._resolveLookupPaths(request, mod, true); } diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 294c94d36943d4..d79f375ba60b44 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -47,10 +47,10 @@ const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); const experimentalModules = getOptionValue('--experimental-modules'); const { - ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, ERR_REQUIRE_ESM } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); module.exports = Module; @@ -138,7 +138,7 @@ const debug = util.debuglog('module'); Module._debug = util.deprecate(debug, 'Module._debug is deprecated.', 'DEP0077'); -// given a module name, and a list of paths to test, returns the first +// Given a module name, and a list of paths to test, returns the first // matching file in the following precedence. // // require("a.") @@ -207,7 +207,7 @@ function toRealPath(requestPath) { }); } -// given a path, check if the file exists with any of the set extensions +// Given a path, check if the file exists with any of the set extensions function tryExtensions(p, exts, isMain) { for (var i = 0; i < exts.length; i++) { const filename = tryFile(p + exts[i], isMain); @@ -452,7 +452,7 @@ Module._resolveLookupPaths = function(request, parent, newReturn) { // with --eval, parent.id is not set and parent.filename is null if (!parent || !parent.id || !parent.filename) { - // make require('./path/to/foo') work - normally the path is taken + // Make require('./path/to/foo') work - normally the path is taken // from realpath(__filename) but with eval there is no filename var mainPaths = ['.'].concat(Module._nodeModulePaths('.'), modulePaths); @@ -498,7 +498,7 @@ Module._resolveLookupPaths = function(request, parent, newReturn) { } var id = path.resolve(parentIdPath, request); - // make sure require('./path') and require('path') get distinct ids, even + // Make sure require('./path') and require('path') get distinct ids, even // when called from the toplevel js file if (parentIdPath === '.' && id.indexOf('/') === -1 && @@ -625,7 +625,7 @@ Module.prototype.load = function(filename) { const ESMLoader = asyncESM.ESMLoader; const url = `${pathToFileURL(filename)}`; const module = ESMLoader.moduleMap.get(url); - // create module entry at load time to snapshot exports correctly + // Create module entry at load time to snapshot exports correctly const exports = this.exports; if (module !== undefined) { // called from cjs translator module.reflect.onReady((reflect) => { @@ -649,9 +649,7 @@ Module.prototype.load = function(filename) { // Loads a module at the given file path. Returns that module's // `exports` property. Module.prototype.require = function(id) { - if (typeof id !== 'string') { - throw new ERR_INVALID_ARG_TYPE('id', 'string', id); - } + validateString(id, 'id'); if (id === '') { throw new ERR_INVALID_ARG_VALUE('id', id, 'must be a non-empty string'); diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 60f1e31f94e86e..820b593446ca79 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -1,7 +1,6 @@ 'use strict'; const { - ERR_INVALID_ARG_TYPE, ERR_INVALID_RETURN_PROPERTY, ERR_INVALID_RETURN_PROPERTY_VALUE, ERR_INVALID_RETURN_VALUE, @@ -9,6 +8,7 @@ const { ERR_UNKNOWN_MODULE_FORMAT } = require('internal/errors').codes; const { URL } = require('url'); +const { validateString } = require('internal/validators'); const ModuleMap = require('internal/modules/esm/module_map'); const ModuleJob = require('internal/modules/esm/module_job'); const defaultResolve = require('internal/modules/esm/default_resolve'); @@ -52,8 +52,8 @@ class Loader { async resolve(specifier, parentURL) { const isMain = parentURL === undefined; - if (!isMain && typeof parentURL !== 'string') - throw new ERR_INVALID_ARG_TYPE('parentURL', 'string', parentURL); + if (!isMain) + validateString(parentURL, 'parentURL'); const resolved = await this._resolve(specifier, parentURL, defaultResolve); diff --git a/lib/internal/modules/esm/module_map.js b/lib/internal/modules/esm/module_map.js index f4786f8e9ef0be..a9d0c23c0e5ee9 100644 --- a/lib/internal/modules/esm/module_map.js +++ b/lib/internal/modules/esm/module_map.js @@ -4,19 +4,16 @@ const ModuleJob = require('internal/modules/esm/module_job'); const { SafeMap } = require('internal/safe_globals'); const debug = require('util').debuglog('esm'); const { ERR_INVALID_ARG_TYPE } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); // Tracks the state of the loader-level module cache class ModuleMap extends SafeMap { get(url) { - if (typeof url !== 'string') { - throw new ERR_INVALID_ARG_TYPE('url', 'string', url); - } + validateString(url, 'url'); return super.get(url); } set(url, job) { - if (typeof url !== 'string') { - throw new ERR_INVALID_ARG_TYPE('url', 'string', url); - } + validateString(url, 'url'); if (job instanceof ModuleJob !== true) { throw new ERR_INVALID_ARG_TYPE('job', 'ModuleJob', job); } @@ -24,9 +21,7 @@ class ModuleMap extends SafeMap { return super.set(url, job); } has(url) { - if (typeof url !== 'string') { - throw new ERR_INVALID_ARG_TYPE('url', 'string', url); - } + validateString(url, 'url'); return super.has(url); } } diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 0d19a728aa788b..6bfc4c8a98ed83 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -67,7 +67,7 @@ translators.set('cjs', async (url, isMain) => { } return createDynamicModule(['default'], url, () => { debug(`Loading CJSModule ${url}`); - // we don't care about the return val of _load here because Module#load + // We don't care about the return val of _load here because Module#load // will handle it for us by checking the loader registry and filling the // exports like above CJSModule._load(pathname, undefined, isMain); diff --git a/lib/internal/process/per_thread.js b/lib/internal/process/per_thread.js index 952abda8b67147..ad634b757eca48 100644 --- a/lib/internal/process/per_thread.js +++ b/lib/internal/process/per_thread.js @@ -85,7 +85,7 @@ function setupCpuUsage(_cpuUsage) { // Ensure that a previously passed in value is valid. Currently, the native // implementation always returns numbers <= Number.MAX_SAFE_INTEGER. function previousValueIsValid(num) { - return Number.isFinite(num) && + return typeof num === 'number' && num <= Number.MAX_SAFE_INTEGER && num >= 0; } diff --git a/lib/internal/process/warning.js b/lib/internal/process/warning.js index 5dac78082bf205..6635f7b9b1dda0 100644 --- a/lib/internal/process/warning.js +++ b/lib/internal/process/warning.js @@ -22,7 +22,9 @@ function writeOut(message) { function onClose(fd) { return () => { if (fs === null) fs = require('fs'); - fs.close(fd, nop); + try { + fs.closeSync(fd); + } catch {} }; } @@ -127,8 +129,13 @@ function setupProcessWarnings() { throw new ERR_INVALID_ARG_TYPE('code', 'string', code); } if (typeof warning === 'string') { + // Improve error creation performance by skipping the error frames. + // They are added in the `captureStackTrace()` function below. + const tmpStackLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; // eslint-disable-next-line no-restricted-syntax warning = new Error(warning); + Error.stackTraceLimit = tmpStackLimit; warning.name = String(type || 'Warning'); if (code !== undefined) warning.code = code; if (detail !== undefined) warning.detail = detail; diff --git a/lib/internal/repl/recoverable.js b/lib/internal/repl/recoverable.js index 023de2f7abcf73..2c31db9faf6d80 100644 --- a/lib/internal/repl/recoverable.js +++ b/lib/internal/repl/recoverable.js @@ -45,7 +45,7 @@ function isRecoverableError(e, code) { case 'Unterminated string constant': const token = this.input.slice(this.lastTokStart, this.pos); - // see https://www.ecma-international.org/ecma-262/#sec-line-terminators + // See https://www.ecma-international.org/ecma-262/#sec-line-terminators recoverable = /\\(?:\r\n?|\n|\u2028|\u2029)$/.test(token); } diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js index ce9d2545e45022..de6bcf9cdb1b9a 100644 --- a/lib/internal/streams/destroy.js +++ b/lib/internal/streams/destroy.js @@ -17,14 +17,14 @@ function destroy(err, cb) { return this; } - // we set destroyed to true before firing error callbacks in order + // We set destroyed to true before firing error callbacks in order // to make it re-entrance safe in case destroy() is called within callbacks if (this._readableState) { this._readableState.destroyed = true; } - // if this is a duplex stream mark the writable part as destroyed as well + // If this is a duplex stream mark the writable part as destroyed as well if (this._writableState) { this._writableState.destroyed = true; } diff --git a/lib/internal/streams/end-of-stream.js b/lib/internal/streams/end-of-stream.js index 8bbd4827b23a3a..1753996a4f85de 100644 --- a/lib/internal/streams/end-of-stream.js +++ b/lib/internal/streams/end-of-stream.js @@ -7,20 +7,12 @@ const { ERR_INVALID_ARG_TYPE, ERR_STREAM_PREMATURE_CLOSE } = require('internal/errors').codes; +const { once } = require('internal/util'); function isRequest(stream) { return stream.setHeader && typeof stream.abort === 'function'; } -function once(callback) { - let called = false; - return function(err) { - if (called) return; - called = true; - callback.call(this, err); - }; -} - function eos(stream, opts, callback) { if (arguments.length === 2) { callback = opts; @@ -36,8 +28,6 @@ function eos(stream, opts, callback) { callback = once(callback); - const ws = stream._writableState; - const rs = stream._readableState; let readable = opts.readable || (opts.readable !== false && stream.readable); let writable = opts.writable || (opts.writable !== false && stream.writable); @@ -45,13 +35,17 @@ function eos(stream, opts, callback) { if (!stream.writable) onfinish(); }; + var writableEnded = stream._writableState && stream._writableState.finished; const onfinish = () => { writable = false; + writableEnded = true; if (!readable) callback.call(stream); }; + var readableEnded = stream._readableState && stream._readableState.endEmitted; const onend = () => { readable = false; + readableEnded = true; if (!writable) callback.call(stream); }; @@ -60,11 +54,16 @@ function eos(stream, opts, callback) { }; const onclose = () => { - if (readable && !(rs && rs.ended)) { - return callback.call(stream, new ERR_STREAM_PREMATURE_CLOSE()); + let err; + if (readable && !readableEnded) { + if (!stream._readableState || !stream._readableState.ended) + err = new ERR_STREAM_PREMATURE_CLOSE(); + return callback.call(stream, err); } - if (writable && !(ws && ws.ended)) { - return callback.call(stream, new ERR_STREAM_PREMATURE_CLOSE()); + if (writable && !writableEnded) { + if (!stream._writableState || !stream._writableState.ended) + err = new ERR_STREAM_PREMATURE_CLOSE(); + return callback.call(stream, err); } }; @@ -77,7 +76,7 @@ function eos(stream, opts, callback) { stream.on('abort', onclose); if (stream.req) onrequest(); else stream.on('request', onrequest); - } else if (writable && !ws) { // legacy streams + } else if (writable && !stream._writableState) { // legacy streams stream.on('end', onlegacyfinish); stream.on('close', onlegacyfinish); } diff --git a/lib/internal/timers.js b/lib/internal/timers.js index 3bfa1f03775fe1..fc9979e4b54e65 100644 --- a/lib/internal/timers.js +++ b/lib/internal/timers.js @@ -123,7 +123,7 @@ function setUnrefTimeout(callback, after, arg1, arg2, arg3) { default: args = [arg1, arg2, arg3]; for (i = 5; i < arguments.length; i++) { - // extend array dynamically, makes .apply run much faster in v6.0.0 + // Extend array dynamically, makes .apply run much faster in v6.0.0 args[i - 2] = arguments[i]; } break; diff --git a/lib/internal/url.js b/lib/internal/url.js index ae1adad8c1a214..13063cb8f2f5a6 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -771,8 +771,7 @@ function parseParams(qs) { if (code === CHAR_PERCENT) { encodeCheck = 1; } else if (encodeCheck > 0) { - // eslint-disable-next-line no-extra-boolean-cast - if (!!isHexTable[code]) { + if (isHexTable[code] === 1) { if (++encodeCheck === 3) { querystring = require('querystring'); encoded = true; diff --git a/lib/internal/util.js b/lib/internal/util.js index 23c201da371099..3aa00fed35957f 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -375,7 +375,7 @@ function once(callback) { return function(...args) { if (called) return; called = true; - callback(...args); + callback.apply(this, args); }; } diff --git a/lib/internal/util/comparisons.js b/lib/internal/util/comparisons.js index 905946fdee3f44..1d959f843bcbd3 100644 --- a/lib/internal/util/comparisons.js +++ b/lib/internal/util/comparisons.js @@ -7,7 +7,14 @@ const { isDate, isMap, isRegExp, - isSet + isSet, + isNativeError, + isBoxedPrimitive, + isNumberObject, + isStringObject, + isBooleanObject, + isBigIntObject, + isSymbolObject } = internalBinding('types'); const { getOwnNonIndexProperties, @@ -33,6 +40,13 @@ const kIsMap = 3; const objectToString = uncurryThis(Object.prototype.toString); const hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty); const propertyIsEnumerable = uncurryThis(Object.prototype.propertyIsEnumerable); +const dateGetTime = uncurryThis(Date.prototype.getTime); + +const bigIntValueOf = uncurryThis(BigInt.prototype.valueOf); +const booleanValueOf = uncurryThis(Boolean.prototype.valueOf); +const numberValueOf = uncurryThis(Number.prototype.valueOf); +const symbolValueOf = uncurryThis(Symbol.prototype.valueOf); +const stringValueOf = uncurryThis(String.prototype.valueOf); const objectKeys = Object.keys; const getPrototypeOf = Object.getPrototypeOf; @@ -82,6 +96,24 @@ function isObjectOrArrayTag(tag) { return tag === '[object Array]' || tag === '[object Object]'; } +function isEqualBoxedPrimitive(val1, val2) { + if (isNumberObject(val1)) { + return isNumberObject(val2) && + objectIs(numberValueOf(val1), numberValueOf(val2)); + } + if (isStringObject(val1)) { + return isStringObject(val2) && stringValueOf(val1) === stringValueOf(val2); + } + if (isBooleanObject(val1)) { + return isBooleanObject(val2) && + booleanValueOf(val1) === booleanValueOf(val2); + } + if (isBigIntObject(val1)) { + return isBigIntObject(val2) && bigIntValueOf(val1) === bigIntValueOf(val2); + } + return isSymbolObject(val2) && symbolValueOf(val1) === symbolValueOf(val2); +} + // Notes: Type tags are historical [[Class]] properties that can be set by // FunctionTemplate::SetClassName() in C++ or Symbol.toStringTag in JS // and retrieved using Object.prototype.toString.call(obj) in JS @@ -117,7 +149,7 @@ function strictDeepEqual(val1, val2, memos) { if (getPrototypeOf(val1) !== getPrototypeOf(val2)) { return false; } - if (val1Tag === '[object Array]') { + if (Array.isArray(val1)) { // Check for sparse arrays and general fast path if (val1.length !== val2.length) { return false; @@ -133,15 +165,14 @@ function strictDeepEqual(val1, val2, memos) { return keyCheck(val1, val2, kStrict, memos, kNoIterator); } if (isDate(val1)) { - // TODO: Make these safe. - if (val1.getTime() !== val2.getTime()) { + if (dateGetTime(val1) !== dateGetTime(val2)) { return false; } } else if (isRegExp(val1)) { if (!areSimilarRegExps(val1, val2)) { return false; } - } else if (val1Tag === '[object Error]') { + } else if (isNativeError(val1) || val1 instanceof Error) { // Do not compare the stack as it might differ even though the error itself // is otherwise identical. The non-enumerable name should be identical as // the prototype is also identical. Otherwise this is caught later on. @@ -175,14 +206,8 @@ function strictDeepEqual(val1, val2, memos) { if (!areEqualArrayBuffers(val1, val2)) { return false; } - // TODO: Make the valueOf checks safe. - } else if (typeof val1.valueOf === 'function') { - const val1Value = val1.valueOf(); - if (val1Value !== val1 && - (typeof val2.valueOf !== 'function' || - !innerDeepEqual(val1Value, val2.valueOf(), kStrict))) { - return false; - } + } else if (isBoxedPrimitive(val1) && !isEqualBoxedPrimitive(val1, val2)) { + return false; } return keyCheck(val1, val2, kStrict, memos, kNoIterator); } diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 6ec27b9d1d9c05..256a4a8b06904b 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -99,7 +99,8 @@ const inspectDefaultOptions = Object.seal({ maxArrayLength: 100, breakLength: 60, compact: true, - sorted: false + sorted: false, + getters: false }); const kObjectType = 0; @@ -162,12 +163,11 @@ function inspect(value, opts) { colors: inspectDefaultOptions.colors, customInspect: inspectDefaultOptions.customInspect, showProxy: inspectDefaultOptions.showProxy, - // TODO(BridgeAR): Deprecate `maxArrayLength` and replace it with - // `maxEntries`. maxArrayLength: inspectDefaultOptions.maxArrayLength, breakLength: inspectDefaultOptions.breakLength, compact: inspectDefaultOptions.compact, - sorted: inspectDefaultOptions.sorted + sorted: inspectDefaultOptions.sorted, + getters: inspectDefaultOptions.getters }; if (arguments.length > 1) { // Legacy... @@ -322,7 +322,7 @@ function getEmptyFormatArray() { return []; } -function getConstructorName(obj) { +function getConstructorName(obj, ctx) { let firstProto; while (obj) { const descriptor = Object.getOwnPropertyDescriptor(obj, 'constructor'); @@ -341,10 +341,11 @@ function getConstructorName(obj) { if (firstProto === null) { return null; } - // TODO(BridgeAR): Improve prototype inspection. - // We could use inspect on the prototype itself to improve the output. - return ''; + return `<${inspect(firstProto, { + ...ctx, + customInspect: false + })}>`; } function getPrefix(constructor, tag, fallback) { @@ -503,7 +504,7 @@ function formatValue(ctx, value, recurseTimes) { } if (ctx.stop !== undefined) { - const name = getConstructorName(value) || value[Symbol.toStringTag]; + const name = getConstructorName(value, ctx) || value[Symbol.toStringTag]; return ctx.stylize(`[${name || 'Object'}]`, 'special'); } @@ -547,7 +548,7 @@ function formatValue(ctx, value, recurseTimes) { function formatRaw(ctx, value, recurseTimes) { let keys; - const constructor = getConstructorName(value); + const constructor = getConstructorName(value, ctx); let tag = value[Symbol.toStringTag]; if (typeof tag !== 'string') tag = ''; @@ -1131,10 +1132,30 @@ function formatProperty(ctx, value, recurseTimes, key, type) { } ctx.indentationLvl -= diff; } else if (desc.get !== undefined) { - if (desc.set !== undefined) { - str = ctx.stylize('[Getter/Setter]', 'special'); + const label = desc.set !== undefined ? 'Getter/Setter' : 'Getter'; + const s = ctx.stylize; + const sp = 'special'; + if (ctx.getters && (ctx.getters === true || + ctx.getters === 'get' && desc.set === undefined || + ctx.getters === 'set' && desc.set !== undefined)) { + try { + const tmp = value[key]; + ctx.indentationLvl += 2; + if (tmp === null) { + str = `${s(`[${label}:`, sp)} ${s('null', 'null')}${s(']', sp)}`; + } else if (typeof tmp === 'object') { + str = `${s(`[${label}]`, sp)} ${formatValue(ctx, tmp, recurseTimes)}`; + } else { + const primitive = formatPrimitive(s, tmp, ctx); + str = `${s(`[${label}:`, sp)} ${primitive}${s(']', sp)}`; + } + ctx.indentationLvl -= 2; + } catch (err) { + const message = ``; + str = `${s(`[${label}:`, sp)} ${message}${s(']', sp)}`; + } } else { - str = ctx.stylize('[Getter]', 'special'); + str = ctx.stylize(`[${label}]`, sp); } } else if (desc.set !== undefined) { str = ctx.stylize('[Setter]', 'special'); diff --git a/lib/internal/worker.js b/lib/internal/worker.js index 88580893cdc015..669a86bb23faef 100644 --- a/lib/internal/worker.js +++ b/lib/internal/worker.js @@ -317,6 +317,7 @@ class Worker extends EventEmitter { [kOnExit](code) { debug(`[${threadId}] hears end event for Worker ${this.threadId}`); MessagePortPrototype.drain.call(this[kPublicPort]); + MessagePortPrototype.drain.call(this[kPort]); this[kDispose](); this.emit('exit', code); this.removeAllListeners(); diff --git a/lib/net.js b/lib/net.js index 0229e450fc6e10..942a187ba54e20 100644 --- a/lib/net.js +++ b/lib/net.js @@ -209,7 +209,7 @@ function normalizeArgs(args) { } -// called when creating new Socket, or when re-using a closed Socket +// Called when creating new Socket, or when re-using a closed Socket function initSocketHandle(self) { self._undestroy(); self._sockname = null; @@ -281,11 +281,8 @@ function Socket(options) { throw errnoException(err, 'open'); this[async_id_symbol] = this._handle.getAsyncId(); - // options.fd can be string (since it is user-defined), - // so changing this to === would be semver-major - // See: https://github.com/nodejs/node/pull/11513 - // eslint-disable-next-line eqeqeq - if ((fd == 1 || fd == 2) && + + if ((fd === 1 || fd === 2) && (this._handle instanceof Pipe) && process.platform === 'win32') { // Make stdout and stderr blocking on Windows @@ -1266,10 +1263,10 @@ function setupListenHandle(address, port, addressType, backlog, fd, flags) { return; } - // generate connection key, this should be unique to the connection + // Generate connection key, this should be unique to the connection this._connectionKey = addressType + ':' + address + ':' + port; - // unref the handle if the server was unref'ed prior to listening + // Unref the handle if the server was unref'ed prior to listening if (this._unref) this.unref(); diff --git a/lib/path.js b/lib/path.js index 798682ca0f1a6b..7ea431d1d00bb4 100644 --- a/lib/path.js +++ b/lib/path.js @@ -33,12 +33,7 @@ const { CHAR_COLON, CHAR_QUESTION_MARK, } = require('internal/constants'); - -function assertPath(path) { - if (typeof path !== 'string') { - throw new ERR_INVALID_ARG_TYPE('path', 'string', path); - } -} +const { validateString } = require('internal/validators'); function isPathSeparator(code) { return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; @@ -163,7 +158,7 @@ const win32 = { } } - assertPath(path); + validateString(path, 'path'); // Skip empty entries if (path.length === 0) { @@ -282,7 +277,7 @@ const win32 = { }, normalize: function normalize(path) { - assertPath(path); + validateString(path, 'path'); const len = path.length; if (len === 0) return '.'; @@ -401,7 +396,7 @@ const win32 = { isAbsolute: function isAbsolute(path) { - assertPath(path); + validateString(path, 'path'); const len = path.length; if (len === 0) return false; @@ -429,7 +424,7 @@ const win32 = { var firstPart; for (var i = 0; i < arguments.length; ++i) { var arg = arguments[i]; - assertPath(arg); + validateString(arg, 'path'); if (arg.length > 0) { if (joined === undefined) joined = firstPart = arg; @@ -494,8 +489,8 @@ const win32 = { // to = 'C:\\orandea\\impl\\bbb' // The output of the function should be: '..\\..\\impl\\bbb' relative: function relative(from, to) { - assertPath(from); - assertPath(to); + validateString(from, 'from'); + validateString(to, 'to'); if (from === to) return ''; @@ -648,7 +643,7 @@ const win32 = { }, dirname: function dirname(path) { - assertPath(path); + validateString(path, 'path'); const len = path.length; if (len === 0) return '.'; @@ -744,9 +739,9 @@ const win32 = { basename: function basename(path, ext) { - if (ext !== undefined && typeof ext !== 'string') - throw new ERR_INVALID_ARG_TYPE('ext', 'string', ext); - assertPath(path); + if (ext !== undefined) + validateString(ext, 'ext'); + validateString(path, 'path'); var start = 0; var end = -1; var matchedSlash = true; @@ -832,7 +827,7 @@ const win32 = { extname: function extname(path) { - assertPath(path); + validateString(path, 'path'); var start = 0; var startDot = -1; var startPart = 0; @@ -905,7 +900,7 @@ const win32 = { parse: function parse(path) { - assertPath(path); + validateString(path, 'path'); var ret = { root: '', dir: '', base: '', ext: '', name: '' }; if (path.length === 0) @@ -1082,7 +1077,7 @@ const posix = { path = process.cwd(); } - assertPath(path); + validateString(path, 'path'); // Skip empty entries if (path.length === 0) { @@ -1114,7 +1109,7 @@ const posix = { normalize: function normalize(path) { - assertPath(path); + validateString(path, 'path'); if (path.length === 0) return '.'; @@ -1138,7 +1133,7 @@ const posix = { isAbsolute: function isAbsolute(path) { - assertPath(path); + validateString(path, 'path'); return path.length > 0 && path.charCodeAt(0) === CHAR_FORWARD_SLASH; }, @@ -1149,7 +1144,7 @@ const posix = { var joined; for (var i = 0; i < arguments.length; ++i) { var arg = arguments[i]; - assertPath(arg); + validateString(arg, 'path'); if (arg.length > 0) { if (joined === undefined) joined = arg; @@ -1164,8 +1159,8 @@ const posix = { relative: function relative(from, to) { - assertPath(from); - assertPath(to); + validateString(from, 'from'); + validateString(to, 'to'); if (from === to) return ''; @@ -1262,7 +1257,7 @@ const posix = { }, dirname: function dirname(path) { - assertPath(path); + validateString(path, 'path'); if (path.length === 0) return '.'; const hasRoot = path.charCodeAt(0) === CHAR_FORWARD_SLASH; @@ -1289,9 +1284,9 @@ const posix = { basename: function basename(path, ext) { - if (ext !== undefined && typeof ext !== 'string') - throw new ERR_INVALID_ARG_TYPE('ext', 'string', ext); - assertPath(path); + if (ext !== undefined) + validateString(ext, 'ext'); + validateString(path, 'path'); var start = 0; var end = -1; @@ -1367,7 +1362,7 @@ const posix = { extname: function extname(path) { - assertPath(path); + validateString(path, 'path'); var startDot = -1; var startPart = 0; var end = -1; @@ -1428,7 +1423,7 @@ const posix = { parse: function parse(path) { - assertPath(path); + validateString(path, 'path'); var ret = { root: '', dir: '', base: '', ext: '', name: '' }; if (path.length === 0) diff --git a/lib/querystring.js b/lib/querystring.js index 5189a28f235770..5839ca6b0d0d0b 100644 --- a/lib/querystring.js +++ b/lib/querystring.js @@ -318,8 +318,7 @@ function parse(qs, sep, eq, options) { encodeCheck = 1; continue; } else if (encodeCheck > 0) { - // eslint-disable-next-line no-extra-boolean-cast - if (!!isHexTable[code]) { + if (isHexTable[code] === 1) { if (++encodeCheck === 3) keyEncoded = true; continue; @@ -348,8 +347,7 @@ function parse(qs, sep, eq, options) { if (code === 37/* % */) { encodeCheck = 1; } else if (encodeCheck > 0) { - // eslint-disable-next-line no-extra-boolean-cast - if (!!isHexTable[code]) { + if (isHexTable[code] === 1) { if (++encodeCheck === 3) valEncoded = true; } else { diff --git a/lib/readline.js b/lib/readline.js index 6fad26db4dff28..e4d9e1aa45fbf5 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -356,7 +356,7 @@ Interface.prototype._refreshLine = function() { // cursor position var cursorPos = this._getCursorPos(); - // first move to the bottom of the current line, based on cursor pos + // First move to the bottom of the current line, based on cursor pos var prevRows = this.prevRows || 0; if (prevRows > 0) { moveCursor(this.output, 0, -prevRows); @@ -444,7 +444,7 @@ Interface.prototype._normalWrite = function(b) { // got one or more newlines; process into "line" events var lines = string.split(lineEnding); - // either '' or (conceivably) the unfinished portion of the next line + // Either '' or (conceivably) the unfinished portion of the next line string = lines.pop(); this._line_buffer = string; for (var n = 0; n < lines.length; n++) diff --git a/lib/timers.js b/lib/timers.js index 1531cd1fb60726..4f2fef449db211 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -389,7 +389,7 @@ function unenroll(item) { } item[kRefed] = null; - // if active is called later, then we want to make sure not to insert again + // If active is called later, then we want to make sure not to insert again item._idleTimeout = -1; } @@ -444,7 +444,7 @@ function setTimeout(callback, after, arg1, arg2, arg3) { default: args = [arg1, arg2, arg3]; for (i = 5; i < arguments.length; i++) { - // extend array dynamically, makes .apply run much faster in v6.0.0 + // Extend array dynamically, makes .apply run much faster in v6.0.0 args[i - 2] = arguments[i]; } break; @@ -493,7 +493,7 @@ exports.setInterval = function setInterval(callback, repeat, arg1, arg2, arg3) { default: args = [arg1, arg2, arg3]; for (i = 5; i < arguments.length; i++) { - // extend array dynamically, makes .apply run much faster in v6.0.0 + // Extend array dynamically, makes .apply run much faster in v6.0.0 args[i - 2] = arguments[i]; } break; @@ -712,7 +712,7 @@ function setImmediate(callback, arg1, arg2, arg3) { default: args = [arg1, arg2, arg3]; for (i = 4; i < arguments.length; i++) { - // extend array dynamically, makes .apply run much faster in v6.0.0 + // Extend array dynamically, makes .apply run much faster in v6.0.0 args[i - 1] = arguments[i]; } break; diff --git a/lib/url.js b/lib/url.js index eac9d1511b9f8c..29dec5cc5f91c2 100644 --- a/lib/url.js +++ b/lib/url.js @@ -461,7 +461,7 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) { this.path = p + s; } - // finally, reconstruct the href based on what has been validated. + // Finally, reconstruct the href based on what has been validated. this.href = this.format(); return this; }; @@ -629,7 +629,7 @@ Url.prototype.format = function format() { pathname = newPathname; } - // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // Only the slashedProtocols get the //. Not mailto:, xmpp:, etc. // unless they had them to begin with. if (this.slashes || slashedProtocol.has(protocol)) { if (this.slashes || host) { @@ -686,7 +686,7 @@ Url.prototype.resolveObject = function resolveObject(relative) { // even href="" will remove it. result.hash = relative.hash; - // if the relative url is empty, then there's nothing left to do here. + // If the relative url is empty, then there's nothing left to do here. if (relative.href === '') { result.href = result.format(); return result; @@ -888,7 +888,7 @@ Url.prototype.resolveObject = function resolveObject(relative) { } } - // if the path is allowed to go above the root, restore leading ..s + // If the path is allowed to go above the root, restore leading ..s if (!mustEndAbs && !removeAllDots) { while (up--) { srcPath.unshift('..'); diff --git a/lib/util.js b/lib/util.js index cd96db044a834b..922a01f357e408 100644 --- a/lib/util.js +++ b/lib/util.js @@ -278,7 +278,7 @@ function timestamp() { return [d.getDate(), months[d.getMonth()], time].join(' '); } -// log is just a thin wrapper to console.log that prepends a timestamp +// Log is just a thin wrapper to console.log that prepends a timestamp function log() { console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); } diff --git a/lib/zlib.js b/lib/zlib.js index 559f6c2d5f3056..2ecec19f3064e9 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -510,7 +510,7 @@ function processChunkSync(self, chunk, flushFlag) { assert(have === 0, 'have should not go down'); } - // exhausted the output buffer, or used all the input create a new one. + // Exhausted the output buffer, or used all the input create a new one. if (availOutAfter === 0 || offset >= chunkSize) { availOutBefore = chunkSize; offset = 0; @@ -599,7 +599,7 @@ function processCallback() { return; } - // exhausted the output buffer, or used all the input create a new one. + // Exhausted the output buffer, or used all the input create a new one. if (availOutAfter === 0 || self._outOffset >= self._chunkSize) { handle.availOutBefore = self._chunkSize; self._outOffset = 0; diff --git a/src/debug_utils.cc b/src/debug_utils.cc index 77ea219bfc880a..4f086106b66ca7 100644 --- a/src/debug_utils.cc +++ b/src/debug_utils.cc @@ -30,6 +30,27 @@ #endif // __POSIX__ +#if defined(__linux__) || defined(__sun) +#include +#endif // (__linux__) || defined(__sun) + +#ifdef __APPLE__ +#include // _dyld_get_image_name() +#endif // __APPLE__ + +#ifdef _AIX +#include // ld_info structure +#endif // _AIX + +#ifdef _WIN32 +#include +#include +#include +#include +#include +#include +#endif // _WIN32 + namespace node { #ifdef __POSIX__ @@ -299,6 +320,108 @@ void CheckedUvLoopClose(uv_loop_t* loop) { CHECK(0 && "uv_loop_close() while having open handles"); } +std::vector NativeSymbolDebuggingContext::GetLoadedLibraries() { + std::vector list; +#ifdef __linux__ + dl_iterate_phdr( + [](struct dl_phdr_info* info, size_t size, void* data) { + auto list = static_cast*>(data); + if (*info->dlpi_name != '\0') { + list->push_back(info->dlpi_name); + } + return 0; + }, + &list); +#elif __APPLE__ + uint32_t i = 0; + for (const char* name = _dyld_get_image_name(i); name != nullptr; + name = _dyld_get_image_name(++i)) { + list.push_back(name); + } + +#elif _AIX + // We can't tell in advance how large the buffer needs to be. + // Retry until we reach too large a size (1Mb). + const unsigned int kBufferGrowStep = 4096; + MallocedBuffer buffer(kBufferGrowStep); + int rc = -1; + do { + rc = loadquery(L_GETINFO, buffer.data, buffer.size); + if (rc == 0) break; + buffer = MallocedBuffer(buffer.size + kBufferGrowStep); + } while (buffer.size < 1024 * 1024); + + if (rc == 0) { + char* buf = buffer.data; + ld_info* cur_info = nullptr; + do { + std::ostringstream str; + cur_info = reinterpret_cast(buf); + char* member_name = cur_info->ldinfo_filename + + strlen(cur_info->ldinfo_filename) + 1; + if (*member_name != '\0') { + str << cur_info->ldinfo_filename << "(" << member_name << ")"; + list.push_back(str.str()); + str.str(""); + } else { + list.push_back(cur_info->ldinfo_filename); + } + buf += cur_info->ldinfo_next; + } while (cur_info->ldinfo_next != 0); + } +#elif __sun + Link_map* p; + + if (dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &p) != -1) { + for (Link_map* l = p; l != nullptr; l = l->l_next) { + list.push_back(l->l_name); + } + } + +#elif _WIN32 + // Windows implementation - get a handle to the process. + HANDLE process_handle = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, + FALSE, GetCurrentProcessId()); + if (process_handle == nullptr) { + // Cannot proceed, return an empty list. + return list; + } + // Get a list of all the modules in this process + DWORD size_1 = 0; + DWORD size_2 = 0; + // First call to get the size of module array needed + if (EnumProcessModules(process_handle, nullptr, 0, &size_1)) { + MallocedBuffer modules(size_1); + + // Second call to populate the module array + if (EnumProcessModules(process_handle, modules.data, size_1, &size_2)) { + for (DWORD i = 0; + i < (size_1 / sizeof(HMODULE)) && i < (size_2 / sizeof(HMODULE)); + i++) { + WCHAR module_name[MAX_PATH]; + // Obtain and report the full pathname for each module + if (GetModuleFileNameExW(process_handle, + modules.data[i], + module_name, + arraysize(module_name) / sizeof(WCHAR))) { + DWORD size = WideCharToMultiByte( + CP_UTF8, 0, module_name, -1, nullptr, 0, nullptr, nullptr); + char* str = new char[size]; + WideCharToMultiByte( + CP_UTF8, 0, module_name, -1, str, size, nullptr, nullptr); + list.push_back(str); + } + } + } + } + + // Release the handle to the process. + CloseHandle(process_handle); +#endif + return list; +} + + } // namespace node extern "C" void __DumpBacktrace(FILE* fp) { diff --git a/src/debug_utils.h b/src/debug_utils.h index c6c8e03b51fd64..034d8a9ab331dc 100644 --- a/src/debug_utils.h +++ b/src/debug_utils.h @@ -113,6 +113,7 @@ class NativeSymbolDebuggingContext { = delete; NativeSymbolDebuggingContext operator=(NativeSymbolDebuggingContext&&) = delete; + static std::vector GetLoadedLibraries(); }; // Variant of `uv_loop_close` that tries to be as helpful as possible diff --git a/src/env-inl.h b/src/env-inl.h index ba5704ed2e9574..f28701c70f14d2 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -585,6 +585,10 @@ inline std::shared_ptr Environment::options() { return options_; } +inline std::shared_ptr Environment::inspector_host_port() { + return inspector_host_port_; +} + inline std::shared_ptr IsolateData::options() { return options_; } diff --git a/src/env.cc b/src/env.cc index bdb3c1ea247e21..023e69665d94ed 100644 --- a/src/env.cc +++ b/src/env.cc @@ -5,6 +5,7 @@ #include "node_file.h" #include "node_internals.h" #include "node_native_module.h" +#include "node_options-inl.h" #include "node_platform.h" #include "node_worker.h" #include "tracing/agent.h" @@ -192,7 +193,7 @@ Environment::Environment(IsolateData* isolate_data, // part of the per-Isolate option set, for which in turn the defaults are // part of the per-process option set. options_.reset(new EnvironmentOptions(*isolate_data->options()->per_env)); - options_->debug_options.reset(new DebugOptions(*options_->debug_options)); + inspector_host_port_.reset(new HostPort(options_->debug_options().host_port)); #if HAVE_INSPECTOR // We can only create the inspector agent after having cloned the options. @@ -340,6 +341,13 @@ void Environment::Start(const std::vector& args, static uv_once_t init_once = UV_ONCE_INIT; uv_once(&init_once, InitThreadLocalOnce); uv_key_set(&thread_local_env, this); + +#if HAVE_INSPECTOR + // This needs to be set before we start the inspector + Local obj = Object::New(isolate()); + CHECK(obj->SetPrototype(context(), Null(isolate())).FromJust()); + set_inspector_console_api_object(obj); +#endif // HAVE_INSPECTOR } void Environment::RegisterHandleCleanups() { diff --git a/src/env.h b/src/env.h index 64593a0025c3b6..ec0368e040a608 100644 --- a/src/env.h +++ b/src/env.h @@ -911,6 +911,7 @@ class Environment { void* data); inline std::shared_ptr options(); + inline std::shared_ptr inspector_host_port(); private: inline void CreateImmediate(native_immediate_callback cb, @@ -942,6 +943,14 @@ class Environment { std::vector destroy_async_id_list_; std::shared_ptr options_; + // options_ contains debug options parsed from CLI arguments, + // while inspector_host_port_ stores the actual inspector host + // and port being used. For example the port is -1 by default + // and can be specified as 0 (meaning any port allocated when the + // server starts listening), but when the inspector server starts + // the inspector_host_port_->port() will be the actual port being + // used. + std::shared_ptr inspector_host_port_; uint32_t module_id_counter_ = 0; uint32_t script_id_counter_ = 0; diff --git a/src/inspector/main_thread_interface.cc b/src/inspector/main_thread_interface.cc index bb637d3a77f6fa..2ed6362df53fda 100644 --- a/src/inspector/main_thread_interface.cc +++ b/src/inspector/main_thread_interface.cc @@ -255,8 +255,9 @@ void MainThreadInterface::Post(std::unique_ptr request) { if (needs_notify) { CHECK_EQ(0, uv_async_send(&main_thread_request_->first)); if (isolate_ != nullptr && platform_ != nullptr) { - platform_->CallOnForegroundThread(isolate_, - new DispatchMessagesTask(this)); + std::shared_ptr taskrunner = + platform_->GetForegroundTaskRunner(isolate_); + taskrunner->PostTask(std::make_unique(this)); isolate_->RequestInterrupt([](v8::Isolate* isolate, void* thread) { static_cast(thread)->DispatchMessages(); }, this); diff --git a/src/inspector/tracing_agent.cc b/src/inspector/tracing_agent.cc index 64bf7457d9f728..e8f9d569f8ee69 100644 --- a/src/inspector/tracing_agent.cc +++ b/src/inspector/tracing_agent.cc @@ -31,7 +31,7 @@ class InspectorTraceWriter : public node::tracing::AsyncTraceWriter { return; json_writer_.reset(); std::ostringstream result( - "{\"method\":\"NodeTracing.dataCollected\",\"data\":", + "{\"method\":\"NodeTracing.dataCollected\",\"params\":", std::ostringstream::ate); result << stream_.str(); result << "}"; diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index 5e53201c42d5c2..8710b8569072a1 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -40,6 +40,8 @@ using v8::Local; using v8::Message; using v8::Object; using v8::String; +using v8::Task; +using v8::TaskRunner; using v8::Value; using v8_inspector::StringBuffer; @@ -50,7 +52,7 @@ using v8_inspector::V8InspectorClient; static uv_sem_t start_io_thread_semaphore; static uv_async_t start_io_thread_async; -class StartIoTask : public v8::Task { +class StartIoTask : public Task { public: explicit StartIoTask(Agent* agent) : agent(agent) {} @@ -110,7 +112,9 @@ static int StartDebugSignalHandler() { sigset_t sigmask; // Mask all signals. sigfillset(&sigmask); - CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, &sigmask)); + sigset_t savemask; + CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, &savemask)); + sigmask = savemask; pthread_t thread; const int err = pthread_create(&thread, &attr, StartIoThreadMain, nullptr); @@ -502,6 +506,7 @@ class NodeInspectorClient : public V8InspectorClient { void installAdditionalCommandLineAPI(Local context, Local target) override { Local console_api = env_->inspector_console_api_object(); + CHECK(!console_api.IsEmpty()); Local properties = console_api->GetOwnPropertyNames(context).ToLocalChecked(); @@ -667,8 +672,9 @@ class NodeInspectorClient : public V8InspectorClient { }; Agent::Agent(Environment* env) - : parent_env_(env), - debug_options_(env->options()->debug_options) {} + : parent_env_(env), + debug_options_(env->options()->debug_options()), + host_port_(env->inspector_host_port()) {} Agent::~Agent() { if (start_io_thread_async.data == this) { @@ -679,13 +685,14 @@ Agent::~Agent() { } bool Agent::Start(const std::string& path, - std::shared_ptr options, + const DebugOptions& options, + std::shared_ptr host_port, bool is_main) { - if (options == nullptr) { - options = std::make_shared(); - } path_ = path; debug_options_ = options; + CHECK_NE(host_port, nullptr); + host_port_ = host_port; + client_ = std::make_shared(parent_env_, is_main); if (parent_env_->is_main_thread()) { CHECK_EQ(0, uv_async_init(parent_env_->event_loop(), @@ -697,13 +704,18 @@ bool Agent::Start(const std::string& path, StartDebugSignalHandler(); } - bool wait_for_connect = options->wait_for_connect(); + bool wait_for_connect = options.wait_for_connect(); if (parent_handle_) { wait_for_connect = parent_handle_->WaitForConnect(); parent_handle_->WorkerStarted(client_->getThreadHandle(), wait_for_connect); - } else if (!options->inspector_enabled || !StartIoThread()) { + } else if (!options.inspector_enabled || !StartIoThread()) { return false; } + + // TODO(joyeecheung): we should not be using process as a global object + // to transport --inspect-brk. Instead, the JS land can get this through + // require('internal/options') since it should be set once CLI parsing + // is done. if (wait_for_connect) { HandleScope scope(parent_env_->isolate()); parent_env_->process_object()->DefineOwnProperty( @@ -723,8 +735,7 @@ bool Agent::StartIoThread() { CHECK_NOT_NULL(client_); - io_ = InspectorIo::Start( - client_->getThreadHandle(), path_, debug_options_); + io_ = InspectorIo::Start(client_->getThreadHandle(), path_, host_port_); if (io_ == nullptr) { return false; } @@ -853,7 +864,9 @@ void Agent::RequestIoThreadStart() { uv_async_send(&start_io_thread_async); Isolate* isolate = parent_env_->isolate(); v8::Platform* platform = parent_env_->isolate_data()->platform(); - platform->CallOnForegroundThread(isolate, new StartIoTask(this)); + std::shared_ptr taskrunner = + platform->GetForegroundTaskRunner(isolate); + taskrunner->PostTask(std::make_unique(this)); isolate->RequestInterrupt(StartIoInterrupt, this); uv_async_send(&start_io_thread_async); } @@ -865,8 +878,7 @@ void Agent::ContextCreated(Local context, const ContextInfo& info) { } bool Agent::WillWaitForConnect() { - if (debug_options_->wait_for_connect()) - return true; + if (debug_options_.wait_for_connect()) return true; if (parent_handle_) return parent_handle_->WaitForConnect(); return false; diff --git a/src/inspector_agent.h b/src/inspector_agent.h index 9537ae05b61691..5e599a6339e903 100644 --- a/src/inspector_agent.h +++ b/src/inspector_agent.h @@ -11,7 +11,7 @@ #error("This header can only be used when inspector is enabled") #endif -#include "node_options.h" +#include "node_options-inl.h" #include "node_persistent.h" #include "v8.h" @@ -50,8 +50,9 @@ class Agent { // Create client_, may create io_ if option enabled bool Start(const std::string& path, - std::shared_ptr options, - bool is_worker); + const DebugOptions& options, + std::shared_ptr host_port, + bool is_main); // Stop and destroy io_ void Stop(); @@ -104,7 +105,8 @@ class Agent { // Calls StartIoThread() from off the main thread. void RequestIoThreadStart(); - std::shared_ptr options() { return debug_options_; } + const DebugOptions& options() { return debug_options_; } + std::shared_ptr host_port() { return host_port_; } void ContextCreated(v8::Local context, const ContextInfo& info); // Interface for interacting with inspectors in worker threads @@ -121,7 +123,13 @@ class Agent { std::unique_ptr io_; std::unique_ptr parent_handle_; std::string path_; - std::shared_ptr debug_options_; + + // This is a copy of the debug options parsed from CLI in the Environment. + // Do not use the host_port in that, instead manipulate the shared host_port_ + // pointer which is meant to store the actual host and port of the inspector + // server. + DebugOptions debug_options_; + std::shared_ptr host_port_; bool pending_enable_async_hook_ = false; bool pending_disable_async_hook_ = false; diff --git a/src/inspector_io.cc b/src/inspector_io.cc index da44d55d06e10a..7686294b2e2842 100644 --- a/src/inspector_io.cc +++ b/src/inspector_io.cc @@ -242,9 +242,9 @@ class InspectorIoDelegate: public node::inspector::SocketServerDelegate { std::unique_ptr InspectorIo::Start( std::shared_ptr main_thread, const std::string& path, - std::shared_ptr options) { + std::shared_ptr host_port) { auto io = std::unique_ptr( - new InspectorIo(main_thread, path, options)); + new InspectorIo(main_thread, path, host_port)); if (io->request_queue_->Expired()) { // Thread is not running return nullptr; } @@ -253,9 +253,12 @@ std::unique_ptr InspectorIo::Start( InspectorIo::InspectorIo(std::shared_ptr main_thread, const std::string& path, - std::shared_ptr options) - : main_thread_(main_thread), options_(options), - thread_(), script_name_(path), id_(GenerateID()) { + std::shared_ptr host_port) + : main_thread_(main_thread), + host_port_(host_port), + thread_(), + script_name_(path), + id_(GenerateID()) { Mutex::ScopedLock scoped_lock(thread_start_lock_); CHECK_EQ(uv_thread_create(&thread_, InspectorIo::ThreadMain, this), 0); thread_start_condition_.Wait(scoped_lock); @@ -287,16 +290,17 @@ void InspectorIo::ThreadMain() { std::unique_ptr delegate( new InspectorIoDelegate(queue, main_thread_, id_, script_path, script_name_)); - InspectorSocketServer server(std::move(delegate), &loop, - options_->host().c_str(), - options_->port()); + InspectorSocketServer server(std::move(delegate), + &loop, + host_port_->host().c_str(), + host_port_->port()); request_queue_ = queue->handle(); // Its lifetime is now that of the server delegate queue.reset(); { Mutex::ScopedLock scoped_lock(thread_start_lock_); if (server.Start()) { - port_ = server.Port(); + host_port_->set_port(server.Port()); } thread_start_condition_.Broadcast(scoped_lock); } diff --git a/src/inspector_io.h b/src/inspector_io.h index 21df54e03126e9..bc09afdd3df54e 100644 --- a/src/inspector_io.h +++ b/src/inspector_io.h @@ -46,21 +46,22 @@ class InspectorIo { // bool Start(); // Returns empty pointer if thread was not started static std::unique_ptr Start( - std::shared_ptr main_thread, const std::string& path, - std::shared_ptr options); + std::shared_ptr main_thread, + const std::string& path, + std::shared_ptr host_port); // Will block till the transport thread shuts down ~InspectorIo(); void StopAcceptingNewConnections(); - const std::string& host() const { return options_->host(); } - int port() const { return port_; } + const std::string& host() const { return host_port_->host(); } + int port() const { return host_port_->port(); } std::vector GetTargetIds() const; private: InspectorIo(std::shared_ptr handle, const std::string& path, - std::shared_ptr options); + std::shared_ptr host_port); // Wrapper for agent->ThreadMain() static void ThreadMain(void* agent); @@ -74,7 +75,7 @@ class InspectorIo { // Used to post on a frontend interface thread, lives while the server is // running std::shared_ptr request_queue_; - std::shared_ptr options_; + std::shared_ptr host_port_; // The IO thread runs its own uv_loop to implement the TCP server off // the main thread. @@ -84,7 +85,6 @@ class InspectorIo { Mutex thread_start_lock_; ConditionVariable thread_start_condition_; std::string script_name_; - int port_ = -1; // May be accessed from any thread const std::string id_; }; diff --git a/src/inspector_js_api.cc b/src/inspector_js_api.cc index 52f14639a430d3..8f0332cc616341 100644 --- a/src/inspector_js_api.cc +++ b/src/inspector_js_api.cc @@ -243,12 +243,12 @@ void Open(const FunctionCallbackInfo& args) { if (args.Length() > 0 && args[0]->IsUint32()) { uint32_t port = args[0].As()->Value(); - agent->options()->host_port.port = port; + agent->host_port()->set_port(static_cast(port)); } if (args.Length() > 1 && args[1]->IsString()) { Utf8Value host(env->isolate(), args[1].As()); - agent->options()->host_port.host_name = *host; + agent->host_port()->set_host(*host); } if (args.Length() > 2 && args[2]->IsBoolean()) { @@ -277,12 +277,6 @@ void Url(const FunctionCallbackInfo& args) { void Initialize(Local target, Local unused, Local context, void* priv) { Environment* env = Environment::GetCurrent(context); - { - auto obj = Object::New(env->isolate()); - auto null = Null(env->isolate()); - CHECK(obj->SetPrototype(context, null).FromJust()); - env->set_inspector_console_api_object(obj); - } Agent* agent = env->inspector_agent(); env->SetMethod(target, "consoleCall", InspectorConsoleCall); diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index 6b8d3f91056823..9e67e2ca24b7c0 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -11,10 +11,6 @@ #define CHECK_TO_NUMBER(env, context, result, src) \ CHECK_TO_TYPE((env), Number, (context), (result), (src), napi_number_expected) -#define CHECK_TO_BOOL(env, context, result, src) \ - CHECK_TO_TYPE((env), Boolean, (context), (result), (src), \ - napi_boolean_expected) - // n-api defines NAPI_AUTO_LENGHTH as the indicator that a string // is null terminated. For V8 the equivalent is -1. The assert // validates that our cast of NAPI_AUTO_LENGTH results in -1 as @@ -2155,11 +2151,9 @@ napi_status napi_coerce_to_bool(napi_env env, CHECK_ARG(env, value); CHECK_ARG(env, result); - v8::Local context = env->context(); - v8::Local b; - - CHECK_TO_BOOL(env, context, b, value); - + v8::Isolate* isolate = env->isolate; + v8::Local b = + v8impl::V8LocalValueFromJsValue(value)->ToBoolean(isolate); *result = v8impl::JsValueFromV8LocalValue(b); return GET_RETURN_STATUS(env); } diff --git a/src/node.cc b/src/node.cc index 25020734430426..82d8653c08ab9e 100644 --- a/src/node.cc +++ b/src/node.cc @@ -27,6 +27,7 @@ #include "node_internals.h" #include "node_metadata.h" #include "node_native_module.h" +#include "node_options-inl.h" #include "node_perf.h" #include "node_platform.h" #include "node_revert.h" @@ -259,13 +260,15 @@ static struct { } #if HAVE_INSPECTOR - bool StartInspector(Environment* env, const char* script_path, - std::shared_ptr options) { + bool StartInspector(Environment* env, const char* script_path) { // Inspector agent can't fail to start, but if it was configured to listen // right away on the websocket port and fails to bind/etc, this will return // false. return env->inspector_agent()->Start( - script_path == nullptr ? "" : script_path, options, true); + script_path == nullptr ? "" : script_path, + env->options()->debug_options(), + env->inspector_host_port(), + true); } bool InspectorStarted(Environment* env) { @@ -306,8 +309,7 @@ static struct { void Dispose() {} void DrainVMTasks(Isolate* isolate) {} void CancelVMTasks(Isolate* isolate) {} - bool StartInspector(Environment* env, const char* script_path, - const DebugOptions& options) { + bool StartInspector(Environment* env, const char* script_path) { env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0"); return true; } @@ -1127,24 +1129,24 @@ void SetupProcessObject(Environment* env, // TODO(refack): move the following 4 to `node_config` // --inspect-brk - if (env->options()->debug_options->wait_for_connect()) { + if (env->options()->debug_options().wait_for_connect()) { READONLY_DONT_ENUM_PROPERTY(process, "_breakFirstLine", True(env->isolate())); } - if (env->options()->debug_options->break_node_first_line) { + if (env->options()->debug_options().break_node_first_line) { READONLY_DONT_ENUM_PROPERTY(process, "_breakNodeFirstLine", True(env->isolate())); } // --inspect --debug-brk - if (env->options()->debug_options->deprecated_invocation()) { + if (env->options()->debug_options().deprecated_invocation()) { READONLY_DONT_ENUM_PROPERTY(process, "_deprecatedDebugBrk", True(env->isolate())); } // --debug or, --debug-brk without --inspect - if (env->options()->debug_options->invalid_invocation()) { + if (env->options()->debug_options().invalid_invocation()) { READONLY_DONT_ENUM_PROPERTY(process, "_invalidDebug", True(env->isolate())); } @@ -1356,7 +1358,7 @@ void LoadEnvironment(Environment* env) { get_linked_binding_fn, get_internal_binding_fn, Boolean::New(env->isolate(), - env->options()->debug_options->break_node_first_line) + env->options()->debug_options().break_node_first_line) }; // Bootstrap internal loaders @@ -1390,12 +1392,10 @@ void LoadEnvironment(Environment* env) { } } - -static void StartInspector(Environment* env, const char* path, - std::shared_ptr debug_options) { +static void StartInspector(Environment* env, const char* path) { #if HAVE_INSPECTOR CHECK(!env->inspector_agent()->IsListening()); - v8_platform.StartInspector(env, path, debug_options); + v8_platform.StartInspector(env, path); #endif // HAVE_INSPECTOR } @@ -2038,9 +2038,9 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data, env.Start(args, exec_args, v8_is_profiling); const char* path = args.size() > 1 ? args[1].c_str() : nullptr; - StartInspector(&env, path, env.options()->debug_options); + StartInspector(&env, path); - if (env.options()->debug_options->inspector_enabled && + if (env.options()->debug_options().inspector_enabled && !v8_platform.InspectorStarted(&env)) { return 12; // Signal internal error. } diff --git a/src/node_config.cc b/src/node_config.cc index c2bf3349c46269..27ec44b8d30538 100644 --- a/src/node_config.cc +++ b/src/node_config.cc @@ -1,5 +1,6 @@ #include "node.h" #include "node_i18n.h" +#include "node_options-inl.h" #include "env-inl.h" #include "util-inl.h" @@ -94,20 +95,18 @@ static void Initialize(Local target, READONLY_STRING_PROPERTY(target, "warningFile", warning_file); } - std::shared_ptr debug_options = env->options()->debug_options; Local debug_options_obj = Object::New(isolate); READONLY_PROPERTY(target, "debugOptions", debug_options_obj); - READONLY_STRING_PROPERTY(debug_options_obj, "host", - debug_options->host()); - - READONLY_PROPERTY(debug_options_obj, - "port", - Integer::New(isolate, debug_options->port())); - + const DebugOptions& debug_options = env->options()->debug_options(); READONLY_PROPERTY(debug_options_obj, "inspectorEnabled", - Boolean::New(isolate, debug_options->inspector_enabled)); + Boolean::New(isolate, debug_options.inspector_enabled)); + READONLY_STRING_PROPERTY( + debug_options_obj, "host", debug_options.host_port.host()); + READONLY_PROPERTY(debug_options_obj, + "port", + Integer::New(isolate, debug_options.host_port.port())); } // InitConfig } // namespace node diff --git a/src/node_crypto.cc b/src/node_crypto.cc index e20b902d03bbb3..b6c3a715982bdc 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -801,7 +801,7 @@ void SecureContext::AddCACert(const FunctionCallbackInfo& args) { return; X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get()); - while (X509* x509 = PEM_read_bio_X509( + while (X509* x509 = PEM_read_bio_X509_AUX( bio.get(), nullptr, NoPasswordCallback, nullptr)) { if (cert_store == root_cert_store) { cert_store = NewRootCertStore(); @@ -3431,7 +3431,6 @@ bool Hash::HashInit(const char* hash_type) { mdctx_.reset(); return false; } - finalized_ = false; return true; } @@ -3485,7 +3484,6 @@ void Hash::HashDigest(const FunctionCallbackInfo& args) { unsigned int md_len; EVP_DigestFinal_ex(hash->mdctx_.get(), md_value, &md_len); - hash->finalized_ = true; Local error; MaybeLocal rc = diff --git a/src/node_crypto.h b/src/node_crypto.h index 5f98af754ea727..0ee45cf9ea2c02 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -476,14 +476,12 @@ class Hash : public BaseObject { Hash(Environment* env, v8::Local wrap) : BaseObject(env, wrap), - mdctx_(nullptr), - finalized_(false) { + mdctx_(nullptr) { MakeWeak(); } private: EVPMDPointer mdctx_; - bool finalized_; }; class SignBase : public BaseObject { diff --git a/src/node_metadata.cc b/src/node_metadata.cc index fd37dbb97bf303..822b6a490d13d2 100644 --- a/src/node_metadata.cc +++ b/src/node_metadata.cc @@ -2,6 +2,7 @@ #include "ares.h" #include "nghttp2/nghttp2ver.h" #include "node.h" +#include "node_internals.h" #include "util.h" #include "uv.h" #include "v8.h" diff --git a/src/node_options-inl.h b/src/node_options-inl.h index 468368ac84f630..8aaa62524b8ee6 100644 --- a/src/node_options-inl.h +++ b/src/node_options-inl.h @@ -14,7 +14,11 @@ PerIsolateOptions* PerProcessOptions::get_per_isolate_options() { } DebugOptions* EnvironmentOptions::get_debug_options() { - return debug_options.get(); + return &debug_options_; +} + +const DebugOptions& EnvironmentOptions::debug_options() const { + return debug_options_; } EnvironmentOptions* PerIsolateOptions::get_per_env_options() { diff --git a/src/node_options.cc b/src/node_options.cc index 7f6ae8bdf009e2..f75010b64e83ed 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -44,7 +44,9 @@ void EnvironmentOptions::CheckOptions(std::vector* errors) { errors->push_back("invalid value for --http-parser"); } - debug_options->CheckOptions(errors); +#if HAVE_INSPECTOR + debug_options_.CheckOptions(errors); +#endif // HAVE_INSPECTOR } namespace options_parser { @@ -54,7 +56,6 @@ namespace options_parser { // TODO(addaleax): Make that unnecessary. DebugOptionsParser::DebugOptionsParser() { -#if HAVE_INSPECTOR AddOption("--inspect-port", "set host:port for inspector", &DebugOptions::host_port, @@ -84,10 +85,11 @@ DebugOptionsParser::DebugOptionsParser() { AddOption("--debug-brk", "", &DebugOptions::break_first_line); Implies("--debug-brk", "--debug"); AddAlias("--debug-brk=", { "--inspect-port", "--debug-brk" }); -#endif } +#if HAVE_INSPECTOR DebugOptionsParser DebugOptionsParser::instance; +#endif // HAVE_INSPECTOR EnvironmentOptionsParser::EnvironmentOptionsParser() { AddOption("--experimental-modules", @@ -203,8 +205,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { AddOption("--napi-modules", "", NoOp{}, kAllowedInEnvironment); +#if HAVE_INSPECTOR Insert(&DebugOptionsParser::instance, &EnvironmentOptions::get_debug_options); +#endif // HAVE_INSPECTOR } EnvironmentOptionsParser EnvironmentOptionsParser::instance; @@ -361,7 +365,7 @@ HostPort SplitHostPort(const std::string& arg, // so if it has an effect only an IPv6 address was specified. std::string host = RemoveBrackets(arg); if (host.length() < arg.length()) - return HostPort { host, -1 }; + return HostPort{host, DebugOptions::kDefaultInspectorPort}; size_t colon = arg.rfind(':'); if (colon == std::string::npos) { @@ -369,7 +373,7 @@ HostPort SplitHostPort(const std::string& arg, // if it's not all decimal digits, it's a host name. for (char c : arg) { if (c < '0' || c > '9') { - return HostPort { arg, -1 }; + return HostPort{arg, DebugOptions::kDefaultInspectorPort}; } } return HostPort { "", ParseAndValidatePort(arg, errors) }; @@ -435,11 +439,11 @@ void GetOptions(const FunctionCallbackInfo& args) { const HostPort& host_port = *parser.Lookup(field, opts); Local obj = Object::New(isolate); Local host; - if (!ToV8Value(context, host_port.host_name).ToLocal(&host) || + if (!ToV8Value(context, host_port.host()).ToLocal(&host) || obj->Set(context, env->host_string(), host).IsNothing() || obj->Set(context, env->port_string(), - Integer::New(isolate, host_port.port)) + Integer::New(isolate, host_port.port())) .IsNothing()) { return; } diff --git a/src/node_options.h b/src/node_options.h index abfd491c98fe7e..a62293286ceb6a 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -3,22 +3,44 @@ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS +#include #include -#include #include -#include +#include #include "node_constants.h" +#include "util.h" namespace node { -struct HostPort { - std::string host_name; - int port; +class HostPort { + public: + HostPort(const std::string& host_name, int port) + : host_name_(host_name), port_(port) {} + HostPort(const HostPort&) = default; + HostPort& operator=(const HostPort&) = default; + HostPort(HostPort&&) = default; + HostPort& operator=(HostPort&&) = default; + + void set_host(const std::string& host) { host_name_ = host; } + + void set_port(int port) { port_ = port; } + + const std::string& host() const { return host_name_; } + + int port() const { + // TODO(joyeecheung): make port a uint16_t + CHECK_GE(port_, 0); + return port_; + } void Update(const HostPort& other) { - if (!other.host_name.empty()) host_name = other.host_name; - if (other.port >= 0) port = other.port; + if (!other.host_name_.empty()) host_name_ = other.host_name_; + if (other.port_ >= 0) port_ = other.port_; } + + private: + std::string host_name_; + int port_; }; class Options { @@ -33,13 +55,25 @@ class Options { // per-Isolate, rather than per-Environment. class DebugOptions : public Options { public: + DebugOptions() = default; + DebugOptions(const DebugOptions&) = default; + DebugOptions& operator=(const DebugOptions&) = default; + DebugOptions(DebugOptions&&) = default; + DebugOptions& operator=(DebugOptions&&) = default; + + // --inspect bool inspector_enabled = false; + // --debug bool deprecated_debug = false; + // --inspect-brk bool break_first_line = false; + // --inspect-brk-node bool break_node_first_line = false; - HostPort host_port = {"127.0.0.1", -1}; + enum { kDefaultInspectorPort = 9229 }; + HostPort host_port{"127.0.0.1", kDefaultInspectorPort}; + bool deprecated_invocation() const { return deprecated_debug && inspector_enabled && @@ -53,19 +87,10 @@ class DebugOptions : public Options { bool wait_for_connect() const { return break_first_line || break_node_first_line; } - - const std::string& host() { - return host_port.host_name; - } - - int port() { - return host_port.port < 0 ? kDefaultInspectorPort : host_port.port; - } }; class EnvironmentOptions : public Options { public: - std::shared_ptr debug_options { new DebugOptions() }; bool abort_on_uncaught_exception = false; bool experimental_modules = false; bool experimental_repl_await = false; @@ -103,7 +128,11 @@ class EnvironmentOptions : public Options { std::vector user_argv; inline DebugOptions* get_debug_options(); + inline const DebugOptions& debug_options() const; void CheckOptions(std::vector* errors); + + private: + DebugOptions debug_options_; }; class PerIsolateOptions : public Options { diff --git a/src/node_process.cc b/src/node_process.cc index a3ccc2343e96e3..792cc510924b4e 100644 --- a/src/node_process.cc +++ b/src/node_process.cc @@ -825,14 +825,7 @@ void GetActiveHandles(const FunctionCallbackInfo& args) { void DebugPortGetter(Local property, const PropertyCallbackInfo& info) { Environment* env = Environment::GetCurrent(info); - Mutex::ScopedLock lock(process_mutex); - int port = env->options()->debug_options->port(); -#if HAVE_INSPECTOR - if (port == 0) { - if (auto io = env->inspector_agent()->io()) - port = io->port(); - } -#endif // HAVE_INSPECTOR + int port = env->inspector_host_port()->port(); info.GetReturnValue().Set(port); } @@ -841,9 +834,8 @@ void DebugPortSetter(Local property, Local value, const PropertyCallbackInfo& info) { Environment* env = Environment::GetCurrent(info); - Mutex::ScopedLock lock(process_mutex); - env->options()->debug_options->host_port.port = - value->Int32Value(env->context()).FromMaybe(0); + int32_t port = value->Int32Value(env->context()).FromMaybe(0); + env->inspector_host_port()->set_port(static_cast(port)); } diff --git a/src/node_util.cc b/src/node_util.cc index 4a426ddadb2a20..f6ebee895fe3bf 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -56,7 +56,6 @@ static void GetOwnNonIndexProperties( } static void GetPromiseDetails(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); // Return undefined if it's not a Promise. if (!args[0]->IsPromise()) return; @@ -75,7 +74,6 @@ static void GetPromiseDetails(const FunctionCallbackInfo& args) { } static void GetProxyDetails(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); // Return undefined if it's not a proxy. if (!args[0]->IsProxy()) return; diff --git a/src/node_version.h b/src/node_version.h index d5d11030cfac2c..8961375429df59 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -23,13 +23,13 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 11 -#define NODE_MINOR_VERSION 4 -#define NODE_PATCH_VERSION 1 +#define NODE_MINOR_VERSION 5 +#define NODE_PATCH_VERSION 0 #define NODE_VERSION_IS_LTS 0 #define NODE_VERSION_LTS_CODENAME "" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) diff --git a/src/node_watchdog.cc b/src/node_watchdog.cc index b8665dc1be225d..9ef7bafeded44f 100644 --- a/src/node_watchdog.cc +++ b/src/node_watchdog.cc @@ -187,7 +187,9 @@ int SigintWatchdogHelper::Start() { sigset_t sigmask; sigfillset(&sigmask); - CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, &sigmask)); + sigset_t savemask; + CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, &savemask)); + sigmask = savemask; int ret = pthread_create(&thread_, nullptr, RunSigintWatchdog, nullptr); CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, nullptr)); if (ret != 0) { diff --git a/src/node_worker.cc b/src/node_worker.cc index e99ac59c01e06d..65d3b7297cc65b 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -37,7 +37,10 @@ Mutex next_thread_id_mutex; #if NODE_USE_V8_PLATFORM && HAVE_INSPECTOR void StartWorkerInspector(Environment* child, const std::string& url) { - child->inspector_agent()->Start(url, nullptr, false); + child->inspector_agent()->Start(url, + child->options()->debug_options(), + child->inspector_host_port(), + false); } void AddWorkerInspector(Environment* parent, diff --git a/src/notrace_macros.py b/src/notrace_macros.py index e49dd350d1db23..334f9c0c7f7a87 100644 --- a/src/notrace_macros.py +++ b/src/notrace_macros.py @@ -1,6 +1,9 @@ # This file is used by tools/js2c.py to preprocess out the DTRACE symbols in # builds that don't support DTrace. This is not used in builds that support # DTrace. + +# flake8: noqa + macro DTRACE_HTTP_CLIENT_REQUEST(x) = ; macro DTRACE_HTTP_CLIENT_RESPONSE(x) = ; macro DTRACE_HTTP_SERVER_REQUEST(x) = ; diff --git a/src/util.cc b/src/util.cc index 9f0b8ebc9d7596..ba30b23770b52e 100644 --- a/src/util.cc +++ b/src/util.cc @@ -116,7 +116,8 @@ std::string GetHumanReadableProcessName() { } void GetHumanReadableProcessName(char (*name)[1024]) { - char title[1024] = "Node.js"; + // Leave room after title for pid, which can be up to 20 digits for 64 bit. + char title[1000] = "Node.js"; uv_get_process_title(title, sizeof(title)); snprintf(*name, sizeof(*name), "%s[%d]", title, uv_os_getpid()); } diff --git a/test/abort/test-abort-backtrace.js b/test/abort/test-abort-backtrace.js index 7f87ef0e7f4559..b609ec7e4e6a7a 100644 --- a/test/abort/test-abort-backtrace.js +++ b/test/abort/test-abort-backtrace.js @@ -10,7 +10,7 @@ if (process.argv[2] === 'child') { const stderr = child.stderr.toString(); assert.strictEqual(child.stdout.toString(), ''); - // stderr will be empty for systems that don't support backtraces. + // Stderr will be empty for systems that don't support backtraces. if (stderr !== '') { const frames = stderr.trimRight().split('\n').map((s) => s.trim()); diff --git a/test/async-hooks/test-async-await.js b/test/async-hooks/test-async-await.js index 0103f63621e3ba..8aee59a36ff561 100644 --- a/test/async-hooks/test-async-await.js +++ b/test/async-hooks/test-async-await.js @@ -14,7 +14,7 @@ const util = require('util'); const sleep = util.promisify(setTimeout); // either 'inited' or 'resolved' const promisesInitState = new Map(); -// either 'before' or 'after' AND asyncId must be present in the other map +// Either 'before' or 'after' AND asyncId must be present in the other map const promisesExecutionState = new Map(); const hooks = initHooks({ diff --git a/test/async-hooks/test-embedder.api.async-resource.after-on-destroyed.js b/test/async-hooks/test-embedder.api.async-resource.after-on-destroyed.js index 3cf0cc430f0fe0..a389eddf421cc8 100644 --- a/test/async-hooks/test-embedder.api.async-resource.after-on-destroyed.js +++ b/test/async-hooks/test-embedder.api.async-resource.after-on-destroyed.js @@ -14,7 +14,7 @@ if (process.argv[2] === 'child') { const hooks = initHooks(); hooks.enable(); - // once 'destroy' has been emitted, we can no longer emit 'after' + // Once 'destroy' has been emitted, we can no longer emit 'after' // Emitting 'before', 'after' and then 'destroy' const event1 = new AsyncResource('event1', async_hooks.executionAsyncId()); diff --git a/test/async-hooks/test-embedder.api.async-resource.before-on-destroyed.js b/test/async-hooks/test-embedder.api.async-resource.before-on-destroyed.js index 6463c438ed9102..d6465a8445282d 100644 --- a/test/async-hooks/test-embedder.api.async-resource.before-on-destroyed.js +++ b/test/async-hooks/test-embedder.api.async-resource.before-on-destroyed.js @@ -14,7 +14,7 @@ if (process.argv[2] === 'child') { const hooks = initHooks(); hooks.enable(); - // once 'destroy' has been emitted, we can no longer emit 'before' + // Once 'destroy' has been emitted, we can no longer emit 'before' // Emitting 'before', 'after' and then 'destroy' const event1 = new AsyncResource('event1', async_hooks.executionAsyncId()); diff --git a/test/async-hooks/test-embedder.api.async-resource.improper-order.js b/test/async-hooks/test-embedder.api.async-resource.improper-order.js index 048ae0841357ec..4a38d87ce21e1f 100644 --- a/test/async-hooks/test-embedder.api.async-resource.improper-order.js +++ b/test/async-hooks/test-embedder.api.async-resource.improper-order.js @@ -14,7 +14,7 @@ if (process.argv[2] === 'child') { const hooks = initHooks(); hooks.enable(); - // async hooks enforce proper order of 'before' and 'after' invocations + // Async hooks enforce proper order of 'before' and 'after' invocations // Proper ordering const event1 = new AsyncResource('event1', async_hooks.executionAsyncId()); diff --git a/test/async-hooks/test-embedder.api.async-resource.js b/test/async-hooks/test-embedder.api.async-resource.js index 6f71a3e98cbf0f..74d6c478c835bb 100644 --- a/test/async-hooks/test-embedder.api.async-resource.js +++ b/test/async-hooks/test-embedder.api.async-resource.js @@ -29,13 +29,13 @@ assert.strictEqual( async_hooks.executionAsyncId() ); -// create first custom event 'alcazares' with triggerAsyncId derived +// Create first custom event 'alcazares' with triggerAsyncId derived // from async_hooks executionAsyncId const alcaTriggerId = async_hooks.executionAsyncId(); const alcaEvent = new AsyncResource('alcazares', alcaTriggerId); const alcazaresActivities = hooks.activitiesOfTypes([ 'alcazares' ]); -// alcazares event was constructed and thus only has an `init` call +// Alcazares event was constructed and thus only has an `init` call assert.strictEqual(alcazaresActivities.length, 1); const alcazares = alcazaresActivities[0]; assert.strictEqual(alcazares.type, 'alcazares'); @@ -83,7 +83,7 @@ function tick1() { checkInvocations(poblado, { init: 1, before: 1, after: 1 }, 'poblado emitted after'); - // after we disable the hooks we shouldn't receive any events anymore + // After we disable the hooks we shouldn't receive any events anymore hooks.disable(); alcaEvent.emitDestroy(); tick(1, common.mustCall(tick2)); diff --git a/test/async-hooks/test-enable-disable.js b/test/async-hooks/test-enable-disable.js index c14a125688d0f4..f71fd63e1c7756 100644 --- a/test/async-hooks/test-enable-disable.js +++ b/test/async-hooks/test-enable-disable.js @@ -261,7 +261,7 @@ function onexit() { 'hook2Second: when process exits'); checkInvocations(hook3First, { init: 1, before: 1, after: 1, destroy: 1 }, 'hook3First: when process exits'); - // we don't see a "destroy" invocation here since hook3 disabled itself + // We don't see a "destroy" invocation here since hook3 disabled itself // during its "after" invocation checkInvocations(hook3Second, { init: 1, before: 1, after: 1 }, 'hook3Second: when process exits'); diff --git a/test/async-hooks/test-enable-in-init.js b/test/async-hooks/test-enable-in-init.js index e4be9f9f87e3eb..7bc70994e1fa7d 100644 --- a/test/async-hooks/test-enable-in-init.js +++ b/test/async-hooks/test-enable-in-init.js @@ -10,7 +10,7 @@ const nestedHook = async_hooks.createHook({ let nestedCall = false; async_hooks.createHook({ - init: common.mustCall(function(id, type) { + init: common.mustCall(() => { nestedHook.enable(); if (!nestedCall) { nestedCall = true; diff --git a/test/async-hooks/test-fsreqcallback-readFile.js b/test/async-hooks/test-fsreqcallback-readFile.js index 3ae31378cd3199..01ccce9b4cc694 100644 --- a/test/async-hooks/test-fsreqcallback-readFile.js +++ b/test/async-hooks/test-fsreqcallback-readFile.js @@ -32,7 +32,7 @@ function onread() { checkInvocations(as[2], { init: 1, before: 1, after: 1, destroy: 1 }, 'reqwrap[2]: while in onread callback'); - // this callback is called from within the last fs req callback therefore + // This callback is called from within the last fs req callback therefore // the last req is still going and after/destroy haven't been called yet checkInvocations(as[3], { init: 1, before: 1 }, 'reqwrap[3]: while in onread callback'); diff --git a/test/async-hooks/test-pipeconnectwrap.js b/test/async-hooks/test-pipeconnectwrap.js index 6c68186e2f239f..5d3706ac44fef6 100644 --- a/test/async-hooks/test-pipeconnectwrap.js +++ b/test/async-hooks/test-pipeconnectwrap.js @@ -53,7 +53,7 @@ function onlisten() { const awaitOnconnectCalls = new Set(['server', 'client']); function maybeOnconnect(source) { - // both server and client must call onconnect. On most OS's waiting for + // Both server and client must call onconnect. On most OS's waiting for // the client is sufficient, but on CentOS 5 the sever needs to respond too. assert.ok(awaitOnconnectCalls.size > 0); awaitOnconnectCalls.delete(source); diff --git a/test/async-hooks/test-pipewrap.js b/test/async-hooks/test-pipewrap.js index a632115d228d64..0a4d082856df22 100644 --- a/test/async-hooks/test-pipewrap.js +++ b/test/async-hooks/test-pipewrap.js @@ -22,7 +22,7 @@ nodeVersionSpawn .on('exit', common.mustCall(onsleepExit)) .on('close', common.mustCall(onsleepClose)); -// a process wrap and 3 pipe wraps for std{in,out,err} are initialized +// A process wrap and 3 pipe wraps for std{in,out,err} are initialized // synchronously const processes = hooks.activitiesOfTypes('PROCESSWRAP'); const pipes = hooks.activitiesOfTypes('PIPEWRAP'); diff --git a/test/async-hooks/test-promise.promise-before-init-hooks.js b/test/async-hooks/test-promise.promise-before-init-hooks.js index f9ba24c044298f..0f74c968e6a25e 100644 --- a/test/async-hooks/test-promise.promise-before-init-hooks.js +++ b/test/async-hooks/test-promise.promise-before-init-hooks.js @@ -32,7 +32,7 @@ process.on('exit', function onexit() { const a0 = as[0]; assert.strictEqual(a0.type, 'PROMISE'); assert.strictEqual(typeof a0.uid, 'number'); - // we can't get the asyncId from the parent dynamically, since init was + // We can't get the asyncId from the parent dynamically, since init was // never called. However, it is known that the parent promise was created // immediately before the child promise, thus there should only be one // difference in id. diff --git a/test/async-hooks/test-signalwrap.js b/test/async-hooks/test-signalwrap.js index c94d763450ab24..5bc02e6dc46204 100644 --- a/test/async-hooks/test-signalwrap.js +++ b/test/async-hooks/test-signalwrap.js @@ -92,7 +92,7 @@ function onexit() { checkInvocations( signal1, { init: 1, before: 2, after: 2, destroy: 1 }, 'signal1: when second SIGUSR2 process exits'); - // second signal not destroyed yet since its event listener is still active + // Second signal not destroyed yet since its event listener is still active checkInvocations( signal2, { init: 1, before: 1, after: 1 }, 'signal2: when second SIGUSR2 process exits'); diff --git a/test/common/index.js b/test/common/index.js index 7b668e58c48ead..33089e69af6072 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -336,7 +336,7 @@ function _mustCallInner(fn, criteria = 1, field) { name: fn.name || '' }; - // add the exit listener only once to avoid listener leak warnings + // Add the exit listener only once to avoid listener leak warnings if (mustCallChecks.length === 0) process.on('exit', runCallChecks); mustCallChecks.push(context); @@ -392,7 +392,7 @@ function getCallSite(top) { `${stack[0].getFileName()}:${stack[0].getLineNumber()}`; const err = new Error(); Error.captureStackTrace(err, top); - // with the V8 Error API, the stack is not formatted until it is accessed + // With the V8 Error API, the stack is not formatted until it is accessed err.stack; Error.prepareStackTrace = originalStackFormatter; return err.stack; @@ -507,7 +507,7 @@ function expectWarningByMap(warningMap) { process.on('warning', (warning) => catchWarning[warning.name](warning)); } -// accepts a warning name and description or array of descriptions or a map +// Accepts a warning name and description or array of descriptions or a map // of warning names to description(s) // ensures a warning is generated for each name/description pair function expectWarning(nameOrMap, expected, code) { diff --git a/test/common/wpt.js b/test/common/wpt.js index 4f2f39c8e595d2..2a25a22af53710 100644 --- a/test/common/wpt.js +++ b/test/common/wpt.js @@ -66,20 +66,92 @@ class ResourceLoader { } } +class StatusRule { + constructor(key, value, pattern = undefined) { + this.key = key; + this.requires = value.requires || []; + this.fail = value.fail; + this.skip = value.skip; + if (pattern) { + this.pattern = this.transformPattern(pattern); + } + // TODO(joyeecheung): implement this + this.scope = value.scope; + this.comment = value.comment; + } + + /** + * Transform a filename pattern into a RegExp + * @param {string} pattern + * @returns {RegExp} + */ + transformPattern(pattern) { + const result = pattern.replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&'); + return new RegExp(result.replace('*', '.*')); + } +} + +class StatusRuleSet { + constructor() { + // We use two sets of rules to speed up matching + this.exactMatch = {}; + this.patternMatch = []; + } + + /** + * @param {object} rules + */ + addRules(rules) { + for (const key of Object.keys(rules)) { + if (key.includes('*')) { + this.patternMatch.push(new StatusRule(key, rules[key], key)); + } else { + this.exactMatch[key] = new StatusRule(key, rules[key]); + } + } + } + + match(file) { + const result = []; + const exact = this.exactMatch[file]; + if (exact) { + result.push(exact); + } + for (const item of this.patternMatch) { + if (item.pattern.test(file)) { + result.push(item); + } + } + return result; + } +} + class WPTTest { /** * @param {string} mod * @param {string} filename - * @param {string[]} requires - * @param {string | undefined} failReason - * @param {string | undefined} skipReason + * @param {StatusRule[]} rules */ - constructor(mod, filename, requires, failReason, skipReason) { + constructor(mod, filename, rules) { this.module = mod; // name of the WPT module, e.g. 'url' this.filename = filename; // name of the test file - this.requires = requires; - this.failReason = failReason; - this.skipReason = skipReason; + + this.requires = new Set(); + this.failReasons = []; + this.skipReasons = []; + for (const item of rules) { + if (item.requires.length) { + for (const req of item.requires) { + this.requires.add(req); + } + } + if (item.fail) { + this.failReasons.push(item.fail); + } + if (item.skip) { + this.skipReasons.push(item.skip); + } + } } getAbsolutePath() { @@ -90,12 +162,8 @@ class WPTTest { return fs.readFileSync(this.getAbsolutePath(), 'utf8'); } - shouldSkip() { - return this.failReason || this.skipReason; - } - requireIntl() { - return this.requires.includes('intl'); + return this.requires.has('intl'); } } @@ -103,41 +171,28 @@ class StatusLoader { constructor(path) { this.path = path; this.loaded = false; - this.status = null; + this.rules = new StatusRuleSet(); /** @type {WPTTest[]} */ this.tests = []; } - loadTest(file) { - let requires = []; - let failReason; - let skipReason; - if (this.status[file]) { - requires = this.status[file].requires || []; - failReason = this.status[file].fail; - skipReason = this.status[file].skip; - } - return new WPTTest(this.path, file, requires, - failReason, skipReason); - } - load() { const dir = path.join(__dirname, '..', 'wpt'); const statusFile = path.join(dir, 'status', `${this.path}.json`); const result = JSON.parse(fs.readFileSync(statusFile, 'utf8')); - this.status = result; + this.rules.addRules(result); const list = fs.readdirSync(fixtures.path('wpt', this.path)); for (const file of list) { - this.tests.push(this.loadTest(file)); + if (!(/\.\w+\.js$/.test(file))) { + continue; + } + const match = this.rules.match(file); + this.tests.push(new WPTTest(this.path, file, match)); } this.loaded = true; } - - get jsTests() { - return this.tests.filter((test) => test.filename.endsWith('.js')); - } } const PASSED = 1; @@ -156,7 +211,7 @@ class WPTRunner { this.status = new StatusLoader(path); this.status.load(); this.tests = new Map( - this.status.jsTests.map((item) => [item.filename, item]) + this.status.tests.map((item) => [item.filename, item]) ); this.results = new Map(); @@ -171,7 +226,10 @@ class WPTRunner { */ copyGlobalsFromObject(obj, names) { for (const name of names) { - const desc = Object.getOwnPropertyDescriptor(global, name); + const desc = Object.getOwnPropertyDescriptor(obj, name); + if (!desc) { + assert.fail(`${name} does not exist on the object`); + } this.globals.set(name, desc); } } @@ -328,8 +386,9 @@ class WPTRunner { for (const item of items) { switch (item.type) { case FAILED: { - if (test.failReason) { + if (test.failReasons.length) { console.log(`[EXPECTED_FAILURE] ${item.test.name}`); + console.log(test.failReasons.join('; ')); } else { console.log(`[UNEXPECTED_FAILURE] ${item.test.name}`); unexpectedFailures.push([title, filename, item]); @@ -386,10 +445,10 @@ class WPTRunner { }); } - skip(filename, reason) { + skip(filename, reasons) { this.addResult(filename, { type: SKIPPED, - reason + reason: reasons.join('; ') }); } @@ -435,13 +494,13 @@ class WPTRunner { const queue = []; for (const test of this.tests.values()) { const filename = test.filename; - if (test.skipReason) { - this.skip(filename, test.skipReason); + if (test.skipReasons.length > 0) { + this.skip(filename, test.skipReasons); continue; } if (!common.hasIntl && test.requireIntl()) { - this.skip(filename, 'missing Intl'); + this.skip(filename, [ 'missing Intl' ]); continue; } diff --git a/test/es-module/test-esm-dynamic-import.js b/test/es-module/test-esm-dynamic-import.js index 6cbbd0ac67dd66..887339977669ea 100644 --- a/test/es-module/test-esm-dynamic-import.js +++ b/test/es-module/test-esm-dynamic-import.js @@ -3,7 +3,6 @@ const common = require('../common'); const assert = require('assert'); const { URL } = require('url'); -const vm = require('vm'); const relativePath = '../fixtures/es-modules/test-esm-ok.mjs'; const absolutePath = require.resolve('../fixtures/es-modules/test-esm-ok.mjs'); @@ -12,7 +11,7 @@ targetURL.pathname = absolutePath; function expectErrorProperty(result, propertyKey, value) { Promise.resolve(result) - .catch(common.mustCall(error => { + .catch(common.mustCall((error) => { assert.strictEqual(error[propertyKey], value); })); } @@ -21,34 +20,18 @@ function expectMissingModuleError(result) { expectErrorProperty(result, 'code', 'MODULE_NOT_FOUND'); } -function expectInvalidUrlError(result) { - expectErrorProperty(result, 'code', 'ERR_INVALID_URL'); -} - -function expectInvalidReferrerError(result) { - expectErrorProperty(result, 'code', 'ERR_INVALID_URL'); -} - -function expectInvalidProtocolError(result) { - expectErrorProperty(result, 'code', 'ERR_INVALID_PROTOCOL'); -} - -function expectInvalidContextError(result) { - expectErrorProperty(result, - 'message', 'import() called outside of main context'); -} - function expectOkNamespace(result) { Promise.resolve(result) - .then(common.mustCall(ns => { + .then(common.mustCall((ns) => { // Can't deepStrictEqual because ns isn't a normal object + // eslint-disable-next-line no-restricted-properties assert.deepEqual(ns, { default: true }); })); } function expectFsNamespace(result) { Promise.resolve(result) - .then(common.mustCall(ns => { + .then(common.mustCall((ns) => { assert.strictEqual(typeof ns.default.writeFile, 'function'); assert.strictEqual(typeof ns.writeFile, 'function'); })); @@ -59,19 +42,19 @@ function expectFsNamespace(result) { (function testScriptOrModuleImport() { // Importing another file, both direct & via eval // expectOkNamespace(import(relativePath)); - expectOkNamespace(eval.call(null, `import("${relativePath}")`)); expectOkNamespace(eval(`import("${relativePath}")`)); - expectOkNamespace(eval.call(null, `import("${targetURL}")`)); + expectOkNamespace(eval(`import("${relativePath}")`)); + expectOkNamespace(eval(`import("${targetURL}")`)); // Importing a built-in, both direct & via eval - expectFsNamespace(import("fs")); + expectFsNamespace(import('fs')); + expectFsNamespace(eval('import("fs")')); expectFsNamespace(eval('import("fs")')); - expectFsNamespace(eval.call(null, 'import("fs")')); - expectMissingModuleError(import("./not-an-existing-module.mjs")); + expectMissingModuleError(import('./not-an-existing-module.mjs')); // TODO(jkrems): Right now this doesn't hit a protocol error because the // module resolution step already rejects it. These arguably should be // protocol errors. - expectMissingModuleError(import("node:fs")); + expectMissingModuleError(import('node:fs')); expectMissingModuleError(import('http://example.com/foo.js')); })(); diff --git a/test/es-module/test-esm-preserve-symlinks-main.js b/test/es-module/test-esm-preserve-symlinks-main.js index fbca5dce743674..808b6c9a15f6fd 100644 --- a/test/es-module/test-esm-preserve-symlinks-main.js +++ b/test/es-module/test-esm-preserve-symlinks-main.js @@ -35,7 +35,7 @@ try { } function doTest(flags, done) { - // invoke the main file via a symlink. In this case --preserve-symlinks-main + // Invoke the main file via a symlink. In this case --preserve-symlinks-main // dictates that it'll resolve relative imports in the main file relative to // the symlink, and not relative to the symlink target; the file structure set // up above requires this to not crash when loading ./submodule_link.js diff --git a/test/fixtures/tls-connect.js b/test/fixtures/tls-connect.js index 303061adc3223e..764bea77033d28 100644 --- a/test/fixtures/tls-connect.js +++ b/test/fixtures/tls-connect.js @@ -26,15 +26,18 @@ const keys = exports.keys = { agent5: load('agent5', 'ca2'), agent6: load('agent6', 'ca1'), agent7: load('agent7', 'fake-cnnic-root'), + agent10: load('agent10', 'ca2'), + ec10: load('ec10', 'ca5'), ec: load('ec', 'ec'), }; -function load(cert, issuer) { - issuer = issuer || cert; // Assume self-signed if no issuer +// root is the self-signed root of the trust chain, not an intermediate ca. +function load(cert, root) { + root = root || cert; // Assume self-signed if no issuer const id = { key: fixtures.readKey(cert + '-key.pem', 'binary'), cert: fixtures.readKey(cert + '-cert.pem', 'binary'), - ca: fixtures.readKey(issuer + '-cert.pem', 'binary'), + ca: fixtures.readKey(root + '-cert.pem', 'binary'), }; return id; } diff --git a/test/internet/test-dns.js b/test/internet/test-dns.js index 1f6639b2d5ce6c..3d331fd196a722 100644 --- a/test/internet/test-dns.js +++ b/test/internet/test-dns.js @@ -83,9 +83,7 @@ TEST(async function test_resolve4_ttl(done) { function validateResult(result) { assert.ok(result.length > 0); - for (let i = 0; i < result.length; i++) { - const item = result[i]; - assert.ok(item); + for (const item of result) { assert.strictEqual(typeof item, 'object'); assert.strictEqual(typeof item.ttl, 'number'); assert.strictEqual(typeof item.address, 'string'); @@ -113,9 +111,7 @@ TEST(async function test_resolve6_ttl(done) { function validateResult(result) { assert.ok(result.length > 0); - for (let i = 0; i < result.length; i++) { - const item = result[i]; - assert.ok(item); + for (const item of result) { assert.strictEqual(typeof item, 'object'); assert.strictEqual(typeof item.ttl, 'number'); assert.strictEqual(typeof item.address, 'string'); @@ -143,9 +139,7 @@ TEST(async function test_resolveMx(done) { function validateResult(result) { assert.ok(result.length > 0); - for (let i = 0; i < result.length; i++) { - const item = result[i]; - assert.ok(item); + for (const item of result) { assert.strictEqual(typeof item, 'object'); assert.ok(item.exchange); assert.strictEqual(typeof item.exchange, 'string'); @@ -185,9 +179,7 @@ TEST(async function test_resolveNs(done) { function validateResult(result) { assert.ok(result.length > 0); - for (let i = 0; i < result.length; i++) { - const item = result[i]; - + for (const item of result) { assert.ok(item); assert.strictEqual(typeof item, 'string'); } @@ -225,14 +217,10 @@ TEST(async function test_resolveSrv(done) { function validateResult(result) { assert.ok(result.length > 0); - for (let i = 0; i < result.length; i++) { - const item = result[i]; - assert.ok(item); + for (const item of result) { assert.strictEqual(typeof item, 'object'); - assert.ok(item.name); assert.strictEqual(typeof item.name, 'string'); - assert.strictEqual(typeof item.port, 'number'); assert.strictEqual(typeof item.priority, 'number'); assert.strictEqual(typeof item.weight, 'number'); @@ -271,8 +259,7 @@ TEST(async function test_resolvePtr(done) { function validateResult(result) { assert.ok(result.length > 0); - for (let i = 0; i < result.length; i++) { - const item = result[i]; + for (const item of result) { assert.ok(item); assert.strictEqual(typeof item, 'string'); } @@ -310,9 +297,7 @@ TEST(async function test_resolveNaptr(done) { function validateResult(result) { assert.ok(result.length > 0); - for (let i = 0; i < result.length; i++) { - const item = result[i]; - assert.ok(item); + for (const item of result) { assert.strictEqual(typeof item, 'object'); assert.strictEqual(typeof item.flags, 'string'); assert.strictEqual(typeof item.service, 'string'); @@ -353,7 +338,6 @@ TEST(function test_resolveNaptr_failure(done) { TEST(async function test_resolveSoa(done) { function validateResult(result) { - assert.ok(result); assert.strictEqual(typeof result, 'object'); assert.strictEqual(typeof result.nsname, 'string'); assert.ok(result.nsname.length > 0); @@ -403,10 +387,9 @@ TEST(async function test_resolveCname(done) { function validateResult(result) { assert.ok(result.length > 0); - for (let i = 0; i < result.length; i++) { - const name = result[i]; - assert.ok(name); - assert.strictEqual(typeof name, 'string'); + for (const item of result) { + assert.ok(item); + assert.strictEqual(typeof item, 'string'); } } @@ -480,7 +463,7 @@ TEST(function test_lookup_failure(done) { .then(common.mustNotCall()) .catch(common.expectsError({ errno: dns.NOTFOUND })); - const req = dns.lookup(addresses.INVALID_HOST, 4, (err, ip, family) => { + const req = dns.lookup(addresses.INVALID_HOST, 4, (err) => { assert.ok(err instanceof Error); assert.strictEqual(err.errno, dns.NOTFOUND); assert.strictEqual(err.errno, 'ENOTFOUND'); @@ -548,7 +531,7 @@ TEST(function test_lookup_ip_promise(done) { TEST(async function test_lookup_null_all(done) { assert.deepStrictEqual(await dnsPromises.lookup(null, { all: true }), []); - const req = dns.lookup(null, { all: true }, function(err, ips, family) { + const req = dns.lookup(null, { all: true }, (err, ips) => { assert.ifError(err); assert.ok(Array.isArray(ips)); assert.strictEqual(ips.length, 0); @@ -594,7 +577,7 @@ TEST(function test_lookupservice_invalid(done) { .then(common.mustNotCall()) .catch(common.expectsError({ code: 'ENOTFOUND' })); - const req = dns.lookupService('1.2.3.4', 80, function(err, host, service) { + const req = dns.lookupService('1.2.3.4', 80, (err) => { assert(err instanceof Error); assert.strictEqual(err.code, 'ENOTFOUND'); assert.ok(/1\.2\.3\.4/.test(err.message)); diff --git a/test/js-native-api/test_general/test.js b/test/js-native-api/test_general/test.js index a8548bcdf916a4..7a65297cd3a368 100644 --- a/test/js-native-api/test_general/test.js +++ b/test/js-native-api/test_general/test.js @@ -48,7 +48,7 @@ assert.strictEqual(test_general.testGetVersion(), 3); assert.strictEqual(test_general.testNapiTypeof(val), typeof val); }); -// since typeof in js return object need to validate specific case +// Since typeof in js return object need to validate specific case // for null assert.strictEqual(test_general.testNapiTypeof(null), 'null'); diff --git a/test/js-native-api/test_number/test.js b/test/js-native-api/test_number/test.js index 34f48aee578ac6..a7a6009852d884 100644 --- a/test/js-native-api/test_number/test.js +++ b/test/js-native-api/test_number/test.js @@ -49,7 +49,7 @@ testUint32(4294967296, 0); testUint32(4294967297, 1); testUint32(17 * 4294967296 + 1, 1); -// validate documented behavior when value is retrieved as 32-bit integer with +// Validate documented behavior when value is retrieved as 32-bit integer with // `napi_get_value_int32` function testInt32(input, expected = input) { assert.strictEqual(expected, test_number.TestInt32Truncation(input)); @@ -92,7 +92,7 @@ testInt32(Number.POSITIVE_INFINITY, 0); testInt32(Number.NEGATIVE_INFINITY, 0); testInt32(Number.NaN, 0); -// validate documented behavior when value is retrieved as 64-bit integer with +// Validate documented behavior when value is retrieved as 64-bit integer with // `napi_get_value_int64` function testInt64(input, expected = input) { assert.strictEqual(expected, test_number.TestInt64Truncation(input)); diff --git a/test/known_issues/test-dgram-bind-shared-ports-after-port-0.js b/test/known_issues/test-dgram-bind-shared-ports-after-port-0.js index 7b750c765ba226..fbf88d41650d24 100644 --- a/test/known_issues/test-dgram-bind-shared-ports-after-port-0.js +++ b/test/known_issues/test-dgram-bind-shared-ports-after-port-0.js @@ -45,7 +45,7 @@ if (cluster.isMaster) { // worker code process.on('message', (msg) => msg === BYE && process.exit(0)); - // first worker will bind to '0', second will try the assigned port and fail + // First worker will bind to '0', second will try the assigned port and fail const PRT1 = process.env.PRT1 || 0; const socket1 = dgram.createSocket('udp4', () => {}); socket1.on('error', PRT1 === 0 ? () => {} : assert.fail); diff --git a/test/message/testcfg.py b/test/message/testcfg.py index 62776bcb7af0e2..a4f802f3efc584 100644 --- a/test/message/testcfg.py +++ b/test/message/testcfg.py @@ -31,6 +31,16 @@ from os.path import join, exists, basename, isdir import re +try: + reduce # Python 2 +except NameError: # Python 3 + from functools import reduce + +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)") class MessageTestCase(test.TestCase): @@ -49,7 +59,7 @@ def IgnoreLine(self, str): else: return str.startswith('==') or str.startswith('**') def IsFailureOutput(self, output): - f = file(self.expected) + f = open(self.expected) # Skip initial '#' comment and spaces #for line in f: # if (not line.startswith('#')) and (not line.strip()): diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status index cfc4e36e9a565f..a906d4108c87c1 100644 --- a/test/parallel/parallel.status +++ b/test/parallel/parallel.status @@ -5,21 +5,27 @@ prefix parallel # sample-test : PASS,FLAKY [true] # This section applies to all platforms +# https://github.com/nodejs/node/issues/25029 +test-child-process-execfile: PASS,FLAKY # https://github.com/nodejs/node/issues/23207 test-net-connect-options-port: PASS,FLAKY +# https://github.com/nodejs/node/issues/25033 +test-child-process-exit-code: PASS,FLAKY [$system==win32] test-http2-pipe: PASS,FLAKY test-worker-syntax-error: PASS,FLAKY test-worker-syntax-error-file: PASS,FLAKY -# https://github.com/nodejs/node/issues/24456 -test-stream-pipeline-http2: PASS,FLAKY +# https://github.com/nodejs/node/issues/23277 +test-worker-memory: PASS,FLAKY [$system==linux] [$system==macos] [$arch==arm || $arch==arm64] +# https://github.com/nodejs/node/issues/25028 +test-cli-node-options: PASS,FLAKY [$system==solaris] # Also applies to SmartOS diff --git a/test/parallel/test-assert-deep.js b/test/parallel/test-assert-deep.js index 0abad5788e7dd1..c1e8c2f246663b 100644 --- a/test/parallel/test-assert-deep.js +++ b/test/parallel/test-assert-deep.js @@ -985,3 +985,67 @@ assert.throws( ' ]' } ); + +// Verify that manipulating the `getTime()` function has no impact on the time +// verification. +{ + const a = new Date('2000'); + const b = new Date('2000'); + Object.defineProperty(a, 'getTime', { + value: () => 5 + }); + assert.deepStrictEqual(a, b); +} + +// Verify that extra keys will be tested for when using fake arrays. +{ + const a = { + 0: 1, + 1: 1, + 2: 'broken' + }; + Object.setPrototypeOf(a, Object.getPrototypeOf([])); + Object.defineProperty(a, Symbol.toStringTag, { + value: 'Array', + }); + Object.defineProperty(a, 'length', { + value: 2 + }); + assert.notDeepStrictEqual(a, [1, 1]); +} + +// Verify that changed tags will still check for the error message. +{ + const err = new Error('foo'); + err[Symbol.toStringTag] = 'Foobar'; + const err2 = new Error('bar'); + err2[Symbol.toStringTag] = 'Foobar'; + assertNotDeepOrStrict(err, err2, AssertionError); +} + +// Check for non-native errors. +{ + const source = new Error('abc'); + const err = Object.create( + Object.getPrototypeOf(source), Object.getOwnPropertyDescriptors(source)); + Object.defineProperty(err, 'message', { value: 'foo' }); + const err2 = Object.create( + Object.getPrototypeOf(source), Object.getOwnPropertyDescriptors(source)); + Object.defineProperty(err2, 'message', { value: 'bar' }); + err[Symbol.toStringTag] = 'Foo'; + err2[Symbol.toStringTag] = 'Foo'; + assert.notDeepStrictEqual(err, err2); +} + +// Verify that `valueOf` is not called for boxed primitives. +{ + const a = new Number(5); + const b = new Number(5); + Object.defineProperty(a, 'valueOf', { + value: () => { throw new Error('failed'); } + }); + Object.defineProperty(b, 'valueOf', { + value: () => { throw new Error('failed'); } + }); + assertDeepAndStrictEqual(a, b); +} diff --git a/test/parallel/test-async-hooks-http-parser-destroy.js b/test/parallel/test-async-hooks-http-parser-destroy.js index aeb805702d89e9..d2e1071c280d66 100644 --- a/test/parallel/test-async-hooks-http-parser-destroy.js +++ b/test/parallel/test-async-hooks-http-parser-destroy.js @@ -36,7 +36,7 @@ const keepAliveAgent = new http.Agent({ const countdown = new Countdown(N, () => { server.close(() => { - // give the server sockets time to close (which will also free their + // Give the server sockets time to close (which will also free their // associated parser objects) after the server has been closed. setTimeout(() => { createdIds.forEach((createdAsyncId) => { diff --git a/test/parallel/test-buffer-alloc.js b/test/parallel/test-buffer-alloc.js index bdba19ae66ddb5..cee87994965493 100644 --- a/test/parallel/test-buffer-alloc.js +++ b/test/parallel/test-buffer-alloc.js @@ -106,7 +106,7 @@ b.copy(Buffer.alloc(1), 1, 1, 1); // try to copy 0 bytes from past the end of the source buffer b.copy(Buffer.alloc(1), 0, 2048, 2048); -// testing for smart defaults and ability to pass string values as offset +// Testing for smart defaults and ability to pass string values as offset { const writeTest = Buffer.from('abcdes'); writeTest.write('n', 'ascii'); @@ -799,7 +799,7 @@ common.expectsError( outOfRangeError ); -// attempt to overflow buffers, similar to previous bug in array buffers +// Attempt to overflow buffers, similar to previous bug in array buffers common.expectsError( () => Buffer.allocUnsafe(8).writeFloatLE(0.0, 0xffffffff), outOfRangeError diff --git a/test/parallel/test-buffer-compare-offset.js b/test/parallel/test-buffer-compare-offset.js index a437d8fa6345f6..47e5f3041e12e6 100644 --- a/test/parallel/test-buffer-compare-offset.js +++ b/test/parallel/test-buffer-compare-offset.js @@ -54,7 +54,7 @@ assert.strictEqual(a.compare(b, 0, { valueOf: () => 5 }), -1); // zero length target assert.strictEqual(a.compare(b, Infinity, -Infinity), 1); -// zero length target because default for targetEnd <= targetSource +// Zero length target because default for targetEnd <= targetSource assert.strictEqual(a.compare(b, '0xff'), 1); const oor = common.expectsError({ code: 'ERR_OUT_OF_RANGE' }, 7); diff --git a/test/parallel/test-buffer-copy.js b/test/parallel/test-buffer-copy.js index 6fb6a4ec707ef0..e9f789a88623e7 100644 --- a/test/parallel/test-buffer-copy.js +++ b/test/parallel/test-buffer-copy.js @@ -108,7 +108,7 @@ common.expectsError( errorProperty); { - // check sourceEnd resets to targetEnd if former is greater than the latter + // Check sourceEnd resets to targetEnd if former is greater than the latter b.fill(++cntr); c.fill(++cntr); b.copy(c, 0, 0, 1025); diff --git a/test/parallel/test-buffer-read.js b/test/parallel/test-buffer-read.js index 6f4ff3ca86f5e9..94e198fedca7b1 100644 --- a/test/parallel/test-buffer-read.js +++ b/test/parallel/test-buffer-read.js @@ -13,22 +13,22 @@ function read(buff, funx, args, expected) { ); } -// testing basic functionality of readDoubleBE() and readDoubleLE() +// Testing basic functionality of readDoubleBE() and readDoubleLE() read(buf, 'readDoubleBE', [1], -3.1827727774563287e+295); read(buf, 'readDoubleLE', [1], -6.966010051009108e+144); -// testing basic functionality of readFloatBE() and readFloatLE() +// Testing basic functionality of readFloatBE() and readFloatLE() read(buf, 'readFloatBE', [1], -1.6691549692541768e+37); read(buf, 'readFloatLE', [1], -7861303808); // testing basic functionality of readInt8() read(buf, 'readInt8', [1], -3); -// testing basic functionality of readInt16BE() and readInt16LE() +// Testing basic functionality of readInt16BE() and readInt16LE() read(buf, 'readInt16BE', [1], -696); read(buf, 'readInt16LE', [1], 0x48fd); -// testing basic functionality of readInt32BE() and readInt32LE() +// Testing basic functionality of readInt32BE() and readInt32LE() read(buf, 'readInt32BE', [1], -45552945); read(buf, 'readInt32LE', [1], -806729475); @@ -39,11 +39,11 @@ read(buf, 'readIntLE', [2, 1], 0x48); // testing basic functionality of readUInt8() read(buf, 'readUInt8', [1], 0xfd); -// testing basic functionality of readUInt16BE() and readUInt16LE() +// Testing basic functionality of readUInt16BE() and readUInt16LE() read(buf, 'readUInt16BE', [2], 0x48ea); read(buf, 'readUInt16LE', [2], 0xea48); -// testing basic functionality of readUInt32BE() and readUInt32LE() +// Testing basic functionality of readUInt32BE() and readUInt32LE() read(buf, 'readUInt32BE', [1], 0xfd48eacf); read(buf, 'readUInt32LE', [1], 0xcfea48fd); diff --git a/test/parallel/test-buffer-tostring-range.js b/test/parallel/test-buffer-tostring-range.js index f6ee846dd8ef34..436414e1b7da55 100644 --- a/test/parallel/test-buffer-tostring-range.js +++ b/test/parallel/test-buffer-tostring-range.js @@ -35,7 +35,7 @@ assert.strictEqual(rangeBuffer.toString('ascii', undefined, 3), 'abc'); assert.strictEqual(rangeBuffer.toString('ascii', false, 3), 'abc'); assert.strictEqual(rangeBuffer.toString('ascii', '', 3), 'abc'); -// but, if start is an integer when coerced, then it will be coerced and used. +// But, if start is an integer when coerced, then it will be coerced and used. assert.strictEqual(rangeBuffer.toString('ascii', '-1', 3), 'abc'); assert.strictEqual(rangeBuffer.toString('ascii', '1', 3), 'bc'); assert.strictEqual(rangeBuffer.toString('ascii', '-Infinity', 3), 'abc'); @@ -47,7 +47,7 @@ assert.strictEqual(rangeBuffer.toString('ascii', '-1.99', 3), 'abc'); assert.strictEqual(rangeBuffer.toString('ascii', 1.99, 3), 'bc'); assert.strictEqual(rangeBuffer.toString('ascii', true, 3), 'bc'); -// if end > buffer's length, end will be taken as buffer's length +// If end > buffer's length, end will be taken as buffer's length assert.strictEqual(rangeBuffer.toString('ascii', 0, 5), 'abc'); assert.strictEqual(rangeBuffer.toString('ascii', 0, 6.99), 'abc'); assert.strictEqual(rangeBuffer.toString('ascii', 0, Infinity), 'abc'); @@ -55,7 +55,7 @@ assert.strictEqual(rangeBuffer.toString('ascii', 0, '5'), 'abc'); assert.strictEqual(rangeBuffer.toString('ascii', 0, '6.99'), 'abc'); assert.strictEqual(rangeBuffer.toString('ascii', 0, 'Infinity'), 'abc'); -// if end is an invalid integer, end will be taken as buffer's length +// If end is an invalid integer, end will be taken as buffer's length assert.strictEqual(rangeBuffer.toString('ascii', 0, 'node.js'), ''); assert.strictEqual(rangeBuffer.toString('ascii', 0, {}), ''); assert.strictEqual(rangeBuffer.toString('ascii', 0, NaN), ''); @@ -66,7 +66,7 @@ assert.strictEqual(rangeBuffer.toString('ascii', 0, []), ''); assert.strictEqual(rangeBuffer.toString('ascii', 0, false), ''); assert.strictEqual(rangeBuffer.toString('ascii', 0, ''), ''); -// but, if end is an integer when coerced, then it will be coerced and used. +// But, if end is an integer when coerced, then it will be coerced and used. assert.strictEqual(rangeBuffer.toString('ascii', 0, '-1'), ''); assert.strictEqual(rangeBuffer.toString('ascii', 0, '1'), 'a'); assert.strictEqual(rangeBuffer.toString('ascii', 0, '-Infinity'), ''); diff --git a/test/parallel/test-child-process-spawn-typeerror.js b/test/parallel/test-child-process-spawn-typeerror.js index 82acaf8e088038..71bfdfdfe8f24f 100644 --- a/test/parallel/test-child-process-spawn-typeerror.js +++ b/test/parallel/test-child-process-spawn-typeerror.js @@ -91,7 +91,7 @@ const s = 'string'; const u = undefined; const n = null; -// function spawn(file=f [,args=a] [, options=o]) has valid combinations: +// Function spawn(file=f [,args=a] [, options=o]) has valid combinations: // (f) // (f, a) // (f, a, o) diff --git a/test/parallel/test-child-process-stdout-flush-exit.js b/test/parallel/test-child-process-stdout-flush-exit.js index f3fdf4949aadd5..679d78269fc441 100644 --- a/test/parallel/test-child-process-stdout-flush-exit.js +++ b/test/parallel/test-child-process-stdout-flush-exit.js @@ -45,7 +45,7 @@ if (process.argv[2] === 'child') { assert.fail(`Unexpected parent stderr: ${data}`); }); - // check if we receive both 'hello' at start and 'goodbye' at end + // Check if we receive both 'hello' at start and 'goodbye' at end child.stdout.setEncoding('utf8'); child.stdout.on('data', function(data) { stdout += data; diff --git a/test/parallel/test-cli-syntax-eval.js b/test/parallel/test-cli-syntax-eval.js new file mode 100644 index 00000000000000..cb4c4fd5688642 --- /dev/null +++ b/test/parallel/test-cli-syntax-eval.js @@ -0,0 +1,24 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { exec } = require('child_process'); + +const node = process.execPath; + +// should throw if -c and -e flags are both passed +['-c', '--check'].forEach(function(checkFlag) { + ['-e', '--eval'].forEach(function(evalFlag) { + const args = [checkFlag, evalFlag, 'foo']; + const cmd = [node, ...args].join(' '); + exec(cmd, common.mustCall((err, stdout, stderr) => { + assert.strictEqual(err instanceof Error, true); + assert.strictEqual(err.code, 9); + assert( + stderr.startsWith( + `${node}: either --check or --eval can be used, not both` + ) + ); + })); + }); +}); diff --git a/test/parallel/test-cli-syntax-piped-bad.js b/test/parallel/test-cli-syntax-piped-bad.js new file mode 100644 index 00000000000000..64e2d47931eea1 --- /dev/null +++ b/test/parallel/test-cli-syntax-piped-bad.js @@ -0,0 +1,35 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); + +const node = process.execPath; + +// test both sets of arguments that check syntax +const syntaxArgs = [ + ['-c'], + ['--check'] +]; + +// Match on the name of the `Error` but not the message as it is different +// depending on the JavaScript engine. +const syntaxErrorRE = /^SyntaxError: \b/m; + +// Should throw if code piped from stdin with --check has bad syntax +// loop each possible option, `-c` or `--check` +syntaxArgs.forEach(function(args) { + const stdin = 'var foo bar;'; + const c = spawnSync(node, args, { encoding: 'utf8', input: stdin }); + + // stderr should include '[stdin]' as the filename + assert(c.stderr.startsWith('[stdin]'), `${c.stderr} starts with ${stdin}`); + + // no stdout or stderr should be produced + assert.strictEqual(c.stdout, ''); + + // stderr should have a syntax error message + assert(syntaxErrorRE.test(c.stderr), `${syntaxErrorRE} === ${c.stderr}`); + + assert.strictEqual(c.status, 1); +}); diff --git a/test/parallel/test-cli-syntax-piped-good.js b/test/parallel/test-cli-syntax-piped-good.js new file mode 100644 index 00000000000000..7e0cfbc89a491a --- /dev/null +++ b/test/parallel/test-cli-syntax-piped-good.js @@ -0,0 +1,26 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); + +const node = process.execPath; + +// test both sets of arguments that check syntax +const syntaxArgs = [ + ['-c'], + ['--check'] +]; + +// should not execute code piped from stdin with --check +// loop each possible option, `-c` or `--check` +syntaxArgs.forEach(function(args) { + const stdin = 'throw new Error("should not get run");'; + const c = spawnSync(node, args, { encoding: 'utf8', input: stdin }); + + // no stdout or stderr should be produced + assert.strictEqual(c.stdout, ''); + assert.strictEqual(c.stderr, ''); + + assert.strictEqual(c.status, 0); +}); diff --git a/test/parallel/test-cli-syntax.js b/test/parallel/test-cli-syntax.js deleted file mode 100644 index 35cc78258dad01..00000000000000 --- a/test/parallel/test-cli-syntax.js +++ /dev/null @@ -1,171 +0,0 @@ -'use strict'; - -const common = require('../common'); -const assert = require('assert'); -const { exec, spawnSync } = require('child_process'); -const fixtures = require('../common/fixtures'); - -const node = process.execPath; - -// test both sets of arguments that check syntax -const syntaxArgs = [ - ['-c'], - ['--check'] -]; - -// Match on the name of the `Error` but not the message as it is different -// depending on the JavaScript engine. -const syntaxErrorRE = /^SyntaxError: \b/m; -const notFoundRE = /^Error: Cannot find module/m; - -// test good syntax with and without shebang -[ - 'syntax/good_syntax.js', - 'syntax/good_syntax', - 'syntax/good_syntax_shebang.js', - 'syntax/good_syntax_shebang', - 'syntax/illegal_if_not_wrapped.js' -].forEach(function(file) { - file = fixtures.path(file); - - // loop each possible option, `-c` or `--check` - syntaxArgs.forEach(function(args) { - const _args = args.concat(file); - - const cmd = [node, ..._args].join(' '); - exec(cmd, common.mustCall((err, stdout, stderr) => { - if (err) { - console.log('-- stdout --'); - console.log(stdout); - console.log('-- stderr --'); - console.log(stderr); - } - assert.ifError(err); - assert.strictEqual(stdout, ''); - assert.strictEqual(stderr, ''); - })); - }); -}); - -// test bad syntax with and without shebang -[ - 'syntax/bad_syntax.js', - 'syntax/bad_syntax', - 'syntax/bad_syntax_shebang.js', - 'syntax/bad_syntax_shebang' -].forEach(function(file) { - file = fixtures.path(file); - - // loop each possible option, `-c` or `--check` - syntaxArgs.forEach(function(args) { - const _args = args.concat(file); - const cmd = [node, ..._args].join(' '); - exec(cmd, common.mustCall((err, stdout, stderr) => { - assert.strictEqual(err instanceof Error, true); - assert.strictEqual(err.code, 1); - - // no stdout should be produced - assert.strictEqual(stdout, ''); - - // stderr should have a syntax error message - assert(syntaxErrorRE.test(stderr), `${syntaxErrorRE} === ${stderr}`); - - // stderr should include the filename - assert(stderr.startsWith(file), `${stderr} starts with ${file}`); - })); - }); -}); - -// test file not found -[ - 'syntax/file_not_found.js', - 'syntax/file_not_found' -].forEach(function(file) { - file = fixtures.path(file); - - // loop each possible option, `-c` or `--check` - syntaxArgs.forEach(function(args) { - const _args = args.concat(file); - const cmd = [node, ..._args].join(' '); - exec(cmd, common.mustCall((err, stdout, stderr) => { - // no stdout should be produced - assert.strictEqual(stdout, ''); - - // stderr should have a module not found error message - assert(notFoundRE.test(stderr), `${notFoundRE} === ${stderr}`); - - assert.strictEqual(err.code, 1); - })); - }); -}); - -// should not execute code piped from stdin with --check -// loop each possible option, `-c` or `--check` -syntaxArgs.forEach(function(args) { - const stdin = 'throw new Error("should not get run");'; - const c = spawnSync(node, args, { encoding: 'utf8', input: stdin }); - - // no stdout or stderr should be produced - assert.strictEqual(c.stdout, ''); - assert.strictEqual(c.stderr, ''); - - assert.strictEqual(c.status, 0); -}); - -// should throw if code piped from stdin with --check has bad syntax -// loop each possible option, `-c` or `--check` -syntaxArgs.forEach(function(args) { - const stdin = 'var foo bar;'; - const c = spawnSync(node, args, { encoding: 'utf8', input: stdin }); - - // stderr should include '[stdin]' as the filename - assert(c.stderr.startsWith('[stdin]'), `${c.stderr} starts with ${stdin}`); - - // no stdout or stderr should be produced - assert.strictEqual(c.stdout, ''); - - // stderr should have a syntax error message - assert(syntaxErrorRE.test(c.stderr), `${syntaxErrorRE} === ${c.stderr}`); - - assert.strictEqual(c.status, 1); -}); - -// should throw if -c and -e flags are both passed -['-c', '--check'].forEach(function(checkFlag) { - ['-e', '--eval'].forEach(function(evalFlag) { - const args = [checkFlag, evalFlag, 'foo']; - const cmd = [node, ...args].join(' '); - exec(cmd, common.mustCall((err, stdout, stderr) => { - assert.strictEqual(err instanceof Error, true); - assert.strictEqual(err.code, 9); - assert( - stderr.startsWith( - `${node}: either --check or --eval can be used, not both` - ) - ); - })); - }); -}); - -// should work with -r flags -['-c', '--check'].forEach(function(checkFlag) { - ['-r', '--require'].forEach(function(requireFlag) { - const preloadFile = fixtures.path('no-wrapper.js'); - const file = fixtures.path('syntax', 'illegal_if_not_wrapped.js'); - const args = [requireFlag, preloadFile, checkFlag, file]; - const cmd = [node, ...args].join(' '); - exec(cmd, common.mustCall((err, stdout, stderr) => { - assert.strictEqual(err instanceof Error, true); - assert.strictEqual(err.code, 1); - - // no stdout should be produced - assert.strictEqual(stdout, ''); - - // stderr should have a syntax error message - assert(syntaxErrorRE.test(stderr), `${syntaxErrorRE} === ${stderr}`); - - // stderr should include the filename - assert(stderr.startsWith(file), `${stderr} starts with ${file}`); - })); - }); -}); diff --git a/test/parallel/test-cluster-setup-master-multiple.js b/test/parallel/test-cluster-setup-master-multiple.js index b33acccd411a0a..33d490df45f57a 100644 --- a/test/parallel/test-cluster-setup-master-multiple.js +++ b/test/parallel/test-cluster-setup-master-multiple.js @@ -62,7 +62,7 @@ execs.forEach((v, i) => { }, i * 100); }); -// cluster emits 'setup' asynchronously, so we must stay alive long +// Cluster emits 'setup' asynchronously, so we must stay alive long // enough for that to happen setTimeout(() => { console.log('cluster setup complete'); diff --git a/test/parallel/test-cluster-worker-forced-exit.js b/test/parallel/test-cluster-worker-forced-exit.js index cc76b4ba3aff3a..6d2bf4f53747d6 100644 --- a/test/parallel/test-cluster-worker-forced-exit.js +++ b/test/parallel/test-cluster-worker-forced-exit.js @@ -26,7 +26,7 @@ const cluster = require('cluster'); const SENTINEL = 42; -// workers forcibly exit when control channel is disconnected, if +// Workers forcibly exit when control channel is disconnected, if // their .exitedAfterDisconnect flag isn't set // // test this by: diff --git a/test/parallel/test-cluster-worker-no-exit.js b/test/parallel/test-cluster-worker-no-exit.js index b87b58b3f8b74a..ecd7c47f5aa568 100644 --- a/test/parallel/test-cluster-worker-no-exit.js +++ b/test/parallel/test-cluster-worker-no-exit.js @@ -30,7 +30,7 @@ let success; let worker; let server; -// workers do not exit on disconnect, they exit under normal node rules: when +// Workers do not exit on disconnect, they exit under normal node rules: when // they have nothing keeping their loop alive, like an active connection // // test this by: diff --git a/test/parallel/test-console.js b/test/parallel/test-console.js index 92e66596d76ca7..f781d619946e1a 100644 --- a/test/parallel/test-console.js +++ b/test/parallel/test-console.js @@ -174,7 +174,7 @@ console.timeEnd(); console.time(NaN); console.timeEnd(NaN); -// make sure calling time twice without timeEnd doesn't reset the timer. +// Make sure calling time twice without timeEnd doesn't reset the timer. console.time('test'); const time = console._times.get('test'); setTimeout(() => { @@ -248,7 +248,7 @@ assert.ok(/^__proto__: \d+\.\d{3}ms$/.test(strings.shift().trim())); assert.ok(/^constructor: \d+\.\d{3}ms$/.test(strings.shift().trim())); assert.ok(/^hasOwnProperty: \d+\.\d{3}ms$/.test(strings.shift().trim())); -// verify that console.time() coerces label values to strings as expected +// Verify that console.time() coerces label values to strings as expected assert.ok(/^: \d+\.\d{3}ms$/.test(strings.shift().trim())); assert.ok(/^\[object Object\]: \d+\.\d{3}ms$/.test(strings.shift().trim())); assert.ok(/^\[object Object\]: \d+\.\d{3}ms$/.test(strings.shift().trim())); diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js index 01ce1d9996863e..b62ce1a5b088bc 100644 --- a/test/parallel/test-crypto-authenticated.js +++ b/test/parallel/test-crypto-authenticated.js @@ -122,7 +122,7 @@ for (const test of TEST_CASES) { hex += encrypt.final('hex'); const auth_tag = encrypt.getAuthTag(); - // only test basic encryption run if output is marked as tampered. + // Only test basic encryption run if output is marked as tampered. if (!test.tampered) { assert.strictEqual(hex, test.ct); assert.strictEqual(auth_tag.toString('hex'), test.tag); @@ -170,7 +170,7 @@ for (const test of TEST_CASES) { let hex = encrypt.update(test.plain, 'ascii', 'hex'); hex += encrypt.final('hex'); const auth_tag = encrypt.getAuthTag(); - // only test basic encryption run if output is marked as tampered. + // Only test basic encryption run if output is marked as tampered. if (!test.tampered) { assert.strictEqual(hex, test.ct); assert.strictEqual(auth_tag.toString('hex'), test.tag); diff --git a/test/parallel/test-dgram-bind-default-address.js b/test/parallel/test-dgram-bind-default-address.js index 762ead7c869e8d..130d614c5812b5 100644 --- a/test/parallel/test-dgram-bind-default-address.js +++ b/test/parallel/test-dgram-bind-default-address.js @@ -21,7 +21,7 @@ 'use strict'; const common = require('../common'); -// skip test in FreeBSD jails since 0.0.0.0 will resolve to default interface +// Skip test in FreeBSD jails since 0.0.0.0 will resolve to default interface if (common.inFreeBSDJail) common.skip('In a FreeBSD jail'); diff --git a/test/parallel/test-dgram-exclusive-implicit-bind.js b/test/parallel/test-dgram-exclusive-implicit-bind.js index 171b221ee2982c..4603507240f8b7 100644 --- a/test/parallel/test-dgram-exclusive-implicit-bind.js +++ b/test/parallel/test-dgram-exclusive-implicit-bind.js @@ -92,7 +92,7 @@ source.on('close', function() { if (process.env.BOUND === 'y') { source.bind(0); } else { - // cluster doesn't know about exclusive sockets, so it won't close them. This + // Cluster doesn't know about exclusive sockets, so it won't close them. This // is expected, its the same situation for timers, outgoing tcp connections, // etc, which also keep workers alive after disconnect was requested. source.unref(); diff --git a/test/parallel/test-dgram-ref.js b/test/parallel/test-dgram-ref.js index b3b8488297507c..0c5474b118bd6b 100644 --- a/test/parallel/test-dgram-ref.js +++ b/test/parallel/test-dgram-ref.js @@ -23,7 +23,7 @@ const common = require('../common'); const dgram = require('dgram'); -// should not hang, see https://github.com/nodejs/node-v0.x-archive/issues/1282 +// Should not hang, see https://github.com/nodejs/node-v0.x-archive/issues/1282 dgram.createSocket('udp4'); dgram.createSocket('udp6'); diff --git a/test/parallel/test-domain-crypto.js b/test/parallel/test-domain-crypto.js index 26ee6b888efb2d..cb397c2fe33eb6 100644 --- a/test/parallel/test-domain-crypto.js +++ b/test/parallel/test-domain-crypto.js @@ -33,7 +33,7 @@ common.allowGlobals(require('domain')); // See https://github.com/nodejs/node/commit/d1eff9ab global.domain = require('domain'); -// should not throw a 'TypeError: undefined is not a function' exception +// Should not throw a 'TypeError: undefined is not a function' exception crypto.randomBytes(8); crypto.randomBytes(8, common.mustCall()); const buf = Buffer.alloc(8); diff --git a/test/parallel/test-domain-from-timer.js b/test/parallel/test-domain-from-timer.js index 3f8252543c9d2f..419a8aa96eb38f 100644 --- a/test/parallel/test-domain-from-timer.js +++ b/test/parallel/test-domain-from-timer.js @@ -25,7 +25,7 @@ require('../common'); const assert = require('assert'); -// timeouts call the callback directly from cc, so need to make sure the +// Timeouts call the callback directly from cc, so need to make sure the // domain will be used regardless setTimeout(() => { const domain = require('domain'); diff --git a/test/parallel/test-event-emitter-check-listener-leaks.js b/test/parallel/test-event-emitter-check-listener-leaks.js index 7688c61a435cfb..037d090e6332a4 100644 --- a/test/parallel/test-event-emitter-check-listener-leaks.js +++ b/test/parallel/test-event-emitter-check-listener-leaks.js @@ -88,7 +88,7 @@ const events = require('events'); assert.ok(e._events.fortytwo.hasOwnProperty('warned')); } -// but _maxListeners still has precedence over defaultMaxListeners +// But _maxListeners still has precedence over defaultMaxListeners { events.EventEmitter.defaultMaxListeners = 42; const e = new events.EventEmitter(); diff --git a/test/parallel/test-force-repl-with-eval.js b/test/parallel/test-force-repl-with-eval.js index 8c75818508d17e..3f81d362d449b7 100644 --- a/test/parallel/test-force-repl-with-eval.js +++ b/test/parallel/test-force-repl-with-eval.js @@ -3,7 +3,7 @@ require('../common'); const assert = require('assert'); const spawn = require('child_process').spawn; -// spawn a node child process in "interactive" mode (force the repl) and eval +// Spawn a node child process in "interactive" mode (force the repl) and eval const cp = spawn(process.execPath, ['-i', '-e', 'console.log("42")']); let gotToEnd = false; diff --git a/test/parallel/test-fs-append-file.js b/test/parallel/test-fs-append-file.js index 4d8f66682ed634..20cba235f035b6 100644 --- a/test/parallel/test-fs-append-file.js +++ b/test/parallel/test-fs-append-file.js @@ -42,7 +42,7 @@ tmpdir.refresh(); const throwNextTick = (e) => { process.nextTick(() => { throw e; }); }; -// test that empty file will be created and have content added (callback API) +// Test that empty file will be created and have content added (callback API) { const filename = join(tmpdir.path, 'append.txt'); @@ -56,7 +56,7 @@ const throwNextTick = (e) => { process.nextTick(() => { throw e; }); }; })); } -// test that empty file will be created and have content added (promise API) +// Test that empty file will be created and have content added (promise API) { const filename = join(tmpdir.path, 'append-promise.txt'); diff --git a/test/parallel/test-fs-filehandle.js b/test/parallel/test-fs-filehandle.js index 84b462aa90914d..0d1dffa2b5ff78 100644 --- a/test/parallel/test-fs-filehandle.js +++ b/test/parallel/test-fs-filehandle.js @@ -24,6 +24,6 @@ common.expectWarning( common.noWarnCode ); -gc(); // eslint-disable-line no-undef +global.gc(); setTimeout(() => {}, 10); diff --git a/test/parallel/test-fs-read-stream-double-close.js b/test/parallel/test-fs-read-stream-double-close.js index 38556e6e644a3d..32117a0a1e9402 100644 --- a/test/parallel/test-fs-read-stream-double-close.js +++ b/test/parallel/test-fs-read-stream-double-close.js @@ -13,7 +13,7 @@ const fs = require('fs'); { const s = fs.createReadStream(__filename); - // this is a private API, but it is worth testing. close calls this + // This is a private API, but it is worth testing. close calls this s.destroy(null, common.mustCall()); s.destroy(null, common.mustCall()); } diff --git a/test/parallel/test-fs-realpath.js b/test/parallel/test-fs-realpath.js index 18b9de471bc3a8..5c1c0cd962a3d5 100644 --- a/test/parallel/test-fs-realpath.js +++ b/test/parallel/test-fs-realpath.js @@ -251,7 +251,7 @@ function test_relative_input_cwd(realpath, realpathSync, callback) { return callback(); } - // we need to calculate the relative path to the tmp dir from cwd + // We need to calculate the relative path to the tmp dir from cwd const entrydir = process.cwd(); const entry = path.relative(entrydir, path.join(`${tmpDir}/cycles/realpath-3a`)); diff --git a/test/parallel/test-fs-sync-fd-leak.js b/test/parallel/test-fs-sync-fd-leak.js index ee2e0355ec7aab..30016e02845298 100644 --- a/test/parallel/test-fs-sync-fd-leak.js +++ b/test/parallel/test-fs-sync-fd-leak.js @@ -27,7 +27,7 @@ const fs = require('fs'); const { internalBinding } = require('internal/test/binding'); const { UV_EBADF } = internalBinding('uv'); -// ensure that (read|write|append)FileSync() closes the file descriptor +// Ensure that (read|write|append)FileSync() closes the file descriptor fs.openSync = function() { return 42; }; diff --git a/test/parallel/test-fs-utimes.js b/test/parallel/test-fs-utimes.js index 92558eef149040..4c13fc46592105 100644 --- a/test/parallel/test-fs-utimes.js +++ b/test/parallel/test-fs-utimes.js @@ -186,11 +186,9 @@ process.on('exit', () => { const path = `${tmpdir.path}/test-utimes-precision`; fs.writeFileSync(path, ''); -// test Y2K38 for all platforms [except 'arm', 'OpenBSD' and 'SunOS'] +// Test Y2K38 for all platforms [except 'arm', 'OpenBSD' and 'SunOS'] if (!process.arch.includes('arm') && !common.isOpenBSD && !common.isSunOS) { - // because 2 ** 31 doesn't look right - // eslint-disable-next-line space-infix-ops - const Y2K38_mtime = 2**31; + const Y2K38_mtime = 2 ** 31; fs.utimesSync(path, Y2K38_mtime, Y2K38_mtime); const Y2K38_stats = fs.statSync(path); assert.strictEqual(Y2K38_mtime, Y2K38_stats.mtime.getTime() / 1000); diff --git a/test/parallel/test-fs-write-file-sync.js b/test/parallel/test-fs-write-file-sync.js index cb0f16f370f43c..743a3858546931 100644 --- a/test/parallel/test-fs-write-file-sync.js +++ b/test/parallel/test-fs-write-file-sync.js @@ -21,87 +21,83 @@ 'use strict'; const common = require('../common'); -const assert = require('assert'); -const path = require('path'); -const fs = require('fs'); -let openCount = 0; -let mode; -let content; if (!common.isMainThread) common.skip('process.umask is not available in Workers'); -// Need to hijack fs.open/close to make sure that things -// get closed once they're opened. -fs._openSync = fs.openSync; -fs.openSync = openSync; -fs._closeSync = fs.closeSync; -fs.closeSync = closeSync; - -// Reset the umask for testing -process.umask(0o000); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); // On Windows chmod is only able to manipulate read-only bit. Test if creating // the file in read-only mode works. -if (common.isWindows) { - mode = 0o444; -} else { - mode = 0o755; -} +const mode = common.isWindows ? 0o444 : 0o755; + +// Reset the umask for testing +process.umask(0o000); const tmpdir = require('../common/tmpdir'); tmpdir.refresh(); // Test writeFileSync -const file1 = path.join(tmpdir.path, 'testWriteFileSync.txt'); - -fs.writeFileSync(file1, '123', { mode }); +{ + const file = path.join(tmpdir.path, 'testWriteFileSync.txt'); -content = fs.readFileSync(file1, { encoding: 'utf8' }); -assert.strictEqual(content, '123'); - -assert.strictEqual(fs.statSync(file1).mode & 0o777, mode); + fs.writeFileSync(file, '123', { mode }); + const content = fs.readFileSync(file, { encoding: 'utf8' }); + assert.strictEqual(content, '123'); + assert.strictEqual(fs.statSync(file).mode & 0o777, mode); +} // Test appendFileSync -const file2 = path.join(tmpdir.path, 'testAppendFileSync.txt'); - -fs.appendFileSync(file2, 'abc', { mode }); - -content = fs.readFileSync(file2, { encoding: 'utf8' }); -assert.strictEqual(content, 'abc'); - -assert.strictEqual(fs.statSync(file2).mode & mode, mode); - -// Test writeFileSync with file descriptor -const file3 = path.join(tmpdir.path, 'testWriteFileSyncFd.txt'); +{ + const file = path.join(tmpdir.path, 'testAppendFileSync.txt'); -const fd = fs.openSync(file3, 'w+', mode); -fs.writeFileSync(fd, '123'); -fs.closeSync(fd); - -content = fs.readFileSync(file3, { encoding: 'utf8' }); -assert.strictEqual(content, '123'); - -assert.strictEqual(fs.statSync(file3).mode & 0o777, mode); - -// Verify that all opened files were closed. -assert.strictEqual(openCount, 0); - -function openSync() { - openCount++; - return fs._openSync.apply(fs, arguments); + fs.appendFileSync(file, 'abc', { mode }); + const content = fs.readFileSync(file, { encoding: 'utf8' }); + assert.strictEqual(content, 'abc'); + assert.strictEqual(fs.statSync(file).mode & mode, mode); } -function closeSync() { - openCount--; - return fs._closeSync.apply(fs, arguments); +// Test writeFileSync with file descriptor +{ + // Need to hijack fs.open/close to make sure that things + // get closed once they're opened. + const _openSync = fs.openSync; + const _closeSync = fs.closeSync; + let openCount = 0; + + fs.openSync = (...args) => { + openCount++; + return _openSync(...args); + }; + + fs.closeSync = (...args) => { + openCount--; + return _closeSync(...args); + }; + + const file = path.join(tmpdir.path, 'testWriteFileSyncFd.txt'); + const fd = fs.openSync(file, 'w+', mode); + + fs.writeFileSync(fd, '123'); + fs.closeSync(fd); + const content = fs.readFileSync(file, { encoding: 'utf8' }); + assert.strictEqual(content, '123'); + assert.strictEqual(fs.statSync(file).mode & 0o777, mode); + + // Verify that all opened files were closed. + assert.strictEqual(openCount, 0); + fs.openSync = _openSync; + fs.closeSync = _closeSync; } // Test writeFileSync with flags -const file4 = path.join(tmpdir.path, 'testWriteFileSyncFlags.txt'); - -fs.writeFileSync(file4, 'hello ', { encoding: 'utf8', flag: 'a' }); -fs.writeFileSync(file4, 'world!', { encoding: 'utf8', flag: 'a' }); +{ + const file = path.join(tmpdir.path, 'testWriteFileSyncFlags.txt'); -content = fs.readFileSync(file4, { encoding: 'utf8' }); -assert.strictEqual(content, 'hello world!'); + fs.writeFileSync(file, 'hello ', { encoding: 'utf8', flag: 'a' }); + fs.writeFileSync(file, 'world!', { encoding: 'utf8', flag: 'a' }); + const content = fs.readFileSync(file, { encoding: 'utf8' }); + assert.strictEqual(content, 'hello world!'); +} diff --git a/test/parallel/test-fs-write-stream-change-open.js b/test/parallel/test-fs-write-stream-change-open.js index 8f79e59427e50d..56dbafd656431b 100644 --- a/test/parallel/test-fs-write-stream-change-open.js +++ b/test/parallel/test-fs-write-stream-change-open.js @@ -35,7 +35,7 @@ const stream = fs.WriteStream(file); const _fs_close = fs.close; const _fs_open = fs.open; -// change the fs.open with an identical function after the WriteStream +// Change the fs.open with an identical function after the WriteStream // has pushed it onto its internal action queue, but before it's // returned. This simulates AOP-style extension of the fs lib. fs.open = function() { diff --git a/test/parallel/test-heapdump-inspector.js b/test/parallel/test-heapdump-inspector.js index 963b85ac3a029a..d46be57c914a06 100644 --- a/test/parallel/test-heapdump-inspector.js +++ b/test/parallel/test-heapdump-inspector.js @@ -13,7 +13,7 @@ const snapshotNode = { ] }; -// starts with no JSBindingsConnection (or 1 if coverage enabled). +// Starts with no JSBindingsConnection (or 1 if coverage enabled). { const expected = []; if (process.env.NODE_V8_COVERAGE) { diff --git a/test/parallel/test-http-agent-false.js b/test/parallel/test-http-agent-false.js index 4d92d5e01e03e2..2f4505ef66ef3e 100644 --- a/test/parallel/test-http-agent-false.js +++ b/test/parallel/test-http-agent-false.js @@ -23,7 +23,7 @@ const common = require('../common'); const http = require('http'); -// sending `agent: false` when `port: null` is also passed in (i.e. the result +// Sending `agent: false` when `port: null` is also passed in (i.e. the result // of a `url.parse()` call with the default port used, 80 or 443), should not // result in an assertion error... const opts = { @@ -34,7 +34,7 @@ const opts = { agent: false }; -// we just want an "error" (no local HTTP server on port 80) or "response" +// We just want an "error" (no local HTTP server on port 80) or "response" // to happen (user happens ot have HTTP server running on port 80). // As long as the process doesn't crash from a C++ assertion then we're good. const req = http.request(opts); diff --git a/test/parallel/test-http-agent-no-protocol.js b/test/parallel/test-http-agent-no-protocol.js index b5a144abc93d9e..d1eaf242a51004 100644 --- a/test/parallel/test-http-agent-no-protocol.js +++ b/test/parallel/test-http-agent-no-protocol.js @@ -29,7 +29,7 @@ const server = http.createServer(common.mustCall((req, res) => { })).listen(0, '127.0.0.1', common.mustCall(() => { const opts = url.parse(`http://127.0.0.1:${server.address().port}/`); - // remove the `protocol` field… the `http` module should fall back + // Remove the `protocol` field… the `http` module should fall back // to "http:", as defined by the global, default `http.Agent` instance. opts.agent = new http.Agent(); opts.agent.protocol = null; diff --git a/test/parallel/test-http-client-headers-array.js b/test/parallel/test-http-client-headers-array.js index c637de61c012b5..31ee35a123ccb9 100644 --- a/test/parallel/test-http-client-headers-array.js +++ b/test/parallel/test-http-client-headers-array.js @@ -39,7 +39,7 @@ function execute(options) { }); } -// should be the same except for implicit Host header on the first two +// Should be the same except for implicit Host header on the first two execute({ headers: { 'x-foo': 'boom', 'cookie': 'a=1; b=2; c=3' } }); execute({ headers: { 'x-foo': 'boom', 'cookie': [ 'a=1', 'b=2', 'c=3' ] } }); execute({ headers: [[ 'x-foo', 'boom' ], [ 'cookie', 'a=1; b=2; c=3' ]] }); diff --git a/test/parallel/test-http-conn-reset.js b/test/parallel/test-http-conn-reset.js index 7d0509a89ff68e..fef75b72891e9c 100644 --- a/test/parallel/test-http-conn-reset.js +++ b/test/parallel/test-http-conn-reset.js @@ -31,7 +31,7 @@ const options = { }; process.env.NODE_DEBUG = 'http'; -// start a tcp server that closes incoming connections immediately +// Start a tcp server that closes incoming connections immediately const server = net.createServer(function(client) { client.destroy(); server.close(); diff --git a/test/parallel/test-http-outgoing-message-inheritance.js b/test/parallel/test-http-outgoing-message-inheritance.js index 05a241dc8bda00..9beb4aeff17fab 100644 --- a/test/parallel/test-http-outgoing-message-inheritance.js +++ b/test/parallel/test-http-outgoing-message-inheritance.js @@ -5,7 +5,7 @@ const { OutgoingMessage } = require('http'); const { Writable } = require('stream'); const assert = require('assert'); -// check that OutgoingMessage can be used without a proper Socket +// Check that OutgoingMessage can be used without a proper Socket // Fixes: https://github.com/nodejs/node/issues/14386 // Fixes: https://github.com/nodejs/node/issues/14381 diff --git a/test/parallel/test-http-remove-header-stays-removed.js b/test/parallel/test-http-remove-header-stays-removed.js index 337fcd3becd177..09a44753885d1b 100644 --- a/test/parallel/test-http-remove-header-stays-removed.js +++ b/test/parallel/test-http-remove-header-stays-removed.js @@ -26,7 +26,7 @@ const assert = require('assert'); const http = require('http'); const server = http.createServer(function(request, response) { - // removed headers should stay removed, even if node automatically adds them + // Removed headers should stay removed, even if node automatically adds them // to the output: response.removeHeader('connection'); response.removeHeader('transfer-encoding'); diff --git a/test/parallel/test-http-url.parse-auth-with-header-in-request.js b/test/parallel/test-http-url.parse-auth-with-header-in-request.js index c10f5ed7b0d31b..eb96ac19c172ff 100644 --- a/test/parallel/test-http-url.parse-auth-with-header-in-request.js +++ b/test/parallel/test-http-url.parse-auth-with-header-in-request.js @@ -41,7 +41,7 @@ const server = http.createServer(function(request, response) { server.listen(0, function() { const testURL = url.parse(`http://asdf:qwer@localhost:${this.address().port}`); - // the test here is if you set a specific authorization header in the + // The test here is if you set a specific authorization header in the // request we should not override that with basic auth testURL.headers = { Authorization: 'NoAuthForYOU' diff --git a/test/parallel/test-http2-client-onconnect-errors.js b/test/parallel/test-http2-client-onconnect-errors.js index e72b5f454ba650..ab166c22f0e9de 100644 --- a/test/parallel/test-http2-client-onconnect-errors.js +++ b/test/parallel/test-http2-client-onconnect-errors.js @@ -65,7 +65,7 @@ const tests = specificTests.concat(genericTests); let currentError; -// mock submitRequest because we only care about testing error handling +// Mock submitRequest because we only care about testing error handling Http2Session.prototype.request = () => currentError; const server = http2.createServer(common.mustNotCall()); diff --git a/test/parallel/test-http2-client-setNextStreamID-errors.js b/test/parallel/test-http2-client-setNextStreamID-errors.js index 3fb4728b7d3a1c..39d194e1f51a93 100644 --- a/test/parallel/test-http2-client-setNextStreamID-errors.js +++ b/test/parallel/test-http2-client-setNextStreamID-errors.js @@ -37,7 +37,7 @@ server.listen(0, common.mustCall(() => { } ); - // should throw if something other than number is passed to setNextStreamID + // Should throw if something other than number is passed to setNextStreamID Object.entries(types).forEach(([type, value]) => { if (type === 'number') { return; diff --git a/test/parallel/test-http2-compat-serverresponse-headers-after-destroy.js b/test/parallel/test-http2-compat-serverresponse-headers-after-destroy.js index 206bd1c9d43e06..fc97a70f42d956 100644 --- a/test/parallel/test-http2-compat-serverresponse-headers-after-destroy.js +++ b/test/parallel/test-http2-compat-serverresponse-headers-after-destroy.js @@ -6,7 +6,7 @@ if (!common.hasCrypto) const assert = require('assert'); const h2 = require('http2'); -// makes sure that Http2ServerResponse setHeader & removeHeader, do not throw +// Makes sure that Http2ServerResponse setHeader & removeHeader, do not throw // any errors if the stream was destroyed before headers were sent const server = h2.createServer(); diff --git a/test/parallel/test-http2-compat-socket.js b/test/parallel/test-http2-compat-socket.js index 498677af6ee796..5b61f27bb2b828 100644 --- a/test/parallel/test-http2-compat-socket.js +++ b/test/parallel/test-http2-compat-socket.js @@ -62,7 +62,7 @@ server.on('request', common.mustCall(function(request, response) { }); })); - // properties that do not exist on the proxy are retrieved from the socket + // Properties that do not exist on the proxy are retrieved from the socket assert.ok(request.socket._server); assert.strictEqual(request.socket.connecting, false); diff --git a/test/parallel/test-http2-connect-method.js b/test/parallel/test-http2-connect-method.js index 0ddbc60433cf85..46c5bf9795db69 100644 --- a/test/parallel/test-http2-connect-method.js +++ b/test/parallel/test-http2-connect-method.js @@ -55,7 +55,7 @@ server.listen(0, common.mustCall(() => { proxy.listen(0, () => { const client = http2.connect(`http://localhost:${proxy.address().port}`); - // confirm that :authority is required and :scheme & :path are forbidden + // Confirm that :authority is required and :scheme & :path are forbidden common.expectsError( () => client.request({ [HTTP2_HEADER_METHOD]: 'CONNECT' diff --git a/test/parallel/test-http2-connect.js b/test/parallel/test-http2-connect.js index 252efa1229ad85..b93faf9d938380 100644 --- a/test/parallel/test-http2-connect.js +++ b/test/parallel/test-http2-connect.js @@ -33,7 +33,7 @@ const { connect: netConnect } = require('net'); })); } -// check for session connect callback on already connected socket +// Check for session connect callback on already connected socket { const server = createServer(); server.listen(0, mustCall(() => { diff --git a/test/parallel/test-http2-info-headers-errors.js b/test/parallel/test-http2-info-headers-errors.js index e2cae58466bb82..6540747fd25a5f 100644 --- a/test/parallel/test-http2-info-headers-errors.js +++ b/test/parallel/test-http2-info-headers-errors.js @@ -39,7 +39,7 @@ const tests = specificTests.concat(genericTests); let currentError; -// mock sendHeaders because we only care about testing error handling +// Mock sendHeaders because we only care about testing error handling Http2Stream.prototype.info = () => currentError.ngError; const server = http2.createServer(); diff --git a/test/parallel/test-http2-respond-nghttperrors.js b/test/parallel/test-http2-respond-nghttperrors.js index 5ebd24a65b1b2f..d720ec1fa486f7 100644 --- a/test/parallel/test-http2-respond-nghttperrors.js +++ b/test/parallel/test-http2-respond-nghttperrors.js @@ -40,7 +40,7 @@ const tests = specificTests.concat(genericTests); let currentError; -// mock submitResponse because we only care about testing error handling +// Mock submitResponse because we only care about testing error handling Http2Stream.prototype.respond = () => currentError.ngError; const server = http2.createServer(); diff --git a/test/parallel/test-http2-respond-with-fd-errors.js b/test/parallel/test-http2-respond-with-fd-errors.js index 9dfd95ea5a2c7c..f336d9caac1f8f 100644 --- a/test/parallel/test-http2-respond-with-fd-errors.js +++ b/test/parallel/test-http2-respond-with-fd-errors.js @@ -47,7 +47,7 @@ const tests = specificTests.concat(genericTests); let currentError; -// mock `respond` because we only care about testing error handling +// Mock `respond` because we only care about testing error handling Http2Stream.prototype.respond = () => currentError.ngError; const server = http2.createServer(); diff --git a/test/parallel/test-http2-server-push-stream-errors.js b/test/parallel/test-http2-server-push-stream-errors.js index e489cae439205e..fb6fc11b63f999 100644 --- a/test/parallel/test-http2-server-push-stream-errors.js +++ b/test/parallel/test-http2-server-push-stream-errors.js @@ -64,7 +64,7 @@ const tests = specificTests.concat(genericTests); let currentError; -// mock submitPushPromise because we only care about testing error handling +// Mock submitPushPromise because we only care about testing error handling Http2Stream.prototype.pushPromise = () => currentError.ngError; const server = http2.createServer(); diff --git a/test/sequential/test-http2-session-timeout.js b/test/parallel/test-http2-session-timeout.js similarity index 64% rename from test/sequential/test-http2-session-timeout.js rename to test/parallel/test-http2-session-timeout.js index 14a31bad9bd0fc..0fa6a2c13c6b6c 100644 --- a/test/sequential/test-http2-session-timeout.js +++ b/test/parallel/test-http2-session-timeout.js @@ -6,15 +6,15 @@ if (!common.hasCrypto) const assert = require('assert'); const http2 = require('http2'); -const serverTimeout = common.platformTimeout(200); - let requests = 0; const mustNotCall = () => { assert.fail(`Timeout after ${requests} request(s)`); }; const server = http2.createServer(); -server.timeout = serverTimeout; +// Disable server timeout until first request. We will set the timeout based on +// how long the first request takes. +server.timeout = 0; server.on('request', (req, res) => res.end()); server.on('timeout', mustNotCall); @@ -24,7 +24,7 @@ server.listen(0, common.mustCall(() => { const url = `http://localhost:${port}`; const client = http2.connect(url); - const startTime = process.hrtime(); + let startTime = process.hrtime(); makeReq(); function makeReq() { @@ -42,7 +42,15 @@ server.listen(0, common.mustCall(() => { request.on('end', () => { const diff = process.hrtime(startTime); const milliseconds = (diff[0] * 1e3 + diff[1] / 1e6); - if (milliseconds < serverTimeout * 2) { + if (server.timeout === 0) { + // Set the timeout now. First connection will take significantly longer + // than subsequent connections, so using the duration of the first + // connection as the timeout should be robust. Double it anyway for good + // measure. + server.timeout = milliseconds * 2; + startTime = process.hrtime(); + makeReq(); + } else if (milliseconds < server.timeout * 2) { makeReq(); } else { server.removeListener('timeout', mustNotCall); diff --git a/test/parallel/test-https-argument-of-creating.js b/test/parallel/test-https-argument-of-creating.js index 063002840616fc..1154f968d792c3 100644 --- a/test/parallel/test-https-argument-of-creating.js +++ b/test/parallel/test-https-argument-of-creating.js @@ -22,7 +22,7 @@ const dftProtocol = {}; } -// validate that `createServer` can work with the only argument requestListener +// Validate that `createServer` can work with the only argument requestListener { const mustNotCall = common.mustNotCall(); const server = https.createServer(mustNotCall); diff --git a/test/parallel/test-inspector-tracing-domain.js b/test/parallel/test-inspector-tracing-domain.js index ecf15c5be97630..9d3d33d94d5bbd 100644 --- a/test/parallel/test-inspector-tracing-domain.js +++ b/test/parallel/test-inspector-tracing-domain.js @@ -60,7 +60,7 @@ async function test() { await generateTrace(); JSON.stringify(await post('NodeTracing.stop', { traceConfig })); session.disconnect(); - assert(traceNotification.data.value.length > 0); + assert(traceNotification.params.value.length > 0); assert(tracingComplete); clearInterval(interval); console.log('Success'); diff --git a/test/parallel/test-listen-fd-cluster.js b/test/parallel/test-listen-fd-cluster.js index da8abd868300e3..bc81a8da0bc312 100644 --- a/test/parallel/test-listen-fd-cluster.js +++ b/test/parallel/test-listen-fd-cluster.js @@ -47,14 +47,14 @@ process.on('exit', function() { assert.ok(ok); }); -// spawn the parent, and listen for it to tell us the pid of the cluster. +// Spawn the parent, and listen for it to tell us the pid of the cluster. // WARNING: This is an example of listening on some arbitrary FD number // that has already been bound elsewhere in advance. However, binding // server handles to stdio fd's is NOT a good or reliable way to do // concurrency in HTTP servers! Use the cluster module, or if you want // a more low-level approach, use child process IPC manually. test(function(parent, port) { - // now make sure that we can request to the worker, then kill it. + // Now make sure that we can request to the worker, then kill it. http.get({ server: 'localhost', port: port, diff --git a/test/parallel/test-listen-fd-detached-inherit.js b/test/parallel/test-listen-fd-detached-inherit.js index 4feb7dc3ab03dd..e0fc25134cce93 100644 --- a/test/parallel/test-listen-fd-detached-inherit.js +++ b/test/parallel/test-listen-fd-detached-inherit.js @@ -35,7 +35,7 @@ switch (process.argv[2]) { default: return test(); } -// spawn the parent, and listen for it to tell us the pid of the child. +// Spawn the parent, and listen for it to tell us the pid of the child. // WARNING: This is an example of listening on some arbitrary FD number // that has already been bound elsewhere in advance. However, binding // server handles to stdio fd's is NOT a good or reliable way to do @@ -53,7 +53,7 @@ function test() { function next() { console.error('output from parent = %s', json); const child = JSON.parse(json); - // now make sure that we can request to the subprocess, then kill it. + // Now make sure that we can request to the subprocess, then kill it. http.get({ server: 'localhost', port: child.port, diff --git a/test/parallel/test-listen-fd-detached.js b/test/parallel/test-listen-fd-detached.js index 09d7f8b6c1a68c..eec12132a1d6f2 100644 --- a/test/parallel/test-listen-fd-detached.js +++ b/test/parallel/test-listen-fd-detached.js @@ -35,7 +35,7 @@ switch (process.argv[2]) { default: return test(); } -// spawn the parent, and listen for it to tell us the pid of the child. +// Spawn the parent, and listen for it to tell us the pid of the child. // WARNING: This is an example of listening on some arbitrary FD number // that has already been bound elsewhere in advance. However, binding // server handles to stdio fd's is NOT a good or reliable way to do @@ -53,7 +53,7 @@ function test() { function next() { console.error('output from parent = %s', json); const child = JSON.parse(json); - // now make sure that we can request to the subprocess, then kill it. + // Now make sure that we can request to the subprocess, then kill it. http.get({ server: 'localhost', port: child.port, diff --git a/test/parallel/test-listen-fd-server.js b/test/parallel/test-listen-fd-server.js index 7cdba8b405892a..a09a01f219daf1 100644 --- a/test/parallel/test-listen-fd-server.js +++ b/test/parallel/test-listen-fd-server.js @@ -44,7 +44,7 @@ process.on('exit', function() { // concurrency in HTTP servers! Use the cluster module, or if you want // a more low-level approach, use child process IPC manually. test(function(child, port) { - // now make sure that we can request to the subprocess, then kill it. + // Now make sure that we can request to the subprocess, then kill it. http.get({ server: 'localhost', port: port, diff --git a/test/parallel/test-net-pipe-connect-errors.js b/test/parallel/test-net-pipe-connect-errors.js index 8db452669991f0..330203365e7fbe 100644 --- a/test/parallel/test-net-pipe-connect-errors.js +++ b/test/parallel/test-net-pipe-connect-errors.js @@ -32,7 +32,7 @@ const assert = require('assert'); let emptyTxt; if (common.isWindows) { - // on Win, common.PIPE will be a named pipe, so we use an existing empty + // On Win, common.PIPE will be a named pipe, so we use an existing empty // file instead emptyTxt = fixtures.path('empty.txt'); } else { diff --git a/test/parallel/test-net-server-connections.js b/test/parallel/test-net-server-connections.js index 9e1213ada558c3..52b2fe6bf567e3 100644 --- a/test/parallel/test-net-server-connections.js +++ b/test/parallel/test-net-server-connections.js @@ -32,7 +32,7 @@ const expectedWarning = 'Server.connections property is deprecated. ' + common.expectWarning('DeprecationWarning', expectedWarning, 'DEP0020'); -// test that server.connections property is no longer enumerable now that it +// Test that server.connections property is no longer enumerable now that it // has been marked as deprecated assert.strictEqual(Object.keys(server).includes('connections'), false); diff --git a/test/parallel/test-net-socket-setnodelay.js b/test/parallel/test-net-socket-setnodelay.js index be5c8ffc8524dc..55b4c773fa5bf7 100644 --- a/test/parallel/test-net-socket-setnodelay.js +++ b/test/parallel/test-net-socket-setnodelay.js @@ -32,7 +32,7 @@ socket = new net.Socket({ }); falseyValues.forEach((testVal) => socket.setNoDelay(testVal)); -// if a handler doesn't have a setNoDelay function it shouldn't be called. +// If a handler doesn't have a setNoDelay function it shouldn't be called. // In the case below, if it is called an exception will be thrown socket = new net.Socket({ handle: { diff --git a/test/parallel/test-net-socket-timeout.js b/test/parallel/test-net-socket-timeout.js index 2826b1dd76f146..a30ab8ce293764 100644 --- a/test/parallel/test-net-socket-timeout.js +++ b/test/parallel/test-net-socket-timeout.js @@ -34,15 +34,15 @@ const validDelays = [0, 0.001, 1, 1e6]; for (let i = 0; i < nonNumericDelays.length; i++) { - assert.throws(function() { + assert.throws(() => { s.setTimeout(nonNumericDelays[i], () => {}); - }, TypeError, nonNumericDelays[i]); + }, { code: 'ERR_INVALID_ARG_TYPE' }, nonNumericDelays[i]); } for (let i = 0; i < badRangeDelays.length; i++) { - assert.throws(function() { + assert.throws(() => { s.setTimeout(badRangeDelays[i], () => {}); - }, RangeError, badRangeDelays[i]); + }, { code: 'ERR_OUT_OF_RANGE' }, badRangeDelays[i]); } for (let i = 0; i < validDelays.length; i++) { @@ -50,9 +50,9 @@ for (let i = 0; i < validDelays.length; i++) { } const server = net.Server(); -server.listen(0, common.mustCall(function() { - const socket = net.createConnection(this.address().port); - socket.setTimeout(1, common.mustCall(function() { +server.listen(0, common.mustCall(() => { + const socket = net.createConnection(server.address().port); + socket.setTimeout(1, common.mustCall(() => { socket.destroy(); server.close(); })); diff --git a/test/parallel/test-net-stream.js b/test/parallel/test-net-stream.js index 4e7e06bfcf2546..8e996dd58a7ef6 100644 --- a/test/parallel/test-net-stream.js +++ b/test/parallel/test-net-stream.js @@ -27,7 +27,7 @@ const net = require('net'); const s = new net.Stream(); -// test that destroy called on a stream with a server only ever decrements the +// Test that destroy called on a stream with a server only ever decrements the // server connection count once s.server = new net.Server(); diff --git a/test/parallel/test-path-join.js b/test/parallel/test-path-join.js index 691ba98f9bc095..945cf0e9b5d772 100644 --- a/test/parallel/test-path-join.js +++ b/test/parallel/test-path-join.js @@ -90,7 +90,7 @@ joinTests.push([ [['//', 'foo/bar'], '\\foo\\bar'], [['//', '/foo/bar'], '\\foo\\bar'], [['\\\\', '/', '/foo/bar'], '\\foo\\bar'], - [['//'], '/'], + [['//'], '\\'], // No UNC path expected (share name missing - questionable). [['//foo'], '\\foo'], [['//foo/'], '\\foo\\'], diff --git a/test/parallel/test-path-zero-length-strings.js b/test/parallel/test-path-zero-length-strings.js index c1b74c515fccdc..f6516ffff85acb 100644 --- a/test/parallel/test-path-zero-length-strings.js +++ b/test/parallel/test-path-zero-length-strings.js @@ -10,7 +10,7 @@ const assert = require('assert'); const path = require('path'); const pwd = process.cwd(); -// join will internally ignore all the zero-length strings and it will return +// Join will internally ignore all the zero-length strings and it will return // '.' if the joined string is a zero-length string. assert.strictEqual(path.posix.join(''), '.'); assert.strictEqual(path.posix.join('', ''), '.'); @@ -19,7 +19,7 @@ assert.strictEqual(path.win32.join('', ''), '.'); assert.strictEqual(path.join(pwd), pwd); assert.strictEqual(path.join(pwd, ''), pwd); -// normalize will return '.' if the input is a zero-length string +// Normalize will return '.' if the input is a zero-length string assert.strictEqual(path.posix.normalize(''), '.'); assert.strictEqual(path.win32.normalize(''), '.'); assert.strictEqual(path.normalize(pwd), pwd); @@ -28,12 +28,12 @@ assert.strictEqual(path.normalize(pwd), pwd); assert.strictEqual(path.posix.isAbsolute(''), false); assert.strictEqual(path.win32.isAbsolute(''), false); -// resolve, internally ignores all the zero-length strings and returns the +// Resolve, internally ignores all the zero-length strings and returns the // current working directory assert.strictEqual(path.resolve(''), pwd); assert.strictEqual(path.resolve('', ''), pwd); -// relative, internally calls resolve. So, '' is actually the current directory +// Relative, internally calls resolve. So, '' is actually the current directory assert.strictEqual(path.relative('', pwd), ''); assert.strictEqual(path.relative(pwd, ''), ''); assert.strictEqual(path.relative(pwd, pwd), ''); diff --git a/test/parallel/test-process-beforeexit.js b/test/parallel/test-process-beforeexit.js index d197d943a4b07d..215e73dc0650f3 100644 --- a/test/parallel/test-process-beforeexit.js +++ b/test/parallel/test-process-beforeexit.js @@ -46,7 +46,7 @@ function tryListen() { })); } -// test that a function invoked from the beforeExit handler can use a timer +// Test that a function invoked from the beforeExit handler can use a timer // to keep the event loop open, which can use another timer to keep the event // loop open, etc. function tryRepeatedTimer() { diff --git a/test/parallel/test-process-config.js b/test/parallel/test-process-config.js index 05f4ca915a5524..0cb7e8e8d590d7 100644 --- a/test/parallel/test-process-config.js +++ b/test/parallel/test-process-config.js @@ -48,7 +48,7 @@ let config = fs.readFileSync(configPath, 'utf8'); config = config.split('\n').slice(1).join('\n'); config = config.replace(/"/g, '\\"'); config = config.replace(/'/g, '"'); -config = JSON.parse(config, function(key, value) { +config = JSON.parse(config, (key, value) => { if (value === 'true') return true; if (value === 'false') return false; return value; diff --git a/test/parallel/test-process-env-allowed-flags.js b/test/parallel/test-process-env-allowed-flags.js index ddd8d894eabcb1..b3d815f66de6da 100644 --- a/test/parallel/test-process-env-allowed-flags.js +++ b/test/parallel/test-process-env-allowed-flags.js @@ -3,7 +3,7 @@ const assert = require('assert'); require('../common'); -// assert legit flags are allowed, and bogus flags are disallowed +// Assert legit flags are allowed, and bogus flags are disallowed { const goodFlags = [ '--perf_basic_prof', diff --git a/test/parallel/test-process-env.js b/test/parallel/test-process-env.js index 81651efbea024d..d146d5c616607a 100644 --- a/test/parallel/test-process-env.js +++ b/test/parallel/test-process-env.js @@ -65,7 +65,7 @@ if (process.argv[2] === 'you-are-the-child') { } -// delete should return true except for non-configurable properties +// Delete should return true except for non-configurable properties // https://github.com/nodejs/node/issues/7960 delete process.env.NON_EXISTING_VARIABLE; assert(delete process.env.NON_EXISTING_VARIABLE); diff --git a/test/parallel/test-process-exit-recursive.js b/test/parallel/test-process-exit-recursive.js index 57f5c2956f8c0d..727aa4abe7232c 100644 --- a/test/parallel/test-process-exit-recursive.js +++ b/test/parallel/test-process-exit-recursive.js @@ -23,14 +23,14 @@ require('../common'); const assert = require('assert'); -// recursively calling .exit() should not overflow the call stack +// Recursively calling .exit() should not overflow the call stack let nexits = 0; process.on('exit', function(code) { assert.strictEqual(nexits++, 0); assert.strictEqual(code, 1); - // now override the exit code of 1 with 0 so that the test passes + // Now override the exit code of 1 with 0 so that the test passes process.exit(0); }); diff --git a/test/parallel/test-process-exit.js b/test/parallel/test-process-exit.js index ac934d4c6818a4..cd605949af51e8 100644 --- a/test/parallel/test-process-exit.js +++ b/test/parallel/test-process-exit.js @@ -23,7 +23,7 @@ require('../common'); const assert = require('assert'); -// calling .exit() from within "exit" should not overflow the call stack +// Calling .exit() from within "exit" should not overflow the call stack let nexits = 0; process.on('exit', function(code) { diff --git a/test/parallel/test-process-release.js b/test/parallel/test-process-release.js index 8b6bca9141beed..874c658c20d8ff 100644 --- a/test/parallel/test-process-release.js +++ b/test/parallel/test-process-release.js @@ -7,7 +7,7 @@ const versionParts = process.versions.node.split('.'); assert.strictEqual(process.release.name, 'node'); -// it's expected that future LTS release lines will have additional +// It's expected that future LTS release lines will have additional // branches in here if (versionParts[0] === '4' && versionParts[1] >= 2) { assert.strictEqual(process.release.lts, 'Argon'); diff --git a/test/parallel/test-readline-interface.js b/test/parallel/test-readline-interface.js index ec553832c42d68..408d70e788095e 100644 --- a/test/parallel/test-readline-interface.js +++ b/test/parallel/test-readline-interface.js @@ -189,7 +189,7 @@ function isWarned(emitter) { rli.close(); } - // sending multiple newlines at once that does not end with a new line + // Sending multiple newlines at once that does not end with a new line { const fi = new FakeInput(); const rli = new readline.Interface( @@ -206,7 +206,7 @@ function isWarned(emitter) { rli.close(); } - // sending multiple newlines at once that does not end with a new(empty) + // Sending multiple newlines at once that does not end with a new(empty) // line and a `end` event { const fi = new FakeInput(); @@ -228,7 +228,7 @@ function isWarned(emitter) { rli.close(); } - // sending multiple newlines at once that does not end with a new line + // Sending multiple newlines at once that does not end with a new line // and a `end` event(last line is) // \r should behave like \n when alone @@ -354,7 +354,7 @@ function isWarned(emitter) { rli.close(); } - // constructor throws if completer is not a function or undefined + // Constructor throws if completer is not a function or undefined { const fi = new FakeInput(); common.expectsError(function() { @@ -979,7 +979,7 @@ function isWarned(emitter) { assert.strictEqual(isWarned(process.stdout._events), false); } - // can create a new readline Interface with a null output argument + // Can create a new readline Interface with a null output argument { const fi = new FakeInput(); const rli = new readline.Interface( @@ -1037,7 +1037,7 @@ function isWarned(emitter) { const crlfDelay = Infinity; [ true, false ].forEach(function(terminal) { - // sending multiple newlines at once that does not end with a new line + // Sending multiple newlines at once that does not end with a new line // and a `end` event(last line is) // \r\n should emit one line event, not two diff --git a/test/parallel/test-repl-history-navigation.js b/test/parallel/test-repl-history-navigation.js new file mode 100644 index 00000000000000..562b79dae846d4 --- /dev/null +++ b/test/parallel/test-repl-history-navigation.js @@ -0,0 +1,139 @@ +'use strict'; + +// Flags: --expose-internals + +const common = require('../common'); +const stream = require('stream'); +const REPL = require('internal/repl'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const defaultHistoryPath = path.join(tmpdir.path, '.node_repl_history'); + +// Create an input stream specialized for testing an array of actions +class ActionStream extends stream.Stream { + run(data) { + const _iter = data[Symbol.iterator](); + const doAction = () => { + const next = _iter.next(); + if (next.done) { + // Close the repl. Note that it must have a clean prompt to do so. + this.emit('keypress', '', { ctrl: true, name: 'd' }); + return; + } + const action = next.value; + + if (typeof action === 'object') { + this.emit('keypress', '', action); + } else { + this.emit('data', `${action}`); + } + setImmediate(doAction); + }; + setImmediate(doAction); + } + resume() {} + pause() {} +} +ActionStream.prototype.readable = true; + + +// Mock keys +const ENTER = { name: 'enter' }; +const UP = { name: 'up' }; +const DOWN = { name: 'down' }; + +const prompt = '> '; + +const tests = [ + { // creates few history to navigate for + env: { NODE_REPL_HISTORY: defaultHistoryPath }, + test: [ 'let ab = 45', ENTER, + '555 + 909', ENTER, + '{key : {key2 :[] }}', ENTER], + expected: [], + clean: false + }, + { + env: { NODE_REPL_HISTORY: defaultHistoryPath }, + test: [UP, UP, UP, UP, DOWN, DOWN, DOWN], + expected: [prompt, + `${prompt}{key : {key2 :[] }}`, + `${prompt}555 + 909`, + `${prompt}let ab = 45`, + `${prompt}555 + 909`, + `${prompt}{key : {key2 :[] }}`, + prompt], + clean: true + } +]; +const numtests = tests.length; + +const runTestWrap = common.mustCall(runTest, numtests); + +function cleanupTmpFile() { + try { + // Write over the file, clearing any history + fs.writeFileSync(defaultHistoryPath, ''); + } catch (err) { + if (err.code === 'ENOENT') return true; + throw err; + } + return true; +} + +function runTest() { + const opts = tests.shift(); + if (!opts) return; // All done + + const env = opts.env; + const test = opts.test; + const expected = opts.expected; + + REPL.createInternalRepl(env, { + input: new ActionStream(), + output: new stream.Writable({ + write(chunk, _, next) { + const output = chunk.toString(); + + if (output.charCodeAt(0) === 27 || /^[\r\n]+$/.test(output)) { + return next(); + } + + if (expected.length) { + assert.strictEqual(output, expected[0]); + expected.shift(); + } + + next(); + } + }), + prompt: prompt, + useColors: false, + terminal: true + }, function(err, repl) { + if (err) { + console.error(`Failed test # ${numtests - tests.length}`); + throw err; + } + + repl.once('close', () => { + if (opts.clean) + cleanupTmpFile(); + + if (expected.length !== 0) { + throw new Error(`Failed test # ${numtests - tests.length}`); + } + setImmediate(runTestWrap, true); + }); + + repl.inputStream.run(test); + }); +} + +// run the tests +runTest(); diff --git a/test/parallel/test-repl-save-load.js b/test/parallel/test-repl-save-load.js index 7ca0e9c0164056..2767c0f02629be 100644 --- a/test/parallel/test-repl-save-load.js +++ b/test/parallel/test-repl-save-load.js @@ -97,7 +97,7 @@ let loadFile = join(tmpdir.path, 'file.does.not.exist'); // should not break putIn.write = function(data) { - // make sure I get a failed to load message and not some crazy error + // Make sure I get a failed to load message and not some crazy error assert.strictEqual(data, `Failed to load:${loadFile}\n`); // eat me to avoid work putIn.write = () => {}; @@ -121,7 +121,7 @@ const invalidFileName = join(tmpdir.path, '\0\0\0\0\0'); // should not break putIn.write = function(data) { - // make sure I get a failed to save message and not some other error + // Make sure I get a failed to save message and not some other error assert.strictEqual(data, `Failed to save:${invalidFileName}\n`); // reset to no-op putIn.write = () => {}; diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index 378072ecb8c3e7..9edebe90365939 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -207,7 +207,7 @@ testMe.complete(' ', common.mustCall(function(error, data) { clearTimeout(spaceTimeout); })); -// tab completion should pick up the global "toString" object, and +// Tab completion should pick up the global "toString" object, and // any other properties up the "global" object's prototype chain testMe.complete('toSt', common.mustCall(function(error, data) { assert.deepStrictEqual(data, [['toString'], 'toSt']); diff --git a/test/parallel/test-repl-unexpected-token-recoverable.js b/test/parallel/test-repl-unexpected-token-recoverable.js index 652c17d8f8ac59..c4b3a08e969000 100644 --- a/test/parallel/test-repl-unexpected-token-recoverable.js +++ b/test/parallel/test-repl-unexpected-token-recoverable.js @@ -6,7 +6,7 @@ require('../common'); const assert = require('assert'); const spawn = require('child_process').spawn; -// use -i to force node into interactive mode, despite stdout not being a TTY +// Use -i to force node into interactive mode, despite stdout not being a TTY const args = [ '-i' ]; const child = spawn(process.execPath, args); diff --git a/test/parallel/test-repl.js b/test/parallel/test-repl.js index f8261dedd98974..98f47a03aaf008 100644 --- a/test/parallel/test-repl.js +++ b/test/parallel/test-repl.js @@ -204,13 +204,13 @@ const errorTests = [ send: 'JSON.parse(\'{"valid": "json"}\');', expect: '{ valid: \'json\' }' }, - // invalid input to JSON.parse error is special case of syntax error, + // Invalid input to JSON.parse error is special case of syntax error, // should throw { send: 'JSON.parse(\'{invalid: \\\'json\\\'}\');', expect: [/^SyntaxError: /, ''] }, - // end of input to JSON.parse error is special case of syntax error, + // End of input to JSON.parse error is special case of syntax error, // should throw { send: 'JSON.parse(\'066\');', @@ -380,19 +380,19 @@ const errorTests = [ send: 'var path = 42; path', expect: '42' }, - // this makes sure that we don't print `undefined` when we actually print + // This makes sure that we don't print `undefined` when we actually print // the error message { send: '.invalid_repl_command', expect: 'Invalid REPL keyword' }, - // this makes sure that we don't crash when we use an inherited property as + // This makes sure that we don't crash when we use an inherited property as // a REPL command { send: '.toString', expect: 'Invalid REPL keyword' }, - // fail when we are not inside a String and a line continuation is used + // Fail when we are not inside a String and a line continuation is used { send: '[] \\', expect: [ @@ -421,7 +421,7 @@ const errorTests = [ send: '\'the \\\n fourth\t\t\\\n eye \'', expect: '... ... \'the fourth\\t\\t eye \'' }, - // more than one multiline strings also should preserve whitespace chars + // More than one multiline strings also should preserve whitespace chars { send: '\'the \\\n fourth\' + \'\t\t\\\n eye \'', expect: '... ... \'the fourth\\t\\t eye \'' @@ -431,7 +431,7 @@ const errorTests = [ send: '\'\\\n.break', expect: '... ' + prompt_unix }, - // using REPL command "help" within a string literal should still work + // Using REPL command "help" within a string literal should still work { send: '\'thefourth\\\n.help\neye\'', expect: [ @@ -450,7 +450,7 @@ const errorTests = [ send: '\n\r\n\r\n', expect: '' }, - // empty lines in the string literals should not affect the string + // Empty lines in the string literals should not affect the string { send: '\'the\\\n\\\nfourtheye\'\n', expect: '... ... \'thefourtheye\'' @@ -460,14 +460,14 @@ const errorTests = [ send: '/(.)(.)(.)(.)(.)(.)(.)(.)(.)/.test(\'123456789\')\n', expect: 'true' }, - // the following test's result depends on the RegExp's match from the above + // The following test's result depends on the RegExp's match from the above { send: 'RegExp.$1\nRegExp.$2\nRegExp.$3\nRegExp.$4\nRegExp.$5\n' + 'RegExp.$6\nRegExp.$7\nRegExp.$8\nRegExp.$9\n', expect: ['\'1\'', '\'2\'', '\'3\'', '\'4\'', '\'5\'', '\'6\'', '\'7\'', '\'8\'', '\'9\''] }, - // regression tests for https://github.com/nodejs/node/issues/2749 + // Regression tests for https://github.com/nodejs/node/issues/2749 { send: 'function x() {\nreturn \'\\n\';\n }', expect: '... ... undefined' @@ -476,7 +476,7 @@ const errorTests = [ send: 'function x() {\nreturn \'\\\\\';\n }', expect: '... ... undefined' }, - // regression tests for https://github.com/nodejs/node/issues/3421 + // Regression tests for https://github.com/nodejs/node/issues/3421 { send: 'function x() {\n//\'\n }', expect: '... ... undefined' diff --git a/test/parallel/test-stream-pipeline-queued-end-in-destroy.js b/test/parallel/test-stream-pipeline-queued-end-in-destroy.js new file mode 100644 index 00000000000000..d5e399ddda531b --- /dev/null +++ b/test/parallel/test-stream-pipeline-queued-end-in-destroy.js @@ -0,0 +1,39 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Readable, Duplex, pipeline } = require('stream'); + +// Test that the callback for pipeline() is called even when the ._destroy() +// method of the stream places an .end() request to itself that does not +// get processed before the destruction of the stream (i.e. the 'close' event). +// Refs: https://github.com/nodejs/node/issues/24456 + +const readable = new Readable({ + read: common.mustCall(() => {}) +}); + +const duplex = new Duplex({ + write(chunk, enc, cb) { + // Simulate messages queueing up. + }, + read() {}, + destroy(err, cb) { + // Call end() from inside the destroy() method, like HTTP/2 streams + // do at the time of writing. + this.end(); + cb(err); + } +}); + +duplex.on('finished', common.mustNotCall()); + +pipeline(readable, duplex, common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_PREMATURE_CLOSE'); +})); + +// Write one chunk of data, and destroy the stream later. +// That should trigger the pipeline destruction. +readable.push('foo'); +setImmediate(() => { + readable.destroy(); +}); diff --git a/test/parallel/test-stream-readable-async-iterators.js b/test/parallel/test-stream-readable-async-iterators.js index aca1e5bcc9d18d..13da0d9c4514af 100644 --- a/test/parallel/test-stream-readable-async-iterators.js +++ b/test/parallel/test-stream-readable-async-iterators.js @@ -14,7 +14,7 @@ async function tests() { AsyncIteratorPrototype); } - await (async function() { + { const readable = new Readable({ objectMode: true, read() {} }); readable.push(0); readable.push(1); @@ -25,9 +25,9 @@ async function tests() { for await (const d of iter) { assert.strictEqual(d, 1); } - })(); + } - await (async function() { + { console.log('read without for..await'); const max = 5; const readable = new Readable({ @@ -55,9 +55,9 @@ async function tests() { const last = await iter.next(); assert.strictEqual(last.done, true); - })(); + } - await (async function() { + { console.log('read without for..await deferred'); const readable = new Readable({ objectMode: true, @@ -95,9 +95,9 @@ async function tests() { const last = await iter.next(); assert.strictEqual(last.done, true); - })(); + } - await (async function() { + { console.log('read without for..await with errors'); const max = 3; const readable = new Readable({ @@ -133,9 +133,9 @@ async function tests() { }); readable.destroy(new Error('kaboom')); - })(); + } - await (async function() { + { console.log('call next() after error'); const readable = new Readable({ read() {} @@ -145,9 +145,9 @@ async function tests() { const err = new Error('kaboom'); readable.destroy(new Error('kaboom')); await assert.rejects(iterator.next.bind(iterator), err); - })(); + } - await (async function() { + { console.log('read object mode'); const max = 42; let readed = 0; @@ -168,9 +168,9 @@ async function tests() { } assert.strictEqual(readed, received); - })(); + } - await (async function() { + { console.log('destroy sync'); const readable = new Readable({ objectMode: true, @@ -187,9 +187,9 @@ async function tests() { err = e; } assert.strictEqual(err.message, 'kaboom from read'); - })(); + } - await (async function() { + { console.log('destroy async'); const readable = new Readable({ objectMode: true, @@ -219,9 +219,9 @@ async function tests() { assert.strictEqual(err.message, 'kaboom'); assert.strictEqual(received, 1); - })(); + } - await (async function() { + { console.log('destroyed by throw'); const readable = new Readable({ objectMode: true, @@ -242,9 +242,9 @@ async function tests() { assert.strictEqual(err.message, 'kaboom'); assert.strictEqual(readable.destroyed, true); - })(); + } - await (async function() { + { console.log('destroyed sync after push'); const readable = new Readable({ objectMode: true, @@ -268,9 +268,9 @@ async function tests() { assert.strictEqual(err.message, 'kaboom'); assert.strictEqual(received, 1); - })(); + } - await (async function() { + { console.log('push async'); const max = 42; let readed = 0; @@ -293,9 +293,9 @@ async function tests() { } assert.strictEqual(readed, received); - })(); + } - await (async function() { + { console.log('push binary async'); const max = 42; let readed = 0; @@ -323,9 +323,9 @@ async function tests() { } assert.strictEqual(data, expected); - })(); + } - await (async function() { + { console.log('.next() on destroyed stream'); const readable = new Readable({ read() { @@ -337,9 +337,9 @@ async function tests() { const { done } = await readable[Symbol.asyncIterator]().next(); assert.strictEqual(done, true); - })(); + } - await (async function() { + { console.log('.next() on pipelined stream'); const readable = new Readable({ read() { @@ -358,9 +358,9 @@ async function tests() { } catch (e) { assert.strictEqual(e, err); } - })(); + } - await (async () => { + { console.log('iterating on an ended stream completes'); const r = new Readable({ objectMode: true, @@ -376,9 +376,9 @@ async function tests() { // eslint-disable-next-line no-unused-vars for await (const b of r) { } - })(); + } - await (async () => { + { console.log('destroy mid-stream does not error'); const r = new Readable({ objectMode: true, @@ -392,9 +392,9 @@ async function tests() { for await (const a of r) { r.destroy(null); } - })(); + } - await (async () => { + { console.log('all next promises must be resolved on end'); const r = new Readable({ objectMode: true, @@ -408,9 +408,9 @@ async function tests() { r.push(null); assert.deepStrictEqual(await c, { done: true, value: undefined }); assert.deepStrictEqual(await d, { done: true, value: undefined }); - })(); + } - await (async () => { + { console.log('all next promises must be resolved on destroy'); const r = new Readable({ objectMode: true, @@ -424,9 +424,9 @@ async function tests() { r.destroy(); assert.deepStrictEqual(await c, { done: true, value: undefined }); assert.deepStrictEqual(await d, { done: true, value: undefined }); - })(); + } - await (async () => { + { console.log('all next promises must be resolved on destroy with error'); const r = new Readable({ objectMode: true, @@ -457,7 +457,7 @@ async function tests() { } assert.strictEqual(e, err); })()]); - })(); + } } // to avoid missing some tests if a promise does not resolve diff --git a/test/parallel/test-stream-readable-hwm-0-async.js b/test/parallel/test-stream-readable-hwm-0-async.js new file mode 100644 index 00000000000000..866b524893d530 --- /dev/null +++ b/test/parallel/test-stream-readable-hwm-0-async.js @@ -0,0 +1,27 @@ +'use strict'; + +const common = require('../common'); + +// This test ensures that Readable stream will continue to call _read +// for streams with highWaterMark === 0 once the stream returns data +// by calling push() asynchronously. + +const { Readable } = require('stream'); + +let count = 5; + +const r = new Readable({ + // Called 6 times: First 5 return data, last one signals end of stream. + read: common.mustCall(() => { + process.nextTick(common.mustCall(() => { + if (count--) + r.push('a'); + else + r.push(null); + })); + }, 6), + highWaterMark: 0, +}); + +r.on('end', common.mustCall()); +r.on('data', common.mustCall(5)); diff --git a/test/parallel/test-stream-readable-hwm-0-no-flow-data.js b/test/parallel/test-stream-readable-hwm-0-no-flow-data.js new file mode 100644 index 00000000000000..5f0186d720dd63 --- /dev/null +++ b/test/parallel/test-stream-readable-hwm-0-no-flow-data.js @@ -0,0 +1,104 @@ +'use strict'; + +const common = require('../common'); + +// Ensure that subscribing the 'data' event will not make the stream flow. +// The 'data' event will require calling read() by hand. +// +// The test is written for the (somewhat rare) highWaterMark: 0 streams to +// specifically catch any regressions that might occur with these streams. + +const assert = require('assert'); +const { Readable } = require('stream'); + +const streamData = [ 'a', null ]; + +// Track the calls so we can assert their order later. +const calls = []; +const r = new Readable({ + read: common.mustCall(() => { + calls.push('_read:' + streamData[0]); + process.nextTick(() => { + calls.push('push:' + streamData[0]); + r.push(streamData.shift()); + }); + }, streamData.length), + highWaterMark: 0, + + // Object mode is used here just for testing convenience. It really + // shouldn't affect the order of events. Just the data and its format. + objectMode: true, +}); + +assert.strictEqual(r.readableFlowing, null); +r.on('readable', common.mustCall(() => { + calls.push('readable'); +}, 2)); +assert.strictEqual(r.readableFlowing, false); +r.on('data', common.mustCall((data) => { + calls.push('data:' + data); +}, 1)); +r.on('end', common.mustCall(() => { + calls.push('end'); +})); +assert.strictEqual(r.readableFlowing, false); + +// The stream emits the events asynchronously but that's not guaranteed to +// happen on the next tick (especially since the _read implementation above +// uses process.nextTick). +// +// We use setImmediate here to give the stream enough time to emit all the +// events it's about to emit. +setImmediate(() => { + + // Only the _read, push, readable calls have happened. No data must be + // emitted yet. + assert.deepStrictEqual(calls, ['_read:a', 'push:a', 'readable']); + + // Calling 'r.read()' should trigger the data event. + assert.strictEqual(r.read(), 'a'); + assert.deepStrictEqual( + calls, + ['_read:a', 'push:a', 'readable', 'data:a']); + + // The next 'read()' will return null because hwm: 0 does not buffer any + // data and the _read implementation above does the push() asynchronously. + // + // Note: This 'null' signals "no data available". It isn't the end-of-stream + // null value as the stream doesn't know yet that it is about to reach the + // end. + // + // Using setImmediate again to give the stream enough time to emit all the + // events it wants to emit. + assert.strictEqual(r.read(), null); + setImmediate(() => { + + // There's a new 'readable' event after the data has been pushed. + // The 'end' event will be emitted only after a 'read()'. + // + // This is somewhat special for the case where the '_read' implementation + // calls 'push' asynchronously. If 'push' was synchronous, the 'end' event + // would be emitted here _before_ we call read(). + assert.deepStrictEqual( + calls, + ['_read:a', 'push:a', 'readable', 'data:a', + '_read:null', 'push:null', 'readable']); + + assert.strictEqual(r.read(), null); + + // While it isn't really specified whether the 'end' event should happen + // synchronously with read() or not, we'll assert the current behavior + // ('end' event happening on the next tick after read()) so any changes + // to it are noted and acknowledged in the future. + assert.deepStrictEqual( + calls, + ['_read:a', 'push:a', 'readable', 'data:a', + '_read:null', 'push:null', 'readable']); + process.nextTick(() => { + assert.deepStrictEqual( + calls, + ['_read:a', 'push:a', 'readable', 'data:a', + '_read:null', 'push:null', 'readable', 'end']); + }); + }); +}); diff --git a/test/parallel/test-stream-readable-hwm-0.js b/test/parallel/test-stream-readable-hwm-0.js index ecbc197d48208f..b66782b7713765 100644 --- a/test/parallel/test-stream-readable-hwm-0.js +++ b/test/parallel/test-stream-readable-hwm-0.js @@ -16,7 +16,7 @@ const r = new Readable({ }); let pushedNull = false; -// this will trigger read(0) but must only be called after push(null) +// This will trigger read(0) but must only be called after push(null) // because the we haven't pushed any data r.on('readable', common.mustCall(() => { assert.strictEqual(r.read(), null); diff --git a/test/parallel/test-stream-readable-reading-readingMore.js b/test/parallel/test-stream-readable-reading-readingMore.js index 71c07d7b062c18..74468ed68afc8e 100644 --- a/test/parallel/test-stream-readable-reading-readingMore.js +++ b/test/parallel/test-stream-readable-reading-readingMore.js @@ -143,7 +143,7 @@ const Readable = require('stream').Readable; readable.on('end', common.mustCall(onStreamEnd)); readable.push('pushed'); - // we are still not flowing, we will be resuming in the next tick + // We are still not flowing, we will be resuming in the next tick assert.strictEqual(state.flowing, false); // wait for nextTick, so the readableListener flag resets diff --git a/test/parallel/test-stream-unshift-read-race.js b/test/parallel/test-stream-unshift-read-race.js index f2977b285f4db3..69f966e05f4f36 100644 --- a/test/parallel/test-stream-unshift-read-race.js +++ b/test/parallel/test-stream-unshift-read-race.js @@ -106,7 +106,7 @@ r.on('readable', function() { }); w.on('finish', common.mustCall(function() { - // each chunk should start with 1234, and then be asfdasdfasdf... + // Each chunk should start with 1234, and then be asfdasdfasdf... // The first got pulled out before the first unshift('1234'), so it's // lacking that piece. assert.strictEqual(written[0], 'asdfasdfas'); diff --git a/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js b/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js index 86dd7aed1b1403..ca5d3dfb0f02bc 100644 --- a/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js +++ b/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js @@ -35,7 +35,7 @@ assert.strictEqual(writable._writableState.bufferedRequestCount, 1); process.nextTick(uncork); -// the second chunk is buffered, because we uncork at the end of tick +// The second chunk is buffered, because we uncork at the end of tick writable.write('second chunk'); assert.strictEqual(writable._writableState.corked, 1); assert.strictEqual(writable._writableState.bufferedRequestCount, 2); diff --git a/test/parallel/test-stream2-basic.js b/test/parallel/test-stream2-basic.js index 0083077fc2d649..f1e4fb02b4436c 100644 --- a/test/parallel/test-stream2-basic.js +++ b/test/parallel/test-stream2-basic.js @@ -40,7 +40,7 @@ class TestReader extends R { n = Math.max(n, 0); const toRead = Math.min(n, max); if (toRead === 0) { - // simulate the read buffer filling up with some more bytes some time + // Simulate the read buffer filling up with some more bytes some time // in the future. setTimeout(() => { this._pos = 0; diff --git a/test/parallel/test-stream2-push.js b/test/parallel/test-stream2-push.js index 33645df8a5541c..9d209c18b9f489 100644 --- a/test/parallel/test-stream2-push.js +++ b/test/parallel/test-stream2-push.js @@ -27,7 +27,7 @@ const { Readable, Writable } = require('stream'); const EE = require('events').EventEmitter; -// a mock thing a bit like the net.Socket/tcp_wrap.handle interaction +// A mock thing a bit like the net.Socket/tcp_wrap.handle interaction const stream = new Readable({ highWaterMark: 16, diff --git a/test/parallel/test-stream2-readable-empty-buffer-no-eof.js b/test/parallel/test-stream2-readable-empty-buffer-no-eof.js index 219a902c71fd56..f1e74ad949c590 100644 --- a/test/parallel/test-stream2-readable-empty-buffer-no-eof.js +++ b/test/parallel/test-stream2-readable-empty-buffer-no-eof.js @@ -31,7 +31,7 @@ test2(); function test1() { const r = new Readable(); - // should not end when we get a Buffer.alloc(0) or '' as the _read + // Should not end when we get a Buffer.alloc(0) or '' as the _read // result that just means that there is *temporarily* no data, but to // go ahead and try again later. // diff --git a/test/parallel/test-string-decoder-end.js b/test/parallel/test-string-decoder-end.js index c686b19b713d73..3dd445e6c7149b 100644 --- a/test/parallel/test-string-decoder-end.js +++ b/test/parallel/test-string-decoder-end.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -// verify that the string decoder works getting 1 byte at a time, +// Verify that the string decoder works getting 1 byte at a time, // the whole buffer at once, and that both match the .toString(enc) // result of the entire buffer. diff --git a/test/parallel/test-string-decoder.js b/test/parallel/test-string-decoder.js index c043795fc6ee5e..aaffa131cd8246 100644 --- a/test/parallel/test-string-decoder.js +++ b/test/parallel/test-string-decoder.js @@ -201,7 +201,7 @@ common.expectsError( } ); -// test verifies that StringDecoder will correctly decode the given input +// Test verifies that StringDecoder will correctly decode the given input // buffer with the given encoding to the expected output. It will attempt all // possible ways to write() the input buffer, see writeSequences(). The // singleSequence allows for easy debugging of a specific sequence which is diff --git a/test/parallel/test-timers-api-refs.js b/test/parallel/test-timers-api-refs.js index c062369444b1e0..3c55a05ac4c20a 100644 --- a/test/parallel/test-timers-api-refs.js +++ b/test/parallel/test-timers-api-refs.js @@ -2,7 +2,7 @@ const common = require('../common'); const timers = require('timers'); -// delete global APIs to make sure they're not relied on by the internal timers +// Delete global APIs to make sure they're not relied on by the internal timers // code delete global.setTimeout; delete global.clearTimeout; diff --git a/test/parallel/test-timers-ordering.js b/test/parallel/test-timers-ordering.js index e163ea55bf2dd8..1f2809ab4e1831 100644 --- a/test/parallel/test-timers-ordering.js +++ b/test/parallel/test-timers-ordering.js @@ -38,7 +38,7 @@ function f(i) { assert.strictEqual(i, last_i + 1, `order is broken: ${i} != ${last_i} + 1`); last_i = i; - // check that this iteration is fired at least 1ms later than the previous + // Check that this iteration is fired at least 1ms later than the previous const now = getLibuvNow(); assert(now >= last_ts + 1, `current ts ${now} < prev ts ${last_ts} + 1`); diff --git a/test/parallel/test-tls-client-auth.js b/test/parallel/test-tls-client-auth.js new file mode 100644 index 00000000000000..1f8c7e6096ff11 --- /dev/null +++ b/test/parallel/test-tls-client-auth.js @@ -0,0 +1,331 @@ +'use strict'; + +require('../common'); +const fixtures = require('../common/fixtures'); + +const { + assert, connect, keys +} = require(fixtures.path('tls-connect')); + +// Use ec10 and agent10, they are the only identities with intermediate CAs. +const client = keys.ec10; +const server = keys.agent10; + +// The certificates aren't for "localhost", so override the identity check. +function checkServerIdentity(hostname, cert) { + assert.strictEqual(hostname, 'localhost'); + assert.strictEqual(cert.subject.CN, 'agent10.example.com'); +} + +// Split out the single end-entity cert and the subordinate CA for later use. +split(client.cert, client); +split(server.cert, server); + +function split(file, into) { + const certs = /([^]*END CERTIFICATE-----\r?\n)(-----BEGIN[^]*)/.exec(file); + assert.strictEqual(certs.length, 3); + into.single = certs[1]; + into.subca = certs[2]; +} + +// Typical setup, nothing special, complete cert chains sent to peer. +connect({ + client: { + key: client.key, + cert: client.cert, + ca: server.ca, + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert, + ca: client.ca, + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.ifError(err); + return cleanup(); +}); + +// As above, but without requesting client's cert. +connect({ + client: { + ca: server.ca, + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert, + ca: client.ca, + }, +}, function(err, pair, cleanup) { + assert.ifError(err); + return cleanup(); +}); + +// Request cert from client that doesn't have one. +connect({ + client: { + ca: server.ca, + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert, + ca: client.ca, + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.strictEqual(err.code, 'ECONNRESET'); + return cleanup(); +}); + +// Typical configuration error, incomplete cert chains sent, we have to know the +// peer's subordinate CAs in order to verify the peer. +connect({ + client: { + key: client.key, + cert: client.single, + ca: [server.ca, server.subca], + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.single, + ca: [client.ca, client.subca], + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.ifError(err); + return cleanup(); +}); + +// Like above, but provide root CA and subordinate CA as multi-PEM. +connect({ + client: { + key: client.key, + cert: client.single, + ca: server.ca + '\n' + server.subca, + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.single, + ca: client.ca + '\n' + client.subca, + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.ifError(err); + return cleanup(); +}); + +// Like above, but provide multi-PEM in an array. +connect({ + client: { + key: client.key, + cert: client.single, + ca: [server.ca + '\n' + server.subca], + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.single, + ca: [client.ca + '\n' + client.subca], + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.ifError(err); + return cleanup(); +}); + +// Fail to complete server's chain +connect({ + client: { + ca: server.ca, + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.single, + }, +}, function(err, pair, cleanup) { + assert.strictEqual(err.code, 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'); + return cleanup(); +}); + +// Fail to complete client's chain. +connect({ + client: { + key: client.key, + cert: client.single, + ca: server.ca, + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert, + ca: client.ca, + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.ifError(pair.client.error); + assert.ifError(pair.server.error); + assert.strictEqual(err.code, 'ECONNRESET'); + return cleanup(); +}); + +// Fail to find CA for server. +connect({ + client: { + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert, + }, +}, function(err, pair, cleanup) { + assert.strictEqual(err.code, 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY'); + return cleanup(); +}); + +// Server sent their CA, but CA cannot be trusted if it is not locally known. +connect({ + client: { + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert + '\n' + server.ca, + }, +}, function(err, pair, cleanup) { + assert.strictEqual(err.code, 'SELF_SIGNED_CERT_IN_CHAIN'); + return cleanup(); +}); + +// Server sent their CA, wrongly, but its OK since we know the CA locally. +connect({ + client: { + checkServerIdentity, + ca: server.ca, + }, + server: { + key: server.key, + cert: server.cert + '\n' + server.ca, + }, +}, function(err, pair, cleanup) { + assert.ifError(err); + return cleanup(); +}); + +// Fail to complete client's chain. +connect({ + client: { + key: client.key, + cert: client.single, + ca: server.ca, + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert, + ca: client.ca, + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.strictEqual(err.code, 'ECONNRESET'); + return cleanup(); +}); + +// Fail to find CA for client. +connect({ + client: { + key: client.key, + cert: client.cert, + ca: server.ca, + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert, + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.strictEqual(err.code, 'ECONNRESET'); + return cleanup(); +}); + +// Confirm support for "BEGIN TRUSTED CERTIFICATE". +connect({ + client: { + key: client.key, + cert: client.cert, + ca: server.ca.replace(/CERTIFICATE/g, 'TRUSTED CERTIFICATE'), + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert, + ca: client.ca, + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.ifError(err); + return cleanup(); +}); + +// Confirm support for "BEGIN TRUSTED CERTIFICATE". +connect({ + client: { + key: client.key, + cert: client.cert, + ca: server.ca, + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert, + ca: client.ca.replace(/CERTIFICATE/g, 'TRUSTED CERTIFICATE'), + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.ifError(err); + return cleanup(); +}); + +// Confirm support for "BEGIN X509 CERTIFICATE". +connect({ + client: { + key: client.key, + cert: client.cert, + ca: server.ca.replace(/CERTIFICATE/g, 'X509 CERTIFICATE'), + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert, + ca: client.ca, + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.ifError(err); + return cleanup(); +}); + +// Confirm support for "BEGIN X509 CERTIFICATE". +connect({ + client: { + key: client.key, + cert: client.cert, + ca: server.ca, + checkServerIdentity, + }, + server: { + key: server.key, + cert: server.cert, + ca: client.ca.replace(/CERTIFICATE/g, 'X509 CERTIFICATE'), + requestCert: true, + }, +}, function(err, pair, cleanup) { + assert.ifError(err); + return cleanup(); +}); diff --git a/test/parallel/test-tls-securepair-fiftharg.js b/test/parallel/test-tls-securepair-fiftharg.js index 185dc43d941ca6..0651f98c6d780d 100644 --- a/test/parallel/test-tls-securepair-fiftharg.js +++ b/test/parallel/test-tls-securepair-fiftharg.js @@ -19,7 +19,7 @@ const pair = tls.createSecurePair(sslcontext, true, false, false, { }) }); -// captured traffic from browser's request to https://www.google.com +// Captured traffic from browser's request to https://www.google.com const sslHello = fixtures.readSync('google_ssl_hello.bin'); pair.encrypted.write(sslHello); diff --git a/test/parallel/test-tls-socket-snicallback-without-server.js b/test/parallel/test-tls-socket-snicallback-without-server.js index 9d30bc17b96b65..3ef28b95702552 100644 --- a/test/parallel/test-tls-socket-snicallback-without-server.js +++ b/test/parallel/test-tls-socket-snicallback-without-server.js @@ -20,7 +20,7 @@ new tls.TLSSocket(serverSide, { }) }); -// captured traffic from browser's request to https://www.google.com +// Captured traffic from browser's request to https://www.google.com const sslHello = fixtures.readSync('google_ssl_hello.bin'); clientSide.write(sslHello); diff --git a/test/parallel/test-trace-events-dynamic-enable.js b/test/parallel/test-trace-events-dynamic-enable.js index 645dcb2764a1be..b10152370f0116 100644 --- a/test/parallel/test-trace-events-dynamic-enable.js +++ b/test/parallel/test-trace-events-dynamic-enable.js @@ -28,8 +28,8 @@ async function test() { const events = []; let tracingComplete = false; session.on('NodeTracing.dataCollected', (n) => { - assert.ok(n && n.data && n.data.value); - events.push(...n.data.value); // append the events. + assert.ok(n && n.params && n.params.value); + events.push(...n.params.value); // append the events. }); session.on('NodeTracing.tracingComplete', () => tracingComplete = true); diff --git a/test/parallel/test-url-relative.js b/test/parallel/test-url-relative.js index d8532fcfee0ed6..6bead6a30d7007 100644 --- a/test/parallel/test-url-relative.js +++ b/test/parallel/test-url-relative.js @@ -234,7 +234,7 @@ const relativeTests2 = [ // may change to http:///s//a/../../../g ['../../../../g', bases[4], 'http:///g'], - // from Dan Connelly's tests in http://www.w3.org/2000/10/swap/uripath.py + // From Dan Connelly's tests in http://www.w3.org/2000/10/swap/uripath.py ['bar:abc', 'foo:xyz', 'bar:abc'], ['../abc', 'http://example/x/y/z', 'http://example/x/abc'], ['http://example/x/abc', 'http://example2/x/y/z', 'http://example/x/abc'], diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index c0fc3219ce736f..0d9cbdbe9d25fe 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -1738,19 +1738,34 @@ assert.strictEqual( ); } -// Manipulate the prototype to one that we can not handle. +// Manipulate the prototype in weird ways. { let obj = { a: true }; let value = (function() { return function() {}; })(); Object.setPrototypeOf(value, null); Object.setPrototypeOf(obj, value); - assert.strictEqual(util.inspect(obj), '{ a: true }'); + assert.strictEqual(util.inspect(obj), '<[Function]> { a: true }'); + assert.strictEqual( + util.inspect(obj, { colors: true }), + '<\u001b[36m[Function]\u001b[39m> { a: \u001b[33mtrue\u001b[39m }' + ); obj = { a: true }; value = []; Object.setPrototypeOf(value, null); Object.setPrototypeOf(obj, value); - assert.strictEqual(util.inspect(obj), '{ a: true }'); + assert.strictEqual( + util.inspect(obj), + '<[Array: null prototype] []> { a: true }' + ); + + function StorageObject() {} + StorageObject.prototype = Object.create(null); + assert.strictEqual( + util.inspect(new StorageObject()), + '<[Object: null prototype] {}> {}' + ); + } // Check that the fallback always works. @@ -1764,3 +1779,36 @@ assert.strictEqual( }); assert.strictEqual(util.inspect(obj), '[Set: null prototype] { 1, 2 }'); } + +// Check the getter option. +{ + let foo = 1; + const get = { get foo() { return foo; } }; + const getset = { + get foo() { return foo; }, + set foo(val) { foo = val; }, + get inc() { return ++foo; } + }; + const thrower = { get foo() { throw new Error('Oops'); } }; + assert.strictEqual( + inspect(get, { getters: true, colors: true }), + '{ foo: \u001b[36m[Getter:\u001b[39m ' + + '\u001b[33m1\u001b[39m\u001b[36m]\u001b[39m }'); + assert.strictEqual( + inspect(thrower, { getters: true }), + '{ foo: [Getter: ] }'); + assert.strictEqual( + inspect(getset, { getters: true }), + '{ foo: [Getter/Setter: 1], inc: [Getter: 2] }'); + assert.strictEqual( + inspect(getset, { getters: 'get' }), + '{ foo: [Getter/Setter], inc: [Getter: 3] }'); + assert.strictEqual( + inspect(getset, { getters: 'set' }), + '{ foo: [Getter/Setter: 3], inc: [Getter] }'); + getset.foo = new Set([[{ a: true }, 2, {}], 'foobar', { x: 1 }]); + assert.strictEqual( + inspect(getset, { getters: true }), + '{ foo: [Getter/Setter] Set { [ [Object], 2, {} ], ' + + "'foobar', { x: 1 } },\n inc: [Getter: NaN] }"); +} diff --git a/test/parallel/test-v8-coverage.js b/test/parallel/test-v8-coverage.js index 191835fe0f5af9..69a8286eed886d 100644 --- a/test/parallel/test-v8-coverage.js +++ b/test/parallel/test-v8-coverage.js @@ -16,7 +16,7 @@ function nextdir() { return `cov_${++dirc}`; } -// outputs coverage when event loop is drained, with no async logic. +// Outputs coverage when event loop is drained, with no async logic. { const coverageDirectory = path.join(tmpdir.path, nextdir()); const output = spawnSync(process.execPath, [ @@ -46,7 +46,7 @@ function nextdir() { assert.strictEqual(fixtureCoverage.functions[1].ranges[1].count, 0); } -// outputs coverage when process.kill(process.pid, "SIGINT"); exits process. +// Outputs coverage when process.kill(process.pid, "SIGINT"); exits process. { const coverageDirectory = path.join(tmpdir.path, nextdir()); const output = spawnSync(process.execPath, [ diff --git a/test/parallel/test-whatwg-encoding-textdecoder.js b/test/parallel/test-whatwg-encoding-textdecoder.js index e1d8575a644490..55afd34a02b11e 100644 --- a/test/parallel/test-whatwg-encoding-textdecoder.js +++ b/test/parallel/test-whatwg-encoding-textdecoder.js @@ -177,7 +177,7 @@ function testDecodeSample(encoding, string, bytes) { string); } -// z (ASCII U+007A), cent (Latin-1 U+00A2), CJK water (BMP U+6C34), +// `z` (ASCII U+007A), cent (Latin-1 U+00A2), CJK water (BMP U+6C34), // G-Clef (non-BMP U+1D11E), PUA (BMP U+F8FF), PUA (non-BMP U+10FFFD) // byte-swapped BOM (non-character U+FFFE) const sample = 'z\xA2\u6C34\uD834\uDD1E\uF8FF\uDBFF\uDFFD\uFFFE'; diff --git a/test/parallel/test-worker-message-port-drain.js b/test/parallel/test-worker-message-port-drain.js new file mode 100644 index 00000000000000..4fcb3da25e3f14 --- /dev/null +++ b/test/parallel/test-worker-message-port-drain.js @@ -0,0 +1,41 @@ +// Flags: --experimental-worker +'use strict'; +require('../common'); + +// This test ensures that the messages from the internal +// message port are drained before the call to 'kDispose', +// and so all the stdio messages from the worker are processed +// in the parent and are pushed to their target streams. + +const assert = require('assert'); +const { + Worker, + isMainThread, + parentPort, + threadId, +} = require('worker_threads'); + +if (isMainThread) { + const workerIdsToOutput = new Map(); + + for (let i = 0; i < 2; i++) { + const worker = new Worker(__filename, { stdout: true }); + const workerOutput = []; + workerIdsToOutput.set(worker.threadId, workerOutput); + worker.on('message', console.log); + worker.stdout.on('data', (chunk) => { + workerOutput.push(chunk.toString().trim()); + }); + } + + process.on('exit', () => { + for (const [threadId, workerOutput] of workerIdsToOutput) { + assert.ok(workerOutput.includes(`1 threadId: ${threadId}`)); + assert.ok(workerOutput.includes(`2 threadId: ${threadId}`)); + } + }); +} else { + console.log(`1 threadId: ${threadId}`); + console.log(`2 threadId: ${threadId}`); + parentPort.postMessage(Array(100).fill(1)); +} diff --git a/test/parallel/test-zlib-from-concatenated-gzip.js b/test/parallel/test-zlib-from-concatenated-gzip.js index c73a29e649765b..fea8ab6de2870a 100644 --- a/test/parallel/test-zlib-from-concatenated-gzip.js +++ b/test/parallel/test-zlib-from-concatenated-gzip.js @@ -39,7 +39,7 @@ zlib.unzip(Buffer.concat([ assert.strictEqual(result.toString(), abc); })); -// files that have the "right" magic bytes for starting a new gzip member +// Files that have the "right" magic bytes for starting a new gzip member // in the middle of themselves, even if they are part of a single // regularly compressed member const pmmFileZlib = fixtures.path('pseudo-multimember-gzip.z'); @@ -59,7 +59,7 @@ fs.createReadStream(pmmFileGz) assert.deepStrictEqual(Buffer.concat(pmmResultBuffers), pmmExpected); })); -// test that the next gzip member can wrap around the input buffer boundary +// Test that the next gzip member can wrap around the input buffer boundary [0, 1, 2, 3, 4, defEncoded.length].forEach((offset) => { const resultBuffers = []; diff --git a/test/parallel/test-zlib-from-gzip-with-trailing-garbage.js b/test/parallel/test-zlib-from-gzip-with-trailing-garbage.js index 48d9e441429eeb..c9eeb29f937c06 100644 --- a/test/parallel/test-zlib-from-gzip-with-trailing-garbage.js +++ b/test/parallel/test-zlib-from-gzip-with-trailing-garbage.js @@ -23,7 +23,7 @@ zlib.gunzip(data, common.mustCall((err, result) => { ); })); -// if the trailing garbage happens to look like a gzip header, it should +// If the trailing garbage happens to look like a gzip header, it should // throw an error. data = Buffer.concat([ zlib.gzipSync('abc'), diff --git a/test/parallel/test-zlib-from-gzip.js b/test/parallel/test-zlib-from-gzip.js index 99c3f1757e05d8..277df3c4cc2bc3 100644 --- a/test/parallel/test-zlib-from-gzip.js +++ b/test/parallel/test-zlib-from-gzip.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -// test unzipping a file that was created with a non-node gzip lib, +// Test unzipping a file that was created with a non-node gzip lib, // piped in as fast as possible. const common = require('../common'); diff --git a/test/pseudo-tty/testcfg.py b/test/pseudo-tty/testcfg.py index 9289ce4f10d33a..c12a16f8059e20 100644 --- a/test/pseudo-tty/testcfg.py +++ b/test/pseudo-tty/testcfg.py @@ -1,4 +1,3 @@ -from __future__ import print_function # Copyright 2008 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -26,12 +25,24 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from __future__ import print_function + import test import os from os.path import join, exists, basename, isdir import re import utils +try: + reduce # Python 2 +except NameError: # Python 3 + from functools import reduce + +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)") class TTYTestCase(test.TestCase): @@ -51,7 +62,7 @@ def IgnoreLine(self, str): else: return str.startswith('==') or str.startswith('**') def IsFailureOutput(self, output): - f = file(self.expected) + f = open(self.expected) # Convert output lines to regexps that we can match env = { 'basename': basename(self.file) } patterns = [ ] diff --git a/test/pummel/test-https-ci-reneg-attack.js b/test/pummel/test-https-ci-reneg-attack.js index 9411d24e077097..fad8cd992dd35d 100644 --- a/test/pummel/test-https-ci-reneg-attack.js +++ b/test/pummel/test-https-ci-reneg-attack.js @@ -72,7 +72,7 @@ function test(next) { child.stdout.resume(); child.stderr.resume(); - // count handshakes, start the attack after the initial handshake is done + // Count handshakes, start the attack after the initial handshake is done let handshakes = 0; let renegs = 0; diff --git a/test/pummel/test-timers.js b/test/pummel/test-timers.js index a6766b7a33c11d..6b761f455de20e 100644 --- a/test/pummel/test-timers.js +++ b/test/pummel/test-timers.js @@ -103,7 +103,7 @@ const interval4 = setInterval(function() { }, 0); -// we should be able to clearTimeout multiple times without breakage. +// We should be able to clearTimeout multiple times without breakage. let expectedTimeouts = 3; function t() { diff --git a/test/pummel/test-tls-ci-reneg-attack.js b/test/pummel/test-tls-ci-reneg-attack.js index 528ebe4516c71d..3509dcfd43f853 100644 --- a/test/pummel/test-tls-ci-reneg-attack.js +++ b/test/pummel/test-tls-ci-reneg-attack.js @@ -70,7 +70,7 @@ function test(next) { child.stdout.resume(); child.stderr.resume(); - // count handshakes, start the attack after the initial handshake is done + // Count handshakes, start the attack after the initial handshake is done let handshakes = 0; let renegs = 0; diff --git a/test/sequential/sequential.status b/test/sequential/sequential.status index 89f639777b5ca9..c4797734fb8603 100644 --- a/test/sequential/sequential.status +++ b/test/sequential/sequential.status @@ -7,6 +7,11 @@ prefix sequential [true] # This section applies to all platforms # https://github.com/nodejs/node/issues/22336 test-gc-http-client: PASS,FLAKY +# https://github.com/nodejs/node/issues/24403 +test-cli-syntax-bad: PASS,FLAKY +test-cli-syntax-file-not-found: PASS,FLAKY +test-cli-syntax-good: PASS,FLAKY +test-cli-syntax-require: PASS,FLAKY [$system==win32] # https://github.com/nodejs/node/issues/22327 @@ -21,7 +26,7 @@ test-http2-large-file: PASS, FLAKY [$system==freebsd] [$system==aix] +# https://github.com/nodejs/node/issues/24921 +test-child-process-execsync: PASS, FLAKY [$arch==arm] -# https://github.com/nodejs/node/issues/20628 -test-http2-session-timeout: PASS,FLAKY diff --git a/test/sequential/test-cli-syntax-bad.js b/test/sequential/test-cli-syntax-bad.js new file mode 100644 index 00000000000000..7c4c9c70d9097c --- /dev/null +++ b/test/sequential/test-cli-syntax-bad.js @@ -0,0 +1,48 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { exec } = require('child_process'); +const fixtures = require('../common/fixtures'); + +const node = process.execPath; + +// test both sets of arguments that check syntax +const syntaxArgs = [ + ['-c'], + ['--check'] +]; + +// Match on the name of the `Error` but not the message as it is different +// depending on the JavaScript engine. +const syntaxErrorRE = /^SyntaxError: \b/m; + +// test bad syntax with and without shebang +[ + 'syntax/bad_syntax.js', + 'syntax/bad_syntax', + 'syntax/bad_syntax_shebang.js', + 'syntax/bad_syntax_shebang' +].forEach(function(file) { + file = fixtures.path(file); + + // loop each possible option, `-c` or `--check` + syntaxArgs.forEach(function(args) { + const _args = args.concat(file); + const cmd = [node, ..._args].join(' '); + exec(cmd, common.mustCall((err, stdout, stderr) => { + assert.strictEqual(err instanceof Error, true); + assert.strictEqual(err.code, 1, + `code ${err.code} !== 1 for error:\n\n${err}`); + + // no stdout should be produced + assert.strictEqual(stdout, ''); + + // stderr should have a syntax error message + assert(syntaxErrorRE.test(stderr), `${syntaxErrorRE} === ${stderr}`); + + // stderr should include the filename + assert(stderr.startsWith(file), `${stderr} starts with ${file}`); + })); + }); +}); diff --git a/test/sequential/test-cli-syntax-file-not-found.js b/test/sequential/test-cli-syntax-file-not-found.js new file mode 100644 index 00000000000000..b90033a3966573 --- /dev/null +++ b/test/sequential/test-cli-syntax-file-not-found.js @@ -0,0 +1,40 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { exec } = require('child_process'); +const fixtures = require('../common/fixtures'); + +const node = process.execPath; + +// test both sets of arguments that check syntax +const syntaxArgs = [ + ['-c'], + ['--check'] +]; + +const notFoundRE = /^Error: Cannot find module/m; + +// test file not found +[ + 'syntax/file_not_found.js', + 'syntax/file_not_found' +].forEach(function(file) { + file = fixtures.path(file); + + // loop each possible option, `-c` or `--check` + syntaxArgs.forEach(function(args) { + const _args = args.concat(file); + const cmd = [node, ..._args].join(' '); + exec(cmd, common.mustCall((err, stdout, stderr) => { + // no stdout should be produced + assert.strictEqual(stdout, ''); + + // stderr should have a module not found error message + assert(notFoundRE.test(stderr), `${notFoundRE} === ${stderr}`); + + assert.strictEqual(err.code, 1, + `code ${err.code} !== 1 for error:\n\n${err}`); + })); + }); +}); diff --git a/test/sequential/test-cli-syntax-good.js b/test/sequential/test-cli-syntax-good.js new file mode 100644 index 00000000000000..1c2b3cbe55db80 --- /dev/null +++ b/test/sequential/test-cli-syntax-good.js @@ -0,0 +1,43 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { exec } = require('child_process'); +const fixtures = require('../common/fixtures'); + +const node = process.execPath; + +// test both sets of arguments that check syntax +const syntaxArgs = [ + ['-c'], + ['--check'] +]; + +// test good syntax with and without shebang +[ + 'syntax/good_syntax.js', + 'syntax/good_syntax', + 'syntax/good_syntax_shebang.js', + 'syntax/good_syntax_shebang', + 'syntax/illegal_if_not_wrapped.js' +].forEach(function(file) { + file = fixtures.path(file); + + // loop each possible option, `-c` or `--check` + syntaxArgs.forEach(function(args) { + const _args = args.concat(file); + + const cmd = [node, ..._args].join(' '); + exec(cmd, common.mustCall((err, stdout, stderr) => { + if (err) { + console.log('-- stdout --'); + console.log(stdout); + console.log('-- stderr --'); + console.log(stderr); + } + assert.ifError(err); + assert.strictEqual(stdout, ''); + assert.strictEqual(stderr, ''); + })); + }); +}); diff --git a/test/sequential/test-cli-syntax-require.js b/test/sequential/test-cli-syntax-require.js new file mode 100644 index 00000000000000..d99dc2ff71a9f1 --- /dev/null +++ b/test/sequential/test-cli-syntax-require.js @@ -0,0 +1,36 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { exec } = require('child_process'); +const fixtures = require('../common/fixtures'); + +const node = process.execPath; + +// Match on the name of the `Error` but not the message as it is different +// depending on the JavaScript engine. +const syntaxErrorRE = /^SyntaxError: \b/m; + +// should work with -r flags +['-c', '--check'].forEach(function(checkFlag) { + ['-r', '--require'].forEach(function(requireFlag) { + const preloadFile = fixtures.path('no-wrapper.js'); + const file = fixtures.path('syntax', 'illegal_if_not_wrapped.js'); + const args = [requireFlag, preloadFile, checkFlag, file]; + const cmd = [node, ...args].join(' '); + exec(cmd, common.mustCall((err, stdout, stderr) => { + assert.strictEqual(err instanceof Error, true); + assert.strictEqual(err.code, 1, + `code ${err.code} !== 1 for error:\n\n${err}`); + + // no stdout should be produced + assert.strictEqual(stdout, ''); + + // stderr should have a syntax error message + assert(syntaxErrorRE.test(stderr), `${syntaxErrorRE} === ${stderr}`); + + // stderr should include the filename + assert(stderr.startsWith(file), `${stderr} starts with ${file}`); + })); + }); +}); diff --git a/test/sequential/test-http-max-http-headers.js b/test/sequential/test-http-max-http-headers.js index 1dece8beed2f68..64358e8140f9a3 100644 --- a/test/sequential/test-http-max-http-headers.js +++ b/test/sequential/test-http-max-http-headers.js @@ -27,8 +27,8 @@ function finished(client, callback) { } function fillHeaders(headers, currentSize, valid = false) { - // llhttp counts actual header name/value sizes, excluding the whitespace and - // stripped chars. + // `llhttp` counts actual header name/value sizes, excluding the whitespace + // and stripped chars. if (getOptionValue('--http-parser') === 'llhttp') { // OK, Content-Length, 0, X-CRASH, aaa... headers += 'a'.repeat(MAX - currentSize); diff --git a/test/sequential/test-init.js b/test/sequential/test-init.js index 1b1b09ee833191..a86a1fd045f48c 100644 --- a/test/sequential/test-init.js +++ b/test/sequential/test-init.js @@ -43,7 +43,7 @@ function test(file, expected) { } { - // change CWD as we do this test so it's not dependent on current CWD + // Change CWD as we do this test so it's not dependent on current CWD // being in the test folder process.chdir(__dirname); test('test-init', 'Loaded successfully!'); @@ -57,7 +57,7 @@ function test(file, expected) { } { - // ensures that `node fs` does not mistakenly load the native 'fs' module + // Ensures that `node fs` does not mistakenly load the native 'fs' module // instead of the desired file and that the fs module loads as // expected in node process.chdir(fixtures.path('test-init-native')); diff --git a/test/sequential/test-inspector.js b/test/sequential/test-inspector.js index 00fdb000e9e251..237b65193fa86e 100644 --- a/test/sequential/test-inspector.js +++ b/test/sequential/test-inspector.js @@ -171,7 +171,7 @@ async function testCommandLineAPI(session) { const printBModulePath = require.resolve('../fixtures/printB.js'); const printBModuleStr = JSON.stringify(printBModulePath); - // we can use `require` outside of a callframe with require in scope + // We can use `require` outside of a callframe with require in scope let result = await session.send( { 'method': 'Runtime.evaluate', 'params': { @@ -182,7 +182,7 @@ async function testCommandLineAPI(session) { checkException(result); assert.strictEqual(result.result.value, true); - // the global require has the same properties as a normal `require` + // The global require has the same properties as a normal `require` result = await session.send( { 'method': 'Runtime.evaluate', 'params': { @@ -273,7 +273,7 @@ async function testCommandLineAPI(session) { parentsEqual: true, parentId: '' }); - // the `require` in the module shadows the command line API's `require` + // The `require` in the module shadows the command line API's `require` result = await session.send( { 'method': 'Debugger.evaluateOnCallFrame', 'params': { diff --git a/test/testpy/__init__.py b/test/testpy/__init__.py index 7ba9674d7d6e57..7d23c47214eedb 100644 --- a/test/testpy/__init__.py +++ b/test/testpy/__init__.py @@ -31,6 +31,11 @@ import re import ast +try: + reduce +except NameError: + from functools import reduce + FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)") FILES_PATTERN = re.compile(r"//\s+Files:(.*)") diff --git a/test/wpt/README.md b/test/wpt/README.md index 1810a98c8dc982..ff9092e6a1acd9 100644 --- a/test/wpt/README.md +++ b/test/wpt/README.md @@ -40,7 +40,7 @@ $ git node wpt url ### 3. Create the test driver -For example, for the URL tests, add a file `test/wpt/test-whatwg-url.js`: +For example, for the URL tests, add a file `test/wpt/test-url.js`: ```js 'use strict'; @@ -75,14 +75,14 @@ Run the test using `tools/test.py` and see if there are any failures. For example, to run all the URL tests under `test/fixtures/wpt/url`: ```text -$ tools/test.py wpt/test-whatwg-url +$ tools/test.py wpt/test-url ``` To run a specific test in WPT, for example, `url/url-searchparams.any.js`, pass the file name as argument to the corresponding test driver: ```text -node --expose-internals test/wpt/test-whatwg-url.js url-searchparams.any.js +node --expose-internals test/wpt/test-url.js url-searchparams.any.js ``` If there are any failures, update the corresponding status file diff --git a/test/wpt/test-whatwg-console.js b/test/wpt/test-console.js similarity index 100% rename from test/wpt/test-whatwg-console.js rename to test/wpt/test-console.js diff --git a/test/wpt/test-whatwg-url.js b/test/wpt/test-url.js similarity index 100% rename from test/wpt/test-whatwg-url.js rename to test/wpt/test-url.js diff --git a/tools/compress_json.py b/tools/compress_json.py index 34dbb878c48a27..b52c5d7a252cf6 100644 --- a/tools/compress_json.py +++ b/tools/compress_json.py @@ -5,6 +5,12 @@ import sys import zlib +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + + if __name__ == '__main__': fp = open(sys.argv[1]) obj = json.load(fp) diff --git a/tools/dcheck_macros.py b/tools/dcheck_macros.py index acc68fadb01abe..f22c08598fd694 100644 --- a/tools/dcheck_macros.py +++ b/tools/dcheck_macros.py @@ -1,3 +1,5 @@ +# flake8: noqa + macro DCHECK(x) = do { if (!(x)) (process._rawDebug("DCHECK: x == true"), process.abort()) } while (0); macro DCHECK_EQ(a, b) = DCHECK((a) === (b)); macro DCHECK_GE(a, b) = DCHECK((a) >= (b)); diff --git a/tools/eslint-rules/required-modules.js b/tools/eslint-rules/required-modules.js index 948c46c036d99d..208e13ffe74fc2 100644 --- a/tools/eslint-rules/required-modules.js +++ b/tools/eslint-rules/required-modules.js @@ -17,7 +17,7 @@ module.exports = function(context) { const foundModules = []; - // if no modules are required we don't need to check the CallExpressions + // If no modules are required we don't need to check the CallExpressions if (requiredModules.length === 0) { return {}; } diff --git a/tools/genv8constants.py b/tools/genv8constants.py index 0f56857700c403..8ab2ed8bae50c0 100755 --- a/tools/genv8constants.py +++ b/tools/genv8constants.py @@ -15,13 +15,13 @@ if len(sys.argv) != 3: print("usage: objsym.py outfile libv8_base.a") - sys.exit(2); + sys.exit(2) -outfile = file(sys.argv[1], 'w'); +outfile = open(sys.argv[1], 'w') try: pipe = subprocess.Popen([ 'objdump', '-z', '-D', sys.argv[2] ], - bufsize=-1, stdout=subprocess.PIPE).stdout; -except OSError, e: + bufsize=-1, stdout=subprocess.PIPE).stdout +except OSError as e: if e.errno == errno.ENOENT: print(''' Node.js compile error: could not find objdump @@ -33,9 +33,9 @@ sys.exit() -pattern = re.compile('([0-9a-fA-F]{8}|[0-9a-fA-F]{16}) <(.*)>:'); +pattern = re.compile('([0-9a-fA-F]{8}|[0-9a-fA-F]{16}) <(.*)>:') v8dbg = re.compile('^v8dbg.*$') -numpattern = re.compile('^[0-9a-fA-F]{2} $'); +numpattern = re.compile('^[0-9a-fA-F]{2} $') octets = 4 outfile.write(""" @@ -49,28 +49,28 @@ #ifndef V8_CONSTANTS_H #define V8_CONSTANTS_H -"""); +""") -curr_sym = None; -curr_val = 0; -curr_octet = 0; +curr_sym = None +curr_val = 0 +curr_octet = 0 def out_reset(): global curr_sym, curr_val, curr_octet - curr_sym = None; - curr_val = 0; - curr_octet = 0; + curr_sym = None + curr_val = 0 + curr_octet = 0 def out_define(): global curr_sym, curr_val, curr_octet, outfile, octets if curr_sym != None: - wrapped_val = curr_val & 0xffffffff; + wrapped_val = curr_val & 0xffffffff if curr_val & 0x80000000 != 0: - wrapped_val = 0x100000000 - wrapped_val; - outfile.write("#define %s -0x%x\n" % (curr_sym.upper(), wrapped_val)); + wrapped_val = 0x100000000 - wrapped_val + outfile.write("#define %s -0x%x\n" % (curr_sym.upper(), wrapped_val)) else: - outfile.write("#define %s 0x%x\n" % (curr_sym.upper(), wrapped_val)); - out_reset(); + outfile.write("#define %s 0x%x\n" % (curr_sym.upper(), wrapped_val)) + out_reset() for line in pipe: if curr_sym != None: @@ -81,35 +81,35 @@ def out_define(): # much like hex numbers (e.g., "adc"), and we don't want to risk picking # those up by mistake, so we look at character-based columns instead. # - for i in range (0, 3): + for i in range(0, 3): # 6-character margin, 2-characters + 1 space for each field - idx = 6 + i * 3; + idx = 6 + i * 3 octetstr = line[idx:idx+3] if curr_octet > octets: - break; + break if not numpattern.match(octetstr): - break; + break - curr_val += int('0x%s' % octetstr, 16) << (curr_octet * 8); - curr_octet += 1; + curr_val += int('0x%s' % octetstr, 16) << (curr_octet * 8) + curr_octet += 1 match = pattern.match(line) if match == None: - continue; + continue # Print previous symbol - out_define(); + out_define() - v8match = v8dbg.match(match.group(2)); + v8match = v8dbg.match(match.group(2)) if v8match != None: - out_reset(); - curr_sym = match.group(2); + out_reset() + curr_sym = match.group(2) # Print last symbol -out_define(); +out_define() outfile.write(""" #endif /* V8_CONSTANTS_H */ -"""); +""") diff --git a/tools/icu/icutrim.py b/tools/icu/icutrim.py index 2b771cb641ec37..116af32e0220a8 100755 --- a/tools/icu/icutrim.py +++ b/tools/icu/icutrim.py @@ -12,16 +12,25 @@ # Use "-h" to get help options. from __future__ import print_function -import sys -import shutil -# for utf-8 -reload(sys) -sys.setdefaultencoding("utf-8") +import json import optparse import os -import json import re +import shutil +import sys + +try: + # for utf-8 on Python 2 + reload(sys) + sys.setdefaultencoding("utf-8") +except NameError: + pass # Python 3 already defaults to utf-8 + +try: + basestring # Python 2 +except NameError: + basestring = str # Python 3 endian=sys.byteorder @@ -214,7 +223,7 @@ def queueForRemoval(tree): if(options.verbose>0): print("* %s: %d items" % (tree, len(mytree["locs"]))) # do varible substitution for this tree here - if type(config["trees"][tree]) == str or type(config["trees"][tree]) == unicode: + if isinstance(config["trees"][tree], basestring): treeStr = config["trees"][tree] if(options.verbose>5): print(" Substituting $%s for tree %s" % (treeStr, tree)) diff --git a/tools/js2c.py b/tools/js2c.py index e01e385afcf75c..e9a52047739adf 100755 --- a/tools/js2c.py +++ b/tools/js2c.py @@ -37,6 +37,11 @@ import string import hashlib +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + def ToCArray(elements, step=10): slices = (elements[i:i+step] for i in xrange(0, len(elements), step)) diff --git a/tools/nodcheck_macros.py b/tools/nodcheck_macros.py index 7bd2f209f511fc..0a59001b549fe5 100644 --- a/tools/nodcheck_macros.py +++ b/tools/nodcheck_macros.py @@ -1,3 +1,5 @@ +# flake8: noqa + macro DCHECK(x) = void(x); macro DCHECK_EQ(a, b) = void(a, b); macro DCHECK_GE(a, b) = void(a, b); diff --git a/tools/node_modules/eslint/README.md b/tools/node_modules/eslint/README.md index 572cd8a07af831..65ee43400d729f 100644 --- a/tools/node_modules/eslint/README.md +++ b/tools/node_modules/eslint/README.md @@ -38,7 +38,7 @@ If you want to include ESLint as part of your project's build system, we recomme $ npm install eslint --save-dev ``` -You should then setup a configuration file: +You should then set up a configuration file: ``` $ ./node_modules/.bin/eslint --init @@ -60,7 +60,7 @@ If you want to make ESLint available to tools that run across all of your projec $ npm install -g eslint ``` -You should then setup a configuration file: +You should then set up a configuration file: ``` $ eslint --init diff --git a/tools/node_modules/eslint/lib/cli-engine.js b/tools/node_modules/eslint/lib/cli-engine.js index 652d68b59b4953..ce9fe289b8c626 100644 --- a/tools/node_modules/eslint/lib/cli-engine.js +++ b/tools/node_modules/eslint/lib/cli-engine.js @@ -20,7 +20,7 @@ const fs = require("fs"), defaultOptions = require("../conf/default-cli-options"), Linter = require("./linter"), lodash = require("lodash"), - IgnoredPaths = require("./ignored-paths"), + IgnoredPaths = require("./util/ignored-paths"), Config = require("./config"), ConfigOps = require("./config/config-ops"), LintResultCache = require("./util/lint-result-cache"), diff --git a/tools/node_modules/eslint/lib/config.js b/tools/node_modules/eslint/lib/config.js index 8ea9aeb6f377b9..abcb38b50d5338 100644 --- a/tools/node_modules/eslint/lib/config.js +++ b/tools/node_modules/eslint/lib/config.js @@ -15,8 +15,7 @@ const path = require("path"), ConfigFile = require("./config/config-file"), ConfigCache = require("./config/config-cache"), Plugins = require("./config/plugins"), - FileFinder = require("./util/file-finder"), - isResolvable = require("is-resolvable"); + FileFinder = require("./util/file-finder"); const debug = require("debug")("eslint:config"); @@ -41,6 +40,20 @@ function hasRules(options) { return options.rules && Object.keys(options.rules).length > 0; } +/** + * Determines if a module is can be resolved. + * @param {string} moduleId The ID (name) of the module + * @returns {boolean} True if it is resolvable; False otherwise. + */ +function isResolvable(moduleId) { + try { + require.resolve(moduleId); + return true; + } catch (err) { + return false; + } +} + //------------------------------------------------------------------------------ // API //------------------------------------------------------------------------------ diff --git a/tools/node_modules/eslint/lib/config/autoconfig.js b/tools/node_modules/eslint/lib/config/autoconfig.js index 8536fdc55ad733..f2c707be843876 100644 --- a/tools/node_modules/eslint/lib/config/autoconfig.js +++ b/tools/node_modules/eslint/lib/config/autoconfig.js @@ -102,7 +102,6 @@ class Registry { * * The length of the returned array will be <= MAX_CONFIG_COMBINATIONS. * - * @param {Object} registry The autoconfig registry * @returns {Object[]} "rules" configurations to use for linting */ buildRuleSets() { diff --git a/tools/node_modules/eslint/lib/config/config-rule.js b/tools/node_modules/eslint/lib/config/config-rule.js index 27d29446dbb39c..e4221406df12c5 100644 --- a/tools/node_modules/eslint/lib/config/config-rule.js +++ b/tools/node_modules/eslint/lib/config/config-rule.js @@ -37,9 +37,9 @@ function explodeArray(xs) { * For example: * combineArrays([a, [b, c]], [x, y]); // -> [[a, x], [a, y], [b, c, x], [b, c, y]] * - * @param {array} arr1 The first array to combine. - * @param {array} arr2 The second array to combine. - * @returns {array} A mixture of the elements of the first and second arrays. + * @param {Array} arr1 The first array to combine. + * @param {Array} arr2 The second array to combine. + * @returns {Array} A mixture of the elements of the first and second arrays. */ function combineArrays(arr1, arr2) { const res = []; @@ -268,7 +268,7 @@ class RuleConfigSet { /** * Generate valid rule configurations based on a schema object * @param {Object} schema A rule's schema object - * @returns {array[]} Valid rule configurations + * @returns {Array[]} Valid rule configurations */ function generateConfigsFromSchema(schema) { const configSet = new RuleConfigSet(); diff --git a/tools/node_modules/eslint/lib/config/config-validator.js b/tools/node_modules/eslint/lib/config/config-validator.js index 6b151f46a496cc..0c63b68f76c943 100644 --- a/tools/node_modules/eslint/lib/config/config-validator.js +++ b/tools/node_modules/eslint/lib/config/config-validator.js @@ -83,7 +83,7 @@ function validateRuleSeverity(options) { /** * Validates the non-severity options passed to a rule, based on its schema. * @param {{create: Function}} rule The rule to validate - * @param {array} localOptions The options for the rule, excluding severity + * @param {Array} localOptions The options for the rule, excluding severity * @returns {void} */ function validateRuleSchema(rule, localOptions) { @@ -111,7 +111,7 @@ function validateRuleSchema(rule, localOptions) { * Validates a rule's options against its schema. * @param {{create: Function}|null} rule The rule that the config is being validated for * @param {string} ruleId The rule's unique name. - * @param {array|number} options The given options for the rule. + * @param {Array|number} options The given options for the rule. * @param {string|null} source The name of the configuration source to report in any errors. If null or undefined, * no source is prepended to the message. * @returns {void} diff --git a/tools/node_modules/eslint/lib/linter.js b/tools/node_modules/eslint/lib/linter.js index b47e6eb1fcfb6a..d6d635f9f47d79 100644 --- a/tools/node_modules/eslint/lib/linter.js +++ b/tools/node_modules/eslint/lib/linter.js @@ -11,7 +11,6 @@ const eslintScope = require("eslint-scope"), evk = require("eslint-visitor-keys"), - levn = require("levn"), lodash = require("lodash"), CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"), ConfigOps = require("./config/config-ops"), @@ -22,9 +21,10 @@ const eslintScope = require("eslint-scope"), NodeEventGenerator = require("./util/node-event-generator"), SourceCode = require("./util/source-code"), Traverser = require("./util/traverser"), - createReportTranslator = require("./report-translator"), + createReportTranslator = require("./util/report-translator"), Rules = require("./rules"), timing = require("./util/timing"), + ConfigCommentParser = require("./util/config-comment-parser"), astUtils = require("./util/ast-utils"), pkg = require("../package.json"), SourceCodeFixer = require("./util/source-code-fixer"); @@ -32,6 +32,7 @@ const eslintScope = require("eslint-scope"), const debug = require("debug")("eslint:linter"); const MAX_AUTOFIX_PASSES = 10; const DEFAULT_PARSER_NAME = "espree"; +const commentParser = new ConfigCommentParser(); //------------------------------------------------------------------------------ // Typedefs @@ -59,117 +60,6 @@ const DEFAULT_PARSER_NAME = "espree"; // Helpers //------------------------------------------------------------------------------ -/** - * Parses a list of "name:boolean_value" or/and "name" options divided by comma or - * whitespace. - * @param {string} string The string to parse. - * @param {Comment} comment The comment node which has the string. - * @returns {Object} Result map object of names and boolean values - */ -function parseBooleanConfig(string, comment) { - const items = {}; - - // Collapse whitespace around `:` and `,` to make parsing easier - const trimmedString = string.replace(/\s*([:,])\s*/g, "$1"); - - trimmedString.split(/\s|,+/).forEach(name => { - if (!name) { - return; - } - const pos = name.indexOf(":"); - - if (pos === -1) { - items[name] = { - value: false, - comment - }; - } else { - items[name.slice(0, pos)] = { - value: name.slice(pos + 1) === "true", - comment - }; - } - }); - return items; -} - -/** - * Parses a JSON-like config. - * @param {string} string The string to parse. - * @param {Object} location Start line and column of comments for potential error message. - * @returns {({success: true, config: Object}|{success: false, error: Problem})} Result map object - */ -function parseJsonConfig(string, location) { - let items = {}; - - // Parses a JSON-like comment by the same way as parsing CLI option. - try { - items = levn.parse("Object", string) || {}; - - // Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`. - // Also, commaless notations have invalid severity: - // "no-alert: 2 no-console: 2" --> {"no-alert": "2 no-console: 2"} - // Should ignore that case as well. - if (ConfigOps.isEverySeverityValid(items)) { - return { - success: true, - config: items - }; - } - } catch (ex) { - - // ignore to parse the string by a fallback. - } - - /* - * Optionator cannot parse commaless notations. - * But we are supporting that. So this is a fallback for that. - */ - items = {}; - const normalizedString = string.replace(/([a-zA-Z0-9\-/]+):/g, "\"$1\":").replace(/(]|[0-9])\s+(?=")/, "$1,"); - - try { - items = JSON.parse(`{${normalizedString}}`); - } catch (ex) { - return { - success: false, - error: { - ruleId: null, - fatal: true, - severity: 2, - message: `Failed to parse JSON from '${normalizedString}': ${ex.message}`, - line: location.start.line, - column: location.start.column + 1 - } - }; - - } - - return { - success: true, - config: items - }; -} - -/** - * Parses a config of values separated by comma. - * @param {string} string The string to parse. - * @returns {Object} Result map of values and true values - */ -function parseListConfig(string) { - const items = {}; - - // Collapse whitespace around , - string.replace(/\s*,\s*/g, ",").split(/,+/).forEach(name => { - const trimmedName = name.trim(); - - if (trimmedName) { - items[trimmedName] = true; - } - }); - return items; -} - /** * Ensures that variables representing built-in properties of the Global Object, * and any globals declared by special block comments, are present in the global @@ -248,7 +138,7 @@ function addDeclaredGlobals(globalScope, configGlobals, commentDirectives) { * @returns {DisableDirective[]} Directives from the comment */ function createDisableDirectives(type, loc, value) { - const ruleIds = Object.keys(parseListConfig(value)); + const ruleIds = Object.keys(commentParser.parseListConfig(value)); const directiveRules = ruleIds.length ? ruleIds : [null]; return directiveRules.map(ruleId => ({ type, line: loc.line, column: loc.column + 1, ruleId })); @@ -301,12 +191,12 @@ function getDirectiveComments(filename, ast, ruleMapper) { } else if (comment.type === "Block") { switch (match[1]) { case "exported": - Object.assign(exportedVariables, parseBooleanConfig(directiveValue, comment)); + Object.assign(exportedVariables, commentParser.parseBooleanConfig(directiveValue, comment)); break; case "globals": case "global": - Object.assign(enabledGlobals, parseBooleanConfig(directiveValue, comment)); + Object.assign(enabledGlobals, commentParser.parseBooleanConfig(directiveValue, comment)); break; case "eslint-disable": @@ -318,7 +208,7 @@ function getDirectiveComments(filename, ast, ruleMapper) { break; case "eslint": { - const parseResult = parseJsonConfig(directiveValue, comment.loc); + const parseResult = commentParser.parseJsonConfig(directiveValue, comment.loc); if (parseResult.success) { Object.keys(parseResult.config).forEach(name => { @@ -398,7 +288,7 @@ function findEslintEnv(text) { eslintEnvPattern.lastIndex = 0; while ((match = eslintEnvPattern.exec(text))) { - retv = Object.assign(retv || {}, parseListConfig(match[1])); + retv = Object.assign(retv || {}, commentParser.parseListConfig(match[1])); } return retv; @@ -1032,8 +922,6 @@ module.exports = class Linter { * @param {(string|Object)} [filenameOrOptions] The optional filename of the file being checked. * If this is not set, the filename will default to '' in the rule context. If * an object, then it has "filename", "saveState", and "allowInlineConfig" properties. - * @param {boolean} [saveState] Indicates if the state from the last run should be saved. - * Mostly useful for testing purposes. * @param {boolean} [filenameOrOptions.allowInlineConfig] Allow/disallow inline comments' ability to change config once it is set. Defaults to true if not supplied. * Useful if you want to validate JS without comments overriding rules. * @param {function(string): string[]} [filenameOrOptions.preprocess] preprocessor for source text. If provided, diff --git a/tools/node_modules/eslint/lib/rules/array-element-newline.js b/tools/node_modules/eslint/lib/rules/array-element-newline.js index 440290917d39b0..dadb26fdd226de 100644 --- a/tools/node_modules/eslint/lib/rules/array-element-newline.js +++ b/tools/node_modules/eslint/lib/rules/array-element-newline.js @@ -173,7 +173,6 @@ module.exports = { * Reports a given node if it violated this rule. * * @param {ASTNode} node - A node to check. This is an ObjectExpression node or an ObjectPattern node. - * @param {{multiline: boolean, minItems: number}} options - An option object. * @returns {void} */ function check(node) { diff --git a/tools/node_modules/eslint/lib/rules/camelcase.js b/tools/node_modules/eslint/lib/rules/camelcase.js index 8aeb4b5bd0df92..6fb8760f105346 100644 --- a/tools/node_modules/eslint/lib/rules/camelcase.js +++ b/tools/node_modules/eslint/lib/rules/camelcase.js @@ -132,9 +132,10 @@ module.exports = { /* * Leading and trailing underscores are commonly used to flag - * private/protected identifiers, strip them + * private/protected identifiers, strip them before checking if underscored */ - const name = node.name.replace(/^_+|_+$/g, ""), + const name = node.name, + nameIsUnderscored = isUnderscored(name.replace(/^_+|_+$/g, "")), effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; // First, we ignore the node if it match the ignore list @@ -151,11 +152,11 @@ module.exports = { } // Always report underscored object names - if (node.parent.object.type === "Identifier" && node.parent.object.name === node.name && isUnderscored(name)) { + if (node.parent.object.type === "Identifier" && node.parent.object.name === node.name && nameIsUnderscored) { report(node); // Report AssignmentExpressions only if they are the left side of the assignment - } else if (effectiveParent.type === "AssignmentExpression" && isUnderscored(name) && (effectiveParent.right.type !== "MemberExpression" || effectiveParent.left.type === "MemberExpression" && effectiveParent.left.property.name === node.name)) { + } else if (effectiveParent.type === "AssignmentExpression" && nameIsUnderscored && (effectiveParent.right.type !== "MemberExpression" || effectiveParent.left.type === "MemberExpression" && effectiveParent.left.property.name === node.name)) { report(node); } @@ -167,7 +168,7 @@ module.exports = { } else if (node.parent.type === "Property" || node.parent.type === "AssignmentPattern") { if (node.parent.parent && node.parent.parent.type === "ObjectPattern") { - if (node.parent.shorthand && node.parent.value.left && isUnderscored(name)) { + if (node.parent.shorthand && node.parent.value.left && nameIsUnderscored) { report(node); } @@ -179,7 +180,7 @@ module.exports = { return; } - const valueIsUnderscored = node.parent.value.name && isUnderscored(name); + const valueIsUnderscored = node.parent.value.name && nameIsUnderscored; // ignore destructuring if the option is set, unless a new identifier is created if (valueIsUnderscored && !(assignmentKeyEqualsValue && ignoreDestructuring)) { @@ -193,7 +194,7 @@ module.exports = { } // don't check right hand side of AssignmentExpression to prevent duplicate warnings - if (isUnderscored(name) && !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && !(node.parent.right === node)) { + if (nameIsUnderscored && !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && !(node.parent.right === node)) { report(node); } @@ -201,12 +202,12 @@ module.exports = { } else if (["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"].indexOf(node.parent.type) >= 0) { // Report only if the local imported identifier is underscored - if (node.parent.local && node.parent.local.name === node.name && isUnderscored(name)) { + if (node.parent.local && node.parent.local.name === node.name && nameIsUnderscored) { report(node); } // Report anything that is underscored that isn't a CallExpression - } else if (isUnderscored(name) && !ALLOWED_PARENT_TYPES.has(effectiveParent.type)) { + } else if (nameIsUnderscored && !ALLOWED_PARENT_TYPES.has(effectiveParent.type)) { report(node); } } diff --git a/tools/node_modules/eslint/lib/rules/comma-style.js b/tools/node_modules/eslint/lib/rules/comma-style.js index 2586cf66e9226b..78438a858dbb12 100644 --- a/tools/node_modules/eslint/lib/rules/comma-style.js +++ b/tools/node_modules/eslint/lib/rules/comma-style.js @@ -85,7 +85,7 @@ module.exports = { function getReplacedText(styleType, text) { switch (styleType) { case "between": - return `,${text.replace("\n", "")}`; + return `,${text.replace(astUtils.LINEBREAK_MATCHER, "")}`; case "first": return `${text},`; @@ -138,6 +138,11 @@ module.exports = { } else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) && !astUtils.isTokenOnSameLine(previousItemToken, commaToken)) { + const comment = sourceCode.getCommentsAfter(commaToken)[0]; + const styleType = comment && comment.type === "Block" && astUtils.isTokenOnSameLine(commaToken, comment) + ? style + : "between"; + // lone comma context.report({ node: reportItem, @@ -146,7 +151,7 @@ module.exports = { column: commaToken.loc.start.column }, messageId: "unexpectedLineBeforeAndAfterComma", - fix: getFixerFunction("between", previousItemToken, commaToken, currentItemToken) + fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) }); } else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) { diff --git a/tools/node_modules/eslint/lib/rules/eqeqeq.js b/tools/node_modules/eslint/lib/rules/eqeqeq.js index 715c5ce7c027c7..3e8a392cf6983e 100644 --- a/tools/node_modules/eslint/lib/rules/eqeqeq.js +++ b/tools/node_modules/eslint/lib/rules/eqeqeq.js @@ -119,7 +119,6 @@ module.exports = { /** * Gets the location (line and column) of the binary expression's operator * @param {ASTNode} node The binary expression node to check - * @param {string} operator The operator to find * @returns {Object} { line, column } location of operator * @private */ diff --git a/tools/node_modules/eslint/lib/rules/handle-callback-err.js b/tools/node_modules/eslint/lib/rules/handle-callback-err.js index c62016d5895dcc..5845aff4bc636c 100644 --- a/tools/node_modules/eslint/lib/rules/handle-callback-err.js +++ b/tools/node_modules/eslint/lib/rules/handle-callback-err.js @@ -59,7 +59,7 @@ module.exports = { /** * Get the parameters of a given function scope. * @param {Object} scope The function scope. - * @returns {array} All parameters of the given scope. + * @returns {Array} All parameters of the given scope. */ function getParameters(scope) { return scope.variables.filter(variable => variable.defs[0] && variable.defs[0].type === "Parameter"); diff --git a/tools/node_modules/eslint/lib/rules/implicit-arrow-linebreak.js b/tools/node_modules/eslint/lib/rules/implicit-arrow-linebreak.js index cd729f8ad931ee..a883b2264714f2 100644 --- a/tools/node_modules/eslint/lib/rules/implicit-arrow-linebreak.js +++ b/tools/node_modules/eslint/lib/rules/implicit-arrow-linebreak.js @@ -44,7 +44,6 @@ module.exports = { /** * Validates the location of an arrow function body * @param {ASTNode} node The arrow function body - * @param {string} keywordName The applicable keyword name for the arrow function body * @returns {void} */ function validateExpression(node) { diff --git a/tools/node_modules/eslint/lib/rules/indent-legacy.js b/tools/node_modules/eslint/lib/rules/indent-legacy.js index 16687b521ed31a..cfb807e34e0ee3 100644 --- a/tools/node_modules/eslint/lib/rules/indent-legacy.js +++ b/tools/node_modules/eslint/lib/rules/indent-legacy.js @@ -300,7 +300,6 @@ module.exports = { * @param {int} gottenTabs Indentation tab count in the actual node/code * @param {Object=} loc Error line and column location * @param {boolean} isLastNodeCheck Is the error for last node check - * @param {int} lastNodeCheckEndOffset Number of charecters to skip from the end * @returns {void} */ function report(node, needed, gottenSpaces, gottenTabs, loc, isLastNodeCheck) { @@ -365,7 +364,6 @@ module.exports = { * Check indent for node * @param {ASTNode} node Node to check * @param {int} neededIndent needed indent - * @param {boolean} [excludeCommas=false] skip comma on start of line * @returns {void} */ function checkNodeIndent(node, neededIndent) { @@ -413,7 +411,6 @@ module.exports = { * Check indent for nodes list * @param {ASTNode[]} nodes list of node objects * @param {int} indent needed indent - * @param {boolean} [excludeCommas=false] skip comma on start of line * @returns {void} */ function checkNodesIndent(nodes, indent) { diff --git a/tools/node_modules/eslint/lib/rules/indent.js b/tools/node_modules/eslint/lib/rules/indent.js index dc9fbaf908b815..0b87412c8fcb6b 100644 --- a/tools/node_modules/eslint/lib/rules/indent.js +++ b/tools/node_modules/eslint/lib/rules/indent.js @@ -1229,9 +1229,13 @@ module.exports = { } const fromToken = sourceCode.getLastToken(node, token => token.type === "Identifier" && token.value === "from"); + const sourceToken = sourceCode.getLastToken(node, token => token.type === "String"); + const semiToken = sourceCode.getLastToken(node, token => token.type === "Punctuator" && token.value === ";"); if (fromToken) { - offsets.setDesiredOffsets([fromToken.range[0], node.range[1]], sourceCode.getFirstToken(node), 1); + const end = semiToken && semiToken.range[1] === sourceToken.range[1] ? node.range[1] : sourceToken.range[1]; + + offsets.setDesiredOffsets([fromToken.range[0], end], sourceCode.getFirstToken(node), 1); } }, diff --git a/tools/node_modules/eslint/lib/rules/keyword-spacing.js b/tools/node_modules/eslint/lib/rules/keyword-spacing.js index 66ce2cb34c0e2b..790d7b031d8ecd 100644 --- a/tools/node_modules/eslint/lib/rules/keyword-spacing.js +++ b/tools/node_modules/eslint/lib/rules/keyword-spacing.js @@ -453,6 +453,10 @@ module.exports = { checkSpacingBefore(firstToken, PREV_TOKEN_M); checkSpacingAfter(firstToken, NEXT_TOKEN_M); + if (node.type === "ExportDefaultDeclaration") { + checkSpacingAround(sourceCode.getTokenAfter(firstToken)); + } + if (node.source) { const fromToken = sourceCode.getTokenBefore(node.source); @@ -554,7 +558,7 @@ module.exports = { // Statements - Declarations ClassDeclaration: checkSpacingForClass, ExportNamedDeclaration: checkSpacingForModuleDeclaration, - ExportDefaultDeclaration: checkSpacingAroundFirstToken, + ExportDefaultDeclaration: checkSpacingForModuleDeclaration, ExportAllDeclaration: checkSpacingForModuleDeclaration, FunctionDeclaration: checkSpacingForFunction, ImportDeclaration: checkSpacingForModuleDeclaration, diff --git a/tools/node_modules/eslint/lib/rules/newline-before-return.js b/tools/node_modules/eslint/lib/rules/newline-before-return.js index 2743bf7a8bea34..6a0ec8d5eb731f 100644 --- a/tools/node_modules/eslint/lib/rules/newline-before-return.js +++ b/tools/node_modules/eslint/lib/rules/newline-before-return.js @@ -36,7 +36,7 @@ module.exports = { /** * Tests whether node is preceded by supplied tokens * @param {ASTNode} node - node to check - * @param {array} testTokens - array of tokens to test against + * @param {Array} testTokens - array of tokens to test against * @returns {boolean} Whether or not the node is preceded by one of the supplied tokens * @private */ diff --git a/tools/node_modules/eslint/lib/rules/no-constant-condition.js b/tools/node_modules/eslint/lib/rules/no-constant-condition.js index 88984c36e7f70f..8d7934d8a595ba 100644 --- a/tools/node_modules/eslint/lib/rules/no-constant-condition.js +++ b/tools/node_modules/eslint/lib/rules/no-constant-condition.js @@ -173,7 +173,6 @@ module.exports = { /** * Reports when the set still contains stored constant conditions - * @param {ASTNode} node The AST node to check. * @returns {void} * @private */ diff --git a/tools/node_modules/eslint/lib/rules/no-else-return.js b/tools/node_modules/eslint/lib/rules/no-else-return.js index eebdec76e0e7d4..5ba02de29136f8 100644 --- a/tools/node_modules/eslint/lib/rules/no-else-return.js +++ b/tools/node_modules/eslint/lib/rules/no-else-return.js @@ -183,7 +183,6 @@ module.exports = { * code paths. * * @param {Node} node The consequent or body node - * @param {Node} alternate The alternate node * @returns {boolean} `true` if it is a Return/If node that always returns. */ function checkForReturnOrIf(node) { diff --git a/tools/node_modules/eslint/lib/rules/no-implied-eval.js b/tools/node_modules/eslint/lib/rules/no-implied-eval.js index d31b5dfee8041f..afa24ab8efda75 100644 --- a/tools/node_modules/eslint/lib/rules/no-implied-eval.js +++ b/tools/node_modules/eslint/lib/rules/no-implied-eval.js @@ -38,7 +38,7 @@ module.exports = { /** * Get the last element of an array, without modifying arr, like pop(), but non-destructive. - * @param {array} arr What to inspect + * @param {Array} arr What to inspect * @returns {*} The last element of arr * @private */ diff --git a/tools/node_modules/eslint/lib/rules/no-restricted-imports.js b/tools/node_modules/eslint/lib/rules/no-restricted-imports.js index b8fcca1aaf8b6f..b8917ee9c563d1 100644 --- a/tools/node_modules/eslint/lib/rules/no-restricted-imports.js +++ b/tools/node_modules/eslint/lib/rules/no-restricted-imports.js @@ -195,7 +195,7 @@ module.exports = { /** * Check if the given importNames are restricted given a list of restrictedImportNames. * @param {Set.} importNames - Set of import names that are being imported - * @param {[string]} restrictedImportNames - array of import names that are restricted for this import + * @param {string[]} restrictedImportNames - array of import names that are restricted for this import * @returns {boolean} whether the objectName is restricted * @private */ diff --git a/tools/node_modules/eslint/lib/rules/no-this-before-super.js b/tools/node_modules/eslint/lib/rules/no-this-before-super.js index 93fb094e9bc139..bca379bf971b80 100644 --- a/tools/node_modules/eslint/lib/rules/no-this-before-super.js +++ b/tools/node_modules/eslint/lib/rules/no-this-before-super.js @@ -171,7 +171,6 @@ module.exports = { * invalid node. * * @param {CodePath} codePath - A code path which was ended. - * @param {ASTNode} node - The current node. * @returns {void} */ onCodePathEnd(codePath) { diff --git a/tools/node_modules/eslint/lib/rules/object-curly-newline.js b/tools/node_modules/eslint/lib/rules/object-curly-newline.js index c460ea56bc3128..d1a6bc20f6361e 100644 --- a/tools/node_modules/eslint/lib/rules/object-curly-newline.js +++ b/tools/node_modules/eslint/lib/rules/object-curly-newline.js @@ -172,7 +172,6 @@ module.exports = { /** * Reports a given node if it violated this rule. * @param {ASTNode} node - A node to check. This is an ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration node. - * @param {{multiline: boolean, minProperties: number, consistent: boolean}} options - An option object. * @returns {void} */ function check(node) { diff --git a/tools/node_modules/eslint/lib/rules/one-var.js b/tools/node_modules/eslint/lib/rules/one-var.js index 44f05fb700a0d6..0e9dff416588f7 100644 --- a/tools/node_modules/eslint/lib/rules/one-var.js +++ b/tools/node_modules/eslint/lib/rules/one-var.js @@ -310,7 +310,6 @@ module.exports = { /** * Fixer to split a VariableDeclaration into individual declarations * @param {VariableDeclaration} declaration The `VariableDeclaration` to split - * @param {?Function} filter Function to filter the declarations * @returns {Function} The fixer function */ function splitDeclarations(declaration) { diff --git a/tools/node_modules/eslint/lib/rules/padding-line-between-statements.js b/tools/node_modules/eslint/lib/rules/padding-line-between-statements.js index 3e55a2516d0156..c9995885442f2f 100644 --- a/tools/node_modules/eslint/lib/rules/padding-line-between-statements.js +++ b/tools/node_modules/eslint/lib/rules/padding-line-between-statements.js @@ -36,6 +36,36 @@ function newKeywordTester(keyword) { }; } +/** + * Creates tester which check if a node starts with specific keyword and spans a single line. + * + * @param {string} keyword The keyword to test. + * @returns {Object} the created tester. + * @private + */ +function newSinglelineKeywordTester(keyword) { + return { + test: (node, sourceCode) => + node.loc.start.line === node.loc.end.line && + sourceCode.getFirstToken(node).value === keyword + }; +} + +/** + * Creates tester which check if a node starts with specific keyword and spans multiple lines. + * + * @param {string} keyword The keyword to test. + * @returns {Object} the created tester. + * @private + */ +function newMultilineKeywordTester(keyword) { + return { + test: (node, sourceCode) => + node.loc.start.line !== node.loc.end.line && + sourceCode.getFirstToken(node).value === keyword + }; +} + /** * Creates tester which check if a node is specific type. * @@ -368,6 +398,13 @@ const StatementTypes = { !isDirectivePrologue(node, sourceCode) }, + "multiline-const": newMultilineKeywordTester("const"), + "multiline-let": newMultilineKeywordTester("let"), + "multiline-var": newMultilineKeywordTester("var"), + "singleline-const": newSinglelineKeywordTester("const"), + "singleline-let": newSinglelineKeywordTester("let"), + "singleline-var": newSinglelineKeywordTester("var"), + block: newNodeTypeTester("BlockStatement"), empty: newNodeTypeTester("EmptyStatement"), function: newNodeTypeTester("FunctionDeclaration"), diff --git a/tools/node_modules/eslint/lib/rules/quotes.js b/tools/node_modules/eslint/lib/rules/quotes.js index e0db17fcb7c45f..c3c077822462b8 100644 --- a/tools/node_modules/eslint/lib/rules/quotes.js +++ b/tools/node_modules/eslint/lib/rules/quotes.js @@ -228,6 +228,34 @@ module.exports = { } } + /** + * Checks whether or not a given TemplateLiteral node is actually using any of the special features provided by template literal strings. + * @param {ASTNode} node - A TemplateLiteral node to check. + * @returns {boolean} Whether or not the TemplateLiteral node is using any of the special features provided by template literal strings. + * @private + */ + function isUsingFeatureOfTemplateLiteral(node) { + const hasTag = node.parent.type === "TaggedTemplateExpression" && node === node.parent.quasi; + + if (hasTag) { + return true; + } + + const hasStringInterpolation = node.expressions.length > 0; + + if (hasStringInterpolation) { + return true; + } + + const isMultilineString = node.quasis.length >= 1 && UNESCAPED_LINEBREAK_PATTERN.test(node.quasis[0].value.raw); + + if (isMultilineString) { + return true; + } + + return false; + } + return { Literal(node) { @@ -260,39 +288,34 @@ module.exports = { TemplateLiteral(node) { - // If backticks are expected or it's a tagged template, then this shouldn't throw an errors + // Don't throw an error if backticks are expected or a template literal feature is in use. if ( allowTemplateLiterals || quoteOption === "backtick" || - node.parent.type === "TaggedTemplateExpression" && node === node.parent.quasi + isUsingFeatureOfTemplateLiteral(node) ) { return; } - // A warning should be produced if the template literal only has one TemplateElement, and has no unescaped newlines. - const shouldWarn = node.quasis.length === 1 && !UNESCAPED_LINEBREAK_PATTERN.test(node.quasis[0].value.raw); - - if (shouldWarn) { - context.report({ - node, - message: "Strings must use {{description}}.", - data: { - description: settings.description - }, - fix(fixer) { - if (isPartOfDirectivePrologue(node)) { - - /* - * TemplateLiterals in a directive prologue aren't actually directives, but if they're - * in the directive prologue, then fixing them might turn them into directives and change - * the behavior of the code. - */ - return null; - } - return fixer.replaceText(node, settings.convert(sourceCode.getText(node))); + context.report({ + node, + message: "Strings must use {{description}}.", + data: { + description: settings.description + }, + fix(fixer) { + if (isPartOfDirectivePrologue(node)) { + + /* + * TemplateLiterals in a directive prologue aren't actually directives, but if they're + * in the directive prologue, then fixing them might turn them into directives and change + * the behavior of the code. + */ + return null; } - }); - } + return fixer.replaceText(node, settings.convert(sourceCode.getText(node))); + } + }); } }; diff --git a/tools/node_modules/eslint/lib/rules/require-jsdoc.js b/tools/node_modules/eslint/lib/rules/require-jsdoc.js index 949314993b64fb..389bfb692bbae8 100644 --- a/tools/node_modules/eslint/lib/rules/require-jsdoc.js +++ b/tools/node_modules/eslint/lib/rules/require-jsdoc.js @@ -43,7 +43,10 @@ module.exports = { }, additionalProperties: false } - ] + ], + + deprecated: true, + replacedBy: [] }, create(context) { diff --git a/tools/node_modules/eslint/lib/rules/space-in-parens.js b/tools/node_modules/eslint/lib/rules/space-in-parens.js index 88f4f0b50e150d..3068662632172e 100644 --- a/tools/node_modules/eslint/lib/rules/space-in-parens.js +++ b/tools/node_modules/eslint/lib/rules/space-in-parens.js @@ -61,7 +61,6 @@ module.exports = { /** * Produces an object with the opener and closer exception values - * @param {Object} opts The exception options * @returns {Object} `openers` and `closers` exception values * @private */ diff --git a/tools/node_modules/eslint/lib/rules/space-infix-ops.js b/tools/node_modules/eslint/lib/rules/space-infix-ops.js index 45b76795eae14e..254616d998d40d 100644 --- a/tools/node_modules/eslint/lib/rules/space-infix-ops.js +++ b/tools/node_modules/eslint/lib/rules/space-infix-ops.js @@ -69,7 +69,10 @@ module.exports = { context.report({ node: mainNode, loc: culpritToken.loc.start, - message: "Infix operators must be spaced.", + message: "Operator '{{operator}}' must be spaced.", + data: { + operator: culpritToken.value + }, fix(fixer) { const previousToken = sourceCode.getTokenBefore(culpritToken); const afterToken = sourceCode.getTokenAfter(culpritToken); diff --git a/tools/node_modules/eslint/lib/rules/valid-jsdoc.js b/tools/node_modules/eslint/lib/rules/valid-jsdoc.js index b434491bfad873..b40a20f6b4b3ab 100644 --- a/tools/node_modules/eslint/lib/rules/valid-jsdoc.js +++ b/tools/node_modules/eslint/lib/rules/valid-jsdoc.js @@ -64,7 +64,10 @@ module.exports = { } ], - fixable: "code" + fixable: "code", + + deprecated: true, + replacedBy: [] }, create(context) { diff --git a/tools/node_modules/eslint/lib/util/config-comment-parser.js b/tools/node_modules/eslint/lib/util/config-comment-parser.js new file mode 100644 index 00000000000000..88504caf1ca8bf --- /dev/null +++ b/tools/node_modules/eslint/lib/util/config-comment-parser.js @@ -0,0 +1,144 @@ +/** + * @fileoverview Config Comment Parser + * @author Nicholas C. Zakas + */ + +/* eslint-disable class-methods-use-this*/ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const levn = require("levn"), + ConfigOps = require("../config/config-ops"); + +const debug = require("debug")("eslint:config-comment-parser"); + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Object to parse ESLint configuration comments inside JavaScript files. + * @name ConfigCommentParser + */ +module.exports = class ConfigCommentParser { + + /** + * Parses a list of "name:boolean_value" or/and "name" options divided by comma or + * whitespace. Used for "global" and "exported" comments. + * @param {string} string The string to parse. + * @param {Comment} comment The comment node which has the string. + * @returns {Object} Result map object of names and boolean values + */ + parseBooleanConfig(string, comment) { + debug("Parsing Boolean config"); + + const items = {}; + + // Collapse whitespace around `:` and `,` to make parsing easier + const trimmedString = string.replace(/\s*([:,])\s*/g, "$1"); + + trimmedString.split(/\s|,+/).forEach(name => { + if (!name) { + return; + } + + // value defaults to "false" (if not provided), e.g: "foo" => ["foo", "false"] + const [key, value = "false"] = name.split(":"); + + items[key] = { + value: value === "true", + comment + }; + }); + return items; + } + + /** + * Parses a JSON-like config. + * @param {string} string The string to parse. + * @param {Object} location Start line and column of comments for potential error message. + * @returns {({success: true, config: Object}|{success: false, error: Problem})} Result map object + */ + parseJsonConfig(string, location) { + debug("Parsing JSON config"); + + let items = {}; + + // Parses a JSON-like comment by the same way as parsing CLI option. + try { + items = levn.parse("Object", string) || {}; + + // Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`. + // Also, commaless notations have invalid severity: + // "no-alert: 2 no-console: 2" --> {"no-alert": "2 no-console: 2"} + // Should ignore that case as well. + if (ConfigOps.isEverySeverityValid(items)) { + return { + success: true, + config: items + }; + } + } catch (ex) { + + debug("Levn parsing failed; falling back to manual parsing."); + + // ignore to parse the string by a fallback. + } + + /* + * Optionator cannot parse commaless notations. + * But we are supporting that. So this is a fallback for that. + */ + items = {}; + const normalizedString = string.replace(/([a-zA-Z0-9\-/]+):/g, "\"$1\":").replace(/(]|[0-9])\s+(?=")/, "$1,"); + + try { + items = JSON.parse(`{${normalizedString}}`); + } catch (ex) { + debug("Manual parsing failed."); + + return { + success: false, + error: { + ruleId: null, + fatal: true, + severity: 2, + message: `Failed to parse JSON from '${normalizedString}': ${ex.message}`, + line: location.start.line, + column: location.start.column + 1 + } + }; + + } + + return { + success: true, + config: items + }; + } + + /** + * Parses a config of values separated by comma. + * @param {string} string The string to parse. + * @returns {Object} Result map of values and true values + */ + parseListConfig(string) { + debug("Parsing list config"); + + const items = {}; + + // Collapse whitespace around commas + string.replace(/\s*,\s*/g, ",").split(/,+/).forEach(name => { + const trimmedName = name.trim(); + + if (trimmedName) { + items[trimmedName] = true; + } + }); + return items; + } + +}; diff --git a/tools/node_modules/eslint/lib/util/glob-utils.js b/tools/node_modules/eslint/lib/util/glob-utils.js index a2be0f0425cf67..fd4cfa00851d05 100644 --- a/tools/node_modules/eslint/lib/util/glob-utils.js +++ b/tools/node_modules/eslint/lib/util/glob-utils.js @@ -14,7 +14,7 @@ const lodash = require("lodash"), GlobSync = require("./glob"), pathUtils = require("./path-utils"), - IgnoredPaths = require("../ignored-paths"); + IgnoredPaths = require("./ignored-paths"); const debug = require("debug")("eslint:glob-utils"); diff --git a/tools/node_modules/eslint/lib/ignored-paths.js b/tools/node_modules/eslint/lib/util/ignored-paths.js similarity index 98% rename from tools/node_modules/eslint/lib/ignored-paths.js rename to tools/node_modules/eslint/lib/util/ignored-paths.js index 8520090af52a97..de4a79cde336a1 100644 --- a/tools/node_modules/eslint/lib/ignored-paths.js +++ b/tools/node_modules/eslint/lib/util/ignored-paths.js @@ -12,7 +12,7 @@ const fs = require("fs"), path = require("path"), ignore = require("ignore"), - pathUtils = require("./util/path-utils"); + pathUtils = require("./path-utils"); const debug = require("debug")("eslint:ignored-paths"); @@ -296,7 +296,7 @@ class IgnoredPaths { /** * read ignore filepath * @param {string} filePath, file to add to ig - * @returns {array} raw ignore rules + * @returns {Array} raw ignore rules */ readIgnoreFile(filePath) { if (typeof this.cache[filePath] === "undefined") { @@ -307,8 +307,8 @@ class IgnoredPaths { /** * add ignore file to node-ignore instance - * @param {Object} ig, instance of node-ignore - * @param {string} filePath, file to add to ig + * @param {Object} ig instance of node-ignore + * @param {string} filePath file to add to ig * @returns {void} */ addIgnoreFile(ig, filePath) { diff --git a/tools/node_modules/eslint/lib/report-translator.js b/tools/node_modules/eslint/lib/util/report-translator.js similarity index 99% rename from tools/node_modules/eslint/lib/report-translator.js rename to tools/node_modules/eslint/lib/util/report-translator.js index f828305860f6f3..3dfdca0e4944d3 100644 --- a/tools/node_modules/eslint/lib/report-translator.js +++ b/tools/node_modules/eslint/lib/util/report-translator.js @@ -10,8 +10,8 @@ //------------------------------------------------------------------------------ const assert = require("assert"); -const ruleFixer = require("./util/rule-fixer"); -const interpolate = require("./util/interpolate"); +const ruleFixer = require("./rule-fixer"); +const interpolate = require("./interpolate"); //------------------------------------------------------------------------------ // Typedefs diff --git a/tools/node_modules/eslint/lib/util/source-code.js b/tools/node_modules/eslint/lib/util/source-code.js index dd45f6112ad4f2..4e90ac1aa92721 100644 --- a/tools/node_modules/eslint/lib/util/source-code.js +++ b/tools/node_modules/eslint/lib/util/source-code.js @@ -87,7 +87,7 @@ class SourceCode extends TokenStore { * @param {string|Object} textOrConfig - The source code text or config object. * @param {string} textOrConfig.text - The source code text. * @param {ASTNode} textOrConfig.ast - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped. - * @param {Object|null} textOrConfig.parserServices - The parser srevices. + * @param {Object|null} textOrConfig.parserServices - The parser services. * @param {ScopeManager|null} textOrConfig.scopeManager - The scope of this source code. * @param {Object|null} textOrConfig.visitorKeys - The visitor keys to traverse AST. * @param {ASTNode} [astIfNoConfig] - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped. @@ -316,6 +316,7 @@ class SourceCode extends TokenStore { * @returns {Token|null} The Block comment token containing the JSDoc comment * for the given node or null if not found. * @public + * @deprecated */ getJSDocComment(node) { diff --git a/tools/node_modules/eslint/messages/all-files-ignored.txt b/tools/node_modules/eslint/messages/all-files-ignored.txt index 3b741a03e373da..3f4c8ced4c9ada 100644 --- a/tools/node_modules/eslint/messages/all-files-ignored.txt +++ b/tools/node_modules/eslint/messages/all-files-ignored.txt @@ -1,4 +1,4 @@ -All of the files matching the glob pattern "<%= pattern %>" are ignored. +You are linting "<%= pattern %>", but all of the files matching the glob pattern "<%= pattern %>" are ignored. If you don't want to lint these files, remove the pattern "<%= pattern %>" from the list of arguments passed to ESLint. diff --git a/tools/node_modules/eslint/node_modules/acorn-jsx/index.js b/tools/node_modules/eslint/node_modules/acorn-jsx/index.js index 292315f65bfc90..460e7933992122 100644 --- a/tools/node_modules/eslint/node_modules/acorn-jsx/index.js +++ b/tools/node_modules/eslint/node_modules/acorn-jsx/index.js @@ -1,9 +1,18 @@ +'use strict'; + const XHTMLEntities = require('./xhtml'); const hexNumber = /^[\da-fA-F]+$/; const decimalNumber = /^\d+$/; -const {tokTypes: tt, TokContext, tokContexts, TokenType, isNewLine, isIdentifierStart, isIdentifierChar} = require("acorn"); +const acorn = require("acorn"); +const tt = acorn.tokTypes; +const TokContext = acorn.TokContext; +const tokContexts = acorn.tokContexts; +const TokenType = acorn.TokenType; +const isNewLine = acorn.isNewLine; +const isIdentifierStart = acorn.isIdentifierStart; +const isIdentifierChar = acorn.isIdentifierChar; const tc_oTag = new TokContext('Gary Court - * @see http://github.com/garycourt/uri-js +/** + * URI.js + * + * @fileoverview An RFC 3986 compliant, scheme extendable URI parsing/validating/resolving library for JavaScript. + * @author Gary Court + * @see http://github.com/garycourt/uri-js */ -/** - * Copyright 2011 Gary Court. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY GARY COURT ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARY COURT OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of Gary Court. +/** + * Copyright 2011 Gary Court. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY GARY COURT ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARY COURT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Gary Court. */ var SCHEMES = {}; function pctEncChar(chr) { @@ -6594,8 +6610,9 @@ function Ajv(opts) { this._metaOpts = getMetaSchemaOptions(this); if (opts.formats) addInitialFormats(this); - addDraft6MetaSchema(this); + addDefaultMetaSchema(this); if (typeof opts.meta == 'object') this.addMetaSchema(opts.meta); + if (opts.nullable) this.addKeyword('nullable', {metaSchema: {const: true}}); addInitialSchemas(this); } @@ -6967,7 +6984,7 @@ function addFormat(name, format) { } -function addDraft6MetaSchema(self) { +function addDefaultMetaSchema(self) { var $dataSchema; if (self._opts.$data) { $dataSchema = require('./refs/data.json'); diff --git a/tools/node_modules/eslint/node_modules/ajv/dist/ajv.min.js b/tools/node_modules/eslint/node_modules/ajv/dist/ajv.min.js index 3fbafcc4a7d900..57e3eb05509f2c 100644 --- a/tools/node_modules/eslint/node_modules/ajv/dist/ajv.min.js +++ b/tools/node_modules/eslint/node_modules/ajv/dist/ajv.min.js @@ -1,3 +1,3 @@ -/* ajv 6.5.5: Another JSON Schema Validator */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Ajv=e()}}(function(){return function o(i,n,l){function c(r,e){if(!n[r]){if(!i[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(u)return u(r,!0);var a=new Error("Cannot find module '"+r+"'");throw a.code="MODULE_NOT_FOUND",a}var s=n[r]={exports:{}};i[r][0].call(s.exports,function(e){return c(i[r][1][e]||e)},s,s.exports,o,i,n,l)}return n[r].exports}for(var u="function"==typeof require&&require,e=0;e%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,u=/^(?:(?:http[s\u017F]?|ftp):\/\/)(?:(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+(?::(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?@)?(?:(?!10(?:\.[0-9]{1,3}){3})(?!127(?:\.[0-9]{1,3}){3})(?!169\.254(?:\.[0-9]{1,3}){2})(?!192\.168(?:\.[0-9]{1,3}){2})(?!172\.(?:1[6-9]|2[0-9]|3[01])(?:\.[0-9]{1,3}){2})(?:[1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])(?:\.(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])){2}(?:\.(?:[1-9][0-9]?|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))|(?:(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)(?:\.(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)*(?:\.(?:(?:[KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]){2,})))(?::[0-9]{2,5})?(?:\/(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?$/i,h=/^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,d=/^(?:\/(?:[^~/]|~0|~1)*)*$/,f=/^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,p=/^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/;function m(e){return a.copy(m[e="full"==e?"full":"fast"])}function v(e){var r=e.match(o);if(!r)return!1;var t,a=+r[2],s=+r[3];return 1<=a&&a<=12&&1<=s&&s<=(2!=a||((t=+r[1])%4!=0||t%100==0&&t%400!=0)?i[a]:29)}function g(e,r){var t=e.match(n);if(!t)return!1;var a=t[1],s=t[2],o=t[3];return(a<=23&&s<=59&&o<=59||23==a&&59==s&&60==o)&&(!r||t[5])}(r.exports=m).fast={date:/^\d\d\d\d-[0-1]\d-[0-3]\d$/,time:/^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d:\d\d)?$/i,"date-time":/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d:\d\d)$/i,uri:/^(?:[a-z][a-z0-9+-.]*:)(?:\/?\/)?[^\s]*$/i,"uri-reference":/^(?:(?:[a-z][a-z0-9+-.]*:)?\/?\/)?(?:[^\\\s#][^\s#]*)?(?:#[^\\\s]*)?$/i,"uri-template":c,url:u,email:/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i,hostname:s,ipv4:/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,ipv6:/^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,regex:w,uuid:h,"json-pointer":d,"json-pointer-uri-fragment":f,"relative-json-pointer":p},m.full={date:v,time:g,"date-time":function(e){var r=e.split(y);return 2==r.length&&v(r[0])&&g(r[1],!0)},uri:function(e){return P.test(e)&&l.test(e)},"uri-reference":/^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i,"uri-template":c,url:u,email:/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i,hostname:function(e){return e.length<=255&&s.test(e)},ipv4:/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,ipv6:/^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,regex:w,uuid:h,"json-pointer":d,"json-pointer-uri-fragment":f,"relative-json-pointer":p};var y=/t|\s/i;var P=/\/|:/;var E=/[^\\]\\Z/;function w(e){if(E.test(e))return!1;try{return new RegExp(e),!0}catch(e){return!1}}},{"./util":10}],5:[function(e,r,t){"use strict";var $=e("./resolve"),D=e("./util"),j=e("./error_classes"),l=e("fast-json-stable-stringify"),O=e("../dotjs/validate"),I=D.ucs2length,A=e("fast-deep-equal"),C=j.Validation;function k(e,r,t){for(var a=0;a",y=f?">":"<",P=void 0;if(v){var E=e.util.getData(m.$data,i,e.dataPathArr),w="exclusive"+o,S="exclType"+o,b="exclIsNumber"+o,_="' + "+(R="op"+o)+" + '";s+=" var schemaExcl"+o+" = "+E+"; ";var F;P=p;(F=F||[]).push(s+=" var "+w+"; var "+S+" = typeof "+(E="schemaExcl"+o)+"; if ("+S+" != 'boolean' && "+S+" != 'undefined' && "+S+" != 'number') { "),s="",!1!==e.createErrors?(s+=" { keyword: '"+(P||"_exclusiveLimit")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(c)+" , params: {} ",!1!==e.opts.messages&&(s+=" , message: '"+p+" should be boolean' "),e.opts.verbose&&(s+=" , schema: validate.schema"+l+" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var x=s;s=F.pop(),s+=!e.compositeRule&&u?e.async?" throw new ValidationError(["+x+"]); ":" validate.errors = ["+x+"]; return false; ":" var err = "+x+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+=" } else if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || "),s+=" "+S+" == 'number' ? ( ("+w+" = "+a+" === undefined || "+E+" "+g+"= "+a+") ? "+h+" "+y+"= "+E+" : "+h+" "+y+" "+a+" ) : ( ("+w+" = "+E+" === true) ? "+h+" "+y+"= "+a+" : "+h+" "+y+" "+a+" ) || "+h+" !== "+h+") { var op"+o+" = "+w+" ? '"+g+"' : '"+g+"='; ",void 0===n&&(c=e.errSchemaPath+"/"+(P=p),a=E,d=v)}else{_=g;if((b="number"==typeof m)&&d){var R="'"+_+"'";s+=" if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || "),s+=" ( "+a+" === undefined || "+m+" "+g+"= "+a+" ? "+h+" "+y+"= "+m+" : "+h+" "+y+" "+a+" ) || "+h+" !== "+h+") { "}else{b&&void 0===n?(w=!0,c=e.errSchemaPath+"/"+(P=p),a=m,y+="="):(b&&(a=Math[f?"min":"max"](m,n)),m===(!b||a)?(w=!0,c=e.errSchemaPath+"/"+(P=p),y+="="):(w=!1,_+="="));R="'"+_+"'";s+=" if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || "),s+=" "+h+" "+y+" "+a+" || "+h+" !== "+h+") { "}}P=P||r,(F=F||[]).push(s),s="",!1!==e.createErrors?(s+=" { keyword: '"+(P||"_limit")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(c)+" , params: { comparison: "+R+", limit: "+a+", exclusive: "+w+" } ",!1!==e.opts.messages&&(s+=" , message: 'should be "+_+" ",s+=d?"' + "+a:a+"'"),e.opts.verbose&&(s+=" , schema: ",s+=d?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";x=s;return s=F.pop(),s+=!e.compositeRule&&u?e.async?" throw new ValidationError(["+x+"]); ":" validate.errors = ["+x+"]; return false; ":" var err = "+x+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+=" } ",u&&(s+=" else { "),s}},{}],13:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a,s=" ",o=e.level,i=e.dataLevel,n=e.schema[r],l=e.schemaPath+e.util.getProperty(r),c=e.errSchemaPath+"/"+r,u=!e.opts.allErrors,h="data"+(i||""),d=e.opts.$data&&n&&n.$data;d?(s+=" var schema"+o+" = "+e.util.getData(n.$data,i,e.dataPathArr)+"; ",a="schema"+o):a=n,s+="if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || ");var f=r,p=p||[];p.push(s+=" "+h+".length "+("maxItems"==r?">":"<")+" "+a+") { "),s="",!1!==e.createErrors?(s+=" { keyword: '"+(f||"_limitItems")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(c)+" , params: { limit: "+a+" } ",!1!==e.opts.messages&&(s+=" , message: 'should NOT have ",s+="maxItems"==r?"more":"fewer",s+=" than ",s+=d?"' + "+a+" + '":""+n,s+=" items' "),e.opts.verbose&&(s+=" , schema: ",s+=d?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var m=s;return s=p.pop(),s+=!e.compositeRule&&u?e.async?" throw new ValidationError(["+m+"]); ":" validate.errors = ["+m+"]; return false; ":" var err = "+m+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+="} ",u&&(s+=" else { "),s}},{}],14:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a,s=" ",o=e.level,i=e.dataLevel,n=e.schema[r],l=e.schemaPath+e.util.getProperty(r),c=e.errSchemaPath+"/"+r,u=!e.opts.allErrors,h="data"+(i||""),d=e.opts.$data&&n&&n.$data;d?(s+=" var schema"+o+" = "+e.util.getData(n.$data,i,e.dataPathArr)+"; ",a="schema"+o):a=n,s+="if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || "),s+=!1===e.opts.unicode?" "+h+".length ":" ucs2length("+h+") ";var f=r,p=p||[];p.push(s+=" "+("maxLength"==r?">":"<")+" "+a+") { "),s="",!1!==e.createErrors?(s+=" { keyword: '"+(f||"_limitLength")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(c)+" , params: { limit: "+a+" } ",!1!==e.opts.messages&&(s+=" , message: 'should NOT be ",s+="maxLength"==r?"longer":"shorter",s+=" than ",s+=d?"' + "+a+" + '":""+n,s+=" characters' "),e.opts.verbose&&(s+=" , schema: ",s+=d?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var m=s;return s=p.pop(),s+=!e.compositeRule&&u?e.async?" throw new ValidationError(["+m+"]); ":" validate.errors = ["+m+"]; return false; ":" var err = "+m+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+="} ",u&&(s+=" else { "),s}},{}],15:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a,s=" ",o=e.level,i=e.dataLevel,n=e.schema[r],l=e.schemaPath+e.util.getProperty(r),c=e.errSchemaPath+"/"+r,u=!e.opts.allErrors,h="data"+(i||""),d=e.opts.$data&&n&&n.$data;d?(s+=" var schema"+o+" = "+e.util.getData(n.$data,i,e.dataPathArr)+"; ",a="schema"+o):a=n,s+="if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || ");var f=r,p=p||[];p.push(s+=" Object.keys("+h+").length "+("maxProperties"==r?">":"<")+" "+a+") { "),s="",!1!==e.createErrors?(s+=" { keyword: '"+(f||"_limitProperties")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(c)+" , params: { limit: "+a+" } ",!1!==e.opts.messages&&(s+=" , message: 'should NOT have ",s+="maxProperties"==r?"more":"fewer",s+=" than ",s+=d?"' + "+a+" + '":""+n,s+=" properties' "),e.opts.verbose&&(s+=" , schema: ",s+=d?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var m=s;return s=p.pop(),s+=!e.compositeRule&&u?e.async?" throw new ValidationError(["+m+"]); ":" validate.errors = ["+m+"]; return false; ":" var err = "+m+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+="} ",u&&(s+=" else { "),s}},{}],16:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a=" ",s=e.schema[r],o=e.schemaPath+e.util.getProperty(r),i=e.errSchemaPath+"/"+r,n=!e.opts.allErrors,l=e.util.copy(e),c="";l.level++;var u="valid"+l.level,h=l.baseId,d=!0,f=s;if(f)for(var p,m=-1,v=f.length-1;m "+x+") { ";var $=u+"["+x+"]";f.schema=F,f.schemaPath=n+"["+x+"]",f.errSchemaPath=l+"/"+x,f.errorPath=e.util.getPathExpr(e.errorPath,x,e.opts.jsonPointers,!0),f.dataPathArr[g]=x;var D=e.validate(f);f.baseId=P,e.util.varOccurences(D,y)<2?a+=" "+e.util.varReplace(D,y,$)+" ":a+=" var "+y+" = "+$+"; "+D+" ",a+=" } ",c&&(a+=" if ("+m+") { ",p+="}")}if("object"==typeof E&&e.util.schemaHasRules(E,e.RULES.all)){f.schema=E,f.schemaPath=e.schemaPath+".additionalItems",f.errSchemaPath=e.errSchemaPath+"/additionalItems",a+=" "+m+" = true; if ("+u+".length > "+i.length+") { for (var "+v+" = "+i.length+"; "+v+" < "+u+".length; "+v+"++) { ",f.errorPath=e.util.getPathExpr(e.errorPath,v,e.opts.jsonPointers,!0);$=u+"["+v+"]";f.dataPathArr[g]=v;D=e.validate(f);f.baseId=P,e.util.varOccurences(D,y)<2?a+=" "+e.util.varReplace(D,y,$)+" ":a+=" var "+y+" = "+$+"; "+D+" ",c&&(a+=" if (!"+m+") break; "),a+=" } } ",c&&(a+=" if ("+m+") { ",p+="}")}}else if(e.util.schemaHasRules(i,e.RULES.all)){f.schema=i,f.schemaPath=n,f.errSchemaPath=l,a+=" for (var "+v+" = 0; "+v+" < "+u+".length; "+v+"++) { ",f.errorPath=e.util.getPathExpr(e.errorPath,v,e.opts.jsonPointers,!0);$=u+"["+v+"]";f.dataPathArr[g]=v;D=e.validate(f);f.baseId=P,e.util.varOccurences(D,y)<2?a+=" "+e.util.varReplace(D,y,$)+" ":a+=" var "+y+" = "+$+"; "+D+" ",c&&(a+=" if (!"+m+") break; "),a+=" }"}return c&&(a+=" "+p+" if ("+d+" == errors) {"),a=e.util.cleanUpCode(a)}},{}],28:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a,s=" ",o=e.level,i=e.dataLevel,n=e.schema[r],l=e.schemaPath+e.util.getProperty(r),c=e.errSchemaPath+"/"+r,u=!e.opts.allErrors,h="data"+(i||""),d=e.opts.$data&&n&&n.$data;d?(s+=" var schema"+o+" = "+e.util.getData(n.$data,i,e.dataPathArr)+"; ",a="schema"+o):a=n,s+="var division"+o+";if (",d&&(s+=" "+a+" !== undefined && ( typeof "+a+" != 'number' || "),s+=" (division"+o+" = "+h+" / "+a+", ",s+=e.opts.multipleOfPrecision?" Math.abs(Math.round(division"+o+") - division"+o+") > 1e-"+e.opts.multipleOfPrecision+" ":" division"+o+" !== parseInt(division"+o+") ",s+=" ) ",d&&(s+=" ) ");var f=f||[];f.push(s+=" ) { "),s="",!1!==e.createErrors?(s+=" { keyword: 'multipleOf' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(c)+" , params: { multipleOf: "+a+" } ",!1!==e.opts.messages&&(s+=" , message: 'should be multiple of ",s+=d?"' + "+a:a+"'"),e.opts.verbose&&(s+=" , schema: ",s+=d?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var p=s;return s=f.pop(),s+=!e.compositeRule&&u?e.async?" throw new ValidationError(["+p+"]); ":" validate.errors = ["+p+"]; return false; ":" var err = "+p+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+="} ",u&&(s+=" else { "),s}},{}],29:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a=" ",s=e.level,o=e.dataLevel,i=e.schema[r],n=e.schemaPath+e.util.getProperty(r),l=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,u="data"+(o||""),h="errs__"+s,d=e.util.copy(e);d.level++;var f="valid"+d.level;if(e.util.schemaHasRules(i,e.RULES.all)){d.schema=i,d.schemaPath=n,d.errSchemaPath=l,a+=" var "+h+" = errors; ";var p,m=e.compositeRule;e.compositeRule=d.compositeRule=!0,d.createErrors=!1,d.opts.allErrors&&(p=d.opts.allErrors,d.opts.allErrors=!1),a+=" "+e.validate(d)+" ",d.createErrors=!0,p&&(d.opts.allErrors=p),e.compositeRule=d.compositeRule=m;var v=v||[];v.push(a+=" if ("+f+") { "),a="",!1!==e.createErrors?(a+=" { keyword: 'not' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: {} ",!1!==e.opts.messages&&(a+=" , message: 'should NOT be valid' "),e.opts.verbose&&(a+=" , schema: validate.schema"+n+" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ";var g=a;a=v.pop(),a+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+g+"]); ":" validate.errors = ["+g+"]; return false; ":" var err = "+g+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+=" } else { errors = "+h+"; if (vErrors !== null) { if ("+h+") vErrors.length = "+h+"; else vErrors = null; } ",e.opts.allErrors&&(a+=" } ")}else a+=" var err = ",!1!==e.createErrors?(a+=" { keyword: 'not' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: {} ",!1!==e.opts.messages&&(a+=" , message: 'should NOT be valid' "),e.opts.verbose&&(a+=" , schema: validate.schema"+n+" , parentSchema: validate.schema"+e.schemaPath+" , data: "+u+" "),a+=" } "):a+=" {} ",a+="; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",c&&(a+=" if (false) { ");return a}},{}],30:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a=" ",s=e.level,o=e.dataLevel,i=e.schema[r],n=e.schemaPath+e.util.getProperty(r),l=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,u="data"+(o||""),h="valid"+s,d="errs__"+s,f=e.util.copy(e),p="";f.level++;var m="valid"+f.level,v=f.baseId,g="prevValid"+s,y="passingSchemas"+s;a+="var "+d+" = errors , "+g+" = false , "+h+" = false , "+y+" = null; ";var P=e.compositeRule;e.compositeRule=f.compositeRule=!0;var E=i;if(E)for(var w,S=-1,b=E.length-1;S 1) { ";var p=e.schema.items&&e.schema.items.type,m=Array.isArray(p);if(!p||"object"==p||"array"==p||m&&(0<=p.indexOf("object")||0<=p.indexOf("array")))s+=" outer: for (;i--;) { for (j = i; j--;) { if (equal("+h+"[i], "+h+"[j])) { "+d+" = false; break outer; } } } ";else s+=" var itemIndices = {}, item; for (;i--;) { var item = "+h+"[i]; ",s+=" if ("+e.util["checkDataType"+(m?"s":"")](p,"item",!0)+") continue; ",m&&(s+=" if (typeof item == 'string') item = '\"' + item; "),s+=" if (typeof itemIndices[item] == 'number') { "+d+" = false; j = itemIndices[item]; break; } itemIndices[item] = i; } ";s+=" } ",f&&(s+=" } ");var v=v||[];v.push(s+=" if (!"+d+") { "),s="",!1!==e.createErrors?(s+=" { keyword: 'uniqueItems' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(c)+" , params: { i: i, j: j } ",!1!==e.opts.messages&&(s+=" , message: 'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)' "),e.opts.verbose&&(s+=" , schema: ",s+=f?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var g=s;s=v.pop(),s+=!e.compositeRule&&u?e.async?" throw new ValidationError(["+g+"]); ":" validate.errors = ["+g+"]; return false; ":" var err = "+g+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+=" } ",u&&(s+=" else { ")}else u&&(s+=" if (true) { ");return s}},{}],37:[function(e,r,t){"use strict";r.exports=function(a,e,r){var t="",s=!0===a.schema.$async,o=a.util.schemaHasRulesExcept(a.schema,a.RULES.all,"$ref"),i=a.self._getId(a.schema);if(a.isTop&&(t+=" var validate = ",s&&(a.async=!0,t+="async "),t+="function(data, dataPath, parentData, parentDataProperty, rootData) { 'use strict'; ",i&&(a.opts.sourceCode||a.opts.processCode)&&(t+=" /*# sourceURL="+i+" */ ")),"boolean"==typeof a.schema||!o&&!a.schema.$ref){var n=a.level,l=a.dataLevel,c=a.schema[e="false schema"],u=a.schemaPath+a.util.getProperty(e),h=a.errSchemaPath+"/"+e,d=!a.opts.allErrors,f="data"+(l||""),p="valid"+n;if(!1===a.schema){a.isTop?d=!0:t+=" var "+p+" = false; ",(K=K||[]).push(t),t="",!1!==a.createErrors?(t+=" { keyword: 'false schema' , dataPath: (dataPath || '') + "+a.errorPath+" , schemaPath: "+a.util.toQuotedString(h)+" , params: {} ",!1!==a.opts.messages&&(t+=" , message: 'boolean schema is false' "),a.opts.verbose&&(t+=" , schema: false , parentSchema: validate.schema"+a.schemaPath+" , data: "+f+" "),t+=" } "):t+=" {} ";var m=t;t=K.pop(),t+=!a.compositeRule&&d?a.async?" throw new ValidationError(["+m+"]); ":" validate.errors = ["+m+"]; return false; ":" var err = "+m+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; "}else t+=a.isTop?s?" return data; ":" validate.errors = null; return true; ":" var "+p+" = true; ";return a.isTop&&(t+=" }; return validate; "),t}if(a.isTop){var v=a.isTop;n=a.level=0,l=a.dataLevel=0,f="data";a.rootId=a.resolve.fullPath(a.self._getId(a.root.schema)),a.baseId=a.baseId||a.rootId,delete a.isTop,a.dataPathArr=[void 0],t+=" var vErrors = null; ",t+=" var errors = 0; ",t+=" if (rootData === undefined) rootData = data; "}else{n=a.level,f="data"+((l=a.dataLevel)||"");if(i&&(a.baseId=a.resolve.url(a.baseId,i)),s&&!a.async)throw new Error("async schema in sync schema");t+=" var errs_"+n+" = errors;"}p="valid"+n,d=!a.opts.allErrors;var g="",y="",P=a.schema.type,E=Array.isArray(P);if(E&&1==P.length&&(P=P[0],E=!1),a.schema.$ref&&o){if("fail"==a.opts.extendRefs)throw new Error('$ref: validation keywords used in schema at path "'+a.errSchemaPath+'" (see option extendRefs)');!0!==a.opts.extendRefs&&(o=!1,a.logger.warn('$ref: keywords ignored in schema at path "'+a.errSchemaPath+'"'))}if(a.schema.$comment&&a.opts.$comment&&(t+=" "+a.RULES.all.$comment.code(a,"$comment")),P){if(a.opts.coerceTypes)var w=a.util.coerceToTypes(a.opts.coerceTypes,P);var S=a.RULES.types[P];if(w||E||!0===S||S&&!J(S)){u=a.schemaPath+".type",h=a.errSchemaPath+"/type",u=a.schemaPath+".type",h=a.errSchemaPath+"/type";if(t+=" if ("+a.util[E?"checkDataTypes":"checkDataType"](P,f,!0)+") { ",w){var b="dataType"+n,_="coerced"+n;t+=" var "+b+" = typeof "+f+"; ","array"==a.opts.coerceTypes&&(t+=" if ("+b+" == 'object' && Array.isArray("+f+")) "+b+" = 'array'; "),t+=" var "+_+" = undefined; ";var F="",x=w;if(x)for(var R,$=-1,D=x.length-1;$= 0x80 (not a basic code point)","invalid-input":"Invalid input"},L=Math.floor,z=String.fromCharCode;function T(e){throw new RangeError(i[e])}function n(e,r){var t=e.split("@"),a="";return 1>1,e+=L(e/r);455L((A-s)/h))&&T("overflow"),s+=f*h;var p=d<=i?1:i+26<=d?26:d-i;if(fL(A/m)&&T("overflow"),h*=m}var v=t.length+1;i=U(s-u,v,0==u),L(s/v)>A-o&&T("overflow"),o+=L(s/v),s%=v,t.splice(s++,0,o)}return String.fromCodePoint.apply(String,t)},c=function(e){var r=[],t=(e=N(e)).length,a=128,s=0,o=72,i=!0,n=!1,l=void 0;try{for(var c,u=e[Symbol.iterator]();!(i=(c=u.next()).done);i=!0){var h=c.value;h<128&&r.push(z(h))}}catch(e){n=!0,l=e}finally{try{!i&&u.return&&u.return()}finally{if(n)throw l}}var d=r.length,f=d;for(d&&r.push("-");fL((A-s)/w)&&T("overflow"),s+=(p-a)*w,a=p;var S=!0,b=!1,_=void 0;try{for(var F,x=e[Symbol.iterator]();!(S=(F=x.next()).done);S=!0){var R=F.value;if(RA&&T("overflow"),R==a){for(var $=s,D=36;;D+=36){var j=D<=o?1:o+26<=D?26:D-o;if($>6|192).toString(16).toUpperCase()+"%"+(63&r|128).toString(16).toUpperCase():"%"+(r>>12|224).toString(16).toUpperCase()+"%"+(r>>6&63|128).toString(16).toUpperCase()+"%"+(63&r|128).toString(16).toUpperCase()}function f(e){for(var r="",t=0,a=e.length;tA-Z\\x5E-\\x7E]",'[\\"\\\\]'),Z=new RegExp(M,"g"),G=new RegExp(K,"g"),Y=new RegExp(C("[^]","[A-Za-z0-9\\!\\$\\%\\'\\*\\+\\-\\^\\_\\`\\{\\|\\}\\~]","[\\.]",'[\\"]',J),"g"),W=new RegExp(C("[^]",M,"[\\!\\$\\'\\(\\)\\*\\+\\,\\;\\:\\@]"),"g"),X=W;function ee(e){var r=f(e);return r.match(Z)?r:e}var re={scheme:"mailto",parse:function(e,r){var t=e,a=t.to=t.path?t.path.split(","):[];if(t.path=void 0,t.query){for(var s=!1,o={},i=t.query.split("&"),n=0,l=i.length;n%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,c=/^(?:(?:http[s\u017F]?|ftp):\/\/)(?:(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+(?::(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?@)?(?:(?!10(?:\.[0-9]{1,3}){3})(?!127(?:\.[0-9]{1,3}){3})(?!169\.254(?:\.[0-9]{1,3}){2})(?!192\.168(?:\.[0-9]{1,3}){2})(?!172\.(?:1[6-9]|2[0-9]|3[01])(?:\.[0-9]{1,3}){2})(?:[1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])(?:\.(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])){2}(?:\.(?:[1-9][0-9]?|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))|(?:(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)(?:\.(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)*(?:\.(?:(?:[KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]){2,})))(?::[0-9]{2,5})?(?:\/(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?$/i,h=/^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,d=/^(?:\/(?:[^~/]|~0|~1)*)*$/,f=/^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,p=/^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/;function m(e){return a.copy(m[e="full"==e?"full":"fast"])}function v(e){var r=e.match(o);if(!r)return!1;var t,a=+r[2],s=+r[3];return 1<=a&&a<=12&&1<=s&&s<=(2!=a||((t=+r[1])%4!=0||t%100==0&&t%400!=0)?i[a]:29)}function g(e,r){var t=e.match(n);if(!t)return!1;var a=t[1],s=t[2],o=t[3];return(a<=23&&s<=59&&o<=59||23==a&&59==s&&60==o)&&(!r||t[5])}(r.exports=m).fast={date:/^\d\d\d\d-[0-1]\d-[0-3]\d$/,time:/^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d:\d\d)?$/i,"date-time":/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d:\d\d)$/i,uri:/^(?:[a-z][a-z0-9+-.]*:)(?:\/?\/)?[^\s]*$/i,"uri-reference":/^(?:(?:[a-z][a-z0-9+-.]*:)?\/?\/)?(?:[^\\\s#][^\s#]*)?(?:#[^\\\s]*)?$/i,"uri-template":u,url:c,email:/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i,hostname:s,ipv4:/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,ipv6:/^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,regex:w,uuid:h,"json-pointer":d,"json-pointer-uri-fragment":f,"relative-json-pointer":p},m.full={date:v,time:g,"date-time":function(e){var r=e.split(y);return 2==r.length&&v(r[0])&&g(r[1],!0)},uri:function(e){return P.test(e)&&l.test(e)},"uri-reference":/^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i,"uri-template":u,url:c,email:/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i,hostname:function(e){return e.length<=255&&s.test(e)},ipv4:/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,ipv6:/^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,regex:w,uuid:h,"json-pointer":d,"json-pointer-uri-fragment":f,"relative-json-pointer":p};var y=/t|\s/i;var P=/\/|:/;var E=/[^\\]\\Z/;function w(e){if(E.test(e))return!1;try{return new RegExp(e),!0}catch(e){return!1}}},{"./util":10}],5:[function(e,r,t){"use strict";var $=e("./resolve"),D=e("./util"),j=e("./error_classes"),l=e("fast-json-stable-stringify"),O=e("../dotjs/validate"),I=D.ucs2length,A=e("fast-deep-equal"),C=j.Validation;function k(e,r,t){for(var a=0;a",y=f?">":"<",P=void 0;if(v){var E=e.util.getData(m.$data,i,e.dataPathArr),w="exclusive"+o,S="exclType"+o,b="exclIsNumber"+o,_="' + "+(R="op"+o)+" + '";s+=" var schemaExcl"+o+" = "+E+"; ";var F;P=p;(F=F||[]).push(s+=" var "+w+"; var "+S+" = typeof "+(E="schemaExcl"+o)+"; if ("+S+" != 'boolean' && "+S+" != 'undefined' && "+S+" != 'number') { "),s="",!1!==e.createErrors?(s+=" { keyword: '"+(P||"_exclusiveLimit")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(u)+" , params: {} ",!1!==e.opts.messages&&(s+=" , message: '"+p+" should be boolean' "),e.opts.verbose&&(s+=" , schema: validate.schema"+l+" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var x=s;s=F.pop(),s+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+x+"]); ":" validate.errors = ["+x+"]; return false; ":" var err = "+x+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+=" } else if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || "),s+=" "+S+" == 'number' ? ( ("+w+" = "+a+" === undefined || "+E+" "+g+"= "+a+") ? "+h+" "+y+"= "+E+" : "+h+" "+y+" "+a+" ) : ( ("+w+" = "+E+" === true) ? "+h+" "+y+"= "+a+" : "+h+" "+y+" "+a+" ) || "+h+" !== "+h+") { var op"+o+" = "+w+" ? '"+g+"' : '"+g+"='; ",void 0===n&&(u=e.errSchemaPath+"/"+(P=p),a=E,d=v)}else{_=g;if((b="number"==typeof m)&&d){var R="'"+_+"'";s+=" if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || "),s+=" ( "+a+" === undefined || "+m+" "+g+"= "+a+" ? "+h+" "+y+"= "+m+" : "+h+" "+y+" "+a+" ) || "+h+" !== "+h+") { "}else{b&&void 0===n?(w=!0,u=e.errSchemaPath+"/"+(P=p),a=m,y+="="):(b&&(a=Math[f?"min":"max"](m,n)),m===(!b||a)?(w=!0,u=e.errSchemaPath+"/"+(P=p),y+="="):(w=!1,_+="="));R="'"+_+"'";s+=" if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || "),s+=" "+h+" "+y+" "+a+" || "+h+" !== "+h+") { "}}P=P||r,(F=F||[]).push(s),s="",!1!==e.createErrors?(s+=" { keyword: '"+(P||"_limit")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(u)+" , params: { comparison: "+R+", limit: "+a+", exclusive: "+w+" } ",!1!==e.opts.messages&&(s+=" , message: 'should be "+_+" ",s+=d?"' + "+a:a+"'"),e.opts.verbose&&(s+=" , schema: ",s+=d?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";x=s;return s=F.pop(),s+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+x+"]); ":" validate.errors = ["+x+"]; return false; ":" var err = "+x+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+=" } ",c&&(s+=" else { "),s}},{}],13:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a,s=" ",o=e.level,i=e.dataLevel,n=e.schema[r],l=e.schemaPath+e.util.getProperty(r),u=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,h="data"+(i||""),d=e.opts.$data&&n&&n.$data;d?(s+=" var schema"+o+" = "+e.util.getData(n.$data,i,e.dataPathArr)+"; ",a="schema"+o):a=n,s+="if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || ");var f=r,p=p||[];p.push(s+=" "+h+".length "+("maxItems"==r?">":"<")+" "+a+") { "),s="",!1!==e.createErrors?(s+=" { keyword: '"+(f||"_limitItems")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(u)+" , params: { limit: "+a+" } ",!1!==e.opts.messages&&(s+=" , message: 'should NOT have ",s+="maxItems"==r?"more":"fewer",s+=" than ",s+=d?"' + "+a+" + '":""+n,s+=" items' "),e.opts.verbose&&(s+=" , schema: ",s+=d?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var m=s;return s=p.pop(),s+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+m+"]); ":" validate.errors = ["+m+"]; return false; ":" var err = "+m+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+="} ",c&&(s+=" else { "),s}},{}],14:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a,s=" ",o=e.level,i=e.dataLevel,n=e.schema[r],l=e.schemaPath+e.util.getProperty(r),u=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,h="data"+(i||""),d=e.opts.$data&&n&&n.$data;d?(s+=" var schema"+o+" = "+e.util.getData(n.$data,i,e.dataPathArr)+"; ",a="schema"+o):a=n,s+="if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || "),s+=!1===e.opts.unicode?" "+h+".length ":" ucs2length("+h+") ";var f=r,p=p||[];p.push(s+=" "+("maxLength"==r?">":"<")+" "+a+") { "),s="",!1!==e.createErrors?(s+=" { keyword: '"+(f||"_limitLength")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(u)+" , params: { limit: "+a+" } ",!1!==e.opts.messages&&(s+=" , message: 'should NOT be ",s+="maxLength"==r?"longer":"shorter",s+=" than ",s+=d?"' + "+a+" + '":""+n,s+=" characters' "),e.opts.verbose&&(s+=" , schema: ",s+=d?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var m=s;return s=p.pop(),s+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+m+"]); ":" validate.errors = ["+m+"]; return false; ":" var err = "+m+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+="} ",c&&(s+=" else { "),s}},{}],15:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a,s=" ",o=e.level,i=e.dataLevel,n=e.schema[r],l=e.schemaPath+e.util.getProperty(r),u=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,h="data"+(i||""),d=e.opts.$data&&n&&n.$data;d?(s+=" var schema"+o+" = "+e.util.getData(n.$data,i,e.dataPathArr)+"; ",a="schema"+o):a=n,s+="if ( ",d&&(s+=" ("+a+" !== undefined && typeof "+a+" != 'number') || ");var f=r,p=p||[];p.push(s+=" Object.keys("+h+").length "+("maxProperties"==r?">":"<")+" "+a+") { "),s="",!1!==e.createErrors?(s+=" { keyword: '"+(f||"_limitProperties")+"' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(u)+" , params: { limit: "+a+" } ",!1!==e.opts.messages&&(s+=" , message: 'should NOT have ",s+="maxProperties"==r?"more":"fewer",s+=" than ",s+=d?"' + "+a+" + '":""+n,s+=" properties' "),e.opts.verbose&&(s+=" , schema: ",s+=d?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var m=s;return s=p.pop(),s+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+m+"]); ":" validate.errors = ["+m+"]; return false; ":" var err = "+m+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+="} ",c&&(s+=" else { "),s}},{}],16:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a=" ",s=e.schema[r],o=e.schemaPath+e.util.getProperty(r),i=e.errSchemaPath+"/"+r,n=!e.opts.allErrors,l=e.util.copy(e),u="";l.level++;var c="valid"+l.level,h=l.baseId,d=!0,f=s;if(f)for(var p,m=-1,v=f.length-1;m "+x+") { ";var $=c+"["+x+"]";f.schema=F,f.schemaPath=n+"["+x+"]",f.errSchemaPath=l+"/"+x,f.errorPath=e.util.getPathExpr(e.errorPath,x,e.opts.jsonPointers,!0),f.dataPathArr[g]=x;var D=e.validate(f);f.baseId=P,e.util.varOccurences(D,y)<2?a+=" "+e.util.varReplace(D,y,$)+" ":a+=" var "+y+" = "+$+"; "+D+" ",a+=" } ",u&&(a+=" if ("+m+") { ",p+="}")}if("object"==typeof E&&e.util.schemaHasRules(E,e.RULES.all)){f.schema=E,f.schemaPath=e.schemaPath+".additionalItems",f.errSchemaPath=e.errSchemaPath+"/additionalItems",a+=" "+m+" = true; if ("+c+".length > "+i.length+") { for (var "+v+" = "+i.length+"; "+v+" < "+c+".length; "+v+"++) { ",f.errorPath=e.util.getPathExpr(e.errorPath,v,e.opts.jsonPointers,!0);$=c+"["+v+"]";f.dataPathArr[g]=v;D=e.validate(f);f.baseId=P,e.util.varOccurences(D,y)<2?a+=" "+e.util.varReplace(D,y,$)+" ":a+=" var "+y+" = "+$+"; "+D+" ",u&&(a+=" if (!"+m+") break; "),a+=" } } ",u&&(a+=" if ("+m+") { ",p+="}")}}else if(e.util.schemaHasRules(i,e.RULES.all)){f.schema=i,f.schemaPath=n,f.errSchemaPath=l,a+=" for (var "+v+" = 0; "+v+" < "+c+".length; "+v+"++) { ",f.errorPath=e.util.getPathExpr(e.errorPath,v,e.opts.jsonPointers,!0);$=c+"["+v+"]";f.dataPathArr[g]=v;D=e.validate(f);f.baseId=P,e.util.varOccurences(D,y)<2?a+=" "+e.util.varReplace(D,y,$)+" ":a+=" var "+y+" = "+$+"; "+D+" ",u&&(a+=" if (!"+m+") break; "),a+=" }"}return u&&(a+=" "+p+" if ("+d+" == errors) {"),a=e.util.cleanUpCode(a)}},{}],28:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a,s=" ",o=e.level,i=e.dataLevel,n=e.schema[r],l=e.schemaPath+e.util.getProperty(r),u=e.errSchemaPath+"/"+r,c=!e.opts.allErrors,h="data"+(i||""),d=e.opts.$data&&n&&n.$data;d?(s+=" var schema"+o+" = "+e.util.getData(n.$data,i,e.dataPathArr)+"; ",a="schema"+o):a=n,s+="var division"+o+";if (",d&&(s+=" "+a+" !== undefined && ( typeof "+a+" != 'number' || "),s+=" (division"+o+" = "+h+" / "+a+", ",s+=e.opts.multipleOfPrecision?" Math.abs(Math.round(division"+o+") - division"+o+") > 1e-"+e.opts.multipleOfPrecision+" ":" division"+o+" !== parseInt(division"+o+") ",s+=" ) ",d&&(s+=" ) ");var f=f||[];f.push(s+=" ) { "),s="",!1!==e.createErrors?(s+=" { keyword: 'multipleOf' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(u)+" , params: { multipleOf: "+a+" } ",!1!==e.opts.messages&&(s+=" , message: 'should be multiple of ",s+=d?"' + "+a:a+"'"),e.opts.verbose&&(s+=" , schema: ",s+=d?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var p=s;return s=f.pop(),s+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+p+"]); ":" validate.errors = ["+p+"]; return false; ":" var err = "+p+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+="} ",c&&(s+=" else { "),s}},{}],29:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a=" ",s=e.level,o=e.dataLevel,i=e.schema[r],n=e.schemaPath+e.util.getProperty(r),l=e.errSchemaPath+"/"+r,u=!e.opts.allErrors,c="data"+(o||""),h="errs__"+s,d=e.util.copy(e);d.level++;var f="valid"+d.level;if(e.util.schemaHasRules(i,e.RULES.all)){d.schema=i,d.schemaPath=n,d.errSchemaPath=l,a+=" var "+h+" = errors; ";var p,m=e.compositeRule;e.compositeRule=d.compositeRule=!0,d.createErrors=!1,d.opts.allErrors&&(p=d.opts.allErrors,d.opts.allErrors=!1),a+=" "+e.validate(d)+" ",d.createErrors=!0,p&&(d.opts.allErrors=p),e.compositeRule=d.compositeRule=m;var v=v||[];v.push(a+=" if ("+f+") { "),a="",!1!==e.createErrors?(a+=" { keyword: 'not' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: {} ",!1!==e.opts.messages&&(a+=" , message: 'should NOT be valid' "),e.opts.verbose&&(a+=" , schema: validate.schema"+n+" , parentSchema: validate.schema"+e.schemaPath+" , data: "+c+" "),a+=" } "):a+=" {} ";var g=a;a=v.pop(),a+=!e.compositeRule&&u?e.async?" throw new ValidationError(["+g+"]); ":" validate.errors = ["+g+"]; return false; ":" var err = "+g+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",a+=" } else { errors = "+h+"; if (vErrors !== null) { if ("+h+") vErrors.length = "+h+"; else vErrors = null; } ",e.opts.allErrors&&(a+=" } ")}else a+=" var err = ",!1!==e.createErrors?(a+=" { keyword: 'not' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(l)+" , params: {} ",!1!==e.opts.messages&&(a+=" , message: 'should NOT be valid' "),e.opts.verbose&&(a+=" , schema: validate.schema"+n+" , parentSchema: validate.schema"+e.schemaPath+" , data: "+c+" "),a+=" } "):a+=" {} ",a+="; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",u&&(a+=" if (false) { ");return a}},{}],30:[function(e,r,t){"use strict";r.exports=function(e,r,t){var a=" ",s=e.level,o=e.dataLevel,i=e.schema[r],n=e.schemaPath+e.util.getProperty(r),l=e.errSchemaPath+"/"+r,u=!e.opts.allErrors,c="data"+(o||""),h="valid"+s,d="errs__"+s,f=e.util.copy(e),p="";f.level++;var m="valid"+f.level,v=f.baseId,g="prevValid"+s,y="passingSchemas"+s;a+="var "+d+" = errors , "+g+" = false , "+h+" = false , "+y+" = null; ";var P=e.compositeRule;e.compositeRule=f.compositeRule=!0;var E=i;if(E)for(var w,S=-1,b=E.length-1;S 1) { ";var p=e.schema.items&&e.schema.items.type,m=Array.isArray(p);if(!p||"object"==p||"array"==p||m&&(0<=p.indexOf("object")||0<=p.indexOf("array")))s+=" outer: for (;i--;) { for (j = i; j--;) { if (equal("+h+"[i], "+h+"[j])) { "+d+" = false; break outer; } } } ";else s+=" var itemIndices = {}, item; for (;i--;) { var item = "+h+"[i]; ",s+=" if ("+e.util["checkDataType"+(m?"s":"")](p,"item",!0)+") continue; ",m&&(s+=" if (typeof item == 'string') item = '\"' + item; "),s+=" if (typeof itemIndices[item] == 'number') { "+d+" = false; j = itemIndices[item]; break; } itemIndices[item] = i; } ";s+=" } ",f&&(s+=" } ");var v=v||[];v.push(s+=" if (!"+d+") { "),s="",!1!==e.createErrors?(s+=" { keyword: 'uniqueItems' , dataPath: (dataPath || '') + "+e.errorPath+" , schemaPath: "+e.util.toQuotedString(u)+" , params: { i: i, j: j } ",!1!==e.opts.messages&&(s+=" , message: 'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)' "),e.opts.verbose&&(s+=" , schema: ",s+=f?"validate.schema"+l:""+n,s+=" , parentSchema: validate.schema"+e.schemaPath+" , data: "+h+" "),s+=" } "):s+=" {} ";var g=s;s=v.pop(),s+=!e.compositeRule&&c?e.async?" throw new ValidationError(["+g+"]); ":" validate.errors = ["+g+"]; return false; ":" var err = "+g+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ",s+=" } ",c&&(s+=" else { ")}else c&&(s+=" if (true) { ");return s}},{}],37:[function(e,r,t){"use strict";r.exports=function(a,e,r){var t="",s=!0===a.schema.$async,o=a.util.schemaHasRulesExcept(a.schema,a.RULES.all,"$ref"),i=a.self._getId(a.schema);if(a.isTop&&(t+=" var validate = ",s&&(a.async=!0,t+="async "),t+="function(data, dataPath, parentData, parentDataProperty, rootData) { 'use strict'; ",i&&(a.opts.sourceCode||a.opts.processCode)&&(t+=" /*# sourceURL="+i+" */ ")),"boolean"==typeof a.schema||!o&&!a.schema.$ref){var n=a.level,l=a.dataLevel,u=a.schema[e="false schema"],c=a.schemaPath+a.util.getProperty(e),h=a.errSchemaPath+"/"+e,d=!a.opts.allErrors,f="data"+(l||""),p="valid"+n;if(!1===a.schema){a.isTop?d=!0:t+=" var "+p+" = false; ",(B=B||[]).push(t),t="",!1!==a.createErrors?(t+=" { keyword: 'false schema' , dataPath: (dataPath || '') + "+a.errorPath+" , schemaPath: "+a.util.toQuotedString(h)+" , params: {} ",!1!==a.opts.messages&&(t+=" , message: 'boolean schema is false' "),a.opts.verbose&&(t+=" , schema: false , parentSchema: validate.schema"+a.schemaPath+" , data: "+f+" "),t+=" } "):t+=" {} ";var m=t;t=B.pop(),t+=!a.compositeRule&&d?a.async?" throw new ValidationError(["+m+"]); ":" validate.errors = ["+m+"]; return false; ":" var err = "+m+"; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; "}else t+=a.isTop?s?" return data; ":" validate.errors = null; return true; ":" var "+p+" = true; ";return a.isTop&&(t+=" }; return validate; "),t}if(a.isTop){var v=a.isTop;n=a.level=0,l=a.dataLevel=0,f="data";a.rootId=a.resolve.fullPath(a.self._getId(a.root.schema)),a.baseId=a.baseId||a.rootId,delete a.isTop,a.dataPathArr=[void 0],t+=" var vErrors = null; ",t+=" var errors = 0; ",t+=" if (rootData === undefined) rootData = data; "}else{n=a.level,f="data"+((l=a.dataLevel)||"");if(i&&(a.baseId=a.resolve.url(a.baseId,i)),s&&!a.async)throw new Error("async schema in sync schema");t+=" var errs_"+n+" = errors;"}p="valid"+n,d=!a.opts.allErrors;var g="",y="",P=a.schema.type,E=Array.isArray(P);if(P&&a.opts.nullable&&!0===a.schema.nullable&&(E?-1==P.indexOf("null")&&(P=P.concat("null")):"null"!=P&&(P=[P,"null"],E=!0)),E&&1==P.length&&(P=P[0],E=!1),a.schema.$ref&&o){if("fail"==a.opts.extendRefs)throw new Error('$ref: validation keywords used in schema at path "'+a.errSchemaPath+'" (see option extendRefs)');!0!==a.opts.extendRefs&&(o=!1,a.logger.warn('$ref: keywords ignored in schema at path "'+a.errSchemaPath+'"'))}if(a.schema.$comment&&a.opts.$comment&&(t+=" "+a.RULES.all.$comment.code(a,"$comment")),P){if(a.opts.coerceTypes)var w=a.util.coerceToTypes(a.opts.coerceTypes,P);var S=a.RULES.types[P];if(w||E||!0===S||S&&!J(S)){c=a.schemaPath+".type",h=a.errSchemaPath+"/type",c=a.schemaPath+".type",h=a.errSchemaPath+"/type";if(t+=" if ("+a.util[E?"checkDataTypes":"checkDataType"](P,f,!0)+") { ",w){var b="dataType"+n,_="coerced"+n;t+=" var "+b+" = typeof "+f+"; ","array"==a.opts.coerceTypes&&(t+=" if ("+b+" == 'object' && Array.isArray("+f+")) "+b+" = 'array'; "),t+=" var "+_+" = undefined; ";var F="",x=w;if(x)for(var R,$=-1,D=x.length-1;$= 0x80 (not a basic code point)","invalid-input":"Invalid input"},L=Math.floor,z=String.fromCharCode;function T(e){throw new RangeError(i[e])}function n(e,r){var t=e.split("@"),a="";return 1>1,e+=L(e/r);455L((A-s)/h))&&T("overflow"),s+=f*h;var p=d<=i?1:i+26<=d?26:d-i;if(fL(A/m)&&T("overflow"),h*=m}var v=t.length+1;i=U(s-c,v,0==c),L(s/v)>A-o&&T("overflow"),o+=L(s/v),s%=v,t.splice(s++,0,o)}return String.fromCodePoint.apply(String,t)},u=function(e){var r=[],t=(e=N(e)).length,a=128,s=0,o=72,i=!0,n=!1,l=void 0;try{for(var u,c=e[Symbol.iterator]();!(i=(u=c.next()).done);i=!0){var h=u.value;h<128&&r.push(z(h))}}catch(e){n=!0,l=e}finally{try{!i&&c.return&&c.return()}finally{if(n)throw l}}var d=r.length,f=d;for(d&&r.push("-");fL((A-s)/w)&&T("overflow"),s+=(p-a)*w,a=p;var S=!0,b=!1,_=void 0;try{for(var F,x=e[Symbol.iterator]();!(S=(F=x.next()).done);S=!0){var R=F.value;if(RA&&T("overflow"),R==a){for(var $=s,D=36;;D+=36){var j=D<=o?1:o+26<=D?26:D-o;if($>6|192).toString(16).toUpperCase()+"%"+(63&r|128).toString(16).toUpperCase():"%"+(r>>12|224).toString(16).toUpperCase()+"%"+(r>>6&63|128).toString(16).toUpperCase()+"%"+(63&r|128).toString(16).toUpperCase()}function f(e){for(var r="",t=0,a=e.length;tA-Z\\x5E-\\x7E]",'[\\"\\\\]'),Z=new RegExp(M,"g"),G=new RegExp(B,"g"),Y=new RegExp(C("[^]","[A-Za-z0-9\\!\\$\\%\\'\\*\\+\\-\\^\\_\\`\\{\\|\\}\\~]","[\\.]",'[\\"]',J),"g"),W=new RegExp(C("[^]",M,"[\\!\\$\\'\\(\\)\\*\\+\\,\\;\\:\\@]"),"g"),X=W;function ee(e){var r=f(e);return r.match(Z)?r:e}var re={scheme:"mailto",parse:function(e,r){var t=e,a=t.to=t.path?t.path.split(","):[];if(t.path=void 0,t.query){for(var s=!1,o={},i=t.query.split("&"),n=0,l=i.length;n | null, options?: ErrorsTextOptions): string; - errors?: Array; + errors?: Array | null; } interface CustomLogger { @@ -163,7 +163,9 @@ declare namespace ajv { sourceCode?: boolean; processCode?: (code: string) => string; cache?: object; - logger?: CustomLogger | false + logger?: CustomLogger | false; + nullable?: boolean; + serialize?: ((schema: object | boolean) => any) | false; } type FormatValidator = string | RegExp | ((data: string) => boolean | PromiseLike); diff --git a/tools/node_modules/eslint/node_modules/ajv/lib/ajv.js b/tools/node_modules/eslint/node_modules/ajv/lib/ajv.js index 4740eb6a7db4b3..9f16723aa80774 100644 --- a/tools/node_modules/eslint/node_modules/ajv/lib/ajv.js +++ b/tools/node_modules/eslint/node_modules/ajv/lib/ajv.js @@ -70,8 +70,9 @@ function Ajv(opts) { this._metaOpts = getMetaSchemaOptions(this); if (opts.formats) addInitialFormats(this); - addDraft6MetaSchema(this); + addDefaultMetaSchema(this); if (typeof opts.meta == 'object') this.addMetaSchema(opts.meta); + if (opts.nullable) this.addKeyword('nullable', {metaSchema: {const: true}}); addInitialSchemas(this); } @@ -443,7 +444,7 @@ function addFormat(name, format) { } -function addDraft6MetaSchema(self) { +function addDefaultMetaSchema(self) { var $dataSchema; if (self._opts.$data) { $dataSchema = require('./refs/data.json'); diff --git a/tools/node_modules/eslint/node_modules/ajv/lib/dot/validate.jst b/tools/node_modules/eslint/node_modules/ajv/lib/dot/validate.jst index 27393cf300c03e..89a5b3b49f0f59 100644 --- a/tools/node_modules/eslint/node_modules/ajv/lib/dot/validate.jst +++ b/tools/node_modules/eslint/node_modules/ajv/lib/dot/validate.jst @@ -100,6 +100,16 @@ var $typeSchema = it.schema.type , $typeIsArray = Array.isArray($typeSchema); + if ($typeSchema && it.opts.nullable && it.schema.nullable === true) { + if ($typeIsArray) { + if ($typeSchema.indexOf('null') == -1) + $typeSchema = $typeSchema.concat('null'); + } else if ($typeSchema != 'null') { + $typeSchema = [$typeSchema, 'null']; + $typeIsArray = true; + } + } + if ($typeIsArray && $typeSchema.length == 1) { $typeSchema = $typeSchema[0]; $typeIsArray = false; diff --git a/tools/node_modules/eslint/node_modules/ajv/lib/dotjs/validate.js b/tools/node_modules/eslint/node_modules/ajv/lib/dotjs/validate.js index 9f9e1ae4079b83..019c193ac148b0 100644 --- a/tools/node_modules/eslint/node_modules/ajv/lib/dotjs/validate.js +++ b/tools/node_modules/eslint/node_modules/ajv/lib/dotjs/validate.js @@ -101,6 +101,14 @@ module.exports = function generate_validate(it, $keyword, $ruleType) { var $errorKeyword; var $typeSchema = it.schema.type, $typeIsArray = Array.isArray($typeSchema); + if ($typeSchema && it.opts.nullable && it.schema.nullable === true) { + if ($typeIsArray) { + if ($typeSchema.indexOf('null') == -1) $typeSchema = $typeSchema.concat('null'); + } else if ($typeSchema != 'null') { + $typeSchema = [$typeSchema, 'null']; + $typeIsArray = true; + } + } if ($typeIsArray && $typeSchema.length == 1) { $typeSchema = $typeSchema[0]; $typeIsArray = false; diff --git a/tools/node_modules/eslint/node_modules/ajv/package.json b/tools/node_modules/eslint/node_modules/ajv/package.json index 426998a4f7b59b..e508c3a61cdab7 100644 --- a/tools/node_modules/eslint/node_modules/ajv/package.json +++ b/tools/node_modules/eslint/node_modules/ajv/package.json @@ -16,7 +16,7 @@ "description": "Another JSON Schema Validator", "devDependencies": { "ajv-async": "^1.0.0", - "bluebird": "3.5.1", + "bluebird": "^3.5.3", "brfs": "^2.0.0", "browserify": "^16.2.0", "chai": "^4.0.1", @@ -96,5 +96,5 @@ }, "tonicExampleFilename": ".tonic_example.js", "typings": "lib/ajv.d.ts", - "version": "6.5.5" + "version": "6.6.1" } \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/array-union/index.js b/tools/node_modules/eslint/node_modules/array-union/index.js deleted file mode 100644 index e33f38a1eb4acd..00000000000000 --- a/tools/node_modules/eslint/node_modules/array-union/index.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; -var arrayUniq = require('array-uniq'); - -module.exports = function () { - return arrayUniq([].concat.apply([], arguments)); -}; diff --git a/tools/node_modules/eslint/node_modules/array-union/license b/tools/node_modules/eslint/node_modules/array-union/license deleted file mode 100644 index 654d0bfe943437..00000000000000 --- a/tools/node_modules/eslint/node_modules/array-union/license +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -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/tools/node_modules/eslint/node_modules/array-union/package.json b/tools/node_modules/eslint/node_modules/array-union/package.json deleted file mode 100644 index abfa223ebe3321..00000000000000 --- a/tools/node_modules/eslint/node_modules/array-union/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "bugs": { - "url": "https://github.com/sindresorhus/array-union/issues" - }, - "bundleDependencies": false, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "deprecated": false, - "description": "Create an array of unique values, in order, from the input arrays", - "devDependencies": { - "ava": "*", - "xo": "*" - }, - "engines": { - "node": ">=0.10.0" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/sindresorhus/array-union#readme", - "keywords": [ - "array", - "arr", - "set", - "uniq", - "unique", - "duplicate", - "remove", - "union", - "combine", - "merge" - ], - "license": "MIT", - "name": "array-union", - "repository": { - "type": "git", - "url": "git+https://github.com/sindresorhus/array-union.git" - }, - "scripts": { - "test": "xo && ava" - }, - "version": "1.0.2" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/array-union/readme.md b/tools/node_modules/eslint/node_modules/array-union/readme.md deleted file mode 100644 index ea472dd079613b..00000000000000 --- a/tools/node_modules/eslint/node_modules/array-union/readme.md +++ /dev/null @@ -1,28 +0,0 @@ -# array-union [![Build Status](https://travis-ci.org/sindresorhus/array-union.svg?branch=master)](https://travis-ci.org/sindresorhus/array-union) - -> Create an array of unique values, in order, from the input arrays - - -## Install - -``` -$ npm install --save array-union -``` - - -## Usage - -```js -const arrayUnion = require('array-union'); - -arrayUnion([1, 1, 2, 3], [2, 3]); -//=> [1, 2, 3] - -arrayUnion(['foo', 'foo', 'bar'], ['foo']); -//=> ['foo', 'bar'] -``` - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/tools/node_modules/eslint/node_modules/array-uniq/index.js b/tools/node_modules/eslint/node_modules/array-uniq/index.js deleted file mode 100644 index edd09f8114b1a0..00000000000000 --- a/tools/node_modules/eslint/node_modules/array-uniq/index.js +++ /dev/null @@ -1,62 +0,0 @@ -'use strict'; - -// there's 3 implementations written in increasing order of efficiency - -// 1 - no Set type is defined -function uniqNoSet(arr) { - var ret = []; - - for (var i = 0; i < arr.length; i++) { - if (ret.indexOf(arr[i]) === -1) { - ret.push(arr[i]); - } - } - - return ret; -} - -// 2 - a simple Set type is defined -function uniqSet(arr) { - var seen = new Set(); - return arr.filter(function (el) { - if (!seen.has(el)) { - seen.add(el); - return true; - } - - return false; - }); -} - -// 3 - a standard Set type is defined and it has a forEach method -function uniqSetWithForEach(arr) { - var ret = []; - - (new Set(arr)).forEach(function (el) { - ret.push(el); - }); - - return ret; -} - -// V8 currently has a broken implementation -// https://github.com/joyent/node/issues/8449 -function doesForEachActuallyWork() { - var ret = false; - - (new Set([true])).forEach(function (el) { - ret = el; - }); - - return ret === true; -} - -if ('Set' in global) { - if (typeof Set.prototype.forEach === 'function' && doesForEachActuallyWork()) { - module.exports = uniqSetWithForEach; - } else { - module.exports = uniqSet; - } -} else { - module.exports = uniqNoSet; -} diff --git a/tools/node_modules/eslint/node_modules/array-uniq/license b/tools/node_modules/eslint/node_modules/array-uniq/license deleted file mode 100644 index 654d0bfe943437..00000000000000 --- a/tools/node_modules/eslint/node_modules/array-uniq/license +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -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/tools/node_modules/eslint/node_modules/array-uniq/package.json b/tools/node_modules/eslint/node_modules/array-uniq/package.json deleted file mode 100644 index 6b878a386c74a7..00000000000000 --- a/tools/node_modules/eslint/node_modules/array-uniq/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "bugs": { - "url": "https://github.com/sindresorhus/array-uniq/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Create an array without duplicates", - "devDependencies": { - "ava": "*", - "es6-set": "^0.1.0", - "require-uncached": "^1.0.2", - "xo": "*" - }, - "engines": { - "node": ">=0.10.0" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/sindresorhus/array-uniq#readme", - "keywords": [ - "array", - "arr", - "set", - "uniq", - "unique", - "es6", - "duplicate", - "remove" - ], - "license": "MIT", - "name": "array-uniq", - "repository": { - "type": "git", - "url": "git+https://github.com/sindresorhus/array-uniq.git" - }, - "scripts": { - "test": "xo && ava" - }, - "version": "1.0.3" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/array-uniq/readme.md b/tools/node_modules/eslint/node_modules/array-uniq/readme.md deleted file mode 100644 index f0bd98c4f053c9..00000000000000 --- a/tools/node_modules/eslint/node_modules/array-uniq/readme.md +++ /dev/null @@ -1,30 +0,0 @@ -# array-uniq [![Build Status](https://travis-ci.org/sindresorhus/array-uniq.svg?branch=master)](https://travis-ci.org/sindresorhus/array-uniq) - -> Create an array without duplicates - -It's already pretty fast, but will be much faster when [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) becomes available in V8 (especially with large arrays). - - -## Install - -``` -$ npm install --save array-uniq -``` - - -## Usage - -```js -const arrayUniq = require('array-uniq'); - -arrayUniq([1, 1, 2, 3, 3]); -//=> [1, 2, 3] - -arrayUniq(['foo', 'foo', 'bar', 'foo']); -//=> ['foo', 'bar'] -``` - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/tools/node_modules/eslint/node_modules/astral-regex/index.js b/tools/node_modules/eslint/node_modules/astral-regex/index.js new file mode 100644 index 00000000000000..f90e6a225c40ca --- /dev/null +++ b/tools/node_modules/eslint/node_modules/astral-regex/index.js @@ -0,0 +1,4 @@ +'use strict'; +const regex = '[\uD800-\uDBFF][\uDC00-\uDFFF]'; + +module.exports = opts => opts && opts.exact ? new RegExp(`^${regex}$`) : new RegExp(regex, 'g'); diff --git a/tools/node_modules/eslint/node_modules/pify/license b/tools/node_modules/eslint/node_modules/astral-regex/license similarity index 92% rename from tools/node_modules/eslint/node_modules/pify/license rename to tools/node_modules/eslint/node_modules/astral-regex/license index e7af2f77107d73..db6bc32cc7c44e 100644 --- a/tools/node_modules/eslint/node_modules/pify/license +++ b/tools/node_modules/eslint/node_modules/astral-regex/license @@ -1,6 +1,6 @@ MIT License -Copyright (c) Sindre Sorhus (sindresorhus.com) +Copyright (c) Kevin Mårtensson (github.com/kevva) 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: diff --git a/tools/node_modules/eslint/node_modules/astral-regex/package.json b/tools/node_modules/eslint/node_modules/astral-regex/package.json new file mode 100644 index 00000000000000..61089098b382bc --- /dev/null +++ b/tools/node_modules/eslint/node_modules/astral-regex/package.json @@ -0,0 +1,41 @@ +{ + "author": { + "name": "Kevin Mårtensson", + "email": "kevinmartensson@gmail.com", + "url": "github.com/kevva" + }, + "bugs": { + "url": "https://github.com/kevva/astral-regex/issues" + }, + "bundleDependencies": false, + "dependencies": {}, + "deprecated": false, + "description": "Regular expression for matching astral symbols", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "engines": { + "node": ">=4" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/kevva/astral-regex#readme", + "keywords": [ + "astral", + "emoji", + "regex", + "surrogate" + ], + "license": "MIT", + "name": "astral-regex", + "repository": { + "type": "git", + "url": "git+https://github.com/kevva/astral-regex.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "1.0.0" +} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/astral-regex/readme.md b/tools/node_modules/eslint/node_modules/astral-regex/readme.md new file mode 100644 index 00000000000000..cde44f7bc0cc83 --- /dev/null +++ b/tools/node_modules/eslint/node_modules/astral-regex/readme.md @@ -0,0 +1,43 @@ +# astral-regex [![Build Status](https://travis-ci.org/kevva/astral-regex.svg?branch=master)](https://travis-ci.org/kevva/astral-regex) + +> Regular expression for matching astral symbols + + +## Install + +``` +$ npm install astral-regex +``` + + +## Usage + +```js +const astralRegex = require('astral-regex'); + +astralRegex({exact: true}).test(''); +//=> true +``` + + +## API + +### astralRegex([options]) + +Returns a `RegExp` for matching astral symbols. + +#### options + +Type: `Object` + +##### exact + +Type: `boolean`
+Default: `false` *(Matches any astral symbols in a string)* + +Only match an exact string. Useful with `RegExp#test()` to check if a string is a astral symbol. + + +## License + +MIT © [Kevin Mårtensson](https://github.com/kevva) diff --git a/tools/node_modules/eslint/node_modules/del/index.js b/tools/node_modules/eslint/node_modules/del/index.js deleted file mode 100644 index 3b602af374f9e7..00000000000000 --- a/tools/node_modules/eslint/node_modules/del/index.js +++ /dev/null @@ -1,70 +0,0 @@ -'use strict'; -const path = require('path'); -const globby = require('globby'); -const isPathCwd = require('is-path-cwd'); -const isPathInCwd = require('is-path-in-cwd'); -const pify = require('pify'); -const rimraf = require('rimraf'); -const pMap = require('p-map'); - -const rimrafP = pify(rimraf); - -function safeCheck(file) { - if (isPathCwd(file)) { - throw new Error('Cannot delete the current working directory. Can be overriden with the `force` option.'); - } - - if (!isPathInCwd(file)) { - throw new Error('Cannot delete files/folders outside the current working directory. Can be overriden with the `force` option.'); - } -} - -module.exports = (patterns, opts) => { - opts = Object.assign({}, opts); - - const force = opts.force; - delete opts.force; - - const dryRun = opts.dryRun; - delete opts.dryRun; - - const mapper = file => { - if (!force) { - safeCheck(file); - } - - file = path.resolve(opts.cwd || '', file); - - if (dryRun) { - return file; - } - - return rimrafP(file, {glob: false}).then(() => file); - }; - - return globby(patterns, opts).then(files => pMap(files, mapper, opts)); -}; - -module.exports.sync = (patterns, opts) => { - opts = Object.assign({}, opts); - - const force = opts.force; - delete opts.force; - - const dryRun = opts.dryRun; - delete opts.dryRun; - - return globby.sync(patterns, opts).map(file => { - if (!force) { - safeCheck(file); - } - - file = path.resolve(opts.cwd || '', file); - - if (!dryRun) { - rimraf.sync(file, {glob: false}); - } - - return file; - }); -}; diff --git a/tools/node_modules/eslint/node_modules/del/package.json b/tools/node_modules/eslint/node_modules/del/package.json deleted file mode 100644 index ce3433dce6550e..00000000000000 --- a/tools/node_modules/eslint/node_modules/del/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "bugs": { - "url": "https://github.com/sindresorhus/del/issues" - }, - "bundleDependencies": false, - "dependencies": { - "globby": "^6.1.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "p-map": "^1.1.1", - "pify": "^3.0.0", - "rimraf": "^2.2.8" - }, - "deprecated": false, - "description": "Delete files and folders", - "devDependencies": { - "ava": "*", - "make-dir": "^1.0.0", - "tempy": "^0.1.0", - "xo": "*" - }, - "engines": { - "node": ">=4" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/sindresorhus/del#readme", - "keywords": [ - "delete", - "files", - "folders", - "directories", - "del", - "remove", - "destroy", - "trash", - "unlink", - "clean", - "cleaning", - "cleanup", - "rm", - "rmrf", - "rimraf", - "rmdir", - "glob", - "gulpfriendly", - "file", - "folder", - "directory", - "dir", - "fs", - "filesystem" - ], - "license": "MIT", - "name": "del", - "repository": { - "type": "git", - "url": "git+https://github.com/sindresorhus/del.git" - }, - "scripts": { - "test": "xo && ava" - }, - "version": "3.0.0" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/del/readme.md b/tools/node_modules/eslint/node_modules/del/readme.md deleted file mode 100644 index 664aa0f67fb06c..00000000000000 --- a/tools/node_modules/eslint/node_modules/del/readme.md +++ /dev/null @@ -1,121 +0,0 @@ -# del [![Build Status](https://travis-ci.org/sindresorhus/del.svg?branch=master)](https://travis-ci.org/sindresorhus/del) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) - -> Delete files and folders using [globs](https://github.com/isaacs/minimatch#usage) - -Similar to [rimraf](https://github.com/isaacs/rimraf), but with a Promise API and support for multiple files and globbing. It also protects you against deleting the current working directory and above. - ---- - -

🐶

-

Support this project and improve your JavaScript skills with this great ES6 course by Wes Bos.
Try his free JavaScript 30 course for a taste of what to expect. You might also like his React and Sublime course.

- ---- - - -## Install - -``` -$ npm install --save del -``` - - -## Usage - -```js -const del = require('del'); - -del(['tmp/*.js', '!tmp/unicorn.js']).then(paths => { - console.log('Deleted files and folders:\n', paths.join('\n')); -}); -``` - - -## Beware - -The glob pattern `**` matches all children and *the parent*. - -So this won't work: - -```js -del.sync(['public/assets/**', '!public/assets/goat.png']); -``` - -You have to explicitly ignore the parent directories too: - -```js -del.sync(['public/assets/**', '!public/assets', '!public/assets/goat.png']); -``` - -Suggestions on how to improve this welcome! - - -## API - -### del(patterns, [options]) - -Returns a promise for an array of deleted paths. - -### del.sync(patterns, [options]) - -Returns an array of deleted paths. - -#### patterns - -Type: `string` `Array` - -See supported minimatch [patterns](https://github.com/isaacs/minimatch#usage). - -- [Pattern examples with expected matches](https://github.com/sindresorhus/multimatch/blob/master/test.js) -- [Quick globbing pattern overview](https://github.com/sindresorhus/multimatch#globbing-patterns) - -#### options - -Type: `Object` - -See the [`glob` options](https://github.com/isaacs/node-glob#options). - -##### force - -Type: `boolean`
-Default: `false` - -Allow deleting the current working directory and outside. - -##### dryRun - -Type: `boolean`
-Default: `false` - -See what would be deleted. - -```js -const del = require('del'); - -del(['tmp/*.js'], {dryRun: true}).then(paths => { - console.log('Files and folders that would be deleted:\n', paths.join('\n')); -}); -``` - -##### concurrency - -Type: `number`
-Default: `Infinity`
-Minimum: `1` - -Concurrency limit. - - -## CLI - -See [del-cli](https://github.com/sindresorhus/del-cli) for a CLI for this module and [trash-cli](https://github.com/sindresorhus/trash-cli) for a safe version that is suitable for running by hand. - - -## Related - -- [make-dir](https://github.com/sindresorhus/make-dir) - Make a directory and its parents if needed -- [globby](https://github.com/sindresorhus/globby) - User-friendly glob matching - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/tools/node_modules/eslint/node_modules/espree/README.md b/tools/node_modules/eslint/node_modules/espree/README.md index 16fb93f85607e2..7e496f661987a7 100644 --- a/tools/node_modules/eslint/node_modules/espree/README.md +++ b/tools/node_modules/eslint/node_modules/espree/README.md @@ -12,24 +12,24 @@ Espree started out as a fork of [Esprima](http://esprima.org) v1.2.2, the last s Install: ``` -npm i espree --save +npm i espree ``` And in your Node.js code: ```javascript -var espree = require("espree"); +const espree = require("espree"); -var ast = espree.parse(code); +const ast = espree.parse(code); ``` There is a second argument to `parse()` that allows you to specify various options: ```javascript -var espree = require("espree"); +const espree = require("espree"); // Optional second options argument with the following default settings -var ast = espree.parse(code, { +const ast = espree.parse(code, { // attach range information to each node range: false, @@ -40,9 +40,6 @@ var ast = espree.parse(code, { // create a top-level comments array containing all comments comment: false, - // attach comments to the closest relevant node as leadingComments and trailingComments - attachComment: false, - // create a top-level tokens array containing all tokens tokens: false, diff --git a/tools/node_modules/eslint/node_modules/espree/espree.js b/tools/node_modules/eslint/node_modules/espree/espree.js index dea35ef083db54..7c16b696563656 100644 --- a/tools/node_modules/eslint/node_modules/espree/espree.js +++ b/tools/node_modules/eslint/node_modules/espree/espree.js @@ -88,6 +88,7 @@ const parsers = { options.ecmaFeatures && options.ecmaFeatures.jsx ); + return useJsx ? this.jsx : this.regular; } }; @@ -109,7 +110,7 @@ function tokenize(code, options) { // Ensure to collect tokens. if (!options || options.tokens !== true) { - options = Object.assign({}, options, { tokens: true }); + options = Object.assign({}, options, { tokens: true }); // eslint-disable-line no-param-reassign } return new Parser(options, code).tokenize(); @@ -128,6 +129,7 @@ function tokenize(code, options) { */ function parse(code, options) { const Parser = parsers.get(options); + return new Parser(options, code).parse(); } @@ -144,7 +146,8 @@ exports.parse = parse; // Deep copy. /* istanbul ignore next */ exports.Syntax = (function() { - var name, types = {}; + let name, + types = {}; if (typeof Object.create === "function") { types = Object.create(null); diff --git a/tools/node_modules/eslint/node_modules/espree/lib/comment-attachment.js b/tools/node_modules/eslint/node_modules/espree/lib/comment-attachment.js deleted file mode 100644 index b82b5f1cd39cdd..00000000000000 --- a/tools/node_modules/eslint/node_modules/espree/lib/comment-attachment.js +++ /dev/null @@ -1,175 +0,0 @@ -/** - * @fileoverview Attaches comments to the AST. - * @author Nicholas C. Zakas - */ - -"use strict"; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -var astNodeTypes = require("./ast-node-types"); - -//------------------------------------------------------------------------------ -// Private -//------------------------------------------------------------------------------ - -var extra = { - trailingComments: [], - leadingComments: [], - bottomRightStack: [], - previousNode: null -}; - -//------------------------------------------------------------------------------ -// Public -//------------------------------------------------------------------------------ - -module.exports = { - - reset: function() { - extra.trailingComments = []; - extra.leadingComments = []; - extra.bottomRightStack = []; - extra.previousNode = null; - }, - - addComment: function(comment) { - extra.trailingComments.push(comment); - extra.leadingComments.push(comment); - }, - - processComment: function(node) { - var lastChild, - trailingComments, - i, - j; - - if (node.type === astNodeTypes.Program) { - if (node.body.length > 0) { - return; - } - } - - if (extra.trailingComments.length > 0) { - - /* - * If the first comment in trailingComments comes after the - * current node, then we're good - all comments in the array will - * come after the node and so it's safe to add then as official - * trailingComments. - */ - if (extra.trailingComments[0].range[0] >= node.range[1]) { - trailingComments = extra.trailingComments; - extra.trailingComments = []; - } else { - - /* - * Otherwise, if the first comment doesn't come after the - * current node, that means we have a mix of leading and trailing - * comments in the array and that leadingComments contains the - * same items as trailingComments. Reset trailingComments to - * zero items and we'll handle this by evaluating leadingComments - * later. - */ - extra.trailingComments.length = 0; - } - } else { - if (extra.bottomRightStack.length > 0 && - extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments && - extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments[0].range[0] >= node.range[1]) { - trailingComments = extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments; - delete extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments; - } - } - - // Eating the stack. - while (extra.bottomRightStack.length > 0 && extra.bottomRightStack[extra.bottomRightStack.length - 1].range[0] >= node.range[0]) { - lastChild = extra.bottomRightStack.pop(); - } - - if (lastChild) { - if (lastChild.leadingComments) { - if (lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] <= node.range[0]) { - node.leadingComments = lastChild.leadingComments; - delete lastChild.leadingComments; - } else { - // A leading comment for an anonymous class had been stolen by its first MethodDefinition, - // so this takes back the leading comment. - // See Also: https://github.com/eslint/espree/issues/158 - for (i = lastChild.leadingComments.length - 2; i >= 0; --i) { - if (lastChild.leadingComments[i].range[1] <= node.range[0]) { - node.leadingComments = lastChild.leadingComments.splice(0, i + 1); - break; - } - } - } - } - } else if (extra.leadingComments.length > 0) { - if (extra.leadingComments[extra.leadingComments.length - 1].range[1] <= node.range[0]) { - if (extra.previousNode) { - for (j = 0; j < extra.leadingComments.length; j++) { - if (extra.leadingComments[j].end < extra.previousNode.end) { - extra.leadingComments.splice(j, 1); - j--; - } - } - } - if (extra.leadingComments.length > 0) { - node.leadingComments = extra.leadingComments; - extra.leadingComments = []; - } - } else { - - // https://github.com/eslint/espree/issues/2 - - /* - * In special cases, such as return (without a value) and - * debugger, all comments will end up as leadingComments and - * will otherwise be eliminated. This extra step runs when the - * bottomRightStack is empty and there are comments left - * in leadingComments. - * - * This loop figures out the stopping point between the actual - * leading and trailing comments by finding the location of the - * first comment that comes after the given node. - */ - for (i = 0; i < extra.leadingComments.length; i++) { - if (extra.leadingComments[i].range[1] > node.range[0]) { - break; - } - } - - /* - * Split the array based on the location of the first comment - * that comes after the node. Keep in mind that this could - * result in an empty array, and if so, the array must be - * deleted. - */ - node.leadingComments = extra.leadingComments.slice(0, i); - if (node.leadingComments.length === 0) { - delete node.leadingComments; - } - - /* - * Similarly, trailing comments are attached later. The variable - * must be reset to null if there are no trailing comments. - */ - trailingComments = extra.leadingComments.slice(i); - if (trailingComments.length === 0) { - trailingComments = null; - } - } - } - - extra.previousNode = node; - - if (trailingComments) { - node.trailingComments = trailingComments; - } - - extra.bottomRightStack.push(node); - } - -}; diff --git a/tools/node_modules/eslint/node_modules/espree/lib/espree.js b/tools/node_modules/eslint/node_modules/espree/lib/espree.js index 3b4d1eab65d379..107affd1d6ca26 100644 --- a/tools/node_modules/eslint/node_modules/espree/lib/espree.js +++ b/tools/node_modules/eslint/node_modules/espree/lib/espree.js @@ -1,8 +1,8 @@ "use strict"; +/* eslint-disable no-param-reassign*/ const acorn = require("acorn"); const jsx = require("acorn-jsx"); -const commentAttachment = require("./comment-attachment"); const TokenTranslator = require("./token-translator"); const DEFAULT_ECMA_VERSION = 5; @@ -89,23 +89,24 @@ module.exports = () => Parser => class Espree extends Parser { const ecmaVersion = normalizeEcmaVersion(options.ecmaVersion); const isModule = options.sourceType === "module"; const tokenTranslator = - options.tokens === true ? - new TokenTranslator(tokTypes, code) : - null; + options.tokens === true + ? new TokenTranslator(tokTypes, code) + : null; // Initialize acorn parser. super({ ecmaVersion: isModule ? Math.max(6, ecmaVersion) : ecmaVersion, sourceType: isModule ? "module" : "script", - ranges: options.range === true || options.attachComment === true, + ranges: options.range === true, locations: options.loc === true, // Truthy value is true for backward compatibility. allowReturnOutsideFunction: Boolean(ecmaFeatures.globalReturn), // Collect tokens - onToken: (token) => { + onToken: token => { if (tokenTranslator) { + // Use `tokens`, `ecmaVersion`, and `jsxAttrValueToken` in the state. tokenTranslator.onToken(token, this[STATE]); } @@ -118,23 +119,16 @@ module.exports = () => Parser => class Espree extends Parser { onComment: (block, text, start, end, startLoc, endLoc) => { if (this[STATE].comments) { const comment = convertAcornCommentToEsprimaComment(block, text, start, end, startLoc, endLoc); - this[STATE].comments.push(comment); - if (options.attachComment === true) { - commentAttachment.addComment(comment); - } + this[STATE].comments.push(comment); } } }, code); - // TODO: remove global state. - commentAttachment.reset(); - // Initialize internal state. this[STATE] = { tokens: tokenTranslator ? [] : null, - comments: options.comment === true || options.attachComment === true ? [] : null, - attachComment: options.attachComment === true, + comments: options.comment === true ? [] : null, impliedStrict: ecmaFeatures.impliedStrict === true && this.options.ecmaVersion >= 5, ecmaVersion: this.options.ecmaVersion, jsxAttrValueToken: false, @@ -159,11 +153,13 @@ module.exports = () => Parser => class Espree extends Parser { finishNode(...args) { const result = super.finishNode(...args); + return this[ESPRIMA_FINISH_NODE](result); } finishNodeAt(...args) { const result = super.finishNodeAt(...args); + return this[ESPRIMA_FINISH_NODE](result); } @@ -216,6 +212,7 @@ module.exports = () => Parser => class Espree extends Parser { raise(pos, message) { const loc = acorn.getLineInfo(this.input, pos); const err = new SyntaxError(message); + err.index = pos; err.lineNumber = loc.line; err.column = loc.column + 1; // acorn uses 0-based columns @@ -256,7 +253,7 @@ module.exports = () => Parser => class Espree extends Parser { } if (this.end > this.start) { - message += " " + this.input.slice(this.start, this.end); + message += ` ${this.input.slice(this.start, this.end)}`; } this.raise(this.start, message); @@ -271,6 +268,7 @@ module.exports = () => Parser => class Espree extends Parser { */ jsx_readString(quote) { // eslint-disable-line camelcase const result = super.jsx_readString(quote); + if (this.type === tokTypes.string) { this[STATE].jsxAttrValueToken = true; } @@ -283,6 +281,7 @@ module.exports = () => Parser => class Espree extends Parser { * @returns {ASTNode} The finished node. */ [ESPRIMA_FINISH_NODE](result) { + // Acorn doesn't count the opening and closing backticks as part of templates // so we have to adjust ranges/locations appropriately. if (result.type === "TemplateElement") { @@ -301,10 +300,6 @@ module.exports = () => Parser => class Espree extends Parser { } } - if (this[STATE].attachComment) { - commentAttachment.processComment(result); - } - if (result.type.indexOf("Function") > -1 && !result.generator) { result.generator = false; } diff --git a/tools/node_modules/eslint/node_modules/espree/lib/token-translator.js b/tools/node_modules/eslint/node_modules/espree/lib/token-translator.js index f47b3621beb269..9919e1af236476 100644 --- a/tools/node_modules/eslint/node_modules/espree/lib/token-translator.js +++ b/tools/node_modules/eslint/node_modules/espree/lib/token-translator.js @@ -18,7 +18,7 @@ // Esprima Token Types -var Token = { +const Token = { Boolean: "Boolean", EOF: "", Identifier: "Identifier", @@ -41,10 +41,10 @@ var Token = { * @private */ function convertTemplatePart(tokens, code) { - var firstToken = tokens[0], + const firstToken = tokens[0], lastTemplateToken = tokens[tokens.length - 1]; - var token = { + const token = { type: Token.Template, value: code.slice(firstToken.start, lastTemplateToken.end) }; @@ -99,9 +99,9 @@ TokenTranslator.prototype = { * @param {Object} extra Espree extra object. * @returns {EsprimaToken} The Esprima version of the token. */ - translate: function(token, extra) { + translate(token, extra) { - var type = token.type, + const type = token.type, tt = this._acornTokTypes; if (type === tt.name) { @@ -157,12 +157,13 @@ TokenTranslator.prototype = { token.value = this._code.slice(token.start, token.end); } else if (type === tt.regexp) { token.type = Token.RegularExpression; - var value = token.value; + const value = token.value; + token.regex = { flags: value.flags, pattern: value.pattern }; - token.value = "/" + value.pattern + "/" + value.flags; + token.value = `/${value.pattern}/${value.flags}`; } return token; @@ -174,9 +175,9 @@ TokenTranslator.prototype = { * @param {Object} extra The Espree extra object. * @returns {void} */ - onToken: function(token, extra) { + onToken(token, extra) { - var that = this, + const that = this, tt = this._acornTokTypes, tokens = extra.tokens, templateTokens = this._tokens; @@ -218,11 +219,13 @@ TokenTranslator.prototype = { } return; - } else if (token.type === tt.dollarBraceL) { + } + if (token.type === tt.dollarBraceL) { templateTokens.push(token); translateTemplateTokens(); return; - } else if (token.type === tt.braceR) { + } + if (token.type === tt.braceR) { // if there's already a curly, it's not part of the template if (this._curlyBrace) { @@ -232,7 +235,8 @@ TokenTranslator.prototype = { // store new curly for later this._curlyBrace = token; return; - } else if (token.type === tt.template || token.type === tt.invalidTemplate) { + } + if (token.type === tt.template || token.type === tt.invalidTemplate) { if (this._curlyBrace) { templateTokens.push(this._curlyBrace); this._curlyBrace = null; diff --git a/tools/node_modules/eslint/node_modules/espree/lib/visitor-keys.js b/tools/node_modules/eslint/node_modules/espree/lib/visitor-keys.js new file mode 100644 index 00000000000000..4216864f1c27c9 --- /dev/null +++ b/tools/node_modules/eslint/node_modules/espree/lib/visitor-keys.js @@ -0,0 +1,123 @@ +/** + * @fileoverview The visitor keys for the node types Espree supports + * @author Nicholas C. Zakas + * + * This file contains code from estraverse-fb. + * + * The MIT license. Copyright (c) 2014 Ingvar Stepanyan + * + * 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. + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +// None! + +//------------------------------------------------------------------------------ +// Public +//------------------------------------------------------------------------------ + +module.exports = { + + // ECMAScript + AssignmentExpression: ["left", "right"], + AssignmentPattern: ["left", "right"], + ArrayExpression: ["elements"], + ArrayPattern: ["elements"], + ArrowFunctionExpression: ["params", "body"], + BlockStatement: ["body"], + BinaryExpression: ["left", "right"], + BreakStatement: ["label"], + CallExpression: ["callee", "arguments"], + CatchClause: ["param", "body"], + ClassBody: ["body"], + ClassDeclaration: ["id", "superClass", "body"], + ClassExpression: ["id", "superClass", "body"], + ConditionalExpression: ["test", "consequent", "alternate"], + ContinueStatement: ["label"], + DebuggerStatement: [], + DirectiveStatement: [], + DoWhileStatement: ["body", "test"], + EmptyStatement: [], + ExportAllDeclaration: ["source"], + ExportDefaultDeclaration: ["declaration"], + ExportNamedDeclaration: ["declaration", "specifiers", "source"], + ExportSpecifier: ["exported", "local"], + ExpressionStatement: ["expression"], + ForStatement: ["init", "test", "update", "body"], + ForInStatement: ["left", "right", "body"], + ForOfStatement: ["left", "right", "body"], + FunctionDeclaration: ["id", "params", "body"], + FunctionExpression: ["id", "params", "body"], + Identifier: [], + IfStatement: ["test", "consequent", "alternate"], + ImportDeclaration: ["specifiers", "source"], + ImportDefaultSpecifier: ["local"], + ImportNamespaceSpecifier: ["local"], + ImportSpecifier: ["imported", "local"], + Literal: [], + LabeledStatement: ["label", "body"], + LogicalExpression: ["left", "right"], + MemberExpression: ["object", "property"], + MetaProperty: ["meta", "property"], + MethodDefinition: ["key", "value"], + ModuleSpecifier: [], + NewExpression: ["callee", "arguments"], + ObjectExpression: ["properties"], + ObjectPattern: ["properties"], + Program: ["body"], + Property: ["key", "value"], + RestElement: ["argument"], + ReturnStatement: ["argument"], + SequenceExpression: ["expressions"], + SpreadElement: ["argument"], + Super: [], + SwitchStatement: ["discriminant", "cases"], + SwitchCase: ["test", "consequent"], + TaggedTemplateExpression: ["tag", "quasi"], + TemplateElement: [], + TemplateLiteral: ["quasis", "expressions"], + ThisExpression: [], + ThrowStatement: ["argument"], + TryStatement: ["block", "handler", "finalizer"], + UnaryExpression: ["argument"], + UpdateExpression: ["argument"], + VariableDeclaration: ["declarations"], + VariableDeclarator: ["id", "init"], + WhileStatement: ["test", "body"], + WithStatement: ["object", "body"], + YieldExpression: ["argument"], + + // JSX + JSXIdentifier: [], + JSXNamespacedName: ["namespace", "name"], + JSXMemberExpression: ["object", "property"], + JSXEmptyExpression: [], + JSXExpressionContainer: ["expression"], + JSXElement: ["openingElement", "closingElement", "children"], + JSXClosingElement: ["name"], + JSXOpeningElement: ["name", "attributes"], + JSXAttribute: ["name", "value"], + JSXText: null, + JSXSpreadAttribute: ["argument"] +}; diff --git a/tools/node_modules/eslint/node_modules/espree/package.json b/tools/node_modules/eslint/node_modules/espree/package.json index 91e99e4b2136c0..273d2c5bda0d7c 100644 --- a/tools/node_modules/eslint/node_modules/espree/package.json +++ b/tools/node_modules/eslint/node_modules/espree/package.json @@ -17,8 +17,9 @@ "devDependencies": { "browserify": "^7.0.0", "chai": "^1.10.0", - "eslint": "^2.13.1", - "eslint-config-eslint": "^3.0.0", + "eslint": "^5.7.0", + "eslint-config-eslint": "^5.0.1", + "eslint-plugin-node": "^8.0.0", "eslint-release": "^1.0.0", "esprima": "latest", "esprima-fb": "^8001.2001.0-dev-harmony-fb", @@ -65,5 +66,5 @@ "publish-release": "eslint-publish-release", "test": "npm run-script lint && node Makefile.js test" }, - "version": "4.1.0" + "version": "5.0.0" } \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/flat-cache/cache.js b/tools/node_modules/eslint/node_modules/flat-cache/cache.js index 799e09eb7cb0fe..29219c86b1700d 100644 --- a/tools/node_modules/eslint/node_modules/flat-cache/cache.js +++ b/tools/node_modules/eslint/node_modules/flat-cache/cache.js @@ -1,7 +1,7 @@ var path = require( 'path' ); var fs = require( 'graceful-fs' ); -var del = require( 'del' ).sync; var utils = require( './utils' ); +var del = require( './del' ); var writeJSON = utils.writeJSON; var cache = { @@ -125,9 +125,7 @@ var cache = { * @return {Boolean} true or false if the file was successfully deleted */ removeCacheFile: function () { - return del( this._pathToFile, { - force: true - } ); + return del( this._pathToFile ); }, /** * Destroy the file cache and cache content. @@ -185,9 +183,7 @@ module.exports = { */ clearCacheById: function ( docId, cacheDir ) { var filePath = cacheDir ? path.resolve( cacheDir, docId ) : path.resolve( __dirname, './.cache/', docId ); - return del( filePath, { - force: true - } ).length > 0; + return del( filePath ); }, /** * Remove all cache stored in the cache directory @@ -196,8 +192,6 @@ module.exports = { */ clearAll: function ( cacheDir ) { var filePath = cacheDir ? path.resolve( cacheDir ) : path.resolve( __dirname, './.cache/' ); - return del( filePath, { - force: true - } ).length > 0; + return del( filePath ); } }; diff --git a/tools/node_modules/eslint/node_modules/flat-cache/changelog.md b/tools/node_modules/eslint/node_modules/flat-cache/changelog.md index f35f6da4bfeb07..037a08ba17fbb8 100644 --- a/tools/node_modules/eslint/node_modules/flat-cache/changelog.md +++ b/tools/node_modules/eslint/node_modules/flat-cache/changelog.md @@ -1,31 +1,56 @@ # flat-cache - Changelog -## v1.3.2 +## v1.3.4 +- **Refactoring** + - Add del.js and utils.js to the list of files to be beautified - [9d0ca9b]( https://github.com/royriojas/flat-cache/commit/9d0ca9b ), [Roy Riojas](https://github.com/Roy Riojas), 14/11/2018 12:19:02 + + +## v1.3.3 - **Refactoring** - - remove yarn.lock file - [704c6c4]( https://github.com/royriojas/flat-cache/commit/704c6c4 ), [Roy Riojas](https://github.com/Roy Riojas), 07/11/2018 18:41:08 + - Make sure package-lock.json is up to date - [a7d2598]( https://github.com/royriojas/flat-cache/commit/a7d2598 ), [Roy Riojas](https://github.com/Roy Riojas), 14/11/2018 11:36:08 + + +- **Other changes** + - Removed the need for del ([#33](https://github.com/royriojas/flat-cache/issues/33)) - [c429012]( https://github.com/royriojas/flat-cache/commit/c429012 ), [S. Gilroy](https://github.com/S. Gilroy), 13/11/2018 13:56:37 + * Removed the need for del + + Removed the need for del as newer versions have broken backwards + compatibility. del mainly uses rimraf for deleting folders + and files, replaceing it with rimraf only is a minimal change. + + * Disable glob on rimraf calls + + * Added glob disable to wrong call + + * Wrapped rimraf to simplify solution + +## v1.3.2 +- **Refactoring** + - remove yarn.lock file - [704c6c4]( https://github.com/royriojas/flat-cache/commit/704c6c4 ), [Roy Riojas](https://github.com/Roy Riojas), 07/11/2018 15:41:08 + - **undefined** - - replace circular-json with flatted ([#23](https://github.com/royriojas/flat-cache/issues/23))" - [db12d74]( https://github.com/royriojas/flat-cache/commit/db12d74 ), [Roy Riojas](https://github.com/Roy Riojas), 07/11/2018 18:40:39 + - replace circular-json with flatted ([#23](https://github.com/royriojas/flat-cache/issues/23))" - [db12d74]( https://github.com/royriojas/flat-cache/commit/db12d74 ), [Roy Riojas](https://github.com/Roy Riojas), 07/11/2018 15:40:39 This reverts commit 00f689277a75e85fef28e6a048fad227afc525e6. - + ## v1.3.1 - **Refactoring** - - upgrade deps to remove some security warnings - [f405719]( https://github.com/royriojas/flat-cache/commit/f405719 ), [Roy Riojas](https://github.com/Roy Riojas), 06/11/2018 15:07:31 - + - upgrade deps to remove some security warnings - [f405719]( https://github.com/royriojas/flat-cache/commit/f405719 ), [Roy Riojas](https://github.com/Roy Riojas), 06/11/2018 12:07:31 + - **Bug Fixes** - - replace circular-json with flatted ([#23](https://github.com/royriojas/flat-cache/issues/23)) - [00f6892]( https://github.com/royriojas/flat-cache/commit/00f6892 ), [Terry](https://github.com/Terry), 05/11/2018 21:44:16 - + - replace circular-json with flatted ([#23](https://github.com/royriojas/flat-cache/issues/23)) - [00f6892]( https://github.com/royriojas/flat-cache/commit/00f6892 ), [Terry](https://github.com/Terry), 05/11/2018 18:44:16 + - **undefined** - - update del to v3.0.0 ([#26](https://github.com/royriojas/flat-cache/issues/26)) - [d42883f]( https://github.com/royriojas/flat-cache/commit/d42883f ), [Patrick Silva](https://github.com/Patrick Silva), 03/11/2018 03:00:44 + - update del to v3.0.0 ([#26](https://github.com/royriojas/flat-cache/issues/26)) - [d42883f]( https://github.com/royriojas/flat-cache/commit/d42883f ), [Patrick Silva](https://github.com/Patrick Silva), 03/11/2018 01:00:44 Closes #25 ## v1.3.0 - **Other changes** - - Added #all method ([#16](https://github.com/royriojas/flat-cache/issues/16)) - [12293be]( https://github.com/royriojas/flat-cache/commit/12293be ), [Ozair Patel](https://github.com/Ozair Patel), 25/09/2017 16:46:38 + - Added #all method ([#16](https://github.com/royriojas/flat-cache/issues/16)) - [12293be]( https://github.com/royriojas/flat-cache/commit/12293be ), [Ozair Patel](https://github.com/Ozair Patel), 25/09/2017 14:46:38 * Added #all method @@ -39,12 +64,12 @@ * Beautified file - - fix changelog title style ([#14](https://github.com/royriojas/flat-cache/issues/14)) - [af8338a]( https://github.com/royriojas/flat-cache/commit/af8338a ), [前端小武](https://github.com/前端小武), 19/12/2016 23:34:48 + - fix changelog title style ([#14](https://github.com/royriojas/flat-cache/issues/14)) - [af8338a]( https://github.com/royriojas/flat-cache/commit/af8338a ), [前端小武](https://github.com/前端小武), 19/12/2016 20:34:48 ## v1.2.2 - **Bug Fixes** - - Do not crash if cache file is invalid JSON. ([#13](https://github.com/royriojas/flat-cache/issues/13)) - [87beaa6]( https://github.com/royriojas/flat-cache/commit/87beaa6 ), [Roy Riojas](https://github.com/Roy Riojas), 19/12/2016 21:03:35 + - Do not crash if cache file is invalid JSON. ([#13](https://github.com/royriojas/flat-cache/issues/13)) - [87beaa6]( https://github.com/royriojas/flat-cache/commit/87beaa6 ), [Roy Riojas](https://github.com/Roy Riojas), 19/12/2016 18:03:35 Fixes #12 @@ -55,186 +80,186 @@ If the cache is somehow not valid the cache will be discarded an a a new cache will be stored instead - **Other changes** - - Added travis ci support for modern node versions ([#11](https://github.com/royriojas/flat-cache/issues/11)) - [1c2b1f7]( https://github.com/royriojas/flat-cache/commit/1c2b1f7 ), [Amila Welihinda](https://github.com/Amila Welihinda), 11/11/2016 02:47:52 + - Added travis ci support for modern node versions ([#11](https://github.com/royriojas/flat-cache/issues/11)) - [1c2b1f7]( https://github.com/royriojas/flat-cache/commit/1c2b1f7 ), [Amila Welihinda](https://github.com/Amila Welihinda), 10/11/2016 23:47:52 - - Bumping `circular-son` version ([#10](https://github.com/royriojas/flat-cache/issues/10)) - [4d5e861]( https://github.com/royriojas/flat-cache/commit/4d5e861 ), [Andrea Giammarchi](https://github.com/Andrea Giammarchi), 02/08/2016 09:13:52 + - Bumping `circular-son` version ([#10](https://github.com/royriojas/flat-cache/issues/10)) - [4d5e861]( https://github.com/royriojas/flat-cache/commit/4d5e861 ), [Andrea Giammarchi](https://github.com/Andrea Giammarchi), 02/08/2016 07:13:52 As mentioned in https://github.com/WebReflection/circular-json/issues/25 `circular-json` wan't rightly implementing the license field. Latest version bump changed only that bit so that ESLint should now be happy. ## v1.2.1 - **Bug Fixes** - - Add missing utils.js file to the package. closes [#8](https://github.com/royriojas/flat-cache/issues/8) - [ec10cf2]( https://github.com/royriojas/flat-cache/commit/ec10cf2 ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 04:18:57 + - Add missing utils.js file to the package. closes [#8](https://github.com/royriojas/flat-cache/issues/8) - [ec10cf2]( https://github.com/royriojas/flat-cache/commit/ec10cf2 ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 02:18:57 ## v1.2.0 - **Documentation** - - Add documentation about noPrune option - [23e11f9]( https://github.com/royriojas/flat-cache/commit/23e11f9 ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 04:06:49 + - Add documentation about noPrune option - [23e11f9]( https://github.com/royriojas/flat-cache/commit/23e11f9 ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 02:06:49 ## v1.1.0 - **Features** - - Add noPrune option to cache.save() method. closes [#7](https://github.com/royriojas/flat-cache/issues/7) - [2c8016a]( https://github.com/royriojas/flat-cache/commit/2c8016a ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 04:00:29 + - Add noPrune option to cache.save() method. closes [#7](https://github.com/royriojas/flat-cache/issues/7) - [2c8016a]( https://github.com/royriojas/flat-cache/commit/2c8016a ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 02:00:29 - - Add json read and write utility based on circular-json - [c31081e]( https://github.com/royriojas/flat-cache/commit/c31081e ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 10:58:17 + - Add json read and write utility based on circular-json - [c31081e]( https://github.com/royriojas/flat-cache/commit/c31081e ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 08:58:17 - **Bug Fixes** - - Remove UTF16 BOM stripping - [4a41e22]( https://github.com/royriojas/flat-cache/commit/4a41e22 ), [Jean Ponchon](https://github.com/Jean Ponchon), 29/07/2016 04:18:06 + - Remove UTF16 BOM stripping - [4a41e22]( https://github.com/royriojas/flat-cache/commit/4a41e22 ), [Jean Ponchon](https://github.com/Jean Ponchon), 29/07/2016 02:18:06 Since we control both writing and reading of JSON stream, there no needs to handle unicode BOM. - - Use circular-json to handle circular references (fix [#5](https://github.com/royriojas/flat-cache/issues/5)) - [cd7aeed]( https://github.com/royriojas/flat-cache/commit/cd7aeed ), [Jean Ponchon](https://github.com/Jean Ponchon), 25/07/2016 13:11:59 + - Use circular-json to handle circular references (fix [#5](https://github.com/royriojas/flat-cache/issues/5)) - [cd7aeed]( https://github.com/royriojas/flat-cache/commit/cd7aeed ), [Jean Ponchon](https://github.com/Jean Ponchon), 25/07/2016 11:11:59 - **Tests Related fixes** - - Add missing file from eslint test - [d6fa3c3]( https://github.com/royriojas/flat-cache/commit/d6fa3c3 ), [Jean Ponchon](https://github.com/Jean Ponchon), 29/07/2016 04:15:51 + - Add missing file from eslint test - [d6fa3c3]( https://github.com/royriojas/flat-cache/commit/d6fa3c3 ), [Jean Ponchon](https://github.com/Jean Ponchon), 29/07/2016 02:15:51 - - Add test for circular json serialization / deserialization - [07d2ddd]( https://github.com/royriojas/flat-cache/commit/07d2ddd ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 10:59:36 + - Add test for circular json serialization / deserialization - [07d2ddd]( https://github.com/royriojas/flat-cache/commit/07d2ddd ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 08:59:36 - **Refactoring** - - Remove unused read-json-sync - [2be1c24]( https://github.com/royriojas/flat-cache/commit/2be1c24 ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 10:59:18 + - Remove unused read-json-sync - [2be1c24]( https://github.com/royriojas/flat-cache/commit/2be1c24 ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 08:59:18 - **Build Scripts Changes** - - travis tests on 0.12 and 4x - [3a613fd]( https://github.com/royriojas/flat-cache/commit/3a613fd ), [royriojas](https://github.com/royriojas), 15/11/2015 17:34:40 + - travis tests on 0.12 and 4x - [3a613fd]( https://github.com/royriojas/flat-cache/commit/3a613fd ), [royriojas](https://github.com/royriojas), 15/11/2015 14:34:40 - - add eslint-fix task - [fd29e52]( https://github.com/royriojas/flat-cache/commit/fd29e52 ), [royriojas](https://github.com/royriojas), 01/11/2015 18:04:08 + - add eslint-fix task - [fd29e52]( https://github.com/royriojas/flat-cache/commit/fd29e52 ), [royriojas](https://github.com/royriojas), 01/11/2015 15:04:08 - - make sure the test script also verify beautification and linting of files before running tests - [e94e176]( https://github.com/royriojas/flat-cache/commit/e94e176 ), [royriojas](https://github.com/royriojas), 01/11/2015 14:54:48 + - make sure the test script also verify beautification and linting of files before running tests - [e94e176]( https://github.com/royriojas/flat-cache/commit/e94e176 ), [royriojas](https://github.com/royriojas), 01/11/2015 11:54:48 - **Other changes** - - add clearAll for cacheDir - [97383d9]( https://github.com/royriojas/flat-cache/commit/97383d9 ), [xieyaowu](https://github.com/xieyaowu), 31/10/2015 23:02:18 + - add clearAll for cacheDir - [97383d9]( https://github.com/royriojas/flat-cache/commit/97383d9 ), [xieyaowu](https://github.com/xieyaowu), 31/10/2015 21:02:18 ## v1.0.9 - **Bug Fixes** - - wrong default values for changelogx user repo name - [7bb52d1]( https://github.com/royriojas/flat-cache/commit/7bb52d1 ), [royriojas](https://github.com/royriojas), 11/09/2015 17:59:30 + - wrong default values for changelogx user repo name - [7bb52d1]( https://github.com/royriojas/flat-cache/commit/7bb52d1 ), [royriojas](https://github.com/royriojas), 11/09/2015 15:59:30 ## v1.0.8 - **Build Scripts Changes** - - test against node 4 - [c395b66]( https://github.com/royriojas/flat-cache/commit/c395b66 ), [royriojas](https://github.com/royriojas), 11/09/2015 17:51:39 + - test against node 4 - [c395b66]( https://github.com/royriojas/flat-cache/commit/c395b66 ), [royriojas](https://github.com/royriojas), 11/09/2015 15:51:39 ## v1.0.7 - **Other changes** - - Move dependencies into devDep - [7e47099]( https://github.com/royriojas/flat-cache/commit/7e47099 ), [Bogdan Chadkin](https://github.com/Bogdan Chadkin), 11/09/2015 17:10:57 + - Move dependencies into devDep - [7e47099]( https://github.com/royriojas/flat-cache/commit/7e47099 ), [Bogdan Chadkin](https://github.com/Bogdan Chadkin), 11/09/2015 15:10:57 - **Documentation** - - Add missing changelog link - [f51197a]( https://github.com/royriojas/flat-cache/commit/f51197a ), [royriojas](https://github.com/royriojas), 11/09/2015 16:48:05 + - Add missing changelog link - [f51197a]( https://github.com/royriojas/flat-cache/commit/f51197a ), [royriojas](https://github.com/royriojas), 11/09/2015 14:48:05 ## v1.0.6 - **Build Scripts Changes** - - Add helpers/code check scripts - [bdb82f3]( https://github.com/royriojas/flat-cache/commit/bdb82f3 ), [royriojas](https://github.com/royriojas), 11/09/2015 16:44:31 + - Add helpers/code check scripts - [bdb82f3]( https://github.com/royriojas/flat-cache/commit/bdb82f3 ), [royriojas](https://github.com/royriojas), 11/09/2015 14:44:31 ## v1.0.5 - **Documentation** - - better description for the module - [436817f]( https://github.com/royriojas/flat-cache/commit/436817f ), [royriojas](https://github.com/royriojas), 11/09/2015 16:35:33 + - better description for the module - [436817f]( https://github.com/royriojas/flat-cache/commit/436817f ), [royriojas](https://github.com/royriojas), 11/09/2015 14:35:33 - **Other changes** - - Update dependencies - [be88aa3]( https://github.com/royriojas/flat-cache/commit/be88aa3 ), [Bogdan Chadkin](https://github.com/Bogdan Chadkin), 11/09/2015 15:47:41 + - Update dependencies - [be88aa3]( https://github.com/royriojas/flat-cache/commit/be88aa3 ), [Bogdan Chadkin](https://github.com/Bogdan Chadkin), 11/09/2015 13:47:41 ## v1.0.11 - **Features** - - Add noPrune option to cache.save() method. closes [#7](https://github.com/royriojas/flat-cache/issues/7) - [2c8016a]( https://github.com/royriojas/flat-cache/commit/2c8016a ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 04:00:29 - - - - Add json read and write utility based on circular-json - [c31081e]( https://github.com/royriojas/flat-cache/commit/c31081e ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 10:58:17 + - Add noPrune option to cache.save() method. closes [#7](https://github.com/royriojas/flat-cache/issues/7) - [2c8016a]( https://github.com/royriojas/flat-cache/commit/2c8016a ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 02:00:29 + + - Add json read and write utility based on circular-json - [c31081e]( https://github.com/royriojas/flat-cache/commit/c31081e ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 08:58:17 + - **Bug Fixes** - - Remove UTF16 BOM stripping - [4a41e22]( https://github.com/royriojas/flat-cache/commit/4a41e22 ), [Jean Ponchon](https://github.com/Jean Ponchon), 29/07/2016 04:18:06 + - Remove UTF16 BOM stripping - [4a41e22]( https://github.com/royriojas/flat-cache/commit/4a41e22 ), [Jean Ponchon](https://github.com/Jean Ponchon), 29/07/2016 02:18:06 - Since we control both writing and reading of JSON stream, there no needs + Since we control both writing and reading of JSON stream, there no needs to handle unicode BOM. - - Use circular-json to handle circular references (fix [#5](https://github.com/royriojas/flat-cache/issues/5)) - [cd7aeed]( https://github.com/royriojas/flat-cache/commit/cd7aeed ), [Jean Ponchon](https://github.com/Jean Ponchon), 25/07/2016 13:11:59 - + - Use circular-json to handle circular references (fix [#5](https://github.com/royriojas/flat-cache/issues/5)) - [cd7aeed]( https://github.com/royriojas/flat-cache/commit/cd7aeed ), [Jean Ponchon](https://github.com/Jean Ponchon), 25/07/2016 11:11:59 + - **Tests Related fixes** - - Add missing file from eslint test - [d6fa3c3]( https://github.com/royriojas/flat-cache/commit/d6fa3c3 ), [Jean Ponchon](https://github.com/Jean Ponchon), 29/07/2016 04:15:51 - - - - Add test for circular json serialization / deserialization - [07d2ddd]( https://github.com/royriojas/flat-cache/commit/07d2ddd ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 10:59:36 + - Add missing file from eslint test - [d6fa3c3]( https://github.com/royriojas/flat-cache/commit/d6fa3c3 ), [Jean Ponchon](https://github.com/Jean Ponchon), 29/07/2016 02:15:51 + + - Add test for circular json serialization / deserialization - [07d2ddd]( https://github.com/royriojas/flat-cache/commit/07d2ddd ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 08:59:36 + - **Refactoring** - - Remove unused read-json-sync - [2be1c24]( https://github.com/royriojas/flat-cache/commit/2be1c24 ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 10:59:18 - + - Remove unused read-json-sync - [2be1c24]( https://github.com/royriojas/flat-cache/commit/2be1c24 ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 08:59:18 + - **Build Scripts Changes** - - travis tests on 0.12 and 4x - [3a613fd]( https://github.com/royriojas/flat-cache/commit/3a613fd ), [royriojas](https://github.com/royriojas), 15/11/2015 17:34:40 - + - travis tests on 0.12 and 4x - [3a613fd]( https://github.com/royriojas/flat-cache/commit/3a613fd ), [royriojas](https://github.com/royriojas), 15/11/2015 14:34:40 + ## v1.0.10 - **Build Scripts Changes** - - add eslint-fix task - [fd29e52]( https://github.com/royriojas/flat-cache/commit/fd29e52 ), [royriojas](https://github.com/royriojas), 01/11/2015 18:04:08 - - - - make sure the test script also verify beautification and linting of files before running tests - [e94e176]( https://github.com/royriojas/flat-cache/commit/e94e176 ), [royriojas](https://github.com/royriojas), 01/11/2015 14:54:48 - - - - test against node 4 - [c395b66]( https://github.com/royriojas/flat-cache/commit/c395b66 ), [royriojas](https://github.com/royriojas), 11/09/2015 17:51:39 + - add eslint-fix task - [fd29e52]( https://github.com/royriojas/flat-cache/commit/fd29e52 ), [royriojas](https://github.com/royriojas), 01/11/2015 15:04:08 + + - make sure the test script also verify beautification and linting of files before running tests - [e94e176]( https://github.com/royriojas/flat-cache/commit/e94e176 ), [royriojas](https://github.com/royriojas), 01/11/2015 11:54:48 - - Add helpers/code check scripts - [bdb82f3]( https://github.com/royriojas/flat-cache/commit/bdb82f3 ), [royriojas](https://github.com/royriojas), 11/09/2015 16:44:31 + + - test against node 4 - [c395b66]( https://github.com/royriojas/flat-cache/commit/c395b66 ), [royriojas](https://github.com/royriojas), 11/09/2015 15:51:39 + + - Add helpers/code check scripts - [bdb82f3]( https://github.com/royriojas/flat-cache/commit/bdb82f3 ), [royriojas](https://github.com/royriojas), 11/09/2015 14:44:31 + - **Other changes** - - add clearAll for cacheDir - [97383d9]( https://github.com/royriojas/flat-cache/commit/97383d9 ), [xieyaowu](https://github.com/xieyaowu), 31/10/2015 23:02:18 - - - - Move dependencies into devDep - [7e47099]( https://github.com/royriojas/flat-cache/commit/7e47099 ), [Bogdan Chadkin](https://github.com/Bogdan Chadkin), 11/09/2015 17:10:57 + - add clearAll for cacheDir - [97383d9]( https://github.com/royriojas/flat-cache/commit/97383d9 ), [xieyaowu](https://github.com/xieyaowu), 31/10/2015 21:02:18 + + - Move dependencies into devDep - [7e47099]( https://github.com/royriojas/flat-cache/commit/7e47099 ), [Bogdan Chadkin](https://github.com/Bogdan Chadkin), 11/09/2015 15:10:57 - - Update dependencies - [be88aa3]( https://github.com/royriojas/flat-cache/commit/be88aa3 ), [Bogdan Chadkin](https://github.com/Bogdan Chadkin), 11/09/2015 15:47:41 - + + - Update dependencies - [be88aa3]( https://github.com/royriojas/flat-cache/commit/be88aa3 ), [Bogdan Chadkin](https://github.com/Bogdan Chadkin), 11/09/2015 13:47:41 + - **Bug Fixes** - - wrong default values for changelogx user repo name - [7bb52d1]( https://github.com/royriojas/flat-cache/commit/7bb52d1 ), [royriojas](https://github.com/royriojas), 11/09/2015 17:59:30 + - wrong default values for changelogx user repo name - [7bb52d1]( https://github.com/royriojas/flat-cache/commit/7bb52d1 ), [royriojas](https://github.com/royriojas), 11/09/2015 15:59:30 - **Documentation** - - Add missing changelog link - [f51197a]( https://github.com/royriojas/flat-cache/commit/f51197a ), [royriojas](https://github.com/royriojas), 11/09/2015 16:48:05 - - - - better description for the module - [436817f]( https://github.com/royriojas/flat-cache/commit/436817f ), [royriojas](https://github.com/royriojas), 11/09/2015 16:35:33 + - Add missing changelog link - [f51197a]( https://github.com/royriojas/flat-cache/commit/f51197a ), [royriojas](https://github.com/royriojas), 11/09/2015 14:48:05 + + - better description for the module - [436817f]( https://github.com/royriojas/flat-cache/commit/436817f ), [royriojas](https://github.com/royriojas), 11/09/2015 14:35:33 - - Add documentation about `clearAll` and `clearCacheById` - [13947c1]( https://github.com/royriojas/flat-cache/commit/13947c1 ), [Roy Riojas](https://github.com/Roy Riojas), 02/03/2015 02:44:05 + + - Add documentation about `clearAll` and `clearCacheById` - [13947c1]( https://github.com/royriojas/flat-cache/commit/13947c1 ), [Roy Riojas](https://github.com/Roy Riojas), 01/03/2015 23:44:05 - **Refactoring** - - load a cache file using the full filepath - [b8f68c2]( https://github.com/royriojas/flat-cache/commit/b8f68c2 ), [Roy Riojas](https://github.com/Roy Riojas), 30/08/2015 06:19:14 - + - load a cache file using the full filepath - [b8f68c2]( https://github.com/royriojas/flat-cache/commit/b8f68c2 ), [Roy Riojas](https://github.com/Roy Riojas), 30/08/2015 04:19:14 + - **Features** - - Add methods to remove the cache documents created - [af40443]( https://github.com/royriojas/flat-cache/commit/af40443 ), [Roy Riojas](https://github.com/Roy Riojas), 02/03/2015 02:39:27 + - Add methods to remove the cache documents created - [af40443]( https://github.com/royriojas/flat-cache/commit/af40443 ), [Roy Riojas](https://github.com/Roy Riojas), 01/03/2015 23:39:27 ## v1.0.1 - **Other changes** - - Update README.md - [c2b6805]( https://github.com/royriojas/flat-cache/commit/c2b6805 ), [Roy Riojas](https://github.com/Roy Riojas), 26/02/2015 07:28:07 + - Update README.md - [c2b6805]( https://github.com/royriojas/flat-cache/commit/c2b6805 ), [Roy Riojas](https://github.com/Roy Riojas), 26/02/2015 04:28:07 ## v1.0.0 - **Refactoring** - - flat-cache v.1.0.0 - [c984274]( https://github.com/royriojas/flat-cache/commit/c984274 ), [Roy Riojas](https://github.com/Roy Riojas), 26/02/2015 07:11:50 + - flat-cache v.1.0.0 - [c984274]( https://github.com/royriojas/flat-cache/commit/c984274 ), [Roy Riojas](https://github.com/Roy Riojas), 26/02/2015 04:11:50 - **Other changes** - - Initial commit - [d43cccf]( https://github.com/royriojas/flat-cache/commit/d43cccf ), [Roy Riojas](https://github.com/Roy Riojas), 26/02/2015 04:12:16 + - Initial commit - [d43cccf]( https://github.com/royriojas/flat-cache/commit/d43cccf ), [Roy Riojas](https://github.com/Roy Riojas), 26/02/2015 01:12:16 diff --git a/tools/node_modules/eslint/node_modules/flat-cache/del.js b/tools/node_modules/eslint/node_modules/flat-cache/del.js new file mode 100644 index 00000000000000..542baac70a0c78 --- /dev/null +++ b/tools/node_modules/eslint/node_modules/flat-cache/del.js @@ -0,0 +1,13 @@ +var rimraf = require( 'rimraf' ).sync; +var fs = require( 'graceful-fs' ); + +module.exports = function del( file ) { + if ( fs.existsSync( file ) ) { + //if rimraf doesn't throw then the file has been deleted or didn't exist + rimraf( file, { + glob: false + } ); + return true; + } + return false; +}; diff --git a/tools/node_modules/eslint/node_modules/flat-cache/package.json b/tools/node_modules/eslint/node_modules/flat-cache/package.json index 5e7f5f3acabcfa..66290b456afaee 100644 --- a/tools/node_modules/eslint/node_modules/flat-cache/package.json +++ b/tools/node_modules/eslint/node_modules/flat-cache/package.json @@ -21,8 +21,8 @@ }, "dependencies": { "circular-json": "^0.3.1", - "del": "^3.0.0", "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", "write": "^0.2.1" }, "deprecated": false, @@ -47,7 +47,8 @@ }, "files": [ "cache.js", - "utils.js" + "utils.js", + "del.js" ], "homepage": "https://github.com/royriojas/flat-cache#readme", "keywords": [ @@ -73,7 +74,7 @@ }, "scripts": { "autofix": "npm run beautify && npm run eslint-fix", - "beautify": "esbeautifier 'cache.js' 'test/specs/**/*.js'", + "beautify": "esbeautifier 'cache.js' 'utils.js' 'del.js' 'test/specs/**/*.js'", "beautify-check": "npm run beautify -- -k", "bump-major": "npm run pre-v && npm version major -m 'BLD: Release v%s' && npm run post-v", "bump-minor": "npm run pre-v && npm version minor -m 'BLD: Release v%s' && npm run post-v", @@ -82,7 +83,7 @@ "check": "npm run beautify-check && npm run eslint", "cover": "istanbul cover test/runner.js html text-summary", "do-changelog": "npm run changelog && git add ./changelog.md && git commit -m 'DOC: Generate changelog' --no-verify", - "eslint": "eslinter 'cache.js' 'utils.js' 'specs/**/*.js'", + "eslint": "eslinter 'cache.js' 'utils.js' 'del.js' 'specs/**/*.js'", "eslint-fix": "npm run eslint -- --fix", "install-hooks": "prepush install && changelogx install-hook && precommit install", "post-v": "npm run do-changelog && git push --no-verify && git push --tags --no-verify", @@ -92,5 +93,5 @@ "verify": "npm run check && npm run test:cache", "watch": "watch-run -i -p 'test/specs/**/*.js' istanbul cover test/runner.js html text-summary" }, - "version": "1.3.2" + "version": "1.3.4" } \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/flat-cache/utils.js b/tools/node_modules/eslint/node_modules/flat-cache/utils.js index e3654d23fa3d87..11b41f437027b5 100644 --- a/tools/node_modules/eslint/node_modules/flat-cache/utils.js +++ b/tools/node_modules/eslint/node_modules/flat-cache/utils.js @@ -4,7 +4,7 @@ var circularJson = require( 'circular-json' ); module.exports = { - tryParse: function ( filePath, defaultValue) { + tryParse: function ( filePath, defaultValue ) { var result; try { result = this.readJSON( filePath ); @@ -32,7 +32,7 @@ module.exports = { * @param {String} filePath Json filepath * @param {*} data Object to serialize */ - writeJSON: function (filePath, data ) { + writeJSON: function ( filePath, data ) { write.sync( filePath, circularJson.stringify( data ) ); } diff --git a/tools/node_modules/eslint/node_modules/globals/globals.json b/tools/node_modules/eslint/node_modules/globals/globals.json index d805cdd73c6bdb..2619096e68b7c4 100644 --- a/tools/node_modules/eslint/node_modules/globals/globals.json +++ b/tools/node_modules/eslint/node_modules/globals/globals.json @@ -698,6 +698,7 @@ "PushManager": false, "PushSubscription": false, "PushSubscriptionOptions": false, + "queueMicrotask": false, "RadioNodeList": false, "Range": false, "ReadableStream": false, @@ -984,6 +985,7 @@ "PerformanceTiming": false, "postMessage": true, "Promise": false, + "queueMicrotask": false, "Request": false, "Response": false, "self": true, @@ -1012,10 +1014,13 @@ "Intl": false, "module": false, "process": false, + "queueMicrotask": false, "require": false, "setImmediate": false, "setInterval": false, "setTimeout": false, + "TextDecoder": false, + "TextEncoder": false, "URL": false, "URLSearchParams": false }, diff --git a/tools/node_modules/eslint/node_modules/globals/package.json b/tools/node_modules/eslint/node_modules/globals/package.json index ef0bf02ac857ab..958e4c737e64e6 100644 --- a/tools/node_modules/eslint/node_modules/globals/package.json +++ b/tools/node_modules/eslint/node_modules/globals/package.json @@ -41,7 +41,7 @@ "scripts": { "test": "xo && ava" }, - "version": "11.8.0", + "version": "11.9.0", "xo": { "ignores": [ "get-browser-globals.js" diff --git a/tools/node_modules/eslint/node_modules/globby/index.js b/tools/node_modules/eslint/node_modules/globby/index.js deleted file mode 100644 index 587a0fdd1cc0fb..00000000000000 --- a/tools/node_modules/eslint/node_modules/globby/index.js +++ /dev/null @@ -1,88 +0,0 @@ -'use strict'; -var Promise = require('pinkie-promise'); -var arrayUnion = require('array-union'); -var objectAssign = require('object-assign'); -var glob = require('glob'); -var pify = require('pify'); - -var globP = pify(glob, Promise).bind(glob); - -function isNegative(pattern) { - return pattern[0] === '!'; -} - -function isString(value) { - return typeof value === 'string'; -} - -function assertPatternsInput(patterns) { - if (!patterns.every(isString)) { - throw new TypeError('patterns must be a string or an array of strings'); - } -} - -function generateGlobTasks(patterns, opts) { - patterns = [].concat(patterns); - assertPatternsInput(patterns); - - var globTasks = []; - - opts = objectAssign({ - cache: Object.create(null), - statCache: Object.create(null), - realpathCache: Object.create(null), - symlinks: Object.create(null), - ignore: [] - }, opts); - - patterns.forEach(function (pattern, i) { - if (isNegative(pattern)) { - return; - } - - var ignore = patterns.slice(i).filter(isNegative).map(function (pattern) { - return pattern.slice(1); - }); - - globTasks.push({ - pattern: pattern, - opts: objectAssign({}, opts, { - ignore: opts.ignore.concat(ignore) - }) - }); - }); - - return globTasks; -} - -module.exports = function (patterns, opts) { - var globTasks; - - try { - globTasks = generateGlobTasks(patterns, opts); - } catch (err) { - return Promise.reject(err); - } - - return Promise.all(globTasks.map(function (task) { - return globP(task.pattern, task.opts); - })).then(function (paths) { - return arrayUnion.apply(null, paths); - }); -}; - -module.exports.sync = function (patterns, opts) { - var globTasks = generateGlobTasks(patterns, opts); - - return globTasks.reduce(function (matches, task) { - return arrayUnion(matches, glob.sync(task.pattern, task.opts)); - }, []); -}; - -module.exports.generateGlobTasks = generateGlobTasks; - -module.exports.hasMagic = function (patterns, opts) { - return [].concat(patterns).some(function (pattern) { - return glob.hasMagic(pattern, opts); - }); -}; diff --git a/tools/node_modules/eslint/node_modules/globby/license b/tools/node_modules/eslint/node_modules/globby/license deleted file mode 100644 index 654d0bfe943437..00000000000000 --- a/tools/node_modules/eslint/node_modules/globby/license +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -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/tools/node_modules/eslint/node_modules/globby/node_modules/pify/index.js b/tools/node_modules/eslint/node_modules/globby/node_modules/pify/index.js deleted file mode 100644 index 7c720ebee88727..00000000000000 --- a/tools/node_modules/eslint/node_modules/globby/node_modules/pify/index.js +++ /dev/null @@ -1,68 +0,0 @@ -'use strict'; - -var processFn = function (fn, P, opts) { - return function () { - var that = this; - var args = new Array(arguments.length); - - for (var i = 0; i < arguments.length; i++) { - args[i] = arguments[i]; - } - - return new P(function (resolve, reject) { - args.push(function (err, result) { - if (err) { - reject(err); - } else if (opts.multiArgs) { - var results = new Array(arguments.length - 1); - - for (var i = 1; i < arguments.length; i++) { - results[i - 1] = arguments[i]; - } - - resolve(results); - } else { - resolve(result); - } - }); - - fn.apply(that, args); - }); - }; -}; - -var pify = module.exports = function (obj, P, opts) { - if (typeof P !== 'function') { - opts = P; - P = Promise; - } - - opts = opts || {}; - opts.exclude = opts.exclude || [/.+Sync$/]; - - var filter = function (key) { - var match = function (pattern) { - return typeof pattern === 'string' ? key === pattern : pattern.test(key); - }; - - return opts.include ? opts.include.some(match) : !opts.exclude.some(match); - }; - - var ret = typeof obj === 'function' ? function () { - if (opts.excludeMain) { - return obj.apply(this, arguments); - } - - return processFn(obj, P, opts).apply(this, arguments); - } : {}; - - return Object.keys(obj).reduce(function (ret, key) { - var x = obj[key]; - - ret[key] = typeof x === 'function' && filter(key) ? processFn(x, P, opts) : x; - - return ret; - }, ret); -}; - -pify.all = pify; diff --git a/tools/node_modules/eslint/node_modules/globby/node_modules/pify/license b/tools/node_modules/eslint/node_modules/globby/node_modules/pify/license deleted file mode 100644 index 654d0bfe943437..00000000000000 --- a/tools/node_modules/eslint/node_modules/globby/node_modules/pify/license +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -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/tools/node_modules/eslint/node_modules/globby/node_modules/pify/package.json b/tools/node_modules/eslint/node_modules/globby/node_modules/pify/package.json deleted file mode 100644 index 40780115cf1d0a..00000000000000 --- a/tools/node_modules/eslint/node_modules/globby/node_modules/pify/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "bugs": { - "url": "https://github.com/sindresorhus/pify/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Promisify a callback-style function", - "devDependencies": { - "ava": "*", - "pinkie-promise": "^1.0.0", - "v8-natives": "0.0.2", - "xo": "*" - }, - "engines": { - "node": ">=0.10.0" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/sindresorhus/pify#readme", - "keywords": [ - "promise", - "promises", - "promisify", - "denodify", - "denodeify", - "callback", - "cb", - "node", - "then", - "thenify", - "convert", - "transform", - "wrap", - "wrapper", - "bind", - "to", - "async", - "es2015" - ], - "license": "MIT", - "name": "pify", - "repository": { - "type": "git", - "url": "git+https://github.com/sindresorhus/pify.git" - }, - "scripts": { - "optimization-test": "node --allow-natives-syntax optimization-test.js", - "test": "xo && ava && npm run optimization-test" - }, - "version": "2.3.0" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/globby/node_modules/pify/readme.md b/tools/node_modules/eslint/node_modules/globby/node_modules/pify/readme.md deleted file mode 100644 index 97aeeb628b0897..00000000000000 --- a/tools/node_modules/eslint/node_modules/globby/node_modules/pify/readme.md +++ /dev/null @@ -1,119 +0,0 @@ -# pify [![Build Status](https://travis-ci.org/sindresorhus/pify.svg?branch=master)](https://travis-ci.org/sindresorhus/pify) - -> Promisify a callback-style function - - -## Install - -``` -$ npm install --save pify -``` - - -## Usage - -```js -const fs = require('fs'); -const pify = require('pify'); - -// promisify a single function - -pify(fs.readFile)('package.json', 'utf8').then(data => { - console.log(JSON.parse(data).name); - //=> 'pify' -}); - -// or promisify all methods in a module - -pify(fs).readFile('package.json', 'utf8').then(data => { - console.log(JSON.parse(data).name); - //=> 'pify' -}); -``` - - -## API - -### pify(input, [promiseModule], [options]) - -Returns a promise wrapped version of the supplied function or module. - -#### input - -Type: `function`, `object` - -Callback-style function or module whose methods you want to promisify. - -#### promiseModule - -Type: `function` - -Custom promise module to use instead of the native one. - -Check out [`pinkie-promise`](https://github.com/floatdrop/pinkie-promise) if you need a tiny promise polyfill. - -#### options - -##### multiArgs - -Type: `boolean` -Default: `false` - -By default, the promisified function will only return the second argument from the callback, which works fine for most APIs. This option can be useful for modules like `request` that return multiple arguments. Turning this on will make it return an array of all arguments from the callback, excluding the error argument, instead of just the second argument. - -```js -const request = require('request'); -const pify = require('pify'); - -pify(request, {multiArgs: true})('https://sindresorhus.com').then(result => { - const [httpResponse, body] = result; -}); -``` - -##### include - -Type: `array` of (`string`|`regex`) - -Methods in a module to promisify. Remaining methods will be left untouched. - -##### exclude - -Type: `array` of (`string`|`regex`) -Default: `[/.+Sync$/]` - -Methods in a module **not** to promisify. Methods with names ending with `'Sync'` are excluded by default. - -##### excludeMain - -Type: `boolean` -Default: `false` - -By default, if given module is a function itself, this function will be promisified. Turn this option on if you want to promisify only methods of the module. - -```js -const pify = require('pify'); - -function fn() { - return true; -} - -fn.method = (data, callback) => { - setImmediate(() => { - callback(data, null); - }); -}; - -// promisify methods but not fn() -const promiseFn = pify(fn, {excludeMain: true}); - -if (promiseFn()) { - promiseFn.method('hi').then(data => { - console.log(data); - }); -} -``` - - -## License - -MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/tools/node_modules/eslint/node_modules/globby/package.json b/tools/node_modules/eslint/node_modules/globby/package.json deleted file mode 100644 index fad7fc179674cb..00000000000000 --- a/tools/node_modules/eslint/node_modules/globby/package.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "bugs": { - "url": "https://github.com/sindresorhus/globby/issues" - }, - "bundleDependencies": false, - "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "deprecated": false, - "description": "Extends `glob` with support for multiple patterns and exposes a Promise API", - "devDependencies": { - "ava": "*", - "glob-stream": "github:gulpjs/glob-stream#master", - "globby": "github:sindresorhus/globby#master", - "matcha": "^0.7.0", - "rimraf": "^2.2.8", - "xo": "^0.16.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/sindresorhus/globby#readme", - "keywords": [ - "all", - "array", - "directories", - "dirs", - "expand", - "files", - "filesystem", - "filter", - "find", - "fnmatch", - "folders", - "fs", - "glob", - "globbing", - "globs", - "gulpfriendly", - "match", - "matcher", - "minimatch", - "multi", - "multiple", - "paths", - "pattern", - "patterns", - "traverse", - "util", - "utility", - "wildcard", - "wildcards", - "promise" - ], - "license": "MIT", - "name": "globby", - "repository": { - "type": "git", - "url": "git+https://github.com/sindresorhus/globby.git" - }, - "scripts": { - "bench": "npm update glob-stream && matcha bench.js", - "test": "xo && ava" - }, - "version": "6.1.0" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/globby/readme.md b/tools/node_modules/eslint/node_modules/globby/readme.md deleted file mode 100644 index e10a48868f9e29..00000000000000 --- a/tools/node_modules/eslint/node_modules/globby/readme.md +++ /dev/null @@ -1,88 +0,0 @@ -# globby [![Build Status](https://travis-ci.org/sindresorhus/globby.svg?branch=master)](https://travis-ci.org/sindresorhus/globby) - -> Extends [glob](https://github.com/isaacs/node-glob) with support for multiple patterns and exposes a Promise API - - -## Install - -``` -$ npm install --save globby -``` - - -## Usage - -``` -├── unicorn -├── cake -└── rainbow -``` - -```js -const globby = require('globby'); - -globby(['*', '!cake']).then(paths => { - console.log(paths); - //=> ['unicorn', 'rainbow'] -}); -``` - - -## API - -### globby(patterns, [options]) - -Returns a Promise for an array of matching paths. - -### globby.sync(patterns, [options]) - -Returns an array of matching paths. - -### globby.generateGlobTasks(patterns, [options]) - -Returns an array of objects in the format `{ pattern: string, opts: Object }`, which can be passed as arguments to [`node-glob`](https://github.com/isaacs/node-glob). This is useful for other globbing-related packages. - -Note that you should avoid running the same tasks multiple times as they contain a file system cache. Instead, run this method each time to ensure file system changes are taken into consideration. - -### globby.hasMagic(patterns, [options]) - -Returns a `boolean` of whether there are any special glob characters in the `patterns`. - -Note that the options affect the results. If `noext: true` is set, then `+(a|b)` will not be considered a magic pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}`, then that is considered magical, unless `nobrace: true` is set. - -#### patterns - -Type: `string` `Array` - -See supported `minimatch` [patterns](https://github.com/isaacs/minimatch#usage). - -#### options - -Type: `Object` - -See the `node-glob` [options](https://github.com/isaacs/node-glob#options). - - -## Globbing patterns - -Just a quick overview. - -- `*` matches any number of characters, but not `/` -- `?` matches a single character, but not `/` -- `**` matches any number of characters, including `/`, as long as it's the only thing in a path part -- `{}` allows for a comma-separated list of "or" expressions -- `!` at the beginning of a pattern will negate the match - -[Various patterns and expected matches.](https://github.com/sindresorhus/multimatch/blob/master/test.js) - - -## Related - -- [multimatch](https://github.com/sindresorhus/multimatch) - Match against a list instead of the filesystem -- [glob-stream](https://github.com/wearefractal/glob-stream) - Streaming alternative -- [matcher](https://github.com/sindresorhus/matcher) - Simple wildcard matching - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/tools/node_modules/eslint/node_modules/inquirer/README.md b/tools/node_modules/eslint/node_modules/inquirer/README.md new file mode 100644 index 00000000000000..1038bbd526336b --- /dev/null +++ b/tools/node_modules/eslint/node_modules/inquirer/README.md @@ -0,0 +1,424 @@ +Inquirer Logo + +# Inquirer.js + +[![npm](https://badge.fury.io/js/inquirer.svg)](http://badge.fury.io/js/inquirer) [![tests](https://travis-ci.org/SBoudrias/Inquirer.js.svg?branch=master)](http://travis-ci.org/SBoudrias/Inquirer.js) [![Coverage Status](https://codecov.io/gh/SBoudrias/Inquirer.js/branch/master/graph/badge.svg)](https://codecov.io/gh/SBoudrias/Inquirer.js) [![dependencies](https://david-dm.org/SBoudrias/Inquirer.js.svg?theme=shields.io)](https://david-dm.org/SBoudrias/Inquirer.js) + +A collection of common interactive command line user interfaces. + +**Version 4.x** only supports Node 6 and over. For Node 4 support please use [version 3.x](https://github.com/SBoudrias/Inquirer.js/tree/v3.3.0). + +## Table of Contents + +1. [Documentation](#documentation) + 1. [Installation](#installation) + 2. [Examples](#examples) + 3. [Methods](#methods) + 4. [Objects](#objects) + 5. [Questions](#questions) + 6. [Answers](#answers) + 7. [Separator](#separator) + 8. [Prompt Types](#prompt) +2. [User Interfaces and Layouts](#layouts) + 1. [Reactive Interface](#reactive) +3. [Support](#support) +4. [News](#news) +5. [Contributing](#contributing) +6. [License](#license) +7. [Plugins](#plugins) + +## Goal and Philosophy + +**`Inquirer.js`** strives to be an easily embeddable and beautiful command line interface for [Node.js](https://nodejs.org/) (and perhaps the "CLI [Xanadu](https://en.wikipedia.org/wiki/Citizen_Kane)"). + +**`Inquirer.js`** should ease the process of + +- providing _error feedback_ +- _asking questions_ +- _parsing_ input +- _validating_ answers +- managing _hierarchical prompts_ + +> **Note:** **`Inquirer.js`** provides the user interface and the inquiry session flow. If you're searching for a full blown command line program utility, then check out [commander](https://github.com/visionmedia/commander.js), [vorpal](https://github.com/dthree/vorpal) or [args](https://github.com/leo/args). + +## [Documentation](#documentation) + + + +### Installation + + + +```shell +npm install inquirer +``` + +```javascript +var inquirer = require('inquirer'); +inquirer + .prompt([ + /* Pass your questions in here */ + ]) + .then(answers => { + // Use user feedback for... whatever!! + }); +``` + + + +### Examples (Run it and see it) + +Check out the [`packages/inquirer/examples/`](https://github.com/SBoudrias/Inquirer.js/tree/master/packages/inquirer/examples) folder for code and interface examples. + +```shell +node packages/inquirer/examples/pizza.js +node packages/inquirer/examples/checkbox.js +# etc... +``` + +### Methods + + + +#### `inquirer.prompt(questions) -> promise` + +Launch the prompt interface (inquiry session) + +- **questions** (Array) containing [Question Object](#question) (using the [reactive interface](#reactive-interface), you can also pass a `Rx.Observable` instance) +- returns a **Promise** + +#### `inquirer.registerPrompt(name, prompt)` + +Register prompt plugins under `name`. + +- **name** (string) name of the this new prompt. (used for question `type`) +- **prompt** (object) the prompt object itself (the plugin) + +#### `inquirer.createPromptModule() -> prompt function` + +Create a self contained inquirer module. If you don't want to affect other libraries that also rely on inquirer when you overwrite or add new prompt types. + +```js +var prompt = inquirer.createPromptModule(); + +prompt(questions).then(/* ... */); +``` + +### Objects + + + +#### Question + + +A question object is a `hash` containing question related values: + +- **type**: (String) Type of the prompt. Defaults: `input` - Possible values: `input`, `confirm`, + `list`, `rawlist`, `expand`, `checkbox`, `password`, `editor` +- **name**: (String) The name to use when storing the answer in the answers hash. If the name contains periods, it will define a path in the answers hash. +- **message**: (String|Function) The question to print. If defined as a function, the first parameter will be the current inquirer session answers. Defaults to the value of `name` (followed by a colon). +- **default**: (String|Number|Boolean|Array|Function) Default value(s) to use if nothing is entered, or a function that returns the default value(s). If defined as a function, the first parameter will be the current inquirer session answers. +- **choices**: (Array|Function) Choices array or a function returning a choices array. If defined as a function, the first parameter will be the current inquirer session answers. + Array values can be simple `strings`, or `objects` containing a `name` (to display in list), a `value` (to save in the answers hash) and a `short` (to display after selection) properties. The choices array can also contain [a `Separator`](#separator). +- **validate**: (Function) Receive the user input and answers hash. Should return `true` if the value is valid, and an error message (`String`) otherwise. If `false` is returned, a default error message is provided. +- **filter**: (Function) Receive the user input and return the filtered value to be used inside the program. The value returned will be added to the _Answers_ hash. +- **transformer**: (Function) Receive the user input, answers hash and option flags, and return a transformed value to display to the user. The transformation only impacts what is shown while editing. It does not modify the answers hash. +- **when**: (Function, Boolean) Receive the current user answers hash and should return `true` or `false` depending on whether or not this question should be asked. The value can also be a simple boolean. +- **pageSize**: (Number) Change the number of lines that will be rendered when using `list`, `rawList`, `expand` or `checkbox`. +- **prefix**: (String) Change the default _prefix_ message. +- **suffix**: (String) Change the default _suffix_ message. + +`default`, `choices`(if defined as functions), `validate`, `filter` and `when` functions can be called asynchronously. Either return a promise or use `this.async()` to get a callback you'll call with the final value. + +```javascript +{ + /* Preferred way: with promise */ + filter() { + return new Promise(/* etc... */); + }, + + /* Legacy way: with this.async */ + validate: function (input) { + // Declare function as asynchronous, and save the done callback + var done = this.async(); + + // Do async stuff + setTimeout(function() { + if (typeof input !== 'number') { + // Pass the return value in the done callback + done('You need to provide a number'); + return; + } + // Pass the return value in the done callback + done(null, true); + }, 3000); + } +} +``` + +### Answers + + +A key/value hash containing the client answers in each prompt. + +- **Key** The `name` property of the _question_ object +- **Value** (Depends on the prompt) + - `confirm`: (Boolean) + - `input` : User input (filtered if `filter` is defined) (String) + - `rawlist`, `list` : Selected choice value (or name if no value specified) (String) + +### Separator + + +A separator can be added to any `choices` array: + +``` +// In the question object +choices: [ "Choice A", new inquirer.Separator(), "choice B" ] + +// Which'll be displayed this way +[?] What do you want to do? + > Order a pizza + Make a reservation + -------- + Ask opening hours + Talk to the receptionist +``` + +The constructor takes a facultative `String` value that'll be use as the separator. If omitted, the separator will be `--------`. + +Separator instances have a property `type` equal to `separator`. This should allow tools façading Inquirer interface from detecting separator types in lists. + + + +### Prompt types + +--- + +> **Note:**: _allowed options written inside square brackets (`[]`) are optional. Others are required._ + +#### List - `{type: 'list'}` + +Take `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that +default must be the choice `index` in the array or a choice `value`) + +![List prompt](https://cdn.rawgit.com/SBoudrias/Inquirer.js/28ae8337ba51d93e359ef4f7ee24e79b69898962/assets/screenshots/list.svg) + +--- + +#### Raw List - `{type: 'rawlist'}` + +Take `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that +default must be the choice `index` in the array) + +![Raw list prompt](https://cdn.rawgit.com/SBoudrias/Inquirer.js/28ae8337ba51d93e359ef4f7ee24e79b69898962/assets/screenshots/rawlist.svg) + +--- + +#### Expand - `{type: 'expand'}` + +Take `type`, `name`, `message`, `choices`[, `default`] properties. (Note that +default must be the choice `index` in the array. If `default` key not provided, then `help` will be used as default choice) + +Note that the `choices` object will take an extra parameter called `key` for the `expand` prompt. This parameter must be a single (lowercased) character. The `h` option is added by the prompt and shouldn't be defined by the user. + +See `examples/expand.js` for a running example. + +![Expand prompt closed](https://cdn.rawgit.com/SBoudrias/Inquirer.js/28ae8337ba51d93e359ef4f7ee24e79b69898962/assets/screenshots/expand-y.svg) +![Expand prompt expanded](https://cdn.rawgit.com/SBoudrias/Inquirer.js/28ae8337ba51d93e359ef4f7ee24e79b69898962/assets/screenshots/expand-d.svg) + +--- + +#### Checkbox - `{type: 'checkbox'}` + +Take `type`, `name`, `message`, `choices`[, `filter`, `validate`, `default`] properties. `default` is expected to be an Array of the checked choices value. + +Choices marked as `{checked: true}` will be checked by default. + +Choices whose property `disabled` is truthy will be unselectable. If `disabled` is a string, then the string will be outputted next to the disabled choice, otherwise it'll default to `"Disabled"`. The `disabled` property can also be a synchronous function receiving the current answers as argument and returning a boolean or a string. + +![Checkbox prompt](https://cdn.rawgit.com/SBoudrias/Inquirer.js/28ae8337ba51d93e359ef4f7ee24e79b69898962/assets/screenshots/checkbox.svg) + +--- + +#### Confirm - `{type: 'confirm'}` + +Take `type`, `name`, `message`, [`default`] properties. `default` is expected to be a boolean if used. + +![Confirm prompt](https://cdn.rawgit.com/SBoudrias/Inquirer.js/28ae8337ba51d93e359ef4f7ee24e79b69898962/assets/screenshots/confirm.svg) + +--- + +#### Input - `{type: 'input'}` + +Take `type`, `name`, `message`[, `default`, `filter`, `validate`, `transformer`] properties. + +![Input prompt](https://cdn.rawgit.com/SBoudrias/Inquirer.js/28ae8337ba51d93e359ef4f7ee24e79b69898962/assets/screenshots/input.svg) + +--- + +#### Password - `{type: 'password'}` + +Take `type`, `name`, `message`, `mask`,[, `default`, `filter`, `validate`] properties. + +![Password prompt](https://cdn.rawgit.com/SBoudrias/Inquirer.js/28ae8337ba51d93e359ef4f7ee24e79b69898962/assets/screenshots/password.svg) + +--- + +Note that `mask` is required to hide the actual user input. + +#### Editor - `{type: 'editor'}` + +Take `type`, `name`, `message`[, `default`, `filter`, `validate`] properties + +Launches an instance of the users preferred editor on a temporary file. Once the user exits their editor, the contents of the temporary file are read in as the result. The editor to use is determined by reading the $VISUAL or $EDITOR environment variables. If neither of those are present, notepad (on Windows) or vim (Linux or Mac) is used. + + + +## User Interfaces and layouts + +Along with the prompts, Inquirer offers some basic text UI. + +#### Bottom Bar - `inquirer.ui.BottomBar` + +This UI present a fixed text at the bottom of a free text zone. This is useful to keep a message to the bottom of the screen while outputting command outputs on the higher section. + +```javascript +var ui = new inquirer.ui.BottomBar(); + +// pipe a Stream to the log zone +outputStream.pipe(ui.log); + +// Or simply write output +ui.log.write('something just happened.'); +ui.log.write('Almost over, standby!'); + +// During processing, update the bottom bar content to display a loader +// or output a progress bar, etc +ui.updateBottomBar('new bottom bar content'); +``` + + + +## Reactive interface + +Internally, Inquirer uses the [JS reactive extension](https://github.com/ReactiveX/rxjs) to handle events and async flows. + +This mean you can take advantage of this feature to provide more advanced flows. For example, you can dynamically add questions to be asked: + +```js +var prompts = new Rx.Subject(); +inquirer.prompt(prompts); + +// At some point in the future, push new questions +prompts.next({ + /* question... */ +}); +prompts.next({ + /* question... */ +}); + +// When you're done +prompts.complete(); +``` + +And using the return value `process` property, you can access more fine grained callbacks: + +```js +inquirer.prompt(prompts).ui.process.subscribe(onEachAnswer, onError, onComplete); +``` + +## Support (OS Terminals) + + + +You should expect mostly good support for the CLI below. This does not mean we won't +look at issues found on other command line - feel free to report any! + +- **Mac OS**: + - Terminal.app + - iTerm +- **Windows**: + - [ConEmu](https://conemu.github.io/) + - cmd.exe + - Powershell + - Cygwin +- **Linux (Ubuntu, openSUSE, Arch Linux, etc)**: + - gnome-terminal (Terminal GNOME) + - konsole + +## News on the march (Release notes) + + + +Please refer to the [Github releases section for the changelog](https://github.com/SBoudrias/Inquirer.js/releases) + +## Contributing + + + +**Unit test** +Unit test are written in [Mocha](https://mochajs.org/). Please add a unit test for every new feature or bug fix. `npm test` to run the test suite. + +**Documentation** +Add documentation for every API change. Feel free to send typo fixes and better docs! + +We're looking to offer good support for multiple prompts and environments. If you want to +help, we'd like to keep a list of testers for each terminal/OS so we can contact you and +get feedback before release. Let us know if you want to be added to the list (just tweet +to [@vaxilart](https://twitter.com/Vaxilart)) or just add your name to [the wiki](https://github.com/SBoudrias/Inquirer.js/wiki/Testers) + +## License + + + +Copyright (c) 2016 Simon Boudrias (twitter: [@vaxilart](https://twitter.com/Vaxilart)) +Licensed under the MIT license. + +## Plugins + + + +### Prompts + +[**autocomplete**](https://github.com/mokkabonna/inquirer-autocomplete-prompt)
+Presents a list of options as the user types, compatible with other packages such as fuzzy (for search)
+
+![autocomplete prompt](https://github.com/mokkabonna/inquirer-autocomplete-prompt/raw/master/inquirer.gif) + +[**checkbox-plus**](https://github.com/faressoft/inquirer-checkbox-plus-prompt)
+Checkbox list with autocomplete and other additions
+
+![checkbox-plus](https://github.com/faressoft/inquirer-checkbox-plus-prompt/raw/master/demo.gif) + +[**datetime**](https://github.com/DerekTBrown/inquirer-datepicker-prompt)
+Customizable date/time selector using both number pad and arrow keys
+
+![Datetime Prompt](https://github.com/DerekTBrown/inquirer-datepicker-prompt/raw/master/example/datetime-prompt.png) + +[**inquirer-select-line**](https://github.com/adam-golab/inquirer-select-line)
+Prompt for selecting index in array where add new element
+
+![inquirer-select-line gif](https://media.giphy.com/media/xUA7b1MxpngddUvdHW/giphy.gif) + +[**command**](https://github.com/sullof/inquirer-command-prompt)
+
+Simple prompt with command history and dynamic autocomplete + +[**inquirer-fuzzy-path**](https://github.com/adelsz/inquirer-fuzzy-path)
+Prompt for fuzzy file/directory selection.
+
+![inquirer-fuzzy-path](https://raw.githubusercontent.com/adelsz/inquirer-fuzzy-path/master/recording.gif) + +[**inquirer-chalk-pipe**](https://github.com/LitoMore/inquirer-chalk-pipe)
+Prompt for input chalk-pipe style strings
+
+![inquirer-chalk-pipe](https://github.com/LitoMore/inquirer-chalk-pipe/raw/master/screenshot.gif) + +[**inquirer-search-checkbox**](https://github.com/clinyong/inquirer-search-checkbox)
+Searchable Inquirer checkbox
+ +[**inquirer-prompt-suggest**](https://github.com/olistic/inquirer-prompt-suggest)
+Inquirer prompt for your less creative users. + +![inquirer-prompt-suggest](https://user-images.githubusercontent.com/5600126/40391192-d4f3d6d0-5ded-11e8-932f-4b75b642c09e.gif) diff --git a/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/checkbox.js b/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/checkbox.js index d27d46d85d7b9f..f1e3bad2e52ec2 100644 --- a/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/checkbox.js +++ b/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/checkbox.js @@ -29,7 +29,6 @@ class CheckboxPrompt extends Base { } this.pointer = 0; - this.firstRender = true; // Make sure no default is set (so it won't be printed) this.opt.default = null; @@ -87,7 +86,7 @@ class CheckboxPrompt extends Base { var message = this.getQuestion(); var bottomContent = ''; - if (this.firstRender) { + if (!this.spaceKeyPressed) { message += '(Press ' + chalk.cyan.bold('') + @@ -166,6 +165,7 @@ class CheckboxPrompt extends Base { } onSpaceKey() { + this.spaceKeyPressed = true; this.toggleChoice(this.pointer); this.render(); } diff --git a/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/password.js b/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/password.js index 1acdc86327d748..6b85d98cf63031 100644 --- a/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/password.js +++ b/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/password.js @@ -37,11 +37,9 @@ class PasswordPrompt extends Base { validation.success.forEach(this.onEnd.bind(this)); validation.error.forEach(this.onError.bind(this)); - if (this.opt.mask) { - events.keypress - .pipe(takeUntil(validation.success)) - .forEach(this.onKeypress.bind(this)); - } + events.keypress + .pipe(takeUntil(validation.success)) + .forEach(this.onKeypress.bind(this)); // Init this.render(); diff --git a/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/rawlist.js b/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/rawlist.js index 33f2ead18a3971..4e0bcab0f6f3ab 100644 --- a/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/rawlist.js +++ b/tools/node_modules/eslint/node_modules/inquirer/lib/prompts/rawlist.js @@ -67,6 +67,10 @@ class RawListPrompt extends Base { events.keypress .pipe(takeUntil(validation.success)) .forEach(this.onKeypress.bind(this)); + events.normalizedUpKey.pipe(takeUntil(events.line)).forEach(this.onUpKey.bind(this)); + events.normalizedDownKey + .pipe(takeUntil(events.line)) + .forEach(this.onDownKey.bind(this)); // Init the prompt this.render(); @@ -146,6 +150,34 @@ class RawListPrompt extends Base { this.render(); } + + /** + * When user press up key + */ + + onUpKey() { + this.onArrowKey('up'); + } + + /** + * When user press down key + */ + + onDownKey() { + this.onArrowKey('down'); + } + + /** + * When user press up or down key + * @param {String} type Arrow type: up or down + */ + + onArrowKey(type) { + var index = this.rl.line.length ? Number(this.rl.line) - 1 : 0; + index += type === 'up' ? -1 : 1; + this.rl.line = String(index + 1); + this.onKeypress(); + } } /** diff --git a/tools/node_modules/eslint/node_modules/inquirer/node_modules/ansi-regex/index.js b/tools/node_modules/eslint/node_modules/inquirer/node_modules/ansi-regex/index.js new file mode 100644 index 00000000000000..76d354a9afffd0 --- /dev/null +++ b/tools/node_modules/eslint/node_modules/inquirer/node_modules/ansi-regex/index.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = options => { + options = Object.assign({ + onlyFirst: false + }, options); + + const pattern = [ + '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\\u0007)', + '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' + ].join('|'); + + return new RegExp(pattern, options.onlyFirst ? undefined : 'g'); +}; diff --git a/tools/node_modules/eslint/node_modules/del/license b/tools/node_modules/eslint/node_modules/inquirer/node_modules/ansi-regex/license similarity index 100% rename from tools/node_modules/eslint/node_modules/del/license rename to tools/node_modules/eslint/node_modules/inquirer/node_modules/ansi-regex/license diff --git a/tools/node_modules/eslint/node_modules/inquirer/node_modules/ansi-regex/package.json b/tools/node_modules/eslint/node_modules/inquirer/node_modules/ansi-regex/package.json new file mode 100644 index 00000000000000..bcc09292f62a6d --- /dev/null +++ b/tools/node_modules/eslint/node_modules/inquirer/node_modules/ansi-regex/package.json @@ -0,0 +1,62 @@ +{ + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/chalk/ansi-regex/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Regular expression for matching ANSI escape codes", + "devDependencies": { + "ava": "^0.25.0", + "xo": "^0.23.0" + }, + "engines": { + "node": ">=6" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/chalk/ansi-regex#readme", + "keywords": [ + "ansi", + "styles", + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "string", + "tty", + "escape", + "formatting", + "rgb", + "256", + "shell", + "xterm", + "command-line", + "text", + "regex", + "regexp", + "re", + "match", + "test", + "find", + "pattern" + ], + "license": "MIT", + "name": "ansi-regex", + "repository": { + "type": "git", + "url": "git+https://github.com/chalk/ansi-regex.git" + }, + "scripts": { + "test": "xo && ava", + "view-supported": "node fixtures/view-codes.js" + }, + "version": "4.0.0" +} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/inquirer/node_modules/ansi-regex/readme.md b/tools/node_modules/eslint/node_modules/inquirer/node_modules/ansi-regex/readme.md new file mode 100644 index 00000000000000..1b9d5fa98a0a26 --- /dev/null +++ b/tools/node_modules/eslint/node_modules/inquirer/node_modules/ansi-regex/readme.md @@ -0,0 +1,65 @@ +# ansi-regex [![Build Status](https://travis-ci.org/chalk/ansi-regex.svg?branch=master)](https://travis-ci.org/chalk/ansi-regex) + +> Regular expression for matching [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) + + +## Install + +``` +$ npm install ansi-regex +``` + + +## Usage + +```js +const ansiRegex = require('ansi-regex'); + +ansiRegex().test('\u001B[4mcake\u001B[0m'); +//=> true + +ansiRegex().test('cake'); +//=> false + +'\u001B[4mcake\u001B[0m'.match(ansiRegex()); +//=> ['\u001B[4m', '\u001B[0m'] + +'\u001B[4mcake\u001B[0m'.match(ansiRegex({onlyFirst: true})); +//=> ['\u001B[4m'] +``` + + +## API + +### ansiRegex([options]) + +Returns a regex for matching ANSI escape codes. + +#### options + +##### onlyFirst + +Type: `boolean`
+Default: `false` *(Matches any ANSI escape codes in a string)* + +Match only the first ANSI escape. + + +## FAQ + +### Why do you test for codes not in the ECMA 48 standard? + +Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. We test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them. + +On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out. + + +## Maintainers + +- [Sindre Sorhus](https://github.com/sindresorhus) +- [Josh Junon](https://github.com/qix-) + + +## License + +MIT diff --git a/tools/node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi/index.js b/tools/node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi/index.js new file mode 100644 index 00000000000000..96e0292c8e2f64 --- /dev/null +++ b/tools/node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi/index.js @@ -0,0 +1,4 @@ +'use strict'; +const ansiRegex = require('ansi-regex'); + +module.exports = input => typeof input === 'string' ? input.replace(ansiRegex(), '') : input; diff --git a/tools/node_modules/eslint/node_modules/p-map/license b/tools/node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi/license similarity index 100% rename from tools/node_modules/eslint/node_modules/p-map/license rename to tools/node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi/license diff --git a/tools/node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi/package.json b/tools/node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi/package.json new file mode 100644 index 00000000000000..8b96e6d04b563a --- /dev/null +++ b/tools/node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi/package.json @@ -0,0 +1,61 @@ +{ + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/chalk/strip-ansi/issues" + }, + "bundleDependencies": false, + "dependencies": { + "ansi-regex": "^4.0.0" + }, + "deprecated": false, + "description": "Strip ANSI escape codes", + "devDependencies": { + "ava": "^0.25.0", + "xo": "^0.23.0" + }, + "engines": { + "node": ">=6" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/chalk/strip-ansi#readme", + "keywords": [ + "strip", + "trim", + "remove", + "ansi", + "styles", + "color", + "colour", + "colors", + "terminal", + "console", + "string", + "tty", + "escape", + "formatting", + "rgb", + "256", + "shell", + "xterm", + "log", + "logging", + "command-line", + "text" + ], + "license": "MIT", + "name": "strip-ansi", + "repository": { + "type": "git", + "url": "git+https://github.com/chalk/strip-ansi.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "5.0.0" +} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi/readme.md b/tools/node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi/readme.md new file mode 100644 index 00000000000000..d4871fb44351c6 --- /dev/null +++ b/tools/node_modules/eslint/node_modules/inquirer/node_modules/strip-ansi/readme.md @@ -0,0 +1,53 @@ +# strip-ansi [![Build Status](https://travis-ci.org/chalk/strip-ansi.svg?branch=master)](https://travis-ci.org/chalk/strip-ansi) + +> Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) + +--- + +
+ + Get professional support for 'strip-ansi' with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
+ +--- + +## Install + +``` +$ npm install strip-ansi +``` + + +## Usage + +```js +const stripAnsi = require('strip-ansi'); + +stripAnsi('\u001B[4mUnicorn\u001B[0m'); +//=> 'Unicorn' +``` + + +## Related + +- [strip-ansi-cli](https://github.com/chalk/strip-ansi-cli) - CLI for this module +- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Streaming version of this module +- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes +- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes +- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right + + +## Maintainers + +- [Sindre Sorhus](https://github.com/sindresorhus) +- [Josh Junon](https://github.com/qix-) + + +## License + +MIT diff --git a/tools/node_modules/eslint/node_modules/inquirer/package.json b/tools/node_modules/eslint/node_modules/inquirer/package.json index a9679e830a3986..6f1433efc24094 100644 --- a/tools/node_modules/eslint/node_modules/inquirer/package.json +++ b/tools/node_modules/eslint/node_modules/inquirer/package.json @@ -19,26 +19,26 @@ "run-async": "^2.2.0", "rxjs": "^6.1.0", "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", + "strip-ansi": "^5.0.0", "through": "^2.3.6" }, "deprecated": false, "description": "A collection of common interactive command line user interfaces.", "devDependencies": { "chai": "^4.0.1", - "chalk-pipe": "^1.2.0", + "chalk-pipe": "^2.0.0", "cmdify": "^0.0.4", "mocha": "^5.0.0", "mockery": "^2.1.0", - "nsp": "^3.0.0", - "nyc": "^12.0.1", - "sinon": "^5.0.0" + "nyc": "^13.1.0", + "sinon": "^7.1.1" }, "engines": { "node": ">=6.0.0" }, "files": [ - "lib" + "lib", + "README.md" ], "homepage": "https://github.com/SBoudrias/Inquirer.js#readme", "keywords": [ @@ -57,9 +57,10 @@ "url": "git+https://github.com/SBoudrias/Inquirer.js.git" }, "scripts": { + "postpublish": "rm -f README.md", "posttest": "nyc report --reporter=text-lcov > ../../coverage/nyc-report.lcov", - "prepublish": "nsp check", + "prepublishOnly": "cp ../../README.md .", "test": "nyc mocha test/**/* -r ./test/before" }, - "version": "6.2.0" + "version": "6.2.1" } \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/is-path-cwd/index.js b/tools/node_modules/eslint/node_modules/is-path-cwd/index.js deleted file mode 100644 index 24b6fdea37ee36..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-path-cwd/index.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; -var path = require('path'); - -module.exports = function (str) { - return path.resolve(str) === path.resolve(process.cwd()); -}; diff --git a/tools/node_modules/eslint/node_modules/is-path-cwd/package.json b/tools/node_modules/eslint/node_modules/is-path-cwd/package.json deleted file mode 100644 index cfb452cc043352..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-path-cwd/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "http://sindresorhus.com" - }, - "bugs": { - "url": "https://github.com/sindresorhus/is-path-cwd/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Check if a path is CWD", - "devDependencies": { - "mocha": "*" - }, - "engines": { - "node": ">=0.10.0" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/sindresorhus/is-path-cwd#readme", - "keywords": [ - "path", - "cwd", - "pwd", - "check", - "filepath", - "file", - "folder" - ], - "license": "MIT", - "name": "is-path-cwd", - "repository": { - "type": "git", - "url": "git+https://github.com/sindresorhus/is-path-cwd.git" - }, - "scripts": { - "test": "mocha" - }, - "version": "1.0.0" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/is-path-cwd/readme.md b/tools/node_modules/eslint/node_modules/is-path-cwd/readme.md deleted file mode 100644 index 2d9d65f989c106..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-path-cwd/readme.md +++ /dev/null @@ -1,28 +0,0 @@ -# is-path-cwd [![Build Status](https://travis-ci.org/sindresorhus/is-path-cwd.svg?branch=master)](https://travis-ci.org/sindresorhus/is-path-cwd) - -> Check if a path is [CWD](http://en.wikipedia.org/wiki/Working_directory) - - -## Install - -```sh -$ npm install --save is-path-cwd -``` - - -## Usage - -```js -var isPathCwd = require('is-path-cwd'); - -isPathCwd(process.cwd()); -//=> true - -isPathCwd('unicorn'); -//=> false -``` - - -## License - -MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/tools/node_modules/eslint/node_modules/is-path-in-cwd/index.js b/tools/node_modules/eslint/node_modules/is-path-in-cwd/index.js deleted file mode 100644 index 75611656ae7e3d..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-path-in-cwd/index.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; -var isPathInside = require('is-path-inside'); - -module.exports = function (str) { - return isPathInside(str, process.cwd()); -}; diff --git a/tools/node_modules/eslint/node_modules/is-path-in-cwd/license b/tools/node_modules/eslint/node_modules/is-path-in-cwd/license deleted file mode 100644 index 654d0bfe943437..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-path-in-cwd/license +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -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/tools/node_modules/eslint/node_modules/is-path-in-cwd/package.json b/tools/node_modules/eslint/node_modules/is-path-in-cwd/package.json deleted file mode 100644 index 4110075d9af370..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-path-in-cwd/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "http://sindresorhus.com" - }, - "bugs": { - "url": "https://github.com/sindresorhus/is-path-in-cwd/issues" - }, - "bundleDependencies": false, - "dependencies": { - "is-path-inside": "^1.0.0" - }, - "deprecated": false, - "description": "Check if a path is in the current working directory", - "devDependencies": { - "mocha": "*" - }, - "engines": { - "node": ">=0.10.0" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/sindresorhus/is-path-in-cwd#readme", - "keywords": [ - "path", - "cwd", - "pwd", - "check", - "filepath", - "file", - "folder", - "in", - "inside" - ], - "license": "MIT", - "name": "is-path-in-cwd", - "repository": { - "type": "git", - "url": "git+https://github.com/sindresorhus/is-path-in-cwd.git" - }, - "scripts": { - "test": "mocha" - }, - "version": "1.0.1" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/is-path-in-cwd/readme.md b/tools/node_modules/eslint/node_modules/is-path-in-cwd/readme.md deleted file mode 100644 index 81185502a810c0..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-path-in-cwd/readme.md +++ /dev/null @@ -1,31 +0,0 @@ -# is-path-in-cwd [![Build Status](https://travis-ci.org/sindresorhus/is-path-in-cwd.svg?branch=master)](https://travis-ci.org/sindresorhus/is-path-in-cwd) - -> Check if a path is in the [current working directory](http://en.wikipedia.org/wiki/Working_directory) - - -## Install - -```sh -$ npm install --save is-path-in-cwd -``` - - -## Usage - -```js -var isPathInCwd = require('is-path-in-cwd'); - -isPathInCwd('unicorn'); -//=> true - -isPathInCwd('../rainbow'); -//=> false - -isPathInCwd('.'); -//=> false -``` - - -## License - -MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/tools/node_modules/eslint/node_modules/is-path-inside/index.js b/tools/node_modules/eslint/node_modules/is-path-inside/index.js deleted file mode 100644 index 0a4d2fd1e58074..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-path-inside/index.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; -var path = require('path'); -var pathIsInside = require('path-is-inside'); - -module.exports = function (a, b) { - a = path.resolve(a); - b = path.resolve(b); - - if (a === b) { - return false; - } - - return pathIsInside(a, b); -}; diff --git a/tools/node_modules/eslint/node_modules/is-path-inside/license b/tools/node_modules/eslint/node_modules/is-path-inside/license deleted file mode 100644 index 654d0bfe943437..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-path-inside/license +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -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/tools/node_modules/eslint/node_modules/is-path-inside/package.json b/tools/node_modules/eslint/node_modules/is-path-inside/package.json deleted file mode 100644 index 8686a73d3e52be..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-path-inside/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "bugs": { - "url": "https://github.com/sindresorhus/is-path-inside/issues" - }, - "bundleDependencies": false, - "dependencies": { - "path-is-inside": "^1.0.1" - }, - "deprecated": false, - "description": "Check if a path is inside another path", - "devDependencies": { - "ava": "*", - "xo": "*" - }, - "engines": { - "node": ">=0.10.0" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/sindresorhus/is-path-inside#readme", - "keywords": [ - "path", - "inside", - "folder", - "directory", - "dir", - "file", - "resolve" - ], - "license": "MIT", - "name": "is-path-inside", - "repository": { - "type": "git", - "url": "git+https://github.com/sindresorhus/is-path-inside.git" - }, - "scripts": { - "test": "xo && ava" - }, - "version": "1.0.1" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/is-path-inside/readme.md b/tools/node_modules/eslint/node_modules/is-path-inside/readme.md deleted file mode 100644 index cc5f51625d3e9c..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-path-inside/readme.md +++ /dev/null @@ -1,34 +0,0 @@ -# is-path-inside [![Build Status](https://travis-ci.org/sindresorhus/is-path-inside.svg?branch=master)](https://travis-ci.org/sindresorhus/is-path-inside) - -> Check if a path is inside another path - - -## Install - -``` -$ npm install --save is-path-inside -``` - - -## Usage - -```js -var isPathInside = require('is-path-inside'); - -isPathInside('a/b/c', 'a/b'); -//=> true - -isPathInside('a/b/c', 'x/y'); -//=> false - -isPathInside('a/b/c', 'a/b/c'); -//=> false - -isPathInside('/Users/sindresorhus/dev/unicorn', '/Users/sindresorhus'); -//=> true -``` - - -## License - -MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/tools/node_modules/eslint/node_modules/is-resolvable/LICENSE b/tools/node_modules/eslint/node_modules/is-resolvable/LICENSE deleted file mode 100644 index b291242ea6dfd4..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-resolvable/LICENSE +++ /dev/null @@ -1,6 +0,0 @@ -ISC License (ISC) -Copyright 2018 Shinnosuke Watanabe - -Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/tools/node_modules/eslint/node_modules/is-resolvable/README.md b/tools/node_modules/eslint/node_modules/is-resolvable/README.md deleted file mode 100644 index 040c165ac8aed7..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-resolvable/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# is-resolvable - -[![npm version](https://img.shields.io/npm/v/is-resolvable.svg)](https://www.npmjs.com/package/is-resolvable) -[![Build Status](https://travis-ci.org/shinnn/is-resolvable.svg?branch=master)](https://travis-ci.org/shinnn/is-resolvable) -[![Build status](https://ci.appveyor.com/api/projects/status/ww1cdpignehlasbs?svg=true)](https://ci.appveyor.com/project/ShinnosukeWatanabe/is-resolvable) -[![Coverage Status](https://img.shields.io/coveralls/shinnn/is-resolvable.svg)](https://coveralls.io/r/shinnn/is-resolvable) - -A [Node.js](https://nodejs.org/) module to check if a given module ID is resolvable with [`require()`](https://nodejs.org/api/globals.html#globals_require) - -```javascript -const isResolvable = require('is-resolvable'); - -isResolvable('fs'); //=> true -isResolvable('path'); //=> true - -// When ./index.js exists -isResolvable('./index.js') //=> true -isResolvable('./index') //=> true -isResolvable('.') //=> true -``` - -## Installation - -[Use](https://docs.npmjs.com/cli/install) [npm](https://docs.npmjs.com/getting-started/what-is-npm). - -``` -npm install is-resolvable -``` - -## API - -```javascript -const isResolvable = require('is-resolvable'); -``` - -### isResolvable(*moduleId* [, *options*]) - -*moduleId*: `string` (module ID) -*options*: `Object` ([`require.resolve`](https://nodejs.org/api/modules.html#modules_require_resolve_request_options) options) -Return: `boolean` - -It returns `true` if `require()` can load a file form a given module ID, otherwise `false`. - -```javascript -const isResolvable = require('is-resolvable'); - -// When ./foo.json exists -isResolvable('./foo.json'); //=> true -isResolvable('./foo'); //=> true - -isResolvable('./foo.js'); //=> false - -// When `eslint` module is installed but `jshint` isn't -isResolvable('eslint'); //=> true -isResolvable('jshint'); //=> false - -// When `lodash` module is installed -isResolvable('lodash/isObject'); //=> true -isResolvable('lodash/fp/reject.js'); //=> true -``` - -The second argument accepts an options object for `require.resolve()`. - -```javascript -// When ./bar/baz.js exists - -isResolvable('./baz.js'); //=> false -isResolvable('./baz.js', {paths: ['bar']}); //=> true -``` - -## License - -[ISC License](./LICENSE) © 2018 Shinnosuke Watanabe diff --git a/tools/node_modules/eslint/node_modules/is-resolvable/index.js b/tools/node_modules/eslint/node_modules/is-resolvable/index.js deleted file mode 100644 index 1be95c0258126a..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-resolvable/index.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -var inspect = require('util').inspect; - -module.exports = function isResolvable(moduleId, options) { - if (typeof moduleId !== 'string') { - throw new TypeError(inspect(moduleId) + ' is not a string. Expected a valid Node.js module identifier (), for example \'eslint\', \'./index.js\', \'./lib\'.'); - } - - try { - require.resolve(moduleId, options); - return true; - } catch (err) { - return false; - } -}; diff --git a/tools/node_modules/eslint/node_modules/is-resolvable/package.json b/tools/node_modules/eslint/node_modules/is-resolvable/package.json deleted file mode 100644 index 46538d27f7fced..00000000000000 --- a/tools/node_modules/eslint/node_modules/is-resolvable/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "author": { - "name": "Shinnosuke Watanabe", - "url": "https://github.com/shinnn" - }, - "bugs": { - "url": "https://github.com/shinnn/is-resolvable/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Check if a module ID is resolvable with require()", - "devDependencies": { - "@shinnn/eslint-config-node": "^5.0.0", - "eslint": "^4.16.0", - "istanbul": "^0.4.5", - "tape": "^4.8.0" - }, - "eslintConfig": { - "extends": "@shinnn/node", - "rules": { - "no-var": "off", - "prefer-template": "off" - } - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/shinnn/is-resolvable#readme", - "keywords": [ - "file", - "path", - "resolve", - "resolvable", - "check", - "module" - ], - "license": "ISC", - "name": "is-resolvable", - "repository": { - "type": "git", - "url": "git+https://github.com/shinnn/is-resolvable.git" - }, - "scripts": { - "coverage": "istanbul cover --print=both test.js", - "pretest": "eslint --fix --format=codeframe index.js test.js", - "test": "node --throw-deprecation --track-heap-objects test.js" - }, - "version": "1.1.0" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/p-map/index.js b/tools/node_modules/eslint/node_modules/p-map/index.js deleted file mode 100644 index f91477e1f5b3f3..00000000000000 --- a/tools/node_modules/eslint/node_modules/p-map/index.js +++ /dev/null @@ -1,67 +0,0 @@ -'use strict'; -module.exports = (iterable, mapper, opts) => new Promise((resolve, reject) => { - opts = Object.assign({ - concurrency: Infinity - }, opts); - - if (typeof mapper !== 'function') { - throw new TypeError('Mapper function is required'); - } - - const concurrency = opts.concurrency; - - if (!(typeof concurrency === 'number' && concurrency >= 1)) { - throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${concurrency}\` (${typeof concurrency})`); - } - - const ret = []; - const iterator = iterable[Symbol.iterator](); - let isRejected = false; - let iterableDone = false; - let resolvingCount = 0; - let currentIdx = 0; - - const next = () => { - if (isRejected) { - return; - } - - const nextItem = iterator.next(); - const i = currentIdx; - currentIdx++; - - if (nextItem.done) { - iterableDone = true; - - if (resolvingCount === 0) { - resolve(ret); - } - - return; - } - - resolvingCount++; - - Promise.resolve(nextItem.value) - .then(el => mapper(el, i)) - .then( - val => { - ret[i] = val; - resolvingCount--; - next(); - }, - err => { - isRejected = true; - reject(err); - } - ); - }; - - for (let i = 0; i < concurrency; i++) { - next(); - - if (iterableDone) { - break; - } - } -}); diff --git a/tools/node_modules/eslint/node_modules/p-map/package.json b/tools/node_modules/eslint/node_modules/p-map/package.json deleted file mode 100644 index 455e05c8bf2ebf..00000000000000 --- a/tools/node_modules/eslint/node_modules/p-map/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "bugs": { - "url": "https://github.com/sindresorhus/p-map/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Map over promises concurrently", - "devDependencies": { - "ava": "*", - "delay": "^2.0.0", - "in-range": "^1.0.0", - "random-int": "^1.0.0", - "time-span": "^2.0.0", - "xo": "*" - }, - "engines": { - "node": ">=4" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/sindresorhus/p-map#readme", - "keywords": [ - "promise", - "map", - "resolved", - "wait", - "collection", - "iterable", - "iterator", - "race", - "fulfilled", - "async", - "await", - "promises", - "concurrently", - "concurrency", - "parallel", - "bluebird" - ], - "license": "MIT", - "name": "p-map", - "repository": { - "type": "git", - "url": "git+https://github.com/sindresorhus/p-map.git" - }, - "scripts": { - "test": "xo && ava" - }, - "version": "1.2.0" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/p-map/readme.md b/tools/node_modules/eslint/node_modules/p-map/readme.md deleted file mode 100644 index 7727581a0e578c..00000000000000 --- a/tools/node_modules/eslint/node_modules/p-map/readme.md +++ /dev/null @@ -1,81 +0,0 @@ -# p-map [![Build Status](https://travis-ci.org/sindresorhus/p-map.svg?branch=master)](https://travis-ci.org/sindresorhus/p-map) - -> Map over promises concurrently - -Useful when you need to run promise-returning & async functions multiple times with different inputs concurrently. - - -## Install - -``` -$ npm install p-map -``` - - -## Usage - -```js -const pMap = require('p-map'); -const got = require('got'); - -const sites = [ - getWebsiteFromUsername('sindresorhus'), //=> Promise - 'ava.li', - 'todomvc.com', - 'github.com' -]; - -const mapper = el => got.head(el).then(res => res.requestUrl); - -pMap(sites, mapper, {concurrency: 2}).then(result => { - console.log(result); - //=> ['http://sindresorhus.com/', 'http://ava.li/', 'http://todomvc.com/', 'http://github.com/'] -}); -``` - - -## API - -### pMap(input, mapper, [options]) - -Returns a `Promise` that is fulfilled when all promises in `input` and ones returned from `mapper` are fulfilled, or rejects if any of the promises reject. The fulfilled value is an `Array` of the fulfilled values returned from `mapper` in `input` order. - -#### input - -Type: `Iterable` - -Iterated over concurrently in the `mapper` function. - -#### mapper(element, index) - -Type: `Function` - -Expected to return a `Promise` or value. - -#### options - -Type: `Object` - -##### concurrency - -Type: `number`
-Default: `Infinity`
-Minimum: `1` - -Number of concurrently pending promises returned by `mapper`. - - -## Related - -- [p-all](https://github.com/sindresorhus/p-all) - Run promise-returning & async functions concurrently with optional limited concurrency -- [p-filter](https://github.com/sindresorhus/p-filter) - Filter promises concurrently -- [p-times](https://github.com/sindresorhus/p-times) - Run promise-returning & async functions a specific number of times concurrently -- [p-props](https://github.com/sindresorhus/p-props) - Like `Promise.all()` but for `Map` and `Object` -- [p-map-series](https://github.com/sindresorhus/p-map-series) - Map over promises serially -- [p-queue](https://github.com/sindresorhus/p-queue) - Promise queue with concurrency control -- [More…](https://github.com/sindresorhus/promise-fun) - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/tools/node_modules/eslint/node_modules/pify/index.js b/tools/node_modules/eslint/node_modules/pify/index.js deleted file mode 100644 index 1dee43ad08f62b..00000000000000 --- a/tools/node_modules/eslint/node_modules/pify/index.js +++ /dev/null @@ -1,84 +0,0 @@ -'use strict'; - -const processFn = (fn, opts) => function () { - const P = opts.promiseModule; - const args = new Array(arguments.length); - - for (let i = 0; i < arguments.length; i++) { - args[i] = arguments[i]; - } - - return new P((resolve, reject) => { - if (opts.errorFirst) { - args.push(function (err, result) { - if (opts.multiArgs) { - const results = new Array(arguments.length - 1); - - for (let i = 1; i < arguments.length; i++) { - results[i - 1] = arguments[i]; - } - - if (err) { - results.unshift(err); - reject(results); - } else { - resolve(results); - } - } else if (err) { - reject(err); - } else { - resolve(result); - } - }); - } else { - args.push(function (result) { - if (opts.multiArgs) { - const results = new Array(arguments.length - 1); - - for (let i = 0; i < arguments.length; i++) { - results[i] = arguments[i]; - } - - resolve(results); - } else { - resolve(result); - } - }); - } - - fn.apply(this, args); - }); -}; - -module.exports = (obj, opts) => { - opts = Object.assign({ - exclude: [/.+(Sync|Stream)$/], - errorFirst: true, - promiseModule: Promise - }, opts); - - const filter = key => { - const match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key); - return opts.include ? opts.include.some(match) : !opts.exclude.some(match); - }; - - let ret; - if (typeof obj === 'function') { - ret = function () { - if (opts.excludeMain) { - return obj.apply(this, arguments); - } - - return processFn(obj, opts).apply(this, arguments); - }; - } else { - ret = Object.create(Object.getPrototypeOf(obj)); - } - - for (const key in obj) { // eslint-disable-line guard-for-in - const x = obj[key]; - ret[key] = typeof x === 'function' && filter(key) ? processFn(x, opts) : x; - } - - return ret; -}; diff --git a/tools/node_modules/eslint/node_modules/pify/package.json b/tools/node_modules/eslint/node_modules/pify/package.json deleted file mode 100644 index 37d6bd41a0aeb6..00000000000000 --- a/tools/node_modules/eslint/node_modules/pify/package.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "bugs": { - "url": "https://github.com/sindresorhus/pify/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Promisify a callback-style function", - "devDependencies": { - "ava": "*", - "pinkie-promise": "^2.0.0", - "v8-natives": "^1.0.0", - "xo": "*" - }, - "engines": { - "node": ">=4" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/sindresorhus/pify#readme", - "keywords": [ - "promise", - "promises", - "promisify", - "all", - "denodify", - "denodeify", - "callback", - "cb", - "node", - "then", - "thenify", - "convert", - "transform", - "wrap", - "wrapper", - "bind", - "to", - "async", - "await", - "es2015", - "bluebird" - ], - "license": "MIT", - "name": "pify", - "repository": { - "type": "git", - "url": "git+https://github.com/sindresorhus/pify.git" - }, - "scripts": { - "optimization-test": "node --allow-natives-syntax optimization-test.js", - "test": "xo && ava && npm run optimization-test" - }, - "version": "3.0.0" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/pify/readme.md b/tools/node_modules/eslint/node_modules/pify/readme.md deleted file mode 100644 index 376ca4e59d74c4..00000000000000 --- a/tools/node_modules/eslint/node_modules/pify/readme.md +++ /dev/null @@ -1,131 +0,0 @@ -# pify [![Build Status](https://travis-ci.org/sindresorhus/pify.svg?branch=master)](https://travis-ci.org/sindresorhus/pify) - -> Promisify a callback-style function - - -## Install - -``` -$ npm install --save pify -``` - - -## Usage - -```js -const fs = require('fs'); -const pify = require('pify'); - -// Promisify a single function -pify(fs.readFile)('package.json', 'utf8').then(data => { - console.log(JSON.parse(data).name); - //=> 'pify' -}); - -// Promisify all methods in a module -pify(fs).readFile('package.json', 'utf8').then(data => { - console.log(JSON.parse(data).name); - //=> 'pify' -}); -``` - - -## API - -### pify(input, [options]) - -Returns a `Promise` wrapped version of the supplied function or module. - -#### input - -Type: `Function` `Object` - -Callback-style function or module whose methods you want to promisify. - -#### options - -##### multiArgs - -Type: `boolean`
-Default: `false` - -By default, the promisified function will only return the second argument from the callback, which works fine for most APIs. This option can be useful for modules like `request` that return multiple arguments. Turning this on will make it return an array of all arguments from the callback, excluding the error argument, instead of just the second argument. This also applies to rejections, where it returns an array of all the callback arguments, including the error. - -```js -const request = require('request'); -const pify = require('pify'); - -pify(request, {multiArgs: true})('https://sindresorhus.com').then(result => { - const [httpResponse, body] = result; -}); -``` - -##### include - -Type: `string[]` `RegExp[]` - -Methods in a module to promisify. Remaining methods will be left untouched. - -##### exclude - -Type: `string[]` `RegExp[]`
-Default: `[/.+(Sync|Stream)$/]` - -Methods in a module **not** to promisify. Methods with names ending with `'Sync'` are excluded by default. - -##### excludeMain - -Type: `boolean`
-Default: `false` - -If given module is a function itself, it will be promisified. Turn this option on if you want to promisify only methods of the module. - -```js -const pify = require('pify'); - -function fn() { - return true; -} - -fn.method = (data, callback) => { - setImmediate(() => { - callback(null, data); - }); -}; - -// Promisify methods but not `fn()` -const promiseFn = pify(fn, {excludeMain: true}); - -if (promiseFn()) { - promiseFn.method('hi').then(data => { - console.log(data); - }); -} -``` - -##### errorFirst - -Type: `boolean`
-Default: `true` - -Whether the callback has an error as the first argument. You'll want to set this to `false` if you're dealing with an API that doesn't have an error as the first argument, like `fs.exists()`, some browser APIs, Chrome Extension APIs, etc. - -##### promiseModule - -Type: `Function` - -Custom promise module to use instead of the native one. - -Check out [`pinkie-promise`](https://github.com/floatdrop/pinkie-promise) if you need a tiny promise polyfill. - - -## Related - -- [p-event](https://github.com/sindresorhus/p-event) - Promisify an event by waiting for it to be emitted -- [p-map](https://github.com/sindresorhus/p-map) - Map over promises concurrently -- [More…](https://github.com/sindresorhus/promise-fun) - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/tools/node_modules/eslint/node_modules/pinkie-promise/index.js b/tools/node_modules/eslint/node_modules/pinkie-promise/index.js deleted file mode 100644 index 777377a1f777b1..00000000000000 --- a/tools/node_modules/eslint/node_modules/pinkie-promise/index.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; - -module.exports = typeof Promise === 'function' ? Promise : require('pinkie'); diff --git a/tools/node_modules/eslint/node_modules/pinkie-promise/license b/tools/node_modules/eslint/node_modules/pinkie-promise/license deleted file mode 100644 index 1aeb74fd25e171..00000000000000 --- a/tools/node_modules/eslint/node_modules/pinkie-promise/license +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Vsevolod Strukchinsky (github.com/floatdrop) - -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/tools/node_modules/eslint/node_modules/pinkie-promise/package.json b/tools/node_modules/eslint/node_modules/pinkie-promise/package.json deleted file mode 100644 index fb467d516c196d..00000000000000 --- a/tools/node_modules/eslint/node_modules/pinkie-promise/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "author": { - "name": "Vsevolod Strukchinsky", - "email": "floatdrop@gmail.com", - "url": "github.com/floatdrop" - }, - "bugs": { - "url": "https://github.com/floatdrop/pinkie-promise/issues" - }, - "bundleDependencies": false, - "dependencies": { - "pinkie": "^2.0.0" - }, - "deprecated": false, - "description": "ES2015 Promise ponyfill", - "devDependencies": { - "mocha": "*" - }, - "engines": { - "node": ">=0.10.0" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/floatdrop/pinkie-promise#readme", - "keywords": [ - "promise", - "promises", - "es2015", - "es6", - "polyfill", - "ponyfill" - ], - "license": "MIT", - "name": "pinkie-promise", - "repository": { - "type": "git", - "url": "git+https://github.com/floatdrop/pinkie-promise.git" - }, - "scripts": { - "test": "mocha" - }, - "version": "2.0.1" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/pinkie-promise/readme.md b/tools/node_modules/eslint/node_modules/pinkie-promise/readme.md deleted file mode 100644 index 78477f4297d677..00000000000000 --- a/tools/node_modules/eslint/node_modules/pinkie-promise/readme.md +++ /dev/null @@ -1,28 +0,0 @@ -# pinkie-promise [![Build Status](https://travis-ci.org/floatdrop/pinkie-promise.svg?branch=master)](https://travis-ci.org/floatdrop/pinkie-promise) - -> [ES2015 Promise](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) ponyfill - -Module exports global Promise object (if available) or [`pinkie`](http://github.com/floatdrop/pinkie) Promise polyfill. - -## Install - -``` -$ npm install --save pinkie-promise -``` - -## Usage - -```js -var Promise = require('pinkie-promise'); - -new Promise(function (resolve) { resolve('unicorns'); }); -//=> Promise { 'unicorns' } -``` - -## Related - -- [pify](https://github.com/sindresorhus/pify) - Promisify a callback-style function - -## License - -MIT © [Vsevolod Strukchinsky](http://github.com/floatdrop) diff --git a/tools/node_modules/eslint/node_modules/pinkie/index.js b/tools/node_modules/eslint/node_modules/pinkie/index.js deleted file mode 100644 index 14ce1bfe3d4918..00000000000000 --- a/tools/node_modules/eslint/node_modules/pinkie/index.js +++ /dev/null @@ -1,292 +0,0 @@ -'use strict'; - -var PENDING = 'pending'; -var SETTLED = 'settled'; -var FULFILLED = 'fulfilled'; -var REJECTED = 'rejected'; -var NOOP = function () {}; -var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function'; - -var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate; -var asyncQueue = []; -var asyncTimer; - -function asyncFlush() { - // run promise callbacks - for (var i = 0; i < asyncQueue.length; i++) { - asyncQueue[i][0](asyncQueue[i][1]); - } - - // reset async asyncQueue - asyncQueue = []; - asyncTimer = false; -} - -function asyncCall(callback, arg) { - asyncQueue.push([callback, arg]); - - if (!asyncTimer) { - asyncTimer = true; - asyncSetTimer(asyncFlush, 0); - } -} - -function invokeResolver(resolver, promise) { - function resolvePromise(value) { - resolve(promise, value); - } - - function rejectPromise(reason) { - reject(promise, reason); - } - - try { - resolver(resolvePromise, rejectPromise); - } catch (e) { - rejectPromise(e); - } -} - -function invokeCallback(subscriber) { - var owner = subscriber.owner; - var settled = owner._state; - var value = owner._data; - var callback = subscriber[settled]; - var promise = subscriber.then; - - if (typeof callback === 'function') { - settled = FULFILLED; - try { - value = callback(value); - } catch (e) { - reject(promise, e); - } - } - - if (!handleThenable(promise, value)) { - if (settled === FULFILLED) { - resolve(promise, value); - } - - if (settled === REJECTED) { - reject(promise, value); - } - } -} - -function handleThenable(promise, value) { - var resolved; - - try { - if (promise === value) { - throw new TypeError('A promises callback cannot return that same promise.'); - } - - if (value && (typeof value === 'function' || typeof value === 'object')) { - // then should be retrieved only once - var then = value.then; - - if (typeof then === 'function') { - then.call(value, function (val) { - if (!resolved) { - resolved = true; - - if (value === val) { - fulfill(promise, val); - } else { - resolve(promise, val); - } - } - }, function (reason) { - if (!resolved) { - resolved = true; - - reject(promise, reason); - } - }); - - return true; - } - } - } catch (e) { - if (!resolved) { - reject(promise, e); - } - - return true; - } - - return false; -} - -function resolve(promise, value) { - if (promise === value || !handleThenable(promise, value)) { - fulfill(promise, value); - } -} - -function fulfill(promise, value) { - if (promise._state === PENDING) { - promise._state = SETTLED; - promise._data = value; - - asyncCall(publishFulfillment, promise); - } -} - -function reject(promise, reason) { - if (promise._state === PENDING) { - promise._state = SETTLED; - promise._data = reason; - - asyncCall(publishRejection, promise); - } -} - -function publish(promise) { - promise._then = promise._then.forEach(invokeCallback); -} - -function publishFulfillment(promise) { - promise._state = FULFILLED; - publish(promise); -} - -function publishRejection(promise) { - promise._state = REJECTED; - publish(promise); - if (!promise._handled && isNode) { - global.process.emit('unhandledRejection', promise._data, promise); - } -} - -function notifyRejectionHandled(promise) { - global.process.emit('rejectionHandled', promise); -} - -/** - * @class - */ -function Promise(resolver) { - if (typeof resolver !== 'function') { - throw new TypeError('Promise resolver ' + resolver + ' is not a function'); - } - - if (this instanceof Promise === false) { - throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); - } - - this._then = []; - - invokeResolver(resolver, this); -} - -Promise.prototype = { - constructor: Promise, - - _state: PENDING, - _then: null, - _data: undefined, - _handled: false, - - then: function (onFulfillment, onRejection) { - var subscriber = { - owner: this, - then: new this.constructor(NOOP), - fulfilled: onFulfillment, - rejected: onRejection - }; - - if ((onRejection || onFulfillment) && !this._handled) { - this._handled = true; - if (this._state === REJECTED && isNode) { - asyncCall(notifyRejectionHandled, this); - } - } - - if (this._state === FULFILLED || this._state === REJECTED) { - // already resolved, call callback async - asyncCall(invokeCallback, subscriber); - } else { - // subscribe - this._then.push(subscriber); - } - - return subscriber.then; - }, - - catch: function (onRejection) { - return this.then(null, onRejection); - } -}; - -Promise.all = function (promises) { - if (!Array.isArray(promises)) { - throw new TypeError('You must pass an array to Promise.all().'); - } - - return new Promise(function (resolve, reject) { - var results = []; - var remaining = 0; - - function resolver(index) { - remaining++; - return function (value) { - results[index] = value; - if (!--remaining) { - resolve(results); - } - }; - } - - for (var i = 0, promise; i < promises.length; i++) { - promise = promises[i]; - - if (promise && typeof promise.then === 'function') { - promise.then(resolver(i), reject); - } else { - results[i] = promise; - } - } - - if (!remaining) { - resolve(results); - } - }); -}; - -Promise.race = function (promises) { - if (!Array.isArray(promises)) { - throw new TypeError('You must pass an array to Promise.race().'); - } - - return new Promise(function (resolve, reject) { - for (var i = 0, promise; i < promises.length; i++) { - promise = promises[i]; - - if (promise && typeof promise.then === 'function') { - promise.then(resolve, reject); - } else { - resolve(promise); - } - } - }); -}; - -Promise.resolve = function (value) { - if (value && typeof value === 'object' && value.constructor === Promise) { - return value; - } - - return new Promise(function (resolve) { - resolve(value); - }); -}; - -Promise.reject = function (reason) { - return new Promise(function (resolve, reject) { - reject(reason); - }); -}; - -module.exports = Promise; diff --git a/tools/node_modules/eslint/node_modules/pinkie/license b/tools/node_modules/eslint/node_modules/pinkie/license deleted file mode 100644 index 1aeb74fd25e171..00000000000000 --- a/tools/node_modules/eslint/node_modules/pinkie/license +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Vsevolod Strukchinsky (github.com/floatdrop) - -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/tools/node_modules/eslint/node_modules/pinkie/package.json b/tools/node_modules/eslint/node_modules/pinkie/package.json deleted file mode 100644 index e554170bb8a5ba..00000000000000 --- a/tools/node_modules/eslint/node_modules/pinkie/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "author": { - "name": "Vsevolod Strukchinsky", - "email": "floatdrop@gmail.com", - "url": "github.com/floatdrop" - }, - "bugs": { - "url": "https://github.com/floatdrop/pinkie/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "Itty bitty little widdle twinkie pinkie ES2015 Promise implementation", - "devDependencies": { - "core-assert": "^0.1.1", - "coveralls": "^2.11.4", - "mocha": "*", - "nyc": "^3.2.2", - "promises-aplus-tests": "*", - "xo": "^0.10.1" - }, - "engines": { - "node": ">=0.10.0" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/floatdrop/pinkie#readme", - "keywords": [ - "promise", - "promises", - "es2015", - "es6" - ], - "license": "MIT", - "name": "pinkie", - "repository": { - "type": "git", - "url": "git+https://github.com/floatdrop/pinkie.git" - }, - "scripts": { - "coverage": "nyc report --reporter=text-lcov | coveralls", - "test": "xo && nyc mocha" - }, - "version": "2.0.4" -} \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/pinkie/readme.md b/tools/node_modules/eslint/node_modules/pinkie/readme.md deleted file mode 100644 index 1565f95889661b..00000000000000 --- a/tools/node_modules/eslint/node_modules/pinkie/readme.md +++ /dev/null @@ -1,83 +0,0 @@ -

-
- pinkie -
-
-

- -> Itty bitty little widdle twinkie pinkie [ES2015 Promise](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) implementation - -[![Build Status](https://travis-ci.org/floatdrop/pinkie.svg?branch=master)](https://travis-ci.org/floatdrop/pinkie) [![Coverage Status](https://coveralls.io/repos/floatdrop/pinkie/badge.svg?branch=master&service=github)](https://coveralls.io/github/floatdrop/pinkie?branch=master) - -There are [tons of Promise implementations](https://github.com/promises-aplus/promises-spec/blob/master/implementations.md#standalone) out there, but all of them focus on browser compatibility and are often bloated with functionality. - -This module is an exact Promise specification polyfill (like [native-promise-only](https://github.com/getify/native-promise-only)), but in Node.js land (it should be browserify-able though). - - -## Install - -``` -$ npm install --save pinkie -``` - - -## Usage - -```js -var fs = require('fs'); -var Promise = require('pinkie'); - -new Promise(function (resolve, reject) { - fs.readFile('foo.json', 'utf8', function (err, data) { - if (err) { - reject(err); - return; - } - - resolve(data); - }); -}); -//=> Promise -``` - - -### API - -`pinkie` exports bare [ES2015 Promise](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) implementation and polyfills [Node.js rejection events](https://nodejs.org/api/process.html#process_event_unhandledrejection). In case you forgot: - -#### new Promise(executor) - -Returns new instance of `Promise`. - -##### executor - -*Required* -Type: `function` - -Function with two arguments `resolve` and `reject`. The first argument fulfills the promise, the second argument rejects it. - -#### pinkie.all(promises) - -Returns a promise that resolves when all of the promises in the `promises` Array argument have resolved. - -#### pinkie.race(promises) - -Returns a promise that resolves or rejects as soon as one of the promises in the `promises` Array resolves or rejects, with the value or reason from that promise. - -#### pinkie.reject(reason) - -Returns a Promise object that is rejected with the given `reason`. - -#### pinkie.resolve(value) - -Returns a Promise object that is resolved with the given `value`. If the `value` is a thenable (i.e. has a then method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the `value`. - - -## Related - -- [pinkie-promise](https://github.com/floatdrop/pinkie-promise) - Returns the native Promise or this module - - -## License - -MIT © [Vsevolod Strukchinsky](http://github.com/floatdrop) diff --git a/tools/node_modules/eslint/node_modules/progress/lib/node-progress.js b/tools/node_modules/eslint/node_modules/progress/lib/node-progress.js index 5b56c1529d57b3..8eb0740a721c67 100644 --- a/tools/node_modules/eslint/node_modules/progress/lib/node-progress.js +++ b/tools/node_modules/eslint/node_modules/progress/lib/node-progress.js @@ -98,7 +98,7 @@ ProgressBar.prototype.tick = function(len, tokens){ // progress complete if (this.curr >= this.total) { - this.render(); + this.render(undefined, true); this.complete = true; this.terminate(); this.callback(this); @@ -114,14 +114,15 @@ ProgressBar.prototype.tick = function(len, tokens){ * @api public */ -ProgressBar.prototype.render = function (tokens) { +ProgressBar.prototype.render = function (tokens, force) { + force = force !== undefined ? force : false; if (tokens) this.tokens = tokens; if (!this.stream.isTTY) return; var now = Date.now(); var delta = now - this.lastRender; - if (delta < this.renderThrottle) { + if (!force && (delta < this.renderThrottle)) { return; } else { this.lastRender = now; diff --git a/tools/node_modules/eslint/node_modules/progress/package.json b/tools/node_modules/eslint/node_modules/progress/package.json index d20aaf0f9e27d5..64511f8344114f 100644 --- a/tools/node_modules/eslint/node_modules/progress/package.json +++ b/tools/node_modules/eslint/node_modules/progress/package.json @@ -43,5 +43,5 @@ "type": "git", "url": "git://github.com/visionmedia/node-progress.git" }, - "version": "2.0.1" + "version": "2.0.3" } \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/slice-ansi/index.js b/tools/node_modules/eslint/node_modules/slice-ansi/index.js index 634ee9c7be775b..65a1aef5c83d90 100755 --- a/tools/node_modules/eslint/node_modules/slice-ansi/index.js +++ b/tools/node_modules/eslint/node_modules/slice-ansi/index.js @@ -1,5 +1,7 @@ 'use strict'; const isFullwidthCodePoint = require('is-fullwidth-code-point'); +const astralRegex = require('astral-regex'); +const ansiStyles = require('ansi-styles'); const ESCAPES = [ '\u001B', @@ -7,55 +9,23 @@ const ESCAPES = [ ]; const END_CODE = 39; -const ASTRAL_REGEX = /[\uD800-\uDBFF][\uDC00-\uDFFF]/; - -const ESCAPE_CODES = new Map([ - [0, 0], - [1, 22], - [2, 22], - [3, 23], - [4, 24], - [7, 27], - [8, 28], - [9, 29], - [30, 39], - [31, 39], - [32, 39], - [33, 39], - [34, 39], - [35, 39], - [36, 39], - [37, 39], - [90, 39], - [40, 49], - [41, 49], - [42, 49], - [43, 49], - [44, 49], - [45, 49], - [46, 49], - [47, 49] -]); const wrapAnsi = code => `${ESCAPES[0]}[${code}m`; module.exports = (str, begin, end) => { - const arr = Array.from(str.normalize()); + const arr = [...str.normalize()]; end = typeof end === 'number' ? end : arr.length; let insideEscape = false; - let escapeCode; + let escapeCode = null; let visible = 0; let output = ''; - for (const item of arr.entries()) { - const i = item[0]; - const x = item[1]; - + for (const [i, x] of arr.entries()) { let leftEscape = false; - if (ESCAPES.indexOf(x) !== -1) { + if (ESCAPES.includes(x)) { insideEscape = true; const code = /\d[^m]*/.exec(str.slice(i, i + 4)); escapeCode = code === END_CODE ? null : code; @@ -68,17 +38,17 @@ module.exports = (str, begin, end) => { ++visible; } - if (!ASTRAL_REGEX.test(x) && isFullwidthCodePoint(x.codePointAt())) { + if (!astralRegex({exact: true}).test(x) && isFullwidthCodePoint(x.codePointAt())) { ++visible; } if (visible > begin && visible <= end) { output += x; - } else if (visible === begin && !insideEscape && escapeCode !== undefined && escapeCode !== END_CODE) { + } else if (visible === begin && !insideEscape && escapeCode !== null && escapeCode !== END_CODE) { output += wrapAnsi(escapeCode); } else if (visible >= end) { - if (escapeCode !== undefined) { - output += wrapAnsi(ESCAPE_CODES.get(parseInt(escapeCode, 10)) || END_CODE); + if (escapeCode !== null) { + output += wrapAnsi(ansiStyles.codes.get(parseInt(escapeCode, 10)) || END_CODE); } break; } diff --git a/tools/node_modules/eslint/node_modules/slice-ansi/package.json b/tools/node_modules/eslint/node_modules/slice-ansi/package.json index 7d63fad2d0703b..f0f253539f9dc2 100644 --- a/tools/node_modules/eslint/node_modules/slice-ansi/package.json +++ b/tools/node_modules/eslint/node_modules/slice-ansi/package.json @@ -1,26 +1,24 @@ { - "author": { - "name": "David Caccavella", - "email": "threedeecee@gmail.com" - }, "bugs": { "url": "https://github.com/chalk/slice-ansi/issues" }, "bundleDependencies": false, "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" }, "deprecated": false, "description": "Slice a string with ANSI escape codes", "devDependencies": { - "ava": "*", + "ava": "^0.25.0", "chalk": "^2.0.1", "random-item": "^1.0.0", - "strip-ansi": "^4.0.0", - "xo": "*" + "strip-ansi": "^5.0.0", + "xo": "^0.23.0" }, "engines": { - "node": ">=4" + "node": ">=6" }, "files": [ "index.js" @@ -58,5 +56,5 @@ "scripts": { "test": "xo && ava" }, - "version": "1.0.0" + "version": "2.0.0" } \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/slice-ansi/readme.md b/tools/node_modules/eslint/node_modules/slice-ansi/readme.md index 628eed2e5053b4..7e9243e46a9086 100755 --- a/tools/node_modules/eslint/node_modules/slice-ansi/readme.md +++ b/tools/node_modules/eslint/node_modules/slice-ansi/readme.md @@ -1,4 +1,4 @@ -# slice-ansi [![Build Status](https://travis-ci.org/chalk/slice-ansi.svg?branch=master)](https://travis-ci.org/chalk/slice-ansi) [![XO: Linted](https://img.shields.io/badge/xo-linted-blue.svg)](https://github.com/sindresorhus/xo) +# slice-ansi [![Build Status](https://travis-ci.org/chalk/slice-ansi.svg?branch=master)](https://travis-ci.org/chalk/slice-ansi) [![XO: Linted](https://img.shields.io/badge/xo-linted-blue.svg)](https://github.com/xojs/xo) > Slice a string with [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) diff --git a/tools/node_modules/eslint/node_modules/table/package.json b/tools/node_modules/eslint/node_modules/table/package.json index 3e6fcb12d1985a..ea3580ca152692 100644 --- a/tools/node_modules/eslint/node_modules/table/package.json +++ b/tools/node_modules/eslint/node_modules/table/package.json @@ -9,19 +9,19 @@ }, "bundleDependencies": false, "dependencies": { - "ajv": "^6.5.3", - "lodash": "^4.17.10", - "slice-ansi": "1.0.0", + "ajv": "^6.6.1", + "lodash": "^4.17.11", + "slice-ansi": "2.0.0", "string-width": "^2.1.1" }, "deprecated": false, "description": "Formats data into a string table.", "devDependencies": { - "@babel/cli": "^7.1.2", - "@babel/core": "^7.1.2", + "@babel/cli": "^7.1.5", + "@babel/core": "^7.1.6", "@babel/node": "^7.0.0", - "@babel/plugin-transform-flow-strip-types": "^7.0.0", - "@babel/preset-env": "^7.1.0", + "@babel/plugin-transform-flow-strip-types": "^7.1.6", + "@babel/preset-env": "^7.1.6", "@babel/register": "^7.0.0", "ajv-cli": "^3.0.0", "ajv-keywords": "^3.2.0", @@ -30,16 +30,16 @@ "chai": "^4.2.0", "chalk": "^2.4.1", "coveralls": "^3.0.2", - "eslint": "^5.6.1", + "eslint": "^5.9.0", "eslint-config-canonical": "^13.0.0", - "flow-bin": "^0.81.0", + "flow-bin": "^0.87.0", "flow-copy-source": "^2.0.2", - "gitdown": "^2.5.4", - "husky": "^1.0.1", + "gitdown": "^2.5.5", + "husky": "^1.2.0", "mocha": "^5.2.0", "nyc": "^13.1.0", - "semantic-release": "^15.9.16", - "sinon": "^6.3.4" + "semantic-release": "^15.12.3", + "sinon": "^7.1.1" }, "engines": { "node": ">=6.0.0" @@ -85,5 +85,5 @@ "lint": "npm run build && eslint ./src ./test && flow", "test": "mocha --require @babel/register" }, - "version": "5.1.0" + "version": "5.1.1" } \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/vfile-location/index.js b/tools/node_modules/eslint/node_modules/vfile-location/index.js index e2046ce22b3e4c..2d7c21c1808b7f 100644 --- a/tools/node_modules/eslint/node_modules/vfile-location/index.js +++ b/tools/node_modules/eslint/node_modules/vfile-location/index.js @@ -1,9 +1,7 @@ 'use strict' -/* Expose. */ module.exports = factory -/* Factory. */ function factory(file) { var contents = indices(String(file)) @@ -13,13 +11,12 @@ function factory(file) { } } -/* Factory to get the line and column-based `position` for - * `offset` in the bound indices. */ +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. function offsetToPositionFactory(indices) { return offsetToPosition - /* Get the line and column-based `position` for - * `offset` in the bound indices. */ + // Get the line and column-based `position` for `offset` in the bound indices. function offsetToPosition(offset) { var index = -1 var length = indices.length @@ -42,13 +39,13 @@ function offsetToPositionFactory(indices) { } } -/* Factory to get the `offset` for a line and column-based - * `position` in the bound indices. */ +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. function positionToOffsetFactory(indices) { return positionToOffset - /* Get the `offset` for a line and column-based - * `position` in the bound indices. */ + // Get the `offset` for a line and column-based `position` in the bound + // indices. function positionToOffset(position) { var line = position && position.line var column = position && position.column @@ -61,7 +58,7 @@ function positionToOffsetFactory(indices) { } } -/* Get indices of line-breaks in `value`. */ +// Get indices of line-breaks in `value`. function indices(value) { var result = [] var index = value.indexOf('\n') diff --git a/tools/node_modules/eslint/node_modules/vfile-location/package.json b/tools/node_modules/eslint/node_modules/vfile-location/package.json index e6f5695ec0c23d..d7e748e789a82b 100644 --- a/tools/node_modules/eslint/node_modules/vfile-location/package.json +++ b/tools/node_modules/eslint/node_modules/vfile-location/package.json @@ -2,7 +2,7 @@ "author": { "name": "Titus Wormer", "email": "tituswormer@gmail.com", - "url": "http://wooorm.com" + "url": "https://wooorm.com" }, "bugs": { "url": "https://github.com/vfile/vfile-location/issues" @@ -12,7 +12,7 @@ { "name": "Titus Wormer", "email": "tituswormer@gmail.com", - "url": "http://wooorm.com" + "url": "https://wooorm.com" } ], "dependencies": {}, @@ -20,14 +20,14 @@ "description": "Convert between positions (line and column-based) and offsets (range-based) locations in a virtual file", "devDependencies": { "browserify": "^16.0.0", - "esmangle": "^1.0.1", - "nyc": "^11.0.0", + "nyc": "^13.0.0", "prettier": "^1.12.1", - "remark-cli": "^5.0.0", + "remark-cli": "^6.0.0", "remark-preset-wooorm": "^4.0.0", "tape": "^4.0.0", - "vfile": "^2.0.0", - "xo": "^0.20.0" + "tinyify": "^2.4.3", + "vfile": "^3.0.0", + "xo": "^0.23.0" }, "files": [ "index.js" @@ -67,14 +67,14 @@ }, "scripts": { "build": "npm run build-bundle && npm run build-mangle", - "build-bundle": "browserify index.js --bare -s vfileLocation > vfile-location.js", - "build-mangle": "esmangle vfile-location.js > vfile-location.min.js", + "build-bundle": "browserify . -s vfileLocation > vfile-location.js", + "build-mangle": "browserify . -s vfileLocation -p tinyify > vfile-location.min.js", "format": "remark . -qfo && prettier --write '**/*.js' && xo --fix", "test": "npm run format && npm run build && npm run test-coverage", "test-api": "node test", "test-coverage": "nyc --reporter lcov tape test.js" }, - "version": "2.0.3", + "version": "2.0.4", "xo": { "prettier": true, "esnext": false, diff --git a/tools/node_modules/eslint/node_modules/vfile-location/readme.md b/tools/node_modules/eslint/node_modules/vfile-location/readme.md index 87e27dcd8ef0f4..8b2d91f1564e6f 100644 --- a/tools/node_modules/eslint/node_modules/vfile-location/readme.md +++ b/tools/node_modules/eslint/node_modules/vfile-location/readme.md @@ -1,4 +1,9 @@ -# vfile-location [![Build Status][travis-badge]][travis] [![Coverage Status][codecov-badge]][codecov] +# vfile-location + +[![Build][build-badge]][build] +[![Coverage][coverage-badge]][coverage] +[![Downloads][downloads-badge]][downloads] +[![Chat][chat-badge]][chat] Convert between positions (line and column-based) and offsets (range-based) locations in a [virtual file][vfile]. @@ -57,19 +62,27 @@ repository, organisation, or community you agree to abide by its terms. -[travis-badge]: https://img.shields.io/travis/vfile/vfile-location.svg +[build-badge]: https://img.shields.io/travis/vfile/vfile-location.svg + +[build]: https://travis-ci.org/vfile/vfile-location + +[coverage-badge]: https://img.shields.io/codecov/c/github/vfile/vfile-location.svg + +[coverage]: https://codecov.io/github/vfile/vfile-location + +[downloads-badge]: https://img.shields.io/npm/dm/vfile-location.svg -[travis]: https://travis-ci.org/vfile/vfile-location +[downloads]: https://www.npmjs.com/package/vfile-location -[codecov-badge]: https://img.shields.io/codecov/c/github/vfile/vfile-location.svg +[chat-badge]: https://img.shields.io/badge/join%20the%20community-on%20spectrum-7b16ff.svg -[codecov]: https://codecov.io/github/vfile/vfile-location +[chat]: https://spectrum.chat/unified/vfile [npm]: https://docs.npmjs.com/cli/install -[license]: LICENSE +[license]: license -[author]: http://wooorm.com +[author]: https://wooorm.com [vfile]: https://github.com/vfile/vfile diff --git a/tools/node_modules/eslint/node_modules/vfile-message/index.js b/tools/node_modules/eslint/node_modules/vfile-message/index.js index 1a63df89f5b163..c913753249edad 100644 --- a/tools/node_modules/eslint/node_modules/vfile-message/index.js +++ b/tools/node_modules/eslint/node_modules/vfile-message/index.js @@ -4,12 +4,12 @@ var stringify = require('unist-util-stringify-position') module.exports = VMessage -/* Inherit from `Error#`. */ +// Inherit from `Error#`. function VMessagePrototype() {} VMessagePrototype.prototype = Error.prototype VMessage.prototype = new VMessagePrototype() -/* Message properties. */ +// Message properties. var proto = VMessage.prototype proto.file = '' @@ -21,11 +21,11 @@ proto.fatal = null proto.column = null proto.line = null -/* Construct a new VMessage. - * - * Note: We cannot invoke `Error` on the created context, - * as that adds readonly `line` and `column` attributes on - * Safari 9, thus throwing and failing the data. */ +// Construct a new VMessage. +// +// Note: We cannot invoke `Error` on the created context, as that adds readonly +// `line` and `column` attributes on Safari 9, thus throwing and failing the +// data. function VMessage(reason, position, origin) { var parts var range @@ -44,18 +44,18 @@ function VMessage(reason, position, origin) { end: {line: null, column: null} } - /* Node. */ + // Node. if (position && position.position) { position = position.position } if (position) { - /* Position. */ + // Position. if (position.start) { location = position position = position.start } else { - /* Point. */ + // Point. location.start = position } } diff --git a/tools/node_modules/eslint/node_modules/vfile-message/package.json b/tools/node_modules/eslint/node_modules/vfile-message/package.json index 0e54c49bf5c79d..e514c057c2bfa0 100644 --- a/tools/node_modules/eslint/node_modules/vfile-message/package.json +++ b/tools/node_modules/eslint/node_modules/vfile-message/package.json @@ -2,7 +2,7 @@ "author": { "name": "Titus Wormer", "email": "tituswormer@gmail.com", - "url": "http://wooorm.com" + "url": "https://wooorm.com" }, "bugs": { "url": "https://github.com/vfile/vfile-message/issues" @@ -12,7 +12,7 @@ { "name": "Titus Wormer", "email": "tituswormer@gmail.com", - "url": "http://wooorm.com" + "url": "https://wooorm.com" } ], "dependencies": { @@ -22,13 +22,13 @@ "description": "Create a virtual message", "devDependencies": { "browserify": "^16.0.0", - "esmangle": "^1.0.1", - "nyc": "^11.0.0", + "nyc": "^13.0.0", "prettier": "^1.12.1", - "remark-cli": "^5.0.0", + "remark-cli": "^6.0.0", "remark-preset-wooorm": "^4.0.0", "tape": "^4.0.0", - "xo": "^0.20.0" + "tinyify": "^2.4.3", + "xo": "^0.23.0" }, "files": [ "index.js" @@ -66,14 +66,14 @@ }, "scripts": { "build": "npm run build-bundle && npm run build-mangle", - "build-bundle": "browserify index.js --bare -s vfileMessage > vfile-message.js", - "build-mangle": "esmangle vfile-message.js > vfile-message.min.js", + "build-bundle": "browserify . -s vfileMessage > vfile-message.js", + "build-mangle": "browserify . -s vfileMessage -p tinyify > vfile-message.min.js", "format": "remark . -qfo && prettier --write '**/*.js' && xo --fix", "test": "npm run format && npm run build && npm run test-coverage", "test-api": "node test", "test-coverage": "nyc --reporter lcov tape test.js" }, - "version": "1.0.1", + "version": "1.0.2", "xo": { "prettier": true, "esnext": false, diff --git a/tools/node_modules/eslint/node_modules/vfile-message/readme.md b/tools/node_modules/eslint/node_modules/vfile-message/readme.md index c69cc406e35e74..0c88353a53c9cf 100644 --- a/tools/node_modules/eslint/node_modules/vfile-message/readme.md +++ b/tools/node_modules/eslint/node_modules/vfile-message/readme.md @@ -1,4 +1,9 @@ -# vfile-message [![Build Status][travis-badge]][travis] [![Coverage Status][codecov-badge]][codecov] +# vfile-message + +[![Build][build-badge]][build] +[![Coverage][coverage-badge]][coverage] +[![Downloads][downloads-badge]][downloads] +[![Chat][chat-badge]][chat] Create [vfile][] messages. @@ -144,19 +149,27 @@ repository, organisation, or community you agree to abide by its terms. -[travis-badge]: https://img.shields.io/travis/vfile/vfile-message.svg +[build-badge]: https://img.shields.io/travis/vfile/vfile-message.svg + +[build]: https://travis-ci.org/vfile/vfile-message + +[coverage-badge]: https://img.shields.io/codecov/c/github/vfile/vfile-message.svg + +[coverage]: https://codecov.io/github/vfile/vfile-message + +[downloads-badge]: https://img.shields.io/npm/dm/vfile-message.svg -[travis]: https://travis-ci.org/vfile/vfile-message +[downloads]: https://www.npmjs.com/package/vfile-message -[codecov-badge]: https://img.shields.io/codecov/c/github/vfile/vfile-message.svg +[chat-badge]: https://img.shields.io/badge/join%20the%20community-on%20spectrum-7b16ff.svg -[codecov]: https://codecov.io/github/vfile/vfile-message +[chat]: https://spectrum.chat/unified/vfile [npm]: https://docs.npmjs.com/cli/install -[license]: LICENSE +[license]: license -[author]: http://wooorm.com +[author]: https://wooorm.com [error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error diff --git a/tools/node_modules/eslint/package.json b/tools/node_modules/eslint/package.json index f35659fc8a1c23..39bed7a7e7ef51 100644 --- a/tools/node_modules/eslint/package.json +++ b/tools/node_modules/eslint/package.json @@ -21,7 +21,7 @@ "eslint-scope": "^4.0.0", "eslint-utils": "^1.3.1", "eslint-visitor-keys": "^1.0.0", - "espree": "^4.0.0", + "espree": "^5.0.0", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^2.0.0", @@ -31,7 +31,6 @@ "ignore": "^4.0.6", "imurmurhash": "^0.1.4", "inquirer": "^6.1.0", - "is-resolvable": "^1.1.0", "js-yaml": "^3.12.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", @@ -69,7 +68,7 @@ "eslint-plugin-eslint-plugin": "^1.4.1", "eslint-plugin-node": "^8.0.0", "eslint-plugin-rulesdir": "^0.1.0", - "eslint-release": "^1.0.0", + "eslint-release": "^1.2.0", "eslint-rule-composer": "^0.3.0", "eslump": "^1.6.2", "esprima": "^4.0.1", @@ -135,5 +134,5 @@ "publish-release": "node Makefile.js publishRelease", "test": "node Makefile.js test" }, - "version": "5.9.0" + "version": "5.10.0" } \ No newline at end of file diff --git a/tools/specialize_node_d.py b/tools/specialize_node_d.py index d9e8c1fd13ea51..825047c9d60f48 100755 --- a/tools/specialize_node_d.py +++ b/tools/specialize_node_d.py @@ -12,20 +12,20 @@ if len(sys.argv) != 5: print("usage: specialize_node_d.py outfile src/node.d flavor arch") - sys.exit(2); + sys.exit(2) -outfile = file(sys.argv[1], 'w'); -infile = file(sys.argv[2], 'r'); -flavor = sys.argv[3]; -arch = sys.argv[4]; +outfile = open(sys.argv[1], 'w') +infile = open(sys.argv[2], 'r') +flavor = sys.argv[3] +arch = sys.argv[4] model = r'curpsinfo->pr_dmodel == PR_MODEL_ILP32' for line in infile: if flavor == 'freebsd': - line = re.sub('procfs.d', 'psinfo.d', line); + line = re.sub('procfs.d', 'psinfo.d', line) if arch == 'x64': - line = re.sub(model, '0', line); + line = re.sub(model, '0', line) else: - line = re.sub(model, '1', line); - outfile.write(line); + line = re.sub(model, '1', line) + outfile.write(line) diff --git a/tools/test.py b/tools/test.py index e59dd8b782e13c..ff20cb133cea6a 100755 --- a/tools/test.py +++ b/tools/test.py @@ -44,12 +44,27 @@ import multiprocessing import errno import copy -import ast from os.path import join, dirname, abspath, basename, isdir, exists from datetime import datetime from Queue import Queue, Empty +try: + cmp # Python 2 +except NameError: + def cmp(x, y): # Python 3 + return (x > y) - (x < y) + +try: + reduce # Python 2 +except NameError: # Python 3 + from functools import reduce + +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + logger = logging.getLogger('testrunner') skip_regex = re.compile(r'# SKIP\S*\s+(.*)', re.IGNORECASE) @@ -110,9 +125,9 @@ def Run(self, tasks): for thread in threads: # Use a timeout so that signals (ctrl-c) will be processed. thread.join(timeout=10000000) - except (KeyboardInterrupt, SystemExit), e: + except (KeyboardInterrupt, SystemExit) as e: self.shutdown_event.set() - except Exception, e: + except Exception as e: # If there's an exception we schedule an interruption for any # remaining threads. self.shutdown_event.set() @@ -149,7 +164,7 @@ def RunSingle(self, parallel, thread_id): output = case.Run() output.diagnostic.append('ECONNREFUSED received, test retried') case.duration = (datetime.now() - start) - except IOError, e: + except IOError as e: return if self.shutdown_event.is_set(): return @@ -600,7 +615,7 @@ def Win32SetErrorMode(mode): prev_error_mode = SEM_INVALID_VALUE try: import ctypes - prev_error_mode = ctypes.windll.kernel32.SetErrorMode(mode); + prev_error_mode = ctypes.windll.kernel32.SetErrorMode(mode) except ImportError: pass return prev_error_mode @@ -619,15 +634,15 @@ def KillTimedOutProcess(context, pid): def RunProcess(context, timeout, args, **rest): if context.verbose: print("#", " ".join(args)) popen_args = args - prev_error_mode = SEM_INVALID_VALUE; + prev_error_mode = SEM_INVALID_VALUE if utils.IsWindows(): if context.suppress_dialogs: # Try to change the error mode to avoid dialogs on fatal errors. Don't # touch any existing error mode flags by merging the existing error mode. # See http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx. - error_mode = SEM_NOGPFAULTERRORBOX; - prev_error_mode = Win32SetErrorMode(error_mode); - Win32SetErrorMode(error_mode | prev_error_mode); + error_mode = SEM_NOGPFAULTERRORBOX + prev_error_mode = Win32SetErrorMode(error_mode) + Win32SetErrorMode(error_mode | prev_error_mode) faketty = rest.pop('faketty', False) pty_out = rest.pop('pty_out') @@ -696,7 +711,7 @@ def CheckedUnlink(name): while True: try: os.unlink(name) - except OSError, e: + except OSError as e: # On Windows unlink() fails if another process (typically a virus scanner # or the indexing service) has the file open. Those processes keep a # file open for a short time only, so yield and try again; it'll succeed. @@ -765,8 +780,8 @@ def disableCoreFiles(): else: os.close(fd_out) os.close(fd_err) - output = file(outname).read() - errors = file(errname).read() + output = open(outname).read() + errors = open(errname).read() CheckedUnlink(outname) CheckedUnlink(errname)