@oclif/core 2.0.1 → 2.0.2-beta.10
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 +5 -5
- package/lib/args.d.ts +39 -0
- package/lib/args.js +62 -0
- package/lib/cli-ux/action/base.d.ts +1 -1
- package/lib/cli-ux/action/pride-spinner.js +0 -1
- package/lib/cli-ux/action/spinner.js +10 -11
- package/lib/cli-ux/action/spinners.d.ts +251 -0
- package/lib/cli-ux/action/spinners.js +2 -1
- package/lib/cli-ux/config.d.ts +1 -1
- package/lib/cli-ux/config.js +7 -5
- package/lib/cli-ux/index.d.ts +51 -29
- package/lib/cli-ux/index.js +111 -69
- package/lib/cli-ux/list.js +3 -4
- package/lib/cli-ux/prompt.js +9 -8
- package/lib/cli-ux/styled/header.js +1 -1
- package/lib/cli-ux/styled/index.d.ts +7 -0
- package/lib/cli-ux/styled/index.js +15 -0
- package/lib/cli-ux/styled/json.d.ts +1 -1
- package/lib/cli-ux/styled/json.js +2 -3
- package/lib/cli-ux/styled/object.js +1 -1
- package/lib/cli-ux/styled/progress.d.ts +2 -1
- package/lib/cli-ux/styled/progress.js +3 -7
- package/lib/cli-ux/styled/table.js +1 -3
- package/lib/cli-ux/styled/tree.js +0 -1
- package/lib/cli-ux/wait.d.ts +1 -1
- package/lib/cli-ux/wait.js +0 -1
- package/lib/command.d.ts +78 -27
- package/lib/command.js +51 -43
- package/lib/config/config.d.ts +20 -17
- package/lib/config/config.js +86 -28
- package/lib/config/index.js +0 -5
- package/lib/config/plugin.d.ts +3 -2
- package/lib/config/plugin.js +10 -14
- package/lib/config/util.js +2 -2
- package/lib/errors/index.js +0 -1
- package/lib/errors/logger.js +2 -4
- package/lib/flags.d.ts +46 -18
- package/lib/flags.js +71 -29
- package/lib/help/command.d.ts +12 -12
- package/lib/help/command.js +6 -6
- package/lib/help/docopts.d.ts +3 -3
- package/lib/help/docopts.js +3 -3
- package/lib/help/formatter.d.ts +4 -3
- package/lib/help/index.d.ts +10 -14
- package/lib/help/index.js +0 -5
- package/lib/help/util.d.ts +1 -2
- package/lib/help/util.js +2 -1
- package/lib/index.d.ts +6 -5
- package/lib/index.js +10 -8
- package/lib/interfaces/args.d.ts +22 -0
- package/lib/interfaces/{command.js → args.js} +0 -0
- package/lib/interfaces/config.d.ts +1 -2
- package/lib/interfaces/flags.d.ts +2 -2
- package/lib/interfaces/hooks.d.ts +12 -1
- package/lib/interfaces/index.d.ts +2 -2
- package/lib/interfaces/manifest.d.ts +2 -2
- package/lib/interfaces/parser.d.ts +97 -82
- package/lib/interfaces/pjson.d.ts +2 -0
- package/lib/interfaces/plugin.d.ts +2 -1
- package/lib/main.d.ts +54 -1
- package/lib/main.js +71 -7
- package/lib/parser/errors.d.ts +15 -8
- package/lib/parser/errors.js +17 -14
- package/lib/parser/help.d.ts +1 -1
- package/lib/parser/help.js +4 -9
- package/lib/parser/index.d.ts +2 -9
- package/lib/parser/index.js +5 -26
- package/lib/parser/parse.d.ts +4 -11
- package/lib/parser/parse.js +107 -72
- package/lib/parser/validate.d.ts +1 -1
- package/lib/parser/validate.js +6 -3
- package/lib/util.d.ts +20 -0
- package/lib/util.js +57 -1
- package/package.json +8 -8
- package/lib/cli-ux/deps.d.ts +0 -22
- package/lib/cli-ux/deps.js +0 -47
- package/lib/cli-ux/open.d.ts +0 -6
- package/lib/cli-ux/open.js +0 -69
- package/lib/help/_test-help-class.d.ts +0 -6
- package/lib/help/_test-help-class.js +0 -19
- package/lib/interfaces/command.d.ts +0 -110
- package/lib/parser/args.d.ts +0 -5
- package/lib/parser/args.js +0 -11
- package/lib/parser/deps.d.ts +0 -4
- package/lib/parser/deps.js +0 -17
- package/lib/parser/flags.d.ts +0 -60
- package/lib/parser/flags.js +0 -107
- package/lib/parser/list.d.ts +0 -2
- package/lib/parser/list.js +0 -29
- package/lib/parser/util.d.ts +0 -7
- package/lib/parser/util.js +0 -50
package/lib/parser/index.js
CHANGED
|
@@ -1,43 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const args = require("./args");
|
|
5
|
-
exports.args = args;
|
|
6
|
-
const deps_1 = require("./deps");
|
|
7
|
-
const flags = require("./flags");
|
|
8
|
-
exports.flags = flags;
|
|
3
|
+
exports.parse = exports.flagUsages = void 0;
|
|
9
4
|
const parse_1 = require("./parse");
|
|
5
|
+
const validate_1 = require("./validate");
|
|
10
6
|
var help_1 = require("./help");
|
|
11
7
|
Object.defineProperty(exports, "flagUsages", { enumerable: true, get: function () { return help_1.flagUsages; } });
|
|
12
|
-
// eslint-disable-next-line new-cap
|
|
13
|
-
const m = (0, deps_1.default)()
|
|
14
|
-
// eslint-disable-next-line node/no-missing-require
|
|
15
|
-
.add('validate', () => require('./validate').validate);
|
|
16
8
|
async function parse(argv, options) {
|
|
17
9
|
const input = {
|
|
18
10
|
argv,
|
|
19
11
|
context: options.context,
|
|
20
|
-
args: (options.args || []).map((a) => args.newArg(a)),
|
|
21
12
|
'--': options['--'],
|
|
22
|
-
flags: {
|
|
23
|
-
|
|
24
|
-
...options.flags,
|
|
25
|
-
},
|
|
13
|
+
flags: (options.flags ?? {}),
|
|
14
|
+
args: (options.args ?? {}),
|
|
26
15
|
strict: options.strict !== false,
|
|
27
16
|
};
|
|
28
17
|
const parser = new parse_1.Parser(input);
|
|
29
18
|
const output = await parser.parse();
|
|
30
|
-
await
|
|
19
|
+
await (0, validate_1.validate)({ input, output });
|
|
31
20
|
return output;
|
|
32
21
|
}
|
|
33
22
|
exports.parse = parse;
|
|
34
|
-
var flags_1 = require("./flags");
|
|
35
|
-
Object.defineProperty(exports, "boolean", { enumerable: true, get: function () { return flags_1.boolean; } });
|
|
36
|
-
Object.defineProperty(exports, "integer", { enumerable: true, get: function () { return flags_1.integer; } });
|
|
37
|
-
Object.defineProperty(exports, "url", { enumerable: true, get: function () { return flags_1.url; } });
|
|
38
|
-
Object.defineProperty(exports, "directory", { enumerable: true, get: function () { return flags_1.directory; } });
|
|
39
|
-
Object.defineProperty(exports, "file", { enumerable: true, get: function () { return flags_1.file; } });
|
|
40
|
-
Object.defineProperty(exports, "string", { enumerable: true, get: function () { return flags_1.string; } });
|
|
41
|
-
Object.defineProperty(exports, "build", { enumerable: true, get: function () { return flags_1.build; } });
|
|
42
|
-
Object.defineProperty(exports, "option", { enumerable: true, get: function () { return flags_1.option; } });
|
|
43
|
-
Object.defineProperty(exports, "custom", { enumerable: true, get: function () { return flags_1.custom; } });
|
package/lib/parser/parse.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare class Parser<T extends ParserInput, TFlags extends OutputFlags<T['flags']>, TArgs extends OutputArgs
|
|
1
|
+
import { OutputArgs, OutputFlags, ParserInput, ParserOutput } from '../interfaces/parser';
|
|
2
|
+
export declare class Parser<T extends ParserInput, TFlags extends OutputFlags<T['flags']>, BFlags extends OutputFlags<T['flags']>, TArgs extends OutputArgs<T['args']>> {
|
|
3
3
|
private readonly input;
|
|
4
4
|
private readonly argv;
|
|
5
5
|
private readonly raw;
|
|
@@ -9,17 +9,10 @@ export declare class Parser<T extends ParserInput, TFlags extends OutputFlags<T[
|
|
|
9
9
|
private readonly metaData;
|
|
10
10
|
private currentFlag?;
|
|
11
11
|
constructor(input: T);
|
|
12
|
-
parse(): Promise<
|
|
13
|
-
args: TArgs;
|
|
14
|
-
argv: any[];
|
|
15
|
-
flags: TFlags;
|
|
16
|
-
raw: ParsingToken[];
|
|
17
|
-
metadata: any;
|
|
18
|
-
}>;
|
|
19
|
-
private _args;
|
|
12
|
+
parse(): Promise<ParserOutput<TFlags, BFlags, TArgs>>;
|
|
20
13
|
private _flags;
|
|
21
14
|
private _validateOptions;
|
|
22
|
-
private
|
|
15
|
+
private _args;
|
|
23
16
|
private _debugOutput;
|
|
24
17
|
private _debugInput;
|
|
25
18
|
private get _argTokens();
|
package/lib/parser/parse.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// tslint:disable interface-over-type-literal
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.Parser = void 0;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
.add('errors', () => require('./errors'))
|
|
10
|
-
// eslint-disable-next-line node/no-missing-require
|
|
11
|
-
.add('util', () => require('./util'));
|
|
4
|
+
/* eslint-disable no-await-in-loop */
|
|
5
|
+
const errors_1 = require("./errors");
|
|
6
|
+
const readline = require("readline");
|
|
7
|
+
const util_1 = require("../util");
|
|
12
8
|
let debug;
|
|
13
9
|
try {
|
|
14
10
|
// eslint-disable-next-line no-negated-condition
|
|
@@ -18,26 +14,49 @@ catch {
|
|
|
18
14
|
debug = () => { };
|
|
19
15
|
}
|
|
20
16
|
const readStdin = async () => {
|
|
21
|
-
const { stdin } = process;
|
|
22
|
-
|
|
23
|
-
if (stdin.isTTY
|
|
24
|
-
return
|
|
25
|
-
|
|
26
|
-
stdin.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return
|
|
17
|
+
const { stdin, stdout } = process;
|
|
18
|
+
debug('stdin.isTTY', stdin.isTTY);
|
|
19
|
+
if (stdin.isTTY)
|
|
20
|
+
return null;
|
|
21
|
+
// process.stdin.isTTY is true whenever it's running in a terminal.
|
|
22
|
+
// process.stdin.isTTY is undefined when it's running in a pipe, e.g. echo 'foo' | my-cli command
|
|
23
|
+
// process.stdin.isTTY is undefined when it's running in a spawned process, even if there's no pipe.
|
|
24
|
+
// This means that reading from stdin could hang indefinitely while waiting for a non-existent pipe.
|
|
25
|
+
// Because of this, we have to set a timeout to prevent the process from hanging.
|
|
26
|
+
return new Promise(resolve => {
|
|
27
|
+
let result = '';
|
|
28
|
+
const ac = new AbortController();
|
|
29
|
+
const signal = ac.signal;
|
|
30
|
+
const timeout = setTimeout(() => ac.abort(), 100);
|
|
31
|
+
const rl = readline.createInterface({
|
|
32
|
+
input: stdin,
|
|
33
|
+
output: stdout,
|
|
34
|
+
terminal: false,
|
|
35
|
+
});
|
|
36
|
+
rl.on('line', line => {
|
|
37
|
+
result += line;
|
|
38
|
+
});
|
|
39
|
+
rl.once('close', () => {
|
|
40
|
+
clearTimeout(timeout);
|
|
41
|
+
debug('resolved from stdin', result);
|
|
42
|
+
resolve(result);
|
|
43
|
+
});
|
|
44
|
+
signal.addEventListener('abort', () => {
|
|
45
|
+
debug('stdin aborted');
|
|
46
|
+
clearTimeout(timeout);
|
|
47
|
+
rl.close();
|
|
48
|
+
resolve(null);
|
|
49
|
+
}, { once: true });
|
|
50
|
+
});
|
|
31
51
|
};
|
|
32
52
|
class Parser {
|
|
33
53
|
constructor(input) {
|
|
34
54
|
this.input = input;
|
|
35
55
|
this.raw = [];
|
|
36
|
-
const { pickBy } = m.util;
|
|
37
56
|
this.context = input.context || {};
|
|
38
57
|
this.argv = [...input.argv];
|
|
39
58
|
this._setNames();
|
|
40
|
-
this.booleanFlags = pickBy(input.flags, f => f.type === 'boolean');
|
|
59
|
+
this.booleanFlags = (0, util_1.pickBy)(input.flags, f => f.type === 'boolean');
|
|
41
60
|
this.flagAliases = Object.fromEntries(Object.values(input.flags).flatMap(flag => {
|
|
42
61
|
return (flag.aliases ?? []).map(a => [a, flag]);
|
|
43
62
|
}));
|
|
@@ -86,7 +105,7 @@ class Parser {
|
|
|
86
105
|
this.currentFlag = flag;
|
|
87
106
|
const input = long || arg.length < 3 ? this.argv.shift() : arg.slice(arg[2] === '=' ? 3 : 2);
|
|
88
107
|
if (typeof input !== 'string') {
|
|
89
|
-
throw new
|
|
108
|
+
throw new errors_1.CLIError(`Flag --${name} expects a value`);
|
|
90
109
|
}
|
|
91
110
|
this.raw.push({ type: 'flag', flag: flag.name, input });
|
|
92
111
|
}
|
|
@@ -100,6 +119,9 @@ class Parser {
|
|
|
100
119
|
return true;
|
|
101
120
|
};
|
|
102
121
|
let parsingFlags = true;
|
|
122
|
+
const nonExistentFlags = [];
|
|
123
|
+
let dashdash = false;
|
|
124
|
+
const originalArgv = [...this.argv];
|
|
103
125
|
while (this.argv.length > 0) {
|
|
104
126
|
const input = this.argv.shift();
|
|
105
127
|
if (parsingFlags && input.startsWith('-') && input !== '-') {
|
|
@@ -111,45 +133,48 @@ class Parser {
|
|
|
111
133
|
if (parseFlag(input)) {
|
|
112
134
|
continue;
|
|
113
135
|
}
|
|
114
|
-
|
|
136
|
+
if (input === '--') {
|
|
137
|
+
dashdash = true;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (this.input['--'] !== false) {
|
|
141
|
+
// At this point we have a value that begins with '-' or '--'
|
|
142
|
+
// but doesn't match up to a flag definition. So we assume that
|
|
143
|
+
// this is a misspelled flag or a non-existent flag,
|
|
144
|
+
// e.g. --hekp instead of --help
|
|
145
|
+
nonExistentFlags.push(input);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
115
148
|
}
|
|
116
149
|
if (parsingFlags && this.currentFlag && this.currentFlag.multiple) {
|
|
117
150
|
this.raw.push({ type: 'flag', flag: this.currentFlag.name, input });
|
|
118
151
|
continue;
|
|
119
152
|
}
|
|
120
153
|
// not a flag, parse as arg
|
|
121
|
-
const arg = this.input.args[this._argTokens.length];
|
|
122
|
-
|
|
123
|
-
arg.input = input;
|
|
124
|
-
this.raw.push({ type: 'arg', input });
|
|
154
|
+
const arg = Object.keys(this.input.args)[this._argTokens.length];
|
|
155
|
+
this.raw.push({ type: 'arg', arg, input });
|
|
125
156
|
}
|
|
126
|
-
const argv = await this.
|
|
127
|
-
const args = this._args(argv);
|
|
157
|
+
const { argv, args } = await this._args();
|
|
128
158
|
const flags = await this._flags();
|
|
129
159
|
this._debugOutput(argv, args, flags);
|
|
160
|
+
const unsortedArgv = (dashdash ? [...argv, ...nonExistentFlags, '--'] : [...argv, ...nonExistentFlags]);
|
|
130
161
|
return {
|
|
131
|
-
|
|
132
|
-
argv,
|
|
162
|
+
argv: unsortedArgv.sort((a, b) => originalArgv.indexOf(a) - originalArgv.indexOf(b)),
|
|
133
163
|
flags,
|
|
164
|
+
args: args,
|
|
134
165
|
raw: this.raw,
|
|
135
166
|
metadata: this.metaData,
|
|
167
|
+
nonExistentFlags,
|
|
136
168
|
};
|
|
137
169
|
}
|
|
138
|
-
|
|
139
|
-
const args = {};
|
|
140
|
-
for (let i = 0; i < this.input.args.length; i++) {
|
|
141
|
-
const arg = this.input.args[i];
|
|
142
|
-
args[arg.name] = argv[i];
|
|
143
|
-
}
|
|
144
|
-
return args;
|
|
145
|
-
}
|
|
170
|
+
// eslint-disable-next-line complexity
|
|
146
171
|
async _flags() {
|
|
147
172
|
const flags = {};
|
|
148
173
|
this.metaData.flags = {};
|
|
149
174
|
for (const token of this._flagTokens) {
|
|
150
175
|
const flag = this.input.flags[token.flag];
|
|
151
176
|
if (!flag)
|
|
152
|
-
throw new
|
|
177
|
+
throw new errors_1.CLIError(`Unexpected flag ${token.flag}`);
|
|
153
178
|
if (flag.type === 'boolean') {
|
|
154
179
|
if (token.input === `--no-${flag.name}`) {
|
|
155
180
|
flags[token.flag] = false;
|
|
@@ -157,20 +182,25 @@ class Parser {
|
|
|
157
182
|
else {
|
|
158
183
|
flags[token.flag] = true;
|
|
159
184
|
}
|
|
160
|
-
// eslint-disable-next-line no-await-in-loop
|
|
161
185
|
flags[token.flag] = await flag.parse(flags[token.flag], this.context, flag);
|
|
162
186
|
}
|
|
163
187
|
else {
|
|
164
188
|
const input = token.input;
|
|
165
189
|
this._validateOptions(flag, input);
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if (flag.multiple) {
|
|
190
|
+
if (flag.delimiter && flag.multiple) {
|
|
191
|
+
const values = await Promise.all(input.split(flag.delimiter).map(async (v) => flag.parse ? flag.parse(v.trim(), this.context, flag) : v.trim()));
|
|
169
192
|
flags[token.flag] = flags[token.flag] || [];
|
|
170
|
-
flags[token.flag].push(...
|
|
193
|
+
flags[token.flag].push(...values);
|
|
171
194
|
}
|
|
172
195
|
else {
|
|
173
|
-
|
|
196
|
+
const value = flag.parse ? await flag.parse(input, this.context, flag) : input;
|
|
197
|
+
if (flag.multiple) {
|
|
198
|
+
flags[token.flag] = flags[token.flag] || [];
|
|
199
|
+
flags[token.flag].push(value);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
flags[token.flag] = value;
|
|
203
|
+
}
|
|
174
204
|
}
|
|
175
205
|
}
|
|
176
206
|
}
|
|
@@ -183,18 +213,16 @@ class Parser {
|
|
|
183
213
|
if (flag.type === 'option') {
|
|
184
214
|
if (input) {
|
|
185
215
|
this._validateOptions(flag, input);
|
|
186
|
-
// eslint-disable-next-line no-await-in-loop
|
|
187
216
|
flags[k] = await flag.parse(input, this.context, flag);
|
|
188
217
|
}
|
|
189
218
|
}
|
|
190
219
|
else if (flag.type === 'boolean') {
|
|
191
220
|
// eslint-disable-next-line no-negated-condition
|
|
192
|
-
flags[k] = input !== undefined ?
|
|
221
|
+
flags[k] = input !== undefined ? (0, util_1.isTruthy)(input) : false;
|
|
193
222
|
}
|
|
194
223
|
}
|
|
195
224
|
if (!(k in flags) && flag.default !== undefined) {
|
|
196
225
|
this.metaData.flags[k] = { setFromDefault: true };
|
|
197
|
-
// eslint-disable-next-line no-await-in-loop
|
|
198
226
|
const defaultValue = (typeof flag.default === 'function' ? await flag.default({ options: flag, flags, ...this.context }) : flag.default);
|
|
199
227
|
flags[k] = defaultValue;
|
|
200
228
|
}
|
|
@@ -203,48 +231,51 @@ class Parser {
|
|
|
203
231
|
}
|
|
204
232
|
_validateOptions(flag, input) {
|
|
205
233
|
if (flag.options && !flag.options.includes(input))
|
|
206
|
-
throw new
|
|
234
|
+
throw new errors_1.FlagInvalidOptionError(flag, input);
|
|
207
235
|
}
|
|
208
|
-
async
|
|
209
|
-
const
|
|
236
|
+
async _args() {
|
|
237
|
+
const argv = [];
|
|
238
|
+
const args = {};
|
|
210
239
|
const tokens = this._argTokens;
|
|
211
240
|
let stdinRead = false;
|
|
212
|
-
for (
|
|
213
|
-
const token = tokens
|
|
214
|
-
const arg = this.input.args[i];
|
|
241
|
+
for (const [name, arg] of Object.entries(this.input.args)) {
|
|
242
|
+
const token = tokens.find(t => t.arg === name);
|
|
215
243
|
if (token) {
|
|
216
|
-
if (arg) {
|
|
217
|
-
|
|
218
|
-
throw new m.errors.ArgInvalidOptionError(arg, token.input);
|
|
219
|
-
}
|
|
220
|
-
// eslint-disable-next-line no-await-in-loop
|
|
221
|
-
args[i] = await arg.parse(token.input);
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
args[i] = token.input;
|
|
244
|
+
if (arg.options && !arg.options.includes(token.input)) {
|
|
245
|
+
throw new errors_1.ArgInvalidOptionError(arg, token.input);
|
|
225
246
|
}
|
|
247
|
+
const parsed = await arg.parse(token.input, this.context, arg);
|
|
248
|
+
argv.push(parsed);
|
|
249
|
+
args[token.arg] = parsed;
|
|
226
250
|
}
|
|
227
251
|
else if (!arg.ignoreStdin && !stdinRead) {
|
|
228
|
-
// eslint-disable-next-line no-await-in-loop
|
|
229
252
|
let stdin = await readStdin();
|
|
230
253
|
if (stdin) {
|
|
231
254
|
stdin = stdin.trim();
|
|
232
|
-
|
|
255
|
+
const parsed = await arg.parse(stdin, this.context, arg);
|
|
256
|
+
argv.push(parsed);
|
|
257
|
+
args[name] = parsed;
|
|
233
258
|
}
|
|
234
259
|
stdinRead = true;
|
|
235
260
|
}
|
|
236
|
-
if (!args[
|
|
261
|
+
if (!args[name] && (arg.default || arg.default === false)) {
|
|
237
262
|
if (typeof arg.default === 'function') {
|
|
238
|
-
// eslint-disable-next-line no-await-in-loop
|
|
239
263
|
const f = await arg.default();
|
|
240
|
-
|
|
264
|
+
argv.push(f);
|
|
265
|
+
args[name] = f;
|
|
241
266
|
}
|
|
242
267
|
else {
|
|
243
|
-
|
|
268
|
+
argv.push(arg.default);
|
|
269
|
+
args[name] = arg.default;
|
|
244
270
|
}
|
|
245
271
|
}
|
|
246
272
|
}
|
|
247
|
-
|
|
273
|
+
for (const token of tokens) {
|
|
274
|
+
if (args[token.arg])
|
|
275
|
+
continue;
|
|
276
|
+
argv.push(token.input);
|
|
277
|
+
}
|
|
278
|
+
return { argv, args: args };
|
|
248
279
|
}
|
|
249
280
|
_debugOutput(args, flags, argv) {
|
|
250
281
|
if (argv.length > 0) {
|
|
@@ -259,8 +290,9 @@ class Parser {
|
|
|
259
290
|
}
|
|
260
291
|
_debugInput() {
|
|
261
292
|
debug('input: %s', this.argv.join(' '));
|
|
262
|
-
|
|
263
|
-
|
|
293
|
+
const args = Object.keys(this.input.args);
|
|
294
|
+
if (args.length > 0) {
|
|
295
|
+
debug('available args: %s', args.join(' '));
|
|
264
296
|
}
|
|
265
297
|
if (Object.keys(this.input.flags).length === 0)
|
|
266
298
|
return;
|
|
@@ -278,6 +310,9 @@ class Parser {
|
|
|
278
310
|
for (const k of Object.keys(this.input.flags)) {
|
|
279
311
|
this.input.flags[k].name = k;
|
|
280
312
|
}
|
|
313
|
+
for (const k of Object.keys(this.input.args)) {
|
|
314
|
+
this.input.args[k].name = k;
|
|
315
|
+
}
|
|
281
316
|
}
|
|
282
317
|
}
|
|
283
318
|
exports.Parser = Parser;
|
package/lib/parser/validate.d.ts
CHANGED
package/lib/parser/validate.js
CHANGED
|
@@ -5,14 +5,17 @@ const errors_1 = require("./errors");
|
|
|
5
5
|
const util_1 = require("../config/util");
|
|
6
6
|
async function validate(parse) {
|
|
7
7
|
function validateArgs() {
|
|
8
|
-
|
|
8
|
+
if (parse.output.nonExistentFlags?.length > 0) {
|
|
9
|
+
throw new errors_1.NonExistentFlagsError({ parse, flags: parse.output.nonExistentFlags });
|
|
10
|
+
}
|
|
11
|
+
const maxArgs = Object.keys(parse.input.args).length;
|
|
9
12
|
if (parse.input.strict && parse.output.argv.length > maxArgs) {
|
|
10
13
|
const extras = parse.output.argv.slice(maxArgs);
|
|
11
14
|
throw new errors_1.UnexpectedArgsError({ parse, args: extras });
|
|
12
15
|
}
|
|
13
16
|
const missingRequiredArgs = [];
|
|
14
17
|
let hasOptional = false;
|
|
15
|
-
for (const [
|
|
18
|
+
for (const [name, arg] of Object.entries(parse.input.args)) {
|
|
16
19
|
if (!arg.required) {
|
|
17
20
|
hasOptional = true;
|
|
18
21
|
}
|
|
@@ -21,7 +24,7 @@ async function validate(parse) {
|
|
|
21
24
|
// optionals should follow required, not before
|
|
22
25
|
throw new errors_1.InvalidArgsSpecError({ parse, args: parse.input.args });
|
|
23
26
|
}
|
|
24
|
-
if (arg.required && !parse.output.
|
|
27
|
+
if (arg.required && !parse.output.args[name] && parse.output.args[name] !== 0) {
|
|
25
28
|
missingRequiredArgs.push(arg);
|
|
26
29
|
}
|
|
27
30
|
}
|
package/lib/util.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { Command } from './command';
|
|
2
|
+
import { ArgInput } from './interfaces/parser';
|
|
3
|
+
export declare function pickBy<T extends {
|
|
4
|
+
[s: string]: T[keyof T];
|
|
5
|
+
} | ArrayLike<T[keyof T]>>(obj: T, fn: (i: T[keyof T]) => boolean): Partial<T>;
|
|
1
6
|
export declare function compact<T>(a: (T | undefined)[]): T[];
|
|
2
7
|
export declare function uniqBy<T>(arr: T[], fn: (cur: T) => any): T[];
|
|
3
8
|
type SortTypes = string | number | undefined | boolean;
|
|
@@ -7,4 +12,19 @@ export declare function isProd(): boolean;
|
|
|
7
12
|
export declare function maxBy<T>(arr: T[], fn: (i: T) => number): T | undefined;
|
|
8
13
|
export declare function sumBy<T>(arr: T[], fn: (i: T) => number): number;
|
|
9
14
|
export declare function capitalize(s: string): string;
|
|
15
|
+
export declare const dirExists: (input: string) => Promise<string>;
|
|
16
|
+
export declare const fileExists: (input: string) => Promise<string>;
|
|
17
|
+
export declare function isTruthy(input: string): boolean;
|
|
18
|
+
export declare function isNotFalsy(input: string): boolean;
|
|
19
|
+
export declare function requireJson<T>(...pathParts: string[]): T;
|
|
20
|
+
/**
|
|
21
|
+
* Ensure that the provided args are an object. This is for backwards compatibility with v1 commands which
|
|
22
|
+
* defined args as an array.
|
|
23
|
+
*
|
|
24
|
+
* @param args Either an array of args or an object of args
|
|
25
|
+
* @returns ArgInput
|
|
26
|
+
*/
|
|
27
|
+
export declare function ensureArgObject(args?: any[] | ArgInput | {
|
|
28
|
+
[name: string]: Command.Arg.Cached;
|
|
29
|
+
}): ArgInput;
|
|
10
30
|
export {};
|
package/lib/util.js
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.capitalize = exports.sumBy = exports.maxBy = exports.isProd = exports.castArray = exports.sortBy = exports.uniqBy = exports.compact = void 0;
|
|
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.uniqBy = exports.compact = exports.pickBy = void 0;
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
function pickBy(obj, fn) {
|
|
7
|
+
return Object.entries(obj)
|
|
8
|
+
.reduce((o, [k, v]) => {
|
|
9
|
+
if (fn(v))
|
|
10
|
+
o[k] = v;
|
|
11
|
+
return o;
|
|
12
|
+
}, {});
|
|
13
|
+
}
|
|
14
|
+
exports.pickBy = pickBy;
|
|
4
15
|
function compact(a) {
|
|
5
16
|
return a.filter((a) => Boolean(a));
|
|
6
17
|
}
|
|
@@ -62,3 +73,48 @@ function capitalize(s) {
|
|
|
62
73
|
return s ? s.charAt(0).toUpperCase() + s.slice(1).toLowerCase() : '';
|
|
63
74
|
}
|
|
64
75
|
exports.capitalize = capitalize;
|
|
76
|
+
const dirExists = async (input) => {
|
|
77
|
+
if (!fs.existsSync(input)) {
|
|
78
|
+
throw new Error(`No directory found at ${input}`);
|
|
79
|
+
}
|
|
80
|
+
if (!(await fs.promises.stat(input)).isDirectory()) {
|
|
81
|
+
throw new Error(`${input} exists but is not a directory`);
|
|
82
|
+
}
|
|
83
|
+
return input;
|
|
84
|
+
};
|
|
85
|
+
exports.dirExists = dirExists;
|
|
86
|
+
const fileExists = async (input) => {
|
|
87
|
+
if (!fs.existsSync(input)) {
|
|
88
|
+
throw new Error(`No file found at ${input}`);
|
|
89
|
+
}
|
|
90
|
+
if (!(await fs.promises.stat(input)).isFile()) {
|
|
91
|
+
throw new Error(`${input} exists but is not a file`);
|
|
92
|
+
}
|
|
93
|
+
return input;
|
|
94
|
+
};
|
|
95
|
+
exports.fileExists = fileExists;
|
|
96
|
+
function isTruthy(input) {
|
|
97
|
+
return ['true', '1', 'yes', 'y'].includes(input.toLowerCase());
|
|
98
|
+
}
|
|
99
|
+
exports.isTruthy = isTruthy;
|
|
100
|
+
function isNotFalsy(input) {
|
|
101
|
+
return !['false', '0', 'no', 'n'].includes(input.toLowerCase());
|
|
102
|
+
}
|
|
103
|
+
exports.isNotFalsy = isNotFalsy;
|
|
104
|
+
function requireJson(...pathParts) {
|
|
105
|
+
return JSON.parse(fs.readFileSync((0, path_1.join)(...pathParts), 'utf8'));
|
|
106
|
+
}
|
|
107
|
+
exports.requireJson = requireJson;
|
|
108
|
+
/**
|
|
109
|
+
* Ensure that the provided args are an object. This is for backwards compatibility with v1 commands which
|
|
110
|
+
* defined args as an array.
|
|
111
|
+
*
|
|
112
|
+
* @param args Either an array of args or an object of args
|
|
113
|
+
* @returns ArgInput
|
|
114
|
+
*/
|
|
115
|
+
function ensureArgObject(args) {
|
|
116
|
+
return (Array.isArray(args) ? (args ?? []).reduce((x, y) => {
|
|
117
|
+
return { ...x, [y.name]: y };
|
|
118
|
+
}, {}) : args ?? {});
|
|
119
|
+
}
|
|
120
|
+
exports.ensureArgObject = ensureArgObject;
|
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oclif/core",
|
|
3
3
|
"description": "base library for oclif CLIs",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.2-beta.10",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"bugs": "https://github.com/oclif/core/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@
|
|
9
|
-
"@oclif/screen": "^3.0.4",
|
|
8
|
+
"@types/cli-progress": "^3.11.0",
|
|
10
9
|
"ansi-escapes": "^4.3.2",
|
|
11
10
|
"ansi-styles": "^4.3.0",
|
|
12
11
|
"cardinal": "^2.1.1",
|
|
@@ -32,31 +31,32 @@
|
|
|
32
31
|
"supports-hyperlinks": "^2.2.0",
|
|
33
32
|
"tslib": "^2.4.1",
|
|
34
33
|
"widest-line": "^3.1.0",
|
|
34
|
+
"wordwrap": "^1.0.0",
|
|
35
35
|
"wrap-ansi": "^7.0.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@commitlint/config-conventional": "^12.1.4",
|
|
39
39
|
"@oclif/plugin-help": "^5.1.22",
|
|
40
40
|
"@oclif/plugin-plugins": "^2.1.12",
|
|
41
|
-
"@oclif/test": "^2.2.
|
|
41
|
+
"@oclif/test": "^2.2.20",
|
|
42
42
|
"@types/ansi-styles": "^3.2.1",
|
|
43
43
|
"@types/chai": "^4.3.4",
|
|
44
44
|
"@types/chai-as-promised": "^7.1.5",
|
|
45
45
|
"@types/clean-stack": "^2.1.1",
|
|
46
|
-
"@types/cli-progress": "^3.9.2",
|
|
47
46
|
"@types/ejs": "^3.1.0",
|
|
48
47
|
"@types/fs-extra": "^9.0.13",
|
|
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": "^16",
|
|
54
53
|
"@types/node-notifier": "^8.0.2",
|
|
55
54
|
"@types/proxyquire": "^1.3.28",
|
|
56
55
|
"@types/semver": "^7.3.13",
|
|
57
56
|
"@types/shelljs": "^0.8.11",
|
|
58
57
|
"@types/strip-ansi": "^5.2.1",
|
|
59
58
|
"@types/supports-color": "^8.1.1",
|
|
59
|
+
"@types/wordwrap": "^1.0.1",
|
|
60
60
|
"@types/wrap-ansi": "^3.0.0",
|
|
61
61
|
"chai": "^4.3.7",
|
|
62
62
|
"chai-as-promised": "^7.1.1",
|
|
@@ -64,11 +64,11 @@
|
|
|
64
64
|
"eslint": "^7.32.0",
|
|
65
65
|
"eslint-config-oclif": "^4.0.0",
|
|
66
66
|
"eslint-config-oclif-typescript": "^1.0.2",
|
|
67
|
-
"fancy-test": "^
|
|
67
|
+
"fancy-test": "^2.0.12",
|
|
68
68
|
"globby": "^11.1.0",
|
|
69
69
|
"husky": "6",
|
|
70
70
|
"mocha": "^8.4.0",
|
|
71
|
-
"nock": "^13.
|
|
71
|
+
"nock": "^13.3.0",
|
|
72
72
|
"proxyquire": "^2.1.3",
|
|
73
73
|
"shelljs": "^0.8.5",
|
|
74
74
|
"shx": "^0.3.4",
|
package/lib/cli-ux/deps.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
declare const _default: {
|
|
2
|
-
readonly stripAnsi: (string: string) => string;
|
|
3
|
-
readonly ansiStyles: {
|
|
4
|
-
readonly modifier: import("ansi-styles").Modifier;
|
|
5
|
-
readonly color: import("ansi-styles").ForegroundColor & import("ansi-styles").ColorBase;
|
|
6
|
-
readonly bgColor: import("ansi-styles").BackgroundColor & import("ansi-styles").ColorBase;
|
|
7
|
-
readonly codes: ReadonlyMap<number, number>;
|
|
8
|
-
} & import("ansi-styles").BackgroundColor & import("ansi-styles").ForegroundColor & import("ansi-styles").Modifier;
|
|
9
|
-
readonly ansiEscapes: any;
|
|
10
|
-
readonly passwordPrompt: any;
|
|
11
|
-
readonly screen: typeof import("@oclif/screen");
|
|
12
|
-
readonly open: typeof import("./open").default;
|
|
13
|
-
readonly prompt: typeof import("./prompt");
|
|
14
|
-
readonly styledObject: typeof import("./styled/object").default;
|
|
15
|
-
readonly styledHeader: typeof import("./styled/header").default;
|
|
16
|
-
readonly styledJSON: typeof import("./styled/json").default;
|
|
17
|
-
readonly table: typeof import("./styled/table").table;
|
|
18
|
-
readonly tree: typeof import("./styled/tree").default;
|
|
19
|
-
readonly wait: (ms?: number) => Promise<unknown>;
|
|
20
|
-
readonly progress: typeof import("./styled/progress").default;
|
|
21
|
-
};
|
|
22
|
-
export default _default;
|
package/lib/cli-ux/deps.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
/* eslint-disable node/no-missing-require */
|
|
4
|
-
exports.default = {
|
|
5
|
-
get stripAnsi() {
|
|
6
|
-
return require('strip-ansi');
|
|
7
|
-
},
|
|
8
|
-
get ansiStyles() {
|
|
9
|
-
return require('ansi-styles');
|
|
10
|
-
},
|
|
11
|
-
get ansiEscapes() {
|
|
12
|
-
return require('ansi-escapes');
|
|
13
|
-
},
|
|
14
|
-
get passwordPrompt() {
|
|
15
|
-
return require('password-prompt');
|
|
16
|
-
},
|
|
17
|
-
get screen() {
|
|
18
|
-
return require('@oclif/screen');
|
|
19
|
-
},
|
|
20
|
-
get open() {
|
|
21
|
-
return require('./open').default;
|
|
22
|
-
},
|
|
23
|
-
get prompt() {
|
|
24
|
-
return require('./prompt');
|
|
25
|
-
},
|
|
26
|
-
get styledObject() {
|
|
27
|
-
return require('./styled/object').default;
|
|
28
|
-
},
|
|
29
|
-
get styledHeader() {
|
|
30
|
-
return require('./styled/header').default;
|
|
31
|
-
},
|
|
32
|
-
get styledJSON() {
|
|
33
|
-
return require('./styled/json').default;
|
|
34
|
-
},
|
|
35
|
-
get table() {
|
|
36
|
-
return require('./styled/table').table;
|
|
37
|
-
},
|
|
38
|
-
get tree() {
|
|
39
|
-
return require('./styled/tree').default;
|
|
40
|
-
},
|
|
41
|
-
get wait() {
|
|
42
|
-
return require('./wait').default;
|
|
43
|
-
},
|
|
44
|
-
get progress() {
|
|
45
|
-
return require('./styled/progress').default;
|
|
46
|
-
},
|
|
47
|
-
};
|