@oclif/core 3.0.0-beta.2 → 3.0.0-beta.21

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 (112) hide show
  1. package/README.md +10 -6
  2. package/flush.js +1 -1
  3. package/handle.js +1 -1
  4. package/lib/args.d.ts +1 -1
  5. package/lib/args.js +17 -18
  6. package/lib/cli-ux/action/base.d.ts +3 -5
  7. package/lib/cli-ux/action/base.js +32 -26
  8. package/lib/cli-ux/action/simple.js +13 -18
  9. package/lib/cli-ux/action/spinner.d.ts +4 -2
  10. package/lib/cli-ux/action/spinner.js +27 -19
  11. package/lib/cli-ux/action/spinners.js +1 -1
  12. package/lib/cli-ux/action/types.d.ts +5 -0
  13. package/lib/cli-ux/action/types.js +2 -0
  14. package/lib/cli-ux/config.d.ts +0 -1
  15. package/lib/cli-ux/config.js +17 -21
  16. package/lib/cli-ux/exit.d.ts +1 -1
  17. package/lib/cli-ux/exit.js +4 -1
  18. package/lib/cli-ux/flush.d.ts +1 -0
  19. package/lib/cli-ux/flush.js +28 -0
  20. package/lib/cli-ux/index.d.ts +10 -30
  21. package/lib/cli-ux/index.js +32 -75
  22. package/lib/cli-ux/list.js +3 -3
  23. package/lib/cli-ux/prompt.js +32 -22
  24. package/lib/cli-ux/stream.js +1 -0
  25. package/lib/cli-ux/styled/index.d.ts +5 -6
  26. package/lib/cli-ux/styled/index.js +11 -11
  27. package/lib/cli-ux/styled/json.js +8 -5
  28. package/lib/cli-ux/styled/object.js +7 -9
  29. package/lib/cli-ux/styled/table.d.ts +4 -4
  30. package/lib/cli-ux/styled/table.js +61 -64
  31. package/lib/cli-ux/styled/tree.js +1 -3
  32. package/lib/cli-ux/wait.js +3 -5
  33. package/lib/command.d.ts +15 -19
  34. package/lib/command.js +117 -96
  35. package/lib/config/config.d.ts +16 -23
  36. package/lib/config/config.js +180 -334
  37. package/lib/config/index.d.ts +1 -1
  38. package/lib/config/index.js +1 -2
  39. package/lib/config/plugin-loader.d.ts +30 -0
  40. package/lib/config/plugin-loader.js +145 -0
  41. package/lib/config/plugin.d.ts +6 -11
  42. package/lib/config/plugin.js +112 -78
  43. package/lib/config/ts-node.d.ts +2 -1
  44. package/lib/config/ts-node.js +64 -51
  45. package/lib/config/util.d.ts +1 -11
  46. package/lib/config/util.js +6 -59
  47. package/lib/errors/config.js +1 -1
  48. package/lib/errors/errors/cli.d.ts +1 -1
  49. package/lib/errors/errors/cli.js +18 -14
  50. package/lib/errors/errors/exit.d.ts +0 -3
  51. package/lib/errors/errors/exit.js +1 -1
  52. package/lib/errors/errors/module-load.d.ts +0 -3
  53. package/lib/errors/errors/module-load.js +1 -1
  54. package/lib/errors/errors/pretty-print.js +11 -9
  55. package/lib/errors/handle.d.ts +12 -2
  56. package/lib/errors/handle.js +28 -18
  57. package/lib/errors/index.d.ts +2 -2
  58. package/lib/errors/index.js +20 -19
  59. package/lib/errors/logger.js +9 -8
  60. package/lib/execute.d.ts +49 -0
  61. package/lib/execute.js +63 -0
  62. package/lib/flags.d.ts +102 -31
  63. package/lib/flags.js +81 -46
  64. package/lib/help/command.d.ts +2 -0
  65. package/lib/help/command.js +68 -53
  66. package/lib/help/docopts.js +9 -13
  67. package/lib/help/formatter.d.ts +1 -1
  68. package/lib/help/formatter.js +35 -24
  69. package/lib/help/index.d.ts +7 -3
  70. package/lib/help/index.js +77 -55
  71. package/lib/help/root.js +7 -9
  72. package/lib/help/util.d.ts +1 -7
  73. package/lib/help/util.js +8 -28
  74. package/lib/index.d.ts +19 -18
  75. package/lib/index.js +36 -48
  76. package/lib/interfaces/config.d.ts +30 -30
  77. package/lib/interfaces/errors.d.ts +1 -1
  78. package/lib/interfaces/hooks.d.ts +3 -3
  79. package/lib/interfaces/index.d.ts +14 -14
  80. package/lib/interfaces/parser.d.ts +188 -116
  81. package/lib/interfaces/pjson.d.ts +2 -1
  82. package/lib/interfaces/plugin.d.ts +10 -1
  83. package/lib/main.d.ts +0 -48
  84. package/lib/main.js +11 -66
  85. package/lib/module-loader.d.ts +68 -79
  86. package/lib/module-loader.js +183 -150
  87. package/lib/parser/errors.d.ts +3 -3
  88. package/lib/parser/errors.js +17 -10
  89. package/lib/parser/help.js +5 -5
  90. package/lib/parser/parse.d.ts +3 -0
  91. package/lib/parser/parse.js +114 -115
  92. package/lib/parser/validate.js +45 -25
  93. package/lib/performance.d.ts +5 -1
  94. package/lib/performance.js +40 -19
  95. package/lib/util/aggregate-flags.d.ts +2 -0
  96. package/lib/util/aggregate-flags.js +13 -0
  97. package/lib/util/cache-command.d.ts +3 -0
  98. package/lib/util/cache-command.js +109 -0
  99. package/lib/util/cache-default-value.d.ts +2 -0
  100. package/lib/util/cache-default-value.js +28 -0
  101. package/lib/util/ensure-arg-object.d.ts +12 -0
  102. package/lib/util/ensure-arg-object.js +14 -0
  103. package/lib/util/fs.d.ts +7 -0
  104. package/lib/util/fs.js +54 -0
  105. package/lib/util/os.d.ts +19 -0
  106. package/lib/util/os.js +28 -0
  107. package/lib/{util.d.ts → util/util.d.ts} +6 -15
  108. package/lib/util/util.js +98 -0
  109. package/package.json +32 -34
  110. package/lib/cli-ux/action/pride-spinner.d.ts +0 -4
  111. package/lib/cli-ux/action/pride-spinner.js +0 -30
  112. package/lib/util.js +0 -126
