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

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 (81) hide show
  1. package/README.md +9 -7
  2. package/lib/command.d.ts +2 -0
  3. package/lib/command.js +4 -4
  4. package/lib/config/config.d.ts +7 -13
  5. package/lib/config/config.js +85 -139
  6. package/lib/config/index.d.ts +2 -1
  7. package/lib/config/index.js +2 -1
  8. package/lib/config/plugin-loader.d.ts +30 -0
  9. package/lib/config/plugin-loader.js +129 -0
  10. package/lib/config/plugin.d.ts +4 -10
  11. package/lib/config/plugin.js +19 -16
  12. package/lib/config/ts-node.js +2 -2
  13. package/lib/errors/config.js +5 -5
  14. package/lib/errors/handle.d.ts +2 -2
  15. package/lib/errors/handle.js +4 -5
  16. package/lib/errors/index.d.ts +1 -1
  17. package/lib/errors/index.js +1 -1
  18. package/lib/errors/logger.js +3 -3
  19. package/lib/execute.d.ts +49 -0
  20. package/lib/execute.js +62 -0
  21. package/lib/flags.js +6 -4
  22. package/lib/help/index.js +3 -3
  23. package/lib/index.d.ts +9 -7
  24. package/lib/index.js +13 -19
  25. package/lib/interfaces/config.d.ts +25 -26
  26. package/lib/interfaces/parser.d.ts +14 -66
  27. package/lib/interfaces/pjson.d.ts +1 -0
  28. package/lib/interfaces/plugin.d.ts +4 -1
  29. package/lib/main.d.ts +1 -49
  30. package/lib/main.js +7 -62
  31. package/lib/module-loader.d.ts +1 -2
  32. package/lib/module-loader.js +4 -4
  33. package/lib/parser/errors.js +1 -1
  34. package/lib/parser/parse.js +1 -34
  35. package/lib/performance.d.ts +1 -1
  36. package/lib/performance.js +2 -3
  37. package/lib/screen.js +2 -2
  38. package/lib/settings.d.ts +2 -1
  39. package/lib/settings.js +2 -2
  40. package/lib/{cli-ux → ux}/action/base.js +2 -2
  41. package/lib/{cli-ux → ux}/action/spinner.js +1 -1
  42. package/lib/{cli-ux → ux}/config.d.ts +0 -1
  43. package/lib/{cli-ux → ux}/config.js +6 -10
  44. package/lib/{cli-ux → ux}/exit.d.ts +1 -1
  45. package/lib/{cli-ux → ux}/exit.js +1 -1
  46. package/lib/ux/flush.d.ts +1 -0
  47. package/lib/ux/flush.js +27 -0
  48. package/lib/{cli-ux → ux}/index.d.ts +8 -27
  49. package/lib/{cli-ux → ux}/index.js +21 -80
  50. package/lib/{cli-ux → ux}/prompt.js +2 -2
  51. package/lib/{cli-ux → ux}/styled/json.js +3 -3
  52. package/package.json +17 -14
  53. package/flush.d.ts +0 -3
  54. package/flush.js +0 -1
  55. package/handle.js +0 -1
  56. package/lib/cli-ux/action/pride-spinner.d.ts +0 -4
  57. package/lib/cli-ux/action/pride-spinner.js +0 -30
  58. /package/lib/{cli-ux → ux}/action/base.d.ts +0 -0
  59. /package/lib/{cli-ux → ux}/action/simple.d.ts +0 -0
  60. /package/lib/{cli-ux → ux}/action/simple.js +0 -0
  61. /package/lib/{cli-ux → ux}/action/spinner.d.ts +0 -0
  62. /package/lib/{cli-ux → ux}/action/spinners.d.ts +0 -0
  63. /package/lib/{cli-ux → ux}/action/spinners.js +0 -0
  64. /package/lib/{cli-ux → ux}/list.d.ts +0 -0
  65. /package/lib/{cli-ux → ux}/list.js +0 -0
  66. /package/lib/{cli-ux → ux}/prompt.d.ts +0 -0
  67. /package/lib/{cli-ux → ux}/stream.d.ts +0 -0
  68. /package/lib/{cli-ux → ux}/stream.js +0 -0
  69. /package/lib/{cli-ux → ux}/styled/index.d.ts +0 -0
  70. /package/lib/{cli-ux → ux}/styled/index.js +0 -0
  71. /package/lib/{cli-ux → ux}/styled/json.d.ts +0 -0
  72. /package/lib/{cli-ux → ux}/styled/object.d.ts +0 -0
  73. /package/lib/{cli-ux → ux}/styled/object.js +0 -0
  74. /package/lib/{cli-ux → ux}/styled/progress.d.ts +0 -0
  75. /package/lib/{cli-ux → ux}/styled/progress.js +0 -0
  76. /package/lib/{cli-ux → ux}/styled/table.d.ts +0 -0
  77. /package/lib/{cli-ux → ux}/styled/table.js +0 -0
  78. /package/lib/{cli-ux → ux}/styled/tree.d.ts +0 -0
  79. /package/lib/{cli-ux → ux}/styled/tree.js +0 -0
  80. /package/lib/{cli-ux → ux}/wait.d.ts +0 -0
  81. /package/lib/{cli-ux → ux}/wait.js +0 -0
