mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
3.5 KiB
113 lines
3.5 KiB
'use strict'
|
|
var union = require('lodash.union')
|
|
var without = require('lodash.without')
|
|
var validate = require('aproba')
|
|
var flattenTree = require('./flatten-tree.js')
|
|
var isExtraneous = require('./is-extraneous.js')
|
|
var validateAllPeerDeps = require('./deps.js').validateAllPeerDeps
|
|
var packageId = require('../utils/package-id.js')
|
|
var moduleName = require('../utils/module-name.js')
|
|
|
|
var mutateIntoLogicalTree = module.exports = function (tree) {
|
|
validate('O', arguments)
|
|
|
|
validateAllPeerDeps(tree, function (tree, pkgname, version) {
|
|
if (!tree.missingPeers) tree.missingPeers = {}
|
|
tree.missingPeers[pkgname] = version
|
|
})
|
|
|
|
var flat = flattenTree(tree)
|
|
|
|
function getNode (flatname) {
|
|
return flatname.substr(0, 5) === '#DEV:'
|
|
? flat[flatname.substr(5)]
|
|
: flat[flatname]
|
|
}
|
|
|
|
Object.keys(flat).sort().forEach(function (flatname) {
|
|
var node = flat[flatname]
|
|
var requiredBy = node.package._requiredBy || []
|
|
var requiredByNames = requiredBy.filter(function (parentFlatname) {
|
|
var parentNode = getNode(parentFlatname)
|
|
if (!parentNode) return false
|
|
return parentNode.package.dependencies[moduleName(node)] ||
|
|
(parentNode.package.devDependencies && parentNode.package.devDependencies[moduleName(node)])
|
|
})
|
|
requiredBy = requiredByNames.map(getNode)
|
|
|
|
node.requiredBy = requiredBy
|
|
|
|
if (!requiredBy.length) return
|
|
|
|
if (node.parent) node.parent.children = without(node.parent.children, node)
|
|
|
|
requiredBy.forEach(function (parentNode) {
|
|
parentNode.children = union(parentNode.children, [node])
|
|
})
|
|
if (node.package._requiredBy.some(function (nodename) { return nodename[0] === '#' })) {
|
|
tree.children = union(tree.children, [node])
|
|
}
|
|
})
|
|
return tree
|
|
}
|
|
|
|
module.exports.asReadInstalled = function (tree) {
|
|
mutateIntoLogicalTree(tree)
|
|
return translateTree(tree)
|
|
}
|
|
|
|
function translateTree (tree) {
|
|
return translateTree_(tree, {})
|
|
}
|
|
|
|
function translateTree_ (tree, seen) {
|
|
var pkg = tree.package
|
|
if (seen[tree.path]) return pkg
|
|
seen[tree.path] = pkg
|
|
if (pkg._dependencies) return pkg
|
|
pkg._dependencies = pkg.dependencies
|
|
pkg.dependencies = {}
|
|
tree.children.forEach(function (child) {
|
|
pkg.dependencies[moduleName(child)] = translateTree_(child, seen)
|
|
})
|
|
Object.keys(tree.missingDeps).forEach(function (name) {
|
|
if (pkg.dependencies[name]) {
|
|
pkg.dependencies[name].invalid = true
|
|
pkg.dependencies[name].realName = name
|
|
pkg.dependencies[name].extraneous = false
|
|
} else {
|
|
pkg.dependencies[name] = {
|
|
requiredBy: tree.missingDeps[name],
|
|
missing: true,
|
|
optional: !!pkg.optionalDependencies[name]
|
|
}
|
|
}
|
|
})
|
|
var checkForMissingPeers = (tree.parent ? [] : [tree]).concat(tree.children)
|
|
checkForMissingPeers.filter(function (child) {
|
|
return child.missingPeers
|
|
}).forEach(function (child) {
|
|
Object.keys(child.missingPeers).forEach(function (pkgname) {
|
|
var version = child.missingPeers[pkgname]
|
|
var peerPkg = pkg.dependencies[pkgname]
|
|
if (!peerPkg) {
|
|
peerPkg = pkg.dependencies[pkgname] = {
|
|
_id: pkgname + '@' + version,
|
|
name: pkgname,
|
|
version: version
|
|
}
|
|
}
|
|
if (!peerPkg.peerMissing) peerPkg.peerMissing = []
|
|
peerPkg.peerMissing.push({
|
|
requiredBy: packageId(child),
|
|
requires: pkgname + '@' + version
|
|
})
|
|
})
|
|
})
|
|
pkg.path = tree.path
|
|
|
|
pkg.error = tree.error
|
|
pkg.extraneous = isExtraneous(tree)
|
|
if (tree.target && tree.parent && !tree.parent.target) pkg.link = tree.realpath
|
|
return pkg
|
|
}
|
|
|