summaryrefslogtreecommitdiff
path: root/deps/npm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/lib')
-rw-r--r--deps/npm/lib/ci.js4
-rw-r--r--deps/npm/lib/config/cmd-list.js1
-rw-r--r--deps/npm/lib/config/defaults.js8
-rw-r--r--deps/npm/lib/doctor/check-ping.js2
-rw-r--r--deps/npm/lib/fund.js202
-rw-r--r--deps/npm/lib/help.js15
-rw-r--r--deps/npm/lib/install.js26
-rw-r--r--deps/npm/lib/install/actions.js2
-rw-r--r--deps/npm/lib/install/deps.js15
-rw-r--r--deps/npm/lib/install/fund.js48
-rw-r--r--deps/npm/lib/install/inflate-shrinkwrap.js7
-rw-r--r--deps/npm/lib/install/read-shrinkwrap.js3
-rw-r--r--deps/npm/lib/install/validate-args.js25
-rw-r--r--deps/npm/lib/npm.js22
-rw-r--r--deps/npm/lib/pack.js4
-rw-r--r--deps/npm/lib/shrinkwrap.js8
-rw-r--r--deps/npm/lib/token.js1
-rw-r--r--deps/npm/lib/unbuild.js7
-rw-r--r--deps/npm/lib/utils/error-message.js5
-rw-r--r--deps/npm/lib/utils/funding.js153
-rw-r--r--deps/npm/lib/utils/open-url.js23
-rw-r--r--deps/npm/lib/utils/unsupported.js5
-rw-r--r--deps/npm/lib/version.js2
23 files changed, 543 insertions, 45 deletions
diff --git a/deps/npm/lib/ci.js b/deps/npm/lib/ci.js
index 309ad2f784..a0df3b86ff 100644
--- a/deps/npm/lib/ci.js
+++ b/deps/npm/lib/ci.js
@@ -4,6 +4,7 @@ const npm = require('./npm.js')
const Installer = require('libcipm')
const log = require('npmlog')
const path = require('path')
+const pack = require('./pack.js')
ci.usage = 'npm ci'
@@ -27,7 +28,8 @@ function ci (args, cb) {
fmode: npm.modes.file,
umask: npm.modes.umask,
npmVersion: npm.version,
- tmp: npm.tmp
+ tmp: npm.tmp,
+ dirPacker: pack.packGitDep
}
for (const key in npm.config.list[0]) {
diff --git a/deps/npm/lib/config/cmd-list.js b/deps/npm/lib/config/cmd-list.js
index fa4390fcdc..d9d0d85b7d 100644
--- a/deps/npm/lib/config/cmd-list.js
+++ b/deps/npm/lib/config/cmd-list.js
@@ -91,6 +91,7 @@ var cmdList = [
'token',
'profile',
'audit',
+ 'fund',
'org',
'help',
diff --git a/deps/npm/lib/config/defaults.js b/deps/npm/lib/config/defaults.js
index f563357d4c..e07da3aaf9 100644
--- a/deps/npm/lib/config/defaults.js
+++ b/deps/npm/lib/config/defaults.js
@@ -141,6 +141,9 @@ Object.defineProperty(exports, 'defaults', {get: function () {
editor: osenv.editor(),
'engine-strict': false,
force: false,
+ 'format-package-lock': true,
+
+ fund: true,
'fetch-retries': 2,
'fetch-retry-factor': 10,
@@ -201,7 +204,8 @@ Object.defineProperty(exports, 'defaults', {get: function () {
'user-agent': 'npm/{npm-version} ' +
'node/{node-version} ' +
'{platform} ' +
- '{arch}',
+ '{arch} ' +
+ '{ci}',
'read-only': false,
'rebuild-bundle': true,
registry: 'https://registry.npmjs.org/',
@@ -282,6 +286,8 @@ exports.types = {
editor: String,
'engine-strict': Boolean,
force: Boolean,
+ fund: Boolean,
+ 'format-package-lock': Boolean,
'fetch-retries': Number,
'fetch-retry-factor': Number,
'fetch-retry-mintimeout': Number,
diff --git a/deps/npm/lib/doctor/check-ping.js b/deps/npm/lib/doctor/check-ping.js
index 70db255480..58f14fe69e 100644
--- a/deps/npm/lib/doctor/check-ping.js
+++ b/deps/npm/lib/doctor/check-ping.js
@@ -8,7 +8,7 @@ function checkPing (cb) {
if (err && err.code && err.code.match(/^E\d{3}$/)) {
return cb(null, [err.code.substr(1)])
} else {
- cb(null, [200, 'OK'])
+ cb(null, [200, 'ok'])
}
})
}
diff --git a/deps/npm/lib/fund.js b/deps/npm/lib/fund.js
new file mode 100644
index 0000000000..00954c844d
--- /dev/null
+++ b/deps/npm/lib/fund.js
@@ -0,0 +1,202 @@
+'use strict'
+
+const path = require('path')
+
+const archy = require('archy')
+const figgyPudding = require('figgy-pudding')
+const readPackageTree = require('read-package-tree')
+
+const npm = require('./npm.js')
+const npmConfig = require('./config/figgy-config.js')
+const fetchPackageMetadata = require('./fetch-package-metadata.js')
+const computeMetadata = require('./install/deps.js').computeMetadata
+const readShrinkwrap = require('./install/read-shrinkwrap.js')
+const mutateIntoLogicalTree = require('./install/mutate-into-logical-tree.js')
+const output = require('./utils/output.js')
+const openUrl = require('./utils/open-url.js')
+const { getFundingInfo, retrieveFunding, validFundingUrl } = require('./utils/funding.js')
+
+const FundConfig = figgyPudding({
+ browser: {}, // used by ./utils/open-url
+ global: {},
+ json: {},
+ unicode: {}
+})
+
+module.exports = fundCmd
+
+const usage = require('./utils/usage')
+fundCmd.usage = usage(
+ 'fund',
+ 'npm fund [--json]',
+ 'npm fund [--browser] [[<@scope>/]<pkg>'
+)
+
+fundCmd.completion = function (opts, cb) {
+ const argv = opts.conf.argv.remain
+ switch (argv[2]) {
+ case 'fund':
+ return cb(null, [])
+ default:
+ return cb(new Error(argv[2] + ' not recognized'))
+ }
+}
+
+function printJSON (fundingInfo) {
+ return JSON.stringify(fundingInfo, null, 2)
+}
+
+// the human-printable version does some special things that turned out to
+// be very verbose but hopefully not hard to follow: we stack up items
+// that have a shared url/type and make sure they're printed at the highest
+// level possible, in that process they also carry their dependencies along
+// with them, moving those up in the visual tree
+function printHuman (fundingInfo, opts) {
+ // mapping logic that keeps track of seen items in order to be able
+ // to push all other items from the same type/url in the same place
+ const seen = new Map()
+
+ function seenKey ({ type, url } = {}) {
+ return url ? String(type) + String(url) : null
+ }
+
+ function setStackedItem (funding, result) {
+ const key = seenKey(funding)
+ if (key && !seen.has(key)) seen.set(key, result)
+ }
+
+ function retrieveStackedItem (funding) {
+ const key = seenKey(funding)
+ if (key && seen.has(key)) return seen.get(key)
+ }
+
+ // ---
+
+ const getFundingItems = (fundingItems) =>
+ Object.keys(fundingItems || {}).map((fundingItemName) => {
+ // first-level loop, prepare the pretty-printed formatted data
+ const fundingItem = fundingItems[fundingItemName]
+ const { version, funding } = fundingItem
+ const { type, url } = funding || {}
+
+ const printableVersion = version ? `@${version}` : ''
+ const printableType = type && { label: `type: ${funding.type}` }
+ const printableUrl = url && { label: `url: ${funding.url}` }
+ const result = {
+ fundingItem,
+ label: fundingItemName + printableVersion,
+ nodes: []
+ }
+
+ if (printableType) {
+ result.nodes.push(printableType)
+ }
+
+ if (printableUrl) {
+ result.nodes.push(printableUrl)
+ }
+
+ setStackedItem(funding, result)
+
+ return result
+ }).reduce((res, result) => {
+ // recurse and exclude nodes that are going to be stacked together
+ const { fundingItem } = result
+ const { dependencies, funding } = fundingItem
+ const items = getFundingItems(dependencies)
+ const stackedResult = retrieveStackedItem(funding)
+ items.forEach(i => result.nodes.push(i))
+
+ if (stackedResult && stackedResult !== result) {
+ stackedResult.label += `, ${result.label}`
+ items.forEach(i => stackedResult.nodes.push(i))
+ return res
+ }
+
+ res.push(result)
+
+ return res
+ }, [])
+
+ const [ result ] = getFundingItems({
+ [fundingInfo.name]: {
+ dependencies: fundingInfo.dependencies,
+ funding: fundingInfo.funding,
+ version: fundingInfo.version
+ }
+ })
+
+ return archy(result, '', { unicode: opts.unicode })
+}
+
+function openFundingUrl (packageName, cb) {
+ function getUrlAndOpen (packageMetadata) {
+ const { funding } = packageMetadata
+ const { type, url } = retrieveFunding(funding) || {}
+ const noFundingError =
+ new Error(`No funding method available for: ${packageName}`)
+ noFundingError.code = 'ENOFUND'
+ const typePrefix = type ? `${type} funding` : 'Funding'
+ const msg = `${typePrefix} available at the following URL`
+
+ if (validFundingUrl(funding)) {
+ openUrl(url, msg, cb)
+ } else {
+ throw noFundingError
+ }
+ }
+
+ fetchPackageMetadata(
+ packageName,
+ '.',
+ { fullMetadata: true },
+ function (err, packageMetadata) {
+ if (err) return cb(err)
+ getUrlAndOpen(packageMetadata)
+ }
+ )
+}
+
+function fundCmd (args, cb) {
+ const opts = FundConfig(npmConfig())
+ const dir = path.resolve(npm.dir, '..')
+ const packageName = args[0]
+
+ if (opts.global) {
+ const err = new Error('`npm fund` does not support globals')
+ err.code = 'EFUNDGLOBAL'
+ throw err
+ }
+
+ if (packageName) {
+ openFundingUrl(packageName, cb)
+ return
+ }
+
+ readPackageTree(dir, function (err, tree) {
+ if (err) {
+ process.exitCode = 1
+ return cb(err)
+ }
+
+ readShrinkwrap.andInflate(tree, function () {
+ const fundingInfo = getFundingInfo(
+ mutateIntoLogicalTree.asReadInstalled(
+ computeMetadata(tree)
+ )
+ )
+
+ const print = opts.json
+ ? printJSON
+ : printHuman
+
+ output(
+ print(
+ fundingInfo,
+ opts
+ )
+ )
+ cb(err, tree)
+ })
+ })
+}
diff --git a/deps/npm/lib/help.js b/deps/npm/lib/help.js
index 3f70f2dc1f..61f1f3f94c 100644
--- a/deps/npm/lib/help.js
+++ b/deps/npm/lib/help.js
@@ -63,7 +63,7 @@ function help (args, cb) {
// legacy
if (section === 'global') section = 'folders'
- else if (section === 'json') section = 'package.json'
+ else if (section.match(/.*json/)) section = section.replace('.json', '-json')
// find either /section.n or /npm-section.n
// The glob is used in the glob. The regexp is used much
@@ -140,24 +140,21 @@ function viewMan (man, cb) {
function htmlMan (man) {
var sect = +man.match(/([0-9]+)$/)[1]
- var f = path.basename(man).replace(/([0-9]+)$/, 'html')
+ var f = path.basename(man).replace(/[.]([0-9]+)$/, '')
switch (sect) {
case 1:
- sect = 'cli'
- break
- case 3:
- sect = 'api'
+ sect = 'cli-commands'
break
case 5:
- sect = 'files'
+ sect = 'configuring-npm'
break
case 7:
- sect = 'misc'
+ sect = 'using-npm'
break
default:
throw new Error('invalid man section: ' + sect)
}
- return path.resolve(__dirname, '..', 'html', 'doc', sect, f)
+ return path.resolve(__dirname, '..', 'docs', 'public', sect, f, 'index.html')
}
function npmUsage (valid, cb) {
diff --git a/deps/npm/lib/install.js b/deps/npm/lib/install.js
index 8cc6d16bdd..378ada7b05 100644
--- a/deps/npm/lib/install.js
+++ b/deps/npm/lib/install.js
@@ -26,6 +26,7 @@ install.usage = usage(
'\nnpm install [<@scope>/]<pkg>@<tag>' +
'\nnpm install [<@scope>/]<pkg>@<version>' +
'\nnpm install [<@scope>/]<pkg>@<version range>' +
+ '\nnpm install <alias>@npm:<name>' +
'\nnpm install <folder>' +
'\nnpm install <tarball file>' +
'\nnpm install <tarball url>' +
@@ -138,6 +139,10 @@ var validateArgs = require('./install/validate-args.js')
var saveRequested = require('./install/save.js').saveRequested
var saveShrinkwrap = require('./install/save.js').saveShrinkwrap
var audit = require('./install/audit.js')
+var {
+ getPrintFundingReport,
+ getPrintFundingReportJSON
+} = require('./install/fund.js')
var getSaveType = require('./install/save.js').getSaveType
var doSerialActions = require('./install/actions.js').doSerial
var doReverseSerialActions = require('./install/actions.js').doReverseSerial
@@ -240,6 +245,7 @@ function Installer (where, dryrun, args, opts) {
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.fund = npm.config.get('fund') && !this.global
this.started = Date.now()
}
Installer.prototype = {}
@@ -872,7 +878,6 @@ Installer.prototype.printInstalledForHuman = function (diffs, auditResult) {
report += ' in ' + ((Date.now() - this.started) / 1000) + 's'
output(report)
- return auditResult && audit.printInstallReport(auditResult)
function packages (num) {
return num + ' package' + (num > 1 ? 's' : '')
@@ -894,9 +899,27 @@ Installer.prototype.printInstalledForHuman = function (diffs, auditResult) {
if (argument.url) returned += ' (' + argument.email + ')'
return returned
}
+
+ const { fund, idealTree } = this
+ const printFundingReport = getPrintFundingReport({
+ fund,
+ idealTree
+ })
+ if (printFundingReport.length) {
+ output(printFundingReport)
+ }
+
+ if (auditResult) {
+ return audit.printInstallReport(auditResult)
+ }
}
Installer.prototype.printInstalledForJSON = function (diffs, auditResult) {
+ const { fund, idealTree } = this
+ const printFundingReport = getPrintFundingReportJSON({
+ fund,
+ idealTree
+ })
var result = {
added: [],
removed: [],
@@ -905,6 +928,7 @@ Installer.prototype.printInstalledForJSON = function (diffs, auditResult) {
failed: [],
warnings: [],
audit: auditResult,
+ funding: printFundingReport,
elapsed: Date.now() - this.started
}
var self = this
diff --git a/deps/npm/lib/install/actions.js b/deps/npm/lib/install/actions.js
index a34d03ffe2..e26432b77c 100644
--- a/deps/npm/lib/install/actions.js
+++ b/deps/npm/lib/install/actions.js
@@ -49,7 +49,7 @@ Object.keys(actions).forEach(function (actionName) {
if (pkg.knownInstallable) {
actionP = runAction(action, staging, pkg, log)
} else {
- actionP = isInstallable(pkg.package).then(() => {
+ actionP = isInstallable(null, pkg.package).then(() => {
pkg.knownInstallable = true
return runAction(action, staging, pkg, log)
})
diff --git a/deps/npm/lib/install/deps.js b/deps/npm/lib/install/deps.js
index bfc94ae504..3d8b333c64 100644
--- a/deps/npm/lib/install/deps.js
+++ b/deps/npm/lib/install/deps.js
@@ -203,10 +203,15 @@ function removeObsoleteDep (child, log) {
function packageRelativePath (tree) {
if (!tree) return ''
var requested = tree.package._requested || {}
- var isLocal = requested.type === 'directory' || requested.type === 'file'
- return isLocal ? requested.fetchSpec
- : (tree.isLink || tree.isInLink) && !preserveSymlinks() ? tree.realpath
- : tree.path
+ if (requested.type === 'directory') {
+ return requested.fetchSpec
+ } else if (requested.type === 'file') {
+ return path.dirname(requested.fetchSpec)
+ } else if ((tree.isLink || tree.isInLink) && !preserveSymlinks()) {
+ return tree.realpath
+ } else {
+ return tree.path
+ }
}
function matchingDep (tree, name) {
@@ -665,7 +670,7 @@ function resolveWithNewModule (pkg, tree, log, next) {
validate('OOOF', arguments)
log.silly('resolveWithNewModule', packageId(pkg), 'checking installable status')
- return isInstallable(pkg, (err) => {
+ return isInstallable(tree, pkg, (err) => {
let installable = !err
addBundled(pkg, (bundleErr) => {
var parent = earliestInstallable(tree, tree, pkg, log) || tree
diff --git a/deps/npm/lib/install/fund.js b/deps/npm/lib/install/fund.js
new file mode 100644
index 0000000000..809c05b338
--- /dev/null
+++ b/deps/npm/lib/install/fund.js
@@ -0,0 +1,48 @@
+'use strict'
+
+const { EOL } = require('os')
+
+const computeMetadata = require('./deps.js').computeMetadata
+const mutateIntoLogicalTree = require('./mutate-into-logical-tree.js')
+var { getFundingInfo } = require('../utils/funding.js')
+
+exports.getPrintFundingReport = getPrintFundingReport
+exports.getPrintFundingReportJSON = getPrintFundingReportJSON
+
+function getFundingResult ({ fund, idealTree }) {
+ if (fund) {
+ const fundingInfoTree =
+ mutateIntoLogicalTree.asReadInstalled(
+ computeMetadata(idealTree)
+ )
+ const fundResult = getFundingInfo(fundingInfoTree, { countOnly: true })
+ return fundResult
+ } else {
+ return {}
+ }
+}
+
+function getPrintFundingReport ({ fund, idealTree }, opts) {
+ const fundResult = getFundingResult({ fund, idealTree })
+ const { length } = fundResult || {}
+ const { json } = opts || {}
+
+ function padding (msg) {
+ return json ? '' : (EOL + msg)
+ }
+
+ function packageQuantity (amount) {
+ return `package${amount > 1 ? 's are' : ' is'}`
+ }
+
+ if (!length) return ''
+
+ return padding('') + length + ' ' +
+ packageQuantity(length) +
+ ' looking for funding' +
+ padding(' run `npm fund` for details\n')
+}
+
+function getPrintFundingReportJSON ({ fund, idealTree }) {
+ return getPrintFundingReport({ fund, idealTree }, { json: true })
+}
diff --git a/deps/npm/lib/install/inflate-shrinkwrap.js b/deps/npm/lib/install/inflate-shrinkwrap.js
index b0b71ef6b1..1ec4f9ba6d 100644
--- a/deps/npm/lib/install/inflate-shrinkwrap.js
+++ b/deps/npm/lib/install/inflate-shrinkwrap.js
@@ -141,6 +141,7 @@ function isGit (sw) {
}
function makeFakeChild (name, topPath, tree, sw, requested) {
+ const isDirectory = requested.type === 'directory'
const from = sw.from || requested.raw
const pkg = {
name: name,
@@ -167,16 +168,16 @@ function makeFakeChild (name, topPath, tree, sw, requested) {
}
const child = createChild({
package: pkg,
- loaded: true,
+ loaded: isDirectory,
parent: tree,
children: [],
fromShrinkwrap: requested,
fakeChild: sw,
fromBundle: sw.bundled ? tree.fromBundle || tree : null,
path: childPath(tree.path, pkg),
- realpath: requested.type === 'directory' ? requested.fetchSpec : childPath(tree.realpath, pkg),
+ realpath: isDirectory ? requested.fetchSpec : childPath(tree.realpath, pkg),
location: (tree.location === '/' ? '' : tree.location + '/') + pkg.name,
- isLink: requested.type === 'directory',
+ isLink: isDirectory,
isInLink: tree.isLink || tree.isInLink,
swRequires: sw.requires
})
diff --git a/deps/npm/lib/install/read-shrinkwrap.js b/deps/npm/lib/install/read-shrinkwrap.js
index 7074678011..1d9fb99c1d 100644
--- a/deps/npm/lib/install/read-shrinkwrap.js
+++ b/deps/npm/lib/install/read-shrinkwrap.js
@@ -19,8 +19,7 @@ function readShrinkwrap (child, next) {
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) => {
+ (shrinkwrap, lockfile) => {
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.')
}
diff --git a/deps/npm/lib/install/validate-args.js b/deps/npm/lib/install/validate-args.js
index 65b660417a..b680a1b24b 100644
--- a/deps/npm/lib/install/validate-args.js
+++ b/deps/npm/lib/install/validate-args.js
@@ -16,7 +16,7 @@ module.exports = function (idealTree, args, next) {
chain([
[hasMinimumFields, pkg],
[checkSelf, idealTree, pkg, force],
- [isInstallable, pkg]
+ [isInstallable, idealTree, pkg]
], done)
}, next)
}
@@ -31,13 +31,24 @@ function hasMinimumFields (pkg, cb) {
}
}
-function getWarnings (pkg) {
- while (pkg.parent) pkg = pkg.parent
- if (!pkg.warnings) pkg.warnings = []
- return pkg.warnings
+function setWarnings (idealTree, warn) {
+ function top (tree) {
+ if (tree.parent) return top(tree.parent)
+ return tree
+ }
+
+ var topTree = top(idealTree)
+ if (!topTree.warnings) topTree.warnings = []
+
+ if (topTree.warnings.every(i => (
+ i.code !== warn.code ||
+ i.required !== warn.required ||
+ i.pkgid !== warn.pkgid))) {
+ topTree.warnings.push(warn)
+ }
}
-var isInstallable = module.exports.isInstallable = function (pkg, next) {
+var isInstallable = module.exports.isInstallable = function (idealTree, pkg, next) {
var force = npm.config.get('force')
var nodeVersion = npm.config.get('node-version')
if (/-/.test(nodeVersion)) {
@@ -48,7 +59,7 @@ var isInstallable = module.exports.isInstallable = function (pkg, next) {
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)
+ if (idealTree && warn) setWarnings(idealTree, warn)
checkPlatform(pkg, force, next)
}
}
diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js
index 2ee9a99126..35850078f8 100644
--- a/deps/npm/lib/npm.js
+++ b/deps/npm/lib/npm.js
@@ -281,7 +281,27 @@
ua = ua.replace(/\{npm-version\}/gi, npm.version)
ua = ua.replace(/\{platform\}/gi, process.platform)
ua = ua.replace(/\{arch\}/gi, process.arch)
- config.set('user-agent', ua)
+
+ // continuous integration platforms
+ const ci = process.env.GERRIT_PROJECT ? 'ci/gerrit'
+ : process.env.GITLAB_CI ? 'ci/gitlab'
+ : process.env.CIRCLECI ? 'ci/circle-ci'
+ : process.env.SEMAPHORE ? 'ci/semaphore'
+ : process.env.DRONE ? 'ci/drone'
+ : process.env.GITHUB_ACTION ? 'ci/github-actions'
+ : process.env.TDDIUM ? 'ci/tddium'
+ : process.env.JENKINS_URL ? 'ci/jenkins'
+ : process.env['bamboo.buildKey'] ? 'ci/bamboo'
+ : process.env.GO_PIPELINE_NAME ? 'ci/gocd'
+ // codeship and a few others
+ : process.env.CI_NAME ? `ci/${process.env.CI_NAME}`
+ // test travis last, since many of these mimic it
+ : process.env.TRAVIS ? 'ci/travis-ci'
+ : process.env.CI === 'true' || process.env.CI === '1' ? 'ci/custom'
+ : ''
+ ua = ua.replace(/\{ci\}/gi, ci)
+
+ config.set('user-agent', ua.trim())
if (config.get('metrics-registry') == null) {
config.set('metrics-registry', config.get('registry'))
diff --git a/deps/npm/lib/pack.js b/deps/npm/lib/pack.js
index 78e5bfd174..8189cb6ced 100644
--- a/deps/npm/lib/pack.js
+++ b/deps/npm/lib/pack.js
@@ -4,6 +4,9 @@
// Packs the specified package into a .tgz file, which can then
// be installed.
+// Set this early to avoid issues with circular dependencies.
+module.exports = pack
+
const BB = require('bluebird')
const byteSize = require('byte-size')
@@ -37,7 +40,6 @@ pack.usage = 'npm pack [[<@scope>/]<pkg>...] [--dry-run]'
// if it can be installed, it can be packed.
pack.completion = install.completion
-module.exports = pack
function pack (args, silent, cb) {
const cwd = process.cwd()
if (typeof cb !== 'function') {
diff --git a/deps/npm/lib/shrinkwrap.js b/deps/npm/lib/shrinkwrap.js
index 0a3f53546c..5428e7255b 100644
--- a/deps/npm/lib/shrinkwrap.js
+++ b/deps/npm/lib/shrinkwrap.js
@@ -282,11 +282,15 @@ function checkPackageFile (dir, name) {
return readFile(
file, 'utf8'
).then((data) => {
+ const format = npm.config.get('format-package-lock') !== false
+ const indent = format ? detectIndent(data).indent : 0
+ const newline = format ? detectNewline(data) : 0
+
return {
path: file,
raw: data,
- indent: detectIndent(data).indent,
- newline: detectNewline(data)
+ indent,
+ newline
}
}).catch({code: 'ENOENT'}, () => {})
}
diff --git a/deps/npm/lib/token.js b/deps/npm/lib/token.js
index 9b1fbef9ce..96a05e4566 100644
--- a/deps/npm/lib/token.js
+++ b/deps/npm/lib/token.js
@@ -118,7 +118,6 @@ function config () {
})
} else {
conf = conf.concat({ auth: {} })
- conf.auth = {}
}
if (conf.otp) conf.auth.otp = conf.otp
return conf
diff --git a/deps/npm/lib/unbuild.js b/deps/npm/lib/unbuild.js
index e06ee5eb30..3e8d3e4f1f 100644
--- a/deps/npm/lib/unbuild.js
+++ b/deps/npm/lib/unbuild.js
@@ -78,8 +78,11 @@ function rmBins (pkg, folder, parent, top, cb) {
const binRoot = top ? npm.bin : path.resolve(parent, '.bin')
asyncMap(Object.keys(pkg.bin), function (b, cb) {
if (process.platform === 'win32') {
- chain([ [gentlyRm, path.resolve(binRoot, b) + '.cmd', true, folder],
- [gentlyRm, path.resolve(binRoot, b), true, folder] ], cb)
+ chain([
+ [gentlyRm, path.resolve(binRoot, b) + '.ps1', true, folder],
+ [gentlyRm, path.resolve(binRoot, b) + '.cmd', true, folder],
+ [gentlyRm, path.resolve(binRoot, b), true, folder]
+ ], cb)
} else {
gentlyRm(path.resolve(binRoot, b), true, folder, cb)
}
diff --git a/deps/npm/lib/utils/error-message.js b/deps/npm/lib/utils/error-message.js
index 5ddfb37682..12f304d1e8 100644
--- a/deps/npm/lib/utils/error-message.js
+++ b/deps/npm/lib/utils/error-message.js
@@ -280,8 +280,9 @@ function errorMessage (er) {
case 'EEXIST':
short.push(['', er.message])
- short.push(['', 'File exists: ' + er.path])
- detail.push(['', 'Move it away, and try again.'])
+ short.push(['', 'File exists: ' + (er.dest || er.path)])
+ detail.push(['', 'Remove the existing file and try again, or run npm'])
+ detail.push(['', 'with --force to overwrite files recklessly.'])
break
case 'ENEEDAUTH':
diff --git a/deps/npm/lib/utils/funding.js b/deps/npm/lib/utils/funding.js
new file mode 100644
index 0000000000..c3d06b1089
--- /dev/null
+++ b/deps/npm/lib/utils/funding.js
@@ -0,0 +1,153 @@
+'use strict'
+
+const URL = require('url').URL
+
+exports.getFundingInfo = getFundingInfo
+exports.retrieveFunding = retrieveFunding
+exports.validFundingUrl = validFundingUrl
+
+// supports both object funding and string shorthand
+function retrieveFunding (funding) {
+ return typeof funding === 'string'
+ ? {
+ url: funding
+ }
+ : funding
+}
+
+// Is the value of a `funding` property of a `package.json`
+// a valid type+url for `npm fund` to display?
+function validFundingUrl (funding) {
+ if (!funding) return false
+
+ try {
+ var parsed = new URL(funding.url || funding)
+ } catch (error) {
+ return false
+ }
+
+ if (
+ parsed.protocol !== 'https:' &&
+ parsed.protocol !== 'http:'
+ ) return false
+
+ return Boolean(parsed.host)
+}
+
+function getFundingInfo (idealTree, opts) {
+ let length = 0
+ const seen = new Set()
+ const { countOnly } = opts || {}
+ const empty = () => Object.create(null)
+ const _trailingDependencies = Symbol('trailingDependencies')
+
+ function tracked (name, version) {
+ const key = String(name) + String(version)
+ if (seen.has(key)) {
+ return true
+ }
+ seen.add(key)
+ }
+
+ function retrieveDependencies (dependencies) {
+ const trailing = dependencies[_trailingDependencies]
+
+ if (trailing) {
+ return Object.assign(
+ empty(),
+ dependencies,
+ trailing
+ )
+ }
+
+ return dependencies
+ }
+
+ function hasDependencies (dependencies) {
+ return dependencies && (
+ Object.keys(dependencies).length ||
+ dependencies[_trailingDependencies]
+ )
+ }
+
+ function getFundingDependencies (tree) {
+ const deps = tree && tree.dependencies
+ if (!deps) return empty()
+
+ // broken into two steps to make sure items appearance
+ // within top levels takes precedence over nested ones
+ return (Object.keys(deps)).map((key) => {
+ const dep = deps[key]
+ const { name, funding, version } = dep
+
+ const fundingItem = {}
+
+ // avoids duplicated items within the funding tree
+ if (tracked(name, version)) return empty()
+
+ if (version) {
+ fundingItem.version = version
+ }
+
+ if (funding && validFundingUrl(funding)) {
+ fundingItem.funding = retrieveFunding(funding)
+ length++
+ }
+
+ return {
+ dep,
+ fundingItem
+ }
+ }).reduce((res, { dep, fundingItem }, i) => {
+ if (!fundingItem) return res
+
+ // recurse
+ const dependencies = dep.dependencies &&
+ Object.keys(dep.dependencies).length > 0 &&
+ getFundingDependencies(dep)
+
+ // if we're only counting items there's no need
+ // to add all the data to the resulting object
+ if (countOnly) return null
+
+ if (hasDependencies(dependencies)) {
+ fundingItem.dependencies = retrieveDependencies(dependencies)
+ }
+
+ if (fundingItem.funding) {
+ res[dep.name] = fundingItem
+ } else if (fundingItem.dependencies) {
+ res[_trailingDependencies] =
+ Object.assign(
+ empty(),
+ res[_trailingDependencies],
+ fundingItem.dependencies
+ )
+ }
+
+ return res
+ }, empty())
+ }
+
+ const idealTreeDependencies = getFundingDependencies(idealTree)
+ const result = {
+ length
+ }
+
+ if (!countOnly) {
+ result.name = idealTree.name || idealTree.path
+
+ if (idealTree && idealTree.version) {
+ result.version = idealTree.version
+ }
+
+ if (idealTree && idealTree.funding) {
+ result.funding = retrieveFunding(idealTree.funding)
+ }
+
+ result.dependencies =
+ retrieveDependencies(idealTreeDependencies)
+ }
+
+ return result
+}
diff --git a/deps/npm/lib/utils/open-url.js b/deps/npm/lib/utils/open-url.js
index 7a48d2e868..e1ed2b3fab 100644
--- a/deps/npm/lib/utils/open-url.js
+++ b/deps/npm/lib/utils/open-url.js
@@ -5,9 +5,28 @@ const opener = require('opener')
// attempt to open URL in web-browser, print address otherwise:
module.exports = function open (url, errMsg, cb, browser = npm.config.get('browser')) {
- opener(url, { command: npm.config.get('browser') }, (er) => {
+ function printAlternateMsg () {
+ const json = npm.config.get('json')
+ const alternateMsg = json
+ ? JSON.stringify({
+ title: errMsg,
+ url
+ }, null, 2)
+ : `${errMsg}:\n\n${url}`
+
+ output(alternateMsg)
+ }
+
+ const skipBrowser = process.argv.indexOf('--no-browser') > -1
+
+ if (skipBrowser) {
+ printAlternateMsg()
+ return cb()
+ }
+
+ opener(url, { command: browser }, (er) => {
if (er && er.code === 'ENOENT') {
- output(`${errMsg}:\n\n${url}`)
+ printAlternateMsg()
return cb()
} else {
return cb(er)
diff --git a/deps/npm/lib/utils/unsupported.js b/deps/npm/lib/utils/unsupported.js
index 20cee157ee..71a304030e 100644
--- a/deps/npm/lib/utils/unsupported.js
+++ b/deps/npm/lib/utils/unsupported.js
@@ -6,9 +6,10 @@ var supportedNode = [
{ver: '9', min: '9.0.0'},
{ver: '10', min: '10.0.0'},
{ver: '11', min: '11.0.0'},
- {ver: '12', min: '12.0.0'}
+ {ver: '12', min: '12.0.0'},
+ {ver: '13', min: '13.0.0'}
]
-var knownBroken = '<6.0.0'
+var knownBroken = '<6.2.0 || 9.0 - 9.2'
var checkVersion = exports.checkVersion = function (version) {
var versionNoPrerelease = version.replace(/-.*$/, '')
diff --git a/deps/npm/lib/version.js b/deps/npm/lib/version.js
index 0f1e97aedd..a8c2a648c7 100644
--- a/deps/npm/lib/version.js
+++ b/deps/npm/lib/version.js
@@ -256,7 +256,7 @@ function checkGit (localData, cb) {
statGitFolder(function (er) {
var doGit = !er && npm.config.get('git-tag-version')
if (!doGit) {
- if (er) log.verbose('version', 'error checking for .git', er)
+ if (er && npm.config.get('git-tag-version')) log.verbose('version', 'error checking for .git', er)
log.verbose('version', 'not tagging in git')
return cb(null, false)
}