From 189cdd3657906917fbc5bc0ab70150e2d4132b2b Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Mon, 17 Aug 2020 10:10:56 +0100 Subject: [PATCH 01/10] feat: wip update and esmodule --- CHANGELOG.md | 14 + lib/batch.js | 36 - lib/david.js | 237 ---- lib/npm.js | 56 - lib/version.js | 87 -- package-lock.json | 3189 ++------------------------------------------- package.json | 10 +- src/david.js | 193 +++ 8 files changed, 290 insertions(+), 3532 deletions(-) delete mode 100644 lib/batch.js delete mode 100644 lib/david.js delete mode 100644 lib/npm.js delete mode 100644 lib/version.js create mode 100644 src/david.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 272e4f5..7a23bd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## 12.0.0 - 2020-08-xx + +This release switches the code base to use esmodules and promises and removes the npm dependency in favour of calling the API directly. It has breaking API changes: + +- `getDependencies` has been renamed to `dependenciesInfo`, it now returns a promise and no longer takes a callback. The following changes to the options this function takes have been made: + - `versions` option has been removed, dependency versions are always returned + - `rangeVersions` option has been removed, simply filter versions by `semver.satisfies(version, range)` + - `loose` option should now be passed as `{ semver: { loose: true } }` + - `errors.E404` option has changed to `ignoreNotFound` and has the opposite meaning i.e. 404 errors are thrown by default + - `errors.EDEPTYPE` and `errors.ESCM` options have merged into `ignoreNonSemverRange`. Any version ranges that are not a semver version or range will be ignored when set to `true`. + - `ignore` option has been renamed to `ignoreModules`. +- `getUpdatedDependencies` has been removed, use `dependenciesInfo` and then `isUpdated` to filter out the dependencies that are not updates. +- A new function `moduleInfo` has been added (and exported) to get the module versions info for a single module. It is used by `dependenciesInfo` for each module. + ## 11.0.0 - 2017-03-02 - Update dependencies diff --git a/lib/batch.js b/lib/batch.js deleted file mode 100644 index 189de65..0000000 --- a/lib/batch.js +++ /dev/null @@ -1,36 +0,0 @@ -function Batch () { - if (!(this instanceof Batch)) return new Batch() - this._batch = {} -} - -/** - * Create or add a callback function to the end of a batch for a given key. - * @param key - * @param cb - */ -Batch.prototype.push = function (key, cb) { - this._batch[key] = this._batch[key] || [] - this._batch[key].push(cb) -} - -/** - * Determine if there is a batch for the given key. - * @param {String} key - * @returns {boolean} - */ -Batch.prototype.exists = function (key) { - return this._batch[key] != null -} - -/** - * Call all the batched callback functions for a key and remove them. - * @param {String} key ID of the batch operation - * @param {Function} fn Function to call for each - */ -Batch.prototype.call = function (key, cb) { - var cbs = this._batch[key] - this._batch[key] = null - cbs.forEach(cb) -} - -module.exports = Batch diff --git a/lib/david.js b/lib/david.js deleted file mode 100644 index d155b6a..0000000 --- a/lib/david.js +++ /dev/null @@ -1,237 +0,0 @@ -/** - * david - * https://github.com/alanshaw/david - * - * Copyright (c) 2013 Alan Shaw - * Licensed under the MIT license. - */ - -var multimatch = require('multimatch') -var parallel = require('async/parallel') -var semver = require('semver') -var Version = require('./version') -var Npm = require('./npm') - -// Convert dependencies specified as an array to an object -function normaliseDeps (deps) { - if (Array.isArray(deps)) { - deps = deps.reduce(function (d, depName) { - d[depName] = '*' - return d - }, {}) - } - return deps -} - -/** - * Given dep, an object obtained by calling getDependencies, determine whether dep.required (the version specified - * in package.json) is out of date wrt dep.stable or dep.latest. - * @param {Object} dep - * @param {Object} [opts] Options - * @param {Boolean} [opts.stable] Consider only stable packages - * @param {Boolean} [opts.loose] Use loose option when querying semver - * @returns {boolean} - */ -function isUpdated (dep, opts) { - opts = opts || {} - - var required = dep.required || '*' - - // TODO: Handle tags correctly - if (required !== 'latest' && required !== '*') { - var range = semver.validRange(required, opts.loose) || '' - var version = opts.stable ? dep.stable : dep.latest - - if (version) { - if (!range) { - return true - } else if (!semver.satisfies(version, range, opts.loose)) { - if (opts.stable && semver.gtr(version, range, opts.loose)) { - return true - } else if (!opts.stable) { - return true - } - } - } - } - return false -} - -exports.isUpdated = isUpdated - -/** - * Given the options passed to david, figure out the dep type. - */ -function depType (opts) { - if (opts.dev) { - return 'devDependencies' - } else if (opts.optional) { - return 'optionalDependencies' - } else if (opts.peer) { - return 'peerDependencies' - } - return 'dependencies' -} - -/** - * Get a list of dependencies for the passed manifest. - * @param {Object} manifest Parsed package.json file contents - * @param {Object|Function} [opts] Options or callback - * @param {Boolean} [opts.dev] Consider devDependencies - * @param {Boolean} [opts.optional] Consider optionalDependencies - * @param {Boolean} [opts.peer] Consider peerDependencies - * @param {Boolean} [opts.loose] Use loose option when querying semver - * @param {Object} [opts.npm] npm configuration options - * @param {Boolean} [opts.error.E404] Error on 404s - * @param {Boolean} [opts.versions] For each dependency, return the available versions - * @param {Boolean} [opts.rangeVersions] For each dependency, return the available versions for the range specified in the package.json - * @param {Array} [opts.ignore] List of dependency names or globs to ignore - * @param {Function} cb Function that receives the results - */ -function getDependencies (manifest, opts, cb) { - manifest = manifest || {} - - // Allow callback to be passed as second parameter - if (!cb) { - cb = opts - opts = {} - } else { - opts = opts || {} - } - - opts.error = opts.error || {} - opts.ignore = opts.ignore || [] - - if (manifest.david && manifest.david.ignore) { - opts.ignore = opts.ignore.concat(manifest.david.ignore) - } - - var pkgs = {} - var deps = normaliseDeps(manifest[depType(opts)] || {}) - var depNames = Object.keys(deps) - var error // Return any error that occurred but don't stop processing - - if (!depNames.length) { - return setImmediate(function () { cb(null, pkgs) }) - } - - var tasks = depNames.map(function (depName) { - return function (cb) { - if (multimatch(depName, opts.ignore).length > 0) { - return cb() - } - - var err - - if (Object.prototype.toString.call(deps[depName]) !== '[object String]') { - err = new Error('Non-string dependency: ' + deps[depName]) - err.code = 'EDEPTYPE' - - if (!opts.error.EDEPTYPE) { - pkgs[depName] = { required: deps[depName], warn: err } - } else { - error = err - } - - return cb() - } - - if (Version.isScm(deps[depName])) { - err = new Error('SCM dependency: ' + deps[depName]) - err.code = 'ESCM' - - if (!opts.error.ESCM) { - pkgs[depName] = { required: deps[depName], warn: err } - } else { - error = err - } - return cb() - } - - Npm.getVersionsInfo(depName, opts, function (err, versionsInfo) { - if (err) { - if (!opts.error.E404 && err.code === 'E404') { - if (err === '404 Not Found') { - err = new Error('404 Not Found: ' + depName) - err.pkgid = depName - err.statusCode = 404 - err.code = 'E404' - } - - pkgs[depName] = { required: deps[depName], warn: err } - } else { - error = err - } - return cb() - } - - try { - var latestVersionInfo = Version.getLatest(versionsInfo.current, versionsInfo.versions, opts) - - pkgs[depName] = { - required: deps[depName], - stable: latestVersionInfo.stable, - latest: latestVersionInfo.latest - } - - if (opts.versions) { - pkgs[depName].versions = versionsInfo.versions - } - - if (opts.rangeVersions) { - pkgs[depName].rangeVersions = Version.getVersionsInRange(deps[depName], versionsInfo.versions, opts.loose) - } - } catch (err) { - error = err - } - - cb() - }) - } - }) - - parallel(tasks, function () { cb(error, pkgs) }) -} - -exports.getDependencies = getDependencies - -/** - * Get a list of updated packages for the passed manifest. - * @param {Object} manifest Parsed package.json file contents - * @param {Object|Function} [opts] Options or callback - * @param {Boolean} [opts.stable] Consider only stable packages - * @param {Boolean} [opts.dev] Consider devDependencies - * @param {Boolean} [opts.optional] Consider optionalDependencies - * @param {Boolean} [opts.peer] Consider peerDependencies - * @param {Boolean} [opts.loose] Use loose option when querying semver - * @param {Object} [opts.npm] npm configuration options - * @param {Boolean} [opts.error.E404] Error on 404s - * @param {Boolean} [opts.versions] For each dependency, return the available versions - * @param {Boolean} [opts.rangeVersions] For each dependency, return the available versions for the range specified in the package.json - * @param {Array} [opts.ignore] List of dependency names to ignore - * @param {Function} cb Function that receives the results - */ -exports.getUpdatedDependencies = function (manifest, opts, cb) { - if (!cb) { - cb = opts - opts = {} - } else { - opts = opts || {} - } - opts.error = opts.error || {} - - getDependencies(manifest, opts, function (err, pkgs) { - if (err) return cb(err) - - // Filter out the non-updated dependencies - Object.keys(pkgs).forEach(function (depName) { - if (pkgs[depName].warn) return - - if (!isUpdated(pkgs[depName], opts)) { - delete pkgs[depName] - } - }) - - cb(err, pkgs) - }) -} diff --git a/lib/npm.js b/lib/npm.js deleted file mode 100644 index f6edd2e..0000000 --- a/lib/npm.js +++ /dev/null @@ -1,56 +0,0 @@ -var npm = require('npm') -var Batch = require('./batch') - -var batch = new Batch() - -/** - * Get info about the versions for this dependency. Returns an object with - * `current` and `versions` properties. Where `current` is the version you'd - * get when you `npm install [package]` and `versions` is a sorted array of - * available versions for the dependency. - * @param {String} name Dependency name - * @param {Object} opts Options - * @param {Object} [opts.npm] npm configuration options - */ -function getVersionsInfo (name, opts, cb) { - if (batch.exists(name)) { - return batch.push(name, cb) - } - - batch.push(name, cb) - - npm.load(opts.npm || {}, function (err) { - if (err) return batch.call(name, function (cb) { cb(err) }) - - npm.commands.view([name, 'versions', 'time'], true, function (err, data) { - if (err) return batch.call(name, function (cb) { cb(err) }) - - var currentVersion = Object.keys(data)[0] - var versions = null - - // `npm view 0 versions` returns {} - if (!currentVersion) { - return batch.call(name, function (cb) { - cb(new Error('Failed to get versions for ' + name)) - }) - } - - // Some packages simply don't have a time object - if (data[currentVersion].time) { - versions = data[currentVersion].versions.sort(function (a, b) { - a = data[currentVersion].time[a] - b = data[currentVersion].time[b] - return (a < b ? -1 : (a > b ? 1 : 0)) - }) - } else { - versions = data[currentVersion].versions - } - - batch.call(name, function (cb) { - cb(null, { current: currentVersion, versions: versions }) - }) - }) - }) -} - -exports.getVersionsInfo = getVersionsInfo diff --git a/lib/version.js b/lib/version.js deleted file mode 100644 index f5512b9..0000000 --- a/lib/version.js +++ /dev/null @@ -1,87 +0,0 @@ -var semver = require('semver') - -var unstablePattern = /[a-z+-]/i - -/** - * Determine if a version is a stable version or not. - * @param {String} version - * @return {Boolean} - */ -function isStable (version) { - return !unstablePattern.test(version || '') -} - -exports.isStable = isStable - -/** - * Determine if a version is a SCM URL or not. - * @param {String} version - * @return {Boolean} - */ -function isScm (version) { - var scmPrefixes = ['git:', 'git+ssh:', 'https:', 'git+https:'] - var blacklisted = scmPrefixes.filter(function (prefix) { - return version.indexOf(prefix) === 0 - }) - return !!blacklisted.length -} - -exports.isScm = isScm - -/** - * Get the latest stable version from a list of versions in ascending order. - * @param {Array} versions - * @return {String} - */ -function getLatestStable (versions) { - versions = versions.slice() - while (versions.length) { - var version = versions.pop() - if (isStable(version)) { - return version - } - } - return null -} - -exports.getLatestStable = getLatestStable - -/** - * Get the latest version and latest stable version - * @param {String} current The version you get when you `npm install [package]` - * @param {Array} versions All versions available - * @param {Object} opts Options - * @param {Boolean} [opts.loose] Use loose option when querying semver - */ -function getLatest (current, versions, opts) { - var stable = current - var latest = versions[versions.length - 1] - - if (!isStable(stable)) { - stable = getLatestStable(versions) - } - - // getLatestStable might not have found a stable version - if (stable) { - // Latest is the most recent version with higher version than stable - for (var i = versions.length - 1; i >= 0; i--) { - // If !opts.loose then this may throw - if (semver.gt(versions[i], stable, opts.loose)) { - latest = versions[i] - break - } - } - } - - return { latest: latest, stable: stable } -} - -exports.getLatest = getLatest - -function getVersionsInRange (range, versions, loose) { - return versions.filter(function (v) { - return semver.satisfies(v, range, loose) - }) -} - -exports.getVersionsInRange = getVersionsInRange diff --git a/package-lock.json b/package-lock.json index 6e7b87f..a70fffa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -263,11 +263,6 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "async": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz", - "integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ==" - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1259,6 +1254,12 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -1956,6 +1957,14 @@ "@babel/types": "^7.4.0", "istanbul-lib-coverage": "^2.0.5", "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "istanbul-lib-report": { @@ -2374,6 +2383,11 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -2394,3112 +2408,51 @@ } } }, - "npm": { - "version": "6.13.4", - "resolved": "https://registry.npmjs.org/npm/-/npm-6.13.4.tgz", - "integrity": "sha512-vTcUL4SCg3AzwInWTbqg1OIaOXlzKSS8Mb8kc5avwrJpcvevDA5J9BhYSuei+fNs3pwOp4lzA5x2FVDXACvoXA==", - "requires": { - "JSONStream": "^1.3.5", - "abbrev": "~1.1.1", - "ansicolors": "~0.3.2", - "ansistyles": "~0.1.3", - "aproba": "^2.0.0", - "archy": "~1.0.0", - "bin-links": "^1.1.6", - "bluebird": "^3.5.5", - "byte-size": "^5.0.1", - "cacache": "^12.0.3", - "call-limit": "^1.1.1", - "chownr": "^1.1.3", - "ci-info": "^2.0.0", - "cli-columns": "^3.1.2", - "cli-table3": "^0.5.1", - "cmd-shim": "^3.0.3", - "columnify": "~1.5.4", - "config-chain": "^1.1.12", - "debuglog": "*", - "detect-indent": "~5.0.0", - "detect-newline": "^2.1.0", - "dezalgo": "~1.0.3", - "editor": "~1.0.0", - "figgy-pudding": "^3.5.1", - "find-npm-prefix": "^1.0.2", - "fs-vacuum": "~1.2.10", - "fs-write-stream-atomic": "~1.0.10", - "gentle-fs": "^2.3.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.3", - "has-unicode": "~2.0.1", - "hosted-git-info": "^2.8.5", - "iferr": "^1.0.2", - "imurmurhash": "*", - "infer-owner": "^1.0.4", - "inflight": "~1.0.6", - "inherits": "^2.0.4", - "ini": "^1.3.5", - "init-package-json": "^1.10.3", - "is-cidr": "^3.0.0", - "json-parse-better-errors": "^1.0.2", - "lazy-property": "~1.0.0", - "libcipm": "^4.0.7", - "libnpm": "^3.0.1", - "libnpmaccess": "^3.0.2", - "libnpmhook": "^5.0.3", - "libnpmorg": "^1.0.1", - "libnpmsearch": "^2.0.2", - "libnpmteam": "^1.0.2", - "libnpx": "^10.2.0", - "lock-verify": "^2.1.0", - "lockfile": "^1.0.4", - "lodash._baseindexof": "*", - "lodash._baseuniq": "~4.6.0", - "lodash._bindcallback": "*", - "lodash._cacheindexof": "*", - "lodash._createcache": "*", - "lodash._getnative": "*", - "lodash.clonedeep": "~4.5.0", - "lodash.restparam": "*", - "lodash.union": "~4.6.0", - "lodash.uniq": "~4.5.0", - "lodash.without": "~4.4.0", - "lru-cache": "^5.1.1", - "meant": "~1.0.1", - "mississippi": "^3.0.0", - "mkdirp": "~0.5.1", - "move-concurrently": "^1.0.1", - "node-gyp": "^5.0.5", - "nopt": "~4.0.1", - "normalize-package-data": "^2.5.0", - "npm-audit-report": "^1.3.2", - "npm-cache-filename": "~1.0.2", - "npm-install-checks": "^3.0.2", - "npm-lifecycle": "^3.1.4", - "npm-package-arg": "^6.1.1", - "npm-packlist": "^1.4.7", - "npm-pick-manifest": "^3.0.2", - "npm-profile": "^4.0.2", - "npm-registry-fetch": "^4.0.2", - "npm-user-validate": "~1.0.0", - "npmlog": "~4.1.2", - "once": "~1.4.0", - "opener": "^1.5.1", - "osenv": "^0.1.5", - "pacote": "^9.5.11", - "path-is-inside": "~1.0.2", - "promise-inflight": "~1.0.1", - "qrcode-terminal": "^0.12.0", - "query-string": "^6.8.2", - "qw": "~1.0.1", - "read": "~1.0.7", - "read-cmd-shim": "^1.0.5", - "read-installed": "~4.0.3", - "read-package-json": "^2.1.1", - "read-package-tree": "^5.3.1", - "readable-stream": "^3.4.0", - "readdir-scoped-modules": "^1.1.0", - "request": "^2.88.0", - "retry": "^0.12.0", + "nyc": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", + "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "caching-transform": "^3.0.2", + "convert-source-map": "^1.6.0", + "cp-file": "^6.2.0", + "find-cache-dir": "^2.1.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", "rimraf": "^2.6.3", - "safe-buffer": "^5.1.2", - "semver": "^5.7.1", - "sha": "^3.0.0", - "slide": "~1.1.6", - "sorted-object": "~2.0.1", - "sorted-union-stream": "~2.1.3", - "ssri": "^6.0.1", - "stringify-package": "^1.0.1", - "tar": "^4.4.13", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "uid-number": "0.0.6", - "umask": "~1.1.0", - "unique-filename": "^1.1.1", - "unpipe": "~1.0.0", - "update-notifier": "^2.5.0", - "uuid": "^3.3.3", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "~3.0.0", - "which": "^1.3.1", - "worker-farm": "^1.7.0", - "write-file-atomic": "^2.4.3" + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.2.3", + "uuid": "^3.3.2", + "yargs": "^13.2.2", + "yargs-parser": "^13.0.0" }, "dependencies": { - "JSONStream": { - "version": "1.3.5", - "bundled": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "abbrev": { - "version": "1.1.1", - "bundled": true - }, - "agent-base": { - "version": "4.3.0", - "bundled": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "agentkeepalive": { - "version": "3.5.2", - "bundled": true, - "requires": { - "humanize-ms": "^1.2.1" - } - }, - "ajv": { - "version": "5.5.2", - "bundled": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ansi-align": { - "version": "2.0.0", - "bundled": true, - "requires": { - "string-width": "^2.0.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true - }, - "ansi-styles": { - "version": "3.2.1", - "bundled": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "ansicolors": { - "version": "0.3.2", - "bundled": true - }, - "ansistyles": { - "version": "0.1.3", - "bundled": true - }, - "aproba": { - "version": "2.0.0", - "bundled": true - }, - "archy": { - "version": "1.0.0", - "bundled": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "asap": { - "version": "2.0.6", - "bundled": true - }, - "asn1": { - "version": "0.2.4", - "bundled": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "bundled": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true - }, - "aws-sign2": { - "version": "0.7.0", - "bundled": true - }, - "aws4": { - "version": "1.8.0", - "bundled": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bin-links": { - "version": "1.1.6", - "bundled": true, - "requires": { - "bluebird": "^3.5.3", - "cmd-shim": "^3.0.0", - "gentle-fs": "^2.3.0", - "graceful-fs": "^4.1.15", - "npm-normalize-package-bin": "^1.0.0", - "write-file-atomic": "^2.3.0" - } - }, - "bluebird": { - "version": "3.5.5", - "bundled": true - }, - "boxen": { - "version": "1.3.0", - "bundled": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-from": { - "version": "1.0.0", - "bundled": true - }, - "builtins": { - "version": "1.0.3", - "bundled": true - }, - "byline": { - "version": "5.0.0", - "bundled": true - }, - "byte-size": { - "version": "5.0.1", - "bundled": true - }, - "cacache": { - "version": "12.0.3", - "bundled": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "call-limit": { - "version": "1.1.1", - "bundled": true - }, - "camelcase": { - "version": "4.1.0", - "bundled": true - }, - "capture-stack-trace": { - "version": "1.0.0", - "bundled": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true - }, - "chalk": { - "version": "2.4.1", - "bundled": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chownr": { - "version": "1.1.3", - "bundled": true - }, - "ci-info": { - "version": "2.0.0", - "bundled": true - }, - "cidr-regex": { - "version": "2.0.10", - "bundled": true, - "requires": { - "ip-regex": "^2.1.0" - } - }, - "cli-boxes": { - "version": "1.0.0", - "bundled": true - }, - "cli-columns": { - "version": "3.1.2", - "bundled": true, - "requires": { - "string-width": "^2.0.0", - "strip-ansi": "^3.0.1" - } - }, - "cli-table3": { - "version": "0.5.1", - "bundled": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - } - }, - "cliui": { - "version": "4.1.0", - "bundled": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "clone": { - "version": "1.0.4", - "bundled": true - }, - "cmd-shim": { - "version": "3.0.3", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "mkdirp": "~0.5.0" - } - }, - "co": { - "version": "4.6.0", - "bundled": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "color-convert": { - "version": "1.9.1", - "bundled": true, - "requires": { - "color-name": "^1.1.1" - } - }, - "color-name": { - "version": "1.1.3", - "bundled": true - }, - "colors": { - "version": "1.3.3", - "bundled": true, - "optional": true - }, - "columnify": { - "version": "1.5.4", - "bundled": true, - "requires": { - "strip-ansi": "^3.0.0", - "wcwidth": "^1.0.0" - } - }, - "combined-stream": { - "version": "1.0.6", - "bundled": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - }, - "concat-stream": { - "version": "1.6.2", - "bundled": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "config-chain": { - "version": "1.1.12", - "bundled": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "configstore": { - "version": "3.1.2", - "bundled": true, - "requires": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - } - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true - }, - "copy-concurrently": { - "version": "1.0.5", - "bundled": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - }, - "dependencies": { - "aproba": { - "version": "1.2.0", - "bundled": true - }, - "iferr": { - "version": "0.1.5", - "bundled": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "create-error-class": { - "version": "3.0.2", - "bundled": true, - "requires": { - "capture-stack-trace": "^1.0.0" - } - }, - "cross-spawn": { - "version": "5.1.0", - "bundled": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.5", - "bundled": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "bundled": true - } - } - }, - "crypto-random-string": { - "version": "1.0.0", - "bundled": true - }, - "cyclist": { - "version": "0.2.2", - "bundled": true - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "3.1.0", - "bundled": true, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "bundled": true - } - } - }, - "debuglog": { - "version": "1.0.1", - "bundled": true - }, - "decamelize": { - "version": "1.2.0", - "bundled": true - }, - "decode-uri-component": { - "version": "0.2.0", - "bundled": true - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true - }, - "defaults": { - "version": "1.0.3", - "bundled": true, - "requires": { - "clone": "^1.0.2" - } - }, - "define-properties": { - "version": "1.1.3", - "bundled": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true - }, - "detect-indent": { - "version": "5.0.0", - "bundled": true - }, - "detect-newline": { - "version": "2.1.0", - "bundled": true - }, - "dezalgo": { - "version": "1.0.3", - "bundled": true, - "requires": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "dot-prop": { - "version": "4.2.0", - "bundled": true, - "requires": { - "is-obj": "^1.0.0" - } - }, - "dotenv": { - "version": "5.0.1", - "bundled": true - }, - "duplexer3": { - "version": "0.1.4", - "bundled": true - }, - "duplexify": { - "version": "3.6.0", - "bundled": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "bundled": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "editor": { - "version": "1.0.0", - "bundled": true - }, - "encoding": { - "version": "0.1.12", - "bundled": true, - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "end-of-stream": { - "version": "1.4.1", - "bundled": true, - "requires": { - "once": "^1.4.0" - } - }, - "env-paths": { - "version": "1.0.0", - "bundled": true - }, - "err-code": { - "version": "1.1.2", - "bundled": true - }, - "errno": { - "version": "0.1.7", - "bundled": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.12.0", - "bundled": true, - "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "bundled": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-promise": { - "version": "4.2.8", - "bundled": true - }, - "es6-promisify": { - "version": "5.0.0", - "bundled": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true - }, - "execa": { - "version": "0.7.0", - "bundled": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "bundled": true - } - } - }, - "extend": { - "version": "3.0.2", - "bundled": true - }, - "extsprintf": { - "version": "1.3.0", - "bundled": true - }, - "fast-deep-equal": { - "version": "1.1.0", - "bundled": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "bundled": true - }, - "figgy-pudding": { - "version": "3.5.1", - "bundled": true - }, - "find-npm-prefix": { - "version": "1.0.2", - "bundled": true - }, - "find-up": { - "version": "2.1.0", - "bundled": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "flush-write-stream": { - "version": "1.0.3", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.4" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true - }, - "form-data": { - "version": "2.3.2", - "bundled": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - } - }, - "from2": { - "version": "2.3.0", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "requires": { - "minipass": "^2.6.0" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "fs-vacuum": { - "version": "1.2.10", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "path-is-inside": "^1.0.1", - "rimraf": "^2.5.2" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "iferr": { - "version": "0.1.5", - "bundled": true - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true - }, - "function-bind": { - "version": "1.1.1", - "bundled": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "aproba": { - "version": "1.2.0", - "bundled": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "genfun": { - "version": "5.0.0", - "bundled": true - }, - "gentle-fs": { - "version": "2.3.0", - "bundled": true, - "requires": { - "aproba": "^1.1.2", - "chownr": "^1.1.2", - "cmd-shim": "^3.0.3", - "fs-vacuum": "^1.2.10", - "graceful-fs": "^4.1.11", - "iferr": "^0.1.5", - "infer-owner": "^1.0.4", - "mkdirp": "^0.5.1", - "path-is-inside": "^1.0.2", - "read-cmd-shim": "^1.0.1", - "slide": "^1.1.6" - }, - "dependencies": { - "aproba": { - "version": "1.2.0", - "bundled": true - }, - "iferr": { - "version": "0.1.5", - "bundled": true - } - } - }, - "get-caller-file": { - "version": "1.0.2", - "bundled": true - }, - "get-stream": { - "version": "4.1.0", - "bundled": true, - "requires": { - "pump": "^3.0.0" - } - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.4", - "bundled": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "global-dirs": { - "version": "0.1.1", - "bundled": true, - "requires": { - "ini": "^1.3.4" - } - }, - "got": { - "version": "6.7.1", - "bundled": true, - "requires": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "bundled": true - } - } - }, - "graceful-fs": { - "version": "4.2.3", - "bundled": true - }, - "har-schema": { - "version": "2.0.0", - "bundled": true - }, - "har-validator": { - "version": "5.1.0", - "bundled": true, - "requires": { - "ajv": "^5.3.0", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "bundled": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "bundled": true - }, - "has-symbols": { - "version": "1.0.0", - "bundled": true - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true - }, - "hosted-git-info": { - "version": "2.8.5", - "bundled": true - }, - "http-cache-semantics": { - "version": "3.8.1", - "bundled": true - }, - "http-proxy-agent": { - "version": "2.1.0", - "bundled": true, - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "bundled": true, - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "humanize-ms": { - "version": "1.2.1", - "bundled": true, - "requires": { - "ms": "^2.0.0" - } - }, - "iconv-lite": { - "version": "0.4.23", - "bundled": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "iferr": { - "version": "1.0.2", - "bundled": true - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "import-lazy": { - "version": "2.1.0", - "bundled": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true - }, - "infer-owner": { - "version": "1.0.4", - "bundled": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true - }, - "ini": { - "version": "1.3.5", - "bundled": true - }, - "init-package-json": { - "version": "1.10.3", - "bundled": true, - "requires": { - "glob": "^7.1.1", - "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0", - "promzard": "^0.3.0", - "read": "~1.0.1", - "read-package-json": "1 || 2", - "semver": "2.x || 3.x || 4 || 5", - "validate-npm-package-license": "^3.0.1", - "validate-npm-package-name": "^3.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "bundled": true - }, - "ip": { - "version": "1.1.5", - "bundled": true - }, - "ip-regex": { - "version": "2.1.0", - "bundled": true - }, - "is-callable": { - "version": "1.1.4", - "bundled": true - }, - "is-ci": { - "version": "1.1.0", - "bundled": true, - "requires": { - "ci-info": "^1.0.0" - }, - "dependencies": { - "ci-info": { - "version": "1.6.0", - "bundled": true - } - } - }, - "is-cidr": { - "version": "3.0.0", - "bundled": true, - "requires": { - "cidr-regex": "^2.0.10" - } - }, - "is-date-object": { - "version": "1.0.1", - "bundled": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-installed-globally": { - "version": "0.1.0", - "bundled": true, - "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" - } - }, - "is-npm": { - "version": "1.0.0", - "bundled": true - }, - "is-obj": { - "version": "1.0.1", - "bundled": true - }, - "is-path-inside": { - "version": "1.0.1", - "bundled": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-redirect": { - "version": "1.0.0", - "bundled": true - }, - "is-regex": { - "version": "1.0.4", - "bundled": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-retry-allowed": { - "version": "1.1.0", - "bundled": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true - }, - "is-symbol": { - "version": "1.0.2", - "bundled": true, - "requires": { - "has-symbols": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "bundled": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "bundled": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true - }, - "jsonparse": { - "version": "1.3.1", - "bundled": true - }, - "jsprim": { - "version": "1.4.1", - "bundled": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "latest-version": { - "version": "3.1.0", - "bundled": true, - "requires": { - "package-json": "^4.0.0" - } - }, - "lazy-property": { - "version": "1.0.0", - "bundled": true - }, - "lcid": { - "version": "1.0.0", - "bundled": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "libcipm": { - "version": "4.0.7", - "bundled": true, - "requires": { - "bin-links": "^1.1.2", - "bluebird": "^3.5.1", - "figgy-pudding": "^3.5.1", - "find-npm-prefix": "^1.0.2", - "graceful-fs": "^4.1.11", - "ini": "^1.3.5", - "lock-verify": "^2.0.2", - "mkdirp": "^0.5.1", - "npm-lifecycle": "^3.0.0", - "npm-logical-tree": "^1.2.1", - "npm-package-arg": "^6.1.0", - "pacote": "^9.1.0", - "read-package-json": "^2.0.13", - "rimraf": "^2.6.2", - "worker-farm": "^1.6.0" - } - }, - "libnpm": { - "version": "3.0.1", - "bundled": true, - "requires": { - "bin-links": "^1.1.2", - "bluebird": "^3.5.3", - "find-npm-prefix": "^1.0.2", - "libnpmaccess": "^3.0.2", - "libnpmconfig": "^1.2.1", - "libnpmhook": "^5.0.3", - "libnpmorg": "^1.0.1", - "libnpmpublish": "^1.1.2", - "libnpmsearch": "^2.0.2", - "libnpmteam": "^1.0.2", - "lock-verify": "^2.0.2", - "npm-lifecycle": "^3.0.0", - "npm-logical-tree": "^1.2.1", - "npm-package-arg": "^6.1.0", - "npm-profile": "^4.0.2", - "npm-registry-fetch": "^4.0.0", - "npmlog": "^4.1.2", - "pacote": "^9.5.3", - "read-package-json": "^2.0.13", - "stringify-package": "^1.0.0" - } - }, - "libnpmaccess": { - "version": "3.0.2", - "bundled": true, - "requires": { - "aproba": "^2.0.0", - "get-stream": "^4.0.0", - "npm-package-arg": "^6.1.0", - "npm-registry-fetch": "^4.0.0" - } - }, - "libnpmconfig": { - "version": "1.2.1", - "bundled": true, - "requires": { - "figgy-pudding": "^3.5.1", - "find-up": "^3.0.0", - "ini": "^1.3.5" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "bundled": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "bundled": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.2.0", - "bundled": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "bundled": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "bundled": true - } - } - }, - "libnpmhook": { - "version": "5.0.3", - "bundled": true, - "requires": { - "aproba": "^2.0.0", - "figgy-pudding": "^3.4.1", - "get-stream": "^4.0.0", - "npm-registry-fetch": "^4.0.0" - } - }, - "libnpmorg": { - "version": "1.0.1", - "bundled": true, - "requires": { - "aproba": "^2.0.0", - "figgy-pudding": "^3.4.1", - "get-stream": "^4.0.0", - "npm-registry-fetch": "^4.0.0" - } - }, - "libnpmpublish": { - "version": "1.1.2", - "bundled": true, - "requires": { - "aproba": "^2.0.0", - "figgy-pudding": "^3.5.1", - "get-stream": "^4.0.0", - "lodash.clonedeep": "^4.5.0", - "normalize-package-data": "^2.4.0", - "npm-package-arg": "^6.1.0", - "npm-registry-fetch": "^4.0.0", - "semver": "^5.5.1", - "ssri": "^6.0.1" - } - }, - "libnpmsearch": { - "version": "2.0.2", - "bundled": true, - "requires": { - "figgy-pudding": "^3.5.1", - "get-stream": "^4.0.0", - "npm-registry-fetch": "^4.0.0" - } - }, - "libnpmteam": { - "version": "1.0.2", - "bundled": true, - "requires": { - "aproba": "^2.0.0", - "figgy-pudding": "^3.4.1", - "get-stream": "^4.0.0", - "npm-registry-fetch": "^4.0.0" - } - }, - "libnpx": { - "version": "10.2.0", - "bundled": true, - "requires": { - "dotenv": "^5.0.1", - "npm-package-arg": "^6.0.0", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.0", - "update-notifier": "^2.3.0", - "which": "^1.3.0", - "y18n": "^4.0.0", - "yargs": "^11.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "bundled": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lock-verify": { - "version": "2.1.0", - "bundled": true, - "requires": { - "npm-package-arg": "^6.1.0", - "semver": "^5.4.1" - } - }, - "lockfile": { - "version": "1.0.4", - "bundled": true, - "requires": { - "signal-exit": "^3.0.2" - } - }, - "lodash._baseindexof": { - "version": "3.1.0", - "bundled": true - }, - "lodash._baseuniq": { - "version": "4.6.0", - "bundled": true, - "requires": { - "lodash._createset": "~4.0.0", - "lodash._root": "~3.0.0" - } - }, - "lodash._bindcallback": { - "version": "3.0.1", - "bundled": true - }, - "lodash._cacheindexof": { - "version": "3.0.2", - "bundled": true - }, - "lodash._createcache": { - "version": "3.1.2", - "bundled": true, - "requires": { - "lodash._getnative": "^3.0.0" - } - }, - "lodash._createset": { - "version": "4.0.3", - "bundled": true - }, - "lodash._getnative": { - "version": "3.9.1", - "bundled": true - }, - "lodash._root": { - "version": "3.0.1", - "bundled": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "bundled": true - }, - "lodash.restparam": { - "version": "3.6.1", - "bundled": true - }, - "lodash.union": { - "version": "4.6.0", - "bundled": true - }, - "lodash.uniq": { - "version": "4.5.0", - "bundled": true - }, - "lodash.without": { - "version": "4.4.0", - "bundled": true - }, - "lowercase-keys": { - "version": "1.0.1", - "bundled": true - }, - "lru-cache": { - "version": "5.1.1", - "bundled": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "1.3.0", - "bundled": true, - "requires": { - "pify": "^3.0.0" - } - }, - "make-fetch-happen": { - "version": "5.0.2", - "bundled": true, - "requires": { - "agentkeepalive": "^3.4.1", - "cacache": "^12.0.0", - "http-cache-semantics": "^3.8.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "node-fetch-npm": "^2.0.2", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^4.0.0", - "ssri": "^6.0.0" - } - }, - "meant": { - "version": "1.0.1", - "bundled": true - }, - "mem": { - "version": "1.1.0", - "bundled": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "mime-db": { - "version": "1.35.0", - "bundled": true - }, - "mime-types": { - "version": "2.1.19", - "bundled": true, - "requires": { - "mime-db": "~1.35.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "bundled": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "requires": { - "minipass": "^2.9.0" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "mississippi": { - "version": "3.0.0", - "bundled": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - } - }, - "move-concurrently": { - "version": "1.0.1", - "bundled": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - }, - "dependencies": { - "aproba": { - "version": "1.2.0", - "bundled": true - } - } - }, - "ms": { - "version": "2.1.1", - "bundled": true - }, - "mute-stream": { - "version": "0.0.7", - "bundled": true - }, - "node-fetch-npm": { - "version": "2.0.2", - "bundled": true, - "requires": { - "encoding": "^0.1.11", - "json-parse-better-errors": "^1.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node-gyp": { - "version": "5.0.5", - "bundled": true, - "requires": { - "env-paths": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^4.4.12", - "which": "1" - }, - "dependencies": { - "nopt": { - "version": "3.0.6", - "bundled": true, - "requires": { - "abbrev": "1" - } - }, - "semver": { - "version": "5.3.0", - "bundled": true - } - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "bundled": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "resolve": { - "version": "1.10.0", - "bundled": true, - "requires": { - "path-parse": "^1.0.6" - } - } - } - }, - "npm-audit-report": { - "version": "1.3.2", - "bundled": true, - "requires": { - "cli-table3": "^0.5.0", - "console-control-strings": "^1.1.0" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-cache-filename": { - "version": "1.0.2", - "bundled": true - }, - "npm-install-checks": { - "version": "3.0.2", - "bundled": true, - "requires": { - "semver": "^2.3.0 || 3.x || 4 || 5" - } - }, - "npm-lifecycle": { - "version": "3.1.4", - "bundled": true, - "requires": { - "byline": "^5.0.0", - "graceful-fs": "^4.1.15", - "node-gyp": "^5.0.2", - "resolve-from": "^4.0.0", - "slide": "^1.1.6", - "uid-number": "0.0.6", - "umask": "^1.1.0", - "which": "^1.3.1" - } - }, - "npm-logical-tree": { - "version": "1.2.1", - "bundled": true - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true - }, - "npm-package-arg": { - "version": "6.1.1", - "bundled": true, - "requires": { - "hosted-git-info": "^2.7.1", - "osenv": "^0.1.5", - "semver": "^5.6.0", - "validate-npm-package-name": "^3.0.0" - } - }, - "npm-packlist": { - "version": "1.4.7", - "bundled": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npm-pick-manifest": { - "version": "3.0.2", - "bundled": true, - "requires": { - "figgy-pudding": "^3.5.1", - "npm-package-arg": "^6.0.0", - "semver": "^5.4.1" - } - }, - "npm-profile": { - "version": "4.0.2", - "bundled": true, - "requires": { - "aproba": "^1.1.2 || 2", - "figgy-pudding": "^3.4.1", - "npm-registry-fetch": "^4.0.0" - } - }, - "npm-registry-fetch": { - "version": "4.0.2", - "bundled": true, - "requires": { - "JSONStream": "^1.3.4", - "bluebird": "^3.5.1", - "figgy-pudding": "^3.4.1", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^5.0.0", - "npm-package-arg": "^6.1.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.0", - "bundled": true - } - } - }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "npm-user-validate": { - "version": "1.0.0", - "bundled": true - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true - }, - "oauth-sign": { - "version": "0.9.0", - "bundled": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true - }, - "object-keys": { - "version": "1.0.12", - "bundled": true - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "bundled": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.5.1", - "bundled": true - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true - }, - "os-locale": { - "version": "2.1.0", - "bundled": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "p-finally": { - "version": "1.0.0", - "bundled": true - }, - "p-limit": { - "version": "1.2.0", - "bundled": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "bundled": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "bundled": true - }, - "package-json": { - "version": "4.0.1", - "bundled": true, - "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" - } - }, - "pacote": { - "version": "9.5.11", - "bundled": true, - "requires": { - "bluebird": "^3.5.3", - "cacache": "^12.0.2", - "chownr": "^1.1.2", - "figgy-pudding": "^3.5.1", - "get-stream": "^4.1.0", - "glob": "^7.1.3", - "infer-owner": "^1.0.4", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^5.0.0", - "minimatch": "^3.0.4", - "minipass": "^2.3.5", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "normalize-package-data": "^2.4.0", - "npm-normalize-package-bin": "^1.0.0", - "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.1.12", - "npm-pick-manifest": "^3.0.0", - "npm-registry-fetch": "^4.0.0", - "osenv": "^0.1.5", - "promise-inflight": "^1.0.1", - "promise-retry": "^1.1.1", - "protoduck": "^5.0.1", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.2", - "semver": "^5.6.0", - "ssri": "^6.0.1", - "tar": "^4.4.10", - "unique-filename": "^1.1.1", - "which": "^1.3.1" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "parallel-transform": { - "version": "1.1.0", - "bundled": true, - "requires": { - "cyclist": "~0.2.2", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "path-exists": { - "version": "3.0.0", - "bundled": true - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true - }, - "path-is-inside": { - "version": "1.0.2", - "bundled": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true - }, - "path-parse": { - "version": "1.0.6", - "bundled": true - }, - "performance-now": { - "version": "2.1.0", - "bundled": true - }, - "pify": { - "version": "3.0.0", - "bundled": true - }, - "prepend-http": { - "version": "1.0.4", - "bundled": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true - }, - "promise-inflight": { - "version": "1.0.1", - "bundled": true - }, - "promise-retry": { - "version": "1.1.1", - "bundled": true, - "requires": { - "err-code": "^1.0.0", - "retry": "^0.10.0" - }, - "dependencies": { - "retry": { - "version": "0.10.1", - "bundled": true - } - } - }, - "promzard": { - "version": "0.3.0", - "bundled": true, - "requires": { - "read": "1" - } - }, - "proto-list": { - "version": "1.2.4", - "bundled": true - }, - "protoduck": { - "version": "5.0.1", - "bundled": true, - "requires": { - "genfun": "^5.0.0" - } - }, - "prr": { - "version": "1.0.1", - "bundled": true - }, - "pseudomap": { - "version": "1.0.2", - "bundled": true - }, - "psl": { - "version": "1.1.29", - "bundled": true - }, - "pump": { - "version": "3.0.0", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "bundled": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "1.4.1", - "bundled": true - }, - "qrcode-terminal": { - "version": "0.12.0", - "bundled": true - }, - "qs": { - "version": "6.5.2", - "bundled": true - }, - "query-string": { - "version": "6.8.2", - "bundled": true, - "requires": { - "decode-uri-component": "^0.2.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - } - }, - "qw": { - "version": "1.0.1", - "bundled": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true - } - } - }, - "read": { - "version": "1.0.7", - "bundled": true, - "requires": { - "mute-stream": "~0.0.4" - } - }, - "read-cmd-shim": { - "version": "1.0.5", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2" - } - }, - "read-installed": { - "version": "4.0.3", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "graceful-fs": "^4.1.2", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "slide": "~1.1.3", - "util-extend": "^1.0.1" - } - }, - "read-package-json": { - "version": "2.1.1", - "bundled": true, - "requires": { - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "json-parse-better-errors": "^1.0.1", - "normalize-package-data": "^2.0.0", - "npm-normalize-package-bin": "^1.0.0" - } - }, - "read-package-tree": { - "version": "5.3.1", - "bundled": true, - "requires": { - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "util-promisify": "^2.1.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "bundled": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdir-scoped-modules": { - "version": "1.1.0", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, - "registry-auth-token": { - "version": "3.3.2", - "bundled": true, - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "registry-url": { - "version": "3.1.0", - "bundled": true, - "requires": { - "rc": "^1.0.1" - } - }, - "request": { - "version": "2.88.0", - "bundled": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "bundled": true - }, - "require-main-filename": { - "version": "1.0.1", - "bundled": true - }, - "resolve-from": { - "version": "4.0.0", - "bundled": true - }, - "retry": { - "version": "0.12.0", - "bundled": true - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-queue": { - "version": "1.0.3", - "bundled": true, - "requires": { - "aproba": "^1.1.1" - }, - "dependencies": { - "aproba": { - "version": "1.2.0", - "bundled": true - } - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true - }, - "semver": { - "version": "5.7.1", - "bundled": true - }, - "semver-diff": { - "version": "2.1.0", - "bundled": true, - "requires": { - "semver": "^5.0.3" - } - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true - }, - "sha": { - "version": "3.0.0", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2" - } - }, - "shebang-command": { - "version": "1.2.0", - "bundled": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true - }, - "slide": { - "version": "1.1.6", - "bundled": true - }, - "smart-buffer": { - "version": "4.1.0", - "bundled": true - }, - "socks": { - "version": "2.3.3", - "bundled": true, - "requires": { - "ip": "1.1.5", - "smart-buffer": "^4.1.0" - } - }, - "socks-proxy-agent": { - "version": "4.0.2", - "bundled": true, - "requires": { - "agent-base": "~4.2.1", - "socks": "~2.3.2" - }, - "dependencies": { - "agent-base": { - "version": "4.2.1", - "bundled": true, - "requires": { - "es6-promisify": "^5.0.0" - } - } - } - }, - "sorted-object": { - "version": "2.0.1", - "bundled": true - }, - "sorted-union-stream": { - "version": "2.1.3", - "bundled": true, - "requires": { - "from2": "^1.3.0", - "stream-iterate": "^1.1.0" - }, - "dependencies": { - "from2": { - "version": "1.3.0", - "bundled": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "~1.1.10" - } - }, - "isarray": { - "version": "0.0.1", - "bundled": true - }, - "readable-stream": { - "version": "1.1.14", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "bundled": true - } - } - }, - "spdx-correct": { - "version": "3.0.0", - "bundled": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.1.0", - "bundled": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "bundled": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.3", - "bundled": true - }, - "split-on-first": { - "version": "1.1.0", - "bundled": true - }, - "sshpk": { - "version": "1.14.2", - "bundled": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "6.0.1", - "bundled": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stream-each": { - "version": "1.2.2", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-iterate": { - "version": "1.2.0", - "bundled": true, - "requires": { - "readable-stream": "^2.1.5", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.0", - "bundled": true - }, - "strict-uri-encode": { - "version": "2.0.0", - "bundled": true - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string_decoder": { - "version": "1.2.0", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "stringify-package": { - "version": "1.0.1", - "bundled": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true - }, - "supports-color": { - "version": "5.4.0", - "bundled": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "term-size": { - "version": "1.2.0", - "bundled": true, - "requires": { - "execa": "^0.7.0" - } - }, - "text-table": { - "version": "0.2.0", - "bundled": true - }, - "through": { - "version": "2.3.8", - "bundled": true - }, - "through2": { - "version": "2.0.3", - "bundled": true, - "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timed-out": { - "version": "4.0.1", - "bundled": true - }, - "tiny-relative-date": { - "version": "1.3.0", - "bundled": true - }, - "tough-cookie": { - "version": "2.4.3", - "bundled": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "optional": true - }, - "typedarray": { - "version": "0.0.6", - "bundled": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true - }, - "umask": { - "version": "1.1.0", - "bundled": true - }, - "unique-filename": { - "version": "1.1.1", - "bundled": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.0", - "bundled": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unique-string": { - "version": "1.0.0", - "bundled": true, - "requires": { - "crypto-random-string": "^1.0.0" - } - }, - "unpipe": { - "version": "1.0.0", - "bundled": true - }, - "unzip-response": { - "version": "2.0.1", - "bundled": true - }, - "update-notifier": { - "version": "2.5.0", - "bundled": true, - "requires": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - } - }, - "url-parse-lax": { - "version": "1.0.0", - "bundled": true, - "requires": { - "prepend-http": "^1.0.1" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - }, - "util-extend": { - "version": "1.0.3", - "bundled": true - }, - "util-promisify": { - "version": "2.1.0", - "bundled": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3" - } - }, - "uuid": { - "version": "3.3.3", - "bundled": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "bundled": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validate-npm-package-name": { - "version": "3.0.0", - "bundled": true, - "requires": { - "builtins": "^1.0.3" - } - }, - "verror": { - "version": "1.10.0", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "wcwidth": { - "version": "1.0.1", - "bundled": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "which": { - "version": "1.3.1", - "bundled": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "bundled": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "requires": { - "string-width": "^1.0.2" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "widest-line": { - "version": "2.0.0", - "bundled": true, - "requires": { - "string-width": "^2.1.1" - } - }, - "worker-farm": { - "version": "1.7.0", - "bundled": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "bundled": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - }, - "write-file-atomic": { - "version": "2.4.3", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "xdg-basedir": { - "version": "3.0.0", - "bundled": true - }, - "xtend": { - "version": "4.0.1", - "bundled": true - }, - "y18n": { - "version": "4.0.0", - "bundled": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true - }, - "yargs": { - "version": "11.0.0", - "bundled": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - }, - "dependencies": { - "y18n": { - "version": "3.2.1", - "bundled": true - } - } - }, - "yargs-parser": { - "version": "9.0.2", - "bundled": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "nyc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", - "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "caching-transform": "^3.0.2", - "convert-source-map": "^1.6.0", - "cp-file": "^6.2.0", - "find-cache-dir": "^2.1.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.5", - "istanbul-lib-hook": "^2.0.7", - "istanbul-lib-instrument": "^3.3.0", - "istanbul-lib-report": "^2.0.8", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^2.2.4", - "js-yaml": "^3.13.1", - "make-dir": "^2.1.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.3", - "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.2.3", - "uuid": "^3.3.2", - "yargs": "^13.2.2", - "yargs-parser": "^13.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } } } @@ -5829,6 +2782,11 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + }, "prop-types": { "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", @@ -6113,9 +3071,9 @@ "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" }, "set-blocking": { "version": "2.0.0", @@ -6351,6 +3309,14 @@ "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "eslint-scope": { @@ -7060,7 +4026,8 @@ "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true }, "y18n": { "version": "4.0.0", diff --git a/package.json b/package.json index acb81f4..906e851 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "name": "david", "version": "12.0.0", "description": "Node.js module that tells you when your project npm dependencies are out of date.", - "main": "lib/david.js", + "type": "module", + "main": "src/david.js", "repository": { "type": "git", "url": "git://github.com/alanshaw/david.git" @@ -25,15 +26,14 @@ "LICENCE" ], "dependencies": { - "async": "^3.1.0", "cli-color-tty": "^2.0.0", "cli-table": "^0.3.1", "exit": "^0.1.2", "minimist": "^1.1.0", "multimatch": "^4.0.0", - "npm": "^6.10.2", - "semver": "^6.3.0", - "xtend": "^4.0.0" + "node-fetch": "^2.6.0", + "promise-inflight": "^1.0.1", + "semver": "^7.3.2" }, "devDependencies": { "coveralls": "^3.0.5", diff --git a/src/david.js b/src/david.js new file mode 100644 index 0000000..9bd8c9e --- /dev/null +++ b/src/david.js @@ -0,0 +1,193 @@ +/** + * david + * https://github.com/alanshaw/david + * + * Copyright (c) 2013 Alan Shaw + * Licensed under the MIT license. + */ + +import multimatch from 'multimatch' +import Semver from 'semver' +import inflight from 'promise-inflight' +import fetch from 'node-fetch' + +const REGISTRY = 'https://registry.npmjs.org' +const CORGI_DOC = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' + +/** + * @typedef {{ required: string, latest: string, stable: string, versions: string[] }} Info + */ + +/** + * @typedef {{ [moduleName: string]: Info }} Infos + */ + +/** + * @typedef {{ [moduleName: string]: string }} Dependencies + */ + +/** + * moduleInfo gets version info for the passed module. + * @param {Dependencies} deps A dependencies, devDependencies, peerDependencies etc. object as would be found in a package.json. + * @param {object} [options] Options + * @param {boolean} [options.registry] npm registry URL. + * @param {{ loose?: boolean }} [options.semver] Semver options. + * @param {boolean} [options.ignoreNotFound] Ignore 404 errors. + * @param {string[]} [options.ignoreModules] List of dependency names or globs to ignore. + * @return {Promise} + */ +export function moduleInfo (name, range, options) { + range = range || '*' + options = options || {} + + return inflight(`${name}:${range}`, async () => { + const url = `${options.registry || REGISTRY}/${encodeURIComponent(name)}` + const res = await fetch(url, { headers: { accept: CORGI_DOC } }) + + if (!res.ok) { + const err = new Error(`not ok (${res.status}) fetching ${url}`) + err.response = res + throw err + } + + const packument = await res.json() + const distTagsLatest = packument['dist-tags'] && packument['dist-tags'].latest + + if (!distTagsLatest) { + throw new Error('missing dist-tags.latest') + } + + const versions = Object.keys(packument.versions) + const { latest, stable } = getLatest(distTagsLatest, versions, options) + + return { required: range, latest, stable, versions } + }) +} + +/** + * dependenciesInfo gets module info for the passed dependencies object. + * @param {Dependencies} deps A dependencies, devDependencies, peerDependencies etc. object as would be found in a package.json. + * @param {object} [options] Options + * @param {boolean} [options.registry] npm registry URL. + * @param {{ loose?: boolean }} [options.semver] Semver options. + * @param {string[]} [options.ignoreModules] List of dependency names or globs to ignore. + * @param {boolean} [options.ignoreNotFound] Ignore 404 errors. + * @param {boolean} [options.ignoreNonSemverRange] Ignore version ranges that aren't semver strings. + * @return {Promise} + */ +export async function dependenciesInfo (deps, options) { + deps = normaliseDeps(deps) + options = options || {} + + const entries = await Promise.all( + Object.entries(deps) + .filter(([n, r]) => { + if (options.ignoreModules && multimatch(n, options.ignoreModules).length) { + return false + } + if (!Semver.validRange(r, options.semver)) { + if (options.ignoreNonSemverRange) { + return false + } else { + throw new Error(`non semver version for module ${n}`) + } + } + return true + }) + .map(async ([n, r]) => { + try { + return [n, await moduleInfo(n, r, options)] + } catch (err) { + if (options.ignoreNotFound && err.response && err.response.status === 404) { + return null + } + throw err + } + }) + ) + + return Object.fromEntries(entries.filter(Boolean)) +} + +// normaliseDeps converts dependencies specified as an array to an object. +function normaliseDeps (deps) { + return Array.isArray(deps) + ? Object.fromEntries(deps.map(n => [n, '*'])) + : deps || {} +} + +/** + * Given moduleInfo, an object obtained by calling dependenciesInfo, determine + * whether dep.required (the version specified in package.json) is out of date + * wrt dep.stable or dep.latest. + * + * @param {Info} moduleInfo + * @param {object} [options] Options + * @param {boolean} [options.stable] Consider only stable versions. + * @param {{ loose?: boolean }} [options.semver] Semver options. + * @returns {boolean} + */ +export function isUpdated (moduleInfo, options) { + options = options || {} + + const required = moduleInfo.required || '*' + + // TODO: Handle tags correctly + if (required !== 'latest' && required !== '*') { + const range = Semver.validRange(required, options.semver) || '' + const version = options.stable ? moduleInfo.stable : moduleInfo.latest + + if (version) { + if (!range) { + return true + } else if (!Semver.satisfies(version, range, options.semver)) { + if (options.stable && Semver.gtr(version, range, options.semver)) { + return true + } else if (!options.stable) { + return true + } + } + } + } + return false +} + +const unstablePattern = /[a-z+-]/i + +// isStable determines if a version is a stable version or not. +function isStable (version) { + return !unstablePattern.test(version || '') +} + +/** + * Get the latest version and latest stable version. + * @param {string} current The version you get when you `npm install [package]` + * @param {string[]} versions All versions available + * @param {object} options Options + * @param {object} [opts.semver] Semver options + */ +function getLatest (current, versions, options) { + options = options || {} + versions = Array.from(versions).sort((a, b) => Semver.gt(a, b, options.semver) ? -1 : 1) + + let stable = current + let latest = versions[0] + + if (!isStable(stable)) { + stable = versions.find(isStable) + } + + // we might not have found a stable version... + if (stable) { + // Latest is the most recent version with higher version than stable + for (const v of versions) { + // If !opts.loose then this may throw + if (Semver.gt(v, stable, options.semver)) { + latest = v + break + } + } + } + + return { latest, stable } +} From 4ae0f57ebb56d0f02fd160f847b544cbf85544d9 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Mon, 17 Aug 2020 11:58:46 +0100 Subject: [PATCH 02/10] fix: wip CLI --- CHANGELOG.md | 8 +- README.md | 111 ++++------- bin/david.js | 488 +++++++++++++++++++++++----------------------- example.js | 23 +++ package-lock.json | 5 + package.json | 5 +- src/david.js | 21 +- 7 files changed, 329 insertions(+), 332 deletions(-) create mode 100644 example.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a23bd5..9952382 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## 12.0.0 - 2020-08-xx +## 13.0.0 - 2020-08-xx This release switches the code base to use esmodules and promises and removes the npm dependency in favour of calling the API directly. It has breaking API changes: @@ -14,10 +14,14 @@ This release switches the code base to use esmodules and promises and removes th - `errors.EDEPTYPE` and `errors.ESCM` options have merged into `ignoreNonSemverRange`. Any version ranges that are not a semver version or range will be ignored when set to `true`. - `ignore` option has been renamed to `ignoreModules`. - `getUpdatedDependencies` has been removed, use `dependenciesInfo` and then `isUpdated` to filter out the dependencies that are not updates. -- A new function `moduleInfo` has been added (and exported) to get the module versions info for a single module. It is used by `dependenciesInfo` for each module. + +## 12.0.0 - 2019-12-09 + +- Fix broken package.lock ## 11.0.0 - 2017-03-02 +- Ignore dependencies via globs - Update dependencies ## 10.0.0 - 2017-01-20 diff --git a/README.md b/README.md index cefc01e..1fcf36a 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Node.js module that tells you when your package npm dependencies are out of date. -## Getting Started +## Install Install [Node.js](http://nodejs.org/). @@ -22,80 +22,42 @@ cd /your/project/directory npm install david ``` -Use: - -```javascript -var david = require('david'); - -// Your package.json -var manifest = { - name: 'xxx', - dependencies: { - 'aaa': '~0.0.0', - 'bbb': '~0.0.0' - }, - devDependencies: { - 'yyy': '~0.0.0', - 'zzz': '~0.0.0' - } -}; - -david.getDependencies(manifest, function (er, deps) { - console.log('latest dependencies information for', manifest.name); - listDependencies(deps); -}); - -david.getDependencies(manifest, { dev: true }, function (er, deps) { - console.log('latest devDependencies information for', manifest.name); - listDependencies(deps); -}); - -david.getUpdatedDependencies(manifest, function (er, deps) { - console.log('dependencies with newer versions for', manifest.name); - listDependencies(deps); -}); - -david.getUpdatedDependencies(manifest, { dev: true }, function (er, deps) { - console.log('devDependencies with newer versions for', manifest.name); - listDependencies(deps); -}); - -david.getUpdatedDependencies(manifest, { stable: true }, function (er, deps) { - console.log('dependencies with newer STABLE versions for', manifest.name); - listDependencies(deps); -}); - -david.getUpdatedDependencies(manifest, { dev: true, stable: true }, function (er, deps) { - console.log('devDependencies with newer STABLE versions for', manifest.name); - listDependencies(deps); -}); - -function listDependencies(deps) { - Object.keys(deps).forEach(function(depName) { - var required = deps[depName].required || '*'; - var stable = deps[depName].stable || 'None'; - var latest = deps[depName].latest; - console.log('%s Required: %s Stable: %s Latest: %s', depName, required, stable, latest); - }); -} -``` +## Usage + +```js +import * as david from 'david' +import fs from 'fs' + +async function main () { + const pkg = JSON.parse(fs.readFileSync('package.json')) + + const infos = await david.dependenciesInfo(pkg.dependencies) + console.log(`\n# Dependencies information for "${pkg.name}":`) + Object.entries(infos).forEach(printInfo) + + console.log('\n# Newer versions:') + Object.entries(infos).filter(([_, i]) => david.isUpdated(i)).forEach(printInfo) -Both `getDependencies` and `getUpdatedDependencies` return an object result, -whose keys are package names. The values are objects which contain the following properties: + console.log('\n# Newer STABLE versions:') + Object.entries(infos).filter(([_, i]) => david.isUpdated(i, { stable: true })).forEach(printInfo) +} -* `required` - The version required according to the manifest -* `stable` - The latest stable version available -* `latest` - The latest version available (including build and patch versions) +function printInfo ([name, info]) { + const { required, stable, latest } = info + console.log(`${name} (Required: ${required} Stable: ${stable || 'None'} Latest: ${latest})`) +} +main() +``` -## CLI +### CLI If you install David globally with `npm install -g david`, you can run `david` in your project directory to see which dependencies are out of date. You can also run `david --global` to see your outdated global dependencies. -### Update to latest +#### Update to latest To update all your project dependencies to the latest **stable** versions, and save to your `package.json`, run: @@ -124,13 +86,13 @@ To update all your project dependencies to the latest versions david update --unstable ``` -### Alternate registry +#### Alternate registry ```sh david update --registry http://registry.nodejitsu.com/ ``` -### Non-npm and SCM (Git) dependencies +#### Non-npm and SCM (Git) dependencies If you have dependencies that are not published to npm, david will print a warning message by default. To throw an error and exit, pass the `error404` option: @@ -148,11 +110,11 @@ david --errorSCM If using david programmatically, pass `error: {ESCM: true}` in the options object. -### Specify package.json path +#### Specify package.json path Use `-p, --package` to specify the path to your package.json. -### Ignore dependencies +#### Ignore dependencies To tell david to ignore dependencies, add a `david.ignore` property to your `package.json` which lists the dependencies david should ignore. If using david programmatically you can also pass this as an option. Globs are also supported. e.g. @@ -165,6 +127,17 @@ To tell david to ignore dependencies, add a `david.ignore` property to your `pac } ``` +## API + +### `dependenciesInfo(deps: Dependencies): Promise` + +`dependenciesInfo` returns a promise of a object result, whose keys are package names. The values are objects which contain the following properties: + +* `required` - The version required according to the manifest. +* `stable` - The latest stable version available. +* `latest` - The latest version available (including build and patch versions). +* `versions` - All versions of the module. + ---

