Comparing version 0.0.10 to 0.1.0
139
dist/cli.js
@@ -315,3 +315,3 @@ 'use strict'; | ||
if (!range) | ||
return null; | ||
throw new Error('invalid_range'); | ||
const prefix = getVersionRangePrefix(current); | ||
@@ -325,2 +325,3 @@ if (range === '*') | ||
function getLatestVersions(name) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -341,3 +342,3 @@ if (versionCache[name]) | ||
versions: [], | ||
error: e.statusCode || e, | ||
error: ((_a = e === null || e === void 0 ? void 0 : e.statusCode) === null || _a === void 0 ? void 0 : _a.toString()) || e, | ||
}; | ||
@@ -355,9 +356,18 @@ return versionCache[name]; | ||
const { versions, tags, error } = yield getLatestVersions(dep.name); | ||
let err = null; | ||
let max = null; | ||
if (!error) { | ||
max = mode === 'latest' | ||
? tags.latest | ||
: getMaxSatisfying(versions, dep.currentVersion, mode); | ||
if (error == null) { | ||
try { | ||
max = mode === 'latest' | ||
? tags.latest | ||
: getMaxSatisfying(versions, dep.currentVersion, mode); | ||
} | ||
catch (e) { | ||
err = e.message || e; | ||
} | ||
} | ||
if (!error && max) { | ||
else { | ||
err = error; | ||
} | ||
if (err != null && max) { | ||
dep.latestVersion = max; | ||
@@ -373,3 +383,3 @@ const current = semver.minVersion(dep.currentVersion); | ||
dep.update = false; | ||
dep.resolveError = error !== null && error !== void 0 ? error : 'invalid_range'; | ||
dep.resolveError = err; | ||
} | ||
@@ -429,7 +439,2 @@ return dep; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const logger = new TableLogger({ | ||
columns: 5, | ||
pending: 2, | ||
align: 'LLRRR', | ||
}); | ||
// packages loading | ||
@@ -444,4 +449,12 @@ const packages = yield loadPackages(options); | ||
const filter = (dep) => filterAction(dep.name) && !privatePackageNames.includes(dep.name); | ||
// progress bar | ||
console.log(); | ||
checkAllPackages(options, packages, filter); | ||
}); | ||
} | ||
function checkAllPackages(options, packages, filter) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const logger = new TableLogger({ | ||
columns: 5, | ||
pending: 2, | ||
align: 'LLRRR', | ||
}); | ||
const bars = new cliProgress.MultiBar({ | ||
@@ -454,2 +467,4 @@ clearOnComplete: true, | ||
}, cliProgress.Presets.shades_grey); | ||
// progress bar | ||
console.log(); | ||
const packagesBar = options.recursive ? bars.create(packages.length, 0, { type: chalk.cyan('pkg') }) : null; | ||
@@ -459,3 +474,3 @@ const depBar = bars.create(1, 0); | ||
packagesBar === null || packagesBar === void 0 ? void 0 : packagesBar.increment(0, { name: chalk.cyan(pkg.name) }); | ||
yield checkProject(pkg, options, filter, privatePackageNames, logger, depBar); | ||
yield checkProject(pkg, options, filter, logger, depBar); | ||
packagesBar === null || packagesBar === void 0 ? void 0 : packagesBar.increment(1); | ||
@@ -476,3 +491,3 @@ } | ||
} | ||
function checkProject(pkg, options, filter, privatePackageNames, logger, bar) { | ||
function checkProject(pkg, options, filter, logger, bar) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -529,3 +544,3 @@ bar.start(pkg.deps.length, 0, { type: chalk.green('dep') }); | ||
return; | ||
if (dep.resolveError === 404) { | ||
if (dep.resolveError === '404') { | ||
logger.log(chalk.redBright(`> ${chalk.underline(dep.name)} not found`)); | ||
@@ -542,2 +557,39 @@ } | ||
function usage(options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const pkgs = yield loadPackages(options); | ||
const names = {}; | ||
for (const pkg of pkgs) { | ||
for (const dep of pkg.deps) { | ||
if (!names[dep.name]) | ||
names[dep.name] = {}; | ||
if (!names[dep.name][dep.currentVersion]) | ||
names[dep.name][dep.currentVersion] = []; | ||
names[dep.name][dep.currentVersion].push(pkg); | ||
} | ||
} | ||
const logger = new TableLogger({ | ||
columns: 4, | ||
align: 'LRRR', | ||
}); | ||
logger.log(); | ||
const usages = Object.entries(names) | ||
.sort((a, b) => Object.keys(b[1]).length - Object.keys(a[1]).length); | ||
for (const [name, deps] of usages) { | ||
const versions = Object.keys(deps).sort(); | ||
const packages = Object.values(deps).flatMap(i => i).length; | ||
if (versions.length > 1) { | ||
const color = versions.length >= 5 | ||
? 'magenta' | ||
: versions.length >= 3 | ||
? 'red' | ||
: 'yellow'; | ||
logger.row(chalk.green(name), chalk.gray(`${chalk.cyan(packages.toString())} in use / ${chalk[color](versions.length.toString())} versions`), versions.join(chalk.gray(', '))); | ||
} | ||
} | ||
logger.log(); | ||
logger.output(); | ||
}); | ||
} | ||
// eslint-disable-next-line no-unused-expressions | ||
@@ -547,2 +599,48 @@ yargs | ||
.usage('$0 [args]') | ||
.command('usage', 'List dependencies versions usage across packages', (args) => { | ||
args | ||
.option('cwd', { | ||
alias: 'C', | ||
default: '', | ||
type: 'string', | ||
describe: 'specify the current working directory', | ||
}) | ||
.option('recursive', { | ||
alias: 'r', | ||
default: false, | ||
type: 'boolean', | ||
describe: 'recursively search for package.json in subdirectories', | ||
}) | ||
// TODO: | ||
.option('detail', { | ||
alias: 'a', | ||
type: 'boolean', | ||
default: false, | ||
describe: 'show more info', | ||
}) | ||
// TODO: | ||
.option('filter', { | ||
type: 'string', | ||
describe: 'filter rules to restrict dependencies to check updates', | ||
array: true, | ||
}) | ||
.option('ignore', { | ||
type: 'string', | ||
describe: 'ignore rules to restrict dependencies to not check updates', | ||
}) | ||
// TODO: | ||
.option('dev', { | ||
alias: 'D', | ||
default: false, | ||
type: 'boolean', | ||
describe: 'update only for devDependencies', | ||
}) | ||
// TODO: | ||
.option('prod', { | ||
alias: 'P', | ||
default: false, | ||
type: 'boolean', | ||
describe: 'update only for dependencies', | ||
}); | ||
}, usage) | ||
.command('* [mode]', 'Keeps your deps fresh', (args) => { | ||
@@ -573,2 +671,7 @@ args | ||
}) | ||
.option('usage', { | ||
type: 'boolean', | ||
default: false, | ||
describe: 'list usages of dependencies accross packages', | ||
}) | ||
// TODO: | ||
@@ -575,0 +678,0 @@ .option('filter', { |
@@ -24,9 +24,15 @@ import semver from 'semver'; | ||
update: boolean; | ||
resolveError?: number | string | Error; | ||
resolveError?: Error | string | null; | ||
} | ||
interface CheckOptions { | ||
interface LoadOptions { | ||
cwd: string; | ||
recursive: boolean; | ||
} | ||
interface UsageOptions extends LoadOptions { | ||
filter?: string; | ||
} | ||
interface CheckOptions extends LoadOptions { | ||
mode: RangeMode; | ||
write: boolean; | ||
usage: boolean; | ||
filter: string[]; | ||
@@ -73,3 +79,3 @@ } | ||
declare function loadPackage(root: string, relative: string): Promise<PackageMeta>; | ||
declare function loadPackages(options: CheckOptions): Promise<PackageMeta[]>; | ||
declare function loadPackages(options: LoadOptions): Promise<PackageMeta[]>; | ||
@@ -79,2 +85,2 @@ declare function parseDependencies(pkg: any, type: DependenciesType): RawDependency[]; | ||
export { CheckOptions, DependenciesType, DependenciesTypeShortMap, DependencyFilter, DiffType, PackageMeta, ProgressCallback, RangeMode, RawDependency, ResolvedDependencies, dumpDependencies, loadPackage, loadPackages, parseDependencies, resolveDependencies, resolveDependency, resolvePackage, writePackage }; | ||
export { CheckOptions, DependenciesType, DependenciesTypeShortMap, DependencyFilter, DiffType, LoadOptions, PackageMeta, ProgressCallback, RangeMode, RawDependency, ResolvedDependencies, UsageOptions, dumpDependencies, loadPackage, loadPackages, parseDependencies, resolveDependencies, resolveDependency, resolvePackage, writePackage }; |
@@ -114,3 +114,3 @@ import pacote from 'pacote'; | ||
if (!range) | ||
return null; | ||
throw new Error('invalid_range'); | ||
const prefix = getVersionRangePrefix(current); | ||
@@ -124,2 +124,3 @@ if (range === '*') | ||
function getLatestVersions(name) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -140,3 +141,3 @@ if (versionCache[name]) | ||
versions: [], | ||
error: e.statusCode || e, | ||
error: ((_a = e === null || e === void 0 ? void 0 : e.statusCode) === null || _a === void 0 ? void 0 : _a.toString()) || e, | ||
}; | ||
@@ -154,9 +155,18 @@ return versionCache[name]; | ||
const { versions, tags, error } = yield getLatestVersions(dep.name); | ||
let err = null; | ||
let max = null; | ||
if (!error) { | ||
max = mode === 'latest' | ||
? tags.latest | ||
: getMaxSatisfying(versions, dep.currentVersion, mode); | ||
if (error == null) { | ||
try { | ||
max = mode === 'latest' | ||
? tags.latest | ||
: getMaxSatisfying(versions, dep.currentVersion, mode); | ||
} | ||
catch (e) { | ||
err = e.message || e; | ||
} | ||
} | ||
if (!error && max) { | ||
else { | ||
err = error; | ||
} | ||
if (err != null && max) { | ||
dep.latestVersion = max; | ||
@@ -172,3 +182,3 @@ const current = semver.minVersion(dep.currentVersion); | ||
dep.update = false; | ||
dep.resolveError = error !== null && error !== void 0 ? error : 'invalid_range'; | ||
dep.resolveError = err; | ||
} | ||
@@ -175,0 +185,0 @@ return dep; |
@@ -120,3 +120,3 @@ 'use strict'; | ||
if (!range) | ||
return null; | ||
throw new Error('invalid_range'); | ||
const prefix = getVersionRangePrefix(current); | ||
@@ -130,2 +130,3 @@ if (range === '*') | ||
function getLatestVersions(name) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -146,3 +147,3 @@ if (versionCache[name]) | ||
versions: [], | ||
error: e.statusCode || e, | ||
error: ((_a = e === null || e === void 0 ? void 0 : e.statusCode) === null || _a === void 0 ? void 0 : _a.toString()) || e, | ||
}; | ||
@@ -160,9 +161,18 @@ return versionCache[name]; | ||
const { versions, tags, error } = yield getLatestVersions(dep.name); | ||
let err = null; | ||
let max = null; | ||
if (!error) { | ||
max = mode === 'latest' | ||
? tags.latest | ||
: getMaxSatisfying(versions, dep.currentVersion, mode); | ||
if (error == null) { | ||
try { | ||
max = mode === 'latest' | ||
? tags.latest | ||
: getMaxSatisfying(versions, dep.currentVersion, mode); | ||
} | ||
catch (e) { | ||
err = e.message || e; | ||
} | ||
} | ||
if (!error && max) { | ||
else { | ||
err = error; | ||
} | ||
if (err != null && max) { | ||
dep.latestVersion = max; | ||
@@ -178,3 +188,3 @@ const current = semver.minVersion(dep.currentVersion); | ||
dep.update = false; | ||
dep.resolveError = error !== null && error !== void 0 ? error : 'invalid_range'; | ||
dep.resolveError = err; | ||
} | ||
@@ -181,0 +191,0 @@ return dep; |
{ | ||
"name": "taze", | ||
"version": "0.0.10", | ||
"version": "0.1.0", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -11,15 +11,86 @@ <h1 align="center">🥦 Taze<sup>𝛼</sup></h1> | ||
## Usage | ||
<p align='center'> | ||
<img src='./screenshots/r-major.png' width='600'/> | ||
</p> | ||
## Features | ||
- Built-in support for monorepos | ||
- Update in the version range your defined by default | ||
- No installation required - `npx taze` | ||
- Safe by default - updates in the version range your allowed | ||
## Usage | ||
By default, `taze` will only bump versions in the ranges you specified in package.json *(which is safe and the default behavior of `npm install`)* | ||
<p align='center'> | ||
<img src='./screenshots/default.png' width='600'/> | ||
</p> | ||
To ignore the ranges, if you explicitly set the maximum allowenace version changes. | ||
For example `taze major` will check all changes and bump to the lastest stable changes including majors(breaking changes), or `taze minor` that bump to lastest minor changes within the same major version. | ||
<br> | ||
<p align='center'> | ||
Check for <b>major</b> updates | ||
<br> | ||
<img src='./screenshots/major.png' width='600'/> | ||
</p> | ||
<p align='center'> | ||
Check up to <b>minor</b> updates | ||
<br> | ||
<img src='./screenshots/minor.png' width='600'/> | ||
</p> | ||
<p align='center'> | ||
Check up to <b>patch</b> updates | ||
<br> | ||
<img src='./screenshots/patch.png' width='600'/> | ||
</p> | ||
### Monorepo | ||
`taze` has the built-in first-class monorepo support. Simply adding `-r`, it will scan the subdirectories that contains `package.json` and update them together. It will handles in local private packages automatically. | ||
<p align='center'> | ||
<img src='./screenshots/r-default.png' width='600'/> | ||
</p> | ||
## Configures | ||
See `taze --help` for more details | ||
### Filter | ||
You can filter out packages you want to check for upgrades by string or regex. | ||
```bash | ||
taze --filter lodash,webpack | ||
taze --filter /(lo|hi)dash/ # regex is also supported | ||
``` | ||
<p align='center'> | ||
<img src='./screenshots/filter.png' width='600'/> | ||
</p> | ||
## Programmatic APIs | ||
> TODO: | ||
## Alternatives | ||
`taze` is great inspired from the following tools. They work well but have different feature sets and focuses, try them out as well! | ||
`taze` is inspired from the following tools. | ||
- [npm-check-updates](https://github.com/raineorshine/npm-check-updates) | ||
- [npm-check](https://github.com/dylang/npm-check) | ||
- [npm-check](https://github.com/dylang/npm-check) | ||
They work well but have different focuses and feature sets, try them out as well :) | ||
## Thanks | ||
Great thanks to [@sinoon](https://github.com/sinoon) who helped a lot on having idea brainstroming and feedback discussion. |
53183
1350
95