diff options
author | Gar <gar+gh@danger.computer> | 2021-11-04 20:21:00 +0300 |
---|---|---|
committer | Gar <gar+gh@danger.computer> | 2021-11-05 00:45:18 +0300 |
commit | 225645420cf3d13bc0b0d591f7f7bf21a9c24e47 (patch) | |
tree | 107797bef3206793cda93d7dad97f3ab54ef3cd8 /lib/commands | |
parent | de45f90eebbf51205748ed3f09fbeab6cc000b3e (diff) |
chore: update to latest eslint and linting rules
This brings us in line with the rest of the linting rules we are wanting
to use on the npm cli repos.
There were several hundred over-length lines and instead of editing them
all by hand I piped the failing file through `prettier` and back through
`eslint` just to save some time and energy. This means there may be
some quirks in the linting those files have, but we can fix those if we
see them and they bother us.
Other than that there were about 50 lines that are legitimately
over-length, all are now explicitly overridden. Many are tests that
could be snapshots.
PR-URL: https://github.com/npm/cli/pull/3995
Credit: @wraithgar
Close: #3995
Reviewed-by: @lukekarrys
Diffstat (limited to 'lib/commands')
49 files changed, 1083 insertions, 665 deletions
diff --git a/lib/commands/access.js b/lib/commands/access.js index 15e51a450..df783c35f 100644 --- a/lib/commands/access.js +++ b/lib/commands/access.js @@ -52,15 +52,17 @@ class Access extends BaseCommand { async completion (opts) { const argv = opts.conf.argv.remain - if (argv.length === 2) + if (argv.length === 2) { return subcommands + } switch (argv[2]) { case 'grant': - if (argv.length === 3) + if (argv.length === 3) { return ['read-only', 'read-write'] - else + } else { return [] + } case 'public': case 'restricted': @@ -77,11 +79,13 @@ class Access extends BaseCommand { } async exec ([cmd, ...args]) { - if (!cmd) + if (!cmd) { throw this.usageError('Subcommand is required.') + } - if (!subcommands.includes(cmd) || !this[cmd]) + if (!subcommands.includes(cmd) || !this[cmd]) { throw this.usageError(`${cmd} is not a recognized subcommand.`) + } return this[cmd](args, this.npm.flatOptions) } @@ -95,11 +99,13 @@ class Access extends BaseCommand { } async grant ([perms, scopeteam, pkg], opts) { - if (!perms || (perms !== 'read-only' && perms !== 'read-write')) + if (!perms || (perms !== 'read-only' && perms !== 'read-write')) { throw this.usageError('First argument must be either `read-only` or `read-write`.') + } - if (!scopeteam) + if (!scopeteam) { throw this.usageError('`<scope:team>` argument is required.') + } const [, scope, team] = scopeteam.match(/^@?([^:]+):(.*)$/) || [] @@ -115,8 +121,9 @@ class Access extends BaseCommand { } async revoke ([scopeteam, pkg], opts) { - if (!scopeteam) + if (!scopeteam) { throw this.usageError('`<scope:team>` argument is required.') + } const [, scope, team] = scopeteam.match(/^@?([^:]+):(.*)$/) || [] @@ -152,8 +159,9 @@ class Access extends BaseCommand { } async lsPackages ([owner], opts) { - if (!owner) + if (!owner) { owner = await getIdentity(this.npm, opts) + } const pkgs = await libaccess.lsPackages(owner, opts) @@ -183,9 +191,9 @@ class Access extends BaseCommand { } async getPackage (name, requireScope) { - if (name && name.trim()) + if (name && name.trim()) { return name.trim() - else { + } else { try { const pkg = await readPackageJson(path.resolve(this.npm.prefix, 'package.json')) name = pkg.name @@ -194,14 +202,16 @@ class Access extends BaseCommand { throw new Error( 'no package name passed to command and no package.json found' ) - } else + } else { throw err + } } - if (requireScope && !name.match(/^@[^/]+\/.*$/)) + if (requireScope && !name.match(/^@[^/]+\/.*$/)) { throw this.usageError('This command is only available for scoped packages.') - else + } else { return name + } } } } diff --git a/lib/commands/adduser.js b/lib/commands/adduser.js index 6136eb726..aa3d8a336 100644 --- a/lib/commands/adduser.js +++ b/lib/commands/adduser.js @@ -54,8 +54,9 @@ class AddUser extends BaseCommand { if (scope) { const scopedRegistry = this.npm.config.get(`${scope}:registry`) const cliRegistry = this.npm.config.get('registry', 'cli') - if (scopedRegistry && !cliRegistry) + if (scopedRegistry && !cliRegistry) { return scopedRegistry + } } return registry } @@ -63,8 +64,9 @@ class AddUser extends BaseCommand { getAuthType ({ authType }) { const type = authTypes[authType] - if (!type) + if (!type) { throw new Error('no such auth module') + } return type } @@ -72,8 +74,9 @@ class AddUser extends BaseCommand { async updateConfig ({ newCreds, registry, scope }) { this.npm.config.delete('_token', 'user') // prevent legacy pollution this.npm.config.setCredentialsByURI(registry, newCreds) - if (scope) + if (scope) { this.npm.config.set(scope + ':registry', registry, 'user') + } await this.npm.config.save('user') } } diff --git a/lib/commands/audit.js b/lib/commands/audit.js index d05633ab0..ebc9f65c5 100644 --- a/lib/commands/audit.js +++ b/lib/commands/audit.js @@ -36,8 +36,9 @@ class Audit extends ArboristWorkspaceCmd { async completion (opts) { const argv = opts.conf.argv.remain - if (argv.length === 2) + if (argv.length === 2) { return ['fix'] + } switch (argv[2]) { case 'fix': @@ -60,9 +61,9 @@ class Audit extends ArboristWorkspaceCmd { const arb = new Arborist(opts) const fix = args[0] === 'fix' await arb.audit({ fix }) - if (fix) + if (fix) { await reifyFinish(this.npm, arb) - else { + } else { // will throw if there's an error, because this is an audit command auditError(this.npm, arb.auditReport) const result = auditReport(arb.auditReport, opts) diff --git a/lib/commands/bin.js b/lib/commands/bin.js index 9a894f3bb..68559e413 100644 --- a/lib/commands/bin.js +++ b/lib/commands/bin.js @@ -17,8 +17,9 @@ class Bin extends BaseCommand { async exec (args) { const b = this.npm.bin this.npm.output(b) - if (this.npm.config.get('global') && !envPath.includes(b)) + if (this.npm.config.get('global') && !envPath.includes(b)) { console.error('(not in PATH env variable)') + } } } module.exports = Bin diff --git a/lib/commands/bugs.js b/lib/commands/bugs.js index 863a7ffec..ecf50f32e 100644 --- a/lib/commands/bugs.js +++ b/lib/commands/bugs.js @@ -23,8 +23,9 @@ class Bugs extends BaseCommand { } async exec (args) { - if (!args || !args.length) + if (!args || !args.length) { args = ['.'] + } await Promise.all(args.map(pkg => this.getBugs(pkg))) } @@ -39,20 +40,24 @@ class Bugs extends BaseCommand { getBugsUrl (mani) { if (mani.bugs) { - if (typeof mani.bugs === 'string') + if (typeof mani.bugs === 'string') { return mani.bugs + } - if (typeof mani.bugs === 'object' && mani.bugs.url) + if (typeof mani.bugs === 'object' && mani.bugs.url) { return mani.bugs.url + } - if (typeof mani.bugs === 'object' && mani.bugs.email) + if (typeof mani.bugs === 'object' && mani.bugs.email) { return `mailto:${mani.bugs.email}` + } } // try to get it from the repo, if possible const info = hostedFromMani(mani) - if (info) + if (info) { return info.bugs() + } // just send them to the website, hopefully that has some info! return `https://www.npmjs.com/package/${mani.name}` diff --git a/lib/commands/cache.js b/lib/commands/cache.js index b4a932d1b..9a089c562 100644 --- a/lib/commands/cache.js +++ b/lib/commands/cache.js @@ -12,8 +12,10 @@ const localeCompare = require('@isaacs/string-locale-compare')('en') const searchCachePackage = async (path, spec, cacheKeys) => { const parsed = npa(spec) - if (parsed.rawSpec !== '' && parsed.type === 'tag') + if (parsed.rawSpec !== '' && parsed.type === 'tag') { throw new Error(`Cannot list cache keys for a tagged package.`) + } + /* eslint-disable-next-line max-len */ const searchMFH = new RegExp(`^make-fetch-happen:request-cache:.*(?<!/[@a-zA-Z]+)/${parsed.name}/-/(${parsed.name}[^/]+.tgz)$`) const searchPack = new RegExp(`^make-fetch-happen:request-cache:.*/${parsed.escapedName}$`) const results = new Set() @@ -26,13 +28,15 @@ const searchCachePackage = async (path, spec, cacheKeys) => { const noExt = filename.slice(0, -4) const noScope = `${parsed.name.split('/').pop()}-` const ver = noExt.slice(noScope.length) - if (semver.satisfies(ver, parsed.rawSpec)) + if (semver.satisfies(ver, parsed.rawSpec)) { results.add(key) + } continue } // is this key a packument? - if (!searchPack.test(key)) + if (!searchPack.test(key)) { continue + } results.add(key) let packument, details @@ -43,16 +47,19 @@ const searchCachePackage = async (path, spec, cacheKeys) => { // if we couldn't parse the packument, abort continue } - if (!packument.versions || typeof packument.versions !== 'object') + if (!packument.versions || typeof packument.versions !== 'object') { continue + } // assuming this is a packument for (const ver of Object.keys(packument.versions)) { if (semver.satisfies(ver, parsed.rawSpec)) { - if (packument.versions[ver].dist - && typeof packument.versions[ver].dist === 'object' - && packument.versions[ver].dist.tarball !== undefined - && cacheKeys.has(`make-fetch-happen:request-cache:${packument.versions[ver].dist.tarball}`)) + if (packument.versions[ver].dist && + typeof packument.versions[ver].dist === 'object' && + packument.versions[ver].dist.tarball !== undefined && + cacheKeys.has(`make-fetch-happen:request-cache:${packument.versions[ver].dist.tarball}`) + ) { results.add(`make-fetch-happen:request-cache:${packument.versions[ver].dist.tarball}`) + } } } } @@ -90,8 +97,9 @@ class Cache extends BaseCommand { async completion (opts) { const argv = opts.conf.argv.remain - if (argv.length === 2) + if (argv.length === 2) { return ['add', 'clean', 'verify', 'ls', 'delete'] + } // TODO - eventually... switch (argv[2]) { @@ -162,8 +170,9 @@ class Cache extends BaseCommand { // npm cache add <folder>... async add (args) { log.silly('cache add', 'args', args) - if (args.length === 0) + if (args.length === 0) { throw this.usageError('First argument to `add` is required') + } return Promise.all(args.map(spec => { log.silly('cache add', 'spec', spec) @@ -185,9 +194,16 @@ class Cache extends BaseCommand { const stats = await cacache.verify(cache) this.npm.output(`Cache verified and compressed (${prefix})`) this.npm.output(`Content verified: ${stats.verifiedContent} (${stats.keptSize} bytes)`) - stats.badContentCount && this.npm.output(`Corrupted content removed: ${stats.badContentCount}`) - stats.reclaimedCount && this.npm.output(`Content garbage-collected: ${stats.reclaimedCount} (${stats.reclaimedSize} bytes)`) - stats.missingContent && this.npm.output(`Missing content: ${stats.missingContent}`) + if (stats.badContentCount) { + this.npm.output(`Corrupted content removed: ${stats.badContentCount}`) + } + if (stats.reclaimedCount) { + /* eslint-disable-next-line max-len */ + this.npm.output(`Content garbage-collected: ${stats.reclaimedCount} (${stats.reclaimedSize} bytes)`) + } + if (stats.missingContent) { + this.npm.output(`Missing content: ${stats.missingContent}`) + } this.npm.output(`Index entries: ${stats.totalEntries}`) this.npm.output(`Finished in ${stats.runTime.total / 1000}s`) } @@ -201,8 +217,9 @@ class Cache extends BaseCommand { const results = new Set() for (const spec of specs) { const keySet = await searchCachePackage(cachePath, spec, cacheKeys) - for (const key of keySet) + for (const key of keySet) { results.add(key) + } } [...results].sort(localeCompare).forEach(key => this.npm.output(key)) return diff --git a/lib/commands/completion.js b/lib/commands/completion.js index fbbde0df7..bce6c3619 100644 --- a/lib/commands/completion.js +++ b/lib/commands/completion.js @@ -57,8 +57,9 @@ class Completion extends BaseCommand { // completion for the completion command async completion (opts) { - if (opts.w > 2) + if (opts.w > 2) { return + } const { resolve } = require('path') const [bashExists, zshExists] = await Promise.all([ @@ -66,11 +67,13 @@ class Completion extends BaseCommand { fileExists(resolve(process.env.HOME, '.zshrc')), ]) const out = [] - if (zshExists) + if (zshExists) { out.push(['>>', '~/.zshrc']) + } - if (bashExists) + if (bashExists) { out.push(['>>', '~/.bashrc']) + } return out } @@ -88,8 +91,9 @@ class Completion extends BaseCommand { // if the COMP_* isn't in the env, then just dump the script. if (COMP_CWORD === undefined || COMP_LINE === undefined || - COMP_POINT === undefined) + COMP_POINT === undefined) { return dumpScript() + } // ok we're actually looking at the envs and outputting the suggestions // get the partial line and partial word, @@ -106,8 +110,9 @@ class Completion extends BaseCommand { // figure out where in that last word the point is. const partialWordRaw = args[w] let i = partialWordRaw.length - while (partialWordRaw.substr(0, i) !== partialLine.substr(-1 * i) && i > 0) + while (partialWordRaw.substr(0, i) !== partialLine.substr(-1 * i) && i > 0) { i-- + } const partialWord = unescape(partialWordRaw.substr(0, i)) partialWords.push(partialWord) @@ -126,8 +131,9 @@ class Completion extends BaseCommand { } if (partialWords.slice(0, -1).indexOf('--') === -1) { - if (word.charAt(0) === '-') + if (word.charAt(0) === '-') { return this.wrap(opts, configCompl(opts)) + } if (words[w - 1] && words[w - 1].charAt(0) === '-' && @@ -151,8 +157,9 @@ class Completion extends BaseCommand { nopt(types, shorthands, partialWords.slice(0, -1), 0) // check if there's a command already. const cmd = parsed.argv.remain[1] - if (!cmd) + if (!cmd) { return this.wrap(opts, cmdCompl(opts)) + } Object.keys(parsed).forEach(k => this.npm.config.set(k, parsed[k])) @@ -173,17 +180,20 @@ class Completion extends BaseCommand { // Ie, returning ['a', 'b c', ['d', 'e']] would allow it to expand // to: 'a', 'b c', or 'd' 'e' wrap (opts, compls) { - if (!Array.isArray(compls)) + if (!Array.isArray(compls)) { compls = compls ? [compls] : [] + } compls = compls.map(c => Array.isArray(c) ? c.map(escape).join(' ') : escape(c)) - if (opts.partialWord) + if (opts.partialWord) { compls = compls.filter(c => c.startsWith(opts.partialWord)) + } - if (compls.length > 0) + if (compls.length > 0) { this.npm.output(compls.join('\n')) + } } } @@ -197,8 +207,9 @@ const dumpScript = async () => { await new Promise((res, rej) => { let done = false process.stdout.on('error', er => { - if (done) + if (done) { return + } done = true @@ -214,15 +225,17 @@ const dumpScript = async () => { // can never ever work on OS X. // TODO Ignoring coverage, see 'non EPIPE errors cause failures' test. /* istanbul ignore next */ - if (er.errno === 'EPIPE') + if (er.errno === 'EPIPE') { res() - else + } else { rej(er) + } }) process.stdout.write(d, () => { - if (done) + if (done) { return + } done = true res() @@ -258,7 +271,7 @@ const isFlag = word => { const split = word.match(/^(-*)((?:no-)+)?(.*)$/) const no = split[2] const conf = split[3] - const {type} = definitions[conf] + const { type } = definitions[conf] return no || type === Boolean || (Array.isArray(type) && type.includes(Boolean)) || @@ -269,12 +282,14 @@ const isFlag = word => { // if they all resolve to the same thing, just return the thing it already is const cmdCompl = opts => { const matches = fullList.filter(c => c.startsWith(opts.partialWord)) - if (!matches.length) + if (!matches.length) { return matches + } const derefs = new Set([...matches.map(c => deref(c))]) - if (derefs.size === 1) + if (derefs.size === 1) { return [...derefs] + } return fullList } diff --git a/lib/commands/config.js b/lib/commands/config.js index fc482edb6..0e92f6f3e 100644 --- a/lib/commands/config.js +++ b/lib/commands/config.js @@ -64,13 +64,15 @@ class Config extends BaseCommand { async completion (opts) { const argv = opts.conf.argv.remain - if (argv[1] !== 'config') + if (argv[1] !== 'config') { argv.unshift('config') + } if (argv.length === 2) { const cmds = ['get', 'set', 'delete', 'ls', 'rm', 'edit'] - if (opts.partialWord !== 'l') + if (opts.partialWord !== 'l') { cmds.push('list') + } return cmds } @@ -79,8 +81,9 @@ class Config extends BaseCommand { switch (action) { case 'set': // todo: complete with valid values, if possible. - if (argv.length > 3) + if (argv.length > 3) { return [] + } // fallthrough /* eslint no-fallthrough:0 */ @@ -132,28 +135,32 @@ class Config extends BaseCommand { } async set (args) { - if (!args.length) + if (!args.length) { throw this.usageError() + } const where = this.npm.flatOptions.location for (const [key, val] of Object.entries(keyValues(args))) { this.npm.log.info('config', 'set %j %j', key, val) this.npm.config.set(key, val || '', where) - if (!this.npm.config.validate(where)) + if (!this.npm.config.validate(where)) { this.npm.log.warn('config', 'omitting invalid config values') + } } await this.npm.config.save(where) } async get (keys) { - if (!keys.length) + if (!keys.length) { return this.list() + } const out = [] for (const key of keys) { - if (!publicVar(key)) + if (!publicVar(key)) { throw `The ${key} option is protected, and cannot be retrieved in this way` + } const pref = keys.length > 1 ? `${key}=` : '' out.push(pref + this.npm.config.get(key)) @@ -162,12 +169,14 @@ class Config extends BaseCommand { } async del (keys) { - if (!keys.length) + if (!keys.length) { throw this.usageError() + } const where = this.npm.flatOptions.location - for (const key of keys) + for (const key of keys) { this.npm.config.delete(key, where) + } await this.npm.config.save(where) } @@ -220,8 +229,9 @@ ${defData} const [bin, ...args] = e.split(/\s+/) const editor = spawn(bin, [...args, file], { stdio: 'inherit' }) editor.on('exit', (code) => { - if (code) + if (code) { return reject(new Error(`editor process exited with code: ${code}`)) + } return resolve() }) }) @@ -232,12 +242,14 @@ ${defData} // long does not have a flattener const long = this.npm.config.get('long') for (const [where, { data, source }] of this.npm.config.data.entries()) { - if (where === 'default' && !long) + if (where === 'default' && !long) { continue + } const keys = Object.keys(data).sort(localeCompare) - if (!keys.length) + if (!keys.length) { continue + } msg.push(`; "${where}" config from ${source}`, '') for (const k of keys) { @@ -265,8 +277,9 @@ ${defData} async listJson () { const publicConf = {} for (const key in this.npm.config.list[0]) { - if (!publicVar(key)) + if (!publicVar(key)) { continue + } publicConf[key] = this.npm.config.get(key) } diff --git a/lib/commands/deprecate.js b/lib/commands/deprecate.js index 37b9d2dc2..1e33b98bf 100644 --- a/lib/commands/deprecate.js +++ b/lib/commands/deprecate.js @@ -30,8 +30,9 @@ class Deprecate extends BaseCommand { } async completion (opts) { - if (opts.conf.argv.remain.length > 1) + if (opts.conf.argv.remain.length > 1) { return [] + } const username = await getIdentity(this.npm, this.npm.flatOptions) const packages = await libaccess.lsPackages(username, this.npm.flatOptions) @@ -44,8 +45,9 @@ class Deprecate extends BaseCommand { async exec ([pkg, msg]) { // msg == null because '' is a valid value, it indicates undeprecate - if (!pkg || msg == null) + if (!pkg || msg == null) { throw this.usageError() + } // fetch the data and make sure it exists. const p = npa(pkg) @@ -53,8 +55,9 @@ class Deprecate extends BaseCommand { // "*" is the appropriate default. const spec = p.rawSpec === '' ? '*' : p.fetchSpec - if (semver.validRange(spec, true) === null) + if (semver.validRange(spec, true) === null) { throw new Error(`invalid version range: ${spec}`) + } const uri = '/' + p.escapedName const packument = await fetch.json(uri, { diff --git a/lib/commands/diff.js b/lib/commands/diff.js index 67d0d1505..f6e2cce8b 100644 --- a/lib/commands/diff.js +++ b/lib/commands/diff.js @@ -49,22 +49,25 @@ class Diff extends BaseCommand { async exec (args) { const specs = this.npm.config.get('diff').filter(d => d) - if (specs.length > 2) + if (specs.length > 2) { throw this.usageError(`Can't use more than two --diff arguments.`) + } // execWorkspaces may have set this already - if (!this.prefix) + if (!this.prefix) { this.prefix = this.npm.prefix + } // this is the "top" directory, one up from node_modules // in global mode we have to walk one up from globalDir because our // node_modules is sometimes under ./lib, and in global mode we're only ever // walking through node_modules (because we will have been given a package // name already) - if (this.npm.config.get('global')) + if (this.npm.config.get('global')) { this.top = resolve(this.npm.globalDir, '..') - else + } else { this.top = this.prefix + } const [a, b] = await this.retrieveSpecs(specs) npmlog.info('diff', { src: a, dst: b }) @@ -96,8 +99,9 @@ class Diff extends BaseCommand { npmlog.verbose('diff', 'could not read project dir package.json') } - if (!name) + if (!name) { throw this.usageError('Needs multiple arguments to compare or run from a project dir.') + } return name } @@ -129,14 +133,16 @@ class Diff extends BaseCommand { noPackageJson = true } - const missingPackageJson = this.usageError('Needs multiple arguments to compare or run from a project dir.') + const missingPackageJson = + this.usageError('Needs multiple arguments to compare or run from a project dir.') // using a valid semver range, that means it should just diff // the cwd against a published version to the registry using the // same project name and the provided semver range if (semver.validRange(a)) { - if (!pkgName) + if (!pkgName) { throw missingPackageJson + } return [ `${pkgName}@${a}`, `file:${this.prefix}`, @@ -165,8 +171,9 @@ class Diff extends BaseCommand { } if (!node || !node.name || !node.package || !node.package.version) { - if (noPackageJson) + if (noPackageJson) { throw missingPackageJson + } return [ `${spec.name}@${spec.fetchSpec}`, `file:${this.prefix}`, @@ -177,8 +184,9 @@ class Diff extends BaseCommand { (actualTree && actualTree.edgesOut.get(spec.name) || {}).spec const tryAnySpec = () => { - for (const edge of node.edgesIn) + for (const edge of node.edgesIn) { return edge.spec + } } const aSpec = `file:${node.realpath}` @@ -188,9 +196,9 @@ class Diff extends BaseCommand { // work from the top of the arborist tree to find the original semver // range declared in the package that depends on the package. let bSpec - if (spec.rawSpec) + if (spec.rawSpec) { bSpec = spec.rawSpec - else { + } else { const bTargetVersion = tryRootNodeSpec() || tryAnySpec() @@ -217,8 +225,9 @@ class Diff extends BaseCommand { `file:${spec.fetchSpec}`, `file:${this.prefix}`, ] - } else + } else { throw this.usageError(`Spec type ${spec.type} not supported.`) + } } async convertVersionsToSpecs ([a, b]) { @@ -234,19 +243,22 @@ class Diff extends BaseCommand { npmlog.verbose('diff', 'could not read project dir package.json') } - if (!pkgName) + if (!pkgName) { throw this.usageError('Needs to be run from a project dir in order to diff two versions.') + } return [`${pkgName}@${a}`, `${pkgName}@${b}`] } // otherwise uses the name from the other arg to // figure out the spec.name of what to compare - if (!semverA && semverB) + if (!semverA && semverB) { return [a, `${npa(a).name}@${b}`] + } - if (semverA && !semverB) + if (semverA && !semverB) { return [`${npa(b).name}@${a}`, b] + } // no valid semver ranges used return [a, b] @@ -267,8 +279,9 @@ class Diff extends BaseCommand { return specs.map(i => { const spec = npa(i) - if (spec.rawSpec) + if (spec.rawSpec) { return i + } const node = actualTree && actualTree.inventory.query('name', spec.name) diff --git a/lib/commands/dist-tag.js b/lib/commands/dist-tag.js index b7baa3d46..9c938851a 100644 --- a/lib/commands/dist-tag.js +++ b/lib/commands/dist-tag.js @@ -33,8 +33,9 @@ class DistTag extends BaseCommand { async completion (opts) { const argv = opts.conf.argv.remain - if (argv.length === 2) + if (argv.length === 2) { return ['add', 'rm', 'ls'] + } switch (argv[2]) { default: @@ -45,21 +46,25 @@ class DistTag extends BaseCommand { async exec ([cmdName, pkg, tag]) { const opts = this.npm.flatOptions - if (['add', 'a', 'set', 's'].includes(cmdName)) + if (['add', 'a', 'set', 's'].includes(cmdName)) { return this.add(pkg, tag, opts) + } - if (['rm', 'r', 'del', 'd', 'remove'].includes(cmdName)) + if (['rm', 'r', 'del', 'd', 'remove'].includes(cmdName)) { return this.remove(pkg, tag, opts) + } - if (['ls', 'l', 'sl', 'list'].includes(cmdName)) + if (['ls', 'l', 'sl', 'list'].includes(cmdName)) { return this.list(pkg, opts) + } if (!pkg) { // when only using the pkg name the default behavior // should be listing the existing tags return this.list(cmdName, opts) - } else + } else { throw this.usageError() + } } async execWorkspaces ([cmdName, pkg, tag], filters) { @@ -68,16 +73,18 @@ class DistTag extends BaseCommand { // - unset // - . // - .@version - if (['ls', 'l', 'sl', 'list'].includes(cmdName) && (!pkg || pkg === '.' || /^\.@/.test(pkg))) + if (['ls', 'l', 'sl', 'list'].includes(cmdName) && (!pkg || pkg === '.' || /^\.@/.test(pkg))) { return this.listWorkspaces(filters) + } // pkg is unset // cmdName is one of: // - unset // - . // - .@version - if (!pkg && (!cmdName || cmdName === '.' || /^\.@/.test(cmdName))) + if (!pkg && (!cmdName || cmdName === '.' || /^\.@/.test(cmdName))) { return this.listWorkspaces(filters) + } // anything else is just a regular dist-tag command // so we fallback to the non-workspaces implementation @@ -92,13 +99,15 @@ class DistTag extends BaseCommand { log.verbose('dist-tag add', defaultTag, 'to', spec.name + '@' + version) - if (!spec.name || !version || !defaultTag) + if (!spec.name || !version || !defaultTag) { throw this.usageError() + } const t = defaultTag.trim() - if (semver.validRange(t)) + if (semver.validRange(t)) { throw new Error('Tag name must not be a valid SemVer range: ' + t) + } const tags = await this.fetchTags(spec, opts) if (tags[t] === version) { @@ -125,8 +134,9 @@ class DistTag extends BaseCommand { spec = npa(spec || '') log.verbose('dist-tag del', tag, 'from', spec.name) - if (!spec.name) + if (!spec.name) { throw this.usageError() + } const tags = await this.fetchTags(spec, opts) if (!tags[tag]) { @@ -148,11 +158,13 @@ class DistTag extends BaseCommand { async list (spec, opts) { if (!spec) { - if (this.npm.config.get('global')) + if (this.npm.config.get('global')) { throw this.usageError() + } const pkg = await readPackageName(this.npm.prefix) - if (!pkg) + if (!pkg) { throw this.usageError() + } return this.list(pkg, opts) } @@ -190,10 +202,12 @@ class DistTag extends BaseCommand { `/-/package/${spec.escapedName}/dist-tags`, { ...opts, 'prefer-online': true, spec } ) - if (data && typeof data === 'object') + if (data && typeof data === 'object') { delete data._etag - if (!data || !Object.keys(data).length) + } + if (!data || !Object.keys(data).length) { throw new Error('No dist-tags found for ' + spec.name) + } return data } diff --git a/lib/commands/docs.js b/lib/commands/docs.js index 4482678ea..e73528d18 100644 --- a/lib/commands/docs.js +++ b/lib/commands/docs.js @@ -32,8 +32,9 @@ class Docs extends BaseCommand { } async exec (args) { - if (!args || !args.length) + if (!args || !args.length) { args = ['.'] + } await Promise.all(args.map(pkg => this.getDocs(pkg))) } @@ -52,12 +53,14 @@ class Docs extends BaseCommand { } getDocsUrl (mani) { - if (mani.homepage) + if (mani.homepage) { return mani.homepage + } const info = hostedFromMani(mani) - if (info) + if (info) { return info.docs() + } return 'https://www.npmjs.com/package/' + mani.name } diff --git a/lib/commands/doctor.js b/lib/commands/doctor.js index b6363467c..8cb774ee3 100644 --- a/lib/commands/doctor.js +++ b/lib/commands/doctor.js @@ -11,21 +11,26 @@ const { promisify } = require('util') const ansiTrim = require('../utils/ansi-trim.js') const isWindows = require('../utils/is-windows.js') const ping = require('../utils/ping.js') -const { registry: { default: defaultRegistry } } = require('../utils/config/definitions.js') +const { + registry: { default: defaultRegistry }, +} = require('../utils/config/definitions.js') const lstat = promisify(fs.lstat) const readdir = promisify(fs.readdir) const access = promisify(fs.access) const { R_OK, W_OK, X_OK } = fs.constants const maskLabel = mask => { const label = [] - if (mask & R_OK) + if (mask & R_OK) { label.push('readable') + } - if (mask & W_OK) + if (mask & W_OK) { label.push('writable') + } - if (mask & X_OK) + if (mask & X_OK) { label.push('executable') + } return label.join(', ') } @@ -59,13 +64,31 @@ class Doctor extends BaseCommand { ['node -v', 'getLatestNodejsVersion', []], ['npm config get registry', 'checkNpmRegistry', []], ['which git', 'getGitPath', []], - ...(isWindows ? [] : [ - ['Perms check on cached files', 'checkFilesPermission', [this.npm.cache, true, R_OK]], - ['Perms check on local node_modules', 'checkFilesPermission', [this.npm.localDir, true]], - ['Perms check on global node_modules', 'checkFilesPermission', [this.npm.globalDir, false]], - ['Perms check on local bin folder', 'checkFilesPermission', [this.npm.localBin, false, R_OK | W_OK | X_OK]], - ['Perms check on global bin folder', 'checkFilesPermission', [this.npm.globalBin, false, X_OK]], - ]), + ...(isWindows + ? [] + : [ + ['Perms check on cached files', 'checkFilesPermission', [this.npm.cache, true, R_OK]], + [ + 'Perms check on local node_modules', + 'checkFilesPermission', + [this.npm.localDir, true], + ], + [ + 'Perms check on global node_modules', + 'checkFilesPermission', + [this.npm.globalDir, false], + ], + [ + 'Perms check on local bin folder', + 'checkFilesPermission', + [this.npm.localBin, false, R_OK | W_OK | X_OK], + ], + [ + 'Perms check on global bin folder', + 'checkFilesPermission', + [this.npm.globalBin, false, X_OK], + ], + ]), ['Verify cache contents', 'verifyCachedFiles', [this.npm.flatOptions.cache]], // TODO: // - ensure arborist.loadActual() runs without errors and no invalid edges @@ -85,39 +108,43 @@ class Doctor extends BaseCommand { messages.push(line) } - const outHead = ['Check', 'Value', 'Recommendation/Notes'] - .map(!this.npm.color ? h => h : h => chalk.underline(h)) + const outHead = ['Check', 'Value', 'Recommendation/Notes'].map( + !this.npm.color ? h => h : h => chalk.underline(h) + ) let allOk = true - const outBody = messages.map(!this.npm.color - ? item => { - allOk = allOk && item[1] - item[1] = item[1] ? 'ok' : 'not ok' - item[2] = String(item[2]) - return item - } - : item => { - allOk = allOk && item[1] - if (!item[1]) { - item[0] = chalk.red(item[0]) - item[2] = chalk.magenta(String(item[2])) + const outBody = messages.map( + !this.npm.color + ? item => { + allOk = allOk && item[1] + item[1] = item[1] ? 'ok' : 'not ok' + item[2] = String(item[2]) + return item } - item[1] = item[1] ? chalk.green('ok') : chalk.red('not ok') - return item - }) + : item => { + allOk = allOk && item[1] + if (!item[1]) { + item[0] = chalk.red(item[0]) + item[2] = chalk.magenta(String(item[2])) + } + item[1] = item[1] ? chalk.green('ok') : chalk.red('not ok') + return item + } + ) const outTable = [outHead, ...outBody] const tableOpts = { stringLength: s => ansiTrim(s).length, } - const silent = this.npm.log.levels[this.npm.log.level] > - this.npm.log.levels.error + const silent = this.npm.log.levels[this.npm.log.level] > this.npm.log.levels.error if (!silent) { this.npm.output(table(outTable, tableOpts)) - if (!allOk) + if (!allOk) { console.error('') + } } - if (!allOk) + if (!allOk) { throw new Error('Some problems found. See above for recommendations.') + } } async checkPing () { @@ -127,10 +154,11 @@ class Doctor extends BaseCommand { await ping(this.npm.flatOptions) return '' } catch (er) { - if (/^E\d{3}$/.test(er.code || '')) + if (/^E\d{3}$/.test(er.code || '')) { throw er.code.substr(1) + ' ' + er.message - else + } else { throw er.message + } } finally { tracker.finish() } @@ -141,10 +169,11 @@ class Doctor extends BaseCommand { tracker.info('getLatestNpmVersion', 'Getting npm package information') try { const latest = (await pacote.manifest('npm@latest', this.npm.flatOptions)).version - if (semver.gte(this.npm.version, latest)) + if (semver.gte(this.npm.version, latest)) { return `current: v${this.npm.version}, latest: v${latest}` - else + } else { throw `Use npm v${latest}` + } } finally { tracker.finish() } @@ -163,26 +192,29 @@ class Doctor extends BaseCommand { let maxCurrent = '0.0.0' let maxLTS = '0.0.0' for (const { lts, version } of data) { - if (lts && semver.gt(version, maxLTS)) + if (lts && semver.gt(version, maxLTS)) { maxLTS = version + } - if (semver.satisfies(version, currentRange) && - semver.gt(version, maxCurrent)) + if (semver.satisfies(version, currentRange) && semver.gt(version, maxCurrent)) { maxCurrent = version + } } const recommended = semver.gt(maxCurrent, maxLTS) ? maxCurrent : maxLTS - if (semver.gte(process.version, recommended)) + if (semver.gte(process.version, recommended)) { return `current: ${current}, recommended: ${recommended}` - else + } else { throw `Use node ${recommended} (current: ${current})` + } } finally { tracker.finish() } } async checkFilesPermission (root, shouldOwn, mask = null) { - if (mask === null) + if (mask === null) { mask = shouldOwn ? R_OK | W_OK : R_OK + } let ok = true @@ -194,24 +226,25 @@ class Doctor extends BaseCommand { const files = new Set([root]) for (const f of files) { tracker.silly('checkFilesPermission', f.substr(root.length + 1)) - const st = await lstat(f) - .catch(er => { - ok = false - tracker.warn('checkFilesPermission', 'error getting info for ' + f) - }) + const st = await lstat(f).catch(er => { + ok = false + tracker.warn('checkFilesPermission', 'error getting info for ' + f) + }) tracker.completeWork(1) - if (!st) + if (!st) { continue + } if (shouldOwn && (uid !== st.uid || gid !== st.gid)) { tracker.warn('checkFilesPermission', 'should be owner of ' + f) ok = false } - if (!st.isDirectory() && !st.isFile()) + if (!st.isDirectory() && !st.isFile()) { continue + } try { await access(f, mask) @@ -223,23 +256,26 @@ class Doctor extends BaseCommand { } if (st.isDirectory()) { - const entries = await readdir(f) - .catch(er => { - ok = false - tracker.warn('checkFilesPermission', 'error reading directory ' + f) - return [] - }) - for (const entry of entries) + const entries = await readdir(f).catch(er => { + ok = false + tracker.warn('checkFilesPermission', 'error reading directory ' + f) + return [] + }) + for (const entry of entries) { files.add(resolve(f, entry)) + } } } } finally { tracker.finish() if (!ok) { - throw `Check the permissions of files in ${root}` + + throw ( + `Check the permissions of files in ${root}` + (shouldOwn ? ' (should be owned by current user)' : '') - } else + ) + } else { return '' + } } } @@ -261,27 +297,29 @@ class Doctor extends BaseCommand { tracker.info('verifyCachedFiles', 'Verifying the npm cache') try { const stats = await cacache.verify(this.npm.flatOptions.cache) - const { - badContentCount, - reclaimedCount, - missingContent, - reclaimedSize, - } = stats + const { badContentCount, reclaimedCount, missingContent, reclaimedSize } = stats if (badContentCount || reclaimedCount || missingContent) { - if (badContentCount) + if (badContentCount) { tracker.warn('verifyCachedFiles', `Corrupted content removed: ${badContentCount}`) + } - if (reclaimedCount) - tracker.warn('verifyCachedFiles', `Content garbage-collected: ${reclaimedCount} (${reclaimedSize} bytes)`) + if (reclaimedCount) { + tracker.warn( + 'verifyCachedFiles', + `Content garbage-collected: ${reclaimedCount} (${reclaimedSize} bytes)` + ) + } - if (missingContent) + if (missingContent) { tracker.warn('verifyCachedFiles', `Missing content: ${missingContent}`) + } tracker.warn('verifyCachedFiles', 'Cache issues have been fixed') } - tracker.info('verifyCachedFiles', `Verification complete. Stats: ${ - JSON.stringify(stats, null, 2) - }`) + tracker.info( + 'verifyCachedFiles', + `Verification complete. Stats: ${JSON.stringify(stats, null, 2)}` + ) return `verified ${stats.verifiedContent} tarballs` } finally { tracker.finish() @@ -289,10 +327,11 @@ class Doctor extends BaseCommand { } async checkNpmRegistry () { - if (this.npm.flatOptions.registry !== defaultRegistry) + if (this.npm.flatOptions.registry !== defaultRegistry) { throw `Try \`npm config set registry=${defaultRegistry}\`` - else + } else { return `using default registry (${defaultRegistry})` + } } } diff --git a/lib/commands/edit.js b/lib/commands/edit.js index 4f0af6e83..3a9a10b40 100644 --- a/lib/commands/edit.js +++ b/lib/commands/edit.js @@ -34,8 +34,9 @@ class Edit extends BaseCommand { } async exec (args) { - if (args.length !== 1) + if (args.length !== 1) { throw this.usageError() + } const path = splitPackageNames(args[0]) const dir = resolve(this.npm.dir, path) @@ -43,13 +44,15 @@ class Edit extends BaseCommand { // graceful-fs does not promisify await new Promise((resolve, reject) => { fs.lstat(dir, (err) => { - if (err) + if (err) { return reject(err) + } const [bin, ...args] = this.npm.config.get('editor').split(/\s+/) const editor = spawn(bin, [...args, dir], { stdio: 'inherit' }) editor.on('exit', (code) => { - if (code) + if (code) { return reject(new Error(`editor process exited with code: ${code}`)) + } this.npm.exec('rebuild', [dir]).catch(reject).then(resolve) }) }) diff --git a/lib/commands/exec.js b/lib/commands/exec.js index ffe72ccb4..86a806eb5 100644 --- a/lib/commands/exec.js +++ b/lib/commands/exec.js @@ -60,11 +60,13 @@ class Exec extends BaseCommand { } async exec (_args, { locationMsg, path, runPath } = {}) { - if (!path) + if (!path) { path = this.npm.localPrefix + } - if (!runPath) + if (!runPath) { runPath = process.cwd() + } const args = [..._args] const call = this.npm.config.get('call') @@ -79,8 +81,9 @@ class Exec extends BaseCommand { const packages = this.npm.config.get('package') const yes = this.npm.config.get('yes') - if (call && _args.length) + if (call && _args.length) { throw this.usageError() + } return libexec({ ...flatOptions, diff --git a/lib/commands/explain.js b/lib/commands/explain.js index 0ef41559f..03930c2f7 100644 --- a/lib/commands/explain.js +++ b/lib/commands/explain.js @@ -36,8 +36,9 @@ class Explain extends ArboristWorkspaceCmd { } async exec (args) { - if (!args.length) + if (!args.length) { throw this.usageError() + } const arb = new Arborist({ path: this.npm.prefix, ...this.npm.flatOptions }) const tree = await arb.loadActual() @@ -45,9 +46,9 @@ class Explain extends ArboristWorkspaceCmd { if (this.npm.flatOptions.workspacesEnabled && this.workspaceNames && this.workspaceNames.length - ) + ) { this.filterSet = arb.workspaceDependencySet(tree, this.workspaceNames) - else if (!this.npm.flatOptions.workspacesEnabled) { + } else if (!this.npm.flatOptions.workspacesEnabled) { this.filterSet = arb.excludeWorkspacesDependencySet(tree) } @@ -58,20 +59,22 @@ class Explain extends ArboristWorkspaceCmd { const filteredOut = this.filterSet && this.filterSet.size > 0 && !this.filterSet.has(node) - if (!filteredOut) + if (!filteredOut) { nodes.add(node) + } } } - if (nodes.size === 0) + if (nodes.size === 0) { throw new Error(`No dependencies found matching ${args.join(', ')}`) + } const expls = [] for (const node of nodes) { const { extraneous, dev, optional, devOptional, peer, inBundle } = node const expl = node.explain() - if (extraneous) + if (extraneous) { expl.extraneous = true - else { + } else { expl.dev = dev expl.optional = optional expl.devOptional = devOptional @@ -81,9 +84,9 @@ class Explain extends ArboristWorkspaceCmd { expls.push(expl) } - if (this.npm.flatOptions.json) + if (this.npm.flatOptions.json) { this.npm.output(JSON.stringify(expls, null, 2)) - else { + } else { this.npm.output(expls.map(expl => { return explainNode(expl, Infinity, this.npm.color) }).join('\n\n')) @@ -93,21 +96,24 @@ class Explain extends ArboristWorkspaceCmd { getNodes (tree, arg) { // if it's just a name, return packages by that name const { validForOldPackages: valid } = validName(arg) - if (valid) + if (valid) { return tree.inventory.query('packageName', arg) + } // if it's a location, get that node const maybeLoc = arg.replace(/\\/g, '/').replace(/\/+$/, '') const nodeByLoc = tree.inventory.get(maybeLoc) - if (nodeByLoc) + if (nodeByLoc) { return [nodeByLoc] + } // maybe a path to a node_modules folder const maybePath = relative(this.npm.prefix, resolve(maybeLoc)) .replace(/\\/g, '/').replace(/\/+$/, '') const nodeByPath = tree.inventory.get(maybePath) - if (nodeByPath) + if (nodeByPath) { return [nodeByPath] + } // otherwise, try to select all matching nodes try { @@ -119,8 +125,9 @@ class Explain extends ArboristWorkspaceCmd { getNodesByVersion (tree, arg) { const spec = npa(arg, this.npm.prefix) - if (spec.type !== 'version' && spec.type !== 'range') + if (spec.type !== 'version' && spec.type !== 'range') { return [] + } return tree.inventory.filter(node => { return node.package.name === spec.name && diff --git a/lib/commands/explore.js b/lib/commands/explore.js index 81a71f86a..d7397262c 100644 --- a/lib/commands/explore.js +++ b/lib/commands/explore.js @@ -33,15 +33,17 @@ class Explore extends BaseCommand { } async exec (args) { - if (args.length < 1 || !args[0]) + if (args.length < 1 || !args[0]) { throw this.usageError() + } const pkgname = args.shift() // detect and prevent any .. shenanigans const path = join(this.npm.dir, join('/', pkgname)) - if (relative(path, this.npm.dir) === '') + if (relative(path, this.npm.dir) === '') { throw this.usageError() + } // run as if running a script named '_explore', which we set to either // the set of arguments, or the shell config, and let @npmcli/run-script @@ -58,8 +60,9 @@ class Explore extends BaseCommand { _explore: args.join(' ').trim() || shell, } - if (!args.length) + if (!args.length) { this.npm.output(`\nExploring ${path}\nType 'exit' or ^D when finished\n`) + } this.npm.log.disableProgress() try { return await runScript({ @@ -76,8 +79,9 @@ class Explore extends BaseCommand { // if it's not an exit error, or non-interactive, throw it const isProcExit = er.message === 'command failed' && (typeof er.code === 'number' || /^SIG/.test(er.signal || '')) - if (args.length || !isProcExit) + if (args.length || !isProcExit) { throw er + } }) } finally { this.npm.log.enableProgress() diff --git a/lib/commands/fund.js b/lib/commands/fund.js index fbf78051d..e2a158bd4 100644 --- a/lib/commands/fund.js +++ b/lib/commands/fund.js @@ -5,11 +5,7 @@ const pacote = require('pacote') const semver = require('semver') const npa = require('npm-package-arg') const { depth } = require('treeverse') -const { - readTree: getFundingInfo, - normalizeFunding, - isValidFunding, -} = require('libnpmfund') +const { readTree: getFundingInfo, normalizeFunding, isValidFunding } = require('libnpmfund') const completion = require('../utils/completion/installed-deep.js') const openUrl = require('../utils/open-url.js') @@ -33,13 +29,7 @@ class Fund extends ArboristWorkspaceCmd { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return [ - 'json', - 'browser', - 'unicode', - 'workspace', - 'which', - ] + return ['json', 'browser', 'unicode', 'workspace', 'which'] } /* istanbul ignore next - see test/lib/load-all-commands.js */ @@ -59,11 +49,12 @@ class Fund extends ArboristWorkspaceCmd { const fundingSourceNumber = numberArg && parseInt(numberArg, 10) const badFundingSourceNumber = - numberArg !== null && - (String(fundingSourceNumber) !== numberArg || fundingSourceNumber < 1) + numberArg !== null && (String(fundingSourceNumber) !== numberArg || fundingSourceNumber < 1) if (badFundingSourceNumber) { - const err = new Error('`npm fund [<@scope>/]<pkg> [--which=fundingSourceNumber]` must be given a positive integer') + const err = new Error( + '`npm fund [<@scope>/]<pkg> [--which=fundingSourceNumber]` must be given a positive integer' + ) err.code = 'EFUNDNUMBER' throw err } @@ -95,10 +86,11 @@ class Fund extends ArboristWorkspaceCmd { workspaces: this.workspaceNames, }) - if (this.npm.config.get('json')) + if (this.npm.config.get('json')) { this.npm.output(this.printJSON(fundingInfo)) - else + } else { this.npm.output(this.printHuman(fundingInfo)) + } } printJSON (fundingInfo) { @@ -110,8 +102,7 @@ class Fund extends ArboristWorkspaceCmd { const unicode = this.npm.config.get('unicode') const seenUrls = new Map() - const tree = obj => - archy(obj, '', { unicode }) + const tree = obj => archy(obj, '', { unicode }) const result = depth({ tree: fundingInfo, @@ -119,9 +110,7 @@ class Fund extends ArboristWorkspaceCmd { // composes human readable package name // and creates a new archy item for readable output visit: ({ name, version, funding }) => { - const [fundingSource] = [] - .concat(normalizeFunding(funding)) - .filter(isValidFunding) + const [fundingSource] = [].concat(normalizeFunding(funding)).filter(isValidFunding) const { url } = fundingSource || {} const pkgRef = getPrintableName({ name, version }) let item = { @@ -139,8 +128,9 @@ class Fund extends ArboristWorkspaceCmd { item = seenUrls.get(url) item.label += `, ${pkgRef}` return null - } else + } else { seenUrls.set(url, item) + } } return item @@ -149,20 +139,20 @@ class Fund extends ArboristWorkspaceCmd { // puts child nodes back into returned archy // output while also filtering out missing items leave: (item, children) => { - if (item) + if (item) { item.nodes = children.filter(Boolean) + } return item }, // turns tree-like object return by libnpmfund // into children to be properly read by treeverse - getChildren: (node) => - Object.keys(node.dependencies || {}) - .map(key => ({ - name: key, - ...node.dependencies[key], - })), + getChildren: node => + Object.keys(node.dependencies || {}).map(key => ({ + name: key, + ...node.dependencies[key], + })), }) const res = tree(result) @@ -179,8 +169,9 @@ class Fund extends ArboristWorkspaceCmd { } else { // matches any file path within current arborist inventory for (const item of tree.inventory.values()) { - if (item.path === arg.fetchSpec) + if (item.path === arg.fetchSpec) { return item.package + } } } } else { @@ -190,17 +181,17 @@ class Fund extends ArboristWorkspaceCmd { .filter(i => semver.valid(i.package.version)) .sort((a, b) => semver.rcompare(a.package.version, b.package.version)) - if (item) + if (item) { return item.package + } } } - const { funding } = retrievePackageMetadata() || - await pacote.manifest(arg, this.npm.flatOptions).catch(() => ({})) + const { funding } = + retrievePackageMetadata() || + (await pacote.manifest(arg, this.npm.flatOptions).catch(() => ({}))) - const validSources = [] - .concat(normalizeFunding(funding)) - .filter(isValidFunding) + const validSources = [].concat(normalizeFunding(funding)).filter(isValidFunding) const matchesValidSource = validSources.length === 1 || @@ -218,7 +209,10 @@ class Fund extends ArboristWorkspaceCmd { const msg = `${typePrefix} available at the following URL` this.npm.output(`${i + 1}: ${msg}: ${url}`) }) - this.npm.output('Run `npm fund [<@scope>/]<pkg> --which=1`, for example, to open the first funding URL listed in that package') + this.npm.output( + /* eslint-disable-next-line max-len */ + 'Run `npm fund [<@scope>/]<pkg> --which=1`, for example, to open the first funding URL listed in that package' + ) } else { const noFundingError = new Error(`No valid funding method available for: ${spec}`) noFundingError.code = 'ENOFUND' diff --git a/lib/commands/help-search.js b/lib/commands/help-search.js index a179939ab..a2586f309 100644 --- a/lib/commands/help-search.js +++ b/lib/commands/help-search.js @@ -27,18 +27,20 @@ class HelpSearch extends BaseCommand { } async exec (args) { - if (!args.length) + if (!args.length) { throw this.usageError() + } const docPath = path.resolve(__dirname, '..', '..', 'docs/content') const files = await glob(`${docPath}/*/*.md`) const data = await this.readFiles(files) const results = await this.searchFiles(args, data, files) const formatted = this.formatResults(args, results) - if (!formatted.trim()) + if (!formatted.trim()) { this.npm.output(`No matches in help for: ${args.join(' ')}\n`) - else + } else { this.npm.output(formatted) + } } async readFiles (files) { @@ -55,8 +57,9 @@ class HelpSearch extends BaseCommand { for (const [file, content] of Object.entries(data)) { const lowerCase = content.toLowerCase() // skip if no matches at all - if (!args.some(a => lowerCase.includes(a.toLowerCase()))) + if (!args.some(a => lowerCase.includes(a.toLowerCase()))) { continue + } const lines = content.split(/\n+/) @@ -90,17 +93,20 @@ class HelpSearch extends BaseCommand { // now squish any string of nulls into a single null const pruned = lines.reduce((l, r) => { - if (!(r === null && l[l.length - 1] === null)) + if (!(r === null && l[l.length - 1] === null)) { l.push(r) + } return l }, []) - if (pruned[pruned.length - 1] === null) + if (pruned[pruned.length - 1] === null) { pruned.pop() + } - if (pruned[0] === null) + if (pruned[0] === null) { pruned.shift() + } // now count how many args were found const found = {} @@ -157,15 +163,17 @@ class HelpSearch extends BaseCommand { out.push(' '.repeat((Math.max(1, cols - out.join(' ').length - r.length - 1)))) out.push(r) - if (!this.npm.config.get('long')) + if (!this.npm.config.get('long')) { return out.join('') + } out.unshift('\n\n') out.push('\n') out.push('-'.repeat(cols - 1) + '\n') res.lines.forEach((line, i) => { - if (line === null || i > 3) + if (line === null || i > 3) { return + } if (!this.npm.color) { out.push(line + '\n') diff --git a/lib/commands/help.js b/lib/commands/help.js index bfc7f8b60..0de047615 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -34,8 +34,9 @@ class Help extends BaseCommand { } async completion (opts) { - if (opts.conf.argv.remain.length > 2) + if (opts.conf.argv.remain.length > 2) { return [] + } const g = path.resolve(__dirname, '../../man/man[0-9]/*.[0-9]') const files = await glob(g) @@ -51,15 +52,18 @@ class Help extends BaseCommand { // By default we search all of our man subdirectories, but if the user has // asked for a specific one we limit the search to just there let manSearch = 'man*' - if (/^\d+$/.test(args[0])) + if (/^\d+$/.test(args[0])) { manSearch = `man${args.shift()}` + } - if (!args.length) + if (!args.length) { return this.npm.output(await this.npm.usage) + } // npm help foo bar baz: search topics - if (args.length > 1) + if (args.length > 1) { return this.helpSearch(args) + } let section = this.npm.deref(args[0]) || args[0] @@ -76,17 +80,19 @@ class Help extends BaseCommand { const bManNumber = b.match(manNumberRegex)[1] // man number sort first so that 1 aka commands are preferred - if (aManNumber !== bManNumber) + if (aManNumber !== bManNumber) { return aManNumber - bManNumber + } return localeCompare(a, b) }) const man = mans[0] - if (man) + if (man) { await this.viewMan(man) - else + } else { return this.helpSearch(args) + } } helpSearch (args) { @@ -125,8 +131,9 @@ class Help extends BaseCommand { const proc = spawn(bin, args, opts) return new Promise((resolve, reject) => { proc.on('exit', (code) => { - if (code) + if (code) { return reject(new Error(`help process exited with code: ${code}`)) + } return resolve() }) diff --git a/lib/commands/hook.js b/lib/commands/hook.js index 7b2deff22..3ae2e07b4 100644 --- a/lib/commands/hook.js +++ b/lib/commands/hook.js @@ -50,9 +50,9 @@ class Hook extends BaseCommand { async add (pkg, uri, secret, opts) { const hook = await hookApi.add(pkg, uri, secret, opts) - if (opts.json) + if (opts.json) { this.npm.output(JSON.stringify(hook, null, 2)) - else if (opts.parseable) { + } else if (opts.parseable) { this.npm.output(Object.keys(hook).join('\t')) this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!opts.silent && opts.loglevel !== 'silent') { @@ -64,20 +64,21 @@ class Hook extends BaseCommand { async ls (pkg, opts) { const hooks = await hookApi.ls({ ...opts, package: pkg }) - if (opts.json) + if (opts.json) { this.npm.output(JSON.stringify(hooks, null, 2)) - else if (opts.parseable) { + } else if (opts.parseable) { this.npm.output(Object.keys(hooks[0]).join('\t')) hooks.forEach(hook => { this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) }) - } else if (!hooks.length) + } else if (!hooks.length) { this.npm.output("You don't have any hooks configured yet.") - else if (!opts.silent && opts.loglevel !== 'silent') { - if (hooks.length === 1) + } else if (!opts.silent && opts.loglevel !== 'silent') { + if (hooks.length === 1) { this.npm.output('You have one hook configured.') - else + } else { this.npm.output(`You have ${hooks.length} hooks configured.`) + } const table = new Table({ head: ['id', 'target', 'endpoint'] }) hooks.forEach((hook) => { @@ -94,8 +95,9 @@ class Hook extends BaseCommand { }, hook.response_code, ]) - } else + } else { table.push([{ colSpan: 2, content: 'never triggered' }]) + } }) this.npm.output(table.toString()) } @@ -103,9 +105,9 @@ class Hook extends BaseCommand { async rm (id, opts) { const hook = await hookApi.rm(id, opts) - if (opts.json) + if (opts.json) { this.npm.output(JSON.stringify(hook, null, 2)) - else if (opts.parseable) { + } else if (opts.parseable) { this.npm.output(Object.keys(hook).join('\t')) this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!opts.silent && opts.loglevel !== 'silent') { @@ -117,9 +119,9 @@ class Hook extends BaseCommand { async update (id, uri, secret, opts) { const hook = await hookApi.update(id, uri, secret, opts) - if (opts.json) + if (opts.json) { this.npm.output(JSON.stringify(hook, null, 2)) - else if (opts.parseable) { + } else if (opts.parseable) { this.npm.output(Object.keys(hook).join('\t')) this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!opts.silent && opts.loglevel !== 'silent') { @@ -131,10 +133,12 @@ class Hook extends BaseCommand { hookName (hook) { let target = hook.name - if (hook.type === 'scope') + if (hook.type === 'scope') { target = '@' + target - if (hook.type === 'owner') + } + if (hook.type === 'owner') { target = '~' + target + } return target } } diff --git a/lib/commands/init.js b/lib/commands/init.js index b88b38436..1eb6fbf24 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -38,8 +38,9 @@ class Init extends BaseCommand { async exec (args) { // npm exec style - if (args.length) + if (args.length) { return (await this.execCreate({ args, path: process.cwd() })) + } // no args, uses classic init-package-json boilerplate await this.template() @@ -47,8 +48,9 @@ class Init extends BaseCommand { async execWorkspaces (args, filters) { // if the root package is uninitiated, take care of it first - if (this.npm.flatOptions.includeWorkspaceRoot) + if (this.npm.flatOptions.includeWorkspaceRoot) { await this.exec(args) + } // reads package.json for the top-level folder first, by doing this we // ensure the command throw if no package.json is found before trying @@ -80,9 +82,9 @@ class Init extends BaseCommand { const [initerName, ...otherArgs] = args let packageName = initerName - if (/^@[^/]+$/.test(initerName)) + if (/^@[^/]+$/.test(initerName)) { packageName = initerName + '/create' - else { + } else { const req = npa(initerName) if (req.type === 'git' && req.hosted) { const { user, project } = req.hosted @@ -90,8 +92,9 @@ class Init extends BaseCommand { .replace(user + '/' + project, user + '/create-' + project) } else if (req.registry) { packageName = req.name.replace(/^(@[^/]+\/)?/, '$1create-') - if (req.rawSpec) + if (req.rawSpec) { packageName += '@' + req.rawSpec + } } else { throw Object.assign(new Error( 'Unrecognized initializer: ' + initerName + @@ -166,9 +169,9 @@ class Init extends BaseCommand { this.npm.log.warn('init', 'canceled') return res() } - if (er) + if (er) { rej(er) - else { + } else { this.npm.log.info('init', 'written successfully') res(data) } @@ -181,8 +184,9 @@ class Init extends BaseCommand { // skip setting workspace if current package.json glob already satisfies it for (const wPath of workspaces.values()) { - if (wPath === workspacePath) + if (wPath === workspacePath) { return + } } // if a create-pkg didn't generate a package.json at the workspace diff --git a/lib/commands/install.js b/lib/commands/install.js index ea3bbcee3..95b5a5bac 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -1,5 +1,4 @@ /* eslint-disable camelcase */ -/* eslint-disable standard/no-callback-literal */ const fs = require('fs') const util = require('util') const readdir = util.promisify(fs.readdir) @@ -78,10 +77,11 @@ class Install extends ArboristWorkspaceCmd { const partialName = partialWord.slice(lastSlashIdx + 1) const partialPath = partialWord.slice(0, lastSlashIdx) || '/' - const annotatePackageDirMatch = async (sibling) => { + const annotatePackageDirMatch = async sibling => { const fullPath = join(partialPath, sibling) - if (sibling.slice(0, partialName.length) !== partialName) - return null // not name match + if (sibling.slice(0, partialName.length) !== partialName) { + return null + } // not name match try { const contents = await readdir(fullPath) @@ -136,10 +136,15 @@ class Install extends ArboristWorkspaceCmd { try { checks.checkEngine(npmManifest, npmManifest.version, process.version) } catch (e) { - if (forced) - this.npm.log.warn('install', `Forcing global npm install with incompatible version ${npmManifest.version} into node ${process.version}`) - else + if (forced) { + this.npm.log.warn( + 'install', + /* eslint-disable-next-line max-len */ + `Forcing global npm install with incompatible version ${npmManifest.version} into node ${process.version}` + ) + } else { throw e + } } } @@ -147,12 +152,17 @@ class Install extends ArboristWorkspaceCmd { args = args.filter(a => resolve(a) !== this.npm.prefix) // `npm i -g` => "install this package globally" - if (where === globalTop && !args.length) + if (where === globalTop && !args.length) { args = ['.'] + } // TODO: Add warnings for other deprecated flags? or remove this one? - if (isDev) - log.warn('install', 'Usage of the `--dev` option is deprecated. Use `--include=dev` instead.') + if (isDev) { + log.warn( + 'install', + 'Usage of the `--dev` option is deprecated. Use `--include=dev` instead.' + ) + } const opts = { ...this.npm.flatOptions, diff --git a/lib/commands/link.js b/lib/commands/link.js index 4a800d7c6..b4f4a1289 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -169,8 +169,9 @@ class Link extends ArboristWorkspaceCmd { // Returns a list of items that can't be fulfilled by // things found in the current arborist inventory missingArgsFromTree (tree, args) { - if (tree.isLink) + if (tree.isLink) { return this.missingArgsFromTree(tree.target, args) + } const foundNodes = [] const missing = args.filter(a => { @@ -193,8 +194,9 @@ class Link extends ArboristWorkspaceCmd { // remote nodes from the loaded tree in order // to avoid dropping them later when reifying - for (const node of foundNodes) + for (const node of foundNodes) { node.parent = null + } return missing } diff --git a/lib/commands/logout.js b/lib/commands/logout.js index 3c0bdc756..43a04bb57 100644 --- a/lib/commands/logout.js +++ b/lib/commands/logout.js @@ -37,15 +37,16 @@ class Logout extends BaseCommand { method: 'DELETE', ignoreBody: true, }) - } else if (auth.isBasicAuth) + } else if (auth.isBasicAuth) { log.verbose('logout', `clearing user credentials for ${reg}`) - else { + } else { const msg = `not logged in to ${reg}, so can't log out!` throw Object.assign(new Error(msg), { code: 'ENEEDAUTH' }) } - if (scope) + if (scope) { this.npm.config.delete(regRef, 'user') + } this.npm.config.clearCredentialsByURI(reg) diff --git a/lib/commands/ls.js b/lib/commands/ls.js index af7d44ab4..b8c1f0ef9 100644 --- a/lib/commands/ls.js +++ b/lib/commands/ls.js @@ -88,23 +88,26 @@ class LS extends ArboristWorkspaceCmd { legacyPeerDeps: false, path, }) - const tree = await this.initTree({arb, args, packageLockOnly }) + const tree = await this.initTree({ arb, args, packageLockOnly }) // filters by workspaces nodes when using -w <workspace-name> // We only have to filter the first layer of edges, so we don't // explore anything that isn't part of the selected workspace set. let wsNodes - if (this.workspaceNames && this.workspaceNames.length) + if (this.workspaceNames && this.workspaceNames.length) { wsNodes = arb.workspaceNodes(tree, this.workspaceNames) + } const filterBySelectedWorkspaces = edge => { if (!workspacesEnabled && edge.from.isProjectRoot && edge.to.isWorkspace - ) + ) { return false + } - if (!wsNodes || !wsNodes.length) + if (!wsNodes || !wsNodes.length) { return true + } if (edge.from.isProjectRoot) { return edge.to && @@ -176,8 +179,9 @@ class LS extends ArboristWorkspaceCmd { // loop through list of node problems to add them to global list if (node[_include]) { - for (const problem of node[_problems]) + for (const problem of node[_problems]) { problems.add(problem) + } } seenItems.add(item) @@ -200,8 +204,9 @@ class LS extends ArboristWorkspaceCmd { ) // if filtering items, should exit with error code on no results - if (result && !result[_include] && args.length) + if (result && !result[_include] && args.length) { process.exitCode = 1 + } if (rootError) { throw Object.assign( @@ -237,8 +242,9 @@ class LS extends ArboristWorkspaceCmd { module.exports = LS const isGitNode = (node) => { - if (!node.resolved) + if (!node.resolved) { return + } try { const { type } = npa(node.resolved) @@ -257,14 +263,17 @@ const isExtraneous = (node, { global }) => const getProblems = (node, { global }) => { const problems = new Set() - if (node[_missing] && !isOptional(node)) + if (node[_missing] && !isOptional(node)) { problems.add(`missing: ${node.pkgid}, required by ${node[_missing]}`) + } - if (node[_invalid]) + if (node[_invalid]) { problems.add(`invalid: ${node.pkgid} ${node.path}`) + } - if (isExtraneous(node, { global })) + if (isExtraneous(node, { global })) { problems.add(`extraneous: ${node.pkgid} ${node.path}`) + } return problems } @@ -297,10 +306,11 @@ const getHumanOutputItem = (node, { args, color, global, long }) => { // special formatting for top-level package name if (node.isRoot) { const hasNoPackageJson = !Object.keys(node.package).length - if (hasNoPackageJson || global) + if (hasNoPackageJson || global) { printable = path - else + } else { printable += `${long ? EOL : ' '}${path}` + } } const highlightDepName = @@ -347,19 +357,22 @@ const getHumanOutputItem = (node, { args, color, global, long }) => { const getJsonOutputItem = (node, { global, long }) => { const item = {} - if (node.version) + if (node.version) { item.version = node.version + } - if (node.resolved) + if (node.resolved) { item.resolved = node.resolved + } item[_name] = node.name // special formatting for top-level package name const hasPackageJson = node && node.package && Object.keys(node.package).length - if (node.isRoot && hasPackageJson) + if (node.isRoot && hasPackageJson) { item.name = node.package.name || node.name + } if (long && !node[_missing]) { item.name = item[_name] @@ -376,18 +389,21 @@ const getJsonOutputItem = (node, { global, long }) => { } // augment json output items with extra metadata - if (isExtraneous(node, { global })) + if (isExtraneous(node, { global })) { item.extraneous = true + } - if (node[_invalid]) + if (node[_invalid]) { item.invalid = node[_invalid] + } if (node[_missing] && !isOptional(node)) { item.required = node[_required] item.missing = true } - if (node[_include] && node[_problems] && node[_problems].size) + if (node[_include] && node[_problems] && node[_problems].size) { item.problems = [...node[_problems]] + } return augmentItemWithIncludeMetadata(node, item) } @@ -436,8 +452,9 @@ const mapEdgesToNodes = ({ seenPaths }) => (edge) => { // item would appear twice given that it's a children of an extraneous item, // so it's marked extraneous but it will ALSO show up in edgesOuts of // its parent so it ends up as two diff nodes if we don't track it - if (node.path) + if (node.path) { seenPaths.add(node.path) + } node[_required] = edge.spec || '*' node[_type] = edge.type @@ -515,20 +532,23 @@ const humanOutput = ({ color, result, seenItems, unicode }) => { // so that all its ancestors should be displayed) // here is where we put items in their expected place for archy output for (const item of seenItems) { - if (item[_include] && item[_parent]) + if (item[_include] && item[_parent]) { item[_parent].nodes.push(item) + } } - if (!result.nodes.length) + if (!result.nodes.length) { result.nodes = ['(empty)'] + } const archyOutput = archy(result, '', { unicode }) return color ? chalk.reset(archyOutput) : archyOutput } const jsonOutput = ({ path, problems, result, rootError, seenItems }) => { - if (problems.size) + if (problems.size) { result.problems = [...problems] + } if (rootError) { result.problems = [ @@ -546,8 +566,9 @@ const jsonOutput = ({ path, problems, result, rootError, seenItems }) => { // append current item to its parent item.dependencies obj in order // to provide a json object structure that represents the installed tree if (item[_include] && item[_parent]) { - if (!item[_parent].dependencies) + if (!item[_parent].dependencies) { item[_parent].dependencies = {} + } item[_parent].dependencies[item[_name]] = item } diff --git a/lib/commands/org.js b/lib/commands/org.js index 6d0b8cd50..18f73cb59 100644 --- a/lib/commands/org.js +++ b/lib/commands/org.js @@ -24,18 +24,14 @@ class Org extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return [ - 'registry', - 'otp', - 'json', - 'parseable', - ] + return ['registry', 'otp', 'json', 'parseable'] } async completion (opts) { const argv = opts.conf.argv.remain - if (argv.length === 2) + if (argv.length === 2) { return ['set', 'rm', 'ls'] + } switch (argv[2]) { case 'ls': @@ -66,85 +62,109 @@ class Org extends BaseCommand { set (org, user, role, opts) { role = role || 'developer' - if (!org) + if (!org) { throw new Error('First argument `orgname` is required.') + } - if (!user) + if (!user) { throw new Error('Second argument `username` is required.') + } - if (!['owner', 'admin', 'developer'].find(x => x === role)) - throw new Error('Third argument `role` must be one of `owner`, `admin`, or `developer`, with `developer` being the default value if omitted.') + if (!['owner', 'admin', 'developer'].find(x => x === role)) { + throw new Error( + /* eslint-disable-next-line max-len */ + 'Third argument `role` must be one of `owner`, `admin`, or `developer`, with `developer` being the default value if omitted.' + ) + } return liborg.set(org, user, role, opts).then(memDeets => { - if (opts.json) + if (opts.json) { this.npm.output(JSON.stringify(memDeets, null, 2)) - else if (opts.parseable) { + } else if (opts.parseable) { this.npm.output(['org', 'orgsize', 'user', 'role'].join('\t')) - this.npm.output([ - memDeets.org.name, - memDeets.org.size, - memDeets.user, - memDeets.role, - ].join('\t')) - } else if (!opts.silent && opts.loglevel !== 'silent') - this.npm.output(`Added ${memDeets.user} as ${memDeets.role} to ${memDeets.org.name}. You now have ${memDeets.org.size} member${memDeets.org.size === 1 ? '' : 's'} in this org.`) + this.npm.output( + [memDeets.org.name, memDeets.org.size, memDeets.user, memDeets.role].join('\t') + ) + } else if (!opts.silent && opts.loglevel !== 'silent') { + this.npm.output( + `Added ${memDeets.user} as ${memDeets.role} to ${memDeets.org.name}. You now have ${ + memDeets.org.size + } member${memDeets.org.size === 1 ? '' : 's'} in this org.` + ) + } return memDeets }) } rm (org, user, opts) { - if (!org) + if (!org) { throw new Error('First argument `orgname` is required.') + } - if (!user) + if (!user) { throw new Error('Second argument `username` is required.') + } - return liborg.rm(org, user, opts).then(() => { - return liborg.ls(org, opts) - }).then(roster => { - user = user.replace(/^[~@]?/, '') - org = org.replace(/^[~@]?/, '') - const userCount = Object.keys(roster).length - if (opts.json) { - this.npm.output(JSON.stringify({ - user, - org, - userCount, - deleted: true, - })) - } else if (opts.parseable) { - this.npm.output(['user', 'org', 'userCount', 'deleted'].join('\t')) - this.npm.output([user, org, userCount, true].join('\t')) - } else if (!opts.silent && opts.loglevel !== 'silent') - this.npm.output(`Successfully removed ${user} from ${org}. You now have ${userCount} member${userCount === 1 ? '' : 's'} in this org.`) - }) + return liborg + .rm(org, user, opts) + .then(() => { + return liborg.ls(org, opts) + }) + .then(roster => { + user = user.replace(/^[~@]?/, '') + org = org.replace(/^[~@]?/, '') + const userCount = Object.keys(roster).length + if (opts.json) { + this.npm.output( + JSON.stringify({ + user, + org, + userCount, + deleted: true, + }) + ) + } else if (opts.parseable) { + this.npm.output(['user', 'org', 'userCount', 'deleted'].join('\t')) + this.npm.output([user, org, userCount, true].join('\t')) + } else if (!opts.silent && opts.loglevel !== 'silent') { + this.npm.output( + `Successfully removed ${user} from ${org}. You now have ${userCount} member${ + userCount === 1 ? '' : 's' + } in this org.` + ) + } + }) } ls (org, user, opts) { - if (!org) + if (!org) { throw new Error('First argument `orgname` is required.') + } return liborg.ls(org, opts).then(roster => { if (user) { const newRoster = {} - if (roster[user]) + if (roster[user]) { newRoster[user] = roster[user] + } roster = newRoster } - if (opts.json) + if (opts.json) { this.npm.output(JSON.stringify(roster, null, 2)) - else if (opts.parseable) { + } else if (opts.parseable) { this.npm.output(['user', 'role'].join('\t')) Object.keys(roster).forEach(user => { this.npm.output([user, roster[user]].join('\t')) }) } else if (!opts.silent && opts.loglevel !== 'silent') { const table = new Table({ head: ['user', 'role'] }) - Object.keys(roster).sort().forEach(user => { - table.push([user, roster[user]]) - }) + Object.keys(roster) + .sort() + .forEach(user => { + table.push([user, roster[user]]) + }) this.npm.output(table.toString()) } }) diff --git a/lib/commands/outdated.js b/lib/commands/outdated.js index 119316d3b..01047b4d3 100644 --- a/lib/commands/outdated.js +++ b/lib/commands/outdated.js @@ -91,19 +91,21 @@ class Outdated extends ArboristWorkspaceCmd { // sorts list alphabetically const outdated = this.list.sort((a, b) => localeCompare(a.name, b.name)) - if (outdated.length > 0) + if (outdated.length > 0) { process.exitCode = 1 + } // return if no outdated packages - if (outdated.length === 0 && !this.npm.config.get('json')) + if (outdated.length === 0 && !this.npm.config.get('json')) { return + } // display results - if (this.npm.config.get('json')) + if (this.npm.config.get('json')) { this.npm.output(this.makeJSON(outdated)) - else if (this.npm.config.get('parseable')) + } else if (this.npm.config.get('parseable')) { this.npm.output(this.makeParseable(outdated)) - else { + } else { const outList = outdated.map(x => this.makePretty(x)) const outHead = ['Package', 'Current', @@ -113,12 +115,14 @@ class Outdated extends ArboristWorkspaceCmd { 'Depended by', ] - if (this.npm.config.get('long')) + if (this.npm.config.get('long')) { outHead.push('Package Type', 'Homepage') + } const outTable = [outHead].concat(outList) - if (this.npm.color) + if (this.npm.color) { outTable[0] = outTable[0].map(heading => styles.underline(heading)) + } const tableOpts = { align: ['l', 'r', 'r', 'r', 'l'], @@ -145,18 +149,21 @@ class Outdated extends ArboristWorkspaceCmd { } getEdgesIn (node) { - for (const edge of node.edgesIn) + for (const edge of node.edgesIn) { this.trackEdge(edge) + } } getEdgesOut (node) { // TODO: normalize usage of edges and avoid looping through nodes here if (this.npm.config.get('global')) { - for (const child of node.children.values()) + for (const child of node.children.values()) { this.trackEdge(child) + } } else { - for (const edge of node.edgesOut.values()) + for (const edge of node.edgesOut.values()) { this.trackEdge(edge) + } } } @@ -167,15 +174,17 @@ class Outdated extends ArboristWorkspaceCmd { && this.filterSet.size > 0 && !this.filterSet.has(edge.from.target) - if (filteredOut) + if (filteredOut) { return + } this.edges.add(edge) } getWorkspacesEdges (node) { - if (this.npm.config.get('global')) + if (this.npm.config.get('global')) { return + } for (const edge of this.tree.edgesOut.values()) { const workspace = edge @@ -183,8 +192,9 @@ class Outdated extends ArboristWorkspaceCmd { && edge.to.target && edge.to.target.isWorkspace - if (workspace) + if (workspace) { this.getEdgesOut(edge.to.target) + } } } @@ -209,22 +219,25 @@ class Outdated extends ArboristWorkspaceCmd { : 'dependencies' for (const omitType of this.npm.config.get('omit')) { - if (node[omitType]) + if (node[omitType]) { return + } } // deps different from prod not currently // on disk are not included in the output - if (edge.error === 'MISSING' && type !== 'dependencies') + if (edge.error === 'MISSING' && type !== 'dependencies') { return + } try { const packument = await this.getPackument(spec) const expected = edge.spec // if it's not a range, version, or tag, skip it try { - if (!npa(`${edge.name}@${edge.spec}`).registry) + if (!npa(`${edge.name}@${edge.spec}`).registry) { return null + } } catch (err) { return null } @@ -259,14 +272,16 @@ class Outdated extends ArboristWorkspaceCmd { err.code === 'ETARGET' || err.code === 'E403' || err.code === 'E404') - ) + ) { throw err + } } } maybeWorkspaceName (node) { - if (!node.isWorkspace) + if (!node.isWorkspace) { return node.name + } const humanOutput = !this.npm.config.get('json') && !this.npm.config.get('parseable') @@ -331,8 +346,9 @@ class Outdated extends ArboristWorkspaceCmd { name + '@' + latest, dependent, ] - if (this.npm.config.get('long')) + if (this.npm.config.get('long')) { out.push(type, homepage) + } return out.join(':') }).join(os.EOL) diff --git a/lib/commands/owner.js b/lib/commands/owner.js index 5d28e2b75..4d1fe9b9f 100644 --- a/lib/commands/owner.js +++ b/lib/commands/owner.js @@ -36,30 +36,36 @@ class Owner extends BaseCommand { async completion (opts) { const argv = opts.conf.argv.remain - if (argv.length > 3) + if (argv.length > 3) { return [] + } - if (argv[1] !== 'owner') + if (argv[1] !== 'owner') { argv.unshift('owner') + } - if (argv.length === 2) + if (argv.length === 2) { return ['add', 'rm', 'ls'] + } // reaches registry in order to autocomplete rm if (argv[2] === 'rm') { - if (this.npm.config.get('global')) + if (this.npm.config.get('global')) { return [] + } const pkgName = await readLocalPkgName(this.npm.prefix) - if (!pkgName) + if (!pkgName) { return [] + } const spec = npa(pkgName) const data = await pacote.packument(spec, { ...this.npm.flatOptions, fullMetadata: true, }) - if (data && data.maintainers && data.maintainers.length) + if (data && data.maintainers && data.maintainers.length) { return data.maintainers.map(m => m.name) + } } return [] } @@ -82,12 +88,14 @@ class Owner extends BaseCommand { async ls (pkg, opts) { if (!pkg) { - if (this.npm.config.get('global')) + if (this.npm.config.get('global')) { throw this.usageError() + } const pkgName = await readLocalPkgName(this.npm.prefix) - if (!pkgName) + if (!pkgName) { throw this.usageError() + } pkg = pkgName } @@ -97,10 +105,11 @@ class Owner extends BaseCommand { try { const packumentOpts = { ...opts, fullMetadata: true } const { maintainers } = await pacote.packument(spec, packumentOpts) - if (!maintainers || !maintainers.length) + if (!maintainers || !maintainers.length) { this.npm.output('no admin found') - else + } else { this.npm.output(maintainers.map(o => `${o.name} <${o.email}>`).join('\n')) + } return maintainers } catch (err) { @@ -110,15 +119,18 @@ class Owner extends BaseCommand { } async add (user, pkg, opts) { - if (!user) + if (!user) { throw this.usageError() + } if (!pkg) { - if (this.npm.config.get('global')) + if (this.npm.config.get('global')) { throw this.usageError() + } const pkgName = await readLocalPkgName(this.npm.prefix) - if (!pkgName) + if (!pkgName) { throw this.usageError() + } pkg = pkgName } @@ -130,15 +142,18 @@ class Owner extends BaseCommand { } async rm (user, pkg, opts) { - if (!user) + if (!user) { throw this.usageError() + } if (!pkg) { - if (this.npm.config.get('global')) + if (this.npm.config.get('global')) { throw this.usageError() + } const pkgName = await readLocalPkgName(this.npm.prefix) - if (!pkgName) + if (!pkgName) { throw this.usageError() + } pkg = pkgName } @@ -178,8 +193,9 @@ class Owner extends BaseCommand { const before = data.maintainers ? data.maintainers.length : 0 const m = validation(u, data.maintainers) - if (!m) - return // invalid owners + if (!m) { + return + } // invalid owners const body = { _id: data._id, @@ -197,10 +213,11 @@ class Owner extends BaseCommand { }) if (!res.error) { - if (m.length < before) + if (m.length < before) { this.npm.output(`- ${user} (${spec.name})`) - else + } else { this.npm.output(`+ ${user} (${spec.name})`) + } } else { throw Object.assign( new Error('Failed to update package: ' + JSON.stringify(res)), diff --git a/lib/commands/pack.js b/lib/commands/pack.js index 013e88b44..27682878c 100644 --- a/lib/commands/pack.js +++ b/lib/commands/pack.js @@ -40,8 +40,9 @@ class Pack extends BaseCommand { } async exec (args) { - if (args.length === 0) + if (args.length === 0) { args = ['.'] + } const unicode = this.npm.config.get('unicode') const dryRun = this.npm.config.get('dry-run') @@ -53,8 +54,9 @@ class Pack extends BaseCommand { for (const arg of args) { const spec = npa(arg) const manifest = await pacote.manifest(spec, this.npm.flatOptions) - if (!manifest._id) + if (!manifest._id) { throw new Error('Invalid package, must have name and version') + } const filename = `${manifest.name}-${manifest.version}.tgz` .replace(/^@/, '').replace(/\//, '-') @@ -69,8 +71,9 @@ class Pack extends BaseCommand { const pkgContents = await getContents(manifest, tarballData) const tarballFilename = path.resolve(this.npm.config.get('pack-destination'), filename) - if (!dryRun) + if (!dryRun) { await writeFile(tarballFilename, tarballData) + } tarballs.push(pkgContents) } diff --git a/lib/commands/ping.js b/lib/commands/ping.js index d8ad1dc2a..0025573d6 100644 --- a/lib/commands/ping.js +++ b/lib/commands/ping.js @@ -30,8 +30,9 @@ class Ping extends BaseCommand { time, details, }, null, 2)) - } else if (Object.keys(details).length) + } else if (Object.keys(details).length) { log.notice('PONG', `${JSON.stringify(details, null, 2)}`) + } } } module.exports = Ping diff --git a/lib/commands/pkg.js b/lib/commands/pkg.js index 1fa2c3bc5..53e6431ee 100644 --- a/lib/commands/pkg.js +++ b/lib/commands/pkg.js @@ -32,10 +32,11 @@ class Pkg extends BaseCommand { } async exec (args, { prefix } = {}) { - if (!prefix) + if (!prefix) { this.prefix = this.npm.localPrefix - else + } else { this.prefix = prefix + } if (this.npm.config.get('global')) { throw Object.assign( @@ -81,15 +82,17 @@ class Pkg extends BaseCommand { // in case there's only a single result from the query // just prints that one element to stdout - if (Object.keys(result).length === 1) + if (Object.keys(result).length === 1) { result = result[args] + } } // only outputs if not running with workspaces config, // in case you're retrieving info for workspaces the pkgWorkspaces // will handle the output to make sure it get keyed by ws name - if (!this.workspaces) + if (!this.workspaces) { this.npm.output(JSON.stringify(result, null, 2)) + } return result } @@ -98,8 +101,9 @@ class Pkg extends BaseCommand { const setError = () => this.usageError('npm pkg set expects a key=value pair of args.') - if (!args.length) + if (!args.length) { throw setError() + } const force = this.npm.config.get('force') const json = this.npm.config.get('json') @@ -108,8 +112,9 @@ class Pkg extends BaseCommand { for (const arg of args) { const [key, ...rest] = arg.split('=') const value = rest.join('=') - if (!key || !value) + if (!key || !value) { throw setError() + } q.set(key, json ? JSON.parse(value) : value, { force }) } @@ -122,14 +127,16 @@ class Pkg extends BaseCommand { const setError = () => this.usageError('npm pkg delete expects key args.') - if (!args.length) + if (!args.length) { throw setError() + } const pkgJson = await PackageJson.load(this.prefix) const q = new Queryable(pkgJson.content) for (const key of args) { - if (!key) + if (!key) { throw setError() + } q.delete(key) } diff --git a/lib/commands/profile.js b/lib/commands/profile.js index abfe5edd7..72e4bb849 100644 --- a/lib/commands/profile.js +++ b/lib/commands/profile.js @@ -70,8 +70,9 @@ class Profile extends BaseCommand { async completion (opts) { var argv = opts.conf.argv.remain - if (!argv[2]) + if (!argv[2]) { return ['enable-2fa', 'disable-2fa', 'get', 'set'] + } switch (argv[2]) { case 'enable-2fa': @@ -89,8 +90,9 @@ class Profile extends BaseCommand { } async exec (args) { - if (args.length === 0) + if (args.length === 0) { throw this.usageError() + } log.gauge.show('profile') @@ -122,8 +124,9 @@ class Profile extends BaseCommand { npmProfile.get(this.npm.flatOptions) ) - if (!info.cidr_whitelist) + if (!info.cidr_whitelist) { delete info.cidr_whitelist + } if (this.npm.config.get('json')) { this.npm.output(JSON.stringify(info, null, 2)) @@ -132,21 +135,24 @@ class Profile extends BaseCommand { // clean up and format key/values for output const cleaned = {} - for (const key of knownProfileKeys) + for (const key of knownProfileKeys) { cleaned[key] = info[key] || '' + } const unknownProfileKeys = Object.keys(info).filter((k) => !(k in cleaned)) - for (const key of unknownProfileKeys) + for (const key of unknownProfileKeys) { cleaned[key] = info[key] || '' + } delete cleaned.tfa delete cleaned.email_verified cleaned.email += info.email_verified ? ' (verified)' : '(unverified)' - if (info.tfa && !info.tfa.pending) + if (info.tfa && !info.tfa.pending) { cleaned[tfa] = info.tfa.mode - else + } else { cleaned[tfa] = 'disabled' + } if (args.length) { const values = args // comma or space separated @@ -159,15 +165,17 @@ class Profile extends BaseCommand { } else { if (this.npm.config.get('parseable')) { for (const key of Object.keys(info)) { - if (key === 'tfa') + if (key === 'tfa') { this.npm.output(`${key}\t${cleaned[tfa]}`) - else + } else { this.npm.output(`${key}\t${info[key]}`) + } } } else { const table = new Table() - for (const key of Object.keys(cleaned)) + for (const key of Object.keys(cleaned)) { table.push({ [ansistyles.bright(key)]: cleaned[key] }) + } this.npm.output(table.toString()) } @@ -192,8 +200,9 @@ class Profile extends BaseCommand { return newpassword } - if (prop !== 'password' && value === null) + if (prop !== 'password' && value === null) { throw new Error('npm profile set <prop> <value>') + } if (prop === 'password' && value !== null) { throw new Error( @@ -217,26 +226,29 @@ class Profile extends BaseCommand { const user = await pulseTillDone.withPromise(npmProfile.get(conf)) const newUser = {} - for (const key of writableProfileKeys) + for (const key of writableProfileKeys) { newUser[key] = user[key] + } newUser[prop] = value const result = await otplease(conf, conf => npmProfile.set(newUser, conf)) - if (this.npm.config.get('json')) + if (this.npm.config.get('json')) { this.npm.output(JSON.stringify({ [prop]: result[prop] }, null, 2)) - else if (this.npm.config.get('parseable')) + } else if (this.npm.config.get('parseable')) { this.npm.output(prop + '\t' + result[prop]) - else if (result[prop] != null) + } else if (result[prop] != null) { this.npm.output('Set', prop, 'to', result[prop]) - else + } else { this.npm.output('Set', prop) + } } async enable2fa (args) { - if (args.length > 1) + if (args.length > 1) { throw new Error('npm profile enable-2fa [auth-and-writes|auth-only]') + } const mode = args[0] || 'auth-and-writes' if (mode !== 'auth-only' && mode !== 'auth-and-writes') { @@ -267,11 +279,11 @@ class Profile extends BaseCommand { const creds = this.npm.config.getCredentialsByURI(this.npm.config.get('registry')) const auth = {} - if (creds.token) + if (creds.token) { auth.token = creds.token - else if (creds.username) + } else if (creds.username) { auth.basic = { username: creds.username, password: creds.password } - else if (creds.auth) { + } else if (creds.auth) { const basic = Buffer.from(creds.auth, 'base64').toString().split(':', 2) auth.basic = { username: basic[0], password: basic[1] } } @@ -370,8 +382,9 @@ class Profile extends BaseCommand { 'if you lose your authentication device.' ) - for (const tfaCode of result.tfa) + for (const tfaCode of result.tfa) { this.npm.output('\t' + tfaCode) + } } async disable2fa (args) { @@ -396,12 +409,13 @@ class Profile extends BaseCommand { tfa: { password: password, mode: 'disable' }, }, conf)) - if (this.npm.config.get('json')) + if (this.npm.config.get('json')) { this.npm.output(JSON.stringify({ tfa: false }, null, 2)) - else if (this.npm.config.get('parseable')) + } else if (this.npm.config.get('parseable')) { this.npm.output('tfa\tfalse') - else + } else { this.npm.output('Two factor authentication disabled.') + } } } module.exports = Profile diff --git a/lib/commands/publish.js b/lib/commands/publish.js index 3bc309c12..efa148565 100644 --- a/lib/commands/publish.js +++ b/lib/commands/publish.js @@ -56,10 +56,12 @@ class Publish extends BaseCommand { } async exec (args) { - if (args.length === 0) + if (args.length === 0) { args = ['.'] - if (args.length !== 1) + } + if (args.length !== 1) { throw this.usageError() + } log.verbose('publish', replaceInfo(args)) @@ -70,8 +72,9 @@ class Publish extends BaseCommand { const ignoreScripts = this.npm.config.get('ignore-scripts') const silent = log.level === 'silent' - if (semver.validRange(defaultTag)) + if (semver.validRange(defaultTag)) { throw new Error('Tag name must not be a valid SemVer range: ' + defaultTag.trim()) + } const opts = { ...this.npm.flatOptions } @@ -80,8 +83,9 @@ class Publish extends BaseCommand { const spec = npa(args[0]) let manifest = await this.getManifest(spec, opts) - if (manifest.publishConfig) + if (manifest.publishConfig) { flatten(manifest.publishConfig, opts) + } // only run scripts for directory type publishes if (spec.type === 'directory' && !ignoreScripts) { @@ -101,13 +105,15 @@ class Publish extends BaseCommand { // so that we send the latest and greatest thing to the registry // note that publishConfig might have changed as well! manifest = await this.getManifest(spec, opts) - if (manifest.publishConfig) + if (manifest.publishConfig) { flatten(manifest.publishConfig, opts) + } // note that logTar calls npmlog.notice(), so if we ARE in silent mode, // this will do nothing, but we still want it in the debuglog if it fails. - if (!json) + if (!json) { logTar(pkgContents, { log, unicode }) + } if (!dryRun) { const resolved = npa.resolve(manifest.name, manifest.version) @@ -140,10 +146,11 @@ class Publish extends BaseCommand { } if (!this.suppressOutput) { - if (!silent && json) + if (!silent && json) { this.npm.output(JSON.stringify(pkgContents, null, 2)) - else if (!silent) + } else if (!silent) { this.npm.output(`+ ${pkgContents.id}`) + } } return pkgContents @@ -180,21 +187,24 @@ class Publish extends BaseCommand { } // This needs to be in-line w/ the rest of the output that non-JSON // publish generates - if (!silent && !json) + if (!silent && !json) { this.npm.output(`+ ${pkgContents.id}`) - else + } else { results[name] = pkgContents + } } - if (!silent && json) + if (!silent && json) { this.npm.output(JSON.stringify(results, null, 2)) + } } // if it's a directory, read it from the file system // otherwise, get the full metadata from whatever it is getManifest (spec, opts) { - if (spec.type === 'directory') + if (spec.type === 'directory') { return readJson(`${spec.fetchSpec}/package.json`) + } return pacote.manifest(spec, { ...opts, fullMetadata: true }) } } diff --git a/lib/commands/rebuild.js b/lib/commands/rebuild.js index 3b9211e2e..d95a865b4 100644 --- a/lib/commands/rebuild.js +++ b/lib/commands/rebuild.js @@ -51,33 +51,39 @@ class Rebuild extends ArboristWorkspaceCmd { const tree = await arb.loadActual() const specs = args.map(arg => { const spec = npa(arg) - if (spec.type === 'tag' && spec.rawSpec === '') + if (spec.type === 'tag' && spec.rawSpec === '') { return spec + } - if (spec.type !== 'range' && spec.type !== 'version' && spec.type !== 'directory') + if (spec.type !== 'range' && spec.type !== 'version' && spec.type !== 'directory') { throw new Error('`npm rebuild` only supports SemVer version/range specifiers') + } return spec }) const nodes = tree.inventory.filter(node => this.isNode(specs, node)) await arb.rebuild({ nodes }) - } else + } else { await arb.rebuild() + } this.npm.output('rebuilt dependencies successfully') } isNode (specs, node) { return specs.some(spec => { - if (spec.type === 'directory') + if (spec.type === 'directory') { return node.path === spec.fetchSpec + } - if (spec.name !== node.name) + if (spec.name !== node.name) { return false + } - if (spec.rawSpec === '' || spec.rawSpec === '*') + if (spec.rawSpec === '' || spec.rawSpec === '*') { return true + } const { version } = node.package // TODO: add tests for a package with missing version diff --git a/lib/commands/repo.js b/lib/commands/repo.js index 372940512..f87309896 100644 --- a/lib/commands/repo.js +++ b/lib/commands/repo.js @@ -28,8 +28,9 @@ class Repo extends BaseCommand { } async exec (args) { - if (!args || !args.length) + if (!args || !args.length) { args = ['.'] + } await Promise.all(args.map(pkg => this.get(pkg))) } @@ -86,8 +87,9 @@ const unknownHostedUrl = url => { } = new URL(url) /* istanbul ignore next - URL ctor should prevent this */ - if (!protocol || !hostname) + if (!protocol || !hostname) { return null + } const proto = /(git\+)http:$/.test(protocol) ? 'http:' : 'https:' const path = pathname.replace(/\.git$/, '') diff --git a/lib/commands/run-script.js b/lib/commands/run-script.js index 34e96257c..832e166a6 100644 --- a/lib/commands/run-script.js +++ b/lib/commands/run-script.js @@ -66,17 +66,19 @@ class RunScript extends BaseCommand { } async exec (args) { - if (args.length) + if (args.length) { return this.run(args) - else + } else { return this.list(args) + } } async execWorkspaces (args, filters) { - if (args.length) + if (args.length) { return this.runWorkspaces(args, filters) - else + } else { return this.listWorkspaces(args, filters) + } } async run ([event, ...args], { path = this.npm.localPrefix, pkg } = {}) { @@ -87,32 +89,38 @@ class RunScript extends BaseCommand { pkg = pkg || (await rpj(`${path}/package.json`)) const { scripts = {} } = pkg - if (event === 'restart' && !scripts.restart) + if (event === 'restart' && !scripts.restart) { scripts.restart = 'npm stop --if-present && npm start' - else if (event === 'env' && !scripts.env) + } else if (event === 'env' && !scripts.env) { scripts.env = isWindowsShell ? 'SET' : 'env' + } pkg.scripts = scripts if ( !Object.prototype.hasOwnProperty.call(scripts, event) && - !(event === 'start' && await isServerPackage(path)) + !(event === 'start' && (await isServerPackage(path))) ) { - if (this.npm.config.get('if-present')) + if (this.npm.config.get('if-present')) { return + } const suggestions = await didYouMean(this.npm, path, event) - throw new Error(`Missing script: "${event}"${suggestions}\n\nTo see a list of scripts, run:\n npm run`) + throw new Error( + `Missing script: "${event}"${suggestions}\n\nTo see a list of scripts, run:\n npm run` + ) } // positional args only added to the main event, not pre/post const events = [[event, args]] if (!this.npm.config.get('ignore-scripts')) { - if (scripts[`pre${event}`]) + if (scripts[`pre${event}`]) { events.unshift([`pre${event}`, []]) + } - if (scripts[`post${event}`]) + if (scripts[`post${event}`]) { events.push([`post${event}`, []]) + } } const opts = { @@ -140,12 +148,14 @@ class RunScript extends BaseCommand { const pkgid = _id || name const color = this.npm.color - if (!scripts) + if (!scripts) { return [] + } const allScripts = Object.keys(scripts) - if (log.level === 'silent') + if (log.level === 'silent') { return allScripts + } if (this.npm.config.get('json')) { this.npm.output(JSON.stringify(scripts, null, 2)) @@ -153,8 +163,9 @@ class RunScript extends BaseCommand { } if (this.npm.config.get('parseable')) { - for (const [script, cmd] of Object.entries(scripts)) + for (const [script, cmd] of Object.entries(scripts)) { this.npm.output(`${script}:${cmd}`) + } return allScripts } @@ -170,24 +181,30 @@ class RunScript extends BaseCommand { const colorize = color ? chalk : nocolor if (cmds.length) { - this.npm.output(`${ - colorize.reset(colorize.bold('Lifecycle scripts'))} included in ${ - colorize.green(pkgid)}:`) + this.npm.output( + `${colorize.reset(colorize.bold('Lifecycle scripts'))} included in ${colorize.green( + pkgid + )}:` + ) } - for (const script of cmds) + for (const script of cmds) { this.npm.output(prefix + script + indent + colorize.dim(scripts[script])) + } if (!cmds.length && runScripts.length) { - this.npm.output(`${ - colorize.bold('Scripts') - } available in ${colorize.green(pkgid)} via \`${ - colorize.blue('npm run-script')}\`:`) - } else if (runScripts.length) + this.npm.output( + `${colorize.bold('Scripts')} available in ${colorize.green(pkgid)} via \`${colorize.blue( + 'npm run-script' + )}\`:` + ) + } else if (runScripts.length) { this.npm.output(`\navailable via \`${colorize.blue('npm run-script')}\`:`) + } - for (const script of runScripts) + for (const script of runScripts) { this.npm.output(prefix + script + indent + colorize.dim(scripts[script])) + } this.npm.output('') return allScripts @@ -212,8 +229,9 @@ class RunScript extends BaseCommand { // avoids exiting with error code in case there's scripts missing // in some workspaces since other scripts might have succeeded - if (!scriptMissing) + if (!scriptMissing) { process.exitCode = 1 + } return scriptMissing }) @@ -221,15 +239,17 @@ class RunScript extends BaseCommand { } // in case **all** tests are missing, then it should exit with error code - if (res.every(Boolean)) + if (res.every(Boolean)) { throw new Error(`Missing script: ${args[0]}`) + } } async listWorkspaces (args, filters) { await this.setWorkspaces(filters) - if (log.level === 'silent') + if (log.level === 'silent') { return + } if (this.npm.config.get('json')) { const res = {} @@ -244,14 +264,16 @@ class RunScript extends BaseCommand { if (this.npm.config.get('parseable')) { for (const workspacePath of this.workspacePaths) { const { scripts, name } = await rpj(`${workspacePath}/package.json`) - for (const [script, cmd] of Object.entries(scripts || {})) + for (const [script, cmd] of Object.entries(scripts || {})) { this.npm.output(`${name}:${script}:${cmd}`) + } } return } - for (const workspacePath of this.workspacePaths) + for (const workspacePath of this.workspacePaths) { await this.list(args, workspacePath) + } } } diff --git a/lib/commands/search.js b/lib/commands/search.js index e60f41afb..6c5c995c3 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -14,10 +14,11 @@ function prepareIncludes (args) { function prepareExcludes (searchexclude) { var exclude - if (typeof searchexclude === 'string') + if (typeof searchexclude === 'string') { exclude = searchexclude.split(/\s+/) - else + } else { exclude = [] + } return exclude .map(s => s.toLowerCase()) @@ -66,16 +67,18 @@ class Search extends BaseCommand { exclude: prepareExcludes(this.npm.flatOptions.search.exclude), } - if (opts.include.length === 0) + if (opts.include.length === 0) { throw new Error('search must be called with arguments') + } // Used later to figure out whether we had any packages go out let anyOutput = false class FilterStream extends Minipass { write (pkg) { - if (packageFilter(pkg, opts.include, opts.exclude)) + if (packageFilter(pkg, opts.include, opts.exclude)) { super.write(pkg) + } } } @@ -96,14 +99,16 @@ class Search extends BaseCommand { ) p.on('data', chunk => { - if (!anyOutput) + if (!anyOutput) { anyOutput = true + } this.npm.output(chunk.toString('utf8')) }) await p.promise() - if (!anyOutput && !this.npm.config.get('json') && !this.npm.config.get('parseable')) + if (!anyOutput && !this.npm.config.get('json') && !this.npm.config.get('parseable')) { this.npm.output('No matches found for ' + (args.map(JSON.stringify).join(' '))) + } log.silly('search', 'search completed') log.clearProgress() diff --git a/lib/commands/set-script.js b/lib/commands/set-script.js index 00f9b5d5b..d99487e67 100644 --- a/lib/commands/set-script.js +++ b/lib/commands/set-script.js @@ -36,19 +36,22 @@ class SetScript extends BaseCommand { } validate (args) { - if (process.env.npm_lifecycle_event === 'postinstall') + if (process.env.npm_lifecycle_event === 'postinstall') { throw new Error('Scripts can’t set from the postinstall script') + } // Parse arguments - if (args.length !== 2) + if (args.length !== 2) { throw new Error(`Expected 2 arguments: got ${args.length}`) + } } async exec (args) { this.validate(args) const warn = await this.doSetScript(this.npm.localPrefix, args[0], args[1]) - if (warn) + if (warn) { log.warn('set-script', `Script "${args[0]}" was overwritten`) + } } async execWorkspaces (args, filters) { @@ -86,8 +89,9 @@ class SetScript extends BaseCommand { && scripts[name] && scripts[name] !== value - if (overwriting) + if (overwriting) { warn = true + } pkgJson.update({ scripts: { diff --git a/lib/commands/set.js b/lib/commands/set.js index cdaabc04a..b38623c60 100644 --- a/lib/commands/set.js +++ b/lib/commands/set.js @@ -21,8 +21,9 @@ class Set extends BaseCommand { } async exec (args) { - if (!args.length) + if (!args.length) { throw this.usageError() + } return this.npm.exec('config', ['set'].concat(args)) } } diff --git a/lib/commands/shrinkwrap.js b/lib/commands/shrinkwrap.js index 42489a27f..2d57e7b91 100644 --- a/lib/commands/shrinkwrap.js +++ b/lib/commands/shrinkwrap.js @@ -57,19 +57,22 @@ class Shrinkwrap extends BaseCommand { if (newFile) { let message = 'created a lockfile as npm-shrinkwrap.json' - if (updatedVersion) + if (updatedVersion) { message += ` with version ${updatedVersion}` + } log.notice('', message) } else if (notSW) { await unlink(oldFilename) let message = 'package-lock.json has been renamed to npm-shrinkwrap.json' - if (updatedVersion) + if (updatedVersion) { message += ` and updated to version ${updatedVersion}` + } log.notice('', message) - } else if (updatedVersion) + } else if (updatedVersion) { log.notice('', `npm-shrinkwrap.json updated to version ${updatedVersion}`) - else + } else { log.notice('', 'npm-shrinkwrap.json up to date') + } } } module.exports = Shrinkwrap diff --git a/lib/commands/star.js b/lib/commands/star.js index 36003a020..ce1564ff1 100644 --- a/lib/commands/star.js +++ b/lib/commands/star.js @@ -29,8 +29,9 @@ class Star extends BaseCommand { } async exec (args) { - if (!args.length) + if (!args.length) { throw this.usageError() + } // if we're unstarring, then show an empty star image // otherwise, show the full star image @@ -52,8 +53,9 @@ class Star extends BaseCommand { }), ]) - if (!username) + if (!username) { throw new Error('You need to be logged in!') + } const body = { _id: fullData._id, diff --git a/lib/commands/stars.js b/lib/commands/stars.js index d430be2ce..61fd45f84 100644 --- a/lib/commands/stars.js +++ b/lib/commands/stars.js @@ -29,21 +29,25 @@ class Stars extends BaseCommand { async exec ([user]) { try { - if (!user) + if (!user) { user = await getIdentity(this.npm, this.npm.flatOptions) + } const { rows } = await fetch.json('/-/_view/starredByUser', { ...this.npm.flatOptions, query: { key: `"${user}"` }, }) - if (rows.length === 0) + if (rows.length === 0) { log.warn('stars', 'user has not starred any packages') + } - for (const row of rows) + for (const row of rows) { this.npm.output(row.value) + } } catch (err) { - if (err.code === 'ENEEDAUTH') + if (err.code === 'ENEEDAUTH') { log.warn('stars', 'auth is required to look up your username') + } throw err } } diff --git a/lib/commands/team.js b/lib/commands/team.js index b337a7536..04b1b708f 100644 --- a/lib/commands/team.js +++ b/lib/commands/team.js @@ -39,11 +39,13 @@ class Team extends BaseCommand { const { conf: { argv: { remain: argv } } } = opts const subcommands = ['create', 'destroy', 'add', 'rm', 'ls'] - if (argv.length === 2) + if (argv.length === 2) { return subcommands + } - if (subcommands.includes(argv[2])) + if (subcommands.includes(argv[2])) { return [] + } throw new Error(argv[2] + ' not recognized') } @@ -62,10 +64,11 @@ class Team extends BaseCommand { case 'rm': return this.rm(entity, user, opts) case 'ls': { const match = entity.match(/[^:]+:.+/) - if (match) + if (match) { return this.listUsers(entity, opts) - else + } else { return this.listTeams(entity, opts) + } } default: throw this.usageError() @@ -80,10 +83,11 @@ class Team extends BaseCommand { created: true, team: entity, })) - } else if (opts.parseable) + } else if (opts.parseable) { this.npm.output(`${entity}\tcreated`) - else if (!opts.silent && opts.loglevel !== 'silent') + } else if (!opts.silent && opts.loglevel !== 'silent') { this.npm.output(`+@${entity}`) + } } async destroy (entity, opts) { @@ -93,10 +97,11 @@ class Team extends BaseCommand { deleted: true, team: entity, })) - } else if (opts.parseable) + } else if (opts.parseable) { this.npm.output(`${entity}\tdeleted`) - else if (!opts.silent && opts.loglevel !== 'silent') + } else if (!opts.silent && opts.loglevel !== 'silent') { this.npm.output(`-@${entity}`) + } } async add (entity, user, opts) { @@ -107,10 +112,11 @@ class Team extends BaseCommand { team: entity, user, })) - } else if (opts.parseable) + } else if (opts.parseable) { this.npm.output(`${user}\t${entity}\tadded`) - else if (!opts.silent && opts.loglevel !== 'silent') + } else if (!opts.silent && opts.loglevel !== 'silent') { this.npm.output(`${user} added to @${entity}`) + } } async rm (entity, user, opts) { @@ -121,19 +127,20 @@ class Team extends BaseCommand { team: entity, user, })) - } else if (opts.parseable) + } else if (opts.parseable) { this.npm.output(`${user}\t${entity}\tremoved`) - else if (!opts.silent && opts.loglevel !== 'silent') + } else if (!opts.silent && opts.loglevel !== 'silent') { this.npm.output(`${user} removed from @${entity}`) + } } async listUsers (entity, opts) { const users = (await libteam.lsUsers(entity, opts)).sort() - if (opts.json) + if (opts.json) { this.npm.output(JSON.stringify(users, null, 2)) - else if (opts.parseable) + } else if (opts.parseable) { this.npm.output(users.join('\n')) - else if (!opts.silent && opts.loglevel !== 'silent') { + } else if (!opts.silent && opts.loglevel !== 'silent') { const plural = users.length === 1 ? '' : 's' const more = users.length === 0 ? '' : ':\n' this.npm.output(`\n@${entity} has ${users.length} user${plural}${more}`) @@ -143,11 +150,11 @@ class Team extends BaseCommand { async listTeams (entity, opts) { const teams = (await libteam.lsTeams(entity, opts)).sort() - if (opts.json) + if (opts.json) { this.npm.output(JSON.stringify(teams, null, 2)) - else if (opts.parseable) + } else if (opts.parseable) { this.npm.output(teams.join('\n')) - else if (!opts.silent && opts.loglevel !== 'silent') { + } else if (!opts.silent && opts.loglevel !== 'silent') { const plural = teams.length === 1 ? '' : 's' const more = teams.length === 0 ? '' : ':\n' this.npm.output(`\n@${entity} has ${teams.length} team${plural}${more}`) diff --git a/lib/commands/token.js b/lib/commands/token.js index f7b92ea1d..499ea3d02 100644 --- a/lib/commands/token.js +++ b/lib/commands/token.js @@ -21,39 +21,33 @@ class Token extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get usage () { - return [ - 'list', - 'revoke <id|token>', - 'create [--read-only] [--cidr=list]', - ] + return ['list', 'revoke <id|token>', 'create [--read-only] [--cidr=list]'] } /* istanbul ignore next - see test/lib/load-all-commands.js */ static get params () { - return [ - 'read-only', - 'cidr', - 'registry', - 'otp', - ] + return ['read-only', 'cidr', 'registry', 'otp'] } async completion (opts) { const argv = opts.conf.argv.remain const subcommands = ['list', 'revoke', 'create'] - if (argv.length === 2) + if (argv.length === 2) { return subcommands + } - if (subcommands.includes(argv[2])) + if (subcommands.includes(argv[2])) { return [] + } throw new Error(argv[2] + ' not recognized') } async exec (args, cb) { log.gauge.show('token') - if (args.length === 0) + if (args.length === 0) { return this.list() + } switch (args[0]) { case 'list': case 'ls': @@ -79,25 +73,26 @@ class Token extends BaseCommand { return } else if (conf.parseable) { this.npm.output(['key', 'token', 'created', 'readonly', 'CIDR whitelist'].join('\t')) - tokens.forEach((token) => { - this.npm.output([ - token.key, - token.token, - token.created, - token.readonly ? 'true' : 'false', - token.cidr_whitelist ? token.cidr_whitelist.join(',') : '', - ].join('\t')) + tokens.forEach(token => { + this.npm.output( + [ + token.key, + token.token, + token.created, + token.readonly ? 'true' : 'false', + token.cidr_whitelist ? token.cidr_whitelist.join(',') : '', + ].join('\t') + ) }) return } this.generateTokenIds(tokens, 6) - const idWidth = tokens.reduce((acc, token) => - Math.max(acc, token.id.length), 0) + const idWidth = tokens.reduce((acc, token) => Math.max(acc, token.id.length), 0) const table = new Table({ head: ['id', 'token', 'created', 'readonly', 'CIDR whitelist'], colWidths: [Math.max(idWidth, 2) + 2, 9, 12, 10], }) - tokens.forEach((token) => { + tokens.forEach(token => { table.push([ token.id, token.token + '…', @@ -110,39 +105,47 @@ class Token extends BaseCommand { } async rm (args) { - if (args.length === 0) + if (args.length === 0) { throw this.usageError('`<tokenKey>` argument is required.') + } const conf = this.config() const toRemove = [] const progress = log.newItem('removing tokens', toRemove.length) progress.info('token', 'getting existing list') const tokens = await pulseTillDone.withPromise(profile.listTokens(conf)) - args.forEach((id) => { - const matches = tokens.filter((token) => token.key.indexOf(id) === 0) - if (matches.length === 1) + args.forEach(id => { + const matches = tokens.filter(token => token.key.indexOf(id) === 0) + if (matches.length === 1) { toRemove.push(matches[0].key) - else if (matches.length > 1) - throw new Error(`Token ID "${id}" was ambiguous, a new token may have been created since you last ran \`npm token list\`.`) - else { + } else if (matches.length > 1) { + throw new Error( + /* eslint-disable-next-line max-len */ + `Token ID "${id}" was ambiguous, a new token may have been created since you last ran \`npm token list\`.` + ) + } else { const tokenMatches = tokens.some(t => id.indexOf(t.token) === 0) - if (!tokenMatches) + if (!tokenMatches) { throw new Error(`Unknown token id or value "${id}".`) + } toRemove.push(id) } }) - await Promise.all(toRemove.map(key => { - return otplease(conf, conf => { - return profile.removeToken(key, conf) + await Promise.all( + toRemove.map(key => { + return otplease(conf, conf => { + return profile.removeToken(key, conf) + }) }) - })) - if (conf.json) + ) + if (conf.json) { this.npm.output(JSON.stringify(toRemove)) - else if (conf.parseable) + } else if (conf.parseable) { this.npm.output(toRemove.join('\t')) - else + } else { this.npm.output('Removed ' + toRemove.length + ' token' + (toRemove.length !== 1 ? 's' : '')) + } } async create (args) { @@ -150,34 +153,40 @@ class Token extends BaseCommand { const cidr = conf.cidr const readonly = conf.readOnly - return readUserInfo.password().then((password) => { - const validCIDR = this.validateCIDRList(cidr) - log.info('token', 'creating') - return pulseTillDone.withPromise(otplease(conf, conf => { - return profile.createToken(password, readonly, validCIDR, conf) - })) - }).then((result) => { - delete result.key - delete result.updated - if (conf.json) - this.npm.output(JSON.stringify(result)) - else if (conf.parseable) - Object.keys(result).forEach((k) => this.npm.output(k + '\t' + result[k])) - else { - const table = new Table() - for (const k of Object.keys(result)) - table.push({ [ansistyles.bright(k)]: String(result[k]) }) - this.npm.output(table.toString()) - } - }) + return readUserInfo + .password() + .then(password => { + const validCIDR = this.validateCIDRList(cidr) + log.info('token', 'creating') + return pulseTillDone.withPromise( + otplease(conf, conf => { + return profile.createToken(password, readonly, validCIDR, conf) + }) + ) + }) + .then(result => { + delete result.key + delete result.updated + if (conf.json) { + this.npm.output(JSON.stringify(result)) + } else if (conf.parseable) { + Object.keys(result).forEach(k => this.npm.output(k + '\t' + result[k])) + } else { + const table = new Table() + for (const k of Object.keys(result)) { + table.push({ [ansistyles.bright(k)]: String(result[k]) }) + } + this.npm.output(table.toString()) + } + }) } config () { const conf = { ...this.npm.flatOptions } const creds = this.npm.config.getCredentialsByURI(conf.registry) - if (creds.token) + if (creds.token) { conf.auth = { token: creds.token } - else if (creds.username) { + } else if (creds.username) { conf.auth = { basic: { username: creds.username, @@ -192,11 +201,13 @@ class Token extends BaseCommand { password: auth[1], }, } - } else + } else { conf.auth = {} + } - if (conf.otp) + if (conf.otp) { conf.auth.otp = conf.otp + } return conf } @@ -209,9 +220,9 @@ class Token extends BaseCommand { for (const token of tokens) { token.id = token.key for (let ii = minLength; ii < token.key.length; ++ii) { - const match = tokens.some(ot => - ot !== token && - ot.key.slice(0, ii) === token.key.slice(0, ii)) + const match = tokens.some( + ot => ot !== token && ot.key.slice(0, ii) === token.key.slice(0, ii) + ) if (!match) { token.id = token.key.slice(0, ii) break @@ -226,11 +237,15 @@ class Token extends BaseCommand { const maybeList = cidrs ? (Array.isArray(cidrs) ? cidrs : [cidrs]) : [] const list = maybeList.length === 1 ? maybeList[0].split(/,\s*/) : maybeList for (const cidr of list) { - if (isCidrV6(cidr)) - throw this.invalidCIDRError('CIDR whitelist can only contain IPv4 addresses, ' + cidr + ' is IPv6') + if (isCidrV6(cidr)) { + throw this.invalidCIDRError( + 'CIDR whitelist can only contain IPv4 addresses, ' + cidr + ' is IPv6' + ) + } - if (!isCidrV4(cidr)) + if (!isCidrV4(cidr)) { throw this.invalidCIDRError('CIDR whitelist contains invalid CIDR entry: ' + cidr) + } } return list } diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index 09b6e47a7..aaebd1a90 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -39,18 +39,19 @@ class Uninstall extends ArboristWorkspaceCmd { : this.npm.localPrefix if (!args.length) { - if (!global) + if (!global) { throw new Error('Must provide a package name to remove') - else { + } else { let pkg try { pkg = await rpj(resolve(this.npm.localPrefix, 'package.json')) } catch (er) { - if (er.code !== 'ENOENT' && er.code !== 'ENOTDIR') + if (er.code !== 'ENOENT' && er.code !== 'ENOTDIR') { throw er - else + } else { throw this.usageError() + } } args.push(pkg.name) diff --git a/lib/commands/unpublish.js b/lib/commands/unpublish.js index 60ab4a5f9..6ef3f282a 100644 --- a/lib/commands/unpublish.js +++ b/lib/commands/unpublish.js @@ -33,38 +33,44 @@ class Unpublish extends BaseCommand { async completion (args) { const { partialWord, conf } = args - if (conf.argv.remain.length >= 3) + if (conf.argv.remain.length >= 3) { return [] + } const opts = this.npm.flatOptions const username = await getIdentity(this.npm, { ...opts }).catch(() => null) - if (!username) + if (!username) { return [] + } const access = await libaccess.lsPackages(username, opts) // do a bit of filtering at this point, so that we don't need // to fetch versions for more than one thing, but also don't // accidentally unpublish a whole project let pkgs = Object.keys(access || {}) - if (!partialWord || !pkgs.length) + if (!partialWord || !pkgs.length) { return pkgs + } const pp = npa(partialWord).name pkgs = pkgs.filter(p => !p.indexOf(pp)) - if (pkgs.length > 1) + if (pkgs.length > 1) { return pkgs + } const json = await npmFetch.json(npa(pkgs[0]).escapedName, opts) const versions = Object.keys(json.versions) - if (!versions.length) + if (!versions.length) { return pkgs - else + } else { return versions.map(v => `${pkgs[0]}@${v}`) + } } async exec (args) { - if (args.length > 1) + if (args.length > 1) { throw this.usageError() + } const spec = args.length && npa(args[0]) const force = this.npm.config.get('force') @@ -93,10 +99,11 @@ class Unpublish extends BaseCommand { try { manifest = await readJson(pkgJson) } catch (err) { - if (err && err.code !== 'ENOENT' && err.code !== 'ENOTDIR') + if (err && err.code !== 'ENOENT' && err.code !== 'ENOTDIR') { throw err - else + } else { throw this.usageError() + } } this.npm.log.verbose('unpublish', manifest) @@ -104,19 +111,22 @@ class Unpublish extends BaseCommand { const { name, version, publishConfig } = manifest const pkgJsonSpec = npa.resolve(name, version) const optsWithPub = { ...opts, publishConfig } - if (!dryRun) + if (!dryRun) { await otplease(opts, opts => libunpub(pkgJsonSpec, optsWithPub)) + } pkgName = name pkgVersion = version ? `@${version}` : '' } else { - if (!dryRun) + if (!dryRun) { await otplease(opts, opts => libunpub(spec, opts)) + } pkgName = spec.name pkgVersion = spec.type === 'version' ? `@${spec.rawSpec}` : '' } - if (!silent) + if (!silent) { this.npm.output(`- ${pkgName}${pkgVersion}`) + } } async execWorkspaces (args, filters) { @@ -130,8 +140,9 @@ class Unpublish extends BaseCommand { ) } - for (const name of this.workspaceNames) + for (const name of this.workspaceNames) { await this.exec([name]) + } } } module.exports = Unpublish diff --git a/lib/commands/version.js b/lib/commands/version.js index 60e1e36f5..1572a3845 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -32,13 +32,21 @@ class Version extends BaseCommand { /* istanbul ignore next - see test/lib/load-all-commands.js */ static get usage () { - return ['[<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]'] + return [ + /* eslint-disable-next-line max-len */ + '[<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]', + ] } async completion (opts) { - const { conf: { argv: { remain } } } = opts - if (remain.length > 2) + const { + conf: { + argv: { remain }, + }, + } = opts + if (remain.length > 2) { return [] + } return [ 'major', @@ -104,17 +112,20 @@ class Version extends BaseCommand { .then(data => JSON.parse(data)) .catch(() => ({})) - if (pkg.name && pkg.version) + if (pkg.name && pkg.version) { results[pkg.name] = pkg.version + } results.npm = this.npm.version - for (const [key, version] of Object.entries(process.versions)) + for (const [key, version] of Object.entries(process.versions)) { results[key] = version + } - if (this.npm.config.get('json')) + if (this.npm.config.get('json')) { this.npm.output(JSON.stringify(results, null, 2)) - else + } else { this.npm.output(results) + } } async listWorkspaces (filters) { @@ -123,11 +134,11 @@ class Version extends BaseCommand { for (const path of this.workspacePaths) { const pj = resolve(path, 'package.json') // setWorkspaces has already parsed package.json so we know it won't error - const pkg = await readFile(pj, 'utf8') - .then(data => JSON.parse(data)) + const pkg = await readFile(pj, 'utf8').then(data => JSON.parse(data)) - if (pkg.name && pkg.version) + if (pkg.name && pkg.version) { results[pkg.name] = pkg.version + } } return this.list(results) } diff --git a/lib/commands/view.js b/lib/commands/view.js index 24d13cfcf..08bed57e0 100644 --- a/lib/commands/view.js +++ b/lib/commands/view.js @@ -67,44 +67,51 @@ class View extends BaseCommand { function getFields (d, f, pref) { f = f || [] - if (!d) + if (!d) { return f + } pref = pref || [] Object.keys(d).forEach((k) => { - if (k.charAt(0) === '_' || k.indexOf('.') !== -1) + if (k.charAt(0) === '_' || k.indexOf('.') !== -1) { return + } const p = pref.concat(k).join('.') f.push(p) if (Array.isArray(d[k])) { d[k].forEach((val, i) => { const pi = p + '[' + i + ']' - if (val && typeof val === 'object') + if (val && typeof val === 'object') { getFields(val, f, [p]) - else + } else { f.push(pi) + } }) return } - if (typeof d[k] === 'object') + if (typeof d[k] === 'object') { getFields(d[k], f, [p]) + } }) return f } } async exec (args) { - if (!args.length) + if (!args.length) { args = ['.'] + } let pkg = args.shift() const local = /^\.@/.test(pkg) || pkg === '.' if (local) { - if (this.npm.config.get('global')) + if (this.npm.config.get('global')) { throw new Error('Cannot use view command in global mode.') + } const dir = this.npm.prefix const manifest = await readJson(resolve(dir, 'package.json')) - if (!manifest.name) + if (!manifest.name) { throw new Error('Invalid package.json, no "name" field') + } // put the version back if it existed pkg = `${manifest.name}${pkg.slice(1)}` } @@ -131,14 +138,16 @@ class View extends BaseCommand { log.disableProgress() const msg = await this.jsonData(reducedData, pckmnt._id) - if (msg !== '') + if (msg !== '') { console.log(msg) + } } } async execWorkspaces (args, filters) { - if (!args.length) + if (!args.length) { args = ['.'] + } const pkg = args.shift() @@ -166,22 +175,25 @@ class View extends BaseCommand { } if (!this.npm.config.get('json')) { - if (wholePackument) + if (wholePackument) { data.map((v) => this.prettyView(pckmnt, v[Object.keys(v)[0]][''])) - else { + } else { console.log(`${name}:`) const msg = await this.jsonData(reducedData, pckmnt._id) - if (msg !== '') + if (msg !== '') { console.log(msg) + } } } else { const msg = await this.jsonData(reducedData, pckmnt._id) - if (msg !== '') + if (msg !== '') { results[name] = JSON.parse(msg) + } } } - if (Object.keys(results).length > 0) + if (Object.keys(results).length > 0) { console.log(JSON.stringify(results, null, 2)) + } } async getData (pkg, args) { @@ -196,13 +208,15 @@ class View extends BaseCommand { // get the data about this package let version = this.npm.config.get('tag') // rawSpec is the git url if this is from git - if (spec.type !== 'git' && spec.rawSpec) + if (spec.type !== 'git' && spec.rawSpec) { version = spec.rawSpec + } const pckmnt = await packument(spec, opts) - if (pckmnt['dist-tags'] && pckmnt['dist-tags'][version]) + if (pckmnt['dist-tags'] && pckmnt['dist-tags'][version]) { version = pckmnt['dist-tags'][version] + } if (pckmnt.time && pckmnt.time.unpublished) { const u = pckmnt.time.unpublished @@ -218,15 +232,17 @@ class View extends BaseCommand { pckmnt.versions = Object.keys(versions).sort(semver.compareLoose) // remove readme unless we asked for it - if (args.indexOf('readme') === -1) + if (args.indexOf('readme') === -1) { delete pckmnt.readme + } Object.keys(versions).forEach((v) => { if (semver.satisfies(v, version, true)) { args.forEach(arg => { // remove readme unless we asked for it - if (args.indexOf('readme') !== -1) + if (args.indexOf('readme') !== -1) { delete versions[v].readme + } data.push(showFields(pckmnt, versions[v], arg)) }) @@ -237,8 +253,9 @@ class View extends BaseCommand { !this.npm.config.get('json') && args.length === 1 && args[0] === '' - ) + ) { pckmnt.version = version + } return [pckmnt, data] } @@ -254,17 +271,19 @@ class View extends BaseCommand { versions.forEach((v) => { const fields = Object.keys(data[v]) includeFields = includeFields || (fields.length > 1) - if (json) + if (json) { msgJson.push({}) + } fields.forEach((f) => { let d = cleanup(data[v][f]) - if (fields.length === 1 && json) + if (fields.length === 1 && json) { msgJson[msgJson.length - 1][f] = d + } if (includeVersions || includeFields || typeof d !== 'string') { - if (json) + if (json) { msgJson[msgJson.length - 1][f] = d - else { + } else { d = inspect(d, { showHidden: false, depth: 5, @@ -272,12 +291,14 @@ class View extends BaseCommand { maxArrayLength: null, }) } - } else if (typeof d === 'string' && json) + } else if (typeof d === 'string' && json) { d = JSON.stringify(d) + } if (!json) { - if (f && includeFields) + if (f && includeFields) { f += ' = ' + } msg += (includeVersions ? name + '@' + v + ' ' : '') + (includeFields ? f : '') + d + '\n' } @@ -289,10 +310,11 @@ class View extends BaseCommand { const k = Object.keys(msgJson[0])[0] msgJson = msgJson.map(m => m[k]) } - if (msgJson.length === 1) + if (msgJson.length === 1) { msg = JSON.stringify(msgJson[0], null, 2) + '\n' - else if (msgJson.length > 1) + } else if (msgJson.length > 1) { msg = JSON.stringify(msgJson, null, 2) + '\n' + } } return msg.trim() @@ -351,10 +373,11 @@ class View extends BaseCommand { manifest.dist.fileCount && color.yellow(manifest.dist.fileCount), unpackedSize: unpackedSize && color.yellow(unpackedSize), } - if (info.license.toLowerCase().trim() === 'proprietary') + if (info.license.toLowerCase().trim() === 'proprietary') { info.license = style.bright(color.red(info.license)) - else + } else { info.license = color.green(info.license) + } console.log('') console.log( @@ -364,8 +387,9 @@ class View extends BaseCommand { ' | versions: ' + info.versions ) info.description && console.log(info.description) - if (info.repo || info.site) + if (info.repo || info.site) { info.site && console.log(color.cyan(info.site)) + } const warningSign = unicode ? ' ⚠️ ' : '!!' info.deprecated && console.log( @@ -396,8 +420,9 @@ class View extends BaseCommand { console.log('') console.log('dependencies:') console.log(columns(info.deps.slice(0, maxDeps), { padding: 1 })) - if (info.deps.length > maxDeps) + if (info.deps.length > maxDeps) { console.log(`(...and ${info.deps.length - maxDeps} more.)`) + } } if (info.maintainers && info.maintainers.length) { @@ -412,10 +437,12 @@ class View extends BaseCommand { if (info.publisher || info.modified) { let publishInfo = 'published' - if (info.modified) + if (info.modified) { publishInfo += ` ${info.modified}` - if (info.publisher) + } + if (info.publisher) { publishInfo += ` by ${info.publisher}` + } console.log('') console.log(publishInfo) } @@ -458,24 +485,28 @@ function showFields (data, version, fields) { const s = queryable.query(fields) const res = { [version.version]: s } - if (s) + if (s) { return res + } } function cleanup (data) { - if (Array.isArray(data)) + if (Array.isArray(data)) { return data.map(cleanup) + } - if (!data || typeof data !== 'object') + if (!data || typeof data !== 'object') { return data + } const keys = Object.keys(data) if (keys.length <= 3 && data.name && (keys.length === 1 || (keys.length === 3 && data.email && data.url) || - (keys.length === 2 && (data.email || data.url)))) + (keys.length === 2 && (data.email || data.url)))) { data = unparsePerson(data) + } return data } |