diff options
Diffstat (limited to 'deps/npm/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js')
-rw-r--r-- | deps/npm/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js | 168 |
1 files changed, 85 insertions, 83 deletions
diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js b/deps/npm/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js index 9a96fd1b379..f78a43319be 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js @@ -1,60 +1,60 @@ // add and remove dependency specs to/from pkg manifest -const removeFromOthers = (name, type, pkg) => { - const others = new Set([ - 'dependencies', - 'optionalDependencies', - 'devDependencies', - 'peerDependenciesMeta', - 'peerDependencies', - ]) - - switch (type) { - case 'prod': - others.delete('dependencies') - break - case 'dev': - others.delete('devDependencies') - others.delete('peerDependencies') - others.delete('peerDependenciesMeta') - break - case 'optional': - others.delete('optionalDependencies') - break - case 'peer': - case 'peerOptional': - others.delete('devDependencies') - others.delete('peerDependencies') - others.delete('peerDependenciesMeta') - break - } - - for (const other of others) - deleteSubKey(pkg, other, name) -} - -const add = ({pkg, add, saveBundle, saveType}) => { +const add = ({pkg, add, saveBundle, saveType, log}) => { for (const spec of add) - addSingle({pkg, spec, saveBundle, saveType}) + addSingle({pkg, spec, saveBundle, saveType, log}) return pkg } -const addSingle = ({pkg, spec, saveBundle, saveType}) => { - if (!saveType) - saveType = getSaveType(pkg, spec) +// Canonical source of both the map between saveType and where it correlates to +// in the package, and the names of all our dependencies attributes +const saveTypeMap = new Map([ + ['dev', 'devDependencies'], + ['optional', 'optionalDependencies'], + ['prod', 'dependencies'], + ['peerOptional', 'peerDependencies'], + ['peer', 'peerDependencies'], +]) +const addSingle = ({pkg, spec, saveBundle, saveType, log}) => { const { name, rawSpec } = spec - removeFromOthers(name, saveType, pkg) - const type = saveType === 'prod' ? 'dependencies' - : saveType === 'optional' ? 'optionalDependencies' - : saveType === 'peer' || saveType === 'peerOptional' ? 'peerDependencies' - : saveType === 'dev' ? 'devDependencies' - : /* istanbul ignore next */ null - pkg[type] = pkg[type] || {} - if (rawSpec !== '' || pkg[type][name] === undefined) - pkg[type][name] = rawSpec || '*' + // if the user does not give us a type, we infer which type(s) + // to keep based on the same order of priority we do when + // building the tree as defined in the _loadDeps method of + // the node class. + if (!saveType) + saveType = inferSaveType(pkg, spec.name) + + if (saveType === 'prod') { + // a production dependency can only exist as production (rpj ensures it + // doesn't coexist w/ optional) + deleteSubKey(pkg, 'devDependencies', name, 'dependencies', log) + deleteSubKey(pkg, 'peerDependencies', name, 'dependencies', log) + } else if (saveType === 'dev') { + // a dev dependency may co-exist as peer, or optional, but not production + deleteSubKey(pkg, 'dependencies', name, 'devDependencies', log) + } else if (saveType === 'optional') { + // an optional dependency may co-exist as dev (rpj ensures it doesn't + // coexist w/ prod) + deleteSubKey(pkg, 'peerDependencies', name, 'optionalDependencies', log) + } else { // peer or peerOptional is all that's left + // a peer dependency may coexist as dev + deleteSubKey(pkg, 'dependencies', name, 'peerDependencies', log) + deleteSubKey(pkg, 'optionalDependencies', name, 'peerDependencies', log) + } + + const depType = saveTypeMap.get(saveType) + + pkg[depType] = pkg[depType] || {} + if (rawSpec !== '' || pkg[depType][name] === undefined) + pkg[depType][name] = rawSpec || '*' + if (saveType === 'optional') { + // Affordance for previous npm versions that require this behaviour + pkg.dependencies = pkg.dependencies || {} + pkg.dependencies[name] = pkg.optionalDependencies[name] + } if (saveType === 'peer' || saveType === 'peerOptional') { const pdm = pkg.peerDependenciesMeta || {} @@ -75,51 +75,53 @@ const addSingle = ({pkg, spec, saveBundle, saveType}) => { // keep it sorted, keep it unique const bd = new Set(pkg.bundleDependencies || []) bd.add(spec.name) - pkg.bundleDependencies = [...bd].sort((a, b) => a.localeCompare(b)) + pkg.bundleDependencies = [...bd].sort((a, b) => a.localeCompare(b, 'en')) } } -const getSaveType = (pkg, spec) => { - const {name} = spec - const { - // these names are so lonnnnngggg - devDependencies: devDeps, - optionalDependencies: optDeps, - peerDependencies: peerDeps, - peerDependenciesMeta: peerDepsMeta, - } = pkg - - if (peerDeps && peerDeps[name] !== undefined) { - if (peerDepsMeta && peerDepsMeta[name] && peerDepsMeta[name].optional) - return 'peerOptional' - else - return 'peer' - } else if (devDeps && devDeps[name] !== undefined) - return 'dev' - else if (optDeps && optDeps[name] !== undefined) - return 'optional' - else - return 'prod' +// Finds where the package is already in the spec and infers saveType from that +const inferSaveType = (pkg, name) => { + for (const saveType of saveTypeMap.keys()) { + if (hasSubKey(pkg, saveTypeMap.get(saveType), name)) { + if ( + saveType === 'peerOptional' && + (!hasSubKey(pkg, 'peerDependenciesMeta', name) || + !pkg.peerDependenciesMeta[name].optional) + ) + return 'peer' + return saveType + } + } + return 'prod' } -const deleteSubKey = (obj, k, sk) => { - if (obj[k]) { - delete obj[k][sk] - if (!Object.keys(obj[k]).length) - delete obj[k] +const hasSubKey = (pkg, depType, name) => { + return pkg[depType] && Object.prototype.hasOwnProperty.call(pkg[depType], name) +} + +// Removes a subkey and warns about it if it's being replaced +const deleteSubKey = (pkg, depType, name, replacedBy, log) => { + if (hasSubKey(pkg, depType, name)) { + if (replacedBy && log) + log.warn('idealTree', `Removing ${depType}.${name} in favor of ${replacedBy}.${name}`) + delete pkg[depType][name] + + // clean up peerDependenciesMeta if we are removing something from peerDependencies + if (depType === 'peerDependencies' && pkg.peerDependenciesMeta) { + delete pkg.peerDependenciesMeta[name] + if (!Object.keys(pkg.peerDependenciesMeta).length) + delete pkg.peerDependenciesMeta + } + + if (!Object.keys(pkg[depType]).length) + delete pkg[depType] } } const rm = (pkg, rm) => { - for (const type of [ - 'dependencies', - 'optionalDependencies', - 'peerDependencies', - 'peerDependenciesMeta', - 'devDependencies', - ]) { + for (const depType of new Set(saveTypeMap.values())) { for (const name of rm) - deleteSubKey(pkg, type, name) + deleteSubKey(pkg, depType, name) } if (pkg.bundleDependencies) { pkg.bundleDependencies = pkg.bundleDependencies @@ -130,4 +132,4 @@ const rm = (pkg, rm) => { return pkg } -module.exports = { add, rm } +module.exports = { add, rm, saveTypeMap, hasSubKey } |