@oclif/core 3.0.4 → 3.0.5
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/lib/cli-ux/action/base.d.ts +12 -12
- package/lib/cli-ux/action/base.js +78 -78
- package/lib/cli-ux/stream.d.ts +1 -1
- package/lib/cli-ux/stream.js +3 -3
- package/lib/cli-ux/styled/table.js +64 -64
- package/lib/command.d.ts +8 -8
- package/lib/command.js +32 -32
- package/lib/config/config.d.ts +50 -50
- package/lib/config/config.js +210 -210
- package/lib/config/plugin-loader.d.ts +5 -5
- package/lib/config/plugin-loader.js +32 -32
- package/lib/config/plugin.d.ts +10 -10
- package/lib/config/plugin.js +145 -133
- package/lib/errors/errors/cli.d.ts +2 -2
- package/lib/errors/errors/cli.js +9 -9
- package/lib/help/command.d.ts +2 -2
- package/lib/help/command.js +11 -11
- package/lib/help/docopts.d.ts +1 -1
- package/lib/help/docopts.js +20 -20
- package/lib/help/index.d.ts +3 -3
- package/lib/help/index.js +25 -25
- package/lib/parser/parse.d.ts +2 -2
- package/lib/parser/parse.js +89 -89
- package/lib/performance.d.ts +2 -2
- package/lib/performance.js +2 -2
- package/lib/util/fs.d.ts +13 -1
- package/lib/util/fs.js +29 -14
- package/package.json +2 -3
package/lib/parser/parse.js
CHANGED
|
@@ -78,8 +78,92 @@ class Parser {
|
|
|
78
78
|
this.booleanFlags = (0, util_1.pickBy)(input.flags, (f) => f.type === 'boolean');
|
|
79
79
|
this.flagAliases = Object.fromEntries(Object.values(input.flags).flatMap((flag) => [...(flag.aliases ?? []), ...(flag.charAliases ?? [])].map((a) => [a, flag])));
|
|
80
80
|
}
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
async parse() {
|
|
82
|
+
this._debugInput();
|
|
83
|
+
const parseFlag = (arg) => {
|
|
84
|
+
const { isLong, name } = this.findFlag(arg);
|
|
85
|
+
if (!name) {
|
|
86
|
+
const i = arg.indexOf('=');
|
|
87
|
+
if (i !== -1) {
|
|
88
|
+
const sliced = arg.slice(i + 1);
|
|
89
|
+
this.argv.unshift(sliced);
|
|
90
|
+
const equalsParsed = parseFlag(arg.slice(0, i));
|
|
91
|
+
if (!equalsParsed) {
|
|
92
|
+
this.argv.shift();
|
|
93
|
+
}
|
|
94
|
+
return equalsParsed;
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
const flag = this.input.flags[name];
|
|
99
|
+
if (flag.type === 'option') {
|
|
100
|
+
if (!flag.multiple && this.raw.some((o) => o.type === 'flag' && o.flag === name)) {
|
|
101
|
+
throw new errors_1.CLIError(`Flag --${name} can only be specified once`);
|
|
102
|
+
}
|
|
103
|
+
this.currentFlag = flag;
|
|
104
|
+
const input = isLong || arg.length < 3 ? this.argv.shift() : arg.slice(arg[2] === '=' ? 3 : 2);
|
|
105
|
+
// if the value ends up being one of the command's flags, the user didn't provide an input
|
|
106
|
+
if (typeof input !== 'string' || this.findFlag(input).name) {
|
|
107
|
+
throw new errors_1.CLIError(`Flag --${name} expects a value`);
|
|
108
|
+
}
|
|
109
|
+
this.raw.push({ flag: flag.name, input, type: 'flag' });
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
this.raw.push({ flag: flag.name, input: arg, type: 'flag' });
|
|
113
|
+
// push the rest of the short characters back on the stack
|
|
114
|
+
if (!isLong && arg.length > 2) {
|
|
115
|
+
this.argv.unshift(`-${arg.slice(2)}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
};
|
|
120
|
+
let parsingFlags = true;
|
|
121
|
+
const nonExistentFlags = [];
|
|
122
|
+
let dashdash = false;
|
|
123
|
+
const originalArgv = [...this.argv];
|
|
124
|
+
while (this.argv.length > 0) {
|
|
125
|
+
const input = this.argv.shift();
|
|
126
|
+
if (parsingFlags && input.startsWith('-') && input !== '-') {
|
|
127
|
+
// attempt to parse as arg
|
|
128
|
+
if (this.input['--'] !== false && input === '--') {
|
|
129
|
+
parsingFlags = false;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (parseFlag(input)) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (input === '--') {
|
|
136
|
+
dashdash = true;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (this.input['--'] !== false && !isNegativeNumber(input)) {
|
|
140
|
+
// At this point we have a value that begins with '-' or '--'
|
|
141
|
+
// but doesn't match up to a flag definition. So we assume that
|
|
142
|
+
// this is a misspelled flag or a non-existent flag,
|
|
143
|
+
// e.g. --hekp instead of --help
|
|
144
|
+
nonExistentFlags.push(input);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (parsingFlags && this.currentFlag && this.currentFlag.multiple) {
|
|
149
|
+
this.raw.push({ flag: this.currentFlag.name, input, type: 'flag' });
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// not a flag, parse as arg
|
|
153
|
+
const arg = Object.keys(this.input.args)[this._argTokens.length];
|
|
154
|
+
this.raw.push({ arg, input, type: 'arg' });
|
|
155
|
+
}
|
|
156
|
+
const [{ args, argv }, { flags, metadata }] = await Promise.all([this._args(), this._flags()]);
|
|
157
|
+
this._debugOutput(argv, args, flags);
|
|
158
|
+
const unsortedArgv = (dashdash ? [...argv, ...nonExistentFlags, '--'] : [...argv, ...nonExistentFlags]);
|
|
159
|
+
return {
|
|
160
|
+
args: args,
|
|
161
|
+
argv: unsortedArgv.sort((a, b) => originalArgv.indexOf(a) - originalArgv.indexOf(b)),
|
|
162
|
+
flags,
|
|
163
|
+
metadata,
|
|
164
|
+
nonExistentFlags,
|
|
165
|
+
raw: this.raw,
|
|
166
|
+
};
|
|
83
167
|
}
|
|
84
168
|
async _args() {
|
|
85
169
|
const argv = [];
|
|
@@ -127,6 +211,9 @@ class Parser {
|
|
|
127
211
|
}
|
|
128
212
|
return { args, argv };
|
|
129
213
|
}
|
|
214
|
+
get _argTokens() {
|
|
215
|
+
return this.raw.filter((o) => o.type === 'arg');
|
|
216
|
+
}
|
|
130
217
|
_debugInput() {
|
|
131
218
|
debug('input: %s', this.argv.join(' '));
|
|
132
219
|
const args = Object.keys(this.input.args);
|
|
@@ -360,92 +447,5 @@ class Parser {
|
|
|
360
447
|
}
|
|
361
448
|
return flagTokenMap;
|
|
362
449
|
}
|
|
363
|
-
async parse() {
|
|
364
|
-
this._debugInput();
|
|
365
|
-
const parseFlag = (arg) => {
|
|
366
|
-
const { isLong, name } = this.findFlag(arg);
|
|
367
|
-
if (!name) {
|
|
368
|
-
const i = arg.indexOf('=');
|
|
369
|
-
if (i !== -1) {
|
|
370
|
-
const sliced = arg.slice(i + 1);
|
|
371
|
-
this.argv.unshift(sliced);
|
|
372
|
-
const equalsParsed = parseFlag(arg.slice(0, i));
|
|
373
|
-
if (!equalsParsed) {
|
|
374
|
-
this.argv.shift();
|
|
375
|
-
}
|
|
376
|
-
return equalsParsed;
|
|
377
|
-
}
|
|
378
|
-
return false;
|
|
379
|
-
}
|
|
380
|
-
const flag = this.input.flags[name];
|
|
381
|
-
if (flag.type === 'option') {
|
|
382
|
-
if (!flag.multiple && this.raw.some((o) => o.type === 'flag' && o.flag === name)) {
|
|
383
|
-
throw new errors_1.CLIError(`Flag --${name} can only be specified once`);
|
|
384
|
-
}
|
|
385
|
-
this.currentFlag = flag;
|
|
386
|
-
const input = isLong || arg.length < 3 ? this.argv.shift() : arg.slice(arg[2] === '=' ? 3 : 2);
|
|
387
|
-
// if the value ends up being one of the command's flags, the user didn't provide an input
|
|
388
|
-
if (typeof input !== 'string' || this.findFlag(input).name) {
|
|
389
|
-
throw new errors_1.CLIError(`Flag --${name} expects a value`);
|
|
390
|
-
}
|
|
391
|
-
this.raw.push({ flag: flag.name, input, type: 'flag' });
|
|
392
|
-
}
|
|
393
|
-
else {
|
|
394
|
-
this.raw.push({ flag: flag.name, input: arg, type: 'flag' });
|
|
395
|
-
// push the rest of the short characters back on the stack
|
|
396
|
-
if (!isLong && arg.length > 2) {
|
|
397
|
-
this.argv.unshift(`-${arg.slice(2)}`);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
return true;
|
|
401
|
-
};
|
|
402
|
-
let parsingFlags = true;
|
|
403
|
-
const nonExistentFlags = [];
|
|
404
|
-
let dashdash = false;
|
|
405
|
-
const originalArgv = [...this.argv];
|
|
406
|
-
while (this.argv.length > 0) {
|
|
407
|
-
const input = this.argv.shift();
|
|
408
|
-
if (parsingFlags && input.startsWith('-') && input !== '-') {
|
|
409
|
-
// attempt to parse as arg
|
|
410
|
-
if (this.input['--'] !== false && input === '--') {
|
|
411
|
-
parsingFlags = false;
|
|
412
|
-
continue;
|
|
413
|
-
}
|
|
414
|
-
if (parseFlag(input)) {
|
|
415
|
-
continue;
|
|
416
|
-
}
|
|
417
|
-
if (input === '--') {
|
|
418
|
-
dashdash = true;
|
|
419
|
-
continue;
|
|
420
|
-
}
|
|
421
|
-
if (this.input['--'] !== false && !isNegativeNumber(input)) {
|
|
422
|
-
// At this point we have a value that begins with '-' or '--'
|
|
423
|
-
// but doesn't match up to a flag definition. So we assume that
|
|
424
|
-
// this is a misspelled flag or a non-existent flag,
|
|
425
|
-
// e.g. --hekp instead of --help
|
|
426
|
-
nonExistentFlags.push(input);
|
|
427
|
-
continue;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
if (parsingFlags && this.currentFlag && this.currentFlag.multiple) {
|
|
431
|
-
this.raw.push({ flag: this.currentFlag.name, input, type: 'flag' });
|
|
432
|
-
continue;
|
|
433
|
-
}
|
|
434
|
-
// not a flag, parse as arg
|
|
435
|
-
const arg = Object.keys(this.input.args)[this._argTokens.length];
|
|
436
|
-
this.raw.push({ arg, input, type: 'arg' });
|
|
437
|
-
}
|
|
438
|
-
const [{ args, argv }, { flags, metadata }] = await Promise.all([this._args(), this._flags()]);
|
|
439
|
-
this._debugOutput(argv, args, flags);
|
|
440
|
-
const unsortedArgv = (dashdash ? [...argv, ...nonExistentFlags, '--'] : [...argv, ...nonExistentFlags]);
|
|
441
|
-
return {
|
|
442
|
-
args: args,
|
|
443
|
-
argv: unsortedArgv.sort((a, b) => originalArgv.indexOf(a) - originalArgv.indexOf(b)),
|
|
444
|
-
flags,
|
|
445
|
-
metadata,
|
|
446
|
-
nonExistentFlags,
|
|
447
|
-
raw: this.raw,
|
|
448
|
-
};
|
|
449
|
-
}
|
|
450
450
|
}
|
|
451
451
|
exports.Parser = Parser;
|
package/lib/performance.d.ts
CHANGED
|
@@ -30,12 +30,12 @@ declare class Marker {
|
|
|
30
30
|
owner: string;
|
|
31
31
|
name: string;
|
|
32
32
|
details: Details;
|
|
33
|
-
private startMarker;
|
|
34
|
-
private stopMarker;
|
|
35
33
|
method: string;
|
|
36
34
|
module: string;
|
|
37
35
|
scope: string;
|
|
38
36
|
stopped: boolean;
|
|
37
|
+
private startMarker;
|
|
38
|
+
private stopMarker;
|
|
39
39
|
constructor(owner: string, name: string, details?: Details);
|
|
40
40
|
addDetails(details: Details): void;
|
|
41
41
|
measure(): void;
|
package/lib/performance.js
CHANGED
package/lib/util/fs.d.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
export declare function requireJson<T>(...pathParts: string[]): T;
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Parser for Args.directory and Flags.directory. Checks that the provided path
|
|
4
|
+
* exists and is a directory.
|
|
5
|
+
* @param input flag or arg input
|
|
6
|
+
* @returns Promise<string>
|
|
7
|
+
*/
|
|
3
8
|
export declare const dirExists: (input: string) => Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Parser for Args.file and Flags.file. Checks that the provided path
|
|
11
|
+
* exists and is a file.
|
|
12
|
+
* @param input flag or arg input
|
|
13
|
+
* @returns Promise<string>
|
|
14
|
+
*/
|
|
4
15
|
export declare const fileExists: (input: string) => Promise<string>;
|
|
5
16
|
export declare function readJson<T = unknown>(path: string): Promise<T>;
|
|
6
17
|
export declare function readJsonSync(path: string, parse: false): string;
|
|
7
18
|
export declare function readJsonSync<T = unknown>(path: string, parse?: true): T;
|
|
19
|
+
export declare function safeReadJson<T>(path: string): Promise<T | undefined>;
|
package/lib/util/fs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.safeReadJson = exports.readJsonSync = exports.readJson = exports.fileExists = exports.dirExists = exports.requireJson = void 0;
|
|
4
4
|
const node_fs_1 = require("node:fs");
|
|
5
5
|
const promises_1 = require("node:fs/promises");
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
@@ -9,32 +9,40 @@ function requireJson(...pathParts) {
|
|
|
9
9
|
return JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(...pathParts), 'utf8'));
|
|
10
10
|
}
|
|
11
11
|
exports.requireJson = requireJson;
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Parser for Args.directory and Flags.directory. Checks that the provided path
|
|
14
|
+
* exists and is a directory.
|
|
15
|
+
* @param input flag or arg input
|
|
16
|
+
* @returns Promise<string>
|
|
17
|
+
*/
|
|
18
|
+
const dirExists = async (input) => {
|
|
19
|
+
let dirStat;
|
|
13
20
|
try {
|
|
14
|
-
await (0, promises_1.
|
|
15
|
-
return true;
|
|
21
|
+
dirStat = await (0, promises_1.stat)(input);
|
|
16
22
|
}
|
|
17
23
|
catch {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
exports.exists = exists;
|
|
22
|
-
const dirExists = async (input) => {
|
|
23
|
-
if (!(await exists(input))) {
|
|
24
24
|
throw new Error(`No directory found at ${input}`);
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
if (!fileStat.isDirectory()) {
|
|
26
|
+
if (!dirStat.isDirectory()) {
|
|
28
27
|
throw new Error(`${input} exists but is not a directory`);
|
|
29
28
|
}
|
|
30
29
|
return input;
|
|
31
30
|
};
|
|
32
31
|
exports.dirExists = dirExists;
|
|
32
|
+
/**
|
|
33
|
+
* Parser for Args.file and Flags.file. Checks that the provided path
|
|
34
|
+
* exists and is a file.
|
|
35
|
+
* @param input flag or arg input
|
|
36
|
+
* @returns Promise<string>
|
|
37
|
+
*/
|
|
33
38
|
const fileExists = async (input) => {
|
|
34
|
-
|
|
39
|
+
let fileStat;
|
|
40
|
+
try {
|
|
41
|
+
fileStat = await (0, promises_1.stat)(input);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
35
44
|
throw new Error(`No file found at ${input}`);
|
|
36
45
|
}
|
|
37
|
-
const fileStat = await (0, promises_1.stat)(input);
|
|
38
46
|
if (!fileStat.isFile()) {
|
|
39
47
|
throw new Error(`${input} exists but is not a file`);
|
|
40
48
|
}
|
|
@@ -52,3 +60,10 @@ function readJsonSync(path, parse = true) {
|
|
|
52
60
|
return parse ? JSON.parse(contents) : contents;
|
|
53
61
|
}
|
|
54
62
|
exports.readJsonSync = readJsonSync;
|
|
63
|
+
async function safeReadJson(path) {
|
|
64
|
+
try {
|
|
65
|
+
return await readJson(path);
|
|
66
|
+
}
|
|
67
|
+
catch { }
|
|
68
|
+
}
|
|
69
|
+
exports.safeReadJson = safeReadJson;
|
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.
|
|
4
|
+
"version": "3.0.5",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"bugs": "https://github.com/oclif/core/issues",
|
|
7
7
|
"dependencies": {
|
|
@@ -61,9 +61,8 @@
|
|
|
61
61
|
"cross-env": "^7.0.3",
|
|
62
62
|
"eslint": "^8.50.0",
|
|
63
63
|
"eslint-config-oclif": "^5.0.0",
|
|
64
|
-
"eslint-config-oclif-typescript": "^
|
|
64
|
+
"eslint-config-oclif-typescript": "^3.0.1",
|
|
65
65
|
"eslint-config-prettier": "^9.0.0",
|
|
66
|
-
"eslint-plugin-perfectionist": "^2.1.0",
|
|
67
66
|
"fancy-test": "^3.0.1",
|
|
68
67
|
"globby": "^11.1.0",
|
|
69
68
|
"husky": "^8",
|