package/README.md CHANGED
@@ -11,12 +11,14 @@ base library for oclif CLIs
11
11
  Migrating
12
12
  =====
13
13
 
14
- See the [migration guide](./MIGRATION.md) for an overview of breaking changes that occurred between v1 and v2.
14
+ See the [v2 migration guide](./guides/V2_MIGRATION.md) for an overview of breaking changes that occurred between v1 and v2.
15
+
16
+ See the [v3 migration guide](./guides/V3_MIGRATION.md) for an overview of breaking changes that occurred between v2 and v3.
15
17
 
16
18
  CLI UX
17
19
  =====
18
20
 
19
- The [ux README](./src/cli-ux/README.md) contains detailed usage examples of using the `ux` export.
21
+ The [ux README](./src/ux/README.md) contains detailed usage examples of using the `ux` export.
20
22
 
21
23
  Usage
22
24
  =====
@@ -28,7 +30,7 @@ You can, however, use `@oclif/core` in a standalone script like this:
28
30
  #!/usr/bin/env ts-node
29
31
 
30
32
  import * as fs from 'fs'
31
- import {Command, Flags} from '@oclif/core'
33
+ import {Command, Flags, flush, handle} from '@oclif/core'
32
34
 
33
35
  class LS extends Command {
34
36
  static description = 'List the files in a directory.'
@@ -50,10 +52,10 @@ class LS extends Command {
50
52
  }
51
53
  }
52
54
 
