summaryrefslogtreecommitdiff
path: root/deps/npm/lib/outdated.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/lib/outdated.js')
-rw-r--r--deps/npm/lib/outdated.js369
1 files changed, 184 insertions, 185 deletions
diff --git a/deps/npm/lib/outdated.js b/deps/npm/lib/outdated.js
index c10f63a12e..fc6967faf6 100644
--- a/deps/npm/lib/outdated.js
+++ b/deps/npm/lib/outdated.js
@@ -9,112 +9,135 @@ const pickManifest = require('npm-pick-manifest')
const Arborist = require('@npmcli/arborist')
-const npm = require('./npm.js')
const output = require('./utils/output.js')
const usageUtil = require('./utils/usage.js')
const ansiTrim = require('./utils/ansi-trim.js')
-const usage = usageUtil('outdated',
- 'npm outdated [[<@scope>/]<pkg> ...]'
-)
+class Outdated {
+ constructor (npm) {
+ this.npm = npm
+ }
-function cmd (args, cb) {
- outdated(args)
- .then(() => cb())
- .catch(cb)
-}
+ /* istanbul ignore next - see test/lib/load-all-commands.js */
+ get usage () {
+ return usageUtil('outdated',
+ 'npm outdated [[<@scope>/]<pkg> ...]'
+ )
+ }
-async function outdated (args) {
- const opts = npm.flatOptions
- const global = path.resolve(npm.globalDir, '..')
- const where = opts.global
- ? global
- : npm.prefix
-
- const arb = new Arborist({
- ...opts,
- path: where,
- })
-
- const tree = await arb.loadActual()
- const list = await outdated_(tree, args, opts)
-
- // sorts list alphabetically
- const outdated = list.sort((a, b) => a.name.localeCompare(b.name))
-
- // return if no outdated packages
- if (outdated.length === 0 && !opts.json)
- return
-
- // display results
- if (opts.json)
- output(makeJSON(outdated, opts))
- else if (opts.parseable)
- output(makeParseable(outdated, opts))
- else {
- const outList = outdated.map(x => makePretty(x, opts))
- const outHead = ['Package',
- 'Current',
- 'Wanted',
- 'Latest',
- 'Location',
- 'Depended by',
- ]
-
- if (opts.long)
- outHead.push('Package Type', 'Homepage')
- const outTable = [outHead].concat(outList)
-
- if (opts.color)
- outTable[0] = outTable[0].map(heading => styles.underline(heading))
-
- const tableOpts = {
- align: ['l', 'r', 'r', 'r', 'l'],
- stringLength: s => ansiTrim(s).length,
- }
- output(table(outTable, tableOpts))
+ exec (args, cb) {
+ this.outdated(args).then(() => cb()).catch(cb)
}
-}
-async function outdated_ (tree, deps, opts) {
- const list = []
+ async outdated (args) {
+ this.opts = this.npm.flatOptions
+
+ const global = path.resolve(this.npm.globalDir, '..')
+ const where = this.opts.global
+ ? global
+ : this.npm.prefix
+
+ const arb = new Arborist({
+ ...this.opts,
+ path: where,
+ })
- const edges = new Set()
- function getEdges (nodes, type) {
- const getEdgesIn = (node) => {
- for (const edge of node.edgesIn)
- edges.add(edge)
+ this.edges = new Set()
+ this.list = []
+ this.tree = await arb.loadActual()
+
+ if (args.length !== 0) {
+ // specific deps
+ for (let i = 0; i < args.length; i++) {
+ const nodes = this.tree.inventory.query('name', args[i])
+ this.getEdges(nodes, 'edgesIn')
+ }
+ } else {
+ if (this.opts.all) {
+ // all deps in tree
+ const nodes = this.tree.inventory.values()
+ this.getEdges(nodes, 'edgesOut')
+ }
+ // top-level deps
+ this.getEdges()
}
- const getEdgesOut = (node) => {
- if (opts.global) {
- for (const child of node.children.values())
- edges.add(child)
- } else {
- for (const edge of node.edgesOut.values())
- edges.add(edge)
+ await Promise.all(Array.from(this.edges).map((edge) => {
+ return this.getOutdatedInfo(edge)
+ }))
+
+ // sorts list alphabetically
+ const outdated = this.list.sort((a, b) => a.name.localeCompare(b.name))
+
+ // return if no outdated packages
+ if (outdated.length === 0 && !this.opts.json)
+ return
+
+ // display results
+ if (this.opts.json)
+ output(this.makeJSON(outdated))
+ else if (this.opts.parseable)
+ output(this.makeParseable(outdated))
+ else {
+ const outList = outdated.map(x => this.makePretty(x))
+ const outHead = ['Package',
+ 'Current',
+ 'Wanted',
+ 'Latest',
+ 'Location',
+ 'Depended by',
+ ]
+
+ if (this.opts.long)
+ outHead.push('Package Type', 'Homepage')
+ const outTable = [outHead].concat(outList)
+
+ if (this.opts.color)
+ outTable[0] = outTable[0].map(heading => styles.underline(heading))
+
+ const tableOpts = {
+ align: ['l', 'r', 'r', 'r', 'l'],
+ stringLength: s => ansiTrim(s).length,
}
+ output(table(outTable, tableOpts))
}
+ }
+ getEdges (nodes, type) {
if (!nodes)
- return getEdgesOut(tree)
+ return this.getEdgesOut(this.tree)
for (const node of nodes) {
type === 'edgesOut'
- ? getEdgesOut(node)
- : getEdgesIn(node)
+ ? this.getEdgesOut(node)
+ : this.getEdgesIn(node)
+ }
+ }
+
+ getEdgesIn (node) {
+ for (const edge of node.edgesIn)
+ this.edges.add(edge)
+ }
+
+ getEdgesOut (node) {
+ if (this.opts.global) {
+ for (const child of node.children.values())
+ this.edges.add(child)
+ } else {
+ for (const edge of node.edgesOut.values())
+ this.edges.add(edge)
}
}
- async function getPackument (spec) {
+ async getPackument (spec) {
const packument = await pacote.packument(spec, {
- ...npm.flatOptions,
- fullMetadata: npm.flatOptions.long,
+ ...this.npm.flatOptions,
+ fullMetadata: this.npm.flatOptions.long,
preferOnline: true,
})
return packument
}
- async function getOutdatedInfo (edge) {
+ async getOutdatedInfo (edge) {
const spec = npa(edge.name)
const node = edge.to || edge
const { path, location } = node
@@ -125,7 +148,7 @@ async function outdated_ (tree, deps, opts) {
: edge.dev ? 'devDependencies'
: 'dependencies'
- for (const omitType of opts.omit || []) {
+ for (const omitType of this.opts.omit || []) {
if (node[omitType])
return
}
@@ -136,7 +159,7 @@ async function outdated_ (tree, deps, opts) {
return
try {
- const packument = await getPackument(spec)
+ const packument = await this.getPackument(spec)
const expected = edge.spec
// if it's not a range, version, or tag, skip it
try {
@@ -145,15 +168,15 @@ async function outdated_ (tree, deps, opts) {
} catch (err) {
return null
}
- const wanted = pickManifest(packument, expected, npm.flatOptions)
- const latest = pickManifest(packument, '*', npm.flatOptions)
+ const wanted = pickManifest(packument, expected, this.npm.flatOptions)
+ const latest = pickManifest(packument, '*', this.npm.flatOptions)
if (
!current ||
current !== wanted.version ||
wanted.version !== latest.version
) {
- list.push({
+ this.list.push({
name: edge.name,
path,
type,
@@ -167,7 +190,7 @@ async function outdated_ (tree, deps, opts) {
}
} catch (err) {
// silently catch and ignore ETARGET, E403 &
- // E404 errors, deps are just skipped {
+ // E404 errors, deps are just skipped
if (!(
err.code === 'ETARGET' ||
err.code === 'E403' ||
@@ -177,113 +200,89 @@ async function outdated_ (tree, deps, opts) {
}
}
- const p = []
- if (deps.length !== 0) {
- // specific deps
- for (let i = 0; i < deps.length; i++) {
- const nodes = tree.inventory.query('name', deps[i])
- getEdges(nodes, 'edgesIn')
- }
- } else {
- if (opts.all) {
- // all deps in tree
- const nodes = tree.inventory.values()
- getEdges(nodes, 'edgesOut')
- }
- // top-level deps
- getEdges()
- }
-
- for (const edge of edges)
- p.push(getOutdatedInfo(edge))
-
- await Promise.all(p)
- return list
-}
-
-// formatting functions
-function makePretty (dep, opts) {
- const {
- current = 'MISSING',
- location = '-',
- homepage = '',
- name,
- wanted,
- latest,
- type,
- dependent,
- } = dep
-
- const columns = [name, current, wanted, latest, location, dependent]
-
- if (opts.long) {
- columns[6] = type
- columns[7] = homepage
- }
-
- if (opts.color) {
- columns[0] = color[current === wanted ? 'yellow' : 'red'](columns[0]) // current
- columns[2] = color.green(columns[2]) // wanted
- columns[3] = color.magenta(columns[3]) // latest
- }
-
- return columns
-}
-
-// --parseable creates output like this:
-// <fullpath>:<name@wanted>:<name@installed>:<name@latest>:<dependedby>
-function makeParseable (list, opts) {
- return list.map(dep => {
+ // formatting functions
+ makePretty (dep) {
const {
+ current = 'MISSING',
+ location = '-',
+ homepage = '',
name,
- current,
wanted,
latest,
- path,
- dependent,
type,
- homepage,
- } = dep
- const out = [
- path,
- name + '@' + wanted,
- current ? (name + '@' + current) : 'MISSING',
- name + '@' + latest,
dependent,
- ]
- if (opts.long)
- out.push(type, homepage)
+ } = dep
- return out.join(':')
- }).join(os.EOL)
-}
+ const columns = [name, current, wanted, latest, location, dependent]
-function makeJSON (list, opts) {
- const out = {}
- list.forEach(dep => {
- const {
- name,
- current,
- wanted,
- latest,
- path,
- type,
- dependent,
- homepage,
- } = dep
- out[name] = {
- current,
- wanted,
- latest,
- dependent,
- location: path,
+ if (this.opts.long) {
+ columns[6] = type
+ columns[7] = homepage
}
- if (opts.long) {
- out[name].type = type
- out[name].homepage = homepage
+
+ if (this.opts.color) {
+ columns[0] = color[current === wanted ? 'yellow' : 'red'](columns[0]) // current
+ columns[2] = color.green(columns[2]) // wanted
+ columns[3] = color.magenta(columns[3]) // latest
}
- })
- return JSON.stringify(out, null, 2)
-}
-module.exports = Object.assign(cmd, { usage })
+ return columns
+ }
+
+ // --parseable creates output like this:
+ // <fullpath>:<name@wanted>:<name@installed>:<name@latest>:<dependedby>
+ makeParseable (list) {
+ return list.map(dep => {
+ const {
+ name,
+ current,
+ wanted,
+ latest,
+ path,
+ dependent,
+ type,
+ homepage,
+ } = dep
+ const out = [
+ path,
+ name + '@' + wanted,
+ current ? (name + '@' + current) : 'MISSING',
+ name + '@' + latest,
+ dependent,
+ ]
+ if (this.opts.long)
+ out.push(type, homepage)
+
+ return out.join(':')
+ }).join(os.EOL)
+ }
+
+ makeJSON (list) {
+ const out = {}
+ list.forEach(dep => {
+ const {
+ name,
+ current,
+ wanted,
+ latest,
+ path,
+ type,
+ dependent,
+ homepage,
+ } = dep
+ out[name] = {
+ current,
+ wanted,
+ latest,
+ dependent,
+ location: path,
+ }
+ if (this.opts.long) {
+ out[name].type = type
+ out[name].homepage = homepage
+ }
+ })
+ return JSON.stringify(out, null, 2)
+ }
+}
+module.exports = Outdated