Socket
Socket
Sign inDemoInstall

@npmcli/arborist

Package Overview
Dependencies
Maintainers
7
Versions
192
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@npmcli/arborist - npm Package Compare versions

Comparing version 0.0.0-pre.4 to 0.0.0-pre.5

lib/arborist/.reify.js.swp

29

lib/arborist/build-ideal-tree.js

@@ -67,2 +67,3 @@ // mixin implementing the buildIdealTree method

const _linkNodes = Symbol('linkNodes')
const _follow = Symbol('follow')

@@ -85,2 +86,4 @@ // used by Reify mixin

this[_follow] = !!options.follow
this[_explicitRequests] = new Set()

@@ -185,2 +188,3 @@ this[_preferDedupe] = false

devOptional: false,
peer: false,
optional: false,

@@ -770,12 +774,13 @@ })

const loc = relpath(this.path, realpath)
if (/^\.\.[\\\/]/.test(loc)) {
const fromInv = this.idealTree.inventory.get(loc)
if (fromInv && fromInv !== link.target)
link.target = fromInv
const external = /^\.\.\//.test(loc)
if (external && !this[_follow]) {
// outside the root, somebody else's problem, ignore it
// TODO: deep updates somehow, with a flag
continue
}
const fromInv = this.idealTree.inventory.get(loc)
if (fromInv && fromInv !== link.target)
link.target = fromInv
if (!link.target.parent && !link.target.fsParent) {

@@ -789,3 +794,6 @@ // the fsParent MUST be some node in the tree, possibly the root.

const path = parts.slice(0, p).join('/')
const node = !path ? this.idealTree : this.idealTree.inventory.get(path)
if (!path && external)
break
const node = !path ? this.idealTree
: this.idealTree.inventory.get(path)
if (node) {

@@ -798,2 +806,7 @@ link.target.fsParent = node

}
// didn't find a parent for it, but we're filling in external
// link targets, so go ahead and process it.
if (this[_follow] && !link.target.parent && !link.target.fsParent)
this[_depsQueue].push(link.target)
}

@@ -832,2 +845,3 @@

this.idealTree.devOptional = false
this.idealTree.peer = false
}

@@ -863,2 +877,3 @@

node.devOptional = true
node.peer = true
node.optional = true

@@ -865,0 +880,0 @@ }

@@ -140,2 +140,3 @@ // mixin providing the loadVirtual method

node.devOptional = !!(sw.devOptional || sw.dev || sw.optional)
node.peer = !!sw.peer
node.optional = !!sw.optional

@@ -157,2 +158,3 @@ node.dev = !!sw.dev

link.devOptional = target.devOptional
link.peer = target.peer
link.optional = target.optional

@@ -166,2 +168,3 @@ link.dev = target.dev

link.dev = link.target.dev = !!meta.dev
link.peer = link.target.peer = !!meta.peer
link.devOptional = link.target.devOptional =

@@ -168,0 +171,0 @@ !!meta.devOptional ||

@@ -74,3 +74,13 @@ // mixin implementing the reify method

const _copyIdealToActual = Symbol('copyIdealToActual')
const _addOmitsToTrashList = Symbol('addOmitsToTrashList')
const _omitDev = Symbol('omitDev')
const _omitOptional = Symbol('omitOptional')
const _omitPeer = Symbol('omitPeer')
const _global = Symbol('global')
const _ignoreScripts = Symbol('ignoreScripts')
const _scriptShell = Symbol('scriptShell')
const _force = Symbol('force')
// defined by Ideal mixin

@@ -84,3 +94,16 @@ const _idealTreePrune = Symbol.for('idealTreePrune')

this[_savePrefix] = options.savePrefix || '^'
const {
ignoreScripts = false,
global = false,
force = false,
scriptShell,
savePrefix = '^',
} = options
this[_ignoreScripts] = !!ignoreScripts
this[_global] = !!global
this[_force] = !!force
this[_scriptShell] = scriptShell
this[_savePrefix] = savePrefix
this[_diff] = null

@@ -94,3 +117,8 @@ this[_retiredPaths] = {}

