diff options
author | isaacs <i@izs.me> | 2020-10-23 21:15:35 +0300 |
---|---|---|
committer | isaacs <i@izs.me> | 2020-10-23 21:23:15 +0300 |
commit | 47640eb2c3cd9891e904e3f6bc705b6618096103 (patch) | |
tree | 8b1b635135a5672ed0da4d8e6feade0f9d8fa60d /lib | |
parent | b737ee99961364827bacf210a3e5ca5d2b7edad2 (diff) |
update lint rules to match @npmcli/arborist
Diffstat (limited to 'lib')
97 files changed, 1098 insertions, 1167 deletions
diff --git a/lib/access.js b/lib/access.js index 33d296f8f..73228cae0 100644 --- a/lib/access.js +++ b/lib/access.js @@ -34,12 +34,12 @@ const subcommands = [ 'ls-collaborators', 'edit', '2fa-required', - '2fa-not-required' + '2fa-not-required', ] const UsageError = (msg) => Object.assign(new Error(`\nUsage: ${msg}\n\n` + usage), { - code: 'EUSAGE' + code: 'EUSAGE', }) const cmd = (args, cb) => @@ -53,30 +53,27 @@ const cmd = (args, cb) => const access = async ([cmd, ...args], cb) => { const fn = subcommands.includes(cmd) && access[cmd] - if (!cmd) { + if (!cmd) throw UsageError('Subcommand is required.') - } - if (!fn) { + if (!fn) throw UsageError(`${cmd} is not a recognized subcommand.`) - } return fn(args, { ...npm.flatOptions }) } const completion = function (opts, cb) { var argv = opts.conf.argv.remain - if (argv.length === 2) { + if (argv.length === 2) return cb(null, subcommands) - } switch (argv[2]) { case 'grant': - if (argv.length === 3) { + if (argv.length === 3) return cb(null, ['read-only', 'read-write']) - } else { + else return cb(null, []) - } + case 'public': case 'restricted': case 'ls-packages': @@ -98,13 +95,11 @@ access.restricted = ([pkg], opts) => modifyPackage(pkg, opts, libaccess.restricted) access.grant = async ([perms, scopeteam, pkg], opts) => { - if (!perms || (perms !== 'read-only' && perms !== 'read-write')) { + if (!perms || (perms !== 'read-only' && perms !== 'read-write')) throw UsageError('First argument must be either `read-only` or `read-write`.') - } - if (!scopeteam) { + if (!scopeteam) throw UsageError('`<scope:team>` argument is required.') - } const [, scope, team] = scopeteam.match(/^@?([^:]+):(.*)$/) || [] @@ -120,9 +115,8 @@ access.grant = async ([perms, scopeteam, pkg], opts) => { } access.revoke = async ([scopeteam, pkg], opts) => { - if (!scopeteam) { + if (!scopeteam) throw UsageError('`<scope:team>` argument is required.') - } const [, scope, team] = scopeteam.match(/^@?([^:]+):(.*)$/) || [] @@ -144,9 +138,8 @@ access['2fa-not-required'] = access.tfaNotRequired = ([pkg], opts) => modifyPackage(pkg, opts, libaccess.tfaNotRequired, false) access['ls-packages'] = access.lsPackages = async ([owner], opts) => { - if (!owner) { + if (!owner) owner = await getIdentity(opts) - } const pkgs = await libaccess.lsPackages(owner, opts) @@ -170,9 +163,9 @@ const modifyPackage = (pkg, opts, fn, requireScope = true) => .then(pkgName => otplease(opts, opts => fn(pkgName, opts))) const getPackage = async (name, requireScope) => { - if (name && name.trim()) { + if (name && name.trim()) return name.trim() - } else { + else { try { const pkg = await readPackageJson(path.resolve(prefix, 'package.json')) name = pkg.name @@ -181,16 +174,14 @@ const getPackage = async (name, requireScope) => { 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 UsageError('This command is only available for scoped packages.') - } else { + else return name - } } } diff --git a/lib/adduser.js b/lib/adduser.js index 017958e02..895a677c0 100644 --- a/lib/adduser.js +++ b/lib/adduser.js @@ -8,7 +8,7 @@ const authTypes = { legacy: require('./auth/legacy.js'), oauth: require('./auth/oauth.js'), saml: require('./auth/saml.js'), - sso: require('./auth/sso.js') + sso: require('./auth/sso.js'), } const usage = usageUtil( @@ -24,9 +24,8 @@ const getRegistry = ({ scope, registry }) => { if (scope) { const scopedRegistry = npm.config.get(`${scope}:registry`) const cliRegistry = npm.config.get('registry', 'cli') - if (scopedRegistry && !cliRegistry) { + if (scopedRegistry && !cliRegistry) return scopedRegistry - } } return registry } @@ -34,9 +33,8 @@ const getRegistry = ({ scope, registry }) => { const getAuthType = ({ authType }) => { const type = authTypes[authType] - if (!type) { + if (!type) throw new Error('no such auth module') - } return type } @@ -44,9 +42,8 @@ const getAuthType = ({ authType }) => { const updateConfig = async ({ newCreds, registry, scope }) => { npm.config.delete('_token', 'user') // prevent legacy pollution - if (scope) { + if (scope) npm.config.set(scope + ':registry', registry, 'user') - } npm.config.setCredentialsByURI(registry, newCreds) await npm.config.save('user') @@ -63,13 +60,13 @@ const adduser = async (args) => { const { message, newCreds } = await auth({ creds, registry, - scope + scope, }) await updateConfig({ newCreds, registry, - scope + scope, }) output(message) diff --git a/lib/audit.js b/lib/audit.js index 30c043fa0..e77beab1e 100644 --- a/lib/audit.js +++ b/lib/audit.js @@ -9,19 +9,19 @@ const audit = async args => { const arb = new Arborist({ ...npm.flatOptions, audit: true, - path: npm.prefix + path: npm.prefix, }) const fix = args[0] === 'fix' await arb.audit({ fix }) - if (fix) { + if (fix) reifyOutput(arb) - } else { + else { // will throw if there's an error, because this is an audit command auditError(arb.auditReport) const reporter = npm.flatOptions.json ? 'json' : 'detail' const result = auditReport(arb.auditReport, { ...npm.flatOptions, - reporter + reporter, }) process.exitCode = process.exitCode || result.exitCode output(result.report) @@ -41,9 +41,8 @@ const usage = usageUtil( const completion = (opts, cb) => { const argv = opts.conf.argv.remain - if (argv.length === 2) { + if (argv.length === 2) return cb(null, ['fix']) - } switch (argv[2]) { case 'fix': diff --git a/lib/auth/legacy.js b/lib/auth/legacy.js index 883a32fd5..4178c40b9 100644 --- a/lib/auth/legacy.js +++ b/lib/auth/legacy.js @@ -47,11 +47,10 @@ const login = async (opts) => { opts ) } catch (err) { - if (err.code === 'EOTP') { + if (err.code === 'EOTP') newUser = await requestOTP() - } else { + else throw err - } } return newUser @@ -65,20 +64,20 @@ const login = async (opts) => { opts.creds.username && opts.creds.password && opts.creds.email) - if (err.code === 'EOTP') { + if (err.code === 'EOTP') res = await requestOTP() - } else if (needsMoreInfo) { + else if (needsMoreInfo) throw err - } else { + else { // TODO: maybe this needs to check for err.code === 'E400' instead? res = await addNewUser() } } const newCreds = {} - if (res && res.token) { + if (res && res.token) newCreds.token = res.token - } else { + else { newCreds.username = opts.creds.username newCreds.password = opts.creds.password newCreds.email = opts.creds.email @@ -94,7 +93,7 @@ const login = async (opts) => { return { message, - newCreds + newCreds, } } diff --git a/lib/auth/sso.js b/lib/auth/sso.js index 5444e9ca0..8e4c34531 100644 --- a/lib/auth/sso.js +++ b/lib/auth/sso.js @@ -30,9 +30,8 @@ const pollForSession = ({ registry, token, opts }) => { return sleep(opts.ssoPollFrequency).then(() => { return pollForSession({ registry, token, opts }) }) - } else { + } else throw err - } } ) } @@ -47,9 +46,8 @@ const login = async ({ creds, registry, scope }) => { const opts = { ...npm.flatOptions, creds, registry, scope } const { ssoType } = opts - if (!ssoType) { + if (!ssoType) throw new Error('Missing option: sso-type') - } // We're reusing the legacy login endpoint, so we need some dummy // stuff here to pass validation. They're never used. @@ -57,15 +55,17 @@ const login = async ({ creds, registry, scope }) => { username: 'npm_' + ssoType + '_auth_dummy_user', password: 'placeholder', email: 'support@npmjs.com', - authType: ssoType + authType: ssoType, } const { token, sso } = await otplease(opts, opts => profile.loginCouch(auth.username, auth.password, opts) ) - if (!token) { throw new Error('no SSO token returned') } - if (!sso) { throw new Error('no SSO URL returned by services') } + if (!token) + throw new Error('no SSO token returned') + if (!sso) + throw new Error('no SSO URL returned by services') await openUrl(sso, 'to complete your login please visit') @@ -78,7 +78,7 @@ const login = async ({ creds, registry, scope }) => { return { message, - newCreds: { token } + newCreds: { token }, } } diff --git a/lib/bin.js b/lib/bin.js index 85b3da747..1d776365c 100644 --- a/lib/bin.js +++ b/lib/bin.js @@ -8,8 +8,7 @@ const usage = usageUtil('bin', 'npm bin [-g]') const bin = async (args, cb) => { const b = npm.bin output(b) - if (npm.flatOptions.global && !PATH.includes(b)) { + if (npm.flatOptions.global && !PATH.includes(b)) console.error('(not in PATH env variable)') - } } module.exports = Object.assign(cmd, { usage, completion }) diff --git a/lib/birthday.js b/lib/birthday.js index 90e8ea79e..097ffd925 100644 --- a/lib/birthday.js +++ b/lib/birthday.js @@ -1,3 +1,4 @@ +/* eslint-disable max-len */ // happy birthday! 🎂 module.exports = (_, c) => { diff --git a/lib/bugs.js b/lib/bugs.js index e6940f36b..012f39efb 100644 --- a/lib/bugs.js +++ b/lib/bugs.js @@ -12,27 +12,25 @@ const completion = require('./utils/completion/none.js') const cmd = (args, cb) => bugs(args).then(() => cb()).catch(cb) const bugs = async args => { - if (!args || !args.length) { + if (!args || !args.length) args = ['.'] - } + await Promise.all(args.map(pkg => getBugs(pkg))) } const 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 - } } // 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/cache.js b/lib/cache.js index dc3a6de72..bf788043a 100644 --- a/lib/cache.js +++ b/lib/cache.js @@ -21,9 +21,8 @@ const usage = usageUtil('cache', const completion = (opts, cb) => { const argv = opts.conf.argv.remain - if (argv.length === 2) { + if (argv.length === 2) return cb(null, ['add', 'clean']) - } // TODO - eventually... switch (argv[2]) { @@ -51,9 +50,9 @@ const cache = async (args) => { // npm cache clean [pkg]* const clean = async (args) => { - if (args.length) { + if (args.length) throw new Error('npm cache clear does not accept arguments') - } + const cachePath = path.join(npm.cache, '_cacache') if (!npm.flatOptions.force) { throw new Error(`As of npm@5, the npm cache self-heals from corruption issues @@ -89,9 +88,8 @@ const add = async (args, where) => { (args[1] === undefined || args[1] === null ? '' : `@${args[1]}`) log.verbose('cache add', 'spec', spec) - if (!spec) { + if (!spec) throw new Error(usage) - } log.silly('cache add', 'parsed spec', spec) const opts = { ...npm.flatOptions, where } @@ -31,7 +31,7 @@ const ci = async () => { 'later to generate a package-lock.json file, then try again.' throw new Error(msg) }), - rimraf(`${where}/node_modules/`) + rimraf(`${where}/node_modules/`), ]) // npm ci should never modify the lockfile or package.json await arb.reify({ save: false }) diff --git a/lib/cli.js b/lib/cli.js index 71bdb1bac..f06abcd18 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -4,7 +4,7 @@ module.exports = (process) => { const { checkForBrokenNode, - checkForUnsupportedNode + checkForUnsupportedNode, } = require('../lib/utils/unsupported.js') checkForBrokenNode() @@ -21,9 +21,8 @@ module.exports = (process) => { // if npm is called as "npmg" or "npm_g", then // run in global mode. - if (process.argv[1][process.argv[1].length - 1] === 'g') { + if (process.argv[1][process.argv[1].length - 1] === 'g') process.argv.splice(1, 1, 'npm', '-g') - } log.verbose('cli', process.argv) @@ -37,7 +36,8 @@ module.exports = (process) => { // this is how to use npm programmatically: const updateNotifier = require('../lib/utils/update-notifier.js') npm.load(async er => { - if (er) return errorHandler(er) + if (er) + return errorHandler(er) if (npm.config.get('version', 'cli')) { console.log(npm.version) return errorHandler.exit(0) @@ -52,9 +52,9 @@ module.exports = (process) => { const cmd = npm.argv.shift() const impl = npm.commands[cmd] - if (impl) { + if (impl) impl(npm.argv, errorHandler) - } else { + else { npm.config.set('usage', false) npm.argv.unshift(cmd) npm.commands.help(npm.argv, errorHandler) diff --git a/lib/completion.js b/lib/completion.js index 11c791d8f..dda7a9ebd 100644 --- a/lib/completion.js +++ b/lib/completion.js @@ -53,22 +53,20 @@ const cmd = (args, cb) => compl(args).then(() => cb()).catch(cb) // completion for the completion command const completion = async (opts, cb) => { - if (opts.w > 3) { + if (opts.w > 3) return cb() - } const { resolve } = require('path') const [bashExists, zshExists] = await Promise.all([ fileExists(resolve(process.env.HOME, '.bashrc')), - fileExists(resolve(process.env.HOME, '.zshrc')) + fileExists(resolve(process.env.HOME, '.zshrc')), ]) const out = [] - if (zshExists) { + if (zshExists) out.push('~/.zshrc') - } - if (bashExists) { + + if (bashExists) out.push('~/.bashrc') - } cb(null, opts.w === 2 ? out.map(m => ['>>', m]) : out) } @@ -77,7 +75,7 @@ const compl = async args => { if (isWindowsShell) { const msg = 'npm completion supported only in MINGW / Git bash on Windows' throw Object.assign(new Error(msg), { - code: 'ENOTSUP' + code: 'ENOTSUP', }) } @@ -86,9 +84,8 @@ const compl = async args => { // 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 console.error({ COMP_CWORD, COMP_LINE, COMP_POINT }) @@ -108,10 +105,11 @@ const compl = async args => { // figure out where in that last word the point is. const partialWordRaw = args[w] console.error('partial word (args[%i])', w, partialWordRaw, args) + 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) @@ -125,16 +123,16 @@ const compl = async args => { partialLine, partialWords, partialWord, - raw: args + raw: args, } console.error(opts) const wrap = getWrap(opts) if (partialWords.slice(0, -1).indexOf('--') === -1) { - if (word.charAt(0) === '-') { + if (word.charAt(0) === '-') return wrap(configCompl(opts)) - } + if (words[w - 1] && words[w - 1].charAt(0) === '-' && !isFlag(words[w - 1])) { @@ -156,9 +154,8 @@ const compl = async args => { console.error('PARSED', parsed) const cmd = parsed.argv.remain[1] console.error('CMD', cmd) - if (!cmd) { + if (!cmd) return wrap(cmdCompl(opts)) - } Object.keys(parsed).forEach(k => npm.config.set(k, parsed[k])) @@ -184,17 +181,16 @@ const dumpScript = async () => { await new Promise((res, rej) => { let done = false process.stdout.write(d, () => { - if (done) { + if (done) return - } + done = true res() }) process.stdout.on('error', er => { - if (done) { + if (done) return - } done = true @@ -208,11 +204,10 @@ const dumpScript = async () => { // Really, one should not be tossing away EPIPE errors, or any // errors, so casually. But, without this, `. <(npm completion)` // can never ever work on OS X. - if (er.errno === 'EPIPE') { + if (er.errno === 'EPIPE') res() - } else { + else rej(er) - } }) }) } @@ -232,9 +227,8 @@ const escape = w => !/\s+/.test(w) ? w const getWrap = opts => compls => { console.error('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)) @@ -245,9 +239,8 @@ const getWrap = opts => compls => { } console.error(compls, opts.partialWord) - if (compls.length > 0) { + if (compls.length > 0) output(compls.join('\n')) - } } // the current word has a dash. Return the config names, @@ -286,9 +279,9 @@ const cmdCompl = opts => { console.error('CMD COMPL', opts.partialWord) const matches = fullList.filter(c => c.startsWith(opts.partialWord)) console.error('MATCHES', matches) - if (!matches.length) { + if (!matches.length) return matches - } + const derefs = new Set([...matches.map(c => deref(c))]) if (derefs.size === 1) { console.error('ONLY ONE MATCH', derefs) diff --git a/lib/config.js b/lib/config.js index 21f3ab693..ad8db4ff5 100644 --- a/lib/config.js +++ b/lib/config.js @@ -28,15 +28,14 @@ const cmd = (args, cb) => config(args).then(() => cb()).catch(cb) const completion = (opts, cb) => { 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 cb(null, cmds) } @@ -44,9 +43,9 @@ const completion = (opts, cb) => { switch (action) { case 'set': // todo: complete with valid values, if possible. - if (argv.length > 3) { + if (argv.length > 3) return cb(null, []) - } + // fallthrough /* eslint no-fallthrough:0 */ case 'get': @@ -95,18 +94,16 @@ const config = async ([action, key, val]) => { } const set = async (key, val) => { - if (key === undefined) { + if (key === undefined) throw UsageError() - } if (val === undefined) { if (key.indexOf('=') !== -1) { const k = key.split('=') key = k.shift() val = k.join('=') - } else { + } else val = '' - } } key = key.trim() @@ -114,28 +111,25 @@ const set = async (key, val) => { npm.log.info('config', 'set %j %j', key, val) const where = npm.flatOptions.global ? 'global' : 'user' npm.config.set(key, val, where) - if (!npm.config.validate(where)) { + if (!npm.config.validate(where)) npm.log.warn('config', 'omitting invalid config values') - } + await npm.config.save(where) } const get = async key => { - if (!key) { + if (!key) return list() - } - if (!publicVar(key)) { + if (!publicVar(key)) throw `The ${key} option is protected, and cannot be retrieved in this way` - } output(npm.config.get(key)) } const del = async key => { - if (!key) { + if (!key) throw UsageError() - } const where = npm.flatOptions.global ? 'global' : 'user' npm.config.delete(key, where) @@ -144,9 +138,8 @@ const del = async key => { const edit = async () => { const { editor: e, global } = npm.flatOptions - if (!e) { + if (!e) throw new Error('No `editor` config or EDITOR environment variable set') - } const where = global ? 'global' : 'user' const file = npm.config.data.get(where).source @@ -199,13 +192,13 @@ const list = async () => { const msg = [] const { long } = npm.flatOptions for (const [where, { data, source }] of npm.config.data.entries()) { - if (where === 'default' && !long) { + if (where === 'default' && !long) continue - } + const keys = Object.keys(data).sort((a, b) => a.localeCompare(b)) - if (!keys.length) { + if (!keys.length) continue - } + msg.push(`; "${where}" config from ${source}`, '') for (const k of keys) { const v = publicVar(k) ? JSON.stringify(data[k]) : '(protected)' @@ -232,9 +225,9 @@ const list = async () => { const listJson = async () => { const publicConf = {} for (const key in npm.config.list[0]) { - if (!publicVar(key)) { + if (!publicVar(key)) continue - } + publicConf[key] = npm.config.get(key) } output(JSON.stringify(publicConf, null, 2)) diff --git a/lib/dedupe.js b/lib/dedupe.js index eb197ec62..a08c9f3f8 100644 --- a/lib/dedupe.js +++ b/lib/dedupe.js @@ -15,7 +15,7 @@ const dedupe = async (args) => { const arb = new Arborist({ ...npm.flatOptions, path: where, - dryRun + dryRun, }) await arb.dedupe(npm.flatOptions) reifyOutput(arb) diff --git a/lib/deprecate.js b/lib/deprecate.js index d7a9a9481..9f8911ddd 100644 --- a/lib/deprecate.js +++ b/lib/deprecate.js @@ -13,7 +13,8 @@ deprecate.usage = 'npm deprecate <pkg>[@<version>] <message>' deprecate.completion = function (opts, cb) { return Promise.resolve().then(() => { - if (opts.conf.argv.remain.length > 2) { return } + if (opts.conf.argv.remain.length > 2) + return return getItentity(npm.flatOptions).then(username => { if (username) { // first, get a list of remote packages this user owns. @@ -35,7 +36,8 @@ function deprecate ([pkg, msg], opts, cb) { } opts = opts || npm.flatOptions return Promise.resolve().then(() => { - if (msg == null) throw new Error(`Usage: ${deprecate.usage}`) + if (msg == null) + throw new Error(`Usage: ${deprecate.usage}`) // fetch the data and make sure it exists. const p = npa(pkg) @@ -43,26 +45,27 @@ function deprecate ([pkg, msg], opts, cb) { // "*" 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 return fetch.json(uri, { ...opts, spec: p, - query: { write: true } + query: { write: true }, }).then(packument => { // filter all the versions that match Object.keys(packument.versions) .filter(v => semver.satisfies(v, spec)) - .forEach(v => { packument.versions[v].deprecated = msg }) + .forEach(v => { + packument.versions[v].deprecated = msg + }) return otplease(opts, opts => fetch(uri, { ...opts, spec: p, method: 'PUT', body: packument, - ignoreBody: true + ignoreBody: true, })) }) }).then(() => cb(), cb) diff --git a/lib/dist-tag.js b/lib/dist-tag.js index 4d8c77d00..bd7ccc9e0 100644 --- a/lib/dist-tag.js +++ b/lib/dist-tag.js @@ -20,9 +20,8 @@ const usage = usageUtil( const completion = function (opts, cb) { const argv = opts.conf.argv.remain - if (argv.length === 2) { + if (argv.length === 2) return cb(null, ['add', 'rm', 'ls']) - } switch (argv[2]) { default: @@ -36,25 +35,21 @@ const distTag = async ([cmdName, pkg, tag]) => { const opts = npm.flatOptions const has = (items) => new Set(items).has(cmdName) - if (has(['add', 'a', 'set', 's'])) { + if (has(['add', 'a', 'set', 's'])) return add(pkg, tag, opts) - } - if (has(['rm', 'r', 'del', 'd', 'remove'])) { + if (has(['rm', 'r', 'del', 'd', 'remove'])) return remove(pkg, tag, opts) - } - if (has(['ls', 'l', 'sl', 'list'])) { + if (has(['ls', 'l', 'sl', 'list'])) return list(pkg, opts) - } if (!pkg) { // when only using the pkg name the default behavior // should be listing the existing tags return list(cmdName, opts) - } else { + } else throw usage - } } function add (spec, tag, opts) { @@ -64,15 +59,13 @@ function add (spec, tag, opts) { log.verbose('dist-tag add', defaultTag, 'to', spec.name + '@' + version) - if (!spec.name || !version || !defaultTag) { + if (!spec.name || !version || !defaultTag) throw usage - } 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) - } return fetchTags(spec, opts).then(tags => { if (tags[t] === version) { @@ -87,9 +80,9 @@ function add (spec, tag, opts) { method: 'PUT', body: JSON.stringify(version), headers: { - 'content-type': 'application/json' + 'content-type': 'application/json', }, - spec + spec, } return otplease(reqOpts, reqOpts => regFetch(url, reqOpts)).then(() => { output(`+${t}: ${spec.name}@${version}`) @@ -101,9 +94,8 @@ function remove (spec, tag, opts) { spec = npa(spec || '') log.verbose('dist-tag del', tag, 'from', spec.name) - if (!spec.name) { + if (!spec.name) throw usage - } return fetchTags(spec, opts).then(tags => { if (!tags[tag]) { @@ -117,7 +109,7 @@ function remove (spec, tag, opts) { const reqOpts = { ...opts, method: 'DELETE', - spec + spec, } return otplease(reqOpts, reqOpts => regFetch(url, reqOpts)).then(() => { output(`-${tag}: ${spec.name}@${version}`) @@ -128,9 +120,8 @@ function remove (spec, tag, opts) { function list (spec, opts) { if (!spec) { return readLocalPkgName().then(pkg => { - if (!pkg) { + if (!pkg) throw usage - } return list(pkg, opts) }) @@ -154,13 +145,14 @@ function fetchTags (spec, opts) { { ...opts, 'prefer-online': true, - spec + spec, } ).then(data => { - if (data && typeof data === 'object') delete data._etag - if (!data || !Object.keys(data).length) { + if (data && typeof data === 'object') + delete data._etag + if (!data || !Object.keys(data).length) throw new Error('No dist-tags found for ' + spec.name) - } + return data }) } diff --git a/lib/docs.js b/lib/docs.js index e101f8fea..b6a3df7f7 100644 --- a/lib/docs.js +++ b/lib/docs.js @@ -12,21 +12,19 @@ const completion = require('./utils/completion/none.js') const cmd = (args, cb) => docs(args).then(() => cb()).catch(cb) const docs = async args => { - if (!args || !args.length) { + if (!args || !args.length) args = ['.'] - } + await Promise.all(args.map(pkg => getDocs(pkg))) } const 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/doctor.js b/lib/doctor.js index 1e781dc59..a596f1f4b 100644 --- a/lib/doctor.js +++ b/lib/doctor.js @@ -17,11 +17,10 @@ const checkPing = async () => { await ping(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 - } } finally { tracker.finish() } @@ -33,11 +32,10 @@ const getLatestNpmVersion = async () => { tracker.info('getLatestNpmVersion', 'Getting npm package information') try { const latest = (await pacote.manifest('npm@latest', npm.flatOptions)).version - if (semver.gte(npm.version, latest)) { + if (semver.gte(npm.version, latest)) return `current: v${npm.version}, latest: v${latest}` - } else { + else throw `Use npm v${latest}` - } } finally { tracker.finish() } @@ -58,19 +56,17 @@ const getLatestNodejsVersion = async () => { 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() } @@ -81,15 +77,15 @@ const fs = require('fs') 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(', ') } const lstat = promisify(fs.lstat) @@ -97,9 +93,8 @@ const readdir = promisify(fs.readdir) const access = promisify(fs.access) const isWindows = require('./utils/is-windows.js') const checkFilesPermission = async (root, shouldOwn = true, mask = null) => { - if (mask === null) { + if (mask === null) mask = shouldOwn ? R_OK | W_OK : R_OK - } let ok = true @@ -119,18 +114,16 @@ const checkFilesPermission = async (root, shouldOwn = true, mask = null) => { 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) @@ -148,9 +141,8 @@ const checkFilesPermission = async (root, shouldOwn = true, mask = null) => { tracker.warn('checkFilesPermission', 'error reading directory ' + f) return [] }) - for (const entry of entries) { + for (const entry of entries) files.add(resolve(f, entry)) - } } } } finally { @@ -158,9 +150,8 @@ const checkFilesPermission = async (root, shouldOwn = true, mask = null) => { if (!ok) { throw `Check the permissions of files in ${root}` + (shouldOwn ? ' (should be owned by current user)' : '') - } else { + } else return '' - } } } @@ -186,15 +177,15 @@ const verifyCachedFiles = async () => { const stats = await cacache.verify(npm.flatOptions.cache) const { badContentCount, reclaimedCount, missingContent, reclaimedSize } = stats if (badContentCount || reclaimedCount || missingContent) { - if (badContentCount) { + if (badContentCount) tracker.warn('verifyCachedFiles', `Corrupted content removed: ${badContentCount}`) - } - if (reclaimedCount) { + + 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: ${ @@ -208,11 +199,10 @@ const verifyCachedFiles = async () => { const { defaults: { registry: defaultRegistry } } = require('./utils/config.js') const checkNpmRegistry = async () => { - if (npm.flatOptions.registry !== defaultRegistry) { + if (npm.flatOptions.registry !== defaultRegistry) throw `Try \`npm config set registry=${defaultRegistry}\`` - } else { + else return `using default registry (${defaultRegistry})` - } } const cmd = (args, cb) => doctor(args).then(() => cb()).catch(cb) @@ -234,9 +224,9 @@ const doctor = async args => { ['Perms check on local node_modules', checkFilesPermission, [npm.localDir, true]], ['Perms check on global node_modules', checkFilesPermission, [npm.globalDir, false]], ['Perms check on local bin folder', checkFilesPermission, [npm.localBin, false, R_OK | W_OK | X_OK]], - ['Perms check on global bin folder', checkFilesPermission, [npm.globalBin, false, X_OK]] + ['Perms check on global bin folder', checkFilesPermission, [npm.globalBin, false, X_OK]], ]), - ['Verify cache contents', verifyCachedFiles, [npm.flatOptions.cache]] + ['Verify cache contents', verifyCachedFiles, [npm.flatOptions.cache]], // TODO: // - ensure arborist.loadActual() runs without errors and no invalid edges // - ensure package-lock.json matches loadActual() @@ -277,18 +267,16 @@ const doctor = async args => { }) const outTable = [outHead, ...outBody] const tableOpts = { - stringLength: s => ansiTrim(s).length + stringLength: s => ansiTrim(s).length, } if (!silent) { output(table(outTable, tableOpts)) - if (!allOk) { + if (!allOk) console.error('') - } } - if (!allOk) { + if (!allOk) throw 'Some problems found. See above for recommendations.' - } } module.exports = Object.assign(cmd, { completion, usage }) diff --git a/lib/edit.js b/lib/edit.js index 2e8b339e9..43f86dfe7 100644 --- a/lib/edit.js +++ b/lib/edit.js @@ -14,7 +14,8 @@ var noProgressTillDone = require('./utils/no-progress-while-running').tillDone function edit (args, cb) { var p = args[0] - if (args.length !== 1 || !p) return cb(edit.usage) + if (args.length !== 1 || !p) + return cb(edit.usage) var e = npm.config.get('editor') if (!e) { return cb(new Error( @@ -24,25 +25,27 @@ function edit (args, cb) { p = p.split('/') // combine scoped parts .reduce(function (parts, part) { - if (parts.length === 0) { + if (parts.length === 0) return [part] - } + var lastPart = parts[parts.length - 1] // check if previous part is the first part of a scoped package - if (lastPart[0] === '@' && !lastPart.includes('/')) { + if (lastPart[0] === '@' && !lastPart.includes('/')) parts[parts.length - 1] += '/' + part - } else { + else parts.push(part) - } + return parts }, []) .join('/node_modules/') .replace(/(\/node_modules)+/, '/node_modules') var f = path.resolve(npm.dir, p) fs.lstat(f, function (er) { - if (er) return cb(er) + if (er) + return cb(er) editor(f, { editor: e }, noProgressTillDone(function (er) { - if (er) return cb(er) + if (er) + return cb(er) npm.commands.rebuild(args, cb) })) }) diff --git a/lib/exec.js b/lib/exec.js index 01336696b..cda884943 100644 --- a/lib/exec.js +++ b/lib/exec.js @@ -67,9 +67,8 @@ const cmd = (args, cb) => exec(args).then(() => cb()).catch(cb) const exec = async args => { const { package: packages, call } = npm.flatOptions - if (call && args.length) { + if (call && args.length) throw usage - } const pathArr = [...PATH] @@ -97,9 +96,9 @@ const exec = async args => { stdioString: true, event: 'npx', env: { - PATH: pathArr.join(delimiter) + PATH: pathArr.join(delimiter), }, - stdio: 'inherit' + stdio: 'inherit', }) } @@ -122,13 +121,12 @@ const exec = async args => { } catch (er) {} } return await pacote.manifest(p, { - ...npm.flatOptions + ...npm.flatOptions, }) })) - if (needPackageCommandSwap) { + if (needPackageCommandSwap) args[0] = getBinFromManifest(manis[0]) - } // turn list of args into command string const script = call || args.map(escapeArg).join(' ').trim() @@ -136,7 +134,7 @@ const exec = async args => { // figure out whether we need to install stuff, or if local is fine const localArb = new Arborist({ ...npm.flatOptions, - path: npm.localPrefix + path: npm.localPrefix, }) const tree = await localArb.loadActual() @@ -160,22 +158,20 @@ const exec = async args => { const isTTY = process.stdin.isTTY && process.stdout.isTTY if (!npm.flatOptions.yes) { // set -n to always say no - if (npm.flatOptions.yes === false) { + if (npm.flatOptions.yes === false) throw 'canceled' - } - if (!isTTY) { + if (!isTTY) npm.log.warn('exec', `The following package${add.length === 1 ? ' was' : 's were'} not found and will be installed: ${add.map((pkg) => pkg.replace(/@$/, '')).join(', ')}`) - } else { + else { const addList = add.map(a => ` ${a.replace(/@$/, '')}`) .join('\n') + '\n' const prompt = `Need to install the following packages:\n${ addList }Ok to proceed? ` const confirm = await read({ prompt, default: 'y' }) - if (confirm.trim().toLowerCase().charAt(0) !== 'y') { + if (confirm.trim().toLowerCase().charAt(0) !== 'y') throw 'canceled' - } } } await arb.reify({ ...npm.flatOptions, add }) @@ -191,8 +187,8 @@ const exec = async args => { ...realPkg, scripts: { ...(realPkg.scripts || {}), - npx: script - } + npx: script, + }, } npm.log.disableProgress() @@ -205,9 +201,9 @@ const exec = async args => { stdioString: true, event: 'npx', env: { - PATH: pathArr.join(delimiter) + PATH: pathArr.join(delimiter), }, - stdio: 'inherit' + stdio: 'inherit', }) } finally { npm.log.enableProgress() @@ -219,13 +215,13 @@ const manifestMissing = (tree, mani) => { // true means we need to install it const child = tree.children.get(mani.name) // if no child, we have to load it - if (!child) { + if (!child) return true - } + // if no version/tag specified, allow whatever's there - if (mani._from === `${mani.name}@`) { + if (mani._from === `${mani.name}@`) return false - } + // otherwise the version has to match what we WOULD get return child.version !== mani.version } @@ -235,17 +231,17 @@ const getBinFromManifest = mani => { // otherwise if there's 1 bin, use that, // otherwise fail const bins = Object.entries(mani.bin || {}) - if (bins.length === 1) { + if (bins.length === 1) return bins[0][0] - } + // XXX probably a util to parse this better? const name = mani.name.replace(/^@[^/]+\//, '') - if (mani.bin && mani.bin[name]) { + if (mani.bin && mani.bin[name]) return name - } + // XXX need better error message throw Object.assign(new Error('could not determine executable to run'), { - pkgid: mani._id + pkgid: mani._id, }) } diff --git a/lib/explain.js b/lib/explain.js index 46f0d0c98..9176f2e6c 100644 --- a/lib/explain.js +++ b/lib/explain.js @@ -14,30 +14,27 @@ const usage = usageUtil('explain', 'npm explain <folder | specifier>') const cmd = (args, cb) => explain(args).then(() => cb()).catch(cb) const explain = async (args) => { - if (!args.length) { + if (!args.length) throw usage - } const arb = new Arborist({ path: npm.prefix, ...npm.flatOptions }) const tree = await arb.loadActual() const nodes = new Set() for (const arg of args) { - for (const node of getNodes(tree, arg)) { + for (const node of getNodes(tree, arg)) nodes.add(node) - } } - if (nodes.size === 0) { + if (nodes.size === 0) throw `No dependencies found matching ${args.join(', ')}` - } const expls = [] for (const node of nodes) { const { extraneous, dev, optional, devOptional, peer } = node const expl = node.explain() - if (extraneous) { + if (extraneous) expl.extraneous = true - } else { + else { expl.dev = dev expl.optional = optional expl.devOptional = devOptional @@ -46,9 +43,9 @@ const explain = async (args) => { expls.push(expl) } - if (npm.flatOptions.json) { + if (npm.flatOptions.json) output(JSON.stringify(expls, null, 2)) - } else { + else { output(expls.map(expl => { return explainNode(expl, Infinity, npm.color) }).join('\n\n')) @@ -58,24 +55,21 @@ const explain = async (args) => { const 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('name', 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(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 { @@ -87,9 +81,8 @@ const getNodes = (tree, arg) => { const getNodesByVersion = (tree, arg) => { const spec = npa(arg, 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/explore.js b/lib/explore.js index cbc30ba09..96221cb49 100644 --- a/lib/explore.js +++ b/lib/explore.js @@ -21,9 +21,8 @@ const { promisify } = require('util') const stat = promisify(require('fs').stat) const explore = async args => { - if (args.length < 1 || !args[0]) { + if (args.length < 1 || !args[0]) throw usage - } const pkg = args.shift() const cwd = resolve(npm.dir, pkg) @@ -35,9 +34,8 @@ const explore = async args => { const execCmd = escapeExecPath(args.shift()) opts.windowsVerbatimArguments = true shellArgs.push('/d', '/s', '/c', execCmd, ...args.map(escapeArg)) - } else { + } else shellArgs.push('-c', args.map(escapeArg).join(' ').trim()) - } } await stat(cwd).catch(er => { @@ -47,9 +45,8 @@ const explore = async args => { const sh = npm.flatOptions.shell log.disableProgress() - if (!shellArgs.length) { + if (!shellArgs.length) output(`\nExploring ${cwd}\nType 'exit' or ^D when finished\n`) - } log.silly('explore', { sh, shellArgs, opts }) diff --git a/lib/fund.js b/lib/fund.js index d1c58d9b9..41dd48c46 100644 --- a/lib/fund.js +++ b/lib/fund.js @@ -8,7 +8,7 @@ const { depth } = require('treeverse') const { readTree: getFundingInfo, normalizeFunding, - isValidFunding + isValidFunding, } = require('libnpmfund') const npm = require('./npm.js') @@ -52,13 +52,13 @@ function printHuman (fundingInfo, { color, unicode }) { const { url } = fundingSource || {} const pkgRef = getPrintableName({ name, version }) let item = { - label: pkgRef + label: pkgRef, } if (url) { item.label = tree({ label: color ? chalk.bgBlack.white(url) : url, - nodes: [pkgRef] + nodes: [pkgRef], }).trim() // stacks all packages together under the same item @@ -66,9 +66,8 @@ function printHuman (fundingInfo, { color, unicode }) { item = seenUrls.get(url) item.label += `, ${pkgRef}` return null - } else { + } else seenUrls.set(url, item) - } } return item @@ -77,7 +76,8 @@ function printHuman (fundingInfo, { color, unicode }) { // puts child nodes back into returned archy // output while also filtering out missing items leave: (item, children) => { - if (item) { item.nodes = children.filter(Boolean) } + if (item) + item.nodes = children.filter(Boolean) return item }, @@ -88,8 +88,8 @@ function printHuman (fundingInfo, { color, unicode }) { Object.keys(node.dependencies || {}) .map(key => ({ name: key, - ...node.dependencies[key] - })) + ...node.dependencies[key], + })), }) const res = tree(result) @@ -106,9 +106,8 @@ async function openFundingUrl ({ path, tree, spec, fundingSourceNumber }) { } 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 { @@ -118,9 +117,8 @@ async function openFundingUrl ({ path, tree, spec, fundingSourceNumber }) { .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 - } } } @@ -192,7 +190,7 @@ const fund = async (args) => { path: where, tree, spec, - fundingSourceNumber + fundingSourceNumber, }) return } diff --git a/lib/help-search.js b/lib/help-search.js index 6d8cf6006..ae4302e8c 100644 --- a/lib/help-search.js +++ b/lib/help-search.js @@ -18,9 +18,8 @@ const npmUsage = require('./utils/npm-usage.js') const cmd = (args, cb) => helpSearch(args).then(() => cb()).catch(cb) const helpSearch = async args => { - if (!args.length) { + if (!args.length) throw usage - } const docPath = path.resolve(__dirname, '..', 'docs/content') @@ -31,9 +30,9 @@ const helpSearch = async args => { const data = await readFiles(files) const results = await searchFiles(args, data, files) const formatted = formatResults(args, results) - if (!formatted.trim()) { + if (!formatted.trim()) npmUsage(false) - } else { + else { output(formatted) output(didYouMean(args[0], cmdList)) } @@ -53,9 +52,8 @@ const searchFiles = async (args, data, files) => { 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+/) @@ -88,18 +86,17 @@ const searchFiles = async (args, data, files) => { // 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 = {} @@ -124,16 +121,15 @@ const searchFiles = async (args, data, files) => { lines: pruned, found: Object.keys(found), hits: found, - totalHits + totalHits, }) } // if only one result, then just show that help section. if (results.length === 1) { npm.commands.help([results[0].file.replace(/\.md$/, '')], er => { - if (er) { + if (er) throw er - } }) return [] } @@ -151,9 +147,8 @@ const searchFiles = async (args, data, files) => { } const formatResults = (args, results) => { - if (!results) { + if (!results) return 'No results for ' + args.map(JSON.stringify).join(' ') - } const cols = Math.min(process.stdout.columns || Infinity, 80) + 1 @@ -167,17 +162,16 @@ const formatResults = (args, results) => { out.push(' '.repeat((Math.max(1, cols - out.join(' ').length - r.length - 1)))) out.push(r) - if (!npm.flatOptions.long) { + if (!npm.flatOptions.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 (!npm.color) { out.push(line + '\n') return diff --git a/lib/help.js b/lib/help.js index 73c40fd1b..5f9563e1c 100644 --- a/lib/help.js +++ b/lib/help.js @@ -2,7 +2,8 @@ module.exports = help help.completion = function (opts, cb) { - if (opts.conf.argv.remain.length > 2) return cb(null, []) + if (opts.conf.argv.remain.length > 2) + return cb(null, []) getSections(cb) } @@ -23,17 +24,15 @@ function help (args, cb) { var argv = npm.config.parsedArgv.cooked var argnum = 0 - if (args.length === 2 && ~~args[0]) { + if (args.length === 2 && ~~args[0]) argnum = ~~args.shift() - } // npm help foo bar baz: search topics - if (args.length > 1 && args[0]) { + if (args.length > 1 && args[0]) return npm.commands['help-search'](args, cb) - } const affordances = { - 'find-dupes': 'dedupe' + 'find-dupes': 'dedupe', } var section = affordances[args[0]] || npm.deref(args[0]) || args[0] @@ -64,8 +63,10 @@ function help (args, cb) { var manroot = path.resolve(__dirname, '..', 'man') // legacy - if (section === 'global') section = 'folders' - else if (section.match(/.*json/)) section = section.replace('.json', '-json') + if (section === 'global') + section = 'folders' + else if (section.match(/.*json/)) + section = section.replace('.json', '-json') // find either /section.n or /npm-section.n // The glob is used in the glob. The regexp is used much @@ -74,13 +75,16 @@ function help (args, cb) { var compextre = '\\.(gz|bz2|lzma|[FYzZ]|xz)$' var f = '+(npm-' + section + '|' + section + ').[0-9]?(' + compextglob + ')' return glob(manroot + '/*/' + f, function (er, mans) { - if (er) return cb(er) + if (er) + return cb(er) - if (!mans.length) return npm.commands['help-search'](args, cb) + if (!mans.length) + return npm.commands['help-search'](args, cb) mans = mans.map(function (man) { var ext = path.extname(man) - if (man.match(new RegExp(compextre))) man = path.basename(man, ext) + if (man.match(new RegExp(compextre))) + man = path.basename(man, ext) return man }) @@ -162,7 +166,8 @@ function htmlMan (man) { function getSections (cb) { var g = path.resolve(__dirname, '../man/man[0-9]/*.[0-9]') glob(g, function (er, files) { - if (er) return cb(er) + if (er) + return cb(er) cb(null, Object.keys(files.reduce(function (acc, file) { file = path.basename(file).replace(/\.[0-9]+$/, '') diff --git a/lib/hook.js b/lib/hook.js index e2c6d76aa..e0e15243e 100644 --- a/lib/hook.js +++ b/lib/hook.js @@ -10,7 +10,7 @@ const usage = usageUtil('hook', [ 'npm hook add <pkg> <url> <secret> [--type=<type>]', 'npm hook ls [pkg]', 'npm hook rm <id>', - 'npm hook update <id> <url> <secret>' + 'npm hook update <id> <url> <secret>', ].join('\n')) const completion = require('./utils/completion/none.js') @@ -35,9 +35,9 @@ const hook = async (args) => otplease(npm.flatOptions, opts => { const add = (pkg, uri, secret, opts) => { hookApi.add(pkg, uri, secret, opts).then(hook => { - if (opts.json) { + if (opts.json) output(JSON.stringify(hook, null, 2)) - } else if (opts.parseable) { + else if (opts.parseable) { output(Object.keys(hook).join('\t')) output(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!opts.silent && opts.loglevel !== 'silent') { @@ -50,39 +50,38 @@ const add = (pkg, uri, secret, opts) => { const ls = (pkg, opts) => { return hookApi.ls({ ...opts, package: pkg }).then(hooks => { - if (opts.json) { + if (opts.json) output(JSON.stringify(hooks, null, 2)) - } else if (opts.parseable) { + else if (opts.parseable) { output(Object.keys(hooks[0]).join('\t')) hooks.forEach(hook => { output(Object.keys(hook).map(k => hook[k]).join('\t')) }) - } else if (!hooks.length) { + } else if (!hooks.length) 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) output('You have one hook configured.') - } else { + else output(`You have ${hooks.length} hooks configured.`) - } + const table = new Table({ head: ['id', 'target', 'endpoint'] }) hooks.forEach((hook) => { table.push([ { rowSpan: 2, content: hook.id }, hookName(hook), - hook.endpoint + hook.endpoint, ]) if (hook.last_delivery) { table.push([ { colSpan: 1, - content: `triggered ${relativeDate(hook.last_delivery)}` + content: `triggered ${relativeDate(hook.last_delivery)}`, }, - hook.response_code + hook.response_code, ]) - } else { + } else table.push([{ colSpan: 2, content: 'never triggered' }]) - } }) output(table.toString()) } @@ -91,9 +90,9 @@ const ls = (pkg, opts) => { const rm = (id, opts) => { return hookApi.rm(id, opts).then(hook => { - if (opts.json) { + if (opts.json) output(JSON.stringify(hook, null, 2)) - } else if (opts.parseable) { + else if (opts.parseable) { output(Object.keys(hook).join('\t')) output(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!opts.silent && opts.loglevel !== 'silent') { @@ -106,9 +105,9 @@ const rm = (id, opts) => { const update = (id, uri, secret, opts) => { return hookApi.update(id, uri, secret, opts).then(hook => { - if (opts.json) { + if (opts.json) output(JSON.stringify(hook, null, 2)) - } else if (opts.parseable) { + else if (opts.parseable) { output(Object.keys(hook).join('\t')) output(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!opts.silent && opts.loglevel !== 'silent') { @@ -121,8 +120,10 @@ const update = (id, uri, secret, opts) => { const hookName = (hook) => { let target = hook.name - if (hook.type === 'scope') { target = '@' + target } - if (hook.type === 'owner') { target = '~' + target } + if (hook.type === 'scope') + target = '@' + target + if (hook.type === 'owner') + target = '~' + target return target } diff --git a/lib/init.js b/lib/init.js index bec96b44c..e805a2eda 100644 --- a/lib/init.js +++ b/lib/init.js @@ -22,9 +22,9 @@ const init = async args => { if (args.length) { const initerName = args[0] 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 @@ -32,9 +32,8 @@ const init = async args => { .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 + @@ -66,7 +65,7 @@ const init = async args => { 'Use `npm install <pkg>` afterwards to install a package and', 'save it as a dependency in the package.json file.', '', - 'Press ^C at any time to quit.' + 'Press ^C at any time to quit.', ].join('\n')) } // XXX promisify init-package-json @@ -80,11 +79,10 @@ const init = async args => { return res() } npm.log.info('init', 'written successfully') - if (er) { + if (er) rej(er) - } else { + else res(data) - } }) }) } diff --git a/lib/install.js b/lib/install.js index b2ab753bc..5f04fcd4f 100644 --- a/lib/install.js +++ b/lib/install.js @@ -22,24 +22,22 @@ const install = async (args, cb) => { args = args.filter(a => resolve(a) !== 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 (npm.config.get('dev')) { + if (npm.config.get('dev')) log.warn('install', 'Usage of the `--dev` option is deprecated. Use `--include=dev` instead.') - } const arb = new Arborist({ ...npm.flatOptions, - path: where + path: where, }) try { await arb.reify({ ...npm.flatOptions, - add: args + add: args, }) if (!args.length && !isGlobalInstall && !ignoreScripts) { const { scriptShell } = npm.flatOptions @@ -50,7 +48,7 @@ const install = async (args, cb) => { 'prepublish', // XXX should we remove this finally?? 'preprepare', 'prepare', - 'postprepare' + 'postprepare', ] for (const event of scripts) { await runScript({ @@ -59,7 +57,7 @@ const install = async (args, cb) => { scriptShell, stdio: 'inherit', stdioString: true, - event + event, }) } } @@ -107,17 +105,16 @@ const completion = async (opts, cb) => { const annotatePackageDirMatch = async (sibling) => { const fullPath = join(partialPath, sibling) - if (sibling.slice(0, partialName.length) !== partialName) { + if (sibling.slice(0, partialName.length) !== partialName) return null // not name match - } try { const contents = await readdir(fullPath) return { fullPath, - isPackage: contents.indexOf('package.json') !== -1 + isPackage: contents.indexOf('package.json') !== -1, } - } catch { + } catch (er) { return { isPackage: false } } } @@ -137,7 +134,7 @@ const completion = async (opts, cb) => { // no matches return cb(null, []) } - } catch { + } catch (er) { return cb(null, []) // invalid dir: no matching } } diff --git a/lib/link.js b/lib/link.js index 56d50f984..d7303fd08 100644 --- a/lib/link.js +++ b/lib/link.js @@ -67,9 +67,8 @@ const missingArgsFromTree = (tree, args) => { // 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 } @@ -82,14 +81,14 @@ const linkInstall = async args => { ...npm.flatOptions, path: globalTop, global: true, - prune: false + prune: false, } const globalArb = new Arborist(globalOpts) // get only current top-level packages from the global space const globals = await globalArb.loadActual({ filter: (node, kid) => - !node.isRoot || args.some(a => npa(a).name === kid) + !node.isRoot || args.some(a => npa(a).name === kid), }) // any extra arg that is missing from the current @@ -98,7 +97,7 @@ const linkInstall = async args => { if (missing.length) { await globalArb.reify({ ...globalOpts, - add: missing + add: missing, }) } @@ -117,10 +116,10 @@ const linkInstall = async args => { // reify all the pending names as symlinks there const localArb = new Arborist({ ...npm.flatOptions, - path: npm.prefix + path: npm.prefix, }) await localArb.reify({ - add: names.map(l => `file:${resolve(globalTop, 'node_modules', l)}`) + add: names.map(l => `file:${resolve(globalTop, 'node_modules', l)}`), }) reifyOutput(localArb) @@ -131,7 +130,7 @@ const linkPkg = async () => { const arb = new Arborist({ ...npm.flatOptions, path: globalTop, - global: true + global: true, }) await arb.reify({ add: [`file:${npm.prefix}`] }) reifyOutput(arb) diff --git a/lib/logout.js b/lib/logout.js index 861a50a23..32f74831d 100644 --- a/lib/logout.js +++ b/lib/logout.js @@ -27,18 +27,17 @@ const logout = async (args) => { await npmFetch(`/-/user/token/${eu(auth.token)}`, { ...npm.flatOptions, method: 'DELETE', - ignoreBody: true + ignoreBody: true, }) - } else if (auth.username || auth.password) { + } else if (auth.username || auth.password) 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) npm.config.delete(regRef, 'user') - } npm.config.clearCredentialsByURI(reg) @@ -42,7 +42,8 @@ const initTree = async ({ arb, args, json }) => { } const isGitNode = (node) => { - if (!node.resolved) return + if (!node.resolved) + return try { const { type } = npa(node.resolved) @@ -61,17 +62,14 @@ 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 } @@ -103,11 +101,10 @@ 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) { + if (hasNoPackageJson) printable = path - } else { + else printable += `${long ? EOL : ' '}${path}` - } } const highlightDepName = @@ -148,21 +145,19 @@ 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) { item.name = item[_name] @@ -176,19 +171,18 @@ 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 = true - } + 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) } @@ -201,7 +195,7 @@ const filterByEdgesTypes = ({ prod, production, only, - tree + tree, }) => { // filter deps by type, allows for: `npm ls --dev`, `npm ls --prod`, // `npm ls --link`, `npm ls --only=dev`, etc @@ -238,9 +232,8 @@ 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 @@ -259,7 +252,7 @@ const augmentNodesWithMetadata = ({ currentDepth, nodeResult, parseable, - seenNodes + seenNodes, }) => (node) => { // if the original edge was a deduped dep, treeverse will fail to // revisit that node in tree traversal logic, so we make it so that @@ -275,7 +268,7 @@ const augmentNodesWithMetadata = ({ realpath: node.realpath, [_invalid]: node[_invalid], [_missing]: node[_missing], - [_dedupe]: true + [_dedupe]: true, } } else { // keeps track of already seen nodes in order to check for dedupes @@ -308,28 +301,25 @@ 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 = [ ...(result.problems || []), - ...[`error in ${path}: Failed to parse root package.json`] + ...[`error in ${path}: Failed to parse root package.json`], ] result.invalid = true } @@ -342,9 +332,8 @@ 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 } @@ -380,7 +369,7 @@ const ls = async (args) => { global, parseable, prefix, - unicode + unicode, } = npm.flatOptions const path = global ? resolve(npm.globalDir, '..') : prefix const dev = npm.config.get('dev') @@ -394,13 +383,13 @@ const ls = async (args) => { global, ...npm.flatOptions, legacyPeerDeps: false, - path + path, }) const tree = await initTree({ arb, args, global, - json + json, }) const seenItems = new Set() @@ -437,7 +426,7 @@ const ls = async (args) => { prod, production, only, - tree + tree, })) .map(mapEdgesToNodes({ seenPaths })) .concat(appendExtraneousChildren({ node, seenPaths })) @@ -447,7 +436,7 @@ const ls = async (args) => { currentDepth: node[_depth], nodeResult, parseable, - seenNodes + seenNodes, })) }, // visit each `node` of the `tree`, returning an `item` - these are @@ -463,16 +452,15 @@ const ls = async (args) => { // 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) // return a promise so we don't blow the stack return Promise.resolve(item) - } + }, }) // handle the special case of a broken package.json in the root folder @@ -488,9 +476,8 @@ const ls = async (args) => { ) // 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( diff --git a/lib/npm.js b/lib/npm.js index c2a172cf0..d6eab9674 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -21,9 +21,8 @@ const proxyCmds = (npm) => { const cmds = {} return new Proxy(cmds, { get: (prop, cmd) => { - if (hasOwnProperty(cmds, cmd)) { + if (hasOwnProperty(cmds, cmd)) return cmds[cmd] - } const actual = deref(cmd) if (!actual) { @@ -37,7 +36,7 @@ const proxyCmds = (npm) => { cmds[actual] = makeCmd(actual) cmds[cmd] = cmds[actual] return cmds[cmd] - } + }, }) } @@ -62,7 +61,7 @@ const npm = module.exports = new class extends EventEmitter { this.modes = { exec: 0o755, file: 0o644, - umask: 0o22 + umask: 0o22, } this.started = Date.now() this.command = null @@ -74,7 +73,7 @@ const npm = module.exports = new class extends EventEmitter { npmPath: dirname(__dirname), types, defaults, - shorthands + shorthands, }) this.updateNotification = null } @@ -124,17 +123,17 @@ const npm = module.exports = new class extends EventEmitter { // call with parsed CLI options and a callback when done loading // XXX promisify this and stop taking a callback load (cb) { - if (!cb || typeof cb !== 'function') { + if (!cb || typeof cb !== 'function') throw new TypeError('must call as: npm.load(callback)') - } + this.once('load', cb) if (this.loaded || this.loadErr) { this.emit('load', this.loadErr) return } - if (this.loading) { + if (this.loading) return - } + this.loading = true process.emit('time', 'npm:load') @@ -142,12 +141,12 @@ const npm = module.exports = new class extends EventEmitter { return this[_load]().catch(er => er).then((er) => { this.loading = false this.loadErr = er - if (!er && this.config.get('force')) { + if (!er && this.config.get('force')) this.log.warn('using --force', 'Recommended protections disabled.') - } - if (!er && !this[_flatOptions]) { + + if (!er && !this[_flatOptions]) this[_flatOptions] = require('./utils/flat-options.js')(this) - } + process.emit('timeEnd', 'npm:load') this.emit('load', er) }) @@ -178,13 +177,13 @@ const npm = module.exports = new class extends EventEmitter { this.modes = { exec: 0o777 & (~umask), file: 0o666 & (~umask), - umask + umask, } const configScope = this.config.get('scope') - if (configScope && !/^@/.test(configScope)) { + if (configScope && !/^@/.test(configScope)) this.config.set('scope', `@${configScope}`, this.config.find('scope')) - } + this.projectScope = this.config.get('scope') || getProjectScope(this.prefix) @@ -286,6 +285,5 @@ const setupLog = require('./utils/setup-log.js') const cleanUpLogFiles = require('./utils/cleanup-log-files.js') const getProjectScope = require('./utils/get-project-scope.js') -if (require.main === module) { +if (require.main === module) require('./cli.js')(process) -} diff --git a/lib/org.js b/lib/org.js index 0d4463fcd..12e46dd8e 100644 --- a/lib/org.js +++ b/lib/org.js @@ -17,9 +17,9 @@ org.usage = org.completion = function (opts, cb) { var argv = opts.conf.argv.remain - if (argv.length === 2) { + if (argv.length === 2) return cb(null, org.subcommands) - } + switch (argv[2]) { case 'ls': case 'add': @@ -56,40 +56,40 @@ function org ([cmd, orgname, username, role], cb) { function orgSet (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)) { + + 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.') - } + return liborg.set(org, user, role, opts).then(memDeets => { - if (opts.json) { + if (opts.json) output(JSON.stringify(memDeets, null, 2)) - } else if (opts.parseable) { + else if (opts.parseable) { output(['org', 'orgsize', 'user', 'role'].join('\t')) output([ memDeets.org.name, memDeets.org.size, memDeets.user, - memDeets.role + memDeets.role, ]) - } else if (!opts.silent && opts.loglevel !== 'silent') { + } else if (!opts.silent && opts.loglevel !== 'silent') output(`Added ${memDeets.user} as ${memDeets.role} to ${memDeets.org.name}. You now ${memDeets.org.size} member${memDeets.org.size === 1 ? '' : 's'} in this org.`) - } + return memDeets }) } function orgRm (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 => { @@ -101,32 +101,31 @@ function orgRm (org, user, opts) { user, org, userCount, - deleted: true + deleted: true, })) } else if (opts.parseable) { output(['user', 'org', 'userCount', 'deleted'].join('\t')) output([user, org, userCount, true].join('\t')) - } else if (!opts.silent && opts.loglevel !== 'silent') { + } else if (!opts.silent && opts.loglevel !== 'silent') output(`Successfully removed ${user} from ${org}. You now have ${userCount} member${userCount === 1 ? '' : 's'} in this org.`) - } }) } function orgList (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) output(JSON.stringify(roster, null, 2)) - } else if (opts.parseable) { + else if (opts.parseable) { output(['user', 'role'].join('\t')) Object.keys(roster).forEach(user => { output([user, roster[user]].join('\t')) diff --git a/lib/outdated.js b/lib/outdated.js index c3b15e411..06bdc4c2d 100644 --- a/lib/outdated.js +++ b/lib/outdated.js @@ -36,7 +36,7 @@ async function outdated (args) { const arb = new Arborist({ ...opts, - path: where + path: where, }) const tree = await arb.loadActual() @@ -46,35 +46,34 @@ async function outdated (args) { const outdated = list.sort((a, b) => a.name.localeCompare(b.name)) // return if no outdated packages - if (outdated.length === 0 && !opts.json) { + if (outdated.length === 0 && !opts.json) return - } // display results - if (opts.json) { + if (opts.json) output(makeJSON(outdated, opts)) - } else if (opts.parseable) { + else if (opts.parseable) output(makeParseable(outdated, opts)) - } else { + else { const outList = outdated.map(x => makePretty(x, opts)) const outHead = ['Package', 'Current', 'Wanted', 'Latest', 'Location', - 'Depended by' + 'Depended by', ] - if (opts.long) outHead.push('Package Type', 'Homepage') + if (opts.long) + outHead.push('Package Type', 'Homepage') const outTable = [outHead].concat(outList) - if (opts.color) { + if (opts.color) outTable[0] = outTable[0].map(heading => styles.underline(heading)) - } const tableOpts = { align: ['l', 'r', 'r', 'r', 'l'], - stringLength: s => ansiTrim(s).length + stringLength: s => ansiTrim(s).length, } output(table(outTable, tableOpts)) } @@ -86,24 +85,22 @@ async function outdated_ (tree, deps, opts) { const edges = new Set() function getEdges (nodes, type) { const getEdgesIn = (node) => { - for (const edge of node.edgesIn) { + for (const edge of node.edgesIn) edges.add(edge) - } } const getEdgesOut = (node) => { if (opts.global) { - for (const child of node.children.values()) { + for (const child of node.children.values()) edges.add(child) - } } else { - for (const edge of node.edgesOut.values()) { + for (const edge of node.edgesOut.values()) edges.add(edge) - } } } - if (!nodes) return getEdgesOut(tree) + if (!nodes) + return getEdgesOut(tree) for (const node of nodes) { type === 'edgesOut' ? getEdgesOut(node) @@ -114,7 +111,7 @@ async function outdated_ (tree, deps, opts) { async function getPackument (spec) { const packument = await pacote.packument(spec, { fullMetadata: npm.flatOptions.long, - preferOnline: true + preferOnline: true, }) return packument } @@ -131,23 +128,22 @@ async function outdated_ (tree, deps, opts) { : 'dependencies' for (const omitType of opts.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') return + if (edge.error === 'MISSING' && type !== 'dependencies') + return try { const packument = await 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 } @@ -168,7 +164,7 @@ async function outdated_ (tree, deps, opts) { wanted: wanted.version, latest: latest.version, dependent: edge.from ? edge.from.name : 'global', - homepage: packument.homepage + homepage: packument.homepage, }) } } catch (err) { @@ -178,9 +174,8 @@ async function outdated_ (tree, deps, opts) { err.code === 'ETARGET' || err.code === 'E403' || err.code === 'E404') - ) { + ) throw err - } } } @@ -201,9 +196,8 @@ async function outdated_ (tree, deps, opts) { getEdges() } - for (const edge of edges) { + for (const edge of edges) p.push(getOutdatedInfo(edge)) - } await Promise.all(p) return list @@ -219,7 +213,7 @@ function makePretty (dep, opts) { wanted, latest, type, - dependent + dependent, } = dep const columns = [name, current, wanted, latest, location, dependent] @@ -248,9 +242,10 @@ function makeParseable (list, opts) { name + '@' + wanted, current ? (name + '@' + current) : 'MISSING', name + '@' + latest, - dependent + dependent, ] - if (opts.long) out.push(type, homepage) + if (opts.long) + out.push(type, homepage) return out.join(':') }).join(os.EOL) @@ -265,7 +260,7 @@ function makeJSON (list, opts) { wanted, latest, dependent, - location: path + location: path, } if (opts.long) { out[name].type = type diff --git a/lib/owner.js b/lib/owner.js index 536c4c54c..dcc1ff630 100644 --- a/lib/owner.js +++ b/lib/owner.js @@ -20,12 +20,12 @@ const usage = usageUtil( const completion = function (opts, cb) { const argv = opts.conf.argv.remain - if (argv.length > 3) { + if (argv.length > 3) return cb(null, []) - } - if (argv[1] !== 'owner') { + + if (argv[1] !== 'owner') argv.unshift('owner') - } + if (argv.length === 2) { var subs = ['add', 'rm', 'ls'] return cb(null, subs) @@ -35,28 +35,27 @@ const completion = function (opts, cb) { if (argv[2] === 'rm') { const opts = { ...npm.flatOptions, - fullMetadata: true + fullMetadata: true, } readLocalPkg() .then(pkgName => { - if (!pkgName) { + if (!pkgName) return null - } + const spec = npa(pkgName) return pacote.packument(spec, opts) }) .then(data => { - if (data && data.maintainers && data.maintainers.length) { + if (data && data.maintainers && data.maintainers.length) return data.maintainers.map(m => m.name) - } + return [] }) .then(owners => { return cb(null, owners) }) - } else { + } else cb(null, []) - } } const UsageError = () => @@ -83,9 +82,9 @@ const owner = async ([action, ...args]) => { const ls = async (pkg, opts) => { if (!pkg) { const pkgName = await readLocalPkg() - if (!pkgName) { + if (!pkgName) throw UsageError() - } + pkg = pkgName } @@ -94,11 +93,11 @@ const ls = async (pkg, opts) => { try { const packumentOpts = { ...opts, fullMetadata: true } const { maintainers } = await pacote.packument(spec, packumentOpts) - if (!maintainers || !maintainers.length) { + if (!maintainers || !maintainers.length) output('no admin found') - } else { + else output(maintainers.map(o => `${o.name} <${o.email}>`).join('\n')) - } + return maintainers } catch (err) { log.error('owner ls', "Couldn't get owner data", pkg) @@ -119,19 +118,19 @@ const validateAddOwner = (newOwner, owners) => { } return [ ...owners, - newOwner + newOwner, ] } const add = async (user, pkg, opts) => { - if (!user) { + if (!user) throw UsageError() - } + if (!pkg) { const pkgName = await readLocalPkg() - if (!pkgName) { + if (!pkgName) throw UsageError() - } + pkg = pkgName } log.verbose('owner add', '%s to %s', user, pkg) @@ -166,14 +165,14 @@ const validateRmOwner = (rmOwner, owners) => { } const rm = async (user, pkg, opts) => { - if (!user) { + if (!user) throw UsageError() - } + if (!pkg) { const pkgName = await readLocalPkg() - if (!pkgName) { + if (!pkgName) throw UsageError() - } + pkg = pkgName } log.verbose('owner rm', '%s from %s', user, pkg) @@ -211,12 +210,13 @@ const putOwners = async (spec, user, opts, validation) => { 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, _rev: data._rev, - maintainers: m + maintainers: m, } const dataPath = `/${spec.escapedName}/-rev/${encodeURIComponent(data._rev)}` const res = await otplease(opts, opts => @@ -224,15 +224,14 @@ const putOwners = async (spec, user, opts, validation) => { ...opts, method: 'PUT', body, - spec + spec, })) if (!res.error) { - if (m.length < before) { + if (m.length < before) output(`- ${user} (${spec.name})`) - } else { + else output(`+ ${user} (${spec.name})`) - } } else { throw Object.assign( new Error('Failed to update package: ' + JSON.stringify(res)), diff --git a/lib/pack.js b/lib/pack.js index 20e518484..7a5c2edab 100644 --- a/lib/pack.js +++ b/lib/pack.js @@ -17,7 +17,8 @@ const usage = usageUtil('pack', 'npm pack [[<@scope>/]<pkg>...] [--dry-run]') const cmd = (args, cb) => pack(args).then(() => cb()).catch(cb) const pack = async (args) => { - if (args.length === 0) args = ['.'] + if (args.length === 0) + args = ['.'] const { unicode } = npm.flatOptions @@ -40,9 +41,8 @@ const pack_ = async (arg, opts) => { const tarballData = await libpack(arg, opts) const pkgContents = await getContents(manifest, tarballData) - if (!dryRun) { + if (!dryRun) await writeFile(filename, tarballData) - } return pkgContents } diff --git a/lib/ping.js b/lib/ping.js index 71e5a1970..7762be6d2 100644 --- a/lib/ping.js +++ b/lib/ping.js @@ -19,11 +19,10 @@ const ping = async args => { output(JSON.stringify({ registry: npm.flatOptions.registry, time, - details + 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 = Object.assign(cmd, { completion, usage }) diff --git a/lib/profile.js b/lib/profile.js index a9e032594..cdecef3af 100644 --- a/lib/profile.js +++ b/lib/profile.js @@ -28,11 +28,11 @@ profileCmd.completion = function (opts, cb) { switch (argv[2]) { case 'enable-2fa': case 'enable-tfa': - if (argv.length === 3) { + if (argv.length === 3) return cb(null, ['auth-and-writes', 'auth-only']) - } else { + else return cb(null, []) - } + case 'disable-2fa': case 'disable-tfa': case 'get': @@ -48,7 +48,8 @@ function withCb (prom, cb) { } function profileCmd (args, cb) { - if (args.length === 0) return cb(new Error(profileCmd.usage)) + if (args.length === 0) + return cb(new Error(profileCmd.usage)) log.gauge.show('profile') switch (args[0]) { case 'enable-2fa': @@ -84,29 +85,34 @@ const knownProfileKeys = [ 'twitter', 'github', 'created', - 'updated' + 'updated', ] function get (args) { const tfa = 'two-factor auth' const conf = npm.flatOptions return pulseTillDone.withPromise(profile.get(conf)).then((info) => { - if (!info.cidr_whitelist) delete info.cidr_whitelist + if (!info.cidr_whitelist) + delete info.cidr_whitelist if (conf.json) { output(JSON.stringify(info, null, 2)) return } const cleaned = {} - knownProfileKeys.forEach((k) => { cleaned[k] = info[k] || '' }) - Object.keys(info).filter((k) => !(k in cleaned)).forEach((k) => { cleaned[k] = info[k] || '' }) + knownProfileKeys.forEach((k) => { + cleaned[k] = info[k] || '' + }) + Object.keys(info).filter((k) => !(k in cleaned)).forEach((k) => { + cleaned[k] = info[k] || '' + }) 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 ↓ .join(',').split(/,/).map((arg) => arg.trim()).filter((arg) => arg !== '') @@ -116,11 +122,10 @@ function get (args) { } else { if (conf.parseable) { Object.keys(info).forEach((key) => { - if (key === 'tfa') { + if (key === 'tfa') output(`${key}\t${cleaned[tfa]}`) - } else { + else output(`${key}\t${info[key]}`) - } }) } else { const table = new Table() @@ -138,24 +143,24 @@ const writableProfileKeys = [ 'homepage', 'freenode', 'twitter', - 'github' + 'github', ] function set (args) { const conf = npm.flatOptions const prop = (args[0] || '').toLowerCase().trim() let value = args.length > 1 ? args.slice(1).join(' ') : null - if (prop !== 'password' && value === null) { + if (prop !== 'password' && value === null) return Promise.reject(Error('npm profile set <prop> <value>')) - } + if (prop === 'password' && value !== null) { return Promise.reject(Error( 'npm profile set password\n' + 'Do not include your current or new passwords on the command line.')) } - if (writableProfileKeys.indexOf(prop) === -1) { + if (writableProfileKeys.indexOf(prop) === -1) return Promise.reject(Error(`"${prop}" is not a property we can set. Valid properties are: ` + writableProfileKeys.join(', '))) - } + return Promise.resolve().then(() => { if (prop === 'password') { return readUserInfo.password('Current password: ').then((current) => { @@ -183,28 +188,29 @@ function set (args) { // FIXME: Work around to not clear everything other than what we're setting return pulseTillDone.withPromise(profile.get(conf).then((user) => { const newUser = {} - writableProfileKeys.forEach((k) => { newUser[k] = user[k] }) + writableProfileKeys.forEach((k) => { + newUser[k] = user[k] + }) newUser[prop] = value return otplease(conf, conf => profile.set(newUser, conf)) .then((result) => { - if (conf.json) { + if (conf.json) output(JSON.stringify({ [prop]: result[prop] }, null, 2)) - } else if (conf.parseable) { + else if (conf.parseable) output(prop + '\t' + result[prop]) - } else if (result[prop] != null) { + else if (result[prop] != null) output('Set', prop, 'to', result[prop]) - } else { + else output('Set', prop) - } }) })) }) } function enable2fa (args) { - if (args.length > 1) { + if (args.length > 1) return Promise.reject(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') { return Promise.reject(new Error(`Invalid two-factor authentication mode "${mode}".\n` + @@ -221,8 +227,8 @@ function enable2fa (args) { const info = { tfa: { - mode: mode - } + mode: mode, + }, } return Promise.resolve().then(() => { @@ -234,7 +240,11 @@ function enable2fa (args) { return profile.createToken( auth.basic.password, false, [], conf ).then((result) => { - if (!result.token) throw new Error('Your registry ' + conf.registry + 'does not seem to support bearer tokens. Bearer tokens are required for two-factor authentication') + if (!result.token) { + throw new Error(`Your registry ${conf.registry} does not seem to ` + + 'support bearer tokens. Bearer tokens are required for ' + + 'two-factor authentication') + } npm.config.setCredentialsByURI(conf.registry, { token: result.token }) return npm.config.save('user') }) @@ -246,12 +256,14 @@ function enable2fa (args) { info.tfa.password = password log.info('profile', 'Determine if tfa is pending') return pulseTillDone.withPromise(profile.get(conf)).then((info) => { - if (!info.tfa) return + if (!info.tfa) + return if (info.tfa.pending) { log.info('profile', 'Resetting two-factor authentication') return pulseTillDone.withPromise(profile.set({ tfa: { password, mode: 'disable' } }, conf)) } else { - if (conf.auth.otp) return + if (conf.auth.otp) + return return readUserInfo.otp('Enter one-time password from your authenticator app: ').then((otp) => { conf.auth.otp = otp }) @@ -265,9 +277,9 @@ function enable2fa (args) { output('Two factor authentication mode changed to: ' + mode) return } - if (typeof challenge.tfa !== 'string' || !/^otpauth:[/][/]/.test(challenge.tfa)) { + if (typeof challenge.tfa !== 'string' || !/^otpauth:[/][/]/.test(challenge.tfa)) throw new Error('Unknown error enabling two-factor authentication. Expected otpauth URL, got: ' + inspect(challenge.tfa)) - } + const otpauth = new URL(challenge.tfa) const secret = otpauth.searchParams.get('secret') return qrcode(challenge.tfa).then((code) => { @@ -288,18 +300,18 @@ function enable2fa (args) { function getAuth (conf) { const creds = npm.config.getCredentialsByURI(conf.registry) let 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] } } - } else { + } else auth = {} - } - if (conf.otp) auth.otp = conf.otp + if (conf.otp) + auth.otp = conf.otp return auth } @@ -312,20 +324,20 @@ function disable2fa (args) { } return readUserInfo.password().then((password) => { return Promise.resolve().then(() => { - if (conf.otp) return + if (conf.otp) + return return readUserInfo.otp('Enter one-time password from your authenticator: ').then((otp) => { conf = { ...conf, otp } }) }).then(() => { log.info('profile', 'disabling tfa') return pulseTillDone.withPromise(profile.set({ tfa: { password: password, mode: 'disable' } }, conf)).then(() => { - if (conf.json) { + if (conf.json) output(JSON.stringify({ tfa: false }, null, 2)) - } else if (conf.parseable) { + else if (conf.parseable) output('tfa\tfalse') - } else { + else output('Two factor authentication disabled.') - } }) }) }) diff --git a/lib/prune.js b/lib/prune.js index 66f9d8ba2..aa2ed3780 100644 --- a/lib/prune.js +++ b/lib/prune.js @@ -16,7 +16,7 @@ const prune = async () => { const where = npm.prefix const arb = new Arborist({ ...npm.flatOptions, - path: where + path: where, }) await arb.prune(npm.flatOptions) reifyOutput(arb) diff --git a/lib/publish.js b/lib/publish.js index 1ff736625..0ad5204c9 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -24,24 +24,24 @@ const usage = usageUtil('publish', const cmd = (args, cb) => publish(args).then(() => cb()).catch(cb) const publish = async args => { - if (args.length === 0) args = ['.'] - if (args.length !== 1) throw usage + if (args.length === 0) + args = ['.'] + if (args.length !== 1) + throw usage log.verbose('publish', args) const opts = { ...npm.flatOptions } const { json, defaultTag } = opts - if (semver.validRange(defaultTag)) { + if (semver.validRange(defaultTag)) throw new Error('Tag name must not be a valid SemVer range: ' + defaultTag.trim()) - } const tarball = await publish_(args[0], opts) const silent = log.level === 'silent' - if (!silent && json) { + if (!silent && json) output(JSON.stringify(tarball, null, 2)) - } else if (!silent) { + else if (!silent) output(`+ ${tarball.id}`) - } return tarball } @@ -55,15 +55,14 @@ const publish_ = async (arg, opts) => { event: 'prepublishOnly', path: arg, stdio: 'inherit', - pkg: manifest + pkg: manifest, }) const tarballData = await pack(arg) const pkgContents = await getContents(manifest, tarballData) - if (!json) { + if (!json) logTar(pkgContents, { log, unicode }) - } if (!dryRun) { // The purpose of re-reading the manifest is in case it changed, @@ -78,7 +77,7 @@ const publish_ = async (arg, opts) => { event: 'publish', path: arg, stdio: 'inherit', - pkg: manifest + pkg: manifest, }) // postpublish @@ -86,7 +85,7 @@ const publish_ = async (arg, opts) => { event: 'postpublish', path: arg, stdio: 'inherit', - pkg: manifest + pkg: manifest, }) return pkgContents diff --git a/lib/rebuild.js b/lib/rebuild.js index a2beecc50..076cfc699 100644 --- a/lib/rebuild.js +++ b/lib/rebuild.js @@ -17,7 +17,7 @@ const rebuild = async args => { const where = npm.flatOptions.global ? globalTop : npm.prefix const arb = new Arborist({ ...npm.flatOptions, - path: where + path: where, }) if (args.length) { @@ -25,11 +25,10 @@ const rebuild = async args => { const tree = await arb.loadActual() const filter = getFilterFn(args) await arb.rebuild({ - nodes: tree.inventory.filter(filter) + nodes: tree.inventory.filter(filter), }) - } else { + } else await arb.rebuild() - } output('rebuilt dependencies successfully') } @@ -37,14 +36,18 @@ const rebuild = async args => { const getFilterFn = args => { const specs = args.map(arg => { const spec = npa(arg) - if (spec.type === 'tag' && spec.rawSpec === '') { return spec } - if (spec.type !== 'range' && spec.type !== 'version') { throw new Error('`npm rebuild` only supports SemVer version/range specifiers') } + if (spec.type === 'tag' && spec.rawSpec === '') + return spec + if (spec.type !== 'range' && spec.type !== 'version') + throw new Error('`npm rebuild` only supports SemVer version/range specifiers') return spec }) return node => specs.some(spec => { const { version } = node.package - if (spec.name !== node.name) { return false } - if (spec.rawSpec === '' || spec.rawSpec === '*') { return true } + if (spec.name !== node.name) + return false + if (spec.rawSpec === '' || spec.rawSpec === '*') + return true return semver.satisfies(version, spec.fetchSpec) }) } diff --git a/lib/repo.js b/lib/repo.js index ed0253859..7bd3bd154 100644 --- a/lib/repo.js +++ b/lib/repo.js @@ -13,9 +13,9 @@ const completion = require('./utils/completion/none.js') const cmd = (args, cb) => repo(args).then(() => cb()).catch(cb) const repo = async args => { - if (!args || !args.length) { + if (!args || !args.length) args = ['.'] - } + await Promise.all(args.map(pkg => getRepo(pkg))) } @@ -31,7 +31,7 @@ const getRepo = async pkg => { if (!rurl) { throw Object.assign(new Error('no repository'), { - pkgid: pkg + pkgid: pkg, }) } @@ -40,7 +40,7 @@ const getRepo = async pkg => { if (!url) { throw Object.assign(new Error('no repository: could not get url'), { - pkgid: pkg + pkgid: pkg, }) } @@ -53,13 +53,12 @@ const unknownHostedUrl = url => { const { protocol, hostname, - pathname + pathname, } = 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/run-script.js b/lib/run-script.js index 989936f25..2802c54ba 100644 --- a/lib/run-script.js +++ b/lib/run-script.js @@ -38,17 +38,17 @@ const runScript = async (args) => { const pkg = await readJson(`${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') { + else if (event === 'env') scripts.env = isWindowsShell ? 'SET' : 'env' - } + pkg.scripts = scripts if (!scripts[event]) { - if (npm.config.get('if-present')) { + if (npm.config.get('if-present')) return - } + const suggestions = didYouMean(event, Object.keys(scripts)) throw new Error(`missing script: ${event}${ suggestions ? `\n${suggestions}` : ''}`) @@ -57,12 +57,11 @@ const runScript = async (args) => { // positional args only added to the main event, not pre/post const events = [[event, args]] if (!npm.flatOptions.ignoreScripts) { - 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 = { @@ -71,14 +70,14 @@ const runScript = async (args) => { scriptShell, stdio: 'inherit', stdioString: true, - pkg + pkg, } for (const [event, args] of events) { await run({ ...opts, event, - args + args, }) } } @@ -94,17 +93,15 @@ const list = async () => { 'stop', 'start', 'restart', - 'version' + 'version', ].reduce((l, p) => l.concat(['pre' + p, p, 'post' + p]), []) - if (!scripts) { + if (!scripts) return [] - } const allScripts = Object.keys(scripts) - if (log.level === 'silent') { + if (log.level === 'silent') return allScripts - } if (npm.flatOptions.json) { output(JSON.stringify(scripts, null, 2)) @@ -112,9 +109,9 @@ const list = async () => { } if (npm.flatOptions.parseable) { - for (const [script, cmd] of Object.entries(scripts)) { + for (const [script, cmd] of Object.entries(scripts)) output(`${script}:${cmd}`) - } + return allScripts } @@ -127,20 +124,20 @@ const list = async () => { list.push(script) } - if (cmds.length) { + if (cmds.length) output(`Lifecycle scripts included in ${name}:`) - } - for (const script of cmds) { + + for (const script of cmds) output(prefix + script + indent + scripts[script]) - } - if (!cmds.length && runScripts.length) { + + if (!cmds.length && runScripts.length) output(`Scripts available in ${name} via \`npm run-script\`:`) - } else if (runScripts.length) { + else if (runScripts.length) output('\navailable via `npm run-script`:') - } - for (const script of runScripts) { + + for (const script of runScripts) output(prefix + script + indent + scripts[script]) - } + return allScripts } diff --git a/lib/search.js b/lib/search.js index 92397d842..5c25bd715 100644 --- a/lib/search.js +++ b/lib/search.js @@ -26,12 +26,11 @@ function search (args, cb) { ...npm.flatOptions, ...npm.flatOptions.search, include: prepareIncludes(args, npm.flatOptions.search.opts), - exclude: prepareExcludes(npm.flatOptions.search.exclude) + exclude: prepareExcludes(npm.flatOptions.search.exclude), } - if (opts.include.length === 0) { + if (opts.include.length === 0) return cb(new Error('search must be called with arguments')) - } // Used later to figure out whether we had any packages go out let anyOutput = false @@ -42,21 +41,22 @@ function search (args, cb) { // This is a text minipass stream var outputStream = formatPackageStream({ args, // --searchinclude options are not highlighted - ...opts + ...opts, }) log.silly('search', 'searching packages') const p = new Pipeline(libSearch.stream(opts.include, opts), outputStream) p.on('data', chunk => { - if (!anyOutput) { anyOutput = true } + if (!anyOutput) + anyOutput = true output(chunk.toString('utf8')) }) p.promise().then(() => { - if (!anyOutput && !opts.json && !opts.parseable) { + if (!anyOutput && !opts.json && !opts.parseable) output('No matches found for ' + (args.map(JSON.stringify).join(' '))) - } + log.silly('search', 'search completed') log.clearProgress() cb(null, {}) @@ -64,19 +64,22 @@ function search (args, cb) { } function prepareIncludes (args, searchopts) { - if (typeof searchopts !== 'string') searchopts = '' + if (typeof searchopts !== 'string') + searchopts = '' return searchopts.split(/\s+/).concat(args).map(function (s) { return s.toLowerCase() - }).filter(function (s) { return s }) + }).filter(function (s) { + return s + }) } function prepareExcludes (searchexclude) { var exclude - if (typeof searchexclude === 'string') { + if (typeof searchexclude === 'string') exclude = searchexclude.split(/\s+/) - } else { + else exclude = [] - } + return exclude.map(function (s) { return s.toLowerCase() }) diff --git a/lib/search/format-package-stream.js b/lib/search/format-package-stream.js index 7a9f61613..0f75bbff7 100644 --- a/lib/search/format-package-stream.js +++ b/lib/search/format-package-stream.js @@ -33,9 +33,9 @@ class JSONOutputStream extends Minipass { if (!this._didFirst) { super.write('[\n') this._didFirst = true - } else { + } else super.write('\n,\n') - } + try { return super.write(JSON.stringify(obj)) } catch (er) { @@ -89,14 +89,14 @@ function prettify (data, num, opts) { author: { minWidth: 15, maxWidth: 15 }, date: { maxWidth: 11 }, version: { minWidth: 8, maxWidth: 8 }, - keywords: { maxWidth: Infinity } - } + keywords: { maxWidth: Infinity }, + }, } ) output = trimToMaxWidth(output) - if (opts.color) { + if (opts.color) output = highlightSearchTerms(output, opts.args) - } + return output } @@ -111,7 +111,7 @@ function addColorMarker (str, arg, i) { if (arg.charAt(0) === '/') { return str.replace( new RegExp(arg.substr(1, arg.length - 2), 'gi'), - function (bit) { return markStart + bit + markEnd } + bit => markStart + bit + markEnd ) } @@ -146,7 +146,9 @@ function getMaxWidth () { var stdout = process.stdout cols = !tty.isatty(stdout.fd) ? Infinity : process.stdout.getWindowSize()[0] cols = (cols === 0) ? Infinity : cols - } catch (ex) { cols = Infinity } + } catch (ex) { + cols = Infinity + } return cols } @@ -184,6 +186,6 @@ function normalizePackage (data, opts) { .split('T').join(' ') .replace(/:[0-9]{2}\.[0-9]{3}Z$/, '')) .slice(0, -5)) || - 'prehistoric' + 'prehistoric', } } diff --git a/lib/search/package-filter.js b/lib/search/package-filter.js index 142350eec..e3d427a4a 100644 --- a/lib/search/package-filter.js +++ b/lib/search/package-filter.js @@ -9,13 +9,11 @@ function filter (data, include, exclude, opts) { function getWords (data, opts) { return [data.name] .concat((opts && opts.description) ? data.description : []) - .concat((data.maintainers || []).map(function (m) { - return '=' + m.name - })) + .concat((data.maintainers || []).map(m => `=${m.name}`)) .concat(data.versions && data.versions.length && data.url && ('<' + data.url + '>')) .concat(data.keywords || []) - .map(function (f) { return f && f.trim && f.trim() }) - .filter(function (f) { return f }) + .map(f => f && f.trim && f.trim()) + .filter(f => f) .join(' ') .toLowerCase() } @@ -23,11 +21,15 @@ function getWords (data, opts) { function filterWords (data, include, exclude, opts) { var words = getWords(data, opts) for (var i = 0, l = include.length; i < l; i++) { - if (!match(words, include[i])) return false + if (!match(words, include[i])) + return false } + for (i = 0, l = exclude.length; i < l; i++) { - if (match(words, exclude[i])) return false + if (match(words, exclude[i])) + return false } + return true } diff --git a/lib/set.js b/lib/set.js index b5e7376fb..62860e53f 100644 --- a/lib/set.js +++ b/lib/set.js @@ -8,6 +8,7 @@ var npm = require('./npm.js') set.completion = npm.commands.config.completion function set (args, cb) { - if (!args.length) return cb(set.usage) + if (!args.length) + return cb(set.usage) npm.commands.config(['set'].concat(args), cb) } diff --git a/lib/shrinkwrap.js b/lib/shrinkwrap.js index ec759578c..0dff6b2ba 100644 --- a/lib/shrinkwrap.js +++ b/lib/shrinkwrap.js @@ -37,16 +37,15 @@ const shrinkwrap = async () => { meta.filename = sw await meta.save() - if (newFile) { + if (newFile) log.notice('', 'created a lockfile as npm-shrinkwrap.json') - } else if (notSW) { + else if (notSW) { await unlink(oldFilename) log.notice('', 'package-lock.json has been renamed to npm-shrinkwrap.json') - } else if (meta.originalLockfileVersion !== npm.lockfileVersion) { + } else if (meta.originalLockfileVersion !== npm.lockfileVersion) log.notice('', `npm-shrinkwrap.json updated to version ${npm.lockfileVersion}`) - } else { + else log.notice('', 'npm-shrinkwrap.json up to date') - } } module.exports = Object.assign(cmd, { usage, completion }) diff --git a/lib/star.js b/lib/star.js index 04b8285fb..15beef373 100644 --- a/lib/star.js +++ b/lib/star.js @@ -24,7 +24,8 @@ module.exports = star function star (args, cb) { const opts = npm.flatOptions return Promise.resolve().then(() => { - if (!args.length) throw new Error(star.usage) + if (!args.length) + throw new Error(star.usage) // if we're unstarring, then show an empty star image // otherwise, show the full star image const unstar = /^un/.test(npm.command) @@ -38,14 +39,15 @@ function star (args, cb) { ...opts, spec: pkg, query: { write: true }, - preferOnline: true - }) + preferOnline: true, + }), ]).then(([username, fullData]) => { - if (!username) { throw new Error('You need to be logged in!') } + if (!username) + throw new Error('You need to be logged in!') const body = { _id: fullData._id, _rev: fullData._rev, - users: fullData.users || {} + users: fullData.users || {}, } if (!unstar) { @@ -61,7 +63,7 @@ function star (args, cb) { ...opts, spec: pkg, method: 'PUT', - body + body, }) }).then(data => { output(show + ' ' + pkg.name) diff --git a/lib/stars.js b/lib/stars.js index 391e3ec86..bd443d09a 100644 --- a/lib/stars.js +++ b/lib/stars.js @@ -13,9 +13,9 @@ const cmd = (args, cb) => stars(args).then(() => cb()).catch(cb) const stars = (args) => { return stars_(args).catch(er => { - if (er.code === 'ENEEDAUTH') { + if (er.code === 'ENEEDAUTH') log.warn('star', 'auth is required to look up your username') - } + throw er }) } @@ -23,14 +23,13 @@ const stars = (args) => { const stars_ = async ([user = getIdentity(npm.flatOptions)]) => { const { rows } = await fetch.json('/-/_view/starredByUser', { ...npm.flatOptions, - query: { key: `"${await user}"` } + query: { key: `"${await 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) output(row.value) - } } module.exports = Object.assign(cmd, { usage, completion }) diff --git a/lib/team.js b/lib/team.js index b0e15e349..582dadb3f 100644 --- a/lib/team.js +++ b/lib/team.js @@ -19,9 +19,9 @@ const usage = usageUtil( const completion = (opts, cb) => { const { conf: { argv: { remain: argv } } } = opts - if (argv.length === 2) { + if (argv.length === 2) return cb(null, subcommands) - } + switch (argv[2]) { case 'ls': case 'create': @@ -51,11 +51,10 @@ const team = async ([cmd, entity = '', user = '']) => { case 'rm': return teamRm(entity, user, opts) case 'ls': { const match = entity.match(/[^:]+:.+/) - if (match) { + if (match) return teamListUsers(entity, opts) - } else { + else return teamListTeams(entity, opts) - } } case 'edit': throw new Error('`npm team edit` is not implemented yet.') @@ -70,13 +69,12 @@ const teamCreate = async (entity, opts) => { if (opts.json) { output(JSON.stringify({ created: true, - team: entity + team: entity, })) - } else if (opts.parseable) { + } else if (opts.parseable) output(`${entity}\tcreated`) - } else if (!opts.silent && opts.loglevel !== 'silent') { + else if (!opts.silent && opts.loglevel !== 'silent') output(`+@${entity}`) - } } const teamDestroy = async (entity, opts) => { @@ -84,13 +82,12 @@ const teamDestroy = async (entity, opts) => { if (opts.json) { output(JSON.stringify({ deleted: true, - team: entity + team: entity, })) - } else if (opts.parseable) { + } else if (opts.parseable) output(`${entity}\tdeleted`) - } else if (!opts.silent && opts.loglevel !== 'silent') { + else if (!opts.silent && opts.loglevel !== 'silent') output(`-@${entity}`) - } } const teamAdd = async (entity, user, opts) => { @@ -99,13 +96,12 @@ const teamAdd = async (entity, user, opts) => { output(JSON.stringify({ added: true, team: entity, - user + user, })) - } else if (opts.parseable) { + } else if (opts.parseable) output(`${user}\t${entity}\tadded`) - } else if (!opts.silent && opts.loglevel !== 'silent') { + else if (!opts.silent && opts.loglevel !== 'silent') output(`${user} added to @${entity}`) - } } const teamRm = async (entity, user, opts) => { @@ -114,22 +110,21 @@ const teamRm = async (entity, user, opts) => { output(JSON.stringify({ removed: true, team: entity, - user + user, })) - } else if (opts.parseable) { + } else if (opts.parseable) output(`${user}\t${entity}\tremoved`) - } else if (!opts.silent && opts.loglevel !== 'silent') { + else if (!opts.silent && opts.loglevel !== 'silent') output(`${user} removed from @${entity}`) - } } const teamListUsers = async (entity, opts) => { const users = (await libteam.lsUsers(entity, opts)).sort() - if (opts.json) { + if (opts.json) output(JSON.stringify(users, null, 2)) - } else if (opts.parseable) { + else if (opts.parseable) output(users.join('\n')) - } else if (!opts.silent && opts.loglevel !== 'silent') { + else if (!opts.silent && opts.loglevel !== 'silent') { output(`\n@${entity} has ${users.length} user${users.length === 1 ? '' : 's'}:\n`) output(columns(users, { padding: 1 })) } @@ -137,11 +132,11 @@ const teamListUsers = async (entity, opts) => { const teamListTeams = async (entity, opts) => { const teams = (await libteam.lsTeams(entity, opts)).sort() - if (opts.json) { + if (opts.json) output(JSON.stringify(teams, null, 2)) - } else if (opts.parseable) { + else if (opts.parseable) output(teams.join('\n')) - } else if (!opts.silent && opts.loglevel !== 'silent') { + else if (!opts.silent && opts.loglevel !== 'silent') { output(`\n@${entity} has ${teams.length} team${teams.length === 1 ? '' : 's'}:\n`) output(columns(teams.map(t => `@${t}`), { padding: 1 })) } diff --git a/lib/test.js b/lib/test.js index 2c7215755..e224aa2de 100644 --- a/lib/test.js +++ b/lib/test.js @@ -4,9 +4,8 @@ const cmd = (args, cb) => testCmd(args, er => { if (er && er.code === 'ELIFECYCLE') { /* eslint-disable standard/no-callback-literal */ cb('Test failed. See above for more details.') - } else { + } else cb(er) - } }) module.exports = Object.assign(cmd, { completion, usage }) diff --git a/lib/token.js b/lib/token.js index 0cd8b7bc6..7e53bd612 100644 --- a/lib/token.js +++ b/lib/token.js @@ -24,7 +24,7 @@ token.usage = usageUtil('token', const UsageError = (msg) => Object.assign(new Error(`\nUsage: ${msg}\n\n` + token.usage), { - code: 'EUSAGE' + code: 'EUSAGE', }) const InvalidCIDRError = (msg) => @@ -34,9 +34,8 @@ token.subcommands = ['list', 'revoke', 'create'] token.completion = function (opts, cb) { var argv = opts.conf.argv.remain - if (argv.length === 2) { + if (argv.length === 2) return cb(null, token.subcommands) - } switch (argv[2]) { case 'list': @@ -54,7 +53,8 @@ function withCb (prom, cb) { function token (args, cb) { log.gauge.show('token') - if (args.length === 0) return withCb(list([]), cb) + if (args.length === 0) + return withCb(list([]), cb) switch (args[0]) { case 'list': case 'ls': @@ -92,27 +92,28 @@ function generateTokenIds (tokens, minLength) { function config () { const conf = { ...npm.flatOptions } const creds = 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, - password: creds.password - } + password: creds.password, + }, } } else if (creds.auth) { const auth = Buffer.from(creds.auth, 'base64').toString().split(':', 2) conf.auth = { basic: { username: auth[0], - password: auth[1] - } + password: auth[1], + }, } - } else { + } else conf.auth = {} - } - if (conf.otp) conf.auth.otp = conf.otp + + if (conf.otp) + conf.auth.otp = conf.otp return conf } @@ -131,7 +132,7 @@ function list (args) { token.token, token.created, token.readonly ? 'true' : 'false', - token.cidr_whitelist ? token.cidr_whitelist.join(',') : '' + token.cidr_whitelist ? token.cidr_whitelist.join(',') : '', ].join('\t')) }) return @@ -140,7 +141,7 @@ function list (args) { 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] + colWidths: [Math.max(idWidth, 2) + 2, 9, 12, 10], }) tokens.forEach((token) => { table.push([ @@ -148,7 +149,7 @@ function list (args) { token.token + '…', String(token.created).slice(0, 10), token.readonly ? 'yes' : 'no', - token.cidr_whitelist ? token.cidr_whitelist.join(', ') : '' + token.cidr_whitelist ? token.cidr_whitelist.join(', ') : '', ]) }) output(table.toString()) @@ -156,9 +157,9 @@ function list (args) { } function rm (args) { - if (args.length === 0) { + if (args.length === 0) return Promise.reject(UsageError('`<tokenKey>` argument is required.')) - } + const conf = config() const toRemove = [] const progress = log.newItem('removing tokens', toRemove.length) @@ -166,15 +167,15 @@ function rm (args) { return pulseTillDone.withPromise(profile.listTokens(conf).then((tokens) => { args.forEach((id) => { const matches = tokens.filter((token) => token.key.indexOf(id) === 0) - if (matches.length === 1) { + if (matches.length === 1) toRemove.push(matches[0].key) - } else if (matches.length > 1) { + 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 { const tokenMatches = tokens.filter((token) => id.indexOf(token.token) === 0) - if (tokenMatches.length === 0) { + if (tokenMatches.length === 0) throw new Error(`Unknown token id or value "${id}".`) - } + toRemove.push(id) } }) @@ -184,13 +185,12 @@ function rm (args) { }) })) })).then(() => { - if (conf.json) { + if (conf.json) output(JSON.stringify(toRemove)) - } else if (conf.parseable) { + else if (conf.parseable) output(toRemove.join('\t')) - } else { + else output('Removed ' + toRemove.length + ' token' + (toRemove.length !== 1 ? 's' : '')) - } }) } @@ -208,11 +208,11 @@ function create (args) { }).then((result) => { delete result.key delete result.updated - if (conf.json) { + if (conf.json) output(JSON.stringify(result)) - } else if (conf.parseable) { + else if (conf.parseable) Object.keys(result).forEach((k) => output(k + '\t' + result[k])) - } else { + else { const table = new Table() Object.keys(result).forEach((k) => table.push({ [ansistyles.bright(k)]: String(result[k]) })) output(table.toString()) @@ -221,12 +221,11 @@ function create (args) { } function validateCIDR (cidr) { - if (isCidrV6(cidr)) { + if (isCidrV6(cidr)) throw InvalidCIDRError('CIDR whitelist can only contain IPv4 addresses, ' + cidr + ' is IPv6') - } - if (!isCidrV4(cidr)) { + + if (!isCidrV4(cidr)) throw InvalidCIDRError('CIDR whitelist contains invalid CIDR entry: ' + cidr) - } } function validateCIDRList (cidrs) { diff --git a/lib/uninstall.js b/lib/uninstall.js index 58e2f61a8..ec997ae64 100644 --- a/lib/uninstall.js +++ b/lib/uninstall.js @@ -15,9 +15,9 @@ const rm = async args => { const path = global ? resolve(npm.globalDir, '..') : prefix if (!args.length) { - if (!global) { + if (!global) throw new Error('must provide a package name to remove') - } else { + else { const pkg = await rpj(resolve(npm.localPrefix, 'package.json')) .catch(er => { throw er.code !== 'ENOENT' && er.code !== 'ENOTDIR' ? er : usage() @@ -30,7 +30,7 @@ const rm = async args => { await arb.reify({ ...npm.flatOptions, - rm: args + rm: args, }) reifyOutput(arb) } diff --git a/lib/unpublish.js b/lib/unpublish.js index ec0f149c5..4d05627d2 100644 --- a/lib/unpublish.js +++ b/lib/unpublish.js @@ -24,10 +24,12 @@ const completion = (args, cb) => completionFn(args) const completionFn = async (args) => { const { partialWord, conf } = args - if (conf.argv.remain.length >= 3) return + if (conf.argv.remain.length >= 3) + return const username = await whoami([], true) - if (!username) { return [] } + if (!username) + return [] const opts = npm.flatOptions const access = await libaccess.lsPackages(username, opts) @@ -35,23 +37,25 @@ const completionFn = async (args) => { // to fetch versions for more than one thing, but also don't // accidentally a whole project let pkgs = Object.keys(access) - if (!partialWord || !pkgs.length) return pkgs + if (!partialWord || !pkgs.length) + return pkgs const pp = npa(partialWord).name pkgs = pkgs.filter(p => !p.indexOf(pp)) - if (pkgs.length > 1) return pkgs + 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 function unpublish (args) { - if (args.length > 1) throw usage + if (args.length > 1) + throw usage const spec = args.length && npa(args[0]) const opts = npm.flatOptions @@ -83,15 +87,13 @@ async function unpublish (args) { try { ret = await otplease(opts, opts => libunpub(pkgJsonSpec, { ...opts, publishConfig })) } catch (err) { - if (err && err.code !== 'ENOENT' && err.code !== 'ENOTDIR') { + if (err && err.code !== 'ENOENT' && err.code !== 'ENOTDIR') throw err - } else { + else throw `Usage: ${usage}` - } } - } else { + } else ret = await otplease(opts, opts => libunpub(spec, opts)) - } if (!silent && loglevel !== 'silent') { output(`- ${spec.name}${ diff --git a/lib/update.js b/lib/update.js index 7f7773153..791e67e40 100644 --- a/lib/update.js +++ b/lib/update.js @@ -28,7 +28,7 @@ const update = async args => { const arb = new Arborist({ ...npm.flatOptions, - path: where + path: where, }) await arb.reify({ update }) diff --git a/lib/utils/audit-error.js b/lib/utils/audit-error.js index 91e880c46..c7423c447 100644 --- a/lib/utils/audit-error.js +++ b/lib/utils/audit-error.js @@ -6,13 +6,11 @@ const output = require('./output.js') const npm = require('../npm.js') const auditError = (report) => { - if (!report || !report.error) { + if (!report || !report.error) return false - } - if (npm.command !== 'audit') { + if (npm.command !== 'audit') return true - } const { error } = report @@ -27,11 +25,10 @@ const auditError = (report) => { uri: error.uri, headers: error.headers, statusCode: error.statusCode, - body + body, }, null, 2)) - } else { + } else output(body) - } throw 'audit endpoint returned an error' } diff --git a/lib/utils/cache-file.js b/lib/utils/cache-file.js index 9db253a3b..b33881e87 100644 --- a/lib/utils/cache-file.js +++ b/lib/utils/cache-file.js @@ -15,9 +15,9 @@ const getCacheOwner = () => { try { st = fs.lstatSync(cache) } catch (er) { - if (er.code !== 'ENOENT') { + if (er.code !== 'ENOENT') throw er - } + st = fs.lstatSync(path.dirname(cache)) } @@ -29,24 +29,21 @@ const getCacheOwner = () => { } const writeOrAppend = (method, file, data) => { - if (!cache) { + if (!cache) cache = npm.config.get('cache') - } // redundant if already absolute, but prevents non-absolute files // from being written as if they're part of the cache. file = path.resolve(cache, file) - if (cacheUid === null && needChown) { + if (cacheUid === null && needChown) getCacheOwner() - } const dir = path.dirname(file) const firstMade = mkdirp.sync(dir) - if (!needChown) { + if (!needChown) return method(file, data) - } let methodThrew = true try { @@ -55,9 +52,9 @@ const writeOrAppend = (method, file, data) => { } finally { // always try to leave it in the right ownership state, even on failure // let the method error fail it instead of the chownr error, though - if (!methodThrew) { + if (!methodThrew) chownr.sync(firstMade || file, cacheUid, cacheGid) - } else { + else { try { chownr.sync(firstMade || file, cacheUid, cacheGid) } catch (_) {} diff --git a/lib/utils/cleanup-log-files.js b/lib/utils/cleanup-log-files.js index a2c28e2e8..13d1e50da 100644 --- a/lib/utils/cleanup-log-files.js +++ b/lib/utils/cleanup-log-files.js @@ -11,23 +11,20 @@ module.exports = (cache, max, warn) => { /* eslint-disable promise/param-names */ return new Promise(done => { glob(resolve(cache, '_logs', '*-debug.log'), (er, files) => { - if (er) { + if (er) return done() - } let pending = files.length - max - if (pending <= 0) { + if (pending <= 0) return done() - } for (let i = 0; i < files.length - max; i++) { rimraf(files[i], (er) => { - if (er) { + if (er) warn('log', 'failed to remove log file', files[i]) - } - if (--pending === 0) { + + if (--pending === 0) done() - } }) } }) diff --git a/lib/utils/cmd-list.js b/lib/utils/cmd-list.js index 6328d80d5..5c188a8e9 100644 --- a/lib/utils/cmd-list.js +++ b/lib/utils/cmd-list.js @@ -21,7 +21,7 @@ const shorthands = { 'clean-install': 'ci', 'clean-install-test': 'cit', x: 'exec', - why: 'explain' + why: 'explain', } const affordances = { @@ -60,7 +60,7 @@ const affordances = { rum: 'run-script', sit: 'cit', urn: 'run-script', - ogr: 'org' + ogr: 'org', } // these are filenames in . @@ -130,7 +130,7 @@ const cmdList = [ 'completion', 'doctor', 'exec', - 'explain' + 'explain', ] const plumbing = ['birthday', 'help-search'] @@ -139,5 +139,5 @@ module.exports = { shorthands, affordances, cmdList, - plumbing + plumbing, } diff --git a/lib/utils/completion/file-completion.js b/lib/utils/completion/file-completion.js index e4daa4dd4..b32eda52d 100644 --- a/lib/utils/completion/file-completion.js +++ b/lib/utils/completion/file-completion.js @@ -13,7 +13,8 @@ function fileCompletion (root, req, depth, cb) { var pattern = root + '/{' + req + ',' + req + '/**/*}' var opts = { mark: true, dot: true, maxDepth: depth } glob(pattern, opts, function (er, files) { - if (er) return cb(er) + if (er) + return cb(er) return cb(null, (files || []).map(function (f) { return f.substr(root.length + 1).replace(/^\/|\/$/g, '') })) diff --git a/lib/utils/completion/installed-deep.js b/lib/utils/completion/installed-deep.js index 8337757bb..0513ef9f8 100644 --- a/lib/utils/completion/installed-deep.js +++ b/lib/utils/completion/installed-deep.js @@ -8,7 +8,7 @@ const readNames = async () => { const { depth, global, - prefix + prefix, } = npm.flatOptions const getValues = (tree) => @@ -24,16 +24,14 @@ const readNames = async () => { const gArb = new Arborist({ global: true, path: resolve(npm.globalDir, '..') }) const gTree = await gArb.loadActual({ global: true }) - for (const node of getValues(gTree)) { + for (const node of getValues(gTree)) res.add(global ? node.name : [node.name, '-g']) - } if (!global) { const arb = new Arborist({ global: false, path: prefix }) const tree = await arb.loadActual() - for (const node of getValues(tree)) { + for (const node of getValues(tree)) res.add(node.name) - } } return [...res] diff --git a/lib/utils/completion/installed-shallow.js b/lib/utils/completion/installed-shallow.js index 5a7a5932f..e2ff5a302 100644 --- a/lib/utils/completion/installed-shallow.js +++ b/lib/utils/completion/installed-shallow.js @@ -6,9 +6,8 @@ const names = global => readdir(global ? npm.globalDir : npm.localDir) const installedShallow = async opts => { const { conf: { argv: { remain } } } = opts - if (remain.length > 3) { + if (remain.length > 3) return null - } const { global } = npm.flatOptions const locals = global ? [] : await names(false) diff --git a/lib/utils/config.js b/lib/utils/config.js index 440806f79..9af6289ff 100644 --- a/lib/utils/config.js +++ b/lib/utils/config.js @@ -5,8 +5,8 @@ const { semver: { type: semver }, Umask: { type: Umask }, url: { type: url }, - path: { type: path } - } + path: { type: path }, + }, } = require('@npmcli/config') const { version: npmVersion } = require('../../package.json') @@ -183,7 +183,7 @@ const defaults = { userconfig: '~/.npmrc', version: false, versions: false, - viewer: isWindows ? 'browser' : 'man' + viewer: isWindows ? 'browser' : 'man', } const types = { @@ -265,7 +265,7 @@ const types = { 'timing', 'info', 'verbose', - 'silly' + 'silly', ], 'logs-max': Number, long: Boolean, @@ -331,7 +331,7 @@ const types = { userconfig: path, version: Boolean, versions: Boolean, - viewer: String + viewer: String, } const shorthands = { @@ -372,7 +372,7 @@ const shorthands = { silent: ['--loglevel', 'silent'], v: ['--version'], verbose: ['--loglevel', 'verbose'], - y: ['--yes'] + y: ['--yes'], } module.exports = { defaults, types, shorthands } diff --git a/lib/utils/deep-sort-object.js b/lib/utils/deep-sort-object.js index 7499efc4b..e7bb7365b 100644 --- a/lib/utils/deep-sort-object.js +++ b/lib/utils/deep-sort-object.js @@ -2,10 +2,11 @@ var sortedObject = require('sorted-object') module.exports = function deepSortObject (obj) { - if (obj == null || typeof obj !== 'object') return obj - if (obj instanceof Array) { + if (obj == null || typeof obj !== 'object') + return obj + if (obj instanceof Array) return obj.map(deepSortObject) - } + obj = sortedObject(obj) Object.keys(obj).forEach(function (key) { obj[key] = deepSortObject(obj[key]) diff --git a/lib/utils/depr-check.js b/lib/utils/depr-check.js index 97023ddda..aa728a336 100644 --- a/lib/utils/depr-check.js +++ b/lib/utils/depr-check.js @@ -7,9 +7,8 @@ const deprWarned = {} module.exports = deprCheck function deprCheck (data) { - if (deprecated[data._id]) { + if (deprecated[data._id]) data.deprecated = deprecated[data._id] - } if (data.deprecated) { deprecated[data._id] = data.deprecated diff --git a/lib/utils/deref-command.js b/lib/utils/deref-command.js index 18e11689e..f45c2627e 100644 --- a/lib/utils/deref-command.js +++ b/lib/utils/deref-command.js @@ -7,21 +7,21 @@ const abbrev = require('abbrev') const abbrevs = abbrev(fullList) module.exports = c => { - if (!c || typeof c !== 'string') { + if (!c || typeof c !== 'string') return '' - } - if (c.match(/[A-Z]/)) { + + if (c.match(/[A-Z]/)) c = c.replace(/([A-Z])/g, m => '-' + m.toLowerCase()) - } - if (plumbing.indexOf(c) !== -1) { + + if (plumbing.indexOf(c) !== -1) return c - } + // first deref the abbrev, if there is one // then resolve any aliases // so `npm install-cl` will resolve to `install-clean` then to `ci` let a = abbrevs[c] - while (aliases[a]) { + while (aliases[a]) a = aliases[a] - } + return a || '' } diff --git a/lib/utils/error-handler.js b/lib/utils/error-handler.js index 16abcd67c..91bfe787a 100644 --- a/lib/utils/error-handler.js +++ b/lib/utils/error-handler.js @@ -12,23 +12,22 @@ const cacheFile = require('./cache-file.js') let logFileName const getLogFile = () => { - if (!logFileName) { + if (!logFileName) logFileName = path.resolve(npm.config.get('cache'), '_logs', (new Date()).toISOString().replace(/[.:]/g, '_') + '-debug.log') - } + return logFileName } const timings = { version: npm.version, command: process.argv.slice(2), - logfile: null + logfile: null, } process.on('timing', (name, value) => { - if (timings[name]) { + if (timings[name]) timings[name] += value - } else { + else timings[name] = value - } }) process.on('exit', code => { @@ -46,10 +45,11 @@ process.on('exit', code => { // kill any outstanding stats reporter if it hasn't finished yet stopMetrics() - if (code) itWorked = false - if (itWorked) { + if (code) + itWorked = false + if (itWorked) log.info('ok') - } else { + else { if (!cbCalled) { log.error('', 'cb() never called!') console.error('') @@ -58,37 +58,40 @@ process.on('exit', code => { writeLogFile() } - if (code) { + if (code) log.verbose('code', code) - } } - if (npm.config && npm.config.loaded && npm.config.get('timing') && !wroteLogFile) writeLogFile() + if (npm.config && npm.config.loaded && npm.config.get('timing') && !wroteLogFile) + writeLogFile() if (wroteLogFile) { // just a line break - if (log.levels[log.level] <= log.levels.error) console.error('') + if (log.levels[log.level] <= log.levels.error) + console.error('') log.error( '', [ 'A complete log of this run can be found in:', - ' ' + getLogFile() + ' ' + getLogFile(), ].join('\n') ) wroteLogFile = false } // actually exit. - if (exitCode === 0 && !itWorked) { + if (exitCode === 0 && !itWorked) exitCode = 1 - } - if (exitCode !== 0) process.exit(exitCode) + + if (exitCode !== 0) + process.exit(exitCode) }) const exit = (code, noLog) => { exitCode = exitCode || process.exitCode || code log.verbose('exit', code) - if (log.level === 'silent') noLog = true + if (log.level === 'silent') + noLog = true const reallyExit = () => { itWorked = !code @@ -103,11 +106,10 @@ const exit = (code, noLog) => { }) } - if (code && !noLog) { + if (code && !noLog) writeLogFile() - } else { + else reallyExit() - } } const errorHandler = (er) => { @@ -118,9 +120,8 @@ const errorHandler = (er) => { console.error(er.stack || er.message) } - if (cbCalled) { + if (cbCalled) er = er || new Error('Callback called more than once.') - } if (npm.updateNotification) { const { level } = log @@ -130,7 +131,8 @@ const errorHandler = (er) => { } cbCalled = true - if (!er) return exit(0) + if (!er) + return exit(0) if (typeof er === 'string') { log.error('', er) return exit(1, true) @@ -146,7 +148,8 @@ const errorHandler = (er) => { for (const k of ['type', 'stack', 'statusCode', 'pkgid']) { const v = er[k] - if (v) log.verbose(k, v) + if (v) + log.verbose(k, v) } log.verbose('cwd', process.cwd()) @@ -159,20 +162,21 @@ const errorHandler = (er) => { for (const k of ['code', 'syscall', 'file', 'path', 'dest', 'errno']) { const v = er[k] - if (v) log.error(k, v) + if (v) + log.error(k, v) } const msg = errorMessage(er) - for (const errline of [...msg.summary, ...msg.detail]) { + for (const errline of [...msg.summary, ...msg.detail]) log.error(...errline) - } + if (npm.config && npm.config.get('json')) { const error = { error: { code: er.code, summary: messageText(msg.summary), - detail: messageText(msg.detail) - } + detail: messageText(msg.detail), + }, } console.log(JSON.stringify(error, null, 2)) } @@ -183,7 +187,8 @@ const errorHandler = (er) => { const messageText = msg => msg.map(line => line.slice(1).join(' ')).join('\n') const writeLogFile = () => { - if (wroteLogFile) return + if (wroteLogFile) + return const os = require('os') @@ -191,7 +196,8 @@ const writeLogFile = () => { let logOutput = '' log.record.forEach(m => { const p = [m.id, m.level] - if (m.prefix) p.push(m.prefix) + if (m.prefix) + p.push(m.prefix) const pref = p.join(' ') m.message.trim().split(/\r?\n/) diff --git a/lib/utils/error-message.js b/lib/utils/error-message.js index a1e1caeeb..26dc7c3cb 100644 --- a/lib/utils/error-message.js +++ b/lib/utils/error-message.js @@ -34,8 +34,8 @@ module.exports = (er) => { '', [ '\nIf you are behind a proxy, please make sure that the', - "'proxy' config is set properly. See: 'npm help config'" - ].join('\n') + "'proxy' config is set properly. See: 'npm help config'", + ].join('\n'), ]) break @@ -59,8 +59,8 @@ module.exports = (er) => { 'previous versions of npm which has since been addressed.', '', 'To permanently fix this problem, please run:', - ` sudo chown -R ${process.getuid()}:${process.getgid()} ${JSON.stringify(npm.config.get('cache'))}` - ].join('\n') + ` sudo chown -R ${process.getuid()}:${process.getgid()} ${JSON.stringify(npm.config.get('cache'))}`, + ].join('\n'), ]) } else { short.push(['', er]) @@ -74,7 +74,7 @@ module.exports = (er) => { : 'It is likely you do not have the permissions to access this file as the current user'), '\nIf you believe this might be a permissions issue, please double-check the', 'permissions of the file and its containing directories, or try running', - 'the command again as root/Administrator.' + 'the command again as root/Administrator.', ].join('\n')]) } break @@ -87,8 +87,8 @@ module.exports = (er) => { [ '', 'Failed using git.', - 'Please check if you have git installed and in your PATH.' - ].join('\n') + 'Please check if you have git installed and in your PATH.', + ].join('\n'), ]) break @@ -106,8 +106,8 @@ module.exports = (er) => { '', 'Please resolve the package.json conflict and retry the command:', '', - `$ ${process.argv.join(' ')}` - ].join('\n') + `$ ${process.argv.join(' ')}`, + ].join('\n'), ]) break } @@ -117,8 +117,8 @@ module.exports = (er) => { 'JSON.parse', [ 'Failed to parse JSON data.', - 'Note: package.json must be actual JSON, not just JavaScript.' - ].join('\n') + 'Note: package.json must be actual JSON, not just JavaScript.', + ].join('\n'), ]) break @@ -132,8 +132,8 @@ module.exports = (er) => { [ 'You can provide a one-time password by passing --otp=<code> to the command you ran.', 'If you already provided a one-time password then it is likely that you either typoed', - 'it, or it timed out. Please try again.' - ].join('\n') + 'it, or it timed out. Please try again.', + ].join('\n'), ]) } else { // npm ERR! code E401 @@ -147,8 +147,8 @@ module.exports = (er) => { '', [ 'To correct this please trying logging in again with:', - ' npm login' - ].join('\n') + ' npm login', + ].join('\n'), ]) } else if (auth.includes('Basic')) { short.push(['', 'Incorrect or missing password.']) @@ -163,12 +163,11 @@ module.exports = (er) => { '', 'If you were doing some other operation then your saved credentials are', 'probably out of date. To correct this please try logging in again with:', - ' npm login' - ].join('\n') + ' npm login', + ].join('\n'), ]) - } else { + } else short.push(['', er.message || er]) - } } break @@ -183,9 +182,9 @@ module.exports = (er) => { const valResult = nameValidator(pkg) - if (valResult.validForNewPackages) { + if (valResult.validForNewPackages) detail.push(['404', 'You should bug the author to publish it (or use the name yourself!)']) - } else { + else { detail.push(['404', 'This package name is not valid, because', '']) const errorsArray = (valResult.errors || []).concat(valResult.warnings || []) @@ -214,8 +213,8 @@ module.exports = (er) => { 'git', [ 'Refusing to remove it. Update manually,', - 'or move it out of the way first.' - ].join('\n') + 'or move it out of the way first.', + ].join('\n'), ]) break @@ -231,8 +230,8 @@ module.exports = (er) => { short.push([ 'notsup', [ - format('Unsupported platform for %s: wanted %j (current: %j)', er.pkgid, expected, actual) - ].join('\n') + format('Unsupported platform for %s: wanted %j (current: %j)', er.pkgid, expected, actual), + ].join('\n'), ]) detail.push([ 'notsup', @@ -240,8 +239,8 @@ module.exports = (er) => { 'Valid OS: ' + validOs, 'Valid Arch: ' + validArch, 'Actual OS: ' + process.platform, - 'Actual Arch: ' + process.arch - ].join('\n') + 'Actual Arch: ' + process.arch, + ].join('\n'), ]) break } @@ -269,8 +268,8 @@ module.exports = (er) => { 'This is a problem related to network connectivity.', 'In most cases you are behind a proxy or have bad network settings.', '\nIf you are behind a proxy, please make sure that the', - "'proxy' config is set properly. See: 'npm help config'" - ].join('\n') + "'proxy' config is set properly. See: 'npm help config'", + ].join('\n'), ]) break @@ -278,7 +277,7 @@ module.exports = (er) => { short.push(['notarget', er.message]) detail.push(['notarget', [ 'In most cases you or one of your dependencies are requesting', - "a package version that doesn't exist." + "a package version that doesn't exist.", ].join('\n')]) break @@ -287,7 +286,7 @@ module.exports = (er) => { detail.push(['403', [ 'In most cases, you or one of your dependencies are requesting', 'a package version that is forbidden by your security policy, or', - 'on a server you do not have access to.' + 'on a server you do not have access to.', ].join('\n')]) break @@ -301,9 +300,9 @@ module.exports = (er) => { 'Required: ' + JSON.stringify(er.required), 'Actual: ' + JSON.stringify({ npm: npm.version, - node: npm.config.loaded ? npm.config.get('node-version') : process.version - }) - ].join('\n') + node: npm.config.loaded ? npm.config.get('node-version') : process.version, + }), + ].join('\n'), ]) break @@ -313,8 +312,8 @@ module.exports = (er) => { 'nospc', [ 'There appears to be insufficient space on your system to finish.', - 'Clear up some disk space and try again.' - ].join('\n') + 'Clear up some disk space and try again.', + ].join('\n'), ]) break @@ -324,8 +323,8 @@ module.exports = (er) => { 'rofs', [ 'Often virtualized file systems, or other file systems', - "that don't support symlinks, give this error." - ].join('\n') + "that don't support symlinks, give this error.", + ].join('\n'), ]) break @@ -335,8 +334,8 @@ module.exports = (er) => { 'enoent', [ 'This is related to npm not being able to find a file.', - er.file ? "\nCheck if the file '" + er.file + "' is present." : '' - ].join('\n') + er.file ? "\nCheck if the file '" + er.file + "' is present." : '', + ].join('\n'), ]) break @@ -349,25 +348,25 @@ module.exports = (er) => { 'typeerror', [ 'This is an error with npm itself. Please report this error at:', - ' https://github.com/npm/cli/issues' - ].join('\n') + ' https://github.com/npm/cli/issues', + ].join('\n'), ]) break default: short.push(['', er.message || er]) - if (er.signal) { + if (er.signal) detail.push(['signal', er.signal]) - } - if (er.cmd && Array.isArray(er.args)) { + + if (er.cmd && Array.isArray(er.args)) detail.push(['command', ...[er.cmd, ...er.args]]) - } - if (er.stdout) { + + if (er.stdout) detail.push(['', er.stdout.trim()]) - } - if (er.stderr) { + + if (er.stderr) detail.push(['', er.stderr.trim()]) - } + break } return { summary: short, detail: detail } diff --git a/lib/utils/explain-dep.js b/lib/utils/explain-dep.js index af819f1c2..096df97ed 100644 --- a/lib/utils/explain-dep.js +++ b/lib/utils/explain-dep.js @@ -5,7 +5,7 @@ const nocolor = { red: s => s, yellow: s => s, cyan: s => s, - magenta: s => s + magenta: s => s, } const explainNode = (node, depth, color) => @@ -30,31 +30,29 @@ const printNode = (node, color) => { extraneous, dev, optional, - peer + peer, } = node const { bold, dim } = color ? chalk : nocolor const extra = [] - if (extraneous) { + if (extraneous) extra.push(' ' + bold(colorType('extraneous', color))) - } - if (dev) { + + if (dev) extra.push(' ' + bold(colorType('dev', color))) - } - if (optional) { + + if (optional) extra.push(' ' + bold(colorType('optional', color))) - } - if (peer) { + + if (peer) extra.push(' ' + bold(colorType('peer', color))) - } return `${bold(name)}@${bold(version)}${extra.join('')}` + (location ? dim(`\n${location}`) : '') } const explainDependents = ({ name, dependents }, depth, color) => { - if (!dependents || !dependents.length || depth <= 0) { + if (!dependents || !dependents.length || depth <= 0) return '' - } const max = Math.ceil(depth / 2) const messages = dependents.slice(0, max) @@ -90,9 +88,8 @@ const explainEdge = ({ name, type, from, spec }, depth, color) => { } const explainFrom = (from, depth, color) => { - if (!from.name && !from.version) { + if (!from.name && !from.version) return 'the root project' - } return printNode(from, color) + explainDependents(from, depth - 1, color) diff --git a/lib/utils/explain-eresolve.js b/lib/utils/explain-eresolve.js index 07a63c240..69789ec9a 100644 --- a/lib/utils/explain-eresolve.js +++ b/lib/utils/explain-eresolve.js @@ -18,9 +18,8 @@ const explainEresolve = (expl, color, depth) => { const { edge, current, peerConflict } = expl const out = [] - if (edge.from && edge.from.whileInstalling) { + if (edge.from && edge.from.whileInstalling) out.push('While resolving: ' + printNode(edge.from.whileInstalling, color)) - } out.push('Found: ' + explainNode(current, depth, color)) out.push('\nCould not resolve dependency:\n' + @@ -66,5 +65,5 @@ const explain = (expl, depth = 2) => explainEresolve(expl, npm.color, depth) module.exports = { explain, - report + report, } diff --git a/lib/utils/flat-options.js b/lib/utils/flat-options.js index 37daabe03..d7713ae13 100644 --- a/lib/utils/flat-options.js +++ b/lib/utils/flat-options.js @@ -13,21 +13,17 @@ const buildOmitList = npm => { .filter(type => !include.includes(type))) const only = npm.config.get('only') - if (/^prod(uction)?$/.test(only) || npm.config.get('production')) { + if (/^prod(uction)?$/.test(only) || npm.config.get('production')) omit.add('dev') - } - if (/dev/.test(npm.config.get('also'))) { + if (/dev/.test(npm.config.get('also'))) omit.delete('dev') - } - if (npm.config.get('dev')) { + if (npm.config.get('dev')) omit.delete('dev') - } - if (npm.config.get('optional') === false) { + if (npm.config.get('optional') === false) omit.add('optional') - } npm.config.set('omit', [...omit]) return [...omit] @@ -91,7 +87,7 @@ const flatOptions = npm => npm.flatOptions || Object.freeze({ lockFile: { retries: npm.config.get('cache-lock-retries'), stale: npm.config.get('cache-lock-stale'), - wait: npm.config.get('cache-lock-wait') + wait: npm.config.get('cache-lock-wait'), }, // XXX remove these once no longer used @@ -134,7 +130,7 @@ const flatOptions = npm => npm.flatOptions || Object.freeze({ exclude: npm.config.get('searchexclude'), limit: npm.config.get('searchlimit') || 20, opts: npm.config.get('searchopts'), - staleness: npm.config.get('searchstaleness') + staleness: npm.config.get('searchstaleness'), }, dryRun: npm.config.get('dry-run'), @@ -144,7 +140,7 @@ const flatOptions = npm => npm.flatOptions || Object.freeze({ retries: npm.config.get('fetch-retries'), factor: npm.config.get('fetch-retry-factor'), maxTimeout: npm.config.get('fetch-retry-maxtimeout'), - minTimeout: npm.config.get('fetch-retry-mintimeout') + minTimeout: npm.config.get('fetch-retry-mintimeout'), }, timeout: npm.config.get('fetch-timeout'), @@ -217,22 +213,22 @@ const flatOptions = npm => npm.flatOptions || Object.freeze({ // note that the various (HTTPS_|HTTP_|)PROXY environs will be // respected if this is not set. proxy: npm.config.get('https-proxy') || npm.config.get('proxy'), - noProxy: npm.config.get('noproxy') + noProxy: npm.config.get('noproxy'), }) const getPreferOnline = npm => { const po = npm.config.get('prefer-online') - if (po !== undefined) { + if (po !== undefined) return po - } + return npm.config.get('cache-max') <= 0 } const getPreferOffline = npm => { const po = npm.config.get('prefer-offline') - if (po !== undefined) { + if (po !== undefined) return po - } + return npm.config.get('cache-min') >= 9999 } @@ -242,9 +238,8 @@ const getScopesAndAuths = npm => { const scopesAndAuths = {} // pull out all the @scope:... configs into a flat object. for (const key in npm.config.list[0]) { - if (/@.*:registry$/i.test(key) || /^\/\//.test(key)) { + if (/@.*:registry$/i.test(key) || /^\/\//.test(key)) scopesAndAuths[key] = npm.config.get(key) - } } return scopesAndAuths } diff --git a/lib/utils/get-identity.js b/lib/utils/get-identity.js index d31b3ae28..d5c560161 100644 --- a/lib/utils/get-identity.js +++ b/lib/utils/get-identity.js @@ -6,9 +6,8 @@ const needsAuthError = (msg) => module.exports = async (opts = {}) => { const { registry } = opts - if (!registry) { + if (!registry) throw Object.assign(new Error('No registry specified.'), { code: 'ENOREGISTRY' }) - } // First, check if we have a user/pass-based auth const creds = npm.config.getCredentialsByURI(registry) @@ -20,13 +19,13 @@ module.exports = async (opts = {}) => { } else if (token) { // No username, but we have a token; fetch the username from registry const registryData = await npmFetch.json('/-/whoami', { - ...opts + ...opts, }) const { username: usernameFromRegistry } = registryData // Retrieved username from registry; return it - if (usernameFromRegistry) { + if (usernameFromRegistry) return usernameFromRegistry - } else { + else { // Didn't get username from registry; bad token throw needsAuthError( 'Your auth token is no longer valid. Please login again.' diff --git a/lib/utils/get-project-scope.js b/lib/utils/get-project-scope.js index 0b2b6061c..3ce84d5bb 100644 --- a/lib/utils/get-project-scope.js +++ b/lib/utils/get-project-scope.js @@ -2,13 +2,13 @@ const { resolve } = require('path') module.exports = prefix => { try { const { name } = require(resolve(prefix, 'package.json')) - if (!name || typeof name !== 'string') { + if (!name || typeof name !== 'string') return '' - } + const split = name.split('/') - if (split.length < 2) { + if (split.length < 2) return '' - } + const scope = split[0] return /^@/.test(scope) ? scope : '' } catch (er) { diff --git a/lib/utils/metrics-launch.js b/lib/utils/metrics-launch.js index 7e2a8d1cc..c39c3fec9 100644 --- a/lib/utils/metrics-launch.js +++ b/lib/utils/metrics-launch.js @@ -4,13 +4,15 @@ module.exports = launchSendMetrics var fs = require('graceful-fs') var child_process = require('child_process') -if (require.main === module) main() +if (require.main === module) + main() function launchSendMetrics () { var path = require('path') var npm = require('../npm.js') try { - if (!npm.config.get('send-metrics')) return + if (!npm.config.get('send-metrics')) + return var cliMetrics = path.join(npm.config.get('cache'), 'anonymous-cli-metrics.json') var targetRegistry = npm.config.get('metrics-registry') fs.statSync(cliMetrics) @@ -21,9 +23,11 @@ function launchSendMetrics () { } function runInBackground (js, args, opts) { - if (!args) args = [] + if (!args) + args = [] args.unshift(js) - if (!opts) opts = {} + if (!opts) + opts = {} opts.stdio = 'ignore' opts.detached = true var child = child_process.spawn(process.execPath, args, opts) diff --git a/lib/utils/metrics.js b/lib/utils/metrics.js index d1f5e5586..c394f1d34 100644 --- a/lib/utils/metrics.js +++ b/lib/utils/metrics.js @@ -14,19 +14,23 @@ const cacheFile = require('./cache-file.js') let inMetrics = false function startMetrics () { - if (inMetrics) return + if (inMetrics) + return // loaded on demand to avoid any recursive deps when `./metrics-launch` requires us. var metricsLaunch = require('./metrics-launch.js') npm.metricsProcess = metricsLaunch() } function stopMetrics () { - if (inMetrics) return - if (npm.metricsProcess) npm.metricsProcess.kill('SIGKILL') + if (inMetrics) + return + if (npm.metricsProcess) + npm.metricsProcess.kill('SIGKILL') } function saveMetrics (itWorked) { - if (inMetrics) return + if (inMetrics) + return // If the metrics reporter hasn't managed to PUT yet then kill it so that it doesn't // step on our updating the anonymous-cli-metrics json stopMetrics() @@ -35,11 +39,10 @@ function saveMetrics (itWorked) { try { metrics = JSON.parse(fs.readFileSync(metricsFile)) metrics.metrics.to = new Date().toISOString() - if (itWorked) { + if (itWorked) ++metrics.metrics.successfulInstalls - } else { + else ++metrics.metrics.failedInstalls - } } catch (ex) { metrics = { metricId: uuidv4(), @@ -47,8 +50,8 @@ function saveMetrics (itWorked) { from: new Date().toISOString(), to: new Date().toISOString(), successfulInstalls: itWorked ? 1 : 0, - failedInstalls: itWorked ? 0 : 1 - } + failedInstalls: itWorked ? 0 : 1, + }, } } try { @@ -68,7 +71,7 @@ function sendMetrics (metricsFile, metricsRegistry) { registry: metricsRegistry, method: 'PUT', body: cliMetrics.metrics, - retry: false + retry: false, } ).then(() => { fs.unlinkSync(metricsFile) diff --git a/lib/utils/module-name.js b/lib/utils/module-name.js index 18f54e411..6152f1258 100644 --- a/lib/utils/module-name.js +++ b/lib/utils/module-name.js @@ -6,11 +6,14 @@ module.exports.test = {} module.exports.test.pathToPackageName = pathToPackageName function pathToPackageName (dir) { - if (dir == null) return '' - if (dir === '') return '' + if (dir == null) + return '' + if (dir === '') + return '' var name = path.relative(path.resolve(dir, '..'), dir) var scoped = path.relative(path.resolve(dir, '../..'), dir) - if (scoped[0] === '@') return scoped.replace(/\\/g, '/') + if (scoped[0] === '@') + return scoped.replace(/\\/g, '/') return name.trim() } @@ -21,12 +24,16 @@ function isNotEmpty (str) { var unknown = 0 function moduleName (tree) { - if (tree.name) { return tree.name } + if (tree.name) + return tree.name var pkg = tree.package || tree - if (isNotEmpty(pkg.name) && typeof pkg.name === 'string') return pkg.name.trim() + if (isNotEmpty(pkg.name) && typeof pkg.name === 'string') + return pkg.name.trim() var pkgName = pathToPackageName(tree.path) - if (pkgName !== '') return pkgName - if (tree._invalidName != null) return tree._invalidName + if (pkgName !== '') + return pkgName + if (tree._invalidName != null) + return tree._invalidName tree._invalidName = '!invalid#' + (++unknown) return tree._invalidName } diff --git a/lib/utils/no-progress-while-running.js b/lib/utils/no-progress-while-running.js index 961fa8b55..13c2c50e1 100644 --- a/lib/utils/no-progress-while-running.js +++ b/lib/utils/no-progress-while-running.js @@ -4,14 +4,17 @@ var progressEnabled var running = 0 var startRunning = exports.startRunning = function () { - if (progressEnabled == null) progressEnabled = log.progressEnabled - if (progressEnabled) log.disableProgress() + if (progressEnabled == null) + progressEnabled = log.progressEnabled + if (progressEnabled) + log.disableProgress() ++running } var stopRunning = exports.stopRunning = function () { --running - if (progressEnabled && running === 0) log.enableProgress() + if (progressEnabled && running === 0) + log.enableProgress() } exports.tillDone = function noProgressTillDone (cb) { diff --git a/lib/utils/npm-usage.js b/lib/utils/npm-usage.js index 77eb97317..720aab3de 100644 --- a/lib/utils/npm-usage.js +++ b/lib/utils/npm-usage.js @@ -32,13 +32,11 @@ Configuration fields: npm help 7 config npm@${npm.version} ${dirname(dirname(__dirname))} `) - if (npm.argv.length >= 1) { + if (npm.argv.length >= 1) output(didYouMean(npm.argv[0], cmdList)) - } - if (!valid) { + if (!valid) process.exitCode = 1 - } } const wrap = (arr) => { @@ -47,17 +45,18 @@ const wrap = (arr) => { var line line = process.stdout.columns - if (!line) { + if (!line) line = 60 - } else { + else line = Math.min(60, Math.max(line - 16, 24)) - } - arr.sort(function (a, b) { return a < b ? -1 : 1 }) + arr.sort(function (a, b) { + return a < b ? -1 : 1 + }) .forEach(function (c) { - if (out[l].length + c.length + 2 < line) { + if (out[l].length + c.length + 2 < line) out[l] += ', ' + c - } else { + else { out[l++] += ',' out[l] = c } diff --git a/lib/utils/open-url.js b/lib/utils/open-url.js index 8f270221c..4d9de4f57 100644 --- a/lib/utils/open-url.js +++ b/lib/utils/open-url.js @@ -20,7 +20,7 @@ module.exports = function open (url, errMsg, cb, browser = npm.config.get('brows const alternateMsg = json ? JSON.stringify({ title: errMsg, - url + url, }, null, 2) : `${errMsg}:\n ${url}\n` @@ -32,17 +32,15 @@ module.exports = function open (url, errMsg, cb, browser = npm.config.get('brows return cb() } - if (!isUrlValid(url)) { + if (!isUrlValid(url)) return cb(new Error('Invalid URL: ' + url)) - } const command = browser === true ? null : browser opener(url, { command }, (er) => { if (er && er.code === 'ENOENT') { printAlternateMsg() return cb() - } else { + } else return cb(er) - } }) } diff --git a/lib/utils/otplease.js b/lib/utils/otplease.js index 6a389a091..3210f3e91 100644 --- a/lib/utils/otplease.js +++ b/lib/utils/otplease.js @@ -10,11 +10,11 @@ module.exports = otplease function otplease (opts, fn) { opts = { prompt, ...opts } return Promise.resolve().then(() => fn(opts)).catch(err => { - if (!isOtpError(err)) { + if (!isOtpError(err)) throw err - } else if (!process.stdin.isTTY || !process.stdout.isTTY) { + else if (!process.stdin.isTTY || !process.stdout.isTTY) throw err - } else { + else { return readUserInfo.otp(opts.prompt) .then(otp => fn({ ...opts, otp })) } diff --git a/lib/utils/package-id.js b/lib/utils/package-id.js index 2c5e33146..4048aee4f 100644 --- a/lib/utils/package-id.js +++ b/lib/utils/package-id.js @@ -5,11 +5,11 @@ module.exports = function (tree) { var pkg = tree.package || tree // FIXME: Excluding the '@' here is cleaning up after the mess that // read-package-json makes. =( - if (pkg._id && pkg._id !== '@') return pkg._id + if (pkg._id && pkg._id !== '@') + return pkg._id var name = moduleName(tree) - if (pkg.version) { + if (pkg.version) return name + '@' + pkg.version - } else { + else return name - } } diff --git a/lib/utils/perf.js b/lib/utils/perf.js index 8cc4573dd..3f81ee4b0 100644 --- a/lib/utils/perf.js +++ b/lib/utils/perf.js @@ -11,7 +11,6 @@ process.on('timeEnd', (name) => { process.emit('timing', name, ms) log.timing(name, `Completed in ${ms}ms`) timings.delete(name) - } else { + } else log.silly('timing', "Tried to end timer that doesn't exist:", name) - } }) diff --git a/lib/utils/pick-manifest-from-registry-metadata.js b/lib/utils/pick-manifest-from-registry-metadata.js index 4161fafcc..a92e30b73 100644 --- a/lib/utils/pick-manifest-from-registry-metadata.js +++ b/lib/utils/pick-manifest-from-registry-metadata.js @@ -11,16 +11,16 @@ function pickManifestFromRegistryMetadata (spec, tag, versions, metadata) { var tagged = metadata['dist-tags'][tag] if (tagged && metadata.versions[tagged] && - semver.satisfies(tagged, spec, true)) { + semver.satisfies(tagged, spec, true)) return { resolvedTo: tag, manifest: metadata.versions[tagged] } - } + // find the max satisfying version. var ms = semver.maxSatisfying(versions, spec, true) - if (ms) { + if (ms) return { resolvedTo: ms, manifest: metadata.versions[ms] } - } else if (spec === '*' && versions.length && tagged && metadata.versions[tagged]) { + else if (spec === '*' && versions.length && tagged && metadata.versions[tagged]) return { resolvedTo: tag, manifest: metadata.versions[tagged] } - } else { + else { } } diff --git a/lib/utils/pulse-till-done.js b/lib/utils/pulse-till-done.js index a533c0644..215a514c8 100644 --- a/lib/utils/pulse-till-done.js +++ b/lib/utils/pulse-till-done.js @@ -6,19 +6,22 @@ let pulsers = 0 let pulse function pulseStart (prefix) { - if (++pulsers > 1) return + if (++pulsers > 1) + return pulse = setInterval(function () { log.gauge.pulse(prefix) }, 150) } function pulseStop () { - if (--pulsers > 0) return + if (--pulsers > 0) + return clearInterval(pulse) } module.exports = function (prefix, cb) { validate('SF', [prefix, cb]) - if (!prefix) prefix = 'network' + if (!prefix) + prefix = 'network' pulseStart(prefix) return (er, ...args) => { pulseStop() diff --git a/lib/utils/read-local-package.js b/lib/utils/read-local-package.js index 8d30883e7..91a1e3a5b 100644 --- a/lib/utils/read-local-package.js +++ b/lib/utils/read-local-package.js @@ -5,9 +5,8 @@ const readJson = require('read-package-json-fast') const npm = require('../npm.js') async function readLocalPackageName (cb) { - if (npm.flatOptions.global) { + if (npm.flatOptions.global) return - } const filepath = resolve(npm.flatOptions.prefix, 'package.json') return (await readJson(filepath)).name diff --git a/lib/utils/read-user-info.js b/lib/utils/read-user-info.js index f5a583be6..9977d2d60 100644 --- a/lib/utils/read-user-info.js +++ b/lib/utils/read-user-info.js @@ -21,32 +21,35 @@ function readOTP (msg, otp, isRetry) { 'Enter one below. You can also pass one on the command line by appending --otp=123456.', 'For more information, see:', 'https://docs.npmjs.com/getting-started/using-two-factor-authentication', - 'Enter OTP: ' + 'Enter OTP: ', ].join('\n') } - if (isRetry && otp && /^[\d ]+$|^[A-Fa-f0-9]{64,64}$/.test(otp)) return otp.replace(/\s+/g, '') + if (isRetry && otp && /^[\d ]+$|^[A-Fa-f0-9]{64,64}$/.test(otp)) + return otp.replace(/\s+/g, '') return read({ prompt: msg, default: otp || '' }) .then((otp) => readOTP(msg, otp, true)) } function readPassword (msg, password, isRetry) { - if (!msg) msg = 'npm password: ' - if (isRetry && password) return password + if (!msg) + msg = 'npm password: ' + if (isRetry && password) + return password return read({ prompt: msg, silent: true, default: password || '' }) .then((password) => readPassword(msg, password, true)) } function readUsername (msg, username, opts, isRetry) { - if (!msg) msg = 'npm username: ' + if (!msg) + msg = 'npm username: ' if (isRetry && username) { const error = userValidate.username(username) - if (error) { + if (error) opts.log && opts.log.warn(error.message) - } else { + else return Promise.resolve(username.trim()) - } } return read({ prompt: msg, default: username || '' }) @@ -54,14 +57,14 @@ function readUsername (msg, username, opts, isRetry) { } function readEmail (msg, email, opts, isRetry) { - if (!msg) msg = 'email (this IS public): ' + if (!msg) + msg = 'email (this IS public): ' if (isRetry && email) { const error = userValidate.email(email) - if (error) { + if (error) opts.log && opts.log.warn(error.message) - } else { + else return email.trim() - } } return read({ prompt: msg, default: email || '' }) diff --git a/lib/utils/reify-output.js b/lib/utils/reify-output.js index 10b276cd9..ed5733487 100644 --- a/lib/utils/reify-output.js +++ b/lib/utils/reify-output.js @@ -21,9 +21,8 @@ const auditError = require('./audit-error.js') // TODO: output JSON if flatOptions.json is true const reifyOutput = arb => { // don't print any info in --silent mode - if (log.levels[log.level] > log.levels.error) { + if (log.levels[log.level] > log.levels.error) return - } const { diff, actualTree } = arb @@ -37,7 +36,7 @@ const reifyOutput = arb => { removed: 0, changed: 0, audited: auditReport && !auditReport.error ? actualTree.inventory.size : 0, - funding: 0 + funding: 0, } if (diff) { @@ -60,7 +59,7 @@ const reifyOutput = arb => { const node = d.actual || d.ideal log.silly(d.action, node.location) }, - getChildren: d => d.children + getChildren: d => d.children, }) } @@ -87,9 +86,9 @@ const reifyOutput = arb => { // to tell you to run `npm audit` for details. otherwise, use the summary // report. if we get here, we know it's not quiet or json. const printAuditReport = report => { - if (!report) { + if (!report) return - } + const reporter = npm.command !== 'audit' ? 'install' : 'detail' const defaultAuditLevel = npm.command !== 'audit' ? 'none' : 'low' const auditLevel = npm.flatOptions.auditLevel || defaultAuditLevel @@ -97,7 +96,7 @@ const printAuditReport = report => { const res = auditReport(report, { reporter, ...npm.flatOptions, - auditLevel + auditLevel, }) process.exitCode = process.exitCode || res.exitCode output('\n' + res.report) @@ -107,46 +106,43 @@ const packagesChangedMessage = ({ added, removed, changed, audited }) => { const msg = ['\n'] if (added === 0 && removed === 0 && changed === 0) { msg.push('up to date') - if (audited) { + if (audited) msg.push(', ') - } } else { - if (added) { + if (added) msg.push(`added ${added} package${added === 1 ? '' : 's'}`) - } + if (removed) { - if (added) { + if (added) msg.push(', ') - } - if (added && !audited && !changed) { + + if (added && !audited && !changed) msg.push('and ') - } + msg.push(`removed ${removed} package${removed === 1 ? '' : 's'}`) } if (changed) { - if (added || removed) { + if (added || removed) msg.push(', ') - } - if (!audited && (added || removed)) { + + if (!audited && (added || removed)) msg.push('and ') - } + msg.push(`changed ${changed} package${changed === 1 ? '' : 's'}`) } - if (audited) { + if (audited) msg.push(', and ') - } } - if (audited) { + if (audited) msg.push(`audited ${audited} package${audited === 1 ? '' : 's'}`) - } + msg.push(` in ${ms(Date.now() - npm.started)}`) output(msg.join('')) } const packagesFundingMessage = ({ funding }) => { - if (!funding) { + if (!funding) return - } output('') const pkg = funding === 1 ? 'package' : 'packages' diff --git a/lib/utils/setup-log.js b/lib/utils/setup-log.js index dde55b4fa..44e612d50 100644 --- a/lib/utils/setup-log.js +++ b/lib/utils/setup-log.js @@ -22,11 +22,11 @@ module.exports = (config) => { return warn(heading, ...args) } - if (config.get('timing') && config.get('loglevel') === 'notice') { + if (config.get('timing') && config.get('loglevel') === 'notice') log.level = 'timing' - } else { + else log.level = config.get('loglevel') - } + log.heading = config.get('heading') || 'npm' const stdoutTTY = process.stdout.isTTY @@ -42,26 +42,23 @@ module.exports = (config) => { : color === false ? false : stdoutTTY - if (enableColorStderr) { + if (enableColorStderr) log.enableColor() - } else { + else log.disableColor() - } - if (config.get('unicode')) { + if (config.get('unicode')) log.enableUnicode() - } else { + else log.disableUnicode() - } // if it's more than error, don't show progress const quiet = log.levels[log.level] > log.levels.error - if (config.get('progress') && stderrNotDumb && !quiet) { + if (config.get('progress') && stderrNotDumb && !quiet) log.enableProgress() - } else { + else log.disableProgress() - } return enableColorStdout } diff --git a/lib/utils/spawn.js b/lib/utils/spawn.js index b164a6acb..3bbe18384 100644 --- a/lib/utils/spawn.js +++ b/lib/utils/spawn.js @@ -5,11 +5,15 @@ var EventEmitter = require('events').EventEmitter var npwr = require('./no-progress-while-running.js') function willCmdOutput (stdio) { - if (stdio === 'inherit') return true - if (!Array.isArray(stdio)) return false + if (stdio === 'inherit') + return true + if (!Array.isArray(stdio)) + return false for (var fh = 1; fh <= 2; ++fh) { - if (stdio[fh] === 'inherit') return true - if (stdio[fh] === 1 || stdio[fh] === 2) return true + if (stdio[fh] === 'inherit') + return true + if (stdio[fh] === 1 || stdio[fh] === 2) + return true } return false } @@ -17,16 +21,19 @@ function willCmdOutput (stdio) { function spawn (cmd, args, options) { var cmdWillOutput = willCmdOutput(options && options.stdio) - if (cmdWillOutput) npwr.startRunning() + if (cmdWillOutput) + npwr.startRunning() var raw = _spawn(cmd, args, options) var cooked = new EventEmitter() raw.on('error', function (er) { - if (cmdWillOutput) npwr.stopRunning() + if (cmdWillOutput) + npwr.stopRunning() er.file = cmd cooked.emit('error', er) }).on('close', function (code, signal) { - if (cmdWillOutput) npwr.stopRunning() + if (cmdWillOutput) + npwr.stopRunning() // Create ENOENT error because Node.js v0.8 will not emit // an `error` event if the command could not be found. if (code === 127) { @@ -36,15 +43,16 @@ function spawn (cmd, args, options) { er.syscall = 'spawn' er.file = cmd cooked.emit('error', er) - } else { + } else cooked.emit('close', code, signal) - } }) cooked.stdin = raw.stdin cooked.stdout = raw.stdout cooked.stderr = raw.stderr - cooked.kill = function (sig) { return raw.kill(sig) } + cooked.kill = function (sig) { + return raw.kill(sig) + } return cooked } diff --git a/lib/utils/tar.js b/lib/utils/tar.js index 4ad1219f2..9e3c7ec25 100644 --- a/lib/utils/tar.js +++ b/lib/utils/tar.js @@ -19,7 +19,7 @@ function logTar (tarball, opts = {}) { return { path: f.path, size: `${bytes.value}${bytes.unit}` } }), { include: ['size', 'path'], - showHeaders: false + showHeaders: false, })) } if (tarball.bundled.length) { @@ -36,15 +36,15 @@ function logTar (tarball, opts = {}) { { name: 'shasum:', value: tarball.shasum }, { name: 'integrity:', - value: tarball.integrity.toString().substr(0, 20) + '[...]' + tarball.integrity.toString().substr(80) + value: tarball.integrity.toString().substr(0, 20) + '[...]' + tarball.integrity.toString().substr(80), }, tarball.bundled.length && { name: 'bundled deps:', value: tarball.bundled.length }, tarball.bundled.length && { name: 'bundled files:', value: tarball.entryCount - tarball.files.length }, tarball.bundled.length && { name: 'own files:', value: tarball.files.length }, - { name: 'total files:', value: tarball.entryCount } + { name: 'total files:', value: tarball.entryCount }, ].filter((x) => x), { include: ['name', 'value'], - showHeaders: false + showHeaders: false, })) log.notice('', '') } @@ -68,20 +68,20 @@ async function getContents (manifest, tarball) { files.push({ path: entry.path.replace(/^package\//, ''), size: entry.size, - mode: entry.mode + mode: entry.mode, }) - } + }, }) stream.end(tarball) const integrity = await ssri.fromData(tarball, { - algorithms: ['sha1', 'sha512'] + algorithms: ['sha1', 'sha512'], }) const comparator = (a, b) => { return a.path.localeCompare(b.path, undefined, { sensitivity: 'case', - numeric: true + numeric: true, }) } @@ -108,6 +108,6 @@ async function getContents (manifest, tarball) { filename: `${manifest.name}-${manifest.version}.tgz`, files: uppers.concat(others), entryCount: totalEntries, - bundled: Array.from(bundled) + bundled: Array.from(bundled), } } diff --git a/lib/utils/unsupported.js b/lib/utils/unsupported.js index 8e880c2cc..5f6a341a8 100644 --- a/lib/utils/unsupported.js +++ b/lib/utils/unsupported.js @@ -7,7 +7,7 @@ const checkVersion = exports.checkVersion = version => { return { version: versionNoPrerelease, broken: semver.satisfies(versionNoPrerelease, knownBroken), - unsupported: !semver.satisfies(versionNoPrerelease, supported) + unsupported: !semver.satisfies(versionNoPrerelease, supported), } } diff --git a/lib/utils/update-notifier.js b/lib/utils/update-notifier.js index dda6f3dca..0a19be94e 100644 --- a/lib/utils/update-notifier.js +++ b/lib/utils/update-notifier.js @@ -33,18 +33,16 @@ const updateTimeout = async (npm, duration) => { // might be using /dev/null as the cache or something weird like that. await writeFile(f, '').catch(() => {}) return true - } else { + } else return false - } } const updateNotifier = module.exports = async (npm, spec = 'latest') => { // never check for updates in CI, when updating npm already, or opted out if (!npm.config.get('update-notifier') || isGlobalNpmUpdate(npm) || - ciDetect()) { + ciDetect()) return null - } // if we're on a prerelease train, then updates are coming fast // check for a new one daily. otherwise, weekly. @@ -52,17 +50,15 @@ const updateNotifier = module.exports = async (npm, spec = 'latest') => { const current = semver.parse(version) // if we're on a beta train, always get the next beta - if (current.prerelease.length) { + if (current.prerelease.length) spec = `^${version}` - } // while on a beta train, get updates daily const duration = spec !== 'latest' ? DAILY : WEEKLY // if we've already checked within the specified duration, don't check again - if (!(await updateTimeout(npm, duration))) { + if (!(await updateTimeout(npm, duration))) return null - } // if they're currently using a prerelease, nudge to the next prerelease // otherwise, nudge to latest. @@ -71,13 +67,12 @@ const updateNotifier = module.exports = async (npm, spec = 'latest') => { const mani = await pacote.manifest(`npm@${spec}`, { // always prefer latest, even if doing --tag=whatever on the cmd defaultTag: 'latest', - ...npm.flatOptions + ...npm.flatOptions, }).catch(() => null) // if pacote failed, give up - if (!mani) { + if (!mani) return null - } const latest = mani.version @@ -85,14 +80,12 @@ const updateNotifier = module.exports = async (npm, spec = 'latest') => { // and should get the updates from that release train. // Note that this isn't another http request over the network, because // the packument will be cached by pacote from previous request. - if (semver.gt(version, latest) && spec === 'latest') { + if (semver.gt(version, latest) && spec === 'latest') return updateNotifier(npm, `^${version}`) - } // if we already have something >= the desired spec, then we're done - if (semver.gte(version, latest)) { + if (semver.gte(version, latest)) return null - } // ok! notify the user about this update they should get. // The message is saved for printing at process exit so it will not get diff --git a/lib/utils/usage.js b/lib/utils/usage.js index 1eda734c0..636914061 100644 --- a/lib/utils/usage.js +++ b/lib/utils/usage.js @@ -4,11 +4,13 @@ var aliases = require('../utils/cmd-list').aliases module.exports = function usage (cmd, txt, opt) { var post = Object.keys(aliases).reduce(function (p, c) { var val = aliases[c] - if (val !== cmd) return p + if (val !== cmd) + return p return p.concat(c) }, []) - if (opt || post.length > 0) txt += '\n\n' + if (opt || post.length > 0) + txt += '\n\n' if (post.length === 1) { txt += 'alias: ' @@ -19,7 +21,8 @@ module.exports = function usage (cmd, txt, opt) { } if (opt) { - if (post.length > 0) txt += '\n' + if (post.length > 0) + txt += '\n' txt += 'common options: ' + opt } diff --git a/lib/utils/warn-deprecated.js b/lib/utils/warn-deprecated.js index fe5c5ec82..ce690f78e 100644 --- a/lib/utils/warn-deprecated.js +++ b/lib/utils/warn-deprecated.js @@ -9,14 +9,19 @@ function warnDeprecated (type) { if (!instance) { if (!deprecations[type]) { deprecations[type] = {} - messages.forEach(function (m) { log.warn(type, m) }) + messages.forEach(function (m) { + log.warn(type, m) + }) } } else { - if (!deprecations[type]) deprecations[type] = {} + if (!deprecations[type]) + deprecations[type] = {} if (!deprecations[type][instance]) { deprecations[type][instance] = true - messages.forEach(function (m) { log.warn(type, m) }) + messages.forEach(function (m) { + log.warn(type, m) + }) } } } diff --git a/lib/version.js b/lib/version.js index 0cfe5906e..98068490d 100644 --- a/lib/version.js +++ b/lib/version.js @@ -6,9 +6,9 @@ const usageUtil = require('./utils/usage.js') const completion = (opts, cb) => { const none = require('./utils/completion/none.js') const { conf: { argv: { remain } } } = opts - if (remain.length > 2) { + if (remain.length > 2) return none(opts, cb) - } + return cb(null, [ 'major', 'minor', @@ -17,7 +17,7 @@ const completion = (opts, cb) => { 'preminor', 'prepatch', 'prerelease', - 'from-git' + 'from-git', ]) } @@ -39,7 +39,7 @@ const version = async args => { case 1: return output(await libversion(args[0], { ...npm.flatOptions, - path: npm.prefix + path: npm.prefix, })) default: throw version.usage @@ -57,13 +57,12 @@ const list = async () => { .then(data => JSON.parse(data)) .catch(() => ({})) - if (pkg.name && pkg.version) { + if (pkg.name && pkg.version) results[pkg.name] = pkg.version - } + results.npm = npm.version - for (const [key, version] of Object.entries(process.versions)) { + for (const [key, version] of Object.entries(process.versions)) results[key] = version - } output(npm.flatOptions.json ? JSON.stringify(results, null, 2) : results) } diff --git a/lib/view.js b/lib/view.js index b8c22cd6a..141514776 100644 --- a/lib/view.js +++ b/lib/view.js @@ -40,57 +40,62 @@ const completion = async (opts, cb) => { function getFields (d, f, pref) { f = f || [] - if (!d) return f + if (!d) + return f pref = pref || [] Object.keys(d).forEach(function (k) { - if (k.charAt(0) === '_' || k.indexOf('.') !== -1) return + 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(function (val, i) { const pi = p + '[' + i + ']' - if (val && typeof val === 'object') getFields(val, f, [p]) - else f.push(pi) + if (val && typeof val === 'object') + getFields(val, f, [p]) + else + f.push(pi) }) return } - if (typeof d[k] === 'object') getFields(d[k], f, [p]) + if (typeof d[k] === 'object') + getFields(d[k], f, [p]) }) return f } } const view = async args => { - if (!args.length) args = ['.'] + if (!args.length) + args = ['.'] const opts = { ...npm.flatOptions, preferOnline: true, fullMetadata: true } const pkg = args.shift() let nv - if (/^[.]@/.test(pkg)) { + if (/^[.]@/.test(pkg)) nv = npa.resolve(null, pkg.slice(2)) - } else { + else nv = npa(pkg) - } + const name = nv.name const local = (name === '.' || !name) - if (opts.global && local) { + if (opts.global && local) throw new Error('Cannot use view command in global mode.') - } if (local) { const dir = npm.prefix const manifest = await readJson(path.resolve(dir, 'package.json')) - if (!manifest || !manifest.name) throw new Error('Invalid package.json') + if (!manifest || !manifest.name) + throw new Error('Invalid package.json') const p = manifest.name nv = npa(p) - if (pkg && ~pkg.indexOf('@')) { + if (pkg && ~pkg.indexOf('@')) nv.rawSpec = pkg.split('@')[pkg.indexOf('@')] - } + await fetchAndRead(nv, args, opts) - } else { + } else await fetchAndRead(nv, args, opts) - } } const fetchAndRead = async (nv, args, opts) => { @@ -99,9 +104,8 @@ const fetchAndRead = async (nv, args, opts) => { const pckmnt = await packument(nv, 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 @@ -115,20 +119,20 @@ const fetchAndRead = async (nv, args, opts) => { const results = [] const versions = pckmnt.versions || {} pckmnt.versions = Object.keys(versions).sort(semver.compareLoose) - if (!args.length) args = [''] + if (!args.length) + args = [''] // remove readme unless we asked for it - if (args.indexOf('readme') === -1) { + if (args.indexOf('readme') === -1) delete pckmnt.readme - } Object.keys(versions).forEach(function (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 - } + results.push(showFields(pckmnt, versions[v], arg)) }) } @@ -186,12 +190,12 @@ const prettyView = async (packument, manifest, opts) => { }), publisher: manifest._npmUser && unparsePerson({ name: color.yellow(manifest._npmUser.name), - email: color.cyan(manifest._npmUser.email) + email: color.cyan(manifest._npmUser.email), }), modified: packument.time ? color.yellow(relativeDate(packument.time[packument.version])) : undefined, maintainers: (packument.maintainers || []).map((u) => unparsePerson({ name: color.yellow(u.name), - email: color.cyan(u.email) + email: color.cyan(u.email), })), repo: ( manifest.bugs && (manifest.bugs.url || manifest.bugs) @@ -206,13 +210,13 @@ const prettyView = async (packument, manifest, opts) => { shasum: color.yellow(manifest.dist.shasum), integrity: manifest.dist.integrity && color.yellow(manifest.dist.integrity), fileCount: manifest.dist.fileCount && color.yellow(manifest.dist.fileCount), - unpackedSize: unpackedSize && color.yellow(unpackedSize.value) + ' ' + unpackedSize.unit + unpackedSize: unpackedSize && color.yellow(unpackedSize.value) + ' ' + unpackedSize.unit, } - 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( style.underline(style.bright(`${info.name}@${info.version}`)) + @@ -221,9 +225,8 @@ const prettyView = async (packument, manifest, opts) => { ' | 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( @@ -254,9 +257,8 @@ const prettyView = async (packument, manifest, opts) => { 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) { @@ -271,8 +273,10 @@ const prettyView = async (packument, manifest, opts) => { if (info.publisher || info.modified) { let publishInfo = 'published' - if (info.modified) { publishInfo += ` ${info.modified}` } - if (info.publisher) { publishInfo += ` by ${info.publisher}` } + if (info.modified) + publishInfo += ` ${info.modified}` + if (info.publisher) + publishInfo += ` by ${info.publisher}` console.log('') console.log(publishInfo) } @@ -313,7 +317,8 @@ function showFields (data, version, fields) { function search (data, fields, version, title) { let field const tail = fields - while (!field && fields.length) field = tail.shift() + while (!field && fields.length) + field = tail.shift() fields = [field].concat(tail) let o if (!field && !tail.length) { @@ -326,16 +331,15 @@ function search (data, fields, version, title) { if (index) { field = index[1] index = index[2] - if (data[field] && data[field][index]) { + if (data[field] && data[field][index]) return search(data[field][index], tail, version, title) - } else { + else field = field + '[' + index + ']' - } } if (Array.isArray(data)) { - if (data.length === 1) { + if (data.length === 1) return search(data[0], fields, version, title) - } + let results = [] data.forEach(function (data, i) { const tl = title.length @@ -346,7 +350,8 @@ function search (data, fields, version, title) { results = results.reduce(reducer, {}) return results } - if (!data[field]) return undefined + if (!data[field]) + return undefined data = data[field] if (tail.length) { // there are more fields to deal with. @@ -368,23 +373,24 @@ async function printData (data, name, opts) { versions.forEach(function (v) { const fields = Object.keys(data[v]) includeFields = includeFields || (fields.length > 1) - if (opts.json) msgJson.push({}) + if (opts.json) + msgJson.push({}) fields.forEach(function (f) { let d = cleanup(data[v][f]) - if (fields.length === 1 && opts.json) { + if (fields.length === 1 && opts.json) msgJson[msgJson.length - 1][f] = d - } + if (includeVersions || includeFields || typeof d !== 'string') { - if (opts.json) { + if (opts.json) msgJson[msgJson.length - 1][f] = d - } else { + else d = inspect(d, { showHidden: false, depth: 5, colors: npm.color, maxArrayLength: null }) - } - } else if (typeof d === 'string' && opts.json) { + } else if (typeof d === 'string' && opts.json) d = JSON.stringify(d) - } + if (!opts.json) { - if (f && includeFields) f += ' = ' + if (f && includeFields) + f += ' = ' msg += (includeVersions ? name + '@' + v + ' ' : '') + (includeFields ? f : '') + d + '\n' } @@ -394,13 +400,14 @@ async function printData (data, name, opts) { if (opts.json) { if (msgJson.length && Object.keys(msgJson[0]).length === 1) { const k = Object.keys(msgJson[0])[0] - msgJson = msgJson.map(function (m) { return m[k] }) + msgJson = msgJson.map(function (m) { + return 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' - } } // disable the progress bar entirely, as we can't meaningfully update it if @@ -408,23 +415,25 @@ async function printData (data, name, opts) { log.disableProgress() // only log if there is something to log - if (msg !== '') console.log(msg.trim()) + if (msg !== '') + console.log(msg.trim()) } function cleanup (data) { - if (Array.isArray(data)) { + if (Array.isArray(data)) return data.map(cleanup) - } - if (!data || typeof data !== 'object') return data + + 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 } function unparsePerson (d) { |