node-power-user 2.0.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -1
- package/dist/cli.js +8 -0
- package/dist/commands/audit.js +18 -0
- package/dist/commands/install.js +62 -0
- package/dist/commands/outdated.js +97 -4
- package/dist/lib/socket.js +159 -0
- package/package.json +15 -11
- package/CHANGELOG.md +0 -33
- package/TODO.md +0 -7
package/README.md
CHANGED
|
@@ -73,10 +73,37 @@ List all global packages for all versions of Node.js on your machine (you **must
|
|
|
73
73
|
npu global
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
### Install Packages
|
|
77
|
+
Install packages with supply chain protection via [Socket](https://socket.dev/). Every install is wrapped with Socket to detect malicious or compromised packages — including transitive dependencies — before they're added to your project. After install, a full `socket npm audit` runs against your entire dependency tree.
|
|
78
|
+
|
|
79
|
+
```shell
|
|
80
|
+
npu install
|
|
81
|
+
npu i <package>
|
|
82
|
+
npu i <package> --save-dev
|
|
83
|
+
npu i <package> --save-exact
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**If Socket CLI is not installed, `npu install` will refuse to run.** Install it globally to enable protection:
|
|
87
|
+
```shell
|
|
88
|
+
npm install -g @socketsecurity/cli --save-exact
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Use `--force` to bypass Socket protection (not recommended):
|
|
92
|
+
```shell
|
|
93
|
+
npu i <package> --force
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Audit
|
|
97
|
+
Run a Socket supply chain audit on your current dependency tree.
|
|
98
|
+
```shell
|
|
99
|
+
npu audit
|
|
100
|
+
```
|
|
101
|
+
|
|
76
102
|
### Outdated Packages
|
|
77
|
-
Compare the versions of installed modules to those in your package.json
|
|
103
|
+
Compare the versions of installed modules to those in your package.json. When you choose to update, the install step and a full post-install audit are both wrapped with Socket for supply chain protection.
|
|
78
104
|
```shell
|
|
79
105
|
npu outdated
|
|
106
|
+
npu out --force # bypass Socket protection
|
|
80
107
|
```
|
|
81
108
|
|
|
82
109
|
### List Packages
|
|
@@ -112,6 +139,19 @@ npu wait <ms>
|
|
|
112
139
|
### Global flags
|
|
113
140
|
* `--debug`: Log the commands and flags before they are executed
|
|
114
141
|
|
|
142
|
+
## 🛠️ Development
|
|
143
|
+
To test commands locally while developing:
|
|
144
|
+
```shell
|
|
145
|
+
npm start -- <command> [options]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
For example:
|
|
149
|
+
```shell
|
|
150
|
+
npm start -- outdated
|
|
151
|
+
npm start -- bump patch
|
|
152
|
+
npm start -- -v
|
|
153
|
+
```
|
|
154
|
+
|
|
115
155
|
## 🗨️ Final Words
|
|
116
156
|
If you are still having difficulty, we would love for you to post a question to [the Node Power User issues page](https://github.com/itw-creative-works/node-power-user/issues). It is much easier to answer questions that include your code and relevant files! So if you can provide them, we'd be extremely grateful (and more likely to help you find the answer!)
|
|
117
157
|
|
package/dist/cli.js
CHANGED
|
@@ -8,6 +8,8 @@ const ALIASES = {
|
|
|
8
8
|
bump: ['-b', '--bump'],
|
|
9
9
|
clean: ['-c', '--clean'],
|
|
10
10
|
global: ['-g', '--global'],
|
|
11
|
+
audit: ['--audit'],
|
|
12
|
+
install: ['-i', '--install', 'i'],
|
|
11
13
|
open: ['--open', 'repo', '--repo'],
|
|
12
14
|
outdated: ['-o', 'out', '--outdated', '-u', '--update', 'up', 'update'],
|
|
13
15
|
packages: ['-p', 'pack', '--packages'],
|
|
@@ -64,6 +66,12 @@ Main.prototype.process = async function (options) {
|
|
|
64
66
|
const Command = require(commandFile);
|
|
65
67
|
return await Command(options);
|
|
66
68
|
} catch (e) {
|
|
69
|
+
// Exit cleanly on Ctrl+C
|
|
70
|
+
if (e.name === 'ExitPromptError' || e.message?.includes('SIGINT')) {
|
|
71
|
+
console.log('\nExited.');
|
|
72
|
+
process.exit(0);
|
|
73
|
+
}
|
|
74
|
+
|
|
67
75
|
console.error(`Error executing command "${command}": ${e.message}`);
|
|
68
76
|
|
|
69
77
|
// Exit with error
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Libraries
|
|
2
|
+
const logger = new (require('../lib/logger'))('node-power-user');
|
|
3
|
+
const socket = require('../lib/socket');
|
|
4
|
+
|
|
5
|
+
// Module
|
|
6
|
+
module.exports = async function (options) {
|
|
7
|
+
// Check socket status upfront (blocks if not installed unless --force)
|
|
8
|
+
await socket.check({ force: options.force });
|
|
9
|
+
|
|
10
|
+
// Run audit
|
|
11
|
+
logger.log('Running Socket audit on current dependency tree...');
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
await socket.audit({ force: options.force });
|
|
15
|
+
} catch (e) {
|
|
16
|
+
logger.error(e.message);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Libraries
|
|
2
|
+
const logger = new (require('../lib/logger'))('node-power-user');
|
|
3
|
+
const socket = require('../lib/socket');
|
|
4
|
+
|
|
5
|
+
// Module
|
|
6
|
+
module.exports = async function (options) {
|
|
7
|
+
// Get packages from positional args (everything after "install" / "i")
|
|
8
|
+
const packages = (options._ || []).slice(1);
|
|
9
|
+
|
|
10
|
+
// Build the npm command
|
|
11
|
+
const flags = [];
|
|
12
|
+
|
|
13
|
+
if (options.D || options['save-dev']) {
|
|
14
|
+
flags.push('--save-dev');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (options.E || options['save-exact']) {
|
|
18
|
+
flags.push('--save-exact');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (options.g || options.global) {
|
|
22
|
+
flags.push('--global');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const command = packages.length > 0
|
|
26
|
+
? `npm install ${packages.join(' ')} ${flags.join(' ')}`.trim()
|
|
27
|
+
: `npm install ${flags.join(' ')}`.trim();
|
|
28
|
+
|
|
29
|
+
// Check socket status upfront (blocks if not installed unless --force)
|
|
30
|
+
await socket.check({ force: options.force });
|
|
31
|
+
|
|
32
|
+
// Log
|
|
33
|
+
logger.log(`Running: ${logger.format.cyan(command)}`);
|
|
34
|
+
|
|
35
|
+
// Wrap with socket
|
|
36
|
+
try {
|
|
37
|
+
await socket.wrap(command, { force: options.force });
|
|
38
|
+
} catch (e) {
|
|
39
|
+
const flaggedPackages = e.flaggedPackages || [];
|
|
40
|
+
|
|
41
|
+
if (flaggedPackages.length > 0) {
|
|
42
|
+
logger.log('');
|
|
43
|
+
logger.error('Socket flagged the following dependencies:');
|
|
44
|
+
flaggedPackages.forEach(pkg => logger.error(` • ${pkg}`));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
logger.log('');
|
|
48
|
+
logger.log('To retry with Socket protection bypassed:');
|
|
49
|
+
logger.log(logger.format.cyan(` npu i ${packages.join(' ')} ${flags.join(' ')} --force`.trim()));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Run full audit after install
|
|
54
|
+
try {
|
|
55
|
+
await socket.audit({ force: options.force });
|
|
56
|
+
} catch (e) {
|
|
57
|
+
logger.error(`Audit warning: ${e.message}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Done
|
|
61
|
+
logger.log(logger.format.green('Install complete.'));
|
|
62
|
+
};
|
|
@@ -7,6 +7,7 @@ const path = require('path');
|
|
|
7
7
|
const version = require('wonderful-version');
|
|
8
8
|
const inquirer = require('@inquirer/prompts');
|
|
9
9
|
const ncu = require('npm-check-updates');
|
|
10
|
+
const socket = require('../lib/socket');
|
|
10
11
|
const { execute } = require('node-powertools');
|
|
11
12
|
|
|
12
13
|
// Load package.json
|
|
@@ -23,13 +24,31 @@ module.exports = async function (options) {
|
|
|
23
24
|
return {};
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
// Check socket status upfront (blocks if not installed unless --force)
|
|
28
|
+
await socket.check({ force: options.force });
|
|
29
|
+
|
|
30
|
+
if (options.force) {
|
|
31
|
+
logger.warn(chalk.red('--force flag detected — Socket supply chain protection is bypassed!'));
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
// Log start
|
|
27
35
|
logger.log(`Checking packages for ${logger.format.bold(projectJson.name || 'Unknown Project')}...`);
|
|
28
36
|
|
|
37
|
+
// Parse --ignore flag (comma-separated list of package names to skip)
|
|
38
|
+
const ignoreList = (options.ignore || '')
|
|
39
|
+
.split(',')
|
|
40
|
+
.map(s => s.trim())
|
|
41
|
+
.filter(Boolean);
|
|
42
|
+
|
|
43
|
+
if (ignoreList.length > 0) {
|
|
44
|
+
logger.log(chalk.dim(`Ignoring: ${ignoreList.join(', ')}`));
|
|
45
|
+
}
|
|
46
|
+
|
|
29
47
|
// Run ncu for patch, minor, and latest (include peer dependencies)
|
|
30
48
|
const ncuOptions = {
|
|
31
49
|
packageFile: packageJsonPath,
|
|
32
50
|
dep: 'prod,dev,peer,optional',
|
|
51
|
+
...(ignoreList.length > 0 ? { reject: ignoreList } : {}),
|
|
33
52
|
};
|
|
34
53
|
|
|
35
54
|
const [patchUpgrades, minorUpgrades, latestUpgrades] = await Promise.all([
|
|
@@ -49,7 +68,7 @@ module.exports = async function (options) {
|
|
|
49
68
|
// Build unified package data
|
|
50
69
|
const allPackages = new Map();
|
|
51
70
|
|
|
52
|
-
for (const dep of Object.keys(allDependencies)) {
|
|
71
|
+
for (const dep of Object.keys(allDependencies).filter(d => !ignoreList.includes(d))) {
|
|
53
72
|
const packageVersion = version.clean(allDependencies[dep]);
|
|
54
73
|
const installedPackagePath = path.join(projectPath, 'node_modules', dep, 'package.json');
|
|
55
74
|
|
|
@@ -225,6 +244,9 @@ module.exports = async function (options) {
|
|
|
225
244
|
: action === 'minor' ? minorUpgrades
|
|
226
245
|
: latestUpgrades;
|
|
227
246
|
|
|
247
|
+
// Back up package.json before modifying
|
|
248
|
+
const packageJsonBackup = jetpack.read(packageJsonPath);
|
|
249
|
+
|
|
228
250
|
await ncu.run({
|
|
229
251
|
packageFile: packageJsonPath,
|
|
230
252
|
target: action,
|
|
@@ -233,9 +255,80 @@ module.exports = async function (options) {
|
|
|
233
255
|
|
|
234
256
|
logger.log(logger.format.green(`\nUpdated ${Object.keys(upgrades).length} package(s) in package.json.`));
|
|
235
257
|
|
|
236
|
-
//
|
|
237
|
-
|
|
238
|
-
|
|
258
|
+
// Install the specific upgraded packages so npm actually pulls them in
|
|
259
|
+
// (plain `npm install` won't upgrade packages that already satisfy the range)
|
|
260
|
+
const packageNames = Object.keys(upgrades);
|
|
261
|
+
const installCmd = `npm install ${packageNames.map(name => `${name}@${version.clean(upgrades[name])}`).join(' ')}`;
|
|
262
|
+
logger.log(logger.format.cyan(`\nRunning ${installCmd}...`));
|
|
263
|
+
|
|
264
|
+
try {
|
|
265
|
+
await socket.wrap(installCmd, { force: options.force });
|
|
266
|
+
} catch (e) {
|
|
267
|
+
const flaggedPackages = e.flaggedPackages || [];
|
|
268
|
+
|
|
269
|
+
// Restore package.json since the bulk install failed
|
|
270
|
+
jetpack.write(packageJsonPath, packageJsonBackup);
|
|
271
|
+
logger.log('package.json has been restored to its original state.');
|
|
272
|
+
|
|
273
|
+
// Trace which of the requested packages bring in the flagged deps
|
|
274
|
+
const riskyParents = new Set();
|
|
275
|
+
|
|
276
|
+
if (flaggedPackages.length > 0) {
|
|
277
|
+
logger.log('');
|
|
278
|
+
logger.error('Socket flagged the following transitive dependencies:');
|
|
279
|
+
|
|
280
|
+
for (const flagged of flaggedPackages) {
|
|
281
|
+
const flaggedName = flagged.replace(/@[^@]+$/, ''); // strip version
|
|
282
|
+
let parentChain = '';
|
|
283
|
+
|
|
284
|
+
try {
|
|
285
|
+
const lsOutput = await execute(`npm ls ${flaggedName} --json`, { log: false });
|
|
286
|
+
const tree = JSON.parse(lsOutput);
|
|
287
|
+
|
|
288
|
+
// Find which top-level deps depend on the flagged package
|
|
289
|
+
const parents = [];
|
|
290
|
+
for (const [dep, info] of Object.entries(tree.dependencies || {})) {
|
|
291
|
+
if (dep === flaggedName || JSON.stringify(info).includes(`"${flaggedName}"`)) {
|
|
292
|
+
parents.push(dep);
|
|
293
|
+
riskyParents.add(dep);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (parents.length > 0) {
|
|
298
|
+
parentChain = chalk.dim(` (from ${parents.join(', ')})`);
|
|
299
|
+
}
|
|
300
|
+
} catch (_) {
|
|
301
|
+
// npm ls may fail, just skip the trace
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
logger.error(` • ${flagged}${parentChain}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Suggest retry commands
|
|
309
|
+
if (riskyParents.size > 0) {
|
|
310
|
+
const ignoreArg = [...riskyParents].join(',');
|
|
311
|
+
logger.log('');
|
|
312
|
+
logger.log('To skip the risky packages and update the rest:');
|
|
313
|
+
logger.log(logger.format.cyan(` npu out --ignore ${ignoreArg}`));
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
logger.log('');
|
|
317
|
+
logger.log('To retry with Socket protection bypassed:');
|
|
318
|
+
logger.log(logger.format.cyan(` npu out --force`));
|
|
319
|
+
logger.log('');
|
|
320
|
+
logger.log('To bypass Socket for this install only:');
|
|
321
|
+
logger.log(logger.format.cyan(` SOCKET_CLI_ACCEPT_RISKS=1 npm install ${packageNames.map(name => `${name}@${version.clean(upgrades[name])}`).join(' ')}`));
|
|
322
|
+
|
|
323
|
+
return { allPackages, updated: false, target: action };
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Run full audit after install
|
|
327
|
+
try {
|
|
328
|
+
await socket.audit({ force: options.force });
|
|
329
|
+
} catch (e) {
|
|
330
|
+
logger.error(`Audit warning: ${e.message}`);
|
|
331
|
+
}
|
|
239
332
|
|
|
240
333
|
return { allPackages, updated: true, target: action };
|
|
241
334
|
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// Libraries
|
|
2
|
+
const { execute } = require('node-powertools');
|
|
3
|
+
const logger = new (require('./logger'))('node-power-user');
|
|
4
|
+
|
|
5
|
+
// Check if socket CLI is installed
|
|
6
|
+
let _socketVersion = undefined;
|
|
7
|
+
async function isSocketAvailable() {
|
|
8
|
+
if (_socketVersion !== undefined) {
|
|
9
|
+
return !!_socketVersion;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
_socketVersion = (await execute('socket --version', { log: false })).trim();
|
|
14
|
+
} catch (e) {
|
|
15
|
+
_socketVersion = null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return !!_socketVersion;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Log socket status upfront (call at the start of commands)
|
|
22
|
+
async function check(options) {
|
|
23
|
+
options = options || {};
|
|
24
|
+
|
|
25
|
+
const available = await isSocketAvailable();
|
|
26
|
+
|
|
27
|
+
if (available) {
|
|
28
|
+
logger.log(logger.format.green(`Socket v${_socketVersion} — supply chain protection enabled.`));
|
|
29
|
+
} else {
|
|
30
|
+
logger.error('Socket CLI is not installed. Your installs are NOT protected against supply chain attacks.');
|
|
31
|
+
logger.error(`Install it with: ${logger.format.cyan('npm install -g @socketsecurity/cli --save-exact')}`);
|
|
32
|
+
|
|
33
|
+
if (!options.force) {
|
|
34
|
+
logger.error('Refusing to proceed without Socket protection. Use --force to bypass.');
|
|
35
|
+
throw new Error('Socket CLI is not installed.');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
logger.warn('Bypassing Socket protection (--force flag detected).');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return available;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Wrap an npm command with socket if available
|
|
45
|
+
async function wrap(command, options) {
|
|
46
|
+
options = options || {};
|
|
47
|
+
|
|
48
|
+
const available = await isSocketAvailable();
|
|
49
|
+
|
|
50
|
+
// If socket is not installed, fall back to plain npm
|
|
51
|
+
if (!available) {
|
|
52
|
+
await execute(command, { log: true });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Run with socket and capture output to check for risks
|
|
57
|
+
// When --force is used, set SOCKET_CLI_ACCEPT_RISKS so Socket actually installs
|
|
58
|
+
const env = options.force ? 'SOCKET_CLI_ACCEPT_RISKS=1 ' : '';
|
|
59
|
+
let output;
|
|
60
|
+
let exitedWithError = false;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
output = await execute(`${env}socket ${command}`, { log: false });
|
|
64
|
+
} catch (e) {
|
|
65
|
+
// Socket exits non-zero when it detects risks
|
|
66
|
+
output = e.message || '';
|
|
67
|
+
exitedWithError = true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Print the output
|
|
71
|
+
if (output) {
|
|
72
|
+
console.log(output);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Check for risk warnings in output
|
|
76
|
+
const hasRisks = exitedWithError
|
|
77
|
+
|| (/new risk|warning|alert|socket found|exiting due to risks/i.test(output)
|
|
78
|
+
&& !/no new risks/i.test(output));
|
|
79
|
+
|
|
80
|
+
if (!hasRisks) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Parse flagged package names from Socket output (e.g. "serialize-javascript@6.0.2")
|
|
85
|
+
const flaggedPackages = [];
|
|
86
|
+
const flaggedRegex = /^(\S+@\S+)\s/gm;
|
|
87
|
+
let match;
|
|
88
|
+
while ((match = flaggedRegex.exec(output)) !== null) {
|
|
89
|
+
flaggedPackages.push(match[1]);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Risks detected — block unless --force flag is passed
|
|
93
|
+
logger.error('Socket detected supply chain risks in the packages above.');
|
|
94
|
+
|
|
95
|
+
if (!options.force) {
|
|
96
|
+
logger.error('Refusing to install. Review the risks above, then use --force to bypass.');
|
|
97
|
+
const err = new Error('Socket detected supply chain risks.');
|
|
98
|
+
err.flaggedPackages = flaggedPackages;
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
logger.warn('Bypassing Socket risk warnings (--force flag detected).');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Run a full socket audit on the current project
|
|
106
|
+
async function audit(options) {
|
|
107
|
+
options = options || {};
|
|
108
|
+
|
|
109
|
+
const available = await isSocketAvailable();
|
|
110
|
+
|
|
111
|
+
if (!available) {
|
|
112
|
+
logger.warn('Skipping post-install audit — Socket CLI is not installed.');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
logger.log(logger.format.cyan('\nRunning post-install Socket audit...'));
|
|
117
|
+
|
|
118
|
+
let output;
|
|
119
|
+
let exitedWithError = false;
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
output = await execute('socket npm audit', { log: false });
|
|
123
|
+
} catch (e) {
|
|
124
|
+
output = e.message || '';
|
|
125
|
+
exitedWithError = true;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Print the output
|
|
129
|
+
if (output) {
|
|
130
|
+
console.log(output);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Check for risk warnings in output
|
|
134
|
+
const hasRisks = exitedWithError
|
|
135
|
+
|| (/new risk|warning|alert|socket found|exiting due to risks/i.test(output)
|
|
136
|
+
&& !/no new risks/i.test(output));
|
|
137
|
+
|
|
138
|
+
if (!hasRisks) {
|
|
139
|
+
logger.log(logger.format.green('Socket audit passed — no risks detected.'));
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
logger.error('Socket audit found supply chain risks in your dependencies.');
|
|
144
|
+
|
|
145
|
+
if (!options.force) {
|
|
146
|
+
logger.error('Review the risks above. Use --force to bypass.');
|
|
147
|
+
throw new Error('Socket audit detected supply chain risks.');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
logger.warn('Bypassing Socket audit warnings (--force flag detected).');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Export
|
|
154
|
+
module.exports = {
|
|
155
|
+
isAvailable: isSocketAvailable,
|
|
156
|
+
check,
|
|
157
|
+
wrap,
|
|
158
|
+
audit,
|
|
159
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-power-user",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "Easy tools for every Node.js developer!",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -15,6 +15,15 @@
|
|
|
15
15
|
"node-power-user": "bin/node-power-user",
|
|
16
16
|
"nodepoweruser": "bin/node-power-user"
|
|
17
17
|
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"preparePackage": {
|
|
22
|
+
"input": "./src",
|
|
23
|
+
"output": "./dist",
|
|
24
|
+
"replace": {},
|
|
25
|
+
"type": "copy"
|
|
26
|
+
},
|
|
18
27
|
"repository": {
|
|
19
28
|
"type": "git",
|
|
20
29
|
"url": "git+https://github.com/itw-creative-works/node-power-user.git"
|
|
@@ -30,26 +39,21 @@
|
|
|
30
39
|
"url": "https://github.com/itw-creative-works/node-power-user/issues"
|
|
31
40
|
},
|
|
32
41
|
"homepage": "https://itwcreativeworks.com",
|
|
33
|
-
"preparePackage": {
|
|
34
|
-
"input": "./src",
|
|
35
|
-
"output": "./dist",
|
|
36
|
-
"replace": {}
|
|
37
|
-
},
|
|
38
42
|
"dependencies": {
|
|
39
|
-
"@inquirer/prompts": "^8.3.
|
|
43
|
+
"@inquirer/prompts": "^8.3.2",
|
|
40
44
|
"chalk": "^5.6.2",
|
|
41
45
|
"cli-progress": "^3.12.0",
|
|
42
46
|
"fs-jetpack": "^5.1.0",
|
|
43
47
|
"itwcw-package-analytics": "^1.0.8",
|
|
44
|
-
"node-powertools": "^
|
|
48
|
+
"node-powertools": "^3.0.0",
|
|
45
49
|
"npm-api": "^1.0.1",
|
|
46
|
-
"npm-check-updates": "^
|
|
50
|
+
"npm-check-updates": "^20.0.0",
|
|
47
51
|
"table": "^6.9.0",
|
|
48
52
|
"wonderful-version": "^1.3.2",
|
|
49
53
|
"yargs": "^18.0.0"
|
|
50
54
|
},
|
|
51
55
|
"devDependencies": {
|
|
52
|
-
"mocha": "^
|
|
53
|
-
"prepare-package": "^
|
|
56
|
+
"mocha": "^11.7.5",
|
|
57
|
+
"prepare-package": "^2.0.7"
|
|
54
58
|
}
|
|
55
59
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# CHANGELOG
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
|
-
|
|
7
|
-
## Changelog Categories
|
|
8
|
-
|
|
9
|
-
- `BREAKING` for breaking changes.
|
|
10
|
-
- `Added` for new features.
|
|
11
|
-
- `Changed` for changes in existing functionality.
|
|
12
|
-
- `Deprecated` for soon-to-be removed features.
|
|
13
|
-
- `Removed` for now removed features.
|
|
14
|
-
- `Fixed` for any bug fixes.
|
|
15
|
-
- `Security` in case of vulnerabilities.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
## [2.0.0] - 2026-02-24
|
|
19
|
-
### BREAKING
|
|
20
|
-
- Upgraded yargs v16 to v18: updated CLI entry point to use `parseSync()` API
|
|
21
|
-
- Upgraded chalk v4 to v5: requires Node 22+ for ESM `require()` support
|
|
22
|
-
- Upgraded @inquirer/prompts v7 to v8
|
|
23
|
-
|
|
24
|
-
### Changed
|
|
25
|
-
- Updated all `require('chalk')` to `require('chalk').default` for chalk v5 ESM compatibility
|
|
26
|
-
- Improved outdated command menu: Minor/Major options only show when relevant updates exist
|
|
27
|
-
- Made breaking changes legend conditional on actual major updates being present
|
|
28
|
-
- Updated npm-check-updates to v19.5 and itwcw-package-analytics to v1.0.8
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
## [1.0.0] - 2024-06-19
|
|
32
|
-
### Added
|
|
33
|
-
- Initial release of the project 🚀
|
package/TODO.md
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
Use "keychain" for something?
|
|
2
|
-
|
|
3
|
-
Interesting - the git status shows your branch is up to date now. However, the error you encountered was about needing to configure how to handle divergent branches in the future. The issue is that git needs to know your preference for handling situations where branches have diverged. You have three options:
|
|
4
|
-
Merge (git config pull.rebase false) - Creates merge commits
|
|
5
|
-
Rebase (git config pull.rebase true) - Replays your local commits on top of remote changes (cleaner history)
|
|
6
|
-
Fast-forward only (git config pull.ff only) - Only pulls if it can fast-forward (safest, but fails if branches diverged)
|
|
7
|
-
Which strategy would you prefer for handling divergent branches during pulls? I'd recommend rebase for a cleaner history, but I can set it to whichever you prefer. Would you like me to configure this globally for all your repositories or just for this one?
|