// public method
reify (options) {
reify (options = {}) {
const omit = new Set(options.omit || [])
this[_omitDev] = omit.has('dev')
this[_omitOptional] = omit.has('optional')
this[_omitPeer] = omit.has('peer')
// start tracker block

@@ -102,2 +130,3 @@ this.addTracker('reify')

.then(() => this[_createSparseTree]())
.then(() => this[_addOmitsToTrashList]())
.then(() => this[_loadShrinkwrapsAndUpdateTrees]())

@@ -194,2 +223,19 @@ .then(() => this[_loadBundlesAndUpdateTrees]())

// adding to the trash list will skip reifying, and delete them
// if they are currently in the tree and otherwise untouched.
[_addOmitsToTrashList] () {
if (!this[_omitDev] && !this[_omitOptional] && !this[_omitPeer])
return
const filter = node =>
node.peer && this[_omitPeer] ||
node.dev && this[_omitDev] ||
node.optional && this[_omitOptional] ||
node.devOptional && this[_omitOptional] && this[_omitDev]
for (const node of this.idealTree.inventory.filter(filter)) {
this[_trashList].add(node.path)
}
}
[_createSparseTree] () {

@@ -230,3 +276,4 @@ // if we call this fn again, we look for the previous list

.filter(d => (d.action === 'CHANGE' || d.action === 'ADD') &&
d.ideal.hasShrinkwrap && !seen.has(d.ideal))
d.ideal.hasShrinkwrap && !seen.has(d.ideal) &&
!this[_trashList].has(d.ideal.path))

@@ -260,8 +307,7 @@ if (!shrinkwraps.length)

[_reifyNode] (node) {
this.addTracker('reify', node.name, node.location)
/* istanbul ignore if - pretty sure this is impossible, just cautious */
if (this[_trashList].has(node.path))
return node
this.addTracker('reify', node.name, node.location)
const p = this[_checkEngineAndPlatform](node)

@@ -316,3 +362,3 @@ .then(() => this[_extractOrLink](node))

[_checkPlatform] (node) {
checkPlatform(node.package, this.options.force)
checkPlatform(node.package, this[_force])
}

@@ -351,4 +397,4 @@

top: node.isTop,
force: this.options.force,
global: this.options.global,
force: this[_force],
global: this[_global],
})

@@ -390,3 +436,4 @@ }

const set = (bundlesByDepth.get(depth) || [])
.filter(node => node.root === this.idealTree)
.filter(node => node.root === this.idealTree &&
!this[_trashList].has(node.path))

@@ -429,4 +476,4 @@ if (!set.length) {

top: node.isTop,
force: this.options.force,
global: this.options.global,
force: this[_force],
global: this[_global],
}))

@@ -560,3 +607,3 @@ }

[_runLifecycleScripts] () {
if (this.options.ignoreScripts)
if (this[_ignoreScripts])
return

@@ -639,6 +686,7 @@

npm_package_dev: boolEnv(node.dev),
npm_package_peer: boolEnv(node.peer),
npm_package_dev_optional:
boolEnv(node.devOptional && !node.dev && !node.optional),
},
scriptShell: this.options.scriptShell,
scriptShell: this[_scriptShell],
}))

@@ -669,3 +717,3 @@ }))

