@oclif/core 2.0.1 → 2.0.2-beta.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 +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 +1 -5
- 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 +18 -17
- package/lib/config/config.js +46 -22
- package/lib/config/index.js +0 -5
- package/lib/config/plugin.d.ts +3 -2
- package/lib/config/plugin.js +4 -13
- 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 +2 -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 +3 -3
- package/lib/help/util.js +1 -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 +1 -1
- package/lib/interfaces/index.d.ts +2 -2
- package/lib/interfaces/manifest.d.ts +2 -2
- package/lib/interfaces/parser.d.ts +96 -81
- package/lib/interfaces/plugin.d.ts +1 -1
- package/lib/main.d.ts +54 -1
- package/lib/main.js +70 -6
- 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 +108 -72
- package/lib/parser/validate.d.ts +1 -1
- package/lib/parser/validate.js +6 -3
- package/lib/util.d.ts +8 -0
- package/lib/util.js +44 -1
- package/package.json +4 -4
- 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/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,50 @@ 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
|
+
// @ts-expect-error because the AbortSignal interface is missing addEventListener
|
|
45
|
+
signal.addEventListener('abort', () => {
|
|
46
|
+
debug('stdin aborted');
|
|
47
|
+
clearTimeout(timeout);
|
|
48
|
+
rl.close();
|
|
49
|
+
resolve(null);
|
|
50
|
+
}, { once: true });
|
|
51
|
+
});
|
|
31
52
|
};
|
|
32
53
|
class Parser {
|
|
33
54
|
constructor(input) {
|
|
34
55
|
this.input = input;
|
|
35
56
|
this.raw = [];
|
|
36
|
-
const { pickBy } = m.util;
|
|
37
57
|
this.context = input.context || {};
|
|
38
58
|
this.argv = [...input.argv];
|
|
39
59
|
this._setNames();
|
|
40
|
-
this.booleanFlags = pickBy(input.flags, f => f.type === 'boolean');
|
|
60
|
+
this.booleanFlags = (0, util_1.pickBy)(input.flags, f => f.type === 'boolean');
|
|
41
61
|
this.flagAliases = Object.fromEntries(Object.values(input.flags).flatMap(flag => {
|
|
42
62
|
return (flag.aliases ?? []).map(a => [a, flag]);
|
|
43
63
|
}));
|
|
@@ -86,7 +106,7 @@ class Parser {
|
|
|
86
106
|
this.currentFlag = flag;
|
|
87
107
|
const input = long || arg.length < 3 ? this.argv.shift() : arg.slice(arg[2] === '=' ? 3 : 2);
|
|
88
108
|
if (typeof input !== 'string') {
|
|
89
|
-
throw new
|
|
109
|
+
throw new errors_1.CLIError(`Flag --${name} expects a value`);
|
|
90
110
|
}
|
|
91
111
|
this.raw.push({ type: 'flag', flag: flag.name, input });
|
|
92
112
|
}
|
|
@@ -100,6 +120,9 @@ class Parser {
|
|
|
100
120
|
return true;
|
|
101
121
|
};
|
|
102
122
|
let parsingFlags = true;
|
|
123
|
+
const nonExistentFlags = [];
|
|
124
|
+
let dashdash = false;
|
|
125
|
+
const originalArgv = [...this.argv];
|
|
103
126
|
while (this.argv.length > 0) {
|
|
104
127
|
const input = this.argv.shift();
|
|
105
128
|
if (parsingFlags && input.startsWith('-') && input !== '-') {
|
|
@@ -111,45 +134,48 @@ class Parser {
|
|
|
111
134
|
if (parseFlag(input)) {
|
|
112
135
|
continue;
|
|
113
136
|
}
|
|
114
|
-
|
|
137
|
+
if (input === '--') {
|
|
138
|
+
dashdash = true;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (this.input['--'] !== false) {
|
|
142
|
+
// At this point we have a value that begins with '-' or '--'
|
|
143
|
+
// but doesn't match up to a flag definition. So we assume that
|
|
144
|
+
// this is a misspelled flag or a non-existent flag,
|
|
145
|
+
// e.g. --hekp instead of --help
|
|
146
|
+
nonExistentFlags.push(input);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
115
149
|
}
|
|
116
150
|
if (parsingFlags && this.currentFlag && this.currentFlag.multiple) {
|
|
117
151
|
this.raw.push({ type: 'flag', flag: this.currentFlag.name, input });
|
|
118
152
|
continue;
|
|
119
153
|
}
|
|
120
154
|
// 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 });
|
|
155
|
+
const arg = Object.keys(this.input.args)[this._argTokens.length];
|
|
156
|
+
this.raw.push({ type: 'arg', arg, input });
|
|
125
157
|
}
|
|
126
|
-
const argv = await this.
|
|
127
|
-
const args = this._args(argv);
|
|
158
|
+
const { argv, args } = await this._args();
|
|
128
159
|
const flags = await this._flags();
|
|
129
160
|
this._debugOutput(argv, args, flags);
|
|
161
|
+
const unsortedArgv = (dashdash ? [...argv, ...nonExistentFlags, '--'] : [...argv, ...nonExistentFlags]);
|
|
130
162
|
return {
|
|
131
|
-
|
|
132
|
-
argv,
|
|
163
|
+
argv: unsortedArgv.sort((a, b) => originalArgv.indexOf(a) - originalArgv.indexOf(b)),
|
|
133
164
|
flags,
|
|
165
|
+
args: args,
|
|
134
166
|
raw: this.raw,
|
|
135
167
|
metadata: this.metaData,
|
|
168
|
+
nonExistentFlags,
|
|
136
169
|
};
|
|
137
170
|
}
|
|
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
|
-
}
|
|
171
|
+
// eslint-disable-next-line complexity
|
|
146
172
|
async _flags() {
|
|
147
173
|
const flags = {};
|
|
148
174
|
this.metaData.flags = {};
|
|
149
175
|
for (const token of this._flagTokens) {
|
|
150
176
|
const flag = this.input.flags[token.flag];
|
|
151
177
|
if (!flag)
|
|
152
|
-
throw new
|
|
178
|
+
throw new errors_1.CLIError(`Unexpected flag ${token.flag}`);
|
|
153
179
|
if (flag.type === 'boolean') {
|
|
154
180
|
if (token.input === `--no-${flag.name}`) {
|
|
155
181
|
flags[token.flag] = false;
|
|
@@ -157,20 +183,25 @@ class Parser {
|
|
|
157
183
|
else {
|
|
158
184
|
flags[token.flag] = true;
|
|
159
185
|
}
|
|
160
|
-
// eslint-disable-next-line no-await-in-loop
|
|
161
186
|
flags[token.flag] = await flag.parse(flags[token.flag], this.context, flag);
|
|
162
187
|
}
|
|
163
188
|
else {
|
|
164
189
|
const input = token.input;
|
|
165
190
|
this._validateOptions(flag, input);
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if (flag.multiple) {
|
|
191
|
+
if (flag.delimiter && flag.multiple) {
|
|
192
|
+
const values = await Promise.all(input.split(flag.delimiter).map(async (v) => flag.parse ? flag.parse(v.trim(), this.context, flag) : v.trim()));
|
|
169
193
|
flags[token.flag] = flags[token.flag] || [];
|
|
170
|
-
flags[token.flag].push(...
|
|
194
|
+
flags[token.flag].push(...values);
|
|
171
195
|
}
|
|
172
196
|
else {
|
|
173
|
-
|
|
197
|
+
const value = flag.parse ? await flag.parse(input, this.context, flag) : input;
|
|
198
|
+
if (flag.multiple) {
|
|
199
|
+
flags[token.flag] = flags[token.flag] || [];
|
|
200
|
+
flags[token.flag].push(value);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
flags[token.flag] = value;
|
|
204
|
+
}
|
|
174
205
|
}
|
|
175
206
|
}
|
|
176
207
|
}
|
|
@@ -183,18 +214,16 @@ class Parser {
|
|
|
183
214
|
if (flag.type === 'option') {
|
|
184
215
|
if (input) {
|
|
185
216
|
this._validateOptions(flag, input);
|
|
186
|
-
// eslint-disable-next-line no-await-in-loop
|
|
187
217
|
flags[k] = await flag.parse(input, this.context, flag);
|
|
188
218
|
}
|
|
189
219
|
}
|
|
190
220
|
else if (flag.type === 'boolean') {
|
|
191
221
|
// eslint-disable-next-line no-negated-condition
|
|
192
|
-
flags[k] = input !== undefined ?
|
|
222
|
+
flags[k] = input !== undefined ? (0, util_1.isTruthy)(input) : false;
|
|
193
223
|
}
|
|
194
224
|
}
|
|
195
225
|
if (!(k in flags) && flag.default !== undefined) {
|
|
196
226
|
this.metaData.flags[k] = { setFromDefault: true };
|
|
197
|
-
// eslint-disable-next-line no-await-in-loop
|
|
198
227
|
const defaultValue = (typeof flag.default === 'function' ? await flag.default({ options: flag, flags, ...this.context }) : flag.default);
|
|
199
228
|
flags[k] = defaultValue;
|
|
200
229
|
}
|
|
@@ -203,48 +232,51 @@ class Parser {
|
|
|
203
232
|
}
|
|
204
233
|
_validateOptions(flag, input) {
|
|
205
234
|
if (flag.options && !flag.options.includes(input))
|
|
206
|
-
throw new
|
|
235
|
+
throw new errors_1.FlagInvalidOptionError(flag, input);
|
|
207
236
|
}
|
|
208
|
-
async
|
|
209
|
-
const
|
|
237
|
+
async _args() {
|
|
238
|
+
const argv = [];
|
|
239
|
+
const args = {};
|
|
210
240
|
const tokens = this._argTokens;
|
|
211
241
|
let stdinRead = false;
|
|
212
|
-
for (
|
|
213
|
-
const token = tokens
|
|
214
|
-
const arg = this.input.args[i];
|
|
242
|
+
for (const [name, arg] of Object.entries(this.input.args)) {
|
|
243
|
+
const token = tokens.find(t => t.arg === name);
|
|
215
244
|
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;
|
|
245
|
+
if (arg.options && !arg.options.includes(token.input)) {
|
|
246
|
+
throw new errors_1.ArgInvalidOptionError(arg, token.input);
|
|
225
247
|
}
|
|
248
|
+
const parsed = await arg.parse(token.input, this.context, arg);
|
|
249
|
+
argv.push(parsed);
|
|
250
|
+
args[token.arg] = parsed;
|
|
226
251
|
}
|
|
227
252
|
else if (!arg.ignoreStdin && !stdinRead) {
|
|
228
|
-
// eslint-disable-next-line no-await-in-loop
|
|
229
253
|
let stdin = await readStdin();
|
|
230
254
|
if (stdin) {
|
|
231
255
|
stdin = stdin.trim();
|
|
232
|
-
|
|
256
|
+
const parsed = await arg.parse(stdin, this.context, arg);
|
|
257
|
+
argv.push(parsed);
|
|
258
|
+
args[name] = parsed;
|
|
233
259
|
}
|
|
234
260
|
stdinRead = true;
|
|
235
261
|
}
|
|
236
|
-
if (!args[
|
|
262
|
+
if (!args[name] && (arg.default || arg.default === false)) {
|
|
237
263
|
if (typeof arg.default === 'function') {
|
|
238
|
-
// eslint-disable-next-line no-await-in-loop
|
|
239
264
|
const f = await arg.default();
|
|
240
|
-
|
|
265
|
+
argv.push(f);
|
|
266
|
+
args[name] = f;
|
|
241
267
|
}
|
|
242
268
|
else {
|
|
243
|
-
|
|
269
|
+
argv.push(arg.default);
|
|
270
|
+
args[name] = arg.default;
|
|
244
271
|
}
|
|
245
272
|
}
|
|
246
273
|
}
|
|
247
|
-
|
|
274
|
+
for (const token of tokens) {
|
|
275
|
+
if (args[token.arg])
|
|
276
|
+
continue;
|
|
277
|
+
argv.push(token.input);
|
|
278
|
+
}
|
|
279
|
+
return { argv, args: args };
|
|
248
280
|
}
|
|
249
281
|
_debugOutput(args, flags, argv) {
|
|
250
282
|
if (argv.length > 0) {
|
|
@@ -259,8 +291,9 @@ class Parser {
|
|
|
259
291
|
}
|
|
260
292
|
_debugInput() {
|
|
261
293
|
debug('input: %s', this.argv.join(' '));
|
|
262
|
-
|
|
263
|
-
|
|
294
|
+
const args = Object.keys(this.input.args);
|
|
295
|
+
if (args.length > 0) {
|
|
296
|
+
debug('available args: %s', args.join(' '));
|
|
264
297
|
}
|
|
265
298
|
if (Object.keys(this.input.flags).length === 0)
|
|
266
299
|
return;
|
|
@@ -278,6 +311,9 @@ class Parser {
|
|
|
278
311
|
for (const k of Object.keys(this.input.flags)) {
|
|
279
312
|
this.input.flags[k].name = k;
|
|
280
313
|
}
|
|
314
|
+
for (const k of Object.keys(this.input.args)) {
|
|
315
|
+
this.input.args[k].name = k;
|
|
316
|
+
}
|
|
281
317
|
}
|
|
282
318
|
}
|
|
283
319
|
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,6 @@
|
|
|
1
|
+
export declare function pickBy<T extends {
|
|
2
|
+
[s: string]: T[keyof T];
|
|
3
|
+
} | ArrayLike<T[keyof T]>>(obj: T, fn: (i: T[keyof T]) => boolean): Partial<T>;
|
|
1
4
|
export declare function compact<T>(a: (T | undefined)[]): T[];
|
|
2
5
|
export declare function uniqBy<T>(arr: T[], fn: (cur: T) => any): T[];
|
|
3
6
|
type SortTypes = string | number | undefined | boolean;
|
|
@@ -7,4 +10,9 @@ export declare function isProd(): boolean;
|
|
|
7
10
|
export declare function maxBy<T>(arr: T[], fn: (i: T) => number): T | undefined;
|
|
8
11
|
export declare function sumBy<T>(arr: T[], fn: (i: T) => number): number;
|
|
9
12
|
export declare function capitalize(s: string): string;
|
|
13
|
+
export declare const dirExists: (input: string) => Promise<string>;
|
|
14
|
+
export declare const fileExists: (input: string) => Promise<string>;
|
|
15
|
+
export declare function isTruthy(input: string): boolean;
|
|
16
|
+
export declare function isNotFalsy(input: string): boolean;
|
|
17
|
+
export declare function requireJson<T>(...pathParts: string[]): T;
|
|
10
18
|
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.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,35 @@ 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', 'TRUE', '1', 'yes', 'YES', 'y', 'Y'].includes(input);
|
|
98
|
+
}
|
|
99
|
+
exports.isTruthy = isTruthy;
|
|
100
|
+
function isNotFalsy(input) {
|
|
101
|
+
return !['false', 'FALSE', '0', 'no', 'NO', 'n', 'N'].includes(input);
|
|
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;
|
package/package.json
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oclif/core",
|
|
3
3
|
"description": "base library for oclif CLIs",
|
|
4
|
-
"version": "2.0.1",
|
|
4
|
+
"version": "2.0.2-beta.1",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"bugs": "https://github.com/oclif/core/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@oclif/linewrap": "^1.0.0",
|
|
9
|
-
"@oclif/screen": "^3.0.4",
|
|
10
8
|
"ansi-escapes": "^4.3.2",
|
|
11
9
|
"ansi-styles": "^4.3.0",
|
|
12
10
|
"cardinal": "^2.1.1",
|
|
@@ -32,6 +30,7 @@
|
|
|
32
30
|
"supports-hyperlinks": "^2.2.0",
|
|
33
31
|
"tslib": "^2.4.1",
|
|
34
32
|
"widest-line": "^3.1.0",
|
|
33
|
+
"wordwrap": "^1.0.0",
|
|
35
34
|
"wrap-ansi": "^7.0.0"
|
|
36
35
|
},
|
|
37
36
|
"devDependencies": {
|
|
@@ -57,6 +56,7 @@
|
|
|
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",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"lint": "eslint . --ext .ts --config .eslintrc",
|
|
110
110
|
"posttest": "yarn lint",
|
|
111
111
|
"prepack": "yarn run build",
|
|
112
|
-
"test": "mocha
|
|
112
|
+
"test": "mocha \"test/**/*.test.ts\"",
|
|
113
113
|
"test:e2e": "mocha \"test/**/*.e2e.ts\" --timeout 1200000",
|
|
114
114
|
"pretest": "yarn build --noEmit && tsc -p test --noEmit --skipLibCheck"
|
|
115
115
|
},
|
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
|
-
};
|
package/lib/cli-ux/open.d.ts
DELETED
package/lib/cli-ux/open.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
// this code is largely taken from opn
|
|
4
|
-
const childProcess = require("child_process");
|
|
5
|
-
const isWsl = require('is-wsl');
|
|
6
|
-
function open(target, opts = {}) {
|
|
7
|
-
// opts = {wait: true, ...opts}
|
|
8
|
-
let cmd;
|
|
9
|
-
let appArgs = [];
|
|
10
|
-
let args = [];
|
|
11
|
-
const cpOpts = {};
|
|
12
|
-
if (Array.isArray(opts.app)) {
|
|
13
|
-
appArgs = opts.app.slice(1);
|
|
14
|
-
opts.app = opts.app[0];
|
|
15
|
-
}
|
|
16
|
-
if (process.platform === 'darwin') {
|
|
17
|
-
cmd = 'open';
|
|
18
|
-
// if (opts.wait) {
|
|
19
|
-
// args.push('-W')
|
|
20
|
-
// }
|
|
21
|
-
if (opts.app) {
|
|
22
|
-
args.push('-a', opts.app);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
else if (process.platform === 'win32' || isWsl) {
|
|
26
|
-
cmd = 'cmd' + (isWsl ? '.exe' : '');
|
|
27
|
-
args.push('/c', 'start', '""', '/b');
|
|
28
|
-
target = target.replace(/&/g, '^&');
|
|
29
|
-
// if (opts.wait) {
|
|
30
|
-
// args.push('/wait')
|
|
31
|
-
// }
|
|
32
|
-
if (opts.app) {
|
|
33
|
-
args.push(opts.app);
|
|
34
|
-
}
|
|
35
|
-
if (appArgs.length > 0) {
|
|
36
|
-
args = [...args, ...appArgs];
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
cmd = opts.app ? opts.app : 'xdg-open';
|
|
41
|
-
if (appArgs.length > 0) {
|
|
42
|
-
args = [...args, ...appArgs];
|
|
43
|
-
}
|
|
44
|
-
// if (!opts.wait) {
|
|
45
|
-
// `xdg-open` will block the process unless
|
|
46
|
-
// stdio is ignored and it's detached from the parent
|
|
47
|
-
// even if it's unref'd
|
|
48
|
-
cpOpts.stdio = 'ignore';
|
|
49
|
-
cpOpts.detached = true;
|
|
50
|
-
// }
|
|
51
|
-
}
|
|
52
|
-
args.push(target);
|
|
53
|
-
if (process.platform === 'darwin' && appArgs.length > 0) {
|
|
54
|
-
args.push('--args');
|
|
55
|
-
args = [...args, ...appArgs];
|
|
56
|
-
}
|
|
57
|
-
const cp = childProcess.spawn(cmd, args, cpOpts);
|
|
58
|
-
return new Promise((resolve, reject) => {
|
|
59
|
-
cp.once('error', reject);
|
|
60
|
-
cp.once('close', code => {
|
|
61
|
-
if (Number.isInteger(code) && code > 0) {
|
|
62
|
-
reject(new Error('Exited with code ' + code));
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
resolve(cp);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
exports.default = open;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// `loadHelpClass` tests require an oclif project for testing so
|
|
3
|
-
// it is re-using the setup here to be able to do a lookup for
|
|
4
|
-
// this sample help class file in tests, although it is not needed
|
|
5
|
-
// for ../help itself.
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const _1 = require(".");
|
|
8
|
-
class default_1 extends _1.HelpBase {
|
|
9
|
-
async showHelp() {
|
|
10
|
-
console.log('help');
|
|
11
|
-
}
|
|
12
|
-
async showCommandHelp() {
|
|
13
|
-
console.log('command help');
|
|
14
|
-
}
|
|
15
|
-
getCommandHelpForReadme() {
|
|
16
|
-
return 'help for readme';
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
exports.default = default_1;
|