diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 6232a8f82..000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,207 +0,0 @@ -{ - "parserOptions": { - "ecmaVersion": 2018, - "ecmaFeatures": {}, - "sourceType": "script" - }, - - "env": { - "es6": true, - "node": true - }, - - "plugins": [ - "import", - "node", - "promise", - "standard" - ], - - "globals": { - "document": "readonly", - "navigator": "readonly", - "window": "readonly" - }, - - "rules": { - "accessor-pairs": "error", - "array-bracket-spacing": ["error", "never"], - "arrow-spacing": ["error", { "before": true, "after": true }], - "block-spacing": ["error", "always"], - "brace-style": ["error", "1tbs", { "allowSingleLine": false }], - "camelcase": ["error", { "properties": "never" }], - "comma-dangle": ["error", { - "arrays": "always-multiline", - "objects": "always-multiline", - "imports": "always-multiline", - "exports": "always-multiline", - "functions": "never" - }], - "comma-spacing": ["error", { "before": false, "after": true }], - "comma-style": ["error", "last"], - "computed-property-spacing": ["error", "never"], - "constructor-super": "error", - "curly": ["error", "multi-or-nest"], - "dot-location": ["error", "property"], - "dot-notation": ["error", { "allowKeywords": true }], - "eol-last": "error", - "eqeqeq": ["error", "always", { "null": "ignore" }], - "func-call-spacing": ["error", "never"], - "generator-star-spacing": ["error", { "before": true, "after": true }], - "handle-callback-err": ["error", "^(err|error)$" ], - "indent": ["error", 2, { - "SwitchCase": 1, - "VariableDeclarator": 1, - "outerIIFEBody": 1, - "MemberExpression": 1, - "FunctionDeclaration": { "parameters": 1, "body": 1 }, - "FunctionExpression": { "parameters": 1, "body": 1 }, - "CallExpression": { "arguments": 1 }, - "ArrayExpression": 1, - "ObjectExpression": 1, - "ImportDeclaration": 1, - "flatTernaryExpressions": true, - "ignoreComments": false, - "ignoredNodes": ["TemplateLiteral *"] - }], - "key-spacing": ["error", { "beforeColon": false, "afterColon": true }], - "keyword-spacing": ["error", { "before": true, "after": true }], - "lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }], - "new-cap": ["error", { "newIsCap": true, "capIsNew": false, "properties": true }], - "new-parens": "error", - "no-array-constructor": "error", - "no-async-promise-executor": "error", - "no-caller": "error", - "no-case-declarations": "error", - "no-class-assign": "error", - "no-compare-neg-zero": "error", - "no-cond-assign": "off", - "no-const-assign": "error", - "no-constant-condition": ["error", { "checkLoops": false }], - "no-control-regex": "error", - "no-debugger": "error", - "no-delete-var": "error", - "no-dupe-args": "error", - "no-dupe-class-members": "error", - "no-dupe-keys": "error", - "no-duplicate-case": "error", - "no-empty-character-class": "error", - "no-empty-pattern": "error", - "no-eval": "error", - "no-ex-assign": "error", - "no-extend-native": "error", - "no-extra-bind": "error", - "no-extra-boolean-cast": "error", - "no-extra-parens": ["error", "functions"], - "no-fallthrough": "error", - "no-floating-decimal": "error", - "no-func-assign": "error", - "no-global-assign": "error", - "no-implied-eval": "error", - "no-inner-declarations": ["error", "functions"], - "no-invalid-regexp": "error", - "no-irregular-whitespace": "error", - "no-iterator": "error", - "no-labels": ["error", { "allowLoop": true, "allowSwitch": false }], - "no-lone-blocks": "error", - "no-misleading-character-class": "error", - "no-prototype-builtins": "error", - "no-useless-catch": "error", - "no-mixed-operators": "off", - "no-mixed-spaces-and-tabs": "error", - "no-multi-spaces": "error", - "no-multi-str": "error", - "no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 0 }], - "no-negated-in-lhs": "error", - "no-new": "off", - "no-new-func": "error", - "no-new-object": "error", - "no-new-require": "error", - "no-new-symbol": "error", - "no-new-wrappers": "error", - "no-obj-calls": "error", - "no-octal": "error", - "no-octal-escape": "error", - "no-path-concat": "error", - "no-proto": "error", - "no-redeclare": ["error", { "builtinGlobals": false }], - "no-regex-spaces": "error", - "no-return-assign": "off", - "no-self-assign": "off", - "no-self-compare": "error", - "no-sequences": "error", - "no-shadow-restricted-names": "error", - "no-sparse-arrays": "error", - "no-tabs": "error", - "no-template-curly-in-string": "error", - "no-this-before-super": "error", - "no-throw-literal": "off", - "no-trailing-spaces": "error", - "no-undef": "error", - "no-undef-init": "error", - "no-unexpected-multiline": "error", - "no-unmodified-loop-condition": "error", - "no-unneeded-ternary": ["error", { "defaultAssignment": false }], - "no-unreachable": "error", - "no-unsafe-finally": 0, - "no-unsafe-negation": "error", - "no-unused-expressions": ["error", { "allowShortCircuit": true, "allowTernary": true, "allowTaggedTemplates": true }], - "no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": true }], - "no-use-before-define": ["error", { "functions": false, "classes": false, "variables": false }], - "no-useless-call": "error", - "no-useless-computed-key": "error", - "no-useless-constructor": "error", - "no-useless-escape": "error", - "no-useless-rename": "error", - "no-useless-return": "error", - "no-void": "error", - "no-whitespace-before-property": "error", - "no-with": "error", - "nonblock-statement-body-position": [2, "below"], - "object-curly-newline": "off", - "object-curly-spacing": "off", - "object-property-newline": ["error", { "allowMultiplePropertiesPerLine": true }], - "one-var": ["error", { "initialized": "never" }], - "operator-linebreak": "off", - "padded-blocks": ["error", { "blocks": "never", "switches": "never", "classes": "never" }], - "prefer-const": ["error", {"destructuring": "all"}], - "prefer-promise-reject-errors": "error", - "quote-props": ["error", "as-needed"], - "quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": true }], - "rest-spread-spacing": ["error", "never"], - "semi": ["error", "never"], - "semi-spacing": ["error", { "before": false, "after": true }], - "space-before-blocks": ["error", "always"], - "space-before-function-paren": ["error", "always"], - "space-in-parens": ["error", "never"], - "space-infix-ops": "error", - "space-unary-ops": ["error", { "words": true, "nonwords": false }], - "spaced-comment": ["error", "always", { - "line": { "markers": ["*package", "!", "/", ",", "="] }, - "block": { "balanced": true, "markers": ["*package", "!", ",", ":", "::", "flow-include"], "exceptions": ["*"] } - }], - "symbol-description": "error", - "template-curly-spacing": ["error", "never"], - "template-tag-spacing": ["error", "never"], - "unicode-bom": ["error", "never"], - "use-isnan": "error", - "valid-typeof": ["error", { "requireStringLiterals": true }], - "wrap-iife": ["error", "any", { "functionPrototypeMethods": true }], - "yield-star-spacing": ["error", "both"], - "yoda": ["error", "never"], - - "import/export": "error", - "import/first": "error", - "import/no-absolute-path": ["error", { "esmodule": true, "commonjs": true, "amd": false }], - "import/no-duplicates": "error", - "import/no-named-default": "error", - "import/no-webpack-loader-syntax": "error", - - "node/no-deprecated-api": "error", - "node/process-exit-as-throw": "error", - - "promise/param-names": "off", - - "standard/no-callback-literal": "error" - } -} diff --git a/bin/actual.js b/bin/actual.js index ef254e1d4..eb0495997 100644 --- a/bin/actual.js +++ b/bin/actual.js @@ -7,12 +7,14 @@ require('./lib/timers.js') const start = process.hrtime() new Arborist(options).loadActual(options).then(tree => { const end = process.hrtime(start) - if (!process.argv.includes('--quiet')) + if (!process.argv.includes('--quiet')) { print(tree) + } console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`) - if (options.save) + if (options.save) { tree.meta.save() + } if (options.saveHidden) { tree.meta.hiddenLockfile = true tree.meta.filename = options.path + '/node_modules/.package-lock.json' diff --git a/bin/audit.js b/bin/audit.js index 5075724e2..d9ac532d3 100644 --- a/bin/audit.js +++ b/bin/audit.js @@ -7,12 +7,14 @@ require('./lib/logging.js') const Vuln = require('../lib/vuln.js') const printReport = report => { - for (const vuln of report.values()) + for (const vuln of report.values()) { console.log(printVuln(vuln)) + } if (report.topVulns.size) { console.log('\n# top-level vulnerabilities') - for (const vuln of report.topVulns.values()) + for (const vuln of report.topVulns.values()) { console.log(printVuln(vuln)) + } } } @@ -37,12 +39,16 @@ const arb = new Arborist(options) arb.audit(options).then(tree => { process.emit('timeEnd', 'audit script') const end = process.hrtime(start) - if (options.fix) + if (options.fix) { print(tree) - if (!options.quiet) + } + if (!options.quiet) { printReport(arb.auditReport) - if (options.fix) + } + if (options.fix) { console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`) - if (tree.meta && options.save) + } + if (tree.meta && options.save) { tree.meta.save() + } }).catch(er => console.error(er)) diff --git a/bin/funding.js b/bin/funding.js index fa1237e87..d0f4f3165 100644 --- a/bin/funding.js +++ b/bin/funding.js @@ -19,13 +19,15 @@ a.loadVirtual().then(tree => { const end = process.hrtime(start) if (!query) { for (const node of tree.inventory.values()) { - if (node.package.funding) + if (node.package.funding) { console.log(node.name, node.location, node.package.funding) + } } } else { for (const node of tree.inventory.query('name', query)) { - if (node.package.funding) + if (node.package.funding) { console.log(node.name, node.location, node.package.funding) + } } } console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`) diff --git a/bin/ideal.js b/bin/ideal.js index 74d79ce0a..5d1ed0dcd 100644 --- a/bin/ideal.js +++ b/bin/ideal.js @@ -11,8 +11,9 @@ new Arborist(options).buildIdealTree(options).then(tree => { const end = process.hrtime(start) print(tree) console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 10e9}s`) - if (tree.meta && options.save) + if (tree.meta && options.save) { tree.meta.save() + } }).catch(er => { const opt = { depth: Infinity, color: true } console.error(er.code === 'ERESOLVE' ? inspect(er, opt) : er) diff --git a/bin/lib/logging.js b/bin/lib/logging.js index 9420bca3c..8183ece1f 100644 --- a/bin/lib/logging.js +++ b/bin/lib/logging.js @@ -24,12 +24,13 @@ const colors = process.stderr.isTTY const magenta = colors ? msg => `\x1B[35m${msg}\x1B[39m` : m => m if (loglevel !== 'silent') { process.on('log', (level, ...args) => { - if (levelMap.get(level) < levelMap.get(loglevel)) + if (levelMap.get(level) < levelMap.get(loglevel)) { return + } const pref = `${process.pid} ${magenta(level)} ` - if (level === 'warn' && args[0] === 'ERESOLVE') + if (level === 'warn' && args[0] === 'ERESOLVE') { args[2] = inspect(args[2], { depth: 10, colors }) - else { + } else { args = args.map(a => { return typeof a === 'string' ? a : inspect(a, { depth: 10, colors }) diff --git a/bin/lib/options.js b/bin/lib/options.js index a1b671962..23e89ddce 100644 --- a/bin/lib/options.js +++ b/bin/lib/options.js @@ -11,17 +11,17 @@ for (const arg of process.argv.slice(2)) { } else if (/^--rm=/.test(arg)) { options.rm = options.rm || [] options.rm.push(arg.substr('--rm='.length)) - } else if (arg === '--global') + } else if (arg === '--global') { options.global = true - else if (arg === '--global-style') + } else if (arg === '--global-style') { options.globalStyle = true - else if (arg === '--prefer-dedupe') + } else if (arg === '--prefer-dedupe') { options.preferDedupe = true - else if (arg === '--legacy-peer-deps') + } else if (arg === '--legacy-peer-deps') { options.legacyPeerDeps = true - else if (arg === '--force') + } else if (arg === '--force') { options.force = true - else if (arg === '--update-all') { + } else if (arg === '--update-all') { options.update = options.update || {} options.update.all = true } else if (/^--update=/.test(arg)) { @@ -31,9 +31,9 @@ for (const arg of process.argv.slice(2)) { } else if (/^--omit=/.test(arg)) { options.omit = options.omit || [] options.omit.push(arg.substr('--omit='.length)) - } else if (/^--before=/.test(arg)) + } else if (/^--before=/.test(arg)) { options.before = new Date(arg.substr('--before='.length)) - else if (/^-w.+/.test(arg)) { + } else if (/^-w.+/.test(arg)) { options.workspaces = options.workspaces || [] options.workspaces.push(arg.replace(/^-w/, '')) } else if (/^--workspace=/.test(arg)) { @@ -43,15 +43,17 @@ for (const arg of process.argv.slice(2)) { const [key, ...v] = arg.replace(/^--/, '').split('=') const val = v.join('=') options[key] = val === 'false' ? false : val === 'true' ? true : val - } else if (/^--.+/.test(arg)) + } else if (/^--.+/.test(arg)) { options[arg.replace(/^--/, '')] = true - else if (options.path === undefined) + } else if (options.path === undefined) { options.path = arg - else + } else { options._.push(arg) + } } -if (options.path === undefined) +if (options.path === undefined) { options.path = '.' +} console.error(options) diff --git a/bin/lib/timers.js b/bin/lib/timers.js index b516af92c..242431980 100644 --- a/bin/lib/timers.js +++ b/bin/lib/timers.js @@ -3,21 +3,24 @@ const { format } = require('util') const options = require('./options.js') process.on('time', name => { - if (timers[name]) + if (timers[name]) { throw new Error('conflicting timer! ' + name) + } timers[name] = process.hrtime() }) const dim = process.stderr.isTTY ? msg => `\x1B[2m${msg}\x1B[22m` : m => m const red = process.stderr.isTTY ? msg => `\x1B[31m${msg}\x1B[39m` : m => m process.on('timeEnd', name => { - if (!timers[name]) + if (!timers[name]) { throw new Error('timer not started! ' + name) + } const res = process.hrtime(timers[name]) delete timers[name] const msg = format(`${process.pid} ${name}`, res[0] * 1e3 + res[1] / 1e6) - if (options.timers !== false) + if (options.timers !== false) { console.error(dim(msg)) + } }) process.on('exit', () => { diff --git a/bin/license.js b/bin/license.js index 89d0d8790..7fc08dd83 100644 --- a/bin/license.js +++ b/bin/license.js @@ -8,27 +8,31 @@ const query = options._.shift() a.loadVirtual().then(tree => { // only load the actual tree if the virtual one doesn't have modern metadata - if (!tree.meta || !(tree.meta.originalLockfileVersion >= 2)) + if (!tree.meta || !(tree.meta.originalLockfileVersion >= 2)) { throw 'load actual' - else + } else { return tree + } }).catch((er) => { console.error('loading actual tree', er) return a.loadActual() }).then(tree => { if (!query) { const set = [] - for (const license of tree.inventory.query('license')) + for (const license of tree.inventory.query('license')) { set.push([tree.inventory.query('license', license).size, license]) + } for (const [count, license] of set.sort((a, b) => a[1] && b[1] ? b[0] - a[0] || a[1].localeCompare(b[1], 'en') : a[1] ? -1 : b[1] ? 1 - : 0)) + : 0)) { console.log(count, license) + } } else { - for (const node of tree.inventory.query('license', query === 'undefined' ? undefined : query)) + for (const node of tree.inventory.query('license', query === 'undefined' ? undefined : query)) { console.log(`${node.name} ${node.location} ${node.package.description || ''}`) + } } }) diff --git a/bin/prune.js b/bin/prune.js index 357dbcaaf..4809a9923 100644 --- a/bin/prune.js +++ b/bin/prune.js @@ -10,8 +10,9 @@ const printDiff = diff => { depth({ tree: diff, visit: d => { - if (d.location === '') + if (d.location === '') { return + } switch (d.action) { case 'REMOVE': console.error('REMOVE', d.actual.location) @@ -38,9 +39,11 @@ arb.prune(options).then(tree => { process.emit('timeEnd', 'install') const end = process.hrtime(start) print(tree) - if (options.dryRun) + if (options.dryRun) { printDiff(arb.diff) + } console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`) - if (tree.meta && options.save) + if (tree.meta && options.save) { tree.meta.save() + } }).catch(er => console.error(require('util').inspect(er, { depth: Infinity }))) diff --git a/bin/reify.js b/bin/reify.js index d17a0e03b..803bac978 100644 --- a/bin/reify.js +++ b/bin/reify.js @@ -10,8 +10,9 @@ const printDiff = diff => { depth({ tree: diff, visit: d => { - if (d.location === '') + if (d.location === '') { return + } switch (d.action) { case 'REMOVE': console.error('REMOVE', d.actual.location) @@ -38,9 +39,11 @@ arb.reify(options).then(tree => { process.emit('timeEnd', 'install') const end = process.hrtime(start) print(tree) - if (options.dryRun) + if (options.dryRun) { printDiff(arb.diff) + } console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`) - if (tree.meta && options.save) + if (tree.meta && options.save) { tree.meta.save() + } }).catch(er => console.error(require('util').inspect(er, { depth: Infinity }))) diff --git a/bin/virtual.js b/bin/virtual.js index 3352802c2..457c945e7 100644 --- a/bin/virtual.js +++ b/bin/virtual.js @@ -8,9 +8,11 @@ require('./lib/timers.js') const start = process.hrtime() new Arborist(options).loadVirtual().then(tree => { const end = process.hrtime(start) - if (!options.quiet) + if (!options.quiet) { print(tree) - if (options.save) + } + if (options.save) { tree.meta.save() + } console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`) }).catch(er => console.error(er)) diff --git a/lib/add-rm-pkg-deps.js b/lib/add-rm-pkg-deps.js index f78a43319..c1b64a461 100644 --- a/lib/add-rm-pkg-deps.js +++ b/lib/add-rm-pkg-deps.js @@ -1,8 +1,9 @@ // add and remove dependency specs to/from pkg manifest const add = ({pkg, add, saveBundle, saveType, log}) => { - for (const spec of add) + for (const spec of add) { addSingle({pkg, spec, saveBundle, saveType, log}) + } return pkg } @@ -24,8 +25,9 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => { // to keep based on the same order of priority we do when // building the tree as defined in the _loadDeps method of // the node class. - if (!saveType) + if (!saveType) { saveType = inferSaveType(pkg, spec.name) + } if (saveType === 'prod') { // a production dependency can only exist as production (rpj ensures it @@ -48,8 +50,9 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => { const depType = saveTypeMap.get(saveType) pkg[depType] = pkg[depType] || {} - if (rawSpec !== '' || pkg[depType][name] === undefined) + if (rawSpec !== '' || pkg[depType][name] === undefined) { pkg[depType][name] = rawSpec || '*' + } if (saveType === 'optional') { // Affordance for previous npm versions that require this behaviour pkg.dependencies = pkg.dependencies || {} @@ -58,17 +61,18 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => { if (saveType === 'peer' || saveType === 'peerOptional') { const pdm = pkg.peerDependenciesMeta || {} - if (saveType === 'peer' && pdm[name] && pdm[name].optional) + if (saveType === 'peer' && pdm[name] && pdm[name].optional) { pdm[name].optional = false - else if (saveType === 'peerOptional') { + } else if (saveType === 'peerOptional') { pdm[name] = pdm[name] || {} pdm[name].optional = true pkg.peerDependenciesMeta = pdm } // peerDeps are often also a devDep, so that they can be tested when // using package managers that don't auto-install peer deps - if (pkg.devDependencies && pkg.devDependencies[name] !== undefined) + if (pkg.devDependencies && pkg.devDependencies[name] !== undefined) { pkg.devDependencies[name] = pkg.peerDependencies[name] + } } if (saveBundle && saveType !== 'peer' && saveType !== 'peerOptional') { @@ -87,47 +91,54 @@ const inferSaveType = (pkg, name) => { saveType === 'peerOptional' && (!hasSubKey(pkg, 'peerDependenciesMeta', name) || !pkg.peerDependenciesMeta[name].optional) - ) + ) { return 'peer' + } return saveType } } return 'prod' } +const { hasOwnProperty } = Object.prototype const hasSubKey = (pkg, depType, name) => { - return pkg[depType] && Object.prototype.hasOwnProperty.call(pkg[depType], name) + return pkg[depType] && hasOwnProperty.call(pkg[depType], name) } // Removes a subkey and warns about it if it's being replaced const deleteSubKey = (pkg, depType, name, replacedBy, log) => { if (hasSubKey(pkg, depType, name)) { - if (replacedBy && log) + if (replacedBy && log) { log.warn('idealTree', `Removing ${depType}.${name} in favor of ${replacedBy}.${name}`) + } delete pkg[depType][name] - // clean up peerDependenciesMeta if we are removing something from peerDependencies + // clean up peerDepsMeta if we are removing something from peerDependencies if (depType === 'peerDependencies' && pkg.peerDependenciesMeta) { delete pkg.peerDependenciesMeta[name] - if (!Object.keys(pkg.peerDependenciesMeta).length) + if (!Object.keys(pkg.peerDependenciesMeta).length) { delete pkg.peerDependenciesMeta + } } - if (!Object.keys(pkg[depType]).length) + if (!Object.keys(pkg[depType]).length) { delete pkg[depType] + } } } const rm = (pkg, rm) => { for (const depType of new Set(saveTypeMap.values())) { - for (const name of rm) + for (const name of rm) { deleteSubKey(pkg, depType, name) + } } if (pkg.bundleDependencies) { pkg.bundleDependencies = pkg.bundleDependencies .filter(name => !rm.includes(name)) - if (!pkg.bundleDependencies.length) + if (!pkg.bundleDependencies.length) { delete pkg.bundleDependencies + } } return pkg } diff --git a/lib/arborist/audit.js b/lib/arborist/audit.js index bf1c335e7..c0cd79bb1 100644 --- a/lib/arborist/audit.js +++ b/lib/arborist/audit.js @@ -22,8 +22,9 @@ module.exports = cls => class Auditor extends cls { process.emit('time', 'audit') const tree = await this.loadVirtual() - if (this[_workspaces] && this[_workspaces].length) + if (this[_workspaces] && this[_workspaces].length) { options.filterSet = this.workspaceDependencySet(tree, this[_workspaces]) + } this.auditReport = await AuditReport.load(tree, options) const ret = options.fix ? this.reify(options) : this.auditReport process.emit('timeEnd', 'audit') diff --git a/lib/arborist/build-ideal-tree.js b/lib/arborist/build-ideal-tree.js index cda7f8acf..c45024d16 100644 --- a/lib/arborist/build-ideal-tree.js +++ b/lib/arborist/build-ideal-tree.js @@ -137,8 +137,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { this[_globalStyle] = this[_global] || globalStyle this[_follow] = !!follow - if (this[_workspaces].length && this[_global]) + if (this[_workspaces].length && this[_global]) { throw new Error('Cannot operate on workspaces in global mode') + } this[_explicitRequests] = new Set() this[_preferDedupe] = false @@ -168,18 +169,21 @@ module.exports = cls => class IdealTreeBuilder extends cls { // public method async buildIdealTree (options = {}) { - if (this.idealTree) + if (this.idealTree) { return Promise.resolve(this.idealTree) + } // allow the user to set reify options on the ctor as well. // XXX: deprecate separate reify() options object. options = { ...this.options, ...options } // an empty array or any falsey value is the same as null - if (!options.add || options.add.length === 0) + if (!options.add || options.add.length === 0) { options.add = null - if (!options.rm || options.rm.length === 0) + } + if (!options.rm || options.rm.length === 0) { options.rm = null + } process.emit('time', 'idealTree') @@ -230,11 +234,12 @@ module.exports = cls => class IdealTreeBuilder extends cls { [_checkEngine] (node) { const { engineStrict, npmVersion, nodeVersion } = this.options - const c = () => checkEngine(node.package, npmVersion, nodeVersion, this[_force]) + const c = () => + checkEngine(node.package, npmVersion, nodeVersion, this[_force]) - if (engineStrict) + if (engineStrict) { c() - else { + } else { try { c() } catch (er) { @@ -252,8 +257,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { : Array.isArray(options.update) ? { names: options.update } : options.update || {} - if (update.all || !Array.isArray(update.names)) + if (update.all || !Array.isArray(update.names)) { update.names = [] + } this[_complete] = !!options.complete this[_preferDedupe] = !!options.preferDedupe @@ -283,8 +289,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { : rpj(this.path + '/package.json').then( pkg => this[_rootNodeFromPackage](pkg), er => { - if (er.code === 'EJSONPARSE') + if (er.code === 'EJSONPARSE') { throw er + } return this[_rootNodeFromPackage]({}) } )) @@ -312,8 +319,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { // even though we didn't load it from a package-lock.json FILE, // we still loaded it "from disk", meaning we have to reset // dep flags before assuming that any mutations were reflected. - if (tree.children.size) + if (tree.children.size) { root.meta.loadedFromDisk = true + } } return root }) @@ -382,9 +390,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { process.emit('time', 'idealTree:userRequests') const tree = this.idealTree.target - if (!this[_workspaces].length) + if (!this[_workspaces].length) { await this[_applyUserRequestsToNode](tree, options) - else { + } else { await Promise.all(this.workspaceNodes(tree, this[_workspaces]) .map(node => this[_applyUserRequestsToNode](node, options))) } @@ -396,8 +404,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { // If we have a list of package names to update, and we know it's // going to update them wherever they are, add any paths into those // named nodes to the buildIdealTree queue. - if (!this[_global] && this[_updateNames].length) + if (!this[_global] && this[_updateNames].length) { this[_queueNamedUpdates]() + } // global updates only update the globalTop nodes, but we need to know // that they're there, and not reinstall the world unnecessarily. @@ -408,46 +417,55 @@ module.exports = cls => class IdealTreeBuilder extends cls { tree.package.dependencies = tree.package.dependencies || {} const updateName = this[_updateNames].includes(name) if (this[_updateAll] || updateName) { - if (updateName) + if (updateName) { globalExplicitUpdateNames.push(name) + } const dir = resolve(nm, name) - const st = await lstat(dir).catch(/* istanbul ignore next */ er => null) + const st = await lstat(dir) + .catch(/* istanbul ignore next */ er => null) if (st && st.isSymbolicLink()) { const target = await readlink(dir) const real = resolve(dirname(dir), target) tree.package.dependencies[name] = `file:${real}` - } else + } else { tree.package.dependencies[name] = '*' + } } } } - if (this.auditReport && this.auditReport.size > 0) + if (this.auditReport && this.auditReport.size > 0) { await this[_queueVulnDependents](options) + } const { add, rm } = options if (rm && rm.length) { addRmPkgDeps.rm(tree.package, rm) - for (const name of rm) + for (const name of rm) { this[_explicitRequests].add({ from: tree, name, action: 'DELETE' }) + } } - if (add && add.length) + if (add && add.length) { await this[_add](tree, options) + } // triggers a refresh of all edgesOut. this has to be done BEFORE // adding the edges to explicitRequests, because the package setter // resets all edgesOut. - if (add && add.length || rm && rm.length || this[_global]) + if (add && add.length || rm && rm.length || this[_global]) { tree.package = tree.package + } for (const spec of this[_resolvedAdd]) { - if (spec.tree === tree) + if (spec.tree === tree) { this[_explicitRequests].add(tree.edgesOut.get(spec.name)) + } } - for (const name of globalExplicitUpdateNames) + for (const name of globalExplicitUpdateNames) { this[_explicitRequests].add(tree.edgesOut.get(name)) + } this[_depsQueue].push(tree) } @@ -487,21 +505,24 @@ module.exports = cls => class IdealTreeBuilder extends cls { // if it's an explicit tag, we need to install that specific tag version const isTag = spec.rawSpec && spec.type === 'tag' - if (spec.name && !isTag) + if (spec.name && !isTag) { return spec + } const mani = await pacote.manifest(spec, { ...this.options }) // if it's a tag type, then we need to run it down to an actual version - if (isTag) + if (isTag) { return npa(`${mani.name}@${mani.version}`) + } spec.name = mani.name return spec } async [_updateFilePath] (spec) { - if (spec.type === 'file') + if (spec.type === 'file') { return this[_getRelpathSpec](spec, spec.fetchSpec) + } return spec } @@ -601,8 +622,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { nodesTouched.add(node) } } - for (const node of nodesTouched) + for (const node of nodesTouched) { node.package = node.package + } } } @@ -611,11 +633,13 @@ module.exports = cls => class IdealTreeBuilder extends cls { } [_avoidRange] (name) { - if (!this.auditReport) + if (!this.auditReport) { return null + } const vuln = this.auditReport.get(name) - if (!vuln) + if (!vuln) { return null + } return vuln.range } @@ -652,8 +676,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { const ancient = meta.ancientLockfile const old = meta.loadedFromDisk && !(meta.originalLockfileVersion >= 2) - if (inventory.size === 0 || !ancient && !old) + if (inventory.size === 0 || !ancient && !old) { return + } // if the lockfile is from node v5 or earlier, then we'll have to reload // all the manifests of everything we encounter. this is costly, but at @@ -672,8 +697,9 @@ This is a one-time fix-up, please be patient... this.addTracker('idealTree:inflate') const queue = [] for (const node of inventory.values()) { - if (node.isProjectRoot) + if (node.isProjectRoot) { continue + } queue.push(async () => { this.log.silly('inflate', node.location) @@ -738,8 +764,9 @@ This is a one-time fix-up, please be patient... this[_currentDep] = null } - if (!this[_depsQueue].length) + if (!this[_depsQueue].length) { return this[_resolveLinks]() + } // sort physically shallower deps up to the front of the queue, // because they'll affect things deeper in, then alphabetical @@ -757,8 +784,9 @@ This is a one-time fix-up, please be patient... // satisfied by whatever's in that file anyway. if (this[_depsSeen].has(node) || node.root !== this.idealTree || - hasShrinkwrap && !this[_complete]) + hasShrinkwrap && !this[_complete]) { return this[_buildDepStep]() + } this[_depsSeen].add(node) this[_currentDep] = node @@ -841,8 +869,9 @@ This is a one-time fix-up, please be patient... const tasks = [] const peerSource = this[_peerSetSource].get(node) || node for (const edge of this[_problemEdges](node)) { - if (edge.overridden) + if (edge.overridden) { continue + } // peerSetSource is only relevant when we have a peerEntryEdge // otherwise we're setting regular non-peer deps as if they have @@ -878,8 +907,9 @@ This is a one-time fix-up, please be patient... /* istanbul ignore next */ debug(() => { - if (!dep) + if (!dep) { throw new Error('no dep??') + } }) tasks.push({edge, dep}) @@ -912,17 +942,20 @@ This is a one-time fix-up, please be patient... visit: pd => { const { placed, edge, canPlace: cpd } = pd // if we didn't place anything, nothing to do here - if (!placed) + if (!placed) { return + } // we placed something, that means we changed the tree - if (placed.errors.length) + if (placed.errors.length) { this[_loadFailures].add(placed) + } this[_mutateTree] = true if (cpd.canPlaceSelf === OK) { for (const edgeIn of placed.edgesIn) { - if (edgeIn === edge) + if (edgeIn === edge) { continue + } const { from, valid, overridden } = edgeIn if (!overridden && !valid && !this[_depsSeen].has(from)) { this.addTracker('idealTree', from.name, from.location) @@ -936,8 +969,9 @@ This is a one-time fix-up, please be patient... // intentionally causing something to get nested which was // previously placed in this location. for (const edgeIn of placed.edgesIn) { - if (edgeIn === edge) + if (edgeIn === edge) { continue + } const { valid, overridden } = edgeIn if (!valid && !overridden) { @@ -975,8 +1009,9 @@ This is a one-time fix-up, please be patient... } for (const { to } of node.edgesOut.values()) { - if (to && to.isLink && to.target) + if (to && to.isLink && to.target) { this[_linkNodes].add(to) + } } await Promise.all(promises) @@ -1019,8 +1054,9 @@ This is a one-time fix-up, please be patient... if (required.has(edge.from) && edge.type !== 'peerOptional' || secondEdge && ( - required.has(secondEdge.from) && secondEdge.type !== 'peerOptional')) + required.has(secondEdge.from) && secondEdge.type !== 'peerOptional')) { required.add(node) + } // keep track of the thing that caused this node to be included. const src = parent.sourceReference @@ -1030,16 +1066,18 @@ This is a one-time fix-up, please be patient... // otherwise we'll be tempted to put peers as other top-level installed // things, potentially clobbering what's there already, which is not // what we want. the missing edges will be picked up on the next pass. - if (this[_global] && edge.from.isProjectRoot) + if (this[_global] && edge.from.isProjectRoot) { return node + } // otherwise, we have to make sure that our peers can go along with us. return this[_loadPeerSet](node, required) } [_virtualRoot] (node, reuse = false) { - if (reuse && this[_virtualRoots].has(node)) + if (reuse && this[_virtualRoots].has(node)) { return this[_virtualRoots].get(node) + } const vr = new Node({ path: node.realpath, @@ -1081,16 +1119,19 @@ This is a one-time fix-up, please be patient... return [...node.edgesOut.values()] .filter(edge => { // If it's included in a bundle, we take whatever is specified. - if (bundled.has(edge.name)) + if (bundled.has(edge.name)) { return false + } // If it's already been logged as a load failure, skip it. - if (edge.to && this[_loadFailures].has(edge.to)) + if (edge.to && this[_loadFailures].has(edge.to)) { return false + } // If it's shrinkwrapped, we use what the shrinkwap wants. - if (edge.to && edge.to.inShrinkwrap) + if (edge.to && edge.to.inShrinkwrap) { return false + } // If the edge has no destination, that's a problem, unless // if it's peerOptional and not explicitly requested. @@ -1100,20 +1141,24 @@ This is a one-time fix-up, please be patient... } // If the edge has an error, there's a problem. - if (!edge.valid) + if (!edge.valid) { return true + } - // If user has explicitly asked to update this package by name, it's a problem. - if (this[_updateNames].includes(edge.name)) + // user explicitly asked to update this package by name, problem + if (this[_updateNames].includes(edge.name)) { return true + } - // If we're fixing a security vulnerability with this package, it's a problem. - if (this[_isVulnerable](edge.to)) + // fixing a security vulnerability with this package, problem + if (this[_isVulnerable](edge.to)) { return true + } - // If the user has explicitly asked to install this package, it's a "problem". - if (this[_explicitRequests].has(edge)) + // user has explicitly asked to install this package, problem + if (this[_explicitRequests].has(edge)) { return true + } // No problems! return false @@ -1129,9 +1174,9 @@ This is a one-time fix-up, please be patient... // if available and valid. spec = this.idealTree.meta.checkYarnLock(spec, options) - if (this[_manifests].has(spec.raw)) + if (this[_manifests].has(spec.raw)) { return this[_manifests].get(spec.raw) - else { + } else { this.log.silly('fetch manifest', spec.raw) const p = pacote.manifest(spec, options) .then(mani => { @@ -1201,8 +1246,9 @@ This is a one-time fix-up, please be patient... for (const edge of peerEdges) { // already placed this one, and we're happy with it. - if (edge.valid && edge.to) + if (edge.valid && edge.to) { continue + } const parentEdge = node.parent.edgesOut.get(edge.name) const {isProjectRoot, isWorkspace} = node.parent.sourceReference @@ -1223,11 +1269,17 @@ This is a one-time fix-up, please be patient... // a conflict. this is always a problem in strict mode, never // in force mode, and a problem in non-strict mode if this isn't // on behalf of our project. in all such cases, we warn at least. - const dep = await this[_nodeFromEdge](parentEdge, node.parent, edge, required) + const dep = await this[_nodeFromEdge]( + parentEdge, + node.parent, + edge, + required + ) // hooray! that worked! - if (edge.valid) + if (edge.valid) { continue + } // allow it. either we're overriding, or it's not something // that will be installed by default anyway, and we'll fail when @@ -1260,8 +1312,9 @@ This is a one-time fix-up, please be patient... // isn't also required, then there's a good chance we won't need it, // so allow it for now and let it conflict if it turns out to actually // be necessary for the installation. - if (conflictOK || !required.has(edge.from)) + if (conflictOK || !required.has(edge.from)) { continue + } // ok, it's the root, or we're in unforced strict mode, so this is bad this[_failPeerConflict](edge, parentEdge) @@ -1304,15 +1357,17 @@ This is a one-time fix-up, please be patient... this[_linkNodes].delete(link) // link we never ended up placing, skip it - if (link.root !== this.idealTree) + if (link.root !== this.idealTree) { continue + } const tree = this.idealTree.target const external = !link.target.isDescendantOf(tree) // outside the root, somebody else's problem, ignore it - if (external && !this[_follow]) + if (external && !this[_follow]) { continue + } // didn't find a parent for it or it has not been seen yet // so go ahead and process it. @@ -1328,8 +1383,9 @@ This is a one-time fix-up, please be patient... } } - if (this[_depsQueue].length) + if (this[_depsQueue].length) { return this[_buildDepStep]() + } } [_fixDepFlags] () { @@ -1344,8 +1400,9 @@ This is a one-time fix-up, please be patient... // all set to true, and there can be nothing extraneous, so there's // nothing to prune, because we built it from scratch. if we didn't // add or remove anything, then also nothing to do. - if (metaFromDisk && mutateTree) + if (metaFromDisk && mutateTree) { resetDepFlags(this.idealTree) + } // update all the dev/optional/etc flags in the tree // either we started with a fresh tree, or we @@ -1353,9 +1410,9 @@ This is a one-time fix-up, please be patient... // // if we started from a blank slate, or changed something, then // the dep flags will be all set to true. - if (!metaFromDisk || mutateTree) + if (!metaFromDisk || mutateTree) { calcDepFlags(this.idealTree) - else { + } else { // otherwise just unset all the flags on the root node // since they will sometimes have the default value this.idealTree.extraneous = false @@ -1370,25 +1427,29 @@ This is a one-time fix-up, please be patient... // then the tree is suspect. Prune what is marked as extraneous. // otherwise, don't bother. const needPrune = metaFromDisk && (mutateTree || flagsSuspect) - if (this[_prune] && needPrune) + if (this[_prune] && needPrune) { this[_idealTreePrune]() + } process.emit('timeEnd', 'idealTree:fixDepFlags') } [_idealTreePrune] () { - for (const node of this.idealTree.inventory.filter(n => n.extraneous)) + for (const node of this.idealTree.inventory.filter(n => n.extraneous)) { node.parent = null + } } [_pruneFailedOptional] () { for (const node of this[_loadFailures]) { - if (!node.optional) + if (!node.optional) { throw node.errors[0] + } const set = optionalSet(node) - for (const node of set) + for (const node of set) { node.parent = null + } } } } diff --git a/lib/arborist/deduper.js b/lib/arborist/deduper.js index c78e42e75..1741c31a1 100644 --- a/lib/arborist/deduper.js +++ b/lib/arborist/deduper.js @@ -6,8 +6,9 @@ module.exports = cls => class Deduper extends cls { const tree = await this.loadVirtual().catch(() => this.loadActual()) const names = [] for (const name of tree.inventory.query('name')) { - if (tree.inventory.query('name', name).size > 1) + if (tree.inventory.query('name', name).size > 1) { names.push(name) + } } return this.reify({ ...options, diff --git a/lib/arborist/index.js b/lib/arborist/index.js index b26a26c2b..d8ca67faa 100644 --- a/lib/arborist/index.js +++ b/lib/arborist/index.js @@ -59,8 +59,9 @@ class Arborist extends Base { packumentCache: options.packumentCache || new Map(), log: options.log || procLog, } - if (options.saveType && !saveTypeMap.get(options.saveType)) + if (options.saveType && !saveTypeMap.get(options.saveType)) { throw new Error(`Invalid saveType ${options.saveType}`) + } this.cache = resolve(this.options.cache) this.path = resolve(this.options.path) process.emit('timeEnd', 'arborist:ctor') @@ -81,17 +82,20 @@ class Arborist extends Base { const dep = edge.to if (dep) { set.add(dep) - if (dep.isLink) + if (dep.isLink) { set.add(dep.target) + } } } for (const child of node.children.values()) { - if (child.extraneous) + if (child.extraneous) { extraneous.add(child) + } } } - for (const extra of extraneous) + for (const extra of extraneous) { set.add(extra) + } return set } } diff --git a/lib/arborist/load-actual.js b/lib/arborist/load-actual.js index 0338b2cd8..68e58af7d 100644 --- a/lib/arborist/load-actual.js +++ b/lib/arborist/load-actual.js @@ -78,8 +78,9 @@ module.exports = cls => class ActualLoader extends cls { [_resetDepFlags] (tree, root) { // reset all deps to extraneous prior to recalc if (!root) { - for (const node of tree.inventory.values()) + for (const node of tree.inventory.values()) { node.extraneous = true + } } // only reset root flags if we're not re-rooting, @@ -176,8 +177,9 @@ module.exports = cls => class ActualLoader extends cls { await this[_loadFSTree](this[_actualTree]) await this[_loadWorkspaces](this[_actualTree]) await this[_loadWorkspaceTargets](this[_actualTree]) - if (!ignoreMissing) + if (!ignoreMissing) { await this[_findMissingEdges]() + } this[_findFSParents]() this[_transplant](root) @@ -200,8 +202,9 @@ module.exports = cls => class ActualLoader extends cls { // if there are workspace targets without Link nodes created, load // the targets, so that we know what they are. async [_loadWorkspaceTargets] (tree) { - if (!tree.workspaces || !tree.workspaces.size) + if (!tree.workspaces || !tree.workspaces.size) { return + } const promises = [] for (const path of tree.workspaces.values()) { @@ -215,18 +218,21 @@ module.exports = cls => class ActualLoader extends cls { } [_transplant] (root) { - if (!root || root === this[_actualTree]) + if (!root || root === this[_actualTree]) { return + } this[_actualTree][_changePath](root.path) for (const node of this[_actualTree].children.values()) { - if (!this[_transplantFilter](node)) + if (!this[_transplantFilter](node)) { node.root = null + } } root.replace(this[_actualTree]) - for (const node of this[_actualTree].fsChildren) + for (const node of this[_actualTree].fsChildren) { node.root = this[_transplantFilter](node) ? root : null + } this[_actualTree] = root } @@ -291,8 +297,9 @@ module.exports = cls => class ActualLoader extends cls { // it'll get parented later, making the fsParent scan a no-op, but better // safe than sorry, since it's cheap. const { parent, realpath } = options - if (!parent) + if (!parent) { this[_topNodes].add(realpath) + } return process.env._TEST_ARBORIST_SLOW_LINK_TARGET_ === '1' ? new Promise(res => setTimeout(() => res(new Node(options)), 100)) : new Node(options) @@ -309,8 +316,9 @@ module.exports = cls => class ActualLoader extends cls { // if a link target points at a node outside of the root tree's // node_modules hierarchy, then load that node as well. return this[_loadFSTree](link.target).then(() => link) - } else if (target.then) + } else if (target.then) { target.then(node => link.target = node) + } return link } @@ -321,13 +329,15 @@ module.exports = cls => class ActualLoader extends cls { // if a Link target has started, but not completed, then // a Promise will be in the cache to indicate this. - if (node.then) + if (node.then) { return node.then(node => this[_loadFSTree](node)) + } // impossible except in pathological ELOOP cases /* istanbul ignore if */ - if (did.has(node.realpath)) + if (did.has(node.realpath)) { return Promise.resolve(node) + } did.add(node.realpath) return this[_loadFSChildren](node) @@ -371,8 +381,11 @@ module.exports = cls => class ActualLoader extends cls { const depPromises = [] for (const [name, edge] of node.edgesOut.entries()) { - if (!edge.missing && !(edge.to && (edge.to.dummy || edge.to.parent !== node))) + const notMissing = !edge.missing && + !(edge.to && (edge.to.dummy || edge.to.parent !== node)) + if (notMissing) { continue + } // start the walk from the dirname, because we would have found // the dep in the loadFSTree step already if it was local. @@ -383,14 +396,16 @@ module.exports = cls => class ActualLoader extends cls { // allows for finding the transitive deps of link targets. // ie, if it has to go up and back out to get to the path // from the nearest common ancestor, we've gone too far. - if (ancestor && /^\.\.(?:[\\/]|$)/.test(relative(ancestor, p))) + if (ancestor && /^\.\.(?:[\\/]|$)/.test(relative(ancestor, p))) { break + } const entries = nmContents.get(p) || await readdir(p + '/node_modules').catch(() => []) nmContents.set(p, entries) - if (!entries.includes(name)) + if (!entries.includes(name)) { continue + } const d = this[_cache].has(p) ? await this[_cache].get(p) : new Node({ path: p, root: node.root, dummy: true }) diff --git a/lib/arborist/load-virtual.js b/lib/arborist/load-virtual.js index d1edcaca0..fa0aa0746 100644 --- a/lib/arborist/load-virtual.js +++ b/lib/arborist/load-virtual.js @@ -40,8 +40,9 @@ module.exports = cls => class VirtualLoader extends cls { // public method async loadVirtual (options = {}) { - if (this.virtualTree) + if (this.virtualTree) { return this.virtualTree + } // allow the user to set reify options on the ctor as well. // XXX: deprecate separate reify() options object. @@ -85,18 +86,21 @@ module.exports = cls => class VirtualLoader extends cls { root.optional = false root.devOptional = false root.peer = false - } else + } else { this[flagsSuspect] = true + } this[checkRootEdges](s, root) root.meta = s this.virtualTree = root const {links, nodes} = this[resolveNodes](s, root) await this[resolveLinks](links, nodes) - if (!(s.originalLockfileVersion >= 2)) + if (!(s.originalLockfileVersion >= 2)) { this[assignBundles](nodes) - if (this[flagsSuspect]) + } + if (this[flagsSuspect]) { this[reCalcDepFlags](nodes.values()) + } return root } @@ -104,8 +108,9 @@ module.exports = cls => class VirtualLoader extends cls { // reset all dep flags // can't use inventory here, because virtualTree might not be root for (const node of nodes) { - if (node.isRoot || node === this[rootOptionProvided]) + if (node.isRoot || node === this[rootOptionProvided]) { continue + } node.extraneous = true node.dev = true node.optional = true @@ -123,8 +128,9 @@ module.exports = cls => class VirtualLoader extends cls { // loaded virtually from tree, no chance of being out of sync // ancient lockfiles are critically damaged by this process, // so we need to just hope for the best in those cases. - if (!s.loadedFromDisk || s.ancientLockfile) + if (!s.loadedFromDisk || s.ancientLockfile) { return + } const lock = s.get('') const prod = lock.dependencies || {} @@ -140,16 +146,18 @@ module.exports = cls => class VirtualLoader extends cls { } } } - for (const name of Object.keys(optional)) + for (const name of Object.keys(optional)) { delete prod[name] + } const lockWS = [] const workspaces = this[loadWorkspacesVirtual]({ cwd: this.path, lockfile: s.data, }) - for (const [name, path] of workspaces.entries()) + for (const [name, path] of workspaces.entries()) { lockWS.push(['workspace', name, `file:${path}`]) + } const lockEdges = [ ...depsToEdges('prod', prod), @@ -174,8 +182,9 @@ module.exports = cls => class VirtualLoader extends cls { for (let i = 0; i < lockEdges.length; i++) { if (rootEdges[i][0] !== lockEdges[i][0] || rootEdges[i][1] !== lockEdges[i][1] || - rootEdges[i][2] !== lockEdges[i][2]) + rootEdges[i][2] !== lockEdges[i][2]) { return this[flagsSuspect] = true + } } } @@ -185,13 +194,15 @@ module.exports = cls => class VirtualLoader extends cls { const nodes = new Map([['', root]]) for (const [location, meta] of Object.entries(s.data.packages)) { // skip the root because we already got it - if (!location) + if (!location) { continue + } - if (meta.link) + if (meta.link) { links.set(location, meta) - else + } else { nodes.set(location, this[loadNode](location, meta)) + } } return {links, nodes} } @@ -212,8 +223,9 @@ module.exports = cls => class VirtualLoader extends cls { if (!link.target.parent) { const pj = link.realpath + '/package.json' const pkg = await rpj(pj).catch(() => null) - if (pkg) + if (pkg) { link.target.package = pkg + } } } } @@ -221,12 +233,14 @@ module.exports = cls => class VirtualLoader extends cls { [assignBundles] (nodes) { for (const [location, node] of nodes) { // Skip assignment of parentage for the root package - if (!location || node.isLink && !node.target.location) + if (!location || node.isLink && !node.target.location) { continue + } const { name, parent, package: { inBundle }} = node - if (!parent) + if (!parent) { continue + } // read inBundle from package because 'package' here is // actually a v2 lockfile metadata entry. @@ -236,10 +250,11 @@ module.exports = cls => class VirtualLoader extends cls { const { package: ppkg } = parent const { inBundle: parentBundled } = ppkg if (inBundle && !parentBundled && parent.edgesOut.has(node.name)) { - if (!ppkg.bundleDependencies) + if (!ppkg.bundleDependencies) { ppkg.bundleDependencies = [name] - else + } else { ppkg.bundleDependencies.push(name) + } } } } @@ -248,8 +263,9 @@ module.exports = cls => class VirtualLoader extends cls { const p = this.virtualTree ? this.virtualTree.realpath : this.path const path = resolve(p, location) // shrinkwrap doesn't include package name unless necessary - if (!sw.name) + if (!sw.name) { sw.name = nameFromFolder(path) + } const dev = sw.dev const optional = sw.optional diff --git a/lib/arborist/load-workspaces.js b/lib/arborist/load-workspaces.js index 93d078415..0a7965ae3 100644 --- a/lib/arborist/load-workspaces.js +++ b/lib/arborist/load-workspaces.js @@ -7,15 +7,17 @@ const _loadWorkspacesVirtual = Symbol.for('loadWorkspacesVirtual') module.exports = cls => class MapWorkspaces extends cls { [_appendWorkspaces] (node, workspaces) { - if (node && workspaces.size) + if (node && workspaces.size) { node.workspaces = workspaces + } return node } async [_loadWorkspaces] (node) { - if (node.workspaces) + if (node.workspaces) { return node + } const workspaces = await mapWorkspaces({ cwd: node.path, diff --git a/lib/arborist/rebuild.js b/lib/arborist/rebuild.js index 8e447bb8f..743794f4b 100644 --- a/lib/arborist/rebuild.js +++ b/lib/arborist/rebuild.js @@ -61,8 +61,9 @@ module.exports = cls => class Builder extends cls { async rebuild ({ nodes, handleOptionalFailure = false } = {}) { // nothing to do if we're not building anything! - if (this[_ignoreScripts] && !this[_binLinks]) + if (this[_ignoreScripts] && !this[_binLinks]) { return + } // when building for the first time, as part of reify, we ignore // failures in optional nodes, and just delete them. however, when @@ -76,8 +77,9 @@ module.exports = cls => class Builder extends cls { if (this[_workspaces] && this[_workspaces].length) { const filterSet = this.workspaceDependencySet(tree, this[_workspaces]) nodes = tree.inventory.filter(node => filterSet.has(node)) - } else + } else { nodes = tree.inventory.values() + } } // separates links nodes so that it can run @@ -88,10 +90,11 @@ module.exports = cls => class Builder extends cls { for (const node of nodes) { // we skip the target nodes to that workspace in order to make sure // we only run lifecycle scripts / place bin links once per workspace - if (node.isLink) + if (node.isLink) { linkNodes.add(node) - else + } else { depNodes.add(node) + } } await this[_build](depNodes, {}) @@ -118,17 +121,20 @@ module.exports = cls => class Builder extends cls { process.emit('time', `build:${type}`) await this[_buildQueues](nodes) - if (!this[_ignoreScripts]) + if (!this[_ignoreScripts]) { await this[_runScripts]('preinstall') - if (this[_binLinks] && type !== 'links') + } + if (this[_binLinks] && type !== 'links') { await this[_linkAllBins]() + } // links should also run prepare scripts and only link bins after that if (type === 'links') { await this[_runScripts]('prepare') - if (this[_binLinks]) + if (this[_binLinks]) { await this[_linkAllBins]() + } } if (!this[_ignoreScripts]) { @@ -173,8 +179,9 @@ module.exports = cls => class Builder extends cls { const { preinstall, install, postinstall, prepare } = scripts const tests = { bin, preinstall, install, postinstall, prepare } for (const [key, has] of Object.entries(tests)) { - if (has) + if (has) { this[_queues][key].push(node) + } } } process.emit('timeEnd', 'build:queue') @@ -186,15 +193,17 @@ module.exports = cls => class Builder extends cls { // the node path. Otherwise a package can have a preinstall script // that unlinks something, to allow them to silently overwrite system // binaries, which is unsafe and insecure. - if (!node.globalTop || this[_force]) + if (!node.globalTop || this[_force]) { return + } const { path, package: pkg } = node await binLinks.checkBins({ pkg, path, top: true, global: true }) } async [_addToBuildSet] (node, set, refreshed = false) { - if (set.has(node)) + if (set.has(node)) { return + } if (this[_oldMeta] === null) { const {root: {meta}} = node @@ -233,8 +242,9 @@ module.exports = cls => class Builder extends cls { await isNodeGypPackage(node.path) if (bin || preinstall || install || postinstall || prepare || isGyp) { - if (bin) + if (bin) { await this[_checkBins](node) + } if (isGyp) { scripts.install = defaultGypInstallScript node.package.scripts = scripts @@ -246,8 +256,9 @@ module.exports = cls => class Builder extends cls { async [_runScripts] (event) { const queue = this[_queues][event] - if (!queue.length) + if (!queue.length) { return + } process.emit('time', `build:run:${event}`) const stdio = this.options.foregroundScripts ? 'inherit' : 'pipe' @@ -266,8 +277,9 @@ module.exports = cls => class Builder extends cls { } = node.target // skip any that we know we'll be deleting - if (this[_trashList].has(path)) + if (this[_trashList].has(path)) { return + } const timer = `build:run:${event}:${location}` process.emit('time', timer) @@ -321,23 +333,26 @@ module.exports = cls => class Builder extends cls { async [_linkAllBins] () { const queue = this[_queues].bin - if (!queue.length) + if (!queue.length) { return + } process.emit('time', 'build:link') const promises = [] // sort the queue by node path, so that the module-local collision // detector in bin-links will always resolve the same way. - for (const node of queue.sort(sortNodes)) + for (const node of queue.sort(sortNodes)) { promises.push(this[_createBinLinks](node)) + } await promiseAllRejectLate(promises) process.emit('timeEnd', 'build:link') } async [_createBinLinks] (node) { - if (this[_trashList].has(node.path)) + if (this[_trashList].has(node.path)) { return + } process.emit('time', `build:link:${node.location}`) diff --git a/lib/arborist/reify.js b/lib/arborist/reify.js index 965435f84..a05de5490 100644 --- a/lib/arborist/reify.js +++ b/lib/arborist/reify.js @@ -158,8 +158,9 @@ module.exports = cls => class Reifier extends cls { async [_validatePath] () { // don't create missing dirs on dry runs - if (this[_packageLockOnly] || this[_dryRun]) + if (this[_packageLockOnly] || this[_dryRun]) { return + } // we do NOT want to set ownership on this folder, especially // recursively, because it can have other side effects to do that @@ -172,8 +173,9 @@ module.exports = cls => class Reifier extends cls { async [_reifyPackages] () { // we don't submit the audit report or write to disk on dry runs - if (this[_dryRun]) + if (this[_dryRun]) { return + } if (this[_packageLockOnly]) { // we already have the complete tree, so just audit it now, @@ -220,8 +222,9 @@ module.exports = cls => class Reifier extends cls { for (const action of actions) { try { await this[action]() - if (reifyTerminated) + if (reifyTerminated) { throw reifyTerminated + } } catch (er) { await this[rollback](er) /* istanbul ignore next - rollback throws, should never hit this */ @@ -233,8 +236,9 @@ module.exports = cls => class Reifier extends cls { // no rollback for this one, just exit with the error, since the // install completed and can't be safely recovered at this point. await this[_removeTrash]() - if (reifyTerminated) + if (reifyTerminated) { throw reifyTerminated + } // done modifying the file system, no need to keep listening for sigs removeHandler() @@ -261,18 +265,21 @@ module.exports = cls => class Reifier extends cls { filter: (node, kid) => { // if it's not the project root, and we have no explicit requests, // then we're already into a nested dep, so we keep it - if (this.explicitRequests.size === 0 || !node.isProjectRoot) + if (this.explicitRequests.size === 0 || !node.isProjectRoot) { return true + } // if we added it as an edgeOut, then we want it - if (this.idealTree.edgesOut.has(kid)) + if (this.idealTree.edgesOut.has(kid)) { return true + } // if it's an explicit request, then we want it const hasExplicit = [...this.explicitRequests] .some(edge => edge.name === kid) - if (hasExplicit) + if (hasExplicit) { return true + } // ignore the rest of the global install folder return false @@ -280,8 +287,10 @@ module.exports = cls => class Reifier extends cls { } : { ignoreMissing: true } if (!this[_global]) { - return Promise.all([this.loadActual(actualOpt), this.buildIdealTree(bitOpt)]) - .then(() => process.emit('timeEnd', 'reify:loadTrees')) + return Promise.all([ + this.loadActual(actualOpt), + this.buildIdealTree(bitOpt), + ]).then(() => process.emit('timeEnd', 'reify:loadTrees')) } // the global install space tends to have a lot of stuff in it. don't @@ -295,8 +304,9 @@ module.exports = cls => class Reifier extends cls { } [_diffTrees] () { - if (this[_packageLockOnly]) + if (this[_packageLockOnly]) { return + } process.emit('time', 'reify:diffTrees') // XXX if we have an existing diff already, there should be a way @@ -311,20 +321,24 @@ module.exports = cls => class Reifier extends cls { // children where there's an explicit request. for (const { name } of this.explicitRequests) { const ideal = idealTree.children.get(name) - if (ideal) + if (ideal) { filterNodes.push(ideal) + } const actual = actualTree.children.get(name) - if (actual) + if (actual) { filterNodes.push(actual) + } } } else { for (const ws of this[_workspaces]) { const ideal = this.idealTree.children.get(ws) - if (ideal) + if (ideal) { filterNodes.push(ideal) + } const actual = this.actualTree.children.get(ws) - if (actual) + if (actual) { filterNodes.push(actual) + } } } @@ -360,8 +374,9 @@ module.exports = cls => class Reifier extends cls { const retired = retirePath(path) moves[path] = retired this[_trashList].add(retired) - } else + } else { this[_trashList].add(path) + } } } @@ -393,10 +408,11 @@ module.exports = cls => class Reifier extends cls { if (er.code === 'ENOENT') { return didMkdirp ? null : mkdirp(dirname(to)).then(() => this[_renamePath](from, to, true)) - } else if (er.code === 'EEXIST') + } else if (er.code === 'EEXIST') { return rimraf(to).then(() => moveFile(from, to)) - else + } else { throw er + } }) } @@ -417,8 +433,9 @@ module.exports = cls => class Reifier extends cls { // adding to the trash list will skip reifying, and delete them // if they are currently in the tree and otherwise untouched. [_addOmitsToTrashList] () { - if (!this[_omitDev] && !this[_omitOptional] && !this[_omitPeer]) + if (!this[_omitDev] && !this[_omitOptional] && !this[_omitPeer]) { return + } process.emit('time', 'reify:trashOmits') @@ -429,8 +446,9 @@ module.exports = cls => class Reifier extends cls { node.optional && this[_omitOptional] || node.devOptional && this[_omitOptional] && this[_omitDev]) - for (const node of this.idealTree.inventory.filter(filter)) + for (const node of this.idealTree.inventory.filter(filter)) { this[_addNodeToTrashList](node) + } process.emit('timeEnd', 'reify:trashOmits') } @@ -452,10 +470,12 @@ module.exports = cls => class Reifier extends cls { const dirsChecked = new Set() return promiseAllRejectLate(leaves.map(async node => { for (const d of walkUp(node.path)) { - if (d === node.top.path) + if (d === node.top.path) { break - if (dirsChecked.has(d)) + } + if (dirsChecked.has(d)) { continue + } dirsChecked.add(d) const st = await lstat(d).catch(er => null) // this can happen if we have a link to a package with a name @@ -487,8 +507,9 @@ module.exports = cls => class Reifier extends cls { .map(path => rimraf(path).catch(er => failures.push([path, er]))) return promiseAllRejectLate(unlinks) .then(() => { - if (failures.length) + if (failures.length) { this.log.warn('cleanup', 'Failed to remove some directories', failures) + } }) .then(() => process.emit('timeEnd', 'reify:rollback:createSparse')) .then(() => this[_rollbackRetireShallowNodes](er)) @@ -504,8 +525,9 @@ module.exports = cls => class Reifier extends cls { d.ideal.hasShrinkwrap && !seen.has(d.ideal) && !this[_trashList].has(d.ideal.path)) - if (!shrinkwraps.length) + if (!shrinkwraps.length) { return + } process.emit('time', 'reify:loadShrinkwraps') @@ -535,8 +557,9 @@ module.exports = cls => class Reifier extends cls { // to the trash list // Always return the node. [_reifyNode] (node) { - if (this[_trashList].has(node.path)) + if (this[_trashList].has(node.path)) { return node + } const timer = `reifyNode:${node.location}` process.emit('time', timer) @@ -569,8 +592,9 @@ module.exports = cls => class Reifier extends cls { // do not allow node_modules to be a symlink async [_validateNodeModules] (nm) { - if (this[_force] || this[_nmValidated].has(nm)) + if (this[_force] || this[_nmValidated].has(nm)) { return + } const st = await lstat(nm).catch(() => null) if (!st || st.isDirectory()) { this[_nmValidated].add(nm) @@ -642,8 +666,9 @@ module.exports = cls => class Reifier extends cls { [_warnDeprecated] (node) { const {_id, deprecated} = node.package - if (deprecated) + if (deprecated) { this.log.warn('deprecated', `${_id}: ${deprecated}`) + } } // if the node is optional, then the failure of the promise is nonfatal @@ -677,8 +702,9 @@ module.exports = cls => class Reifier extends cls { [_loadBundlesAndUpdateTrees] ( depth = 0, bundlesByDepth = this[_getBundlesByDepth]() ) { - if (depth === 0) + if (depth === 0) { process.emit('time', 'reify:loadBundles') + } const maxBundleDepth = bundlesByDepth.get('maxBundleDepth') if (depth > maxBundleDepth) { @@ -698,8 +724,9 @@ module.exports = cls => class Reifier extends cls { node.target !== node.root && !this[_trashList].has(node.path)) - if (!set.length) + if (!set.length) { return this[_loadBundlesAndUpdateTrees](depth + 1, bundlesByDepth) + } // extract all the nodes with bundles return promiseAllRejectLate(set.map(node => { @@ -725,12 +752,14 @@ module.exports = cls => class Reifier extends cls { // it's actually in the bundle if it gets transplanted notTransplanted.delete(node.name) return true - } else + } else { return false + } }, }) - for (const name of notTransplanted) + for (const name of notTransplanted) { this[_bundleMissing].add(node.children.get(name)) + } }))) // move onto the next level of bundled items .then(() => this[_loadBundlesAndUpdateTrees](depth + 1, bundlesByDepth)) @@ -743,18 +772,21 @@ module.exports = cls => class Reifier extends cls { tree: this.diff, visit: diff => { const node = diff.ideal - if (!node) + if (!node) { return - if (node.isProjectRoot) + } + if (node.isProjectRoot) { return + } const { bundleDependencies } = node.package if (bundleDependencies && bundleDependencies.length) { maxBundleDepth = Math.max(maxBundleDepth, node.depth) - if (!bundlesByDepth.has(node.depth)) + if (!bundlesByDepth.has(node.depth)) { bundlesByDepth.set(node.depth, [node]) - else + } else { bundlesByDepth.get(node.depth).push(node) + } } }, getChildren: diff => diff.children, @@ -791,13 +823,15 @@ module.exports = cls => class Reifier extends cls { // create the list of nodes shadowed by children of bundlers for (const bundles of bundlesByDepth.values()) { // skip the 'maxBundleDepth' item - if (!Array.isArray(bundles)) + if (!Array.isArray(bundles)) { continue + } for (const node of bundles) { for (const name of node.children.keys()) { const shadow = node.parent.resolve(name) - if (!shadow) + if (!shadow) { continue + } bundleShadowed.add(shadow) shadow.extraneous = true } @@ -851,8 +885,9 @@ module.exports = cls => class Reifier extends cls { } [_submitQuickAudit] () { - if (this.options.audit === false) + if (this.options.audit === false) { return this.auditReport = null + } // we submit the quick audit at this point in the process, as soon as // we have all the deps resolved, so that it can overlap with the other @@ -865,8 +900,9 @@ module.exports = cls => class Reifier extends cls { const tree = this.idealTree // if we're operating on a workspace, only audit the workspace deps - if (this[_workspaces] && this[_workspaces].length) + if (this[_workspaces] && this[_workspaces].length) { options.filterSet = this.workspaceDependencySet(tree, this[_workspaces]) + } this.auditReport = AuditReport.load(tree, options) .then(res => { @@ -891,8 +927,9 @@ module.exports = cls => class Reifier extends cls { tree: this.diff, visit: diff => { // no unpacking if we don't want to change this thing - if (diff.action !== 'CHANGE' && diff.action !== 'ADD') + if (diff.action !== 'CHANGE' && diff.action !== 'ADD') { return + } const node = diff.ideal const bd = this[_bundleUnpacked].has(node) @@ -902,13 +939,18 @@ module.exports = cls => class Reifier extends cls { // check whether we still need to unpack this one. // test the inDepBundle last, since that's potentially a tree walk. const doUnpack = node && // can't unpack if removed! - !node.isRoot && // root node already exists - !bd && // already unpacked to read bundle - !sw && // already unpacked to read sw - (bundleMissing || !node.inDepBundle) // already unpacked by another dep's bundle - - if (doUnpack) + // root node already exists + !node.isRoot && + // already unpacked to read bundle + !bd && + // already unpacked to read sw + !sw && + // already unpacked by another dep's bundle + (bundleMissing || !node.inDepBundle) + + if (doUnpack) { unpacks.push(this[_reifyNode](node)) + } }, getChildren: diff => diff.children, }) @@ -933,8 +975,9 @@ module.exports = cls => class Reifier extends cls { this[_retiredUnchanged] = {} return promiseAllRejectLate(this.diff.children.map(diff => { // skip if nothing was retired - if (diff.action !== 'CHANGE' && diff.action !== 'REMOVE') + if (diff.action !== 'CHANGE' && diff.action !== 'REMOVE') { return + } const { path: realFolder } = diff.actual const retireFolder = moves[realFolder] @@ -955,12 +998,14 @@ module.exports = cls => class Reifier extends cls { this[_retiredUnchanged][retireFolder] = [] return promiseAllRejectLate(diff.unchanged.map(node => { // no need to roll back links, since we'll just delete them anyway - if (node.isLink) + if (node.isLink) { return mkdirp(dirname(node.path)).then(() => this[_reifyNode](node)) + } // will have been moved/unpacked along with bundler - if (node.inDepBundle && !this[_bundleMissing].has(node)) + if (node.inDepBundle && !this[_bundleMissing].has(node)) { return + } this[_retiredUnchanged][retireFolder].push(node) @@ -1014,8 +1059,9 @@ module.exports = cls => class Reifier extends cls { dfwalk({ tree: this.diff, leave: diff => { - if (!diff.ideal.isProjectRoot) + if (!diff.ideal.isProjectRoot) { nodes.push(diff.ideal) + } }, // process adds before changes, ignore removals getChildren: diff => diff && diff.children, @@ -1030,8 +1076,9 @@ module.exports = cls => class Reifier extends cls { // skip links that only live within node_modules as they are most // likely managed by packages we installed, we only want to rebuild // unchanged links we directly manage - if (node.isLink && node.target.fsTop === tree) + if (node.isLink && node.target.fsTop === tree) { nodes.push(node) + } } return this.rebuild({ nodes, handleOptionalFailure: true }) @@ -1048,12 +1095,14 @@ module.exports = cls => class Reifier extends cls { const failures = [] const rm = path => rimraf(path).catch(er => failures.push([path, er])) - for (const path of this[_trashList]) + for (const path of this[_trashList]) { promises.push(rm(path)) + } return promiseAllRejectLate(promises).then(() => { - if (failures.length) + if (failures.length) { this.log.warn('cleanup', 'Failed to remove some directories', failures) + } }) .then(() => process.emit('timeEnd', 'reify:trash')) } @@ -1067,8 +1116,9 @@ module.exports = cls => class Reifier extends cls { // save it first, then prune out the optional trash, and then return it. // support save=false option - if (options.save === false || this[_global] || this[_dryRun]) + if (options.save === false || this[_global] || this[_dryRun]) { return false + } process.emit('time', 'reify:save') @@ -1105,8 +1155,9 @@ module.exports = cls => class Reifier extends cls { !isRange || spec === '*' || subset(prefixRange, spec, { loose: true }) - ) + ) { range = prefixRange + } const pname = child.packageName const alias = name !== pname @@ -1115,10 +1166,11 @@ module.exports = cls => class Reifier extends cls { // save the git+https url if it has auth, otherwise shortcut const h = req.hosted const opt = { noCommittish: false } - if (h.https && h.auth) + if (h.https && h.auth) { newSpec = `git+${h.https(opt)}` - else + } else { newSpec = h.shortcut(opt) + } } else if (req.type === 'directory' || req.type === 'file') { // save the relative path in package.json // Normally saveSpec is updated with the proper relative @@ -1128,34 +1180,41 @@ module.exports = cls => class Reifier extends cls { const p = req.fetchSpec.replace(/^file:/, '') const rel = relpath(addTree.realpath, p) newSpec = `file:${rel}` - } else + } else { newSpec = req.saveSpec + } if (options.saveType) { const depType = saveTypeMap.get(options.saveType) pkg[depType][name] = newSpec // rpj will have moved it here if it was in both // if it is empty it will be deleted later - if (options.saveType === 'prod' && pkg.optionalDependencies) + if (options.saveType === 'prod' && pkg.optionalDependencies) { delete pkg.optionalDependencies[name] + } } else { - if (hasSubKey(pkg, 'dependencies', name)) + if (hasSubKey(pkg, 'dependencies', name)) { pkg.dependencies[name] = newSpec + } if (hasSubKey(pkg, 'devDependencies', name)) { pkg.devDependencies[name] = newSpec // don't update peer or optional if we don't have to - if (hasSubKey(pkg, 'peerDependencies', name) && !intersects(newSpec, pkg.peerDependencies[name])) + if (hasSubKey(pkg, 'peerDependencies', name) && !intersects(newSpec, pkg.peerDependencies[name])) { pkg.peerDependencies[name] = newSpec + } - if (hasSubKey(pkg, 'optionalDependencies', name) && !intersects(newSpec, pkg.optionalDependencies[name])) + if (hasSubKey(pkg, 'optionalDependencies', name) && !intersects(newSpec, pkg.optionalDependencies[name])) { pkg.optionalDependencies[name] = newSpec + } } else { - if (hasSubKey(pkg, 'peerDependencies', name)) + if (hasSubKey(pkg, 'peerDependencies', name)) { pkg.peerDependencies[name] = newSpec + } - if (hasSubKey(pkg, 'optionalDependencies', name)) + if (hasSubKey(pkg, 'optionalDependencies', name)) { pkg.optionalDependencies[name] = newSpec + } } } @@ -1196,8 +1255,9 @@ module.exports = cls => class Reifier extends cls { } // grab any from explicitRequests that had deps removed - for (const { from: tree } of this.explicitRequests) + for (const { from: tree } of this.explicitRequests) { updatedTrees.add(tree) + } for (const tree of updatedTrees) { // refresh the edges so they have the correct specs @@ -1211,8 +1271,9 @@ module.exports = cls => class Reifier extends cls { } async [_saveLockFile] (saveOpt) { - if (!this[_usePackageLock]) + if (!this[_usePackageLock]) { return + } const { meta } = this.idealTree @@ -1224,8 +1285,9 @@ module.exports = cls => class Reifier extends cls { for (const path of this[_trashList]) { const loc = relpath(this.idealTree.realpath, path) const node = this.idealTree.inventory.get(loc) - if (node && node.root === this.idealTree) + if (node && node.root === this.idealTree) { node.parent = null + } } // if we filtered to only certain nodes, then anything ELSE needs @@ -1244,54 +1306,60 @@ module.exports = cls => class Reifier extends cls { // if it's an ideal node from the filter set, then skip it // because we already made whatever changes were necessary - if (filterSet.has(ideal)) + if (filterSet.has(ideal)) { continue + } // otherwise, if it's not in the actualTree, then it's not a thing // that we actually added. And if it IS in the actualTree, then // it's something that we left untouched, so we need to record // that. const actual = this.actualTree.inventory.get(loc) - if (!actual) + if (!actual) { ideal.root = null - else { + } else { if ([...actual.linksIn].some(link => filterSet.has(link))) { seen.add(actual.location) continue } const { realpath, isLink } = actual - if (isLink && ideal.isLink && ideal.realpath === realpath) + if (isLink && ideal.isLink && ideal.realpath === realpath) { continue - else + } else { reroot.add(actual) + } } } // now find any actual nodes that may not be present in the ideal // tree, but were left behind by virtue of not being in the filter for (const [loc, actual] of this.actualTree.inventory.entries()) { - if (seen.has(loc)) + if (seen.has(loc)) { continue + } seen.add(loc) // we know that this is something that ISN'T in the idealTree, // or else we will have addressed it in the previous loop. // If it's in the filterSet, that means we intentionally removed // it, so nothing to do here. - if (filterSet.has(actual)) + if (filterSet.has(actual)) { continue + } reroot.add(actual) } // go through the rerooted actual nodes, and move them over. - for (const actual of reroot) + for (const actual of reroot) { actual.root = this.idealTree + } // prune out any tops that lack a linkIn, they are no longer relevant. for (const top of this.idealTree.tops) { - if (top.linksIn.size === 0) + if (top.linksIn.size === 0) { top.root = null + } } // need to calculate dep flags, since nodes may have been marked @@ -1307,7 +1375,8 @@ module.exports = cls => class Reifier extends cls { this.actualTree = this.idealTree this.idealTree = null - if (!this[_global]) + if (!this[_global]) { await this.actualTree.meta.save() + } } } diff --git a/lib/audit-report.js b/lib/audit-report.js index 8f7d6546d..2e6c207b3 100644 --- a/lib/audit-report.js +++ b/lib/audit-report.js @@ -63,8 +63,9 @@ class AuditReport extends Map { prod = false } } - if (prod) + if (prod) { dependencies.prod++ + } } // if it doesn't have any topVulns, then it's fixable with audit fix @@ -104,8 +105,9 @@ class AuditReport extends Map { async run () { this.report = await this[_getReport]() this.log.silly('audit report', this.report) - if (this.report) + if (this.report) { await this[_init]() + } return this } @@ -119,8 +121,9 @@ class AuditReport extends Map { const promises = [] for (const [name, advisories] of Object.entries(this.report)) { - for (const advisory of advisories) + for (const advisory of advisories) { promises.push(this.calculator.calculate(name, advisory)) + } } // now the advisories are calculated with a set of versions @@ -136,43 +139,51 @@ class AuditReport extends Map { // adding multiple advisories with the same range is fine, but no // need to search for nodes we already would have added. const k = `${name}@${range}` - if (seen.has(k)) + if (seen.has(k)) { continue + } seen.add(k) const vuln = this.get(name) || new Vuln({ name, advisory }) - if (this.has(name)) + if (this.has(name)) { vuln.addAdvisory(advisory) + } super.set(name, vuln) const p = [] for (const node of this.tree.inventory.query('packageName', name)) { - if (!shouldAudit(node, this[_omit], this.filterSet)) + if (!shouldAudit(node, this[_omit], this.filterSet)) { continue + } // if not vulnerable by this advisory, keep searching - if (!advisory.testVersion(node.version)) + if (!advisory.testVersion(node.version)) { continue + } // we will have loaded the source already if this is a metavuln - if (advisory.type === 'metavuln') + if (advisory.type === 'metavuln') { vuln.addVia(this.get(advisory.dependency)) + } // already marked this one, no need to do it again - if (vuln.nodes.has(node)) + if (vuln.nodes.has(node)) { continue + } // haven't marked this one yet. get its dependents. vuln.nodes.add(node) for (const { from: dep, spec } of node.edgesIn) { - if (dep.isTop && !vuln.topNodes.has(dep)) + if (dep.isTop && !vuln.topNodes.has(dep)) { this[_checkTopNode](dep, vuln, spec) - else { + } else { // calculate a metavuln, if necessary - p.push(this.calculator.calculate(dep.packageName, advisory).then(meta => { - if (meta.testVersion(dep.version, spec)) + const calc = this.calculator.calculate(dep.packageName, advisory) + p.push(calc.then(meta => { + if (meta.testVersion(dep.version, spec)) { advisories.add(meta) + } })) } } @@ -193,9 +204,11 @@ class AuditReport extends Map { // the nodes it references, then remove it from the advisory list. // happens when using omit with old audit endpoint. for (const advisory of vuln.advisories) { - const relevant = [...vuln.nodes].some(n => advisory.testVersion(n.version)) - if (!relevant) + const relevant = [...vuln.nodes] + .some(n => advisory.testVersion(n.version)) + if (!relevant) { vuln.deleteAdvisory(advisory) + } } } process.emit('timeEnd', 'auditReport:init') @@ -221,18 +234,21 @@ class AuditReport extends Map { // this will always be set to at least {name, versions:{}} const paku = vuln.packument - if (!vuln.testSpec(spec)) + if (!vuln.testSpec(spec)) { return true + } // similarly, even if we HAVE a packument, but we're looking for it // somewhere other than the registry, and we got something vulnerable, // then we're stuck with it. const specObj = npa(spec) - if (!specObj.registry) + if (!specObj.registry) { return false + } - if (specObj.subSpec) + if (specObj.subSpec) { spec = specObj.subSpec.rawSpec + } // We don't provide fixes for top nodes other than root, but we // still check to see if the node is fixable with a different version, @@ -287,8 +303,9 @@ class AuditReport extends Map { async [_getReport] () { // if we're not auditing, just return false - if (this.options.audit === false || this.tree.inventory.size === 1) + if (this.options.audit === false || this.tree.inventory.size === 1) { return null + } process.emit('time', 'auditReport:getReport') try { @@ -299,8 +316,9 @@ class AuditReport extends Map { // no sense asking if we don't have anything to audit, // we know it'll be empty - if (!Object.keys(body).length) + if (!Object.keys(body).length) { return null + } const res = await fetch('/-/npm/v1/security/advisories/bulk', { ...this.options, @@ -353,13 +371,15 @@ const prepareBulkData = (tree, omit, filterSet) => { for (const name of tree.inventory.query('packageName')) { const set = new Set() for (const node of tree.inventory.query('packageName', name)) { - if (!shouldAudit(node, omit, filterSet)) + if (!shouldAudit(node, omit, filterSet)) { continue + } set.add(node.version) } - if (set.size) + if (set.size) { payload[name] = [...set] + } } return payload } diff --git a/lib/calc-dep-flags.js b/lib/calc-dep-flags.js index 968fc83c5..95ecc8a61 100644 --- a/lib/calc-dep-flags.js +++ b/lib/calc-dep-flags.js @@ -11,7 +11,8 @@ const calcDepFlags = (tree, resetRoot = true) => { tree, visit: node => calcDepFlagsStep(node), filter: node => node, - getChildren: (node, tree) => [...tree.edgesOut.values()].map(edge => edge.to), + getChildren: (node, tree) => + [...tree.edgesOut.values()].map(edge => edge.to), }) return ret } @@ -39,8 +40,9 @@ const calcDepFlagsStep = (node) => { node.edgesOut.forEach(({peer, optional, dev, to}) => { // if the dep is missing, then its flags are already maximally unset - if (!to) + if (!to) { return + } // everything with any kind of edge into it is not extraneous to.extraneous = false @@ -59,28 +61,34 @@ const calcDepFlagsStep = (node) => { !node.optional && !optional const unsetPeer = !node.peer && !peer - if (unsetPeer) + if (unsetPeer) { unsetFlag(to, 'peer') + } - if (unsetDevOpt) + if (unsetDevOpt) { unsetFlag(to, 'devOptional') + } - if (unsetDev) + if (unsetDev) { unsetFlag(to, 'dev') + } - if (unsetOpt) + if (unsetOpt) { unsetFlag(to, 'optional') + } }) return node } const resetParents = (node, flag) => { - if (node[flag]) + if (node[flag]) { return + } - for (let p = node; p && (p === node || p[flag]); p = p.resolveParent) + for (let p = node; p && (p === node || p[flag]); p = p.resolveParent) { p[flag] = false + } } // typically a short walk, since it only traverses deps that @@ -92,8 +100,9 @@ const unsetFlag = (node, flag) => { tree: node, visit: node => { node.extraneous = node[flag] = false - if (node.isLink) + if (node.isLink) { node.target.extraneous = node.target[flag] = false + } }, getChildren: node => [...node.target.edgesOut.values()] .filter(edge => edge.to && edge.to[flag] && diff --git a/lib/can-place-dep.js b/lib/can-place-dep.js index 9601ad7af..7e2e1a0e2 100644 --- a/lib/can-place-dep.js +++ b/lib/can-place-dep.js @@ -64,14 +64,17 @@ class CanPlaceDep { } = options debug(() => { - if (!dep) + if (!dep) { throw new Error('no dep provided to CanPlaceDep') + } - if (!target) + if (!target) { throw new Error('no target provided to CanPlaceDep') + } - if (!edge) + if (!edge) { throw new Error('no edge provided to CanPlaceDep') + } this._treeSnapshot = JSON.stringify([...target.root.inventory.entries()] .map(([loc, {packageName, version, resolved}]) => { @@ -108,8 +111,9 @@ class CanPlaceDep { this.edgeOverride = !dep.satisfies(edge) this.canPlace = this.checkCanPlace() - if (!this.canPlaceSelf) + if (!this.canPlaceSelf) { this.canPlaceSelf = this.canPlace + } debug(() => { const treeSnapshot = JSON.stringify([...target.root.inventory.entries()] @@ -131,15 +135,18 @@ class CanPlaceDep { // if the dep failed to load, we're going to fail the build or // prune it out anyway, so just move forward placing/replacing it. - if (dep.errors.length) + if (dep.errors.length) { return current ? REPLACE : OK + } // cannot place peers inside their dependents, except for tops - if (targetEdge && targetEdge.peer && !target.isTop) + if (targetEdge && targetEdge.peer && !target.isTop) { return CONFLICT + } - if (targetEdge && !dep.satisfies(targetEdge) && targetEdge !== this.edge) + if (targetEdge && !dep.satisfies(targetEdge) && targetEdge !== this.edge) { return CONFLICT + } return current ? this.checkCanPlaceCurrent() : this.checkCanPlaceNoCurrent() } @@ -150,8 +157,9 @@ class CanPlaceDep { const { preferDedupe, explicitRequest, current, target, edge, dep } = this if (dep.matches(current)) { - if (current.satisfies(edge) || this.edgeOverride) + if (current.satisfies(edge) || this.edgeOverride) { return explicitRequest ? REPLACE : KEEP + } } const { version: curVer } = current @@ -163,19 +171,22 @@ class CanPlaceDep { * but it is theoretically possible if peer deps are pinned. In * that case we treat it like any other conflict, and keep trying */ const cpp = this.canPlacePeers(REPLACE) - if (cpp !== CONFLICT) + if (cpp !== CONFLICT) { return cpp + } } // ok, can't replace the current with new one, but maybe current is ok? - if (current.satisfies(edge) && (!explicitRequest || preferDedupe)) + if (current.satisfies(edge) && (!explicitRequest || preferDedupe)) { return KEEP + } // if we prefer deduping, then try replacing newer with older if (preferDedupe && !tryReplace && dep.canReplace(current)) { const cpp = this.canPlacePeers(REPLACE) - if (cpp !== CONFLICT) + if (cpp !== CONFLICT) { return cpp + } } // Check for interesting cases! @@ -185,29 +196,33 @@ class CanPlaceDep { const myDeepest = this.deepestNestingTarget // ok, i COULD be placed deeper, so leave the current one alone. - if (target !== myDeepest) + if (target !== myDeepest) { return CONFLICT + } // if we are not checking a peerDep, then we MUST place it here, in the // target that has a non-peer dep on it. - if (!edge.peer && target === edge.from) + if (!edge.peer && target === edge.from) { return this.canPlacePeers(REPLACE) + } // if we aren't placing a peer in a set, then we're done here. // This is ignored because it SHOULD be redundant, as far as I can tell, // with the deepest target and target===edge.from tests. But until we // can prove that isn't possible, this condition is here for safety. /* istanbul ignore if - allegedly impossible */ - if (!this.parent && !edge.peer) + if (!this.parent && !edge.peer) { return CONFLICT + } // check the deps in the peer group for each edge into that peer group // if ALL of them can be pushed deeper, or if it's ok to replace its // members with the contents of the new peer group, then we're good. let canReplace = true for (const [entryEdge, currentPeers] of peerEntrySets(current)) { - if (entryEdge === this.edge || entryEdge === this.peerEntryEdge) + if (entryEdge === this.edge || entryEdge === this.peerEntryEdge) { continue + } // First, see if it's ok to just replace the peerSet entirely. // we do this by walking out from the entryEdge, because in a case like @@ -231,8 +246,9 @@ class CanPlaceDep { const entryNode = entryEdge.to const entryRep = dep.parent.children.get(entryNode.name) if (entryRep) { - if (entryRep.canReplace(entryNode, dep.parent.children.keys())) + if (entryRep.canReplace(entryNode, dep.parent.children.keys())) { continue + } } let canClobber = !entryRep @@ -240,12 +256,14 @@ class CanPlaceDep { const peerReplacementWalk = new Set([entryNode]) OUTER: for (const currentPeer of peerReplacementWalk) { for (const edge of currentPeer.edgesOut.values()) { - if (!edge.peer || !edge.valid) + if (!edge.peer || !edge.valid) { continue + } const rep = dep.parent.children.get(edge.name) if (!rep) { - if (edge.to) + if (edge.to) { peerReplacementWalk.add(edge.to) + } continue } if (!rep.satisfies(edge)) { @@ -255,14 +273,16 @@ class CanPlaceDep { } } } - if (canClobber) + if (canClobber) { continue + } // ok, we can't replace, but maybe we can nest the current set deeper? let canNestCurrent = true for (const currentPeer of currentPeers) { - if (!canNestCurrent) + if (!canNestCurrent) { break + } // still possible to nest this peerSet const curDeep = deepestNestingTarget(entryEdge.from, currentPeer.name) @@ -270,14 +290,16 @@ class CanPlaceDep { canNestCurrent = false canReplace = false } - if (canNestCurrent) + if (canNestCurrent) { continue + } } } // if we can nest or replace all the current peer groups, we can replace. - if (canReplace) + if (canReplace) { return this.canPlacePeers(REPLACE) + } return CONFLICT } @@ -293,8 +315,9 @@ class CanPlaceDep { if (current) { for (const edge of current.edgesIn.values()) { if (edge.from.isDescendantOf(target) && edge.valid) { - if (!dep.satisfies(edge)) + if (!dep.satisfies(edge)) { return CONFLICT + } } } } @@ -316,8 +339,9 @@ class CanPlaceDep { get allChildren () { const set = new Set(this.children) for (const child of set) { - for (const grandchild of child.children) + for (const grandchild of child.children) { set.add(grandchild) + } } return [...set] } @@ -329,15 +353,17 @@ class CanPlaceDep { // check if peers can go here. returns state or CONFLICT canPlacePeers (state) { this.canPlaceSelf = state - if (this._canPlacePeers) + if (this._canPlacePeers) { return this._canPlacePeers + } // TODO: represent peerPath in ERESOLVE error somehow? const peerPath = [...this.peerPath, this.dep] let sawConflict = false for (const peerEdge of this.dep.edgesOut.values()) { - if (!peerEdge.peer || !peerEdge.to || peerPath.includes(peerEdge.to)) + if (!peerEdge.peer || !peerEdge.to || peerPath.includes(peerEdge.to)) { continue + } const peer = peerEdge.to // it may be the case that the *initial* dep can be nested, but a peer // of that dep needs to be placed shallower, because the target has @@ -354,13 +380,15 @@ class CanPlaceDep { }) /* istanbul ignore next */ debug(() => { - if (this.children.some(c => c.dep === cpp.dep)) + if (this.children.some(c => c.dep === cpp.dep)) { throw new Error('checking same dep repeatedly') + } }) this.children.push(cpp) - if (cpp.canPlace === CONFLICT) + if (cpp.canPlace === CONFLICT) { sawConflict = true + } } this._canPlacePeers = sawConflict ? CONFLICT : state diff --git a/lib/case-insensitive-map.js b/lib/case-insensitive-map.js index 8254c3f7a..016ce6017 100644 --- a/lib/case-insensitive-map.js +++ b/lib/case-insensitive-map.js @@ -10,8 +10,9 @@ module.exports = class Map extends OGMap { constructor (items = []) { super() this[_keys] = new OGMap() - for (const [key, val] of items) + for (const [key, val] of items) { this.set(key, val) + } } [_normKey] (key) { @@ -26,8 +27,9 @@ module.exports = class Map extends OGMap { set (key, val) { const normKey = this[_normKey](key) - if (this[_keys].has(normKey)) + if (this[_keys].has(normKey)) { super.delete(this[_keys].get(normKey)) + } this[_keys].set(normKey, key) return super.set(key, val) } diff --git a/lib/consistent-resolve.js b/lib/consistent-resolve.js index 322764824..e34e40a46 100644 --- a/lib/consistent-resolve.js +++ b/lib/consistent-resolve.js @@ -5,8 +5,9 @@ const npa = require('npm-package-arg') const relpath = require('./relpath.js') const consistentResolve = (resolved, fromPath, toPath, relPaths = false) => { - if (!resolved) + if (!resolved) { return null + } try { const hostedOpt = { noCommittish: false } diff --git a/lib/deepest-nesting-target.js b/lib/deepest-nesting-target.js index 9c433a765..2c6647f5d 100644 --- a/lib/deepest-nesting-target.js +++ b/lib/deepest-nesting-target.js @@ -5,11 +5,13 @@ const deepestNestingTarget = (start, name) => { for (const target of start.ancestry()) { // note: this will skip past the first target if edge is peer - if (target.isProjectRoot || !target.resolveParent || target.globalTop) + if (target.isProjectRoot || !target.resolveParent || target.globalTop) { return target + } const targetEdge = target.edgesOut.get(name) - if (!targetEdge || !targetEdge.peer) + if (!targetEdge || !targetEdge.peer) { return target + } } } diff --git a/lib/dep-valid.js b/lib/dep-valid.js index 01e5e21e9..d80437f20 100644 --- a/lib/dep-valid.js +++ b/lib/dep-valid.js @@ -44,8 +44,9 @@ const depValid = (child, requested, requestor) => { switch (requested.type) { case 'range': - if (requested.fetchSpec === '*') + if (requested.fetchSpec === '*') { return true + } // fallthrough case 'version': // if it's a version or a range other than '*', semver it @@ -108,17 +109,20 @@ const depValid = (child, requested, requestor) => { } const tarballValid = (child, requested, requestor) => { - if (child.isLink) + if (child.isLink) { return false + } - if (child.resolved) + if (child.resolved) { return child.resolved.replace(/\\/g, '/') === `file:${requested.fetchSpec.replace(/\\/g, '/')}` + } // if we have a legacy mutated package.json file. we can't be 100% // sure that it resolved to the same file, but if it was the same // request, that's a pretty good indicator of sameness. - if (child.package._requested) + if (child.package._requested) { return child.package._requested.saveSpec === requested.saveSpec + } // ok, we're probably dealing with some legacy cruft here, not much // we can do at this point unfortunately. diff --git a/lib/diff.js b/lib/diff.js index 2008ef7a3..0d17bde95 100644 --- a/lib/diff.js +++ b/lib/diff.js @@ -31,7 +31,12 @@ class Diff { this.removed = [] } - static calculate ({actual, ideal, filterNodes = [], shrinkwrapInflated = new Set()}) { + static calculate ({ + actual, + ideal, + filterNodes = [], + shrinkwrapInflated = new Set(), + }) { // if there's a filterNode, then: // - get the path from the root to the filterNode. The root or // root.target should have an edge either to the filterNode or @@ -43,8 +48,9 @@ class Diff { const extraneous = new Set() for (const filterNode of filterNodes) { const { root } = filterNode - if (root !== ideal && root !== actual) + if (root !== ideal && root !== actual) { throw new Error('invalid filterNode: outside idealTree/actualTree') + } const rootTarget = root.target const edge = [...rootTarget.edgesOut.values()].filter(e => { return e.to && (e.to === filterNode || e.to.target === filterNode) @@ -73,8 +79,9 @@ class Diff { : [...actualNode.edgesOut.values()].filter(e => e.to).map(e => e.to) if (actualNode) { for (const child of actualNode.children.values()) { - if (child.extraneous) + if (child.extraneous) { extraneous.add(child) + } } } @@ -82,8 +89,9 @@ class Diff { }, }) } - for (const extra of extraneous) + for (const extra of extraneous) { filterSet.add(extra) + } return depth({ tree: new Diff({actual, ideal, filterSet, shrinkwrapInflated}), @@ -94,23 +102,27 @@ class Diff { } const getAction = ({actual, ideal}) => { - if (!ideal) + if (!ideal) { return 'REMOVE' + } // bundled meta-deps are copied over to the ideal tree when we visit it, // so they'll appear to be missing here. There's no need to handle them // in the diff, though, because they'll be replaced at reify time anyway // Otherwise, add the missing node. - if (!actual) + if (!actual) { return ideal.inDepBundle ? null : 'ADD' + } // always ignore the root node - if (ideal.isRoot && actual.isRoot) + if (ideal.isRoot && actual.isRoot) { return null + } // if the versions don't match, it's a change no matter what - if (ideal.version !== actual.version) + if (ideal.version !== actual.version) { return 'CHANGE' + } const binsExist = ideal.binPaths.every((path) => existsSync(path)) @@ -125,33 +137,38 @@ const getAction = ({actual, ideal}) => { const noIntegrity = !ideal.integrity && !actual.integrity const noResolved = !ideal.resolved && !actual.resolved const resolvedMatch = ideal.resolved && ideal.resolved === actual.resolved - if (noIntegrity && binsExist && (resolvedMatch || noResolved)) + if (noIntegrity && binsExist && (resolvedMatch || noResolved)) { return null + } // otherwise, verify that it's the same bits // note that if ideal has integrity, and resolved doesn't, we treat // that as a 'change', so that it gets re-fetched and locked down. const integrityMismatch = !ideal.integrity || !actual.integrity || !ssri.parse(ideal.integrity).match(actual.integrity) - if (integrityMismatch || !binsExist) + if (integrityMismatch || !binsExist) { return 'CHANGE' + } return null } const allChildren = node => { - if (!node) + if (!node) { return new Map() + } // if the node is root, and also a link, then what we really // want is to traverse the target's children - if (node.isRoot && node.isLink) + if (node.isRoot && node.isLink) { return allChildren(node.target) + } const kids = new Map() for (const n of [node, ...node.fsChildren]) { - for (const kid of n.children.values()) + for (const kid of n.children.values()) { kids.set(kid.path, kid) + } } return kids } @@ -160,7 +177,14 @@ const allChildren = node => { // to create the diff tree const getChildren = diff => { const children = [] - const {actual, ideal, unchanged, removed, filterSet, shrinkwrapInflated} = diff + const { + actual, + ideal, + unchanged, + removed, + filterSet, + shrinkwrapInflated, + } = diff // Note: we DON'T diff fsChildren themselves, because they are either // included in the package contents, or part of some other project, and @@ -182,26 +206,45 @@ const getChildren = diff => { for (const path of paths) { const actual = actualKids.get(path) const ideal = idealKids.get(path) - diffNode(actual, ideal, children, unchanged, removed, filterSet, shrinkwrapInflated) + diffNode({ + actual, + ideal, + children, + unchanged, + removed, + filterSet, + shrinkwrapInflated, + }) } - if (diff.leaves && !children.length) + if (diff.leaves && !children.length) { diff.leaves.push(diff) + } return children } -const diffNode = (actual, ideal, children, unchanged, removed, filterSet, shrinkwrapInflated) => { - if (filterSet.size && !(filterSet.has(ideal) || filterSet.has(actual))) +const diffNode = ({ + actual, + ideal, + children, + unchanged, + removed, + filterSet, + shrinkwrapInflated, +}) => { + if (filterSet.size && !(filterSet.has(ideal) || filterSet.has(actual))) { return + } const action = getAction({actual, ideal}) // if it's a match, then get its children // otherwise, this is the child diff node if (action || (!shrinkwrapInflated.has(ideal) && ideal.hasShrinkwrap)) { - if (action === 'REMOVE') + if (action === 'REMOVE') { removed.push(actual) + } children.push(new Diff({actual, ideal, filterSet, shrinkwrapInflated})) } else { unchanged.push(ideal) @@ -227,13 +270,22 @@ const diffNode = (actual, ideal, children, unchanged, removed, filterSet, shrink if (actual && bd && bd.length) { const bundledChildren = [] for (const node of actual.children.values()) { - if (node.inBundle) + if (node.inBundle) { bundledChildren.push(node) + } } - for (const node of bundledChildren) + for (const node of bundledChildren) { node.parent = ideal + } } - children.push(...getChildren({actual, ideal, unchanged, removed, filterSet, shrinkwrapInflated})) + children.push(...getChildren({ + actual, + ideal, + unchanged, + removed, + filterSet, + shrinkwrapInflated, + })) } } diff --git a/lib/edge.js b/lib/edge.js index 9d5ece40e..777ecc44a 100644 --- a/lib/edge.js +++ b/lib/edge.js @@ -45,22 +45,26 @@ class Edge { constructor (options) { const { type, name, spec, accept, from } = options - if (typeof spec !== 'string') + if (typeof spec !== 'string') { throw new TypeError('must provide string spec') + } - if (type === 'workspace' && npa(spec).type !== 'directory') + if (type === 'workspace' && npa(spec).type !== 'directory') { throw new TypeError('workspace edges must be a symlink') + } this[_spec] = spec if (accept !== undefined) { - if (typeof accept !== 'string') + if (typeof accept !== 'string') { throw new TypeError('accept field must be a string if provided') + } this[_accept] = accept || '*' } - if (typeof name !== 'string') + if (typeof name !== 'string') { throw new TypeError('must provide dependency name') + } this[_name] = name if (!types.has(type)) { @@ -69,20 +73,23 @@ class Edge { `(valid types are: ${Edge.types.join(', ')})`) } this[_type] = type - if (!from) + if (!from) { throw new TypeError('must provide "from" node') + } this[_setFrom](from) this[_error] = this[_loadError]() this.overridden = false } satisfiedBy (node) { - return node.name === this.name && depValid(node, this.spec, this.accept, this.from) + return node.name === this.name && + depValid(node, this.spec, this.accept, this.from) } explain (seen = []) { - if (this[_explanation]) + if (this[_explanation]) { return this[_explanation] + } return this[_explanation] = this[_explain](seen) } @@ -101,8 +108,9 @@ class Edge { } get bundled () { - if (!this.from) + if (!this.from) { return false + } const { package: { bundleDependencies = [] } } = this.from return bundleDependencies.includes(this.name) } @@ -175,20 +183,24 @@ class Edge { this[_explanation] = null const newTo = this[_from].resolve(this.name) if (newTo !== this[_to]) { - if (this[_to]) + if (this[_to]) { this[_to].edgesIn.delete(this) + } this[_to] = newTo this[_error] = this[_loadError]() - if (this[_to]) + if (this[_to]) { this[_to].addEdgeIn(this) - } else if (hard) + } + } else if (hard) { this[_error] = this[_loadError]() + } } detach () { this[_explanation] = null - if (this[_to]) + if (this[_to]) { this[_to].edgesIn.delete(this) + } this[_from].edgesOut.delete(this.name) this[_to] = null this[_error] = 'DETACHED' @@ -198,8 +210,9 @@ class Edge { [_setFrom] (node) { this[_explanation] = null this[_from] = node - if (node.edgesOut.has(this.name)) + if (node.edgesOut.has(this.name)) { node.edgesOut.get(this.name).detach() + } node.addEdgeOut(this) this.reload() } diff --git a/lib/gather-dep-set.js b/lib/gather-dep-set.js index 1dc9a0b18..2c85a640f 100644 --- a/lib/gather-dep-set.js +++ b/lib/gather-dep-set.js @@ -14,8 +14,9 @@ const gatherDepSet = (set, edgeFilter) => { // as the deps set increases in size. for (const node of deps) { for (const edge of node.edgesOut.values()) { - if (edge.to && edgeFilter(edge)) + if (edge.to && edgeFilter(edge)) { deps.add(edge.to) + } } } diff --git a/lib/inventory.js b/lib/inventory.js index a4ae11c2a..34b6f98a8 100644 --- a/lib/inventory.js +++ b/lib/inventory.js @@ -13,11 +13,13 @@ const debug = require('./debug.js') const getLicense = pkg => { if (pkg) { const lic = pkg.license || pkg.licence - if (lic) + if (lic) { return lic + } const lics = pkg.licenses || pkg.licences - if (Array.isArray(lics)) + if (Array.isArray(lics)) { return lics[0] + } } } @@ -42,8 +44,9 @@ class Inventory extends Map { * filter (fn) { for (const node of this.values()) { - if (fn(node)) + if (fn(node)) { yield node + } } } @@ -62,8 +65,9 @@ class Inventory extends Map { const current = super.get(node[this.primaryKey]) if (current) { - if (current === node) + if (current === node) { return + } this.delete(current) } super.set(node[this.primaryKey], node) @@ -85,8 +89,9 @@ class Inventory extends Map { } delete (node) { - if (!this.has(node)) + if (!this.has(node)) { return + } super.delete(node[this.primaryKey]) for (const [key, map] of this[_index].entries()) { @@ -95,8 +100,9 @@ class Inventory extends Map { const set = map.get(val) if (set) { set.delete(node) - if (set.size === 0) + if (set.size === 0) { map.delete(node[key]) + } } } } diff --git a/lib/link.js b/lib/link.js index 4d15428d8..0289e0415 100644 --- a/lib/link.js +++ b/lib/link.js @@ -11,8 +11,9 @@ class Link extends Node { constructor (options) { const { root, realpath, target, parent, fsParent } = options - if (!realpath && !(target && target.path)) + if (!realpath && !(target && target.path)) { throw new TypeError('must provide realpath for Link node') + } super({ ...options, @@ -23,11 +24,11 @@ class Link extends Node { : null), }) - if (target) + if (target) { this.target = target - else if (this.realpath === this.root.path) + } else if (this.realpath === this.root.path) { this.target = this.root - else { + } else { this.target = new Node({ ...options, path: realpath, @@ -48,8 +49,9 @@ class Link extends Node { set target (target) { const current = this[_target] - if (target === current) + if (target === current) { return + } if (current && current.then) { debug(() => { @@ -72,25 +74,28 @@ class Link extends Node { } if (!target) { - if (current && current.linksIn) + if (current && current.linksIn) { current.linksIn.delete(this) + } if (this.path) { this[_delistFromMeta]() this[_target] = null this.package = {} this[_refreshLocation]() - } else + } else { this[_target] = null + } return } if (!this.path) { // temp node pending assignment to a tree // we know it's not in the inventory yet, because no path. - if (target.path) + if (target.path) { this.realpath = target.path - else + } else { target.path = target.realpath = this.realpath + } target.root = this.root this[_target] = target target.linksIn.add(this) diff --git a/lib/node.js b/lib/node.js index 5616019dd..a872f2480 100644 --- a/lib/node.js +++ b/lib/node.js @@ -120,8 +120,9 @@ class Node { // should be equal if not a link this.path = path ? resolve(path) : null - if (!this.name && (!this.path || this.path !== dirname(this.path))) + if (!this.name && (!this.path || this.path !== dirname(this.path))) { throw new TypeError('could not detect node name from path or package') + } this.realpath = !this.isLink ? this.path : resolve(realpath) @@ -142,8 +143,9 @@ class Node { // // Otherwise, hopefully a shrinkwrap will help us out. const resolved = consistentResolve(pkg._resolved) - if (resolved && !(/^file:/.test(resolved) && pkg._where)) + if (resolved && !(/^file:/.test(resolved) && pkg._where)) { this.resolved = resolved + } } this.integrity = integrity || pkg._integrity || null this.hasShrinkwrap = hasShrinkwrap || pkg._hasShrinkwrap || false @@ -215,18 +217,21 @@ class Node { // see parent/root setters below. // root is set to parent's root if we have a parent, otherwise if it's // null, then it's set to the node itself. - if (!parent && !fsParent) + if (!parent && !fsParent) { this.root = root || null + } // mostly a convenience for testing, but also a way to create // trees in a more declarative way than setting parent on each if (children) { - for (const c of children) + for (const c of children) { new Node({ ...c, parent: this }) + } } if (fsChildren) { - for (const c of fsChildren) + for (const c of fsChildren) { new Node({ ...c, fsParent: this }) + } } // now load all the dep edges @@ -239,8 +244,9 @@ class Node { set meta (meta) { this[_meta] = meta - if (meta) + if (meta) { meta.add(this) + } } get global () { @@ -260,8 +266,9 @@ class Node { // deletes edges if they already exists if (this[_workspaces]) { for (const name of this[_workspaces].keys()) { - if (!workspaces.has(name)) + if (!workspaces.has(name)) { this.edgesOut.get(name).detach() + } } } @@ -271,8 +278,9 @@ class Node { } get binPaths () { - if (!this.parent) + if (!this.parent) { return [] + } return getBinPaths({ pkg: this[_package], @@ -319,8 +327,9 @@ class Node { // only do this more than once at the root level, so the resolve() calls // are only one level deep, and there's not much to be saved, anyway. // simpler to just toss them all out. - for (const edge of this.edgesOut.values()) + for (const edge of this.edgesOut.values()) { edge.detach() + } this[_explanation] = null /* istanbul ignore next - should be impossible */ @@ -341,8 +350,9 @@ class Node { // node.explain(nodes seen already, edge we're trying to satisfy // if edge is not specified, it lists every edge into the node. explain (edge = null, seen = []) { - if (this[_explanation]) + if (this[_explanation]) { return this[_explanation] + } return this[_explanation] = this[_explain](edge, seen) } @@ -374,11 +384,13 @@ class Node { } } - if (this.sourceReference) + if (this.sourceReference) { return this.sourceReference.explain(edge, seen) + } - if (seen.includes(this)) + if (seen.includes(this)) { return why + } why.location = this.location why.isWorkspace = this.isWorkspace @@ -387,56 +399,64 @@ class Node { seen = seen.concat(this) why.dependents = [] - if (edge) + if (edge) { why.dependents.push(edge.explain(seen)) - else { + } else { // ignore invalid edges, since those aren't satisfied by this thing, // and are not keeping it held in this spot anyway. const edges = [] for (const edge of this.edgesIn) { - if (!edge.valid && !edge.from.isProjectRoot) + if (!edge.valid && !edge.from.isProjectRoot) { continue + } edges.push(edge) } - for (const edge of edges) + for (const edge of edges) { why.dependents.push(edge.explain(seen)) + } } - if (this.linksIn.size) + if (this.linksIn.size) { why.linksIn = [...this.linksIn].map(link => link[_explain](edge, seen)) + } return why } isDescendantOf (node) { for (let p = this; p; p = p.resolveParent) { - if (p === node) + if (p === node) { return true + } } return false } getBundler (path = []) { // made a cycle, definitely not bundled! - if (path.includes(this)) + if (path.includes(this)) { return null + } path.push(this) const parent = this[_parent] - if (!parent) + if (!parent) { return null + } const pBundler = parent.getBundler(path) - if (pBundler) + if (pBundler) { return pBundler + } const ppkg = parent.package const bd = ppkg && ppkg.bundleDependencies // explicit bundling - if (Array.isArray(bd) && bd.includes(this.name)) + if (Array.isArray(bd) && bd.includes(this.name)) { return parent + } // deps that are deduped up to the bundling level are bundled. // however, if they get their dep met further up than that, @@ -444,11 +464,13 @@ class Node { // unmet bundled deps will not cause your deps to be bundled. for (const edge of this.edgesIn) { const eBundler = edge.from.getBundler(path) - if (!eBundler) + if (!eBundler) { continue + } - if (eBundler === parent) + if (eBundler === parent) { return eBundler + } } return null @@ -467,8 +489,9 @@ class Node { } get isWorkspace () { - if (this.isProjectRoot) + if (this.isProjectRoot) { return false + } const { root } = this const { type, to } = root.edgesOut.get(this.packageName) || {} return type === 'workspace' && to && (to.target === this || to === this) @@ -486,15 +509,17 @@ class Node { } * ancestry () { - for (let anc = this; anc; anc = anc.resolveParent) + for (let anc = this; anc; anc = anc.resolveParent) { yield anc + } } set root (root) { // setting to null means this is the new root // should only ever be one step - while (root && root.root !== root) + while (root && root.root !== root) { root = root.root + } root = root || this @@ -504,8 +529,9 @@ class Node { // can't set the root (yet) if there's no way to determine location // this allows us to do new Node({...}) and then set the root later. // just make the assignment so we don't lose it, and move on. - if (!this.path || !root.realpath || !root.path) + if (!this.path || !root.realpath || !root.path) { return this[_root] = root + } // temporarily become a root node this[_root] = this @@ -521,8 +547,9 @@ class Node { if (this.isLink) { if (target) { target.linksIn.delete(this) - if (target.root === this) + if (target.root === this) { target[_delistFromMeta]() + } } this[_target] = null } @@ -539,16 +566,17 @@ class Node { this[_fsParent] = null } - if (root === this) + if (root === this) { this[_refreshLocation]() - else { + } else { // setting to some different node. const loc = relpath(root.realpath, this.path) const current = root.inventory.get(loc) // clobber whatever is there now - if (current) + if (current) { current.root = null + } this[_root] = root // set this.location and add to inventory @@ -556,8 +584,9 @@ class Node { // try to find our parent/fsParent in the new root inventory for (const p of walkUp(dirname(this.path))) { - if (p === this.path) + if (p === this.path) { continue + } const ploc = relpath(root.realpath, p) const parent = root.inventory.get(ploc) if (parent) { @@ -576,8 +605,9 @@ class Node { const isParent = this.location === childLoc if (isParent) { const oldChild = parent.children.get(this.name) - if (oldChild && oldChild !== this) + if (oldChild && oldChild !== this) { oldChild.root = null + } if (this.parent) { this.parent.children.delete(this.name) this.parent[_reloadNamedEdges](this.name) @@ -586,13 +616,15 @@ class Node { this[_parent] = parent // don't do it for links, because they don't have a target yet // we'll hit them up a bit later on. - if (!this.isLink) + if (!this.isLink) { parent[_reloadNamedEdges](this.name) + } } else { /* istanbul ignore if - should be impossible, since we break * all fsParent/child relationships when moving? */ - if (this.fsParent) + if (this.fsParent) { this.fsParent.fsChildren.delete(this) + } parent.fsChildren.add(this) this[_fsParent] = parent } @@ -601,10 +633,11 @@ class Node { } // if it doesn't have a parent, it's a top node - if (!this.parent) + if (!this.parent) { root.tops.add(this) - else + } else { root.tops.delete(this) + } // assign parentage for any nodes that need to have this as a parent // this can happen when we have a node at nm/a/nm/b added *before* @@ -614,24 +647,30 @@ class Node { const nmloc = `${this.location}${this.location ? '/' : ''}node_modules/` const isChild = n => n.location === nmloc + n.name // check dirname so that /foo isn't treated as the fsparent of /foo-bar - const isFsChild = n => dirname(n.path).startsWith(this.path) && - n !== this && - !n.parent && - (!n.fsParent || n.fsParent === this || dirname(this.path).startsWith(n.fsParent.path)) + const isFsChild = n => { + return dirname(n.path).startsWith(this.path) && + n !== this && + !n.parent && + (!n.fsParent || + n.fsParent === this || + dirname(this.path).startsWith(n.fsParent.path)) + } const isKid = n => isChild(n) || isFsChild(n) // only walk top nodes, since anything else already has a parent. for (const child of root.tops) { - if (!isKid(child)) + if (!isKid(child)) { continue + } // set up the internal parentage links - if (this.isLink) + if (this.isLink) { child.root = null - else { + } else { // can't possibly have a parent, because it's in tops - if (child.fsParent) + if (child.fsParent) { child.fsParent.fsChildren.delete(child) + } child[_fsParent] = null if (isChild(child)) { this.children.set(child.name, child) @@ -648,13 +687,15 @@ class Node { // to that realpath, or a thing at that realpath if we're adding a link // (if we're adding a regular node, we already deleted the old one) for (const node of root.inventory.query('realpath', this.realpath)) { - if (node === this) + if (node === this) { continue + } /* istanbul ignore next - should be impossible */ debug(() => { - if (node.root !== root) + if (node.root !== root) { throw new Error('inventory contains node from other root') + } }) if (this.isLink) { @@ -663,8 +704,9 @@ class Node { this[_package] = target.package target.linksIn.add(this) // reload edges here, because now we have a target - if (this.parent) + if (this.parent) { this.parent[_reloadNamedEdges](this.name) + } break } else { /* istanbul ignore else - should be impossible */ @@ -672,8 +714,9 @@ class Node { node[_target] = this node[_package] = this.package this.linksIn.add(node) - if (node.parent) + if (node.parent) { node.parent[_reloadNamedEdges](node.name) + } } else { debug(() => { throw Object.assign(new Error('duplicate node in root setter'), { @@ -690,14 +733,16 @@ class Node { // reload all edgesIn where the root doesn't match, so we don't have // cross-tree dependency graphs for (const edge of this.edgesIn) { - if (edge.from.root !== root) + if (edge.from.root !== root) { edge.reload() + } } // reload all edgesOut where root doens't match, or is missing, since // it might not be missing in the new tree for (const edge of this.edgesOut.values()) { - if (!edge.to || edge.to.root !== root) + if (!edge.to || edge.to.root !== root) { edge.reload() + } } // now make sure our family comes along for the ride! @@ -721,15 +766,17 @@ class Node { } } for (const child of family) { - if (child.root !== root) + if (child.root !== root) { child.root = root + } } // if we had a target, and didn't find one in the new root, then bring // it over as well, but only if we're setting the link into a new root, // as we don't want to lose the target any time we remove a link. - if (this.isLink && target && !this.target && root !== this) + if (this.isLink && target && !this.target && root !== this) { target.root = root + } // tree should always be valid upon root setter completion. treeCheck(this) @@ -741,11 +788,13 @@ class Node { } [_loadWorkspaces] () { - if (!this[_workspaces]) + if (!this[_workspaces]) { return + } - for (const [name, path] of this[_workspaces].entries()) + for (const [name, path] of this[_workspaces].entries()) { new Edge({ from: this, name, spec: `file:${path}`, type: 'workspace' }) + } } [_loadDeps] () { @@ -764,10 +813,11 @@ class Node { const peerDependencies = {} const peerOptional = {} for (const [name, dep] of Object.entries(pd)) { - if (pm[name] && pm[name].optional) + if (pm[name] && pm[name].optional) { peerOptional[name] = dep - else + } else { peerDependencies[name] = dep + } } this[_loadDepType](peerDependencies, 'peer') this[_loadDepType](peerOptional, 'peerOptional') @@ -784,8 +834,9 @@ class Node { } = sourceReference || {} const thisDev = isTop && !globalTop && path const srcDev = !sourceReference || srcTop && !srcGlobalTop && srcPath - if (thisDev && srcDev) + if (thisDev && srcDev) { this[_loadDepType](this.package.devDependencies, 'dev') + } } [_loadDepType] (deps, type) { @@ -794,8 +845,9 @@ class Node { // prioritize a new edge over an existing one for (const [name, spec] of Object.entries(deps || {})) { const current = this.edgesOut.get(name) - if (!current || current.type !== 'workspace') + if (!current || current.type !== 'workspace') { new Edge({ from: this, name, spec, accept: ad[name], type }) + } } } @@ -803,25 +855,29 @@ class Node { const parent = this[_fsParent] /* istanbul ignore next - should be impossible */ debug(() => { - if (parent === this) + if (parent === this) { throw new Error('node set to its own fsParent') + } }) return parent } set fsParent (fsParent) { if (!fsParent) { - if (this[_fsParent]) + if (this[_fsParent]) { this.root = null + } return } debug(() => { - if (fsParent === this) + if (fsParent === this) { throw new Error('setting node to its own fsParent') + } - if (fsParent.realpath === this.realpath) + if (fsParent.realpath === this.realpath) { throw new Error('setting fsParent to same path') + } // the initial set MUST be an actual walk-up from the realpath // subsequent sets will re-root on the new fsParent's path. @@ -837,16 +893,19 @@ class Node { } }) - if (fsParent.isLink) + if (fsParent.isLink) { fsParent = fsParent.target + } // setting a thing to its own fsParent is not normal, but no-op for safety - if (this === fsParent || fsParent.realpath === this.realpath) + if (this === fsParent || fsParent.realpath === this.realpath) { return + } // nothing to do - if (this[_fsParent] === fsParent) + if (this[_fsParent] === fsParent) { return + } const oldFsParent = this[_fsParent] const newPath = !oldFsParent ? this.path @@ -874,11 +933,13 @@ class Node { } // update this.path/realpath for this and all children/fsChildren - if (pathChange) + if (pathChange) { this[_changePath](newPath) + } - if (oldParent) + if (oldParent) { oldParent[_reloadNamedEdges](oldName) + } // clobbers anything at that path, resets all appropriate references this.root = fsParent.root @@ -894,11 +955,13 @@ class Node { // will go ahead and create the invalid state, and then try to resolve // it with more tree construction, because it's a user request. canReplaceWith (node, ignorePeers = []) { - if (node.name !== this.name) + if (node.name !== this.name) { return false + } - if (node.packageName !== this.packageName) + if (node.packageName !== this.packageName) { return false + } ignorePeers = new Set(ignorePeers) @@ -915,12 +978,14 @@ class Node { edge.from.parent === this.parent && edge.peer && ignorePeers.has(edge.from.name) - if (ignored) + if (ignored) { continue + } // only care about edges that don't originate from this node - if (!depSet.has(edge.from) && !edge.satisfiedBy(node)) + if (!depSet.has(edge.from) && !edge.satisfiedBy(node)) { return false + } } return true @@ -935,41 +1000,49 @@ class Node { // to if it was removed, or nothing is depending on it in the first place. canDedupe (preferDedupe = false) { // not allowed to mess with shrinkwraps or bundles - if (this.inDepBundle || this.inShrinkwrap) + if (this.inDepBundle || this.inShrinkwrap) { return false + } // it's a top level pkg, or a dep of one - if (!this.resolveParent || !this.resolveParent.resolveParent) + if (!this.resolveParent || !this.resolveParent.resolveParent) { return false + } // no one wants it, remove it - if (this.edgesIn.size === 0) + if (this.edgesIn.size === 0) { return true + } const other = this.resolveParent.resolveParent.resolve(this.name) // nothing else, need this one - if (!other) + if (!other) { return false + } // if it's the same thing, then always fine to remove - if (other.matches(this)) + if (other.matches(this)) { return true + } // if the other thing can't replace this, then skip it - if (!other.canReplace(this)) + if (!other.canReplace(this)) { return false + } // if we prefer dedupe, or if the version is greater/equal, take the other - if (preferDedupe || semver.gte(other.version, this.version)) + if (preferDedupe || semver.gte(other.version, this.version)) { return true + } return false } satisfies (requested) { - if (requested instanceof Edge) + if (requested instanceof Edge) { return this.name === requested.name && requested.satisfiedBy(this) + } const parsed = npa(requested) const { name = this.name, rawSpec: spec } = parsed @@ -983,29 +1056,35 @@ class Node { matches (node) { // if the nodes are literally the same object, obviously a match. - if (node === this) + if (node === this) { return true + } // if the names don't match, they're different things, even if // the package contents are identical. - if (node.name !== this.name) + if (node.name !== this.name) { return false + } // if they're links, they match if the targets match - if (this.isLink) + if (this.isLink) { return node.isLink && this.target.matches(node.target) + } // if they're two project root nodes, they're different if the paths differ - if (this.isProjectRoot && node.isProjectRoot) + if (this.isProjectRoot && node.isProjectRoot) { return this.path === node.path + } // if the integrity matches, then they're the same. - if (this.integrity && node.integrity) + if (this.integrity && node.integrity) { return this.integrity === node.integrity + } // if no integrity, check resolved - if (this.resolved && node.resolved) + if (this.resolved && node.resolved) { return this.resolved === node.resolved + } // if no resolved, check both package name and version // otherwise, conclude that they are different things @@ -1031,39 +1110,44 @@ class Node { // parent's children map, and leave it at that. const nameMatch = node.parent && node.parent.children.get(this.name) === node - if (nameMatch) + if (nameMatch) { this.path = resolve(node.parent.path, 'node_modules', this.name) - else { + } else { this.path = node.path this.name = node.name } - if (!this.isLink) + if (!this.isLink) { this.realpath = this.path + } this[_refreshLocation]() // keep children when a node replaces another if (!this.isLink) { - for (const kid of node.children.values()) + for (const kid of node.children.values()) { kid.parent = this + } } - if (!node.isRoot) + if (!node.isRoot) { this.root = node.root + } treeCheck(this) } get inShrinkwrap () { - return this.parent && (this.parent.hasShrinkwrap || this.parent.inShrinkwrap) + return this.parent && + (this.parent.hasShrinkwrap || this.parent.inShrinkwrap) } get parent () { const parent = this[_parent] /* istanbul ignore next - should be impossible */ debug(() => { - if (parent === this) + if (parent === this) { throw new Error('node set to its own parent') + } }) return parent } @@ -1083,23 +1167,27 @@ class Node { if (!parent) { // but only delete it if we actually had a parent in the first place // otherwise it's just setting to null when it's already null - if (this[_parent]) + if (this[_parent]) { this.root = null + } return } - if (parent.isLink) + if (parent.isLink) { parent = parent.target + } // setting a thing to its own parent is not normal, but no-op for safety - if (this === parent) + if (this === parent) { return + } const oldParent = this[_parent] // nothing to do - if (oldParent === parent) + if (oldParent === parent) { return + } // ok now we know something is actually changing, and parent is not a link const newPath = resolve(parent.path, 'node_modules', this.name) @@ -1116,8 +1204,9 @@ class Node { } // update this.path/realpath for this and all children/fsChildren - if (pathChange) + if (pathChange) { this[_changePath](newPath) + } // clobbers anything at that path, resets all appropriate references this.root = parent.root @@ -1127,16 +1216,19 @@ class Node { // Removes the node from its root the metadata and inventory. [_delistFromMeta] () { const root = this.root - if (!root.realpath || !this.path) + if (!root.realpath || !this.path) { return + } root.inventory.delete(this) root.tops.delete(this) - if (root.meta) + if (root.meta) { root.meta.delete(this.path) + } /* istanbul ignore next - should be impossible */ debug(() => { - if ([...root.inventory.values()].includes(this)) + if ([...root.inventory.values()].includes(this)) { throw new Error('failed to delist') + } }) } @@ -1148,8 +1240,9 @@ class Node { this.path = newPath const namePattern = /(?:^|\/|\\)node_modules[\\/](@[^/\\]+[\\/][^\\/]+|[^\\/]+)$/ const nameChange = newPath.match(namePattern) - if (nameChange && this.name !== nameChange[1]) + if (nameChange && this.name !== nameChange[1]) { this.name = nameChange[1].replace(/\\/g, '/') + } // if we move a link target, update link realpaths if (!this.isLink) { @@ -1161,10 +1254,12 @@ class Node { } } // if we move /x to /y, then a module at /x/a/b becomes /y/a/b - for (const child of this.fsChildren) + for (const child of this.fsChildren) { child[_changePath](resolve(newPath, relative(oldPath, child.path))) - for (const [name, child] of this.children.entries()) + } + for (const [name, child] of this.children.entries()) { child[_changePath](resolve(newPath, 'node_modules', name)) + } this[_refreshLocation]() } @@ -1179,8 +1274,9 @@ class Node { this.location = loc root.inventory.add(this) - if (root.meta) + if (root.meta) { root.meta.add(this) + } } addEdgeOut (edge) { @@ -1191,8 +1287,9 @@ class Node { this.edgesIn.add(edge) // try to get metadata from the yarn.lock file - if (this.root.meta) + if (this.root.meta) { this.root.meta.addEdge(edge) + } } [_reloadNamedEdges] (name, rootLoc = this.location) { @@ -1202,13 +1299,16 @@ class Node { edge.to.location === `${rootLoc}/node_modules/${edge.name}` const sameResolved = edge && this.resolve(name) === edge.to const recheck = rootLocResolved || !sameResolved - if (edge && recheck) + if (edge && recheck) { edge.reload(true) - for (const c of this.children.values()) + } + for (const c of this.children.values()) { c[_reloadNamedEdges](name, rootLoc) + } - for (const c of this.fsChildren) + for (const c of this.fsChildren) { c[_reloadNamedEdges](name, rootLoc) + } } get isLink () { @@ -1255,15 +1355,18 @@ class Node { /* istanbul ignore next - should be impossible, * but I keep doing this mistake in tests */ debug(() => { - if (typeof name !== 'string' || !name) + if (typeof name !== 'string' || !name) { throw new Error('non-string passed to Node.resolve') + } }) const mine = this.children.get(name) - if (mine) + if (mine) { return mine + } const resolveParent = this.resolveParent - if (resolveParent) + if (resolveParent) { return resolveParent.resolve(name) + } return null } diff --git a/lib/optional-set.js b/lib/optional-set.js index 9472158bc..9f5184ea0 100644 --- a/lib/optional-set.js +++ b/lib/optional-set.js @@ -10,8 +10,9 @@ const gatherDepSet = require('./gather-dep-set.js') const optionalSet = node => { - if (!node.optional) + if (!node.optional) { return new Set() + } // start with the node, then walk up the dependency graph until we // get to the boundaries that define the optional set. since the @@ -21,8 +22,9 @@ const optionalSet = node => { const set = new Set([node]) for (const node of set) { for (const edge of node.edgesIn) { - if (!edge.optional) + if (!edge.optional) { set.add(edge.from) + } } } diff --git a/lib/peer-entry-sets.js b/lib/peer-entry-sets.js index 11f9a4316..2c4322ee6 100644 --- a/lib/peer-entry-sets.js +++ b/lib/peer-entry-sets.js @@ -15,12 +15,14 @@ const peerEntrySets = node => { const unionSet = new Set([node]) for (const node of unionSet) { for (const edge of node.edgesOut.values()) { - if (edge.valid && edge.peer && edge.to) + if (edge.valid && edge.peer && edge.to) { unionSet.add(edge.to) + } } for (const edge of node.edgesIn) { - if (edge.valid && edge.peer) + if (edge.valid && edge.peer) { unionSet.add(edge.from) + } } } const entrySets = new Map() @@ -28,16 +30,18 @@ const peerEntrySets = node => { for (const edge of peer.edgesIn) { // if not valid, it doesn't matter anyway. either it's been previously // overridden, or it's the thing we're interested in replacing. - if (!edge.valid) + if (!edge.valid) { continue + } // this is the entry point into the peer set if (!edge.peer || edge.from.isTop) { // get the subset of peer brought in by this peer entry edge const sub = new Set([peer]) for (const peer of sub) { for (const edge of peer.edgesOut.values()) { - if (edge.valid && edge.peer && edge.to) + if (edge.valid && edge.peer && edge.to) { sub.add(edge.to) + } } } // if this subset does not include the node we are focused on, @@ -60,8 +64,9 @@ const peerEntrySets = node => { // Edge(a->b) => Set(b, d, e, f, g) // Edge(a->d) => Set(d, e, f, g) // } - if (sub.has(node)) + if (sub.has(node)) { entrySets.set(edge, sub) + } } } } diff --git a/lib/place-dep.js b/lib/place-dep.js index c0023e74a..d7cc7d935 100644 --- a/lib/place-dep.js +++ b/lib/place-dep.js @@ -85,8 +85,9 @@ class PlaceDep { !edge.error && !explicitRequest && !updateNames.includes(edge.name) && - !this.isVulnerable(edge.to)) + !this.isVulnerable(edge.to)) { return + } // walk up the tree until we hit either a top/root node, or a place // where the dep is not a peer dep. @@ -110,8 +111,9 @@ class PlaceDep { // but we CAN place it under a, so the correct thing to do is keep // walking up the tree. const targetEdge = target.edgesOut.get(edge.name) - if (!target.isTop && targetEdge && targetEdge.peer) + if (!target.isTop && targetEdge && targetEdge.peer) { continue + } const cpd = new CanPlaceDep({ dep, @@ -141,34 +143,39 @@ class PlaceDep { // should treat (b) and (d) as OK, and place them in the last place // where they did not themselves conflict, and skip c@2 if conflict // is ok by virtue of being forced or not ours and not strict. - if (cpd.canPlaceSelf !== CONFLICT) + if (cpd.canPlaceSelf !== CONFLICT) { canPlaceSelf = cpd + } // we found a place this can go, along with all its peer friends. // we break when we get the first conflict - if (cpd.canPlace !== CONFLICT) + if (cpd.canPlace !== CONFLICT) { canPlace = cpd - else + } else { break + } // if it's a load failure, just plop it in the first place attempted, // since we're going to crash the build or prune it out anyway. // but, this will frequently NOT be a successful canPlace, because // it'll have no version or other information. - if (dep.errors.length) + if (dep.errors.length) { break + } // nest packages like npm v1 and v2 // very disk-inefficient - if (legacyBundling) + if (legacyBundling) { break + } // when installing globally, or just in global style, we never place // deps above the first level. if (globalStyle) { const rp = target.resolveParent - if (rp && rp.isProjectRoot) + if (rp && rp.isProjectRoot) { break + } } } @@ -183,8 +190,9 @@ class PlaceDep { if (!canPlace) { // if not forced, or it's our dep, or strictPeerDeps is set, then // this is an ERESOLVE error. - if (!this.conflictOk) + if (!this.conflictOk) { return this.failPeerConflict() + } // ok! we're gonna allow the conflict, but we should still warn // if we have a current, then we treat CONFLICT as a KEEP. @@ -237,8 +245,9 @@ class PlaceDep { // it's a conflict. Treat it as a KEEP, but warn and move on. if (placementType === KEEP) { // this was an overridden peer dep - if (edge.peer && !edge.valid) + if (edge.peer && !edge.valid) { this.warnPeerConflict() + } // if we get a KEEP in a update scenario, then we MAY have something // already duplicating this unnecessarily! For example: @@ -287,21 +296,24 @@ class PlaceDep { }) this.oldDep = target.children.get(this.name) - if (this.oldDep) + if (this.oldDep) { this.replaceOldDep() - else + } else { this.placed.parent = target + } // if it's an overridden peer dep, warn about it - if (edge.peer && !this.placed.satisfies(edge)) + if (edge.peer && !this.placed.satisfies(edge)) { this.warnPeerConflict() + } // If the edge is not an error, then we're updating something, and // MAY end up putting a better/identical node further up the tree in // a way that causes an unnecessary duplication. If so, remove the // now-unnecessary node. - if (edge.valid && edge.to && edge.to !== this.placed) + if (edge.valid && edge.to && edge.to !== this.placed) { this.pruneDedupable(edge.to, false) + } // in case we just made some duplicates that can be removed, // prune anything deeper in the tree that can be replaced by this @@ -310,8 +322,9 @@ class PlaceDep { this.pruneDedupable(node, false) // only walk the direct children of the ones we kept if (node.root === target.root) { - for (const kid of node.children.values()) + for (const kid of node.children.values()) { this.pruneDedupable(kid, false) + } } } } @@ -323,8 +336,9 @@ class PlaceDep { // otherwise they'd be gone and the peer set would change throughout // this loop. for (const peerEdge of this.placed.edgesOut.values()) { - if (peerEdge.valid || !peerEdge.peer || peerEdge.overridden) + if (peerEdge.valid || !peerEdge.peer || peerEdge.overridden) { continue + } const peer = virtualRoot.children.get(peerEdge.name) @@ -332,12 +346,14 @@ class PlaceDep { // it's an optional peer dep. If it's not being properly met (ie, // peerEdge.valid is false), then this is likely heading for an // ERESOLVE error, unless it can walk further up the tree. - if (!peer) + if (!peer) { continue + } // overridden peerEdge, just accept what's there already - if (!peer.satisfies(peerEdge)) + if (!peer.satisfies(peerEdge)) { continue + } this.children.push(new PlaceDep({ parent: this, @@ -363,8 +379,9 @@ class PlaceDep { // later anyway. const oldDeps = [] for (const [name, edge] of this.oldDep.edgesOut.entries()) { - if (!this.placed.edgesOut.has(name) && edge.to) + if (!this.placed.edgesOut.has(name) && edge.to) { oldDeps.push(...gatherDepSet([edge.to], e => e.to !== edge.to)) + } } this.placed.replace(this.oldDep) this.pruneForReplacement(this.placed, oldDeps) @@ -377,8 +394,9 @@ class PlaceDep { .filter(e => e.to && !e.valid).map(e => e.to)) for (const dep of oldDeps) { const set = gatherDepSet([dep], e => e.to !== dep && e.valid) - for (const dep of set) + for (const dep of set) { invalidDeps.add(dep) + } } // ignore dependency edges from the node being replaced, but @@ -388,8 +406,9 @@ class PlaceDep { edge.from !== node && edge.to !== node && edge.valid) // now just delete whatever's left, because it's junk - for (const dep of deps) + for (const dep of deps) { dep.root = null + } } // prune all the nodes in a branch of the tree that can be safely removed @@ -402,8 +421,9 @@ class PlaceDep { // the dep set, except for this node we're deduping, so that we // also prune deps that would be made extraneous. const deps = gatherDepSet([node], e => e.to !== node && e.valid) - for (const node of deps) + for (const node of deps) { node.root = null + } return } if (descend) { @@ -413,13 +433,15 @@ class PlaceDep { const nodeSort = (a, b) => a.location.localeCompare(b.location, 'en') const children = [...node.children.values()].sort(nodeSort) - for (const child of children) + for (const child of children) { this.pruneDedupable(child) + } const fsChildren = [...node.fsChildren].sort(nodeSort) for (const topNode of fsChildren) { const children = [...topNode.children.values()].sort(nodeSort) - for (const child of children) + for (const child of children) { this.pruneDedupable(child) + } } } } @@ -432,11 +454,13 @@ class PlaceDep { const { edge } = this.top const { from: node } = edge - if (node.isWorkspace || node.isProjectRoot) + if (node.isWorkspace || node.isProjectRoot) { return true + } - if (!edge.peer) + if (!edge.peer) { return false + } // re-entry case. check if any non-peer edges come from the project, // or any entryEdges on peer groups are from the root. @@ -446,13 +470,15 @@ class PlaceDep { hasPeerEdges = true continue } - if (edge.from.isWorkspace || edge.from.isProjectRoot) + if (edge.from.isWorkspace || edge.from.isProjectRoot) { return true + } } if (hasPeerEdges) { for (const edge of peerEntrySets(node).keys()) { - if (edge.from.isWorkspace || edge.from.isProjectRoot) + if (edge.from.isWorkspace || edge.from.isProjectRoot) { return true + } } } @@ -541,8 +567,9 @@ class PlaceDep { get allChildren () { const set = new Set(this.children) for (const child of set) { - for (const grandchild of child.children) + for (const grandchild of child.children) { set.add(grandchild) + } } return [...set] } diff --git a/lib/printable.js b/lib/printable.js index 4aa2fffd1..af24ccb95 100644 --- a/lib/printable.js +++ b/lib/printable.js @@ -7,45 +7,62 @@ const relpath = require('./relpath.js') class ArboristNode { constructor (tree, path) { this.name = tree.name - if (tree.packageName && tree.packageName !== this.name) + if (tree.packageName && tree.packageName !== this.name) { this.packageName = tree.packageName - if (tree.version) + } + if (tree.version) { this.version = tree.version + } this.location = tree.location this.path = tree.path - if (tree.realpath !== this.path) + if (tree.realpath !== this.path) { this.realpath = tree.realpath - if (tree.resolved !== null) + } + if (tree.resolved !== null) { this.resolved = tree.resolved - if (tree.extraneous) + } + if (tree.extraneous) { this.extraneous = true - if (tree.dev) + } + if (tree.dev) { this.dev = true - if (tree.optional) + } + if (tree.optional) { this.optional = true - if (tree.devOptional && !tree.dev && !tree.optional) + } + if (tree.devOptional && !tree.dev && !tree.optional) { this.devOptional = true - if (tree.peer) + } + if (tree.peer) { this.peer = true - if (tree.inBundle) + } + if (tree.inBundle) { this.bundled = true - if (tree.inDepBundle) + } + if (tree.inDepBundle) { this.bundler = tree.getBundler().location - if (tree.isProjectRoot) + } + if (tree.isProjectRoot) { this.isProjectRoot = true - if (tree.isWorkspace) + } + if (tree.isWorkspace) { this.isWorkspace = true + } const bd = tree.package && tree.package.bundleDependencies - if (bd && bd.length) + if (bd && bd.length) { this.bundleDependencies = bd - if (tree.inShrinkwrap) + } + if (tree.inShrinkwrap) { this.inShrinkwrap = true - else if (tree.hasShrinkwrap) + } else if (tree.hasShrinkwrap) { this.hasShrinkwrap = true - if (tree.error) + } + if (tree.error) { this.error = treeError(tree.error) - if (tree.errors && tree.errors.length) + } + if (tree.errors && tree.errors.length) { this.errors = tree.errors.map(treeError) + } // edgesOut sorted by name if (tree.edgesOut.size) { @@ -109,10 +126,12 @@ class Edge { this.type = edge.type this.name = edge.name this.spec = edge.spec || '*' - if (edge.error) + if (edge.error) { this.error = edge.error - if (edge.overridden) + } + if (edge.overridden) { this.overridden = edge.overridden + } } } @@ -151,8 +170,9 @@ class EdgeIn extends Edge { } const printableTree = (tree, path = []) => { - if (!tree) + if (!tree) { return tree + } const Cls = tree.isLink ? ArboristLink : tree.sourceReference ? ArboristVirtualNode diff --git a/lib/realpath.js b/lib/realpath.js index fa467c097..bc4bbbce3 100644 --- a/lib/realpath.js +++ b/lib/realpath.js @@ -14,18 +14,21 @@ const { resolve, basename, dirname } = require('path') const realpathCached = (path, rpcache, stcache, depth) => { // just a safety against extremely deep eloops /* istanbul ignore next */ - if (depth > 2000) + if (depth > 2000) { throw eloop(path) + } path = resolve(path) - if (rpcache.has(path)) + if (rpcache.has(path)) { return Promise.resolve(rpcache.get(path)) + } const dir = dirname(path) const base = basename(path) - if (base && rpcache.has(dir)) + if (base && rpcache.has(dir)) { return realpathChild(dir, base, rpcache, stcache, depth) + } // if it's the root, then we know it's real if (!base) { @@ -40,8 +43,9 @@ const realpathCached = (path, rpcache, stcache, depth) => { } const lstatCached = (path, stcache) => { - if (stcache.has(path)) + if (stcache.has(path)) { return Promise.resolve(stcache.get(path)) + } const p = lstat(path).then(st => { stcache.set(path, st) @@ -66,8 +70,9 @@ const realpathChild = (dir, base, rpcache, stcache, depth) => { const realdir = rpcache.get(dir) // that unpossible /* istanbul ignore next */ - if (typeof realdir === 'undefined') + if (typeof realdir === 'undefined') { throw new Error('in realpathChild without parent being in realpath cache') + } const realish = resolve(realdir, base) return lstatCached(realish, stcache).then(st => { @@ -78,8 +83,9 @@ const realpathChild = (dir, base, rpcache, stcache, depth) => { return readlink(realish).then(target => { const resolved = resolve(realdir, target) - if (realish === resolved) + if (realish === resolved) { throw eloop(realish) + } return realpathCached(resolved, rpcache, stcache, depth + 1) }).then(real => { diff --git a/lib/shrinkwrap.js b/lib/shrinkwrap.js index 83cb1f66f..6e7e0e31f 100644 --- a/lib/shrinkwrap.js +++ b/lib/shrinkwrap.js @@ -47,8 +47,9 @@ const readlink = promisify(fs.readlink) const lstat = promisify(fs.lstat) /* istanbul ignore next - version specific polyfill */ const readdir = async (path, opt) => { - if (!opt || !opt.withFileTypes) + if (!opt || !opt.withFileTypes) { return readdir_(path, opt) + } const ents = await readdir_(path, opt) if (typeof ents[0] === 'string') { return Promise.all(ents.map(async ent => { @@ -97,20 +98,22 @@ const consistentResolve = require('./consistent-resolve.js') const maybeReadFile = file => { return readFile(file, 'utf8').then(d => d, er => { /* istanbul ignore else - can't test without breaking module itself */ - if (er.code === 'ENOENT') + if (er.code === 'ENOENT') { return '' - else + } else { throw er + } }) } const maybeStatFile = file => { return stat(file).then(st => st.isFile(), er => { /* istanbul ignore else - can't test without breaking module itself */ - if (er.code === 'ENOENT') + if (er.code === 'ENOENT') { return null - else + } else { throw er + } }) } @@ -163,13 +166,16 @@ const assertNoNewer = async (path, data, lockTime, dir = path, seen = null) => { const rel = relpath(path, dir) if (dir !== path) { const dirTime = (await stat(dir)).mtime - if (dirTime > lockTime) + if (dirTime > lockTime) { throw 'out of date, updated: ' + rel - if (!isScope && !isNM && !data.packages[rel]) + } + if (!isScope && !isNM && !data.packages[rel]) { throw 'missing from lockfile: ' + rel + } seen.add(rel) - } else + } else { seen = new Set([rel]) + } const parent = isParent ? dir : resolve(dir, 'node_modules') const children = dir === path @@ -179,26 +185,29 @@ const assertNoNewer = async (path, data, lockTime, dir = path, seen = null) => { return children.catch(() => []) .then(ents => Promise.all(ents.map(async ent => { const child = resolve(parent, ent.name) - if (ent.isDirectory() && !/^\./.test(ent.name)) + if (ent.isDirectory() && !/^\./.test(ent.name)) { await assertNoNewer(path, data, lockTime, child, seen) - else if (ent.isSymbolicLink()) { + } else if (ent.isSymbolicLink()) { const target = resolve(parent, await readlink(child)) const tstat = await stat(target).catch( /* istanbul ignore next - windows */ () => null) seen.add(relpath(path, child)) /* istanbul ignore next - windows cannot do this */ - if (tstat && tstat.isDirectory() && !seen.has(relpath(path, target))) + if (tstat && tstat.isDirectory() && !seen.has(relpath(path, target))) { await assertNoNewer(path, data, lockTime, target, seen) + } } }))) .then(() => { - if (dir !== path) + if (dir !== path) { return + } // assert that all the entries in the lockfile were seen for (const loc of new Set(Object.keys(data.packages))) { - if (!seen.has(loc)) + if (!seen.has(loc)) { throw 'missing from node_modules: ' + loc + } } }) } @@ -252,39 +261,48 @@ class Shrinkwrap { const meta = {} pkgMetaKeys.forEach(key => { const val = metaFieldFromPkg(node.package, key) - if (val) + if (val) { meta[key.replace(/^_/, '')] = val + } }) // we only include name if different from the node path name, and for the // root to help prevent churn based on the name of the directory the // project is in const pname = node.packageName - if (pname && (node === node.root || pname !== node.name)) + if (pname && (node === node.root || pname !== node.name)) { meta.name = pname + } - if (node.isTop && node.package.devDependencies) + if (node.isTop && node.package.devDependencies) { meta.devDependencies = node.package.devDependencies + } nodeMetaKeys.forEach(key => { - if (node[key]) + if (node[key]) { meta[key] = node[key] + } }) const resolved = consistentResolve(node.resolved, node.path, path, true) - if (resolved) + if (resolved) { meta.resolved = resolved + } - if (node.extraneous) + if (node.extraneous) { meta.extraneous = true - else { - if (node.peer) + } else { + if (node.peer) { meta.peer = true - if (node.dev) + } + if (node.dev) { meta.dev = true - if (node.optional) + } + if (node.optional) { meta.optional = true - if (node.devOptional && !node.dev && !node.optional) + } + if (node.devOptional && !node.dev && !node.optional) { meta.devOptional = true + } } return meta } @@ -423,8 +441,9 @@ class Shrinkwrap { this.indent = indent !== undefined ? indent : this.indent this.newline = newline !== undefined ? newline : this.newline - if (!this.hiddenLockfile || !data.packages) + if (!this.hiddenLockfile || !data.packages) { return data + } // add a few ms just to account for jitter const lockTime = +(await stat(this.filename)).mtime + 10 @@ -467,8 +486,9 @@ class Shrinkwrap { // migrate a v1 package lock to the new format. const meta = this[_metaFromLock](location, name, lock) // dependencies nested under a link are actually under the link target - if (meta.link) + if (meta.link) { location = meta.resolved + } if (lock.dependencies) { for (const [name, dep] of Object.entries(lock.dependencies)) { const loc = location + (location ? '/' : '') + 'node_modules/' + name @@ -488,13 +508,15 @@ class Shrinkwrap { pkgMetaKeys.forEach(key => { const val = metaFieldFromPkg(pkg, key) const k = key.replace(/^_/, '') - if (val) + if (val) { root[k] = val + } }) for (const [loc, meta] of Object.entries(this.data.packages)) { - if (!meta.requires || !loc) + if (!meta.requires || !loc) { continue + } // resolve each require to a meta entry // if this node isn't optional, but the dep is, then it's an optionalDep @@ -523,27 +545,33 @@ class Shrinkwrap { [_resolveMetaNode] (loc, name) { for (let path = loc; true; path = path.replace(/(^|\/)[^/]*$/, '')) { const check = `${path}${path ? '/' : ''}node_modules/${name}` - if (this.data.packages[check]) + if (this.data.packages[check]) { return this.data.packages[check] + } - if (!path) + if (!path) { break + } } return null } [_lockFromLoc] (lock, path, i = 0) { - if (!lock) + if (!lock) { return null + } - if (path[i] === '') + if (path[i] === '') { i++ + } - if (i >= path.length) + if (i >= path.length) { return lock + } - if (!lock.dependencies) + if (!lock.dependencies) { return null + } return this[_lockFromLoc](lock.dependencies[path[i]], path, i + 1) } @@ -555,8 +583,9 @@ class Shrinkwrap { } delete (nodePath) { - if (!this.data) + if (!this.data) { throw new Error('run load() before getting or setting data') + } const location = this[_pathToLoc](nodePath) this[_awaitingUpdate].delete(location) @@ -564,22 +593,26 @@ class Shrinkwrap { const path = location.split(/(?:^|\/)node_modules\//) const name = path.pop() const pLock = this[_lockFromLoc](this.data, path) - if (pLock && pLock.dependencies) + if (pLock && pLock.dependencies) { delete pLock.dependencies[name] + } } get (nodePath) { - if (!this.data) + if (!this.data) { throw new Error('run load() before getting or setting data') + } const location = this[_pathToLoc](nodePath) - if (this[_awaitingUpdate].has(location)) + if (this[_awaitingUpdate].has(location)) { this[_updateWaitingNode](location) + } // first try to get from the newer spot, which we know has // all the things we need. - if (this.data.packages[location]) + if (this.data.packages[location]) { return this.data.packages[location] + } // otherwise, fall back to the legacy metadata, and hope for the best // get the node in the shrinkwrap corresponding to this spot @@ -595,8 +628,9 @@ class Shrinkwrap { // from a lockfile which may be outdated or incomplete. Since v1 // lockfiles used the "version" field to contain a variety of // different possible types of data, this gets a little complicated. - if (!lock) + if (!lock) { return {} + } // try to figure out a npm-package-arg spec from the lockfile entry // This will return null if we could not get anything valid out of it. @@ -613,29 +647,35 @@ class Shrinkwrap { } // also save the link target, omitting version since we don't know // what it is, but we know it isn't a link to itself! - if (!this.data.packages[target]) + if (!this.data.packages[target]) { this[_metaFromLock](target, name, { ...lock, version: null }) + } return this.data.packages[location] } const meta = {} // when calling loadAll we'll change these into proper dep objects - if (lock.requires && typeof lock.requires === 'object') + if (lock.requires && typeof lock.requires === 'object') { meta.requires = lock.requires + } - if (lock.optional) + if (lock.optional) { meta.optional = true - if (lock.dev) + } + if (lock.dev) { meta.dev = true + } // the root will typically have a name from the root project's // package.json file. - if (location === '') + if (location === '') { meta.name = lock.name + } // if we have integrity, save it now. - if (lock.integrity) + if (lock.integrity) { meta.integrity = lock.integrity + } if (lock.version && !lock.integrity) { // this is usually going to be a git url or symlink, but it could @@ -668,12 +708,13 @@ class Shrinkwrap { // have a fetchSpec equal to the fully resolved thing. // Registry deps, we take what's in the lockfile. if (lock.resolved || (spec.type && !spec.registry)) { - if (spec.registry) + if (spec.registry) { meta.resolved = lock.resolved - else if (spec.type === 'file') + } else if (spec.type === 'file') { meta.resolved = consistentResolve(spec, this.path, this.path, true) - else if (spec.fetchSpec) + } else if (spec.fetchSpec) { meta.resolved = spec.fetchSpec + } } // at this point, if still we don't have a version, do our best to @@ -685,32 +726,37 @@ class Shrinkwrap { versionFromTgz(spec.name, meta.resolved) if (fromTgz) { meta.version = fromTgz.version - if (fromTgz.name !== name) + if (fromTgz.name !== name) { meta.name = fromTgz.name + } } } else if (spec.type === 'alias') { meta.name = spec.subSpec.name meta.version = spec.subSpec.fetchSpec - } else if (spec.type === 'version') + } else if (spec.type === 'version') { meta.version = spec.fetchSpec + } // ok, I did my best! good luck! } - if (lock.bundled) + if (lock.bundled) { meta.inBundle = true + } // save it for next time return this.data.packages[location] = meta } add (node) { - if (!this.data) + if (!this.data) { throw new Error('run load() before getting or setting data') + } // will be actually updated on read const loc = relpath(this.path, node.path) - if (node.path === this.path) + if (node.path === this.path) { this.tree = node + } // if we have metadata about this node, and it's a match, then // try to decorate it. @@ -758,18 +804,21 @@ class Shrinkwrap { } addEdge (edge) { - if (!this.yarnLock || !edge.valid) + if (!this.yarnLock || !edge.valid) { return + } const { to: node } = edge // if it's already set up, nothing to do - if (node.resolved !== null && node.integrity !== null) + if (node.resolved !== null && node.integrity !== null) { return + } // if the yarn lock is empty, nothing to do - if (!this.yarnLock.entries || !this.yarnLock.entries.size) + if (!this.yarnLock.entries || !this.yarnLock.entries.size) { return + } // we relativize the path here because that's how it shows up in the lock // XXX how is this different from pathFixed above?? @@ -783,11 +832,13 @@ class Shrinkwrap { if (!entry || mismatch(node.version, entry.version) || mismatch(node.integrity, entry.integrity) || - mismatch(pathFixed, entry.resolved)) + mismatch(pathFixed, entry.resolved)) { return + } - if (entry.resolved && yarnRegRe.test(entry.resolved) && spec.registry) + if (entry.resolved && yarnRegRe.test(entry.resolved) && spec.registry) { entry.resolved = entry.resolved.replace(yarnRegRe, 'https://registry.npmjs.org/') + } node.integrity = node.integrity || entry.integrity || null node.resolved = node.resolved || @@ -804,30 +855,35 @@ class Shrinkwrap { commit () { if (this.tree) { - if (this.yarnLock) + if (this.yarnLock) { this.yarnLock.fromTree(this.tree) + } const root = Shrinkwrap.metaFromNode(this.tree.target, this.path) this.data.packages = {} - if (Object.keys(root).length) + if (Object.keys(root).length) { this.data.packages[''] = root + } for (const node of this.tree.root.inventory.values()) { // only way this.tree is not root is if the root is a link to it - if (node === this.tree || node.isRoot || node.location === '') + if (node === this.tree || node.isRoot || node.location === '') { continue + } const loc = relpath(this.path, node.path) this.data.packages[loc] = Shrinkwrap.metaFromNode(node, this.path) } } else if (this[_awaitingUpdate].size > 0) { - for (const loc of this[_awaitingUpdate].keys()) + for (const loc of this[_awaitingUpdate].keys()) { this[_updateWaitingNode](loc) + } } // hidden lockfiles don't include legacy metadata or a root entry if (this.hiddenLockfile) { delete this.data.packages[''] delete this.data.dependencies - } else if (this.tree) + } else if (this.tree) { this[_buildLegacyLockfile](this.tree, this.data) + } return this.data } @@ -836,8 +892,9 @@ class Shrinkwrap { if (node === this.tree) { // the root node lock.name = node.packageName || node.name - if (node.version) + if (node.version) { lock.version = node.version + } } // npm v6 and before tracked 'from', meaning "the request that led @@ -868,26 +925,29 @@ class Shrinkwrap { const spec = !edge ? rSpec : npa.resolve(node.name, edge.spec, edge.from.realpath) - if (node.isLink) + if (node.isLink) { lock.version = `file:${relpath(this.path, node.realpath)}` - else if (spec && (spec.type === 'file' || spec.type === 'remote')) + } else if (spec && (spec.type === 'file' || spec.type === 'remote')) { lock.version = spec.saveSpec - else if (spec && spec.type === 'git' || rSpec.type === 'git') { + } else if (spec && spec.type === 'git' || rSpec.type === 'git') { lock.version = node.resolved /* istanbul ignore else - don't think there are any cases where a git * spec (or indeed, ANY npa spec) doesn't have a .raw member */ - if (spec.raw) + if (spec.raw) { lock.from = spec.raw + } } else if (!node.isRoot && node.package && node.packageName && - node.packageName !== node.name) + node.packageName !== node.name) { lock.version = `npm:${node.packageName}@${node.version}` - else if (node.package && node.version) + } else if (node.package && node.version) { lock.version = node.version + } - if (node.inDepBundle) + if (node.inDepBundle) { lock.bundled = true + } // when we didn't resolve to git, file, or dir, and didn't request // git, file, dir, or remote, then the resolved value is necessary. @@ -899,77 +959,90 @@ class Shrinkwrap { spec.type !== 'directory' && spec.type !== 'git' && spec.type !== 'file' && - spec.type !== 'remote') + spec.type !== 'remote') { lock.resolved = node.resolved + } - if (node.integrity) + if (node.integrity) { lock.integrity = node.integrity + } - if (node.extraneous) + if (node.extraneous) { lock.extraneous = true - else if (!node.isLink) { - if (node.peer) + } else if (!node.isLink) { + if (node.peer) { lock.peer = true + } - if (node.devOptional && !node.dev && !node.optional) + if (node.devOptional && !node.dev && !node.optional) { lock.devOptional = true + } - if (node.dev) + if (node.dev) { lock.dev = true + } - if (node.optional) + if (node.optional) { lock.optional = true + } } const depender = node.target if (depender.edgesOut.size > 0) { if (node !== this.tree) { - lock.requires = [...depender.edgesOut.entries()].reduce((set, [k, v]) => { + const entries = [...depender.edgesOut.entries()] + lock.requires = entries.reduce((set, [k, v]) => { // omit peer deps from legacy lockfile requires field, because // npm v6 doesn't handle peer deps, and this triggers some bad // behavior if the dep can't be found in the dependencies list. const { spec, peer } = v - if (peer) + if (peer) { return set + } if (spec.startsWith('file:')) { // turn absolute file: paths into relative paths from the node // this especially shows up with workspace edges when the root // node is also a workspace in the set. const p = resolve(node.realpath, spec.substr('file:'.length)) set[k] = `file:${relpath(node.realpath, p)}` - } else + } else { set[k] = spec + } return set }, {}) - } else + } else { lock.requires = true + } } // now we walk the children, putting them in the 'dependencies' object const {children} = node.target - if (!children.size) + if (!children.size) { delete lock.dependencies - else { + } else { const kidPath = [...path, node.realpath] const dependencies = {} // skip any that are already in the descent path, so cyclical link // dependencies don't blow up with ELOOP. let found = false for (const [name, kid] of children.entries()) { - if (path.includes(kid.realpath)) + if (path.includes(kid.realpath)) { continue + } dependencies[name] = this[_buildLegacyLockfile](kid, {}, kidPath) found = true } - if (found) + if (found) { lock.dependencies = dependencies + } } return lock } save (options = {}) { - if (!this.data) + if (!this.data) { throw new Error('run load() before saving data') + } const { format = true } = options const defaultIndent = this.indent || 2 diff --git a/lib/signal-handling.js b/lib/signal-handling.js index 1051cd593..0afbb05dc 100644 --- a/lib/signal-handling.js +++ b/lib/signal-handling.js @@ -13,8 +13,9 @@ const setup = fn => { const sigListeners = { loaded: false } const unload = () => { - if (!sigListeners.loaded) + if (!sigListeners.loaded) { return + } for (const sig of signals) { try { process.removeListener(sig, sigListeners[sig]) @@ -43,8 +44,9 @@ const setup = fn => { // if we exit normally, but caught a signal which would have been fatal, // then re-send it once we're done with whatever cleanup we have to do. unload() - if (process.listeners(sig).length < 1) + if (process.listeners(sig).length < 1) { process.once('beforeExit', onBeforeExit) + } fn({ signal: sig }) } @@ -56,8 +58,9 @@ const setup = fn => { try { // if we call this a bunch of times, avoid triggering the warning const { length } = process.listeners(sig) - if (length >= max) + if (length >= max) { process.setMaxListeners(length + 1) + } process.on(sig, sigListeners[sig]) } catch (er) {} } diff --git a/lib/spec-from-lock.js b/lib/spec-from-lock.js index eccf472a9..789741976 100644 --- a/lib/spec-from-lock.js +++ b/lib/spec-from-lock.js @@ -5,19 +5,22 @@ const specFromLock = (name, lock, where) => { try { if (lock.version) { const spec = npa.resolve(name, lock.version, where) - if (lock.integrity || spec.type === 'git') + if (lock.integrity || spec.type === 'git') { return spec + } } if (lock.from) { // legacy metadata includes "from", but not integrity const spec = npa.resolve(name, lock.from, where) - if (spec.registry && lock.version) + if (spec.registry && lock.version) { return npa.resolve(name, lock.version, where) - else if (!lock.resolved) + } else if (!lock.resolved) { return spec + } } - if (lock.resolved) + if (lock.resolved) { return npa.resolve(name, lock.resolved, where) + } } catch (_) { } try { return npa.resolve(name, lock.version, where) diff --git a/lib/tracker.js b/lib/tracker.js index aefd5fe1b..b50f06eaa 100644 --- a/lib/tracker.js +++ b/lib/tracker.js @@ -11,35 +11,37 @@ module.exports = cls => class Tracker extends cls { addTracker (section, subsection = null, key = null) { // TrackerGroup type object not found - if (!this.log.newGroup) + if (!this.log.newGroup) { return + } - if (section === null || section === undefined) + if (section === null || section === undefined) { this[_onError](`Tracker can't be null or undefined`) + } - if (key === null) + if (key === null) { key = subsection + } const hasTracker = this[_progress].has(section) const hasSubtracker = this[_progress].has(`${section}:${key}`) - if (hasTracker && subsection === null) + if (hasTracker && subsection === null) { // 0. existing tracker, no subsection this[_onError](`Tracker "${section}" already exists`) - - else if (!hasTracker && subsection === null) { + } else if (!hasTracker && subsection === null) { // 1. no existing tracker, no subsection // Create a new tracker from this.log // starts progress bar - if (this[_progress].size === 0) + if (this[_progress].size === 0) { this.log.enableProgress() + } this[_progress].set(section, this.log.newGroup(section)) - } else if (!hasTracker && subsection !== null) + } else if (!hasTracker && subsection !== null) { // 2. no parent tracker and subsection this[_onError](`Parent tracker "${section}" does not exist`) - - else if (!hasTracker || !hasSubtracker) { + } else if (!hasTracker || !hasSubtracker) { // 3. existing parent tracker, no subsection tracker // Create a new subtracker in this[_progress] from parent tracker this[_progress].set(`${section}:${key}`, @@ -52,14 +54,17 @@ module.exports = cls => class Tracker extends cls { finishTracker (section, subsection = null, key = null) { // TrackerGroup type object not found - if (!this.log.newGroup) + if (!this.log.newGroup) { return + } - if (section === null || section === undefined) + if (section === null || section === undefined) { this[_onError](`Tracker can't be null or undefined`) + } - if (key === null) + if (key === null) { key = subsection + } const hasTracker = this[_progress].has(section) const hasSubtracker = this[_progress].has(`${section}:${key}`) @@ -71,8 +76,9 @@ module.exports = cls => class Tracker extends cls { // not have any remaining children const keys = this[_progress].keys() for (const key of keys) { - if (key.match(new RegExp(section + ':'))) + if (key.match(new RegExp(section + ':'))) { this.finishTracker(section, key) + } } // remove parent tracker @@ -81,13 +87,13 @@ module.exports = cls => class Tracker extends cls { // remove progress bar if all // trackers are finished - if (this[_progress].size === 0) + if (this[_progress].size === 0) { this.log.disableProgress() - } else if (!hasTracker && subsection === null) + } + } else if (!hasTracker && subsection === null) { // 1. no existing parent tracker, no subsection this[_onError](`Tracker "${section}" does not exist`) - - else if (!hasTracker || hasSubtracker) { + } else if (!hasTracker || hasSubtracker) { // 2. subtracker exists // Finish subtracker and remove from this[_progress] this[_progress].get(`${section}:${key}`).finish() diff --git a/lib/tree-check.js b/lib/tree-check.js index a7e8d9c01..44b5484c6 100644 --- a/lib/tree-check.js +++ b/lib/tree-check.js @@ -5,8 +5,9 @@ const checkTree = (tree, checkUnreachable = true) => { // this can only happen in tests where we have a "tree" object // that isn't actually a tree. - if (!tree.root || !tree.root.inventory) + if (!tree.root || !tree.root.inventory) { return tree + } const { inventory } = tree.root const seen = new Set() @@ -21,8 +22,9 @@ const checkTree = (tree, checkUnreachable = true) => { 'root=' + !!(node && node.isRoot), ]) - if (!node || seen.has(node) || node.then) + if (!node || seen.has(node) || node.then) { return + } seen.add(node) @@ -116,14 +118,18 @@ const checkTree = (tree, checkUnreachable = true) => { check(fsParent, node, 'fsParent') check(target, node, 'target') log.push(['CHILDREN', node.location, ...node.children.keys()]) - for (const kid of node.children.values()) + for (const kid of node.children.values()) { check(kid, node, 'children') - for (const kid of node.fsChildren) + } + for (const kid of node.fsChildren) { check(kid, node, 'fsChildren') - for (const link of node.linksIn) + } + for (const link of node.linksIn) { check(link, node, 'linksIn') - for (const top of node.tops) + } + for (const top of node.tops) { check(top, node, 'tops') + } log.push(['DONE', node.location]) } check(tree) diff --git a/lib/version-from-tgz.js b/lib/version-from-tgz.js index 4b433ea63..d5d8f7345 100644 --- a/lib/version-from-tgz.js +++ b/lib/version-from-tgz.js @@ -4,8 +4,9 @@ const {basename} = require('path') const {parse} = require('url') module.exports = (name, tgz) => { const base = basename(tgz) - if (!base.endsWith('.tgz')) + if (!base.endsWith('.tgz')) { return null + } const u = parse(tgz) if (/^https?:/.test(u.protocol)) { @@ -35,8 +36,9 @@ module.exports = (name, tgz) => { } const versionFromBaseScopeName = (base, scope, name) => { - if (!base.startsWith(name + '-')) + if (!base.startsWith(name + '-')) { return null + } const parsed = semver.parse(base.substring(name.length + 1, base.length - 4)) return parsed ? { diff --git a/lib/vuln.js b/lib/vuln.js index 5b1d1dc1a..da44e7c34 100644 --- a/lib/vuln.js +++ b/lib/vuln.js @@ -28,8 +28,9 @@ const severities = new Map([ [null, -1], ]) -for (const [name, val] of severities.entries()) +for (const [name, val] of severities.entries()) { severities.set(val, name) +} class Vuln { constructor ({ name, advisory }) { @@ -43,7 +44,7 @@ class Vuln { this[_simpleRange] = null this.nodes = new Set() // assume a fix is available unless it hits a top node - // that locks it in place, setting this to false or {isSemVerMajor, version}. + // that locks it in place, setting this false or {isSemVerMajor, version}. this[_fixAvailable] = true this.addAdvisory(advisory) this.packument = advisory.packument @@ -65,30 +66,35 @@ class Vuln { // - true: fix does not require -f for (const v of this.via) { // don't blow up on loops - if (v.fixAvailable === f) + if (v.fixAvailable === f) { continue + } - if (f === false) + if (f === false) { v.fixAvailable = f - else if (v.fixAvailable === true) + } else if (v.fixAvailable === true) { v.fixAvailable = f - else if (typeof f === 'object' && ( - typeof v.fixAvailable !== 'object' || !v.fixAvailable.isSemVerMajor)) + } else if (typeof f === 'object' && ( + typeof v.fixAvailable !== 'object' || !v.fixAvailable.isSemVerMajor)) { v.fixAvailable = f + } } } testSpec (spec) { const specObj = npa(spec) - if (!specObj.registry) + if (!specObj.registry) { return true + } - if (specObj.subSpec) + if (specObj.subSpec) { spec = specObj.subSpec.rawSpec + } for (const v of this.versions) { - if (satisfies(v, spec) && !satisfies(v, this.range, semverOpt)) + if (satisfies(v, spec) && !satisfies(v, this.range, semverOpt)) { return false + } } return true } @@ -135,14 +141,16 @@ class Vuln { this[_range] = null this[_simpleRange] = null // refresh severity - for (const advisory of this.advisories) + for (const advisory of this.advisories) { this.addAdvisory(advisory) + } // remove any effects that are no longer relevant const vias = new Set([...this.advisories].map(a => a.dependency)) for (const via of this.via) { - if (!vias.has(via.name)) + if (!vias.has(via.name)) { this.deleteVia(via) + } } } @@ -151,8 +159,9 @@ class Vuln { const sev = severities.get(advisory.severity) this[_range] = null this[_simpleRange] = null - if (sev > severities.get(this.severity)) + if (sev > severities.get(this.severity)) { this.severity = advisory.severity + } } get range () { @@ -161,8 +170,9 @@ class Vuln { } get simpleRange () { - if (this[_simpleRange] && this[_simpleRange] === this[_range]) + if (this[_simpleRange] && this[_simpleRange] === this[_range]) { return this[_simpleRange] + } const versions = [...this.advisories][0].versions const range = this.range @@ -171,12 +181,14 @@ class Vuln { } isVulnerable (node) { - if (this.nodes.has(node)) + if (this.nodes.has(node)) { return true + } const { version } = node.package - if (!version) + if (!version) { return false + } for (const v of this.advisories) { if (v.testVersion(version)) { diff --git a/lib/yarn-lock.js b/lib/yarn-lock.js index e237cc5c6..384ba447d 100644 --- a/lib/yarn-lock.js +++ b/lib/yarn-lock.js @@ -82,13 +82,15 @@ class YarnLock { const linere = /([^\r\n]*)\r?\n/gm let match let lineNum = 0 - if (!/\n$/.test(data)) + if (!/\n$/.test(data)) { data += '\n' + } while (match = linere.exec(data)) { const line = match[1] lineNum++ - if (line.charAt(0) === '#') + if (line.charAt(0) === '#') { continue + } if (line === '') { this.endCurrent() continue @@ -117,8 +119,9 @@ class YarnLock { const metadata = this.splitQuoted(line.trimLeft(), ' ') if (metadata.length === 2) { // strip off the legacy shasum hashes - if (metadata[0] === 'resolved') + if (metadata[0] === 'resolved') { metadata[1] = metadata[1].replace(/#.*/, '') + } this.current[metadata[0]] = metadata[1] continue } @@ -141,9 +144,9 @@ class YarnLock { let o = 0 for (let i = 0; i < split.length; i++) { const chunk = split[i] - if (/^".*"$/.test(chunk)) + if (/^".*"$/.test(chunk)) { out[o++] = chunk.trim().slice(1, -1) - else if (/^"/.test(chunk)) { + } else if (/^"/.test(chunk)) { let collect = chunk.trimLeft().slice(1) while (++i < split.length) { const n = split[i] @@ -152,12 +155,14 @@ class YarnLock { if (/[^\\](\\\\)*"$/.test(n)) { collect += n.trimRight().slice(0, -1) break - } else + } else { collect += n + } } out[o++] = collect - } else + } else { out[o++] = chunk.trim() + } } return out } @@ -226,17 +231,19 @@ class YarnLock { // no previous entry for this spec at all, so it's new if (!prev) { // if we saw a match already, then assign this spec to it as well - if (priorEntry) + if (priorEntry) { priorEntry.addSpec(s) - else + } else { newSpecs.push(s) + } continue } const m = match(prev, n) // there was a prior entry, but a different thing. skip this one - if (!m) + if (!m) { continue + } // previous matches, but first time seeing it, so already has this spec. // go ahead and add all the previously unseen specs, though @@ -259,8 +266,9 @@ class YarnLock { // if we never found a matching prior, then this is a whole new thing if (!priorEntry) { const entry = Object.assign(new YarnLockEntry(newSpecs), n) - for (const s of newSpecs) + for (const s of newSpecs) { this.entries.set(s, entry) + } } else { // pick up any new info that we got for this node, so that we can // decorate with integrity/resolved/etc. @@ -270,12 +278,15 @@ class YarnLock { entryDataFromNode (node) { const n = {} - if (node.package.dependencies) + if (node.package.dependencies) { n.dependencies = node.package.dependencies - if (node.package.optionalDependencies) + } + if (node.package.optionalDependencies) { n.optionalDependencies = node.package.optionalDependencies - if (node.version) + } + if (node.version) { n.version = node.version + } if (node.resolved) { n.resolved = consistentResolve( node.resolved, @@ -284,8 +295,9 @@ class YarnLock { true ) } - if (node.integrity) + if (node.integrity) { n.integrity = node.integrity + } return n } diff --git a/package-lock.json b/package-lock.json index 06f08e232..acd0b9c37 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,13 +45,9 @@ "arborist": "bin/index.js" }, "devDependencies": { + "@npmcli/lint": "^1.0.2", "benchmark": "^2.1.4", "chalk": "^4.1.0", - "eslint": "^7.9.0", - "eslint-plugin-import": "^2.22.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-standard": "^4.0.1", "minify-registry-metadata": "^2.1.0", "tap": "^15.0.9", "tcompare": "^5.0.6" @@ -65,6 +61,7 @@ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, + "peer": true, "dependencies": { "@babel/highlight": "^7.10.4" } @@ -632,6 +629,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, + "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -647,11 +645,17 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/@gar/promisify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz", + "integrity": "sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, + "peer": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", @@ -665,7 +669,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", @@ -771,6 +776,15 @@ "node": ">=8" } }, + "node_modules/@npmcli/fs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.0.0.tgz", + "integrity": "sha512-8ltnOpRR/oJbOp8vaGUnipOi3bqkcW+sLHFlyXIr08OGHmVJLB1Hn7QtGXbYcpVtH1gAYZTlmDXtE4YV0+AMMQ==", + "dependencies": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, "node_modules/@npmcli/git": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.1.0.tgz", @@ -801,6 +815,27 @@ "node": ">= 10" } }, + "node_modules/@npmcli/lint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/lint/-/lint-1.0.2.tgz", + "integrity": "sha512-6oDoKZWnf14g1nXgSmKMrOash38DEOkHAoLnI5XDPvRUt0w7pXkLh87XbUtzxH9hqyv9RMBVWlSDop7+kXdLNA==", + "dev": true, + "dependencies": { + "which": "^2.0.2" + }, + "bin": { + "npmcli-lint": "lib/index.js", + "npmcli-lint-init": "lib/init.js", + "npmcli-lint-setup": "lib/setup.js" + }, + "peerDependencies": { + "eslint": "^7.26.0", + "eslint-plugin-import": "^2.23.2", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^5.1.0", + "eslint-plugin-standard": "^5.0.0" + } + }, "node_modules/@npmcli/map-workspaces": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-1.0.4.tgz", @@ -886,7 +921,8 @@ "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true + "dev": true, + "peer": true }, "node_modules/abbrev": { "version": "1.1.1", @@ -898,6 +934,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -910,6 +947,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "peer": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -970,6 +1008,7 @@ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, + "peer": true, "engines": { "node": ">=6" } @@ -1057,6 +1096,7 @@ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", @@ -1076,6 +1116,7 @@ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -1114,6 +1155,7 @@ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -1258,10 +1300,11 @@ "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=" }, "node_modules/cacache": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", - "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", "dependencies": { + "@npmcli/fs": "^1.0.0", "@npmcli/move-file": "^1.0.1", "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -1304,6 +1347,7 @@ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, + "peer": true, "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -1350,6 +1394,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "peer": true, "engines": { "node": ">=6" } @@ -1664,7 +1709,8 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "dev": true, + "peer": true }, "node_modules/default-require-extensions": { "version": "3.0.0", @@ -1692,6 +1738,7 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, + "peer": true, "dependencies": { "object-keys": "^1.0.12" }, @@ -1743,6 +1790,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -1785,6 +1833,7 @@ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, + "peer": true, "dependencies": { "ansi-colors": "^4.1.1" }, @@ -1810,6 +1859,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "peer": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -1819,6 +1869,7 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", @@ -1850,6 +1901,7 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, + "peer": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -1882,6 +1934,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "peer": true, "engines": { "node": ">=10" }, @@ -1894,6 +1947,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, + "peer": true, "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -1951,6 +2005,7 @@ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, + "peer": true, "dependencies": { "debug": "^3.2.7", "resolve": "^1.20.0" @@ -1961,6 +2016,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -1970,6 +2026,7 @@ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", "dev": true, + "peer": true, "dependencies": { "debug": "^3.2.7", "pkg-dir": "^2.0.0" @@ -1983,6 +2040,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -1992,6 +2050,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", "dev": true, + "peer": true, "dependencies": { "eslint-utils": "^2.0.0", "regexpp": "^3.0.0" @@ -2011,6 +2070,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", "dev": true, + "peer": true, "dependencies": { "array-includes": "^3.1.3", "array.prototype.flat": "^1.2.4", @@ -2040,6 +2100,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "peer": true, "dependencies": { "ms": "2.0.0" } @@ -2049,6 +2110,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -2060,13 +2122,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "dev": true, + "peer": true }, "node_modules/eslint-plugin-node": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", "dev": true, + "peer": true, "dependencies": { "eslint-plugin-es": "^3.0.0", "eslint-utils": "^2.0.0", @@ -2087,6 +2151,7 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true, + "peer": true, "engines": { "node": ">= 4" } @@ -2096,23 +2161,29 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, + "peer": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/eslint-plugin-promise": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", - "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz", + "integrity": "sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng==", "dev": true, + "peer": true, "engines": { - "node": ">=6" + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0" } }, "node_modules/eslint-plugin-standard": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", - "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-5.0.0.tgz", + "integrity": "sha512-eSIXPc9wBM4BrniMzJRBm2uoVuXz2EPa+NXPk2+itrVt+r5SbKFERx/IgrK/HmfjddyKVz2f+j+7gBRvu19xLg==", + "deprecated": "standard 16.0.0 and eslint-config-standard 16.0.0 no longer require the eslint-plugin-standard package. You can remove it from your dependencies with 'npm rm eslint-plugin-standard'. More info here: https://github.com/standard/standard/issues/1316", "dev": true, "funding": [ { @@ -2128,6 +2199,7 @@ "url": "https://feross.org/support" } ], + "peer": true, "peerDependencies": { "eslint": ">=5.0.0" } @@ -2137,6 +2209,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -2150,6 +2223,7 @@ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, + "peer": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, @@ -2165,6 +2239,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, + "peer": true, "engines": { "node": ">=4" } @@ -2174,6 +2249,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, + "peer": true, "engines": { "node": ">=10" } @@ -2183,6 +2259,7 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, + "peer": true, "dependencies": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", @@ -2197,6 +2274,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, + "peer": true, "engines": { "node": ">=4" } @@ -2219,6 +2297,7 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, + "peer": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -2231,6 +2310,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true, + "peer": true, "engines": { "node": ">=4.0" } @@ -2240,6 +2320,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "peer": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -2252,6 +2333,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true, + "peer": true, "engines": { "node": ">=4.0" } @@ -2261,6 +2343,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "peer": true, "engines": { "node": ">=4.0" } @@ -2270,6 +2353,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -2307,13 +2391,15 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "dev": true, + "peer": true }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "peer": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -2437,6 +2523,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, + "peer": true, "dependencies": { "locate-path": "^2.0.0" }, @@ -2455,6 +2542,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, + "peer": true, "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" @@ -2467,7 +2555,8 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/foreground-child": { "version": "2.0.0", @@ -2563,7 +2652,8 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "dev": true, + "peer": true }, "node_modules/function-loop": { "version": "2.0.1", @@ -2575,7 +2665,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "dev": true, + "peer": true }, "node_modules/gauge": { "version": "2.7.4", @@ -2634,6 +2725,7 @@ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, + "peer": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -2696,6 +2788,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", "dev": true, + "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -2737,6 +2830,7 @@ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, + "peer": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -2749,6 +2843,7 @@ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", "dev": true, + "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2767,6 +2862,7 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true, + "peer": true, "engines": { "node": ">= 0.4" }, @@ -2779,6 +2875,7 @@ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, + "peer": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -2905,6 +3002,7 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, + "peer": true, "engines": { "node": ">= 4" } @@ -2922,6 +3020,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "peer": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3002,6 +3101,7 @@ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, + "peer": true, "dependencies": { "get-intrinsic": "^1.1.0", "has": "^1.0.3", @@ -3020,13 +3120,15 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "dev": true, + "peer": true }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, + "peer": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -3051,6 +3153,7 @@ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -3067,6 +3170,7 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true, + "peer": true, "engines": { "node": ">= 0.4" }, @@ -3079,6 +3183,7 @@ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", "dev": true, + "peer": true, "dependencies": { "has": "^1.0.3" }, @@ -3091,6 +3196,7 @@ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -3143,6 +3249,7 @@ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", "dev": true, + "peer": true, "engines": { "node": ">= 0.4" }, @@ -3164,6 +3271,7 @@ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", "dev": true, + "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -3179,6 +3287,7 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -3207,6 +3316,7 @@ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -3222,6 +3332,7 @@ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, + "peer": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -3438,7 +3549,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -3459,7 +3571,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true + "dev": true, + "peer": true }, "node_modules/json-stringify-nice": { "version": "1.1.4", @@ -3535,6 +3648,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "peer": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -3576,6 +3690,7 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, + "peer": true, "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -3591,6 +3706,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, + "peer": true, "dependencies": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" @@ -3609,7 +3725,8 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true + "dev": true, + "peer": true }, "node_modules/lodash.flattendeep": { "version": "4.4.0", @@ -3621,13 +3738,15 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true + "dev": true, + "peer": true }, "node_modules/log-driver": { "version": "1.2.7", @@ -3878,7 +3997,8 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true + "dev": true, + "peer": true }, "node_modules/negotiator": { "version": "0.6.2", @@ -3948,6 +4068,7 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, + "peer": true, "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -3959,13 +4080,15 @@ "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/normalize-package-data/node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, + "peer": true, "bin": { "semver": "bin/semver" } @@ -4232,6 +4355,7 @@ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", "dev": true, + "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4241,6 +4365,7 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "peer": true, "engines": { "node": ">= 0.4" } @@ -4250,6 +4375,7 @@ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -4268,6 +4394,7 @@ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", @@ -4302,6 +4429,7 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, + "peer": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -4334,6 +4462,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, + "peer": true, "dependencies": { "p-try": "^1.0.0" }, @@ -4346,6 +4475,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, + "peer": true, "dependencies": { "p-limit": "^1.1.0" }, @@ -4372,6 +4502,7 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true, + "peer": true, "engines": { "node": ">=4" } @@ -4428,6 +4559,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "peer": true, "dependencies": { "callsites": "^3.0.0" }, @@ -4450,6 +4582,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, + "peer": true, "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -4463,6 +4596,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true, + "peer": true, "engines": { "node": ">=4" } @@ -4488,13 +4622,15 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, + "peer": true, "dependencies": { "pify": "^3.0.0" }, @@ -4524,6 +4660,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true, + "peer": true, "engines": { "node": ">=4" } @@ -4533,6 +4670,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, + "peer": true, "dependencies": { "find-up": "^2.1.0" }, @@ -4545,6 +4683,7 @@ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", "dev": true, + "peer": true, "dependencies": { "find-up": "^2.1.0" }, @@ -4563,6 +4702,7 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "peer": true, "engines": { "node": ">= 0.8.0" } @@ -4594,6 +4734,7 @@ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, + "peer": true, "engines": { "node": ">=0.4.0" } @@ -4705,6 +4846,7 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, + "peer": true, "dependencies": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", @@ -4719,6 +4861,7 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, + "peer": true, "dependencies": { "find-up": "^2.0.0", "read-pkg": "^3.0.0" @@ -4769,6 +4912,7 @@ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, + "peer": true, "engines": { "node": ">=8" }, @@ -4833,6 +4977,7 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -4848,6 +4993,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, + "peer": true, "dependencies": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" @@ -4861,6 +5007,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "peer": true, "engines": { "node": ">=4" } @@ -4942,6 +5089,7 @@ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -4961,6 +5109,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, + "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -4978,6 +5127,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -5067,6 +5217,7 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, + "peer": true, "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -5076,13 +5227,15 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true + "dev": true, + "peer": true }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, + "peer": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -5092,7 +5245,8 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/sprintf-js": { "version": "1.0.3", @@ -5201,6 +5355,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -5214,6 +5369,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dev": true, + "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -5239,6 +5395,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true, + "peer": true, "engines": { "node": ">=4" } @@ -5248,6 +5405,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "peer": true, "engines": { "node": ">=8" }, @@ -5272,6 +5430,7 @@ "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "dev": true, + "peer": true, "dependencies": { "ajv": "^8.0.1", "lodash.clonedeep": "^4.5.0", @@ -5289,6 +5448,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -5305,6 +5465,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -5313,13 +5474,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "peer": true }, "node_modules/table/node_modules/string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, + "peer": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7337,7 +7500,8 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true + "dev": true, + "peer": true }, "node_modules/to-fast-properties": { "version": "2.0.0", @@ -7388,6 +7552,7 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", "dev": true, + "peer": true, "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.1", @@ -7400,6 +7565,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, + "peer": true, "dependencies": { "minimist": "^1.2.0" }, @@ -7428,6 +7594,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "peer": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -7440,6 +7607,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "peer": true, "engines": { "node": ">=10" }, @@ -7460,6 +7628,7 @@ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", "dev": true, + "peer": true, "dependencies": { "function-bind": "^1.1.1", "has-bigints": "^1.0.1", @@ -7543,13 +7712,15 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, + "peer": true, "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -7600,6 +7771,7 @@ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, + "peer": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -7630,6 +7802,7 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -7870,6 +8043,7 @@ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, + "peer": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -8299,6 +8473,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, + "peer": true, "requires": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -8311,11 +8486,17 @@ "strip-json-comments": "^3.1.1" } }, + "@gar/promisify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz", + "integrity": "sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==" + }, "@humanwhocodes/config-array": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, + "peer": true, "requires": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", @@ -8326,7 +8507,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true + "dev": true, + "peer": true }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", @@ -8404,6 +8586,15 @@ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, + "@npmcli/fs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.0.0.tgz", + "integrity": "sha512-8ltnOpRR/oJbOp8vaGUnipOi3bqkcW+sLHFlyXIr08OGHmVJLB1Hn7QtGXbYcpVtH1gAYZTlmDXtE4YV0+AMMQ==", + "requires": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, "@npmcli/git": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.1.0.tgz", @@ -8428,6 +8619,15 @@ "npm-normalize-package-bin": "^1.0.1" } }, + "@npmcli/lint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/lint/-/lint-1.0.2.tgz", + "integrity": "sha512-6oDoKZWnf14g1nXgSmKMrOash38DEOkHAoLnI5XDPvRUt0w7pXkLh87XbUtzxH9hqyv9RMBVWlSDop7+kXdLNA==", + "dev": true, + "requires": { + "which": "^2.0.2" + } + }, "@npmcli/map-workspaces": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-1.0.4.tgz", @@ -8504,7 +8704,8 @@ "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true + "dev": true, + "peer": true }, "abbrev": { "version": "1.1.1", @@ -8515,13 +8716,15 @@ "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true + "dev": true, + "peer": true }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "peer": true, "requires": {} }, "agent-base": { @@ -8566,7 +8769,8 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true + "dev": true, + "peer": true }, "ansi-regex": { "version": "5.0.0", @@ -8636,6 +8840,7 @@ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", @@ -8649,6 +8854,7 @@ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -8677,7 +8883,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true + "dev": true, + "peer": true }, "async-hook-domain": { "version": "2.0.3", @@ -8791,10 +8998,11 @@ "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=" }, "cacache": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", - "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", "requires": { + "@npmcli/fs": "^1.0.0", "@npmcli/move-file": "^1.0.1", "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -8831,6 +9039,7 @@ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, + "peer": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -8866,7 +9075,8 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "dev": true, + "peer": true }, "camelcase": { "version": "5.3.1", @@ -9103,7 +9313,8 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "dev": true, + "peer": true }, "default-require-extensions": { "version": "3.0.0", @@ -9127,6 +9338,7 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, + "peer": true, "requires": { "object-keys": "^1.0.12" } @@ -9166,6 +9378,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "peer": true, "requires": { "esutils": "^2.0.2" } @@ -9205,6 +9418,7 @@ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, + "peer": true, "requires": { "ansi-colors": "^4.1.1" } @@ -9224,6 +9438,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "peer": true, "requires": { "is-arrayish": "^0.2.1" } @@ -9233,6 +9448,7 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", @@ -9258,6 +9474,7 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, + "peer": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -9280,13 +9497,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true + "dev": true, + "peer": true }, "eslint": { "version": "7.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, + "peer": true, "requires": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -9335,6 +9554,7 @@ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, + "peer": true, "requires": { "debug": "^3.2.7", "resolve": "^1.20.0" @@ -9345,6 +9565,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "peer": true, "requires": { "ms": "^2.1.1" } @@ -9356,6 +9577,7 @@ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", "dev": true, + "peer": true, "requires": { "debug": "^3.2.7", "pkg-dir": "^2.0.0" @@ -9366,6 +9588,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "peer": true, "requires": { "ms": "^2.1.1" } @@ -9377,6 +9600,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", "dev": true, + "peer": true, "requires": { "eslint-utils": "^2.0.0", "regexpp": "^3.0.0" @@ -9387,6 +9611,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", "dev": true, + "peer": true, "requires": { "array-includes": "^3.1.3", "array.prototype.flat": "^1.2.4", @@ -9410,6 +9635,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "peer": true, "requires": { "ms": "2.0.0" } @@ -9419,6 +9645,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "peer": true, "requires": { "esutils": "^2.0.2" } @@ -9427,7 +9654,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "dev": true, + "peer": true } } }, @@ -9436,6 +9664,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", "dev": true, + "peer": true, "requires": { "eslint-plugin-es": "^3.0.0", "eslint-utils": "^2.0.0", @@ -9449,27 +9678,32 @@ "version": "5.1.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true + "dev": true, + "peer": true }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "dev": true, + "peer": true } } }, "eslint-plugin-promise": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", - "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", - "dev": true + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz", + "integrity": "sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng==", + "dev": true, + "peer": true, + "requires": {} }, "eslint-plugin-standard": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", - "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-5.0.0.tgz", + "integrity": "sha512-eSIXPc9wBM4BrniMzJRBm2uoVuXz2EPa+NXPk2+itrVt+r5SbKFERx/IgrK/HmfjddyKVz2f+j+7gBRvu19xLg==", "dev": true, + "peer": true, "requires": {} }, "eslint-scope": { @@ -9477,6 +9711,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "peer": true, "requires": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -9487,6 +9722,7 @@ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, + "peer": true, "requires": { "eslint-visitor-keys": "^1.1.0" }, @@ -9495,7 +9731,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true + "dev": true, + "peer": true } } }, @@ -9503,13 +9740,15 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true + "dev": true, + "peer": true }, "espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, + "peer": true, "requires": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", @@ -9520,7 +9759,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true + "dev": true, + "peer": true } } }, @@ -9535,6 +9775,7 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, + "peer": true, "requires": { "estraverse": "^5.1.0" }, @@ -9543,7 +9784,8 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true + "dev": true, + "peer": true } } }, @@ -9552,6 +9794,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "peer": true, "requires": { "estraverse": "^5.2.0" }, @@ -9560,7 +9803,8 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true + "dev": true, + "peer": true } } }, @@ -9568,13 +9812,15 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "dev": true, + "peer": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "dev": true, + "peer": true }, "events-to-array": { "version": "1.1.2", @@ -9606,13 +9852,15 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "dev": true, + "peer": true }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "peer": true, "requires": { "flat-cache": "^3.0.4" } @@ -9702,6 +9950,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, + "peer": true, "requires": { "locate-path": "^2.0.0" } @@ -9717,6 +9966,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, + "peer": true, "requires": { "flatted": "^3.1.0", "rimraf": "^3.0.2" @@ -9726,7 +9976,8 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true + "dev": true, + "peer": true }, "foreground-child": { "version": "2.0.0", @@ -9789,7 +10040,8 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "dev": true, + "peer": true }, "function-loop": { "version": "2.0.1", @@ -9801,7 +10053,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "dev": true, + "peer": true }, "gauge": { "version": "2.7.4", @@ -9850,6 +10103,7 @@ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, + "peer": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -9897,6 +10151,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", "dev": true, + "peer": true, "requires": { "type-fest": "^0.20.2" } @@ -9925,6 +10180,7 @@ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, + "peer": true, "requires": { "function-bind": "^1.1.1" } @@ -9933,7 +10189,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true + "dev": true, + "peer": true }, "has-flag": { "version": "4.0.0", @@ -9945,13 +10202,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true + "dev": true, + "peer": true }, "has-tostringtag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, + "peer": true, "requires": { "has-symbols": "^1.0.2" } @@ -10048,7 +10307,8 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "dev": true, + "peer": true }, "ignore-walk": { "version": "3.0.4", @@ -10063,6 +10323,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "peer": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -10126,6 +10387,7 @@ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, + "peer": true, "requires": { "get-intrinsic": "^1.1.0", "has": "^1.0.3", @@ -10141,13 +10403,15 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "dev": true, + "peer": true }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, + "peer": true, "requires": { "has-bigints": "^1.0.1" } @@ -10166,6 +10430,7 @@ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -10175,13 +10440,15 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true + "dev": true, + "peer": true }, "is-core-module": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", "dev": true, + "peer": true, "requires": { "has": "^1.0.3" } @@ -10191,6 +10458,7 @@ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "peer": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -10227,7 +10495,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true + "dev": true, + "peer": true }, "is-number": { "version": "7.0.0", @@ -10240,6 +10509,7 @@ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", "dev": true, + "peer": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -10249,6 +10519,7 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -10265,6 +10536,7 @@ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "peer": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -10274,6 +10546,7 @@ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, + "peer": true, "requires": { "has-symbols": "^1.0.2" } @@ -10445,7 +10718,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "dev": true, + "peer": true }, "json-parse-even-better-errors": { "version": "2.3.1", @@ -10466,7 +10740,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true + "dev": true, + "peer": true }, "json-stringify-nice": { "version": "1.1.4", @@ -10524,6 +10799,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "peer": true, "requires": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -10556,6 +10832,7 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, + "peer": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -10568,6 +10845,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, + "peer": true, "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" @@ -10583,7 +10861,8 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true + "dev": true, + "peer": true }, "lodash.flattendeep": { "version": "4.4.0", @@ -10595,13 +10874,15 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "peer": true }, "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true + "dev": true, + "peer": true }, "log-driver": { "version": "1.2.7", @@ -10792,7 +11073,8 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true + "dev": true, + "peer": true }, "negotiator": { "version": "0.6.2", @@ -10844,6 +11126,7 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, + "peer": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -10855,13 +11138,15 @@ "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true + "dev": true, + "peer": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "dev": true, + "peer": true } } }, @@ -11068,19 +11353,22 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true + "dev": true, + "peer": true }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "dev": true, + "peer": true }, "object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -11093,6 +11381,7 @@ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", @@ -11118,6 +11407,7 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, + "peer": true, "requires": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -11147,6 +11437,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, + "peer": true, "requires": { "p-try": "^1.0.0" } @@ -11156,6 +11447,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, + "peer": true, "requires": { "p-limit": "^1.1.0" } @@ -11172,7 +11464,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true + "dev": true, + "peer": true }, "package-hash": { "version": "4.0.0", @@ -11217,6 +11510,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "peer": true, "requires": { "callsites": "^3.0.0" } @@ -11236,6 +11530,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, + "peer": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -11245,7 +11540,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "dev": true, + "peer": true }, "path-is-absolute": { "version": "1.0.1", @@ -11262,13 +11558,15 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "peer": true }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, + "peer": true, "requires": { "pify": "^3.0.0" } @@ -11288,13 +11586,15 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "dev": true, + "peer": true }, "pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, + "peer": true, "requires": { "find-up": "^2.1.0" } @@ -11304,6 +11604,7 @@ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", "dev": true, + "peer": true, "requires": { "find-up": "^2.1.0" } @@ -11318,7 +11619,8 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true + "dev": true, + "peer": true }, "proc-log": { "version": "1.0.0", @@ -11343,7 +11645,8 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "dev": true, + "peer": true }, "promise-all-reject-late": { "version": "1.0.1", @@ -11431,6 +11734,7 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, + "peer": true, "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", @@ -11442,6 +11746,7 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, + "peer": true, "requires": { "find-up": "^2.0.0", "read-pkg": "^3.0.0" @@ -11485,7 +11790,8 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true + "dev": true, + "peer": true }, "release-zalgo": { "version": "1.0.0", @@ -11533,7 +11839,8 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true + "dev": true, + "peer": true }, "require-main-filename": { "version": "2.0.0", @@ -11546,6 +11853,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, + "peer": true, "requires": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" @@ -11555,7 +11863,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "dev": true, + "peer": true }, "retry": { "version": "0.12.0", @@ -11613,6 +11922,7 @@ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -11629,6 +11939,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, + "peer": true, "requires": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -11639,7 +11950,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "dev": true, + "peer": true } } }, @@ -11710,6 +12022,7 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, + "peer": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -11719,13 +12032,15 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true + "dev": true, + "peer": true }, "spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, + "peer": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -11735,7 +12050,8 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", - "dev": true + "dev": true, + "peer": true }, "sprintf-js": { "version": "1.0.3", @@ -11822,6 +12138,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -11832,6 +12149,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dev": true, + "peer": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -11850,13 +12168,15 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "dev": true, + "peer": true }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true + "dev": true, + "peer": true }, "supports-color": { "version": "7.2.0", @@ -11872,6 +12192,7 @@ "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "dev": true, + "peer": true, "requires": { "ajv": "^8.0.1", "lodash.clonedeep": "^4.5.0", @@ -11886,6 +12207,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", "dev": true, + "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -11897,19 +12219,22 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "dev": true, + "peer": true }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "peer": true }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, + "peer": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -13319,7 +13644,8 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true + "dev": true, + "peer": true }, "to-fast-properties": { "version": "2.0.0", @@ -13361,6 +13687,7 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", "dev": true, + "peer": true, "requires": { "@types/json5": "^0.0.29", "json5": "^1.0.1", @@ -13373,6 +13700,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, + "peer": true, "requires": { "minimist": "^1.2.0" } @@ -13397,6 +13725,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "peer": true, "requires": { "prelude-ls": "^1.2.1" } @@ -13405,7 +13734,8 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "dev": true, + "peer": true }, "typedarray-to-buffer": { "version": "3.1.5", @@ -13420,6 +13750,7 @@ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", "dev": true, + "peer": true, "requires": { "function-bind": "^1.1.1", "has-bigints": "^1.0.1", @@ -13492,13 +13823,15 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "dev": true, + "peer": true }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, + "peer": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -13540,6 +13873,7 @@ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, + "peer": true, "requires": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -13566,7 +13900,8 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true + "dev": true, + "peer": true }, "wrap-ansi": { "version": "2.1.0", diff --git a/package.json b/package.json index 42ec2eca3..2b14dc469 100644 --- a/package.json +++ b/package.json @@ -36,13 +36,9 @@ "walk-up-path": "^1.0.0" }, "devDependencies": { + "@npmcli/lint": "^1.0.2", "benchmark": "^2.1.4", "chalk": "^4.1.0", - "eslint": "^7.9.0", - "eslint-plugin-import": "^2.22.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-standard": "^4.0.1", "minify-registry-metadata": "^2.1.0", "tap": "^15.0.9", "tcompare": "^5.0.6" @@ -50,18 +46,19 @@ "scripts": { "test": "npm run test-only --", "test-only": "tap", - "posttest": "npm run lint", + "posttest": "npm run lint --", "snap": "tap", - "postsnap": "npm run lintfix", + "postsnap": "npm run lintfix --", "test-proxy": "ARBORIST_TEST_PROXY=1 tap --snapshot", "preversion": "npm test", "postversion": "npm publish", "prepublishOnly": "git push origin --follow-tags", "eslint": "eslint", - "lint": "npm run eslint -- \"lib/**/*.js\" \"test/arborist/*.js\" \"test/*.js\" \"bin/**/*.js\"", + "lint": "npm run npmclilint -- \"lib/**/*.*js\" \"bin/**/*.*js\" \"test/*.*js\" \"test/arborist/*.*js\"", "lintfix": "npm run lint -- --fix", "benchmark": "node scripts/benchmark.js", - "benchclean": "rm -rf scripts/benchmark/*/" + "benchclean": "rm -rf scripts/benchmark/*/", + "npmclilint": "npmcli-lint" }, "repository": { "type": "git", diff --git a/tap-snapshots/test/arborist/reify.js.test.cjs b/tap-snapshots/test/arborist/reify.js.test.cjs index 8470ba468..3caf4d0ff 100644 --- a/tap-snapshots/test/arborist/reify.js.test.cjs +++ b/tap-snapshots/test/arborist/reify.js.test.cjs @@ -4660,40 +4660,6 @@ ArboristNode { } ` -exports[`test/arborist/reify.js TAP move aside symlink clutter > must match snapshot 2`] = ` -ArboristNode { - "children": Map { - "abbrev" => ArboristNode { - "edgesIn": Set { - EdgeIn { - "from": "", - "name": "abbrev", - "spec": "latest", - "type": "prod", - }, - }, - "location": "node_modules/abbrev", - "name": "abbrev", - "path": "{CWD}/test/arborist/tap-testdir-reify-move-aside-symlink-clutter/node_modules/abbrev", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "version": "1.1.1", - }, - }, - "edgesOut": Map { - "abbrev" => EdgeOut { - "name": "abbrev", - "spec": "latest", - "to": "node_modules/abbrev", - "type": "prod", - }, - }, - "isProjectRoot": true, - "location": "", - "name": "tap-testdir-reify-move-aside-symlink-clutter", - "path": "{CWD}/test/arborist/tap-testdir-reify-move-aside-symlink-clutter", -} -` - exports[`test/arborist/reify.js TAP multiple bundles at the same level > must match snapshot 1`] = ` ArboristNode { "children": Map { diff --git a/test/arborist/build-ideal-tree.js b/test/arborist/build-ideal-tree.js index 385fa4252..b518a85aa 100644 --- a/test/arborist/build-ideal-tree.js +++ b/test/arborist/build-ideal-tree.js @@ -1,7 +1,8 @@ // the tree-checking is too abusively slow on Windows, and // can make the test time out unnecessarily. -if (process.platform === 'win32') +if (process.platform === 'win32') { process.env.ARBORIST_DEBUG = 0 +} const {basename, resolve, relative} = require('path') const pacote = require('pacote') @@ -144,8 +145,9 @@ t.test('a tree with an outdated dep, missing dep, no lockfile', async t => { once: '1.3.3', wrappy: '1.0.1', } - for (const [name, version] of Object.entries(expected)) + for (const [name, version] of Object.entries(expected)) { t.equal(tree.children.get(name).package.version, version, `expect ${name}@${version}`) + } t.matchSnapshot(printTree(tree), 'should not update all') }) @@ -154,18 +156,22 @@ t.test('tarball deps with transitive tarball deps', t => t.resolveMatchSnapshot(printIdeal( resolve(fixtures, 'tarball-dependencies')))) -t.test('testing-peer-deps-overlap package', t => { +t.test('testing-peer-deps-overlap package', async t => { const path = resolve(fixtures, 'testing-peer-deps-overlap') - return buildIdeal(path).then(idealTree => new Arborist({ path, idealTree, ...OPT }) - .buildIdealTree().then(tree2 => t.equal(tree2, idealTree)) - .then(() => t.matchSnapshot(printTree(idealTree), 'build ideal tree with overlapping peer dep ranges'))) + const idealTree = await buildIdeal(path) + const arb = new Arborist({ path, idealTree, ...OPT }) + const tree2 = await arb.buildIdealTree() + t.equal(tree2, idealTree) + t.matchSnapshot(printTree(idealTree), 'build ideal tree with overlapping peer dep ranges') }) -t.test('testing-peer-deps package', t => { +t.test('testing-peer-deps package', async t => { const path = resolve(fixtures, 'testing-peer-deps') - return buildIdeal(path).then(idealTree => new Arborist({path, idealTree, ...OPT}) - .buildIdealTree().then(tree2 => t.equal(tree2, idealTree)) - .then(() => t.matchSnapshot(printTree(idealTree), 'build ideal tree with peer deps'))) + const idealTree = await buildIdeal(path) + const arb = new Arborist({path, idealTree, ...OPT}) + const tree2 = await arb.buildIdealTree() + t.equal(tree2, idealTree) + t.matchSnapshot(printTree(idealTree), 'build ideal tree with peer deps') }) t.test('testing-peer-deps package with symlinked root', t => { @@ -1296,8 +1302,9 @@ t.test('more peer dep conflicts', t => { }, }) - if (process.platform !== 'win32') + if (process.platform !== 'win32') { t.jobs = cases.length + } t.plan(cases.length) for (const [name, {pkg, error, resolvable, add}] of cases) { @@ -1334,30 +1341,35 @@ t.test('more peer dep conflicts', t => { const [strictRes, forceRes, defRes] = results if (!resolvable) { - if (!(strictRes instanceof Error)) + if (!(strictRes instanceof Error)) { console.error(printTree(strictRes)) + } t.match(strictRes, { code: 'ERESOLVE' }) - } else if (strictRes instanceof Error) + } else if (strictRes instanceof Error) { t.fail('should not get error in strict mode', { error: strictRes }) - else + } else { t.matchSnapshot(printTree(strictRes), 'strict result') + } - if (forceRes instanceof Error) + if (forceRes instanceof Error) { t.fail('should not get error when forced', { error: forceRes }) - else + } else { t.matchSnapshot(printTree(forceRes), 'force result') + } if (error) { - if (!(defRes instanceof Error)) + if (!(defRes instanceof Error)) { console.error(printTree(defRes)) + } t.match(defRes, { code: 'ERESOLVE' }) - } else if (defRes instanceof Error) + } else if (defRes instanceof Error) { t.fail('should not get error in default mode', { error: defRes }) - else { - if (resolvable) + } else { + if (resolvable) { t.strictSame(warnings, []) - else + } else { t.matchSnapshot(warnings, 'warnings') + } warnings.length = 0 t.matchSnapshot(printTree(defRes), 'default result') } @@ -1789,10 +1801,11 @@ t.test('properly assign fsParent when paths have .. in them', async t => { } for (const node of tree.inventory.filter(n => n.isLink)) { const { target } = node - if (target.location === '../..') + if (target.location === '../..') { t.equal(target.fsParent, null, '../.. has no fsParent') - else + } else { t.equal(tree.inventory.has(target.fsParent), true, 'other targets have fsParent') + } } }) @@ -2109,8 +2122,9 @@ t.test('allow ERESOLVE to be forced when not in the source', async t => { }, }) for (const type of types) { - if (type === 'peerDependencies') + if (type === 'peerDependencies') { continue + } t.test(type, async t => { const path = t.testdir({ 'package.json': JSON.stringify(pj(type)), @@ -2135,8 +2149,9 @@ t.test('allow ERESOLVE to be forced when not in the source', async t => { }, }) for (const type of types) { - if (type === 'peerDependencies') + if (type === 'peerDependencies') { continue + } t.test(type, async t => { const path = t.testdir({ 'package.json': JSON.stringify(pj(type)), diff --git a/test/arborist/load-actual.js b/test/arborist/load-actual.js index 850b25d62..cb9f741d4 100644 --- a/test/arborist/load-actual.js +++ b/test/arborist/load-actual.js @@ -16,17 +16,20 @@ const { const pp = path => path && normalizePath(path).substr(normalizePath(fixtures).length + 1) const defixture = obj => { - if (obj instanceof Set) + if (obj instanceof Set) { return new Set([...obj].map(defixture)) + } - if (obj instanceof Map) + if (obj instanceof Map) { return new Map([...obj].map(([name, val]) => [name, defixture(val)])) + } for (const key in obj) { - if (['path', 'realpath'].includes(key)) + if (['path', 'realpath'].includes(key)) { obj[key] = pp(obj[key]) - else if (typeof obj[key] === 'object' && obj[key] !== null) + } else if (typeof obj[key] === 'object' && obj[key] !== null) { obj[key] = defixture(obj[key]) + } } return obj } @@ -41,7 +44,8 @@ t.cleanSnapshot = s => s.split(cwd).join('{CWD}') t.formatSnapshot = tree => format(defixture(printTree(tree)), { sort: true }) -const loadActual = (path, opts) => new Arborist({path, ...opts}).loadActual(opts) +const loadActual = (path, opts) => + new Arborist({path, ...opts}).loadActual(opts) roots.forEach(path => { const dir = resolve(fixtures, path) @@ -77,8 +81,9 @@ t.test('already loading', t => { // the end of the process and the promise resolves const promise = arb.loadActual() const int = setInterval(() => { - if (arb.actualTree) + if (arb.actualTree) { t.fail('set public arb.actualTree before promise resolved') + } arb.loadActual() }) return promise.then(() => clearInterval(int)) diff --git a/test/arborist/load-virtual.js b/test/arborist/load-virtual.js index 16f6ede0e..2c221ffdc 100644 --- a/test/arborist/load-virtual.js +++ b/test/arborist/load-virtual.js @@ -24,7 +24,8 @@ const { const cwd = normalizePath(process.cwd()) t.cleanSnapshot = s => s.split(cwd).join('{CWD}') -const loadVirtual = (path, opts) => new Arborist({path, ...(opts || {})}).loadVirtual(opts) +const loadVirtual = (path, opts) => + new Arborist({path, ...(opts || {})}).loadVirtual(opts) t.test('load from fixture', t => loadVirtual(fixture).then(virtualTree => { diff --git a/test/arborist/pruner.js b/test/arborist/pruner.js index fe0147b4c..924704d7b 100644 --- a/test/arborist/pruner.js +++ b/test/arborist/pruner.js @@ -87,10 +87,11 @@ t.test('prune omit dev with bins', async t => { // should have bin files const reifiedBin = resolve(path, 'node_modules/.bin/yes') - if (process.platform === 'win32') + if (process.platform === 'win32') { t.ok(fs.statSync(reifiedBin + '.cmd').isFile(), 'should have shim') - else + } else { t.ok(fs.lstatSync(reifiedBin).isSymbolicLink(), 'should have symlink') + } // PRUNE things const tree = await pruneTree(path, { prefix: path, omit: ['dev'] }) @@ -105,8 +106,9 @@ t.test('prune omit dev with bins', async t => { // should also remove ./bin/* files const bin = resolve(path, 'node_modules/.bin/yes') - if (process.platform === 'win32') + if (process.platform === 'win32') { t.throws(() => fs.statSync(bin + '.cmd').isFile(), /ENOENT/, 'should not have shim') - else + } else { t.throws(() => fs.lstatSync(bin).isSymbolicLink(), /ENOENT/, 'should not have symlink') + } }) diff --git a/test/arborist/reify.js b/test/arborist/reify.js index c76a4d8d4..76cee8612 100644 --- a/test/arborist/reify.js +++ b/test/arborist/reify.js @@ -6,16 +6,18 @@ const runScript = require('@npmcli/run-script') const realRimraf = require('rimraf') let failRimraf = false const rimrafMock = (...args) => { - if (!failRimraf) + if (!failRimraf) { return realRimraf(...args) - else + } else { return args.pop()(new Error('rimraf fail')) + } } rimrafMock.sync = (...args) => { - if (!failRimraf) + if (!failRimraf) { return realRimraf.sync(...args) - else + } else { throw new Error('rimraf fail') + } } const fs = require('fs') let failRename = null @@ -25,20 +27,22 @@ const {rename: realRename, mkdir: realMkdir} = fs const fsMock = { ...fs, mkdir (...args) { - if (failMkdir) + if (failMkdir) { process.nextTick(() => args.pop()(failMkdir)) + } realMkdir(...args) }, rename (...args) { - if (failRename) + if (failRename) { process.nextTick(() => args.pop()(failRename)) - else if (failRenameOnce) { + } else if (failRenameOnce) { const er = failRenameOnce failRenameOnce = null process.nextTick(() => args.pop()(er)) - } else + } else { realRename(...args) + } }, } const mocks = { @@ -221,15 +225,17 @@ t.test('omit peer deps', t => { return reify(path, { omit: ['peer'] }) .then(tree => { - for (const node of tree.inventory.values()) + for (const node of tree.inventory.values()) { t.equal(node.peer, false, 'did not reify any peer nodes') + } const lock = require(tree.path + '/package-lock.json') for (const [loc, meta] of Object.entries(lock.packages)) { - if (meta.peer) + if (meta.peer) { t.throws(() => fs.statSync(resolve(path, loc)), 'peer not reified') - else + } else { t.equal(fs.statSync(resolve(path, loc)).isDirectory(), true) + } } }) .then(() => { @@ -369,9 +375,9 @@ t.test('multiple bundles at the same level', t => { const p = printTree(tree) // just fail on the failures, we don't need a zillion tap lines here for (const n of tree.inventory.values()) { - if (n.root !== root) + if (n.root !== root) { t.equal(n.root, root, 'in same tree') - else { + } else { for (const e of n.edgesIn) { if (e.from.root !== root) { t.equal(e.from.root, root, @@ -1157,10 +1163,11 @@ t.test('workspaces', t => { const checkBin = () => { for (const bin of bins) { - if (process.platform === 'win32') + if (process.platform === 'win32') { t.ok(fs.statSync(bin + '.cmd').isFile(), 'created shim') - else + } else { t.ok(fs.lstatSync(bin).isSymbolicLink(), 'created symlink') + } } } @@ -1203,10 +1210,11 @@ t.test('reify from old package-lock with bins', async t => { ) const bin = resolve(path, 'node_modules/.bin/ruy') - if (process.platform === 'win32') + if (process.platform === 'win32') { t.ok(fs.statSync(`${bin}.cmd`).isFile(), 'created shim') - else + } else { t.ok(fs.lstatSync(bin).isSymbolicLink(), 'created symlink') + } }) t.test('fail early if bins will conflict', async t => { @@ -1389,8 +1397,9 @@ t.test('rollback if process is terminated during reify process', async t => { // ignore the beforeExit handler, since we won't actually let that happen once (ev, ...args) { - if (ev !== 'beforeExit') + if (ev !== 'beforeExit') { return super.once(ev, ...args) + } } kill (pid, signal) { @@ -1442,8 +1451,9 @@ t.test('rollback if process is terminated during reify process', async t => { }) // if it fails while removing trash well... it's already over. // we can't actually roll back at that point, because "trash" is gone - if (method !== Symbol.for('removeTrash')) + if (method !== Symbol.for('removeTrash')) { t.throws(() => fs.statSync(path + '/node_modules'), { code: 'ENOENT' }) + } }) t.test('upgrade install', async t => { diff --git a/test/audit-report.js b/test/audit-report.js index b0e73410a..efc71b837 100644 --- a/test/audit-report.js +++ b/test/audit-report.js @@ -19,7 +19,8 @@ const {resolve} = require('path') const fixtures = resolve(__dirname, 'fixtures') const cache = t.testdir() -const newArb = (path, opts = {}) => new Arborist({path, registry, cache, ...opts}) +const newArb = (path, opts = {}) => + new Arborist({path, registry, cache, ...opts}) const sortReport = report => { const entries = Object.entries(report.vulnerabilities) @@ -206,8 +207,9 @@ t.test('audit returns an error', async t => { const logs = [] const onlog = (...msg) => { - if (msg[0] === 'http') + if (msg[0] === 'http') { return + } logs.push(msg) } process.on('log', onlog) @@ -347,11 +349,13 @@ t.test('omit options', async t => { const s = omit.map(o => `-omit${o}`).join('') const bulk = resolve(path, `bulk${s}.json`) const rmBulk = advisoryBulkResponse(bulk) - const r1 = (await AuditReport.load(tree, { ...arb.options, omit })).toJSON() + const r1 = (await AuditReport.load(tree, { ...arb.options, omit })) + .toJSON() sortReport(r1) rmBulk() t.matchSnapshot(r1, 'bulk') - const r2 = (await AuditReport.load(tree, { ...arb.options, omit })).toJSON() + const r2 = (await AuditReport.load(tree, { ...arb.options, omit })) + .toJSON() sortReport(r2) t.strictSame(r1, r2, 'same results') t.end() diff --git a/test/can-place-dep.js b/test/can-place-dep.js index 783d7d439..b9ea2b813 100644 --- a/test/can-place-dep.js +++ b/test/can-place-dep.js @@ -39,8 +39,9 @@ t.test('basic placement check tests', t => { const target = tree.inventory.get(targetLoc) const node = tree.inventory.get(nodeLoc) const edge = node.edgesOut.get(dep.name) - if (!dep.satisfies(edge)) + if (!dep.satisfies(edge)) { edge.overridden = true + } const vr = new Node({ sourceReference: node, path: node.path, @@ -52,8 +53,9 @@ t.test('basic placement check tests', t => { // mark any invalid edges in the virtual root as overridden for (const child of vr.children.values()) { for (const edgeIn of child.edgesIn) { - if (edgeIn.invalid) + if (edgeIn.invalid) { edgeIn.overridden = true + } } } @@ -76,10 +78,12 @@ t.test('basic placement check tests', t => { // dump a comment if the assertion fails. // would put it in the diags, but yaml stringifies Set objects // super awkwardly, and Node objects have a lot of those. - if (!t.equal(cpd.canPlace, expect, msg)) + if (!t.equal(cpd.canPlace, expect, msg)) { t.comment(cpd) - if (expectSelf) + } + if (expectSelf) { t.equal(cpd.canPlaceSelf, expectSelf, msg) + } t.equal(cpd.description, cpd.canPlace.description || cpd.canPlace) t.matchSnapshot([...cpd.conflictChildren].map(c => ({ dep: [c.dep.name, c.dep.version], diff --git a/test/diff.js b/test/diff.js index 9f80aa7af..fc3e62bae 100644 --- a/test/diff.js +++ b/test/diff.js @@ -411,7 +411,11 @@ t.test('diff doesnt break unchanged shrinkwrapped deps', async t => { // marked as unchanged. const shrinkwrappedInner = ideal.children.get('regular-dep') .children.get('shrinkwrapped-inner') - const diff = Diff.calculate({ actual, ideal, shrinkwrapInflated: new Set([shrinkwrappedInner]) }) + const diff = Diff.calculate({ + actual, + ideal, + shrinkwrapInflated: new Set([shrinkwrappedInner]), + }) t.matchSnapshot(diff, 'made no changes') t.equal(diff.leaves.length, 1, 'diff has exactly one leaf') @@ -479,17 +483,26 @@ t.test('extraneous pruning in workspaces', async t => { const actual = await new Arborist({path}).loadVirtual() const ideal = await new Arborist({path}).loadVirtual() for (const node of ideal.inventory.values()) { - if (node.extraneous) + if (node.extraneous) { node.root = null + } } const idealA = ideal.children.get('a').target const actualA = actual.children.get('a').target - const pruneWsA = Diff.calculate({actual, ideal, filterNodes: [idealA, actualA]}) + const pruneWsA = Diff.calculate({ + actual, + ideal, + filterNodes: [idealA, actualA], + }) t.matchSnapshot(pruneWsA, 'prune in workspace A') const idealB = ideal.children.get('b').target const actualB = actual.children.get('b').target - const pruneWsB = Diff.calculate({actual, ideal, filterNodes: [idealB, actualB]}) + const pruneWsB = Diff.calculate({ + actual, + ideal, + filterNodes: [idealB, actualB], + }) t.matchSnapshot(pruneWsB, 'prune in workspace B') }) diff --git a/test/edge.js b/test/edge.js index 11955e850..2e1fdffab 100644 --- a/test/edge.js +++ b/test/edge.js @@ -512,7 +512,8 @@ const bundledEdge = new Edge({ }) t.ok(bundledEdge.satisfiedBy(bundleChild), 'bundled dependency') -const fromBundleDependencies = bundledEdge.from && bundledEdge.from.package.bundleDependencies +const fromBundleDependencies = bundledEdge.from && + bundledEdge.from.package.bundleDependencies t.same(fromBundleDependencies, ['bundle-child'], 'edge.from bundledDependencies as expected') t.same(bundledEdge.name, 'bundle-child', 'edge name as expected') t.equal(bundledEdge.bundled, true, 'bundled prop is true') diff --git a/test/node.js b/test/node.js index 6068fcab5..d4baefa05 100644 --- a/test/node.js +++ b/test/node.js @@ -264,8 +264,8 @@ t.test('testing with dep tree', t => { t.equal(prod.children.size, 0, 'kids moved to newProd') t.equal(prod.root, prod, 'prod excised from tree') t.equal(newProd.root, root, 'newProd in the tree') - // XXX seems like these should be flipped, taking over fsChildren is weird? - t.equal(newProd.fsChildren.size, 0, 'fsChildren replaced by replacement node') + // XXX seems wrong, taking over fsChildren is weird? + t.equal(newProd.fsChildren.size, 0, 'fsChildren replaced') t.equal(prod.fsChildren.size, 1, 'fsChildren go along with fsParent') t.equal([...prod.fsChildren][0], foo, 'foo still in old prod fsChildren set') t.equal(foo.fsParent, prod, 'prod is still foos fsParent') @@ -611,8 +611,9 @@ t.test('load with a virtual filesystem parent', t => { aLink.root = root t.equal(root.inventory.get(aLoc), aLink) t.equal(a.root, a) - for (const node of underA) + for (const node of underA) { t.not(node.root, root, `${node.path} still under old root`) + } // create a new fsChild several steps below the root, then shove // a link in the way of it, removing it. @@ -1440,8 +1441,9 @@ t.test('reloading named edges should refresh edgesIn', t => { t.test('detect that two nodes are the same thing', async t => { const check = (a, b, expect, message) => { t.equal(a.matches(b), expect, message) - if (a !== b) + if (a !== b) { t.equal(b.matches(a), expect, message) + } } { @@ -2455,13 +2457,17 @@ t.test('canDedupe()', t => { ], }) - t.match([...root.inventory.filter(n => n.canDedupe())].map(n => n.location), [ + const canDedupeLocs = [...root.inventory.filter(n => n.canDedupe())] + .map(n => n.location) + t.match(canDedupeLocs, [ 'node_modules/c/node_modules/a', 'node_modules/b/node_modules/e', 'node_modules/b/node_modules/c/node_modules/a/node_modules/e', ], 'preferDedupe=false') - t.match([...root.inventory.filter(n => n.canDedupe(true))].map(n => n.location), [ + const canDedupeTrueLocs = [...root.inventory.filter(n => n.canDedupe(true))] + .map(n => n.location) + t.match(canDedupeTrueLocs, [ 'node_modules/c/node_modules/a', // this is the one that's only deduped if we preferDedupe 'node_modules/b/node_modules/a', @@ -2656,5 +2662,4 @@ t.test('children of the global root are considered tops', t => { t.equal(foo.top, foo) t.equal(bar.top, foo) t.end() - t.equal(foo.isTop, true) }) diff --git a/test/place-dep.js b/test/place-dep.js index efe656157..4e8352967 100644 --- a/test/place-dep.js +++ b/test/place-dep.js @@ -50,8 +50,9 @@ t.test('placement tests', t => { const node = tree.inventory.get(nodeLoc) const edge = node.edgesOut.get(dep.name) - if (!dep.satisfies(edge)) + if (!dep.satisfies(edge)) { edge.overridden = true + } const vr = new Node({ sourceReference: node, path: node.path, @@ -63,8 +64,9 @@ t.test('placement tests', t => { // mark any invalid edges in the virtual root as overridden for (const child of vr.children.values()) { for (const edgeIn of child.edgesIn) { - if (edgeIn.invalid) + if (edgeIn.invalid) { edgeIn.overridden = true + } } } @@ -117,8 +119,9 @@ t.test('placement tests', t => { const warnings = [] const onwarn = (level, ...msg) => { - if (level === 'warn') + if (level === 'warn') { warnings.push(msg) + } } process.on('log', onwarn) @@ -131,8 +134,9 @@ t.test('placement tests', t => { } process.removeListener('log', onwarn) - if (test) + if (test) { test(t, tree) + } const after = normalizePaths(tree.toJSON()) const { diff } = strict(after, before) @@ -140,8 +144,9 @@ t.test('placement tests', t => { t.matchSnapshot(diff, 'changes to tree') t.matchSnapshot(normalizePaths(warnings), 'warnings') t.matchSnapshot([pd, ...pd.allChildren].map(c => { - if (c.canPlace && c.canPlace.canPlace === KEEP) + if (c.canPlace && c.canPlace.canPlace === KEEP) { t.equal(c.placed, null, 'should not place if result is KEEP') + } return normalizePaths({ ...(c.parent ? { parent: c.parent.name } : {}), edge: `{ ${ diff --git a/test/shrinkwrap.js b/test/shrinkwrap.js index 784ef2e9a..c5902b2ed 100644 --- a/test/shrinkwrap.js +++ b/test/shrinkwrap.js @@ -25,7 +25,11 @@ const saxFixture = resolve(__dirname, 'fixtures/sax') // start out with the file being fresh const later = Date.now() + 10000 -fs.utimesSync(resolve(hiddenLockfileFixture, hidden), new Date(later), new Date(later)) +fs.utimesSync( + resolve(hiddenLockfileFixture, hidden), + new Date(later), + new Date(later) +) t.test('shrinkwrap key order', async t => t.matchSnapshot(Shrinkwrap.keyOrder)) @@ -95,7 +99,11 @@ t.test('loading in empty dir gets empty lockfile', t => path: emptyFixture, realpath: emptyFixture, }) - root.peer = root.dev = root.devOptional = root.optional = root.extraneous = false + root.peer = false + root.dev = false + root.devOptional = false + root.optional = false + root.extraneous = false sw.add(root) t.strictSame(sw.commit(), { name: 'empty', @@ -808,8 +816,9 @@ t.test('hidden lockfile understands symlinks', async t => { name: 'missing', version: '1.2.3', })) - if (process.platform === 'win32') + if (process.platform === 'win32') { fs.symlinkSync(resolve(path, 'missing'), resolve(path, 'node_modules/missing'), 'junction') + } // even though it's newer, the 'missing' is not found in the lock const later = Date.now() + 30000 fs.utimesSync(resolve(path, hidden), new Date(later), new Date(later)) @@ -1363,7 +1372,9 @@ t.test('metadata that only has one of resolved/integrity', t => { }) t.test('load an ancient lockfile', async t => - t.match(await Shrinkwrap.load({ path: saxFixture }), { ancientLockfile: true })) + t.match(await Shrinkwrap.load({ path: saxFixture }), { + ancientLockfile: true, + })) t.test('shrinkwrap where root is a link node', async t => { const meta = await Shrinkwrap.reset({ path: '/actual/project/path' }) diff --git a/test/signal-handling.js b/test/signal-handling.js index 8a9e45ce0..344f60cf8 100644 --- a/test/signal-handling.js +++ b/test/signal-handling.js @@ -115,10 +115,12 @@ t.test('no max listener warning', t => { })) const unloads = [] - for (let i = 0; i < 1000; i++) + for (let i = 0; i < 1000; i++) { unloads.push(onExit(() => {})) - for (const unload of unloads) + } + for (const unload of unloads) { unload() + } t.pass('if no throw, then it worked') }) diff --git a/test/spec-from-lock.js b/test/spec-from-lock.js index a657905e0..af313e2f4 100644 --- a/test/spec-from-lock.js +++ b/test/spec-from-lock.js @@ -10,12 +10,13 @@ const isHGIFn = (key, val) => const normalizePaths = obj => { for (const key in obj) { - if (['where', 'fetchSpec', 'saveSpec'].includes(key) && obj[key]) + if (['where', 'fetchSpec', 'saveSpec'].includes(key) && obj[key]) { obj[key] = normalizePath(obj[key]) - else if (isHGIFn(key, obj[key])) + } else if (isHGIFn(key, obj[key])) { obj[key] = `function ${key}` - else if (typeof obj[key] === 'object' && obj[key] !== null) + } else if (typeof obj[key] === 'object' && obj[key] !== null) { obj[key] = normalizePaths(obj[key]) + } } return obj }