// or shrinkwrap file, and any additions or removals to package.json
[_saveIdealTree] (options = {}) {
[_saveIdealTree] (options) {
// the ideal tree is actualized now, hooray!

@@ -672,0 +720,0 @@ // it still contains all the references to optional nodes that were removed

@@ -7,2 +7,3 @@ const { depth } = require('treeverse')

tree.devOptional = false
tree.peer = false
return depth({

@@ -28,2 +29,3 @@ tree,

node.target.devOptional = node.devOptional
node.target.peer = node.peer
node.target.extraneous = false

@@ -33,3 +35,3 @@ node = node.target

node.edgesOut.forEach(({type, to}) => {
node.edgesOut.forEach(({peer, optional, dev, to}) => {
// if the dep is missing, then its flags are already maximally unset

@@ -47,9 +49,14 @@ if (!to)

const unsetDevOpt = !node.devOptional && !node.dev && !node.optional &&
type !== 'dev' && type !== 'optional'
!dev && !optional
// if we are not in the devOpt tree, then we're also not in
// either the dev or opt trees
const unsetDev = unsetDevOpt || !node.dev && type !== 'dev'
const unsetOpt = unsetDevOpt || !node.optional && type !== 'optional'
const unsetDev = unsetDevOpt || !node.dev && !dev
const unsetOpt = unsetDevOpt ||
!node.optional && !optional
const unsetPeer = !node.peer && !peer
if (unsetPeer)
unsetFlag(to, 'peer')
if (unsetDevOpt)

@@ -82,3 +89,3 @@ unsetFlag(to, 'devOptional')

.filter(edge => edge.to && edge.to[flag] &&
(edge.type === 'peer' || edge.type === 'prod'))
(flag !== 'peer' && edge.type === 'peer' || edge.type === 'prod'))
.map(edge => edge.to),

@@ -85,0 +92,0 @@ })

@@ -107,2 +107,4 @@ // Do not rely on package._fields, so that we don't throw

module.exports = depValid
module.exports = (child, requested, accept, requestor) =>
depValid(child, requested, requestor) ||
(typeof accept === 'string' ? depValid(child, accept, requestor) : false)

@@ -9,2 +9,3 @@ // An edge in the dependency graph

const _spec = Symbol('_spec')
const _accept = Symbol('_accept')
const _name = Symbol('_name')

@@ -25,3 +26,3 @@ const _error = Symbol('_error')

constructor (options) {
const { type, name, spec, from } = options
const { type, name, spec, accept, from } = options

@@ -32,2 +33,8 @@ if (typeof spec !== 'string')

if (accept !== undefined) {
if (typeof accept !== 'string')
throw new TypeError('accept field must be a string if provided')
this[_accept] = accept || '*'
}
if (typeof name !== 'string')

@@ -50,5 +57,9 @@ throw new TypeError('must provide dependency name')

satisfiedBy (node) {
return depValid(node, this.spec, this.from)
return depValid(node, this.spec, this.accept, this.from)
}
get dev () {
return this[_type] === 'dev'
}
get optional () {

@@ -74,2 +85,6 @@ return this[_type] === 'optional' || this[_type] === 'peerOptional'

get accept () {
return this[_accept]
}
get valid () {

@@ -90,3 +105,3 @@ return !this.error

? 'PEER LOCAL'
: !depValid(this.to, this.spec, this.from)
: !depValid(this.to, this.spec, this.accept, this.from)
? 'INVALID'

@@ -93,0 +108,0 @@ : 'OK'

@@ -86,2 +86,3 @@ // inventory, path, realpath, root, and parent

devOptional = true,
peer = true,
} = options

@@ -136,2 +137,3 @@

this.devOptional = devOptional
this.peer = peer
this.extraneous = extraneous

@@ -359,7 +361,9 @@

const from = this
const ad = this.package.acceptDependencies || {}
for (const [name, spec] of Object.entries(obj || {})) {
const accept = ad[name]
// if it's already set, then we keep the existing edge
// NB: the Edge ctor adds itself to from.edgesOut
if (!this.edgesOut.get(name)) {
new Edge({ from, name, spec, type })
new Edge({ from, name, spec, accept, type })
}

@@ -366,0 +370,0 @@ }

@@ -83,2 +83,3 @@ // a module that manages a shrinkwrap file (npm-shrinkwrap.json or

'bundleDependencies',
'acceptDependencies',
'funding',

@@ -156,2 +157,4 @@ 'engines',

else {
if (node.peer)
meta.peer = true
if (node.dev)

@@ -610,2 +613,5 @@ meta.dev = true

else if (!node.isLink) {
if (node.peer)
lock.peer = true
if (node.devOptional && !node.dev && !node.optional)

@@ -612,0 +618,0 @@ lock.devOptional = true

{
"name": "@npmcli/arborist",
"version": "0.0.0-pre.4",
"version": "0.0.0-pre.5",
"description": "Manage node_modules trees",

@@ -5,0 +5,0 @@ "dependencies": {

@@ -163,3 +163,4 @@ # @npmcli/arborist

* `node.children` Map of packages located in the node's `node_modules` folder.
* `node.children` Map of packages located in the node's `node_modules`
folder.
* `node.package` The contents of this node's `package.json` file.

@@ -170,21 +171,22 @@ * `node.path` File path to this package. If the node is a link, then this

* `node.realpath` The full real filepath on disk where this node lives.
* `node.location` A slash-normalized relative path from the root node
to this node's path.
* `node.location` A slash-normalized relative path from the root node to
this node's path.
* `node.isLink` Whether this represents a symlink. Always `false` for Node
objects, always `true` for Link objects.
* `node.isRoot` True if this node is a root node. (Ie, if `node.root ===
node`.)
node`.)
* `node.root` The root node where we are working. If not assigned to some
other value, resolves to the node itself. (Ie, the root node's `root`
property refers to itself.)
other value, resolves to the node itself. (Ie, the root node's `root`
property refers to itself.)
* `node.isTop` True if this node is the top of its tree (ie, has no
`parent`, false otherwise).
`parent`, false otherwise).
* `node.top` The top node in this node's tree. This will be equal to
`node.root` for simple trees, but link targets will frequently be
outside of (or nested somewhere within) a `node_modules` hierarchy, and
so will have a different `top`.
* `node.dev`, `node.optional`, `node.devOptional` Indicators as to whether
this node is a dev dependency and/or optional dependency. These flags
are relevant when pruning optional and/or dev dependencies out of the
tree. See **Package Dependency Flags** below for explanations.
`node.root` for simple trees, but link targets will frequently be outside
of (or nested somewhere within) a `node_modules` hierarchy, and so will
have a different `top`.
* `node.dev`, `node.optional`, `node.devOptional`, `node.peer`, Indicators
as to whether this node is a dev, optional, and/or peer dependency.
These flags are relevant when pruning dependencies out of the tree or
deciding what to reify. See **Package Dependency Flags** below for
explanations.
* `node.edgesOut` Edges in the dependency graph indicating nodes that this

@@ -263,27 +265,47 @@ node depends on, which resolve its dependencies.

```
| extraneous | dev | optional | devOptional | meaning | prune? |
|------------+-----+----------+-------------+---------------------+-------------------|
| | | | | production dep | never |
|------------+-----+----------+-------------+---------------------+-------------------|
| X | N/A | N/A | N/A | nothing depends on | always |
| | | | | this, it is trash | |
|------------+-----+----------+-------------+---------------------+-------------------|
| | X | | X | devDependency, or | if pruning dev |
| | | | not in lock | only depended upon | |
| | | | | by devDependencies | |
|------------+-----+----------+-------------+---------------------+-------------------|
| | | X | X | optionalDependency, | if pruning |
| | | | not in lock | or only depended on | optional |
| | | | | by optionalDeps | |
|------------+-----+----------+-------------+---------------------+-------------------|
| | X | X | X | Optional dependency | if pruning EITHER |
| | | | not in lock | of dep(s) in the | dev OR optional |
| | | | | dev hierarchy | |
|------------+-----+----------+-------------+---------------------+-------------------|
| | | | X | BOTH a non-optional | if pruning BOTH |
| | | | in lock | dep within the dev | dev AND optional |
| | | | | hierarchy, AND a | |
| | | | | dep within the | |
| | | | | optional hierarchy | |
+------------+-----+----------+-------------+---------------------+-------------------+
| extraneous | peer | dev | optional | devOptional | meaning | prune? |
|------------+------+-----+----------+-------------+---------------------+-------------------|
| | | | | | production dep | never |
|------------+------+-----+----------+-------------+---------------------+-------------------|
| X | N/A | N/A | N/A | N/A | nothing depends on | always |
| | | | | | this, it is trash | |
|------------+------+-----+----------+-------------+---------------------+-------------------|
| | | X | | X | devDependency, or | if pruning dev |
| | | | | not in lock | only depended upon | |
| | | | | | by devDependencies | |
|------------+------+-----+----------+-------------+---------------------+-------------------|
| | | | X | X | optionalDependency, | if pruning |
| | | | | not in lock | or only depended on | optional |
| | | | | | by optionalDeps | |
|------------+------+-----+----------+-------------+---------------------+-------------------|
| | | X | X | X | Optional dependency | if pruning EITHER |
| | | | | not in lock | of dep(s) in the | dev OR optional |
| | | | | | dev hierarchy | |
|------------+------+-----+----------+-------------+---------------------+-------------------|
| | | | | X | BOTH a non-optional | if pruning BOTH |
| | | | | in lock | dep within the dev | dev AND optional |
| | | | | | hierarchy, AND a | |
| | | | | | dep within the | |
| | | | | | optional hierarchy | |
|------------+------+-----+----------+-------------+---------------------+-------------------|
| | X | | | | peer dependency, or | if pruning peers |
| | | | | | only depended on by | |
| | | | | | peer dependencies | |
|------------+------+-----+----------+-------------+---------------------+-------------------|
| | X | X | | X | peer dependency of | if pruning peer |
| | | | | not in lock | dev node heirarchy | OR dev deps |
|------------+------+-----+----------+-------------+---------------------+-------------------|
| | X | | X | X | peer dependency of | if pruning peer |
| | | | | not in lock | optional nodes, or | OR optional deps |
| | | | | | peerOptional dep | |
|------------+------+-----+----------+-------------+---------------------+-------------------|
| | X | X | X | X | peer optional deps | if pruning peer |
| | | | | not in lock | of the dev dep | OR optional OR |
| | | | | | heirarchy | dev |
|------------+------+-----+----------+-------------+---------------------+-------------------|
| | X | | | X | BOTH a non-optional | if pruning peers |
| | | | | in lock | peer dep within the | OR: |
| | | | | | dev heirarchy, AND | BOTH optional |
| | | | | | a peer optional dep | AND dev deps |
+------------+------+-----+----------+-------------+---------------------+-------------------+
```

@@ -307,4 +329,7 @@

_both_ dev and optional dependencies are being removed.
* If `node.peer` is set, then all the same semantics apply as above, except
that the dep is brought in by a peer dep at some point, rather than a
normal non-peer dependency.
Note: `devOptional` is only set in the shrinkwrap/package-lock file if
_neither_ `dev` nor `optional` are set, as it would be redundant.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc