mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
deps: upgrade npm to 7.1.1
PR-URL: https://github.com/nodejs/node/pull/36459 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com>
This commit is contained in:
1 parent
7faeddf23a
commit
f51a0e4b85
127 files changed
+4161
-766
No files matched your search
Vendored
+47
@@ -1,3 +1,50 @@
|
||||
## 7.1.1 (2020-12-08)
|
||||
|
||||
### DEPENDENCIES
|
||||
|
||||
* [`bf09e719c`](https://github.com/npm/cli/commit/bf09e719c7f563a255b1e9af6b1237ebc5598db6)
|
||||
`@npmcli/arborist@2.0.0`
|
||||
* Much stricter tree integrity guarantees
|
||||
* Fix issues where the root project is a symlink, or linked as a
|
||||
workspace
|
||||
* [`7ceb5b728`](https://github.com/npm/cli/commit/7ceb5b728b9f326c567f5ffe5831c9eccf013aa0)
|
||||
`ini@1.3.6`
|
||||
* [`77c6ced2a`](https://github.com/npm/cli/commit/77c6ced2a6daaadbff715c8f05b2e61ba76e9bab)
|
||||
`make-fetch-happen@8.0.11`
|
||||
* Avoid caching headers that are hazardous or unnecessary to leave
|
||||
lying around (authorization, npm-session, etc.)
|
||||
* [#38](https://github.com/npm/make-fetch-happen/pull/38) Include query
|
||||
string in cache key ([@jpb](https://github.com/jpb))
|
||||
* [`0ef25b6cd`](https://github.com/npm/cli/commit/0ef25b6cd2921794d36f066e2b11c406342cf167)
|
||||
`libnpmsearch@3.1.0`:
|
||||
* Update to accept query params as options, so we can paginate.
|
||||
([@nlf](https://github.com/nlf))
|
||||
* [`518a66450`](https://github.com/npm/cli/commit/518a664500bcde30475788e8c1c3e651f23e881b)
|
||||
`@npmcli/config@1.2.4`:
|
||||
* Do not allow path options to be set to a boolean `false` value
|
||||
* [`3d7aff9d8`](https://github.com/npm/cli/commit/3d7aff9d8dd1cf29956aa306464cd44fbc2af426)
|
||||
update all dependencies using latest npm to install them
|
||||
|
||||
### TESTS
|
||||
|
||||
* [`2848f5940`](https://github.com/npm/cli/commit/2848f594034b87939bfc5546e3e603f123d98a01)
|
||||
[npm/statusboard#173](https://github.com/npm/statusboard/issues/173)
|
||||
[#2293](https://github.com/npm/cli/issues/2293) npm shrinkwrap
|
||||
([@ruyadorno](https://github.com/ruyadorno))
|
||||
* [`f6824459a`](https://github.com/npm/cli/commit/f6824459ae0c86e2fa9c84b3dcec85f572ae8e1b)
|
||||
[#2302](https://github.com/npm/cli/issues/2302) npm deprecate
|
||||
([@nlf](https://github.com/nlf))
|
||||
* [`b7d74b627`](https://github.com/npm/cli/commit/b7d74b627859f08fca23209d6e0d3ec6657a4489)
|
||||
[npm/statusboard#180](https://github.com/npm/statusboard/issues/180)
|
||||
[#2304](https://github.com/npm/cli/issues/2304) npm unpublish
|
||||
([@ruyadorno](https://github.com/ruyadorno))
|
||||
|
||||
### FEATURES
|
||||
|
||||
* [`3db90d944`](https://github.com/npm/cli/commit/3db90d94474f673591811fdab5eb6a5bfdeba261)
|
||||
[#2303](https://github.com/npm/cli/issues/2303) allow for passing object
|
||||
keys to searchopts to allow pagination ([@nlf](https://github.com/nlf))
|
||||
|
||||
## 7.1.0 (2020-12-04)
|
||||
|
||||
### FEATURES
|
||||
|
||||
+1
-1
@@ -156,7 +156,7 @@ installed, as well as their dependencies, in a tree-structure.</p>
|
||||
limit the results to only the paths to the packages named. Note that
|
||||
nested packages will <em>also</em> show the paths to the specified packages.
|
||||
For example, running <code>npm ls promzard</code> in npm’s source tree will show:</p>
|
||||
<pre lang="bash"><code> npm@7.1.0 /path/to/npm
|
||||
<pre lang="bash"><code> npm@7.1.1 /path/to/npm
|
||||
└─┬ init-package-json@0.0.4
|
||||
└── promzard@0.1.5
|
||||
</code></pre>
|
||||
|
||||
+1
-1
@@ -148,7 +148,7 @@ npm command-line interface
|
||||
<pre lang="bash"><code>npm <command> [args]
|
||||
</code></pre>
|
||||
<h3 id="version">Version</h3>
|
||||
<p>7.1.0</p>
|
||||
<p>7.1.1</p>
|
||||
<h3 id="description">Description</h3>
|
||||
<p>npm is the package manager for the Node JavaScript platform. It puts
|
||||
modules in place so that node can find them, and manages dependency
|
||||
|
||||
Vendored
+58
-54
@@ -5,68 +5,72 @@ const fetch = require('npm-registry-fetch')
|
||||
const otplease = require('./utils/otplease.js')
|
||||
const npa = require('npm-package-arg')
|
||||
const semver = require('semver')
|
||||
const getItentity = require('./utils/get-identity')
|
||||
const getIdentity = require('./utils/get-identity.js')
|
||||
const libaccess = require('libnpmaccess')
|
||||
const usageUtil = require('./utils/usage.js')
|
||||
|
||||
module.exports = deprecate
|
||||
const UsageError = () =>
|
||||
Object.assign(new Error(`\nUsage: ${usage}`), {
|
||||
code: 'EUSAGE',
|
||||
})
|
||||
|
||||
deprecate.usage = 'npm deprecate <pkg>[@<version>] <message>'
|
||||
const usage = usageUtil(
|
||||
'deprecate',
|
||||
'npm deprecate <pkg>[@<version>] <message>'
|
||||
)
|
||||
|
||||
deprecate.completion = function (opts, cb) {
|
||||
return Promise.resolve().then(() => {
|
||||
if (opts.conf.argv.remain.length > 2)
|
||||
return
|
||||
return getItentity(npm.flatOptions).then(username => {
|
||||
if (username) {
|
||||
// first, get a list of remote packages this user owns.
|
||||
// once we have a user account, then don't complete anything.
|
||||
// get the list of packages by user
|
||||
return fetch(
|
||||
`/-/by-user/${encodeURIComponent(username)}`,
|
||||
npm.flatOptions
|
||||
).then(list => list[username])
|
||||
}
|
||||
const completion = (opts, cb) => {
|
||||
if (opts.conf.argv.remain.length > 1)
|
||||
return cb(null, [])
|
||||
|
||||
return getIdentity(npm.flatOptions).then((username) => {
|
||||
return libaccess.lsPackages(username, npm.flatOptions).then((packages) => {
|
||||
return Object.keys(packages)
|
||||
.filter((name) => packages[name] === 'write' &&
|
||||
(opts.conf.argv.remain.length === 0 || name.startsWith(opts.conf.argv.remain[0]))
|
||||
)
|
||||
})
|
||||
}).then(() => cb(), er => cb(er))
|
||||
}).then((list) => cb(null, list), (err) => cb(err))
|
||||
}
|
||||
|
||||
function deprecate ([pkg, msg], opts, cb) {
|
||||
if (typeof cb !== 'function') {
|
||||
cb = opts
|
||||
opts = null
|
||||
}
|
||||
opts = opts || npm.flatOptions
|
||||
return Promise.resolve().then(() => {
|
||||
if (msg == null)
|
||||
throw new Error(`Usage: ${deprecate.usage}`)
|
||||
// fetch the data and make sure it exists.
|
||||
const p = npa(pkg)
|
||||
const cmd = (args, cb) =>
|
||||
deprecate(args)
|
||||
.then(() => cb())
|
||||
.catch(err => cb(err.code === 'EUSAGE' ? err.message : err))
|
||||
|
||||
// npa makes the default spec "latest", but for deprecation
|
||||
// "*" is the appropriate default.
|
||||
const spec = p.rawSpec === '' ? '*' : p.fetchSpec
|
||||
const deprecate = async ([pkg, msg]) => {
|
||||
if (!pkg || !msg)
|
||||
throw UsageError()
|
||||
|
||||
if (semver.validRange(spec, true) === null)
|
||||
throw new Error('invalid version range: ' + spec)
|
||||
// fetch the data and make sure it exists.
|
||||
const p = npa(pkg)
|
||||
// npa makes the default spec "latest", but for deprecation
|
||||
// "*" is the appropriate default.
|
||||
const spec = p.rawSpec === '' ? '*' : p.fetchSpec
|
||||
|
||||
const uri = '/' + p.escapedName
|
||||
return fetch.json(uri, {
|
||||
...opts,
|
||||
spec: p,
|
||||
query: { write: true },
|
||||
}).then(packument => {
|
||||
// filter all the versions that match
|
||||
Object.keys(packument.versions)
|
||||
.filter(v => semver.satisfies(v, spec))
|
||||
.forEach(v => {
|
||||
packument.versions[v].deprecated = msg
|
||||
})
|
||||
return otplease(opts, opts => fetch(uri, {
|
||||
...opts,
|
||||
spec: p,
|
||||
method: 'PUT',
|
||||
body: packument,
|
||||
ignoreBody: true,
|
||||
}))
|
||||
if (semver.validRange(spec, true) === null)
|
||||
throw new Error(`invalid version range: ${spec}`)
|
||||
|
||||
const uri = '/' + p.escapedName
|
||||
const packument = await fetch.json(uri, {
|
||||
...npm.flatOptions,
|
||||
spec: p,
|
||||
query: { write: true },
|
||||
})
|
||||
|
||||
Object.keys(packument.versions)
|
||||
.filter(v => semver.satisfies(v, spec))
|
||||
.forEach(v => {
|
||||
packument.versions[v].deprecated = msg
|
||||
})
|
||||
}).then(() => cb(), cb)
|
||||
|
||||
return otplease(npm.flatOptions, opts => fetch(uri, {
|
||||
...opts,
|
||||
spec: p,
|
||||
method: 'PUT',
|
||||
body: packument,
|
||||
ignoreBody: true,
|
||||
}))
|
||||
}
|
||||
|
||||
module.exports = Object.assign(cmd, { completion, usage })
|
||||
Vendored
+9
-7
@@ -1,13 +1,16 @@
|
||||
const Arborist = require('@npmcli/arborist')
|
||||
const npm = require('./npm.js')
|
||||
const usageUtil = require('./utils/usage.js')
|
||||
const usage = usageUtil('shrinkwrap', 'npm shrinkwrap')
|
||||
'use strict'
|
||||
|
||||
const { resolve, basename } = require('path')
|
||||
const { promises: { unlink } } = require('fs')
|
||||
const Arborist = require('@npmcli/arborist')
|
||||
const log = require('npmlog')
|
||||
|
||||
const cmd = (args, cb) => shrinkwrap().then(() => cb()).catch(cb)
|
||||
|
||||
const npm = require('./npm.js')
|
||||
const completion = require('./utils/completion/none.js')
|
||||
const usageUtil = require('./utils/usage.js')
|
||||
const usage = usageUtil('shrinkwrap', 'npm shrinkwrap')
|
||||
|
||||
const cmd = (args, cb) => shrinkwrap().then(() => cb()).catch(cb)
|
||||
|
||||
const shrinkwrap = async () => {
|
||||
// if has a npm-shrinkwrap.json, nothing to do
|
||||
@@ -31,7 +34,6 @@ const shrinkwrap = async () => {
|
||||
const newFile = meta.hiddenLockfile || !meta.loadedFromDisk
|
||||
const oldFilename = meta.filename
|
||||
const notSW = !newFile && basename(oldFilename) !== 'npm-shrinkwrap.json'
|
||||
const { promises: { unlink } } = require('fs')
|
||||
|
||||
meta.hiddenLockfile = false
|
||||
meta.filename = sw
|
||||
|
||||
Vendored
+32
-25
@@ -1,3 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
const path = require('path')
|
||||
const util = require('util')
|
||||
const log = require('npmlog')
|
||||
@@ -11,7 +13,7 @@ const npm = require('./npm.js')
|
||||
const usageUtil = require('./utils/usage.js')
|
||||
const output = require('./utils/output.js')
|
||||
const otplease = require('./utils/otplease.js')
|
||||
const whoami = util.promisify(require('./whoami.js'))
|
||||
const getIdentity = require('./utils/get-identity.js')
|
||||
|
||||
const usage = usageUtil('unpublish', 'npm unpublish [<@scope>/]<pkg>[@<version>]')
|
||||
|
||||
@@ -25,18 +27,18 @@ const completionFn = async (args) => {
|
||||
const { partialWord, conf } = args
|
||||
|
||||
if (conf.argv.remain.length >= 3)
|
||||
return
|
||||
return []
|
||||
|
||||
const username = await whoami([], true)
|
||||
const opts = npm.flatOptions
|
||||
const username = await getIdentity({ ...opts }).catch(() => null)
|
||||
if (!username)
|
||||
return []
|
||||
const opts = npm.flatOptions
|
||||
|
||||
const access = await libaccess.lsPackages(username, opts)
|
||||
// do a bit of filtering at this point, so that we don't need
|
||||
// to fetch versions for more than one thing, but also don't
|
||||
// accidentally a whole project
|
||||
let pkgs = Object.keys(access)
|
||||
let pkgs = Object.keys(access || {})
|
||||
if (!partialWord || !pkgs.length)
|
||||
return pkgs
|
||||
|
||||
@@ -55,18 +57,20 @@ const completionFn = async (args) => {
|
||||
|
||||
async function unpublish (args) {
|
||||
if (args.length > 1)
|
||||
throw usage
|
||||
throw new Error(usage)
|
||||
|
||||
const spec = args.length && npa(args[0])
|
||||
const opts = npm.flatOptions
|
||||
const { force, silent, loglevel } = opts
|
||||
let ret
|
||||
let res
|
||||
let pkgName
|
||||
let pkgVersion
|
||||
|
||||
log.silly('unpublish', 'args[0]', args[0])
|
||||
log.silly('unpublish', 'spec', spec)
|
||||
|
||||
if (!spec.rawSpec && !force) {
|
||||
throw (
|
||||
throw new Error(
|
||||
'Refusing to delete entire project.\n' +
|
||||
'Run with --force to do this.\n' +
|
||||
usage
|
||||
@@ -77,31 +81,34 @@ async function unpublish (args) {
|
||||
// if there's a package.json in the current folder, then
|
||||
// read the package name and version out of that.
|
||||
const pkgJson = path.join(npm.localPrefix, 'package.json')
|
||||
const manifest = await readJson(pkgJson)
|
||||
let manifest
|
||||
try {
|
||||
manifest = await readJson(pkgJson)
|
||||
} catch (err) {
|
||||
if (err && err.code !== 'ENOENT' && err.code !== 'ENOTDIR')
|
||||
throw err
|
||||
else
|
||||
throw new Error(`Usage: ${usage}`)
|
||||
}
|
||||
|
||||
log.verbose('unpublish', manifest)
|
||||
|
||||
const { name, version, publishConfig } = manifest
|
||||
const pkgJsonSpec = npa.resolve(name, version)
|
||||
|
||||
try {
|
||||
ret = await otplease(opts, opts => libunpub(pkgJsonSpec, { ...opts, publishConfig }))
|
||||
} catch (err) {
|
||||
if (err && err.code !== 'ENOENT' && err.code !== 'ENOTDIR')
|
||||
throw err
|
||||
else
|
||||
throw `Usage: ${usage}`
|
||||
}
|
||||
} else
|
||||
ret = await otplease(opts, opts => libunpub(spec, opts))
|
||||
|
||||
if (!silent && loglevel !== 'silent') {
|
||||
output(`- ${spec.name}${
|
||||
spec.type === 'version' ? `@${spec.rawSpec}` : ''
|
||||
}`)
|
||||
res = await otplease(opts, opts => libunpub(pkgJsonSpec, { ...opts, publishConfig }))
|
||||
pkgName = name
|
||||
pkgVersion = version ? `@${version}` : ''
|
||||
} else {
|
||||
res = await otplease(opts, opts => libunpub(spec, opts))
|
||||
pkgName = spec.name
|
||||
pkgVersion = spec.type === 'version' ? `@${spec.rawSpec}` : ''
|
||||
}
|
||||
|
||||
return ret
|
||||
if (!silent && loglevel !== 'silent')
|
||||
output(`- ${pkgName}${pkgVersion}`)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
module.exports = Object.assign(cmd, { completion, usage })
|
||||
@@ -13,6 +13,7 @@ const readNames = async () => {
|
||||
|
||||
const getValues = (tree) =>
|
||||
[...tree.inventory.values()]
|
||||
.filter(i => i.location !== '' && !i.isRoot)
|
||||
.map(i => {
|
||||
return i
|
||||
})
|
||||
|
||||
Vendored
+2
-1
@@ -3,6 +3,7 @@
|
||||
|
||||
const log = require('npmlog')
|
||||
const crypto = require('crypto')
|
||||
const querystring = require('querystring')
|
||||
const npmSession = crypto.randomBytes(8).toString('hex')
|
||||
log.verbose('npm-session', npmSession)
|
||||
const { join } = require('path')
|
||||
@@ -92,7 +93,7 @@ const flatten = obj => ({
|
||||
description: obj.description,
|
||||
exclude: obj.searchexclude,
|
||||
limit: obj.searchlimit || 20,
|
||||
opts: obj.searchopts,
|
||||
opts: querystring.parse(obj.searchopts),
|
||||
staleness: obj.searchstaleness,
|
||||
},
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -22,7 +22,7 @@ For example, running \fBnpm ls promzard\fP in npm's source tree will show:
|
||||
.P
|
||||
.RS 2
|
||||
.nf
|
||||
npm@7\.1\.0 /path/to/npm
|
||||
npm@7\.1\.1 /path/to/npm
|
||||
└─┬ init\-package\-json@0\.0\.4
|
||||
└── promzard@0\.1\.5
|
||||
.fi
|
||||
|
||||
Vendored
+1
-1
@@ -10,7 +10,7 @@ npm <command> [args]
|
||||
.RE
|
||||
.SS Version
|
||||
.P
|
||||
7\.1\.0
|
||||
7\.1\.1
|
||||
.SS Description
|
||||
.P
|
||||
npm is the package manager for the Node JavaScript platform\. It puts
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 2.0
|
||||
|
||||
* BREAKING CHANGE: root node is now included in inventory
|
||||
* All parent/target/fsParent/etc. references set in `root` setter, rather
|
||||
than the hodgepodge of setters that existed before.
|
||||
* `treeCheck` function added, to enforce strict correctness guarantees when
|
||||
`ARBORIST_DEBUG=1` in the environment (on by default in Arborist tests).
|
||||
|
||||
## 1.0
|
||||
|
||||
* Release for npm v7 beta
|
||||
* Fully functional
|
||||
|
||||
## 0.0
|
||||
|
||||
* Proof of concept
|
||||
* Before this, it was [`read-package-tree`](http://npm.im/read-package-tree)
|
||||
+35
-40
@@ -7,9 +7,9 @@ const semver = require('semver')
|
||||
const promiseCallLimit = require('promise-call-limit')
|
||||
const getPeerSet = require('../peer-set.js')
|
||||
const realpath = require('../../lib/realpath.js')
|
||||
const walkUpPath = require('walk-up-path')
|
||||
const { dirname, resolve } = require('path')
|
||||
const { resolve } = require('path')
|
||||
const { promisify } = require('util')
|
||||
const treeCheck = require('../tree-check.js')
|
||||
const readdir = promisify(require('readdir-scoped-modules'))
|
||||
|
||||
const debug = require('../debug.js')
|
||||
@@ -215,7 +215,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
||||
this.finishTracker('idealTree')
|
||||
}
|
||||
|
||||
return this.idealTree
|
||||
return treeCheck(this.idealTree)
|
||||
}
|
||||
|
||||
[_checkEngineAndPlatform] () {
|
||||
@@ -384,7 +384,8 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
||||
await this[_add](options)
|
||||
|
||||
// triggers a refresh of all edgesOut
|
||||
this.idealTree.package = this.idealTree.package
|
||||
if (options.add && options.add.length || options.rm && options.rm.length)
|
||||
this.idealTree.package = this.idealTree.package
|
||||
process.emit('timeEnd', 'idealTree:userRequests')
|
||||
}
|
||||
|
||||
@@ -599,21 +600,29 @@ This is a one-time fix-up, please be patient...
|
||||
this.addTracker('idealTree:inflate')
|
||||
const queue = []
|
||||
for (const node of inventory.values()) {
|
||||
if (node.isRoot)
|
||||
continue
|
||||
|
||||
queue.push(async () => {
|
||||
this.log.silly('inflate', node.location)
|
||||
const id = `${node.name}@${node.version}`
|
||||
const sloc = node.location.substr('node_modules/'.length)
|
||||
const { resolved, version, path, name, location, integrity } = node
|
||||
// don't try to hit the registry for linked deps
|
||||
const useResolved = !version ||
|
||||
resolved && resolved.startsWith('file:')
|
||||
const id = useResolved ? resolved : version
|
||||
const spec = npa.resolve(name, id, path)
|
||||
const sloc = location.substr('node_modules/'.length)
|
||||
const t = `idealTree:inflate:${sloc}`
|
||||
this.addTracker(t)
|
||||
await pacote.manifest(id, {
|
||||
await pacote.manifest(spec, {
|
||||
...this.options,
|
||||
resolved: node.resolved,
|
||||
integrity: node.integrity,
|
||||
resolved: resolved,
|
||||
integrity: integrity,
|
||||
fullMetadata: false,
|
||||
}).then(mani => {
|
||||
node.package = { ...mani, _id: `${mani.name}@${mani.version}` }
|
||||
}).catch((er) => {
|
||||
const warning = `Could not fetch metadata for ${id}`
|
||||
const warning = `Could not fetch metadata for ${name}@${id}`
|
||||
this.log.warn(heading, warning, er)
|
||||
})
|
||||
this.finishTracker(t)
|
||||
@@ -825,6 +834,7 @@ This is a one-time fix-up, please be patient...
|
||||
// is requesting this one, so that we can get all the peer deps in
|
||||
// a context where they're likely to be resolvable.
|
||||
const parent = parent_ || this[_virtualRoot](edge.from)
|
||||
const realParent = edge.peer ? edge.from.resolveParent : edge.from
|
||||
|
||||
const spec = npa.resolve(edge.name, edge.spec, edge.from.path)
|
||||
return this[_nodeFromSpec](edge.name, spec, parent, edge)
|
||||
@@ -836,7 +846,7 @@ This is a one-time fix-up, please be patient...
|
||||
// a symbolic link to the earlier instance
|
||||
for (let p = edge.from.resolveParent; p; p = p.resolveParent) {
|
||||
if (p.matches(node) && !p.isRoot)
|
||||
return new Link({ parent, target: p })
|
||||
return new Link({ parent: realParent, target: p })
|
||||
}
|
||||
// keep track of the thing that caused this node to be included.
|
||||
const src = parent.sourceReference
|
||||
@@ -1160,7 +1170,7 @@ This is a one-time fix-up, please be patient...
|
||||
integrity: dep.integrity,
|
||||
legacyPeerDeps: this.legacyPeerDeps,
|
||||
error: dep.errors[0],
|
||||
...(dep.target ? { target: dep.target } : {}),
|
||||
...(dep.target ? { target: dep.target, realpath: dep.target.path } : {}),
|
||||
})
|
||||
if (this[_loadFailures].has(dep))
|
||||
this[_loadFailures].add(newDep)
|
||||
@@ -1235,6 +1245,8 @@ This is a one-time fix-up, please be patient...
|
||||
// +-- c2 <-- pruning this would be bad
|
||||
|
||||
const mask = node.parent !== target &&
|
||||
node.parent &&
|
||||
node.parent.parent &&
|
||||
node.parent.parent !== target &&
|
||||
node.parent.parent.resolve(newDep.name)
|
||||
|
||||
@@ -1550,30 +1562,12 @@ This is a one-time fix-up, please be patient...
|
||||
[_resolveLinks] () {
|
||||
for (const link of this[_linkNodes]) {
|
||||
this[_linkNodes].delete(link)
|
||||
const realpath = link.realpath
|
||||
const loc = relpath(this.path, realpath)
|
||||
const fromInv = this.idealTree.inventory.get(loc)
|
||||
if (fromInv && fromInv !== link.target)
|
||||
link.target = fromInv
|
||||
|
||||
const external = /^\.\.(\/|$)/.test(loc)
|
||||
// link we never ended up placing, skip it
|
||||
if (link.root !== this.idealTree)
|
||||
continue
|
||||
|
||||
if (!link.target.parent && !link.target.fsParent) {
|
||||
// the fsParent likely some node in the tree, possibly the root,
|
||||
// unless it is external. find it by walking up. Note that this
|
||||
// is where its deps may end up being installed, if possible.
|
||||
for (const p of walkUpPath(dirname(realpath))) {
|
||||
const path = relpath(this.path, p)
|
||||
const node = !path ? this.idealTree
|
||||
: this.idealTree.inventory.get(path)
|
||||
if (node) {
|
||||
link.target.fsParent = node
|
||||
this.addTracker('idealTree', link.target.name, link.target.location)
|
||||
this[_depsQueue].push(link.target)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
const external = /^\.\.(\/|$)/.test(relpath(this.path, link.realpath))
|
||||
|
||||
// outside the root, somebody else's problem, ignore it
|
||||
if (external && !this[_follow])
|
||||
@@ -1581,12 +1575,13 @@ This is a one-time fix-up, please be patient...
|
||||
|
||||
// didn't find a parent for it or it has not been seen yet
|
||||
// so go ahead and process it.
|
||||
const unseenLink = (link.target.parent || link.target.fsParent)
|
||||
&& !this[_depsSeen].has(link.target)
|
||||
if (this[_follow]
|
||||
&& !link.target.parent
|
||||
&& !link.target.fsParent
|
||||
|| unseenLink) {
|
||||
const unseenLink = (link.target.parent || link.target.fsParent) &&
|
||||
!this[_depsSeen].has(link.target)
|
||||
|
||||
if (this[_follow] &&
|
||||
!link.target.parent &&
|
||||
!link.target.fsParent ||
|
||||
unseenLink) {
|
||||
this.addTracker('idealTree', link.target.name, link.target.location)
|
||||
this[_depsQueue].push(link.target)
|
||||
}
|
||||
|
||||
+10
-12
@@ -7,6 +7,7 @@ const {promisify} = require('util')
|
||||
const readdir = promisify(require('readdir-scoped-modules'))
|
||||
const walkUp = require('walk-up-path')
|
||||
const ancestorPath = require('common-ancestor-path')
|
||||
const treeCheck = require('../tree-check.js')
|
||||
|
||||
const Shrinkwrap = require('../shrinkwrap.js')
|
||||
const calcDepFlags = require('../calc-dep-flags.js')
|
||||
@@ -38,6 +39,7 @@ const _transplantFilter = Symbol('transplantFilter')
|
||||
|
||||
const _filter = Symbol('filter')
|
||||
const _global = Symbol.for('global')
|
||||
const _changePath = Symbol.for('_changePath')
|
||||
|
||||
module.exports = cls => class ActualLoader extends cls {
|
||||
constructor (options) {
|
||||
@@ -85,7 +87,7 @@ module.exports = cls => class ActualLoader extends cls {
|
||||
return this.actualTree ? this.actualTree
|
||||
: this[_actualTreePromise] ? this[_actualTreePromise]
|
||||
: this[_actualTreePromise] = this[_loadActual](options)
|
||||
.then(tree => this.actualTree = tree)
|
||||
.then(tree => this.actualTree = treeCheck(tree))
|
||||
}
|
||||
|
||||
async [_loadActual] (options) {
|
||||
@@ -166,19 +168,15 @@ module.exports = cls => class ActualLoader extends cls {
|
||||
}
|
||||
|
||||
[_transplant] (root) {
|
||||
if (!root)
|
||||
if (!root || root === this[_actualTree])
|
||||
return
|
||||
// have to set the fsChildren first, because re-rooting a Link
|
||||
// re-roots the target, but without updating its realpath, so
|
||||
// we have to re-root the targets first so their location is
|
||||
// updated appropriately.
|
||||
for (const node of this[_actualTree].fsChildren)
|
||||
node.fsParent = root
|
||||
|
||||
this[_actualTree][_changePath](root.path)
|
||||
for (const node of this[_actualTree].children.values()) {
|
||||
if (this[_transplantFilter](node))
|
||||
node.parent = root
|
||||
if (!this[_transplantFilter](node))
|
||||
node.parent = null
|
||||
}
|
||||
|
||||
root.replace(this[_actualTree])
|
||||
this[_actualTree] = root
|
||||
}
|
||||
|
||||
@@ -322,7 +320,7 @@ module.exports = cls => class ActualLoader extends cls {
|
||||
|
||||
const depPromises = []
|
||||
for (const [name, edge] of node.edgesOut.entries()) {
|
||||
if (!edge.missing && !(edge.to && edge.to.dummy))
|
||||
if (!edge.missing && !(edge.to && (edge.to.dummy || edge.to.parent !== node)))
|
||||
continue
|
||||
|
||||
// start the walk from the dirname, because we would have found
|
||||
|
||||
+35
-46
@@ -1,7 +1,6 @@
|
||||
// mixin providing the loadVirtual method
|
||||
|
||||
const {dirname, resolve} = require('path')
|
||||
const walkUp = require('walk-up-path')
|
||||
const {resolve} = require('path')
|
||||
|
||||
const nameFromFolder = require('@npmcli/name-from-folder')
|
||||
const consistentResolve = require('../consistent-resolve.js')
|
||||
@@ -11,11 +10,12 @@ const Link = require('../link.js')
|
||||
const relpath = require('../relpath.js')
|
||||
const calcDepFlags = require('../calc-dep-flags.js')
|
||||
const rpj = require('read-package-json-fast')
|
||||
const treeCheck = require('../tree-check.js')
|
||||
|
||||
const loadFromShrinkwrap = Symbol('loadFromShrinkwrap')
|
||||
const resolveNodes = Symbol('resolveNodes')
|
||||
const resolveLinks = Symbol('resolveLinks')
|
||||
const assignParentage = Symbol('assignParentage')
|
||||
const assignBundles = Symbol('assignBundles')
|
||||
const loadRoot = Symbol('loadRoot')
|
||||
const loadNode = Symbol('loadVirtualNode')
|
||||
const loadLink = Symbol('loadVirtualLink')
|
||||
@@ -40,14 +40,16 @@ module.exports = cls => class VirtualLoader extends cls {
|
||||
// public method
|
||||
async loadVirtual (options = {}) {
|
||||
if (this.virtualTree)
|
||||
return Promise.resolve(this.virtualTree)
|
||||
return this.virtualTree
|
||||
|
||||
// allow the user to set reify options on the ctor as well.
|
||||
// XXX: deprecate separate reify() options object.
|
||||
options = { ...this.options, ...options }
|
||||
|
||||
if (options.root && options.root.meta)
|
||||
return this[loadFromShrinkwrap](options.root.meta, options.root)
|
||||
if (options.root && options.root.meta) {
|
||||
await this[loadFromShrinkwrap](options.root.meta, options.root)
|
||||
return treeCheck(this.virtualTree)
|
||||
}
|
||||
|
||||
const s = await Shrinkwrap.load({ path: this.path })
|
||||
if (!s.loadedFromDisk && !options.root) {
|
||||
@@ -61,7 +63,8 @@ module.exports = cls => class VirtualLoader extends cls {
|
||||
root = await this[loadRoot](s),
|
||||
} = options
|
||||
|
||||
return this[loadFromShrinkwrap](s, root)
|
||||
await this[loadFromShrinkwrap](s, root)
|
||||
return treeCheck(this.virtualTree)
|
||||
}
|
||||
|
||||
async [loadRoot] (s) {
|
||||
@@ -83,7 +86,7 @@ module.exports = cls => class VirtualLoader extends cls {
|
||||
this.virtualTree = root
|
||||
const {links, nodes} = this[resolveNodes](s, root)
|
||||
await this[resolveLinks](links, nodes)
|
||||
this[assignParentage](nodes)
|
||||
this[assignBundles](nodes)
|
||||
if (this[flagsSuspect])
|
||||
this[reCalcDepFlags]()
|
||||
return root
|
||||
@@ -194,57 +197,43 @@ module.exports = cls => class VirtualLoader extends cls {
|
||||
nodes.set(targetLoc, link.target)
|
||||
|
||||
// we always need to read the package.json for link targets
|
||||
// because they can be changed by the local user
|
||||
const pj = link.realpath + '/package.json'
|
||||
const pkg = await rpj(pj).catch(() => null)
|
||||
if (pkg)
|
||||
link.target.package = pkg
|
||||
// outside node_modules because they can be changed by the local user
|
||||
if (!link.target.parent) {
|
||||
const pj = link.realpath + '/package.json'
|
||||
const pkg = await rpj(pj).catch(() => null)
|
||||
if (pkg)
|
||||
link.target.package = pkg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[assignParentage] (nodes) {
|
||||
[assignBundles] (nodes) {
|
||||
for (const [location, node] of nodes) {
|
||||
// Skip assignment of parentage for the root package
|
||||
if (!location)
|
||||
continue
|
||||
const { path, name } = node
|
||||
for (const p of walkUp(dirname(path))) {
|
||||
const ploc = relpath(this.path, p)
|
||||
const parent = nodes.get(ploc)
|
||||
if (!parent)
|
||||
continue
|
||||
// Safety check: avoid self-assigning nodes as their own parents
|
||||
/* istanbul ignore if - should be obviated by parentage skip check */
|
||||
if (parent === node)
|
||||
continue
|
||||
const { name, parent, package: { inBundle }} = node
|
||||
if (!parent)
|
||||
continue
|
||||
|
||||
const locTest = `${ploc}/node_modules/${name}`.replace(/^\//, '')
|
||||
const ptype = location === locTest
|
||||
? 'parent'
|
||||
: 'fsParent'
|
||||
node[ptype] = parent
|
||||
// read inBundle from package because 'package' here is
|
||||
// actually a v2 lockfile metadata entry.
|
||||
// If the *parent* is also bundled, though, then we assume
|
||||
// that it's being pulled in just by virtue of that.
|
||||
const {inBundle} = node.package
|
||||
const ppkg = parent.package
|
||||
const {inBundle: parentBundled} = ppkg
|
||||
const hasEdge = parent.edgesOut.has(name)
|
||||
if (ptype === 'parent' && inBundle && hasEdge && !parentBundled) {
|
||||
if (!ppkg.bundleDependencies)
|
||||
ppkg.bundleDependencies = [name]
|
||||
else if (!ppkg.bundleDependencies.includes(name))
|
||||
ppkg.bundleDependencies.push(name)
|
||||
}
|
||||
|
||||
break
|
||||
// read inBundle from package because 'package' here is
|
||||
// actually a v2 lockfile metadata entry.
|
||||
// If the *parent* is also bundled, though, then we assume
|
||||
// that it's being pulled in just by virtue of that.
|
||||
const { package: ppkg } = parent
|
||||
const { inBundle: parentBundled } = ppkg
|
||||
if (inBundle && !parentBundled) {
|
||||
if (!ppkg.bundleDependencies)
|
||||
ppkg.bundleDependencies = [name]
|
||||
else if (!ppkg.bundleDependencies.includes(name))
|
||||
ppkg.bundleDependencies.push(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[loadNode] (location, sw) {
|
||||
const path = resolve(this.path, location)
|
||||
const p = this.virtualTree ? this.virtualTree.realpath : this.path
|
||||
const path = resolve(p, location)
|
||||
// shrinkwrap doesn't include package name unless necessary
|
||||
if (!sw.name)
|
||||
sw.name = nameFromFolder(path)
|
||||
|
||||
+2
-1
@@ -16,6 +16,7 @@ const moveFile = require('@npmcli/move-file')
|
||||
const rimraf = promisify(require('rimraf'))
|
||||
const packageContents = require('@npmcli/installed-package-contents')
|
||||
|
||||
const treeCheck = require('../tree-check.js')
|
||||
const relpath = require('../relpath.js')
|
||||
const Diff = require('../diff.js')
|
||||
const retirePath = require('../retire-path.js')
|
||||
@@ -128,7 +129,7 @@ module.exports = cls => class Reifier extends cls {
|
||||
|
||||
this.finishTracker('reify')
|
||||
process.emit('timeEnd', 'reify')
|
||||
return this.actualTree
|
||||
return treeCheck(this.actualTree)
|
||||
}
|
||||
|
||||
async [_reifyPackages] () {
|
||||
|
||||
+5
-4
@@ -44,7 +44,7 @@ class AuditReport extends Map {
|
||||
optional: 0,
|
||||
peer: 0,
|
||||
peerOptional: 0,
|
||||
total: this.tree.inventory.size,
|
||||
total: this.tree.inventory.size - 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -281,7 +281,7 @@ class AuditReport extends Map {
|
||||
|
||||
async [_getReport] () {
|
||||
// if we're not auditing, just return false
|
||||
if (this.options.audit === false || this.tree.inventory.size === 0)
|
||||
if (this.options.audit === false || this.tree.inventory.size === 1)
|
||||
return null
|
||||
|
||||
process.emit('time', 'auditReport:getReport')
|
||||
@@ -290,9 +290,10 @@ class AuditReport extends Map {
|
||||
// first try the super fast bulk advisory listing
|
||||
const body = prepareBulkData(this.tree, this[_omit])
|
||||
|
||||
// no sense asking if we don't have anything to audit
|
||||
// no sense asking if we don't have anything to audit,
|
||||
// we know it'll be empty
|
||||
if (!Object.keys(body).length)
|
||||
return {}
|
||||
return null
|
||||
|
||||
const res = await fetch('/-/npm/v1/security/advisories/bulk', {
|
||||
...this.options,
|
||||
|
||||
+8
-2
@@ -10,9 +10,15 @@
|
||||
// throw new Error('expensive check should have returned false')
|
||||
// })
|
||||
|
||||
const debug = process.env.ARBORIST_DEBUG === '1' ||
|
||||
// run in debug mode if explicitly requested, running arborist tests,
|
||||
// or working in the arborist project directory.
|
||||
const debug = process.env.ARBORIST_DEBUG !== '0' && (
|
||||
process.env.ARBORIST_DEBUG === '1' ||
|
||||
/\barborist\b/.test(process.env.NODE_DEBUG || '') ||
|
||||
process.env.npm_package_name === '@npmcli/arborist' &&
|
||||
['test', 'snap'].includes(process.env.npm_lifecycle_event)
|
||||
['test', 'snap'].includes(process.env.npm_lifecycle_event) ||
|
||||
process.cwd() === require('path').resolve(__dirname, '..')
|
||||
)
|
||||
|
||||
module.exports = debug ? fn => fn() : () => {}
|
||||
module.exports.log = (...msg) => module.exports(() => console.error(...msg))
|
||||
+1
-1
@@ -49,7 +49,7 @@ const depValid = (child, requested, requestor) => {
|
||||
// fallthrough
|
||||
case 'version':
|
||||
// if it's a version or a range other than '*', semver it
|
||||
return semver.satisfies(child.package.version, requested.fetchSpec, true)
|
||||
return semver.satisfies(child.version, requested.fetchSpec, true)
|
||||
|
||||
case 'directory':
|
||||
// directory must be a link to the specified folder
|
||||
|
||||
+20
-3
@@ -4,7 +4,9 @@
|
||||
// keys is the set of fields to be able to query.
|
||||
const _primaryKey = Symbol('_primaryKey')
|
||||
const _index = Symbol('_index')
|
||||
const defaultKeys = ['name', 'license', 'funding']
|
||||
const defaultKeys = ['name', 'license', 'funding', 'realpath']
|
||||
const { hasOwnProperty } = Object.prototype
|
||||
const debug = require('./debug.js')
|
||||
class Inventory extends Map {
|
||||
constructor (opt = {}) {
|
||||
const { primary, keys } = opt
|
||||
@@ -32,6 +34,18 @@ class Inventory extends Map {
|
||||
}
|
||||
|
||||
add (node) {
|
||||
const root = super.get('')
|
||||
if (root && node.root !== root && node.root !== root.root) {
|
||||
debug(() => {
|
||||
throw Object.assign(new Error('adding external node to inventory'), {
|
||||
root: root.path,
|
||||
node: node.path,
|
||||
nodeRoot: node.root.path,
|
||||
})
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const current = super.get(node[this.primaryKey])
|
||||
if (current) {
|
||||
if (current === node)
|
||||
@@ -40,7 +54,9 @@ class Inventory extends Map {
|
||||
}
|
||||
super.set(node[this.primaryKey], node)
|
||||
for (const [key, map] of this[_index].entries()) {
|
||||
const val_ = node[key] || (node.package && node.package[key])
|
||||
// if the node has the value, but it's false, then use that
|
||||
const val_ = hasOwnProperty.call(node, key) ? node[key]
|
||||
: node[key] || (node.package && node.package[key])
|
||||
const val = typeof val_ === 'string' ? val_
|
||||
: !val_ || typeof val_ !== 'object' ? val_
|
||||
: key === 'license' ? val_.type
|
||||
@@ -58,7 +74,8 @@ class Inventory extends Map {
|
||||
|
||||
super.delete(node[this.primaryKey])
|
||||
for (const [key, map] of this[_index].entries()) {
|
||||
const val = node[key] || (node.package && node.package[key])
|
||||
const val = node[key] !== undefined ? node[key]
|
||||
: (node[key] || (node.package && node.package[key]))
|
||||
const set = map.get(val)
|
||||
if (set) {
|
||||
set.delete(node)
|
||||
|
||||
+64
-18
@@ -1,11 +1,15 @@
|
||||
const debug = require('./debug.js')
|
||||
const relpath = require('./relpath.js')
|
||||
const Node = require('./node.js')
|
||||
const _loadDeps = Symbol.for('Arborist.Node._loadDeps')
|
||||
const _target = Symbol('_target')
|
||||
const _target = Symbol.for('_target')
|
||||
const {dirname} = require('path')
|
||||
// defined by Node class
|
||||
const _delistFromMeta = Symbol.for('_delistFromMeta')
|
||||
const _refreshLocation = Symbol.for('_refreshLocation')
|
||||
class Link extends Node {
|
||||
constructor (options) {
|
||||
const { realpath, target } = options
|
||||
const { root, realpath, target, parent, fsParent } = options
|
||||
|
||||
if (!realpath && !(target && target.path))
|
||||
throw new TypeError('must provide realpath for Link node')
|
||||
@@ -13,18 +17,23 @@ class Link extends Node {
|
||||
super({
|
||||
...options,
|
||||
realpath: realpath || target.path,
|
||||
root: root || (parent ? parent.root
|
||||
: fsParent ? fsParent.root
|
||||
: target ? target.root
|
||||
: null),
|
||||
})
|
||||
|
||||
this.target = target || new Node({
|
||||
...options,
|
||||
path: realpath,
|
||||
parent: null,
|
||||
fsParent: null,
|
||||
root: this.root,
|
||||
linksIn: [this],
|
||||
})
|
||||
}
|
||||
|
||||
if (this.root.meta)
|
||||
this.root.meta.add(this)
|
||||
get version () {
|
||||
return this.target ? this.target.version : this.package.version || ''
|
||||
}
|
||||
|
||||
get target () {
|
||||
@@ -33,33 +42,70 @@ class Link extends Node {
|
||||
|
||||
set target (target) {
|
||||
const current = this[_target]
|
||||
if (current && current.linksIn)
|
||||
current.linksIn.delete(this)
|
||||
|
||||
this[_target] = target
|
||||
|
||||
if (!target) {
|
||||
this.package = {}
|
||||
if (target === current)
|
||||
return
|
||||
|
||||
if (current && current.then) {
|
||||
debug(() => {
|
||||
throw Object.assign(new Error('cannot set target while awaiting'), {
|
||||
path: this.path,
|
||||
realpath: this.realpath,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (target.then) {
|
||||
if (target && target.then) {
|
||||
// can set to a promise during an async tree build operation
|
||||
// wait until then to assign it.
|
||||
target.then(node => this.target = node)
|
||||
this[_target] = target
|
||||
target.then(node => {
|
||||
this[_target] = null
|
||||
this.target = node
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
this.package = target.package
|
||||
if (!target) {
|
||||
if (current && current.linksIn)
|
||||
current.linksIn.delete(this)
|
||||
if (this.path) {
|
||||
this[_delistFromMeta]()
|
||||
this[_target] = null
|
||||
this.package = {}
|
||||
this[_refreshLocation]()
|
||||
} else
|
||||
this[_target] = null
|
||||
return
|
||||
}
|
||||
|
||||
this.realpath = target.path
|
||||
if (target.root === target)
|
||||
if (!this.path) {
|
||||
// temp node pending assignment to a tree
|
||||
// we know it's not in the inventory yet, because no path.
|
||||
if (target.path)
|
||||
this.realpath = target.path
|
||||
else
|
||||
target.path = target.realpath = this.realpath
|
||||
target.root = this.root
|
||||
target.linksIn.add(this)
|
||||
this[_target] = target
|
||||
target.linksIn.add(this)
|
||||
this.package = target.package
|
||||
return
|
||||
}
|
||||
|
||||
// have to refresh metadata, because either realpath or package
|
||||
// is very likely changing.
|
||||
this[_delistFromMeta]()
|
||||
this.package = target.package
|
||||
this.realpath = target.path
|
||||
this[_refreshLocation]()
|
||||
|
||||
target.root = this.root
|
||||
}
|
||||
|
||||
// a link always resolves to the relative path to its target
|
||||
get resolved () {
|
||||
// the path/realpath guard is there for the benefit of setting
|
||||
// these things in the "wrong" order
|
||||
return this.path && this.realpath
|
||||
? `file:${relpath(dirname(this.path), this.realpath)}`
|
||||
: null
|
||||
|
||||
+383
-265
@@ -36,22 +36,24 @@ const {getPaths: getBinPaths} = require('bin-links')
|
||||
const npa = require('npm-package-arg')
|
||||
const debug = require('./debug.js')
|
||||
const gatherDepSet = require('./gather-dep-set.js')
|
||||
const treeCheck = require('./tree-check.js')
|
||||
const walkUp = require('walk-up-path')
|
||||
|
||||
const {resolve, relative, dirname, basename} = require('path')
|
||||
const _package = Symbol('_package')
|
||||
const _parent = Symbol('_parent')
|
||||
const _target = Symbol.for('_target')
|
||||
const _fsParent = Symbol('_fsParent')
|
||||
const _reloadEdges = Symbol('_reloadEdges')
|
||||
const _loadDepType = Symbol('_loadDepType')
|
||||
const _loadWorkspaces = Symbol('_loadWorkspaces')
|
||||
const _reloadNamedEdges = Symbol('_reloadNamedEdges')
|
||||
// overridden by Link class
|
||||
const _loadDeps = Symbol.for('Arborist.Node._loadDeps')
|
||||
const _root = Symbol('_root')
|
||||
const _refreshLocation = Symbol('_refreshLocation')
|
||||
const _refreshTopMeta = Symbol('_refreshTopMeta')
|
||||
const _refreshPath = Symbol('_refreshPath')
|
||||
const _delistFromMeta = Symbol('_delistFromMeta')
|
||||
const _refreshLocation = Symbol.for('_refreshLocation')
|
||||
const _changePath = Symbol.for('_changePath')
|
||||
// used by Link class as well
|
||||
const _delistFromMeta = Symbol.for('_delistFromMeta')
|
||||
const _global = Symbol.for('global')
|
||||
const _workspaces = Symbol('_workspaces')
|
||||
const _explain = Symbol('_explain')
|
||||
@@ -111,7 +113,7 @@ class Node {
|
||||
null
|
||||
|
||||
// should be equal if not a link
|
||||
this.path = path && resolve(path)
|
||||
this.path = path ? resolve(path) : null
|
||||
|
||||
if (!this.name && (!this.path || this.path !== dirname(this.path)))
|
||||
throw new TypeError('could not detect node name from path or package')
|
||||
@@ -145,6 +147,7 @@ class Node {
|
||||
this.children = new Map()
|
||||
this.fsChildren = new Set()
|
||||
this.inventory = new Inventory({})
|
||||
this.tops = new Set()
|
||||
this.linksIn = new Set(linksIn || [])
|
||||
|
||||
// these three are set by an Arborist taking a catalog
|
||||
@@ -198,7 +201,8 @@ class Node {
|
||||
// Must be set prior to calling _loadDeps, because top-ness is relevant
|
||||
|
||||
// will also assign root if present on the parent
|
||||
this.parent = parent
|
||||
this[_parent] = null
|
||||
this.parent = parent || null
|
||||
|
||||
this[_fsParent] = null
|
||||
this.fsParent = fsParent || null
|
||||
@@ -209,9 +213,6 @@ class Node {
|
||||
if (!parent && !fsParent)
|
||||
this.root = root || null
|
||||
|
||||
if (this.isRoot)
|
||||
this.location = ''
|
||||
|
||||
// mostly a convenience for testing, but also a way to create
|
||||
// trees in a more declarative way than setting parent on each
|
||||
if (children) {
|
||||
@@ -461,35 +462,244 @@ class Node {
|
||||
}
|
||||
|
||||
set root (root) {
|
||||
const nullRoot = root === null
|
||||
if (nullRoot)
|
||||
root = this
|
||||
else {
|
||||
// should only ever be 1 step
|
||||
while (root.root !== root)
|
||||
root = root.root
|
||||
// setting to null means this is the new root
|
||||
// should only ever be one step
|
||||
while (root && root.root !== root)
|
||||
root = root.root
|
||||
|
||||
root = root || this
|
||||
|
||||
// delete from current root inventory
|
||||
this[_delistFromMeta]()
|
||||
|
||||
// can't set the root (yet) if there's no way to determine location
|
||||
// this allows us to do new Node({...}) and then set the root later.
|
||||
// just make the assignment so we don't lose it, and move on.
|
||||
if (!this.path || !root.realpath || !root.path)
|
||||
return this[_root] = root
|
||||
|
||||
// temporarily become a root node
|
||||
this[_root] = this
|
||||
|
||||
// break all linksIn, we're going to re-set them if needed later
|
||||
for (const link of this.linksIn) {
|
||||
link[_target] = null
|
||||
this.linksIn.delete(link)
|
||||
}
|
||||
|
||||
if (root === this.root)
|
||||
return
|
||||
// temporarily break this link as well, we'll re-set if possible later
|
||||
const { target } = this
|
||||
if (this.isLink) {
|
||||
if (target) {
|
||||
target.linksIn.delete(this)
|
||||
if (target.root === this)
|
||||
target[_delistFromMeta]()
|
||||
}
|
||||
this[_target] = null
|
||||
}
|
||||
|
||||
this[_delistFromMeta]()
|
||||
this[_root] = root
|
||||
this[_refreshLocation]()
|
||||
// if this is part of a cascading root set, then don't do this bit
|
||||
// but if the parent/fsParent is in a different set, we have to break
|
||||
// that reference before proceeding
|
||||
if (this.parent && this.parent.root !== root) {
|
||||
this.parent.children.delete(this.name)
|
||||
this[_parent] = null
|
||||
}
|
||||
if (this.fsParent && this.fsParent.root !== root) {
|
||||
this.fsParent.fsChildren.delete(this)
|
||||
this[_fsParent] = null
|
||||
}
|
||||
|
||||
if (this.top.meta)
|
||||
this[_refreshTopMeta]()
|
||||
if (root === this)
|
||||
this[_refreshLocation]()
|
||||
else {
|
||||
// setting to some different node.
|
||||
const loc = relpath(root.realpath, this.path)
|
||||
const current = root.inventory.get(loc)
|
||||
|
||||
if (this.target && !nullRoot)
|
||||
this.target.root = root
|
||||
// clobber whatever is there now
|
||||
if (current)
|
||||
current.root = null
|
||||
|
||||
this.fsChildren.forEach(c => c.root = root)
|
||||
this.children.forEach(c => c.root = root)
|
||||
/* istanbul ignore next - debug check */
|
||||
debug(() => {
|
||||
if (this !== root && this.inventory.size !== 0)
|
||||
throw new Error('non-root has non-zero inventory')
|
||||
})
|
||||
this[_root] = root
|
||||
// set this.location and add to inventory
|
||||
this[_refreshLocation]()
|
||||
|
||||
// try to find our parent/fsParent in the new root inventory
|
||||
for (const p of walkUp(dirname(this.path))) {
|
||||
const ploc = relpath(root.realpath, p)
|
||||
const parent = root.inventory.get(ploc)
|
||||
if (parent) {
|
||||
/* istanbul ignore next - impossible */
|
||||
if (parent.isLink) {
|
||||
debug(() => {
|
||||
throw Object.assign(new Error('assigning parentage to link'), {
|
||||
path: this.path,
|
||||
parent: parent.path,
|
||||
parentReal: parent.realpath,
|
||||
})
|
||||
})
|
||||
continue
|
||||
}
|
||||
const childLoc = `${ploc}${ploc ? '/' : ''}node_modules/${this.name}`
|
||||
const isParent = this.location === childLoc
|
||||
if (isParent) {
|
||||
const oldChild = parent.children.get(this.name)
|
||||
if (oldChild && oldChild !== this)
|
||||
oldChild.root = null
|
||||
if (this.parent) {
|
||||
this.parent.children.delete(this.name)
|
||||
this.parent[_reloadNamedEdges](this.name)
|
||||
}
|
||||
parent.children.set(this.name, this)
|
||||
this[_parent] = parent
|
||||
// don't do it for links, because they don't have a target yet
|
||||
// we'll hit them up a bit later on.
|
||||
if (!this.isLink)
|
||||
parent[_reloadNamedEdges](this.name)
|
||||
} else {
|
||||
/* istanbul ignore if - should be impossible, since we break
|
||||
* all fsParent/child relationships when moving? */
|
||||
if (this.fsParent)
|
||||
this.fsParent.fsChildren.delete(this)
|
||||
parent.fsChildren.add(this)
|
||||
this[_fsParent] = parent
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// if it doesn't have a parent, it's a top node
|
||||
if (!this.parent)
|
||||
root.tops.add(this)
|
||||
else
|
||||
root.tops.delete(this)
|
||||
|
||||
// assign parentage for any nodes that need to have this as a parent
|
||||
// this can happen when we have a node at nm/a/nm/b added *before*
|
||||
// the node at nm/a, which might have the root node as a fsParent.
|
||||
// we can't rely on the public setter here, because it calls into
|
||||
// this function to set up these references!
|
||||
const nmloc = `${this.location}${this.location ? '/' : ''}node_modules/`
|
||||
const isChild = n => n.location === nmloc + n.name
|
||||
// check dirname so that /foo isn't treated as the fsparent of /foo-bar
|
||||
const isFsChild = n => dirname(n.path).startsWith(this.path) &&
|
||||
n !== this &&
|
||||
!n.parent &&
|
||||
(!n.fsParent || n.fsParent === this || dirname(this.path).startsWith(n.fsParent.path))
|
||||
const isKid = n => isChild(n) || isFsChild(n)
|
||||
|
||||
// only walk top nodes, since anything else already has a parent.
|
||||
for (const child of root.tops) {
|
||||
if (!isKid(child))
|
||||
continue
|
||||
|
||||
// set up the internal parentage links
|
||||
if (this.isLink)
|
||||
child.root = null
|
||||
else {
|
||||
// can't possibly have a parent, because it's in tops
|
||||
if (child.fsParent)
|
||||
child.fsParent.fsChildren.delete(child)
|
||||
child[_fsParent] = null
|
||||
if (isChild(child)) {
|
||||
this.children.set(child.name, child)
|
||||
child[_parent] = this
|
||||
root.tops.delete(child)
|
||||
} else {
|
||||
this.fsChildren.add(child)
|
||||
child[_fsParent] = this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// look for any nodes with the same realpath. either they're links
|
||||
// to that realpath, or a thing at that realpath if we're adding a link
|
||||
// (if we're adding a regular node, we already deleted the old one)
|
||||
for (const node of root.inventory.query('realpath', this.realpath)) {
|
||||
if (node === this)
|
||||
continue
|
||||
|
||||
/* istanbul ignore next - should be impossible */
|
||||
debug(() => {
|
||||
if (node.root !== root)
|
||||
throw new Error('inventory contains node from other root')
|
||||
})
|
||||
|
||||
if (this.isLink) {
|
||||
const target = node.target || node
|
||||
this[_target] = target
|
||||
this[_package] = target.package
|
||||
target.linksIn.add(this)
|
||||
// reload edges here, because now we have a target
|
||||
if (this.parent)
|
||||
this.parent[_reloadNamedEdges](this.name)
|
||||
break
|
||||
} else {
|
||||
/* istanbul ignore else - should be impossible */
|
||||
if (node.isLink) {
|
||||
node[_target] = this
|
||||
node[_package] = this.package
|
||||
this.linksIn.add(node)
|
||||
if (node.parent)
|
||||
node.parent[_reloadNamedEdges](node.name)
|
||||
} else {
|
||||
debug(() => {
|
||||
throw Object.assign(new Error('duplicate node in root setter'), {
|
||||
path: this.path,
|
||||
realpath: this.realpath,
|
||||
root: root.realpath,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reload all edgesIn where the root doesn't match, so we don't have
|
||||
// cross-tree dependency graphs
|
||||
for (const edge of this.edgesIn) {
|
||||
if (edge.from.root !== root)
|
||||
edge.reload()
|
||||
}
|
||||
// reload all edgesOut where root doens't match, or is missing, since
|
||||
// it might not be missing in the new tree
|
||||
for (const edge of this.edgesOut.values()) {
|
||||
if (!edge.to || edge.to.root !== root)
|
||||
edge.reload()
|
||||
}
|
||||
|
||||
// now make sure our family comes along for the ride!
|
||||
const family = new Set([
|
||||
...this.fsChildren,
|
||||
...this.children.values(),
|
||||
...this.inventory.values(),
|
||||
].filter(n => n !== this))
|
||||
for (const child of family) {
|
||||
if (child.root !== root) {
|
||||
child[_delistFromMeta]()
|
||||
child[_parent] = null
|
||||
this.children.delete(child.name)
|
||||
child[_fsParent] = null
|
||||
this.fsChildren.delete(child)
|
||||
for (const l of child.linksIn) {
|
||||
l[_target] = null
|
||||
child.linksIn.delete(l)
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const child of family) {
|
||||
if (child.root !== root)
|
||||
child.root = root
|
||||
}
|
||||
|
||||
// if we had a target, and didn't find one in the new root, then bring
|
||||
// it over as well.
|
||||
if (this.isLink && target && !this.target)
|
||||
target.root = root
|
||||
|
||||
// tree should always be valid upon root setter completion.
|
||||
treeCheck(this)
|
||||
}
|
||||
|
||||
get root () {
|
||||
@@ -516,7 +726,7 @@ class Node {
|
||||
// Linked targets that are disconnected from the tree are tops,
|
||||
// but don't have a 'path' field, only a 'realpath', because we
|
||||
// don't know their canonical location. We don't need their devDeps.
|
||||
if (this.isTop && this.path)
|
||||
if (this.isTop && this.path && !this.sourceReference)
|
||||
this[_loadDepType](this.package.devDependencies, 'dev')
|
||||
|
||||
const pd = this.package.peerDependencies
|
||||
@@ -552,19 +762,9 @@ class Node {
|
||||
}
|
||||
|
||||
set fsParent (fsParent) {
|
||||
fsParent = fsParent || null
|
||||
|
||||
if (this[_fsParent] === fsParent)
|
||||
return
|
||||
|
||||
const current = this[_fsParent]
|
||||
if (current)
|
||||
current.fsChildren.delete(this)
|
||||
|
||||
if (!fsParent) {
|
||||
this[_fsParent] = null
|
||||
// reload ALL edges, since they're now all suspect and likely invalid
|
||||
this[_reloadEdges](e => true)
|
||||
if (this[_fsParent])
|
||||
this.root = null
|
||||
return
|
||||
}
|
||||
|
||||
@@ -587,47 +787,53 @@ class Node {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (fsParent.isLink)
|
||||
throw new Error('setting fsParent to link node')
|
||||
})
|
||||
|
||||
if (fsParent.isLink)
|
||||
fsParent = fsParent.target
|
||||
|
||||
// setting a thing to its own fsParent is not normal, but no-op for safety
|
||||
if (this === fsParent || fsParent.realpath === this.realpath)
|
||||
return
|
||||
|
||||
// prune off the original location, so we don't leave edges lying around
|
||||
if (current)
|
||||
this.fsParent = null
|
||||
// nothing to do
|
||||
if (this[_fsParent] === fsParent)
|
||||
return
|
||||
|
||||
const fspp = fsParent.realpath
|
||||
const nmPath = resolve(fspp, 'node_modules', this.name)
|
||||
// actually in the node_modules folder! this can happen when a link
|
||||
// points deep within a node_modules folder, so that the target node
|
||||
// is loaded before its parent.
|
||||
if (nmPath === this.path) {
|
||||
this[_fsParent] = null
|
||||
const oldFsParent = this[_fsParent]
|
||||
const newPath = !oldFsParent ? this.path
|
||||
: resolve(fsParent.path, relative(oldFsParent.path, this.path))
|
||||
const nmPath = resolve(fsParent.path, 'node_modules', this.name)
|
||||
|
||||
// this is actually the parent, set that instead
|
||||
if (newPath === nmPath) {
|
||||
this.parent = fsParent
|
||||
return
|
||||
}
|
||||
|
||||
// ok! have a pseudo-parent, meaning that we're contained in
|
||||
// the parent node's fs tree, but NOT in its node_modules folder.
|
||||
// Almost certainly due to being a linked workspace-style package.
|
||||
this[_fsParent] = fsParent
|
||||
fsParent.fsChildren.add(this)
|
||||
// refresh the path BEFORE setting root, so meta gets updated properly
|
||||
this[_refreshPath](fsParent, current && current.path)
|
||||
this.root = fsParent.root
|
||||
this[_reloadEdges](e => !e.to)
|
||||
}
|
||||
const pathChange = newPath !== this.path
|
||||
|
||||
// called when we find that we have an fsParent which could account
|
||||
// for some missing edges which are actually fine and not missing at all.
|
||||
[_reloadEdges] (filter) {
|
||||
this[_explanation] = null
|
||||
this.edgesOut.forEach(edge => filter(edge) && edge.reload())
|
||||
this.fsChildren.forEach(c => c[_reloadEdges](filter))
|
||||
this.children.forEach(c => c[_reloadEdges](filter))
|
||||
// remove from old parent/fsParent
|
||||
const oldParent = this.parent
|
||||
const oldName = this.name
|
||||
if (this.parent) {
|
||||
this.parent.children.delete(this.name)
|
||||
this[_parent] = null
|
||||
}
|
||||
if (this.fsParent) {
|
||||
this.fsParent.fsChildren.delete(this)
|
||||
this[_fsParent] = null
|
||||
}
|
||||
|
||||
// update this.path/realpath for this and all children/fsChildren
|
||||
if (pathChange)
|
||||
this[_changePath](newPath)
|
||||
|
||||
if (oldParent)
|
||||
oldParent[_reloadNamedEdges](oldName)
|
||||
|
||||
// clobbers anything at that path, resets all appropriate references
|
||||
this.root = fsParent.root
|
||||
}
|
||||
|
||||
// is it safe to replace one node with another? check the edges to
|
||||
@@ -668,7 +874,7 @@ class Node {
|
||||
const parsed = npa(requested)
|
||||
const { name = this.name, rawSpec: spec } = parsed
|
||||
return this.name === name && this.satisfies(new Edge({
|
||||
from: new Node({ path: this.root.path }),
|
||||
from: new Node({ path: this.root.realpath }),
|
||||
type: 'prod',
|
||||
name,
|
||||
spec,
|
||||
@@ -713,29 +919,27 @@ class Node {
|
||||
// Useful when mutating an ideal tree, so we can avoid having to call
|
||||
// the parent/root setters more than necessary.
|
||||
replaceWith (node) {
|
||||
node.path = this.path
|
||||
node.name = this.name
|
||||
if (!node.isLink)
|
||||
node.realpath = this.path
|
||||
node.root = this.isRoot ? node : this.root
|
||||
// pretend to be in the tree, so top/etc refs are not changing for kids.
|
||||
node.parent = null
|
||||
node[_parent] = this[_parent]
|
||||
|
||||
// if we're replacing a non-link node with a link, then all the children
|
||||
// and fsChildren just go along with it, because links don't have those.
|
||||
if (!node.isLink) {
|
||||
this.fsChildren.forEach(c => c.fsParent = node)
|
||||
this.children.forEach(c => c.parent = node)
|
||||
}
|
||||
|
||||
// now remove the hidden reference, and call parent setter to finalize.
|
||||
node[_parent] = null
|
||||
node.parent = this.parent
|
||||
node.replace(this)
|
||||
}
|
||||
|
||||
replace (node) {
|
||||
node.replaceWith(this)
|
||||
this[_delistFromMeta]()
|
||||
this.path = node.path
|
||||
this.name = node.name
|
||||
if (!this.isLink)
|
||||
this.realpath = this.path
|
||||
this[_refreshLocation]()
|
||||
|
||||
// keep children when a node replaces another
|
||||
if (!this.isLink) {
|
||||
for (const kid of node.children.values())
|
||||
kid.parent = this
|
||||
}
|
||||
|
||||
if (!node.isRoot)
|
||||
this.root = node.root
|
||||
|
||||
treeCheck(this)
|
||||
}
|
||||
|
||||
get inShrinkwrap () {
|
||||
@@ -757,176 +961,94 @@ class Node {
|
||||
// The only walk that starts from the parent rather than this node is
|
||||
// limited by edge name.
|
||||
set parent (parent) {
|
||||
const oldParent = this[_parent]
|
||||
// when setting to null, just remove it from the tree entirely
|
||||
if (!parent) {
|
||||
// but only delete it if we actually had a parent in the first place
|
||||
// otherwise it's just setting to null when it's already null
|
||||
if (this[_parent])
|
||||
this.root = null
|
||||
return
|
||||
}
|
||||
|
||||
if (parent.isLink)
|
||||
parent = parent.target
|
||||
|
||||
// setting a thing to its own parent is not normal, but no-op for safety
|
||||
if (this === parent)
|
||||
return
|
||||
|
||||
// link nodes can't contain children directly.
|
||||
// children go under the link target.
|
||||
if (parent) {
|
||||
if (parent.isLink)
|
||||
parent = parent.target
|
||||
const oldParent = this[_parent]
|
||||
|
||||
if (oldParent === parent)
|
||||
return
|
||||
}
|
||||
// nothing to do
|
||||
if (oldParent === parent)
|
||||
return
|
||||
|
||||
// ok now we know something is actually changing, and parent is not a link
|
||||
|
||||
// check to see if the location is going to change.
|
||||
// we can skip some of the inventory/meta stuff if not.
|
||||
const newPath = parent ? resolve(parent.path, 'node_modules', this.name)
|
||||
: this.path
|
||||
const newPath = resolve(parent.path, 'node_modules', this.name)
|
||||
const pathChange = newPath !== this.path
|
||||
const newTop = parent ? parent.top : this
|
||||
const topChange = newTop !== this.top
|
||||
const newRoot = parent ? parent.root : null
|
||||
const rootChange = newRoot !== this.root
|
||||
|
||||
// if the path, top, or root are changing, then we need to delist
|
||||
// from metadata and inventory where this module (and its children)
|
||||
// are currently tracked. Need to do this BEFORE updating the
|
||||
// path and setting node.root. We don't have to do this for node.target,
|
||||
// because its path isn't changing, so everything we need will happen
|
||||
// safely when we set this.root = parent.root.
|
||||
if (this.path && (pathChange || topChange || rootChange)) {
|
||||
this[_delistFromMeta]()
|
||||
// delisting method doesn't walk children by default, since it would
|
||||
// be excessive to do so when changing the root reference, as a
|
||||
// root change walks children changing root as well. But in this case,
|
||||
// we are about to change the parent, and thus the top, so we have
|
||||
// to delist from the metadata now to ensure we remove it from the
|
||||
// proper top node metadata if it isn't the root.
|
||||
this.fsChildren.forEach(c => c[_delistFromMeta]())
|
||||
this.children.forEach(c => c[_delistFromMeta]())
|
||||
}
|
||||
|
||||
// remove from former parent.
|
||||
if (oldParent)
|
||||
// remove from old parent/fsParent
|
||||
if (oldParent) {
|
||||
oldParent.children.delete(this.name)
|
||||
|
||||
// update internal link. at this point, the node is actually in
|
||||
// the new location in the tree, but the paths are not updated yet.
|
||||
this[_parent] = parent
|
||||
|
||||
// remove former child. calls back into this setter to unlist
|
||||
if (parent) {
|
||||
const oldChild = parent.children.get(this.name)
|
||||
if (oldChild)
|
||||
oldChild.parent = null
|
||||
|
||||
parent.children.set(this.name, this)
|
||||
this[_parent] = null
|
||||
}
|
||||
if (this.fsParent) {
|
||||
this.fsParent.fsChildren.delete(this)
|
||||
this[_fsParent] = null
|
||||
}
|
||||
|
||||
// this is the point of no return. this.location is no longer valid,
|
||||
// and this.path is no longer going to reference this node in the
|
||||
// inventory or shrinkwrap metadata.
|
||||
if (parent)
|
||||
this[_refreshPath](parent, oldParent && oldParent.path)
|
||||
// update this.path/realpath for this and all children/fsChildren
|
||||
if (pathChange)
|
||||
this[_changePath](newPath)
|
||||
|
||||
// call the root setter. this updates this.location, and sets the
|
||||
// root on all children, and this.target if this is a link.
|
||||
// if the root isn't changing, then this is a no-op.
|
||||
// the root setter is a no-op if the root didn't change, so we have
|
||||
// to manually call the method to update location and metadata
|
||||
if (!rootChange)
|
||||
this[_refreshLocation]()
|
||||
else
|
||||
this.root = newRoot
|
||||
|
||||
// if the new top is not the root, and it has meta, then we're updating
|
||||
// nodes within a link target's folder. update it now.
|
||||
if (newTop !== newRoot && newTop.meta)
|
||||
this[_refreshTopMeta]()
|
||||
|
||||
// refresh dep links
|
||||
// note that this is _also_ done when a node is removed from the
|
||||
// tree by setting parent=null, so deduplication is covered.
|
||||
this.edgesIn.forEach(edge => edge.reload())
|
||||
this.edgesOut.forEach(edge => edge.reload())
|
||||
|
||||
// in case any of the parent's other descendants were resolving to
|
||||
// a different instance of this package, walk the tree from that point
|
||||
// reloading edges by this name. This only walks until it stops finding
|
||||
// changes, so if there's a portion of the tree blocked by a different
|
||||
// instance, or already updated by the previous in/out reloading, it won't
|
||||
// needlessly re-resolve deps that won't need to be changed.
|
||||
if (parent)
|
||||
parent[_reloadNamedEdges](this.name, true)
|
||||
|
||||
// since loading a parent can add *or change* resolutions, we also
|
||||
// walk the tree from this point reloading all edges.
|
||||
this[_reloadEdges](e => true)
|
||||
|
||||
// have to refresh the location of children and fsChildren at this point,
|
||||
// because their paths have likely changed, and root may have been set.
|
||||
if (!rootChange) {
|
||||
this.children.forEach(c => c[_refreshLocation]())
|
||||
this.fsChildren.forEach(c => c[_refreshLocation]())
|
||||
}
|
||||
}
|
||||
|
||||
// called after changing the parent (and thus the top), and after changing
|
||||
// the path, if the top is tracking metadata, so that we update the top's
|
||||
// metadata with the new node. Note that we DON'T walk fsChildren here,
|
||||
// because they do not share our top node.
|
||||
[_refreshTopMeta] () {
|
||||
this.top.meta.add(this)
|
||||
this.children.forEach(c => c[_refreshTopMeta]())
|
||||
// clobbers anything at that path, resets all appropriate references
|
||||
this.root = parent.root
|
||||
}
|
||||
|
||||
// Call this before changing path or updating the _root reference.
|
||||
// Removes the node from all the metadata trackers where it might live.
|
||||
// Removes the node from its root the metadata and inventory.
|
||||
[_delistFromMeta] () {
|
||||
const top = this.top
|
||||
const root = this.root
|
||||
|
||||
if (!root.realpath || !this.path)
|
||||
return
|
||||
root.inventory.delete(this)
|
||||
root.tops.delete(this)
|
||||
if (root.meta)
|
||||
root.meta.delete(this.path)
|
||||
|
||||
// need to also remove from the top meta if that's set. but, we only do
|
||||
// that if the top is not the same as the root, or else we'll remove it
|
||||
// twice unnecessarily. If the top and this have different roots, then
|
||||
// that means we're in the process of changing this.parent, which sets the
|
||||
// internal _parent reference BEFORE setting the root node, because paths
|
||||
// need to be set up before assigning root. In that case, don't delist,
|
||||
// or else we'll delete the metadata before we have a chance to apply it.
|
||||
if (top.meta && top !== root && top.root === this.root)
|
||||
top.meta.delete(this.path)
|
||||
/* istanbul ignore next - should be impossible */
|
||||
debug(() => {
|
||||
if ([...root.inventory.values()].includes(this))
|
||||
throw new Error('failed to delist')
|
||||
})
|
||||
}
|
||||
|
||||
// recurse through the tree updating path when it changes.
|
||||
// called by the parent and fsParent setters.
|
||||
[_refreshPath] (parent, fromPath = null) {
|
||||
const ppath = parent.path
|
||||
const relPath = typeof fromPath === 'string'
|
||||
? relative(fromPath, this.path)
|
||||
: null
|
||||
const oldPath = this.path
|
||||
const newPath = relPath !== null ? resolve(ppath, relPath)
|
||||
: parent === this[_parent] ? resolve(ppath, 'node_modules', this.name)
|
||||
// fsparent initial assignment, nothing to update here
|
||||
: oldPath
|
||||
|
||||
// if no change, nothing to do!
|
||||
if (newPath === oldPath)
|
||||
return
|
||||
|
||||
// update this.path/realpath and the paths of all children/fsChildren
|
||||
[_changePath] (newPath) {
|
||||
// have to de-list before changing paths
|
||||
this[_delistFromMeta]()
|
||||
const oldPath = this.path
|
||||
this.path = newPath
|
||||
const namePattern = /(?:^|\/|\\)node_modules[\\/](@[^/\\]+[\\/][^\\/]+|[^\\/]+)$/
|
||||
const nameChange = newPath.match(namePattern)
|
||||
if (nameChange && this.name !== nameChange[1])
|
||||
this.name = nameChange[1].replace(/\\/g, '/')
|
||||
|
||||
// if we move a link target, update link realpaths
|
||||
if (!this.isLink) {
|
||||
this.realpath = this.path
|
||||
if (this.linksIn.size) {
|
||||
for (const link of this.linksIn)
|
||||
link.realpath = newPath
|
||||
this.realpath = newPath
|
||||
for (const link of this.linksIn) {
|
||||
link[_delistFromMeta]()
|
||||
link.realpath = newPath
|
||||
link[_refreshLocation]()
|
||||
}
|
||||
}
|
||||
// if we move /x to /y, then a module at /x/a/b becomes /y/a/b
|
||||
for (const child of this.fsChildren)
|
||||
child[_changePath](resolve(newPath, relative(oldPath, child.path)))
|
||||
for (const [name, child] of this.children.entries())
|
||||
child[_changePath](resolve(newPath, 'node_modules', name))
|
||||
|
||||
this[_refreshLocation]()
|
||||
this.fsChildren.forEach(c => c[_refreshPath](this, oldPath))
|
||||
this.children.forEach(c => c[_refreshPath](this, oldPath))
|
||||
}
|
||||
|
||||
// Called whenever the root/parent is changed.
|
||||
@@ -934,7 +1056,9 @@ class Node {
|
||||
// this.path BEFORE calling this method!
|
||||
[_refreshLocation] () {
|
||||
const root = this.root
|
||||
this.location = relpath(root.realpath, this.path)
|
||||
const loc = relpath(root.realpath, this.path)
|
||||
|
||||
this.location = loc
|
||||
|
||||
root.inventory.add(this)
|
||||
if (root.meta)
|
||||
@@ -953,44 +1077,38 @@ class Node {
|
||||
this.root.meta.addEdge(edge)
|
||||
}
|
||||
|
||||
[_reloadNamedEdges] (name, root) {
|
||||
// either it's the node in question, or it's going to block it anyway
|
||||
if (this.name === name && !this.isTop) {
|
||||
// reload the edges in so that anything that SHOULD be blocked
|
||||
// by this node actually will be.
|
||||
this.edgesIn.forEach(e => e.reload())
|
||||
return
|
||||
}
|
||||
|
||||
[_reloadNamedEdges] (name, rootLoc = this.location) {
|
||||
const edge = this.edgesOut.get(name)
|
||||
// if we don't have an edge, do nothing, but keep descending
|
||||
if (edge) {
|
||||
const toBefore = edge.to
|
||||
edge.reload()
|
||||
const toAfter = edge.to
|
||||
if (toBefore === toAfter && !root) {
|
||||
// nothing changed, we're done here. either it was already
|
||||
// referring to this node (due to its edgesIn reloads), or
|
||||
// it is blocked by another node in the tree. So either its children
|
||||
// have already been updated, or don't need to be.
|
||||
//
|
||||
// but: always descend past the _first_ node, because it's likely
|
||||
// that this is being triggered by this node getting a new child,
|
||||
// so the whole point is to update the rest of the family.
|
||||
return
|
||||
}
|
||||
}
|
||||
const rootLocResolved = edge && edge.to &&
|
||||
edge.to.location === `${rootLoc}/node_modules/${edge.name}`
|
||||
const sameResolved = edge && this.resolve(name) === edge.to
|
||||
const recheck = rootLocResolved || !sameResolved
|
||||
if (edge && recheck)
|
||||
edge.reload(true)
|
||||
for (const c of this.children.values())
|
||||
c[_reloadNamedEdges](name)
|
||||
c[_reloadNamedEdges](name, rootLoc)
|
||||
|
||||
for (const c of this.fsChildren)
|
||||
c[_reloadNamedEdges](name)
|
||||
c[_reloadNamedEdges](name, rootLoc)
|
||||
}
|
||||
|
||||
get isLink () {
|
||||
return false
|
||||
}
|
||||
|
||||
get target () {
|
||||
return null
|
||||
}
|
||||
|
||||
set target (n) {
|
||||
debug(() => {
|
||||
throw Object.assign(new Error('cannot set target on non-Link Nodes'), {
|
||||
path: this.path,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
get depth () {
|
||||
return this.isTop ? 0 : this.parent.depth + 1
|
||||
}
|
||||
|
||||
+16
-4
@@ -758,11 +758,14 @@ class Shrinkwrap {
|
||||
if (this.tree) {
|
||||
if (this.yarnLock)
|
||||
this.yarnLock.fromTree(this.tree)
|
||||
const root = Shrinkwrap.metaFromNode(this.tree, this.path)
|
||||
const root = Shrinkwrap.metaFromNode(this.tree.target || this.tree, this.path)
|
||||
this.data.packages = {}
|
||||
if (Object.keys(root).length)
|
||||
this.data.packages[''] = root
|
||||
for (const node of this.tree.inventory.values()) {
|
||||
for (const node of this.tree.root.inventory.values()) {
|
||||
// only way this.tree is not root is if the root is a link to it
|
||||
if (node === this.tree || node.isRoot || node.location === '')
|
||||
continue
|
||||
const loc = relpath(this.path, node.path)
|
||||
this.data.packages[loc] = Shrinkwrap.metaFromNode(node, this.path)
|
||||
}
|
||||
@@ -877,8 +880,17 @@ class Shrinkwrap {
|
||||
// omit peer deps from legacy lockfile requires field, because
|
||||
// npm v6 doesn't handle peer deps, and this triggers some bad
|
||||
// behavior if the dep can't be found in the dependencies list.
|
||||
if (!v.peer)
|
||||
set[k] = v.spec
|
||||
const { spec, peer } = v
|
||||
if (peer)
|
||||
return set
|
||||
if (spec.startsWith('file:')) {
|
||||
// turn absolute file: paths into relative paths from the node
|
||||
// this especially shows up with workspace edges when the root
|
||||
// node is also a workspace in the set.
|
||||
const p = resolve(node.realpath, spec.substr('file:'.length))
|
||||
set[k] = `file:${relpath(node.realpath, p)}`
|
||||
} else
|
||||
set[k] = spec
|
||||
return set
|
||||
}, {})
|
||||
} else
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
const debug = require('./debug.js')
|
||||
|
||||
const checkTree = (tree, checkUnreachable = true) => {
|
||||
// this can only happen in tests where we have a "tree" object
|
||||
// that isn't actually a tree.
|
||||
if (!tree.root || !tree.root.inventory)
|
||||
return tree
|
||||
|
||||
const { inventory } = tree.root
|
||||
const seen = new Set()
|
||||
const check = (node, via = tree, viaType = 'self') => {
|
||||
if (!node || seen.has(node) || node.then)
|
||||
return
|
||||
if (node.isRoot && node !== tree.root) {
|
||||
throw Object.assign(new Error('double root'), {
|
||||
node: node.path,
|
||||
realpath: node.realpath,
|
||||
tree: tree.path,
|
||||
root: tree.root.path,
|
||||
via: via.path,
|
||||
viaType,
|
||||
})
|
||||
}
|
||||
|
||||
if (node.root !== tree.root) {
|
||||
throw Object.assign(new Error('node from other root in tree'), {
|
||||
node: node.path,
|
||||
realpath: node.realpath,
|
||||
tree: tree.path,
|
||||
root: tree.root.path,
|
||||
via: via.path,
|
||||
viaType,
|
||||
otherRoot: node.root && node.root.path,
|
||||
})
|
||||
}
|
||||
|
||||
if (!node.isRoot && node.inventory.size !== 0) {
|
||||
throw Object.assign(new Error('non-root has non-zero inventory'), {
|
||||
node: node.path,
|
||||
tree: tree.path,
|
||||
root: tree.root.path,
|
||||
via: via.path,
|
||||
viaType,
|
||||
inventory: [...node.inventory.values()].map(node =>
|
||||
[node.path, node.location]),
|
||||
})
|
||||
}
|
||||
|
||||
if (!node.isRoot && !inventory.has(node) && !node.dummy) {
|
||||
throw Object.assign(new Error('not in inventory'), {
|
||||
node: node.path,
|
||||
tree: tree.path,
|
||||
root: tree.root.path,
|
||||
via: via.path,
|
||||
viaType,
|
||||
})
|
||||
}
|
||||
|
||||
const devEdges = [...node.edgesOut.values()].filter(e => e.dev)
|
||||
if (!node.isTop && devEdges.length) {
|
||||
throw Object.assign(new Error('dev edges on non-top node'), {
|
||||
node: node.path,
|
||||
tree: tree.path,
|
||||
root: tree.root.path,
|
||||
via: via.path,
|
||||
viaType,
|
||||
devEdges: devEdges.map(e => [e.type, e.name, e.spec, e.error]),
|
||||
})
|
||||
}
|
||||
|
||||
const { parent, fsParent, target } = node
|
||||
seen.add(node)
|
||||
check(parent, node, 'parent')
|
||||
check(fsParent, node, 'fsParent')
|
||||
check(target, node, 'target')
|
||||
for (const kid of node.children.values())
|
||||
check(kid, node, 'children')
|
||||
for (const kid of node.fsChildren)
|
||||
check(kid, node, 'fsChildren')
|
||||
for (const link of node.linksIn)
|
||||
check(link, node, 'linksIn')
|
||||
for (const top of node.tops)
|
||||
check(top, node, 'tops')
|
||||
}
|
||||
check(tree)
|
||||
if (checkUnreachable) {
|
||||
for (const node of inventory.values()) {
|
||||
if (!seen.has(node) && node !== tree.root) {
|
||||
throw Object.assign(new Error('unreachable in inventory'), {
|
||||
node: node.path,
|
||||
realpath: node.realpath,
|
||||
location: node.location,
|
||||
root: tree.root.path,
|
||||
tree: tree.path,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return tree
|
||||
}
|
||||
|
||||
// should only ever run this check in debug mode
|
||||
module.exports = tree => tree
|
||||
debug(() => module.exports = checkTree)
|
||||
+11
-7
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@npmcli/arborist",
|
||||
"version": "1.0.14",
|
||||
"version": "2.0.0",
|
||||
"description": "Manage node_modules trees",
|
||||
"dependencies": {
|
||||
"@npmcli/installed-package-contents": "^1.0.5",
|
||||
@@ -8,8 +8,8 @@
|
||||
"@npmcli/metavuln-calculator": "^1.0.0",
|
||||
"@npmcli/move-file": "^1.0.1",
|
||||
"@npmcli/name-from-folder": "^1.0.1",
|
||||
"@npmcli/node-gyp": "^1.0.0",
|
||||
"@npmcli/run-script": "^1.8.0",
|
||||
"@npmcli/node-gyp": "^1.0.1",
|
||||
"@npmcli/run-script": "^1.8.1",
|
||||
"bin-links": "^2.2.1",
|
||||
"cacache": "^15.0.3",
|
||||
"common-ancestor-path": "^1.0.1",
|
||||
@@ -17,19 +17,21 @@
|
||||
"json-stringify-nice": "^1.1.1",
|
||||
"mkdirp-infer-owner": "^2.0.0",
|
||||
"npm-install-checks": "^4.0.0",
|
||||
"npm-package-arg": "^8.0.0",
|
||||
"npm-package-arg": "^8.1.0",
|
||||
"npm-pick-manifest": "^6.1.0",
|
||||
"pacote": "^11.1.10",
|
||||
"pacote": "^11.1.13",
|
||||
"parse-conflict-json": "^1.1.1",
|
||||
"promise-all-reject-late": "^1.0.0",
|
||||
"promise-call-limit": "^1.0.1",
|
||||
"read-package-json-fast": "^1.2.1",
|
||||
"readdir-scoped-modules": "^1.1.0",
|
||||
"semver": "^7.1.2",
|
||||
"semver": "^7.3.4",
|
||||
"treeverse": "^1.0.4",
|
||||
"walk-up-path": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"benchmark": "^2.1.4",
|
||||
"chalk": "^4.1.0",
|
||||
"eslint": "^7.9.0",
|
||||
"eslint-plugin-import": "^2.22.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
@@ -52,7 +54,9 @@
|
||||
"prepublishOnly": "git push origin --follow-tags",
|
||||
"eslint": "eslint",
|
||||
"lint": "npm run eslint -- \"lib/**/*.js\"",
|
||||
"lintfix": "npm run lint -- --fix"
|
||||
"lintfix": "npm run lint -- --fix",
|
||||
"benchmark": "node scripts/benchmark.js",
|
||||
"benchclean": "rm -rf scripts/benchmark/*/"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ const parseField = (f, key, opts, listElement = false) => {
|
||||
const typeList = new Set([].concat(types[key]))
|
||||
const isPath = typeList.has(typeDefs.path.type)
|
||||
const isBool = typeList.has(typeDefs.Boolean.type)
|
||||
const isString = typeList.has(typeDefs.String.type)
|
||||
const isString = isPath || typeList.has(typeDefs.String.type)
|
||||
const isUmask = typeList.has(typeDefs.Umask.type)
|
||||
const isNumber = typeList.has(typeDefs.Number.type)
|
||||
const isList = !listElement && typeList.has(Array)
|
||||
@@ -38,7 +38,7 @@ const parseField = (f, key, opts, listElement = false) => {
|
||||
|
||||
// string types can be the string 'true', 'false', etc.
|
||||
// otherwise, parse these values out
|
||||
if (!isString) {
|
||||
if (!isString && !isPath && !isNumber) {
|
||||
switch (f) {
|
||||
case 'true': return true
|
||||
case 'false': return false
|
||||
|
||||
+8
@@ -10,6 +10,13 @@ const validateSemver = (data, k, val) => {
|
||||
data[k] = valid
|
||||
}
|
||||
|
||||
const noptValidatePath = nopt.typeDefs.path.validate
|
||||
const validatePath = (data, k, val) => {
|
||||
if (typeof val !== 'string')
|
||||
return false
|
||||
return noptValidatePath(data, k, val)
|
||||
}
|
||||
|
||||
// add descriptions so we can validate more usefully
|
||||
module.exports = {
|
||||
...nopt.typeDefs,
|
||||
@@ -29,6 +36,7 @@ module.exports = {
|
||||
},
|
||||
path: {
|
||||
...nopt.typeDefs.path,
|
||||
validate: validatePath,
|
||||
description: 'valid filesystem path',
|
||||
},
|
||||
Number: {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@npmcli/config",
|
||||
"version": "1.2.3",
|
||||
"version": "1.2.4",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
|
||||
+16
@@ -26,6 +26,20 @@ function encodeRfc3986Full(str) {
|
||||
return encodeRfc3986(encodeURIComponent(str))
|
||||
}
|
||||
|
||||
// A bit of a combination of:
|
||||
// https://github.com/aws/aws-sdk-java-v2/blob/dc695de6ab49ad03934e1b02e7263abbd2354be0/core/auth/src/main/java/software/amazon/awssdk/auth/signer/internal/AbstractAws4Signer.java#L59
|
||||
// https://github.com/aws/aws-sdk-js/blob/18cb7e5b463b46239f9fdd4a65e2ff8c81831e8f/lib/signers/v4.js#L191-L199
|
||||
// https://github.com/mhart/aws4fetch/blob/b3aed16b6f17384cf36ea33bcba3c1e9f3bdfefd/src/main.js#L25-L34
|
||||
var HEADERS_TO_IGNORE = {
|
||||
'authorization': true,
|
||||
'connection': true,
|
||||
'x-amzn-trace-id': true,
|
||||
'user-agent': true,
|
||||
'expect': true,
|
||||
'presigned-expires': true,
|
||||
'range': true,
|
||||
}
|
||||
|
||||
// request: { path | body, [host], [method], [headers], [service], [region] }
|
||||
// credentials: { accessKeyId, secretAccessKey, [sessionToken] }
|
||||
function RequestSigner(request, credentials) {
|
||||
@@ -284,6 +298,7 @@ RequestSigner.prototype.canonicalHeaders = function() {
|
||||
return header.toString().trim().replace(/\s+/g, ' ')
|
||||
}
|
||||
return Object.keys(headers)
|
||||
.filter(function(key) { return HEADERS_TO_IGNORE[key.toLowerCase()] == null })
|
||||
.sort(function(a, b) { return a.toLowerCase() < b.toLowerCase() ? -1 : 1 })
|
||||
.map(function(key) { return key.toLowerCase() + ':' + trimAll(headers[key]) })
|
||||
.join('\n')
|
||||
@@ -292,6 +307,7 @@ RequestSigner.prototype.canonicalHeaders = function() {
|
||||
RequestSigner.prototype.signedHeaders = function() {
|
||||
return Object.keys(this.request.headers)
|
||||
.map(function(key) { return key.toLowerCase() })
|
||||
.filter(function(key) { return HEADERS_TO_IGNORE[key] == null })
|
||||
.sort()
|
||||
.join(';')
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "aws4",
|
||||
"version": "1.10.1",
|
||||
"version": "1.11.0",
|
||||
"description": "Signs and prepares requests using AWS Signature Version 4",
|
||||
"author": "Michael Hart <michael.hart.au@gmail.com> (https://github.com/mhart)",
|
||||
"license": "MIT",
|
||||
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Helpers.
|
||||
*/
|
||||
|
||||
var s = 1000;
|
||||
var m = s * 60;
|
||||
var h = m * 60;
|
||||
var d = h * 24;
|
||||
var w = d * 7;
|
||||
var y = d * 365.25;
|
||||
|
||||
/**
|
||||
* Parse or format the given `val`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `long` verbose formatting [false]
|
||||
*
|
||||
* @param {String|Number} val
|
||||
* @param {Object} [options]
|
||||
* @throws {Error} throw an error if val is not a non-empty string or a number
|
||||
* @return {String|Number}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function(val, options) {
|
||||
options = options || {};
|
||||
var type = typeof val;
|
||||
if (type === 'string' && val.length > 0) {
|
||||
return parse(val);
|
||||
} else if (type === 'number' && isFinite(val)) {
|
||||
return options.long ? fmtLong(val) : fmtShort(val);
|
||||
}
|
||||
throw new Error(
|
||||
'val is not a non-empty string or a valid number. val=' +
|
||||
JSON.stringify(val)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the given `str` and return milliseconds.
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {Number}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function parse(str) {
|
||||
str = String(str);
|
||||
if (str.length > 100) {
|
||||
return;
|
||||
}
|
||||
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
|
||||
str
|
||||
);
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
var n = parseFloat(match[1]);
|
||||
var type = (match[2] || 'ms').toLowerCase();
|
||||
switch (type) {
|
||||
case 'years':
|
||||
case 'year':
|
||||
case 'yrs':
|
||||
case 'yr':
|
||||
case 'y':
|
||||
return n * y;
|
||||
case 'weeks':
|
||||
case 'week':
|
||||
case 'w':
|
||||
return n * w;
|
||||
case 'days':
|
||||
case 'day':
|
||||
case 'd':
|
||||
return n * d;
|
||||
case 'hours':
|
||||
case 'hour':
|
||||
case 'hrs':
|
||||
case 'hr':
|
||||
case 'h':
|
||||
return n * h;
|
||||
case 'minutes':
|
||||
case 'minute':
|
||||
case 'mins':
|
||||
case 'min':
|
||||
case 'm':
|
||||
return n * m;
|
||||
case 'seconds':
|
||||
case 'second':
|
||||
case 'secs':
|
||||
case 'sec':
|
||||
case 's':
|
||||
return n * s;
|
||||
case 'milliseconds':
|
||||
case 'millisecond':
|
||||
case 'msecs':
|
||||
case 'msec':
|
||||
case 'ms':
|
||||
return n;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Short format for `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function fmtShort(ms) {
|
||||
var msAbs = Math.abs(ms);
|
||||
if (msAbs >= d) {
|
||||
return Math.round(ms / d) + 'd';
|
||||
}
|
||||
if (msAbs >= h) {
|
||||
return Math.round(ms / h) + 'h';
|
||||
}
|
||||
if (msAbs >= m) {
|
||||
return Math.round(ms / m) + 'm';
|
||||
}
|
||||
if (msAbs >= s) {
|
||||
return Math.round(ms / s) + 's';
|
||||
}
|
||||
return ms + 'ms';
|
||||
}
|
||||
|
||||
/**
|
||||
* Long format for `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function fmtLong(ms) {
|
||||
var msAbs = Math.abs(ms);
|
||||
if (msAbs >= d) {
|
||||
return plural(ms, msAbs, d, 'day');
|
||||
}
|
||||
if (msAbs >= h) {
|
||||
return plural(ms, msAbs, h, 'hour');
|
||||
}
|
||||
if (msAbs >= m) {
|
||||
return plural(ms, msAbs, m, 'minute');
|
||||
}
|
||||
if (msAbs >= s) {
|
||||
return plural(ms, msAbs, s, 'second');
|
||||
}
|
||||
return ms + ' ms';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluralization helper.
|
||||
*/
|
||||
|
||||
function plural(ms, msAbs, n, name) {
|
||||
var isPlural = msAbs >= n * 1.5;
|
||||
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Zeit, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "ms",
|
||||
"version": "2.1.2",
|
||||
"description": "Tiny millisecond conversion utility",
|
||||
"repository": "zeit/ms",
|
||||
"main": "./index",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"precommit": "lint-staged",
|
||||
"lint": "eslint lib/* bin/*",
|
||||
"test": "mocha tests.js"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "eslint:recommended",
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"npm run lint",
|
||||
"prettier --single-quote --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"eslint": "4.12.1",
|
||||
"expect.js": "0.3.1",
|
||||
"husky": "0.14.3",
|
||||
"lint-staged": "5.0.0",
|
||||
"mocha": "4.0.1"
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
# ms
|
||||
|
||||
[](https://travis-ci.org/zeit/ms)
|
||||
[](https://spectrum.chat/zeit)
|
||||
|
||||
Use this package to easily convert various time formats to milliseconds.
|
||||
|
||||
## Examples
|
||||
|
||||
```js
|
||||
ms('2 days') // 172800000
|
||||
ms('1d') // 86400000
|
||||
ms('10h') // 36000000
|
||||
ms('2.5 hrs') // 9000000
|
||||
ms('2h') // 7200000
|
||||
ms('1m') // 60000
|
||||
ms('5s') // 5000
|
||||
ms('1y') // 31557600000
|
||||
ms('100') // 100
|
||||
ms('-3 days') // -259200000
|
||||
ms('-1h') // -3600000
|
||||
ms('-200') // -200
|
||||
```
|
||||
|
||||
### Convert from Milliseconds
|
||||
|
||||
```js
|
||||
ms(60000) // "1m"
|
||||
ms(2 * 60000) // "2m"
|
||||
ms(-3 * 60000) // "-3m"
|
||||
ms(ms('10 hours')) // "10h"
|
||||
```
|
||||
|
||||
### Time Format Written-Out
|
||||
|
||||
```js
|
||||
ms(60000, { long: true }) // "1 minute"
|
||||
ms(2 * 60000, { long: true }) // "2 minutes"
|
||||
ms(-3 * 60000, { long: true }) // "-3 minutes"
|
||||
ms(ms('10 hours'), { long: true }) // "10 hours"
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- Works both in [Node.js](https://nodejs.org) and in the browser
|
||||
- If a number is supplied to `ms`, a string with a unit is returned
|
||||
- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`)
|
||||
- If you pass a string with a number and a valid unit, the number of equivalent milliseconds is returned
|
||||
|
||||
## Related Packages
|
||||
|
||||
- [ms.macro](https://github.com/knpwrs/ms.macro) - Run `ms` as a macro at build-time.
|
||||
|
||||
## Caught a Bug?
|
||||
|
||||
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
|
||||
2. Link the package to the global module directory: `npm link`
|
||||
3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, Node.js will now use your clone of ms!
|
||||
|
||||
As always, you can run the tests using: `npm test`
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "debug",
|
||||
"version": "4.2.0",
|
||||
"version": "4.3.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/visionmedia/debug.git"
|
||||
|
||||
+10
@@ -9,6 +9,16 @@ exports.save = save;
|
||||
exports.load = load;
|
||||
exports.useColors = useColors;
|
||||
exports.storage = localstorage();
|
||||
exports.destroy = (() => {
|
||||
let warned = false;
|
||||
|
||||
return () => {
|
||||
if (!warned) {
|
||||
warned = true;
|
||||
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* Colors.
|
||||
|
||||
+21
-24
@@ -12,16 +12,12 @@ function setup(env) {
|
||||
createDebug.enable = enable;
|
||||
createDebug.enabled = enabled;
|
||||
createDebug.humanize = require('ms');
|
||||
createDebug.destroy = destroy;
|
||||
|
||||
Object.keys(env).forEach(key => {
|
||||
createDebug[key] = env[key];
|
||||
});
|
||||
|
||||
/**
|
||||
* Active `debug` instances.
|
||||
*/
|
||||
createDebug.instances = [];
|
||||
|
||||
/**
|
||||
* The currently active debug mode names, and names to skip.
|
||||
*/
|
||||
@@ -63,6 +59,7 @@ function setup(env) {
|
||||
*/
|
||||
function createDebug(namespace) {
|
||||
let prevTime;
|
||||
let enableOverride = null;
|
||||
|
||||
function debug(...args) {
|
||||
// Disabled?
|
||||
@@ -92,7 +89,7 @@ function setup(env) {
|
||||
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
|
||||
// If we encounter an escaped % then don't increase the array index
|
||||
if (match === '%%') {
|
||||
return match;
|
||||
return '%';
|
||||
}
|
||||
index++;
|
||||
const formatter = createDebug.formatters[format];
|
||||
@@ -115,31 +112,28 @@ function setup(env) {
|
||||
}
|
||||
|
||||
debug.namespace = namespace;
|
||||
debug.enabled = createDebug.enabled(namespace);
|
||||
debug.useColors = createDebug.useColors();
|
||||
debug.color = createDebug.selectColor(namespace);
|
||||
debug.destroy = destroy;
|
||||
debug.extend = extend;
|
||||
debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
|
||||
|
||||
Object.defineProperty(debug, 'enabled', {
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
get: () => enableOverride === null ? createDebug.enabled(namespace) : enableOverride,
|
||||
set: v => {
|
||||
enableOverride = v;
|
||||
}
|
||||
});
|
||||
|
||||
// Env-specific initialization logic for debug instances
|
||||
if (typeof createDebug.init === 'function') {
|
||||
createDebug.init(debug);
|
||||
}
|
||||
|
||||
createDebug.instances.push(debug);
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
const index = createDebug.instances.indexOf(this);
|
||||
if (index !== -1) {
|
||||
createDebug.instances.splice(index, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function extend(namespace, delimiter) {
|
||||
const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
|
||||
newDebug.log = this.log;
|
||||
@@ -177,11 +171,6 @@ function setup(env) {
|
||||
createDebug.names.push(new RegExp('^' + namespaces + '$'));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < createDebug.instances.length; i++) {
|
||||
const instance = createDebug.instances[i];
|
||||
instance.enabled = createDebug.enabled(instance.namespace);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,6 +245,14 @@ function setup(env) {
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* XXX DO NOT USE. This is a temporary stub function.
|
||||
* XXX It WILL be removed in the next major release.
|
||||
*/
|
||||
function destroy() {
|
||||
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
||||
}
|
||||
|
||||
createDebug.enable(createDebug.load());
|
||||
|
||||
return createDebug;
|
||||
|
||||
+7
-1
@@ -15,6 +15,10 @@ exports.formatArgs = formatArgs;
|
||||
exports.save = save;
|
||||
exports.load = load;
|
||||
exports.useColors = useColors;
|
||||
exports.destroy = util.deprecate(
|
||||
() => {},
|
||||
'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'
|
||||
);
|
||||
|
||||
/**
|
||||
* Colors.
|
||||
@@ -244,7 +248,9 @@ const {formatters} = module.exports;
|
||||
formatters.o = function (v) {
|
||||
this.inspectOpts.colors = this.useColors;
|
||||
return util.inspect(v, this.inspectOpts)
|
||||
.replace(/\s*\n\s*/g, ' ');
|
||||
.split('\n')
|
||||
.map(str => str.trim())
|
||||
.join(' ');
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
max_line_length = 120
|
||||
|
||||
[CHANGELOG.md]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.json]
|
||||
max_line_length = off
|
||||
|
||||
[Makefile]
|
||||
max_line_length = off
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
{
|
||||
"es3": true,
|
||||
|
||||
"additionalRules": [],
|
||||
|
||||
"requireSemicolons": true,
|
||||
|
||||
"disallowMultipleSpaces": true,
|
||||
|
||||
"disallowIdentifierNames": [],
|
||||
|
||||
"requireCurlyBraces": {
|
||||
"allExcept": [],
|
||||
"keywords": ["if", "else", "for", "while", "do", "try", "catch"]
|
||||
},
|
||||
|
||||
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"],
|
||||
|
||||
"disallowSpaceAfterKeywords": [],
|
||||
|
||||
"disallowSpaceBeforeComma": true,
|
||||
"disallowSpaceAfterComma": false,
|
||||
"disallowSpaceBeforeSemicolon": true,
|
||||
|
||||
"disallowNodeTypes": [
|
||||
"DebuggerStatement",
|
||||
"ForInStatement",
|
||||
"LabeledStatement",
|
||||
"SwitchCase",
|
||||
"SwitchStatement",
|
||||
"WithStatement"
|
||||
],
|
||||
|
||||
"requireObjectKeysOnNewLine": { "allExcept": ["sameLine"] },
|
||||
|
||||
"requireSpacesInAnonymousFunctionExpression": { "beforeOpeningRoundBrace": true, "beforeOpeningCurlyBrace": true },
|
||||
"requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true },
|
||||
"disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true },
|
||||
"requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true },
|
||||
"disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true },
|
||||
|
||||
"requireSpaceBetweenArguments": true,
|
||||
|
||||
"disallowSpacesInsideParentheses": true,
|
||||
|
||||
"disallowSpacesInsideArrayBrackets": true,
|
||||
|
||||
"disallowQuotedKeysInObjects": { "allExcept": ["reserved"] },
|
||||
|
||||
"disallowSpaceAfterObjectKeys": true,
|
||||
|
||||
"requireCommaBeforeLineBreak": true,
|
||||
|
||||
"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
|
||||
"requireSpaceAfterPrefixUnaryOperators": [],
|
||||
|
||||
"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
|
||||
"requireSpaceBeforePostfixUnaryOperators": [],
|
||||
|
||||
"disallowSpaceBeforeBinaryOperators": [],
|
||||
"requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
|
||||
|
||||
"requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
|
||||
"disallowSpaceAfterBinaryOperators": [],
|
||||
|
||||
"disallowImplicitTypeConversion": ["binary", "string"],
|
||||
|
||||
"disallowKeywords": ["with", "eval"],
|
||||
|
||||
"requireKeywordsOnNewLine": [],
|
||||
"disallowKeywordsOnNewLine": ["else"],
|
||||
|
||||
"requireLineFeedAtFileEnd": true,
|
||||
|
||||
"disallowTrailingWhitespace": true,
|
||||
|
||||
"disallowTrailingComma": true,
|
||||
|
||||
"excludeFiles": ["node_modules/**", "vendor/**"],
|
||||
|
||||
"disallowMultipleLineStrings": true,
|
||||
|
||||
"requireDotNotation": { "allExcept": ["keywords"] },
|
||||
|
||||
"requireParenthesesAroundIIFE": true,
|
||||
|
||||
"validateLineBreaks": "LF",
|
||||
|
||||
"validateQuoteMarks": {
|
||||
"escape": true,
|
||||
"mark": "'"
|
||||
},
|
||||
|
||||
"disallowOperatorBeforeLineBreak": [],
|
||||
|
||||
"requireSpaceBeforeKeywords": [
|
||||
"do",
|
||||
"for",
|
||||
"if",
|
||||
"else",
|
||||
"switch",
|
||||
"case",
|
||||
"try",
|
||||
"catch",
|
||||
"finally",
|
||||
"while",
|
||||
"with",
|
||||
"return"
|
||||
],
|
||||
|
||||
"validateAlignedFunctionParameters": {
|
||||
"lineBreakAfterOpeningBraces": true,
|
||||
"lineBreakBeforeClosingBraces": true
|
||||
},
|
||||
|
||||
"requirePaddingNewLinesBeforeExport": true,
|
||||
|
||||
"validateNewlineAfterArrayElements": {
|
||||
"maximum": 8
|
||||
},
|
||||
|
||||
"requirePaddingNewLinesAfterUseStrict": true,
|
||||
|
||||
"disallowArrowFunctions": true,
|
||||
|
||||
"disallowMultiLineTernary": true,
|
||||
|
||||
"validateOrderInObjectKeys": "asc-insensitive",
|
||||
|
||||
"disallowIdenticalDestructuringNames": true,
|
||||
|
||||
"disallowNestedTernaries": { "maxLevel": 1 },
|
||||
|
||||
"requireSpaceAfterComma": { "allExcept": ["trailing"] },
|
||||
"requireAlignedMultilineParams": false,
|
||||
|
||||
"requireSpacesInGenerator": {
|
||||
"afterStar": true
|
||||
},
|
||||
|
||||
"disallowSpacesInGenerator": {
|
||||
"beforeStar": true
|
||||
},
|
||||
|
||||
"disallowVar": false,
|
||||
|
||||
"requireArrayDestructuring": false,
|
||||
|
||||
"requireEnhancedObjectLiterals": false,
|
||||
|
||||
"requireObjectDestructuring": false,
|
||||
|
||||
"requireEarlyReturn": false,
|
||||
|
||||
"requireCapitalizedConstructorsNew": {
|
||||
"allExcept": ["Function", "String", "Object", "Symbol", "Number", "Date", "RegExp", "Error", "Boolean", "Array"]
|
||||
},
|
||||
|
||||
"requireImportAlphabetized": false,
|
||||
|
||||
"requireSpaceBeforeObjectValues": true,
|
||||
"requireSpaceBeforeDestructuredValues": true,
|
||||
|
||||
"disallowSpacesInsideTemplateStringPlaceholders": true,
|
||||
|
||||
"disallowArrayDestructuringReturn": false,
|
||||
|
||||
"requireNewlineBeforeSingleStatementsInIf": false,
|
||||
|
||||
"disallowUnusedVariables": true,
|
||||
|
||||
"requireSpacesInsideImportedObjectBraces": true,
|
||||
|
||||
"requireUseStrict": true
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
# gitignore
|
||||
.DS_Store
|
||||
.monitor
|
||||
.*.swp
|
||||
.nodemonignore
|
||||
releases
|
||||
*.log
|
||||
*.err
|
||||
fleet.json
|
||||
public/browserify
|
||||
bin/*.json
|
||||
.bin
|
||||
build
|
||||
compile
|
||||
.lock-wscript
|
||||
coverage
|
||||
node_modules
|
||||
|
||||
# Only apps should have lockfiles
|
||||
npm-shrinkwrap.json
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
language: node_js
|
||||
os:
|
||||
- linux
|
||||
node_js:
|
||||
- "8.4"
|
||||
- "7.10"
|
||||
- "6.11"
|
||||
- "5.12"
|
||||
- "4.8"
|
||||
- "iojs-v3.3"
|
||||
- "iojs-v2.5"
|
||||
- "iojs-v1.8"
|
||||
- "0.12"
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
before_install:
|
||||
- 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ]; then npm install -g npm@1.3 ; elif [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then case "$(npm --version)" in 1.*) npm install -g npm@1.4.28 ;; 2.*) npm install -g npm@2 ;; esac ; fi'
|
||||
- 'if [ "${TRAVIS_NODE_VERSION}" != "0.6" ] && [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then if [ "${TRAVIS_NODE_VERSION%${TRAVIS_NODE_VERSION#[0-9]}}" = "0" ] || [ "${TRAVIS_NODE_VERSION:0:4}" = "iojs" ]; then npm install -g npm@4.5 ; else npm install -g npm; fi; fi'
|
||||
install:
|
||||
- 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ]; then nvm install 0.8 && npm install -g npm@1.3 && npm install -g npm@1.4.28 && npm install -g npm@2 && npm install && nvm use "${TRAVIS_NODE_VERSION}"; else npm install; fi;'
|
||||
script:
|
||||
- 'if [ -n "${PRETEST-}" ]; then npm run pretest ; fi'
|
||||
- 'if [ -n "${POSTTEST-}" ]; then npm run posttest ; fi'
|
||||
- 'if [ -n "${COVERAGE-}" ]; then npm run coverage ; fi'
|
||||
- 'if [ -n "${TEST-}" ]; then npm run tests-only ; fi'
|
||||
sudo: false
|
||||
env:
|
||||
- TEST=true
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- node_js: "node"
|
||||
env: PRETEST=true
|
||||
- node_js: "4"
|
||||
env: COVERAGE=true
|
||||
- node_js: "8.3"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "8.2"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "8.1"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "8.0"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "7.9"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "7.8"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "7.7"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "7.6"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "7.5"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "7.4"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "7.3"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "7.2"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "7.1"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "7.0"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "6.10"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "6.9"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "6.8"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "6.7"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "6.6"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "6.5"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "6.4"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "6.3"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "6.2"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "6.1"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "6.0"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.11"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.10"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.9"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.8"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.7"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.6"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.5"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.4"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.3"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.2"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.1"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "5.0"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "4.7"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "4.6"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "4.5"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "4.4"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "4.3"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "4.2"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "4.1"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "4.0"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v3.2"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v3.1"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v3.0"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v2.4"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v2.3"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v2.2"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v2.1"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v2.0"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v1.7"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v1.6"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v1.5"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v1.4"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v1.3"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v1.2"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v1.1"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "iojs-v1.0"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "0.11"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "0.9"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "0.6"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
- node_js: "0.4"
|
||||
env: TEST=true ALLOW_FAILURE=true
|
||||
allow_failures:
|
||||
- os: osx
|
||||
- env: TEST=true ALLOW_FAILURE=true
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2013 Raynos.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
# function-bind
|
||||
|
||||
<!--
|
||||
[![build status][travis-svg]][travis-url]
|
||||
[![NPM version][npm-badge-svg]][npm-url]
|
||||
[![Coverage Status][5]][6]
|
||||
[![gemnasium Dependency Status][7]][8]
|
||||
[![Dependency status][deps-svg]][deps-url]
|
||||
[![Dev Dependency status][dev-deps-svg]][dev-deps-url]
|
||||
-->
|
||||
|
||||
<!-- [![browser support][11]][12] -->
|
||||
|
||||
Implementation of function.prototype.bind
|
||||
|
||||
## Example
|
||||
|
||||
I mainly do this for unit tests I run on phantomjs.
|
||||
PhantomJS does not have Function.prototype.bind :(
|
||||
|
||||
```js
|
||||
Function.prototype.bind = require("function-bind")
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
`npm install function-bind`
|
||||
|
||||
## Contributors
|
||||
|
||||
- Raynos
|
||||
|
||||
## MIT Licenced
|
||||
|
||||
[travis-svg]: https://travis-ci.org/Raynos/function-bind.svg
|
||||
[travis-url]: https://travis-ci.org/Raynos/function-bind
|
||||
[npm-badge-svg]: https://badge.fury.io/js/function-bind.svg
|
||||
[npm-url]: https://npmjs.org/package/function-bind
|
||||
[5]: https://coveralls.io/repos/Raynos/function-bind/badge.png
|
||||
[6]: https://coveralls.io/r/Raynos/function-bind
|
||||
[7]: https://gemnasium.com/Raynos/function-bind.png
|
||||
[8]: https://gemnasium.com/Raynos/function-bind
|
||||
[deps-svg]: https://david-dm.org/Raynos/function-bind.svg
|
||||
[deps-url]: https://david-dm.org/Raynos/function-bind
|
||||
[dev-deps-svg]: https://david-dm.org/Raynos/function-bind/dev-status.svg
|
||||
[dev-deps-url]: https://david-dm.org/Raynos/function-bind#info=devDependencies
|
||||
[11]: https://ci.testling.com/Raynos/function-bind.png
|
||||
[12]: https://ci.testling.com/Raynos/function-bind
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
'use strict';
|
||||
|
||||
/* eslint no-invalid-this: 1 */
|
||||
|
||||
var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
|
||||
var slice = Array.prototype.slice;
|
||||
var toStr = Object.prototype.toString;
|
||||
var funcType = '[object Function]';
|
||||
|
||||
module.exports = function bind(that) {
|
||||
var target = this;
|
||||
if (typeof target !== 'function' || toStr.call(target) !== funcType) {
|
||||
throw new TypeError(ERROR_MESSAGE + target);
|
||||
}
|
||||
var args = slice.call(arguments, 1);
|
||||
|
||||
var bound;
|
||||
var binder = function () {
|
||||
if (this instanceof bound) {
|
||||
var result = target.apply(
|
||||
this,
|
||||
args.concat(slice.call(arguments))
|
||||
);
|
||||
if (Object(result) === result) {
|
||||
return result;
|
||||
}
|
||||
return this;
|
||||
} else {
|
||||
return target.apply(
|
||||
that,
|
||||
args.concat(slice.call(arguments))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
var boundLength = Math.max(0, target.length - args.length);
|
||||
var boundArgs = [];
|
||||
for (var i = 0; i < boundLength; i++) {
|
||||
boundArgs.push('$' + i);
|
||||
}
|
||||
|
||||
bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);
|
||||
|
||||
if (target.prototype) {
|
||||
var Empty = function Empty() {};
|
||||
Empty.prototype = target.prototype;
|
||||
bound.prototype = new Empty();
|
||||
Empty.prototype = null;
|
||||
}
|
||||
|
||||
return bound;
|
||||
};
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var implementation = require('./implementation');
|
||||
|
||||
module.exports = Function.prototype.bind || implementation;
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"name": "function-bind",
|
||||
"version": "1.1.1",
|
||||
"description": "Implementation of Function.prototype.bind",
|
||||
"keywords": [
|
||||
"function",
|
||||
"bind",
|
||||
"shim",
|
||||
"es5"
|
||||
],
|
||||
"author": "Raynos <raynos2@gmail.com>",
|
||||
"repository": "git://github.com/Raynos/function-bind.git",
|
||||
"main": "index",
|
||||
"homepage": "https://github.com/Raynos/function-bind",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Raynos"
|
||||
},
|
||||
{
|
||||
"name": "Jordan Harband",
|
||||
"url": "https://github.com/ljharb"
|
||||
}
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/Raynos/function-bind/issues",
|
||||
"email": "raynos2@gmail.com"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@ljharb/eslint-config": "^12.2.1",
|
||||
"covert": "^1.1.0",
|
||||
"eslint": "^4.5.0",
|
||||
"jscs": "^3.0.7",
|
||||
"tape": "^4.8.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"pretest": "npm run lint",
|
||||
"test": "npm run tests-only",
|
||||
"posttest": "npm run coverage -- --quiet",
|
||||
"tests-only": "node test",
|
||||
"coverage": "covert test/*.js",
|
||||
"lint": "npm run jscs && npm run eslint",
|
||||
"jscs": "jscs *.js */*.js",
|
||||
"eslint": "eslint *.js */*.js"
|
||||
},
|
||||
"testling": {
|
||||
"files": "test/index.js",
|
||||
"browsers": [
|
||||
"ie/8..latest",
|
||||
"firefox/16..latest",
|
||||
"firefox/nightly",
|
||||
"chrome/22..latest",
|
||||
"chrome/canary",
|
||||
"opera/12..latest",
|
||||
"opera/next",
|
||||
"safari/5.1..latest",
|
||||
"ipad/6.0..latest",
|
||||
"iphone/6.0..latest",
|
||||
"android-browser/4.2..latest"
|
||||
]
|
||||
}
|
||||
}
|
||||
+252
@@ -0,0 +1,252 @@
|
||||
// jscs:disable requireUseStrict
|
||||
|
||||
var test = require('tape');
|
||||
|
||||
var functionBind = require('../implementation');
|
||||
var getCurrentContext = function () { return this; };
|
||||
|
||||
test('functionBind is a function', function (t) {
|
||||
t.equal(typeof functionBind, 'function');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('non-functions', function (t) {
|
||||
var nonFunctions = [true, false, [], {}, 42, 'foo', NaN, /a/g];
|
||||
t.plan(nonFunctions.length);
|
||||
for (var i = 0; i < nonFunctions.length; ++i) {
|
||||
try { functionBind.call(nonFunctions[i]); } catch (ex) {
|
||||
t.ok(ex instanceof TypeError, 'throws when given ' + String(nonFunctions[i]));
|
||||
}
|
||||
}
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('without a context', function (t) {
|
||||
t.test('binds properly', function (st) {
|
||||
var args, context;
|
||||
var namespace = {
|
||||
func: functionBind.call(function () {
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
context = this;
|
||||
})
|
||||
};
|
||||
namespace.func(1, 2, 3);
|
||||
st.deepEqual(args, [1, 2, 3]);
|
||||
st.equal(context, getCurrentContext.call());
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('binds properly, and still supplies bound arguments', function (st) {
|
||||
var args, context;
|
||||
var namespace = {
|
||||
func: functionBind.call(function () {
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
context = this;
|
||||
}, undefined, 1, 2, 3)
|
||||
};
|
||||
namespace.func(4, 5, 6);
|
||||
st.deepEqual(args, [1, 2, 3, 4, 5, 6]);
|
||||
st.equal(context, getCurrentContext.call());
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('returns properly', function (st) {
|
||||
var args;
|
||||
var namespace = {
|
||||
func: functionBind.call(function () {
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
return this;
|
||||
}, null)
|
||||
};
|
||||
var context = namespace.func(1, 2, 3);
|
||||
st.equal(context, getCurrentContext.call(), 'returned context is namespaced context');
|
||||
st.deepEqual(args, [1, 2, 3], 'passed arguments are correct');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('returns properly with bound arguments', function (st) {
|
||||
var args;
|
||||
var namespace = {
|
||||
func: functionBind.call(function () {
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
return this;
|
||||
}, null, 1, 2, 3)
|
||||
};
|
||||
var context = namespace.func(4, 5, 6);
|
||||
st.equal(context, getCurrentContext.call(), 'returned context is namespaced context');
|
||||
st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('called as a constructor', function (st) {
|
||||
var thunkify = function (value) {
|
||||
return function () { return value; };
|
||||
};
|
||||
st.test('returns object value', function (sst) {
|
||||
var expectedReturnValue = [1, 2, 3];
|
||||
var Constructor = functionBind.call(thunkify(expectedReturnValue), null);
|
||||
var result = new Constructor();
|
||||
sst.equal(result, expectedReturnValue);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('does not return primitive value', function (sst) {
|
||||
var Constructor = functionBind.call(thunkify(42), null);
|
||||
var result = new Constructor();
|
||||
sst.notEqual(result, 42);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('object from bound constructor is instance of original and bound constructor', function (sst) {
|
||||
var A = function (x) {
|
||||
this.name = x || 'A';
|
||||
};
|
||||
var B = functionBind.call(A, null, 'B');
|
||||
|
||||
var result = new B();
|
||||
sst.ok(result instanceof B, 'result is instance of bound constructor');
|
||||
sst.ok(result instanceof A, 'result is instance of original constructor');
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('with a context', function (t) {
|
||||
t.test('with no bound arguments', function (st) {
|
||||
var args, context;
|
||||
var boundContext = {};
|
||||
var namespace = {
|
||||
func: functionBind.call(function () {
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
context = this;
|
||||
}, boundContext)
|
||||
};
|
||||
namespace.func(1, 2, 3);
|
||||
st.equal(context, boundContext, 'binds a context properly');
|
||||
st.deepEqual(args, [1, 2, 3], 'supplies passed arguments');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('with bound arguments', function (st) {
|
||||
var args, context;
|
||||
var boundContext = {};
|
||||
var namespace = {
|
||||
func: functionBind.call(function () {
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
context = this;
|
||||
}, boundContext, 1, 2, 3)
|
||||
};
|
||||
namespace.func(4, 5, 6);
|
||||
st.equal(context, boundContext, 'binds a context properly');
|
||||
st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'supplies bound and passed arguments');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('returns properly', function (st) {
|
||||
var boundContext = {};
|
||||
var args;
|
||||
var namespace = {
|
||||
func: functionBind.call(function () {
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
return this;
|
||||
}, boundContext)
|
||||
};
|
||||
var context = namespace.func(1, 2, 3);
|
||||
st.equal(context, boundContext, 'returned context is bound context');
|
||||
st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context');
|
||||
st.deepEqual(args, [1, 2, 3], 'passed arguments are correct');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('returns properly with bound arguments', function (st) {
|
||||
var boundContext = {};
|
||||
var args;
|
||||
var namespace = {
|
||||
func: functionBind.call(function () {
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
return this;
|
||||
}, boundContext, 1, 2, 3)
|
||||
};
|
||||
var context = namespace.func(4, 5, 6);
|
||||
st.equal(context, boundContext, 'returned context is bound context');
|
||||
st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context');
|
||||
st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('passes the correct arguments when called as a constructor', function (st) {
|
||||
var expected = { name: 'Correct' };
|
||||
var namespace = {
|
||||
Func: functionBind.call(function (arg) {
|
||||
return arg;
|
||||
}, { name: 'Incorrect' })
|
||||
};
|
||||
var returned = new namespace.Func(expected);
|
||||
st.equal(returned, expected, 'returns the right arg when called as a constructor');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('has the new instance\'s context when called as a constructor', function (st) {
|
||||
var actualContext;
|
||||
var expectedContext = { foo: 'bar' };
|
||||
var namespace = {
|
||||
Func: functionBind.call(function () {
|
||||
actualContext = this;
|
||||
}, expectedContext)
|
||||
};
|
||||
var result = new namespace.Func();
|
||||
st.equal(result instanceof namespace.Func, true);
|
||||
st.notEqual(actualContext, expectedContext);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('bound function length', function (t) {
|
||||
t.test('sets a correct length without thisArg', function (st) {
|
||||
var subject = functionBind.call(function (a, b, c) { return a + b + c; });
|
||||
st.equal(subject.length, 3);
|
||||
st.equal(subject(1, 2, 3), 6);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('sets a correct length with thisArg', function (st) {
|
||||
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {});
|
||||
st.equal(subject.length, 3);
|
||||
st.equal(subject(1, 2, 3), 6);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('sets a correct length without thisArg and first argument', function (st) {
|
||||
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1);
|
||||
st.equal(subject.length, 2);
|
||||
st.equal(subject(2, 3), 6);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('sets a correct length with thisArg and first argument', function (st) {
|
||||
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1);
|
||||
st.equal(subject.length, 2);
|
||||
st.equal(subject(2, 3), 6);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('sets a correct length without thisArg and too many arguments', function (st) {
|
||||
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1, 2, 3, 4);
|
||||
st.equal(subject.length, 0);
|
||||
st.equal(subject(), 6);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('sets a correct length with thisArg and too many arguments', function (st) {
|
||||
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1, 2, 3, 4);
|
||||
st.equal(subject.length, 0);
|
||||
st.equal(subject(), 6);
|
||||
st.end();
|
||||
});
|
||||
});
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2013 Thiago de Arruda
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# has
|
||||
|
||||
> Object.prototype.hasOwnProperty.call shortcut
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install --save has
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var has = require('has');
|
||||
|
||||
has({}, 'hasOwnProperty'); // false
|
||||
has(Object.prototype, 'hasOwnProperty'); // true
|
||||
```
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "has",
|
||||
"description": "Object.prototype.hasOwnProperty.call shortcut",
|
||||
"version": "1.0.3",
|
||||
"homepage": "https://github.com/tarruda/has",
|
||||
"author": {
|
||||
"name": "Thiago de Arruda",
|
||||
"email": "tpadilha84@gmail.com"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Jordan Harband",
|
||||
"email": "ljharb@gmail.com",
|
||||
"url": "http://ljharb.codes"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/tarruda/has.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/tarruda/has/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/tarruda/has/blob/master/LICENSE-MIT"
|
||||
}
|
||||
],
|
||||
"main": "./src",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ljharb/eslint-config": "^12.2.1",
|
||||
"eslint": "^4.19.1",
|
||||
"tape": "^4.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"pretest": "npm run lint",
|
||||
"test": "tape test"
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var bind = require('function-bind');
|
||||
|
||||
module.exports = bind.call(Function.call, Object.prototype.hasOwnProperty);
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var has = require('../');
|
||||
|
||||
test('has', function (t) {
|
||||
t.equal(has({}, 'hasOwnProperty'), false, 'object literal does not have own property "hasOwnProperty"');
|
||||
t.equal(has(Object.prototype, 'hasOwnProperty'), true, 'Object.prototype has own property "hasOwnProperty"');
|
||||
t.end();
|
||||
});
|
||||
+8
@@ -80,6 +80,12 @@ function decode (str) {
|
||||
if (!match) return
|
||||
if (match[1] !== undefined) {
|
||||
section = unsafe(match[1])
|
||||
if (section === '__proto__') {
|
||||
// not allowed
|
||||
// keep parsing the section, but don't attach it.
|
||||
p = {}
|
||||
return
|
||||
}
|
||||
p = out[section] = out[section] || {}
|
||||
return
|
||||
}
|
||||
@@ -94,6 +100,7 @@ function decode (str) {
|
||||
// Convert keys with '[]' suffix to an array
|
||||
if (key.length > 2 && key.slice(-2) === '[]') {
|
||||
key = key.substring(0, key.length - 2)
|
||||
if (key === '__proto__') return
|
||||
if (!p[key]) {
|
||||
p[key] = []
|
||||
} else if (!Array.isArray(p[key])) {
|
||||
@@ -125,6 +132,7 @@ function decode (str) {
|
||||
var l = parts.pop()
|
||||
var nl = l.replace(/\\\./g, '.')
|
||||
parts.forEach(function (part, _, __) {
|
||||
if (part === '__proto__') return
|
||||
if (!p[part] || typeof p[part] !== 'object') p[part] = {}
|
||||
p = p[part]
|
||||
})
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
|
||||
"name": "ini",
|
||||
"description": "An ini encoder/decoder for node",
|
||||
"version": "1.3.5",
|
||||
"version": "1.3.6",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/isaacs/ini.git"
|
||||
@@ -13,7 +13,7 @@
|
||||
"test": "tap test/*.js --100 -J",
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"postpublish": "git push origin --all; git push origin --tags"
|
||||
"prepublishOnly": "git push origin --follow-tags"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
coverage/
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [ljharb]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: npm/is-core-module
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
name: 'Tests: node.js'
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
latest: ${{ steps.set-matrix.outputs.requireds }}
|
||||
minors: ${{ steps.set-matrix.outputs.optionals }}
|
||||
steps:
|
||||
- uses: ljharb/actions/node/matrix@main
|
||||
id: set-matrix
|
||||
with:
|
||||
preset: '>=4'
|
||||
|
||||
latest:
|
||||
needs: [matrix]
|
||||
name: 'latest minors'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix: ${{ fromJson(needs.matrix.outputs.latest) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/run@main
|
||||
name: 'npm install && npm run tests-only'
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
command: 'tests-only'
|
||||
minors:
|
||||
needs: [matrix, latest]
|
||||
name: 'non-latest minors'
|
||||
continue-on-error: true
|
||||
if: ${{ !github.head_ref || !startsWith(github.head_ref, 'renovate') }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix: ${{ fromJson(needs.matrix.outputs.minors) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/run@main
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
command: 'tests-only'
|
||||
|
||||
node:
|
||||
name: 'node 4+'
|
||||
needs: [latest, minors]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: 'echo tests completed'
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
name: 'Tests: node.js (io.js)'
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
latest: ${{ steps.set-matrix.outputs.requireds }}
|
||||
minors: ${{ steps.set-matrix.outputs.optionals }}
|
||||
steps:
|
||||
- uses: ljharb/actions/node/matrix@main
|
||||
id: set-matrix
|
||||
with:
|
||||
preset: 'iojs'
|
||||
|
||||
latest:
|
||||
needs: [matrix]
|
||||
name: 'latest minors'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix: ${{ fromJson(needs.matrix.outputs.latest) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/run@main
|
||||
name: 'npm install && npm run tests-only'
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
command: 'tests-only'
|
||||
skip-ls-check: true
|
||||
|
||||
minors:
|
||||
needs: [matrix, latest]
|
||||
name: 'non-latest minors'
|
||||
continue-on-error: true
|
||||
if: ${{ !github.head_ref || !startsWith(github.head_ref, 'renovate') }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix: ${{ fromJson(needs.matrix.outputs.minors) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/run@main
|
||||
name: 'npm install && npm run tests-only'
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
command: 'tests-only'
|
||||
skip-ls-check: true
|
||||
|
||||
node:
|
||||
name: 'io.js'
|
||||
needs: [latest, minors]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: 'echo tests completed'
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
name: 'Tests: pretest/posttest'
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
pretest:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/run@main
|
||||
name: 'npm install && npm run pretest'
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
command: 'pretest'
|
||||
|
||||
posttest:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/run@main
|
||||
name: 'npm install && npm run posttest'
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
command: 'posttest'
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
name: 'Tests: node.js (0.x)'
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
stable: ${{ steps.set-matrix.outputs.requireds }}
|
||||
unstable: ${{ steps.set-matrix.outputs.optionals }}
|
||||
steps:
|
||||
- uses: ljharb/actions/node/matrix@main
|
||||
id: set-matrix
|
||||
with:
|
||||
preset: '0.x'
|
||||
|
||||
stable:
|
||||
needs: [matrix]
|
||||
name: 'stable minors'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix: ${{ fromJson(needs.matrix.outputs.stable) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/run@main
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
command: 'tests-only'
|
||||
cache-node-modules-key: node_modules-${{ github.workflow }}-${{ github.action }}-${{ github.run_id }}
|
||||
skip-ls-check: true
|
||||
|
||||
unstable:
|
||||
needs: [matrix, stable]
|
||||
name: 'unstable minors'
|
||||
continue-on-error: true
|
||||
if: ${{ !github.head_ref || !startsWith(github.head_ref, 'renovate') }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix: ${{ fromJson(needs.matrix.outputs.unstable) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/run@main
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
command: 'tests-only'
|
||||
cache-node-modules-key: node_modules-${{ github.workflow }}-${{ github.action }}-${{ github.run_id }}
|
||||
skip-ls-check: true
|
||||
|
||||
node:
|
||||
name: 'node 0.x'
|
||||
needs: [stable, unstable]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: 'echo tests completed'
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
name: Automatic Rebase
|
||||
|
||||
on: [pull_request_target]
|
||||
|
||||
jobs:
|
||||
_:
|
||||
name: "Automatic Rebase"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: ljharb/rebase@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
name: Require “Allow Edits”
|
||||
|
||||
on: [pull_request_target]
|
||||
|
||||
jobs:
|
||||
_:
|
||||
name: "Require “Allow Edits”"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: ljharb/require-allow-edits@main
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"all": true,
|
||||
"check-coverage": false,
|
||||
"reporter": ["text-summary", "text", "html", "json"],
|
||||
"lines": 86,
|
||||
"statements": 85.93,
|
||||
"functions": 82.43,
|
||||
"branches": 76.06,
|
||||
"exclude": [
|
||||
"coverage",
|
||||
"test"
|
||||
]
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [v2.2.0](https://github.com/inspect-js/is-core-module/compare/v2.1.0...v2.2.0) - 2020-11-26
|
||||
|
||||
### Commits
|
||||
|
||||
- [Tests] migrate tests to Github Actions [`c919f57`](https://github.com/inspect-js/is-core-module/commit/c919f573c0a92d10a0acad0b650b5aecb033d426)
|
||||
- [patch] `core.json`: %s/ /\t/g [`db3f685`](https://github.com/inspect-js/is-core-module/commit/db3f68581f53e73cc09cd675955eb1bdd6a5a39b)
|
||||
- [Tests] run `nyc` on all tests [`b2f925f`](https://github.com/inspect-js/is-core-module/commit/b2f925f8866f210ef441f39fcc8cc42692ab89b1)
|
||||
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`; add `safe-publish-latest` [`89f02a2`](https://github.com/inspect-js/is-core-module/commit/89f02a2b4162246dea303a6ee31bb9a550b05c72)
|
||||
- [New] add `path/posix`, `path/win32`, `util/types` [`77f94f1`](https://github.com/inspect-js/is-core-module/commit/77f94f1e90ffd7c0be2a3f1aa8574ebf7fd981b3)
|
||||
|
||||
## [v2.1.0](https://github.com/inspect-js/is-core-module/compare/v2.0.0...v2.1.0) - 2020-11-04
|
||||
|
||||
### Commits
|
||||
|
||||
- [Dev Deps] update `eslint` [`5e0034e`](https://github.com/inspect-js/is-core-module/commit/5e0034eae57c09c8f1bd769f502486a00f56c6e4)
|
||||
- [New] Add `diagnostics_channel` [`c2d83d0`](https://github.com/inspect-js/is-core-module/commit/c2d83d0a0225a1a658945d9bab7036ea347d29ec)
|
||||
|
||||
## [v2.0.0](https://github.com/inspect-js/is-core-module/compare/v1.0.2...v2.0.0) - 2020-09-29
|
||||
|
||||
### Commits
|
||||
|
||||
- v2 implementation [`865aeb5`](https://github.com/inspect-js/is-core-module/commit/865aeb5ca0e90248a3dfff5d7622e4751fdeb9cd)
|
||||
- Only apps should have lockfiles [`5a5e660`](https://github.com/inspect-js/is-core-module/commit/5a5e660d568e37eb44e17fb1ebb12a105205fc2b)
|
||||
- Initial commit for v2 [`5a51524`](https://github.com/inspect-js/is-core-module/commit/5a51524e06f92adece5fbb138c69b7b9748a2348)
|
||||
- Tests [`116eae4`](https://github.com/inspect-js/is-core-module/commit/116eae4fccd01bc72c1fd3cc4b7561c387afc496)
|
||||
- [meta] add `auto-changelog` [`c24388b`](https://github.com/inspect-js/is-core-module/commit/c24388bee828d223040519d1f5b226ca35beee63)
|
||||
- [actions] add "Automatic Rebase" and "require allow edits" actions [`34292db`](https://github.com/inspect-js/is-core-module/commit/34292dbcbadae0868aff03c22dbd8b7b8a11558a)
|
||||
- [Tests] add `npm run lint` [`4f9eeee`](https://github.com/inspect-js/is-core-module/commit/4f9eeee7ddff10698bbf528620f4dc8d4fa3e697)
|
||||
- [readme] fix travis badges, https all URLs [`e516a73`](https://github.com/inspect-js/is-core-module/commit/e516a73b0dccce20938c432b1ba512eae8eff9e9)
|
||||
- [meta] create FUNDING.yml [`1aabebc`](https://github.com/inspect-js/is-core-module/commit/1aabebca98d01f8a04e46bc2e2520fa93cf21ac6)
|
||||
- [Fix] `domain`: domain landed sometime > v0.7.7 and <= v0.7.12 [`2df7d37`](https://github.com/inspect-js/is-core-module/commit/2df7d37595d41b15eeada732b706b926c2771655)
|
||||
- [Fix] `sys`: worked in 0.6, not 0.7, and 0.8+ [`a75c134`](https://github.com/inspect-js/is-core-module/commit/a75c134229e1e9441801f6b73f6a52489346eb65)
|
||||
|
||||
## [v1.0.2](https://github.com/inspect-js/is-core-module/compare/v1.0.1...v1.0.2) - 2014-09-28
|
||||
|
||||
### Commits
|
||||
|
||||
- simpler [`66fe90f`](https://github.com/inspect-js/is-core-module/commit/66fe90f9771581b9adc0c3900baa52c21b5baea2)
|
||||
|
||||
## [v1.0.1](https://github.com/inspect-js/is-core-module/compare/v1.0.0...v1.0.1) - 2014-09-28
|
||||
|
||||
### Commits
|
||||
|
||||
- remove stupid [`f21f906`](https://github.com/inspect-js/is-core-module/commit/f21f906f882c2bd656a5fc5ed6fbe48ddaffb2ac)
|
||||
- update readme [`1eff0ec`](https://github.com/inspect-js/is-core-module/commit/1eff0ec69798d1ec65771552d1562911e90a8027)
|
||||
|
||||
## v1.0.0 - 2014-09-28
|
||||
|
||||
### Commits
|
||||
|
||||
- init [`48e5e76`](https://github.com/inspect-js/is-core-module/commit/48e5e76cac378fddb8c1f7d4055b8dfc943d6b96)
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Dave Justice
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
# is-core-module <sup>[![Version Badge][2]][1]</sup>
|
||||
|
||||
[![Build Status][3]][4]
|
||||
[![dependency status][5]][6]
|
||||
[![dev dependency status][7]][8]
|
||||
[![License][license-image]][license-url]
|
||||
[![Downloads][downloads-image]][downloads-url]
|
||||
|
||||
[![npm badge][11]][1]
|
||||
|
||||
Is this specifier a node.js core module? Optionally provide a node version to check; defaults to the current node version.
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
var isCore = require('is-core-module');
|
||||
var assert = require('assert');
|
||||
assert(isCore('fs'));
|
||||
assert(!isCore('butts'));
|
||||
```
|
||||
|
||||
## Tests
|
||||
Clone the repo, `npm install`, and run `npm test`
|
||||
|
||||
[1]: https://npmjs.org/package/is-core-module
|
||||
[2]: https://versionbadg.es/inspect-js/is-core-module.svg
|
||||
[3]: https://travis-ci.com/inspect-js/is-core-module.svg
|
||||
[4]: https://travis-ci.com/inspect-js/is-core-module
|
||||
[5]: https://david-dm.org/inspect-js/is-core-module.svg
|
||||
[6]: https://david-dm.org/inspect-js/is-core-module
|
||||
[7]: https://david-dm.org/inspect-js/is-core-module/dev-status.svg
|
||||
[8]: https://david-dm.org/inspect-js/is-core-module#info=devDependencies
|
||||
[11]: https://nodei.co/npm/is-core-module.png?downloads=true&stars=true
|
||||
[license-image]: https://img.shields.io/npm/l/is-core-module.svg
|
||||
[license-url]: LICENSE
|
||||
[downloads-image]: https://img.shields.io/npm/dm/is-core-module.svg
|
||||
[downloads-url]: https://npm-stat.com/charts.html?package=is-core-module
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"assert": true,
|
||||
"assert/strict": ">= 15",
|
||||
"async_hooks": ">= 8",
|
||||
"buffer_ieee754": "< 0.9.7",
|
||||
"buffer": true,
|
||||
"child_process": true,
|
||||
"cluster": true,
|
||||
"console": true,
|
||||
"constants": true,
|
||||
"crypto": true,
|
||||
"_debug_agent": ">= 1 && < 8",
|
||||
"_debugger": "< 8",
|
||||
"dgram": true,
|
||||
"diagnostics_channel": ">= 15.1",
|
||||
"dns": true,
|
||||
"dns/promises": ">= 15",
|
||||
"domain": ">= 0.7.12",
|
||||
"events": true,
|
||||
"freelist": "< 6",
|
||||
"fs": true,
|
||||
"fs/promises": [">= 10 && < 10.1", ">= 14"],
|
||||
"_http_agent": ">= 0.11.1",
|
||||
"_http_client": ">= 0.11.1",
|
||||
"_http_common": ">= 0.11.1",
|
||||
"_http_incoming": ">= 0.11.1",
|
||||
"_http_outgoing": ">= 0.11.1",
|
||||
"_http_server": ">= 0.11.1",
|
||||
"http": true,
|
||||
"http2": ">= 8.8",
|
||||
"https": true,
|
||||
"inspector": ">= 8.0.0",
|
||||
"_linklist": "< 8",
|
||||
"module": true,
|
||||
"net": true,
|
||||
"node-inspect/lib/_inspect": ">= 7.6.0 && < 12",
|
||||
"node-inspect/lib/internal/inspect_client": ">= 7.6.0 && < 12",
|
||||
"node-inspect/lib/internal/inspect_repl": ">= 7.6.0 && < 12",
|
||||
"os": true,
|
||||
"path": true,
|
||||
"path/posix": ">= 15.3",
|
||||
"path/win32": ">= 15.3",
|
||||
"perf_hooks": ">= 8.5",
|
||||
"process": ">= 1",
|
||||
"punycode": true,
|
||||
"querystring": true,
|
||||
"readline": true,
|
||||
"repl": true,
|
||||
"smalloc": ">= 0.11.5 && < 3",
|
||||
"_stream_duplex": ">= 0.9.4",
|
||||
"_stream_transform": ">= 0.9.4",
|
||||
"_stream_wrap": ">= 1.4.1",
|
||||
"_stream_passthrough": ">= 0.9.4",
|
||||
"_stream_readable": ">= 0.9.4",
|
||||
"_stream_writable": ">= 0.9.4",
|
||||
"stream": true,
|
||||
"stream/promises": ">= 15",
|
||||
"string_decoder": true,
|
||||
"sys": [">= 0.6 && < 0.7", ">= 0.8"],
|
||||
"timers": true,
|
||||
"timers/promises": ">= 15",
|
||||
"_tls_common": ">= 0.11.13",
|
||||
"_tls_legacy": ">= 0.11.3 && < 10",
|
||||
"_tls_wrap": ">= 0.11.3",
|
||||
"tls": true,
|
||||
"trace_events": ">= 10",
|
||||
"tty": true,
|
||||
"url": true,
|
||||
"util": true,
|
||||
"util/types": ">= 15.3",
|
||||
"v8/tools/arguments": ">= 10 && < 12",
|
||||
"v8/tools/codemap": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
|
||||
"v8/tools/consarray": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
|
||||
"v8/tools/csvparser": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
|
||||
"v8/tools/logreader": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
|
||||
"v8/tools/profile_view": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
|
||||
"v8/tools/splaytree": [">= 4.4.0 && < 5", ">= 5.2.0 && < 12"],
|
||||
"v8": ">= 1",
|
||||
"vm": true,
|
||||
"wasi": ">= 13.4 && < 13.5",
|
||||
"worker_threads": ">= 11.7",
|
||||
"zlib": true
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
'use strict';
|
||||
|
||||
var has = require('has');
|
||||
|
||||
function specifierIncluded(current, specifier) {
|
||||
var nodeParts = current.split('.');
|
||||
var parts = specifier.split(' ');
|
||||
var op = parts.length > 1 ? parts[0] : '=';
|
||||
var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.');
|
||||
|
||||
for (var i = 0; i < 3; ++i) {
|
||||
var cur = parseInt(nodeParts[i] || 0, 10);
|
||||
var ver = parseInt(versionParts[i] || 0, 10);
|
||||
if (cur === ver) {
|
||||
continue; // eslint-disable-line no-restricted-syntax, no-continue
|
||||
}
|
||||
if (op === '<') {
|
||||
return cur < ver;
|
||||
}
|
||||
if (op === '>=') {
|
||||
return cur >= ver;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return op === '>=';
|
||||
}
|
||||
|
||||
function matchesRange(current, range) {
|
||||
var specifiers = range.split(/ ?&& ?/);
|
||||
if (specifiers.length === 0) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < specifiers.length; ++i) {
|
||||
if (!specifierIncluded(current, specifiers[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function versionIncluded(nodeVersion, specifierValue) {
|
||||
if (typeof specifierValue === 'boolean') {
|
||||
return specifierValue;
|
||||
}
|
||||
|
||||
var current = typeof nodeVersion === 'undefined'
|
||||
? process.versions && process.versions.node && process.versions.node
|
||||
: nodeVersion;
|
||||
|
||||
if (typeof current !== 'string') {
|
||||
throw new TypeError(typeof nodeVersion === 'undefined' ? 'Unable to determine current node version' : 'If provided, a valid node version is required');
|
||||
}
|
||||
|
||||
if (specifierValue && typeof specifierValue === 'object') {
|
||||
for (var i = 0; i < specifierValue.length; ++i) {
|
||||
if (matchesRange(current, specifierValue[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return matchesRange(current, specifierValue);
|
||||
}
|
||||
|
||||
var data = require('./core.json');
|
||||
|
||||
module.exports = function isCore(x, nodeVersion) {
|
||||
return has(data, x) && versionIncluded(nodeVersion, data[x]);
|
||||
};
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "is-core-module",
|
||||
"version": "2.2.0",
|
||||
"description": "Is this specifier a node.js core module?",
|
||||
"main": "index.js",
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./index.js"
|
||||
],
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublish": "safe-publish-latest",
|
||||
"lint": "eslint .",
|
||||
"pretest": "npm run lint",
|
||||
"tests-only": "tape 'test/**/*.js'",
|
||||
"test": "nyc npm run tests-only",
|
||||
"posttest": "aud --production",
|
||||
"version": "auto-changelog && git add CHANGELOG.md",
|
||||
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/inspect-js/is-core-module.git"
|
||||
},
|
||||
"keywords": [
|
||||
"core",
|
||||
"modules",
|
||||
"module",
|
||||
"npm",
|
||||
"node",
|
||||
"dependencies"
|
||||
],
|
||||
"author": "Jordan Harband <ljharb@gmail.com>",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
},
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/inspect-js/is-core-module/issues"
|
||||
},
|
||||
"homepage": "https://github.com/inspect-js/is-core-module",
|
||||
"dependencies": {
|
||||
"has": "^1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ljharb/eslint-config": "^17.3.0",
|
||||
"aud": "^1.1.3",
|
||||
"auto-changelog": "^2.2.1",
|
||||
"eslint": "^7.14.0",
|
||||
"nyc": "^10.3.2",
|
||||
"safe-publish-latest": "^1.1.4",
|
||||
"tape": "^5.0.1"
|
||||
},
|
||||
"auto-changelog": {
|
||||
"output": "CHANGELOG.md",
|
||||
"template": "keepachangelog",
|
||||
"unreleased": false,
|
||||
"commitLimit": false,
|
||||
"backfillLimit": false,
|
||||
"hideCredit": true
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var keys = require('object-keys');
|
||||
var isCore = require('../');
|
||||
var data = require('../core.json');
|
||||
|
||||
test('core modules', function (t) {
|
||||
t.test('isCore()', function (st) {
|
||||
st.ok(isCore('fs'));
|
||||
st.ok(isCore('net'));
|
||||
st.ok(isCore('http'));
|
||||
|
||||
st.ok(!isCore('seq'));
|
||||
st.ok(!isCore('../'));
|
||||
|
||||
st.ok(!isCore('toString'));
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('core list', function (st) {
|
||||
var cores = keys(data);
|
||||
st.plan(cores.length);
|
||||
|
||||
for (var i = 0; i < cores.length; ++i) {
|
||||
var mod = cores[i];
|
||||
var requireFunc = function () { require(mod); }; // eslint-disable-line no-loop-func
|
||||
if (isCore(mod)) {
|
||||
st.doesNotThrow(requireFunc, mod + ' supported; requiring does not throw');
|
||||
} else {
|
||||
st['throws'](requireFunc, mod + ' not supported; requiring throws');
|
||||
}
|
||||
}
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('core via repl module', { skip: !data.repl }, function (st) {
|
||||
var libs = require('repl')._builtinLibs; // eslint-disable-line no-underscore-dangle
|
||||
if (!libs) {
|
||||
st.skip('module.builtinModules does not exist');
|
||||
} else {
|
||||
for (var i = 0; i < libs.length; ++i) {
|
||||
var mod = libs[i];
|
||||
st.ok(data[mod], mod + ' is a core module');
|
||||
st.doesNotThrow(
|
||||
function () { require(mod); }, // eslint-disable-line no-loop-func
|
||||
'requiring ' + mod + ' does not throw'
|
||||
);
|
||||
}
|
||||
}
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('core via builtinModules list', { skip: !data.module }, function (st) {
|
||||
var libs = require('module').builtinModules;
|
||||
if (!libs) {
|
||||
st.skip('module.builtinModules does not exist');
|
||||
} else {
|
||||
var excludeList = [
|
||||
'_debug_agent',
|
||||
'v8/tools/tickprocessor-driver',
|
||||
'v8/tools/SourceMap',
|
||||
'v8/tools/tickprocessor',
|
||||
'v8/tools/profile'
|
||||
];
|
||||
for (var i = 0; i < libs.length; ++i) {
|
||||
var mod = libs[i];
|
||||
if (excludeList.indexOf(mod) === -1) {
|
||||
st.ok(data[mod], mod + ' is a core module');
|
||||
st.doesNotThrow(
|
||||
function () { require(mod); }, // eslint-disable-line no-loop-func
|
||||
'requiring ' + mod + ' does not throw'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "libnpmfund",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
@@ -47,6 +47,6 @@
|
||||
"tap": "^14.10.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"@npmcli/arborist": "^0.0.33 || ^1.x"
|
||||
"@npmcli/arborist": "^2.0.0"
|
||||
}
|
||||
}
|
||||
+1
@@ -15,6 +15,7 @@ function searchStream (query, opts = {}) {
|
||||
quality: 0.65,
|
||||
popularity: 0.98,
|
||||
maintenance: 0.5,
|
||||
...opts.opts, // this is to support the cli's --searchopts parameter
|
||||
...opts
|
||||
}
|
||||
|
||||
|
||||
+6
-7
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "libnpmsearch",
|
||||
"version": "3.0.1",
|
||||
"version": "3.1.0",
|
||||
"description": "Programmatic API for searching in npm and compatible registries.",
|
||||
"author": "Kat Marchán <kzm@sykosomatic.org>",
|
||||
"files": [
|
||||
@@ -15,10 +15,10 @@
|
||||
],
|
||||
"license": "ISC",
|
||||
"scripts": {
|
||||
"prerelease": "npm t",
|
||||
"release": "standard-version -s",
|
||||
"postrelease": "npm publish && git push --follow-tags",
|
||||
"pretest": "standard",
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"prepublishOnly": "git push origin --follow-tags",
|
||||
"posttest": "standard",
|
||||
"test": "tap"
|
||||
},
|
||||
"tap": {
|
||||
@@ -27,8 +27,7 @@
|
||||
"devDependencies": {
|
||||
"nock": "^9.6.1",
|
||||
"standard": "^12.0.0",
|
||||
"standard-version": "*",
|
||||
"tap": "^14.10.6"
|
||||
"tap": "^14.11.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
+24
-28
@@ -38,7 +38,7 @@ function getAgent (uri, opts) {
|
||||
`cert:${(isHttps && opts.cert) || '>no-cert<'}`,
|
||||
`key:${(isHttps && opts.key) || '>no-key<'}`,
|
||||
`timeout:${agentTimeout}`,
|
||||
`maxSockets:${agentMaxSockets}`
|
||||
`maxSockets:${agentMaxSockets}`,
|
||||
].join(':')
|
||||
|
||||
if (opts.agent != null) { // `agent: false` has special behavior!
|
||||
@@ -48,20 +48,18 @@ function getAgent (uri, opts) {
|
||||
// keep alive in AWS lambda makes no sense
|
||||
const lambdaAgent = !isLambda ? null
|
||||
: isHttps ? require('https').globalAgent
|
||||
: require('http').globalAgent
|
||||
: require('http').globalAgent
|
||||
|
||||
if (isLambda && !pxuri) {
|
||||
if (isLambda && !pxuri)
|
||||
return lambdaAgent
|
||||
}
|
||||
|
||||
if (AGENT_CACHE.peek(key)) {
|
||||
if (AGENT_CACHE.peek(key))
|
||||
return AGENT_CACHE.get(key)
|
||||
}
|
||||
|
||||
if (pxuri) {
|
||||
const pxopts = isLambda ? {
|
||||
...opts,
|
||||
agent: lambdaAgent
|
||||
agent: lambdaAgent,
|
||||
} : opts
|
||||
const proxy = getProxy(pxuri, pxopts, isHttps)
|
||||
AGENT_CACHE.set(key, proxy)
|
||||
@@ -80,11 +78,11 @@ function getAgent (uri, opts) {
|
||||
key: opts.key,
|
||||
localAddress: opts.localAddress,
|
||||
rejectUnauthorized: opts.strictSSL,
|
||||
timeout: agentTimeout
|
||||
timeout: agentTimeout,
|
||||
}) : new HttpAgent({
|
||||
maxSockets: agentMaxSockets,
|
||||
localAddress: opts.localAddress,
|
||||
timeout: agentTimeout
|
||||
timeout: agentTimeout,
|
||||
})
|
||||
AGENT_CACHE.set(key, agent)
|
||||
return agent
|
||||
@@ -93,16 +91,16 @@ function getAgent (uri, opts) {
|
||||
function checkNoProxy (uri, opts) {
|
||||
const host = new url.URL(uri).hostname.split('.').reverse()
|
||||
let noproxy = (opts.noProxy || getProcessEnv('no_proxy'))
|
||||
if (typeof noproxy === 'string') {
|
||||
if (typeof noproxy === 'string')
|
||||
noproxy = noproxy.split(/\s*,\s*/g)
|
||||
}
|
||||
|
||||
return noproxy && noproxy.some(no => {
|
||||
const noParts = no.split('.').filter(x => x).reverse()
|
||||
if (!noParts.length) { return false }
|
||||
if (!noParts.length)
|
||||
return false
|
||||
for (let i = 0; i < noParts.length; i++) {
|
||||
if (host[i] !== noParts[i]) {
|
||||
if (host[i] !== noParts[i])
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
@@ -111,9 +109,8 @@ function checkNoProxy (uri, opts) {
|
||||
module.exports.getProcessEnv = getProcessEnv
|
||||
|
||||
function getProcessEnv (env) {
|
||||
if (!env) {
|
||||
if (!env)
|
||||
return
|
||||
}
|
||||
|
||||
let value
|
||||
|
||||
@@ -122,7 +119,8 @@ function getProcessEnv (env) {
|
||||
value = process.env[e] ||
|
||||
process.env[e.toUpperCase()] ||
|
||||
process.env[e.toLowerCase()]
|
||||
if (typeof value !== 'undefined') { break }
|
||||
if (typeof value !== 'undefined')
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +146,8 @@ function getProxyUri (uri, opts) {
|
||||
protocol === 'http:' &&
|
||||
getProcessEnv(['https_proxy', 'http_proxy', 'proxy'])
|
||||
)
|
||||
if (!proxy) { return null }
|
||||
if (!proxy)
|
||||
return null
|
||||
|
||||
const parsedProxy = (typeof proxy === 'string') ? new url.URL(proxy) : proxy
|
||||
|
||||
@@ -157,8 +156,8 @@ function getProxyUri (uri, opts) {
|
||||
|
||||
const getAuth = u =>
|
||||
u.username && u.password ? `${u.username}:${u.password}`
|
||||
: u.username ? u.username
|
||||
: null
|
||||
: u.username ? u.username
|
||||
: null
|
||||
|
||||
const getPath = u => u.pathname + u.search + u.hash
|
||||
|
||||
@@ -179,34 +178,31 @@ function getProxy (proxyUrl, opts, isHttps) {
|
||||
timeout: getAgentTimeout(opts.timeout),
|
||||
localAddress: opts.localAddress,
|
||||
maxSockets: getMaxSockets(opts.maxSockets),
|
||||
rejectUnauthorized: opts.strictSSL
|
||||
rejectUnauthorized: opts.strictSSL,
|
||||
}
|
||||
|
||||
if (proxyUrl.protocol === 'http:' || proxyUrl.protocol === 'https:') {
|
||||
if (!isHttps) {
|
||||
if (!HttpProxyAgent) {
|
||||
if (!HttpProxyAgent)
|
||||
HttpProxyAgent = require('http-proxy-agent')
|
||||
}
|
||||
|
||||
return new HttpProxyAgent(popts)
|
||||
} else {
|
||||
if (!HttpsProxyAgent) {
|
||||
if (!HttpsProxyAgent)
|
||||
HttpsProxyAgent = require('https-proxy-agent')
|
||||
}
|
||||
|
||||
return new HttpsProxyAgent(popts)
|
||||
}
|
||||
} else if (proxyUrl.protocol.startsWith('socks')) {
|
||||
if (!SocksProxyAgent) {
|
||||
if (!SocksProxyAgent)
|
||||
SocksProxyAgent = require('socks-proxy-agent')
|
||||
}
|
||||
|
||||
return new SocksProxyAgent(popts)
|
||||
} else {
|
||||
throw Object.assign(
|
||||
new Error(`unsupported proxy protocol: '${proxyUrl.protocol}'`),
|
||||
{
|
||||
url: proxyUrl.href
|
||||
url: proxyUrl.href,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+44
-19
@@ -12,6 +12,20 @@ const MinipassPipeline = require('minipass-pipeline')
|
||||
|
||||
const MAX_MEM_SIZE = 5 * 1024 * 1024 // 5MB
|
||||
|
||||
// some headers should never be stored in the cache, either because
|
||||
// they're a security footgun to leave lying around, or because we
|
||||
// just don't need them taking up space.
|
||||
// set to undefined so they're omitted from the JSON.stringify
|
||||
const pruneHeaders = {
|
||||
authorization: undefined,
|
||||
'npm-session': undefined,
|
||||
'set-cookie': undefined,
|
||||
'cf-ray': undefined,
|
||||
'cf-cache-status': undefined,
|
||||
'cf-request-id': undefined,
|
||||
'x-fetch-attempts': undefined,
|
||||
}
|
||||
|
||||
function cacheKey (req) {
|
||||
const parsed = new url.URL(req.url)
|
||||
return `make-fetch-happen:request-cache:${
|
||||
@@ -20,7 +34,8 @@ function cacheKey (req) {
|
||||
slashes: true,
|
||||
port: parsed.port,
|
||||
hostname: parsed.hostname,
|
||||
pathname: parsed.pathname
|
||||
pathname: parsed.pathname,
|
||||
search: parsed.search,
|
||||
})
|
||||
}`
|
||||
}
|
||||
@@ -35,6 +50,11 @@ module.exports = class Cache {
|
||||
this.Promise = (opts && opts.Promise) || Promise
|
||||
}
|
||||
|
||||
static get pruneHeaders () {
|
||||
// exposed for testing, not modifiable
|
||||
return { ...pruneHeaders }
|
||||
}
|
||||
|
||||
// Returns a Promise that resolves to the response associated with the first
|
||||
// matching request in the Cache object.
|
||||
match (req, opts) {
|
||||
@@ -49,7 +69,7 @@ module.exports = class Cache {
|
||||
reqHeaders: new fetch.Headers(info.metadata.reqHeaders),
|
||||
resHeaders: new fetch.Headers(info.metadata.resHeaders),
|
||||
cacheIntegrity: info.integrity,
|
||||
integrity: opts && opts.integrity
|
||||
integrity: opts && opts.integrity,
|
||||
})) {
|
||||
const resHeaders = new fetch.Headers(info.metadata.resHeaders)
|
||||
addCacheHeaders(resHeaders, this._path, key, info.integrity, info.time)
|
||||
@@ -57,7 +77,7 @@ module.exports = class Cache {
|
||||
return new fetch.Response(null, {
|
||||
url: req.url,
|
||||
headers: resHeaders,
|
||||
status: 200
|
||||
status: 200,
|
||||
})
|
||||
}
|
||||
const cachePath = this._path
|
||||
@@ -70,7 +90,7 @@ module.exports = class Cache {
|
||||
opts.memoize !== false && fitInMemory
|
||||
? () => {
|
||||
const c = cacache.get.stream.byDigest(cachePath, info.integrity, {
|
||||
memoize: opts.memoize
|
||||
memoize: opts.memoize,
|
||||
})
|
||||
c.on('error', /* istanbul ignore next */ err => {
|
||||
body.emit('error', err)
|
||||
@@ -80,7 +100,7 @@ module.exports = class Cache {
|
||||
: () => {
|
||||
removeOnResume()
|
||||
cacache.get.byDigest(cachePath, info.integrity, {
|
||||
memoize: opts.memoize
|
||||
memoize: opts.memoize,
|
||||
})
|
||||
.then(data => body.end(data))
|
||||
.catch(/* istanbul ignore next */ err => {
|
||||
@@ -93,7 +113,7 @@ module.exports = class Cache {
|
||||
url: req.url,
|
||||
headers: resHeaders,
|
||||
status: 200,
|
||||
size: info.size
|
||||
size: info.size,
|
||||
}))
|
||||
}
|
||||
})
|
||||
@@ -109,11 +129,17 @@ module.exports = class Cache {
|
||||
algorithms: opts.algorithms,
|
||||
metadata: {
|
||||
url: req.url,
|
||||
reqHeaders: req.headers.raw(),
|
||||
resHeaders: response.headers.raw()
|
||||
reqHeaders: {
|
||||
...req.headers.raw(),
|
||||
...pruneHeaders,
|
||||
},
|
||||
resHeaders: {
|
||||
...response.headers.raw(),
|
||||
...pruneHeaders,
|
||||
},
|
||||
},
|
||||
size,
|
||||
memoize: fitInMemory && opts.memoize
|
||||
memoize: fitInMemory && opts.memoize,
|
||||
}
|
||||
if (req.method === 'HEAD' || response.status === 304) {
|
||||
// Update metadata without writing
|
||||
@@ -141,7 +167,7 @@ module.exports = class Cache {
|
||||
const newBody = new MinipassPipeline(new MinipassFlush({
|
||||
flush () {
|
||||
return cacheWritePromise
|
||||
}
|
||||
},
|
||||
}))
|
||||
|
||||
let cacheWriteResolve, cacheWriteReject
|
||||
@@ -184,11 +210,11 @@ module.exports = class Cache {
|
||||
'delete' (req, opts) {
|
||||
opts = opts || {}
|
||||
if (typeof opts.memoize === 'object') {
|
||||
if (opts.memoize.reset) {
|
||||
if (opts.memoize.reset)
|
||||
opts.memoize.reset()
|
||||
} else if (opts.memoize.clear) {
|
||||
else if (opts.memoize.clear)
|
||||
opts.memoize.clear()
|
||||
} else {
|
||||
else {
|
||||
Object.keys(opts.memoize).forEach(k => {
|
||||
opts.memoize[k] = null
|
||||
})
|
||||
@@ -208,20 +234,19 @@ function matchDetails (req, cached) {
|
||||
const vary = cached.resHeaders.get('Vary')
|
||||
// https://tools.ietf.org/html/rfc7234#section-4.1
|
||||
if (vary) {
|
||||
if (vary.match(/\*/)) {
|
||||
if (vary.match(/\*/))
|
||||
return false
|
||||
} else {
|
||||
else {
|
||||
const fieldsMatch = vary.split(/\s*,\s*/).every(field => {
|
||||
return cached.reqHeaders.get(field) === req.headers.get(field)
|
||||
})
|
||||
if (!fieldsMatch) {
|
||||
if (!fieldsMatch)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cached.integrity) {
|
||||
if (cached.integrity)
|
||||
return ssri.parse(cached.integrity).match(cached.cacheIntegrity)
|
||||
}
|
||||
|
||||
reqUrl.hash = null
|
||||
cacheUrl.hash = null
|
||||
return url.format(reqUrl) === url.format(cacheUrl)
|
||||
|
||||
+34
-45
@@ -22,13 +22,13 @@ const RETRY_ERRORS = [
|
||||
'ECONNRESET', // remote socket closed on us
|
||||
'ECONNREFUSED', // remote host refused to open connection
|
||||
'EADDRINUSE', // failed to bind to a local port (proxy?)
|
||||
'ETIMEDOUT' // someone in the transaction is WAY TOO SLOW
|
||||
'ETIMEDOUT', // someone in the transaction is WAY TOO SLOW
|
||||
// Known codes we do NOT retry on:
|
||||
// ENOTFOUND (getaddrinfo failure. Either bad hostname, or offline)
|
||||
]
|
||||
|
||||
const RETRY_TYPES = [
|
||||
'request-timeout'
|
||||
'request-timeout',
|
||||
]
|
||||
|
||||
// https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
|
||||
@@ -56,16 +56,15 @@ function cacheDelete (uri, opts) {
|
||||
if (opts.cacheManager) {
|
||||
const req = new fetch.Request(uri, {
|
||||
method: opts.method,
|
||||
headers: opts.headers
|
||||
headers: opts.headers,
|
||||
})
|
||||
return opts.cacheManager.delete(req, opts)
|
||||
}
|
||||
}
|
||||
|
||||
function initializeSsri () {
|
||||
if (!ssri) {
|
||||
if (!ssri)
|
||||
ssri = require('ssri')
|
||||
}
|
||||
}
|
||||
|
||||
function cachingFetch (uri, _opts) {
|
||||
@@ -90,7 +89,7 @@ function cachingFetch (uri, _opts) {
|
||||
if (isCachable) {
|
||||
const req = new fetch.Request(uri, {
|
||||
method: opts.method,
|
||||
headers: opts.headers
|
||||
headers: opts.headers,
|
||||
})
|
||||
|
||||
return opts.cacheManager.match(req, opts).then(res => {
|
||||
@@ -110,13 +109,11 @@ function cachingFetch (uri, _opts) {
|
||||
res.headers.delete('Warning')
|
||||
}
|
||||
|
||||
if (opts.cache === 'default' && !isStale(req, res)) {
|
||||
if (opts.cache === 'default' && !isStale(req, res))
|
||||
return res
|
||||
}
|
||||
|
||||
if (opts.cache === 'default' || opts.cache === 'no-cache') {
|
||||
if (opts.cache === 'default' || opts.cache === 'no-cache')
|
||||
return conditionalFetch(req, res, opts)
|
||||
}
|
||||
|
||||
if (opts.cache === 'force-cache' || opts.cache === 'only-if-cached') {
|
||||
// 112 Disconnected operation
|
||||
@@ -150,7 +147,7 @@ function isStale (req, res) {
|
||||
const _req = {
|
||||
url: req.url,
|
||||
method: req.method,
|
||||
headers: iterableToObject(req.headers)
|
||||
headers: iterableToObject(req.headers),
|
||||
}
|
||||
|
||||
const policy = makePolicy(req, res)
|
||||
@@ -182,7 +179,7 @@ function conditionalFetch (req, cachedRes, opts) {
|
||||
const _req = {
|
||||
url: req.url,
|
||||
method: req.method,
|
||||
headers: Object.assign({}, opts.headers || {})
|
||||
headers: Object.assign({}, opts.headers || {}),
|
||||
}
|
||||
|
||||
const policy = makePolicy(req, cachedRes)
|
||||
@@ -192,7 +189,7 @@ function conditionalFetch (req, cachedRes, opts) {
|
||||
.then(condRes => {
|
||||
const revalidatedPolicy = policy.revalidatedPolicy(_req, {
|
||||
status: condRes.status,
|
||||
headers: iterableToObject(condRes.headers)
|
||||
headers: iterableToObject(condRes.headers),
|
||||
})
|
||||
|
||||
if (condRes.status >= 500 && !mustRevalidate(cachedRes)) {
|
||||
@@ -216,12 +213,12 @@ function conditionalFetch (req, cachedRes, opts) {
|
||||
const newHeaders = revalidatedPolicy.policy.responseHeaders()
|
||||
const toDelete = [...newRes.headers.keys()]
|
||||
.filter(k => !newHeaders[k])
|
||||
for (const key of toDelete) {
|
||||
for (const key of toDelete)
|
||||
newRes.headers.delete(key)
|
||||
}
|
||||
for (const [key, val] of Object.entries(newHeaders)) {
|
||||
|
||||
for (const [key, val] of Object.entries(newHeaders))
|
||||
newRes.headers.set(key, val)
|
||||
}
|
||||
|
||||
return newRes
|
||||
})
|
||||
}
|
||||
@@ -230,9 +227,9 @@ function conditionalFetch (req, cachedRes, opts) {
|
||||
})
|
||||
.then(res => res)
|
||||
.catch(err => {
|
||||
if (mustRevalidate(cachedRes)) {
|
||||
if (mustRevalidate(cachedRes))
|
||||
throw err
|
||||
} else {
|
||||
else {
|
||||
// 111 Revalidation failed
|
||||
// MUST be included if a cache returns a stale response because an
|
||||
// attempt to revalidate the response failed, due to an inability to
|
||||
@@ -256,12 +253,12 @@ function conditionalFetch (req, cachedRes, opts) {
|
||||
}
|
||||
|
||||
function remoteFetchHandleIntegrity (res, integrity) {
|
||||
if (res.status !== 200) {
|
||||
if (res.status !== 200)
|
||||
return res // Error responses aren't subject to integrity checks.
|
||||
}
|
||||
|
||||
const oldBod = res.body
|
||||
const newBod = ssri.integrityStream({
|
||||
integrity
|
||||
integrity,
|
||||
})
|
||||
return new fetch.Response(new MinipassPipeline(oldBod, newBod), res)
|
||||
}
|
||||
@@ -271,12 +268,11 @@ function remoteFetch (uri, opts) {
|
||||
const headers = opts.headers instanceof fetch.Headers
|
||||
? opts.headers
|
||||
: new fetch.Headers(opts.headers)
|
||||
if (!headers.get('connection')) {
|
||||
if (!headers.get('connection'))
|
||||
headers.set('connection', agent ? 'keep-alive' : 'close')
|
||||
}
|
||||
if (!headers.get('user-agent')) {
|
||||
|
||||
if (!headers.get('user-agent'))
|
||||
headers.set('user-agent', USER_AGENT)
|
||||
}
|
||||
|
||||
const reqOpts = {
|
||||
agent,
|
||||
@@ -288,7 +284,7 @@ function remoteFetch (uri, opts) {
|
||||
redirect: 'manual',
|
||||
size: opts.size,
|
||||
counter: opts.counter,
|
||||
timeout: opts.timeout
|
||||
timeout: opts.timeout,
|
||||
}
|
||||
|
||||
return retry(
|
||||
@@ -296,9 +292,8 @@ function remoteFetch (uri, opts) {
|
||||
const req = new fetch.Request(uri, reqOpts)
|
||||
return fetch(req)
|
||||
.then((res) => {
|
||||
if (opts.integrity) {
|
||||
if (opts.integrity)
|
||||
res = remoteFetchHandleIntegrity(res, opts.integrity)
|
||||
}
|
||||
|
||||
res.headers.set('x-fetch-attempts', attemptNum)
|
||||
|
||||
@@ -317,16 +312,14 @@ function remoteFetch (uri, opts) {
|
||||
res.status === 200 // No other statuses should be stored!
|
||||
)
|
||||
|
||||
if (isCachable) {
|
||||
if (isCachable)
|
||||
return opts.cacheManager.put(req, res, opts)
|
||||
}
|
||||
|
||||
if (!isMethodGetHead) {
|
||||
return opts.cacheManager.delete(req).then(() => {
|
||||
if (res.status >= 500 && req.method !== 'POST' && !isStream) {
|
||||
if (typeof opts.onRetry === 'function') {
|
||||
if (typeof opts.onRetry === 'function')
|
||||
opts.onRetry(res)
|
||||
}
|
||||
|
||||
return retryHandler(res)
|
||||
}
|
||||
@@ -348,19 +341,18 @@ function remoteFetch (uri, opts) {
|
||||
)
|
||||
|
||||
if (isRetriable) {
|
||||
if (typeof opts.onRetry === 'function') {
|
||||
if (typeof opts.onRetry === 'function')
|
||||
opts.onRetry(res)
|
||||
}
|
||||
|
||||
return retryHandler(res)
|
||||
}
|
||||
|
||||
if (!fetch.isRedirect(res.status)) {
|
||||
if (!fetch.isRedirect(res.status))
|
||||
return res
|
||||
}
|
||||
if (opts.redirect === 'manual') {
|
||||
|
||||
if (opts.redirect === 'manual')
|
||||
return res
|
||||
}
|
||||
|
||||
// if (!fetch.isRedirect(res.status) || opts.redirect === 'manual') {
|
||||
// return res
|
||||
// }
|
||||
@@ -402,9 +394,8 @@ function remoteFetch (uri, opts) {
|
||||
// Remove authorization if changing hostnames (but not if just
|
||||
// changing ports or protocols). This matches the behavior of request:
|
||||
// https://github.com/request/request/blob/b12a6245/lib/redirect.js#L134-L138
|
||||
if (new url.URL(req.url).hostname !== redirectURL.hostname) {
|
||||
if (new url.URL(req.url).hostname !== redirectURL.hostname)
|
||||
req.headers.delete('authorization')
|
||||
}
|
||||
|
||||
// for POST request with 301/302 response, or any request with 303 response,
|
||||
// use GET when following redirect
|
||||
@@ -441,13 +432,11 @@ function remoteFetch (uri, opts) {
|
||||
RETRY_TYPES.indexOf(err.type) === -1
|
||||
)
|
||||
|
||||
if (req.method === 'POST' || isRetryError) {
|
||||
if (req.method === 'POST' || isRetryError)
|
||||
throw err
|
||||
}
|
||||
|
||||
if (typeof opts.onRetry === 'function') {
|
||||
if (typeof opts.onRetry === 'function')
|
||||
opts.onRetry(err)
|
||||
}
|
||||
|
||||
return retryHandler(err)
|
||||
})
|
||||
|
||||
+17
-12
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "make-fetch-happen",
|
||||
"version": "8.0.10",
|
||||
"version": "8.0.12",
|
||||
"description": "Opinionated, caching, retrying fetch client",
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
@@ -14,7 +14,9 @@
|
||||
"prepublishOnly": "git push --follow-tags",
|
||||
"test": "tap test/*.js",
|
||||
"posttest": "npm run lint",
|
||||
"lint": "standard"
|
||||
"eslint": "eslint",
|
||||
"lint": "npm run eslint -- *.js utils test",
|
||||
"lintfix": "npm run lint -- --fix"
|
||||
},
|
||||
"repository": "https://github.com/npm/make-fetch-happen",
|
||||
"keywords": [
|
||||
@@ -33,33 +35,36 @@
|
||||
},
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"agentkeepalive": "^4.1.0",
|
||||
"cacache": "^15.0.0",
|
||||
"http-cache-semantics": "^4.0.4",
|
||||
"agentkeepalive": "^4.1.3",
|
||||
"cacache": "^15.0.5",
|
||||
"http-cache-semantics": "^4.1.0",
|
||||
"http-proxy-agent": "^4.0.1",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"is-lambda": "^1.0.1",
|
||||
"lru-cache": "^6.0.0",
|
||||
"minipass": "^3.1.3",
|
||||
"minipass-collect": "^1.0.2",
|
||||
"minipass-fetch": "^1.3.0",
|
||||
"minipass-fetch": "^1.3.2",
|
||||
"minipass-flush": "^1.0.5",
|
||||
"minipass-pipeline": "^1.2.2",
|
||||
"minipass-pipeline": "^1.2.4",
|
||||
"promise-retry": "^1.1.1",
|
||||
"socks-proxy-agent": "^5.0.0",
|
||||
"ssri": "^8.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mkdirp": "^1.0.3",
|
||||
"eslint": "^7.14.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^5.0.0",
|
||||
"mkdirp": "^1.0.4",
|
||||
"nock": "^11.9.1",
|
||||
"npmlog": "^4.1.2",
|
||||
"require-inject": "^1.4.2",
|
||||
"rimraf": "^2.7.1",
|
||||
"safe-buffer": "^5.2.0",
|
||||
"standard": "^14.3.1",
|
||||
"safe-buffer": "^5.2.1",
|
||||
"standard-version": "^7.1.0",
|
||||
"tacks": "^1.2.6",
|
||||
"tap": "^14.10.6"
|
||||
"tap": "^14.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
|
||||
+3
-4
@@ -12,9 +12,9 @@ module.exports = function configureOptions (_opts) {
|
||||
} else {
|
||||
if (typeof opts.retry !== 'object') {
|
||||
// Shorthand
|
||||
if (typeof opts.retry === 'number') {
|
||||
if (typeof opts.retry === 'number')
|
||||
opts.retry = { retries: opts.retry }
|
||||
}
|
||||
|
||||
if (typeof opts.retry === 'string') {
|
||||
const value = parseInt(opts.retry, 10)
|
||||
opts.retry = (value) ? { retries: value } : { retries: 0 }
|
||||
@@ -25,9 +25,8 @@ module.exports = function configureOptions (_opts) {
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.cacheManager) {
|
||||
if (opts.cacheManager)
|
||||
initializeCache(opts)
|
||||
}
|
||||
|
||||
return opts
|
||||
}
|
||||
+2
-3
@@ -1,16 +1,15 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = function isHeaderConditional (headers) {
|
||||
if (!headers || typeof headers !== 'object') {
|
||||
if (!headers || typeof headers !== 'object')
|
||||
return false
|
||||
}
|
||||
|
||||
const modifiers = [
|
||||
'if-modified-since',
|
||||
'if-none-match',
|
||||
'if-unmodified-since',
|
||||
'if-match',
|
||||
'if-range'
|
||||
'if-range',
|
||||
]
|
||||
|
||||
return Object.keys(headers)
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
module.exports = function iterableToObject (iter) {
|
||||
const obj = {}
|
||||
for (const k of iter.keys()) {
|
||||
for (const k of iter.keys())
|
||||
obj[k] = iter.get(k)
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
+2
-2
@@ -8,11 +8,11 @@ module.exports = function makePolicy (req, res) {
|
||||
const _req = {
|
||||
url: req.url,
|
||||
method: req.method,
|
||||
headers: iterableToObject(req.headers)
|
||||
headers: iterableToObject(req.headers),
|
||||
}
|
||||
const _res = {
|
||||
status: res.status,
|
||||
headers: iterableToObject(res.headers)
|
||||
headers: iterableToObject(res.headers),
|
||||
}
|
||||
|
||||
return new CachePolicy(_req, _res, { shared: false })
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ var y = d * 365.25;
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function(val, options) {
|
||||
module.exports = function (val, options) {
|
||||
options = options || {};
|
||||
var type = typeof val;
|
||||
if (type === 'string' && val.length > 0) {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Zeit, Inc.
|
||||
Copyright (c) 2020 Vercel, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+5
-4
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "ms",
|
||||
"version": "2.1.2",
|
||||
"version": "2.1.3",
|
||||
"description": "Tiny millisecond conversion utility",
|
||||
"repository": "zeit/ms",
|
||||
"repository": "vercel/ms",
|
||||
"main": "./index",
|
||||
"files": [
|
||||
"index.js"
|
||||
@@ -28,10 +28,11 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"eslint": "4.12.1",
|
||||
"eslint": "4.18.2",
|
||||
"expect.js": "0.3.1",
|
||||
"husky": "0.14.3",
|
||||
"lint-staged": "5.0.0",
|
||||
"mocha": "4.0.1"
|
||||
"mocha": "4.0.1",
|
||||
"prettier": "2.0.5"
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
# ms
|
||||
|
||||
[](https://travis-ci.org/zeit/ms)
|
||||
[](https://spectrum.chat/zeit)
|
||||

|
||||
|
||||
Use this package to easily convert various time formats to milliseconds.
|
||||
|
||||
|
||||
Generated
Vendored
File renamed without changes.
Generated
Vendored
File renamed without changes.
Generated
Vendored
File renamed without changes.
Generated
Vendored
File renamed without changes.
Generated
Vendored
File renamed without changes.
Generated
Vendored
File renamed without changes.
Generated
Vendored
File renamed without changes.
Generated
Vendored
File renamed without changes.
Generated
Vendored
File renamed without changes.
Generated
Vendored
File renamed without changes.
+19
-5
@@ -1,20 +1,34 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
max_line_length = 150
|
||||
max_line_length = 200
|
||||
|
||||
[*.js]
|
||||
block_comment_start = /*
|
||||
block_comment = *
|
||||
block_comment_end = */
|
||||
|
||||
[*.yml]
|
||||
indent_size = 1
|
||||
|
||||
[package.json]
|
||||
indent_style = tab
|
||||
|
||||
[CHANGELOG.md]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.json]
|
||||
[{*.json,Makefile}]
|
||||
max_line_length = off
|
||||
|
||||
[Makefile]
|
||||
[test/{dotdot,resolver,module_dir,multirepo,node_path,pathfilter,precedence}/**/*]
|
||||
indent_style = off
|
||||
indent_size = off
|
||||
max_line_length = off
|
||||
insert_final_newline = off
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
version: ~> 1.0
|
||||
language: node_js
|
||||
os:
|
||||
- linux
|
||||
import:
|
||||
- ljharb/travis-ci:node/all.yml
|
||||
- ljharb/travis-ci:node/pretest.yml
|
||||
- ljharb/travis-ci:node/posttest.yml
|
||||
+31
-11
@@ -4,6 +4,9 @@ build: off
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
#- nodejs_version: "15"
|
||||
- nodejs_version: "14"
|
||||
- nodejs_version: "13"
|
||||
- nodejs_version: "12"
|
||||
- nodejs_version: "11"
|
||||
- nodejs_version: "10"
|
||||
@@ -25,6 +28,7 @@ matrix:
|
||||
allow_failures:
|
||||
- nodejs_version: "5" # due to windows npm bug, registry-side
|
||||
- nodejs_version: "0.8"
|
||||
# platform: x86 # x64 has started failing on the registry side, around early November 2020
|
||||
- nodejs_version: "0.6"
|
||||
|
||||
platform:
|
||||
@@ -33,17 +37,33 @@ platform:
|
||||
|
||||
# Install scripts. (runs after repo cloning)
|
||||
install:
|
||||
# Fix symlinks in working copy (see https://github.com/appveyor/ci/issues/650#issuecomment-186592582) / https://github.com/charleskorn/batect/commit/d08986802ec43086902958c4ee7e57ff3e71dbef
|
||||
- git config core.symlinks true
|
||||
- git reset --hard
|
||||
# Get the latest stable version of Node.js or io.js
|
||||
- ps: Install-Product node $env:nodejs_version $env:platform
|
||||
- IF %nodejs_version% EQU 0.6 npm config set strict-ssl false && npm -g install npm@1.3
|
||||
- IF %nodejs_version% EQU 0.8 npm config set strict-ssl false && npm -g install npm@1.4.28 && npm install -g npm@4.5
|
||||
- set PATH=%APPDATA%\npm;%PATH%
|
||||
#- IF %nodejs_version% NEQ 0.6 AND %nodejs_version% NEQ 0.8 npm -g install npm
|
||||
# install modules
|
||||
- npm install
|
||||
# Fix symlinks in working copy (see https://github.com/appveyor/ci/issues/650#issuecomment-186592582) / https://github.com/charleskorn/batect/commit/d08986802ec43086902958c4ee7e57ff3e71dbef
|
||||
- git config core.symlinks true
|
||||
- git reset --hard
|
||||
# Get the latest stable version of Node.js or io.js
|
||||
- ps: if ($env:nodejs_version -ne '0.6') { Install-Product node $env:nodejs_version $env:platform }
|
||||
- ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) $env:platform
|
||||
- IF %nodejs_version% EQU 0.6 npm config set strict-ssl false && npm -g install npm@1.3
|
||||
- IF %nodejs_version% EQU 0.8 npm config set strict-ssl false && npm -g install npm@1.4.28 && npm install -g npm@4.5
|
||||
- IF %nodejs_version% EQU 1 npm -g install npm@2.9
|
||||
- IF %nodejs_version% EQU 2 npm -g install npm@4
|
||||
- IF %nodejs_version% EQU 3 npm -g install npm@4
|
||||
- IF %nodejs_version% EQU 4 npm -g install npm@5.3
|
||||
- IF %nodejs_version% EQU 5 npm -g install npm@5.3
|
||||
- IF %nodejs_version% EQU 6 npm -g install npm@6.9
|
||||
- IF %nodejs_version% EQU 7 npm -g install npm@6
|
||||
- IF %nodejs_version% EQU 8 npm -g install npm@6
|
||||
- IF %nodejs_version% EQU 9 npm -g install npm@6.9
|
||||
- IF %nodejs_version% EQU 10 npm -g install npm@7
|
||||
- IF %nodejs_version% EQU 11 npm -g install npm@7
|
||||
- IF %nodejs_version% EQU 12 npm -g install npm@7
|
||||
- IF %nodejs_version% EQU 13 npm -g install npm@7
|
||||
- IF %nodejs_version% EQU 14 npm -g install npm@7
|
||||
- IF %nodejs_version% EQU 15 npm -g install npm@7
|
||||
- set PATH=%APPDATA%\npm;%PATH%
|
||||
#- IF %nodejs_version% NEQ 0.6 AND %nodejs_version% NEQ 0.8 npm -g install npm
|
||||
# install modules
|
||||
- npm install
|
||||
|
||||
# Post-install test scripts.
|
||||
test_script:
|
||||
|
||||
+6
-5
@@ -1,9 +1,9 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var caller = require('./caller.js');
|
||||
var nodeModulesPaths = require('./node-modules-paths.js');
|
||||
var normalizeOptions = require('./normalize-options.js');
|
||||
var isCore = require('./is-core');
|
||||
var caller = require('./caller');
|
||||
var nodeModulesPaths = require('./node-modules-paths');
|
||||
var normalizeOptions = require('./normalize-options');
|
||||
var isCore = require('is-core-module');
|
||||
|
||||
var realpathFS = fs.realpath && typeof fs.realpath.native === 'function' ? fs.realpath.native : fs.realpath;
|
||||
|
||||
@@ -73,6 +73,7 @@ module.exports = function resolve(x, options, callback) {
|
||||
var packageIterator = opts.packageIterator;
|
||||
|
||||
var extensions = opts.extensions || ['.js'];
|
||||
var includeCoreModules = opts.includeCoreModules !== false;
|
||||
var basedir = opts.basedir || path.dirname(caller());
|
||||
var parent = opts.filename || basedir;
|
||||
|
||||
@@ -99,7 +100,7 @@ module.exports = function resolve(x, options, callback) {
|
||||
if ((/\/$/).test(x) && res === basedir) {
|
||||
loadAsDirectory(res, opts.package, onfile);
|
||||
} else loadAsFile(res, opts.package, onfile);
|
||||
} else if (isCore(x)) {
|
||||
} else if (includeCoreModules && isCore(x)) {
|
||||
return cb(null, x);
|
||||
} else loadNodeModules(x, basedir, function (err, n, pkg) {
|
||||
if (err) cb(err);
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@ function specifierIncluded(specifier) {
|
||||
var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.');
|
||||
|
||||
for (var i = 0; i < 3; ++i) {
|
||||
var cur = Number(current[i] || 0);
|
||||
var ver = Number(versionParts[i] || 0);
|
||||
var cur = parseInt(current[i] || 0, 10);
|
||||
var ver = parseInt(versionParts[i] || 0, 10);
|
||||
if (cur === ver) {
|
||||
continue; // eslint-disable-line no-restricted-syntax, no-continue
|
||||
}
|
||||
|
||||
Loaded 100 of 127 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user