]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/lib/ls.js
Adding integrated tile server
[simantics/district.git] / org.simantics.maps.server / node / node-v4.8.0-win-x64 / node_modules / npm / lib / ls.js
1
2 // show the installed versions of packages
3 //
4 // --parseable creates output like this:
5 // <fullpath>:<name@ver>:<realpath>:<flags>
6 // Flags are a :-separated list of zero or more indicators
7
8 module.exports = exports = ls
9
10 var npm = require("./npm.js")
11   , readInstalled = require("read-installed")
12   , log = require("npmlog")
13   , path = require("path")
14   , archy = require("archy")
15   , semver = require("semver")
16   , url = require("url")
17   , color = require("ansicolors")
18   , npa = require("npm-package-arg")
19
20 ls.usage = "npm ls"
21
22 ls.completion = require("./utils/completion/installed-deep.js")
23
24 function ls (args, silent, cb) {
25   if (typeof cb !== "function") cb = silent, silent = false
26
27   var dir = path.resolve(npm.dir, "..")
28
29   // npm ls 'foo@~1.3' bar 'baz@<2'
30   if (!args) args = []
31   else args = args.map(function (a) {
32     var p = npa(a)
33       , name = p.name
34       , ver = semver.validRange(p.rawSpec) || ""
35
36     return [ name, ver ]
37   })
38
39   var depth = npm.config.get("depth")
40   var opt = { depth: depth, log: log.warn, dev: true }
41   readInstalled(dir, opt, function (er, data) {
42     pruneNestedExtraneous(data)
43     filterByEnv(data)
44     var bfs = bfsify(data, args)
45       , lite = getLite(bfs)
46
47     if (er || silent) return cb(er, data, lite)
48
49     var long = npm.config.get("long")
50       , json = npm.config.get("json")
51       , out
52     if (json) {
53       var seen = []
54       var d = long ? bfs : lite
55       // the raw data can be circular
56       out = JSON.stringify(d, function (k, o) {
57         if (typeof o === "object") {
58           if (-1 !== seen.indexOf(o)) return "[Circular]"
59           seen.push(o)
60         }
61         return o
62       }, 2)
63     } else if (npm.config.get("parseable")) {
64       out = makeParseable(bfs, long, dir)
65     } else if (data) {
66       out = makeArchy(bfs, long, dir)
67     }
68     console.log(out)
69
70     if (args.length && !data._found) process.exitCode = 1
71
72     // if any errors were found, then complain and exit status 1
73     if (lite.problems && lite.problems.length) {
74       er = lite.problems.join("\n")
75     }
76     cb(er, data, lite)
77   })
78 }
79
80 function pruneNestedExtraneous (data, visited) {
81   visited = visited || []
82   visited.push(data)
83   for (var i in data.dependencies) {
84     if (data.dependencies[i].extraneous) {
85       data.dependencies[i].dependencies = {}
86     } else if (visited.indexOf(data.dependencies[i]) === -1) {
87       pruneNestedExtraneous(data.dependencies[i], visited)
88     }
89   }
90 }
91
92 function filterByEnv (data) {
93   var dev = npm.config.get("dev")
94   var production = npm.config.get("production")
95   if (dev === production) return
96   var dependencies = {}
97   var devDependencies = data.devDependencies || []
98   Object.keys(data.dependencies).forEach(function (name) {
99     var keys = Object.keys(devDependencies)
100     if (production && keys.indexOf(name) !== -1) return
101     if (dev && keys.indexOf(name) === -1) return
102     dependencies[name] = data.dependencies[name]
103   })
104   data.dependencies = dependencies
105 }
106
107 function alphasort (a, b) {
108   a = a.toLowerCase()
109   b = b.toLowerCase()
110   return a > b ? 1
111        : a < b ? -1 : 0
112 }
113
114 function isCruft (data) {
115   return data.extraneous && data.error && data.error.code === 'ENOTDIR'
116 }
117
118 function getLite (data, noname, depth) {
119   var lite = {}
120     , maxDepth = npm.config.get("depth")
121
122   if (typeof depth === 'undefined') depth = 0
123   if (!noname && data.name) lite.name = data.name
124   if (data.version) lite.version = data.version
125   if (data.extraneous) {
126     lite.extraneous = true
127     lite.problems = lite.problems || []
128     lite.problems.push( "extraneous: "
129                       + data.name + "@" + data.version
130                       + " " + (data.path || "") )
131   }
132
133   if (data._from)
134     lite.from = data._from
135
136   if (data._resolved)
137     lite.resolved = data._resolved
138
139   if (data.invalid) {
140     lite.invalid = true
141     lite.problems = lite.problems || []
142     lite.problems.push( "invalid: "
143                       + data.name + "@" + data.version
144                       + " " + (data.path || "") )
145   }
146
147   if (data.peerInvalid) {
148     lite.peerInvalid = true
149     lite.problems = lite.problems || []
150     lite.problems.push( "peer invalid: "
151                       + data.name + "@" + data.version
152                       + " " + (data.path || "") )
153   }
154
155   if (data.dependencies) {
156     var deps = Object.keys(data.dependencies)
157     if (deps.length) lite.dependencies = deps.map(function (d) {
158       var dep = data.dependencies[d]
159       if (typeof dep === "string") {
160         lite.problems = lite.problems || []
161         var p
162         if (data.depth > maxDepth) {
163           p = "max depth reached: "
164         } else {
165           p = "missing: "
166         }
167         p += d + "@" + dep
168           + ", required by "
169           + data.name + "@" + data.version
170         lite.problems.push(p)
171         return [d, { required: dep.requiredBy, missing: true }]
172       } else if (dep.peerMissing) {
173         lite.problems = lite.problems || []
174         dep.peerMissing.forEach(function (missing) {
175           var pdm = 'peer dep missing: ' +
176               missing.requires +
177               ', required by ' +
178               missing.requiredBy
179           lite.problems.push(pdm)
180         })
181         return [d, { required: dep, peerMissing: true }]
182       } else if (npm.config.get('json')) {
183         if (depth === maxDepth) delete dep.dependencies
184         return [d, getLite(dep, true, depth + 1)]
185       }
186       return [d, getLite(dep, true)]
187     }).reduce(function (deps, d) {
188       if (d[1].problems) {
189         lite.problems = lite.problems || []
190         lite.problems.push.apply(lite.problems, d[1].problems)
191       }
192       deps[d[0]] = d[1]
193       return deps
194     }, {})
195   }
196   return lite
197 }
198
199 function bfsify (root, args, current, queue, seen) {
200   // walk over the data, and turn it from this:
201   // +-- a
202   // |   `-- b
203   // |       `-- a (truncated)
204   // `--b (truncated)
205   // into this:
206   // +-- a
207   // `-- b
208   // which looks nicer
209   args = args || []
210   current = current || root
211   queue = queue || []
212   seen = seen || [root]
213   var deps = current.dependencies = current.dependencies || {}
214   Object.keys(deps).forEach(function (d) {
215     var dep = deps[d]
216     if (typeof dep !== "object") return
217     if (seen.indexOf(dep) !== -1) {
218       if (npm.config.get("parseable") || !npm.config.get("long")) {
219         delete deps[d]
220         return
221       } else {
222         dep = deps[d] = Object.create(dep)
223         dep.dependencies = {}
224       }
225     }
226     queue.push(dep)
227     seen.push(dep)
228   })
229
230   if (!queue.length) {
231     // if there were args, then only show the paths to found nodes.
232     return filterFound(root, args)
233   }
234   return bfsify(root, args, queue.shift(), queue, seen)
235 }
236
237 function filterFound (root, args) {
238   if (!args.length) return root
239   var deps = root.dependencies
240   if (deps) Object.keys(deps).forEach(function (d) {
241     var dep = filterFound(deps[d], args)
242
243     // see if this one itself matches
244     var found = false
245     for (var i = 0; !found && i < args.length; i ++) {
246       if (d === args[i][0]) {
247         found = semver.satisfies(dep.version, args[i][1], true)
248       }
249     }
250     // included explicitly
251     if (found) dep._found = true
252     // included because a child was included
253     if (dep._found && !root._found) root._found = 1
254     // not included
255     if (!dep._found) delete deps[d]
256   })
257   if (!root._found) root._found = false
258   return root
259 }
260
261 function makeArchy (data, long, dir) {
262   var out = makeArchy_(data, long, dir, 0)
263   return archy(out, "", { unicode: npm.config.get("unicode") })
264 }
265
266 function makeArchy_ (data, long, dir, depth, parent, d) {
267   if (typeof data === "string") {
268     if (depth -1 <= npm.config.get("depth")) {
269       // just missing
270       var unmet = "UNMET DEPENDENCY"
271       if (npm.color) {
272         unmet = color.bgBlack(color.red(unmet))
273       }
274       data = unmet + " " + d + "@" + data
275     } else {
276       data = d+"@"+ data
277     }
278     return data
279   }
280
281   var out = {}
282   // the top level is a bit special.
283   out.label = data._id || ""
284   if (data._found === true && data._id) {
285     if (npm.color) {
286       out.label = color.bgBlack(color.yellow(out.label.trim())) + " "
287     } else {
288       out.label = out.label.trim() + " "
289     }
290   }
291   if (data.link) out.label += " -> " + data.link
292
293   if (data.invalid) {
294     if (data.realName !== data.name) out.label += " ("+data.realName+")"
295     var invalid = "invalid"
296     if (npm.color) invalid = color.bgBlack(color.red(invalid))
297     out.label += " " + invalid
298   }
299
300   if (data.peerInvalid) {
301     var peerInvalid = "peer invalid"
302     if (npm.color) peerInvalid = color.bgBlack(color.red(peerInvalid))
303     out.label += " " + peerInvalid
304   }
305
306   if (data.extraneous && data.path !== dir) {
307     var extraneous = "extraneous"
308     if (npm.color) extraneous = color.bgBlack(color.green(extraneous))
309     out.label += " " + extraneous
310   }
311
312   // add giturl to name@version
313   if (data._resolved) {
314     var type = npa(data._resolved).type
315     var isGit = type === 'git' || type === 'hosted'
316     if (isGit) {
317       out.label += ' (' + data._resolved + ')'
318     }
319   }
320
321   if (long) {
322     if (dir === data.path) out.label += "\n" + dir
323     out.label += "\n" + getExtras(data, dir)
324   } else if (dir === data.path) {
325     if (out.label) out.label += " "
326     out.label += dir
327   }
328
329   // now all the children.
330   out.nodes = []
331   if (depth <= npm.config.get("depth")) {
332     out.nodes = Object.keys(data.dependencies || {})
333       .sort(alphasort).map(function (d) {
334         return makeArchy_(data.dependencies[d], long, dir, depth + 1, data, d)
335       })
336   }
337
338   if (out.nodes.length === 0 && data.path === dir) {
339     out.nodes = ["(empty)"]
340   }
341
342   return out
343 }
344
345 function getExtras (data) {
346   var extras = []
347
348   if (data.description) extras.push(data.description)
349   if (data.repository) extras.push(data.repository.url)
350   if (data.homepage) extras.push(data.homepage)
351   if (data._from) {
352     var from = data._from
353     if (from.indexOf(data.name + "@") === 0) {
354       from = from.substr(data.name.length + 1)
355     }
356     var u = url.parse(from)
357     if (u.protocol) extras.push(from)
358   }
359   return extras.join("\n")
360 }
361
362
363 function makeParseable (data, long, dir, depth, parent, d) {
364   depth = depth || 0
365
366   return [ makeParseable_(data, long, dir, depth, parent, d) ]
367   .concat(Object.keys(data.dependencies || {})
368     .sort(alphasort).map(function (d) {
369       return makeParseable(data.dependencies[d], long, dir, depth + 1, data, d)
370     }))
371   .filter(function (x) { return x })
372   .join("\n")
373 }
374
375 function makeParseable_ (data, long, dir, depth, parent, d) {
376   if (data.hasOwnProperty("_found") && data._found !== true) return ""
377
378   if (typeof data === "string") {
379     if (data.depth < npm.config.get("depth")) {
380       data = npm.config.get("long")
381            ? path.resolve(parent.path, "node_modules", d)
382            + ":"+d+"@"+JSON.stringify(data)+":INVALID:MISSING"
383            : ""
384     } else {
385       data = path.resolve(data.path || "", "node_modules", d || "")
386            + (npm.config.get("long")
387              ? ":" + d + "@" + JSON.stringify(data)
388              + ":" // no realpath resolved
389              + ":MAXDEPTH"
390              : "")
391     }
392
393     return data
394   }
395
396   if (!npm.config.get("long")) return data.path
397
398   return data.path
399        + ":" + (data._id || "")
400        + ":" + (data.realPath !== data.path ? data.realPath : "")
401        + (data.extraneous ? ":EXTRANEOUS" : "")
402        + (data.invalid ? ":INVALID" : "")
403        + (data.peerInvalid ? ":PEERINVALID" : "")
404 }