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