From eef5d19fd19fbaf7b0a24969deaa7d52a6742d31 Mon Sep 17 00:00:00 2001 From: Naugtur Date: Sat, 16 Jun 2018 13:19:37 +0200 Subject: [PATCH 1/3] add npm audit resolve command --- lib/audit.js | 10 +- node_modules/default-shell/index.js | 14 + node_modules/default-shell/license | 21 + node_modules/default-shell/package.json | 76 ++ node_modules/default-shell/readme.md | 30 + node_modules/flatten/LICENSE | 21 + node_modules/flatten/README.md | 34 + node_modules/flatten/index.js | 23 + node_modules/flatten/package.json | 54 ++ node_modules/flatten/test.js | 25 + node_modules/is-plain-obj/index.js | 7 + node_modules/is-plain-obj/license | 21 + node_modules/is-plain-obj/package.json | 68 ++ node_modules/is-plain-obj/readme.md | 35 + node_modules/merge-options/index.js | 155 ++++ node_modules/merge-options/license | 21 + node_modules/merge-options/package.json | 74 ++ node_modules/merge-options/readme.md | 102 +++ node_modules/npm-audit-resolver/LICENSE | 201 +++++ node_modules/npm-audit-resolver/README.md | 67 ++ node_modules/npm-audit-resolver/check.js | 34 + node_modules/npm-audit-resolver/index.js | 68 ++ .../node_modules/yargs-parser/CHANGELOG.md | 343 ++++++++ .../node_modules/yargs-parser/LICENSE.txt | 14 + .../node_modules/yargs-parser/README.md | 308 +++++++ .../node_modules/yargs-parser/index.js | 813 ++++++++++++++++++ .../yargs-parser/lib/tokenize-arg-string.js | 40 + .../node_modules/yargs-parser/package.json | 75 ++ node_modules/npm-audit-resolver/package.json | 68 ++ node_modules/npm-audit-resolver/resolve.js | 11 + .../npm-audit-resolver/src/actions.js | 87 ++ .../npm-audit-resolver/src/arguments.js | 2 + .../npm-audit-resolver/src/investigate.js | 56 ++ .../npm-audit-resolver/src/npmfacade.js | 26 + .../npm-audit-resolver/src/promiseCommand.js | 33 + .../npm-audit-resolver/src/prompter.js | 136 +++ .../npm-audit-resolver/src/resolutionState.js | 41 + .../npm-audit-resolver/src/statusManager.js | 30 + node_modules/promptly/CHANGELOG.md | 40 + node_modules/promptly/LICENSE | 21 + node_modules/promptly/README.md | 184 ++++ node_modules/promptly/index.js | 72 ++ node_modules/promptly/lib/getOptions.js | 33 + node_modules/promptly/lib/prompt.js | 48 ++ node_modules/promptly/package.json | 94 ++ node_modules/spawn-shell/index.js | 54 ++ node_modules/spawn-shell/license | 22 + node_modules/spawn-shell/package.json | 69 ++ node_modules/spawn-shell/readme.md | 54 ++ package-lock.json | 66 ++ package.json | 2 + 51 files changed, 4001 insertions(+), 2 deletions(-) create mode 100644 node_modules/default-shell/index.js create mode 100644 node_modules/default-shell/license create mode 100644 node_modules/default-shell/package.json create mode 100644 node_modules/default-shell/readme.md create mode 100644 node_modules/flatten/LICENSE create mode 100644 node_modules/flatten/README.md create mode 100644 node_modules/flatten/index.js create mode 100644 node_modules/flatten/package.json create mode 100644 node_modules/flatten/test.js create mode 100644 node_modules/is-plain-obj/index.js create mode 100644 node_modules/is-plain-obj/license create mode 100644 node_modules/is-plain-obj/package.json create mode 100644 node_modules/is-plain-obj/readme.md create mode 100644 node_modules/merge-options/index.js create mode 100644 node_modules/merge-options/license create mode 100644 node_modules/merge-options/package.json create mode 100644 node_modules/merge-options/readme.md create mode 100644 node_modules/npm-audit-resolver/LICENSE create mode 100644 node_modules/npm-audit-resolver/README.md create mode 100755 node_modules/npm-audit-resolver/check.js create mode 100644 node_modules/npm-audit-resolver/index.js create mode 100644 node_modules/npm-audit-resolver/node_modules/yargs-parser/CHANGELOG.md create mode 100644 node_modules/npm-audit-resolver/node_modules/yargs-parser/LICENSE.txt create mode 100644 node_modules/npm-audit-resolver/node_modules/yargs-parser/README.md create mode 100644 node_modules/npm-audit-resolver/node_modules/yargs-parser/index.js create mode 100644 node_modules/npm-audit-resolver/node_modules/yargs-parser/lib/tokenize-arg-string.js create mode 100644 node_modules/npm-audit-resolver/node_modules/yargs-parser/package.json create mode 100644 node_modules/npm-audit-resolver/package.json create mode 100755 node_modules/npm-audit-resolver/resolve.js create mode 100644 node_modules/npm-audit-resolver/src/actions.js create mode 100644 node_modules/npm-audit-resolver/src/arguments.js create mode 100644 node_modules/npm-audit-resolver/src/investigate.js create mode 100644 node_modules/npm-audit-resolver/src/npmfacade.js create mode 100644 node_modules/npm-audit-resolver/src/promiseCommand.js create mode 100644 node_modules/npm-audit-resolver/src/prompter.js create mode 100644 node_modules/npm-audit-resolver/src/resolutionState.js create mode 100644 node_modules/npm-audit-resolver/src/statusManager.js create mode 100755 node_modules/promptly/CHANGELOG.md create mode 100755 node_modules/promptly/LICENSE create mode 100755 node_modules/promptly/README.md create mode 100755 node_modules/promptly/index.js create mode 100755 node_modules/promptly/lib/getOptions.js create mode 100755 node_modules/promptly/lib/prompt.js create mode 100755 node_modules/promptly/package.json create mode 100755 node_modules/spawn-shell/index.js create mode 100644 node_modules/spawn-shell/license create mode 100644 node_modules/spawn-shell/package.json create mode 100644 node_modules/spawn-shell/readme.md diff --git a/lib/audit.js b/lib/audit.js index e34a50eef3fc8..3bfd22c84cb2b 100644 --- a/lib/audit.js +++ b/lib/audit.js @@ -8,6 +8,7 @@ const Installer = require('./install.js').Installer const lockVerify = require('lock-verify') const log = require('npmlog') const npa = require('npm-package-arg') +const auditResolver = require('npm-audit-resolver') const npm = require('./npm.js') const output = require('./utils/output.js') const parseJson = require('json-parse-better-errors') @@ -21,7 +22,8 @@ auditCmd.usage = usage( 'audit', '\nnpm audit [--json]' + '\nnpm audit fix ' + - '[--force|--package-lock-only|--dry-run|--production|--only=(dev|prod)]' + '[--force|--package-lock-only|--dry-run|--production|--only=(dev|prod)]' + + '\nnpm audit resolve' ) auditCmd.completion = function (opts, cb) { @@ -130,7 +132,7 @@ function auditCmd (args, cb) { err.code = 'EAUDITGLOBAL' throw err } - if (args.length && args[0] !== 'fix') { + if (args.length && !['fix', 'resolve'].includes(args[0])) { return cb(new Error('Invalid audit subcommand: `' + args[0] + '`\n\nUsage:\n' + auditCmd.usage)) } return Bluebird.all([ @@ -255,6 +257,10 @@ function auditCmd (args, cb) { } }) }) + } else if (args[0] === 'resolve') { + output(`Total of ${auditResult.actions.length} actions to process`) + return auditResolver.resolveAudit(auditResult) + .then(() => output('done.')) } else { const vulns = auditResult.metadata.vulnerabilities.low + diff --git a/node_modules/default-shell/index.js b/node_modules/default-shell/index.js new file mode 100644 index 0000000000000..2f5e20ff8b0d2 --- /dev/null +++ b/node_modules/default-shell/index.js @@ -0,0 +1,14 @@ +'use strict'; +module.exports = (() => { + const env = process.env; + + if (process.platform === 'darwin') { + return env.SHELL || '/bin/bash'; + } + + if (process.platform === 'win32') { + return env.COMSPEC || 'cmd.exe'; + } + + return env.SHELL || '/bin/sh'; +})(); diff --git a/node_modules/default-shell/license b/node_modules/default-shell/license new file mode 100644 index 0000000000000..654d0bfe94343 --- /dev/null +++ b/node_modules/default-shell/license @@ -0,0 +1,21 @@ +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/node_modules/default-shell/package.json b/node_modules/default-shell/package.json new file mode 100644 index 0000000000000..2678db5a13324 --- /dev/null +++ b/node_modules/default-shell/package.json @@ -0,0 +1,76 @@ +{ + "_from": "default-shell@^1.0.0", + "_id": "default-shell@1.0.1", + "_inBundle": false, + "_integrity": "sha1-dSMEvdxhdPSespy5iP7qC4gTyLw=", + "_location": "/default-shell", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "default-shell@^1.0.0", + "name": "default-shell", + "escapedName": "default-shell", + "rawSpec": "^1.0.0", + "saveSpec": null, + "fetchSpec": "^1.0.0" + }, + "_requiredBy": [ + "/spawn-shell" + ], + "_resolved": "https://registry.npmjs.org/default-shell/-/default-shell-1.0.1.tgz", + "_shasum": "752304bddc6174f49eb29cb988feea0b8813c8bc", + "_spec": "default-shell@^1.0.0", + "_where": "/storage/projects/github/npm/node_modules/spawn-shell", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/default-shell/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Get the user's default shell", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "engines": { + "node": ">=4" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/sindresorhus/default-shell#readme", + "keywords": [ + "default", + "shell", + "sh", + "zsh", + "bash", + "cmd", + "cmd.exe", + "comspec", + "env", + "environment", + "var", + "variables", + "get", + "user" + ], + "license": "MIT", + "name": "default-shell", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/default-shell.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "1.0.1", + "xo": { + "esnext": true + } +} diff --git a/node_modules/default-shell/readme.md b/node_modules/default-shell/readme.md new file mode 100644 index 0000000000000..a71a1bb2e96cb --- /dev/null +++ b/node_modules/default-shell/readme.md @@ -0,0 +1,30 @@ +# default-shell [![Build Status](https://travis-ci.org/sindresorhus/default-shell.svg?branch=master)](https://travis-ci.org/sindresorhus/default-shell) + +> Get the user's default [shell](https://en.wikipedia.org/wiki/Shell_(computing)) + + +## Install + +``` +$ npm install --save default-shell +``` + + +## Usage + +```js +const defaultShell = require('default-shell'); + +// OS X +console.log(defaultShell); +//=> '/bin/bash' + +// Windows +console.log(defaultShell); +//=> 'C:\\WINDOWS\\system32\\cmd.exe' +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/flatten/LICENSE b/node_modules/flatten/LICENSE new file mode 100644 index 0000000000000..54a689b800f4a --- /dev/null +++ b/node_modules/flatten/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Joshua Holbrook + +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/node_modules/flatten/README.md b/node_modules/flatten/README.md new file mode 100644 index 0000000000000..7b0a3b69063b1 --- /dev/null +++ b/node_modules/flatten/README.md @@ -0,0 +1,34 @@ +# flatten + +A tiny utility to flatten arrays of arrays (of arrays, etc., recursively, infinitely or to an optional depth) into a single array of non-arrays. + +## example: + +```js +> var flatten = require('flatten'); +undefined +> flatten([1, [2, 3], [4, 5, 6], [7, [8, 9]], 10]) +[ 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 ] +> flatten([1, [2, [3, [4, [5]]]]], 2) +[ 1, + 2, + 3, + [ 4, [ 5 ] ] ] +``` + +## install: + + npm install flatten + +## license: + +MIT/X11. diff --git a/node_modules/flatten/index.js b/node_modules/flatten/index.js new file mode 100644 index 0000000000000..a9bd9b8c47c42 --- /dev/null +++ b/node_modules/flatten/index.js @@ -0,0 +1,23 @@ +module.exports = function flatten(list, depth) { + depth = (typeof depth == 'number') ? depth : Infinity; + + if (!depth) { + if (Array.isArray(list)) { + return list.map(function(i) { return i; }); + } + return list; + } + + return _flatten(list, 1); + + function _flatten(list, d) { + return list.reduce(function (acc, item) { + if (Array.isArray(item) && d < depth) { + return acc.concat(_flatten(item, d + 1)); + } + else { + return acc.concat(item); + } + }, []); + } +}; diff --git a/node_modules/flatten/package.json b/node_modules/flatten/package.json new file mode 100644 index 0000000000000..5f16affa3db24 --- /dev/null +++ b/node_modules/flatten/package.json @@ -0,0 +1,54 @@ +{ + "_from": "flatten@^1.0.2", + "_id": "flatten@1.0.2", + "_inBundle": false, + "_integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", + "_location": "/flatten", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "flatten@^1.0.2", + "name": "flatten", + "escapedName": "flatten", + "rawSpec": "^1.0.2", + "saveSpec": null, + "fetchSpec": "^1.0.2" + }, + "_requiredBy": [ + "/npm-audit-resolver" + ], + "_resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "_shasum": "dae46a9d78fbe25292258cc1e780a41d95c03782", + "_spec": "flatten@^1.0.2", + "_where": "/storage/projects/github/npm/node_modules/npm-audit-resolver", + "author": { + "name": "Joshua Holbrook", + "email": "josh.holbrook@gmail.com", + "url": "http://jesusabdullah.net" + }, + "bugs": { + "url": "https://github.com/jesusabdullah/node-flatten/issues" + }, + "bundleDependencies": false, + "dependencies": {}, + "deprecated": false, + "description": "Flatten arbitrarily nested arrays into a non-nested list of non-array items", + "devDependencies": {}, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/jesusabdullah/node-flatten#readme", + "license": "MIT", + "main": "./index.js", + "name": "flatten", + "optionalDependencies": {}, + "repository": { + "type": "git", + "url": "git://github.com/jesusabdullah/node-flatten.git" + }, + "scripts": { + "test": "node ./test.js" + }, + "version": "1.0.2" +} diff --git a/node_modules/flatten/test.js b/node_modules/flatten/test.js new file mode 100644 index 0000000000000..385c27faacc76 --- /dev/null +++ b/node_modules/flatten/test.js @@ -0,0 +1,25 @@ +var flatten = require('./index'), + util = require('util'), + assert = require('assert'); + +[ + [ [1, [ 2, 3]], [1, [2, 3]], 0], + [ [1, 2, 3 ], [1, 2, 3] ], + [ ['a', ['b', ['c']]], ['a', 'b', 'c'] ], + [ [2, [4, 6], 8, [[10]]], [2, 4, 6, 8, 10] ], + [ [1, [2, [3, [4, [5]]]]], [1, 2, 3, [4, [5]]], 2 ] // depth of 2 +].forEach(function (t) { + assert.deepEqual(flatten(t[0], t[2]), t[1], + util.format('☠☠☠☠☠☠☠☠☠ %s ☠☠☠☠☠☠☠☠☠', formatCall(t)) + ); + console.log('✓ %s', formatCall(t)); +}); + +function formatCall(t) { + if (typeof t[2] === 'undefined') { + return util.format('`flatten(%j) == %j`', t[0], t[1]); + } + else { + return util.format('`flatten(%j, %j) == %j`', t[0], t[2], t[1]); + } +} diff --git a/node_modules/is-plain-obj/index.js b/node_modules/is-plain-obj/index.js new file mode 100644 index 0000000000000..0d1ba9eeb8972 --- /dev/null +++ b/node_modules/is-plain-obj/index.js @@ -0,0 +1,7 @@ +'use strict'; +var toString = Object.prototype.toString; + +module.exports = function (x) { + var prototype; + return toString.call(x) === '[object Object]' && (prototype = Object.getPrototypeOf(x), prototype === null || prototype === Object.getPrototypeOf({})); +}; diff --git a/node_modules/is-plain-obj/license b/node_modules/is-plain-obj/license new file mode 100644 index 0000000000000..654d0bfe94343 --- /dev/null +++ b/node_modules/is-plain-obj/license @@ -0,0 +1,21 @@ +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/node_modules/is-plain-obj/package.json b/node_modules/is-plain-obj/package.json new file mode 100644 index 0000000000000..0d0a46344f0cf --- /dev/null +++ b/node_modules/is-plain-obj/package.json @@ -0,0 +1,68 @@ +{ + "_from": "is-plain-obj@^1.1", + "_id": "is-plain-obj@1.1.0", + "_inBundle": false, + "_integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "_location": "/is-plain-obj", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "is-plain-obj@^1.1", + "name": "is-plain-obj", + "escapedName": "is-plain-obj", + "rawSpec": "^1.1", + "saveSpec": null, + "fetchSpec": "^1.1" + }, + "_requiredBy": [ + "/merge-options" + ], + "_resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "_shasum": "71a50c8429dfca773c92a390a4a03b39fcd51d3e", + "_spec": "is-plain-obj@^1.1", + "_where": "/storage/projects/github/npm/node_modules/merge-options", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/is-plain-obj/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Check if a value is a plain object", + "devDependencies": { + "ava": "0.0.4" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/sindresorhus/is-plain-obj#readme", + "keywords": [ + "obj", + "object", + "is", + "check", + "test", + "type", + "plain", + "vanilla", + "pure", + "simple" + ], + "license": "MIT", + "name": "is-plain-obj", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/is-plain-obj.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "1.1.0" +} diff --git a/node_modules/is-plain-obj/readme.md b/node_modules/is-plain-obj/readme.md new file mode 100644 index 0000000000000..269e56aeff064 --- /dev/null +++ b/node_modules/is-plain-obj/readme.md @@ -0,0 +1,35 @@ +# is-plain-obj [![Build Status](https://travis-ci.org/sindresorhus/is-plain-obj.svg?branch=master)](https://travis-ci.org/sindresorhus/is-plain-obj) + +> Check if a value is a plain object + +An object is plain if it's created by either `{}`, `new Object()` or `Object.create(null)`. + + +## Install + +``` +$ npm install --save is-plain-obj +``` + + +## Usage + +```js +var isPlainObj = require('is-plain-obj'); + +isPlainObj({foo: 'bar'}); +//=> true + +isPlainObj([1, 2, 3]); +//=> false +``` + + +## Related + +- [is-obj](https://github.com/sindresorhus/is-obj) - Check if a value is an object + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/merge-options/index.js b/node_modules/merge-options/index.js new file mode 100644 index 0000000000000..d73476b92b68a --- /dev/null +++ b/node_modules/merge-options/index.js @@ -0,0 +1,155 @@ +'use strict'; +const isOptionObject = require('is-plain-obj'); + +const hasOwnProperty = Object.prototype.hasOwnProperty; +const propIsEnumerable = Object.propertyIsEnumerable; +const globalThis = this; +const defaultMergeOpts = { + concatArrays: false +}; + +const getEnumerableOwnPropertyKeys = value => { + const keys = []; + + for (const key in value) { + if (hasOwnProperty.call(value, key)) { + keys.push(key); + } + } + + /* istanbul ignore else */ + if (Object.getOwnPropertySymbols) { + const symbols = Object.getOwnPropertySymbols(value); + + for (let i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(value, symbols[i])) { + keys.push(symbols[i]); + } + } + } + + return keys; +}; + +function clone(value) { + if (Array.isArray(value)) { + return cloneArray(value); + } + + if (isOptionObject(value)) { + return cloneOptionObject(value); + } + + return value; +} + +function cloneArray(array) { + const result = array.slice(0, 0); + + getEnumerableOwnPropertyKeys(array).forEach(key => { + result[key] = clone(array[key]); + }); + + return result; +} + +function cloneOptionObject(obj) { + const result = Object.getPrototypeOf(obj) === null ? Object.create(null) : {}; + + getEnumerableOwnPropertyKeys(obj).forEach(key => { + result[key] = clone(obj[key]); + }); + + return result; +} + +/** + * @param merged {already cloned} + * @return {cloned Object} + */ +const mergeKeys = (merged, source, keys, mergeOpts) => { + keys.forEach(key => { + if (key in merged) { + merged[key] = merge(merged[key], source[key], mergeOpts); + } else { + merged[key] = clone(source[key]); + } + }); + + return merged; +}; + +/** + * @param merged {already cloned} + * @return {cloned Object} + * + * see [Array.prototype.concat ( ...arguments )](http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat) + */ +const concatArrays = (merged, source, mergeOpts) => { + let result = merged.slice(0, 0); + let resultIndex = 0; + + [merged, source].forEach(array => { + const indices = []; + + // `result.concat(array)` with cloning + for (let k = 0; k < array.length; k++) { + if (!hasOwnProperty.call(array, k)) { + continue; + } + + indices.push(String(k)); + + if (array === merged) { + // Already cloned + result[resultIndex++] = array[k]; + } else { + result[resultIndex++] = clone(array[k]); + } + } + + // Merge non-index keys + result = mergeKeys(result, array, getEnumerableOwnPropertyKeys(array).filter(key => { + return indices.indexOf(key) === -1; + }), mergeOpts); + }); + + return result; +}; + +/** + * @param merged {already cloned} + * @return {cloned Object} + */ +function merge(merged, source, mergeOpts) { + if (mergeOpts.concatArrays && Array.isArray(merged) && Array.isArray(source)) { + return concatArrays(merged, source, mergeOpts); + } + + if (!isOptionObject(source) || !isOptionObject(merged)) { + return clone(source); + } + + return mergeKeys(merged, source, getEnumerableOwnPropertyKeys(source), mergeOpts); +} + +module.exports = function () { + const mergeOpts = merge(clone(defaultMergeOpts), (this !== globalThis && this) || {}, defaultMergeOpts); + let merged = {}; + + for (let i = 0; i < arguments.length; i++) { + const option = arguments[i]; + + if (option === undefined) { + continue; + } + + if (!isOptionObject(option)) { + throw new TypeError('`' + option + '` is not an Option Object'); + } + + merged = merge(merged, option, mergeOpts); + } + + return merged; +}; diff --git a/node_modules/merge-options/license b/node_modules/merge-options/license new file mode 100644 index 0000000000000..ea2852dc27ad8 --- /dev/null +++ b/node_modules/merge-options/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016-2017 Michael Mayer + +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/node_modules/merge-options/package.json b/node_modules/merge-options/package.json new file mode 100644 index 0000000000000..814ccfbf6d703 --- /dev/null +++ b/node_modules/merge-options/package.json @@ -0,0 +1,74 @@ +{ + "_from": "merge-options@1.0.0", + "_id": "merge-options@1.0.0", + "_inBundle": false, + "_integrity": "sha1-W08zmpVxkrW5iZSjrFyV0splG5Q=", + "_location": "/merge-options", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "merge-options@1.0.0", + "name": "merge-options", + "escapedName": "merge-options", + "rawSpec": "1.0.0", + "saveSpec": null, + "fetchSpec": "1.0.0" + }, + "_requiredBy": [ + "/spawn-shell" + ], + "_resolved": "https://registry.npmjs.org/merge-options/-/merge-options-1.0.0.tgz", + "_shasum": "5b4f339a957192b5b98994a3ac5c95d2ca651b94", + "_spec": "merge-options@1.0.0", + "_where": "/storage/projects/github/npm/node_modules/spawn-shell", + "author": { + "name": "Michael Mayer", + "email": "michael@schnittstabil.de", + "url": "schnittstabil.de" + }, + "bugs": { + "url": "https://github.com/schnittstabil/merge-options/issues" + }, + "bundleDependencies": false, + "dependencies": { + "is-plain-obj": "^1.1" + }, + "deprecated": false, + "description": "Merge Option Objects", + "devDependencies": { + "ava": "^0.19", + "coveralls": "^2.13", + "nyc": "^10.3", + "rimraf": "^2.5", + "xo": "^0.18" + }, + "engines": { + "node": ">=4" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/schnittstabil/merge-options#readme", + "keywords": [ + "merge", + "options", + "deep", + "plain", + "object", + "extend", + "clone" + ], + "license": "MIT", + "name": "merge-options", + "repository": { + "type": "git", + "url": "git+https://github.com/schnittstabil/merge-options.git" + }, + "scripts": { + "clean": "rimraf .nyc_output/ coverage/", + "coverage-html": "nyc ava && nyc report --reporter=html", + "test": "xo && nyc ava" + }, + "version": "1.0.0" +} diff --git a/node_modules/merge-options/readme.md b/node_modules/merge-options/readme.md new file mode 100644 index 0000000000000..c9c07c87eefd1 --- /dev/null +++ b/node_modules/merge-options/readme.md @@ -0,0 +1,102 @@ +# merge-options [![Build Status](https://travis-ci.org/schnittstabil/merge-options.svg?branch=master)](https://travis-ci.org/schnittstabil/merge-options) [![Coverage Status](https://coveralls.io/repos/schnittstabil/merge-options/badge.svg?branch=master&service=github)](https://coveralls.io/github/schnittstabil/merge-options?branch=master) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) + + +> Merge Option Objects + +`merge-options` considers [plain objects](https://github.com/sindresorhus/is-plain-obj) as *Option Objects*, everything else as *Option Values*. + +## Install + +``` +$ npm install --save merge-options +``` + +## Usage + +```js +const mergeOptions = require('merge-options'); + +mergeOptions({foo: 0}, {bar: 1}, {baz: 2}, {bar: 3}) +//=> {foo: 0, bar: 3, baz: 2} + +mergeOptions({nested: {unicorns: 'none'}}, {nested: {unicorns: 'many'}}) +//=> {nested: {unicorns: 'many'}} + +mergeOptions({[Symbol.for('key')]: 0}, {[Symbol.for('key')]: 42}) +//=> {Symbol(key): 42} +``` + +## API + +### mergeOptions(option1, ...options)
mergeOptions.call(config, option1, ...options)
mergeOptions.apply(config, [option1, ...options]) + +`mergeOptions` recursively merges one or more *Option Objects* into a new one and returns that. The `options` are merged in order, thus *Option Values* of additional `options` take precedence over previous ones. + +The merging does not alter the passed `option` arguments, taking roughly the following steps: +* recursively cloning[1] *Option Objects* and [arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray) until reaching *Option Values* +* copying[1] references to *Option Values* to the result object + + +```js +const defaultOpts = { + fn: () => false, // functions are Option Values + promise: Promise.reject(new Error()), // all non-plain objects are Option Values + array: ['foo'], // arrays are Option Values + nested: {unicorns: 'none'} // {…} is plain, therefore an Option Object +}; + +const opts = { + fn: () => true, // [1] + promise: Promise.resolve('bar'), // [2] + array: ['baz'], // [3] + nested: {unicorns: 'many'} // [4] +}; + +mergeOptions(defaultOpts, opts) +//=> +{ + fn: [Function], // === [1] + promise: Promise { 'bar' }, // === [2] + array: ['baz'], // !== [3] (arrays are cloned) + nested: {unicorns: 'many'} // !== [4] (Option Objects are cloned) +} +``` + +#### config + +Type: `object` + +##### config.concatArrays + +Type: `boolean`
Default: `false` + +Concatenate arrays: + +```js +mergeOptions({src: ['src/**']}, {src: ['test/**']}) +//=> {src: ['test/**']} + +// Via call +mergeOptions.call({concatArrays: true}, {src: ['src/**']}, {src: ['test/**']}) +//=> {src: ['src/**', 'test/**']} + +// Via apply +mergeOptions.apply({concatArrays: true}, [{src: ['src/**']}, {src: ['test/**']}]) +//=> {src: ['src/**', 'test/**']} +``` + + +## Related + +* See [object-assign](https://github.com/sindresorhus/object-assign) if you need a ES2015 Object.assign() ponyfill +* See [deep-assign](https://github.com/sindresorhus/deep-assign) if you need to do Object.assign() recursively + +## Notes + +
    +
  1. copying and cloning take only enumerable own properties into account
  2. +
+ +## License + +MIT © [Michael Mayer](http://schnittstabil.de) diff --git a/node_modules/npm-audit-resolver/LICENSE b/node_modules/npm-audit-resolver/LICENSE new file mode 100644 index 0000000000000..261eeb9e9f8b2 --- /dev/null +++ b/node_modules/npm-audit-resolver/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/npm-audit-resolver/README.md b/node_modules/npm-audit-resolver/README.md new file mode 100644 index 0000000000000..d4b338ee5850b --- /dev/null +++ b/node_modules/npm-audit-resolver/README.md @@ -0,0 +1,67 @@ +# npm audit resolver + +`npm audit` is great. `npm audit fix` is also there if you didn't know. But sometimes you need to manage your security and make decisions about the dependencies you use. + +This tool creates a `audit-resolv.json` file in your app and interactively helps you manage security of your dependencies. + +** This is experimental, built in a few hours. When using this software you are still responsible for the security of your app ** + +## Install + +Requires npm v6.1.0 installed alongside + +``` +npm install -g npm-audit-resolver +``` + +## Usage + +Go into the project folder and run + +``` +resolve-audit +``` + +It goes through the results of `npm audit` and lets you decide what to do with the issues. +The decisions you make are stored in `audit-resolv.json` to keep track of it in version control and have a log of who decided to do what and when. + +### Arguments + +``` +--ignoreLow automatically resolve issue to ignored if severity of all vulnerabilities in that dependency is low +``` + +### Running in CI + +One if the problems this solves is running audit as part of your build pipeline. +You don't want to break your CI for a few days waiting to get a fix on a dependency, but at the same time ignoring the whole class of issues or the audit result entirely means you'll rarely notice it at all. + +Run +``` +check-audit +``` + +This command will only exit with an error if a human needs to make new decisions about vulnerabilities and commit the `audit-resolv.json` file. If all issues are addressed, your build can pass. + +## Features + +Want to give it a go? Download this repo and run `npm test` + +When a vulnerability is found, you get to choose between the following options: + +- fix - Runs the fix proposed by npm audit and makes a note. If the same issue comes back because someone else on the team changed package-lock.json, you'll get a warning about that. +- investigate - If npm audit doesn't suggest a fix, resolver will help you find where the fix could be introduced. +- show details - Prints more information about the issues form the audit and asks what to do again +- remind in 24h - Lets you ignore an issue temporarily to make the build pass until a fix is known +- ignore - Adds the particular dependency paths and advisories to be ignored in the future. If the same issue in the same package comes up, but it's a dependency of another package, it won't get ignored. If a new issue is found in the package, it doesn't get ignored. +- delete - Removes your dependency that brought the vulnerability in its dependencies. +- skip and quit, obviously + +audit-resolv.json is formatted, so git history has a trace of who addressed which vulnerability, when and how. + +### Why would I ignore security vulnerabilities? + +- dev dependencies! a DOS vulnerability in your test runner's dependency is not a showstopper +- build tooling vulnerability +- dependencies of a tool you use very narrowly and can prove it's safe +- new vulnerability without a fix and you want to wait for a fix while running your builds (there's a remind me in 24h option available) diff --git a/node_modules/npm-audit-resolver/check.js b/node_modules/npm-audit-resolver/check.js new file mode 100755 index 0000000000000..b06f6128d6380 --- /dev/null +++ b/node_modules/npm-audit-resolver/check.js @@ -0,0 +1,34 @@ +#!/usr/bin/env node +const core = require("./index"); +const npmFacade = require('./src/npmfacade'); + +npmFacade.runNpmCommand('audit', { ignoreExit: true }) + .then(input => { + console.log(`Total of ${input.actions.length} actions to process`); + return core.checkAudit(input) + }) + .then(issues => { + if(issues && issues.length){ + issues.forEach(issue => { + console.log( + `--------------------------------------------------` + ); + console.log(`[${issue.severity}] ${issue.title}`); + console.log(issue.items.map(item => item.report).join("\n")); + }) + + console.log( + `--------------------------------------------------` + ); + console.error(" 😱 Unresolved issues found!"); + console.log( + `--------------------------------------------------` + ); + process.exit(1); + } + }) + .then(() => console.log("audit ok.")) + .catch(e => { + console.error(e); + process.exit(2); + }); diff --git a/node_modules/npm-audit-resolver/index.js b/node_modules/npm-audit-resolver/index.js new file mode 100644 index 0000000000000..e0d8605172071 --- /dev/null +++ b/node_modules/npm-audit-resolver/index.js @@ -0,0 +1,68 @@ +#!/usr/bin/env node +const prompter = require('./src/prompter'); +const statusManager = require('./src/statusManager'); + +module.exports = { + resolveAudit(input) { + return input.actions + .map(statusManager.addStatus) + .filter(a => { + if (a.humanReviewComplete) { + console.log(`skipping ${a.module} issue based on audit-resolv.json`) + } + return !a.humanReviewComplete + }) + .reduce( + (prev, action) => + prev.then(() => + prompter.handleAction(action, input.advisories) + ), + Promise.resolve() + ) + }, + checkAudit(input){ + return input.actions + .map(statusManager.addStatus) + .filter(a => { + if (a.humanReviewComplete) { + console.log( + `skipping ${a.module} issue based on audit-resolv.json` + ); + } + return !a.humanReviewComplete; + }) + .forEach(action => { + const groupedIssues = action.resolves.reduce((groups, re) => { + groups[re.id] = groups[re.id] || []; + let type = re.dev ? " devDependencies" : "dependencies"; + re.optional && (type += " (optional)"); + re.bundled && (type += " (bundled)"); + let reportLine = ` - ${type}: ${re.path}`; + if (re.humanReviewStatus) { + re.humanReviewStatus.fix && + (reportLine += + "\n ^ this issue was marked as fixed earlier"); + re.humanReviewStatus.remind && + (reportLine += + "\n ^ this issue was postponed, the time ran out"); + } + groups[re.id].push({ + data: re, + report: reportLine + }); + + return groups; + }, {}); + + return Object.keys(groupedIssues).map(reId => { + const adv = input.advisories[reId]; + return { + title: adv.title, + severity: adv.severity, + items: groupedIssues[reId] + } + }); + + }); + } +} diff --git a/node_modules/npm-audit-resolver/node_modules/yargs-parser/CHANGELOG.md b/node_modules/npm-audit-resolver/node_modules/yargs-parser/CHANGELOG.md new file mode 100644 index 0000000000000..6ef55a7d13f60 --- /dev/null +++ b/node_modules/npm-audit-resolver/node_modules/yargs-parser/CHANGELOG.md @@ -0,0 +1,343 @@ +# Change Log + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + + +# [10.0.0](https://github.com/yargs/yargs-parser/compare/v9.0.2...v10.0.0) (2018-04-04) + + +### Bug Fixes + +* do not set boolean flags if not defined in `argv` ([#119](https://github.com/yargs/yargs-parser/issues/119)) ([f6e6599](https://github.com/yargs/yargs-parser/commit/f6e6599)) + + +### BREAKING CHANGES + +* `boolean` flags defined without a `default` value will now behave like other option type and won't be set in the parsed results when the user doesn't set the corresponding CLI arg. + +Previous behavior: +```js +var parse = require('yargs-parser'); + +parse('--flag', {boolean: ['flag']}); +// => { _: [], flag: true } + +parse('--no-flag', {boolean: ['flag']}); +// => { _: [], flag: false } + +parse('', {boolean: ['flag']}); +// => { _: [], flag: false } +``` + +New behavior: +```js +var parse = require('yargs-parser'); + +parse('--flag', {boolean: ['flag']}); +// => { _: [], flag: true } + +parse('--no-flag', {boolean: ['flag']}); +// => { _: [], flag: false } + +parse('', {boolean: ['flag']}); +// => { _: [] } => flag not set similarly to other option type +``` + + + + +## [9.0.2](https://github.com/yargs/yargs-parser/compare/v9.0.1...v9.0.2) (2018-01-20) + + +### Bug Fixes + +* nargs was still aggressively consuming too many arguments ([9b28aad](https://github.com/yargs/yargs-parser/commit/9b28aad)) + + + + +## [9.0.1](https://github.com/yargs/yargs-parser/compare/v9.0.0...v9.0.1) (2018-01-20) + + +### Bug Fixes + +* nargs was consuming too many arguments ([4fef206](https://github.com/yargs/yargs-parser/commit/4fef206)) + + + + +# [9.0.0](https://github.com/yargs/yargs-parser/compare/v8.1.0...v9.0.0) (2018-01-20) + + +### Features + +* narg arguments no longer consume flag arguments ([#114](https://github.com/yargs/yargs-parser/issues/114)) ([60bb9b3](https://github.com/yargs/yargs-parser/commit/60bb9b3)) + + +### BREAKING CHANGES + +* arguments of form --foo, -abc, will no longer be consumed by nargs + + + + +# [8.1.0](https://github.com/yargs/yargs-parser/compare/v8.0.0...v8.1.0) (2017-12-20) + + +### Bug Fixes + +* allow null config values ([#108](https://github.com/yargs/yargs-parser/issues/108)) ([d8b14f9](https://github.com/yargs/yargs-parser/commit/d8b14f9)) +* ensure consistent parsing of dot-notation arguments ([#102](https://github.com/yargs/yargs-parser/issues/102)) ([c9bd79c](https://github.com/yargs/yargs-parser/commit/c9bd79c)) +* implement [@antoniom](https://github.com/antoniom)'s fix for camel-case expansion ([3087e1d](https://github.com/yargs/yargs-parser/commit/3087e1d)) +* only run coercion functions once, despite aliases. ([#76](https://github.com/yargs/yargs-parser/issues/76)) ([#103](https://github.com/yargs/yargs-parser/issues/103)) ([507aaef](https://github.com/yargs/yargs-parser/commit/507aaef)) +* scientific notation circumvented bounds check ([#110](https://github.com/yargs/yargs-parser/issues/110)) ([3571f57](https://github.com/yargs/yargs-parser/commit/3571f57)) +* tokenizer should ignore spaces at the beginning of the argString ([#106](https://github.com/yargs/yargs-parser/issues/106)) ([f34ead9](https://github.com/yargs/yargs-parser/commit/f34ead9)) + + +### Features + +* make combining arrays a configurable option ([#111](https://github.com/yargs/yargs-parser/issues/111)) ([c8bf536](https://github.com/yargs/yargs-parser/commit/c8bf536)) +* merge array from arguments with array from config ([#83](https://github.com/yargs/yargs-parser/issues/83)) ([806ddd6](https://github.com/yargs/yargs-parser/commit/806ddd6)) + + + + +# [8.0.0](https://github.com/yargs/yargs-parser/compare/v7.0.0...v8.0.0) (2017-10-05) + + +### Bug Fixes + +* Ignore multiple spaces between arguments. ([#100](https://github.com/yargs/yargs-parser/issues/100)) ([d137227](https://github.com/yargs/yargs-parser/commit/d137227)) + + +### Features + +* allow configuration of prefix for boolean negation ([#94](https://github.com/yargs/yargs-parser/issues/94)) ([00bde7d](https://github.com/yargs/yargs-parser/commit/00bde7d)) +* reworking how numbers are parsed ([#104](https://github.com/yargs/yargs-parser/issues/104)) ([fba00eb](https://github.com/yargs/yargs-parser/commit/fba00eb)) + + +### BREAKING CHANGES + +* strings that fail `Number.isSafeInteger()` are no longer coerced into numbers. + + + + +# [7.0.0](https://github.com/yargs/yargs-parser/compare/v6.0.1...v7.0.0) (2017-05-02) + + +### Chores + +* revert populate-- logic ([#91](https://github.com/yargs/yargs-parser/issues/91)) ([6003e6d](https://github.com/yargs/yargs-parser/commit/6003e6d)) + + +### BREAKING CHANGES + +* populate-- now defaults to false. + + + + +## [6.0.1](https://github.com/yargs/yargs-parser/compare/v6.0.0...v6.0.1) (2017-05-01) + + +### Bug Fixes + +* default '--' to undefined when not provided; this is closer to the array API ([#90](https://github.com/yargs/yargs-parser/issues/90)) ([4e739cc](https://github.com/yargs/yargs-parser/commit/4e739cc)) + + + + +# [6.0.0](https://github.com/yargs/yargs-parser/compare/v4.2.1...v6.0.0) (2017-05-01) + + +### Bug Fixes + +* environment variables should take precedence over config file ([#81](https://github.com/yargs/yargs-parser/issues/81)) ([76cee1f](https://github.com/yargs/yargs-parser/commit/76cee1f)) +* parsing hints should apply for dot notation keys ([#86](https://github.com/yargs/yargs-parser/issues/86)) ([3e47d62](https://github.com/yargs/yargs-parser/commit/3e47d62)) + + +### Chores + +* upgrade to newest version of camelcase ([#87](https://github.com/yargs/yargs-parser/issues/87)) ([f1903aa](https://github.com/yargs/yargs-parser/commit/f1903aa)) + + +### Features + +* add -- option which allows arguments after the -- flag to be returned separated from positional arguments ([#84](https://github.com/yargs/yargs-parser/issues/84)) ([2572ca8](https://github.com/yargs/yargs-parser/commit/2572ca8)) +* when parsing stops, we now populate "--" by default ([#88](https://github.com/yargs/yargs-parser/issues/88)) ([cd666db](https://github.com/yargs/yargs-parser/commit/cd666db)) + + +### BREAKING CHANGES + +* rather than placing arguments in "_", when parsing is stopped via "--"; we now populate an array called "--" by default. +* camelcase now requires Node 4+. +* environment variables will now override config files (args, env, config-file, config-object) + + + + +# [5.0.0](https://github.com/yargs/yargs-parser/compare/v4.2.1...v5.0.0) (2017-02-18) + + +### Bug Fixes + +* environment variables should take precedence over config file ([#81](https://github.com/yargs/yargs-parser/issues/81)) ([76cee1f](https://github.com/yargs/yargs-parser/commit/76cee1f)) + + +### BREAKING CHANGES + +* environment variables will now override config files (args, env, config-file, config-object) + + + + +## [4.2.1](https://github.com/yargs/yargs-parser/compare/v4.2.0...v4.2.1) (2017-01-02) + + +### Bug Fixes + +* flatten/duplicate regression ([#75](https://github.com/yargs/yargs-parser/issues/75)) ([68d68a0](https://github.com/yargs/yargs-parser/commit/68d68a0)) + + + + +# [4.2.0](https://github.com/yargs/yargs-parser/compare/v4.1.0...v4.2.0) (2016-12-01) + + +### Bug Fixes + +* inner objects in configs had their keys appended to top-level key when dot-notation was disabled ([#72](https://github.com/yargs/yargs-parser/issues/72)) ([0b1b5f9](https://github.com/yargs/yargs-parser/commit/0b1b5f9)) + + +### Features + +* allow multiple arrays to be provided, rather than always combining ([#71](https://github.com/yargs/yargs-parser/issues/71)) ([0f0fb2d](https://github.com/yargs/yargs-parser/commit/0f0fb2d)) + + + + +# [4.1.0](https://github.com/yargs/yargs-parser/compare/v4.0.2...v4.1.0) (2016-11-07) + + +### Features + +* apply coercions to default options ([#65](https://github.com/yargs/yargs-parser/issues/65)) ([c79052b](https://github.com/yargs/yargs-parser/commit/c79052b)) +* handle dot notation boolean options ([#63](https://github.com/yargs/yargs-parser/issues/63)) ([02c3545](https://github.com/yargs/yargs-parser/commit/02c3545)) + + + + +## [4.0.2](https://github.com/yargs/yargs-parser/compare/v4.0.1...v4.0.2) (2016-09-30) + + +### Bug Fixes + +* whoops, let's make the assign not change the Object key order ([29d069a](https://github.com/yargs/yargs-parser/commit/29d069a)) + + + + +## [4.0.1](https://github.com/yargs/yargs-parser/compare/v4.0.0...v4.0.1) (2016-09-30) + + +### Bug Fixes + +* lodash.assign was deprecated ([#59](https://github.com/yargs/yargs-parser/issues/59)) ([5e7eb11](https://github.com/yargs/yargs-parser/commit/5e7eb11)) + + + + +# [4.0.0](https://github.com/yargs/yargs-parser/compare/v3.2.0...v4.0.0) (2016-09-26) + + +### Bug Fixes + +* coerce should be applied to the final objects and arrays created ([#57](https://github.com/yargs/yargs-parser/issues/57)) ([4ca69da](https://github.com/yargs/yargs-parser/commit/4ca69da)) + + +### BREAKING CHANGES + +* coerce is no longer applied to individual arguments in an implicit array. + + + + +# [3.2.0](https://github.com/yargs/yargs-parser/compare/v3.1.0...v3.2.0) (2016-08-13) + + +### Features + +* coerce full array instead of each element ([#51](https://github.com/yargs/yargs-parser/issues/51)) ([cc4dc56](https://github.com/yargs/yargs-parser/commit/cc4dc56)) + + + + +# [3.1.0](https://github.com/yargs/yargs-parser/compare/v3.0.0...v3.1.0) (2016-08-09) + + +### Bug Fixes + +* address pkgConf parsing bug outlined in [#37](https://github.com/yargs/yargs-parser/issues/37) ([#45](https://github.com/yargs/yargs-parser/issues/45)) ([be76ee6](https://github.com/yargs/yargs-parser/commit/be76ee6)) +* better parsing of negative values ([#44](https://github.com/yargs/yargs-parser/issues/44)) ([2e43692](https://github.com/yargs/yargs-parser/commit/2e43692)) +* check aliases when guessing defaults for arguments fixes [#41](https://github.com/yargs/yargs-parser/issues/41) ([#43](https://github.com/yargs/yargs-parser/issues/43)) ([f3e4616](https://github.com/yargs/yargs-parser/commit/f3e4616)) + + +### Features + +* added coerce option, for providing specialized argument parsing ([#42](https://github.com/yargs/yargs-parser/issues/42)) ([7b49cd2](https://github.com/yargs/yargs-parser/commit/7b49cd2)) + + + + +# [3.0.0](https://github.com/yargs/yargs-parser/compare/v2.4.1...v3.0.0) (2016-08-07) + + +### Bug Fixes + +* parsing issue with numeric character in group of options ([#19](https://github.com/yargs/yargs-parser/issues/19)) ([f743236](https://github.com/yargs/yargs-parser/commit/f743236)) +* upgraded lodash.assign ([5d7fdf4](https://github.com/yargs/yargs-parser/commit/5d7fdf4)) + +### BREAKING CHANGES + +* subtle change to how values are parsed in a group of single-character arguments. +* _first released in 3.1.0, better handling of negative values should be considered a breaking change._ + + + + +## [2.4.1](https://github.com/yargs/yargs-parser/compare/v2.4.0...v2.4.1) (2016-07-16) + + +### Bug Fixes + +* **count:** do not increment a default value ([#39](https://github.com/yargs/yargs-parser/issues/39)) ([b04a189](https://github.com/yargs/yargs-parser/commit/b04a189)) + + + + +# [2.4.0](https://github.com/yargs/yargs-parser/compare/v2.3.0...v2.4.0) (2016-04-11) + + +### Features + +* **environment:** Support nested options in environment variables ([#26](https://github.com/yargs/yargs-parser/issues/26)) thanks [@elas7](https://github.com/elas7) \o/ ([020778b](https://github.com/yargs/yargs-parser/commit/020778b)) + + + + +# [2.3.0](https://github.com/yargs/yargs-parser/compare/v2.2.0...v2.3.0) (2016-04-09) + + +### Bug Fixes + +* **boolean:** fix for boolean options with non boolean defaults (#20) ([2dbe86b](https://github.com/yargs/yargs-parser/commit/2dbe86b)), closes [(#20](https://github.com/(/issues/20) +* **package:** remove tests from tarball ([0353c0d](https://github.com/yargs/yargs-parser/commit/0353c0d)) +* **parsing:** handle calling short option with an empty string as the next value. ([a867165](https://github.com/yargs/yargs-parser/commit/a867165)) +* boolean flag when next value contains the strings 'true' or 'false'. ([69941a6](https://github.com/yargs/yargs-parser/commit/69941a6)) +* update dependencies; add standard-version bin for next release (#24) ([822d9d5](https://github.com/yargs/yargs-parser/commit/822d9d5)) + +### Features + +* **configuration:** Allow to pass configuration objects to yargs-parser ([0780900](https://github.com/yargs/yargs-parser/commit/0780900)) +* **normalize:** allow normalize to work with arrays ([e0eaa1a](https://github.com/yargs/yargs-parser/commit/e0eaa1a)) diff --git a/node_modules/npm-audit-resolver/node_modules/yargs-parser/LICENSE.txt b/node_modules/npm-audit-resolver/node_modules/yargs-parser/LICENSE.txt new file mode 100644 index 0000000000000..836440bef7cf1 --- /dev/null +++ b/node_modules/npm-audit-resolver/node_modules/yargs-parser/LICENSE.txt @@ -0,0 +1,14 @@ +Copyright (c) 2016, Contributors + +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/node_modules/npm-audit-resolver/node_modules/yargs-parser/README.md b/node_modules/npm-audit-resolver/node_modules/yargs-parser/README.md new file mode 100644 index 0000000000000..6d6d0d4c9c683 --- /dev/null +++ b/node_modules/npm-audit-resolver/node_modules/yargs-parser/README.md @@ -0,0 +1,308 @@ +# yargs-parser + +[![Build Status](https://travis-ci.org/yargs/yargs-parser.png)](https://travis-ci.org/yargs/yargs-parser) +[![Coverage Status](https://coveralls.io/repos/yargs/yargs-parser/badge.svg?branch=)](https://coveralls.io/r/yargs/yargs-parser?branch=master) +[![NPM version](https://img.shields.io/npm/v/yargs-parser.svg)](https://www.npmjs.com/package/yargs-parser) +[![Windows Tests](https://img.shields.io/appveyor/ci/bcoe/yargs-parser/master.svg?label=Windows%20Tests)](https://ci.appveyor.com/project/bcoe/yargs-parser) +[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version) + + +The mighty option parser used by [yargs](https://github.com/yargs/yargs). + +visit the [yargs website](http://yargs.js.org/) for more examples, and thorough usage instructions. + + + +## Example + +```sh +npm i yargs-parser --save +``` + +```js +var argv = require('yargs-parser')(process.argv.slice(2)) +console.log(argv) +``` + +```sh +node example.js --foo=33 --bar hello +{ _: [], foo: 33, bar: 'hello' } +``` + +_or parse a string!_ + +```js +var argv = require('./')('--foo=99 --bar=33') +console.log(argv) +``` + +```sh +{ _: [], foo: 99, bar: 33 } +``` + +Convert an array of mixed types before passing to `yargs-parser`: + +```js +var parse = require('yargs-parser') +parse(['-f', 11, '--zoom', 55].join(' ')) // <-- array to string +parse(['-f', 11, '--zoom', 55].map(String)) // <-- array of strings +``` + +## API + +### require('yargs-parser')(args, opts={}) + +Parses command line arguments returning a simple mapping of keys and values. + +**expects:** + +* `args`: a string or array of strings representing the options to parse. +* `opts`: provide a set of hints indicating how `args` should be parsed: + * `opts.alias`: an object representing the set of aliases for a key: `{alias: {foo: ['f']}}`. + * `opts.array`: indicate that keys should be parsed as an array: `{array: ['foo', 'bar']}`. + * `opts.boolean`: arguments should be parsed as booleans: `{boolean: ['x', 'y']}`. + * `opts.config`: indicate a key that represents a path to a configuration file (this file will be loaded and parsed). + * `opts.coerce`: provide a custom synchronous function that returns a coerced value from the argument provided + (or throws an error), e.g. `{coerce: {foo: function (arg) {return modifiedArg}}}`. + * `opts.count`: indicate a key that should be used as a counter, e.g., `-vvv` = `{v: 3}`. + * `opts.default`: provide default values for keys: `{default: {x: 33, y: 'hello world!'}}`. + * `opts.envPrefix`: environment variables (`process.env`) with the prefix provided should be parsed. + * `opts.narg`: specify that a key requires `n` arguments: `{narg: {x: 2}}`. + * `opts.normalize`: `path.normalize()` will be applied to values set to this key. + * `opts.string`: keys should be treated as strings (even if they resemble a number `-x 33`). + * `opts.configuration`: provide configuration options to the yargs-parser (see: [configuration](#configuration)). + * `opts.number`: keys should be treated as numbers. + * `opts['--']`: arguments after the end-of-options flag `--` will be set to the `argv.['--']` array instead of being set to the `argv._` array. + +**returns:** + +* `obj`: an object representing the parsed value of `args` + * `key/value`: key value pairs for each argument and their aliases. + * `_`: an array representing the positional arguments. + * [optional] `--`: an array with arguments after the end-of-options flag `--`. + +### require('yargs-parser').detailed(args, opts={}) + +Parses a command line string, returning detailed information required by the +yargs engine. + +**expects:** + +* `args`: a string or array of strings representing options to parse. +* `opts`: provide a set of hints indicating how `args`, inputs are identical to `require('yargs-parser')(args, opts={})`. + +**returns:** + +* `argv`: an object representing the parsed value of `args` + * `key/value`: key value pairs for each argument and their aliases. + * `_`: an array representing the positional arguments. +* `error`: populated with an error object if an exception occurred during parsing. +* `aliases`: the inferred list of aliases built by combining lists in `opts.alias`. +* `newAliases`: any new aliases added via camel-case expansion. +* `configuration`: the configuration loaded from the `yargs` stanza in package.json. + + + +### Configuration + +The yargs-parser applies several automated transformations on the keys provided +in `args`. These features can be turned on and off using the `configuration` field +of `opts`. + +```js +var parsed = parser(['--no-dice'], { + configuration: { + 'boolean-negation': false + } +}) +``` + +### short option groups + +* default: `true`. +* key: `short-option-groups`. + +Should a group of short-options be treated as boolean flags? + +```sh +node example.js -abc +{ _: [], a: true, b: true, c: true } +``` + +_if disabled:_ + +```sh +node example.js -abc +{ _: [], abc: true } +``` + +### camel-case expansion + +* default: `true`. +* key: `camel-case-expansion`. + +Should hyphenated arguments be expanded into camel-case aliases? + +```sh +node example.js --foo-bar +{ _: [], 'foo-bar': true, fooBar: true } +``` + +_if disabled:_ + +```sh +node example.js --foo-bar +{ _: [], 'foo-bar': true } +``` + +### dot-notation + +* default: `true` +* key: `dot-notation` + +Should keys that contain `.` be treated as objects? + +```sh +node example.js --foo.bar +{ _: [], foo: { bar: true } } +``` + +_if disabled:_ + +```sh +node example.js --foo.bar +{ _: [], "foo.bar": true } +``` + +### parse numbers + +* default: `true` +* key: `parse-numbers` + +Should keys that look like numbers be treated as such? + +```sh +node example.js --foo=99.3 +{ _: [], foo: 99.3 } +``` + +_if disabled:_ + +```sh +node example.js --foo=99.3 +{ _: [], foo: "99.3" } +``` + +### boolean negation + +* default: `true` +* key: `boolean-negation` + +Should variables prefixed with `--no` be treated as negations? + +```sh +node example.js --no-foo +{ _: [], foo: false } +``` + +_if disabled:_ + +```sh +node example.js --no-foo +{ _: [], "no-foo": true } +``` + +### combine arrays + +* default: `false` +* key: `combine-arrays` + +Should arrays be combined when provided by both command line arguments and +a configuration file. + +### duplicate arguments array + +* default: `true` +* key: `duplicate-arguments-array` + +Should arguments be coerced into an array when duplicated: + +```sh +node example.js -x 1 -x 2 +{ _: [], x: [1, 2] } +``` + +_if disabled:_ + +```sh +node example.js -x 1 -x 2 +{ _: [], x: 2 } +``` + +### flatten duplicate arrays + +* default: `true` +* key: `flatten-duplicate-arrays` + +Should array arguments be coerced into a single array when duplicated: + +```sh +node example.js -x 1 2 -x 3 4 +{ _: [], x: [1, 2, 3, 4] } +``` + +_if disabled:_ + +```sh +node example.js -x 1 2 -x 3 4 +{ _: [], x: [[1, 2], [3, 4]] } +``` + +### negation prefix + +* default: `no-` +* key: `negation-prefix` + +The prefix to use for negated boolean variables. + +```sh +node example.js --no-foo +{ _: [], foo: false } +``` + +_if set to `quux`:_ + +```sh +node example.js --quuxfoo +{ _: [], foo: false } +``` + +### populate -- + +* default: `false`. +* key: `populate--` + +Should unparsed flags be stored in `--` or `_`. + +_If disabled:_ + +```sh +node example.js a -b -- x y +{ _: [ 'a', 'x', 'y' ], b: true } +``` + +_If enabled:_ + +```sh +node example.js a -b -- x y +{ _: [ 'a' ], '--': [ 'x', 'y' ], b: true } +``` + +## Special Thanks + +The yargs project evolves from optimist and minimist. It owes its +existence to a lot of James Halliday's hard work. Thanks [substack](https://github.com/substack) **beep** **boop** \o/ + +## License + +ISC diff --git a/node_modules/npm-audit-resolver/node_modules/yargs-parser/index.js b/node_modules/npm-audit-resolver/node_modules/yargs-parser/index.js new file mode 100644 index 0000000000000..9889ac5a59e4c --- /dev/null +++ b/node_modules/npm-audit-resolver/node_modules/yargs-parser/index.js @@ -0,0 +1,813 @@ +var camelCase = require('camelcase') +var path = require('path') +var tokenizeArgString = require('./lib/tokenize-arg-string') +var util = require('util') + +function parse (args, opts) { + if (!opts) opts = {} + // allow a string argument to be passed in rather + // than an argv array. + args = tokenizeArgString(args) + // aliases might have transitive relationships, normalize this. + var aliases = combineAliases(opts.alias || {}) + var configuration = assign({ + 'short-option-groups': true, + 'camel-case-expansion': true, + 'dot-notation': true, + 'parse-numbers': true, + 'boolean-negation': true, + 'negation-prefix': 'no-', + 'duplicate-arguments-array': true, + 'flatten-duplicate-arrays': true, + 'populate--': false, + 'combine-arrays': false + }, opts.configuration) + var defaults = opts.default || {} + var configObjects = opts.configObjects || [] + var envPrefix = opts.envPrefix + var notFlagsOption = configuration['populate--'] + var notFlagsArgv = notFlagsOption ? '--' : '_' + var newAliases = {} + // allow a i18n handler to be passed in, default to a fake one (util.format). + var __ = opts.__ || function (str) { + return util.format.apply(util, Array.prototype.slice.call(arguments)) + } + var error = null + var flags = { + aliases: {}, + arrays: {}, + bools: {}, + strings: {}, + numbers: {}, + counts: {}, + normalize: {}, + configs: {}, + defaulted: {}, + nargs: {}, + coercions: {} + } + var negative = /^-[0-9]+(\.[0-9]+)?/ + var negatedBoolean = new RegExp('^--' + configuration['negation-prefix'] + '(.+)') + + ;[].concat(opts.array).filter(Boolean).forEach(function (key) { + flags.arrays[key] = true + }) + + ;[].concat(opts.boolean).filter(Boolean).forEach(function (key) { + flags.bools[key] = true + }) + + ;[].concat(opts.string).filter(Boolean).forEach(function (key) { + flags.strings[key] = true + }) + + ;[].concat(opts.number).filter(Boolean).forEach(function (key) { + flags.numbers[key] = true + }) + + ;[].concat(opts.count).filter(Boolean).forEach(function (key) { + flags.counts[key] = true + }) + + ;[].concat(opts.normalize).filter(Boolean).forEach(function (key) { + flags.normalize[key] = true + }) + + Object.keys(opts.narg || {}).forEach(function (k) { + flags.nargs[k] = opts.narg[k] + }) + + Object.keys(opts.coerce || {}).forEach(function (k) { + flags.coercions[k] = opts.coerce[k] + }) + + if (Array.isArray(opts.config) || typeof opts.config === 'string') { + ;[].concat(opts.config).filter(Boolean).forEach(function (key) { + flags.configs[key] = true + }) + } else { + Object.keys(opts.config || {}).forEach(function (k) { + flags.configs[k] = opts.config[k] + }) + } + + // create a lookup table that takes into account all + // combinations of aliases: {f: ['foo'], foo: ['f']} + extendAliases(opts.key, aliases, opts.default, flags.arrays) + + // apply default values to all aliases. + Object.keys(defaults).forEach(function (key) { + (flags.aliases[key] || []).forEach(function (alias) { + defaults[alias] = defaults[key] + }) + }) + + var argv = { _: [] } + + Object.keys(flags.bools).forEach(function (key) { + if (Object.prototype.hasOwnProperty.call(defaults, key)) { + setArg(key, defaults[key]) + setDefaulted(key) + } + }) + + var notFlags = [] + if (args.indexOf('--') !== -1) { + notFlags = args.slice(args.indexOf('--') + 1) + args = args.slice(0, args.indexOf('--')) + } + + for (var i = 0; i < args.length; i++) { + var arg = args[i] + var broken + var key + var letters + var m + var next + var value + + // -- seperated by = + if (arg.match(/^--.+=/) || ( + !configuration['short-option-groups'] && arg.match(/^-.+=/) + )) { + // Using [\s\S] instead of . because js doesn't support the + // 'dotall' regex modifier. See: + // http://stackoverflow.com/a/1068308/13216 + m = arg.match(/^--?([^=]+)=([\s\S]*)$/) + + // nargs format = '--f=monkey washing cat' + if (checkAllAliases(m[1], flags.nargs)) { + args.splice(i + 1, 0, m[2]) + i = eatNargs(i, m[1], args) + // arrays format = '--f=a b c' + } else if (checkAllAliases(m[1], flags.arrays) && args.length > i + 1) { + args.splice(i + 1, 0, m[2]) + i = eatArray(i, m[1], args) + } else { + setArg(m[1], m[2]) + } + } else if (arg.match(negatedBoolean) && configuration['boolean-negation']) { + key = arg.match(negatedBoolean)[1] + setArg(key, false) + + // -- seperated by space. + } else if (arg.match(/^--.+/) || ( + !configuration['short-option-groups'] && arg.match(/^-.+/) + )) { + key = arg.match(/^--?(.+)/)[1] + + // nargs format = '--foo a b c' + if (checkAllAliases(key, flags.nargs)) { + i = eatNargs(i, key, args) + // array format = '--foo a b c' + } else if (checkAllAliases(key, flags.arrays) && args.length > i + 1) { + i = eatArray(i, key, args) + } else { + next = args[i + 1] + + if (next !== undefined && (!next.match(/^-/) || + next.match(negative)) && + !checkAllAliases(key, flags.bools) && + !checkAllAliases(key, flags.counts)) { + setArg(key, next) + i++ + } else if (/^(true|false)$/.test(next)) { + setArg(key, next) + i++ + } else { + setArg(key, defaultForType(guessType(key, flags))) + } + } + + // dot-notation flag seperated by '='. + } else if (arg.match(/^-.\..+=/)) { + m = arg.match(/^-([^=]+)=([\s\S]*)$/) + setArg(m[1], m[2]) + + // dot-notation flag seperated by space. + } else if (arg.match(/^-.\..+/)) { + next = args[i + 1] + key = arg.match(/^-(.\..+)/)[1] + + if (next !== undefined && !next.match(/^-/) && + !checkAllAliases(key, flags.bools) && + !checkAllAliases(key, flags.counts)) { + setArg(key, next) + i++ + } else { + setArg(key, defaultForType(guessType(key, flags))) + } + } else if (arg.match(/^-[^-]+/) && !arg.match(negative)) { + letters = arg.slice(1, -1).split('') + broken = false + + for (var j = 0; j < letters.length; j++) { + next = arg.slice(j + 2) + + if (letters[j + 1] && letters[j + 1] === '=') { + value = arg.slice(j + 3) + key = letters[j] + + // nargs format = '-f=monkey washing cat' + if (checkAllAliases(key, flags.nargs)) { + args.splice(i + 1, 0, value) + i = eatNargs(i, key, args) + // array format = '-f=a b c' + } else if (checkAllAliases(key, flags.arrays) && args.length > i + 1) { + args.splice(i + 1, 0, value) + i = eatArray(i, key, args) + } else { + setArg(key, value) + } + + broken = true + break + } + + if (next === '-') { + setArg(letters[j], next) + continue + } + + // current letter is an alphabetic character and next value is a number + if (/[A-Za-z]/.test(letters[j]) && + /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { + setArg(letters[j], next) + broken = true + break + } + + if (letters[j + 1] && letters[j + 1].match(/\W/)) { + setArg(letters[j], next) + broken = true + break + } else { + setArg(letters[j], defaultForType(guessType(letters[j], flags))) + } + } + + key = arg.slice(-1)[0] + + if (!broken && key !== '-') { + // nargs format = '-f a b c' + if (checkAllAliases(key, flags.nargs)) { + i = eatNargs(i, key, args) + // array format = '-f a b c' + } else if (checkAllAliases(key, flags.arrays) && args.length > i + 1) { + i = eatArray(i, key, args) + } else { + next = args[i + 1] + + if (next !== undefined && (!/^(-|--)[^-]/.test(next) || + next.match(negative)) && + !checkAllAliases(key, flags.bools) && + !checkAllAliases(key, flags.counts)) { + setArg(key, next) + i++ + } else if (/^(true|false)$/.test(next)) { + setArg(key, next) + i++ + } else { + setArg(key, defaultForType(guessType(key, flags))) + } + } + } + } else { + argv._.push(maybeCoerceNumber('_', arg)) + } + } + + // order of precedence: + // 1. command line arg + // 2. value from env var + // 3. value from config file + // 4. value from config objects + // 5. configured default value + applyEnvVars(argv, true) // special case: check env vars that point to config file + applyEnvVars(argv, false) + setConfig(argv) + setConfigObjects() + applyDefaultsAndAliases(argv, flags.aliases, defaults) + applyCoercions(argv) + + // for any counts either not in args or without an explicit default, set to 0 + Object.keys(flags.counts).forEach(function (key) { + if (!hasKey(argv, key.split('.'))) setArg(key, 0) + }) + + // '--' defaults to undefined. + if (notFlagsOption && notFlags.length) argv[notFlagsArgv] = [] + notFlags.forEach(function (key) { + argv[notFlagsArgv].push(key) + }) + + // how many arguments should we consume, based + // on the nargs option? + function eatNargs (i, key, args) { + var ii + const toEat = checkAllAliases(key, flags.nargs) + + // nargs will not consume flag arguments, e.g., -abc, --foo, + // and terminates when one is observed. + var available = 0 + for (ii = i + 1; ii < args.length; ii++) { + if (!args[ii].match(/^-[^0-9]/)) available++ + else break + } + + if (available < toEat) error = Error(__('Not enough arguments following: %s', key)) + + const consumed = Math.min(available, toEat) + for (ii = i + 1; ii < (consumed + i + 1); ii++) { + setArg(key, args[ii]) + } + + return (i + consumed) + } + + // if an option is an array, eat all non-hyphenated arguments + // following it... YUM! + // e.g., --foo apple banana cat becomes ["apple", "banana", "cat"] + function eatArray (i, key, args) { + var start = i + 1 + var argsToSet = [] + var multipleArrayFlag = i > 0 + for (var ii = i + 1; ii < args.length; ii++) { + if (/^-/.test(args[ii]) && !negative.test(args[ii])) { + if (ii === start) { + setArg(key, defaultForType('array')) + } + multipleArrayFlag = true + break + } + i = ii + argsToSet.push(args[ii]) + } + if (multipleArrayFlag) { + setArg(key, argsToSet.map(function (arg) { + return processValue(key, arg) + })) + } else { + argsToSet.forEach(function (arg) { + setArg(key, arg) + }) + } + + return i + } + + function setArg (key, val) { + unsetDefaulted(key) + + if (/-/.test(key) && configuration['camel-case-expansion']) { + addNewAlias(key, camelCase(key)) + } + + var value = processValue(key, val) + + var splitKey = key.split('.') + setKey(argv, splitKey, value) + + // handle populating aliases of the full key + if (flags.aliases[key]) { + flags.aliases[key].forEach(function (x) { + x = x.split('.') + setKey(argv, x, value) + }) + } + + // handle populating aliases of the first element of the dot-notation key + if (splitKey.length > 1 && configuration['dot-notation']) { + ;(flags.aliases[splitKey[0]] || []).forEach(function (x) { + x = x.split('.') + + // expand alias with nested objects in key + var a = [].concat(splitKey) + a.shift() // nuke the old key. + x = x.concat(a) + + setKey(argv, x, value) + }) + } + + // Set normalize getter and setter when key is in 'normalize' but isn't an array + if (checkAllAliases(key, flags.normalize) && !checkAllAliases(key, flags.arrays)) { + var keys = [key].concat(flags.aliases[key] || []) + keys.forEach(function (key) { + argv.__defineSetter__(key, function (v) { + val = path.normalize(v) + }) + + argv.__defineGetter__(key, function () { + return typeof val === 'string' ? path.normalize(val) : val + }) + }) + } + } + + function addNewAlias (key, alias) { + if (!(flags.aliases[key] && flags.aliases[key].length)) { + flags.aliases[key] = [alias] + newAliases[alias] = true + } + if (!(flags.aliases[alias] && flags.aliases[alias].length)) { + addNewAlias(alias, key) + } + } + + function processValue (key, val) { + // handle parsing boolean arguments --foo=true --bar false. + if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) { + if (typeof val === 'string') val = val === 'true' + } + + var value = maybeCoerceNumber(key, val) + + // increment a count given as arg (either no value or value parsed as boolean) + if (checkAllAliases(key, flags.counts) && (isUndefined(value) || typeof value === 'boolean')) { + value = increment + } + + // Set normalized value when key is in 'normalize' and in 'arrays' + if (checkAllAliases(key, flags.normalize) && checkAllAliases(key, flags.arrays)) { + if (Array.isArray(val)) value = val.map(path.normalize) + else value = path.normalize(val) + } + return value + } + + function maybeCoerceNumber (key, value) { + if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.coercions)) { + const shouldCoerceNumber = isNumber(value) && configuration['parse-numbers'] && ( + Number.isSafeInteger(Math.floor(value)) + ) + if (shouldCoerceNumber || (!isUndefined(value) && checkAllAliases(key, flags.numbers))) value = Number(value) + } + return value + } + + // set args from config.json file, this should be + // applied last so that defaults can be applied. + function setConfig (argv) { + var configLookup = {} + + // expand defaults/aliases, in-case any happen to reference + // the config.json file. + applyDefaultsAndAliases(configLookup, flags.aliases, defaults) + + Object.keys(flags.configs).forEach(function (configKey) { + var configPath = argv[configKey] || configLookup[configKey] + if (configPath) { + try { + var config = null + var resolvedConfigPath = path.resolve(process.cwd(), configPath) + + if (typeof flags.configs[configKey] === 'function') { + try { + config = flags.configs[configKey](resolvedConfigPath) + } catch (e) { + config = e + } + if (config instanceof Error) { + error = config + return + } + } else { + config = require(resolvedConfigPath) + } + + setConfigObject(config) + } catch (ex) { + if (argv[configKey]) error = Error(__('Invalid JSON config file: %s', configPath)) + } + } + }) + } + + // set args from config object. + // it recursively checks nested objects. + function setConfigObject (config, prev) { + Object.keys(config).forEach(function (key) { + var value = config[key] + var fullKey = prev ? prev + '.' + key : key + + // if the value is an inner object and we have dot-notation + // enabled, treat inner objects in config the same as + // heavily nested dot notations (foo.bar.apple). + if (typeof value === 'object' && value !== null && !Array.isArray(value) && configuration['dot-notation']) { + // if the value is an object but not an array, check nested object + setConfigObject(value, fullKey) + } else { + // setting arguments via CLI takes precedence over + // values within the config file. + if (!hasKey(argv, fullKey.split('.')) || (flags.defaulted[fullKey]) || (flags.arrays[fullKey] && configuration['combine-arrays'])) { + setArg(fullKey, value) + } + } + }) + } + + // set all config objects passed in opts + function setConfigObjects () { + if (typeof configObjects === 'undefined') return + configObjects.forEach(function (configObject) { + setConfigObject(configObject) + }) + } + + function applyEnvVars (argv, configOnly) { + if (typeof envPrefix === 'undefined') return + + var prefix = typeof envPrefix === 'string' ? envPrefix : '' + Object.keys(process.env).forEach(function (envVar) { + if (prefix === '' || envVar.lastIndexOf(prefix, 0) === 0) { + // get array of nested keys and convert them to camel case + var keys = envVar.split('__').map(function (key, i) { + if (i === 0) { + key = key.substring(prefix.length) + } + return camelCase(key) + }) + + if (((configOnly && flags.configs[keys.join('.')]) || !configOnly) && (!hasKey(argv, keys) || flags.defaulted[keys.join('.')])) { + setArg(keys.join('.'), process.env[envVar]) + } + } + }) + } + + function applyCoercions (argv) { + var coerce + var applied = {} + Object.keys(argv).forEach(function (key) { + if (!applied.hasOwnProperty(key)) { // If we haven't already coerced this option via one of its aliases + coerce = checkAllAliases(key, flags.coercions) + if (typeof coerce === 'function') { + try { + var value = coerce(argv[key]) + ;([].concat(flags.aliases[key] || [], key)).forEach(ali => { + applied[ali] = argv[ali] = value + }) + } catch (err) { + error = err + } + } + } + }) + } + + function applyDefaultsAndAliases (obj, aliases, defaults) { + Object.keys(defaults).forEach(function (key) { + if (!hasKey(obj, key.split('.'))) { + setKey(obj, key.split('.'), defaults[key]) + + ;(aliases[key] || []).forEach(function (x) { + if (hasKey(obj, x.split('.'))) return + setKey(obj, x.split('.'), defaults[key]) + }) + } + }) + } + + function hasKey (obj, keys) { + var o = obj + + if (!configuration['dot-notation']) keys = [keys.join('.')] + + keys.slice(0, -1).forEach(function (key) { + o = (o[key] || {}) + }) + + var key = keys[keys.length - 1] + + if (typeof o !== 'object') return false + else return key in o + } + + function setKey (obj, keys, value) { + var o = obj + + if (!configuration['dot-notation']) keys = [keys.join('.')] + + keys.slice(0, -1).forEach(function (key, index) { + if (typeof o === 'object' && o[key] === undefined) { + o[key] = {} + } + + if (typeof o[key] !== 'object' || Array.isArray(o[key])) { + // ensure that o[key] is an array, and that the last item is an empty object. + if (Array.isArray(o[key])) { + o[key].push({}) + } else { + o[key] = [o[key], {}] + } + + // we want to update the empty object at the end of the o[key] array, so set o to that object + o = o[key][o[key].length - 1] + } else { + o = o[key] + } + }) + + var key = keys[keys.length - 1] + + var isTypeArray = checkAllAliases(keys.join('.'), flags.arrays) + var isValueArray = Array.isArray(value) + var duplicate = configuration['duplicate-arguments-array'] + + if (value === increment) { + o[key] = increment(o[key]) + } else if (Array.isArray(o[key])) { + if (duplicate && isTypeArray && isValueArray) { + o[key] = configuration['flatten-duplicate-arrays'] ? o[key].concat(value) : [o[key]].concat([value]) + } else if (!duplicate && Boolean(isTypeArray) === Boolean(isValueArray)) { + o[key] = value + } else { + o[key] = o[key].concat([value]) + } + } else if (o[key] === undefined && isTypeArray) { + o[key] = isValueArray ? value : [value] + } else if (duplicate && !(o[key] === undefined || checkAllAliases(key, flags.bools) || checkAllAliases(keys.join('.'), flags.bools) || checkAllAliases(key, flags.counts))) { + o[key] = [ o[key], value ] + } else { + o[key] = value + } + } + + // extend the aliases list with inferred aliases. + function extendAliases () { + Array.prototype.slice.call(arguments).forEach(function (obj) { + Object.keys(obj || {}).forEach(function (key) { + // short-circuit if we've already added a key + // to the aliases array, for example it might + // exist in both 'opts.default' and 'opts.key'. + if (flags.aliases[key]) return + + flags.aliases[key] = [].concat(aliases[key] || []) + // For "--option-name", also set argv.optionName + flags.aliases[key].concat(key).forEach(function (x) { + if (/-/.test(x) && configuration['camel-case-expansion']) { + var c = camelCase(x) + if (c !== key && flags.aliases[key].indexOf(c) === -1) { + flags.aliases[key].push(c) + newAliases[c] = true + } + } + }) + flags.aliases[key].forEach(function (x) { + flags.aliases[x] = [key].concat(flags.aliases[key].filter(function (y) { + return x !== y + })) + }) + }) + }) + } + + // check if a flag is set for any of a key's aliases. + function checkAllAliases (key, flag) { + var isSet = false + var toCheck = [].concat(flags.aliases[key] || [], key) + + toCheck.forEach(function (key) { + if (flag[key]) isSet = flag[key] + }) + + return isSet + } + + function setDefaulted (key) { + [].concat(flags.aliases[key] || [], key).forEach(function (k) { + flags.defaulted[k] = true + }) + } + + function unsetDefaulted (key) { + [].concat(flags.aliases[key] || [], key).forEach(function (k) { + delete flags.defaulted[k] + }) + } + + // return a default value, given the type of a flag., + // e.g., key of type 'string' will default to '', rather than 'true'. + function defaultForType (type) { + var def = { + boolean: true, + string: '', + number: undefined, + array: [] + } + + return def[type] + } + + // given a flag, enforce a default type. + function guessType (key, flags) { + var type = 'boolean' + + if (checkAllAliases(key, flags.strings)) type = 'string' + else if (checkAllAliases(key, flags.numbers)) type = 'number' + else if (checkAllAliases(key, flags.arrays)) type = 'array' + + return type + } + + function isNumber (x) { + if (typeof x === 'number') return true + if (/^0x[0-9a-f]+$/i.test(x)) return true + return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x) + } + + function isUndefined (num) { + return num === undefined + } + + return { + argv: argv, + error: error, + aliases: flags.aliases, + newAliases: newAliases, + configuration: configuration + } +} + +// if any aliases reference each other, we should +// merge them together. +function combineAliases (aliases) { + var aliasArrays = [] + var change = true + var combined = {} + + // turn alias lookup hash {key: ['alias1', 'alias2']} into + // a simple array ['key', 'alias1', 'alias2'] + Object.keys(aliases).forEach(function (key) { + aliasArrays.push( + [].concat(aliases[key], key) + ) + }) + + // combine arrays until zero changes are + // made in an iteration. + while (change) { + change = false + for (var i = 0; i < aliasArrays.length; i++) { + for (var ii = i + 1; ii < aliasArrays.length; ii++) { + var intersect = aliasArrays[i].filter(function (v) { + return aliasArrays[ii].indexOf(v) !== -1 + }) + + if (intersect.length) { + aliasArrays[i] = aliasArrays[i].concat(aliasArrays[ii]) + aliasArrays.splice(ii, 1) + change = true + break + } + } + } + } + + // map arrays back to the hash-lookup (de-dupe while + // we're at it). + aliasArrays.forEach(function (aliasArray) { + aliasArray = aliasArray.filter(function (v, i, self) { + return self.indexOf(v) === i + }) + combined[aliasArray.pop()] = aliasArray + }) + + return combined +} + +function assign (defaults, configuration) { + var o = {} + configuration = configuration || {} + + Object.keys(defaults).forEach(function (k) { + o[k] = defaults[k] + }) + Object.keys(configuration).forEach(function (k) { + o[k] = configuration[k] + }) + + return o +} + +// this function should only be called when a count is given as an arg +// it is NOT called to set a default value +// thus we can start the count at 1 instead of 0 +function increment (orig) { + return orig !== undefined ? orig + 1 : 1 +} + +function Parser (args, opts) { + var result = parse(args.slice(), opts) + + return result.argv +} + +// parse arguments and return detailed +// meta information, aliases, etc. +Parser.detailed = function (args, opts) { + return parse(args.slice(), opts) +} + +module.exports = Parser diff --git a/node_modules/npm-audit-resolver/node_modules/yargs-parser/lib/tokenize-arg-string.js b/node_modules/npm-audit-resolver/node_modules/yargs-parser/lib/tokenize-arg-string.js new file mode 100644 index 0000000000000..6c8d23ef2143a --- /dev/null +++ b/node_modules/npm-audit-resolver/node_modules/yargs-parser/lib/tokenize-arg-string.js @@ -0,0 +1,40 @@ +// take an un-split argv string and tokenize it. +module.exports = function (argString) { + if (Array.isArray(argString)) return argString + + argString = argString.trim() + + var i = 0 + var prevC = null + var c = null + var opening = null + var args = [] + + for (var ii = 0; ii < argString.length; ii++) { + prevC = c + c = argString.charAt(ii) + + // split on spaces unless we're in quotes. + if (c === ' ' && !opening) { + if (!(prevC === ' ')) { + i++ + } + continue + } + + // don't split the string if we're in matching + // opening or closing single and double quotes. + if (c === opening) { + opening = null + continue + } else if ((c === "'" || c === '"') && !opening) { + opening = c + continue + } + + if (!args[i]) args[i] = '' + args[i] += c + } + + return args +} diff --git a/node_modules/npm-audit-resolver/node_modules/yargs-parser/package.json b/node_modules/npm-audit-resolver/node_modules/yargs-parser/package.json new file mode 100644 index 0000000000000..00ec9fc31bbd4 --- /dev/null +++ b/node_modules/npm-audit-resolver/node_modules/yargs-parser/package.json @@ -0,0 +1,75 @@ +{ + "_from": "yargs-parser@^10.0.0", + "_id": "yargs-parser@10.0.0", + "_inBundle": false, + "_integrity": "sha512-+DHejWujTVYeMHLff8U96rLc4uE4Emncoftvn5AjhB1Jw1pWxLzgBUT/WYbPrHmy6YPEBTZQx5myHhVcuuu64g==", + "_location": "/npm-audit-resolver/yargs-parser", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "yargs-parser@^10.0.0", + "name": "yargs-parser", + "escapedName": "yargs-parser", + "rawSpec": "^10.0.0", + "saveSpec": null, + "fetchSpec": "^10.0.0" + }, + "_requiredBy": [ + "/npm-audit-resolver" + ], + "_resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.0.0.tgz", + "_shasum": "c737c93de2567657750cb1f2c00be639fd19c994", + "_spec": "yargs-parser@^10.0.0", + "_where": "/storage/projects/github/npm/node_modules/npm-audit-resolver", + "author": { + "name": "Ben Coe", + "email": "ben@npmjs.com" + }, + "bugs": { + "url": "https://github.com/yargs/yargs-parser/issues" + }, + "bundleDependencies": false, + "dependencies": { + "camelcase": "^4.1.0" + }, + "deprecated": false, + "description": "the mighty option parser used by yargs", + "devDependencies": { + "chai": "^3.5.0", + "coveralls": "^2.11.12", + "mocha": "^3.0.1", + "nyc": "^11.4.1", + "standard": "^10.0.2", + "standard-version": "^4.3.0" + }, + "files": [ + "lib", + "index.js" + ], + "homepage": "https://github.com/yargs/yargs-parser#readme", + "keywords": [ + "argument", + "parser", + "yargs", + "command", + "cli", + "parsing", + "option", + "args", + "argument" + ], + "license": "ISC", + "main": "index.js", + "name": "yargs-parser", + "repository": { + "url": "git+ssh://git@github.com/yargs/yargs-parser.git" + }, + "scripts": { + "coverage": "nyc report --reporter=text-lcov | coveralls", + "posttest": "standard", + "release": "standard-version", + "test": "nyc mocha test/*.js" + }, + "version": "10.0.0" +} diff --git a/node_modules/npm-audit-resolver/package.json b/node_modules/npm-audit-resolver/package.json new file mode 100644 index 0000000000000..8e8151c308c2e --- /dev/null +++ b/node_modules/npm-audit-resolver/package.json @@ -0,0 +1,68 @@ +{ + "_from": "npm-audit-resolver", + "_id": "npm-audit-resolver@1.2.0", + "_inBundle": false, + "_integrity": "sha512-o4KZUrHRiIqbI8HbBiaGJUwKFExwkotElQ6U5lQySzrbA6B7SdGDDa7Cd/ASSu3WRMmFvzEsFzh3SsK49VunxA==", + "_location": "/npm-audit-resolver", + "_phantomChildren": { + "camelcase": "4.1.0" + }, + "_requested": { + "type": "tag", + "registry": true, + "raw": "npm-audit-resolver", + "name": "npm-audit-resolver", + "escapedName": "npm-audit-resolver", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/npm-audit-resolver/-/npm-audit-resolver-1.2.0.tgz", + "_shasum": "49b6b44abc55fe32ea4a5dc18d1904d33bc1a1da", + "_spec": "npm-audit-resolver", + "_where": "/storage/projects/github/npm", + "author": { + "name": "naugtur", + "email": "naugtur@gmail.com" + }, + "bin": { + "resolve-audit": "resolve.js", + "check-audit": "check.js" + }, + "bundleDependencies": false, + "dependencies": { + "chalk": "^2.4.1", + "concat-stream": "^1.6.2", + "flatten": "^1.0.2", + "promptly": "^3.0.3", + "semver": "^5.5.0", + "spawn-shell": "^2.0.1", + "yargs-parser": "^10.0.0" + }, + "deprecated": false, + "description": "Aids humans and automation in managing npm audit results", + "devDependencies": {}, + "keywords": [ + "npm", + "audit", + "security", + "dependencies", + "nsp", + "check", + "resolve" + ], + "license": "Apache 2.0", + "main": "index.js", + "name": "npm-audit-resolver", + "scripts": { + "add-vulns": "npm i -D base64url@2.0.0 lodash@2.0.0 request@2.0.0", + "rm-vulns": "npm rm -D base64url lodash request", + "test": "npm run add-vulns && npm run test-exec && npm run rm-vulns", + "test-exec": "node resolve.js && node check.js" + }, + "version": "1.2.0" +} diff --git a/node_modules/npm-audit-resolver/resolve.js b/node_modules/npm-audit-resolver/resolve.js new file mode 100755 index 0000000000000..0db2ad2b6a069 --- /dev/null +++ b/node_modules/npm-audit-resolver/resolve.js @@ -0,0 +1,11 @@ +#!/usr/bin/env node +const core = require('./index') +const npmFacade = require('./src/npmfacade'); + +npmFacade.runNpmCommand('audit', { ignoreExit: true }) + .then(input => { + console.log(`Total of ${input.actions.length} actions to process`) + return core.resolveAudit(input) + }) + .then(() => console.log('done.')) + .catch(e => console.error(e)); diff --git a/node_modules/npm-audit-resolver/src/actions.js b/node_modules/npm-audit-resolver/src/actions.js new file mode 100644 index 0000000000000..6e95420108b5e --- /dev/null +++ b/node_modules/npm-audit-resolver/src/actions.js @@ -0,0 +1,87 @@ +const promiseCommand = require('./promiseCommand'); +const resolutionState = require('./resolutionState'); +const investigate = require('./investigate'); +const chalk = require('chalk') + +function saveResolutionAll(action, resolution) { + action.resolves.map(re => resolutionState.set( + { id: re.id, path: re.path }, + resolution + )) + + return resolutionState.flush() +} +function saveResolution(singleResolve, resolution) { + resolutionState.set( + { id: singleResolve.id, path: singleResolve.path }, + resolution + ); + return resolutionState.flush() +} + +const LATER = 24 * 60 * 60 * 1000; + +const strategies = { + i: function ignore({ action, advisories, command }) { + return saveResolutionAll(action, { ignore: 1 }); + }, + r: function remindLater({ action, advisories, command }) { + return saveResolutionAll(action, { remind: Date.now() + LATER }); + }, + f: function fix({ action, advisories, command }) { + console.log('Fixing!'); + return promiseCommand(command).then(() => + saveResolutionAll(action, { fix: 1 }) + ); + }, + del: function del({ action, advisories, command }) { + console.log('Removing'); + return Promise.all(Object.keys(action.resolves.reduce((mem, re) => { + const topModule = re.path.split('>')[0] + if (topModule) { + mem[topModule + (re.dev ? ' -D' : ' -S')] = 1 + } + return mem + }, {})).map(commandBit => { + return promiseCommand(`npm rm ${commandBit}`) + })).then(() => { }) + }, + d: function details({ action, advisories, command }) { + console.log(''); + + Object.keys(action.resolves.reduce((mem, re) => { + mem[re.id] = 1 + return mem + }, {})).map(advId => { + const adv = advisories[advId] + const versions = adv.findings.map(f=>f.version).join() + console.log(`${chalk.bold(adv.module_name)} versions installed: ${chalk.bold(versions)} +${adv.overview} +${adv.recommendation} +${adv.references}`) + }) + return null; + }, + '?': function investigateIt({ action, advisories, command }) { + console.log('Investigating!'); + return investigate.findFeasibleResolutions({ action, advisories }) + }, + s: function abort() { + console.log('Skipped'); + }, + q: function abort() { + console.log('Aborting. Bye!'); + process.exit(1); + } +}; + +const noop = () => console.log('doing nothing'); +function strategyOf(choice) { + return strategies[choice] || noop; +} + +module.exports = { + takeAction(choice, details) { + return strategyOf(choice)(details); + } +}; diff --git a/node_modules/npm-audit-resolver/src/arguments.js b/node_modules/npm-audit-resolver/src/arguments.js new file mode 100644 index 0000000000000..2df40cc4996bc --- /dev/null +++ b/node_modules/npm-audit-resolver/src/arguments.js @@ -0,0 +1,2 @@ +const argv = require('yargs-parser')(process.argv.slice(2)); +module.exports = argv \ No newline at end of file diff --git a/node_modules/npm-audit-resolver/src/investigate.js b/node_modules/npm-audit-resolver/src/investigate.js new file mode 100644 index 0000000000000..9d4f131b1e947 --- /dev/null +++ b/node_modules/npm-audit-resolver/src/investigate.js @@ -0,0 +1,56 @@ +const semver = require('semver') +const npmFacade = require('./npmfacade') + +function matchSemverToVersion(range1, range2) { + // console.log('comparing range ', `${range1} and ${range2}`) + return semver.intersects(range1, range2) +} + +function findFeasibleUpdate(targetPackage, targetVersion, dependantsChain) { + return npmFacade.runNpmCommand(`info ${dependantsChain[0]}`) + .then(info => { + const range1 = info.dependencies[targetPackage] || info.devDependencies[targetPackage] + if (!range1) { + console.log(`possible fix: ${targetPackage} doesn't seem to be a dependency in the latest version of ${dependantsChain[0]}`) + console.log(` you might be able to fix it by updating ${dependantsChain[0]} to latest version`) + return ['r', 'i'] + } + if (dependantsChain.length < 1) { + console.log('ran out of parents to go up, this looks fixed, how did we get here?'); + return ['d'] + //TODO: figure out how this can happen + } + if (matchSemverToVersion(range1, targetVersion)) { + // semver range includes the fix, go up + const newTarget = dependantsChain.shift() + // This is a bit strict, maybe we wouldn't have to force an update to latest on everything in the chain, but it'd require iterating over all versions between what's used by dependant and latest + const newTargetVersion = info['dist-tags'].latest + return findFeasibleUpdate(newTarget, newTargetVersion, dependantsChain) + } else { + //TODO: deduplicate this! + console.log(`possible fix: update ${targetPackage} in ${dependantsChain[0]} to ${targetVersion}`) + console.log(` you can submit a PR or see if an issue exists here: ${info.bugs.url}`) + return ['r', 'i'] + } + }) +} + + +module.exports = { + findFeasibleResolutions({ action, advisories }) { + return Promise.all(action.resolves + // .filter(r => r.path === 'jshint>lodash') + .map(issue => { + const adv = advisories[issue.id] + const dependantsChain = issue.path.split('>').reverse() + dependantsChain.shift() + return findFeasibleUpdate(adv.module_name, adv.patched_versions, dependantsChain) + })).then(setsOfOptions => + Array.from(setsOfOptions.reduce((all, o) => { + o.map(all.add, all) + return all; + }, new Set())) + ) + + } +} diff --git a/node_modules/npm-audit-resolver/src/npmfacade.js b/node_modules/npm-audit-resolver/src/npmfacade.js new file mode 100644 index 0000000000000..970a568a19b63 --- /dev/null +++ b/node_modules/npm-audit-resolver/src/npmfacade.js @@ -0,0 +1,26 @@ +const fs = require('fs'); +const promiseCommand = require('./promiseCommand'); +const argv = require('./arguments') + +let seq = 0; +const runner = argv.mock ? + (command) => { + console.log('>>>mock ', command) + return Promise.resolve(fs.readFileSync(`mock-${command.substr(0, 4)}.json`)) + } + : + (command, opts) => promiseCommand('npm ' + command + ' --json', opts); + +module.exports = { + runNpmCommand(command, opts) { + return runner(command, opts).then(output => { + try { + return JSON.parse(output) + } catch (e) { + console.error('failed to parse output') + console.error(output) + throw e; + } + }) + } +} \ No newline at end of file diff --git a/node_modules/npm-audit-resolver/src/promiseCommand.js b/node_modules/npm-audit-resolver/src/promiseCommand.js new file mode 100644 index 0000000000000..483a3d62846f1 --- /dev/null +++ b/node_modules/npm-audit-resolver/src/promiseCommand.js @@ -0,0 +1,33 @@ +const spawnShell = require('spawn-shell'); +const concat = require('concat-stream'); + + +module.exports = function promiseCommand (command, opts={}) { + console.log('>>>>', command) + const pSpawn = spawnShell(command, Object.assign({ + stdio: [0, 'pipe', 2], + env: process.env + }, opts)) + + const pOutput = new Promise((resolve, reject) => { + pSpawn.stdout.pipe(concat( + {encoding: 'string'}, + output => { + resolve(output) + } + ) + ).on('error', reject) + }) + + return Promise.all([ + pSpawn.exitPromise + .then((exitCode) => { + if (opts.ignoreExit || exitCode === 0) { + console.log('>>>> exit:', exitCode) + return + } else { + throw Error('Exit ' + exitCode) + } + }), + pOutput]).then(arr => arr[1]) +} diff --git a/node_modules/npm-audit-resolver/src/prompter.js b/node_modules/npm-audit-resolver/src/prompter.js new file mode 100644 index 0000000000000..edeeb7fd3128c --- /dev/null +++ b/node_modules/npm-audit-resolver/src/prompter.js @@ -0,0 +1,136 @@ +const promptly = require('promptly'); +const actions = require('./actions'); +const chalk = require('chalk') +const argv = require('./arguments') + +module.exports = { + handleAction(action, advisories) { + console.log(`\n--------------------------------------------------`); + console.log(` ${chalk.bold.black.bgWhite(action.module)} needs your attention.\n`); + const groupedResolutions = action.resolves.reduce((groups, re) => { + groups[re.id] = groups[re.id] || []; + let type = re.dev ? ' devDependencies' : 'dependencies'; + re.optional && (type += ' (optional)'); + re.bundled && (type += ' (bundled)'); + let reportLine = ` - ${type}: ${re.path}`; + if (re.humanReviewStatus) { + re.humanReviewStatus.fix && + (reportLine = appendWarningLine(reportLine, '^ this issue was marked as fixed earlier')); + re.humanReviewStatus.remind && + (reportLine = appendWarningLine(reportLine, '^ this issue was already postponed')); + } + if (re.isMajor) { + reportLine = appendWarningLine(reportLine, '! warning, fix is a major version upgrade'); + } + groups[re.id].push(reportLine); + + return groups; + }, {}); + let onlyLow = true; + Object.keys(groupedResolutions).forEach(reId => { + const adv = advisories[reId]; + if (adv.severity !== 'low') { + onlyLow = false + } + const severityTag = getSeverityTag(adv); + console.log(`${severityTag} ${adv.title}`); + console.log( + ` vulnerable versions ${adv.vulnerable_versions} found in:` + ); + console.log(groupedResolutions[reId].join('\n')); + }); + if (argv.ignoreLow && onlyLow) { + console.log(chalk.greenBright(` ✔ automatically ignore low severity issue`)) + return actions.takeAction('i', { action, advisories, command: null }); + } + + const command = [ + 'npm', + action.action, + action.module, + action.depth ? '--depth ' + action.depth : '' + ].join(' '); + + return optionsPrompt({ action, advisories, command }) + } +}; + +function optionsPrompt({ action, advisories, command }, availableChoices = null) { + const actionName = action.action; + + const choices = [ + { + key: 'd', + name: 'show more details and ask me again' + }, + { + key: 'r', + name: 'remind me in 24h' + }, + { + key: 'i', + name: 'ignore paths' + }, + { + key: 'del', + name: 'Remove all listed dependency paths' + }, + { + key: 's', + name: 'Skip this' + }, + { + key: 'q', + name: 'Quit' + } + ]; + + + if (['install', 'update'].includes(actionName)) { + choices.unshift({ + key: 'f', + name: 'fix with ' + chalk.greenBright(command) + }); + } else { + choices.unshift({ + key: '?', + name: chalk.blueBright('investigate') + }); + } + + availableChoices = ['q', 's'].concat(availableChoices || choices.map(c => c.key)) + + console.log('_'); + console.log( + choices + .filter(c => availableChoices.includes(c.key)) + .map(c => ` ${chalk.bold(c.key)}) ${c.name}`).join('\n') + ); + + return promptly.choose( + 'What would you like to do? ', + choices.map(c => c.key), + { trim: true, retry: true } + ).then(answer => { + return actions.takeAction(answer, { action, advisories, command }); + }) + .then(choices => { + if (choices !== undefined) { + return optionsPrompt({ action, advisories, command }, choices) + } + }) +} + +const colors = { + critical: chalk.bold.white.bgRedBright, + high: chalk.bold.redBright, + moderate: chalk.bold.yellow +} +function getSeverityTag(advisory) { + const color = colors[advisory.severity] || (a => a); + return color(`[ ${advisory.severity} ]`) +} + +function appendWarningLine(message, line) { + return message + '\n ' + chalk.bold(line); +} \ No newline at end of file diff --git a/node_modules/npm-audit-resolver/src/resolutionState.js b/node_modules/npm-audit-resolver/src/resolutionState.js new file mode 100644 index 0000000000000..276258b385a98 --- /dev/null +++ b/node_modules/npm-audit-resolver/src/resolutionState.js @@ -0,0 +1,41 @@ +const fs = require("fs"); + +var data = {}; + +const biuldKey = ({ id, path }) => `${id}|${path}`; + +function load() { + try { + const rawdata = fs.readFileSync("audit-resolv.json"); + data = JSON.parse(rawdata); + } catch (e) {} +} + +load(); + +module.exports = { + load, + flush() { + fs.writeFileSync("audit-resolv.json", JSON.stringify(data, null, 2)); + }, + set({ id, path }, value) { + path = pathCorruptionWorkaround(path) + return (data[biuldKey({ id, path })] = value); + }, + get({ id, path }) { + path = pathCorruptionWorkaround(path) + return data[biuldKey({ id, path })]; + } +}; + +const longRandomRegex = /^[a-z0-9]{64}$/ +function pathCorruptionWorkaround(path){ + const chunks = path.split('>') + return chunks.map(c=>{ + if(c.match(longRandomRegex)){ + return '00unidentified' + } else { + return c + } + }).join('>') +} diff --git a/node_modules/npm-audit-resolver/src/statusManager.js b/node_modules/npm-audit-resolver/src/statusManager.js new file mode 100644 index 0000000000000..642e0c971daad --- /dev/null +++ b/node_modules/npm-audit-resolver/src/statusManager.js @@ -0,0 +1,30 @@ +const resolutionState = require("./resolutionState"); + +function addResolution(action) { + action.state = resolutionState.get({}); + return action; +} + +module.exports = { + addStatus(action) { + let unresolved = false; + action.resolves.map(re => { + const status = resolutionState.get({ id: re.id, path: re.path }); + if(status){ + re.humanReviewStatus = status + if(status.remind && Date.now()>status.remind){ + unresolved = true + } + if(status.fix){ + // should have been fixed! + unresolved = true + } + } else { + unresolved = true + } + return re; + }); + action.humanReviewComplete = !unresolved + return action + } +}; diff --git a/node_modules/promptly/CHANGELOG.md b/node_modules/promptly/CHANGELOG.md new file mode 100755 index 0000000000000..7ed068ed87dfb --- /dev/null +++ b/node_modules/promptly/CHANGELOG.md @@ -0,0 +1,40 @@ +# Change Log + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + + +## [3.0.3](https://github.com/moxystudio/node-promptly/compare/v3.0.2...v3.0.3) (2018-01-17) + + +### Bug Fixes + +* add pify to package.json ([#20](https://github.com/moxystudio/node-promptly/issues/20)) ([b7a7c84](https://github.com/moxystudio/node-promptly/commit/b7a7c84)) + + + + +## [3.0.2](https://github.com/moxystudio/node-promptly/compare/v3.0.1...v3.0.2) (2018-01-15) + + + + +## [3.0.1](https://github.com/moxystudio/node-promptly/compare/v3.0.0...v3.0.1) (2018-01-15) + + + + +# [3.0.0](https://github.com/moxystudio/node-promptly/compare/2.2.0...3.0.0) (2018-01-15) + + +### Chores + +* update project to use new features present in node lts ([d3677d0](https://github.com/moxystudio/node-promptly/commit/d3677d0)) + + +### BREAKING CHANGES + +* remove support for old node versions (only latest lts or higher is supported) +* callback support has been removed +* ability to call error.retry has been removed +* built-in choice and confirm validators now run before any custom validators +* the default option value may only be undefined or a string from now on diff --git a/node_modules/promptly/LICENSE b/node_modules/promptly/LICENSE new file mode 100755 index 0000000000000..8407b9a30f51b --- /dev/null +++ b/node_modules/promptly/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Made With MOXY Lda + +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/node_modules/promptly/README.md b/node_modules/promptly/README.md new file mode 100755 index 0000000000000..3aceb2802a67f --- /dev/null +++ b/node_modules/promptly/README.md @@ -0,0 +1,184 @@ +# promptly + +[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coverage Status][codecov-image]][codecov-url] [![Dependency status][david-dm-image]][david-dm-url] [![Dev Dependency status][david-dm-dev-image]][david-dm-dev-url] [![Greenkeeper badge][greenkeeper-image]][greenkeeper-url] + +[npm-url]:https://npmjs.org/package/promptly +[downloads-image]:http://img.shields.io/npm/dm/promptly.svg +[npm-image]:http://img.shields.io/npm/v/promptly.svg +[travis-url]:https://travis-ci.org/moxystudio/node-promptly +[travis-image]:http://img.shields.io/travis/moxystudio/node-promptly/master.svg +[codecov-url]:https://codecov.io/gh/moxystudio/node-promptly +[codecov-image]:https://img.shields.io/codecov/c/github/moxystudio/node-promptly/master.svg +[david-dm-url]:https://david-dm.org/moxystudio/node-promptly +[david-dm-image]:https://img.shields.io/david/moxystudio/node-promptly.svg +[david-dm-dev-url]:https://david-dm.org/moxystudio/node-promptly?type=dev +[david-dm-dev-image]:https://img.shields.io/david/dev/moxystudio/node-promptly.svg +[greenkeeper-image]:https://badges.greenkeeper.io/moxystudio/node-promptly.svg +[greenkeeper-url]:https://greenkeeper.io/ + +Simple command line prompting utility. + + +## Installation + +`$ npm install promptly` + + +## API + +### .prompt(message, [options]) + +Prompts for a value, printing the `message` and waiting for the input. +Returns a promise that resolves with the input. + +Available options: + +| Name | Description | Type | Default | +| ------ | ------------- | -------- | ------- | +| default | The default value to use if the user provided an empty input | string | undefined | +| trim | Trims the user input | boolean | true | +| validator | A validator or an array of validators | function/array | undefined | +| retry | Retry if any of the validators fail | boolean | true | +| silent | Do not print what the user types | boolean | false | +| replace | Replace each character with the specified string when `silent` is true | string | '' | +| input | Input stream to read from | [Stream](https://nodejs.org/api/process.html#process_process_stdin) | process.stdin | +| output | Output stream to write to | [Stream](https://nodejs.org/api/process.html#process_process_stdout) | process.stdout | + +The same **options** are available to **all functions** but with different default values. + +#### Examples + +- Ask for a name: + + ```js + const name = await promptly.prompt('Name: '); + + console.log(name); + ``` + +- Ask for a name with a constraint (non-empty value and length > 2): + + ```js + const validator = function (value) { + if (value.length < 2) { + throw new Error('Min length of 2'); + } + + return value; + }; + + const name = await promptly.prompt('Name: ', { validator }); + + // Since retry is true by default, promptly will keep asking for a name until it is valid + // Between each prompt, the error message from the validator will be printed + console.log('Name is:', value); + ``` + +- Same as above but do not retry automatically: + + ```js + var validator = function (value) { + if (value.length < 2) { + throw new Error('Min length of 2'); + } + + return value; + }; + + try { + const name = await promptly.prompt('Name: ', { validator, retry: false }); + + console.log('Name is:', value); + } catch (err) { + console.error('Invalid name:') + console.error(`- ${err.message}`); + } + ``` + +#### Validators + +The validators have two purposes: to check and transform input. + +```js +(value) => { + // Validation example, throwing an error when invalid + if (value.length !== 2) { + throw new Error('Length must be 2'); + } + + // Parse the value, modifying it + return value.replace('aa', 'bb'); +} +``` + +### .confirm(message, [options]) + +Ask the user for confirmation, printing the `message` and waiting for the input. +Returns a promise that resolves with the answer. + +Truthy values are: `y`, `yes` and `1`. Falsy values are `n`, `no`, and `0`. +Comparison is made in a case insensitive way. + +The options are the same as [prompt](#promptmessage-options), except that `trim` defaults to `false`. + +#### Examples + +- Ask to confirm something important: + + ```js + const answer = await promptly.confirm('Are you really sure? '); + + console.log('Answer:', answer); + ``` + +### .choose(message, choices, [options]) + +Ask the user to choose between multiple `choices` (array of choices), printing the `message` and waiting for the input. +Returns a promise that resolves with the choice. + +The options are the same as [prompt](#promptmessage-options), except that `trim` defaults to `false`. + +#### Examples + +- Ask to choose between: + + ```js + const choice = await promptly.choose('Do you want an apple or an orange? ', ['apple', 'orange']); + + console.log('Choice:', choice); + ``` + +### .password(message, [options]) + +Prompts for a password, printing the `message` and waiting for the input. +Returns a promise that resolves with the password. + +The options are the same as [prompt](#promptmessage-options), except that `trim` and `silent` default to `false` and `default` is an empty string (to allow empty passwords). + +#### Examples + +- Ask for a password: + + ```js + const password = await promptly.password('Type a password: '); + + console.log('Password:', password); + ``` + +- Ask for a password but mask the input with `*`: + + ```js + const password = await promptly.password('Type a password: ', { replace: '*' }); + + console.log('Password:', password); + ``` + +## Tests + +`$ npm test` +`$ npm test -- --watch` during development + + +## License + +Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). diff --git a/node_modules/promptly/index.js b/node_modules/promptly/index.js new file mode 100755 index 0000000000000..93dcc0427d7ec --- /dev/null +++ b/node_modules/promptly/index.js @@ -0,0 +1,72 @@ +'use strict'; + +const prompt = require('./lib/prompt'); +const getOptions = require('./lib/getOptions'); + +const promptly = module.exports; + +promptly.prompt = (message, options) => { + options = getOptions(options); + + return prompt(message, options); +}; + +promptly.password = (message, options) => { + options = getOptions({ + silent: true, // Hide password chars + trim: false, // Do not trim so that spaces can be part of the password + default: '', // Allow empty passwords + ...options, + }); + + return prompt(message, options); +}; + +promptly.confirm = (message, options) => { + options = getOptions({ + trim: false, // Do not trim so that only exact matches pass the validator + ...options, + }); + + // Unshift the validator that will coerse boolean values + options.validator.unshift((value) => { + value = value.toLowerCase(); + + switch (value) { + case 'y': + case 'yes': + case '1': + return true; + case 'n': + case 'no': + case '0': + return false; + default: + throw new Error(`Invalid choice: ${value}`); + } + }); + + return prompt(message, options); +}; + +promptly.choose = (message, choices, options) => { + options = getOptions({ + trim: false, // Do not trim so that only exact matches pass the validator + ...options, + }); + + // Unshift the validator that will validate the data against the choices + options.validator.unshift((value) => { + // Check if the value exists by comparing values loosely + // Additionally, use the coorced value + const index = choices.findIndex((choice) => value == choice); // eslint-disable-line eqeqeq + + if (index === -1) { + throw new Error(`Invalid choice: ${value}`); + } + + return choices[index]; + }); + + return prompt(message, options); +}; diff --git a/node_modules/promptly/lib/getOptions.js b/node_modules/promptly/lib/getOptions.js new file mode 100755 index 0000000000000..1a9a51ad21df9 --- /dev/null +++ b/node_modules/promptly/lib/getOptions.js @@ -0,0 +1,33 @@ +'use strict'; + +function getOptions(options) { + options = { + // Own options + validator: undefined, + retry: true, + trim: true, + default: undefined, + + // `read` package options + silent: false, + replace: '', + input: process.stdin, + output: process.stdout, + + ...options, + }; + + // Validate that default is a string + if (options.default !== undefined && typeof options.default !== 'string') { + throw new Error('The default option value must be a string'); + } + + // Normalize validator to an array + if (!Array.isArray(options.validator)) { + options.validator = options.validator ? [options.validator] : []; + } + + return options; +} + +module.exports = getOptions; diff --git a/node_modules/promptly/lib/prompt.js b/node_modules/promptly/lib/prompt.js new file mode 100755 index 0000000000000..791af00412e7e --- /dev/null +++ b/node_modules/promptly/lib/prompt.js @@ -0,0 +1,48 @@ +'use strict'; + +const { EOL } = require('os'); +const pify = require('pify'); +const read = pify(require('read')); + +async function prompt(message, options) { + // Read input + let value = await read({ + prompt: message, + silent: options.silent, + replace: options.replace, + input: options.input, + output: options.output, + }); + + // Trim? + if (options.trim) { + value = value.trim(); + } + + // Prompt again if there's no data or use the default value + if (!value) { + if (options.default === undefined) { + return prompt(message, options); + } + + value = options.default; + } + + // Validator verification + try { + value = options.validator.reduce((value, validator) => validator(value), value); + } catch (err) { + // Retry automatically if the retry option is enabled + if (options.retry) { + err.message && options.output.write(err.message + EOL); + + return prompt(message, options); + } + + throw err; + } + + return value; +} + +module.exports = prompt; diff --git a/node_modules/promptly/package.json b/node_modules/promptly/package.json new file mode 100755 index 0000000000000..70e8e7d1d4d11 --- /dev/null +++ b/node_modules/promptly/package.json @@ -0,0 +1,94 @@ +{ + "_from": "promptly@^3.0.3", + "_id": "promptly@3.0.3", + "_inBundle": false, + "_integrity": "sha512-EWnzOsxVKUjqKeE6SStH1/cO4+DE44QolaoJ4ojGd9z6pcNkpgfJKr1ncwxrOFHSTIzoudo7jG8y0re30/LO1g==", + "_location": "/promptly", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "promptly@^3.0.3", + "name": "promptly", + "escapedName": "promptly", + "rawSpec": "^3.0.3", + "saveSpec": null, + "fetchSpec": "^3.0.3" + }, + "_requiredBy": [ + "/npm-audit-resolver" + ], + "_resolved": "https://registry.npmjs.org/promptly/-/promptly-3.0.3.tgz", + "_shasum": "e178f722e73d82c60d019462044bccfdd9872f42", + "_spec": "promptly@^3.0.3", + "_where": "/storage/projects/github/npm/node_modules/npm-audit-resolver", + "author": { + "name": "André Cruz", + "email": "andre@moxy.studio" + }, + "bugs": { + "url": "https://github.com/moxystudio/node-promptly/issues" + }, + "bundleDependencies": false, + "commitlint": { + "extends": [ + "@commitlint/config-conventional" + ] + }, + "dependencies": { + "pify": "^3.0.0", + "read": "^1.0.4" + }, + "deprecated": false, + "description": "Simple command line prompting utility", + "devDependencies": { + "@commitlint/cli": "^6.0.0", + "@commitlint/config-conventional": "^6.0.2", + "eslint": "^4.3.0", + "eslint-config-moxy": "^4.1.0", + "husky": "^0.14.3", + "jest": "^22.0.0", + "lint-staged": "^6.0.0", + "p-series": "^1.0.0", + "standard-version": "^4.2.0" + }, + "files": [ + "lib" + ], + "homepage": "https://github.com/moxystudio/node-promptly", + "keywords": [ + "prompt", + "choose", + "choice", + "cli", + "command", + "line" + ], + "license": "MIT", + "lint-staged": { + "*.js": [ + "eslint --fix", + "git add" + ] + }, + "main": "index.js", + "name": "promptly", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/moxystudio/node-promptly.git" + }, + "scripts": { + "commitmsg": "commitlint -e $GIT_PARAMS", + "lint": "eslint .", + "precommit": "lint-staged", + "prerelease": "npm t && npm run lint", + "release": "standard-version", + "test": "jest --env node --coverage" + }, + "standard-version": { + "scripts": { + "posttag": "git push --follow-tags origin master && npm publish" + } + }, + "version": "3.0.3" +} diff --git a/node_modules/spawn-shell/index.js b/node_modules/spawn-shell/index.js new file mode 100755 index 0000000000000..0a8bae7e7eae5 --- /dev/null +++ b/node_modules/spawn-shell/index.js @@ -0,0 +1,54 @@ +'use strict'; + +const childProcess = require('child_process'); +const defaultShell = require('default-shell'); +const merge = require('merge-options'); +const npmRunPath = require('npm-run-path'); + +const spawn = childProcess.spawn; + +const defaultOptions = { + env: {}, + stdio: [0, 1, 2], + windowsVerbatimArguments: process.platform === 'win32' +}; + +module.exports = spawnShell; + +function shellFlags() { + if (process.platform === 'win32') { + return ['/d', '/s', '/c']; + } + return ['-c']; +} + +function resolveOnProcessExit(p) { + return new Promise((resolve, reject) => { + let fullFilled = false; + p.on('error', err => { + fullFilled = true; + reject(err); + }); + + p.on('exit', exitCode => { + if (!fullFilled) { + resolve(exitCode); + } + }); + }); +} + +function spawnShell(command, options) { + const opts = merge({}, defaultOptions, options); + const shell = opts.shell || defaultShell; + delete opts.shell; + + opts.env.PATH = npmRunPath({path: opts.env.PATH}); + const p = spawn( + shell, + shellFlags().concat(command), + opts + ); + p.exitPromise = resolveOnProcessExit(p); + return p; +} diff --git a/node_modules/spawn-shell/license b/node_modules/spawn-shell/license new file mode 100644 index 0000000000000..16fa291a36349 --- /dev/null +++ b/node_modules/spawn-shell/license @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2017 parro-it + +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/node_modules/spawn-shell/package.json b/node_modules/spawn-shell/package.json new file mode 100644 index 0000000000000..29ff8ba9ee77b --- /dev/null +++ b/node_modules/spawn-shell/package.json @@ -0,0 +1,69 @@ +{ + "_from": "spawn-shell@^2.0.1", + "_id": "spawn-shell@2.0.1", + "_inBundle": false, + "_integrity": "sha512-EYo5KSZYxTYzwGgughD9prtzk3kMJB6hpVhiAxmZPvUHLi8KWQHz/46LDydXsXwdSldgniNVtd1Ccia0Og3TfA==", + "_location": "/spawn-shell", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "spawn-shell@^2.0.1", + "name": "spawn-shell", + "escapedName": "spawn-shell", + "rawSpec": "^2.0.1", + "saveSpec": null, + "fetchSpec": "^2.0.1" + }, + "_requiredBy": [ + "/npm-audit-resolver" + ], + "_resolved": "https://registry.npmjs.org/spawn-shell/-/spawn-shell-2.0.1.tgz", + "_shasum": "36b6fa0d420ec3d07a87730ef362478e47cba047", + "_spec": "spawn-shell@^2.0.1", + "_where": "/storage/projects/github/npm/node_modules/npm-audit-resolver", + "author": { + "name": "Andrea Parodi", + "email": "andrea@parro.it" + }, + "bugs": { + "url": "https://github.com/parro-it/spawn-shell/issues" + }, + "bundleDependencies": false, + "dependencies": { + "default-shell": "^1.0.0", + "merge-options": "1.0.0", + "npm-run-path": "^2.0.2" + }, + "deprecated": false, + "description": "Run shell commands using child_process#spawn.", + "devDependencies": { + "ava": "^0.20.0", + "stream-string": "^2.0.0", + "xo": "^0.19.0" + }, + "engines": { + "node": ">=6" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/parro-it/spawn-shell#readme", + "keywords": [ + "spawn", + "shell", + "sh", + "bash", + "multiplatform" + ], + "license": "MIT", + "name": "spawn-shell", + "repository": { + "type": "git", + "url": "git+https://github.com/parro-it/spawn-shell.git" + }, + "scripts": { + "test": "ava && xo" + }, + "version": "2.0.1" +} diff --git a/node_modules/spawn-shell/readme.md b/node_modules/spawn-shell/readme.md new file mode 100644 index 0000000000000..174e00517896a --- /dev/null +++ b/node_modules/spawn-shell/readme.md @@ -0,0 +1,54 @@ +# spawn-shell + +[![Greenkeeper badge](https://badges.greenkeeper.io/parro-it/spawn-shell.svg)](https://greenkeeper.io/) +[![Travis Build Status](https://img.shields.io/travis/parro-it/spawn-shell/master.svg)](http://travis-ci.org/parro-it/spawn-shell) +[![NPM module](https://img.shields.io/npm/v/spawn-shell.svg)](https://npmjs.org/package/spawn-shell) +[![NPM downloads](https://img.shields.io/npm/dt/spawn-shell.svg)](https://npmjs.org/package/spawn-shell) + +> Run shell commands using child_process#spawn. + +# Features + +* Multi-platform - run on OSX, Linux, Windows +* Return a promise that resolve with exitcode when spawned process terminetes +* Use `child_process#spawn` for greater flexibility than `child_process#exec` +* Use user system shell by default, or customize it via `shell` option. +* Inject your package `node_modules/.bin` directory in path. +* `stdio` spawn option defaults to `inherit`, sharing parent process stdin & stdout + +# Installation + +```bash +npm install --save spawn-shell +``` + +# Usage + +```javascript + const spawnShell = require('spawn-shell'); + + // simple to use with promise + const exitCode = await spawnShell('echo "it works" && exit 42').exitPromise; + // output `it works` to stdout + // exitCode === 42 + + + // access ChildProcess instance before promise is resolved + const p = spawnShell('echo "it works"', { + stdio: [0, 'pipe', 2] + }); + + p.stdout.pipe(concat( + {encoding: 'string'}, + output => { + // output === 'it works' + } + )); + +``` + +# License + +The MIT License (MIT) + +Copyright (c) 2017 parro-it diff --git a/package-lock.json b/package-lock.json index 88964ec8b05b4..99dd1ab20f6af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -846,6 +846,11 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "default-shell": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/default-shell/-/default-shell-1.0.1.tgz", + "integrity": "sha1-dSMEvdxhdPSespy5iP7qC4gTyLw=" + }, "defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", @@ -1534,6 +1539,11 @@ "write": "^0.2.1" } }, + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=" + }, "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", @@ -2168,6 +2178,11 @@ "path-is-inside": "^1.0.1" } }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -2634,6 +2649,14 @@ "mimic-fn": "^1.0.0" } }, + "merge-options": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-1.0.0.tgz", + "integrity": "sha1-W08zmpVxkrW5iZSjrFyV0splG5Q=", + "requires": { + "is-plain-obj": "^1.1" + } + }, "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", @@ -2867,6 +2890,30 @@ "console-control-strings": "^1.1.0" } }, + "npm-audit-resolver": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/npm-audit-resolver/-/npm-audit-resolver-1.2.0.tgz", + "integrity": "sha512-o4KZUrHRiIqbI8HbBiaGJUwKFExwkotElQ6U5lQySzrbA6B7SdGDDa7Cd/ASSu3WRMmFvzEsFzh3SsK49VunxA==", + "requires": { + "chalk": "^2.4.1", + "concat-stream": "^1.6.2", + "flatten": "^1.0.2", + "promptly": "^3.0.3", + "semver": "^5.5.0", + "spawn-shell": "^2.0.1", + "yargs-parser": "^10.0.0" + }, + "dependencies": { + "yargs-parser": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.0.0.tgz", + "integrity": "sha512-+DHejWujTVYeMHLff8U96rLc4uE4Emncoftvn5AjhB1Jw1pWxLzgBUT/WYbPrHmy6YPEBTZQx5myHhVcuuu64g==", + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, "npm-bundled": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz", @@ -6205,6 +6252,15 @@ } } }, + "promptly": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/promptly/-/promptly-3.0.3.tgz", + "integrity": "sha512-EWnzOsxVKUjqKeE6SStH1/cO4+DE44QolaoJ4ojGd9z6pcNkpgfJKr1ncwxrOFHSTIzoudo7jG8y0re30/LO1g==", + "requires": { + "pify": "^3.0.0", + "read": "^1.0.4" + } + }, "promzard": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz", @@ -6759,6 +6815,16 @@ "source-map": "^0.6.0" } }, + "spawn-shell": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/spawn-shell/-/spawn-shell-2.0.1.tgz", + "integrity": "sha512-EYo5KSZYxTYzwGgughD9prtzk3kMJB6hpVhiAxmZPvUHLi8KWQHz/46LDydXsXwdSldgniNVtd1Ccia0Og3TfA==", + "requires": { + "default-shell": "^1.0.0", + "merge-options": "1.0.0", + "npm-run-path": "^2.0.2" + } + }, "spdx-correct": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", diff --git a/package.json b/package.json index 0a1404357e718..1d65ab456fd20 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "nopt": "~4.0.1", "normalize-package-data": "~2.4.0", "npm-audit-report": "^1.2.1", + "npm-audit-resolver": "^1.2.0", "npm-cache-filename": "~1.0.2", "npm-install-checks": "~3.0.0", "npm-lifecycle": "^2.0.3", @@ -205,6 +206,7 @@ "nopt", "normalize-package-data", "npm-audit-report", + "npm-audit-resolver", "npm-cache-filename", "npm-lifecycle", "npm-install-checks", From a72795df235de86e68be9ca2b7c4bb0963fd8f70 Mon Sep 17 00:00:00 2001 From: Naugtur Date: Wed, 20 Jun 2018 21:27:59 +0200 Subject: [PATCH 2/3] add audit-resolv.json support to audit command, pass on npm.prefix to resolver --- doc/cli/npm-audit.md | 1 + lib/audit.js | 5 +++-- lib/install/audit.js | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/cli/npm-audit.md b/doc/cli/npm-audit.md index 3bb13259d7746..0daa236fc9a5d 100644 --- a/doc/cli/npm-audit.md +++ b/doc/cli/npm-audit.md @@ -5,6 +5,7 @@ npm-audit(1) -- Run a security audit npm audit [--json] npm audit fix [--force|--package-lock-only|--dry-run|--production|--only=dev] + npm audit resolve ## EXAMPLES diff --git a/lib/audit.js b/lib/audit.js index 3bfd22c84cb2b..ab0f7c2bc7e66 100644 --- a/lib/audit.js +++ b/lib/audit.js @@ -259,8 +259,9 @@ function auditCmd (args, cb) { }) } else if (args[0] === 'resolve') { output(`Total of ${auditResult.actions.length} actions to process`) - return auditResolver.resolveAudit(auditResult) - .then(() => output('done.')) + return auditResolver.resolveAudit(auditResult, { + prefix: npm.prefix + }).then(() => output('done.')) } else { const vulns = auditResult.metadata.vulnerabilities.low + diff --git a/lib/install/audit.js b/lib/install/audit.js index 4be59ca7c5e26..09bca5940c0f2 100644 --- a/lib/install/audit.js +++ b/lib/install/audit.js @@ -8,6 +8,7 @@ exports.printFullReport = printFullReport const Bluebird = require('bluebird') const auditReport = require('npm-audit-report') +const auditResolver = require('npm-audit-resolver') const treeToShrinkwrap = require('../shrinkwrap.js').treeToShrinkwrap const packageId = require('../utils/package-id.js') const output = require('../utils/output.js') @@ -104,6 +105,9 @@ function printInstallReport (auditResult) { } function printFullReport (auditResult) { + auditResult = auditResolver.skipResolvedActions(auditResult, { + prefix: npm.prefix + }) return auditReport(auditResult, { log: output, reporter: npm.config.get('json') ? 'json' : 'detail', @@ -234,6 +238,7 @@ function generateMetadata () { return readFile(path.resolve(npm.prefix, '.git', headFile), 'utf8') }).then((commitHash) => { meta.commit_hash = commitHash.trim() + //hint: this should be inside promise constructor, so if it throws, promise is rejected const proc = spawn('git', qw`diff --quiet --exit-code package.json package-lock.json`, {cwd: npm.prefix, stdio: 'ignore'}) return new Promise((resolve, reject) => { proc.once('error', reject) From f67dd207886da7d195cd1deef48859b1e13a8cf3 Mon Sep 17 00:00:00 2001 From: Naugtur Date: Thu, 21 Jun 2018 01:03:50 +0200 Subject: [PATCH 3/3] latest audit resolver, updated dependencies --- node_modules/flatten/LICENSE | 21 -- node_modules/flatten/README.md | 34 ---- node_modules/flatten/index.js | 23 --- node_modules/flatten/package.json | 54 ----- node_modules/flatten/test.js | 25 --- node_modules/npm-audit-resolver/index.js | 21 +- node_modules/npm-audit-resolver/package.json | 25 ++- .../npm-audit-resolver/src/arguments.js | 10 +- .../npm-audit-resolver/src/micro-promptly.js | 30 +++ .../npm-audit-resolver/src/npmfacade.js | 3 +- .../npm-audit-resolver/src/prompter.js | 16 +- .../npm-audit-resolver/src/resolutionState.js | 45 +++-- .../npm-audit-resolver/src/statusManager.js | 6 +- node_modules/promptly/CHANGELOG.md | 40 ---- node_modules/promptly/LICENSE | 21 -- node_modules/promptly/README.md | 184 ------------------ node_modules/promptly/index.js | 72 ------- node_modules/promptly/lib/getOptions.js | 33 ---- node_modules/promptly/lib/prompt.js | 48 ----- node_modules/promptly/package.json | 94 --------- package-lock.json | 23 +-- package.json | 2 +- 22 files changed, 110 insertions(+), 720 deletions(-) delete mode 100644 node_modules/flatten/LICENSE delete mode 100644 node_modules/flatten/README.md delete mode 100644 node_modules/flatten/index.js delete mode 100644 node_modules/flatten/package.json delete mode 100644 node_modules/flatten/test.js create mode 100644 node_modules/npm-audit-resolver/src/micro-promptly.js delete mode 100755 node_modules/promptly/CHANGELOG.md delete mode 100755 node_modules/promptly/LICENSE delete mode 100755 node_modules/promptly/README.md delete mode 100755 node_modules/promptly/index.js delete mode 100755 node_modules/promptly/lib/getOptions.js delete mode 100755 node_modules/promptly/lib/prompt.js delete mode 100755 node_modules/promptly/package.json diff --git a/node_modules/flatten/LICENSE b/node_modules/flatten/LICENSE deleted file mode 100644 index 54a689b800f4a..0000000000000 --- a/node_modules/flatten/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Joshua Holbrook - -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/node_modules/flatten/README.md b/node_modules/flatten/README.md deleted file mode 100644 index 7b0a3b69063b1..0000000000000 --- a/node_modules/flatten/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# flatten - -A tiny utility to flatten arrays of arrays (of arrays, etc., recursively, infinitely or to an optional depth) into a single array of non-arrays. - -## example: - -```js -> var flatten = require('flatten'); -undefined -> flatten([1, [2, 3], [4, 5, 6], [7, [8, 9]], 10]) -[ 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10 ] -> flatten([1, [2, [3, [4, [5]]]]], 2) -[ 1, - 2, - 3, - [ 4, [ 5 ] ] ] -``` - -## install: - - npm install flatten - -## license: - -MIT/X11. diff --git a/node_modules/flatten/index.js b/node_modules/flatten/index.js deleted file mode 100644 index a9bd9b8c47c42..0000000000000 --- a/node_modules/flatten/index.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = function flatten(list, depth) { - depth = (typeof depth == 'number') ? depth : Infinity; - - if (!depth) { - if (Array.isArray(list)) { - return list.map(function(i) { return i; }); - } - return list; - } - - return _flatten(list, 1); - - function _flatten(list, d) { - return list.reduce(function (acc, item) { - if (Array.isArray(item) && d < depth) { - return acc.concat(_flatten(item, d + 1)); - } - else { - return acc.concat(item); - } - }, []); - } -}; diff --git a/node_modules/flatten/package.json b/node_modules/flatten/package.json deleted file mode 100644 index 5f16affa3db24..0000000000000 --- a/node_modules/flatten/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "_from": "flatten@^1.0.2", - "_id": "flatten@1.0.2", - "_inBundle": false, - "_integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", - "_location": "/flatten", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "flatten@^1.0.2", - "name": "flatten", - "escapedName": "flatten", - "rawSpec": "^1.0.2", - "saveSpec": null, - "fetchSpec": "^1.0.2" - }, - "_requiredBy": [ - "/npm-audit-resolver" - ], - "_resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", - "_shasum": "dae46a9d78fbe25292258cc1e780a41d95c03782", - "_spec": "flatten@^1.0.2", - "_where": "/storage/projects/github/npm/node_modules/npm-audit-resolver", - "author": { - "name": "Joshua Holbrook", - "email": "josh.holbrook@gmail.com", - "url": "http://jesusabdullah.net" - }, - "bugs": { - "url": "https://github.com/jesusabdullah/node-flatten/issues" - }, - "bundleDependencies": false, - "dependencies": {}, - "deprecated": false, - "description": "Flatten arbitrarily nested arrays into a non-nested list of non-array items", - "devDependencies": {}, - "engines": { - "node": "*" - }, - "homepage": "https://github.com/jesusabdullah/node-flatten#readme", - "license": "MIT", - "main": "./index.js", - "name": "flatten", - "optionalDependencies": {}, - "repository": { - "type": "git", - "url": "git://github.com/jesusabdullah/node-flatten.git" - }, - "scripts": { - "test": "node ./test.js" - }, - "version": "1.0.2" -} diff --git a/node_modules/flatten/test.js b/node_modules/flatten/test.js deleted file mode 100644 index 385c27faacc76..0000000000000 --- a/node_modules/flatten/test.js +++ /dev/null @@ -1,25 +0,0 @@ -var flatten = require('./index'), - util = require('util'), - assert = require('assert'); - -[ - [ [1, [ 2, 3]], [1, [2, 3]], 0], - [ [1, 2, 3 ], [1, 2, 3] ], - [ ['a', ['b', ['c']]], ['a', 'b', 'c'] ], - [ [2, [4, 6], 8, [[10]]], [2, 4, 6, 8, 10] ], - [ [1, [2, [3, [4, [5]]]]], [1, 2, 3, [4, [5]]], 2 ] // depth of 2 -].forEach(function (t) { - assert.deepEqual(flatten(t[0], t[2]), t[1], - util.format('☠☠☠☠☠☠☠☠☠ %s ☠☠☠☠☠☠☠☠☠', formatCall(t)) - ); - console.log('✓ %s', formatCall(t)); -}); - -function formatCall(t) { - if (typeof t[2] === 'undefined') { - return util.format('`flatten(%j) == %j`', t[0], t[1]); - } - else { - return util.format('`flatten(%j, %j) == %j`', t[0], t[2], t[1]); - } -} diff --git a/node_modules/npm-audit-resolver/index.js b/node_modules/npm-audit-resolver/index.js index e0d8605172071..2ab2ab82bd870 100644 --- a/node_modules/npm-audit-resolver/index.js +++ b/node_modules/npm-audit-resolver/index.js @@ -1,9 +1,11 @@ #!/usr/bin/env node const prompter = require('./src/prompter'); const statusManager = require('./src/statusManager'); +const argv = require('./src/arguments') module.exports = { - resolveAudit(input) { + resolveAudit(input, args) { + argv.set(args) return input.actions .map(statusManager.addStatus) .filter(a => { @@ -20,7 +22,22 @@ module.exports = { Promise.resolve() ) }, - checkAudit(input){ + skipResolvedActions(input, args) { + argv.set(args) + input.actions = input.actions + .map(statusManager.addStatus) + .filter(a => { + if (a.humanReviewComplete) { + console.error( + `skipping ${a.module} issue based on audit-resolv.json` + ); + } + return !a.humanReviewComplete; + }) + return input + }, + checkAudit(input, args) { + argv.set(args) return input.actions .map(statusManager.addStatus) .filter(a => { diff --git a/node_modules/npm-audit-resolver/package.json b/node_modules/npm-audit-resolver/package.json index 8e8151c308c2e..b7e66de617c11 100644 --- a/node_modules/npm-audit-resolver/package.json +++ b/node_modules/npm-audit-resolver/package.json @@ -1,29 +1,29 @@ { - "_from": "npm-audit-resolver", - "_id": "npm-audit-resolver@1.2.0", + "_from": "npm-audit-resolver@^1.3.1", + "_id": "npm-audit-resolver@1.3.1", "_inBundle": false, - "_integrity": "sha512-o4KZUrHRiIqbI8HbBiaGJUwKFExwkotElQ6U5lQySzrbA6B7SdGDDa7Cd/ASSu3WRMmFvzEsFzh3SsK49VunxA==", + "_integrity": "sha512-EvBZ5SFXsckdwbSc8TsijR0jHHTxeTFkvudufHnKjrWn7GZKlCtKYVx2zLHUI2GG1y/hl5Iaog1PA1Mas7ehEA==", "_location": "/npm-audit-resolver", "_phantomChildren": { "camelcase": "4.1.0" }, "_requested": { - "type": "tag", + "type": "range", "registry": true, - "raw": "npm-audit-resolver", + "raw": "npm-audit-resolver@^1.3.1", "name": "npm-audit-resolver", "escapedName": "npm-audit-resolver", - "rawSpec": "", + "rawSpec": "^1.3.1", "saveSpec": null, - "fetchSpec": "latest" + "fetchSpec": "^1.3.1" }, "_requiredBy": [ "#USER", "/" ], - "_resolved": "https://registry.npmjs.org/npm-audit-resolver/-/npm-audit-resolver-1.2.0.tgz", - "_shasum": "49b6b44abc55fe32ea4a5dc18d1904d33bc1a1da", - "_spec": "npm-audit-resolver", + "_resolved": "https://registry.npmjs.org/npm-audit-resolver/-/npm-audit-resolver-1.3.1.tgz", + "_shasum": "1bc8e2a1708de247efb595e15beee80682de6a28", + "_spec": "npm-audit-resolver@^1.3.1", "_where": "/storage/projects/github/npm", "author": { "name": "naugtur", @@ -37,8 +37,7 @@ "dependencies": { "chalk": "^2.4.1", "concat-stream": "^1.6.2", - "flatten": "^1.0.2", - "promptly": "^3.0.3", + "read": "^1.0.7", "semver": "^5.5.0", "spawn-shell": "^2.0.1", "yargs-parser": "^10.0.0" @@ -64,5 +63,5 @@ "test": "npm run add-vulns && npm run test-exec && npm run rm-vulns", "test-exec": "node resolve.js && node check.js" }, - "version": "1.2.0" + "version": "1.3.1" } diff --git a/node_modules/npm-audit-resolver/src/arguments.js b/node_modules/npm-audit-resolver/src/arguments.js index 2df40cc4996bc..623ab50fc1b25 100644 --- a/node_modules/npm-audit-resolver/src/arguments.js +++ b/node_modules/npm-audit-resolver/src/arguments.js @@ -1,2 +1,8 @@ -const argv = require('yargs-parser')(process.argv.slice(2)); -module.exports = argv \ No newline at end of file +var argv = require('yargs-parser')(process.argv.slice(2)); + +module.exports = { + get: () => argv, + set: a => { + if (a) { argv = a } + } +} \ No newline at end of file diff --git a/node_modules/npm-audit-resolver/src/micro-promptly.js b/node_modules/npm-audit-resolver/src/micro-promptly.js new file mode 100644 index 0000000000000..11a1a4491d40e --- /dev/null +++ b/node_modules/npm-audit-resolver/src/micro-promptly.js @@ -0,0 +1,30 @@ +// I wanted to use promptly, but it uses {...options} syntax, so it wouldn't work in node6 +// This implements the API subset I use +const read = require('read') + +function validate(choices, resp) { + if (choices.indexOf(resp) > -1) { + return resp + } +} + +function choose(text, choices, options) { + return new Promise((resolve, reject) => { + read({ + prompt: text + }, (err, resp) => { + if (err) { + return reject(err) + } + const cleanResult = validate(choices, (options.trim ? resp.trim() : resp)) + if (!cleanResult && options.retry) { + return choose(text, choices, options).then(resolve, reject) + } + resolve(cleanResult) + }) + }) +} + +module.exports = { + choose +} \ No newline at end of file diff --git a/node_modules/npm-audit-resolver/src/npmfacade.js b/node_modules/npm-audit-resolver/src/npmfacade.js index 970a568a19b63..b01fb1c901ce5 100644 --- a/node_modules/npm-audit-resolver/src/npmfacade.js +++ b/node_modules/npm-audit-resolver/src/npmfacade.js @@ -1,8 +1,7 @@ const fs = require('fs'); const promiseCommand = require('./promiseCommand'); -const argv = require('./arguments') +const argv = require('./arguments').get() -let seq = 0; const runner = argv.mock ? (command) => { console.log('>>>mock ', command) diff --git a/node_modules/npm-audit-resolver/src/prompter.js b/node_modules/npm-audit-resolver/src/prompter.js index edeeb7fd3128c..17b201a92b132 100644 --- a/node_modules/npm-audit-resolver/src/prompter.js +++ b/node_modules/npm-audit-resolver/src/prompter.js @@ -1,8 +1,9 @@ -const promptly = require('promptly'); +const promptly = require('./micro-promptly'); const actions = require('./actions'); const chalk = require('chalk') const argv = require('./arguments') + module.exports = { handleAction(action, advisories) { console.log(`\n--------------------------------------------------`); @@ -39,7 +40,7 @@ module.exports = { ); console.log(groupedResolutions[reId].join('\n')); }); - if (argv.ignoreLow && onlyLow) { + if (argv.get().ignoreLow && onlyLow) { console.log(chalk.greenBright(` ✔ automatically ignore low severity issue`)) return actions.takeAction('i', { action, advisories, command: null }); } @@ -111,12 +112,11 @@ function optionsPrompt({ action, advisories, command }, availableChoices = null) 'What would you like to do? ', choices.map(c => c.key), { trim: true, retry: true } - ).then(answer => { - return actions.takeAction(answer, { action, advisories, command }); - }) - .then(choices => { - if (choices !== undefined) { - return optionsPrompt({ action, advisories, command }, choices) + ) + .then(answer => actions.takeAction(answer, { action, advisories, command })) + .then(choicesAvailableNow => { + if (choicesAvailableNow !== undefined) { + return optionsPrompt({ action, advisories, command }, choicesAvailableNow) } }) } diff --git a/node_modules/npm-audit-resolver/src/resolutionState.js b/node_modules/npm-audit-resolver/src/resolutionState.js index 276258b385a98..b399591e18408 100644 --- a/node_modules/npm-audit-resolver/src/resolutionState.js +++ b/node_modules/npm-audit-resolver/src/resolutionState.js @@ -1,41 +1,48 @@ -const fs = require("fs"); +const fs = require('fs'); +const path = require('path'); +const argv = require('./arguments') -var data = {}; +var data = null; const biuldKey = ({ id, path }) => `${id}|${path}`; +const filePath = () => path.resolve(argv.get().prefix || '.', 'audit-resolv.json') function load() { + if (data) { + return + } + data = {} //in case loading fails, have something valid to extend and save try { - const rawdata = fs.readFileSync("audit-resolv.json"); + const rawdata = fs.readFileSync(filePath()); data = JSON.parse(rawdata); - } catch (e) {} + } catch (e) { } } -load(); +const longRandomRegex = /^[a-z0-9]{64}$/ +function pathCorruptionWorkaround(depPath) { + const chunks = depPath.split('>') + return chunks.map(c => { + if (c.match(longRandomRegex)) { + return '00unidentified' + } else { + return c + } + }).join('>') +} module.exports = { load, flush() { - fs.writeFileSync("audit-resolv.json", JSON.stringify(data, null, 2)); + fs.writeFileSync(filePath(), JSON.stringify(data, null, 2)); }, set({ id, path }, value) { + load() path = pathCorruptionWorkaround(path) return (data[biuldKey({ id, path })] = value); }, get({ id, path }) { + load() path = pathCorruptionWorkaround(path) return data[biuldKey({ id, path })]; } -}; - -const longRandomRegex = /^[a-z0-9]{64}$/ -function pathCorruptionWorkaround(path){ - const chunks = path.split('>') - return chunks.map(c=>{ - if(c.match(longRandomRegex)){ - return '00unidentified' - } else { - return c - } - }).join('>') -} +}; \ No newline at end of file diff --git a/node_modules/npm-audit-resolver/src/statusManager.js b/node_modules/npm-audit-resolver/src/statusManager.js index 642e0c971daad..2520d0180e955 100644 --- a/node_modules/npm-audit-resolver/src/statusManager.js +++ b/node_modules/npm-audit-resolver/src/statusManager.js @@ -1,9 +1,5 @@ -const resolutionState = require("./resolutionState"); +const resolutionState = require('./resolutionState'); -function addResolution(action) { - action.state = resolutionState.get({}); - return action; -} module.exports = { addStatus(action) { diff --git a/node_modules/promptly/CHANGELOG.md b/node_modules/promptly/CHANGELOG.md deleted file mode 100755 index 7ed068ed87dfb..0000000000000 --- a/node_modules/promptly/CHANGELOG.md +++ /dev/null @@ -1,40 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. - - -## [3.0.3](https://github.com/moxystudio/node-promptly/compare/v3.0.2...v3.0.3) (2018-01-17) - - -### Bug Fixes - -* add pify to package.json ([#20](https://github.com/moxystudio/node-promptly/issues/20)) ([b7a7c84](https://github.com/moxystudio/node-promptly/commit/b7a7c84)) - - - - -## [3.0.2](https://github.com/moxystudio/node-promptly/compare/v3.0.1...v3.0.2) (2018-01-15) - - - - -## [3.0.1](https://github.com/moxystudio/node-promptly/compare/v3.0.0...v3.0.1) (2018-01-15) - - - - -# [3.0.0](https://github.com/moxystudio/node-promptly/compare/2.2.0...3.0.0) (2018-01-15) - - -### Chores - -* update project to use new features present in node lts ([d3677d0](https://github.com/moxystudio/node-promptly/commit/d3677d0)) - - -### BREAKING CHANGES - -* remove support for old node versions (only latest lts or higher is supported) -* callback support has been removed -* ability to call error.retry has been removed -* built-in choice and confirm validators now run before any custom validators -* the default option value may only be undefined or a string from now on diff --git a/node_modules/promptly/LICENSE b/node_modules/promptly/LICENSE deleted file mode 100755 index 8407b9a30f51b..0000000000000 --- a/node_modules/promptly/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018 Made With MOXY Lda - -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/node_modules/promptly/README.md b/node_modules/promptly/README.md deleted file mode 100755 index 3aceb2802a67f..0000000000000 --- a/node_modules/promptly/README.md +++ /dev/null @@ -1,184 +0,0 @@ -# promptly - -[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coverage Status][codecov-image]][codecov-url] [![Dependency status][david-dm-image]][david-dm-url] [![Dev Dependency status][david-dm-dev-image]][david-dm-dev-url] [![Greenkeeper badge][greenkeeper-image]][greenkeeper-url] - -[npm-url]:https://npmjs.org/package/promptly -[downloads-image]:http://img.shields.io/npm/dm/promptly.svg -[npm-image]:http://img.shields.io/npm/v/promptly.svg -[travis-url]:https://travis-ci.org/moxystudio/node-promptly -[travis-image]:http://img.shields.io/travis/moxystudio/node-promptly/master.svg -[codecov-url]:https://codecov.io/gh/moxystudio/node-promptly -[codecov-image]:https://img.shields.io/codecov/c/github/moxystudio/node-promptly/master.svg -[david-dm-url]:https://david-dm.org/moxystudio/node-promptly -[david-dm-image]:https://img.shields.io/david/moxystudio/node-promptly.svg -[david-dm-dev-url]:https://david-dm.org/moxystudio/node-promptly?type=dev -[david-dm-dev-image]:https://img.shields.io/david/dev/moxystudio/node-promptly.svg -[greenkeeper-image]:https://badges.greenkeeper.io/moxystudio/node-promptly.svg -[greenkeeper-url]:https://greenkeeper.io/ - -Simple command line prompting utility. - - -## Installation - -`$ npm install promptly` - - -## API - -### .prompt(message, [options]) - -Prompts for a value, printing the `message` and waiting for the input. -Returns a promise that resolves with the input. - -Available options: - -| Name | Description | Type | Default | -| ------ | ------------- | -------- | ------- | -| default | The default value to use if the user provided an empty input | string | undefined | -| trim | Trims the user input | boolean | true | -| validator | A validator or an array of validators | function/array | undefined | -| retry | Retry if any of the validators fail | boolean | true | -| silent | Do not print what the user types | boolean | false | -| replace | Replace each character with the specified string when `silent` is true | string | '' | -| input | Input stream to read from | [Stream](https://nodejs.org/api/process.html#process_process_stdin) | process.stdin | -| output | Output stream to write to | [Stream](https://nodejs.org/api/process.html#process_process_stdout) | process.stdout | - -The same **options** are available to **all functions** but with different default values. - -#### Examples - -- Ask for a name: - - ```js - const name = await promptly.prompt('Name: '); - - console.log(name); - ``` - -- Ask for a name with a constraint (non-empty value and length > 2): - - ```js - const validator = function (value) { - if (value.length < 2) { - throw new Error('Min length of 2'); - } - - return value; - }; - - const name = await promptly.prompt('Name: ', { validator }); - - // Since retry is true by default, promptly will keep asking for a name until it is valid - // Between each prompt, the error message from the validator will be printed - console.log('Name is:', value); - ``` - -- Same as above but do not retry automatically: - - ```js - var validator = function (value) { - if (value.length < 2) { - throw new Error('Min length of 2'); - } - - return value; - }; - - try { - const name = await promptly.prompt('Name: ', { validator, retry: false }); - - console.log('Name is:', value); - } catch (err) { - console.error('Invalid name:') - console.error(`- ${err.message}`); - } - ``` - -#### Validators - -The validators have two purposes: to check and transform input. - -```js -(value) => { - // Validation example, throwing an error when invalid - if (value.length !== 2) { - throw new Error('Length must be 2'); - } - - // Parse the value, modifying it - return value.replace('aa', 'bb'); -} -``` - -### .confirm(message, [options]) - -Ask the user for confirmation, printing the `message` and waiting for the input. -Returns a promise that resolves with the answer. - -Truthy values are: `y`, `yes` and `1`. Falsy values are `n`, `no`, and `0`. -Comparison is made in a case insensitive way. - -The options are the same as [prompt](#promptmessage-options), except that `trim` defaults to `false`. - -#### Examples - -- Ask to confirm something important: - - ```js - const answer = await promptly.confirm('Are you really sure? '); - - console.log('Answer:', answer); - ``` - -### .choose(message, choices, [options]) - -Ask the user to choose between multiple `choices` (array of choices), printing the `message` and waiting for the input. -Returns a promise that resolves with the choice. - -The options are the same as [prompt](#promptmessage-options), except that `trim` defaults to `false`. - -#### Examples - -- Ask to choose between: - - ```js - const choice = await promptly.choose('Do you want an apple or an orange? ', ['apple', 'orange']); - - console.log('Choice:', choice); - ``` - -### .password(message, [options]) - -Prompts for a password, printing the `message` and waiting for the input. -Returns a promise that resolves with the password. - -The options are the same as [prompt](#promptmessage-options), except that `trim` and `silent` default to `false` and `default` is an empty string (to allow empty passwords). - -#### Examples - -- Ask for a password: - - ```js - const password = await promptly.password('Type a password: '); - - console.log('Password:', password); - ``` - -- Ask for a password but mask the input with `*`: - - ```js - const password = await promptly.password('Type a password: ', { replace: '*' }); - - console.log('Password:', password); - ``` - -## Tests - -`$ npm test` -`$ npm test -- --watch` during development - - -## License - -Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). diff --git a/node_modules/promptly/index.js b/node_modules/promptly/index.js deleted file mode 100755 index 93dcc0427d7ec..0000000000000 --- a/node_modules/promptly/index.js +++ /dev/null @@ -1,72 +0,0 @@ -'use strict'; - -const prompt = require('./lib/prompt'); -const getOptions = require('./lib/getOptions'); - -const promptly = module.exports; - -promptly.prompt = (message, options) => { - options = getOptions(options); - - return prompt(message, options); -}; - -promptly.password = (message, options) => { - options = getOptions({ - silent: true, // Hide password chars - trim: false, // Do not trim so that spaces can be part of the password - default: '', // Allow empty passwords - ...options, - }); - - return prompt(message, options); -}; - -promptly.confirm = (message, options) => { - options = getOptions({ - trim: false, // Do not trim so that only exact matches pass the validator - ...options, - }); - - // Unshift the validator that will coerse boolean values - options.validator.unshift((value) => { - value = value.toLowerCase(); - - switch (value) { - case 'y': - case 'yes': - case '1': - return true; - case 'n': - case 'no': - case '0': - return false; - default: - throw new Error(`Invalid choice: ${value}`); - } - }); - - return prompt(message, options); -}; - -promptly.choose = (message, choices, options) => { - options = getOptions({ - trim: false, // Do not trim so that only exact matches pass the validator - ...options, - }); - - // Unshift the validator that will validate the data against the choices - options.validator.unshift((value) => { - // Check if the value exists by comparing values loosely - // Additionally, use the coorced value - const index = choices.findIndex((choice) => value == choice); // eslint-disable-line eqeqeq - - if (index === -1) { - throw new Error(`Invalid choice: ${value}`); - } - - return choices[index]; - }); - - return prompt(message, options); -}; diff --git a/node_modules/promptly/lib/getOptions.js b/node_modules/promptly/lib/getOptions.js deleted file mode 100755 index 1a9a51ad21df9..0000000000000 --- a/node_modules/promptly/lib/getOptions.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; - -function getOptions(options) { - options = { - // Own options - validator: undefined, - retry: true, - trim: true, - default: undefined, - - // `read` package options - silent: false, - replace: '', - input: process.stdin, - output: process.stdout, - - ...options, - }; - - // Validate that default is a string - if (options.default !== undefined && typeof options.default !== 'string') { - throw new Error('The default option value must be a string'); - } - - // Normalize validator to an array - if (!Array.isArray(options.validator)) { - options.validator = options.validator ? [options.validator] : []; - } - - return options; -} - -module.exports = getOptions; diff --git a/node_modules/promptly/lib/prompt.js b/node_modules/promptly/lib/prompt.js deleted file mode 100755 index 791af00412e7e..0000000000000 --- a/node_modules/promptly/lib/prompt.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict'; - -const { EOL } = require('os'); -const pify = require('pify'); -const read = pify(require('read')); - -async function prompt(message, options) { - // Read input - let value = await read({ - prompt: message, - silent: options.silent, - replace: options.replace, - input: options.input, - output: options.output, - }); - - // Trim? - if (options.trim) { - value = value.trim(); - } - - // Prompt again if there's no data or use the default value - if (!value) { - if (options.default === undefined) { - return prompt(message, options); - } - - value = options.default; - } - - // Validator verification - try { - value = options.validator.reduce((value, validator) => validator(value), value); - } catch (err) { - // Retry automatically if the retry option is enabled - if (options.retry) { - err.message && options.output.write(err.message + EOL); - - return prompt(message, options); - } - - throw err; - } - - return value; -} - -module.exports = prompt; diff --git a/node_modules/promptly/package.json b/node_modules/promptly/package.json deleted file mode 100755 index 70e8e7d1d4d11..0000000000000 --- a/node_modules/promptly/package.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "_from": "promptly@^3.0.3", - "_id": "promptly@3.0.3", - "_inBundle": false, - "_integrity": "sha512-EWnzOsxVKUjqKeE6SStH1/cO4+DE44QolaoJ4ojGd9z6pcNkpgfJKr1ncwxrOFHSTIzoudo7jG8y0re30/LO1g==", - "_location": "/promptly", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "promptly@^3.0.3", - "name": "promptly", - "escapedName": "promptly", - "rawSpec": "^3.0.3", - "saveSpec": null, - "fetchSpec": "^3.0.3" - }, - "_requiredBy": [ - "/npm-audit-resolver" - ], - "_resolved": "https://registry.npmjs.org/promptly/-/promptly-3.0.3.tgz", - "_shasum": "e178f722e73d82c60d019462044bccfdd9872f42", - "_spec": "promptly@^3.0.3", - "_where": "/storage/projects/github/npm/node_modules/npm-audit-resolver", - "author": { - "name": "André Cruz", - "email": "andre@moxy.studio" - }, - "bugs": { - "url": "https://github.com/moxystudio/node-promptly/issues" - }, - "bundleDependencies": false, - "commitlint": { - "extends": [ - "@commitlint/config-conventional" - ] - }, - "dependencies": { - "pify": "^3.0.0", - "read": "^1.0.4" - }, - "deprecated": false, - "description": "Simple command line prompting utility", - "devDependencies": { - "@commitlint/cli": "^6.0.0", - "@commitlint/config-conventional": "^6.0.2", - "eslint": "^4.3.0", - "eslint-config-moxy": "^4.1.0", - "husky": "^0.14.3", - "jest": "^22.0.0", - "lint-staged": "^6.0.0", - "p-series": "^1.0.0", - "standard-version": "^4.2.0" - }, - "files": [ - "lib" - ], - "homepage": "https://github.com/moxystudio/node-promptly", - "keywords": [ - "prompt", - "choose", - "choice", - "cli", - "command", - "line" - ], - "license": "MIT", - "lint-staged": { - "*.js": [ - "eslint --fix", - "git add" - ] - }, - "main": "index.js", - "name": "promptly", - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/moxystudio/node-promptly.git" - }, - "scripts": { - "commitmsg": "commitlint -e $GIT_PARAMS", - "lint": "eslint .", - "precommit": "lint-staged", - "prerelease": "npm t && npm run lint", - "release": "standard-version", - "test": "jest --env node --coverage" - }, - "standard-version": { - "scripts": { - "posttag": "git push --follow-tags origin master && npm publish" - } - }, - "version": "3.0.3" -} diff --git a/package-lock.json b/package-lock.json index 99dd1ab20f6af..e85523e6ffa7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1539,11 +1539,6 @@ "write": "^0.2.1" } }, - "flatten": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", - "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=" - }, "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", @@ -2891,14 +2886,13 @@ } }, "npm-audit-resolver": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/npm-audit-resolver/-/npm-audit-resolver-1.2.0.tgz", - "integrity": "sha512-o4KZUrHRiIqbI8HbBiaGJUwKFExwkotElQ6U5lQySzrbA6B7SdGDDa7Cd/ASSu3WRMmFvzEsFzh3SsK49VunxA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/npm-audit-resolver/-/npm-audit-resolver-1.3.1.tgz", + "integrity": "sha512-EvBZ5SFXsckdwbSc8TsijR0jHHTxeTFkvudufHnKjrWn7GZKlCtKYVx2zLHUI2GG1y/hl5Iaog1PA1Mas7ehEA==", "requires": { "chalk": "^2.4.1", "concat-stream": "^1.6.2", - "flatten": "^1.0.2", - "promptly": "^3.0.3", + "read": "^1.0.7", "semver": "^5.5.0", "spawn-shell": "^2.0.1", "yargs-parser": "^10.0.0" @@ -6252,15 +6246,6 @@ } } }, - "promptly": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/promptly/-/promptly-3.0.3.tgz", - "integrity": "sha512-EWnzOsxVKUjqKeE6SStH1/cO4+DE44QolaoJ4ojGd9z6pcNkpgfJKr1ncwxrOFHSTIzoudo7jG8y0re30/LO1g==", - "requires": { - "pify": "^3.0.0", - "read": "^1.0.4" - } - }, "promzard": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz", diff --git a/package.json b/package.json index 1d65ab456fd20..6e9c733ff2acd 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "nopt": "~4.0.1", "normalize-package-data": "~2.4.0", "npm-audit-report": "^1.2.1", - "npm-audit-resolver": "^1.2.0", + "npm-audit-resolver": "^1.3.1", "npm-cache-filename": "~1.0.2", "npm-install-checks": "~3.0.0", "npm-lifecycle": "^2.0.3",