diff --git a/bin/david.js b/bin/david.js index 4c01361..f59263e 100755 --- a/bin/david.js +++ b/bin/david.js @@ -1,71 +1,74 @@ #!/usr/bin/env node -var david = require('../') -var clc = require('cli-color-tty')() -var Table = require('cli-table') -var fs = require('fs') -var path = require('path') -var npm = require('npm') -var argv = require('minimist')(process.argv.slice(2)) -var xtend = require('xtend') -var exit = require('exit') +import * as david from '../src/david.js' +import Color from 'cli-color-tty' +import Table from 'cli-table' +import fs from 'fs' +import path from 'path' +// import npm from 'npm' +import minimist from 'minimist' +import umeta from 'umeta' + +const argv = minimist(process.argv.slice(2)) +const clc = Color() +const { dirName, require } = umeta(import.meta) if (argv.usage || argv.help || argv.h) { - console.log(fs.readFileSync(path.join(__dirname, 'usage.txt'), 'utf8')) - exit() + console.log(fs.readFileSync(path.join(dirName, 'usage.txt'), 'utf8')) + process.exit() } if (argv.version || argv.v) { console.log('v' + require('../package.json').version) - exit() + process.exit() } argv.update = argv._.indexOf('update') > -1 || argv._.indexOf('u') > -1 -function getNonWarnDepNames (deps) { - return Object.keys(deps).reduce(function (names, name) { - if (!deps[name].warn) { - names.push(name) - } - return names - }, []) -} - -/** - * Like printDeps, walk the list, but only print dependencies - * with warnings. - * @param {Object} deps - * @param {String} type - */ -function printWarnings (deps, type) { - if (!Object.keys(deps).length) return - - var warnings = { - E404: { title: 'Unregistered', list: [] }, - ESCM: { title: 'SCM', list: [] }, - EDEPTYPE: { title: 'Non-string dependency', list: [] } - } - - for (var name in deps) { - var dep = deps[name] - - if (dep.warn) { - warnings[dep.warn.code].list.push([clc.magenta(name), clc.red(dep.warn.toString())]) - } - } - - Object.keys(warnings).forEach(function (warnType) { - var warnList = warnings[warnType].list - - if (!warnList.length) return - - var table = new Table({ head: ['Name', 'Message'], style: { head: ['reset'] } }) - - console.log(clc.underline(warnings[warnType].title + ' ' + (type ? type + 'D' : 'd') + 'ependencies') + '\n') - warnList.forEach(function (row) { table.push(row) }) - console.log(table.toString() + '\n') - }) -} +// function getNonWarnDepNames (deps) { +// return Object.keys(deps).reduce(function (names, name) { +// if (!deps[name].warn) { +// names.push(name) +// } +// return names +// }, []) +// } + +// /** +// * Like printDeps, walk the list, but only print dependencies +// * with warnings. +// * @param {Object} deps +// * @param {String} type +// */ +// function printWarnings (deps, type) { +// if (!Object.keys(deps).length) return + +// var warnings = { +// E404: { title: 'Unregistered', list: [] }, +// ESCM: { title: 'SCM', list: [] }, +// EDEPTYPE: { title: 'Non-string dependency', list: [] } +// } + +// for (var name in deps) { +// var dep = deps[name] + +// if (dep.warn) { +// warnings[dep.warn.code].list.push([clc.magenta(name), clc.red(dep.warn.toString())]) +// } +// } + +// Object.keys(warnings).forEach(function (warnType) { +// var warnList = warnings[warnType].list + +// if (!warnList.length) return + +// var table = new Table({ head: ['Name', 'Message'], style: { head: ['reset'] } }) + +// console.log(clc.underline(warnings[warnType].title + ' ' + (type ? type + 'D' : 'd') + 'ependencies') + '\n') +// warnList.forEach(function (row) { table.push(row) }) +// console.log(table.toString() + '\n') +// }) +// } function printDeps (deps, type) { if (!Object.keys(deps).length) return @@ -82,7 +85,7 @@ function printDeps (deps, type) { oneLine.push('--save') } - var nonWarnDepNames = getNonWarnDepNames(deps) + var nonWarnDepNames = Object.keys(deps) if (nonWarnDepNames.length) { if (type) { @@ -108,54 +111,39 @@ function printDeps (deps, type) { console.log('\n' + table.toString() + '\n\n' + oneLine.join(' ') + '\n') } - printWarnings(deps, type) + // printWarnings(deps, type) } // Get a list of dependency filters -var filterList = argv._.filter(function (v) { - return !(v === 'update' || v === 'u') -}) +const filterList = argv._.filter(v => !(v === 'update' || v === 'u')) // Filter the passed deps (result from david) by the dependency names passed on the command line function filterDeps (deps) { - if (!filterList.length) return deps - - return Object.keys(deps).reduce(function (filteredDeps, name) { - if (filterList.indexOf(name) !== -1) { - filteredDeps[name] = deps[name] - } - return filteredDeps - }, {}) + filterList.forEach(n => { delete deps[n] }) + return deps } // Get updated deps, devDeps and optionalDeps -function getUpdatedDeps (pkg, cb) { - var opts = { - stable: !argv.unstable, - loose: true, - error: { - E404: argv.error404, - ESCM: argv.errorSCM, - EDEPTYPE: argv.errorDepType - }, - ignore: argv.ignore || argv.i +async function getUpdatedDeps (pkg) { + const stable = !argv.unstable + + const opts = { + registry: argv.registry, + semver: { loose: true }, + ignoreNotFound: !argv.error404, + ignoreNonSemver: !argv.errorSCM || !argv.errorDepType, + ignoreModules: argv.ignore || argv.i } - if (argv.registry) { - opts.npm = { registry: argv.registry } - } - - david.getUpdatedDependencies(pkg, opts, function (err, deps) { - if (err) return cb(err) + const [ infos, devInfos, optionalInfos ] = (await Promise.all([ + david.dependenciesInfo(pkg.dependencies, opts), + david.dependenciesInfo(pkg.devDependencies, opts), + david.dependenciesInfo(pkg.optionalDependencies, opts) + ])).map(filterDeps).map(infos => ( + Object.fromEntries(Object.entries(infos).filter(([, i]) => david.isUpdated(i, { stable }))) + )) - david.getUpdatedDependencies(pkg, xtend(opts, { dev: true }), function (err, devDeps) { - if (err) return cb(err) - - david.getUpdatedDependencies(pkg, xtend(opts, { optional: true }), function (err, optionalDeps) { - cb(err, filterDeps(deps), filterDeps(devDeps), filterDeps(optionalDeps)) - }) - }) - }) + return { infos, devInfos, optionalInfos } } /** @@ -170,171 +158,173 @@ function getUpdatedDeps (pkg, cb) { * @param {String} [opts.registry] The npm registry URL to use * @param {Function} cb Callback */ -function installDeps (deps, opts, cb) { - opts = opts || {} - - var depNames = Object.keys(deps) - - // Nothing to install! - if (!depNames.length) { - return cb(null) - } - - depNames = depNames.filter(function (depName) { - return !deps[depName].warn - }) - - var npmOpts = { global: opts.global } - - // Avoid warning message from npm for invalid registry url - if (opts.registry) { - npmOpts.registry = opts.registry - } - - npm.load(npmOpts, function (err) { - if (err) return cb(err) - - if (opts.save) { - npm.config.set('save' + (opts.dev ? '-dev' : opts.optional ? '-optional' : ''), true) - } - - var installArgs = [depNames.map(function (depName) { - return depName + '@' + deps[depName][argv.unstable ? 'latest' : 'stable'] - }), function (err) { - npm.config.set('save' + (opts.dev ? '-dev' : opts.optional ? '-optional' : ''), false) - cb(err) - }] - - if (opts.path) { installArgs.unshift(opts.path) } - - npm.commands.install.apply(npm.commands, installArgs) - }) -} - -if (argv.global || argv.g) { - var opts = { global: true } - - // Avoid warning message from npm for invalid registry url - if (argv.registry) { - opts.registry = argv.registry - } - - npm.load(opts, function (err) { - if (err) { - console.error('Failed to load npm', err) - exit(1) - } - - npm.commands.ls([], true, function (err, data) { - if (err) { - console.error('Failed to list global dependencies', err) - exit(1) - } - - var pkg = { - name: 'Global Dependencies', - dependencies: {} - } - - for (var key in data.dependencies) { - pkg.dependencies[key] = data.dependencies[key].version - } - - getUpdatedDeps(pkg, function (err, deps) { - if (err) { - console.error('Failed to get updated dependencies/devDependencies', err) - exit(1) - } - - if (argv.update) { - installDeps(deps, opts, function (err) { - if (err) { - console.error('Failed to update global dependencies', err) - exit(1) - } - printWarnings(deps, 'global') - }) - } else { - printDeps(deps, 'global') - if (getNonWarnDepNames(deps).length) { - exit(1) - } - // Log feedback if all global dependencies are up to date - console.log(clc.green('All global dependencies up to date')) - } - }) - }) - }) -} else { - var pkg, pkgDir - - if (argv.package || argv.p) { - pkg = argv.package || argv.p - pkgDir = path.dirname(pkg) +// function installDeps (deps, opts, cb) { +// opts = opts || {} + +// var depNames = Object.keys(deps) + +// // Nothing to install! +// if (!depNames.length) { +// return cb(null) +// } + +// depNames = depNames.filter(function (depName) { +// return !deps[depName].warn +// }) + +// var npmOpts = { global: opts.global } + +// // Avoid warning message from npm for invalid registry url +// if (opts.registry) { +// npmOpts.registry = opts.registry +// } + +// npm.load(npmOpts, function (err) { +// if (err) return cb(err) + +// if (opts.save) { +// npm.config.set('save' + (opts.dev ? '-dev' : opts.optional ? '-optional' : ''), true) +// } + +// var installArgs = [depNames.map(function (depName) { +// return depName + '@' + deps[depName][argv.unstable ? 'latest' : 'stable'] +// }), function (err) { +// npm.config.set('save' + (opts.dev ? '-dev' : opts.optional ? '-optional' : ''), false) +// cb(err) +// }] + +// if (opts.path) { installArgs.unshift(opts.path) } + +// npm.commands.install.apply(npm.commands, installArgs) +// }) +// } + +async function main () { + if (argv.global || argv.g) { + throw new Error('not implemented') + // var opts = { global: true } + + // // Avoid warning message from npm for invalid registry url + // if (argv.registry) { + // opts.registry = argv.registry + // } + + // npm.load(opts, function (err) { + // if (err) { + // console.error('Failed to load npm', err) + // exit(1) + // } + + // npm.commands.ls([], true, function (err, data) { + // if (err) { + // console.error('Failed to list global dependencies', err) + // exit(1) + // } + + // var pkg = { + // name: 'Global Dependencies', + // dependencies: {} + // } + + // for (var key in data.dependencies) { + // pkg.dependencies[key] = data.dependencies[key].version + // } + + // getUpdatedDeps(pkg, function (err, deps) { + // if (err) { + // console.error('Failed to get updated dependencies/devDependencies', err) + // exit(1) + // } + + // if (argv.update) { + // installDeps(deps, opts, function (err) { + // if (err) { + // console.error('Failed to update global dependencies', err) + // exit(1) + // } + // printWarnings(deps, 'global') + // }) + // } else { + // printDeps(deps, 'global') + // if (getNonWarnDepNames(deps).length) { + // exit(1) + // } + // // Log feedback if all global dependencies are up to date + // console.log(clc.green('All global dependencies up to date')) + // } + // }) + // }) + // }) } else { - pkgDir = process.cwd() - pkg = pkgDir + '/package.json' - } - - try { - pkg = fs.readFileSync(pkg) + var pkg, pkgDir + + if (argv.package || argv.p) { + pkg = argv.package || argv.p + pkgDir = path.dirname(pkg) + } else { + pkgDir = process.cwd() + pkg = pkgDir + '/package.json' + } + try { - pkg = JSON.parse(pkg) + pkg = fs.readFileSync(pkg) + try { + pkg = JSON.parse(pkg) + } catch (err) { + throw Object.assign(err, { message: `Failed to parse package.json: ${err.message}` }) + } } catch (err) { - console.error('Failed to parse package.json', err) - exit(1) - } - } catch (err) { - console.error('Failed to read package.json', err) - exit(1) - } - - getUpdatedDeps(pkg, function (err, deps, devDeps, optionalDeps) { - if (err) { - console.error('Failed to get updated dependencies/devDependencies', err) - exit(1) + throw Object.assign(err, { message: `Failed to read package.json: ${err.message}` }) } - + + const { infos, devInfos, optionalInfos } = await getUpdatedDeps(pkg) + if (argv.update) { - var opts = { save: true, registry: argv.registry, path: pkgDir } - - installDeps(deps, opts, function (err) { - if (err) { - console.error('Failed to update/save dependencies', err) - exit(1) - } - - installDeps(devDeps, xtend(opts, { dev: true }), function (err) { - if (err) { - console.error('Failed to update/save devDependencies', err) - exit(1) - } - - installDeps(optionalDeps, xtend(opts, { optional: true }), function (err) { - if (err) { - console.error('Failed to update/save optionalDependencies', err) - exit(1) - } - - printWarnings(deps) - printWarnings(devDeps, 'dev') - printWarnings(optionalDeps, 'optional') - }) - }) - }) + throw new Error('not implemented') + // var opts = { save: true, registry: argv.registry, path: pkgDir } + + // installDeps(deps, opts, function (err) { + // if (err) { + // console.error('Failed to update/save dependencies', err) + // exit(1) + // } + + // installDeps(devDeps, xtend(opts, { dev: true }), function (err) { + // if (err) { + // console.error('Failed to update/save devDependencies', err) + // exit(1) + // } + + // installDeps(optionalDeps, xtend(opts, { optional: true }), function (err) { + // if (err) { + // console.error('Failed to update/save optionalDependencies', err) + // exit(1) + // } + + // printWarnings(deps) + // printWarnings(devDeps, 'dev') + // printWarnings(optionalDeps, 'optional') + // }) + // }) + // }) } else { - printDeps(deps) - printDeps(devDeps, 'dev') - printDeps(optionalDeps, 'optional') - - if (getNonWarnDepNames(deps).length || - getNonWarnDepNames(devDeps).length || - getNonWarnDepNames(optionalDeps).length) { - exit(1) + printDeps(infos) + printDeps(devInfos, 'dev') + printDeps(optionalInfos, 'optional') + + if (Object.keys(infos).length || + Object.keys(devInfos).length || + Object.keys(optionalInfos).length) { + process.exit(1) } else { // Log feedback if all dependencies are up to date console.log(clc.green('All dependencies up to date')) } } - }) + } } + +main().catch(err => { + console.error(err) + process.exit(1) +}) diff --git a/example.js b/example.js new file mode 100644 index 0000000..a5bac02 --- /dev/null +++ b/example.js @@ -0,0 +1,23 @@ +import * as david from './src/david.js' +import { promises as fs } from 'fs' + +async function main () { + const pkg = JSON.parse(await fs.readFile('package.json')) + + const infos = await david.dependenciesInfo(pkg.dependencies) + console.log(`\n# Dependencies information for "${pkg.name}":`) + Object.entries(infos).forEach(printInfo) + + console.log('\n# Newer versions:') + Object.entries(infos).filter(([_, i]) => david.isUpdated(i)).forEach(printInfo) + + console.log('\n# Newer STABLE versions:') + Object.entries(infos).filter(([_, i]) => david.isUpdated(i, { stable: true })).forEach(printInfo) +} + +function printInfo ([name, info]) { + const { required, stable, latest } = info + console.log(`${name} (Required: ${required} Stable: ${stable || 'None'} Latest: ${latest})`) +} + +main() diff --git a/package-lock.json b/package-lock.json index a70fffa..b75f66b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3889,6 +3889,11 @@ } } }, + "umeta": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/umeta/-/umeta-0.2.4.tgz", + "integrity": "sha512-5jP1UTOgGVaXSnB/9qSGEkAe6f6C7buM0EFGA3fEMf7cZzCxGFjYIq6za1QttkooXrWUo4YDcSvOwLP8sgX3eQ==" + }, "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", diff --git a/package.json b/package.json index 906e851..0de0ac2 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,8 @@ "multimatch": "^4.0.0", "node-fetch": "^2.6.0", "promise-inflight": "^1.0.1", - "semver": "^7.3.2" + "semver": "^7.3.2", + "umeta": "^0.2.4" }, "devDependencies": { "coveralls": "^3.0.5", @@ -44,6 +45,6 @@ "tape": "^4.11.0" }, "engines": { - "node": ">=0.10.1" + "node": ">=14" } } diff --git a/src/david.js b/src/david.js index 9bd8c9e..6f9926b 100644 --- a/src/david.js +++ b/src/david.js @@ -28,19 +28,18 @@ const CORGI_DOC = 'application/vnd.npm.install-v1+json; q=1.0, application/json; /** * moduleInfo gets version info for the passed module. - * @param {Dependencies} deps A dependencies, devDependencies, peerDependencies etc. object as would be found in a package.json. + * @param {string} name Module name. * @param {object} [options] Options - * @param {boolean} [options.registry] npm registry URL. + * @param {string} [options.registry] npm registry URL. * @param {{ loose?: boolean }} [options.semver] Semver options. * @param {boolean} [options.ignoreNotFound] Ignore 404 errors. * @param {string[]} [options.ignoreModules] List of dependency names or globs to ignore. - * @return {Promise} + * @return {Promise<{ latest: string, stable: string, versions: string[] }>} */ -export function moduleInfo (name, range, options) { - range = range || '*' +function moduleInfo (name, options) { options = options || {} - return inflight(`${name}:${range}`, async () => { + return inflight(name, async () => { const url = `${options.registry || REGISTRY}/${encodeURIComponent(name)}` const res = await fetch(url, { headers: { accept: CORGI_DOC } }) @@ -60,7 +59,7 @@ export function moduleInfo (name, range, options) { const versions = Object.keys(packument.versions) const { latest, stable } = getLatest(distTagsLatest, versions, options) - return { required: range, latest, stable, versions } + return { latest, stable, versions } }) } @@ -68,7 +67,7 @@ export function moduleInfo (name, range, options) { * dependenciesInfo gets module info for the passed dependencies object. * @param {Dependencies} deps A dependencies, devDependencies, peerDependencies etc. object as would be found in a package.json. * @param {object} [options] Options - * @param {boolean} [options.registry] npm registry URL. + * @param {string} [options.registry] npm registry URL. * @param {{ loose?: boolean }} [options.semver] Semver options. * @param {string[]} [options.ignoreModules] List of dependency names or globs to ignore. * @param {boolean} [options.ignoreNotFound] Ignore 404 errors. @@ -96,7 +95,8 @@ export async function dependenciesInfo (deps, options) { }) .map(async ([n, r]) => { try { - return [n, await moduleInfo(n, r, options)] + const info = await moduleInfo(n, options) + return [n, { required: r, ...info }] } catch (err) { if (options.ignoreNotFound && err.response && err.response.status === 404) { return null @@ -160,11 +160,12 @@ function isStable (version) { } /** - * Get the latest version and latest stable version. + * getLatest get the latest version and latest stable version. * @param {string} current The version you get when you `npm install [package]` * @param {string[]} versions All versions available * @param {object} options Options * @param {object} [opts.semver] Semver options + * @returns {Promise<{ latest: string, stable: string }>} */ function getLatest (current, versions, options) { options = options || {} From a2b5b83cf387520fe162b3e63e5965335926fbff Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Mon, 17 Aug 2020 11:59:42 +0100 Subject: [PATCH 03/10] 13.0.0-alpha.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index b75f66b..dcd0576 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "david", - "version": "12.0.0", + "version": "13.0.0-alpha.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 0de0ac2..06bbebb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "david", - "version": "12.0.0", + "version": "13.0.0-alpha.0", "description": "Node.js module that tells you when your project npm dependencies are out of date.", "type": "module", "main": "src/david.js", From 2f197ea76f6c5f5a8dd6b38b4a012832b4e77586 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Wed, 26 Aug 2020 21:03:54 +0100 Subject: [PATCH 04/10] fix: better normalise --- src/david.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/david.js b/src/david.js index 6f9926b..731492e 100644 --- a/src/david.js +++ b/src/david.js @@ -111,9 +111,14 @@ export async function dependenciesInfo (deps, options) { // normaliseDeps converts dependencies specified as an array to an object. function normaliseDeps (deps) { - return Array.isArray(deps) - ? Object.fromEntries(deps.map(n => [n, '*'])) - : deps || {} + if (Array.isArray(deps)) { + return Object.fromEntries(deps.map(n => [n, '*'])) + } else if (Object.prototype.toString.call(deps) === '[object String]') { + return { [deps]: '*' } + } else if (!(deps instanceof Object)) { + return {} + } + return deps } /** From ce68e47977fd8bd6beac135f32820d8c454ed9f6 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Wed, 26 Aug 2020 21:05:17 +0100 Subject: [PATCH 05/10] 13.0.0-alpha.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index dcd0576..7ec3b0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "david", - "version": "13.0.0-alpha.0", + "version": "13.0.0-alpha.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 06bbebb..129bd1b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "david", - "version": "13.0.0-alpha.0", + "version": "13.0.0-alpha.1", "description": "Node.js module that tells you when your project npm dependencies are out of date.", "type": "module", "main": "src/david.js", From 82838e49638bf7a7c248564a021c745b15a49dc5 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Wed, 26 Aug 2020 21:14:12 +0100 Subject: [PATCH 06/10] feat: export normalize function --- src/david.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/david.js b/src/david.js index 731492e..54be9e3 100644 --- a/src/david.js +++ b/src/david.js @@ -75,7 +75,7 @@ function moduleInfo (name, options) { * @return {Promise} */ export async function dependenciesInfo (deps, options) { - deps = normaliseDeps(deps) + deps = normalizeDependencies(deps) options = options || {} const entries = await Promise.all( @@ -109,8 +109,8 @@ export async function dependenciesInfo (deps, options) { return Object.fromEntries(entries.filter(Boolean)) } -// normaliseDeps converts dependencies specified as an array to an object. -function normaliseDeps (deps) { +// normalizeDependencies converts dependencies specified as an array to an object. +export function normalizeDependencies (deps) { if (Array.isArray(deps)) { return Object.fromEntries(deps.map(n => [n, '*'])) } else if (Object.prototype.toString.call(deps) === '[object String]') { From 401e3b4bbf7c9942c62e1709f124a51d288a5560 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Wed, 26 Aug 2020 21:14:35 +0100 Subject: [PATCH 07/10] 13.0.0-alpha.2 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7ec3b0f..fc2f71a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "david", - "version": "13.0.0-alpha.1", + "version": "13.0.0-alpha.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 129bd1b..3465b86 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "david", - "version": "13.0.0-alpha.1", + "version": "13.0.0-alpha.2", "description": "Node.js module that tells you when your project npm dependencies are out of date.", "type": "module", "main": "src/david.js", From e0e3b39ffd09862e52e020fc315e7a86e51bbf16 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Sun, 6 Sep 2020 19:56:21 +0100 Subject: [PATCH 08/10] docs: remove invalid params --- src/david.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/david.js b/src/david.js index 54be9e3..2c27bc6 100644 --- a/src/david.js +++ b/src/david.js @@ -32,8 +32,6 @@ const CORGI_DOC = 'application/vnd.npm.install-v1+json; q=1.0, application/json; * @param {object} [options] Options * @param {string} [options.registry] npm registry URL. * @param {{ loose?: boolean }} [options.semver] Semver options. - * @param {boolean} [options.ignoreNotFound] Ignore 404 errors. - * @param {string[]} [options.ignoreModules] List of dependency names or globs to ignore. * @return {Promise<{ latest: string, stable: string, versions: string[] }>} */ function moduleInfo (name, options) { From 017e24205eb36d4552c244b840452d256e8c367a Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Tue, 15 Dec 2020 10:45:48 +0000 Subject: [PATCH 09/10] feat: include invalid range in error message --- src/david.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/david.js b/src/david.js index 2c27bc6..030f2d0 100644 --- a/src/david.js +++ b/src/david.js @@ -86,7 +86,7 @@ export async function dependenciesInfo (deps, options) { if (options.ignoreNonSemverRange) { return false } else { - throw new Error(`non semver version for module ${n}`) + throw new Error(`non semver version for module ${n}: ${r}`) } } return true From a97cfd97d9392d122f10c4a2d09bc9514b1f0f6f Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Tue, 15 Dec 2020 10:46:48 +0000 Subject: [PATCH 10/10] 13.0.0-beta.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3465b86..148bfc3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "david", - "version": "13.0.0-alpha.2", + "version": "13.0.0-beta.0", "description": "Node.js module that tells you when your project npm dependencies are out of date.", "type": "module", "main": "src/david.js",