node-power-user 1.0.17 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/commands/outdated.js +193 -66
- package/dist/commands/sync.js +1 -1
- package/package.json +5 -4
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ const ALIASES = {
|
|
|
9
9
|
clean: ['-c', '--clean'],
|
|
10
10
|
global: ['-g', '--global'],
|
|
11
11
|
open: ['--open', 'repo', '--repo'],
|
|
12
|
-
outdated: ['-o', 'out', '--outdated'],
|
|
12
|
+
outdated: ['-o', 'out', '--outdated', '-u', '--update', 'up', 'update'],
|
|
13
13
|
packages: ['-p', 'pack', '--packages'],
|
|
14
14
|
version: ['-v', '--version'],
|
|
15
15
|
sync: ['-s', '--sync', 'push', '--push'],
|
|
@@ -2,21 +2,38 @@
|
|
|
2
2
|
const logger = new (require('../lib/logger'))('node-power-user');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const { table } = require('table');
|
|
5
|
-
const ProgressBar = require('cli-progress');
|
|
6
|
-
const Npm = require('npm-api');
|
|
7
|
-
const version = require('wonderful-version');
|
|
8
5
|
const jetpack = require('fs-jetpack');
|
|
9
6
|
const path = require('path');
|
|
10
|
-
|
|
11
|
-
const
|
|
7
|
+
const version = require('wonderful-version');
|
|
8
|
+
const inquirer = require('@inquirer/prompts');
|
|
9
|
+
const ncu = require('npm-check-updates');
|
|
10
|
+
const { execute } = require('node-powertools');
|
|
12
11
|
|
|
13
12
|
// Load package.json
|
|
14
13
|
const projectPath = process.cwd();
|
|
15
|
-
const projectJson = jetpack.read(path.join(projectPath, 'package.json'), 'json') || {};
|
|
16
14
|
|
|
17
15
|
// Module
|
|
18
16
|
module.exports = async function (options) {
|
|
19
|
-
|
|
17
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
18
|
+
let projectJson = jetpack.read(packageJsonPath, 'json');
|
|
19
|
+
|
|
20
|
+
// Check if package.json exists
|
|
21
|
+
if (!projectJson) {
|
|
22
|
+
logger.error('No package.json found in the current directory.');
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Log start
|
|
27
|
+
logger.log(`Checking packages for ${logger.format.bold(projectJson.name || 'Unknown Project')}...`);
|
|
28
|
+
|
|
29
|
+
// Run ncu for patch, minor, and latest
|
|
30
|
+
const [patchUpgrades, minorUpgrades, latestUpgrades] = await Promise.all([
|
|
31
|
+
ncu.run({ packageFile: packageJsonPath, target: 'patch' }),
|
|
32
|
+
ncu.run({ packageFile: packageJsonPath, target: 'minor' }),
|
|
33
|
+
ncu.run({ packageFile: packageJsonPath, target: 'latest' }),
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
// Get all dependencies
|
|
20
37
|
const allDependencies = Object.assign(
|
|
21
38
|
{},
|
|
22
39
|
projectJson.dependencies,
|
|
@@ -24,77 +41,187 @@ module.exports = async function (options) {
|
|
|
24
41
|
projectJson.peerDependencies
|
|
25
42
|
);
|
|
26
43
|
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
logger.warn('No dependencies found in package.json.');
|
|
30
|
-
return {};
|
|
31
|
-
}
|
|
44
|
+
// Build unified package data
|
|
45
|
+
const allPackages = new Map();
|
|
32
46
|
|
|
33
|
-
|
|
34
|
-
|
|
47
|
+
for (const dep of Object.keys(allDependencies)) {
|
|
48
|
+
const packageVersion = version.clean(allDependencies[dep]);
|
|
49
|
+
const installedPackagePath = path.join(projectPath, 'node_modules', dep, 'package.json');
|
|
35
50
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
51
|
+
let installedVersion = null;
|
|
52
|
+
if (jetpack.exists(installedPackagePath)) {
|
|
53
|
+
const installedJson = jetpack.read(installedPackagePath, 'json');
|
|
54
|
+
installedVersion = installedJson?.version ? version.clean(installedJson.version) : null;
|
|
55
|
+
}
|
|
40
56
|
|
|
41
|
-
|
|
57
|
+
const patchVersion = patchUpgrades[dep] ? version.clean(patchUpgrades[dep]) : null;
|
|
58
|
+
const minorVersion = minorUpgrades[dep] ? version.clean(minorUpgrades[dep]) : null;
|
|
59
|
+
const latestVersion = latestUpgrades[dep] ? version.clean(latestUpgrades[dep]) : null;
|
|
42
60
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
progress.increment();
|
|
61
|
+
// Check if this package needs attention
|
|
62
|
+
const hasDiscrepancy = installedVersion && !version.is(installedVersion, '==', packageVersion);
|
|
63
|
+
const hasUpdate = latestVersion && latestVersion !== packageVersion;
|
|
47
64
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
65
|
+
if (hasDiscrepancy || hasUpdate) {
|
|
66
|
+
allPackages.set(dep, {
|
|
67
|
+
name: dep,
|
|
68
|
+
packageVersion,
|
|
69
|
+
installedVersion: installedVersion || '?',
|
|
70
|
+
patchVersion,
|
|
71
|
+
minorVersion,
|
|
72
|
+
latestVersion,
|
|
73
|
+
type: getDependencyType(projectJson, dep),
|
|
74
|
+
hasDiscrepancy,
|
|
75
|
+
hasMajorUpdate: latestVersion && minorVersion !== latestVersion,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
51
79
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
80
|
+
// Display unified table
|
|
81
|
+
if (allPackages.size === 0) {
|
|
82
|
+
logger.log(logger.format.green('\nAll packages are up to date!'));
|
|
83
|
+
return { allPackages };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const dataTable = [['Package', 'package.json', 'Installed', 'Latest', 'Type']];
|
|
87
|
+
|
|
88
|
+
for (const pkg of allPackages.values()) {
|
|
89
|
+
const pkgVersionColor = pkg.hasDiscrepancy ? 'red' : 'green';
|
|
90
|
+
|
|
91
|
+
// Format latest version - show major updates in magenta
|
|
92
|
+
let latestDisplay;
|
|
93
|
+
if (pkg.latestVersion) {
|
|
94
|
+
if (pkg.hasMajorUpdate) {
|
|
95
|
+
latestDisplay = chalk.magenta(pkg.latestVersion + ' ⚠');
|
|
96
|
+
} else if (pkg.latestVersion !== pkg.installedVersion) {
|
|
97
|
+
latestDisplay = chalk.cyan(pkg.latestVersion);
|
|
98
|
+
} else {
|
|
99
|
+
latestDisplay = chalk.green(pkg.latestVersion);
|
|
56
100
|
}
|
|
101
|
+
} else {
|
|
102
|
+
latestDisplay = chalk.dim('-');
|
|
103
|
+
}
|
|
57
104
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
105
|
+
dataTable.push([
|
|
106
|
+
pkg.name,
|
|
107
|
+
chalk[pkgVersionColor](pkg.packageVersion),
|
|
108
|
+
chalk.green(pkg.installedVersion),
|
|
109
|
+
latestDisplay,
|
|
110
|
+
pkg.type,
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
console.log(table(dataTable));
|
|
115
|
+
logger.log(chalk.dim('Legend: ') + chalk.magenta('⚠ = major version (breaking changes)'));
|
|
116
|
+
|
|
117
|
+
// Get counts for menu
|
|
118
|
+
const discrepancies = [...allPackages.values()].filter(pkg => pkg.hasDiscrepancy);
|
|
119
|
+
const patchCount = Object.keys(patchUpgrades).length;
|
|
120
|
+
const minorCount = Object.keys(minorUpgrades).length;
|
|
121
|
+
const majorCount = Object.keys(latestUpgrades).length;
|
|
122
|
+
|
|
123
|
+
// Check for shortcut flags (skip menu)
|
|
124
|
+
let action = null;
|
|
125
|
+
if (options.r || options.reconcile) {
|
|
126
|
+
action = 'reconcile';
|
|
127
|
+
} else if (options.P || options.patch) {
|
|
128
|
+
action = 'patch';
|
|
129
|
+
} else if (options.m || options.minor) {
|
|
130
|
+
action = 'minor';
|
|
131
|
+
} else if (options.M || options.major) {
|
|
132
|
+
action = 'latest';
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// If no shortcut, show menu
|
|
136
|
+
if (!action) {
|
|
137
|
+
const choices = [];
|
|
138
|
+
|
|
139
|
+
if (discrepancies.length > 0) {
|
|
140
|
+
choices.push({
|
|
141
|
+
name: `Reconcile (${discrepancies.length}) - sync package.json to installed versions`,
|
|
142
|
+
value: 'reconcile',
|
|
143
|
+
});
|
|
87
144
|
}
|
|
145
|
+
|
|
146
|
+
if (patchCount > 0) {
|
|
147
|
+
choices.push({
|
|
148
|
+
name: `Patch (${patchCount}) - safe bug fixes only`,
|
|
149
|
+
value: 'patch',
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (minorCount > 0) {
|
|
154
|
+
choices.push({
|
|
155
|
+
name: `Minor (${minorCount}) - new features, no breaking changes`,
|
|
156
|
+
value: 'minor',
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (majorCount > 0) {
|
|
161
|
+
choices.push({
|
|
162
|
+
name: `Major (${majorCount}) - all updates including breaking changes ⚠`,
|
|
163
|
+
value: 'latest',
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
choices.push({ name: 'Exit', value: 'exit' });
|
|
168
|
+
|
|
169
|
+
action = await inquirer.select({
|
|
170
|
+
message: 'What would you like to do?',
|
|
171
|
+
choices,
|
|
172
|
+
});
|
|
88
173
|
}
|
|
89
174
|
|
|
90
|
-
|
|
91
|
-
|
|
175
|
+
if (action === 'exit') {
|
|
176
|
+
return { allPackages };
|
|
177
|
+
}
|
|
92
178
|
|
|
93
|
-
//
|
|
94
|
-
|
|
179
|
+
// Handle reconcile
|
|
180
|
+
if (action === 'reconcile') {
|
|
181
|
+
// Re-read in case it changed
|
|
182
|
+
projectJson = jetpack.read(packageJsonPath, 'json');
|
|
95
183
|
|
|
96
|
-
|
|
97
|
-
|
|
184
|
+
for (const pkg of discrepancies) {
|
|
185
|
+
const depType = pkg.type === 'dev' ? 'devDependencies'
|
|
186
|
+
: pkg.type === 'peer' ? 'peerDependencies'
|
|
187
|
+
: 'dependencies';
|
|
98
188
|
|
|
99
|
-
|
|
189
|
+
projectJson[depType][pkg.name] = `^${pkg.installedVersion}`;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
jetpack.write(packageJsonPath, projectJson);
|
|
193
|
+
logger.log(logger.format.green(`\nReconciled ${discrepancies.length} package(s) in package.json.`));
|
|
194
|
+
|
|
195
|
+
return { allPackages, reconciled: true };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Handle patch/minor/major updates
|
|
199
|
+
const upgrades = action === 'patch' ? patchUpgrades
|
|
200
|
+
: action === 'minor' ? minorUpgrades
|
|
201
|
+
: latestUpgrades;
|
|
202
|
+
|
|
203
|
+
await ncu.run({
|
|
204
|
+
packageFile: packageJsonPath,
|
|
205
|
+
target: action,
|
|
206
|
+
upgrade: true,
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
logger.log(logger.format.green(`\nUpdated ${Object.keys(upgrades).length} package(s) in package.json.`));
|
|
210
|
+
|
|
211
|
+
// Run npm install
|
|
212
|
+
logger.log(logger.format.cyan('\nRunning npm install...'));
|
|
213
|
+
await execute('npm install', { log: true });
|
|
214
|
+
|
|
215
|
+
return { allPackages, updated: true, target: action };
|
|
100
216
|
};
|
|
217
|
+
|
|
218
|
+
// Helper to determine dependency type
|
|
219
|
+
function getDependencyType(packageJson, dep) {
|
|
220
|
+
if (packageJson.devDependencies?.[dep]) {
|
|
221
|
+
return 'dev';
|
|
222
|
+
}
|
|
223
|
+
if (packageJson.peerDependencies?.[dep]) {
|
|
224
|
+
return 'peer';
|
|
225
|
+
}
|
|
226
|
+
return 'prod';
|
|
227
|
+
}
|
package/dist/commands/sync.js
CHANGED
|
@@ -32,7 +32,7 @@ module.exports = async function (options) {
|
|
|
32
32
|
// Check if there were any changes pulled
|
|
33
33
|
const pullOutput = pullResult || '';
|
|
34
34
|
if (pullOutput.includes('Already up to date') || pullOutput.includes('Already up-to-date')) {
|
|
35
|
-
logger.log('Already up to date - no changes pulled');
|
|
35
|
+
logger.log(logger.format.green('Already up to date - no changes pulled'));
|
|
36
36
|
} else {
|
|
37
37
|
// Try to extract the number of files changed
|
|
38
38
|
const filesChangedMatch = pullOutput.match(/(\d+) file[s]? changed/);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-power-user",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.20",
|
|
4
4
|
"description": "Easy tools for every Node.js developer!",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -36,19 +36,20 @@
|
|
|
36
36
|
"replace": {}
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@inquirer/prompts": "^7.
|
|
39
|
+
"@inquirer/prompts": "^7.10.1",
|
|
40
40
|
"chalk": "^4.1.2",
|
|
41
41
|
"cli-progress": "^3.12.0",
|
|
42
42
|
"fs-jetpack": "^5.1.0",
|
|
43
43
|
"itwcw-package-analytics": "^1.0.6",
|
|
44
|
-
"node-powertools": "^2.3.
|
|
44
|
+
"node-powertools": "^2.3.2",
|
|
45
45
|
"npm-api": "^1.0.1",
|
|
46
|
+
"npm-check-updates": "^19.3.2",
|
|
46
47
|
"table": "^6.9.0",
|
|
47
48
|
"wonderful-version": "^1.3.2",
|
|
48
49
|
"yargs": "^16.2.0"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"mocha": "^8.4.0",
|
|
52
|
-
"prepare-package": "^1.2.
|
|
53
|
+
"prepare-package": "^1.2.6"
|
|
53
54
|
}
|
|
54
55
|
}
|