53
- LS.run().then(() => {
54
- require('@oclif/core/flush')
55
- }, () => {
56
- require('@oclif/core/handle')
55
+ LS.run().then(async () => {
56
+ await flush()
57
+ }, async (err) => {
58
+ await handle(err)
57
59
  })
58
60
  ```
59
61
 
package/lib/command.d.ts CHANGED
@@ -157,6 +157,8 @@ export declare namespace Command {
157
157
  [name: string]: Arg.Cached;
158
158
  };
159
159
  hasDynamicHelp?: boolean;
160
+ permutations?: string[];
161
+ aliasPermutations?: string[];
160
162
  };
161
163
  type Flag = CompletableFlag<any>;
162
164
  namespace Flag {
package/lib/command.js CHANGED
@@ -4,14 +4,14 @@ exports.Command = void 0;
4
4
  const url_1 = require("url");
5
5
  const chalk = require("chalk");
6
6
  const util_1 = require("util");
7
- const cli_ux_1 = require("./cli-ux");
7
+ const ux_1 = require("./ux");
8
8
  const config_1 = require("./config");
9
9
  const Errors = require("./errors");
10
10
  const Parser = require("./parser");
11
11
  const util_2 = require("./help/util");
12
12
  const flags_1 = require("./flags");
13
13
  const util_3 = require("./util");
14
- const stream_1 = require("./cli-ux/stream");
14
+ const stream_1 = require("./ux/stream");
15
15
  const pjson = (0, util_3.requireJson)(__dirname, '..', 'package.json');
16
16
  /**
17
17
  * swallows stdout epipe errors
@@ -231,7 +231,7 @@ class Command {
231
231
  if (!err.message)
232
232
  throw err;
233
233
  try {
234
- cli_ux_1.ux.action.stop(chalk.bold.red('!'));
234
+ ux_1.default.action.stop(chalk.bold.red('!'));
235
235
  }
236
236
  catch { }
237
237
  throw err;
@@ -254,7 +254,7 @@ class Command {
254
254
  return { error: err };
255
255
  }
256
256
  logJson(json) {
257
- cli_ux_1.ux.styledJSON(json);
257
+ ux_1.default.styledJSON(json);
258
258
  }
259
259
  removeEnvVar(envVar) {
260
260
  const keys = [];
@@ -1,7 +1,6 @@
1
1
  import { Options, Plugin as IPlugin } from '../interfaces/plugin';
2
2
  import { Config as IConfig, ArchTypes, PlatformTypes, LoadOptions, VersionDetails } from '../interfaces/config';
3
3
  import { Hook, Hooks, PJSON, Topic } from '../interfaces';
4
- import * as Plugin from './plugin';
5
4
  import { Command } from '../command';
6
5
  export declare class Config implements IConfig {
7
6
  options: Options;
@@ -22,7 +21,7 @@ export declare class Config implements IConfig {
22
21
  npmRegistry?: string;
23
22
  pjson: PJSON.CLI;
24
23
  platform: PlatformTypes;
25
- plugins: IPlugin[];
24
+ plugins: Map<string, IPlugin>;
26
25
  root: string;
27
26
  shell: string;
28
27
  topicSeparator: ':' | ' ';
@@ -39,15 +38,15 @@ export declare class Config implements IConfig {
39
38
  private _commands;
40
39
  private _topics;
41
40
  private _commandIDs;
41
+ private pluginLoader;
42
42
  private static _rootPlugin;
43
43
  constructor(options: Options);
44
44
  static load(opts?: LoadOptions): Promise<Config>;
45
- static get rootPlugin(): Plugin.Plugin | undefined;
45
+ static get rootPlugin(): IPlugin | undefined;
46
46
  load(): Promise<void>;
47
- loadPluginsAndCommands(): Promise<void>;
48
- loadCorePlugins(): Promise<void>;
49
- loadDevPlugins(): Promise<void>;
50
- loadUserPlugins(): Promise<void>;
47
+ loadPluginsAndCommands(opts?: {
48
+ force: boolean;
49
+ }): Promise<void>;
51
50
  runHook<T extends keyof Hooks>(event: T, opts: Hooks[T]['options'], timeout?: number, captureErrors?: boolean): Promise<Hook.Result<Hooks[T]['return']>>;
52
51
  runCommand<T = unknown>(id: string, argv?: string[], cachedCommand?: Command.Loadable | null): Promise<T>;
53
52
  scopedEnvVar(k: string): string | undefined;
@@ -114,11 +113,6 @@ export declare class Config implements IConfig {
114
113
  protected macosCacheDir(): string | undefined;
115
114
  protected _shell(): string;
116
115
  protected _debug(): number;
117
- protected loadPlugins(root: string, type: string, plugins: (string | {
118
- root?: string;
119
- name?: string;
120
- tag?: string;
121
- })[], parent?: Plugin.Plugin): Promise<void>;
122
116
  protected warn(err: string | Error | {
123
117
  name: string;
124
118
  detail: string;
@@ -160,4 +154,4 @@ export declare class Config implements IConfig {
160
154
  */
161
155
  private insertLegacyPlugins;
162
156
  }
163
- export declare function toCached(c: Command.Class, plugin?: IPlugin | undefined, isWritingManifest?: boolean): Promise<Command.Cached>;
157
+ export declare function toCached(c: Command.Class, plugin?: IPlugin, respectNoCacheDefault?: boolean): Promise<Command.Cached>;
@@ -7,19 +7,20 @@ const os = require("os");
7
7
  const path = require("path");
8
8
  const url_1 = require("url");
9
9
  const util_1 = require("util");
10
- const Plugin = require("./plugin");
11
10
  const util_2 = require("./util");
12
11
  const util_3 = require("../util");
13
12
  const module_loader_1 = require("../module-loader");
14
13
  const help_1 = require("../help");
15
- const stream_1 = require("../cli-ux/stream");
14
+ const stream_1 = require("../ux/stream");
16
15
  const performance_1 = require("../performance");
17
16
  const settings_1 = require("../settings");
18
17
  const node_os_1 = require("node:os");
19
18
  const node_path_1 = require("node:path");
19
+ const plugin_loader_1 = require("./plugin-loader");
20
20
  // eslint-disable-next-line new-cap
21
21
  const debug = (0, util_2.Debug)();
22
22
  const _pjson = (0, util_3.requireJson)(__dirname, '..', '..', 'package.json');
23
+ const BASE = `${_pjson.name}@${_pjson.version}`;
23
24
  function channelFromVersion(version) {
24
25
  const m = version.match(/[^-]+(?:-([^.]+))?/);
25
26
  return (m && m[1]) || 'stable';
@@ -60,9 +61,9 @@ class Permutations extends Map {
60
61
  class Config {
61
62
  constructor(options) {
62
63
  this.options = options;
63
- this._base = `${_pjson.name}@${_pjson.version}`;
64
+ this._base = BASE;
64
65
  this.debug = 0;
65
- this.plugins = [];
66
+ this.plugins = new Map();
66
67
  this.topicSeparator = ':';
67
68
  this.warned = false;
68
69
  this.commandPermutations = new Permutations();
@@ -77,8 +78,25 @@ class Config {
77
78
  }
78
79
  if (typeof opts === 'string')
79
80
  opts = { root: opts };
80
- if (isConfig(opts))
81
+ if (isConfig(opts)) {
82
+ /**
83
+ * Reload the Config based on the version required by the command.
84
+ * This is needed because the command is given the Config instantiated
85
+ * by the root plugin, which may be a different version than the one
86
+ * required by the command.
87
+ *
88
+ * Doing this ensures that the command can freely use any method on Config that
89
+ * exists in the version of Config required by the command but may not exist on the
90
+ * root's instance of Config.
91
+ */
92
+ if (BASE !== opts._base) {
93
+ debug(`reloading config from ${opts._base} to ${BASE}`);
94
+ const config = new Config({ ...opts.options, plugins: opts.plugins });
95
+ await config.load();
96
+ return config;
97
+ }
81
98
  return opts;
99
+ }
82
100
  const config = new Config(opts);
83
101
  await config.load();
84
102
  return config;
@@ -88,17 +106,18 @@ class Config {
88
106
  }
89
107
  // eslint-disable-next-line complexity
90
108
  async load() {
91
- settings_1.settings.performanceEnabled = (settings_1.settings.performanceEnabled === undefined ? this.options.enablePerf : settings_1.settings.performanceEnabled) ?? false;
92
- const plugin = new Plugin.Plugin({ root: this.options.root });
93
- await plugin.load();
94
- Config._rootPlugin = plugin;
95
- this.plugins.push(plugin);
96
- this.root = plugin.root;
97
- this.pjson = plugin.pjson;
109
+ settings_1.default.performanceEnabled = (settings_1.default.performanceEnabled === undefined ? this.options.enablePerf : settings_1.default.performanceEnabled) ?? false;
110
+ this.pluginLoader = new plugin_loader_1.default({ root: this.options.root, plugins: this.options.plugins });
111
+ Config._rootPlugin = await this.pluginLoader.loadRoot();
112
+ this.root = Config._rootPlugin.root;
113
+ this.pjson = Config._rootPlugin.pjson;
114
+ this.plugins.set(Config._rootPlugin.name, Config._rootPlugin);
115
+ this.root = Config._rootPlugin.root;
116
+ this.pjson = Config._rootPlugin.pjson;
98
117
  this.name = this.pjson.name;
99
118
  this.version = this.options.version || this.pjson.version || '0.0.0';
100
119
  this.channel = this.options.channel || channelFromVersion(this.version);
101
- this.valid = plugin.valid;
120
+ this.valid = Config._rootPlugin.valid;
102
121
  this.arch = (os.arch() === 'ia32' ? 'x86' : os.arch());
103
122
  this.platform = WSL ? 'wsl' : os.platform();
104
123
  this.windows = this.platform === 'win32';
@@ -146,70 +165,38 @@ class Config {
146
165
  ...s3.templates && s3.templates.vanilla,
147
166
  },
148
167
  };
149
- const marker = performance_1.Performance.mark('config.load');
168
+ const marker = performance_1.default.mark('config.load');
150
169
  await this.loadPluginsAndCommands();
151
170
  debug('config done');
152
171
  marker?.addDetails({
153
- plugins: this.plugins.length,
172
+ plugins: this.plugins.size,
154
173
  commandPermutations: this.commands.length,
155
- commands: this.plugins.reduce((acc, p) => acc + p.commands.length, 0),
174
+ commands: [...this.plugins.values()].reduce((acc, p) => acc + p.commands.length, 0),
156
175
  topics: this.topics.length,
157
176
  });
158
177
  marker?.stop();
159
178
  }
160
- async loadPluginsAndCommands() {
161
- const marker = performance_1.Performance.mark('config.loadPluginsAndCommands');
162
- await this.loadUserPlugins();
163
- await this.loadDevPlugins();
164
- await this.loadCorePlugins();
165
- for (const plugin of this.plugins) {
179
+ async loadPluginsAndCommands(opts) {
180
+ const marker = performance_1.default.mark('config.loadPluginsAndCommands');
181
+ const { plugins, errors } = await this.pluginLoader.loadChildren({
182
+ devPlugins: this.options.devPlugins,
183
+ userPlugins: this.options.userPlugins,
184
+ dataDir: this.dataDir,
185
+ rootPlugin: Config._rootPlugin,
186
+ force: opts?.force ?? false,
187
+ });
188
+ this.plugins = plugins;
189
+ for (const plugin of this.plugins.values()) {
166
190
  this.loadCommands(plugin);
167
191
  this.loadTopics(plugin);
168
192
  }
169
- marker?.stop();
170
- }
171
- async loadCorePlugins() {
172
- if (this.pjson.oclif.plugins) {
173
- await this.loadPlugins(this.root, 'core', this.pjson.oclif.plugins);
174
- }
175
- }
176
- async loadDevPlugins() {
177
- if (this.options.devPlugins !== false) {
178
- // do not load oclif.devPlugins in production
179
- if (this.isProd)
180
- return;
181
- try {
182
- const devPlugins = this.pjson.oclif.devPlugins;
183
- if (devPlugins)
184
- await this.loadPlugins(this.root, 'dev', devPlugins);
185
- }
186
- catch (error) {
187
- process.emitWarning(error);
188
- }
189
- }
190
- }
191
- async loadUserPlugins() {
192
- if (this.options.userPlugins !== false) {
193
- try {
194
- const userPJSONPath = path.join(this.dataDir, 'package.json');
195
- debug('reading user plugins pjson %s', userPJSONPath);
196
- const pjson = await (0, util_2.loadJSON)(userPJSONPath);
197
- this.userPJSON = pjson;
198
- if (!pjson.oclif)
199
- pjson.oclif = { schema: 1 };
200
- if (!pjson.oclif.plugins)
201
- pjson.oclif.plugins = [];
202
- await this.loadPlugins(userPJSONPath, 'user', pjson.oclif.plugins.filter((p) => p.type === 'user'));
203
- await this.loadPlugins(userPJSONPath, 'link', pjson.oclif.plugins.filter((p) => p.type === 'link'));
204
- }
205
- catch (error) {
206
- if (error.code !== 'ENOENT')
207
- process.emitWarning(error);
208
- }
193
+ for (const error of errors) {
194
+ this.warn(error);
209
195
  }
196
+ marker?.stop();
210
197
  }
211
198
  async runHook(event, opts, timeout, captureErrors) {
212
- const marker = performance_1.Performance.mark(`config.runHook#${event}`);
199
+ const marker = performance_1.default.mark(`config.runHook#${event}`);
213
200
  debug('start %s hook', event);
214
201
  const search = (m) => {
215
202
  if (typeof m === 'function')
@@ -234,7 +221,7 @@ class Config {
234
221
  successes: [],
235
222
  failures: [],
236
223
  };
237
- const promises = this.plugins.map(async (p) => {
224
+ const promises = [...this.plugins.values()].map(async (p) => {
238
225
  const debug = require('debug')([this.bin, p.name, 'hooks', event].join(':'));
239
226
  const context = {
240
227
  config: this,
@@ -254,7 +241,7 @@ class Config {
254
241
  };
255
242
  const hooks = p.hooks[event] || [];
256
243
  for (const hook of hooks) {
257
- const marker = performance_1.Performance.mark(`config.runHook#${p.name}(${hook})`);
244
+ const marker = performance_1.default.mark(`config.runHook#${p.name}(${hook})`);
258
245
  try {
259
246
  /* eslint-disable no-await-in-loop */
260
247
  const { isESM, module, filePath } = await module_loader_1.default.loadWithData(p, hook);
@@ -288,7 +275,7 @@ class Config {
288
275
  return final;
289
276
  }
290
277
  async runCommand(id, argv = [], cachedCommand = null) {
291
- const marker = performance_1.Performance.mark(`config.runCommand#${id}`);
278
+ const marker = performance_1.default.mark(`config.runCommand#${id}`);
292
279
  debug('runCommand %s %o', id, argv);
293
280
  let c = cachedCommand ?? this.findCommand(id);
294
281
  if (!c) {
@@ -315,7 +302,7 @@ class Config {
315
302
  if (jitResult.failures[0])
316
303
  throw jitResult.failures[0].error;
317
304
  if (jitResult.successes[0]) {
318
- await this.loadPluginsAndCommands();
305
+ await this.loadPluginsAndCommands({ force: true });
319
306
  c = this.findCommand(id) ?? c;
320
307
  }
321
308
  else {
@@ -442,7 +429,7 @@ class Config {
442
429
  cliVersion,
443
430
  architecture,
444
431
  nodeVersion,
445
- pluginVersions: Object.fromEntries(this.plugins.map(p => [p.name, { version: p.version, type: p.type, root: p.root }])),
432
+ pluginVersions: Object.fromEntries([...this.plugins.values()].map(p => [p.name, { version: p.version, type: p.type, root: p.root }])),
446
433
  osVersion: `${os.type()} ${os.release()}`,
447
434
  shell: this.shell,
448
435
  rootPath: this.root,
@@ -465,7 +452,7 @@ class Config {
465
452
  return url.toString();
466
453
  }
467
454
  getPluginsList() {
468
- return this.plugins;
455
+ return [...this.plugins.values()];
469
456
  }
470
457
  dir(category) {
471
458
  const base = process.env[`XDG_${category.toUpperCase()}_HOME`] ||
@@ -511,52 +498,6 @@ class Config {
511
498
  catch { }
512
499
  return 0;
513
500
  }
514
- async loadPlugins(root, type, plugins, parent) {
515
- if (!plugins || plugins.length === 0)
516
- return;
517
- const mark = performance_1.Performance.mark(`config.loadPlugins#${type}`);
518
- debug('loading plugins', plugins);
519
- await Promise.all((plugins || []).map(async (plugin) => {
520
- try {
521
- const opts = { type, root };
522
- if (typeof plugin === 'string') {
523
- opts.name = plugin;
524
- }
525
- else {
526
- opts.name = plugin.name || opts.name;
527
- opts.tag = plugin.tag || opts.tag;
528
- opts.root = plugin.root || opts.root;
529
- }
530
- const pluginMarker = performance_1.Performance.mark(`plugin.load#${opts.name}`);
531
- const instance = new Plugin.Plugin(opts);
532
- await instance.load();
533
- pluginMarker?.addDetails({
534
- hasManifest: instance.hasManifest,
535
- commandCount: instance.commands.length,
536
- topicCount: instance.topics.length,
537
- type: instance.type,
538
- usesMain: Boolean(instance.pjson.main),
539
- name: instance.name,
540
- });
541
- pluginMarker?.stop();
542
- if (this.plugins.find(p => p.name === instance.name))
543
- return;
544
- this.plugins.push(instance);
545
- if (parent) {
546
- instance.parent = parent;
547
- if (!parent.children)
548
- parent.children = [];
549
- parent.children.push(instance);
550
- }
551
- await this.loadPlugins(instance.root, type, instance.pjson.oclif.plugins || [], instance);
552
- }
553
- catch (error) {
554
- this.warn(error, 'loadPlugins');
555
- }
556
- }));
557
- mark?.addDetails({ pluginCount: plugins.length });
558
- mark?.stop();
559
- }
560
501
  warn(err, scope) {
561
502
  if (this.warned)
562
503
  return;
@@ -595,7 +536,8 @@ class Config {
595
536
  return (0, util_3.isProd)();
596
537
  }
597
538
  isJitPluginCommand(c) {
598
- return Object.keys(this.pjson.oclif.jitPlugins ?? {}).includes(c.pluginName ?? '') && !this.plugins.find(p => p.name === c?.pluginName);
539
+ // Return true if the command's plugin is listed under oclif.jitPlugins AND if the plugin hasn't been loaded to this.plugins
540
+ return Object.keys(this.pjson.oclif.jitPlugins ?? {}).includes(c.pluginName ?? '') && Boolean(c?.pluginName && !this.plugins.has(c.pluginName));
599
541
  }
600
542
  getCmdLookupId(id) {
601
543
  if (this._commands.has(id))
@@ -612,8 +554,9 @@ class Config {
612
554
  return id;
613
555
  }
614
556
  loadCommands(plugin) {
615
- const marker = performance_1.Performance.mark(`config.loadCommands#${plugin.name}`, { plugin: plugin.name });
557
+ const marker = performance_1.default.mark(`config.loadCommands#${plugin.name}`, { plugin: plugin.name });
616
558
  for (const command of plugin.commands) {
559
+ // set canonical command id
617
560
  if (this._commands.has(command.id)) {
618
561
  const prioritizedCommand = this.determinePriority([this._commands.get(command.id), command]);
619
562
  this._commands.set(prioritizedCommand.id, prioritizedCommand);
@@ -621,10 +564,11 @@ class Config {
621
564
  else {
622
565
  this._commands.set(command.id, command);
623
566
  }
624
- const permutations = this.flexibleTaxonomy ? (0, util_2.getCommandIdPermutations)(command.id) : [command.id];
625
- for (const permutation of permutations) {
567
+ // set every permutation
568
+ for (const permutation of command.permutations ?? [command.id]) {
626
569
  this.commandPermutations.add(permutation, command.id);
627
570
  }
571
+ // set command aliases
628
572
  for (const alias of command.aliases ?? []) {
629
573
  if (this._commands.has(alias)) {
630
574
  const prioritizedCommand = this.determinePriority([this._commands.get(alias), command]);
@@ -633,8 +577,8 @@ class Config {
633
577
  else {
634
578
  this._commands.set(alias, { ...command, id: alias });
635
579
  }
636
- const aliasPermutations = this.flexibleTaxonomy ? (0, util_2.getCommandIdPermutations)(alias) : [alias];
637
- for (const permutation of aliasPermutations) {
580
+ // set every permutation of the aliases
581
+ for (const permutation of command.aliasPermutations ?? [alias]) {
638
582
  this.commandPermutations.add(permutation, command.id);
639
583
  }
640
584
  }
@@ -643,7 +587,7 @@ class Config {
643
587
  marker?.stop();
644
588
  }
645
589
  loadTopics(plugin) {
646
- const marker = performance_1.Performance.mark(`config.loadTopics#${plugin.name}`, { plugin: plugin.name });
590
+ const marker = performance_1.default.mark(`config.loadTopics#${plugin.name}`, { plugin: plugin.name });
647
591
  for (const topic of (0, util_2.compact)(plugin.topics)) {
648
592
  const existing = this._topics.get(topic.name);
649
593
  if (existing) {
@@ -734,23 +678,20 @@ class Config {
734
678
  */
735
679
  insertLegacyPlugins(plugins) {
736
680
  for (const plugin of plugins) {
737
- const idx = this.plugins.findIndex(p => p.name === plugin.name);
738
- if (idx !== -1) {
739
- // invalid plugin instance found in `this.plugins`
740
- // replace with the oclif-compatible one
741
- this.plugins.splice(idx, 1, plugin);
742
- }
681
+ this.plugins.set(plugin.name, plugin);
743
682
  this.loadCommands(plugin);
744
683
  }
745
684
  }
746
685
  }
747
686
  exports.Config = Config;
748
687
  // when no manifest exists, the default is calculated. This may throw, so we need to catch it
749
- const defaultFlagToCached = async (flag, isWritingManifest = false) => {
750
- // Prefer the helpDefaultValue function (returns a friendly string for complex types)
688
+ const defaultFlagToCached = async (flag, respectNoCacheDefault) => {
689
+ if (respectNoCacheDefault && flag.noCacheDefault)
690
+ return;
691
+ // Prefer the defaultHelp function (returns a friendly string for complex types)
751
692
  if (typeof flag.defaultHelp === 'function') {
752
693
  try {
753
- return await flag.defaultHelp({ options: flag, flags: {} }, isWritingManifest);
694
+ return await flag.defaultHelp({ options: flag, flags: {} });
754
695
  }
755
696
  catch {
756
697
  return;
@@ -759,7 +700,7 @@ const defaultFlagToCached = async (flag, isWritingManifest = false) => {
759
700
  // if not specified, try the default function
760
701
  if (typeof flag.default === 'function') {
761
702
  try {
762
- return await flag.default({ options: flag, flags: {} }, isWritingManifest);
703
+ return await flag.default({ options: flag, flags: {} });
763
704
  }
764
705
  catch { }
765
706
  }
@@ -767,11 +708,13 @@ const defaultFlagToCached = async (flag, isWritingManifest = false) => {
767
708
  return flag.default;
768
709
  }
769
710
  };
770
- const defaultArgToCached = async (arg, isWritingManifest = false) => {
771
- // Prefer the helpDefaultValue function (returns a friendly string for complex types)
711
+ const defaultArgToCached = async (arg, respectNoCacheDefault) => {
712
+ if (respectNoCacheDefault && arg.noCacheDefault)
713
+ return;
714
+ // Prefer the defaultHelp function (returns a friendly string for complex types)
772
715
  if (typeof arg.defaultHelp === 'function') {
773
716
  try {
774
- return await arg.defaultHelp({ options: arg, flags: {} }, isWritingManifest);
717
+ return await arg.defaultHelp({ options: arg, flags: {} });
775
718
  }
776
719
  catch {
777
720
  return;
@@ -780,7 +723,7 @@ const defaultArgToCached = async (arg, isWritingManifest = false) => {
780
723
  // if not specified, try the default function
781
724
  if (typeof arg.default === 'function') {
782
725
  try {
783
- return await arg.default({ options: arg, flags: {} }, isWritingManifest);
726
+ return await arg.default({ options: arg, flags: {} });
784
727
  }
785
728
  catch { }
786
729
  }
@@ -788,7 +731,7 @@ const defaultArgToCached = async (arg, isWritingManifest = false) => {
788
731
  return arg.default;
789
732
  }
790
733
  };
791
- async function toCached(c, plugin, isWritingManifest) {
734
+ async function toCached(c, plugin, respectNoCacheDefault = false) {
792
735
  const flags = {};
793
736
  for (const [name, flag] of Object.entries(c.flags || {})) {
794
737
  if (flag.type === 'boolean') {
@@ -810,6 +753,7 @@ async function toCached(c, plugin, isWritingManifest) {
810
753
  deprecateAliases: c.deprecateAliases,
811
754
  aliases: flag.aliases,
812
755
  delimiter: flag.delimiter,
756
+ noCacheDefault: flag.noCacheDefault,
813
757
  };
814
758
  }
815
759
  else {
@@ -829,11 +773,12 @@ async function toCached(c, plugin, isWritingManifest) {
829
773
  dependsOn: flag.dependsOn,
830
774
  relationships: flag.relationships,
831
775
  exclusive: flag.exclusive,
832
- default: await defaultFlagToCached(flag, isWritingManifest),
776
+ default: await defaultFlagToCached(flag, respectNoCacheDefault),
833
777
  deprecated: flag.deprecated,
834
778
  deprecateAliases: c.deprecateAliases,
835
779
  aliases: flag.aliases,
836
780
  delimiter: flag.delimiter,
781
+ noCacheDefault: flag.noCacheDefault,
837
782
  };
838
783
  // a command-level placeholder in the manifest so that oclif knows it should regenerate the command during help-time
839
784
  if (typeof flag.defaultHelp === 'function') {
@@ -848,8 +793,9 @@ async function toCached(c, plugin, isWritingManifest) {
848
793
  description: arg.description,
849
794
  required: arg.required,
850
795
  options: arg.options,
851
- default: await defaultArgToCached(arg, isWritingManifest),
796
+ default: await defaultArgToCached(arg, respectNoCacheDefault),
852
797
  hidden: arg.hidden,
798
+ noCacheDefault: arg.noCacheDefault,
853
799
  };
854
800
  }
855
801
  const stdProperties = {
@@ -1,3 +1,4 @@
1
- export { Config, toCached } from './config';
1
+ export { Config } from './config';
2
+ export { toCached } from './config';
2
3
  export { Plugin } from './plugin';
3
4
  export { tsPath } from './ts-node';
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.tsPath = exports.Plugin = exports.toCached = exports.Config = void 0;
4
4
  var config_1 = require("./config");
5
5
  Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return config_1.Config; } });
6
- Object.defineProperty(exports, "toCached", { enumerable: true, get: function () { return config_1.toCached; } });
6
+ var config_2 = require("./config");
7
+ Object.defineProperty(exports, "toCached", { enumerable: true, get: function () { return config_2.toCached; } });
7
8
  var plugin_1 = require("./plugin");
8
9
  Object.defineProperty(exports, "Plugin", { enumerable: true, get: function () { return plugin_1.Plugin; } });
9
10
  var ts_node_1 = require("./ts-node");
@@ -0,0 +1,30 @@
1
+ import { Plugin as IPlugin } from '../interfaces/plugin';
2
+ type PluginLoaderOptions = {
3
+ root: string;
4
+ plugins?: IPlugin[] | PluginsMap;
5
+ };
6
+ type LoadOpts = {
7
+ devPlugins?: boolean;
8
+ userPlugins?: boolean;
9
+ dataDir: string;
10
+ rootPlugin: IPlugin;
11
+ force?: boolean;
12
+ };
13
+ type PluginsMap = Map<string, IPlugin>;
14
+ export default class PluginLoader {
15
+ options: PluginLoaderOptions;
16
+ plugins: PluginsMap;
17
+ errors: (string | Error)[];
18
+ private pluginsProvided;
19
+ constructor(options: PluginLoaderOptions);
20
+ loadRoot(): Promise<IPlugin>;
21
+ loadChildren(opts: LoadOpts): Promise<{
22
+ plugins: PluginsMap;
23
+ errors: (string | Error)[];
24
+ }>;
25
+ private loadCorePlugins;
26
+ private loadDevPlugins;
27
+ private loadUserPlugins;
28
+ private loadPlugins;
29
+ }
30
+ export {};