@@ -1,13 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Performance = void 0;
4
- const perf_hooks_1 = require("perf_hooks");
4
+ const node_perf_hooks_1 = require("node:perf_hooks");
5
5
  const settings_1 = require("./settings");
6
6
  class Marker {
7
+ name;
8
+ details;
9
+ module;
10
+ method;
11
+ scope;
12
+ stopped = false;
13
+ startMarker;
14
+ stopMarker;
7
15
  constructor(name, details = {}) {
8
16
  this.name = name;
9
17
  this.details = details;
10
- this.stopped = false;
11
18
  this.startMarker = `${this.name}-start`;
12
19
  this.stopMarker = `${this.name}-stop`;
13
20
  const [caller, scope] = name.split('#');
@@ -15,20 +22,23 @@ class Marker {
15
22
  this.module = module;
16
23
  this.method = method;
17
24
  this.scope = scope;
18
- perf_hooks_1.performance.mark(this.startMarker);
25
+ node_perf_hooks_1.performance.mark(this.startMarker);
19
26
  }
20
27
  addDetails(details) {
21
28
  this.details = { ...this.details, ...details };
22
29
  }
23
30
  stop() {
24
31
  this.stopped = true;
25
- perf_hooks_1.performance.mark(this.stopMarker);
32
+ node_perf_hooks_1.performance.mark(this.stopMarker);
26
33
  }
27
34
  measure() {
28
- perf_hooks_1.performance.measure(this.name, this.startMarker, this.stopMarker);
35
+ node_perf_hooks_1.performance.measure(this.name, this.startMarker, this.stopMarker);
29
36
  }
30
37
  }
31
38
  class Performance {
39
+ static markers = {};
40
+ static _results = [];
41
+ static _highlights;
32
42
  static get enabled() {
33
43
  return settings_1.settings.performanceEnabled ?? false;
34
44
  }
@@ -40,7 +50,7 @@ class Performance {
40
50
  throw new Error('Perf results not available. Did you forget to call await Performance.collect()?');
41
51
  }
42
52
  static getResult(name) {
43
- return Performance.results.find(r => r.name === name);
53
+ return Performance.results.find((r) => r.name === name);
44
54
  }
45
55
  static get highlights() {
46
56
  if (!Performance.enabled)
@@ -76,11 +86,11 @@ class Performance {
76
86
  const markers = Object.values(Performance.markers);
77
87
  if (markers.length === 0)
78
88
  return;
79
- for (const marker of markers.filter(m => !m.stopped)) {
89
+ for (const marker of markers.filter((m) => !m.stopped)) {
80
90
  marker.stop();
81
91
  }
82
- return new Promise(resolve => {
83
- const perfObserver = new perf_hooks_1.PerformanceObserver(items => {
92
+ return new Promise((resolve) => {
93
+ const perfObserver = new node_perf_hooks_1.PerformanceObserver((items) => {
84
94
  for (const entry of items.getEntries()) {
85
95
  if (Performance.markers[entry.name]) {
86
96
  const marker = Performance.markers[entry.name];
@@ -94,12 +104,15 @@ class Performance {
94
104
  });
95
105
  }
96
106
  }
97
- const command = Performance.results.find(r => r.name.startsWith('config.runCommand'));
98
- const commandLoadTime = command ? Performance.getResult(`plugin.findCommand#${command.details.plugin}.${command.details.command}`)?.duration ?? 0 : 0;
107
+ const command = Performance.results.find((r) => r.name.startsWith('config.runCommand'));
108
+ const commandLoadTime = command
109
+ ? Performance.getResult(`plugin.findCommand#${command.details.plugin}.${command.details.command}`)
110
+ ?.duration ?? 0
111
+ : 0;
99
112
  const pluginLoadTimes = Object.fromEntries(Performance.results
100
113
  .filter(({ name }) => name.startsWith('plugin.load#'))
101
114
  .sort((a, b) => b.duration - a.duration)
102
- .map(({ scope, duration }) => [scope, duration]));
115
+ .map(({ scope, duration, details }) => [scope, { duration, details }]));
103
116
  const hookRunTimes = Performance.results
104
117
  .filter(({ name }) => name.startsWith('config.runHook#'))
105
118
  .reduce((acc, perfResult) => {
@@ -121,10 +134,12 @@ class Performance {
121
134
  .filter(({ name }) => name.startsWith('config.loadPlugins#'))
122
135
  .sort((a, b) => b.duration - a.duration)
123
136
  .map(({ scope, duration }) => [scope, duration]));
137
+ const commandRunTime = Performance.results.find(({ name }) => name.startsWith('config.runCommand#'))?.duration ?? 0;
124
138
  Performance._highlights = {
125
139
  configLoadTime: Performance.getResult('config.load')?.duration ?? 0,
126
140
  runTime: Performance.getResult('main.run')?.duration ?? 0,
127
141
  initTime: Performance.getResult('main.run#init')?.duration ?? 0,
142
+ commandRunTime,
128
143
  commandLoadTime,
129
144
  pluginLoadTimes,
130
145
  hookRunTimes,
@@ -143,7 +158,7 @@ class Performance {
143
158
  // ignore
144
159
  }
145
160
  }
146
- perf_hooks_1.performance.clearMarks();
161
+ node_perf_hooks_1.performance.clearMarks();
147
162
  });
148
163
  }
149
164
  /**
@@ -154,16 +169,22 @@ class Performance {
154
169
  if (!Performance.enabled)
155
170
  return;
156
171
  const debug = require('debug')('perf');
172
+ debug('Total Time: %sms', Performance.highlights.runTime.toFixed(4));
157
173
  debug('Init Time: %sms', Performance.highlights.initTime.toFixed(4));
158
174
  debug('Config Load Time: %sms', Performance.highlights.configLoadTime.toFixed(4));
159
- debug('Command Load Time: %sms', Performance.highlights.commandLoadTime.toFixed(4));
160
- debug('Execution Time: %sms', Performance.highlights.runTime.toFixed(4));
175
+ debug(' Plugins Load Time: %sms', Performance.getResult('config.loadAllPlugins')?.duration.toFixed(4) ?? 0);
176
+ debug(' Commands Load Time: %sms', Performance.getResult('config.loadAllCommands')?.duration.toFixed(4) ?? 0);
161
177
  debug('Core Plugin Load Time: %sms', Performance.highlights.corePluginsLoadTime.toFixed(4));
162
178
  debug('User Plugin Load Time: %sms', Performance.highlights.userPluginsLoadTime.toFixed(4));
163
179
  debug('Linked Plugin Load Time: %sms', Performance.highlights.linkedPluginsLoadTime.toFixed(4));
164
180
  debug('Plugin Load Times:');
165
- for (const [plugin, duration] of Object.entries(Performance.highlights.pluginLoadTimes)) {
166
- debug(` ${plugin}: ${duration.toFixed(4)}ms`);
181
+ for (const [plugin, result] of Object.entries(Performance.highlights.pluginLoadTimes)) {
182
+ if (result.details.hasManifest) {
183
+ debug(` ${plugin}: ${result.duration.toFixed(4)}ms`);
184
+ }
185
+ else {
186
+ debug(` ${plugin}: ${result.duration.toFixed(4)}ms (no manifest!)`);
187
+ }
167
188
  }
168
189
  debug('Hook Run Times:');
169
190
  for (const [event, runTimes] of Object.entries(Performance.highlights.hookRunTimes)) {
@@ -172,8 +193,8 @@ class Performance {
172
193
  debug(` ${plugin}: ${duration.toFixed(4)}ms`);
173
194
  }
174
195
  }
196
+ debug('Command Load Time: %sms', Performance.highlights.commandLoadTime.toFixed(4));
197
+ debug('Command Run Time: %sms', Performance.highlights.commandRunTime.toFixed(4));
175
198
  }
176
199
  }
177
200
  exports.Performance = Performance;
178
- Performance.markers = {};
179
- Performance._results = [];
@@ -0,0 +1,2 @@
1
+ import { FlagInput, FlagOutput } from '../interfaces/parser';
2
+ export declare function aggregateFlags<F extends FlagOutput, B extends FlagOutput>(flags: FlagInput<F> | undefined, baseFlags: FlagInput<B> | undefined, enableJsonFlag: boolean | undefined): FlagInput<F>;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.aggregateFlags = void 0;
4
+ const flags_1 = require("../flags");
5
+ const json = (0, flags_1.boolean)({
6
+ description: 'Format output as json.',
7
+ helpGroup: 'GLOBAL',
8
+ });
9
+ function aggregateFlags(flags, baseFlags, enableJsonFlag) {
10
+ const combinedFlags = { ...baseFlags, ...flags };
11
+ return (enableJsonFlag ? { json, ...combinedFlags } : combinedFlags);
12
+ }
13
+ exports.aggregateFlags = aggregateFlags;
@@ -0,0 +1,3 @@
1
+ import { Command } from '../command';
2
+ import { Plugin as IPlugin } from '../interfaces/plugin';
3
+ export declare function cacheCommand(uncachedCmd: Command.Class, plugin?: IPlugin, respectNoCacheDefault?: boolean): Promise<Command.Cached>;
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cacheCommand = void 0;
4
+ const aggregate_flags_1 = require("./aggregate-flags");
5
+ const cache_default_value_1 = require("./cache-default-value");
6
+ const ensure_arg_object_1 = require("./ensure-arg-object");
7
+ const util_1 = require("./util");
8
+ // In order to collect static properties up the inheritance chain, we need to recursively
9
+ // access the prototypes until there's nothing left. This allows us to combine baseFlags
10
+ // and flags as well as add in the json flag if enableJsonFlag is enabled.
11
+ function mergePrototype(result, cmd) {
12
+ const proto = Object.getPrototypeOf(cmd);
13
+ const filteredProto = (0, util_1.pickBy)(proto, (v) => v !== undefined);
14
+ return Object.keys(proto).length > 0 ? mergePrototype({ ...filteredProto, ...result }, proto) : result;
15
+ }
16
+ async function cacheFlags(cmdFlags, respectNoCacheDefault) {
17
+ const promises = Object.entries(cmdFlags).map(async ([name, flag]) => [
18
+ name,
19
+ {
20
+ name,
21
+ char: flag.char,
22
+ summary: flag.summary,
23
+ hidden: flag.hidden,
24
+ required: flag.required,
25
+ helpLabel: flag.helpLabel,
26
+ helpGroup: flag.helpGroup,
27
+ description: flag.description,
28
+ dependsOn: flag.dependsOn,
29
+ relationships: flag.relationships,
30
+ exclusive: flag.exclusive,
31
+ deprecated: flag.deprecated,
32
+ deprecateAliases: flag.deprecateAliases,
33
+ aliases: flag.aliases,
34
+ charAliases: flag.charAliases,
35
+ noCacheDefault: flag.noCacheDefault,
36
+ ...(flag.type === 'boolean'
37
+ ? {
38
+ allowNo: flag.allowNo,
39
+ type: flag.type,
40
+ }
41
+ : {
42
+ type: flag.type,
43
+ helpValue: flag.helpValue,
44
+ multiple: flag.multiple,
45
+ options: flag.options,
46
+ delimiter: flag.delimiter,
47
+ default: await (0, cache_default_value_1.cacheDefaultValue)(flag, respectNoCacheDefault),
48
+ hasDynamicHelp: typeof flag.defaultHelp === 'function',
49
+ }),
50
+ },
51
+ ]);
52
+ return Object.fromEntries(await Promise.all(promises));
53
+ }
54
+ async function cacheArgs(cmdArgs, respectNoCacheDefault) {
55
+ const promises = Object.entries(cmdArgs).map(async ([name, arg]) => [
56
+ name,
57
+ {
58
+ name,
59
+ description: arg.description,
60
+ required: arg.required,
61
+ options: arg.options,
62
+ default: await (0, cache_default_value_1.cacheDefaultValue)(arg, respectNoCacheDefault),
63
+ hidden: arg.hidden,
64
+ noCacheDefault: arg.noCacheDefault,
65
+ },
66
+ ]);
67
+ return Object.fromEntries(await Promise.all(promises));
68
+ }
69
+ async function cacheCommand(uncachedCmd, plugin, respectNoCacheDefault = false) {
70
+ const cmd = mergePrototype(uncachedCmd, uncachedCmd);
71
+ const flags = await cacheFlags((0, aggregate_flags_1.aggregateFlags)(cmd.flags, cmd.baseFlags, cmd.enableJsonFlag), respectNoCacheDefault);
72
+ const args = await cacheArgs((0, ensure_arg_object_1.ensureArgObject)(cmd.args), respectNoCacheDefault);
73
+ const stdProperties = {
74
+ id: cmd.id,
75
+ summary: cmd.summary,
76
+ description: cmd.description,
77
+ strict: cmd.strict,
78
+ usage: cmd.usage,
79
+ pluginName: plugin && plugin.name,
80
+ pluginAlias: plugin && plugin.alias,
81
+ pluginType: plugin && plugin.type,
82
+ hidden: cmd.hidden,
83
+ state: cmd.state,
84
+ aliases: cmd.aliases || [],
85
+ examples: cmd.examples || cmd.example,
86
+ deprecationOptions: cmd.deprecationOptions,
87
+ deprecateAliases: cmd.deprecateAliases,
88
+ flags,
89
+ args,
90
+ hasDynamicHelp: Object.values(flags).some((f) => f.hasDynamicHelp),
91
+ };
92
+ // do not include these properties in manifest
93
+ const ignoreCommandProperties = [
94
+ 'plugin',
95
+ '_flags',
96
+ '_enableJsonFlag',
97
+ '_globalFlags',
98
+ '_baseFlags',
99
+ 'baseFlags',
100
+ '_--',
101
+ '_base',
102
+ ];
103
+ // Add in any additional properties that are not standard command properties.
104
+ const stdKeysAndIgnored = new Set([...Object.keys(stdProperties), ...ignoreCommandProperties]);
105
+ const keysToAdd = Object.keys(cmd).filter((property) => !stdKeysAndIgnored.has(property));
106
+ const additionalProperties = Object.fromEntries(keysToAdd.map((key) => [key, cmd[key]]));
107
+ return { ...stdProperties, ...additionalProperties };
108
+ }
109
+ exports.cacheCommand = cacheCommand;
@@ -0,0 +1,2 @@
1
+ import { Arg, OptionFlag } from '../interfaces/parser';
2
+ export declare const cacheDefaultValue: (flagOrArg: OptionFlag<any> | Arg<any>, respectNoCacheDefault: boolean) => Promise<any>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cacheDefaultValue = void 0;
4
+ // when no manifest exists, the default is calculated. This may throw, so we need to catch it
5
+ const cacheDefaultValue = async (flagOrArg, respectNoCacheDefault) => {
6
+ if (respectNoCacheDefault && flagOrArg.noCacheDefault)
7
+ return;
8
+ // Prefer the defaultHelp function (returns a friendly string for complex types)
9
+ if (typeof flagOrArg.defaultHelp === 'function') {
10
+ try {
11
+ return await flagOrArg.defaultHelp({ options: flagOrArg, flags: {} });
12
+ }
13
+ catch {
14
+ return;
15
+ }
16
+ }
17
+ // if not specified, try the default function
18
+ if (typeof flagOrArg.default === 'function') {
19
+ try {
20
+ return await flagOrArg.default({ options: flagOrArg, flags: {} });
21
+ }
22
+ catch { }
23
+ }
24
+ else {
25
+ return flagOrArg.default;
26
+ }
27
+ };
28
+ exports.cacheDefaultValue = cacheDefaultValue;
@@ -0,0 +1,12 @@
1
+ import { ArgInput } from '../interfaces/parser';
2
+ import { Command } from '../command';
3
+ /**
4
+ * Ensure that the provided args are an object. This is for backwards compatibility with v1 commands which
5
+ * defined args as an array.
6
+ *
7
+ * @param args Either an array of args or an object of args
8
+ * @returns ArgInput
9
+ */
10
+ export declare function ensureArgObject(args?: any[] | ArgInput | {
11
+ [name: string]: Command.Arg.Cached;
12
+ }): ArgInput;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureArgObject = void 0;
4
+ /**
5
+ * Ensure that the provided args are an object. This is for backwards compatibility with v1 commands which
6
+ * defined args as an array.
7
+ *
8
+ * @param args Either an array of args or an object of args
9
+ * @returns ArgInput
10
+ */
11
+ function ensureArgObject(args) {
12
+ return (Array.isArray(args) ? (args ?? []).reduce((x, y) => ({ ...x, [y.name]: y }), {}) : args ?? {});
13
+ }
14
+ exports.ensureArgObject = ensureArgObject;
@@ -0,0 +1,7 @@
1
+ export declare function requireJson<T>(...pathParts: string[]): T;
2
+ export declare function exists(path: string): Promise<boolean>;
3
+ export declare const dirExists: (input: string) => Promise<string>;
4
+ export declare const fileExists: (input: string) => Promise<string>;
5
+ export declare function readJson<T = unknown>(path: string): Promise<T>;
6
+ export declare function readJsonSync(path: string, parse: false): string;
7
+ export declare function readJsonSync<T = unknown>(path: string, parse?: true): T;
package/lib/util/fs.js ADDED
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readJsonSync = exports.readJson = exports.fileExists = exports.dirExists = exports.exists = exports.requireJson = void 0;
4
+ const promises_1 = require("node:fs/promises");
5
+ const node_path_1 = require("node:path");
6
+ const node_fs_1 = require("node:fs");
7
+ const debug = require('debug');
8
+ function requireJson(...pathParts) {
9
+ return JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(...pathParts), 'utf8'));
10
+ }
11
+ exports.requireJson = requireJson;
12
+ async function exists(path) {
13
+ try {
14
+ await (0, promises_1.access)(path);
15
+ return true;
16
+ }
17
+ catch {
18
+ return false;
19
+ }
20
+ }
21
+ exports.exists = exists;
22
+ const dirExists = async (input) => {
23
+ if (!(await exists(input))) {
24
+ throw new Error(`No directory found at ${input}`);
25
+ }
26
+ const fileStat = await (0, promises_1.stat)(input);
27
+ if (!fileStat.isDirectory()) {
28
+ throw new Error(`${input} exists but is not a directory`);
29
+ }
30
+ return input;
31
+ };
32
+ exports.dirExists = dirExists;
33
+ const fileExists = async (input) => {
34
+ if (!(await exists(input))) {
35
+ throw new Error(`No file found at ${input}`);
36
+ }
37
+ const fileStat = await (0, promises_1.stat)(input);
38
+ if (!fileStat.isFile()) {
39
+ throw new Error(`${input} exists but is not a file`);
40
+ }
41
+ return input;
42
+ };
43
+ exports.fileExists = fileExists;
44
+ async function readJson(path) {
45
+ debug('config')('readJson %s', path);
46
+ const contents = await (0, promises_1.readFile)(path, 'utf8');
47
+ return JSON.parse(contents);
48
+ }
49
+ exports.readJson = readJson;
50
+ function readJsonSync(path, parse = true) {
51
+ const contents = (0, node_fs_1.readFileSync)(path, 'utf8');
52
+ return parse ? JSON.parse(contents) : contents;
53
+ }
54
+ exports.readJsonSync = readJsonSync;
@@ -0,0 +1,19 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * Call os.homedir() and return the result
4
+ *
5
+ * Wrapping this allows us to stub these in tests since os.homedir() is
6
+ * non-configurable and non-writable.
7
+ *
8
+ * @returns The user's home directory
9
+ */
10
+ export declare function getHomeDir(): string;
11
+ /**
12
+ * Call os.platform() and return the result
13
+ *
14
+ * Wrapping this allows us to stub these in tests since os.platform() is
15
+ * non-configurable and non-writable.
16
+ *
17
+ * @returns The process' platform
18
+ */
19
+ export declare function getPlatform(): NodeJS.Platform;
package/lib/util/os.js ADDED
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPlatform = exports.getHomeDir = void 0;
4
+ const node_os_1 = require("node:os");
5
+ /**
6
+ * Call os.homedir() and return the result
7
+ *
8
+ * Wrapping this allows us to stub these in tests since os.homedir() is
9
+ * non-configurable and non-writable.
10
+ *
11
+ * @returns The user's home directory
12
+ */
13
+ function getHomeDir() {
14
+ return (0, node_os_1.homedir)();
15
+ }
16
+ exports.getHomeDir = getHomeDir;
17
+ /**
18
+ * Call os.platform() and return the result
19
+ *
20
+ * Wrapping this allows us to stub these in tests since os.platform() is
21
+ * non-configurable and non-writable.
22
+ *
23
+ * @returns The process' platform
24
+ */
25
+ function getPlatform() {
26
+ return (0, node_os_1.platform)();
27
+ }
28
+ exports.getPlatform = getPlatform;
@@ -1,5 +1,3 @@
1
- import { Command } from './command';
2
- import { ArgInput } from './interfaces/parser';
3
1
  export declare function pickBy<T extends {
4
2
  [s: string]: T[keyof T];
5
3
  } | ArrayLike<T[keyof T]>>(obj: T, fn: (i: T[keyof T]) => boolean): Partial<T>;
@@ -13,19 +11,12 @@ export declare function isProd(): boolean;
13
11
  export declare function maxBy<T>(arr: T[], fn: (i: T) => number): T | undefined;
14
12
  export declare function sumBy<T>(arr: T[], fn: (i: T) => number): number;
15
13
  export declare function capitalize(s: string): string;
16
- export declare const dirExists: (input: string) => Promise<string>;
17
- export declare const fileExists: (input: string) => Promise<string>;
18
14
  export declare function isTruthy(input: string): boolean;
19
15
  export declare function isNotFalsy(input: string): boolean;
20
- export declare function requireJson<T>(...pathParts: string[]): T;
21
- /**
22
- * Ensure that the provided args are an object. This is for backwards compatibility with v1 commands which
23
- * defined args as an array.
24
- *
25
- * @param args Either an array of args or an object of args
26
- * @returns ArgInput
27
- */
28
- export declare function ensureArgObject(args?: any[] | ArgInput | {
29
- [name: string]: Command.Arg.Cached;
30
- }): ArgInput;
16
+ export declare function uniq<T>(arr: T[]): T[];
17
+ export declare function mapValues<T extends Record<string, any>, TResult>(obj: {
18
+ [P in keyof T]: T[P];
19
+ }, fn: (i: T[keyof T], k: keyof T) => TResult): {
20
+ [P in keyof T]: TResult;
21
+ };
31
22
  export {};
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mapValues = exports.uniq = exports.isNotFalsy = exports.isTruthy = exports.capitalize = exports.sumBy = exports.maxBy = exports.isProd = exports.castArray = exports.sortBy = exports.last = exports.uniqBy = exports.compact = exports.pickBy = void 0;
4
+ function pickBy(obj, fn) {
5
+ return Object.entries(obj).reduce((o, [k, v]) => {
6
+ if (fn(v))
7
+ o[k] = v;
8
+ return o;
9
+ }, {});
10
+ }
11
+ exports.pickBy = pickBy;
12
+ function compact(a) {
13
+ // eslint-disable-next-line unicorn/prefer-native-coercion-functions
14
+ return a.filter((a) => Boolean(a));
15
+ }
16
+ exports.compact = compact;
17
+ function uniqBy(arr, fn) {
18
+ return arr.filter((a, i) => {
19
+ const aVal = fn(a);
20
+ return !arr.find((b, j) => j > i && fn(b) === aVal);
21
+ });
22
+ }
23
+ exports.uniqBy = uniqBy;
24
+ function last(arr) {
25
+ if (!arr)
26
+ return;
27
+ return arr.at(-1);
28
+ }
29
+ exports.last = last;
30
+ function compare(a, b) {
31
+ a = a === undefined ? 0 : a;
32
+ b = b === undefined ? 0 : b;
33
+ if (Array.isArray(a) && Array.isArray(b)) {
34
+ if (a.length === 0 && b.length === 0)
35
+ return 0;
36
+ const diff = compare(a[0], b[0]);
37
+ if (diff !== 0)
38
+ return diff;
39
+ return compare(a.slice(1), b.slice(1));
40
+ }
41
+ if (a < b)
42
+ return -1;
43
+ if (a > b)
44
+ return 1;
45
+ return 0;
46
+ }
47
+ function sortBy(arr, fn) {
48
+ return arr.sort((a, b) => compare(fn(a), fn(b)));
49
+ }
50
+ exports.sortBy = sortBy;
51
+ function castArray(input) {
52
+ if (input === undefined)
53
+ return [];
54
+ return Array.isArray(input) ? input : [input];
55
+ }
56
+ exports.castArray = castArray;
57
+ function isProd() {
58
+ return !['development', 'test'].includes(process.env.NODE_ENV ?? '');
59
+ }
60
+ exports.isProd = isProd;
61
+ function maxBy(arr, fn) {
62
+ if (arr.length === 0) {
63
+ return undefined;
64
+ }
65
+ return arr.reduce((maxItem, i) => {
66
+ const curr = fn(i);
67
+ const max = fn(maxItem);
68
+ return curr > max ? i : maxItem;
69
+ });
70
+ }
71
+ exports.maxBy = maxBy;
72
+ function sumBy(arr, fn) {
73
+ return arr.reduce((sum, i) => sum + fn(i), 0);
74
+ }
75
+ exports.sumBy = sumBy;
76
+ function capitalize(s) {
77
+ return s ? s.charAt(0).toUpperCase() + s.slice(1).toLowerCase() : '';
78
+ }
79
+ exports.capitalize = capitalize;
80
+ function isTruthy(input) {
81
+ return ['true', '1', 'yes', 'y'].includes(input.toLowerCase());
82
+ }
83
+ exports.isTruthy = isTruthy;
84
+ function isNotFalsy(input) {
85
+ return !['false', '0', 'no', 'n'].includes(input.toLowerCase());
86
+ }
87
+ exports.isNotFalsy = isNotFalsy;
88
+ function uniq(arr) {
89
+ return [...new Set(arr)].sort();
90
+ }
91
+ exports.uniq = uniq;
92
+ function mapValues(obj, fn) {
93
+ return Object.entries(obj).reduce((o, [k, v]) => {
94
+ o[k] = fn(v, k);
95
+ return o;
96
+ }, {});
97
+ }
98
+ exports.mapValues = mapValues;