@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.
Files changed (90) hide show
  1. package/README.md +5 -5
  2. package/lib/args.d.ts +39 -0
  3. package/lib/args.js +62 -0
  4. package/lib/cli-ux/action/base.d.ts +1 -1
  5. package/lib/cli-ux/action/pride-spinner.js +0 -1
  6. package/lib/cli-ux/action/spinner.js +10 -11
  7. package/lib/cli-ux/action/spinners.d.ts +251 -0
  8. package/lib/cli-ux/action/spinners.js +2 -1
  9. package/lib/cli-ux/config.d.ts +1 -1
  10. package/lib/cli-ux/config.js +7 -5
  11. package/lib/cli-ux/index.d.ts +51 -29
  12. package/lib/cli-ux/index.js +111 -69
  13. package/lib/cli-ux/list.js +3 -4
  14. package/lib/cli-ux/prompt.js +9 -8
  15. package/lib/cli-ux/styled/header.js +1 -1
  16. package/lib/cli-ux/styled/index.d.ts +7 -0
  17. package/lib/cli-ux/styled/index.js +15 -0
  18. package/lib/cli-ux/styled/json.d.ts +1 -1
  19. package/lib/cli-ux/styled/json.js +2 -3
  20. package/lib/cli-ux/styled/object.js +1 -1
  21. package/lib/cli-ux/styled/progress.d.ts +2 -1
  22. package/lib/cli-ux/styled/progress.js +1 -5
  23. package/lib/cli-ux/styled/table.js +1 -3
  24. package/lib/cli-ux/styled/tree.js +0 -1
  25. package/lib/cli-ux/wait.d.ts +1 -1
  26. package/lib/cli-ux/wait.js +0 -1
  27. package/lib/command.d.ts +78 -27
  28. package/lib/command.js +51 -43
  29. package/lib/config/config.d.ts +18 -17
  30. package/lib/config/config.js +46 -22
  31. package/lib/config/index.js +0 -5
  32. package/lib/config/plugin.d.ts +3 -2
  33. package/lib/config/plugin.js +4 -13
  34. package/lib/config/util.js +2 -2
  35. package/lib/errors/index.js +0 -1
  36. package/lib/errors/logger.js +2 -4
  37. package/lib/flags.d.ts +46 -18
  38. package/lib/flags.js +71 -29
  39. package/lib/help/command.d.ts +12 -12
  40. package/lib/help/command.js +6 -6
  41. package/lib/help/docopts.d.ts +3 -3
  42. package/lib/help/docopts.js +2 -3
  43. package/lib/help/formatter.d.ts +4 -3
  44. package/lib/help/index.d.ts +10 -14
  45. package/lib/help/index.js +0 -5
  46. package/lib/help/util.d.ts +3 -3
  47. package/lib/help/util.js +1 -1
  48. package/lib/index.d.ts +6 -5
  49. package/lib/index.js +10 -8
  50. package/lib/interfaces/args.d.ts +22 -0
  51. package/lib/interfaces/{command.js → args.js} +0 -0
  52. package/lib/interfaces/config.d.ts +1 -2
  53. package/lib/interfaces/flags.d.ts +2 -2
  54. package/lib/interfaces/hooks.d.ts +1 -1
  55. package/lib/interfaces/index.d.ts +2 -2
  56. package/lib/interfaces/manifest.d.ts +2 -2
  57. package/lib/interfaces/parser.d.ts +96 -81
  58. package/lib/interfaces/plugin.d.ts +1 -1
  59. package/lib/main.d.ts +54 -1
  60. package/lib/main.js +70 -6
  61. package/lib/parser/errors.d.ts +15 -8
  62. package/lib/parser/errors.js +17 -14
  63. package/lib/parser/help.d.ts +1 -1
  64. package/lib/parser/help.js +4 -9
  65. package/lib/parser/index.d.ts +2 -9
  66. package/lib/parser/index.js +5 -26
  67. package/lib/parser/parse.d.ts +4 -11
  68. package/lib/parser/parse.js +108 -72
  69. package/lib/parser/validate.d.ts +1 -1
  70. package/lib/parser/validate.js +6 -3
  71. package/lib/util.d.ts +8 -0
  72. package/lib/util.js +44 -1
  73. package/package.json +4 -4
  74. package/lib/cli-ux/deps.d.ts +0 -22
  75. package/lib/cli-ux/deps.js +0 -47
  76. package/lib/cli-ux/open.d.ts +0 -6
  77. package/lib/cli-ux/open.js +0 -69
  78. package/lib/help/_test-help-class.d.ts +0 -6
  79. package/lib/help/_test-help-class.js +0 -19
  80. package/lib/interfaces/command.d.ts +0 -110
  81. package/lib/parser/args.d.ts +0 -5
  82. package/lib/parser/args.js +0 -11
  83. package/lib/parser/deps.d.ts +0 -4
  84. package/lib/parser/deps.js +0 -17
  85. package/lib/parser/flags.d.ts +0 -60
  86. package/lib/parser/flags.js +0 -107
  87. package/lib/parser/list.d.ts +0 -2
  88. package/lib/parser/list.js +0 -29
  89. package/lib/parser/util.d.ts +0 -7
  90. package/lib/parser/util.js +0 -50
