Skip to content

Commit ea5e3a3

Browse files
wraithgarlukekarrys
authored andcommitted
fix: inline single-use functions
1 parent 3569094 commit ea5e3a3

File tree

2 files changed

+112
-167
lines changed

2 files changed

+112
-167
lines changed

workspaces/arborist/lib/add-rm-pkg-deps.js

+62-69
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,67 @@ const log = require('proc-log')
44
const localeCompare = require('@isaacs/string-locale-compare')('en')
55

66
const add = ({ pkg, add, saveBundle, saveType }) => {
7-
for (const spec of add) {
8-
addSingle({ pkg, spec, saveBundle, saveType })
7+
for (const { name, rawSpec } of add) {
8+
// if the user does not give us a type, we infer which type(s)
9+
// to keep based on the same order of priority we do when
10+
// building the tree as defined in the _loadDeps method of
11+
// the node class.
12+
if (!saveType) {
13+
saveType = inferSaveType(pkg, name)
14+
}
15+
16+
if (saveType === 'prod') {
17+
// a production dependency can only exist as production (rpj ensures it
18+
// doesn't coexist w/ optional)
19+
deleteSubKey(pkg, 'devDependencies', name, 'dependencies')
20+
deleteSubKey(pkg, 'peerDependencies', name, 'dependencies')
21+
} else if (saveType === 'dev') {
22+
// a dev dependency may co-exist as peer, or optional, but not production
23+
deleteSubKey(pkg, 'dependencies', name, 'devDependencies')
24+
} else if (saveType === 'optional') {
25+
// an optional dependency may co-exist as dev (rpj ensures it doesn't
26+
// coexist w/ prod)
27+
deleteSubKey(pkg, 'peerDependencies', name, 'optionalDependencies')
28+
} else { // peer or peerOptional is all that's left
29+
// a peer dependency may coexist as dev
30+
deleteSubKey(pkg, 'dependencies', name, 'peerDependencies')
31+
deleteSubKey(pkg, 'optionalDependencies', name, 'peerDependencies')
32+
}
33+
34+
const depType = saveTypeMap.get(saveType)
35+
36+
pkg[depType] = pkg[depType] || {}
37+
if (rawSpec !== '' || pkg[depType][name] === undefined) {
38+
pkg[depType][name] = rawSpec || '*'
39+
}
40+
if (saveType === 'optional') {
41+
// Affordance for previous npm versions that require this behaviour
42+
pkg.dependencies = pkg.dependencies || {}
43+
pkg.dependencies[name] = pkg.optionalDependencies[name]
44+
}
45+
46+
if (saveType === 'peer' || saveType === 'peerOptional') {
47+
const pdm = pkg.peerDependenciesMeta || {}
48+
if (saveType === 'peer' && pdm[name] && pdm[name].optional) {
49+
pdm[name].optional = false
50+
} else if (saveType === 'peerOptional') {
51+
pdm[name] = pdm[name] || {}
52+
pdm[name].optional = true
53+
pkg.peerDependenciesMeta = pdm
54+
}
55+
// peerDeps are often also a devDep, so that they can be tested when
56+
// using package managers that don't auto-install peer deps
57+
if (pkg.devDependencies && pkg.devDependencies[name] !== undefined) {
58+
pkg.devDependencies[name] = pkg.peerDependencies[name]
59+
}
60+
}
61+
62+
if (saveBundle && saveType !== 'peer' && saveType !== 'peerOptional') {
63+
// keep it sorted, keep it unique
64+
const bd = new Set(pkg.bundleDependencies || [])
65+
bd.add(name)
66+
pkg.bundleDependencies = [...bd].sort(localeCompare)
67+
}
968
}
1069

1170
return pkg
@@ -21,71 +80,6 @@ const saveTypeMap = new Map([
2180
['peer', 'peerDependencies'],
2281
])
2382

24-
const addSingle = ({ pkg, spec, saveBundle, saveType }) => {
25-
const { name, rawSpec } = spec
26-
27-
// if the user does not give us a type, we infer which type(s)
28-
// to keep based on the same order of priority we do when
29-
// building the tree as defined in the _loadDeps method of
30-
// the node class.
31-
if (!saveType) {
32-
saveType = inferSaveType(pkg, spec.name)
33-
}
34-
35-
if (saveType === 'prod') {
36-
// a production dependency can only exist as production (rpj ensures it
37-
// doesn't coexist w/ optional)
38-
deleteSubKey(pkg, 'devDependencies', name, 'dependencies')
39-
deleteSubKey(pkg, 'peerDependencies', name, 'dependencies')
40-
} else if (saveType === 'dev') {
41-
// a dev dependency may co-exist as peer, or optional, but not production
42-
deleteSubKey(pkg, 'dependencies', name, 'devDependencies')
43-
} else if (saveType === 'optional') {
44-
// an optional dependency may co-exist as dev (rpj ensures it doesn't
45-
// coexist w/ prod)
46-
deleteSubKey(pkg, 'peerDependencies', name, 'optionalDependencies')
47-
} else { // peer or peerOptional is all that's left
48-
// a peer dependency may coexist as dev
49-
deleteSubKey(pkg, 'dependencies', name, 'peerDependencies')
50-
deleteSubKey(pkg, 'optionalDependencies', name, 'peerDependencies')
51-
}
52-
53-
const depType = saveTypeMap.get(saveType)
54-
55-
pkg[depType] = pkg[depType] || {}
56-
if (rawSpec !== '' || pkg[depType][name] === undefined) {
57-
pkg[depType][name] = rawSpec || '*'
58-
}
59-
if (saveType === 'optional') {
60-
// Affordance for previous npm versions that require this behaviour
61-
pkg.dependencies = pkg.dependencies || {}
62-
pkg.dependencies[name] = pkg.optionalDependencies[name]
63-
}
64-
65-
if (saveType === 'peer' || saveType === 'peerOptional') {
66-
const pdm = pkg.peerDependenciesMeta || {}
67-
if (saveType === 'peer' && pdm[name] && pdm[name].optional) {
68-
pdm[name].optional = false
69-
} else if (saveType === 'peerOptional') {
70-
pdm[name] = pdm[name] || {}
71-
pdm[name].optional = true
72-
pkg.peerDependenciesMeta = pdm
73-
}
74-
// peerDeps are often also a devDep, so that they can be tested when
75-
// using package managers that don't auto-install peer deps
76-
if (pkg.devDependencies && pkg.devDependencies[name] !== undefined) {
77-
pkg.devDependencies[name] = pkg.peerDependencies[name]
78-
}
79-
}
80-
81-
if (saveBundle && saveType !== 'peer' && saveType !== 'peerOptional') {
82-
// keep it sorted, keep it unique
83-
const bd = new Set(pkg.bundleDependencies || [])
84-
bd.add(spec.name)
85-
pkg.bundleDependencies = [...bd].sort(localeCompare)
86-
}
87-
}
88-
8983
// Finds where the package is already in the spec and infers saveType from that
9084
const inferSaveType = (pkg, name) => {
9185
for (const saveType of saveTypeMap.keys()) {
@@ -103,9 +97,8 @@ const inferSaveType = (pkg, name) => {
10397
return 'prod'
10498
}
10599

106-
const { hasOwnProperty } = Object.prototype
107100
const hasSubKey = (pkg, depType, name) => {
108-
return pkg[depType] && hasOwnProperty.call(pkg[depType], name)
101+
return pkg[depType] && Object.prototype.hasOwnProperty.call(pkg[depType], name)
109102
}
110103

111104
// Removes a subkey and warns about it if it's being replaced

workspaces/arborist/lib/arborist/build-ideal-tree.js

+50-98
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,11 @@ const _linkNodes = Symbol('linkNodes')
8181
const _follow = Symbol('follow')
8282
const _globalStyle = Symbol('globalStyle')
8383
const _globalRootNode = Symbol('globalRootNode')
84-
const _isVulnerable = Symbol.for('isVulnerable')
8584
const _usePackageLock = Symbol.for('usePackageLock')
8685
const _rpcache = Symbol.for('realpathCache')
8786
const _stcache = Symbol.for('statCache')
88-
const _updateFilePath = Symbol('updateFilePath')
89-
const _followSymlinkPath = Symbol('followSymlinkPath')
90-
const _getRelpathSpec = Symbol('getRelpathSpec')
91-
const _retrieveSpecName = Symbol('retrieveSpecName')
9287
const _strictPeerDeps = Symbol('strictPeerDeps')
9388
const _checkEngineAndPlatform = Symbol('checkEngineAndPlatform')
94-
const _checkEngine = Symbol('checkEngine')
95-
const _checkPlatform = Symbol('checkPlatform')
9689
const _virtualRoots = Symbol('virtualRoots')
9790
const _virtualRoot = Symbol('virtualRoot')
9891
const _includeWorkspaceRoot = Symbol.for('includeWorkspaceRoot')
@@ -228,34 +221,22 @@ module.exports = cls => class IdealTreeBuilder extends cls {
228221
}
229222

230223
async [_checkEngineAndPlatform] () {
224+
const { engineStrict, npmVersion, nodeVersion } = this.options
231225
for (const node of this.idealTree.inventory.values()) {
232226
if (!node.optional) {
233-
this[_checkEngine](node)
234-
this[_checkPlatform](node)
235-
}
236-
}
237-
}
238-
239-
[_checkPlatform] (node) {
240-
checkPlatform(node.package, this[_force])
241-
}
242-
243-
[_checkEngine] (node) {
244-
const { engineStrict, npmVersion, nodeVersion } = this.options
245-
const c = () =>
246-
checkEngine(node.package, npmVersion, nodeVersion, this[_force])
247-
248-
if (engineStrict) {
249-
c()
250-
} else {
251-
try {
252-
c()
253-
} catch (er) {
254-
log.warn(er.code, er.message, {
255-
package: er.pkgid,
256-
required: er.required,
257-
current: er.current,
258-
})
227+
try {
228+
checkEngine(node.package, npmVersion, nodeVersion, this[_force])
229+
} catch (err) {
230+
if (engineStrict) {
231+
throw err
232+
}
233+
log.warn(err.code, err.message, {
234+
package: err.pkgid,
235+
required: err.required,
236+
current: err.current,
237+
})
238+
}
239+
checkPlatform(node.package, this[_force])
259240
}
260241
}
261242
}
@@ -533,82 +514,57 @@ Try using the package name instead, e.g:
533514
// This returns a promise because we might not have the name yet,
534515
// and need to call pacote.manifest to find the name.
535516
async [_add] (tree, { add, saveType = null, saveBundle = false }) {
517+
const path = this.idealTree.target.path
536518
// get the name for each of the specs in the list.
537519
// ie, doing `foo@bar` we just return foo
538520
// but if it's a url or git, we don't know the name until we
539521
// fetch it and look in its manifest.
540-
const resolvedAdd = await Promise.all(add.map(async rawSpec => {
522+
await Promise.all(add.map(async rawSpec => {
541523
// We do NOT provide the path to npa here, because user-additions
542524
// need to be resolved relative to the CWD the user is in.
543-
const spec = await this[_retrieveSpecName](npa(rawSpec))
544-
.then(spec => this[_updateFilePath](spec))
545-
.then(spec => this[_followSymlinkPath](spec))
525+
let spec = npa(rawSpec)
526+
527+
// if it's just @'' then we reload whatever's there, or get latest
528+
// if it's an explicit tag, we need to install that specific tag version
529+
const isTag = spec.rawSpec && spec.type === 'tag'
530+
531+
// look up the names of file/directory/git specs
532+
if (!spec.name || isTag) {
533+
const mani = await pacote.manifest(spec, { ...this.options })
534+
if (isTag) {
535+
// translate tag to a version
536+
spec = npa(`${mani.name}@${mani.version}`)
537+
}
538+
spec.name = mani.name
539+
}
540+
541+
const { name } = spec
542+
if (spec.type === 'file') {
543+
spec = npa(`file:${relpath(path, spec.fetchSpec).replace(/#/g, '%23')}`, path)
544+
spec.name = name
545+
} else if (spec.type === 'directory') {
546+
try {
547+
const real = await realpath(spec.fetchSpec, this[_rpcache], this[_stcache])
548+
spec = npa(`file:${relpath(path, real).replace(/#/g, '%23')}`, path)
549+
spec.name = name
550+
} catch {
551+
// TODO: create synthetic test case to simulate realpath failure
552+
}
553+
}
546554
spec.tree = tree
547-
return spec
555+
this[_resolvedAdd].push(spec)
548556
}))
549-
this[_resolvedAdd].push(...resolvedAdd)
550-
// now resolvedAdd is a list of spec objects with names.
557+
558+
// now this._resolvedAdd is a list of spec objects with names.
551559
// find a home for each of them!
552560
addRmPkgDeps.add({
553561
pkg: tree.package,
554-
add: resolvedAdd,
562+
add: this[_resolvedAdd],
555563
saveBundle,
556564
saveType,
557-
path: this.path,
558565
})
559566
}
560567

561-
async [_retrieveSpecName] (spec) {
562-
// if it's just @'' then we reload whatever's there, or get latest
563-
// if it's an explicit tag, we need to install that specific tag version
564-
const isTag = spec.rawSpec && spec.type === 'tag'
565-
566-
if (spec.name && !isTag) {
567-
return spec
568-
}
569-
570-
const mani = await pacote.manifest(spec, { ...this.options })
571-
// if it's a tag type, then we need to run it down to an actual version
572-
if (isTag) {
573-
return npa(`${mani.name}@${mani.version}`)
574-
}
575-
576-
spec.name = mani.name
577-
return spec
578-
}
579-
580-
async [_updateFilePath] (spec) {
581-
if (spec.type === 'file') {
582-
return this[_getRelpathSpec](spec, spec.fetchSpec)
583-
}
584-
585-
return spec
586-
}
587-
588-
async [_followSymlinkPath] (spec) {
589-
if (spec.type === 'directory') {
590-
const real = await (
591-
realpath(spec.fetchSpec, this[_rpcache], this[_stcache])
592-
// TODO: create synthetic test case to simulate realpath failure
593-
.catch(/* istanbul ignore next */() => null)
594-
)
595-
596-
return this[_getRelpathSpec](spec, real)
597-
}
598-
return spec
599-
}
600-
601-
[_getRelpathSpec] (spec, filepath) {
602-
/* istanbul ignore else - should also be covered by realpath failure */
603-
if (filepath) {
604-
const { name } = spec
605-
const tree = this.idealTree.target
606-
spec = npa(`file:${relpath(tree.path, filepath).replace(/#/g, '%23')}`, tree.path)
607-
spec.name = name
608-
}
609-
return spec
610-
}
611-
612568
// TODO: provide a way to fix bundled deps by exposing metadata about
613569
// what's in the bundle at each published manifest. Without that, we
614570
// can't possibly fix bundled deps without breaking a ton of other stuff,
@@ -686,10 +642,6 @@ Try using the package name instead, e.g:
686642
}
687643
}
688644

689-
[_isVulnerable] (node) {
690-
return this.auditReport && this.auditReport.isVulnerable(node)
691-
}
692-
693645
[_avoidRange] (name) {
694646
if (!this.auditReport) {
695647
return null
@@ -1234,7 +1186,7 @@ This is a one-time fix-up, please be patient...
12341186
}
12351187

12361188
// fixing a security vulnerability with this package, problem
1237-
if (this[_isVulnerable](edge.to)) {
1189+
if (this.auditReport && this.auditReport.isVulnerable(edge.to)) {
12381190
return true
12391191
}
12401192

0 commit comments

Comments
 (0)