function access(args, cb) {
var cmd = args.shift()
var params
return parseParams(cmd, args, function (err, p) {
if (err) { return cb(err) }
params = p
return mapToRegistry(params.package, npm.config, invokeCmd)
})
function invokeCmd (err, uri, auth, base) {
if (err) { return cb(err) }
params.auth = auth
try {
return npm.registry.access(cmd, uri, params, function (err, data) {
if (!err && data) {
output(JSON.stringify(data, undefined, 2))
}
cb(err, data)
})
} catch (e) {
cb(e.message + '\n\nUsage:\n' + access.usage)
}
}
}...
return mapToRegistry(params.package, npm.config, invokeCmd)
})
function invokeCmd (err, uri, auth, base) {
if (err) { return cb(err) }
params.auth = auth
try {
return npm.registry.access(cmd, uri, params, function (err, data) {
if (!err && data) {
output(JSON.stringify(data, undefined, 2))
}
cb(err, data)
})
} catch (e) {
cb(e.message + '\n\nUsage:\n' + access.usage)
...function allPackageMetadata(staleness) {
var stream = ms.through.obj()
mapToRegistry('-/all', npm.config, function (er, uri, auth) {
if (er) return stream.emit('error', er)
var cacheBase = cacheFile(npm.config.get('cache'))(uri)
var cachePath = path.join(cacheBase, '.cache.json')
createEntryStream(cachePath, uri, auth, staleness, function (err, entryStream, latest, newEntries) {
if (err) return stream.emit('error', err)
log.silly('all-package-metadata', 'entry stream created')
if (entryStream && newEntries) {
createCacheWriteStream(cachePath, latest, function (err, writeStream) {
if (err) return stream.emit('error', err)
log.silly('all-package-metadata', 'output stream created')
ms.pipeline.obj(entryStream, writeStream, stream)
})
} else if (entryStream) {
ms.pipeline.obj(entryStream, stream)
} else {
stream.emit('error', new Error('No search sources available'))
}
})
})
return stream
}n/a
and_finish_tracker = function (tracker, cb) {
validate('OF', [tracker, cb])
return function () {
tracker.finish()
cb.apply(null, arguments)
}
}n/a
function auditCmd(args, cb) {
if (npm.config.get('global')) {
const err = new Error('`npm audit` does not support testing globals')
err.code = 'EAUDITGLOBAL'
throw err
}
if (args.length && args[0] !== 'fix') {
return cb(new Error('Invalid audit subcommand: `' + args[0] + '`\n\nUsage:\n' + auditCmd.usage))
}
return Bluebird.all([
maybeReadFile('npm-shrinkwrap.json'),
maybeReadFile('package-lock.json'),
maybeReadFile('package.json')
]).spread((shrinkwrap, lockfile, pkgJson) => {
const sw = shrinkwrap || lockfile
if (!pkgJson) {
const err = new Error('No package.json found: Cannot audit a project without a package.json')
err.code = 'EAUDITNOPJSON'
throw err
}
if (!sw) {
const err = new Error('Neither npm-shrinkwrap.json nor package-lock.json found: Cannot audit a project without a lockfile')
err.code = 'EAUDITNOLOCK'
throw err
} else if (shrinkwrap && lockfile) {
log.warn('audit', 'Both npm-shrinkwrap.json and package-lock.json exist, using npm-shrinkwrap.json.')
}
const requires = Object.assign(
{},
(pkgJson && pkgJson.dependencies) || {},
(pkgJson && pkgJson.devDependencies) || {}
)
return lockVerify(npm.prefix).then(result => {
if (result.status) return audit.generate(sw, requires)
const lockFile = shrinkwrap ? 'npm-shrinkwrap.json' : 'package-lock.json'
const err = new Error(`Errors were found in your ${lockFile}, run npm install to fix them.\n ` +
result.errors.join('\n '))
err.code = 'ELOCKVERIFY'
throw err
})
}).then((auditReport) => {
return audit.submitForFullReport(auditReport)
}).catch(err => {
if (err.statusCode === 404 || err.statusCode >= 500) {
const ne = new Error(`Your configured registry (${npm.config.get('registry')}) does not support audit requests.`)
ne.code = 'ENOAUDIT'
ne.wrapped = err
throw ne
}
throw err
}).then((auditResult) => {
if (args[0] === 'fix') {
const actions = (auditResult.actions || []).reduce((acc, action) => {
action = filterEnv(action)
if (!action) { return acc }
if (action.isMajor) {
acc.major.add(`${action.module}@${action.target}`)
action.resolves.forEach(({id, path}) => acc.majorFixes.add(`${id}::${path}`))
} else if (action.action === 'install') {
acc.install.add(`${action.module}@${action.target}`)
action.resolves.forEach(({id, path}) => acc.installFixes.add(`${id}::${path}`))
} else if (action.action === 'update') {
const name = action.module
const version = action.target
action.resolves.forEach(vuln => {
acc.updateFixes.add(`${vuln.id}::${vuln.path}`)
const modPath = vuln.path.split('>')
const newPath = modPath.slice(
0, modPath.indexOf(name)
).concat(`${name}@${version}`)
if (newPath.length === 1) {
acc.install.add(newPath[0])
} else {
acc.update.add(newPath.join('>'))
}
})
} else if (action.action === 'review') {
action.resolves.forEach(({id, path}) => acc.review.add(`${id}::${path}`))
}
return acc
}, {
install: new Set(),
installFixes: new Set(),
update: new Set(),
updateFixes: new Set(),
major: new Set(),
majorFixes: new Set(),
review: new Set()
})
return Bluebird.try(() => {
const installMajor = npm.config.get('force')
const installCount = actions.install.size + (installMajor ? actions.major.size : 0) + actions.update.si...n/a
function bugs(args, cb) {
var n = args.length ? args[0] : '.'
fetchPackageMetadata(n, '.', {fullMetadata: true}, function (er, d) {
if (er) return cb(er)
var url = d.bugs && ((typeof d.bugs === 'string') ? d.bugs : d.bugs.url)
if (!url) {
url = 'https://www.npmjs.org/package/' + d.name
}
log.silly('bugs', 'url', url)
openUrl(url, 'bug list available at the following URL', cb)
})
}n/a
function ci(args, cb) {
return new Installer({
config: npm.config,
log: npmlog
})
.run()
.then(
(details) => {
npmlog.disableProgress()
console.error(`added ${details.pkgCount} packages in ${
details.runTime / 1000
}s`)
}
)
.then(() => cb(), cb)
}n/a
function completion(args, cb) {
if (isWindowsShell) {
var e = new Error('npm completion supported only in MINGW / Git bash on Windows')
e.code = 'ENOTSUP'
e.errno = require('constants').ENOTSUP // eslint-disable-line node/no-deprecated-api
return cb(e)
}
// if the COMP_* isn't in the env, then just dump the script.
if (process.env.COMP_CWORD === undefined ||
process.env.COMP_LINE === undefined ||
process.env.COMP_POINT === undefined) {
return dumpScript(cb)
}
console.error(process.env.COMP_CWORD)
console.error(process.env.COMP_LINE)
console.error(process.env.COMP_POINT)
// get the partial line and partial word,
// if the point isn't at the end.
// ie, tabbing at: npm foo b|ar
var w = +process.env.COMP_CWORD
var words = args.map(unescape)
var word = words[w]
var line = process.env.COMP_LINE
var point = +process.env.COMP_POINT
var partialLine = line.substr(0, point)
var partialWords = words.slice(0, w)
// figure out where in that last word the point is.
var partialWord = args[w]
var i = partialWord.length
while (partialWord.substr(0, i) !== partialLine.substr(-1 * i) && i > 0) {
i--
}
partialWord = unescape(partialWord.substr(0, i))
partialWords.push(partialWord)
var opts = {
words: words,
w: w,
word: word,
line: line,
lineLength: line.length,
point: point,
partialLine: partialLine,
partialWords: partialWords,
partialWord: partialWord,
raw: args
}
cb = wrapCb(cb, opts)
console.error(opts)
if (partialWords.slice(0, -1).indexOf('--') === -1) {
if (word.charAt(0) === '-') return configCompl(opts, cb)
if (words[w - 1] &&
words[w - 1].charAt(0) === '-' &&
!isFlag(words[w - 1])) {
// awaiting a value for a non-bool config.
// don't even try to do this for now
console.error('configValueCompl')
return configValueCompl(opts, cb)
}
}
// try to find the npm command.
// it's the first thing after all the configs.
// take a little shortcut and use npm's arg parsing logic.
// don't have to worry about the last arg being implicitly
// boolean'ed, since the last block will catch that.
var parsed = opts.conf =
nopt(configTypes, shorthands, partialWords.slice(0, -1), 0)
// check if there's a command already.
console.error(parsed)
var cmd = parsed.argv.remain[1]
if (!cmd) return cmdCompl(opts, cb)
Object.keys(parsed).forEach(function (k) {
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function dedupe(args, cb) {
validate('AF', arguments)
// the /path/to/node_modules/..
var where = path.resolve(npm.dir, '..')
var dryrun = false
if (npm.command.match(/^find/)) dryrun = true
if (npm.config.get('dry-run')) dryrun = true
if (dryrun && !npm.config.get('json')) npm.config.set('parseable', true)
new Deduper(where, dryrun).run(cb)
}n/a
function deprecate(args, cb) {
var pkg = args[0]
var msg = args[1]
if (msg === undefined) return cb('Usage: ' + deprecate.usage)
// fetch the data and make sure it exists.
var p = npa(pkg)
// npa makes the default spec "latest", but for deprecation
// "*" is the appropriate default.
var spec = p.rawSpec === '' ? '*' : p.fetchSpec
mapToRegistry(p.name, npm.config, function (er, uri, auth) {
if (er) return cb(er)
var params = {
version: spec,
message: msg,
auth: auth
}
npm.registry.deprecate(uri, params, cb)
})
}...
if (er) return cb(er)
var params = {
version: spec,
message: msg,
auth: auth
}
npm.registry.deprecate(uri, params, cb)
})
}
...deref = function (c) {
if (!c) return ''
if (c.match(/[A-Z]/)) {
c = c.replace(/([A-Z])/g, function (m) {
return '-' + m.toLowerCase()
})
}
if (plumbing.indexOf(c) !== -1) return c
var a = abbrevs[c]
while (aliases[a]) {
a = aliases[a]
}
return a
}...
process.argv.splice(1, 1, 'npm', '-g')
}
log.verbose('cli', process.argv)
var conf = nopt(types, shorthands)
npm.argv = conf.argv.remain
if (npm.deref(npm.argv[0])) npm.command = npm.argv.shift()
else conf.usage = true
if (conf.version) {
console.log(npm.version)
return errorHandler.exit(0)
}
...diff_trees = function (oldTree, newTree, differences, log, next) {
validate('OOAOF', arguments)
pushAll(differences, sortActions(diffTrees(oldTree, newTree)))
log.finish()
next()
}n/a
function edit(args, cb) {
var p = args[0]
if (args.length !== 1 || !p) return cb(edit.usage)
var e = npm.config.get('editor')
if (!e) {
return cb(new Error(
"No editor set. Set the 'editor' config, or $EDITOR environ."
))
}
p = p.split('/')
.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)
editor(f, { editor: e }, noProgressTillDone(function (er) {
if (er) return cb(er)
npm.commands.rebuild(args, cb)
}))
})
}n/a
function errorHandler(er) {
log.disableProgress()
if (!npm.config || !npm.config.loaded) {
// logging won't work unless we pretend that it's ready
er = er || new Error('Exit prior to config file resolving.')
console.error(er.stack || er.message)
}
if (cbCalled) {
er = er || new Error('Callback called more than once.')
}
cbCalled = true
if (!er) return exit(0)
if (typeof er === 'string') {
log.error('', er)
return exit(1, true)
} else if (!(er instanceof Error)) {
log.error('weird error', er)
return exit(1, true)
}
var m = er.code || er.message.match(/^(?:Error: )?(E[A-Z]+)/)
if (m && !er.code) {
er.code = m
}
;[
'type',
'stack',
'statusCode',
'pkgid'
].forEach(function (k) {
var v = er[k]
if (!v) return
log.verbose(k, v)
})
log.verbose('cwd', process.cwd())
var os = require('os')
log.verbose('', os.type() + ' ' + os.release())
log.verbose('argv', process.argv.map(JSON.stringify).join(' '))
log.verbose('node', process.version)
log.verbose('npm ', 'v' + npm.version)
;[
'file',
'path',
'code',
'errno',
'syscall'
].forEach(function (k) {
var v = er[k]
if (v) log.error(k, v)
})
var msg = errorMessage(er)
msg.summary.concat(msg.detail).forEach(function (errline) {
log.error.apply(log, errline)
})
if (npm.config.get('json')) {
var error = {
error: {
code: er.code,
summary: messageText(msg.summary),
detail: messageText(msg.detail)
}
}
console.log(JSON.stringify(error, null, 2))
}
exit(typeof er.errno === 'number' ? er.errno : 1)
}n/a
function fsAccessImplementation(dir, done) {
done = inflight('exists:' + dir, done)
if (!done) return
fs.access(dir, fs.F_OK, done)
}n/a
function explore(args, cb) {
if (args.length < 1 || !args[0]) return cb(explore.usage)
var p = args.shift()
var cwd = path.resolve(npm.dir, p)
var opts = {cwd: cwd, stdio: 'inherit'}
var shellArgs = []
if (args) {
if (isWindowsShell) {
var execCmd = escapeExecPath(args.shift())
var execArgs = [execCmd].concat(args.map(escapeArg))
opts.windowsVerbatimArguments = true
shellArgs = ['/d', '/s', '/c'].concat(execArgs)
} else {
shellArgs.unshift('-c')
shellArgs = ['-c', args.map(escapeArg).join(' ').trim()]
}
}
var sh = npm.config.get('shell')
fs.stat(cwd, function (er, s) {
if (er || !s.isDirectory()) {
return cb(new Error(
"It doesn't look like " + p + ' is installed.'
))
}
if (!shellArgs.length) {
output(
'\nExploring ' + cwd + '\n' +
"Type 'exit' or ^D when finished\n"
)
}
var shell = spawn(sh, shellArgs, opts)
shell.on('close', function (er) {
// only fail if non-interactive.
if (!shellArgs.length) return cb()
cb(er)
})
})
}n/a
function extract(staging, pkg, log) {
log.silly('extract', packageId(pkg))
const extractTo = moduleStagingPath(staging, pkg)
if (!pacoteOpts) {
pacoteOpts = require('../../config/pacote')
}
const opts = pacoteOpts({
integrity: pkg.package._integrity,
resolved: pkg.package._resolved
})
const args = [
pkg.package._requested,
extractTo,
opts
]
return BB.fromNode((cb) => {
let launcher = localWorker
let msg = args
const spec = typeof args[0] === 'string' ? npa(args[0]) : args[0]
args[0] = spec.raw
if (ENABLE_WORKERS && (isRegistry(spec) || spec.type === 'remote')) {
// We can't serialize these options
opts.loglevel = opts.log.level
opts.log = null
opts.dirPacker = null
// workers will run things in parallel!
launcher = workers
try {
msg = JSON.stringify(msg)
} catch (e) {
return cb(e)
}
}
launcher(msg, cb)
}).then(() => {
if (pkg.package.bundleDependencies || anyBundled(pkg)) {
return readBundled(pkg, staging, extractTo)
}
}).then(() => {
return gentlyRm(path.join(extractTo, 'node_modules'))
})
}...
})
}
cache.unpack = unpack
function unpack (pkg, ver, unpackTarget, dmode, fmode, uid, gid) {
return unbuild([unpackTarget], true).then(() => {
const opts = pacoteOpts({dmode, fmode, uid, gid, offline: true})
return pacote.extract(npa.resolve(pkg, ver), unpackTarget, opts)
})
}
...function limited() {
var self = this
var args = Array.prototype.slice.call(arguments)
if (running >= maxRunning) {
queue.push({self: this, args: args})
return
}
var cb = typeof args[args.length-1] === 'function' && args.pop()
++ running
args.push(function () {
var cbargs = arguments
-- running
cb && process.nextTick(function () {
cb.apply(self, cbargs)
})
if (queue.length) {
var next = queue.shift()
limited.apply(next.self, next.args)
}
})
func.apply(self, args)
}n/a
finalize = function (staging, pkg, log) {
log.silly('finalize', pkg.realpath)
const extractedTo = moduleStagingPath(staging, pkg)
const delpath = path.join(path.dirname(pkg.realpath), '.' + path.basename(pkg.realpath) + '.DELETE')
let movedDestAway = false
const requested = pkg.package._requested || getRequested(pkg)
if (requested.type === 'directory') {
const relative = path.relative(path.dirname(pkg.path), pkg.realpath)
return makeParentPath(pkg.path)
.then(() => symlink(relative, pkg.path, 'junction'))
.catch((ex) => {
return rimraf(pkg.path).then(() => symlink(relative, pkg.path, 'junction'))
})
} else {
return makeParentPath(pkg.realpath)
.then(moveStagingToDestination)
.then(restoreOldNodeModules)
.catch((err) => {
if (movedDestAway) {
return rimraf(pkg.realpath).then(moveOldDestinationBack).then(() => {
throw err
})
} else {
throw err
}
})
.then(() => rimraf(delpath))
}
function makeParentPath (dir) {
return mkdirp(path.dirname(dir))
}
function moveStagingToDestination () {
return destinationIsClear()
.then(actuallyMoveStaging)
.catch(() => moveOldDestinationAway().then(actuallyMoveStaging))
}
function destinationIsClear () {
return lstat(pkg.realpath).then(() => {
throw new Error('destination exists')
}, () => {})
}
function actuallyMoveStaging () {
return move(extractedTo, pkg.realpath, moveOpts)
}
function moveOldDestinationAway () {
return rimraf(delpath).then(() => {
return move(pkg.realpath, delpath, moveOpts)
}).then(() => { movedDestAway = true })
}
function moveOldDestinationBack () {
return move(delpath, pkg.realpath, moveOpts).then(() => { movedDestAway = false })
}
function restoreOldNodeModules () {
if (!movedDestAway) return
return readdir(path.join(delpath, 'node_modules')).catch(() => []).then((modules) => {
if (!modules.length) return
return mkdirp(path.join(pkg.realpath, 'node_modules')).then(() => Bluebird.map(modules, (file) => {
const from = path.join(delpath, 'node_modules', file)
const to = path.join(pkg.realpath, 'node_modules', file)
return move(from, to, moveOpts)
}))
})
}
}n/a
function flattenTree(tree) {
validate('O', arguments)
var seen = new Set()
var flat = {}
var todo = [[tree, '/']]
while (todo.length) {
var next = todo.shift()
var pkg = next[0]
seen.add(pkg)
var path = next[1]
flat[path] = pkg
if (path !== '/') path += '/'
for (var ii = 0; ii < pkg.children.length; ++ii) {
var child = pkg.children[ii]
if (!seen.has(child)) {
todo.push([child, flatName(path, child)])
}
}
}
return flat
}n/a
function help(args, cb) {
var argv = npm.config.get('argv').cooked
var argnum = 0
if (args.length === 2 && ~~args[0]) {
argnum = ~~args.shift()
}
// npm help foo bar baz: search topics
if (args.length > 1 && args[0]) {
return npm.commands['help-search'](args, argnum, cb)
}
var section = npm.deref(args[0]) || args[0]
// npm help <noargs>: show basic usage
if (!section) {
var valid = argv[0] === 'help' ? 0 : 1
return npmUsage(valid, cb)
}
// npm <command> -h: show command usage
if (npm.config.get('usage') &&
npm.commands[section] &&
npm.commands[section].usage) {
npm.config.set('loglevel', 'silent')
log.level = 'silent'
output(npm.commands[section].usage)
return cb()
}
// npm apihelp <section>: Prefer section 3 over section 1
var apihelp = argv.length && argv[0].indexOf('api') !== -1
var pref = apihelp ? [3, 1, 5, 7] : [1, 3, 5, 7]
if (argnum) {
pref = [ argnum ].concat(pref.filter(function (n) {
return n !== argnum
}))
}
// npm help <section>: Try to find the path
var manroot = path.resolve(__dirname, '..', 'man')
// legacy
if (section === 'global') section = 'folders'
else if (section === 'json') section = 'package.json'
// find either /section.n or /npm-section.n
// The glob is used in the glob. The regexp is used much
// further down. Globs and regexps are different
var compextglob = '.+(gz|bz2|lzma|[FYzZ]|xz)'
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 (!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)
return man
})
viewMan(pickMan(mans, pref), cb)
})
}...
hits: found,
totalHits: totalHits
})
})
// if only one result, then just show that help section.
if (results.length === 1) {
return npm.commands.help([results[0].file.replace(/\.md$/, '')], cb)
}
if (results.length === 0) {
output('No results for ' + args.map(JSON.stringify).join(' '))
return cb()
}
...function install(where, args, cb) {
if (!cb) {
cb = args
args = where
where = null
}
var globalTop = path.resolve(npm.globalDir, '..')
if (!where) {
where = npm.config.get('global')
? globalTop
: npm.prefix
}
validate('SAF', [where, args, cb])
// the /path/to/node_modules/..
var dryrun = !!npm.config.get('dry-run')
if (npm.config.get('dev')) {
log.warn('install', 'Usage of the `--dev` option is deprecated. Use `--only=dev` instead.')
}
if (where === globalTop && !args.length) {
args = ['.']
}
args = args.filter(function (a) {
return path.resolve(a) !== npm.prefix
})
new Installer(where, dryrun, args).run(cb)
}...
}
// if it's a folder, a random not-installed thing, or not a scoped package,
// then link or install it first
if (pkg[0] !== '@' && (pkg.indexOf('/') !== -1 || pkg.indexOf('\\') !== -1)) {
return fs.lstat(path.resolve(pkg), function (er, st) {
if (er || !st.isDirectory()) {
npm.commands.install(t, pkg, n)
} else {
rp = path.resolve(pkg)
linkPkg(rp, n)
}
})
}
...function link(args, cb) {
if (process.platform === 'win32') {
var semver = require('semver')
if (!semver.gte(process.version, '0.7.9')) {
var msg = 'npm link not supported on windows prior to node 0.7.9'
var e = new Error(msg)
e.code = 'ENOTSUP'
e.errno = require('constants').ENOTSUP // eslint-disable-line node/no-deprecated-api
return cb(e)
}
}
if (npm.config.get('global')) {
return cb(new Error(
'link should never be --global.\n' +
'Please re-run this command with --local'
))
}
if (args.length === 1 && args[0] === '.') args = []
if (args.length) return linkInstall(args, cb)
linkPkg(npm.prefix, cb)
}n/a
load = function (cli, cb_) {
if (!cb_ && typeof cli === 'function') {
cb_ = cli
cli = {}
}
if (!cb_) cb_ = function () {}
if (!cli) cli = {}
loadListeners.push(cb_)
if (loaded || loadErr) return cb(loadErr)
if (loading) return
loading = true
var onload = true
function cb (er) {
if (loadErr) return
loadErr = er
if (er) return cb_(er)
if (npm.config.get('force')) {
log.warn('using --force', 'I sure hope you know what you are doing.')
}
npm.config.loaded = true
loaded = true
loadCb(loadErr = er)
onload = onload && npm.config.get('onload-script')
if (onload) {
try {
require(onload)
} catch (err) {
log.warn('onload-script', 'failed to require onload script', onload)
log.warn('onload-script', err)
}
onload = false
}
}
log.pause()
load(npm, cli, cb)
}...
npm.argv.unshift(npm.command)
npm.command = 'help'
}
// now actually fire up npm and run the command.
// this is how to use npm programmatically:
conf._exit = true
npm.load(conf, function (er) {
if (er) return errorHandler(er)
if (!unsupported.checkVersion(process.version).unsupported) {
const pkg = require('../package.json')
let notifier = require('update-notifier')({pkg})
if (
notifier.update &&
notifier.update.latest !== pkg.version
...function ls(args, silent, cb) {
if (typeof cb !== 'function') {
cb = silent
silent = false
}
var dir = path.resolve(npm.dir, '..')
readPackageTree(dir, function (_, physicalTree) {
if (!physicalTree) physicalTree = {package: {}, path: dir}
physicalTree.isTop = true
readShrinkwrap.andInflate(physicalTree, function () {
lsFromTree(dir, computeMetadata(physicalTree), args, silent, cb)
})
})
}...
npm.config.get('unicode') ? ' ➜ ' : ' -> '
} ${hook.endpoint}`)
}
})
}
function ls (pkg) {
return hookApi.ls(pkg, config())
.then((hooks) => {
if (npm.config.get('json')) {
output(JSON.stringify(hooks, null, 2))
} else if (!hooks.length) {
output("You don't have any hooks configured yet.")
} else {
if (hooks.length === 1) {
...mutate_into_logical_tree = function (tree) {
validate('O', arguments)
validateAllPeerDeps(tree, function (tree, pkgname, version) {
if (!tree.missingPeers) tree.missingPeers = {}
tree.missingPeers[pkgname] = version
})
var flat = flattenTree(tree)
Object.keys(flat).sort().forEach(function (flatname) {
var node = flat[flatname]
if (!(node.requiredBy && node.requiredBy.length)) return
if (node.parent) {
// If a node is a cycle that never reaches the root of the logical
// tree then we'll leave it attached to the root, or else it
// would go missing. Further we'll note that this is the node in the
// cycle that we picked arbitrarily to be the one attached to the root.
// others will fall
if (isDisconnectedCycle(node)) {
node.cycleTop = true
// Nor do we want to disconnect non-cyclical extraneous modules from the tree.
} else if (node.requiredBy.length) {
// regular deps though, we do, as we're moving them into the capable
// hands of the modules that require them.
node.parent.children = without(node.parent.children, node)
}
}
node.requiredBy.forEach(function (parentNode) {
parentNode.children = union(parentNode.children, [node])
})
})
return tree
}n/a
function owner(args, cb) {
var action = args.shift()
switch (action) {
case 'ls': case 'list': return ls(args[0], cb)
case 'add': return add(args[0], args[1], cb)
case 'rm': case 'remove': return rm(args[0], args[1], cb)
default: return unknown(action, cb)
}
}n/a
function pack(args, silent, cb) {
const cwd = process.cwd()
if (typeof cb !== 'function') {
cb = silent
silent = false
}
if (args.length === 0) args = ['.']
BB.all(
args.map((arg) => pack_(arg, cwd))
).then((tarballs) => {
if (!silent && npm.config.get('json')) {
output(JSON.stringify(tarballs, null, 2))
} else if (!silent) {
tarballs.forEach(logContents)
output(tarballs.map((f) => path.relative(cwd, f.filename)).join('\n'))
}
return tarballs
}).nodeify(cb)
}n/a
parse_json = function (content) {
return parseJsonWithErrors(stripBOM(content))
}n/a
function profileCmd(args, cb) {
if (args.length === 0) return cb(new Error(profileCmd.usage))
log.gauge.show('profile')
switch (args[0]) {
case 'enable-2fa':
case 'enable-tfa':
case 'enable2fa':
case 'enabletfa':
withCb(enable2fa(args.slice(1)), cb)
break
case 'disable-2fa':
case 'disable-tfa':
case 'disable2fa':
case 'disabletfa':
withCb(disable2fa(), cb)
break
case 'get':
withCb(get(args.slice(1)), cb)
break
case 'set':
withCb(set(args.slice(1)), cb)
break
default:
cb(new Error('Unknown profile command: ' + args[0]))
}
}n/a
function prune(args, cb) {
var dryrun = !!npm.config.get('dry-run')
new Pruner('.', dryrun, args).run(cb)
}n/a
function publish(args, isRetry, cb) {
if (typeof cb !== 'function') {
cb = isRetry
isRetry = false
}
if (args.length === 0) args = ['.']
if (args.length !== 1) return cb(publish.usage)
log.verbose('publish', args)
const t = npm.config.get('tag').trim()
if (semver.validRange(t)) {
return cb(new Error('Tag name must not be a valid SemVer range: ' + t))
}
return publish_(args[0])
.then((tarball) => {
const silent = log.level === 'silent'
if (!silent && npm.config.get('json')) {
output(JSON.stringify(tarball, null, 2))
} else if (!silent) {
output(`+ ${tarball.id}`)
}
})
.nodeify(cb)
}...
if (npm.config.get('dry-run')) {
log.verbose('publish', '--dry-run mode enabled. Skipping upload.')
return BB.resolve()
}
log.showProgress('publish:' + pkg._id)
return BB.fromNode((cb) => {
registry.publish(registryBase, params, cb)
}).catch((err) => {
if (
err.code === 'EPUBLISHCONFLICT' &&
npm.config.get('force') &&
!isRetry
) {
log.warn('publish', 'Forced publish over ' + pkg._id)
...pulse_till_done = function (prefix, cb) {
validate('SF', [prefix, cb])
if (!prefix) prefix = 'network'
pulseStart(prefix)
return function () {
pulseStop()
cb.apply(null, arguments)
}
}n/a
function readShrinkwrap(child, next) {
if (child.package._shrinkwrap) return process.nextTick(next)
BB.join(
maybeReadFile('npm-shrinkwrap.json', child),
// Don't read non-root lockfiles
child.isTop && maybeReadFile('package-lock.json', child),
child.isTop && maybeReadFile('package.json', child),
(shrinkwrap, lockfile, pkgJson) => {
if (shrinkwrap && lockfile) {
log.warn('read-shrinkwrap', 'Ignoring package-lock.json because there is already an npm-shrinkwrap.json. Please use only
one of the two.')
}
const name = shrinkwrap ? 'npm-shrinkwrap.json' : 'package-lock.json'
const parsed = parsePkgLock(shrinkwrap || lockfile, name)
if (parsed && parsed.lockfileVersion !== PKGLOCK_VERSION) {
log.warn('read-shrinkwrap', `This version of npm is compatible with lockfileVersion@${PKGLOCK_VERSION}, but ${name} was
generated for lockfileVersion@${parsed.lockfileVersion || 0}. I'll try to do my best with it!`)
}
child.package._shrinkwrap = parsed
}
).then(() => next(), next)
}n/a
function rebuild(args, cb) {
var opt = { depth: npm.config.get('depth'), dev: true }
readInstalled(npm.prefix, opt, function (er, data) {
log.info('readInstalled', typeof data)
if (er) return cb(er)
var set = filter(data, args)
var folders = Object.keys(set).filter(function (f) {
return f !== npm.prefix
})
if (!folders.length) return cb()
log.silly('rebuild set', folders)
cleanBuild(folders, set, cb)
})
}...
.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)
editor(f, { editor: e }, noProgressTillDone(function (er) {
if (er) return cb(er)
npm.commands.rebuild(args, cb)
}))
})
}
...function repo(args, cb) {
var n = args.length ? args[0] : '.'
fetchPackageMetadata(n, '.', {fullMetadata: true}, function (er, d) {
if (er) return cb(er)
getUrlAndOpen(d, cb)
})
}n/a
function CMD(args, cb) {
npm.commands['run-script']([stage].concat(args), cb)
}n/a
function runScript(args, cb) {
if (!args.length) return list(cb)
var pkgdir = npm.localPrefix
var cmd = args.shift()
readJson(path.resolve(pkgdir, 'package.json'), function (er, d) {
if (er) return cb(er)
run(d, pkgdir, cmd, args, cb)
})
}n/a
function SaveStack(fn) {
Error.call(this)
Error.captureStackTrace(this, fn || SaveStack)
}n/a
function search(args, cb) {
var searchOpts = {
description: npm.config.get('description'),
exclude: prepareExcludes(npm.config.get('searchexclude')),
include: prepareIncludes(args, npm.config.get('searchopts')),
limit: npm.config.get('searchlimit'),
log: log,
staleness: npm.config.get('searchstaleness'),
unicode: npm.config.get('unicode')
}
if (searchOpts.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
var anyOutput = false
var entriesStream = ms.through.obj()
var esearchWritten = false
esearch(searchOpts).on('data', function (pkg) {
entriesStream.write(pkg)
!esearchWritten && (esearchWritten = true)
}).on('error', function (e) {
if (esearchWritten) {
// If esearch errored after already starting output, we can't fall back.
return entriesStream.emit('error', e)
}
log.warn('search', 'fast search endpoint errored. Using old search.')
allPackageSearch(searchOpts).on('data', function (pkg) {
entriesStream.write(pkg)
}).on('error', function (e) {
entriesStream.emit('error', e)
}).on('end', function () {
entriesStream.end()
})
}).on('end', function () {
entriesStream.end()
})
// Grab a configured output stream that will spit out packages in the
// desired format.
var outputStream = formatPackageStream({
args: args, // --searchinclude options are not highlighted
long: npm.config.get('long'),
description: npm.config.get('description'),
json: npm.config.get('json'),
parseable: npm.config.get('parseable'),
color: npm.color
})
outputStream.on('data', function (chunk) {
if (!anyOutput) { anyOutput = true }
output(chunk.toString('utf8'))
})
log.silly('search', 'searching packages')
ms.pipe(entriesStream, outputStream, function (er) {
if (er) return cb(er)
if (!anyOutput && !npm.config.get('json') && !npm.config.get('parseable')) {
output('No matches found for ' + (args.map(JSON.stringify).join(' ')))
}
log.silly('search', 'search completed')
log.clearProgress()
cb(null, {})
})
}n/a
function shrinkwrap(args, silent, cb) {
if (typeof cb !== 'function') {
cb = silent
silent = false
}
if (args.length) {
log.warn('shrinkwrap', "doesn't take positional args")
}
move(
path.resolve(npm.prefix, PKGLOCK),
path.resolve(npm.prefix, SHRINKWRAP),
{ Promise: BB }
).then(() => {
log.notice('', `${PKGLOCK} has been renamed to ${SHRINKWRAP}. ${SHRINKWRAP} will be used for future installations.`)
return readFile(path.resolve(npm.prefix, SHRINKWRAP)).then((d) => {
return JSON.parse(d)
})
}, (err) => {
if (err.code !== 'ENOENT') {
throw err
} else {
return readPackageTree(npm.localPrefix).then(
id.computeMetadata
).then((tree) => {
return BB.fromNode((cb) => {
createShrinkwrap(tree, {
silent,
defaultFile: SHRINKWRAP
}, cb)
})
})
}
}).then((data) => cb(null, data), cb)
}n/a
function star(args, cb) {
if (!args.length) return cb(star.usage)
var s = npm.config.get('unicode') ? '\u2605 ' : '(*)'
var u = npm.config.get('unicode') ? '\u2606 ' : '( )'
var using = !(npm.command.match(/^un/))
if (!using) s = u
asyncMap(args, function (pkg, cb) {
mapToRegistry(pkg, npm.config, function (er, uri, auth) {
if (er) return cb(er)
var params = {
starred: using,
auth: auth
}
npm.registry.star(uri, params, function (er, data, raw, req) {
if (!er) {
output(s + ' ' + pkg)
log.verbose('star', data)
}
cb(er, data, raw, req)
})
})
}, cb)
}...
mapToRegistry(pkg, npm.config, function (er, uri, auth) {
if (er) return cb(er)
var params = {
starred: using,
auth: auth
}
npm.registry.star(uri, params, function (er, data, raw, req) {
if (!er) {
output(s + ' ' + pkg)
log.verbose('star', data)
}
cb(er, data, raw, req)
})
})
...function CMD(args, cb) {
npm.commands['run-script']([stage].concat(args), cb)
}n/a
function CMD(args, cb) {
npm.commands['run-script']([stage].concat(args), cb)
}n/a
function team(args, cb) {
// Entities are in the format <scope>:<team>
var cmd = args.shift()
var entity = (args.shift() || '').split(':')
return mapToRegistry('/', npm.config, function (err, uri, auth) {
if (err) { return cb(err) }
try {
return npm.registry.team(cmd, uri, {
auth: auth,
scope: entity[0].replace(/^@/, ''), // '@' prefix on scope is optional.
team: entity[1],
user: args.shift()
}, function (err, data) {
!err && data && output(JSON.stringify(data, undefined, 2))
cb(err, data)
})
} catch (e) {
cb(e.message + '\n\nUsage:\n' + team.usage)
}
})
}...
function team (args, cb) {
// Entities are in the format <scope>:<team>
var cmd = args.shift()
var entity = (args.shift() || '').split(':')
return mapToRegistry('/', npm.config, function (err, uri, auth) {
if (err) { return cb(err) }
try {
return npm.registry.team(cmd, uri, {
auth: auth,
scope: entity[0].replace(/^@/, ''), // '@' prefix on scope is optional.
team: entity[1],
user: args.shift()
}, function (err, data) {
!err && data && output(JSON.stringify(data, undefined, 2))
cb(err, data)
...function token(args, cb) {
log.gauge.show('token')
if (args.length === 0) return withCb(list([]), cb)
switch (args[0]) {
case 'list':
case 'ls':
withCb(list(), cb)
break
case 'delete':
case 'revoke':
case 'remove':
case 'rm':
withCb(rm(args.slice(1)), cb)
break
case 'create':
withCb(create(args.slice(1)), cb)
break
default:
cb(new Error('Unknown profile command: ' + args[0]))
}
}n/a
function unbuild(args, silent, cb) {
if (typeof silent === 'function') {
cb = silent
silent = false
}
asyncMap(args, unbuild_(silent), cb)
}n/a
function uninstall(args, cb) {
validate('AF', arguments)
// the /path/to/node_modules/..
const dryrun = !!npm.config.get('dry-run')
if (args.length === 1 && args[0] === '.') args = []
const where = npm.config.get('global') || !args.length
? path.resolve(npm.globalDir, '..')
: npm.prefix
args = args.filter(function (a) {
return path.resolve(a) !== where
})
if (args.length) {
new Uninstaller(where, dryrun, args).run(cb)
} else {
// remove this package from the global space, if it's installed there
readJson(path.resolve(npm.localPrefix, 'package.json'), function (er, pkg) {
if (er && er.code !== 'ENOENT' && er.code !== 'ENOTDIR') return cb(er)
if (er) return cb(uninstall.usage)
new Uninstaller(where, dryrun, [pkg.name]).run(cb)
})
}
}n/a
function unpublish(args, cb) {
if (args.length > 1) return cb(unpublish.usage)
var thing = args.length ? npa(args[0]) : {}
var project = thing.name
var version = thing.rawSpec
log.silly('unpublish', 'args[0]', args[0])
log.silly('unpublish', 'thing', thing)
if (!version && !npm.config.get('force')) {
return cb(
'Refusing to delete entire project.\n' +
'Run with --force to do this.\n' +
unpublish.usage
)
}
if (!project || path.resolve(project) === npm.localPrefix) {
// if there's a package.json in the current folder, then
// read the package name and version out of that.
var cwdJson = path.join(npm.localPrefix, 'package.json')
return readJson(cwdJson, function (er, data) {
if (er && er.code !== 'ENOENT' && er.code !== 'ENOTDIR') return cb(er)
if (er) return cb('Usage:\n' + unpublish.usage)
log.verbose('unpublish', data)
gotProject(data.name, data.version, data.publishConfig, cb)
})
}
return gotProject(project, version, cb)
}...
if (
err.code === 'EPUBLISHCONFLICT' &&
npm.config.get('force') &&
!isRetry
) {
log.warn('publish', 'Forced publish over ' + pkg._id)
return BB.fromNode((cb) => {
npm.commands.unpublish([pkg._id], cb)
}).finally(() => {
// ignore errors. Use the force. Reach out with your feelings.
return upload(arg, pkg, true, cached).catch(() => {
// but if it fails again, then report the first error.
throw err
})
})
...validate_args = function (idealTree, args, next) {
validate('OAF', arguments)
var force = npm.config.get('force')
asyncMap(args, function (pkg, done) {
chain([
[hasMinimumFields, pkg],
[checkSelf, idealTree, pkg, force],
[isInstallable, pkg]
], done)
}, next)
}n/a
function view(args, silent, cb) {
if (typeof cb !== 'function') {
cb = silent
silent = false
}
if (!args.length) args = ['.']
var pkg = args.shift()
var nv
if (/^[.]@/.test(pkg)) {
nv = npa.resolve(null, pkg.slice(2))
} else {
nv = npa(pkg)
}
var name = nv.name
var local = (name === '.' || !name)
if (npm.config.get('global') && local) {
return cb(new Error('Cannot use view command in global mode.'))
}
if (local) {
var dir = npm.prefix
readJson(path.resolve(dir, 'package.json'), function (er, d) {
d = d || {}
if (er && er.code !== 'ENOENT' && er.code !== 'ENOTDIR') return cb(er)
if (!d.name) return cb(new Error('Invalid package.json'))
var p = d.name
nv = npa(p)
if (pkg && ~pkg.indexOf('@')) {
nv.rawSpec = pkg.split('@')[pkg.indexOf('@')]
}
fetchAndRead(nv, args, silent, cb)
})
} else {
fetchAndRead(nv, args, silent, cb)
}
}n/a
function fsAccessImplementation(dir, done) {
done = inflight('writable:' + dir, done)
if (!done) return
fs.access(dir, fs.W_OK, done)
}n/a
function access(args, cb) {
var cmd = args.shift()
var params
return parseParams(cmd, args, function (err, p) {
if (err) { return cb(err) }
params = p
return mapToRegistry(params.package, npm.config, invokeCmd)
})
function invokeCmd (err, uri, auth, base) {
if (err) { return cb(err) }
params.auth = auth
try {
return npm.registry.access(cmd, uri, params, function (err, data) {
if (!err && data) {
output(JSON.stringify(data, undefined, 2))
}
cb(err, data)
})
} catch (e) {
cb(e.message + '\n\nUsage:\n' + access.usage)
}
}
}...
return mapToRegistry(params.package, npm.config, invokeCmd)
})
function invokeCmd (err, uri, auth, base) {
if (err) { return cb(err) }
params.auth = auth
try {
return npm.registry.access(cmd, uri, params, function (err, data) {
if (!err && data) {
output(JSON.stringify(data, undefined, 2))
}
cb(err, data)
})
} catch (e) {
cb(e.message + '\n\nUsage:\n' + access.usage)
...completion = function (opts, cb) {
var argv = opts.conf.argv.remain
if (argv.length === 2) {
return cb(null, access.subcommands)
}
switch (argv[2]) {
case 'grant':
if (argv.length === 3) {
return cb(null, ['read-only', 'read-write'])
} else {
return cb(null, [])
}
case 'public':
case 'restricted':
case 'ls-packages':
case 'ls-collaborators':
case 'edit':
return cb(null, [])
case 'revoke':
return cb(null, [])
default:
return cb(new Error(argv[2] + ' not recognized'))
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function doOne(cmd, staging, pkg, log, next) {
validate('SSOOF', arguments)
const prepped = prepareAction([cmd, pkg], staging, log)
return withInit(actions[cmd], () => {
return execAction(prepped)
}).nodeify(next)
}n/a
function doParallel(type, staging, actionsToRun, log, next) {
validate('SSAOF', arguments)
const acts = actionsToRun.reduce((acc, todo) => {
if (todo[0] === type) {
acc.push(prepareAction(todo, staging, log))
}
return acc
}, [])
log.silly('doParallel', type + ' ' + acts.length)
time(log)
if (!acts.length) { return next() }
return withInit(actions[type], () => {
return BB.map(acts, execAction, {
concurrency: npm.limit.action
})
}).nodeify((err) => {
log.finish()
timeEnd(log)
next(err)
})
}n/a
function doReverseSerial(type, staging, actionsToRun, log, next) {
validate('SSAOF', arguments)
log.silly('doReverseSerial', '%s %d', type, actionsToRun.length)
runSerial(type, staging, [].concat(actionsToRun).reverse(), log, next)
}n/a
function doSerial(type, staging, actionsToRun, log, next) {
validate('SSAOF', arguments)
log.silly('doSerial', '%s %d', type, actionsToRun.length)
runSerial(type, staging, actionsToRun, log, next)
}n/a
function allPackageMetadata(staleness) {
var stream = ms.through.obj()
mapToRegistry('-/all', npm.config, function (er, uri, auth) {
if (er) return stream.emit('error', er)
var cacheBase = cacheFile(npm.config.get('cache'))(uri)
var cachePath = path.join(cacheBase, '.cache.json')
createEntryStream(cachePath, uri, auth, staleness, function (err, entryStream, latest, newEntries) {
if (err) return stream.emit('error', err)
log.silly('all-package-metadata', 'entry stream created')
if (entryStream && newEntries) {
createCacheWriteStream(cachePath, latest, function (err, writeStream) {
if (err) return stream.emit('error', err)
log.silly('all-package-metadata', 'output stream created')
ms.pipeline.obj(entryStream, writeStream, stream)
})
} else if (entryStream) {
ms.pipeline.obj(entryStream, stream)
} else {
stream.emit('error', new Error('No search sources available'))
}
})
})
return stream
}n/a
function createCacheEntryStream(cacheFile, cb) {
log.verbose('all-package-metadata', 'creating entry stream from local cache')
log.verbose('all-package-metadata', cacheFile)
fs.stat(cacheFile, function (err, stat) {
if (err) return cb(err)
// TODO - This isn't very helpful if `cacheFile` is empty or just `{}`
var entryStream = ms.pipeline.obj(
fs.createReadStream(cacheFile),
jsonstream.parse('*'),
// I believe this passthrough is necessary cause `jsonstream` returns
// weird custom streams that behave funny sometimes.
ms.through.obj()
)
extractUpdated(entryStream, 'cached-entry-stream', cb)
})
}n/a
function createCacheWriteStream(cacheFile, latest, cb) {
_ensureCacheDirExists(cacheFile, function (err) {
if (err) return cb(err)
log.silly('all-package-metadata', 'creating output stream')
var outStream = _createCacheOutStream()
var cacheFileStream = writeStreamAtomic(cacheFile)
var inputStream = _createCacheInStream(cacheFileStream, outStream, latest)
// Glue together the various streams so they fail together.
// `cacheFileStream` errors are already handled by the `inputStream`
// pipeline
var errEmitted = false
linkStreams(inputStream, outStream, function () { errEmitted = true })
cacheFileStream.on('close', function () { !errEmitted && outStream.end() })
cb(null, ms.duplex.obj(inputStream, outStream))
})
}n/a
function createEntryStream(cachePath, uri, auth, staleness, cb) {
createCacheEntryStream(cachePath, function (err, cacheStream, cacheLatest) {
cacheLatest = cacheLatest || 0
if (err) {
log.warn('', 'Failed to read search cache. Rebuilding')
log.silly('all-package-metadata', 'cache read error: ', err)
}
createEntryUpdateStream(uri, auth, staleness, cacheLatest, function (err, updateStream, updatedLatest) {
updatedLatest = updatedLatest || 0
var latest = updatedLatest || cacheLatest
if (!cacheStream && !updateStream) {
return cb(new Error('No search sources available'))
}
if (err) {
log.warn('', 'Search data request failed, search might be stale')
log.silly('all-package-metadata', 'update request error: ', err)
}
if (cacheStream && updateStream) {
// Deduped, unioned, sorted stream from the combination of both.
cb(null,
createMergedStream(cacheStream, updateStream),
latest,
!!updatedLatest)
} else {
// Either one works if one or the other failed
cb(null, cacheStream || updateStream, latest, !!updatedLatest)
}
})
})
}n/a
function createEntryUpdateStream(all, auth, staleness, latest, cb) {
log.verbose('all-package-metadata', 'creating remote entry stream')
var params = {
timeout: 600,
follow: true,
staleOk: true,
auth: auth,
streaming: true
}
var partialUpdate = false
if (latest && (Date.now() - latest < (staleness * 1000))) {
// Skip the request altogether if our `latest` isn't stale.
log.verbose('all-package-metadata', 'Local data up to date, skipping update')
return cb(null)
} else if (latest === 0) {
log.warn('', 'Building the local index for the first time, please be patient')
log.verbose('all-package-metadata', 'No cached data: requesting full metadata db')
} else {
log.verbose('all-package-metadata', 'Cached data present with timestamp:', latest, 'requesting partial index update')
all += '/since?stale=update_after&startkey=' + latest
partialUpdate = true
}
npm.registry.request(all, params, function (er, res) {
if (er) return cb(er)
log.silly('all-package-metadata', 'request stream opened, code:', res.statusCode)
// NOTE - The stream returned by `request` seems to be very persnickety
// and this is almost a magic incantation to get it to work.
// Modify how `res` is used here at your own risk.
var entryStream = ms.pipeline.obj(
res,
ms.through(function (chunk, enc, cb) {
cb(null, chunk)
}),
gunzip(),
jsonstream.parse('*', function (pkg, key) {
if (key[0] === '_updated' || key[0][0] !== '_') {
return pkg
}
})
)
if (partialUpdate) {
// The `/all/since` endpoint doesn't return `_updated`, so we
// just use the request's own timestamp.
cb(null, entryStream, Date.parse(res.headers.date))
} else {
extractUpdated(entryStream, 'entry-update-stream', cb)
}
})
}n/a
function createMergedStream(a, b) {
linkStreams(a, b)
return sortedUnionStream(b, a, function (pkg) { return pkg.name })
}n/a
and_finish_tracker = function (tracker, cb) {
validate('OF', [tracker, cb])
return function () {
tracker.finish()
cb.apply(null, arguments)
}
}n/a
now = function (tracker, cb) {
validate('OF', [tracker, cb])
tracker.finish()
cb.apply(null, Array.prototype.slice.call(arguments, 2))
}...
this.packageLockOnly = opts.packageLockOnly != null
? opts.packageLockOnly : npm.config.get('package-lock-only')
this.rollback = opts.rollback != null ? opts.rollback : npm.config.get('rollback')
this.link = opts.link != null ? opts.link : npm.config.get('link')
this.saveOnlyLock = opts.saveOnlyLock
this.global = opts.global != null ? opts.global : this.where === path.resolve(npm.globalDir, '..')
this.audit = npm.config.get('audit') && !this.global
this.started = Date.now()
}
Installer.prototype = {}
Installer.prototype.run = function (_cb) {
validate('F|', arguments)
var result
...function auditCmd(args, cb) {
if (npm.config.get('global')) {
const err = new Error('`npm audit` does not support testing globals')
err.code = 'EAUDITGLOBAL'
throw err
}
if (args.length && args[0] !== 'fix') {
return cb(new Error('Invalid audit subcommand: `' + args[0] + '`\n\nUsage:\n' + auditCmd.usage))
}
return Bluebird.all([
maybeReadFile('npm-shrinkwrap.json'),
maybeReadFile('package-lock.json'),
maybeReadFile('package.json')
]).spread((shrinkwrap, lockfile, pkgJson) => {
const sw = shrinkwrap || lockfile
if (!pkgJson) {
const err = new Error('No package.json found: Cannot audit a project without a package.json')
err.code = 'EAUDITNOPJSON'
throw err
}
if (!sw) {
const err = new Error('Neither npm-shrinkwrap.json nor package-lock.json found: Cannot audit a project without a lockfile')
err.code = 'EAUDITNOLOCK'
throw err
} else if (shrinkwrap && lockfile) {
log.warn('audit', 'Both npm-shrinkwrap.json and package-lock.json exist, using npm-shrinkwrap.json.')
}
const requires = Object.assign(
{},
(pkgJson && pkgJson.dependencies) || {},
(pkgJson && pkgJson.devDependencies) || {}
)
return lockVerify(npm.prefix).then(result => {
if (result.status) return audit.generate(sw, requires)
const lockFile = shrinkwrap ? 'npm-shrinkwrap.json' : 'package-lock.json'
const err = new Error(`Errors were found in your ${lockFile}, run npm install to fix them.\n ` +
result.errors.join('\n '))
err.code = 'ELOCKVERIFY'
throw err
})
}).then((auditReport) => {
return audit.submitForFullReport(auditReport)
}).catch(err => {
if (err.statusCode === 404 || err.statusCode >= 500) {
const ne = new Error(`Your configured registry (${npm.config.get('registry')}) does not support audit requests.`)
ne.code = 'ENOAUDIT'
ne.wrapped = err
throw ne
}
throw err
}).then((auditResult) => {
if (args[0] === 'fix') {
const actions = (auditResult.actions || []).reduce((acc, action) => {
action = filterEnv(action)
if (!action) { return acc }
if (action.isMajor) {
acc.major.add(`${action.module}@${action.target}`)
action.resolves.forEach(({id, path}) => acc.majorFixes.add(`${id}::${path}`))
} else if (action.action === 'install') {
acc.install.add(`${action.module}@${action.target}`)
action.resolves.forEach(({id, path}) => acc.installFixes.add(`${id}::${path}`))
} else if (action.action === 'update') {
const name = action.module
const version = action.target
action.resolves.forEach(vuln => {
acc.updateFixes.add(`${vuln.id}::${vuln.path}`)
const modPath = vuln.path.split('>')
const newPath = modPath.slice(
0, modPath.indexOf(name)
).concat(`${name}@${version}`)
if (newPath.length === 1) {
acc.install.add(newPath[0])
} else {
acc.update.add(newPath.join('>'))
}
})
} else if (action.action === 'review') {
action.resolves.forEach(({id, path}) => acc.review.add(`${id}::${path}`))
}
return acc
}, {
install: new Set(),
installFixes: new Set(),
update: new Set(),
updateFixes: new Set(),
major: new Set(),
majorFixes: new Set(),
review: new Set()
})
return Bluebird.try(() => {
const installMajor = npm.config.get('force')
const installCount = actions.install.size + (installMajor ? actions.major.size : 0) + actions.update.si...n/a
completion = function (opts, cb) {
const argv = opts.conf.argv.remain
switch (argv[2]) {
case 'audit':
return cb(null, [])
default:
return cb(new Error(argv[2] + ' not recognized'))
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function bugs(args, cb) {
var n = args.length ? args[0] : '.'
fetchPackageMetadata(n, '.', {fullMetadata: true}, function (er, d) {
if (er) return cb(er)
var url = d.bugs && ((typeof d.bugs === 'string') ? d.bugs : d.bugs.url)
if (!url) {
url = 'https://www.npmjs.org/package/' + d.name
}
log.silly('bugs', 'url', url)
openUrl(url, 'bug list available at the following URL', cb)
})
}n/a
completion = function (opts, cb) {
// FIXME: there used to be registry completion here, but it stopped making
// sense somewhere around 50,000 packages on the registry
cb()
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function ci(args, cb) {
return new Installer({
config: npm.config,
log: npmlog
})
.run()
.then(
(details) => {
npmlog.disableProgress()
console.error(`added ${details.pkgCount} packages in ${
details.runTime / 1000
}s`)
}
)
.then(() => cb(), cb)
}n/a
(cb) => cb(null, [])
...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...completion = function (opts, cb) {
if (opts.w > 3) return cb()
var fs = require('graceful-fs')
var path = require('path')
var bashExists = null
var zshExists = null
fs.stat(path.resolve(process.env.HOME, '.bashrc'), function (er) {
bashExists = !er
next()
})
fs.stat(path.resolve(process.env.HOME, '.zshrc'), function (er) {
zshExists = !er
next()
})
function next () {
if (zshExists === null || bashExists === null) return
var out = []
if (zshExists) out.push('~/.zshrc')
if (bashExists) out.push('~/.bashrc')
if (opts.w === 2) {
out = out.map(function (m) {
return ['>>', m]
})
}
cb(null, out)
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function gf() {
if (!gf[kMethods].length && gf[kDefaultMethod]) {
return gf[kDefaultMethod].func.apply(this, arguments)
} else {
return gf.applyGenfun(this, arguments)
}
}...
const pkg = require('../package.json')
let notifier = require('update-notifier')({pkg})
if (
notifier.update &&
notifier.update.latest !== pkg.version
) {
const color = require('ansicolors')
const useColor = npm.config.get('color')
const useUnicode = npm.config.get('unicode')
const old = notifier.update.current
const latest = notifier.update.latest
let type = notifier.update.type
if (useColor) {
switch (type) {
case 'major':
...function gf() {
if (!gf[kMethods].length && gf[kDefaultMethod]) {
return gf[kDefaultMethod].func.apply(this, arguments)
} else {
return gf.applyGenfun(this, arguments)
}
}...
} catch (e) {
return cb(new Error('no such auth module'))
}
auth.login(creds, registry, scope, function (err, newCreds) {
if (err) return cb(err)
npm.config.del('_token', 'user') // prevent legacy pollution
if (scope) npm.config.set(scope + ':registry', registry, 'user&apos
;)
npm.config.setCredentialsByURI(registry, newCreds)
npm.config.save('user', cb)
})
}
...function gf() {
if (!gf[kMethods].length && gf[kDefaultMethod]) {
return gf[kDefaultMethod].func.apply(this, arguments)
} else {
return gf.applyGenfun(this, arguments)
}
}n/a
function gf() {
if (!gf[kMethods].length && gf[kDefaultMethod]) {
return gf[kDefaultMethod].func.apply(this, arguments)
} else {
return gf.applyGenfun(this, arguments)
}
}n/a
function Conf(base) {
if (!(this instanceof Conf)) return new Conf(base)
CC.call(this)
if (base) {
if (base instanceof Conf) {
this.root = base.list[0] || base.root
} else {
this.root = base
}
} else {
this.root = configDefs.defaults
}
}n/a
function load() {
var cli, builtin, cb
for (var i = 0; i < arguments.length; i++) {
switch (typeof arguments[i]) {
case 'string': builtin = arguments[i]; break
case 'object': cli = arguments[i]; break
case 'function': cb = arguments[i]; break
}
}
if (!cb) cb = function () {}
if (exports.loaded) {
var ret = exports.loaded
if (cli) {
ret = new Conf(ret)
ret.unshift(cli)
}
return process.nextTick(cb.bind(null, null, ret))
}
// either a fresh object, or a clone of the passed in obj
if (!cli) {
cli = {}
} else {
cli = Object.keys(cli).reduce(function (c, k) {
c[k] = cli[k]
return c
}, {})
}
loadCbs.push(cb)
if (loading) return
loading = true
cb = once(function (er, conf) {
if (!er) {
exports.loaded = conf
loading = false
}
loadCbs.forEach(function (fn) {
fn(er, conf)
})
loadCbs.length = 0
})
// check for a builtin if provided.
exports.usingBuiltin = !!builtin
var rc = exports.rootConf = new Conf()
if (builtin) {
rc.addFile(builtin, 'builtin')
} else {
rc.add({}, 'builtin')
}
rc.on('load', function () {
load_(builtin, rc, cli, cb)
})
rc.on('error', cb)
}...
npm.argv.unshift(npm.command)
npm.command = 'help'
}
// now actually fire up npm and run the command.
// this is how to use npm programmatically:
conf._exit = true
npm.load(conf, function (er) {
if (er) return errorHandler(er)
if (!unsupported.checkVersion(process.version).unsupported) {
const pkg = require('../package.json')
let notifier = require('update-notifier')({pkg})
if (
notifier.update &&
notifier.update.latest !== pkg.version
...function validate(cl) {
// warn about invalid configs at every level.
cl.list.forEach(function (conf) {
nopt.clean(conf, configDefs.types)
})
nopt.clean(cl.root, configDefs.types)
}...
console.warn(m + ' ' + util.format.apply(util, [].slice.call(arguments, 1)))
} }
}
exports.Umask = Umask
function Umask () {}
function validateUmask (data, k, val) {
return umask.validate(data, k, val)
}
function validateSemver (data, k, val) {
if (!semver.valid(val)) return false
data[k] = semver.valid(val)
}
...function dedupe(args, cb) {
validate('AF', arguments)
// the /path/to/node_modules/..
var where = path.resolve(npm.dir, '..')
var dryrun = false
if (npm.command.match(/^find/)) dryrun = true
if (npm.config.get('dry-run')) dryrun = true
if (dryrun && !npm.config.get('json')) npm.config.set('parseable', true)
new Deduper(where, dryrun).run(cb)
}n/a
function Deduper(where, dryrun) {
validate('SB', arguments)
Installer.call(this, where, dryrun, [])
this.noPackageJsonOk = true
this.topLevelLifecycles = false
}n/a
function Umask() {}n/a
function deprecate(args, cb) {
var pkg = args[0]
var msg = args[1]
if (msg === undefined) return cb('Usage: ' + deprecate.usage)
// fetch the data and make sure it exists.
var p = npa(pkg)
// npa makes the default spec "latest", but for deprecation
// "*" is the appropriate default.
var spec = p.rawSpec === '' ? '*' : p.fetchSpec
mapToRegistry(p.name, npm.config, function (er, uri, auth) {
if (er) return cb(er)
var params = {
version: spec,
message: msg,
auth: auth
}
npm.registry.deprecate(uri, params, cb)
})
}...
if (er) return cb(er)
var params = {
version: spec,
message: msg,
auth: auth
}
npm.registry.deprecate(uri, params, cb)
})
}
...completion = function (opts, cb) {
// first, get a list of remote packages this user owns.
// once we have a user account, then don't complete anything.
if (opts.conf.argv.remain.length > 2) return cb()
// get the list of packages by user
var path = '/-/by-user/'
mapToRegistry(path, npm.config, function (er, uri, c) {
if (er) return cb(er)
if (!(c && c.username)) return cb()
var params = {
timeout: 60000,
auth: c
}
npm.registry.get(uri + c.username, params, function (er, list) {
if (er) return cb()
console.error(list)
return cb(null, list[c.username])
})
})
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function replaceModuleByName(obj, key, child) {
var childName = moduleName(child)
return replaceModule(obj, key, child, function (replacing, child) {
return moduleName(replacing) === childName
})
}n/a
function replaceModuleByPath(obj, key, child) {
return replaceModule(obj, key, child, function (replacing, child) {
return replacing.path === child.path
})
}n/a
function computeMetadata(tree, seen) {
if (!seen) seen = new Set()
if (!tree || seen.has(tree)) return
seen.add(tree)
if (tree.parent == null) {
resetMetadata(tree)
tree.isTop = true
}
tree.location = flatNameFromTree(tree)
function findChild (name, spec, kind) {
try {
var req = childDependencySpecifier(tree, name, spec)
} catch (err) {
return
}
var child = findRequirement(tree, req.name, req)
if (child) {
resolveWithExistingModule(child, tree)
return true
}
}
const deps = tree.package.dependencies || {}
const reqs = tree.swRequires || {}
for (let name of Object.keys(deps)) {
if (findChild(name, deps[name])) continue
if (name in reqs && findChild(name, reqs[name])) continue
tree.missingDeps[name] = deps[name]
}
if (tree.isTop) {
const devDeps = tree.package.devDependencies || {}
for (let name of Object.keys(devDeps)) {
if (findChild(name, devDeps[name])) continue
tree.missingDevDeps[name] = devDeps[name]
}
}
tree.children.filter((child) => !child.removed).forEach((child) => computeMetadata(child, seen))
return tree
}n/a
function computeVersionSpec(tree, child) {
validate('OO', arguments)
var requested
var childReq = child.package._requested
if (child.isLink) {
requested = npa.resolve(child.package.name, 'file:' + child.realpath, getTop(tree).path)
} else if (childReq && (isNotEmpty(childReq.saveSpec) || (isNotEmpty(childReq.rawSpec) && isNotEmpty(childReq.fetchSpec)))) {
requested = child.package._requested
} else if (child.package._from) {
requested = npa(child.package._from, tree.path)
} else {
requested = npa.resolve(child.package.name, child.package.version)
}
if (isRegistry(requested)) {
var version = child.package.version
var rangeDescriptor = ''
if (semver.valid(version, true) &&
semver.gte(version, '0.1.0', true) &&
!npm.config.get('save-exact')) {
rangeDescriptor = npm.config.get('save-prefix')
}
return rangeDescriptor + version
} else if (requested.type === 'directory' || requested.type === 'file') {
return 'file:' + unixFormatPath(path.relative(getTop(tree).path, requested.fetchSpec))
} else {
return requested.saveSpec || requested.rawSpec
}
}n/a
earliestInstallable = function (requiredBy, tree, pkg, log) {
validate('OOOO', arguments)
function undeletedModuleMatches (child) {
return !child.removed && moduleName(child) === pkg.name
}
const undeletedMatches = tree.children.filter(undeletedModuleMatches)
if (undeletedMatches.length) {
// if there's a conflict with another child AT THE SAME level then we're replacing it, so
// mark it as removed and continue with resolution normally.
if (tree === requiredBy) {
undeletedMatches.forEach((pkg) => {
if (pkg.fromBundle) reportBundleOverride(pkg, log)
removeObsoleteDep(pkg, log)
})
} else {
return null
}
}
// If any of the children of this tree have conflicting
// binaries then we need to decline to install this package here.
var binaryMatches = pkg.bin && tree.children.some(function (child) {
if (child.removed || !child.package.bin) return false
return Object.keys(child.package.bin).some(function (bin) {
return pkg.bin[bin]
})
})
if (binaryMatches) return null
// if this tree location requested the same module then we KNOW it
// isn't compatible because if it were findRequirement would have
// found that version.
var deps = tree.package.dependencies || {}
if (!tree.removed && requiredBy !== tree && deps[pkg.name]) {
return null
}
var devDeps = tree.package.devDependencies || {}
if (tree.isTop && devDeps[pkg.name]) {
var requested = childDependencySpecifier(tree, pkg.name, devDeps[pkg.name])
if (!doesChildVersionMatch({package: pkg}, requested, tree)) {
return null
}
}
if (tree.phantomChildren && tree.phantomChildren[pkg.name]) return null
if (tree.isTop) return tree
if (tree.isGlobal) return tree
if (npm.config.get('global-style') && tree.parent.isTop) return tree
if (npm.config.get('legacy-bundling')) return tree
if (!preserveSymlinks() && /^[.][.][\\/]/.test(path.relative(tree.parent.realpath, tree.realpath))) return tree
return (earliestInstallable(requiredBy, tree.parent, pkg, log) || tree)
}n/a
function failedDependency(tree, name, pkg) {
if (name) {
if (isDepOptional(tree, name, pkg || {})) {
return false
}
}
tree.failed = true
if (tree.isTop) return true
if (tree.userRequired) return true
if (!tree.requiredBy) return false
let anyFailed = false
for (var ii = 0; ii < tree.requiredBy.length; ++ii) {
var requireParent = tree.requiredBy[ii]
if (failedDependency(requireParent, moduleName(tree), tree)) {
anyFailed = true
}
}
return anyFailed
}n/a
findRequirement = function (tree, name, requested, requestor) {
validate('OSO', [tree, name, requested])
if (!requestor) requestor = tree
var nameMatch = function (child) {
return moduleName(child) === name && child.parent && !child.removed
}
var versionMatch = function (child) {
return doesChildVersionMatch(child, requested, requestor)
}
if (nameMatch(tree)) {
// this *is* the module, but it doesn't match the version, so a
// new copy will have to be installed
return versionMatch(tree) ? tree : null
}
var matches = tree.children.filter(nameMatch)
if (matches.length) {
matches = matches.filter(versionMatch)
// the module exists as a dependent, but the version doesn't match, so
// a new copy will have to be installed above here
if (matches.length) return matches[0]
return null
}
if (tree.isTop) return null
if (!preserveSymlinks() && /^[.][.][\\/]/.test(path.relative(tree.parent.realpath, tree.realpath))) return null
return findRequirement(tree.parent, name, requested, requestor)
}n/a
getAllMetadata = function (args, tree, where, next) {
asyncMap(args, function (arg, done) {
let spec
try {
spec = npa(arg)
} catch (e) {
return done(e)
}
if (spec.type !== 'file' && spec.type !== 'directory' && (spec.name == null || spec.rawSpec === '')) {
return fs.stat(path.join(arg, 'package.json'), (err) => {
if (err) {
var version = matchingDep(tree, spec.name)
if (version) {
try {
return fetchPackageMetadata(npa.resolve(spec.name, version), where, done)
} catch (e) {
return done(e)
}
} else {
return fetchPackageMetadata(spec, where, done)
}
} else {
try {
return fetchPackageMetadata(npa('file:' + arg), where, done)
} catch (e) {
return done(e)
}
}
})
} else {
return fetchPackageMetadata(spec, where, done)
}
}, next)
}n/a
function loadDeps(tree, log, next) {
validate('OOF', arguments)
if (tree.loaded || (tree.parent && tree.parent.failed) || tree.removed) return andFinishTracker.now(log, next)
if (tree.parent) tree.loaded = true
if (!tree.package.dependencies) tree.package.dependencies = {}
asyncMap(Object.keys(tree.package.dependencies), function (dep, done) {
var version = tree.package.dependencies[dep]
addDependency(dep, version, tree, log.newGroup('loadDep:' + dep), andHandleOptionalErrors(log, tree, dep, done))
}, andForEachChild(loadDeps, andFinishTracker(log, next)))
}n/a
loadDevDeps = function (tree, log, next) {
validate('OOF', arguments)
if (!tree.package.devDependencies) return andFinishTracker.now(log, next)
asyncMap(Object.keys(tree.package.devDependencies), function (dep, done) {
// things defined as both dev dependencies and regular dependencies are treated
// as the former
if (tree.package.dependencies[dep]) return done()
var logGroup = log.newGroup('loadDevDep:' + dep)
addDependency(dep, tree.package.devDependencies[dep], tree, logGroup, andHandleOptionalErrors(log, tree, dep, done))
}, andForEachChild(loadDeps, andFinishTracker(log, next)))
}n/a
loadExtraneous = function (tree, log, next) {
var seen = new Set()
function loadExtraneous (tree) {
if (seen.has(tree)) return
seen.add(tree)
for (var child of tree.children) {
if (child.loaded) continue
resolveWithExistingModule(child, tree)
loadExtraneous(child)
}
}
loadExtraneous(tree)
log.finish()
next()
}n/a
loadRequestedDeps = function (args, tree, saveToDependencies, log, next) {
validate('AOOF', [args, tree, log, next])
asyncMap(args, function (pkg, done) {
var depLoaded = andAddParentToErrors(tree, done)
resolveWithNewModule(pkg, tree, log.newGroup('loadRequestedDeps'), iferr(depLoaded, function (child, tracker) {
validate('OO', arguments)
if (npm.config.get('global')) {
child.isGlobal = true
}
var childName = moduleName(child)
child.saveSpec = computeVersionSpec(tree, child)
child.userRequired = true
child.save = getSaveType(tree, child)
const types = ['dependencies', 'devDependencies', 'optionalDependencies']
if (child.save) {
tree.package[child.save][childName] = child.saveSpec
// Astute readers might notice that this exact same code exists in
// save.js under a different guise. That code is responsible for deps
// being removed from the final written `package.json`. The removal in
// this function is specifically to prevent "installed as both X and Y"
// warnings when moving an existing dep between different dep fields.
//
// Or, try it by removing this loop, and do `npm i -P x && npm i -D x`
for (let saveType of types) {
if (child.save !== saveType) {
delete tree.package[saveType][childName]
}
}
if (child.save === 'optionalDependencies') tree.package.dependencies[childName] = child.saveSpec
}
// For things the user asked to install, that aren't a dependency (or
// won't be when we're done), flag it as "depending" on the user
// themselves, so we don't remove it as a dep that no longer exists
var childIsDep = addRequiredDep(tree, child)
if (!childIsDep) child.userRequired = true
depLoaded(null, child, tracker)
}))
}, andForEachChild(loadDeps, andFinishTracker(log, next)))
}n/a
function prefetchDeps(tree, deps, log, next) {
validate('OOOF', arguments)
var skipOptional = !npm.config.get('optional')
var seen = new Set()
const finished = andFinishTracker(log, next)
const fpm = BB.promisify(fetchPackageMetadata)
resolveBranchDeps(tree.package, deps).then(
() => finished(), finished
)
function resolveBranchDeps (pkg, deps) {
return BB.resolve(null).then(() => {
var allDependencies = Object.keys(deps).map((dep) => {
return npa.resolve(dep, deps[dep])
}).filter((dep) => {
return isRegistry(dep) &&
!seen.has(dep.toString()) &&
!findRequirement(tree, dep.name, dep)
})
if (skipOptional) {
var optDeps = pkg.optionalDependencies || {}
allDependencies = allDependencies.filter((dep) => !optDeps[dep.name])
}
return BB.map(allDependencies, (dep) => {
seen.add(dep.toString())
return fpm(dep, '', {tracker: log.newItem('fetchMetadata')}).then(
(pkg) => {
return pkg && pkg.dependencies && resolveBranchDeps(pkg, pkg.dependencies)
},
() => null
)
})
})
}
}n/a
removeDeps = function (args, tree, saveToDependencies, next) {
validate('AOSF|AOZF', [args, tree, saveToDependencies, next])
for (let pkg of args) {
var pkgName = moduleName(pkg)
var toRemove = tree.children.filter(moduleNameMatches(pkgName))
var pkgToRemove = toRemove[0] || createChild({package: {name: pkgName}})
var saveType = getSaveType(tree, pkg) || 'dependencies'
if (tree.isTop && saveToDependencies) {
pkgToRemove.save = saveType
}
if (tree.package[saveType][pkgName]) {
delete tree.package[saveType][pkgName]
if (saveType === 'optionalDependencies' && tree.package.dependencies[pkgName]) {
delete tree.package.dependencies[pkgName]
}
}
replaceModuleByPath(tree, 'removedChildren', pkgToRemove)
for (let parent of pkgToRemove.requiredBy) {
parent.requires = parent.requires.filter((child) => child !== pkgToRemove)
}
pkgToRemove.requiredBy = pkgToRemove.requiredBy.filter((parent) => parent !== tree)
flagAsRemoving(pkgToRemove)
}
next()
}n/a
removeExtraneous = function (args, tree, next) {
for (let pkg of args) {
var pkgName = moduleName(pkg)
var toRemove = tree.children.filter(moduleNameMatches(pkgName))
if (toRemove.length) {
removeObsoleteDep(toRemove[0])
}
}
next()
}n/a
function removeObsoleteDep(child, log) {
if (child.removed) return
child.removed = true
if (log) {
log.silly('removeObsoleteDep', 'removing ' + packageId(child) +
' from the tree as its been replaced by a newer version or is no longer required')
}
// remove from physical tree
if (child.parent) {
child.parent.children = child.parent.children.filter(function (pchild) { return pchild !== child })
}
// remove from logical tree
var requires = child.requires || []
requires.forEach(function (requirement) {
requirement.requiredBy = requirement.requiredBy.filter(function (reqBy) { return reqBy !== child })
// we don't just check requirement.requires because that doesn't account
// for circular deps. isExtraneous does.
if (isExtraneous(requirement)) removeObsoleteDep(requirement, log)
})
}n/a
updatePhantomChildren = function (current, child) {
validate('OO', arguments)
while (current && current !== child.parent) {
if (!current.phantomChildren) current.phantomChildren = {}
current.phantomChildren[moduleName(child)] = child
current = current.parent
}
}n/a
validateAllPeerDeps = function (tree, onInvalid) {
validateAllPeerDeps(tree, onInvalid, new Set())
}n/a
validatePeerDeps = function (tree, onInvalid) {
if (!tree.package.peerDependencies) return
Object.keys(tree.package.peerDependencies).forEach(function (pkgname) {
var version = tree.package.peerDependencies[pkgname]
try {
var spec = npa.resolve(pkgname, version)
} catch (e) {}
var match = spec && findRequirement(tree.parent || tree, pkgname, spec)
if (!match) onInvalid(tree, pkgname, version)
})
}n/a
diff_trees = function (oldTree, newTree, differences, log, next) {
validate('OOAOF', arguments)
pushAll(differences, sortActions(diffTrees(oldTree, newTree)))
log.finish()
next()
}n/a
_diffTrees = function (oldTree, newTree) {
validate('OO', arguments)
var differences = []
var flatOldTree = flattenTree(oldTree)
var flatNewTree = flattenTree(newTree)
var toRemove = {}
var toRemoveByName = {}
// Build our tentative remove list. We don't add remove actions yet
// because we might resuse them as part of a move.
Object.keys(flatOldTree).forEach(function (flatname) {
if (flatname === '/') return
if (flatNewTree[flatname]) return
var pkg = flatOldTree[flatname]
if (pkg.isInLink && /^[.][.][/\\]/.test(path.relative(newTree.realpath, pkg.realpath))) return
toRemove[flatname] = pkg
var name = moduleName(pkg)
if (!toRemoveByName[name]) toRemoveByName[name] = []
toRemoveByName[name].push({flatname: flatname, pkg: pkg})
})
// generate our add/update/move actions
Object.keys(flatNewTree).forEach(function (flatname) {
if (flatname === '/') return
var pkg = flatNewTree[flatname]
var oldPkg = pkg.oldPkg = flatOldTree[flatname]
if (oldPkg) {
// if the versions are equivalent then we don't need to update… unless
// the user explicitly asked us to.
if (!pkg.userRequired && pkgAreEquiv(oldPkg, pkg)) return
setAction(differences, 'update', pkg)
} else {
var name = moduleName(pkg)
// find any packages we're removing that share the same name and are equivalent
var removing = (toRemoveByName[name] || []).filter((rm) => pkgAreEquiv(rm.pkg, pkg))
var bundlesOrFromBundle = pkg.fromBundle || pkg.package.bundleDependencies
// if we have any removes that match AND we're not working with a bundle then upgrade to a move
if (removing.length && !bundlesOrFromBundle) {
var toMv = removing.shift()
toRemoveByName[name] = toRemoveByName[name].filter((rm) => rm !== toMv)
pkg.fromPath = toMv.pkg.path
setAction(differences, 'move', pkg)
delete toRemove[toMv.flatname]
// we don't generate add actions for things found in links (which already exist on disk)
} else if (!pkg.isInLink || !(pkg.fromBundle && pkg.fromBundle.isLink)) {
setAction(differences, 'add', pkg)
}
}
})
// finally generate our remove actions from any not consumed by moves
Object
.keys(toRemove)
.map((flatname) => toRemove[flatname])
.forEach((pkg) => setAction(differences, 'remove', pkg))
return filterActions(differences)
}n/a
sortActions = function (differences) {
var actions = {}
differences.forEach(function (action) {
var child = action[1]
actions[child.location] = action
})
var sorted = []
var added = {}
var sortedlocs = Object.keys(actions).sort(sortByLocation)
// We're going to sort the actions taken on top level dependencies first, before
// considering the order of transitive deps. Because we're building our list
// from the bottom up, this means we will return a list with top level deps LAST.
// This is important in terms of keeping installations as consistent as possible
// as folks add new dependencies.
var toplocs = sortedlocs.filter(function (location) {
var mod = actions[location][1]
if (!mod.requiredBy) return true
// If this module is required by any non-top level module
// or by any extraneous module, eg user requested or existing
// then we don't want to give this priority sorting.
return !mod.requiredBy.some(isNotTopOrExtraneous)
})
toplocs.concat(sortedlocs).forEach(function (location) {
sortByDeps(actions[location])
})
function sortByLocation (aa, bb) {
return bb.localeCompare(aa)
}
function sortModuleByLocation (aa, bb) {
return sortByLocation(aa && aa.location, bb && bb.location)
}
function sortByDeps (action) {
var mod = action[1]
if (added[mod.location]) return
added[mod.location] = action
if (!mod.requiredBy) mod.requiredBy = []
mod.requiredBy.sort(sortModuleByLocation).forEach(function (mod) {
if (actions[mod.location]) sortByDeps(actions[mod.location])
})
sorted.unshift(action)
}
// safety net, anything excluded above gets tacked on the end
differences.forEach((_) => {
if (sorted.indexOf(_) === -1) sorted.push(_)
})
return sorted
}n/a
function edit(args, cb) {
var p = args[0]
if (args.length !== 1 || !p) return cb(edit.usage)
var e = npm.config.get('editor')
if (!e) {
return cb(new Error(
"No editor set. Set the 'editor' config, or $EDITOR environ."
))
}
p = p.split('/')
.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)
editor(f, { editor: e }, noProgressTillDone(function (er) {
if (er) return cb(er)
npm.commands.rebuild(args, cb)
}))
})
}n/a
function installedShallow(opts, filter, cb) {
if (typeof cb !== 'function') {
cb = filter
filter = null
}
var conf = opts.conf
var args = conf.argv.remain
if (args.length > 3) return cb()
var local
var global
var localDir = npm.dir
var globalDir = npm.globalDir
if (npm.config.get('global')) {
local = []
next()
} else {
fs.readdir(localDir, function (er, pkgs) {
local = (pkgs || []).filter(function (p) {
return p.charAt(0) !== '.'
})
next()
})
}
fs.readdir(globalDir, function (er, pkgs) {
global = (pkgs || []).filter(function (p) {
return p.charAt(0) !== '.'
})
next()
})
function next () {
if (!local || !global) return
filterInstalled(local, global, filter, cb)
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function errorHandler(er) {
log.disableProgress()
if (!npm.config || !npm.config.loaded) {
// logging won't work unless we pretend that it's ready
er = er || new Error('Exit prior to config file resolving.')
console.error(er.stack || er.message)
}
if (cbCalled) {
er = er || new Error('Callback called more than once.')
}
cbCalled = true
if (!er) return exit(0)
if (typeof er === 'string') {
log.error('', er)
return exit(1, true)
} else if (!(er instanceof Error)) {
log.error('weird error', er)
return exit(1, true)
}
var m = er.code || er.message.match(/^(?:Error: )?(E[A-Z]+)/)
if (m && !er.code) {
er.code = m
}
;[
'type',
'stack',
'statusCode',
'pkgid'
].forEach(function (k) {
var v = er[k]
if (!v) return
log.verbose(k, v)
})
log.verbose('cwd', process.cwd())
var os = require('os')
log.verbose('', os.type() + ' ' + os.release())
log.verbose('argv', process.argv.map(JSON.stringify).join(' '))
log.verbose('node', process.version)
log.verbose('npm ', 'v' + npm.version)
;[
'file',
'path',
'code',
'errno',
'syscall'
].forEach(function (k) {
var v = er[k]
if (v) log.error(k, v)
})
var msg = errorMessage(er)
msg.summary.concat(msg.detail).forEach(function (errline) {
log.error.apply(log, errline)
})
if (npm.config.get('json')) {
var error = {
error: {
code: er.code,
summary: messageText(msg.summary),
detail: messageText(msg.detail)
}
}
console.log(JSON.stringify(error, null, 2))
}
exit(typeof er.errno === 'number' ? er.errno : 1)
}n/a
function exit(code, noLog) {
exitCode = exitCode || process.exitCode || code
var doExit = npm.config.loaded ? npm.config.get('_exit') : true
log.verbose('exit', [code, doExit])
if (log.level === 'silent') noLog = true
if (rollbacks.length) {
chain(rollbacks.map(function (f) {
return function (cb) {
npm.commands.unbuild([f], true, cb)
}
}), function (er) {
if (er) {
log.error('error rolling back', er)
if (!code) {
errorHandler(er)
} else {
if (!noLog) writeLogFile()
reallyExit(er)
}
} else {
if (!noLog && code) writeLogFile()
reallyExit()
}
})
rollbacks.length = 0
} else if (code && !noLog) {
writeLogFile()
} else {
reallyExit()
}
function reallyExit (er) {
if (er && !code) code = typeof er.errno === 'number' ? er.errno : 1
itWorked = !code
// Exit directly -- nothing in the CLI should still be running in the
// background at this point, and this makes sure anything left dangling
// for whatever reason gets thrown away, instead of leaving the CLI open
//
// Commands that expect long-running actions should just delay `cb()`
process.stdout.write('', () => {
process.exit(code)
})
}
}...
var conf = nopt(types, shorthands)
npm.argv = conf.argv.remain
if (npm.deref(npm.argv[0])) npm.command = npm.argv.shift()
else conf.usage = true
if (conf.version) {
console.log(npm.version)
return errorHandler.exit(0)
}
if (conf.versions) {
npm.command = 'version'
conf.usage = false
npm.argv = []
}
...function fsAccessImplementation(dir, done) {
done = inflight('exists:' + dir, done)
if (!done) return
fs.access(dir, fs.F_OK, done)
}n/a
function fsAccessImplementation(dir, done) {
done = inflight('exists:' + dir, done)
if (!done) return
fs.access(dir, fs.F_OK, done)
}n/a
function fsStatImplementation(dir, done) {
done = inflight('exists:' + dir, done)
if (!done) return
fs.stat(dir, function (er) { done(accessError(dir, er)) })
}n/a
function explore(args, cb) {
if (args.length < 1 || !args[0]) return cb(explore.usage)
var p = args.shift()
var cwd = path.resolve(npm.dir, p)
var opts = {cwd: cwd, stdio: 'inherit'}
var shellArgs = []
if (args) {
if (isWindowsShell) {
var execCmd = escapeExecPath(args.shift())
var execArgs = [execCmd].concat(args.map(escapeArg))
opts.windowsVerbatimArguments = true
shellArgs = ['/d', '/s', '/c'].concat(execArgs)
} else {
shellArgs.unshift('-c')
shellArgs = ['-c', args.map(escapeArg).join(' ').trim()]
}
}
var sh = npm.config.get('shell')
fs.stat(cwd, function (er, s) {
if (er || !s.isDirectory()) {
return cb(new Error(
"It doesn't look like " + p + ' is installed.'
))
}
if (!shellArgs.length) {
output(
'\nExploring ' + cwd + '\n' +
"Type 'exit' or ^D when finished\n"
)
}
var shell = spawn(sh, shellArgs, opts)
shell.on('close', function (er) {
// only fail if non-interactive.
if (!shellArgs.length) return cb()
cb(er)
})
})
}n/a
function installedShallow(opts, filter, cb) {
if (typeof cb !== 'function') {
cb = filter
filter = null
}
var conf = opts.conf
var args = conf.argv.remain
if (args.length > 3) return cb()
var local
var global
var localDir = npm.dir
var globalDir = npm.globalDir
if (npm.config.get('global')) {
local = []
next()
} else {
fs.readdir(localDir, function (er, pkgs) {
local = (pkgs || []).filter(function (p) {
return p.charAt(0) !== '.'
})
next()
})
}
fs.readdir(globalDir, function (er, pkgs) {
global = (pkgs || []).filter(function (p) {
return p.charAt(0) !== '.'
})
next()
})
function next () {
if (!local || !global) return
filterInstalled(local, global, filter, cb)
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function extract(staging, pkg, log) {
log.silly('extract', packageId(pkg))
const extractTo = moduleStagingPath(staging, pkg)
if (!pacoteOpts) {
pacoteOpts = require('../../config/pacote')
}
const opts = pacoteOpts({
integrity: pkg.package._integrity,
resolved: pkg.package._resolved
})
const args = [
pkg.package._requested,
extractTo,
opts
]
return BB.fromNode((cb) => {
let launcher = localWorker
let msg = args
const spec = typeof args[0] === 'string' ? npa(args[0]) : args[0]
args[0] = spec.raw
if (ENABLE_WORKERS && (isRegistry(spec) || spec.type === 'remote')) {
// We can't serialize these options
opts.loglevel = opts.log.level
opts.log = null
opts.dirPacker = null
// workers will run things in parallel!
launcher = workers
try {
msg = JSON.stringify(msg)
} catch (e) {
return cb(e)
}
}
launcher(msg, cb)
}).then(() => {
if (pkg.package.bundleDependencies || anyBundled(pkg)) {
return readBundled(pkg, staging, extractTo)
}
}).then(() => {
return gentlyRm(path.join(extractTo, 'node_modules'))
})
}...
})
}
cache.unpack = unpack
function unpack (pkg, ver, unpackTarget, dmode, fmode, uid, gid) {
return unbuild([unpackTarget], true).then(() => {
const opts = pacoteOpts({dmode, fmode, uid, gid, offline: true})
return pacote.extract(npa.resolve(pkg, ver), unpackTarget, opts)
})
}
...() => {
if (ENABLE_WORKERS) {
workers = workerFarm({
maxConcurrentCallsPerWorker: npm.limit.fetch,
maxRetries: 1
}, WORKER_PATH)
}
return BB.resolve()
}...
}
function timeEnd (log) {
process.emit('timeEnd', 'action:' + log.name)
}
function withInit (action, body) {
return BB.using(
action.init().disposer(() => action.teardown()),
body
)
}
function prepareAction (action, staging, log) {
validate('ASO', arguments)
validate('SO', action)
...() => {
if (ENABLE_WORKERS) {
workerFarm.end(workers)
workers = null
}
return BB.resolve()
}...
}
function timeEnd (log) {
process.emit('timeEnd', 'action:' + log.name)
}
function withInit (action, body) {
return BB.using(
action.init().disposer(() => action.teardown()),
body
)
}
function prepareAction (action, staging, log) {
validate('ASO', arguments)
validate('SO', action)
...function fromPacote(opts) {
return {
cache: getCacheMode(opts),
cacheManager: opts.cache,
ca: opts.ca,
cert: opts.cert,
headers: getHeaders('', opts.registry, opts),
key: opts.key,
localAddress: opts.localAddress,
maxSockets: opts.maxSockets,
proxy: opts.proxy,
referer: opts.refer,
retry: opts.retry,
strictSSL: !!opts.strictSSL,
timeout: opts.timeout,
uid: opts.uid,
gid: opts.gid
}
}...
log: log,
creds: creds,
registry: registry,
auth: {
otp: npm.config.get('otp')
},
scope: scope,
opts: fetchOpts.fromPacote(pacoteOpts())
}
login(conf).then((newCreds) => cb(null, newCreds)).catch(cb)
}
function login (conf) {
return profile.login(openerPromise, loginPrompter, conf)
.catch((err) => {
...function limited() {
var self = this
var args = Array.prototype.slice.call(arguments)
if (running >= maxRunning) {
queue.push({self: this, args: args})
return
}
var cb = typeof args[args.length-1] === 'function' && args.pop()
++ running
args.push(function () {
var cbargs = arguments
-- running
cb && process.nextTick(function () {
cb.apply(self, cbargs)
})
if (queue.length) {
var next = queue.shift()
limited.apply(next.self, next.args)
}
})
func.apply(self, args)
}n/a
function addBundled(pkg, next) {
validate('OF', arguments)
if (!pacoteOpts) {
pacoteOpts = require('./config/pacote')
}
if (pkg._bundled !== undefined) return next(null, pkg)
if (!pkg.bundleDependencies && pkg._requested.type !== 'directory') return next(null, pkg)
const requested = pkg._requested || npa(pkg._from)
if (requested.type === 'directory') {
pkg._bundled = null
return readPackageTree(pkg._requested.fetchSpec, function (er, tree) {
if (tree) pkg._bundled = tree.children
return next(null, pkg)
})
}
pkg._bundled = null
const target = tempFilename('unpack')
const opts = pacoteOpts({integrity: pkg._integrity})
pacote.extract(pkg._resolved || pkg._requested || npa.resolve(pkg.name, pkg.version), target, opts).then(() => {
log.silly('addBundled', 'read tarball')
readPackageTree(target, (err, tree) => {
if (err) { return next(err) }
log.silly('cleanup', 'remove extracted module')
rimraf(target, function () {
if (tree) {
pkg._bundled = tree.children
}
next(null, pkg)
})
})
}, next)
}n/a
finalize = function (staging, pkg, log) {
log.silly('finalize', pkg.realpath)
const extractedTo = moduleStagingPath(staging, pkg)
const delpath = path.join(path.dirname(pkg.realpath), '.' + path.basename(pkg.realpath) + '.DELETE')
let movedDestAway = false
const requested = pkg.package._requested || getRequested(pkg)
if (requested.type === 'directory') {
const relative = path.relative(path.dirname(pkg.path), pkg.realpath)
return makeParentPath(pkg.path)
.then(() => symlink(relative, pkg.path, 'junction'))
.catch((ex) => {
return rimraf(pkg.path).then(() => symlink(relative, pkg.path, 'junction'))
})
} else {
return makeParentPath(pkg.realpath)
.then(moveStagingToDestination)
.then(restoreOldNodeModules)
.catch((err) => {
if (movedDestAway) {
return rimraf(pkg.realpath).then(moveOldDestinationBack).then(() => {
throw err
})
} else {
throw err
}
})
.then(() => rimraf(delpath))
}
function makeParentPath (dir) {
return mkdirp(path.dirname(dir))
}
function moveStagingToDestination () {
return destinationIsClear()
.then(actuallyMoveStaging)
.catch(() => moveOldDestinationAway().then(actuallyMoveStaging))
}
function destinationIsClear () {
return lstat(pkg.realpath).then(() => {
throw new Error('destination exists')
}, () => {})
}
function actuallyMoveStaging () {
return move(extractedTo, pkg.realpath, moveOpts)
}
function moveOldDestinationAway () {
return rimraf(delpath).then(() => {
return move(pkg.realpath, delpath, moveOpts)
}).then(() => { movedDestAway = true })
}
function moveOldDestinationBack () {
return move(delpath, pkg.realpath, moveOpts).then(() => { movedDestAway = false })
}
function restoreOldNodeModules () {
if (!movedDestAway) return
return readdir(path.join(delpath, 'node_modules')).catch(() => []).then((modules) => {
if (!modules.length) return
return mkdirp(path.join(pkg.realpath, 'node_modules')).then(() => Bluebird.map(modules, (file) => {
const from = path.join(delpath, 'node_modules', file)
const to = path.join(pkg.realpath, 'node_modules', file)
return move(from, to, moveOpts)
}))
})
}
}n/a
rollback = function (top, staging, pkg) {
return Bluebird.try(() => {
const requested = pkg.package._requested || getRequested(pkg)
if (requested && requested.type === 'directory') return Promise.resolve()
// strictly speaking rolling back a finalize should ONLY remove module that
// was being finalized, not any of the things under it. But currently
// those modules are guaranteed to be useless so we may as well remove them too.
// When/if we separate `commit` step and can rollback to previous versions
// of upgraded modules then we'll need to revisit this…
return gentlyRm(pkg.path, false, top).catch((err) => {
log.warn('rollback', `Rolling back ${packageId(pkg)} failed (this is probably harmless): ${err.message ? err.message : err
}`)
})
})
}n/a
function flattenTree(tree) {
validate('O', arguments)
var seen = new Set()
var flat = {}
var todo = [[tree, '/']]
while (todo.length) {
var next = todo.shift()
var pkg = next[0]
seen.add(pkg)
var path = next[1]
flat[path] = pkg
if (path !== '/') path += '/'
for (var ii = 0; ii < pkg.children.length; ++ii) {
var child = pkg.children[ii]
if (!seen.has(child)) {
todo.push([child, flatName(path, child)])
}
}
}
return flat
}n/a
function flatName(path, child) {
validate('SO', arguments)
return path + (moduleName(child) || 'TOP')
}n/a
function flatNameFromTree(tree) {
validate('O', arguments)
if (tree.isTop) return '/'
var path = flatNameFromTree(tree.parent)
if (path !== '/') path += '/'
return flatName(path, tree)
}n/a
function help(args, cb) {
var argv = npm.config.get('argv').cooked
var argnum = 0
if (args.length === 2 && ~~args[0]) {
argnum = ~~args.shift()
}
// npm help foo bar baz: search topics
if (args.length > 1 && args[0]) {
return npm.commands['help-search'](args, argnum, cb)
}
var section = npm.deref(args[0]) || args[0]
// npm help <noargs>: show basic usage
if (!section) {
var valid = argv[0] === 'help' ? 0 : 1
return npmUsage(valid, cb)
}
// npm <command> -h: show command usage
if (npm.config.get('usage') &&
npm.commands[section] &&
npm.commands[section].usage) {
npm.config.set('loglevel', 'silent')
log.level = 'silent'
output(npm.commands[section].usage)
return cb()
}
// npm apihelp <section>: Prefer section 3 over section 1
var apihelp = argv.length && argv[0].indexOf('api') !== -1
var pref = apihelp ? [3, 1, 5, 7] : [1, 3, 5, 7]
if (argnum) {
pref = [ argnum ].concat(pref.filter(function (n) {
return n !== argnum
}))
}
// npm help <section>: Try to find the path
var manroot = path.resolve(__dirname, '..', 'man')
// legacy
if (section === 'global') section = 'folders'
else if (section === 'json') section = 'package.json'
// find either /section.n or /npm-section.n
// The glob is used in the glob. The regexp is used much
// further down. Globs and regexps are different
var compextglob = '.+(gz|bz2|lzma|[FYzZ]|xz)'
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 (!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)
return man
})
viewMan(pickMan(mans, pref), cb)
})
}...
hits: found,
totalHits: totalHits
})
})
// if only one result, then just show that help section.
if (results.length === 1) {
return npm.commands.help([results[0].file.replace(/\.md$/, '')], cb)
}
if (results.length === 0) {
output('No results for ' + args.map(JSON.stringify).join(' '))
return cb()
}
...completion = function (opts, cb) {
if (opts.conf.argv.remain.length > 2) return cb(null, [])
getSections(cb)
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function install(where, args, cb) {
if (!cb) {
cb = args
args = where
where = null
}
var globalTop = path.resolve(npm.globalDir, '..')
if (!where) {
where = npm.config.get('global')
? globalTop
: npm.prefix
}
validate('SAF', [where, args, cb])
// the /path/to/node_modules/..
var dryrun = !!npm.config.get('dry-run')
if (npm.config.get('dev')) {
log.warn('install', 'Usage of the `--dev` option is deprecated. Use `--only=dev` instead.')
}
if (where === globalTop && !args.length) {
args = ['.']
}
args = args.filter(function (a) {
return path.resolve(a) !== npm.prefix
})
new Installer(where, dryrun, args).run(cb)
}...
}
// if it's a folder, a random not-installed thing, or not a scoped package,
// then link or install it first
if (pkg[0] !== '@' && (pkg.indexOf('/') !== -1 || pkg.indexOf('\\') !== -1)) {
return fs.lstat(path.resolve(pkg), function (er, st) {
if (er || !st.isDirectory()) {
npm.commands.install(t, pkg, n)
} else {
rp = path.resolve(pkg)
linkPkg(rp, n)
}
})
}
...function Installer(where, dryrun, args, opts) {
validate('SBA|SBAO', arguments)
if (!opts) opts = {}
this.where = where
this.dryrun = dryrun
this.args = args
// fakechildren are children created from the lockfile and lack relationship data
// the only exist when the tree does not match the lockfile
// this is fine when doing full tree installs/updates but not ok when modifying only
// a few deps via `npm install` or `npm uninstall`.
this.currentTree = null
this.idealTree = null
this.differences = []
this.todo = []
this.progress = {}
this.noPackageJsonOk = !!args.length
this.topLevelLifecycles = !args.length
this.autoPrune = npm.config.get('package-lock')
const dev = npm.config.get('dev')
const only = npm.config.get('only')
const onlyProd = /^prod(uction)?$/.test(only)
const onlyDev = /^dev(elopment)?$/.test(only)
const prod = npm.config.get('production')
this.dev = opts.dev != null ? opts.dev : dev || (!onlyProd && !prod) || onlyDev
this.prod = opts.prod != null ? opts.prod : !onlyDev
this.packageLockOnly = opts.packageLockOnly != null
? opts.packageLockOnly : npm.config.get('package-lock-only')
this.rollback = opts.rollback != null ? opts.rollback : npm.config.get('rollback')
this.link = opts.link != null ? opts.link : npm.config.get('link')
this.saveOnlyLock = opts.saveOnlyLock
this.global = opts.global != null ? opts.global : this.where === path.resolve(npm.globalDir, '..')
this.audit = npm.config.get('audit') && !this.global
this.started = Date.now()
}n/a
completion = function (opts, cb) {
validate('OF', arguments)
// install can complete to a folder with a package.json, or any package.
// if it has a slash, then it's gotta be a folder
// if it starts with https?://, then just give up, because it's a url
if (/^https?:\/\//.test(opts.partialWord)) {
// do not complete to URLs
return cb(null, [])
}
if (/\//.test(opts.partialWord)) {
// Complete fully to folder if there is exactly one match and it
// is a folder containing a package.json file. If that is not the
// case we return 0 matches, which will trigger the default bash
// complete.
var lastSlashIdx = opts.partialWord.lastIndexOf('/')
var partialName = opts.partialWord.slice(lastSlashIdx + 1)
var partialPath = opts.partialWord.slice(0, lastSlashIdx)
if (partialPath === '') partialPath = '/'
var annotatePackageDirMatch = function (sibling, cb) {
var fullPath = path.join(partialPath, sibling)
if (sibling.slice(0, partialName.length) !== partialName) {
return cb(null, null) // not name match
}
fs.readdir(fullPath, function (err, contents) {
if (err) return cb(null, { isPackage: false })
cb(
null,
{
fullPath: fullPath,
isPackage: contents.indexOf('package.json') !== -1
}
)
})
}
return fs.readdir(partialPath, function (err, siblings) {
if (err) return cb(null, []) // invalid dir: no matching
asyncMap(siblings, annotatePackageDirMatch, function (err, matches) {
if (err) return cb(err)
var cleaned = matches.filter(function (x) { return x !== null })
if (cleaned.length !== 1) return cb(null, [])
if (!cleaned[0].isPackage) return cb(null, [])
// Success - only one match and it is a package dir
return cb(null, [cleaned[0].fullPath])
})
})
}
// FIXME: there used to be registry completion here, but it stopped making
// sense somewhere around 50,000 packages on the registry
cb()
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...(creds, registry, scope, cb) => {
const conf = {
log: log,
creds: creds,
registry: registry,
auth: {
otp: npm.config.get('otp')
},
scope: scope,
opts: fetchOpts.fromPacote(pacoteOpts())
}
login(conf).then((newCreds) => cb(null, newCreds)).catch(cb)
}...
log.disableProgress()
try {
var auth = require('./auth/' + npm.config.get('auth-type'))
} catch (e) {
return cb(new Error('no such auth module'))
}
auth.login(creds, registry, scope, function (err, newCreds) {
if (err) return cb(err)
npm.config.del('_token', 'user') // prevent legacy pollution
if (scope) npm.config.set(scope + ':registry', registry, 'user')
npm.config.setCredentialsByURI(registry, newCreds)
npm.config.save('user', cb)
})
...function link(args, cb) {
if (process.platform === 'win32') {
var semver = require('semver')
if (!semver.gte(process.version, '0.7.9')) {
var msg = 'npm link not supported on windows prior to node 0.7.9'
var e = new Error(msg)
e.code = 'ENOTSUP'
e.errno = require('constants').ENOTSUP // eslint-disable-line node/no-deprecated-api
return cb(e)
}
}
if (npm.config.get('global')) {
return cb(new Error(
'link should never be --global.\n' +
'Please re-run this command with --local'
))
}
if (args.length === 1 && args[0] === '.') args = []
if (args.length) return linkInstall(args, cb)
linkPkg(npm.prefix, cb)
}n/a
completion = function (opts, cb) {
var dir = npm.globalDir
fs.readdir(dir, function (er, files) {
cb(er, files.filter(function (f) {
return !f.match(/^[._-]/)
}))
})
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function lock(base, name, cb) {
var lockDir = resolve(npm.cache, '_locks')
correctMkdir(lockDir, function (er) {
if (er) return cb(er)
var opts = {
stale: npm.config.get('cache-lock-stale'),
retries: npm.config.get('cache-lock-retries'),
wait: npm.config.get('cache-lock-wait')
}
var lf = lockFileName(base, name)
lockfile.lock(lf, opts, function (er) {
if (er) log.warn('locking', lf, 'failed', er)
if (!er) {
log.verbose('lock', 'using', lf, 'for', resolve(base, name))
installLocks[lf] = true
}
cb(er)
})
})
}n/a
function unlock(base, name, cb) {
var lf = lockFileName(base, name)
var locked = installLocks[lf]
if (locked === false) {
return process.nextTick(cb)
} else if (locked === true) {
lockfile.unlock(lf, function (er) {
if (er) {
log.warn('unlocking', lf, 'failed', er)
} else {
installLocks[lf] = false
log.verbose('unlock', 'done using', lf, 'for', resolve(base, name))
}
cb(er)
})
} else {
var notLocked = new Error(
'Attempt to unlock ' + resolve(base, name) + ", which hasn't been locked"
)
notLocked.code = 'ENOTLOCKED'
throw notLocked
}
}n/a
function ls(args, silent, cb) {
if (typeof cb !== 'function') {
cb = silent
silent = false
}
var dir = path.resolve(npm.dir, '..')
readPackageTree(dir, function (_, physicalTree) {
if (!physicalTree) physicalTree = {package: {}, path: dir}
physicalTree.isTop = true
readShrinkwrap.andInflate(physicalTree, function () {
lsFromTree(dir, computeMetadata(physicalTree), args, silent, cb)
})
})
}...
npm.config.get('unicode') ? ' ➜ ' : ' -> '
} ${hook.endpoint}`)
}
})
}
function ls (pkg) {
return hookApi.ls(pkg, config())
.then((hooks) => {
if (npm.config.get('json')) {
output(JSON.stringify(hooks, null, 2))
} else if (!hooks.length) {
output("You don't have any hooks configured yet.")
} else {
if (hooks.length === 1) {
...function installedDeep(opts, cb) {
var local
var global
var depth = npm.config.get('depth')
var opt = { depth: depth, dev: true }
if (npm.config.get('global')) {
local = []
next()
} else {
readInstalled(npm.prefix, opt, function (er, data) {
local = getNames(data || {})
next()
})
}
readInstalled(npm.config.get('prefix'), opt, function (er, data) {
global = getNames(data || {})
next()
})
function getNames_ (d, n) {
if (d.realName && n) {
if (n[d.realName]) return n
n[d.realName] = true
}
if (!n) n = {}
Object.keys(d.dependencies || {}).forEach(function (dep) {
getNames_(d.dependencies[dep], n)
})
return n
}
function getNames (d) {
return Object.keys(getNames_(d))
}
function next () {
if (!local || !global) return
if (!npm.config.get('global')) {
global = global.map(function (g) {
return [g, '-g']
})
}
var names = local.concat(global)
return cb(null, names)
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...fromTree = function (dir, physicalTree, args, silent, cb) {
if (typeof cb !== 'function') {
cb = silent
silent = false
}
// npm ls 'foo@~1.3' bar 'baz@<2'
if (!args) {
args = []
} else {
args = args.map(function (a) {
if (typeof a === 'object') {
return [a.package.name, a.package.version, a]
} else {
var p = npa(a)
var name = p.name
// When version spec is missing, we'll skip using it when filtering.
// Otherwise, `semver.validRange` would return '*', which won't
// match prerelease versions.
var ver = (p.rawSpec &&
(semver.validRange(p.rawSpec) || ''))
return [ name, ver, a ]
}
})
}
var data = mutateIntoLogicalTree.asReadInstalled(physicalTree)
pruneNestedExtraneous(data)
filterByEnv(data)
filterByLink(data)
var unlooped = filterFound(unloop(data), args)
var lite = getLite(unlooped)
if (silent) return cb(null, data, lite)
var long = npm.config.get('long')
var json = npm.config.get('json')
var out
if (json) {
var seen = new Set()
var d = long ? unlooped : lite
// the raw data can be circular
out = JSON.stringify(d, function (k, o) {
if (typeof o === 'object') {
if (seen.has(o)) return '[Circular]'
seen.add(o)
}
return o
}, 2)
} else if (npm.config.get('parseable')) {
out = makeParseable(unlooped, long, dir)
} else if (data) {
out = makeArchy(unlooped, long, dir)
}
output(out)
if (args.length && !data._found) process.exitCode = 1
var er
// if any errors were found, then complain and exit status 1
if (lite.problems && lite.problems.length) {
er = lite.problems.join('\n')
}
cb(er, data, lite)
}n/a
function saveMetrics(itWorked) {
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()
var metricsFile = path.join(npm.config.get('cache'), 'anonymous-cli-metrics.json')
var metrics
try {
metrics = JSON.parse(fs.readFileSync(metricsFile))
metrics.metrics.to = new Date().toISOString()
if (itWorked) {
++metrics.metrics.successfulInstalls
} else {
++metrics.metrics.failedInstalls
}
} catch (ex) {
metrics = {
metricId: uuid.v4(),
metrics: {
from: new Date().toISOString(),
to: new Date().toISOString(),
successfulInstalls: itWorked ? 1 : 0,
failedInstalls: itWorked ? 0 : 1
}
}
}
try {
fs.writeFileSync(metricsFile, JSON.stringify(metrics))
} catch (ex) {
// we couldn't write the error metrics file, um, well, oh well.
}
}...
}
auth.login(creds, registry, scope, function (err, newCreds) {
if (err) return cb(err)
npm.config.del('_token', 'user') // prevent legacy pollution
if (scope) npm.config.set(scope + ':registry', registry, 'user')
npm.config.setCredentialsByURI(registry, newCreds)
npm.config.save('user', cb)
})
}
...function sendMetrics(metricsFile, metricsRegistry) {
inMetrics = true
var cliMetrics = JSON.parse(fs.readFileSync(metricsFile))
npm.load({}, function (err) {
if (err) return
npm.registry.config.retry.retries = 0
npm.registry.sendAnonymousCLIMetrics(metricsRegistry, cliMetrics, function (err) {
if (err) {
fs.writeFileSync(path.join(path.dirname(metricsFile), 'last-send-metrics-error.txt'), err.stack)
} else {
fs.unlinkSync(metricsFile)
}
})
})
}n/a
function startMetrics() {
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()
}n/a
function stopMetrics() {
if (inMetrics) return
if (npm.metricsProcess) npm.metricsProcess.kill('SIGKILL')
}n/a
mutate_into_logical_tree = function (tree) {
validate('O', arguments)
validateAllPeerDeps(tree, function (tree, pkgname, version) {
if (!tree.missingPeers) tree.missingPeers = {}
tree.missingPeers[pkgname] = version
})
var flat = flattenTree(tree)
Object.keys(flat).sort().forEach(function (flatname) {
var node = flat[flatname]
if (!(node.requiredBy && node.requiredBy.length)) return
if (node.parent) {
// If a node is a cycle that never reaches the root of the logical
// tree then we'll leave it attached to the root, or else it
// would go missing. Further we'll note that this is the node in the
// cycle that we picked arbitrarily to be the one attached to the root.
// others will fall
if (isDisconnectedCycle(node)) {
node.cycleTop = true
// Nor do we want to disconnect non-cyclical extraneous modules from the tree.
} else if (node.requiredBy.length) {
// regular deps though, we do, as we're moving them into the capable
// hands of the modules that require them.
node.parent.children = without(node.parent.children, node)
}
}
node.requiredBy.forEach(function (parentNode) {
parentNode.children = union(parentNode.children, [node])
})
})
return tree
}n/a
asReadInstalled = function (tree) {
mutateIntoLogicalTree(tree)
return translateTree(tree)
}...
var ver = (p.rawSpec &&
(semver.validRange(p.rawSpec) || ''))
return [ name, ver, a ]
}
})
}
var data = mutateIntoLogicalTree.asReadInstalled(physicalTree)
pruneNestedExtraneous(data)
filterByEnv(data)
filterByLink(data)
var unlooped = filterFound(unloop(data), args)
var lite = getLite(unlooped)
...startRunning = function () {
if (progressEnabled == null) progressEnabled = log.progressEnabled
if (progressEnabled) log.disableProgress()
++running
}n/a
stopRunning = function () {
--running
if (progressEnabled && running === 0) log.enableProgress()
}n/a
function noProgressTillDone(cb) {
startRunning()
return function () {
stopRunning()
cb.apply(this, arguments)
}
}n/a
create = function (node, template, isNotTop) {
if (!template) template = defaultTemplate
Object.keys(template).forEach(function (key) {
if (template[key] != null && typeof template[key] === 'object' && !(template[key] instanceof Array)) {
if (!node[key]) node[key] = {}
return create(node[key], template[key], true)
}
if (node[key] != null) return
node[key] = template[key]
})
if (!isNotTop) {
// isLink is true for the symlink and everything inside it.
// by contrast, isInLink is true for only the things inside a link
if (node.isLink == null) node.isLink = isLink(node.parent)
if (node.isInLink == null) node.isInLink = isInLink(node.parent)
if (node.fromBundle == null) {
node.fromBundle = false
}
}
return node
}...
Fix typo in `npm install` documentation.
([@watilde](https://github.com/watilde))
#### DEPENDENCY UPDATES
* [`7537fe1`](https://github.com/npm/npm/commit/7537fe1748c27e6f1144b279b256cd3376d5c41c)
`sorted-object@2.0.0`:
Create objects with `{}` instead of `Object.create(null)` to make the results
strictly equal to what, say, parsed JSON would provide.
([@domenic](https://github.com/domenic))
* [`8defb0f`](https://github.com/npm/npm/commit/8defb0f7b3ebdbe15c9ef5036052c10eda7e3161)
`readable-stream@2.0.6`:
Fix sync write issue on 0.10.
([@calvinmetcalf](https://github.com/calvinmetcalf))
...reset = function (node) {
reset(node, new Set())
}n/a
function login() {
npm.config.set('sso-type', 'oauth')
ssoAuth.login.apply(this, arguments)
}...
log.disableProgress()
try {
var auth = require('./auth/' + npm.config.get('auth-type'))
} catch (e) {
return cb(new Error('no such auth module'))
}
auth.login(creds, registry, scope, function (err, newCreds) {
if (err) return cb(err)
npm.config.del('_token', 'user') // prevent legacy pollution
if (scope) npm.config.set(scope + ':registry', registry, 'user')
npm.config.setCredentialsByURI(registry, newCreds)
npm.config.save('user', cb)
})
...function owner(args, cb) {
var action = args.shift()
switch (action) {
case 'ls': case 'list': return ls(args[0], cb)
case 'add': return add(args[0], args[1], cb)
case 'rm': case 'remove': return rm(args[0], args[1], cb)
default: return unknown(action, cb)
}
}n/a
completion = function (opts, cb) {
var argv = opts.conf.argv.remain
if (argv.length > 4) return cb()
if (argv.length <= 2) {
var subs = ['add', 'rm']
if (opts.partialWord === 'l') subs.push('ls')
else subs.push('ls', 'list')
return cb(null, subs)
}
npm.commands.whoami([], true, function (er, username) {
if (er) return cb()
var un = encodeURIComponent(username)
var byUser, theUser
switch (argv[2]) {
case 'ls':
// FIXME: there used to be registry completion here, but it stopped
// making sense somewhere around 50,000 packages on the registry
return cb()
case 'rm':
if (argv.length > 3) {
theUser = encodeURIComponent(argv[3])
byUser = '-/by-user/' + theUser + '|' + un
return mapToRegistry(byUser, npm.config, function (er, uri, auth) {
if (er) return cb(er)
console.error(uri)
npm.registry.get(uri, { auth: auth }, function (er, d) {
if (er) return cb(er)
// return the intersection
return cb(null, d[theUser].filter(function (p) {
// kludge for server adminery.
return un === 'isaacs' || d[un].indexOf(p) === -1
}))
})
})
}
// else fallthrough
/* eslint no-fallthrough:0 */
case 'add':
if (argv.length > 3) {
theUser = encodeURIComponent(argv[3])
byUser = '-/by-user/' + theUser + '|' + un
return mapToRegistry(byUser, npm.config, function (er, uri, auth) {
if (er) return cb(er)
console.error(uri)
npm.registry.get(uri, { auth: auth }, function (er, d) {
console.error(uri, er || d)
// return mine that they're not already on.
if (er) return cb(er)
var mine = d[un] || []
var theirs = d[theUser] || []
return cb(null, mine.filter(function (p) {
return theirs.indexOf(p) === -1
}))
})
})
}
// just list all users who aren't me.
return mapToRegistry('-/users', npm.config, function (er, uri, auth) {
if (er) return cb(er)
npm.registry.get(uri, { auth: auth }, function (er, list) {
if (er) return cb()
return cb(null, Object.keys(list).filter(function (n) {
return n !== un
}))
})
})
default:
return cb()
}
})
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function pack(args, silent, cb) {
const cwd = process.cwd()
if (typeof cb !== 'function') {
cb = silent
silent = false
}
if (args.length === 0) args = ['.']
BB.all(
args.map((arg) => pack_(arg, cwd))
).then((tarballs) => {
if (!silent && npm.config.get('json')) {
output(JSON.stringify(tarballs, null, 2))
} else if (!silent) {
tarballs.forEach(logContents)
output(tarballs.map((f) => path.relative(cwd, f.filename)).join('\n'))
}
return tarballs
}).nodeify(cb)
}n/a
completion = function (opts, cb) {
validate('OF', arguments)
// install can complete to a folder with a package.json, or any package.
// if it has a slash, then it's gotta be a folder
// if it starts with https?://, then just give up, because it's a url
if (/^https?:\/\//.test(opts.partialWord)) {
// do not complete to URLs
return cb(null, [])
}
if (/\//.test(opts.partialWord)) {
// Complete fully to folder if there is exactly one match and it
// is a folder containing a package.json file. If that is not the
// case we return 0 matches, which will trigger the default bash
// complete.
var lastSlashIdx = opts.partialWord.lastIndexOf('/')
var partialName = opts.partialWord.slice(lastSlashIdx + 1)
var partialPath = opts.partialWord.slice(0, lastSlashIdx)
if (partialPath === '') partialPath = '/'
var annotatePackageDirMatch = function (sibling, cb) {
var fullPath = path.join(partialPath, sibling)
if (sibling.slice(0, partialName.length) !== partialName) {
return cb(null, null) // not name match
}
fs.readdir(fullPath, function (err, contents) {
if (err) return cb(null, { isPackage: false })
cb(
null,
{
fullPath: fullPath,
isPackage: contents.indexOf('package.json') !== -1
}
)
})
}
return fs.readdir(partialPath, function (err, siblings) {
if (err) return cb(null, []) // invalid dir: no matching
asyncMap(siblings, annotatePackageDirMatch, function (err, matches) {
if (err) return cb(err)
var cleaned = matches.filter(function (x) { return x !== null })
if (cleaned.length !== 1) return cb(null, [])
if (!cleaned[0].isPackage) return cb(null, [])
// Success - only one match and it is a package dir
return cb(null, [cleaned[0].fullPath])
})
})
}
// FIXME: there used to be registry completion here, but it stopped making
// sense somewhere around 50,000 packages on the registry
cb()
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function getContents(pkg, target, filename, silent) {
const bundledWanted = new Set(
pkg.bundleDependencies ||
pkg.bundledDependencies ||
[]
)
const files = []
const bundled = new Set()
let totalEntries = 0
let totalEntrySize = 0
return tar.t({
file: target,
onentry (entry) {
totalEntries++
totalEntrySize += entry.size
const p = entry.path
if (p.startsWith('package/node_modules/')) {
const name = p.match(/^package\/node_modules\/((?:@[^/]+\/)?[^/]+)/)[1]
if (bundledWanted.has(name)) {
bundled.add(name)
}
} else {
files.push({
path: entry.path.replace(/^package\//, ''),
size: entry.size,
mode: entry.mode
})
}
},
strip: 1
})
.then(() => BB.all([
BB.fromNode((cb) => fs.stat(target, cb)),
ssri.fromStream(fs.createReadStream(target), {
algorithms: ['sha1', 'sha512']
})
]))
.then(([stat, integrity]) => {
const shasum = integrity['sha1'][0].hexDigest()
return {
id: pkg._id,
name: pkg.name,
version: pkg.version,
from: pkg._from,
size: stat.size,
unpackedSize: totalEntrySize,
shasum,
integrity: ssri.parse(integrity['sha512'][0]),
filename,
files,
entryCount: totalEntries,
bundled: Array.from(bundled)
}
})
}...
const extracted = path.join(tmp, 'package')
const target = path.join(tmp, 'package.json')
const opts = pacoteOpts()
return pacote.tarball.toFile(arg, target, opts)
.then(() => pacote.extract(arg, extracted, opts))
.then(() => readJson(path.join(extracted, 'package.json')))
.then((pkg) => {
return BB.resolve(pack.getContents(pkg, target))
.tap((c) => !npm.config.get('json') && pack.logContents(c))
.tap(() => upload(arg, pkg, false, target))
})
})
}
function upload (arg, pkg, isRetry, cached) {
...function logContents(tarball) {
log.notice('')
log.notice('', `${npm.config.get('unicode') ? '📦 ' : 'package:'} ${tarball.name}@${tarball.version}`)
log.notice('=== Tarball Contents ===')
if (tarball.files.length) {
log.notice('', columnify(tarball.files.map((f) => {
const bytes = byteSize(f.size)
return {path: f.path, size: `${bytes.value}${bytes.unit}`}
}), {
include: ['size', 'path'],
showHeaders: false
}))
}
if (tarball.bundled.length) {
log.notice('=== Bundled Dependencies ===')
tarball.bundled.forEach((name) => log.notice('', name))
}
log.notice('=== Tarball Details ===')
log.notice('', columnify([
{name: 'name:', value: tarball.name},
{name: 'version:', value: tarball.version},
tarball.filename && {name: 'filename:', value: tarball.filename},
{name: 'package size:', value: byteSize(tarball.size)},
{name: 'unpacked size:', value: byteSize(tarball.unpackedSize)},
{name: 'shasum:', value: tarball.shasum},
{
name: 'integrity:',
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}
].filter((x) => x), {
include: ['name', 'value'],
showHeaders: false
}))
log.notice('', '')
}...
}).then(() => {
return readJson(path.join(arg, 'package.json'))
}).then((pkg) => {
return cacache.tmp.withTmp(npm.tmp, {tmpPrefix: 'fromDir'}, (tmpDir) => {
const target = path.join(tmpDir, 'package.tgz')
return pack.packDirectory(pkg, arg, target, null, true)
.tap((c) => { contents = c })
.then((c) => !npm.config.get('json') && pack.logContents(c
))
.then(() => upload(arg, pkg, false, target))
})
}).then(() => {
return readJson(path.join(arg, 'package.json'))
}).tap((pkg) => {
return lifecycle(pkg, 'publish', arg)
}).tap((pkg) => {
...function packDirectory(mani, dir, target, filename, logIt) {
deprCheck(mani)
return readJson(path.join(dir, 'package.json')).then((pkg) => {
return lifecycle(pkg, 'prepack', dir)
}).then(() => {
return readJson(path.join(dir, 'package.json'))
}).then((pkg) => {
return cacache.tmp.withTmp(npm.tmp, {tmpPrefix: 'packing'}, (tmp) => {
const tmpTarget = path.join(tmp, path.basename(target))
const tarOpt = {
file: tmpTarget,
cwd: dir,
prefix: 'package/',
portable: true,
// Provide a specific date in the 1980s for the benefit of zip,
// which is confounded by files dated at the Unix epoch 0.
mtime: new Date('1985-10-26T08:15:00.000Z'),
gzip: true
}
return BB.resolve(packlist({ path: dir }))
// NOTE: node-tar does some Magic Stuff depending on prefixes for files
// specifically with @ signs, so we just neutralize that one
// and any such future "features" by prepending `./`
.then((files) => tar.create(tarOpt, files.map((f) => `./${f}`)))
.then(() => getContents(pkg, tmpTarget, filename, logIt))
// thread the content info through
.tap(() => move(tmpTarget, target, {Promise: BB, fs}))
.tap(() => lifecycle(pkg, 'postpack', dir))
})
})
}...
}).then((pkg) => {
return lifecycle(pkg, 'prepublishOnly', arg)
}).then(() => {
return readJson(path.join(arg, 'package.json'))
}).then((pkg) => {
return cacache.tmp.withTmp(npm.tmp, {tmpPrefix: 'fromDir'}, (tmpDir) => {
const target = path.join(tmpDir, 'package.tgz')
return pack.packDirectory(pkg, arg, target, null, true)
.tap((c) => { contents = c })
.then((c) => !npm.config.get('json') && pack.logContents(c))
.then(() => upload(arg, pkg, false, target))
})
}).then(() => {
return readJson(path.join(arg, 'package.json'))
}).tap((pkg) => {
...function packGitDep(manifest, dir) {
const stream = new PassThrough()
readJson(path.join(dir, 'package.json')).then((pkg) => {
if (pkg.scripts && pkg.scripts.prepare) {
log.verbose('prepareGitDep', `${manifest._spec}: installing devDeps and running prepare script.`)
const cliArgs = PASSTHROUGH_OPTS.reduce((acc, opt) => {
if (npm.config.get(opt, 'cli') != null) {
acc.push(`--${opt}=${npm.config.get(opt)}`)
}
return acc
}, [])
const child = cp.spawn(process.env.NODE || process.execPath, [
require.resolve('../bin/npm-cli.js'),
'install',
'--dev',
'--prod',
'--ignore-prepublish',
'--no-progress',
'--no-save'
].concat(cliArgs), {
cwd: dir,
env: process.env
})
let errData = []
let errDataLen = 0
let outData = []
let outDataLen = 0
child.stdout.on('data', (data) => {
outData.push(data)
outDataLen += data.length
log.gauge.pulse('preparing git package')
})
child.stderr.on('data', (data) => {
errData.push(data)
errDataLen += data.length
log.gauge.pulse('preparing git package')
})
return BB.fromNode((cb) => {
child.on('error', cb)
child.on('exit', (code, signal) => {
if (code > 0) {
const err = new Error(`${signal}: npm exited with code ${code} while attempting to build ${manifest._requested}. Clone
the repository manually and run 'npm install' in it for more information.`)
err.code = code
err.signal = signal
cb(err)
} else {
cb()
}
})
}).then(() => {
if (outDataLen > 0) log.silly('prepareGitDep', '1>', Buffer.concat(outData, outDataLen).toString())
if (errDataLen > 0) log.silly('prepareGitDep', '2>', Buffer.concat(errData, errDataLen).toString())
}, (err) => {
if (outDataLen > 0) log.error('prepareGitDep', '1>', Buffer.concat(outData, outDataLen).toString())
if (errDataLen > 0) log.error('prepareGitDep', '2>', Buffer.concat(errData, errDataLen).toString())
throw err
})
}
}).then(() => {
return readJson(path.join(dir, 'package.json'))
}).then((pkg) => {
return cacache.tmp.withTmp(npm.tmp, {
tmpPrefix: 'pacote-packing'
}, (tmp) => {
const tmpTar = path.join(tmp, 'package.tgz')
return packDirectory(manifest, dir, tmpTar).then(() => {
return pipe(fs.createReadStream(tmpTar), stream)
})
})
}).catch((err) => stream.emit('error', err))
return stream
}n/a
function prepareDirectory(dir) {
return readJson(path.join(dir, 'package.json')).then((pkg) => {
if (!pkg.name) {
throw new Error('package.json requires a "name" field')
}
if (!pkg.version) {
throw new Error('package.json requires a valid "version" field')
}
if (!pathIsInside(dir, npm.tmp)) {
if (pkg.scripts && pkg.scripts.prepublish) {
prepublishWarning([
'As of npm@5, `prepublish` scripts are deprecated.',
'Use `prepare` for build steps and `prepublishOnly` for upload-only.',
'See the deprecation note in `npm help scripts` for more information.'
])
}
if (npm.config.get('ignore-prepublish')) {
return lifecycle(pkg, 'prepare', dir).then(() => pkg)
} else {
return lifecycle(pkg, 'prepublish', dir).then(() => {
return lifecycle(pkg, 'prepare', dir)
}).then(() => pkg)
}
}
return pkg
})
}...
})
}
function publishFromDirectory (arg) {
// All this readJson is because any of the given scripts might modify the
// package.json in question, so we need to refresh after every step.
let contents
return pack.prepareDirectory(arg).then(() => {
return readJson(path.join(arg, 'package.json'))
}).then((pkg) => {
return lifecycle(pkg, 'prepublishOnly', arg)
}).then(() => {
return readJson(path.join(arg, 'package.json'))
}).then((pkg) => {
return cacache.tmp.withTmp(npm.tmp, {tmpPrefix: 'fromDir'}, (tmpDir) => {
...parse_json = function (content) {
return parseJsonWithErrors(stripBOM(content))
}n/a
noExceptions = function (content) {
try {
return parseJSON(content)
} catch (ex) {
}
}...
function isLinkable (pkg, cb) {
var globalPackage = path.resolve(npm.globalPrefix, 'lib', 'node_modules', moduleName(pkg))
var globalPackageJson = path.resolve(globalPackage, 'package.json')
fs.stat(globalPackage, function (er) {
if (er) return cb(true, true)
fs.readFile(globalPackageJson, function (er, data) {
var json = parseJSON.noExceptions(data)
cb(false, json && json.version === pkg.package.version)
})
})
}
Installer.prototype.executeActions = function (cb) {
validate('F', arguments)
...function profileCmd(args, cb) {
if (args.length === 0) return cb(new Error(profileCmd.usage))
log.gauge.show('profile')
switch (args[0]) {
case 'enable-2fa':
case 'enable-tfa':
case 'enable2fa':
case 'enabletfa':
withCb(enable2fa(args.slice(1)), cb)
break
case 'disable-2fa':
case 'disable-tfa':
case 'disable2fa':
case 'disabletfa':
withCb(disable2fa(), cb)
break
case 'get':
withCb(get(args.slice(1)), cb)
break
case 'set':
withCb(set(args.slice(1)), cb)
break
default:
cb(new Error('Unknown profile command: ' + args[0]))
}
}n/a
completion = function (opts, cb) {
var argv = opts.conf.argv.remain
switch (argv[2]) {
case 'enable-2fa':
case 'enable-tfa':
if (argv.length === 3) {
return cb(null, qw`auth-and-writes auth-only`)
} else {
return cb(null, [])
}
case 'disable-2fa':
case 'disable-tfa':
case 'get':
case 'set':
return cb(null, [])
default:
return cb(new Error(argv[2] + ' not recognized'))
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function prune(args, cb) {
var dryrun = !!npm.config.get('dry-run')
new Pruner('.', dryrun, args).run(cb)
}n/a
function Pruner(where, dryrun, args) {
Installer.call(this, where, dryrun, args)
this.autoPrune = true
}n/a
function installedDeep(opts, cb) {
var local
var global
var depth = npm.config.get('depth')
var opt = { depth: depth, dev: true }
if (npm.config.get('global')) {
local = []
next()
} else {
readInstalled(npm.prefix, opt, function (er, data) {
local = getNames(data || {})
next()
})
}
readInstalled(npm.config.get('prefix'), opt, function (er, data) {
global = getNames(data || {})
next()
})
function getNames_ (d, n) {
if (d.realName && n) {
if (n[d.realName]) return n
n[d.realName] = true
}
if (!n) n = {}
Object.keys(d.dependencies || {}).forEach(function (dep) {
getNames_(d.dependencies[dep], n)
})
return n
}
function getNames (d) {
return Object.keys(getNames_(d))
}
function next () {
if (!local || !global) return
if (!npm.config.get('global')) {
global = global.map(function (g) {
return [g, '-g']
})
}
var names = local.concat(global)
return cb(null, names)
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function publish(args, isRetry, cb) {
if (typeof cb !== 'function') {
cb = isRetry
isRetry = false
}
if (args.length === 0) args = ['.']
if (args.length !== 1) return cb(publish.usage)
log.verbose('publish', args)
const t = npm.config.get('tag').trim()
if (semver.validRange(t)) {
return cb(new Error('Tag name must not be a valid SemVer range: ' + t))
}
return publish_(args[0])
.then((tarball) => {
const silent = log.level === 'silent'
if (!silent && npm.config.get('json')) {
output(JSON.stringify(tarball, null, 2))
} else if (!silent) {
output(`+ ${tarball.id}`)
}
})
.nodeify(cb)
}...
if (npm.config.get('dry-run')) {
log.verbose('publish', '--dry-run mode enabled. Skipping upload.')
return BB.resolve()
}
log.showProgress('publish:' + pkg._id)
return BB.fromNode((cb) => {
registry.publish(registryBase, params, cb)
}).catch((err) => {
if (
err.code === 'EPUBLISHCONFLICT' &&
npm.config.get('force') &&
!isRetry
) {
log.warn('publish', 'Forced publish over ' + pkg._id)
...completion = function (opts, cb) {
// publish can complete to a folder with a package.json
// or a tarball, or a tarball url.
// for now, not yet implemented.
return cb()
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...pulse_till_done = function (prefix, cb) {
validate('SF', [prefix, cb])
if (!prefix) prefix = 'network'
pulseStart(prefix)
return function () {
pulseStop()
cb.apply(null, arguments)
}
}n/a
function pulseWhile(prefix, promise) {
if (!promise) {
promise = prefix
prefix = ''
}
pulseStart(prefix)
return Bluebird.resolve(promise).finally(() => pulseStop())
}...
const knownProfileKeys = qw`
name email ${'two-factor auth'} fullname homepage
freenode twitter github created updated`
function get (args) {
const tfa = 'two-factor auth'
const conf = config()
return pulseTillDone.withPromise(profile.get(conf)).then((info) => {
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] || '' })
...function readShrinkwrap(child, next) {
if (child.package._shrinkwrap) return process.nextTick(next)
BB.join(
maybeReadFile('npm-shrinkwrap.json', child),
// Don't read non-root lockfiles
child.isTop && maybeReadFile('package-lock.json', child),
child.isTop && maybeReadFile('package.json', child),
(shrinkwrap, lockfile, pkgJson) => {
if (shrinkwrap && lockfile) {
log.warn('read-shrinkwrap', 'Ignoring package-lock.json because there is already an npm-shrinkwrap.json. Please use only
one of the two.')
}
const name = shrinkwrap ? 'npm-shrinkwrap.json' : 'package-lock.json'
const parsed = parsePkgLock(shrinkwrap || lockfile, name)
if (parsed && parsed.lockfileVersion !== PKGLOCK_VERSION) {
log.warn('read-shrinkwrap', `This version of npm is compatible with lockfileVersion@${PKGLOCK_VERSION}, but ${name} was
generated for lockfileVersion@${parsed.lockfileVersion || 0}. I'll try to do my best with it!`)
}
child.package._shrinkwrap = parsed
}
).then(() => next(), next)
}n/a
function isDiff(str) {
return str.match(OURS_RE) && str.match(THEIRS_RE) && str.match(END_RE)
}n/a
function parsePkgLock(str, filename) {
if (!str) { return null }
try {
return parseJSON(str)
} catch (e) {
if (isDiff(str)) {
log.warn('conflict', `A git conflict was detected in ${filename}. Attempting to auto-resolve.`)
log.warn('conflict', 'To make this happen automatically on git rebase/merge, consider using the npm-merge-driver:')
log.warn('conflict', '$ npx npm-merge-driver install -g')
const pieces = str.split(/[\n\r]+/g).reduce((acc, line) => {
if (line.match(PARENT_RE)) acc.state = 'parent'
else if (line.match(OURS_RE)) acc.state = 'ours'
else if (line.match(THEIRS_RE)) acc.state = 'theirs'
else if (line.match(END_RE)) acc.state = 'top'
else {
if (acc.state === 'top' || acc.state === 'ours') acc.ours += line
if (acc.state === 'top' || acc.state === 'theirs') acc.theirs += line
if (acc.state === 'top' || acc.state === 'parent') acc.parent += line
}
return acc
}, {
state: 'top',
ours: '',
theirs: '',
parent: ''
})
try {
const ours = parseJSON(pieces.ours)
const theirs = parseJSON(pieces.theirs)
return reconcileLockfiles(ours, theirs)
} catch (_e) {
log.error('conflict', `Automatic conflict resolution failed. Please manually resolve conflicts in ${filename} and try again
.`)
log.silly('conflict', `Error during resolution: ${_e}`)
throw e
}
} else {
throw e
}
}
}n/a
andInflate = function (child, next) {
readShrinkwrap(child, iferr(next, function () {
if (child.package._shrinkwrap) {
return inflateShrinkwrap(child, child.package._shrinkwrap || {}, next)
} else {
return next()
}
}))
}...
this.idealTree.warnings = []
cb()
}
Installer.prototype.loadShrinkwrap = function (cb) {
validate('F', arguments)
log.silly('install', 'loadShrinkwrap')
readShrinkwrap.andInflate(this.idealTree, iferr(cb, () => {
computeMetadata(this.idealTree)
cb()
}))
}
Installer.prototype.getInstalledModules = function () {
return this.differences.filter(function (action) {
...function readEmail(msg, email, opts, isRetry) {
if (!msg) msg = 'email (this IS public): '
if (isRetry && email) {
const error = userValidate.email(email)
if (error) {
opts.log && opts.log.warn(error.message)
} else {
return email.trim()
}
}
return read({prompt: msg, default: email || ''})
.then((username) => readEmail(msg, username, opts, true))
}...
const loginPrompter = (creds) => {
const opts = { log: log }
return read.username('Username:', creds.username, opts).then((u) => {
creds.username = u
return read.password('Password:', creds.password)
}).then((p) => {
creds.password = p
return read.email('Email: (this IS public) ', creds.email, opts)
}).then((e) => {
creds.email = e
return creds
})
}
module.exports.login = (creds, registry, scope, cb) => {
...function readOTP(msg, otp, isRetry) {
if (!msg) {
msg = [
'There was an error while trying authentication due to OTP (One-Time-Password).',
'The One-Time-Password is generated via applications like Authy or',
'Google Authenticator, for more information see:',
'https://docs.npmjs.com/getting-started/using-two-factor-authentication',
'Enter OTP: '
].join('\n')
}
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))
}...
// 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] })
newUser[prop] = value
return profile.set(newUser, conf).catch((err) => {
if (err.code !== 'EOTP') throw err
return readUserInfo.otp('Enter OTP: ').then((otp) => {
conf.auth.otp = otp
return profile.set(newUser, conf)
})
}).then((result) => {
if (conf.json) {
output(JSON.stringify({[prop]: result[prop]}, null, 2))
} else if (conf.parseable) {
...function readPassword(msg, password, isRetry) {
if (!msg) msg = 'npm password: '
if (isRetry && password) return password
return read({prompt: msg, silent: true, default: password || ''})
.then((password) => readPassword(msg, password, true))
}...
'Do not include your current or new passwords on the command line.'))
}
if (writableProfileKeys.indexOf(prop) === -1) {
return Promise.reject(Error(`"${prop}" is not a property we can set. Valid properties are: ` + writableProfileKeys.join
(', ')))
}
return Bluebird.try(() => {
if (prop === 'password') {
return readUserInfo.password('Current password: ').then((current) => {
return readPasswords().then((newpassword) => {
value = {old: current, new: newpassword}
})
})
} else if (prop === 'email') {
return readUserInfo.password('Password: ').then((current) => {
return {password: current, email: value}
...function readUsername(msg, username, opts, isRetry) {
if (!msg) msg = 'npm username: '
if (isRetry && username) {
const error = userValidate.username(username)
if (error) {
opts.log && opts.log.warn(error.message)
} else {
return Promise.resolve(username.trim())
}
}
return read({prompt: msg, default: username || ''})
.then((username) => readUsername(msg, username, opts, true))
}...
const openerPromise = (url) => new Promise((resolve, reject) => {
openUrl(url, 'to complete your login please visit', (er) => er ? reject(er) : resolve())
})
const loginPrompter = (creds) => {
const opts = { log: log }
return read.username('Username:', creds.username, opts).then((u) => {
creds.username = u
return read.password('Password:', creds.password)
}).then((p) => {
creds.password = p
return read.email('Email: (this IS public) ', creds.email, opts)
}).then((e) => {
creds.email = e
...function rebuild(args, cb) {
var opt = { depth: npm.config.get('depth'), dev: true }
readInstalled(npm.prefix, opt, function (er, data) {
log.info('readInstalled', typeof data)
if (er) return cb(er)
var set = filter(data, args)
var folders = Object.keys(set).filter(function (f) {
return f !== npm.prefix
})
if (!folders.length) return cb()
log.silly('rebuild set', folders)
cleanBuild(folders, set, cb)
})
}...
.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)
editor(f, { editor: e }, noProgressTillDone(function (er) {
if (er) return cb(er)
npm.commands.rebuild(args, cb)
}))
})
}
...function installedDeep(opts, cb) {
var local
var global
var depth = npm.config.get('depth')
var opt = { depth: depth, dev: true }
if (npm.config.get('global')) {
local = []
next()
} else {
readInstalled(npm.prefix, opt, function (er, data) {
local = getNames(data || {})
next()
})
}
readInstalled(npm.config.get('prefix'), opt, function (er, data) {
global = getNames(data || {})
next()
})
function getNames_ (d, n) {
if (d.realName && n) {
if (n[d.realName]) return n
n[d.realName] = true
}
if (!n) n = {}
Object.keys(d.dependencies || {}).forEach(function (dep) {
getNames_(d.dependencies[dep], n)
})
return n
}
function getNames (d) {
return Object.keys(getNames_(d))
}
function next () {
if (!local || !global) return
if (!npm.config.get('global')) {
global = global.map(function (g) {
return [g, '-g']
})
}
var names = local.concat(global)
return cb(null, names)
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function repo(args, cb) {
var n = args.length ? args[0] : '.'
fetchPackageMetadata(n, '.', {fullMetadata: true}, function (er, d) {
if (er) return cb(er)
getUrlAndOpen(d, cb)
})
}n/a
completion = function (opts, cb) {
// FIXME: there used to be registry completion here, but it stopped making
// sense somewhere around 50,000 packages on the registry
cb()
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function CMD(args, cb) {
npm.commands['run-script']([stage].concat(args), cb)
}n/a
completion = function (opts, cb) {
installedShallow(opts, function (d) {
return d.scripts && d.scripts[stage]
}, cb)
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function runScript(args, cb) {
if (!args.length) return list(cb)
var pkgdir = npm.localPrefix
var cmd = args.shift()
readJson(path.resolve(pkgdir, 'package.json'), function (er, d) {
if (er) return cb(er)
run(d, pkgdir, cmd, args, cb)
})
}n/a
completion = function (opts, cb) {
// see if there's already a package specified.
var argv = opts.conf.argv.remain
if (argv.length >= 4) return cb()
if (argv.length === 3) {
// either specified a script locally, in which case, done,
// or a package, in which case, complete against its scripts
var json = path.join(npm.localPrefix, 'package.json')
return readJson(json, function (er, d) {
if (er && er.code !== 'ENOENT' && er.code !== 'ENOTDIR') return cb(er)
if (er) d = {}
var scripts = Object.keys(d.scripts || {})
console.error('local scripts', scripts)
if (scripts.indexOf(argv[2]) !== -1) return cb()
// ok, try to find out which package it was, then
var pref = npm.config.get('global') ? npm.config.get('prefix')
: npm.localPrefix
var pkgDir = path.resolve(pref, 'node_modules', argv[2], 'package.json')
readJson(pkgDir, function (er, d) {
if (er && er.code !== 'ENOENT' && er.code !== 'ENOTDIR') return cb(er)
if (er) d = {}
var scripts = Object.keys(d.scripts || {})
return cb(null, scripts)
})
})
}
readJson(path.join(npm.localPrefix, 'package.json'), function (er, d) {
if (er && er.code !== 'ENOENT' && er.code !== 'ENOTDIR') return cb(er)
d = d || {}
cb(null, Object.keys(d.scripts || {}))
})
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function login() {
npm.config.set('sso-type', 'saml')
ssoAuth.login.apply(this, arguments)
}...
log.disableProgress()
try {
var auth = require('./auth/' + npm.config.get('auth-type'))
} catch (e) {
return cb(new Error('no such auth module'))
}
auth.login(creds, registry, scope, function (err, newCreds) {
if (err) return cb(err)
npm.config.del('_token', 'user') // prevent legacy pollution
if (scope) npm.config.set(scope + ':registry', registry, 'user')
npm.config.setCredentialsByURI(registry, newCreds)
npm.config.save('user', cb)
})
...getSaveType = function (tree, arg) {
if (arguments.length) validate('OO', arguments)
var globalInstall = npm.config.get('global')
var noSaveFlags = !npm.config.get('save') &&
!npm.config.get('save-dev') &&
!npm.config.get('save-prod') &&
!npm.config.get('save-optional')
if (globalInstall || noSaveFlags) return null
if (npm.config.get('save-optional')) {
return 'optionalDependencies'
} else if (npm.config.get('save-dev')) {
return 'devDependencies'
} else if (npm.config.get('save-prod')) {
return 'dependencies'
} else {
if (arg) {
var name = moduleName(arg)
if (tree.package.optionalDependencies[name]) {
return 'optionalDependencies'
} else if (tree.package.devDependencies[name]) {
return 'devDependencies'
}
}
return 'dependencies'
}
}n/a
saveRequested = function (tree, andReturn) {
validate('OF', arguments)
savePackageJson(tree, andWarnErrors(andSaveShrinkwrap(tree, andReturn)))
}n/a
function saveShrinkwrap(tree, next) {
validate('OF', arguments)
if (!npm.config.get('shrinkwrap') || !npm.config.get('package-lock')) {
return next()
}
require('../shrinkwrap.js').createShrinkwrap(tree, {silent: false}, next)
}n/a
function SaveStack(fn) {
Error.call(this)
Error.captureStackTrace(this, fn || SaveStack)
}n/a
function Error() { [native code] }n/a
completeWith = function (er) {
this['__' + 'proto' + '__'] = er
this.stack = this.stack + '\n\n' + er.stack
return this
}n/a
function search(args, cb) {
var searchOpts = {
description: npm.config.get('description'),
exclude: prepareExcludes(npm.config.get('searchexclude')),
include: prepareIncludes(args, npm.config.get('searchopts')),
limit: npm.config.get('searchlimit'),
log: log,
staleness: npm.config.get('searchstaleness'),
unicode: npm.config.get('unicode')
}
if (searchOpts.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
var anyOutput = false
var entriesStream = ms.through.obj()
var esearchWritten = false
esearch(searchOpts).on('data', function (pkg) {
entriesStream.write(pkg)
!esearchWritten && (esearchWritten = true)
}).on('error', function (e) {
if (esearchWritten) {
// If esearch errored after already starting output, we can't fall back.
return entriesStream.emit('error', e)
}
log.warn('search', 'fast search endpoint errored. Using old search.')
allPackageSearch(searchOpts).on('data', function (pkg) {
entriesStream.write(pkg)
}).on('error', function (e) {
entriesStream.emit('error', e)
}).on('end', function () {
entriesStream.end()
})
}).on('end', function () {
entriesStream.end()
})
// Grab a configured output stream that will spit out packages in the
// desired format.
var outputStream = formatPackageStream({
args: args, // --searchinclude options are not highlighted
long: npm.config.get('long'),
description: npm.config.get('description'),
json: npm.config.get('json'),
parseable: npm.config.get('parseable'),
color: npm.color
})
outputStream.on('data', function (chunk) {
if (!anyOutput) { anyOutput = true }
output(chunk.toString('utf8'))
})
log.silly('search', 'searching packages')
ms.pipe(entriesStream, outputStream, function (er) {
if (er) return cb(er)
if (!anyOutput && !npm.config.get('json') && !npm.config.get('parseable')) {
output('No matches found for ' + (args.map(JSON.stringify).join(' ')))
}
log.silly('search', 'search completed')
log.clearProgress()
cb(null, {})
})
}n/a
completion = function (opts, cb) {
cb(null, [])
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function shrinkwrap(args, silent, cb) {
if (typeof cb !== 'function') {
cb = silent
silent = false
}
if (args.length) {
log.warn('shrinkwrap', "doesn't take positional args")
}
move(
path.resolve(npm.prefix, PKGLOCK),
path.resolve(npm.prefix, SHRINKWRAP),
{ Promise: BB }
).then(() => {
log.notice('', `${PKGLOCK} has been renamed to ${SHRINKWRAP}. ${SHRINKWRAP} will be used for future installations.`)
return readFile(path.resolve(npm.prefix, SHRINKWRAP)).then((d) => {
return JSON.parse(d)
})
}, (err) => {
if (err.code !== 'ENOENT') {
throw err
} else {
return readPackageTree(npm.localPrefix).then(
id.computeMetadata
).then((tree) => {
return BB.fromNode((cb) => {
createShrinkwrap(tree, {
silent,
defaultFile: SHRINKWRAP
}, cb)
})
})
}
}).then((data) => cb(null, data), cb)
}n/a
function createShrinkwrap(tree, opts, cb) {
opts = opts || {}
lifecycle(tree.package, 'preshrinkwrap', tree.path, function () {
const pkginfo = treeToShrinkwrap(tree)
chain([
[lifecycle, tree.package, 'shrinkwrap', tree.path],
[shrinkwrap_, tree.path, pkginfo, opts],
[lifecycle, tree.package, 'postshrinkwrap', tree.path]
], iferr(cb, function (data) {
cb(null, pkginfo)
}))
})
}...
exports.saveShrinkwrap = saveShrinkwrap
function saveShrinkwrap (tree, next) {
validate('OF', arguments)
if (!npm.config.get('shrinkwrap') || !npm.config.get('package-lock')) {
return next()
}
require('../shrinkwrap.js').createShrinkwrap(tree, {silent: false}, next)
}
function savePackageJson (tree, next) {
validate('OF', arguments)
var saveBundle = npm.config.get('save-bundle')
// each item in the tree is a top-level thing that should be saved
...function treeToShrinkwrap(tree) {
validate('O', arguments)
var pkginfo = {}
if (tree.package.name) pkginfo.name = tree.package.name
if (tree.package.version) pkginfo.version = tree.package.version
if (tree.children.length) {
pkginfo.requires = true
shrinkwrapDeps(pkginfo.dependencies = {}, tree, tree)
}
return pkginfo
}n/a
function login(creds, registry, scope, cb) {
var ssoType = npm.config.get('sso-type')
if (!ssoType) { return cb(new Error('Missing option: sso-type')) }
var params = {
// We're reusing the legacy login endpoint, so we need some dummy
// stuff here to pass validation. They're never used.
auth: {
username: 'npm_' + ssoType + '_auth_dummy_user',
password: 'placeholder',
email: 'support@npmjs.com',
authType: ssoType
}
}
npm.registry.adduser(registry, params, function (er, doc) {
if (er) return cb(er)
if (!doc || !doc.token) return cb(new Error('no SSO token returned'))
if (!doc.sso) return cb(new Error('no SSO URL returned by services'))
openUrl(doc.sso, 'to complete your login please visit', function () {
pollForSession(registry, doc.token, function (err, username) {
if (err) return cb(err)
log.info('adduser', 'Authorized user %s', username)
var scopeMessage = scope ? ' to scope ' + scope : ''
output('Logged in as %s%s on %s.', username, scopeMessage, registry)
cb(null, { token: doc.token })
})
})
})
}...
log.disableProgress()
try {
var auth = require('./auth/' + npm.config.get('auth-type'))
} catch (e) {
return cb(new Error('no such auth module'))
}
auth.login(creds, registry, scope, function (err, newCreds) {
if (err) return cb(err)
npm.config.del('_token', 'user') // prevent legacy pollution
if (scope) npm.config.set(scope + ':registry', registry, 'user')
npm.config.setCredentialsByURI(registry, newCreds)
npm.config.save('user', cb)
})
...function star(args, cb) {
if (!args.length) return cb(star.usage)
var s = npm.config.get('unicode') ? '\u2605 ' : '(*)'
var u = npm.config.get('unicode') ? '\u2606 ' : '( )'
var using = !(npm.command.match(/^un/))
if (!using) s = u
asyncMap(args, function (pkg, cb) {
mapToRegistry(pkg, npm.config, function (er, uri, auth) {
if (er) return cb(er)
var params = {
starred: using,
auth: auth
}
npm.registry.star(uri, params, function (er, data, raw, req) {
if (!er) {
output(s + ' ' + pkg)
log.verbose('star', data)
}
cb(er, data, raw, req)
})
})
}, cb)
}...
mapToRegistry(pkg, npm.config, function (er, uri, auth) {
if (er) return cb(er)
var params = {
starred: using,
auth: auth
}
npm.registry.star(uri, params, function (er, data, raw, req) {
if (!er) {
output(s + ' ' + pkg)
log.verbose('star', data)
}
cb(er, data, raw, req)
})
})
...completion = function (opts, cb) {
// FIXME: there used to be registry completion here, but it stopped making
// sense somewhere around 50,000 packages on the registry
cb()
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function CMD(args, cb) {
npm.commands['run-script']([stage].concat(args), cb)
}n/a
completion = function (opts, cb) {
installedShallow(opts, function (d) {
return d.scripts && d.scripts[stage]
}, cb)
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function CMD(args, cb) {
npm.commands['run-script']([stage].concat(args), cb)
}n/a
completion = function (opts, cb) {
installedShallow(opts, function (d) {
return d.scripts && d.scripts[stage]
}, cb)
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function team(args, cb) {
// Entities are in the format <scope>:<team>
var cmd = args.shift()
var entity = (args.shift() || '').split(':')
return mapToRegistry('/', npm.config, function (err, uri, auth) {
if (err) { return cb(err) }
try {
return npm.registry.team(cmd, uri, {
auth: auth,
scope: entity[0].replace(/^@/, ''), // '@' prefix on scope is optional.
team: entity[1],
user: args.shift()
}, function (err, data) {
!err && data && output(JSON.stringify(data, undefined, 2))
cb(err, data)
})
} catch (e) {
cb(e.message + '\n\nUsage:\n' + team.usage)
}
})
}...
function team (args, cb) {
// Entities are in the format <scope>:<team>
var cmd = args.shift()
var entity = (args.shift() || '').split(':')
return mapToRegistry('/', npm.config, function (err, uri, auth) {
if (err) { return cb(err) }
try {
return npm.registry.team(cmd, uri, {
auth: auth,
scope: entity[0].replace(/^@/, ''), // '@' prefix on scope is optional.
team: entity[1],
user: args.shift()
}, function (err, data) {
!err && data && output(JSON.stringify(data, undefined, 2))
cb(err, data)
...completion = function (opts, cb) {
var argv = opts.conf.argv.remain
if (argv.length === 2) {
return cb(null, team.subcommands)
}
switch (argv[2]) {
case 'ls':
case 'create':
case 'destroy':
case 'add':
case 'rm':
case 'edit':
return cb(null, [])
default:
return cb(new Error(argv[2] + ' not recognized'))
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function token(args, cb) {
log.gauge.show('token')
if (args.length === 0) return withCb(list([]), cb)
switch (args[0]) {
case 'list':
case 'ls':
withCb(list(), cb)
break
case 'delete':
case 'revoke':
case 'remove':
case 'rm':
withCb(rm(args.slice(1)), cb)
break
case 'create':
withCb(create(args.slice(1)), cb)
break
default:
cb(new Error('Unknown profile command: ' + args[0]))
}
}n/a
function validateCIDRList(cidrs) {
const maybeList = cidrs ? (Array.isArray(cidrs) ? cidrs : [cidrs]) : []
const list = maybeList.length === 1 ? maybeList[0].split(/,\s*/) : maybeList
list.forEach(validateCIDR)
return list
}n/a
completion = function (opts, cb) {
var argv = opts.conf.argv.remain
switch (argv[2]) {
case 'list':
case 'revoke':
case 'create':
return cb(null, [])
default:
return cb(new Error(argv[2] + ' not recognized'))
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...fromString = function (val) {
_fromString(val, function (err, result) {
if (err) {
npmlog.warn('invalid umask', err.message)
}
val = result
})
return val
}...
val = ''
}
}
key = key.trim()
val = val.trim()
log.info('config', 'set %j %j', key, val)
var where = npm.config.get('global') ? 'global' : 'user'
if (key.match(/umask/)) val = umask.fromString(val)
npm.config.set(key, val, where)
npm.config.save(where, cb)
}
function get (key, cb) {
if (!key) return list(cb)
if (!publicVar(key)) {
...function toString(val) {
val = val.toString(8);
while (val.length < 4) {
val = "0" + val;
}
return val;
}...
function get (key, cb) {
if (!key) return list(cb)
if (!publicVar(key)) {
return cb(new Error('---sekretz---'))
}
var val = npm.config.get(key)
if (key.match(/umask/)) val = umask.toString(val)
output(val)
cb()
}
function sort (a, b) {
return a > b ? 1 : -1
}
...function validate(data, k, val) {
// must be either an integer or an octal string.
if (typeof val === "number" && !isNaN(val)) {
data[k] = val;
return true;
}
if (typeof val === "string") {
if (val.charAt(0) !== "0") {
return false;
}
data[k] = parseInt(val, 8);
return true;
}
return false;
}...
console.warn(m + ' ' + util.format.apply(util, [].slice.call(arguments, 1)))
} }
}
exports.Umask = Umask
function Umask () {}
function validateUmask (data, k, val) {
return umask.validate(data, k, val)
}
function validateSemver (data, k, val) {
if (!semver.valid(val)) return false
data[k] = semver.valid(val)
}
...function unbuild(args, silent, cb) {
if (typeof silent === 'function') {
cb = silent
silent = false
}
asyncMap(args, unbuild_(silent), cb)
}n/a
function rmStuff(pkg, folder, cb) {
// if it's global, and folder is in {prefix}/node_modules,
// then bins are in {prefix}/bin
// otherwise, then bins are in folder/../.bin
var parent = pkg.name[0] === '@' ? path.dirname(path.dirname(folder)) : path.dirname(folder)
var gnm = npm.dir
// gnm might be an absolute path, parent might be relative
// this checks they're the same directory regardless
var top = path.relative(gnm, parent) === ''
log.verbose('unbuild rmStuff', pkg._id, 'from', gnm)
if (!top) log.verbose('unbuild rmStuff', 'in', parent)
asyncMap([rmBins, rmMans], function (fn, cb) {
fn(pkg, folder, parent, top, cb)
}, cb)
}n/a
function uninstall(args, cb) {
validate('AF', arguments)
// the /path/to/node_modules/..
const dryrun = !!npm.config.get('dry-run')
if (args.length === 1 && args[0] === '.') args = []
const where = npm.config.get('global') || !args.length
? path.resolve(npm.globalDir, '..')
: npm.prefix
args = args.filter(function (a) {
return path.resolve(a) !== where
})
if (args.length) {
new Uninstaller(where, dryrun, args).run(cb)
} else {
// remove this package from the global space, if it's installed there
readJson(path.resolve(npm.localPrefix, 'package.json'), function (er, pkg) {
if (er && er.code !== 'ENOENT' && er.code !== 'ENOTDIR') return cb(er)
if (er) return cb(uninstall.usage)
new Uninstaller(where, dryrun, [pkg.name]).run(cb)
})
}
}n/a
class Uninstaller extends Installer {
constructor (where, dryrun, args) {
super(where, dryrun, args)
this.remove = []
}
loadArgMetadata (next) {
this.args = this.args.map(function (arg) { return {name: arg} })
next()
}
loadAllDepsIntoIdealTree (cb) {
validate('F', arguments)
this.remove = this.args
this.args = []
log.silly('uninstall', 'loadAllDepsIntoIdealTree')
const saveDeps = getSaveType()
super.loadAllDepsIntoIdealTree(iferr(cb, () => {
removeDeps(this.remove, this.idealTree, saveDeps, cb)
}))
}
// no top level lifecycles on rm
runPreinstallTopLevelLifecycles (cb) { cb() }
runPostinstallTopLevelLifecycles (cb) { cb() }
}n/a
function installedShallow(opts, filter, cb) {
if (typeof cb !== 'function') {
cb = filter
filter = null
}
var conf = opts.conf
var args = conf.argv.remain
if (args.length > 3) return cb()
var local
var global
var localDir = npm.dir
var globalDir = npm.globalDir
if (npm.config.get('global')) {
local = []
next()
} else {
fs.readdir(localDir, function (er, pkgs) {
local = (pkgs || []).filter(function (p) {
return p.charAt(0) !== '.'
})
next()
})
}
fs.readdir(globalDir, function (er, pkgs) {
global = (pkgs || []).filter(function (p) {
return p.charAt(0) !== '.'
})
next()
})
function next () {
if (!local || !global) return
filterInstalled(local, global, filter, cb)
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function unpublish(args, cb) {
if (args.length > 1) return cb(unpublish.usage)
var thing = args.length ? npa(args[0]) : {}
var project = thing.name
var version = thing.rawSpec
log.silly('unpublish', 'args[0]', args[0])
log.silly('unpublish', 'thing', thing)
if (!version && !npm.config.get('force')) {
return cb(
'Refusing to delete entire project.\n' +
'Run with --force to do this.\n' +
unpublish.usage
)
}
if (!project || path.resolve(project) === npm.localPrefix) {
// if there's a package.json in the current folder, then
// read the package name and version out of that.
var cwdJson = path.join(npm.localPrefix, 'package.json')
return readJson(cwdJson, function (er, data) {
if (er && er.code !== 'ENOENT' && er.code !== 'ENOTDIR') return cb(er)
if (er) return cb('Usage:\n' + unpublish.usage)
log.verbose('unpublish', data)
gotProject(data.name, data.version, data.publishConfig, cb)
})
}
return gotProject(project, version, cb)
}...
if (
err.code === 'EPUBLISHCONFLICT' &&
npm.config.get('force') &&
!isRetry
) {
log.warn('publish', 'Forced publish over ' + pkg._id)
return BB.fromNode((cb) => {
npm.commands.unpublish([pkg._id], cb)
}).finally(() => {
// ignore errors. Use the force. Reach out with your feelings.
return upload(arg, pkg, true, cached).catch(() => {
// but if it fails again, then report the first error.
throw err
})
})
...completion = function (opts, cb) {
if (opts.conf.argv.remain.length >= 3) return cb()
npm.commands.whoami([], true, function (er, username) {
if (er) return cb()
var un = encodeURIComponent(username)
if (!un) return cb()
var byUser = '-/by-user/' + un
mapToRegistry(byUser, npm.config, function (er, uri, auth) {
if (er) return cb(er)
npm.registry.get(uri, { auth: auth }, function (er, pkgs) {
// do a bit of filtering at this point, so that we don't need
// to fetch versions for more than one thing, but also don't
// accidentally a whole project.
pkgs = pkgs[un]
if (!pkgs || !pkgs.length) return cb()
var pp = npa(opts.partialWord).name
pkgs = pkgs.filter(function (p) {
return p.indexOf(pp) === 0
})
if (pkgs.length > 1) return cb(null, pkgs)
mapToRegistry(pkgs[0], npm.config, function (er, uri, auth) {
if (er) return cb(er)
npm.registry.get(uri, { auth: auth }, function (er, d) {
if (er) return cb(er)
var vers = Object.keys(d.versions)
if (!vers.length) return cb(null, pkgs)
return cb(null, vers.map(function (v) {
return pkgs[0] + '@' + v
}))
})
})
})
})
})
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...checkForBrokenNode = function () {
var nodejs = checkVersion(process.version)
if (nodejs.broken) {
console.error('ERROR: npm is known not to run on Node.js ' + process.version)
supportedNode.forEach(function (rel) {
if (semver.satisfies(nodejs.version, rel.ver)) {
console.error('Node.js ' + rel.ver + " is supported but the specific version you're running has")
console.error('a bug known to break npm. Please update to at least ' + rel.min + ' to use this')
console.error('version of npm. You can find the latest release of Node.js at https://nodejs.org/')
process.exit(1)
}
})
var supportedMajors = supportedNode.map(function (n) { return n.ver }).join(', ')
console.error("You'll need to upgrade to a newer version in order to use this")
console.error('version of npm. Supported versions are ' + supportedMajors + '. You can find the')
console.error('latest version at https://nodejs.org/')
process.exit(1)
}
}...
WScript.quit(1)
return
}
process.title = 'npm'
var unsupported = require('../lib/utils/unsupported.js')
unsupported.checkForBrokenNode()
var log = require('npmlog')
log.pause() // will be unpaused when config is loaded.
log.info('it worked if it ends with', 'ok')
unsupported.checkForUnsupportedNode()
...checkForUnsupportedNode = function () {
var nodejs = checkVersion(process.version)
if (nodejs.unsupported) {
var log = require('npmlog')
var supportedMajors = supportedNode.map(function (n) { return n.ver }).join(', ')
log.warn('npm', 'npm does not support Node.js ' + process.version)
log.warn('npm', 'You should probably upgrade to a newer version of node as we')
log.warn('npm', "can't make any promises that npm will work with this version.")
log.warn('npm', 'Supported releases of Node.js are the latest release of ' + supportedMajors + '.')
log.warn('npm', 'You can find the latest version at https://nodejs.org/')
}
}...
var unsupported = require('../lib/utils/unsupported.js')
unsupported.checkForBrokenNode()
var log = require('npmlog')
log.pause() // will be unpaused when config is loaded.
log.info('it worked if it ends with', 'ok')
unsupported.checkForUnsupportedNode()
var path = require('path')
var npm = require('../lib/npm.js')
var npmconf = require('../lib/config/core.js')
var errorHandler = require('../lib/utils/error-handler.js')
var configDefs = npmconf.defs
...checkVersion = function (version) {
var versionNoPrerelease = version.replace(/-.*$/, '')
return {
version: versionNoPrerelease,
broken: semver.satisfies(versionNoPrerelease, knownBroken),
unsupported: !semver.satisfies(versionNoPrerelease, supportedNode.map(function (n) { return '^' + n.min }).join('||'))
}
}...
}
// now actually fire up npm and run the command.
// this is how to use npm programmatically:
conf._exit = true
npm.load(conf, function (er) {
if (er) return errorHandler(er)
if (!unsupported.checkVersion(process.version).unsupported) {
const pkg = require('../package.json')
let notifier = require('update-notifier')({pkg})
if (
notifier.update &&
notifier.update.latest !== pkg.version
) {
const color = require('ansicolors')
...validate_args = function (idealTree, args, next) {
validate('OAF', arguments)
var force = npm.config.get('force')
asyncMap(args, function (pkg, done) {
chain([
[hasMinimumFields, pkg],
[checkSelf, idealTree, pkg, force],
[isInstallable, pkg]
], done)
}, next)
}n/a
isInstallable = function (pkg, next) {
var force = npm.config.get('force')
var nodeVersion = npm.config.get('node-version')
if (/-/.test(nodeVersion)) {
// for the purposes of validation, if the node version is a prerelease,
// strip that. We check and warn about this sceanrio over in validate-tree.
nodeVersion = nodeVersion.replace(/-.*/, '')
}
var strict = npm.config.get('engine-strict')
checkEngine(pkg, npm.version, nodeVersion, force, strict, iferr(next, thenWarnEngineIssues))
function thenWarnEngineIssues (warn) {
if (warn) getWarnings(pkg).push(warn)
checkPlatform(pkg, force, next)
}
}n/a
function view(args, silent, cb) {
if (typeof cb !== 'function') {
cb = silent
silent = false
}
if (!args.length) args = ['.']
var pkg = args.shift()
var nv
if (/^[.]@/.test(pkg)) {
nv = npa.resolve(null, pkg.slice(2))
} else {
nv = npa(pkg)
}
var name = nv.name
var local = (name === '.' || !name)
if (npm.config.get('global') && local) {
return cb(new Error('Cannot use view command in global mode.'))
}
if (local) {
var dir = npm.prefix
readJson(path.resolve(dir, 'package.json'), function (er, d) {
d = d || {}
if (er && er.code !== 'ENOENT' && er.code !== 'ENOTDIR') return cb(er)
if (!d.name) return cb(new Error('Invalid package.json'))
var p = d.name
nv = npa(p)
if (pkg && ~pkg.indexOf('@')) {
nv.rawSpec = pkg.split('@')[pkg.indexOf('@')]
}
fetchAndRead(nv, args, silent, cb)
})
} else {
fetchAndRead(nv, args, silent, cb)
}
}n/a
completion = function (opts, cb) {
if (opts.conf.argv.remain.length <= 2) {
// FIXME: there used to be registry completion here, but it stopped making
// sense somewhere around 50,000 packages on the registry
return cb()
}
// have the package, get the fields.
var tag = npm.config.get('tag')
mapToRegistry(opts.conf.argv.remain[2], npm.config, function (er, uri, auth) {
if (er) return cb(er)
npm.registry.get(uri, { auth: auth }, function (er, d) {
if (er) return cb(er)
var dv = d.versions[d['dist-tags'][tag]]
var fields = []
d.versions = Object.keys(d.versions).sort(semver.compareLoose)
fields = getFields(d).concat(getFields(dv))
cb(null, fields)
})
})
function getFields (d, f, pref) {
f = f || []
if (!d) return f
pref = pref || []
Object.keys(d).forEach(function (k) {
if (k.charAt(0) === '_' || k.indexOf('.') !== -1) return
var p = pref.concat(k).join('.')
f.push(p)
if (Array.isArray(d[k])) {
d[k].forEach(function (val, i) {
var pi = p + '[' + i + ']'
if (val && typeof val === 'object') getFields(val, f, [p])
else f.push(pi)
})
return
}
if (typeof d[k] === 'object') getFields(d[k], f, [p])
})
return f
}
}...
npm.config.set(k, parsed[k])
})
// at this point, if words[1] is some kind of npm command,
// then complete on it.
// otherwise, do nothing
cmd = npm.commands[cmd]
if (cmd && cmd.completion) return cmd.completion(opts, cb)
// nothing to do.
cb()
}
function dumpScript (cb) {
var fs = require('graceful-fs')
...function fsAccessImplementation(dir, done) {
done = inflight('writable:' + dir, done)
if (!done) return
fs.access(dir, fs.W_OK, done)
}n/a
function fsAccessImplementation(dir, done) {
done = inflight('writable:' + dir, done)
if (!done) return
fs.access(dir, fs.W_OK, done)
}n/a
function fsOpenImplementation(dir, done) {
done = inflight('writable:' + dir, done)
if (!done) return
var tmp = path.join(dir, '.npm.check.permissions')
fs.open(tmp, 'w', function (er, fd) {
if (er) return done(accessError(dir, er))
fs.close(fd, function () {
fs.unlink(tmp, andIgnoreErrors(done))
})
})
}n/a