@oclif/core 3.0.0-beta.13 → 3.0.0-beta.14
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 +3 -1
- package/lib/args.d.ts +1 -1
- package/lib/args.js +13 -15
- package/lib/cli-ux/action/base.d.ts +1 -1
- package/lib/cli-ux/action/base.js +20 -15
- package/lib/cli-ux/action/simple.js +10 -8
- package/lib/cli-ux/action/spinner.js +11 -10
- package/lib/cli-ux/config.js +8 -7
- package/lib/cli-ux/flush.js +2 -3
- package/lib/cli-ux/index.d.ts +10 -28
- package/lib/cli-ux/index.js +26 -45
- package/lib/cli-ux/list.js +1 -1
- package/lib/cli-ux/prompt.js +24 -19
- package/lib/cli-ux/styled/index.d.ts +5 -6
- package/lib/cli-ux/styled/index.js +11 -11
- package/lib/cli-ux/styled/json.js +3 -2
- package/lib/cli-ux/styled/object.js +6 -8
- package/lib/cli-ux/styled/table.js +36 -45
- package/lib/cli-ux/wait.js +3 -5
- package/lib/command.d.ts +7 -5
- package/lib/command.js +35 -28
- package/lib/config/config.d.ts +2 -2
- package/lib/config/config.js +57 -43
- package/lib/config/plugin-loader.js +25 -11
- package/lib/config/plugin.d.ts +1 -1
- package/lib/config/plugin.js +66 -56
- package/lib/config/ts-node.d.ts +2 -1
- package/lib/config/ts-node.js +41 -34
- package/lib/config/util.d.ts +1 -5
- package/lib/config/util.js +5 -46
- package/lib/errors/config.js +1 -1
- package/lib/errors/errors/cli.d.ts +1 -1
- package/lib/errors/errors/cli.js +14 -13
- package/lib/errors/errors/exit.d.ts +0 -3
- package/lib/errors/errors/module-load.d.ts +0 -3
- package/lib/errors/errors/pretty-print.js +9 -8
- package/lib/errors/handle.d.ts +12 -2
- package/lib/errors/handle.js +23 -14
- package/lib/errors/index.d.ts +2 -2
- package/lib/errors/index.js +20 -19
- package/lib/errors/logger.js +4 -4
- package/lib/execute.d.ts +5 -5
- package/lib/execute.js +6 -5
- package/lib/flags.d.ts +102 -31
- package/lib/flags.js +75 -42
- package/lib/help/command.d.ts +2 -0
- package/lib/help/command.js +32 -32
- package/lib/help/docopts.js +2 -9
- package/lib/help/formatter.d.ts +1 -1
- package/lib/help/formatter.js +17 -17
- package/lib/help/index.d.ts +2 -2
- package/lib/help/index.js +22 -21
- package/lib/help/root.js +2 -2
- package/lib/help/util.d.ts +1 -1
- package/lib/help/util.js +9 -9
- package/lib/index.d.ts +19 -20
- package/lib/index.js +38 -42
- package/lib/interfaces/config.d.ts +5 -4
- package/lib/interfaces/errors.d.ts +1 -1
- package/lib/interfaces/parser.d.ts +168 -45
- package/lib/interfaces/plugin.d.ts +1 -0
- package/lib/main.d.ts +1 -1
- package/lib/main.js +16 -16
- package/lib/module-loader.d.ts +67 -77
- package/lib/module-loader.js +179 -149
- package/lib/parser/errors.d.ts +2 -2
- package/lib/parser/errors.js +4 -3
- package/lib/parser/help.js +3 -2
- package/lib/parser/parse.d.ts +3 -0
- package/lib/parser/parse.js +56 -52
- package/lib/parser/validate.js +9 -5
- package/lib/performance.d.ts +6 -2
- package/lib/performance.js +23 -12
- package/lib/util.d.ts +25 -1
- package/lib/util.js +93 -29
- package/package.json +10 -15
package/lib/parser/parse.js
CHANGED
|
@@ -3,15 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Parser = void 0;
|
|
4
4
|
/* eslint-disable no-await-in-loop */
|
|
5
5
|
const errors_1 = require("./errors");
|
|
6
|
-
const readline = require("readline");
|
|
7
6
|
const util_1 = require("../util");
|
|
7
|
+
const node_readline_1 = require("node:readline");
|
|
8
8
|
let debug;
|
|
9
9
|
try {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
debug = process.env.CLI_FLAGS_DEBUG === '1' ? require('debug')('../parser') : () => {
|
|
11
|
+
// noop
|
|
12
|
+
};
|
|
12
13
|
}
|
|
13
14
|
catch {
|
|
14
|
-
debug = () => {
|
|
15
|
+
debug = () => {
|
|
16
|
+
// noop
|
|
17
|
+
};
|
|
15
18
|
}
|
|
16
19
|
const readStdin = async () => {
|
|
17
20
|
const { stdin, stdout } = process;
|
|
@@ -25,9 +28,9 @@ const readStdin = async () => {
|
|
|
25
28
|
return new Promise(resolve => {
|
|
26
29
|
let result = '';
|
|
27
30
|
const ac = new AbortController();
|
|
28
|
-
const signal = ac
|
|
31
|
+
const { signal } = ac;
|
|
29
32
|
const timeout = setTimeout(() => ac.abort(), 100);
|
|
30
|
-
const rl =
|
|
33
|
+
const rl = (0, node_readline_1.createInterface)({
|
|
31
34
|
input: stdin,
|
|
32
35
|
output: stdout,
|
|
33
36
|
terminal: false,
|
|
@@ -51,6 +54,11 @@ const readStdin = async () => {
|
|
|
51
54
|
function isNegativeNumber(input) {
|
|
52
55
|
return /^-\d/g.test(input);
|
|
53
56
|
}
|
|
57
|
+
const validateOptions = (flag, input) => {
|
|
58
|
+
if (flag.options && !flag.options.includes(input))
|
|
59
|
+
throw new errors_1.FlagInvalidOptionError(flag, input);
|
|
60
|
+
return input;
|
|
61
|
+
};
|
|
54
62
|
class Parser {
|
|
55
63
|
constructor(input) {
|
|
56
64
|
this.input = input;
|
|
@@ -59,40 +67,12 @@ class Parser {
|
|
|
59
67
|
this.argv = [...input.argv];
|
|
60
68
|
this._setNames();
|
|
61
69
|
this.booleanFlags = (0, util_1.pickBy)(input.flags, f => f.type === 'boolean');
|
|
62
|
-
this.flagAliases = Object.fromEntries(Object.values(input.flags).flatMap(flag =>
|
|
63
|
-
return (flag.aliases ?? []).map(a => [a, flag]);
|
|
64
|
-
}));
|
|
70
|
+
this.flagAliases = Object.fromEntries(Object.values(input.flags).flatMap(flag => ([...flag.aliases ?? [], ...flag.charAliases ?? []]).map(a => [a, flag])));
|
|
65
71
|
}
|
|
66
72
|
async parse() {
|
|
67
73
|
this._debugInput();
|
|
68
|
-
const findLongFlag = (arg) => {
|
|
69
|
-
const name = arg.slice(2);
|
|
70
|
-
if (this.input.flags[name]) {
|
|
71
|
-
return name;
|
|
72
|
-
}
|
|
73
|
-
if (this.flagAliases[name]) {
|
|
74
|
-
return this.flagAliases[name].name;
|
|
75
|
-
}
|
|
76
|
-
if (arg.startsWith('--no-')) {
|
|
77
|
-
const flag = this.booleanFlags[arg.slice(5)];
|
|
78
|
-
if (flag && flag.allowNo)
|
|
79
|
-
return flag.name;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
const findShortFlag = ([_, char]) => {
|
|
83
|
-
if (this.flagAliases[char]) {
|
|
84
|
-
return this.flagAliases[char].name;
|
|
85
|
-
}
|
|
86
|
-
return Object.keys(this.input.flags).find(k => (this.input.flags[k].char === char && char !== undefined && this.input.flags[k].char !== undefined));
|
|
87
|
-
};
|
|
88
|
-
const findFlag = (arg) => {
|
|
89
|
-
const isLong = arg.startsWith('--');
|
|
90
|
-
const short = isLong ? false : arg.startsWith('-');
|
|
91
|
-
const name = isLong ? findLongFlag(arg) : (short ? findShortFlag(arg) : undefined);
|
|
92
|
-
return { name, isLong };
|
|
93
|
-
};
|
|
94
74
|
const parseFlag = (arg) => {
|
|
95
|
-
const { name, isLong } = findFlag(arg);
|
|
75
|
+
const { name, isLong } = this.findFlag(arg);
|
|
96
76
|
if (!name) {
|
|
97
77
|
const i = arg.indexOf('=');
|
|
98
78
|
if (i !== -1) {
|
|
@@ -108,13 +88,16 @@ class Parser {
|
|
|
108
88
|
}
|
|
109
89
|
const flag = this.input.flags[name];
|
|
110
90
|
if (flag.type === 'option') {
|
|
91
|
+
if (!flag.multiple && this.raw.some(o => o.type === 'flag' && o.flag === name)) {
|
|
92
|
+
throw new errors_1.CLIError(`Flag --${name} can only be specified once`);
|
|
93
|
+
}
|
|
111
94
|
this.currentFlag = flag;
|
|
112
95
|
const input = isLong || arg.length < 3 ? this.argv.shift() : arg.slice(arg[2] === '=' ? 3 : 2);
|
|
113
96
|
// if the value ends up being one of the command's flags, the user didn't provide an input
|
|
114
|
-
if ((typeof input !== 'string') || findFlag(input).name) {
|
|
97
|
+
if ((typeof input !== 'string') || this.findFlag(input).name) {
|
|
115
98
|
throw new errors_1.CLIError(`Flag --${name} expects a value`);
|
|
116
99
|
}
|
|
117
|
-
this.raw.push({ type: 'flag', flag: flag.name, input
|
|
100
|
+
this.raw.push({ type: 'flag', flag: flag.name, input });
|
|
118
101
|
}
|
|
119
102
|
else {
|
|
120
103
|
this.raw.push({ type: 'flag', flag: flag.name, input: arg });
|
|
@@ -174,11 +157,6 @@ class Parser {
|
|
|
174
157
|
};
|
|
175
158
|
}
|
|
176
159
|
async _flags() {
|
|
177
|
-
const validateOptions = (flag, input) => {
|
|
178
|
-
if (flag.options && !flag.options.includes(input))
|
|
179
|
-
throw new errors_1.FlagInvalidOptionError(flag, input);
|
|
180
|
-
return input;
|
|
181
|
-
};
|
|
182
160
|
const parseFlagOrThrowError = async (input, flag, context, token) => {
|
|
183
161
|
if (!flag.parse)
|
|
184
162
|
return input;
|
|
@@ -252,17 +230,18 @@ class Parser {
|
|
|
252
230
|
if (fws.inputFlag.flag.type === 'boolean') {
|
|
253
231
|
return {
|
|
254
232
|
...fws,
|
|
255
|
-
valueFunction: async (i) =>
|
|
233
|
+
valueFunction: async (i) => (0, util_1.isTruthy)(process.env[i.inputFlag.flag.env] ?? 'false'),
|
|
256
234
|
};
|
|
257
235
|
}
|
|
258
236
|
}
|
|
259
237
|
// no input, but flag has default value
|
|
238
|
+
// eslint-disable-next-line no-constant-binary-expression, valid-typeof
|
|
260
239
|
if (typeof fws.inputFlag.flag.default !== undefined) {
|
|
261
240
|
return {
|
|
262
241
|
...fws, metadata: { setFromDefault: true },
|
|
263
|
-
valueFunction: typeof fws.inputFlag.flag.default === 'function'
|
|
264
|
-
(i, allFlags = {}) => fws.inputFlag.flag.default({ options: i.inputFlag.flag, flags: allFlags })
|
|
265
|
-
async () => fws.inputFlag.flag.default,
|
|
242
|
+
valueFunction: typeof fws.inputFlag.flag.default === 'function'
|
|
243
|
+
? (i, allFlags = {}) => fws.inputFlag.flag.default({ options: i.inputFlag.flag, flags: allFlags })
|
|
244
|
+
: async () => fws.inputFlag.flag.default,
|
|
266
245
|
};
|
|
267
246
|
}
|
|
268
247
|
// base case (no value function)
|
|
@@ -271,11 +250,11 @@ class Parser {
|
|
|
271
250
|
const addHelpFunction = (fws) => {
|
|
272
251
|
if (fws.inputFlag.flag.type === 'option' && fws.inputFlag.flag.defaultHelp) {
|
|
273
252
|
return {
|
|
274
|
-
...fws, helpFunction: typeof fws.inputFlag.flag.defaultHelp === 'function'
|
|
253
|
+
...fws, helpFunction: typeof fws.inputFlag.flag.defaultHelp === 'function'
|
|
275
254
|
// @ts-expect-error flag type isn't specific enough to know defaultHelp will definitely be there
|
|
276
|
-
(i, flags, ...context) => i.inputFlag.flag.defaultHelp({ options: i.inputFlag, flags }, ...context)
|
|
255
|
+
? (i, flags, ...context) => i.inputFlag.flag.defaultHelp({ options: i.inputFlag, flags }, ...context)
|
|
277
256
|
// @ts-expect-error flag type isn't specific enough to know defaultHelp will definitely be there
|
|
278
|
-
(i) => i.inputFlag.flag.defaultHelp,
|
|
257
|
+
: (i) => i.inputFlag.flag.defaultHelp,
|
|
279
258
|
};
|
|
280
259
|
}
|
|
281
260
|
return fws;
|
|
@@ -318,7 +297,6 @@ class Parser {
|
|
|
318
297
|
.map(async (fws) => (fws.metadata?.setFromDefault ? { ...fws, value: await fws.valueFunction?.(fws, valueReference) } : fws)));
|
|
319
298
|
const finalFlags = (flagsWithAllValues.some(fws => typeof fws.helpFunction === 'function')) ? await addDefaultHelp(flagsWithAllValues) : flagsWithAllValues;
|
|
320
299
|
return {
|
|
321
|
-
// @ts-ignore original version returned an any. Not sure how to get to the return type for `flags` prop
|
|
322
300
|
flags: fwsArrayToObject(finalFlags),
|
|
323
301
|
metadata: { flags: Object.fromEntries(finalFlags.filter(fws => fws.metadata).map(fws => [fws.inputFlag.name, fws.metadata])) },
|
|
324
302
|
};
|
|
@@ -367,7 +345,7 @@ class Parser {
|
|
|
367
345
|
continue;
|
|
368
346
|
argv.push(token.input);
|
|
369
347
|
}
|
|
370
|
-
return { argv, args
|
|
348
|
+
return { argv, args };
|
|
371
349
|
}
|
|
372
350
|
_debugOutput(args, flags, argv) {
|
|
373
351
|
if (argv.length > 0) {
|
|
@@ -415,5 +393,31 @@ class Parser {
|
|
|
415
393
|
}
|
|
416
394
|
return flagTokenMap;
|
|
417
395
|
}
|
|
396
|
+
findLongFlag(arg) {
|
|
397
|
+
const name = arg.slice(2);
|
|
398
|
+
if (this.input.flags[name]) {
|
|
399
|
+
return name;
|
|
400
|
+
}
|
|
401
|
+
if (this.flagAliases[name]) {
|
|
402
|
+
return this.flagAliases[name].name;
|
|
403
|
+
}
|
|
404
|
+
if (arg.startsWith('--no-')) {
|
|
405
|
+
const flag = this.booleanFlags[arg.slice(5)];
|
|
406
|
+
if (flag && flag.allowNo)
|
|
407
|
+
return flag.name;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
findShortFlag([_, char]) {
|
|
411
|
+
if (this.flagAliases[char]) {
|
|
412
|
+
return this.flagAliases[char].name;
|
|
413
|
+
}
|
|
414
|
+
return Object.keys(this.input.flags).find(k => (this.input.flags[k].char === char && char !== undefined && this.input.flags[k].char !== undefined));
|
|
415
|
+
}
|
|
416
|
+
findFlag(arg) {
|
|
417
|
+
const isLong = arg.startsWith('--');
|
|
418
|
+
const short = isLong ? false : arg.startsWith('-');
|
|
419
|
+
const name = isLong ? this.findLongFlag(arg) : (short ? this.findShortFlag(arg) : undefined);
|
|
420
|
+
return { name, isLong };
|
|
421
|
+
}
|
|
418
422
|
}
|
|
419
423
|
exports.Parser = Parser;
|
package/lib/parser/validate.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.validate = void 0;
|
|
4
4
|
const errors_1 = require("./errors");
|
|
5
|
-
const util_1 = require("../
|
|
5
|
+
const util_1 = require("../util");
|
|
6
6
|
async function validate(parse) {
|
|
7
7
|
let cachedResolvedFlags;
|
|
8
8
|
function validateArgs() {
|
|
@@ -139,14 +139,18 @@ async function validate(parse) {
|
|
|
139
139
|
function validateRelationships(name, flag) {
|
|
140
140
|
return ((flag.relationships ?? []).map(relationship => {
|
|
141
141
|
switch (relationship.type) {
|
|
142
|
-
case 'all':
|
|
142
|
+
case 'all': {
|
|
143
143
|
return validateDependsOn(name, relationship.flags);
|
|
144
|
-
|
|
144
|
+
}
|
|
145
|
+
case 'some': {
|
|
145
146
|
return validateSome(name, relationship.flags);
|
|
146
|
-
|
|
147
|
+
}
|
|
148
|
+
case 'none': {
|
|
147
149
|
return validateExclusive(name, relationship.flags);
|
|
148
|
-
|
|
150
|
+
}
|
|
151
|
+
default: {
|
|
149
152
|
throw new Error(`Unknown relationship type: ${relationship.type}`);
|
|
153
|
+
}
|
|
150
154
|
}
|
|
151
155
|
}));
|
|
152
156
|
}
|
package/lib/performance.d.ts
CHANGED
|
@@ -12,7 +12,11 @@ type PerfHighlights = {
|
|
|
12
12
|
runTime: number;
|
|
13
13
|
initTime: number;
|
|
14
14
|
commandLoadTime: number;
|
|
15
|
-
|
|
15
|
+
commandRunTime: number;
|
|
16
|
+
pluginLoadTimes: Record<string, {
|
|
17
|
+
duration: number;
|
|
18
|
+
details: Details;
|
|
19
|
+
}>;
|
|
16
20
|
corePluginsLoadTime: number;
|
|
17
21
|
userPluginsLoadTime: number;
|
|
18
22
|
linkedPluginsLoadTime: number;
|
|
@@ -32,7 +36,7 @@ declare class Marker {
|
|
|
32
36
|
stop(): void;
|
|
33
37
|
measure(): void;
|
|
34
38
|
}
|
|
35
|
-
export
|
|
39
|
+
export declare class Performance {
|
|
36
40
|
private static markers;
|
|
37
41
|
private static _results;
|
|
38
42
|
private static _highlights;
|
package/lib/performance.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
3
|
+
exports.Performance = void 0;
|
|
4
|
+
const node_perf_hooks_1 = require("node:perf_hooks");
|
|
4
5
|
const settings_1 = require("./settings");
|
|
5
6
|
class Marker {
|
|
6
7
|
constructor(name, details = {}) {
|
|
@@ -14,17 +15,17 @@ class Marker {
|
|
|
14
15
|
this.module = module;
|
|
15
16
|
this.method = method;
|
|
16
17
|
this.scope = scope;
|
|
17
|
-
|
|
18
|
+
node_perf_hooks_1.performance.mark(this.startMarker);
|
|
18
19
|
}
|
|
19
20
|
addDetails(details) {
|
|
20
21
|
this.details = { ...this.details, ...details };
|
|
21
22
|
}
|
|
22
23
|
stop() {
|
|
23
24
|
this.stopped = true;
|
|
24
|
-
|
|
25
|
+
node_perf_hooks_1.performance.mark(this.stopMarker);
|
|
25
26
|
}
|
|
26
27
|
measure() {
|
|
27
|
-
|
|
28
|
+
node_perf_hooks_1.performance.measure(this.name, this.startMarker, this.stopMarker);
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
class Performance {
|
|
@@ -79,7 +80,7 @@ class Performance {
|
|
|
79
80
|
marker.stop();
|
|
80
81
|
}
|
|
81
82
|
return new Promise(resolve => {
|
|
82
|
-
const perfObserver = new
|
|
83
|
+
const perfObserver = new node_perf_hooks_1.PerformanceObserver(items => {
|
|
83
84
|
for (const entry of items.getEntries()) {
|
|
84
85
|
if (Performance.markers[entry.name]) {
|
|
85
86
|
const marker = Performance.markers[entry.name];
|
|
@@ -98,7 +99,7 @@ class Performance {
|
|
|
98
99
|
const pluginLoadTimes = Object.fromEntries(Performance.results
|
|
99
100
|
.filter(({ name }) => name.startsWith('plugin.load#'))
|
|
100
101
|
.sort((a, b) => b.duration - a.duration)
|
|
101
|
-
.map(({ scope, duration }) => [scope, duration]));
|
|
102
|
+
.map(({ scope, duration, details }) => [scope, { duration, details }]));
|
|
102
103
|
const hookRunTimes = Performance.results
|
|
103
104
|
.filter(({ name }) => name.startsWith('config.runHook#'))
|
|
104
105
|
.reduce((acc, perfResult) => {
|
|
@@ -120,10 +121,12 @@ class Performance {
|
|
|
120
121
|
.filter(({ name }) => name.startsWith('config.loadPlugins#'))
|
|
121
122
|
.sort((a, b) => b.duration - a.duration)
|
|
122
123
|
.map(({ scope, duration }) => [scope, duration]));
|
|
124
|
+
const commandRunTime = Performance.results.find(({ name }) => name.startsWith('config.runCommand#'))?.duration ?? 0;
|
|
123
125
|
Performance._highlights = {
|
|
124
126
|
configLoadTime: Performance.getResult('config.load')?.duration ?? 0,
|
|
125
127
|
runTime: Performance.getResult('main.run')?.duration ?? 0,
|
|
126
128
|
initTime: Performance.getResult('main.run#init')?.duration ?? 0,
|
|
129
|
+
commandRunTime,
|
|
127
130
|
commandLoadTime,
|
|
128
131
|
pluginLoadTimes,
|
|
129
132
|
hookRunTimes,
|
|
@@ -142,7 +145,7 @@ class Performance {
|
|
|
142
145
|
// ignore
|
|
143
146
|
}
|
|
144
147
|
}
|
|
145
|
-
|
|
148
|
+
node_perf_hooks_1.performance.clearMarks();
|
|
146
149
|
});
|
|
147
150
|
}
|
|
148
151
|
/**
|
|
@@ -153,16 +156,22 @@ class Performance {
|
|
|
153
156
|
if (!Performance.enabled)
|
|
154
157
|
return;
|
|
155
158
|
const debug = require('debug')('perf');
|
|
159
|
+
debug('Total Time: %sms', Performance.highlights.runTime.toFixed(4));
|
|
156
160
|
debug('Init Time: %sms', Performance.highlights.initTime.toFixed(4));
|
|
157
161
|
debug('Config Load Time: %sms', Performance.highlights.configLoadTime.toFixed(4));
|
|
158
|
-
debug('
|
|
159
|
-
debug('
|
|
162
|
+
debug(' • Plugins Load Time: %sms', Performance.getResult('config.loadAllPlugins')?.duration.toFixed(4) ?? 0);
|
|
163
|
+
debug(' • Commands Load Time: %sms', Performance.getResult('config.loadAllCommands')?.duration.toFixed(4) ?? 0);
|
|
160
164
|
debug('Core Plugin Load Time: %sms', Performance.highlights.corePluginsLoadTime.toFixed(4));
|
|
161
165
|
debug('User Plugin Load Time: %sms', Performance.highlights.userPluginsLoadTime.toFixed(4));
|
|
162
166
|
debug('Linked Plugin Load Time: %sms', Performance.highlights.linkedPluginsLoadTime.toFixed(4));
|
|
163
167
|
debug('Plugin Load Times:');
|
|
164
|
-
for (const [plugin,
|
|
165
|
-
|
|
168
|
+
for (const [plugin, result] of Object.entries(Performance.highlights.pluginLoadTimes)) {
|
|
169
|
+
if (result.details.hasManifest) {
|
|
170
|
+
debug(` ${plugin}: ${result.duration.toFixed(4)}ms`);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
debug(` ${plugin}: ${result.duration.toFixed(4)}ms (no manifest!)`);
|
|
174
|
+
}
|
|
166
175
|
}
|
|
167
176
|
debug('Hook Run Times:');
|
|
168
177
|
for (const [event, runTimes] of Object.entries(Performance.highlights.hookRunTimes)) {
|
|
@@ -171,8 +180,10 @@ class Performance {
|
|
|
171
180
|
debug(` ${plugin}: ${duration.toFixed(4)}ms`);
|
|
172
181
|
}
|
|
173
182
|
}
|
|
183
|
+
debug('Command Load Time: %sms', Performance.highlights.commandLoadTime.toFixed(4));
|
|
184
|
+
debug('Command Run Time: %sms', Performance.highlights.commandRunTime.toFixed(4));
|
|
174
185
|
}
|
|
175
186
|
}
|
|
176
|
-
exports.
|
|
187
|
+
exports.Performance = Performance;
|
|
177
188
|
Performance.markers = {};
|
|
178
189
|
Performance._results = [];
|
package/lib/util.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
2
|
import { ArgInput } from './interfaces/parser';
|
|
3
|
+
import { Command } from './command';
|
|
3
4
|
export declare function pickBy<T extends {
|
|
4
5
|
[s: string]: T[keyof T];
|
|
5
6
|
} | ArrayLike<T[keyof T]>>(obj: T, fn: (i: T[keyof T]) => boolean): Partial<T>;
|
|
@@ -13,6 +14,7 @@ export declare function isProd(): boolean;
|
|
|
13
14
|
export declare function maxBy<T>(arr: T[], fn: (i: T) => number): T | undefined;
|
|
14
15
|
export declare function sumBy<T>(arr: T[], fn: (i: T) => number): number;
|
|
15
16
|
export declare function capitalize(s: string): string;
|
|
17
|
+
export declare function exists(path: string): Promise<boolean>;
|
|
16
18
|
export declare const dirExists: (input: string) => Promise<string>;
|
|
17
19
|
export declare const fileExists: (input: string) => Promise<string>;
|
|
18
20
|
export declare function isTruthy(input: string): boolean;
|
|
@@ -28,4 +30,26 @@ export declare function requireJson<T>(...pathParts: string[]): T;
|
|
|
28
30
|
export declare function ensureArgObject(args?: any[] | ArgInput | {
|
|
29
31
|
[name: string]: Command.Arg.Cached;
|
|
30
32
|
}): ArgInput;
|
|
33
|
+
export declare function uniq<T>(arr: T[]): T[];
|
|
34
|
+
/**
|
|
35
|
+
* Call os.homedir() and return the result
|
|
36
|
+
*
|
|
37
|
+
* Wrapping this allows us to stub these in tests since os.homedir() is
|
|
38
|
+
* non-configurable and non-writable.
|
|
39
|
+
*
|
|
40
|
+
* @returns The user's home directory
|
|
41
|
+
*/
|
|
42
|
+
export declare function getHomeDir(): string;
|
|
43
|
+
/**
|
|
44
|
+
* Call os.platform() and return the result
|
|
45
|
+
*
|
|
46
|
+
* Wrapping this allows us to stub these in tests since os.platform() is
|
|
47
|
+
* non-configurable and non-writable.
|
|
48
|
+
*
|
|
49
|
+
* @returns The process' platform
|
|
50
|
+
*/
|
|
51
|
+
export declare function getPlatform(): NodeJS.Platform;
|
|
52
|
+
export declare function readJson<T = unknown>(path: string): Promise<T>;
|
|
53
|
+
export declare function readJsonSync(path: string, parse: false): string;
|
|
54
|
+
export declare function readJsonSync<T = unknown>(path: string, parse?: true): T;
|
|
31
55
|
export {};
|
package/lib/util.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ensureArgObject = exports.requireJson = exports.isNotFalsy = exports.isTruthy = exports.fileExists = exports.dirExists = exports.capitalize = exports.sumBy = exports.maxBy = exports.isProd = exports.castArray = exports.sortBy = exports.last = exports.uniqBy = exports.compact = exports.pickBy = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
3
|
+
exports.readJsonSync = exports.readJson = exports.getPlatform = exports.getHomeDir = exports.uniq = exports.ensureArgObject = exports.requireJson = exports.isNotFalsy = exports.isTruthy = exports.fileExists = exports.dirExists = exports.exists = exports.capitalize = exports.sumBy = exports.maxBy = exports.isProd = exports.castArray = exports.sortBy = exports.last = exports.uniqBy = exports.compact = exports.pickBy = void 0;
|
|
4
|
+
const promises_1 = require("node:fs/promises");
|
|
5
|
+
const node_os_1 = require("node:os");
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const debug = require('debug');
|
|
6
9
|
function pickBy(obj, fn) {
|
|
7
10
|
return Object.entries(obj)
|
|
8
11
|
.reduce((o, [k, v]) => {
|
|
@@ -13,6 +16,7 @@ function pickBy(obj, fn) {
|
|
|
13
16
|
}
|
|
14
17
|
exports.pickBy = pickBy;
|
|
15
18
|
function compact(a) {
|
|
19
|
+
// eslint-disable-next-line unicorn/prefer-native-coercion-functions
|
|
16
20
|
return a.filter((a) => Boolean(a));
|
|
17
21
|
}
|
|
18
22
|
exports.compact = compact;
|
|
@@ -26,27 +30,27 @@ exports.uniqBy = uniqBy;
|
|
|
26
30
|
function last(arr) {
|
|
27
31
|
if (!arr)
|
|
28
32
|
return;
|
|
29
|
-
return arr.
|
|
33
|
+
return arr.at(-1);
|
|
30
34
|
}
|
|
31
35
|
exports.last = last;
|
|
32
|
-
function
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return compare(a.slice(1), b.slice(1));
|
|
43
|
-
}
|
|
44
|
-
if (a < b)
|
|
45
|
-
return -1;
|
|
46
|
-
if (a > b)
|
|
47
|
-
return 1;
|
|
48
|
-
return 0;
|
|
36
|
+
function compare(a, b) {
|
|
37
|
+
a = a === undefined ? 0 : a;
|
|
38
|
+
b = b === undefined ? 0 : b;
|
|
39
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
40
|
+
if (a.length === 0 && b.length === 0)
|
|
41
|
+
return 0;
|
|
42
|
+
const diff = compare(a[0], b[0]);
|
|
43
|
+
if (diff !== 0)
|
|
44
|
+
return diff;
|
|
45
|
+
return compare(a.slice(1), b.slice(1));
|
|
49
46
|
}
|
|
47
|
+
if (a < b)
|
|
48
|
+
return -1;
|
|
49
|
+
if (a > b)
|
|
50
|
+
return 1;
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
function sortBy(arr, fn) {
|
|
50
54
|
return arr.sort((a, b) => compare(fn(a), fn(b)));
|
|
51
55
|
}
|
|
52
56
|
exports.sortBy = sortBy;
|
|
@@ -79,21 +83,33 @@ function capitalize(s) {
|
|
|
79
83
|
return s ? s.charAt(0).toUpperCase() + s.slice(1).toLowerCase() : '';
|
|
80
84
|
}
|
|
81
85
|
exports.capitalize = capitalize;
|
|
86
|
+
async function exists(path) {
|
|
87
|
+
try {
|
|
88
|
+
await (0, promises_1.access)(path);
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.exists = exists;
|
|
82
96
|
const dirExists = async (input) => {
|
|
83
|
-
if (!
|
|
97
|
+
if (!await exists(input)) {
|
|
84
98
|
throw new Error(`No directory found at ${input}`);
|
|
85
99
|
}
|
|
86
|
-
|
|
100
|
+
const fileStat = await (0, promises_1.stat)(input);
|
|
101
|
+
if (!fileStat.isDirectory()) {
|
|
87
102
|
throw new Error(`${input} exists but is not a directory`);
|
|
88
103
|
}
|
|
89
104
|
return input;
|
|
90
105
|
};
|
|
91
106
|
exports.dirExists = dirExists;
|
|
92
107
|
const fileExists = async (input) => {
|
|
93
|
-
if (!
|
|
108
|
+
if (!await exists(input)) {
|
|
94
109
|
throw new Error(`No file found at ${input}`);
|
|
95
110
|
}
|
|
96
|
-
|
|
111
|
+
const fileStat = await (0, promises_1.stat)(input);
|
|
112
|
+
if (!fileStat.isFile()) {
|
|
97
113
|
throw new Error(`${input} exists but is not a file`);
|
|
98
114
|
}
|
|
99
115
|
return input;
|
|
@@ -108,7 +124,7 @@ function isNotFalsy(input) {
|
|
|
108
124
|
}
|
|
109
125
|
exports.isNotFalsy = isNotFalsy;
|
|
110
126
|
function requireJson(...pathParts) {
|
|
111
|
-
return JSON.parse(
|
|
127
|
+
return JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(...pathParts), 'utf8'));
|
|
112
128
|
}
|
|
113
129
|
exports.requireJson = requireJson;
|
|
114
130
|
/**
|
|
@@ -119,8 +135,56 @@ exports.requireJson = requireJson;
|
|
|
119
135
|
* @returns ArgInput
|
|
120
136
|
*/
|
|
121
137
|
function ensureArgObject(args) {
|
|
122
|
-
return (Array.isArray(args) ? (args ?? []).reduce((x, y) => {
|
|
123
|
-
return { ...x, [y.name]: y };
|
|
124
|
-
}, {}) : args ?? {});
|
|
138
|
+
return (Array.isArray(args) ? (args ?? []).reduce((x, y) => ({ ...x, [y.name]: y }), {}) : args ?? {});
|
|
125
139
|
}
|
|
126
140
|
exports.ensureArgObject = ensureArgObject;
|
|
141
|
+
function uniq(arr) {
|
|
142
|
+
return [...new Set(arr)].sort();
|
|
143
|
+
}
|
|
144
|
+
exports.uniq = uniq;
|
|
145
|
+
/**
|
|
146
|
+
* Call os.homedir() and return the result
|
|
147
|
+
*
|
|
148
|
+
* Wrapping this allows us to stub these in tests since os.homedir() is
|
|
149
|
+
* non-configurable and non-writable.
|
|
150
|
+
*
|
|
151
|
+
* @returns The user's home directory
|
|
152
|
+
*/
|
|
153
|
+
function getHomeDir() {
|
|
154
|
+
return (0, node_os_1.homedir)();
|
|
155
|
+
}
|
|
156
|
+
exports.getHomeDir = getHomeDir;
|
|
157
|
+
/**
|
|
158
|
+
* Call os.platform() and return the result
|
|
159
|
+
*
|
|
160
|
+
* Wrapping this allows us to stub these in tests since os.platform() is
|
|
161
|
+
* non-configurable and non-writable.
|
|
162
|
+
*
|
|
163
|
+
* @returns The process' platform
|
|
164
|
+
*/
|
|
165
|
+
function getPlatform() {
|
|
166
|
+
return (0, node_os_1.platform)();
|
|
167
|
+
}
|
|
168
|
+
exports.getPlatform = getPlatform;
|
|
169
|
+
function readJson(path) {
|
|
170
|
+
debug('config')('readJson %s', path);
|
|
171
|
+
return new Promise((resolve, reject) => {
|
|
172
|
+
(0, node_fs_1.readFile)(path, 'utf8', (err, d) => {
|
|
173
|
+
try {
|
|
174
|
+
if (err)
|
|
175
|
+
reject(err);
|
|
176
|
+
else
|
|
177
|
+
resolve(JSON.parse(d));
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
reject(error);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
exports.readJson = readJson;
|
|
186
|
+
function readJsonSync(path, parse = true) {
|
|
187
|
+
const contents = (0, node_fs_1.readFileSync)(path, 'utf8');
|
|
188
|
+
return parse ? JSON.parse(contents) : contents;
|
|
189
|
+
}
|
|
190
|
+
exports.readJsonSync = readJsonSync;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oclif/core",
|
|
3
3
|
"description": "base library for oclif CLIs",
|
|
4
|
-
"version": "3.0.0-beta.
|
|
4
|
+
"version": "3.0.0-beta.14",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"bugs": "https://github.com/oclif/core/issues",
|
|
7
7
|
"dependencies": {
|
|
@@ -45,15 +45,12 @@
|
|
|
45
45
|
"@types/chai-as-promised": "^7.1.5",
|
|
46
46
|
"@types/clean-stack": "^2.1.1",
|
|
47
47
|
"@types/ejs": "^3.1.2",
|
|
48
|
-
"@types/glob": "^8.1.0",
|
|
49
48
|
"@types/indent-string": "^4.0.1",
|
|
50
49
|
"@types/js-yaml": "^3.12.7",
|
|
51
50
|
"@types/mocha": "^8.2.3",
|
|
52
51
|
"@types/nock": "^11.1.0",
|
|
53
|
-
"@types/node": "^
|
|
52
|
+
"@types/node": "^18",
|
|
54
53
|
"@types/node-notifier": "^8.0.2",
|
|
55
|
-
"@types/proxyquire": "^1.3.28",
|
|
56
|
-
"@types/shelljs": "^0.8.12",
|
|
57
54
|
"@types/slice-ansi": "^4.0.0",
|
|
58
55
|
"@types/strip-ansi": "^5.2.1",
|
|
59
56
|
"@types/supports-color": "^8.1.1",
|
|
@@ -64,23 +61,21 @@
|
|
|
64
61
|
"chai-as-promised": "^7.1.1",
|
|
65
62
|
"commitlint": "^12.1.4",
|
|
66
63
|
"cross-env": "^7.0.3",
|
|
67
|
-
"eslint": "^
|
|
68
|
-
"eslint-config-oclif": "^
|
|
69
|
-
"eslint-config-oclif-typescript": "^
|
|
70
|
-
"fancy-test": "^
|
|
64
|
+
"eslint": "^8.49.0",
|
|
65
|
+
"eslint-config-oclif": "^5.0.0",
|
|
66
|
+
"eslint-config-oclif-typescript": "^2.0.1",
|
|
67
|
+
"fancy-test": "^3.0.0-beta.2",
|
|
71
68
|
"globby": "^11.1.0",
|
|
72
69
|
"husky": "6",
|
|
73
70
|
"mocha": "^10.2.0",
|
|
74
71
|
"nock": "^13.3.0",
|
|
75
|
-
"proxyquire": "^2.1.3",
|
|
76
|
-
"shelljs": "^0.8.5",
|
|
77
72
|
"shx": "^0.3.4",
|
|
78
73
|
"sinon": "^11.1.2",
|
|
79
|
-
"tsd": "^0.
|
|
80
|
-
"typescript": "^
|
|
74
|
+
"tsd": "^0.29.0",
|
|
75
|
+
"typescript": "^5"
|
|
81
76
|
},
|
|
82
77
|
"engines": {
|
|
83
|
-
"node": ">=
|
|
78
|
+
"node": ">=18.0.0"
|
|
84
79
|
},
|
|
85
80
|
"files": [
|
|
86
81
|
"/lib",
|
|
@@ -109,7 +104,7 @@
|
|
|
109
104
|
"build": "shx rm -rf lib && tsc",
|
|
110
105
|
"commitlint": "commitlint",
|
|
111
106
|
"compile": "tsc",
|
|
112
|
-
"lint": "eslint . --ext .ts
|
|
107
|
+
"lint": "eslint . --ext .ts",
|
|
113
108
|
"posttest": "yarn lint",
|
|
114
109
|
"prepack": "yarn run build",
|
|
115
110
|
"pretest": "yarn build --noEmit && tsc -p test --noEmit --skipLibCheck",
|