@@ -1,5 +1,5 @@
1
- import { ParserInput, OutputFlags, ParsingToken, OutputArgs } from '../interfaces';
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 _argv;
15
+ private _args;
23
16
  private _debugOutput;
24
17
  private _debugInput;
25
18
  private get _argTokens();
@@ -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
- const deps_1 = require("./deps");
6
- // eslint-disable-next-line new-cap
7
- const m = (0, deps_1.default)()
8
- // eslint-disable-next-line node/no-missing-require
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
- let result;
23
- if (stdin.isTTY || stdin.isTTY === undefined)
24
- return result;
25
- result = '';
26
- stdin.setEncoding('utf8');
27
- for await (const chunk of stdin) {
28
- result += chunk;
29
- }
30
- return result;
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 m.errors.CLIError(`Flag --${name} expects a value`);
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
- // not actually a flag if it reaches here so parse as an arg
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
- if (arg)
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._argv();
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
- args,
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
- _args(argv) {
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 m.errors.CLIError(`Unexpected flag ${token.flag}`);
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
- // eslint-disable-next-line no-await-in-loop
167
- const value = flag.parse ? await flag.parse(input, this.context, flag) : input;
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(...(Array.isArray(value) ? value : [value]));
194
+ flags[token.flag].push(...values);
171
195
  }
172
196
  else {
173
- flags[token.flag] = value;
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 ? ['true', 'TRUE', '1', 'yes', 'YES', 'y', 'Y'].includes(input) : false;
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 m.errors.FlagInvalidOptionError(flag, input);
235
+ throw new errors_1.FlagInvalidOptionError(flag, input);
207
236
  }
208
- async _argv() {
209
- const args = [];
237
+ async _args() {
238
+ const argv = [];
239
+ const args = {};
210
240
  const tokens = this._argTokens;
211
241
  let stdinRead = false;
212
- for (let i = 0; i < Math.max(this.input.args.length, tokens.length); i++) {
213
- const token = tokens[i];
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
- if (arg.options && !arg.options.includes(token.input)) {
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
- args[i] = stdin;
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[i] && arg?.default !== undefined) {
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
- args[i] = f;
265
+ argv.push(f);
266
+ args[name] = f;
241
267
  }
242
268
  else {
243
- args[i] = arg.default;
269
+ argv.push(arg.default);
270
+ args[name] = arg.default;
244
271
  }
245
272
  }
246
273
  }
247
- return args;
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
- if (this.input.args.length > 0) {
263
- debug('available args: %s', this.input.args.map(a => a.name).join(' '));
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;
@@ -1,4 +1,4 @@
1
- import { ParserInput, ParserOutput } from '../interfaces';
1
+ import { ParserInput, ParserOutput } from '../interfaces/parser';
2
2
  export declare function validate(parse: {
3
3
  input: ParserInput;
4
4
  output: ParserOutput;
@@ -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
- const maxArgs = parse.input.args.length;
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 [index, arg] of parse.input.args.entries()) {
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.argv[index] && parse.output.argv[index] !== 0) {
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 --forbid-only \"test/**/*.test.ts\"",
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
  },
@@ -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;
@@ -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
- };
@@ -1,6 +0,0 @@
1
- export declare namespace open {
2
- type Options = {
3
- app?: string | string[];
4
- };
5
- }
6
- export default function open(target: string, opts?: open.Options): Promise<unknown>;
@@ -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,6 +0,0 @@
1
- import { HelpBase } from '.';
2
- export default class extends HelpBase {
3
- showHelp(): Promise<void>;
4
- showCommandHelp(): Promise<void>;
5
- getCommandHelpForReadme(): string;
6
- }
@@ -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;