npm-check-updates 3.1.25 → 3.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/bin/ncu +2 -1
- package/bin/npm-check-updates +1 -1
- package/lib/npm-check-updates.js +24 -16
- package/lib/package-managers/npm.js +115 -58
- package/lib/versionmanager.js +3 -2
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -90,6 +90,8 @@ Options
|
|
|
90
90
|
--cwd Used as current working directory for `spawn` in npm listing
|
|
91
91
|
--dep check only a specific section(s) of dependencies:
|
|
92
92
|
prod|dev|peer|optional|bundle (comma-delimited)
|
|
93
|
+
--engines-node include only packages that satisfy engines.node as
|
|
94
|
+
specified in the package file
|
|
93
95
|
-e, --error-level set the error-level. 1: exits with error code 0 if no
|
|
94
96
|
errors occur. 2: exits with error code 0 if no
|
|
95
97
|
packages need updating (useful for continuous
|
|
@@ -97,7 +99,8 @@ Options
|
|
|
97
99
|
-f, --filter include only package names matching the given string,
|
|
98
100
|
comma-or-space-delimited list, or /regex/
|
|
99
101
|
-g, --global check global packages instead of in the current project
|
|
100
|
-
-i, --interactive Enable interactive prompts for each dependency
|
|
102
|
+
-i, --interactive Enable interactive prompts for each dependency;
|
|
103
|
+
Implies -u unless one of the json options are set
|
|
101
104
|
-j, --jsonAll output new package file instead of human-readable
|
|
102
105
|
message
|
|
103
106
|
--jsonDeps Will return output like `jsonAll` but only lists
|
package/bin/ncu
CHANGED
|
@@ -23,10 +23,11 @@ program
|
|
|
23
23
|
.option('--cwd <path>', 'Used as current working directory for `spawn` in npm listing')
|
|
24
24
|
.option('--dep <dep>', 'check only a specific section(s) of dependencies: prod|dev|peer|optional|bundle (comma-delimited)')
|
|
25
25
|
.option('-e, --error-level <n>', 'set the error-level. 1: exits with error code 0 if no errors occur. 2: exits with error code 0 if no packages need updating (useful for continuous integration). Default is 1.', cint.partialAt(parseInt, 1, 10), 1)
|
|
26
|
+
.option('--engines-node', 'upgrade to version which satisfies engines.node range')
|
|
26
27
|
.option('-f, --filter <matches>', 'include only package names matching the given string, comma-or-space-delimited list, or /regex/')
|
|
27
28
|
.option('-g, --global', 'check global packages instead of in the current project')
|
|
28
29
|
// program.json is set to true in programInit if any options that begin with 'json' are true
|
|
29
|
-
.option('-i, --interactive', 'Enable interactive prompts for each dependency')
|
|
30
|
+
.option('-i, --interactive', 'Enable interactive prompts for each dependency; implies -u unless one of the json options are set')
|
|
30
31
|
.option('-j, --jsonAll', 'output new package file instead of human-readable message')
|
|
31
32
|
.option('--jsonDeps', 'Will return output like `jsonAll` but only lists `dependencies`, `devDependencies`, and `optionalDependencies` of the new package data.')
|
|
32
33
|
.option('--jsonUpgraded', 'output upgraded dependencies in json')
|
package/bin/npm-check-updates
CHANGED
package/lib/npm-check-updates.js
CHANGED
|
@@ -100,8 +100,10 @@ function createDependencyTable() {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* @param args
|
|
104
|
-
* @param args.
|
|
103
|
+
* @param {object} args
|
|
104
|
+
* @param {object} args.from
|
|
105
|
+
* @param {object} args.to
|
|
106
|
+
* @returns {Table}
|
|
105
107
|
*/
|
|
106
108
|
function toDependencyTable(args) {
|
|
107
109
|
const table = createDependencyTable();
|
|
@@ -144,7 +146,7 @@ function analyzeGlobalPackages(options) {
|
|
|
144
146
|
print(options, latest, 'silly');
|
|
145
147
|
|
|
146
148
|
const upgradedPackageNames = Object.keys(upgraded);
|
|
147
|
-
|
|
149
|
+
printUpgrades(options, {
|
|
148
150
|
current: globalPackages,
|
|
149
151
|
upgraded,
|
|
150
152
|
latest,
|
|
@@ -164,8 +166,6 @@ function analyzeGlobalPackages(options) {
|
|
|
164
166
|
} else if (instruction.length) {
|
|
165
167
|
print(options, '\n' + chalk.cyan('ncu') + ' itself cannot upgrade global packages. Run the following to upgrade all global packages: \n\n' + chalk.cyan('npm -g install ' + instruction) + '\n');
|
|
166
168
|
}
|
|
167
|
-
|
|
168
|
-
return upgradePromise;
|
|
169
169
|
});
|
|
170
170
|
});
|
|
171
171
|
}
|
|
@@ -188,6 +188,10 @@ function analyzeProjectDependencies(options, pkgData, pkgFile) {
|
|
|
188
188
|
|
|
189
189
|
print(options, `Fetching ${vm.getVersionTarget(options)} versions...`, 'verbose');
|
|
190
190
|
|
|
191
|
+
if (options.enginesNode) {
|
|
192
|
+
options.enginesNode = _.get(pkg, 'engines.node');
|
|
193
|
+
}
|
|
194
|
+
|
|
191
195
|
return vm.upgradePackageDefinitions(current, options).then(async ([upgraded, latest]) => {
|
|
192
196
|
const {newPkgData, selectedNewDependencies} = await vm.upgradePackageData(pkgData, current, upgraded, latest, options);
|
|
193
197
|
|
|
@@ -255,6 +259,7 @@ function analyzeProjectDependencies(options, pkgData, pkgFile) {
|
|
|
255
259
|
* @param {Object} args.upgraded - The packages that should be upgraded.
|
|
256
260
|
* @param {number} args.numUpgraded - The number of upgraded packages
|
|
257
261
|
* @param {number} args.total - The total number of all possible upgrades
|
|
262
|
+
* @returns {void}
|
|
258
263
|
*/
|
|
259
264
|
function printUpgrades(options, {current, upgraded, numUpgraded, total}) {
|
|
260
265
|
print(options, '');
|
|
@@ -290,6 +295,11 @@ function printUpgrades(options, {current, upgraded, numUpgraded, total}) {
|
|
|
290
295
|
/** Initializes and consolidates options from the cli. */
|
|
291
296
|
function initOptions(options) {
|
|
292
297
|
|
|
298
|
+
const json = _(options)
|
|
299
|
+
.keys()
|
|
300
|
+
.filter(_.partial(_.startsWith, _, 'json', 0))
|
|
301
|
+
.some(_.propertyOf(options));
|
|
302
|
+
|
|
293
303
|
return Object.assign({}, options, {
|
|
294
304
|
filter: options.args.join(' ') || options.filter,
|
|
295
305
|
// convert silent option to loglevel silent
|
|
@@ -298,10 +308,9 @@ function initOptions(options) {
|
|
|
298
308
|
// default to 0, except when newest or greatest are set
|
|
299
309
|
pre: options.pre ? Boolean(Number(options.pre)) : options.newest || options.greatest,
|
|
300
310
|
// add shortcut for any keys that start with 'json'
|
|
301
|
-
json
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
.some(_.propertyOf(options))
|
|
311
|
+
json,
|
|
312
|
+
// imply upgrade in interactive mode when json is not specified as the output
|
|
313
|
+
upgrade: options.interactive && options.upgrade === undefined ? !json : options.upgrade
|
|
305
314
|
});
|
|
306
315
|
}
|
|
307
316
|
|
|
@@ -382,14 +391,13 @@ async function findPackage(options) {
|
|
|
382
391
|
return Promise.all([pkgData, pkgFile]);
|
|
383
392
|
}
|
|
384
393
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
process.on('unhandledRejection', err => {
|
|
390
|
-
throw err;
|
|
391
|
-
});
|
|
394
|
+
// exit with non-zero error code when there is an unhandled promise rejection
|
|
395
|
+
process.on('unhandledRejection', err => {
|
|
396
|
+
throw err;
|
|
397
|
+
});
|
|
392
398
|
|
|
399
|
+
/** main entry point */
|
|
400
|
+
async function run(options = {}) {
|
|
393
401
|
// if not executed on the command-line (i.e. executed as a node module), set some defaults
|
|
394
402
|
if (!options.cli) {
|
|
395
403
|
options = _.defaults({}, options, {
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
const _ = require('lodash');
|
|
3
3
|
const cint = require('cint');
|
|
4
4
|
const semver = require('semver');
|
|
5
|
-
const versionUtil
|
|
6
|
-
const spawn
|
|
5
|
+
const versionUtil = require('../version-util.js');
|
|
6
|
+
const spawn = require('spawn-please');
|
|
7
7
|
const pacote = require('pacote');
|
|
8
8
|
|
|
9
|
+
const TIME_FIELDS = ['modified', 'created'];
|
|
10
|
+
|
|
9
11
|
// needed until pacote supports full npm config compatibility
|
|
10
12
|
// See: https://github.com/zkat/pacote/issues/156
|
|
11
13
|
const npmConfig = {};
|
|
@@ -43,48 +45,78 @@ function parseJson(result, data) {
|
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
/**
|
|
48
|
+
* Returns the value of one of the properties retrieved by npm view.
|
|
46
49
|
* @param {string} packageName Name of the package
|
|
47
50
|
* @param {string} field Field such as "versions" or "dist-tags.latest" are parsed from the pacote result (https://www.npmjs.com/package/pacote#packument)
|
|
48
51
|
* @param {string} currentVersion
|
|
49
|
-
* @returns {Promise}
|
|
52
|
+
* @returns {Promise} Promised result
|
|
53
|
+
*/
|
|
54
|
+
function viewOne(packageName, field, currentVersion) {
|
|
55
|
+
return viewMany(packageName, [field], currentVersion)
|
|
56
|
+
.then(result => result && result[field]);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Returns an object of specified values retrieved by npm view.
|
|
61
|
+
* @param {string} packageName Name of the package
|
|
62
|
+
* @param {string[]} fields Array of fields like versions, time, version
|
|
63
|
+
* @param {string} currentVersion
|
|
64
|
+
* @returns {Promise} Promised result
|
|
50
65
|
*/
|
|
51
|
-
function
|
|
66
|
+
function viewMany(packageName, fields, currentVersion) {
|
|
52
67
|
if (currentVersion && (!semver.validRange(currentVersion) || versionUtil.isWildCard(currentVersion))) {
|
|
53
|
-
return Promise.resolve();
|
|
68
|
+
return Promise.resolve({});
|
|
54
69
|
}
|
|
55
70
|
|
|
56
|
-
npmConfig['full-metadata'] =
|
|
71
|
+
npmConfig['full-metadata'] = _.includes(fields, 'time');
|
|
57
72
|
|
|
58
|
-
return pacote.packument(packageName, npmConfig).then(result =>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
73
|
+
return pacote.packument(packageName, npmConfig).then(result =>
|
|
74
|
+
fields.reduce((accum, field) => Object.assign(
|
|
75
|
+
accum,
|
|
76
|
+
{
|
|
77
|
+
[field]: field.startsWith('dist-tags.') ?
|
|
78
|
+
result.versions[_.get(result, field)] :
|
|
79
|
+
result[field]
|
|
63
80
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
} else {
|
|
67
|
-
return result[field];
|
|
68
|
-
}
|
|
69
|
-
});
|
|
81
|
+
), {})
|
|
82
|
+
);
|
|
70
83
|
}
|
|
71
84
|
|
|
72
85
|
/**
|
|
73
86
|
* @param {Array} versions Array of all available versions
|
|
87
|
+
* @param {Boolean} pre Enabled prerelease?
|
|
74
88
|
* @returns {Array} An array of versions with the release versions filtered out
|
|
75
89
|
*/
|
|
76
|
-
function filterOutPrereleaseVersions(versions) {
|
|
77
|
-
return _.filter(versions,
|
|
90
|
+
function filterOutPrereleaseVersions(versions, pre) {
|
|
91
|
+
return _.filter(versions, version => pre || !isPre(version));
|
|
78
92
|
}
|
|
79
93
|
|
|
80
94
|
/**
|
|
81
|
-
* @param
|
|
82
|
-
* @returns {boolean}
|
|
95
|
+
* @param {String} version
|
|
96
|
+
* @returns {boolean} True if the version is any kind of prerelease: alpha, beta, rc, pre
|
|
83
97
|
*/
|
|
84
98
|
function isPre(version) {
|
|
85
99
|
return versionUtil.getPrecision(version) === 'release';
|
|
86
100
|
}
|
|
87
101
|
|
|
102
|
+
/**
|
|
103
|
+
* @param {{}} versions Object with all versions
|
|
104
|
+
* @param {String} enginesNode Package engines.node range
|
|
105
|
+
* @returns {Array} An array of versions which satisfies engines.node range
|
|
106
|
+
*/
|
|
107
|
+
function doesSatisfyEnginesNode(versions, enginesNode) {
|
|
108
|
+
if (!enginesNode) {
|
|
109
|
+
return _.keys(versions);
|
|
110
|
+
}
|
|
111
|
+
const minVersion = _.get(semver.minVersion(enginesNode), 'version');
|
|
112
|
+
if (!minVersion) {
|
|
113
|
+
return _.keys(versions);
|
|
114
|
+
}
|
|
115
|
+
return _.keys(versions).filter(version => {
|
|
116
|
+
let versionEnginesNode = _.get(versions[version], 'engines.node');
|
|
117
|
+
return versionEnginesNode && semver.satisfies(minVersion, versionEnginesNode);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
88
120
|
|
|
89
121
|
/**
|
|
90
122
|
* Spawn npm requires a different command on Windows.
|
|
@@ -159,22 +191,25 @@ module.exports = {
|
|
|
159
191
|
/**
|
|
160
192
|
* @param {string} packageName
|
|
161
193
|
* @param {string} currentVersion
|
|
162
|
-
* @param {
|
|
194
|
+
* @param {{}} options
|
|
163
195
|
* @returns {Promise}
|
|
164
196
|
*/
|
|
165
|
-
latest(packageName, currentVersion,
|
|
166
|
-
return
|
|
167
|
-
.then(
|
|
168
|
-
// if latest is not a prerelease version, return it
|
|
169
|
-
// if latest is a prerelease version and --pre is specified, return it
|
|
170
|
-
if
|
|
171
|
-
|
|
197
|
+
latest(packageName, currentVersion, options) {
|
|
198
|
+
return viewOne(packageName, 'dist-tags.latest', currentVersion)
|
|
199
|
+
.then(latest => {
|
|
200
|
+
// if latest exists and latest is not a prerelease version, return it
|
|
201
|
+
// if latest exists and latest is a prerelease version and --pre is specified, return it
|
|
202
|
+
// if latest exists and latest not satisfies min version of engines.node
|
|
203
|
+
if (latest && (!isPre(latest.version) || options.pre) && doesSatisfyEnginesNode({[latest.version]: latest}, options.enginesNode).length) {
|
|
204
|
+
return latest.version;
|
|
172
205
|
// if latest is a prerelease version and --pre is not specified, find the next
|
|
173
206
|
// version that is not a prerelease
|
|
174
207
|
} else {
|
|
175
|
-
return
|
|
176
|
-
.then(
|
|
177
|
-
|
|
208
|
+
return viewOne(packageName, 'versions', currentVersion)
|
|
209
|
+
.then(versions => {
|
|
210
|
+
versions = doesSatisfyEnginesNode(versions, options.enginesNode);
|
|
211
|
+
return _.last(filterOutPrereleaseVersions(versions, options.pre));
|
|
212
|
+
});
|
|
178
213
|
}
|
|
179
214
|
});
|
|
180
215
|
},
|
|
@@ -182,55 +217,77 @@ module.exports = {
|
|
|
182
217
|
/**
|
|
183
218
|
* @param {string} packageName
|
|
184
219
|
* @param {string} currentVersion
|
|
185
|
-
* @param {
|
|
220
|
+
* @param {{}} options
|
|
186
221
|
* @returns {Promise}
|
|
187
222
|
*/
|
|
188
|
-
newest(packageName, currentVersion,
|
|
189
|
-
return
|
|
190
|
-
.then(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
223
|
+
newest(packageName, currentVersion, options) {
|
|
224
|
+
return viewMany(packageName, ['time', 'versions'], currentVersion)
|
|
225
|
+
.then(result => {
|
|
226
|
+
const versions = doesSatisfyEnginesNode(result.versions, options.enginesNode);
|
|
227
|
+
return _.keys(result.time).reduce((accum, key) =>
|
|
228
|
+
accum.concat(_.includes(TIME_FIELDS, key) || _.includes(versions, key) ? key : []), []
|
|
229
|
+
);
|
|
230
|
+
})
|
|
231
|
+
.then(_.partialRight(_.pullAll, TIME_FIELDS))
|
|
232
|
+
.then(versions =>
|
|
233
|
+
_.last(filterOutPrereleaseVersions(versions, options.pre))
|
|
234
|
+
);
|
|
195
235
|
},
|
|
196
236
|
|
|
197
237
|
/**
|
|
198
238
|
* @param {string} packageName
|
|
199
239
|
* @param {string} currentVersion
|
|
200
|
-
* @param {
|
|
240
|
+
* @param {{}} options
|
|
201
241
|
* @returns {Promise}
|
|
202
242
|
*/
|
|
203
|
-
greatest(packageName, currentVersion,
|
|
204
|
-
return
|
|
205
|
-
.then(versions =>
|
|
206
|
-
|
|
207
|
-
|
|
243
|
+
greatest(packageName, currentVersion, options) {
|
|
244
|
+
return viewOne(packageName, 'versions', currentVersion)
|
|
245
|
+
.then(versions =>
|
|
246
|
+
_.last(filterOutPrereleaseVersions(
|
|
247
|
+
doesSatisfyEnginesNode(versions, options.enginesNode),
|
|
248
|
+
options.pre
|
|
249
|
+
))
|
|
250
|
+
);
|
|
208
251
|
},
|
|
209
252
|
|
|
210
253
|
/**
|
|
211
254
|
* @param {string} packageName
|
|
212
255
|
* @param {string} currentVersion
|
|
213
|
-
* @param {
|
|
256
|
+
* @param {{}} options
|
|
214
257
|
* @returns {Promise}
|
|
215
258
|
*/
|
|
216
|
-
greatestMajor(packageName, currentVersion,
|
|
217
|
-
return
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
259
|
+
greatestMajor(packageName, currentVersion, options) {
|
|
260
|
+
return viewOne(packageName, 'versions', currentVersion)
|
|
261
|
+
.then(versions =>
|
|
262
|
+
versionUtil.findGreatestByLevel(
|
|
263
|
+
filterOutPrereleaseVersions(
|
|
264
|
+
doesSatisfyEnginesNode(versions, options.enginesNode),
|
|
265
|
+
options.pre
|
|
266
|
+
),
|
|
267
|
+
currentVersion,
|
|
268
|
+
'major'
|
|
269
|
+
)
|
|
270
|
+
);
|
|
221
271
|
},
|
|
222
272
|
|
|
223
273
|
/**
|
|
224
274
|
* @param {string} packageName
|
|
225
275
|
* @param {string} currentVersion
|
|
226
|
-
* @param {
|
|
276
|
+
* @param {{}} options
|
|
227
277
|
* @returns {Promise}
|
|
228
278
|
*/
|
|
229
|
-
greatestMinor(packageName, currentVersion,
|
|
230
|
-
return
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
279
|
+
greatestMinor(packageName, currentVersion, options) {
|
|
280
|
+
return viewOne(packageName, 'versions', currentVersion)
|
|
281
|
+
.then(versions =>
|
|
282
|
+
versionUtil.findGreatestByLevel(
|
|
283
|
+
filterOutPrereleaseVersions(
|
|
284
|
+
doesSatisfyEnginesNode(versions, options.enginesNode),
|
|
285
|
+
options.pre
|
|
286
|
+
),
|
|
287
|
+
currentVersion,
|
|
288
|
+
'minor'
|
|
289
|
+
)
|
|
290
|
+
);
|
|
234
291
|
},
|
|
235
292
|
|
|
236
293
|
defaultPrefix
|
package/lib/versionmanager.js
CHANGED
|
@@ -253,7 +253,8 @@ function upgradePackageDefinitions(currentDependencies, options) {
|
|
|
253
253
|
pre: options.pre,
|
|
254
254
|
packageManager: options.packageManager,
|
|
255
255
|
json: options.json,
|
|
256
|
-
loglevel: options.loglevel
|
|
256
|
+
loglevel: options.loglevel,
|
|
257
|
+
enginesNode: options.enginesNode
|
|
257
258
|
}).then(latestVersions => {
|
|
258
259
|
|
|
259
260
|
const upgradedDependencies = upgradeDependencies(currentDependencies, latestVersions, {
|
|
@@ -422,7 +423,7 @@ function queryVersions(packageMap, options = {}) {
|
|
|
422
423
|
* @returns {Promise}
|
|
423
424
|
*/
|
|
424
425
|
function getPackageVersionProtected(dep) {
|
|
425
|
-
return getPackageVersion(dep, packageMap[dep], options
|
|
426
|
+
return getPackageVersion(dep, packageMap[dep], options).catch(err => {
|
|
426
427
|
if (err && (err.message || err).toString().match(/E404|ENOTFOUND|404 Not Found/i)) {
|
|
427
428
|
return null;
|
|
428
429
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "npm-check-updates",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"author": "Tomas Junnonen <tomas1@gmail.com>",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"contributors": [
|
|
@@ -69,11 +69,11 @@
|
|
|
69
69
|
"chai": "^4.2.0",
|
|
70
70
|
"chai-as-promised": "^7.1.1",
|
|
71
71
|
"chai-string": "^1.5.0",
|
|
72
|
-
"chokidar-cli": "^2.
|
|
73
|
-
"eslint": "^6.
|
|
74
|
-
"mocha": "^6.2.
|
|
72
|
+
"chokidar-cli": "^2.1.0",
|
|
73
|
+
"eslint": "^6.6.0",
|
|
74
|
+
"mocha": "^6.2.2",
|
|
75
75
|
"should": "^13.2.3",
|
|
76
|
-
"snyk": "^1.
|
|
76
|
+
"snyk": "^1.239.5",
|
|
77
77
|
"tmp": "0.1.0"
|
|
78
78
|
},
|
|
79
79
|
"files": [
|