@oclif/core 3.0.0-beta.1 → 3.0.0-beta.3

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 (85) 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 +9 -12
  5. package/lib/config/config.js +90 -137
  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 +5 -10
  11. package/lib/config/plugin.js +21 -17
  12. package/lib/config/ts-node.d.ts +3 -2
  13. package/lib/config/ts-node.js +83 -36
  14. package/lib/errors/config.js +5 -5
  15. package/lib/errors/errors/cli.d.ts +1 -0
  16. package/lib/errors/errors/cli.js +1 -0
  17. package/lib/errors/handle.d.ts +2 -2
  18. package/lib/errors/handle.js +4 -5
  19. package/lib/errors/index.d.ts +2 -1
  20. package/lib/errors/index.js +9 -2
  21. package/lib/errors/logger.js +3 -3
  22. package/lib/execute.d.ts +49 -0
  23. package/lib/execute.js +62 -0
  24. package/lib/flags.js +6 -4
  25. package/lib/help/index.js +3 -3
  26. package/lib/index.d.ts +9 -7
  27. package/lib/index.js +13 -19
  28. package/lib/interfaces/config.d.ts +26 -26
  29. package/lib/interfaces/parser.d.ts +14 -66
  30. package/lib/interfaces/pjson.d.ts +2 -0
  31. package/lib/interfaces/plugin.d.ts +8 -1
  32. package/lib/interfaces/ts-config.d.ts +9 -0
  33. package/lib/main.d.ts +1 -54
  34. package/lib/main.js +11 -73
  35. package/lib/module-loader.d.ts +1 -2
  36. package/lib/module-loader.js +9 -9
  37. package/lib/parser/errors.js +1 -1
  38. package/lib/parser/parse.js +1 -34
  39. package/lib/performance.d.ts +1 -1
  40. package/lib/performance.js +2 -3
  41. package/lib/screen.js +2 -2
  42. package/lib/settings.d.ts +2 -1
  43. package/lib/settings.js +2 -2
  44. package/lib/{cli-ux → ux}/action/base.js +2 -2
  45. package/lib/{cli-ux → ux}/action/spinner.js +1 -1
  46. package/lib/{cli-ux → ux}/config.d.ts +0 -1
  47. package/lib/{cli-ux → ux}/config.js +6 -10
  48. package/lib/{cli-ux → ux}/exit.d.ts +1 -1
  49. package/lib/{cli-ux → ux}/exit.js +1 -1
  50. package/lib/ux/flush.d.ts +1 -0
  51. package/lib/ux/flush.js +27 -0
  52. package/lib/{cli-ux → ux}/index.d.ts +8 -27
  53. package/lib/{cli-ux → ux}/index.js +21 -80
  54. package/lib/{cli-ux → ux}/prompt.js +2 -2
  55. package/lib/{cli-ux → ux}/styled/json.js +3 -3
  56. package/package.json +24 -19
  57. package/flush.d.ts +0 -3
  58. package/flush.js +0 -1
  59. package/handle.js +0 -1
  60. package/lib/cli-ux/action/pride-spinner.d.ts +0 -4
  61. package/lib/cli-ux/action/pride-spinner.js +0 -30
  62. /package/lib/{cli-ux → ux}/action/base.d.ts +0 -0
  63. /package/lib/{cli-ux → ux}/action/simple.d.ts +0 -0
  64. /package/lib/{cli-ux → ux}/action/simple.js +0 -0
  65. /package/lib/{cli-ux → ux}/action/spinner.d.ts +0 -0
  66. /package/lib/{cli-ux → ux}/action/spinners.d.ts +0 -0
  67. /package/lib/{cli-ux → ux}/action/spinners.js +0 -0
  68. /package/lib/{cli-ux → ux}/list.d.ts +0 -0
  69. /package/lib/{cli-ux → ux}/list.js +0 -0
  70. /package/lib/{cli-ux → ux}/prompt.d.ts +0 -0
  71. /package/lib/{cli-ux → ux}/stream.d.ts +0 -0
  72. /package/lib/{cli-ux → ux}/stream.js +0 -0
  73. /package/lib/{cli-ux → ux}/styled/index.d.ts +0 -0
  74. /package/lib/{cli-ux → ux}/styled/index.js +0 -0
  75. /package/lib/{cli-ux → ux}/styled/json.d.ts +0 -0
  76. /package/lib/{cli-ux → ux}/styled/object.d.ts +0 -0
  77. /package/lib/{cli-ux → ux}/styled/object.js +0 -0
  78. /package/lib/{cli-ux → ux}/styled/progress.d.ts +0 -0
  79. /package/lib/{cli-ux → ux}/styled/progress.js +0 -0
  80. /package/lib/{cli-ux → ux}/styled/table.d.ts +0 -0
  81. /package/lib/{cli-ux → ux}/styled/table.js +0 -0
  82. /package/lib/{cli-ux → ux}/styled/tree.d.ts +0 -0
  83. /package/lib/{cli-ux → ux}/styled/tree.js +0 -0
  84. /package/lib/{cli-ux → ux}/wait.d.ts +0 -0
  85. /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,13 +38,15 @@ export declare class Config implements IConfig {
39
38
  private _commands;
40
39
  private _topics;
41
40
  private _commandIDs;
41
+ private pluginLoader;
42
+ private static _rootPlugin;
42
43
  constructor(options: Options);
43
44
  static load(opts?: LoadOptions): Promise<Config>;
45
+ static get rootPlugin(): IPlugin | undefined;
44
46
  load(): Promise<void>;
45
- loadPluginsAndCommands(): Promise<void>;
46
- loadCorePlugins(): Promise<void>;
47
- loadDevPlugins(): Promise<void>;
48
- loadUserPlugins(): Promise<void>;
47
+ loadPluginsAndCommands(opts?: {
48
+ force: boolean;
49
+ }): Promise<void>;
49
50
  runHook<T extends keyof Hooks>(event: T, opts: Hooks[T]['options'], timeout?: number, captureErrors?: boolean): Promise<Hook.Result<Hooks[T]['return']>>;
50
51
  runCommand<T = unknown>(id: string, argv?: string[], cachedCommand?: Command.Loadable | null): Promise<T>;
51
52
  scopedEnvVar(k: string): string | undefined;
@@ -104,6 +105,7 @@ export declare class Config implements IConfig {
104
105
  get versionDetails(): VersionDetails;
105
106
  s3Key(type: keyof PJSON.S3.Templates, ext?: '.tar.gz' | '.tar.xz' | IConfig.s3Key.Options, options?: IConfig.s3Key.Options): string;
106
107
  s3Url(key: string): string;
108
+ getPluginsList(): IPlugin[];
107
109
  protected dir(category: 'cache' | 'data' | 'config'): string;
108
110
  protected windowsHome(): string | undefined;
109
111
  protected windowsHomedriveHome(): string | undefined;
@@ -111,11 +113,6 @@ export declare class Config implements IConfig {
111
113
  protected macosCacheDir(): string | undefined;
112
114
  protected _shell(): string;
113
115
  protected _debug(): number;
114
- protected loadPlugins(root: string, type: string, plugins: (string | {
115
- root?: string;
116
- name?: string;
117
- tag?: string;
118
- })[], parent?: Plugin.Plugin): Promise<void>;
119
116
  protected warn(err: string | Error | {
120
117
  name: string;
121
118
  detail: string;
@@ -157,4 +154,4 @@ export declare class Config implements IConfig {
157
154
  */
158
155
  private insertLegacyPlugins;
159
156
  }
160
- 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,24 +78,46 @@ 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;
85
103
  }
104
+ static get rootPlugin() {
105
+ return Config._rootPlugin;
106
+ }
86
107
  // eslint-disable-next-line complexity
87
108
  async load() {
88
- settings_1.settings.performanceEnabled = (settings_1.settings.performanceEnabled === undefined ? this.options.enablePerf : settings_1.settings.performanceEnabled) ?? false;
89
- const plugin = new Plugin.Plugin({ root: this.options.root });
90
- await plugin.load();
91
- this.plugins.push(plugin);
92
- this.root = plugin.root;
93
- 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;
94
117
  this.name = this.pjson.name;
95
118
  this.version = this.options.version || this.pjson.version || '0.0.0';
96
119
  this.channel = this.options.channel || channelFromVersion(this.version);
97
- this.valid = plugin.valid;
120
+ this.valid = Config._rootPlugin.valid;
98
121
  this.arch = (os.arch() === 'ia32' ? 'x86' : os.arch());
99
122
  this.platform = WSL ? 'wsl' : os.platform();
100
123
  this.windows = this.platform === 'win32';
@@ -142,70 +165,38 @@ class Config {
142
165
  ...s3.templates && s3.templates.vanilla,
143
166
  },
144
167
  };
145
- const marker = performance_1.Performance.mark('config.load');
168
+ const marker = performance_1.default.mark('config.load');
146
169
  await this.loadPluginsAndCommands();
147
170
  debug('config done');
148
171
  marker?.addDetails({
149
- plugins: this.plugins.length,
172
+ plugins: this.plugins.size,
150
173
  commandPermutations: this.commands.length,
151
- commands: this.plugins.reduce((acc, p) => acc + p.commands.length, 0),
174
+ commands: [...this.plugins.values()].reduce((acc, p) => acc + p.commands.length, 0),
152
175
  topics: this.topics.length,
153
176
  });
154
177
  marker?.stop();
155
178
  }
156
- async loadPluginsAndCommands() {
157
- const marker = performance_1.Performance.mark('config.loadPluginsAndCommands');
158
- await this.loadUserPlugins();
159
- await this.loadDevPlugins();
160
- await this.loadCorePlugins();
161
- 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()) {
162
190
  this.loadCommands(plugin);
163
191
  this.loadTopics(plugin);
164
192
  }
165
- marker?.stop();
166
- }
167
- async loadCorePlugins() {
168
- if (this.pjson.oclif.plugins) {
169
- await this.loadPlugins(this.root, 'core', this.pjson.oclif.plugins);
170
- }
171
- }
172
- async loadDevPlugins() {
173
- if (this.options.devPlugins !== false) {
174
- // do not load oclif.devPlugins in production
175
- if (this.isProd)
176
- return;
177
- try {
178
- const devPlugins = this.pjson.oclif.devPlugins;
179
- if (devPlugins)
180
- await this.loadPlugins(this.root, 'dev', devPlugins);
181
- }
182
- catch (error) {
183
- process.emitWarning(error);
184
- }
185
- }
186
- }
187
- async loadUserPlugins() {
188
- if (this.options.userPlugins !== false) {
189
- try {
190
- const userPJSONPath = path.join(this.dataDir, 'package.json');
191
- debug('reading user plugins pjson %s', userPJSONPath);
192
- const pjson = await (0, util_2.loadJSON)(userPJSONPath);
193
- this.userPJSON = pjson;
194
- if (!pjson.oclif)
195
- pjson.oclif = { schema: 1 };
196
- if (!pjson.oclif.plugins)
197
- pjson.oclif.plugins = [];
198
- await this.loadPlugins(userPJSONPath, 'user', pjson.oclif.plugins.filter((p) => p.type === 'user'));
199
- await this.loadPlugins(userPJSONPath, 'link', pjson.oclif.plugins.filter((p) => p.type === 'link'));
200
- }
201
- catch (error) {
202
- if (error.code !== 'ENOENT')
203
- process.emitWarning(error);
204
- }
193
+ for (const error of errors) {
194
+ this.warn(error);
205
195
  }
196
+ marker?.stop();
206
197
  }
207
198
  async runHook(event, opts, timeout, captureErrors) {
208
- const marker = performance_1.Performance.mark(`config.runHook#${event}`);
199
+ const marker = performance_1.default.mark(`config.runHook#${event}`);
209
200
  debug('start %s hook', event);
210
201
  const search = (m) => {
211
202
  if (typeof m === 'function')
@@ -230,7 +221,7 @@ class Config {
230
221
  successes: [],
231
222
  failures: [],
232
223
  };
233
- const promises = this.plugins.map(async (p) => {
224
+ const promises = [...this.plugins.values()].map(async (p) => {
234
225
  const debug = require('debug')([this.bin, p.name, 'hooks', event].join(':'));
235
226
  const context = {
236
227
  config: this,
@@ -250,7 +241,7 @@ class Config {
250
241
  };
251
242
  const hooks = p.hooks[event] || [];
252
243
  for (const hook of hooks) {
253
- const marker = performance_1.Performance.mark(`config.runHook#${p.name}(${hook})`);
244
+ const marker = performance_1.default.mark(`config.runHook#${p.name}(${hook})`);
254
245
  try {
255
246
  /* eslint-disable no-await-in-loop */
256
247
  const { isESM, module, filePath } = await module_loader_1.default.loadWithData(p, hook);
@@ -284,7 +275,7 @@ class Config {
284
275
  return final;
285
276
  }
286
277
  async runCommand(id, argv = [], cachedCommand = null) {
287
- const marker = performance_1.Performance.mark(`config.runCommand#${id}`);
278
+ const marker = performance_1.default.mark(`config.runCommand#${id}`);
288
279
  debug('runCommand %s %o', id, argv);
289
280
  let c = cachedCommand ?? this.findCommand(id);
290
281
  if (!c) {
@@ -311,7 +302,7 @@ class Config {
311
302
  if (jitResult.failures[0])
312
303
  throw jitResult.failures[0].error;
313
304
  if (jitResult.successes[0]) {
314
- await this.loadPluginsAndCommands();
305
+ await this.loadPluginsAndCommands({ force: true });
315
306
  c = this.findCommand(id) ?? c;
316
307
  }
317
308
  else {
@@ -438,7 +429,7 @@ class Config {
438
429
  cliVersion,
439
430
  architecture,
440
431
  nodeVersion,
441
- 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 }])),
442
433
  osVersion: `${os.type()} ${os.release()}`,
443
434
  shell: this.shell,
444
435
  rootPath: this.root,
@@ -460,6 +451,9 @@ class Config {
460
451
  url.pathname = path.join(url.pathname, key);
461
452
  return url.toString();
462
453
  }
454
+ getPluginsList() {
455
+ return [...this.plugins.values()];
456
+ }
463
457
  dir(category) {
464
458
  const base = process.env[`XDG_${category.toUpperCase()}_HOME`] ||
465
459
  (this.windows && process.env.LOCALAPPDATA) ||
@@ -504,52 +498,6 @@ class Config {
504
498
  catch { }
505
499
  return 0;
506
500
  }
507
- async loadPlugins(root, type, plugins, parent) {
508
- if (!plugins || plugins.length === 0)
509
- return;
510
- const mark = performance_1.Performance.mark(`config.loadPlugins#${type}`);
511
- debug('loading plugins', plugins);
512
- await Promise.all((plugins || []).map(async (plugin) => {
513
- try {
514
- const opts = { type, root };
515
- if (typeof plugin === 'string') {
516
- opts.name = plugin;
517
- }
518
- else {
519
- opts.name = plugin.name || opts.name;
520
- opts.tag = plugin.tag || opts.tag;
521
- opts.root = plugin.root || opts.root;
522
- }
523
- const pluginMarker = performance_1.Performance.mark(`plugin.load#${opts.name}`);
524
- const instance = new Plugin.Plugin(opts);
525
- await instance.load();
526
- pluginMarker?.addDetails({
527
- hasManifest: instance.hasManifest,
528
- commandCount: instance.commands.length,
529
- topicCount: instance.topics.length,
530
- type: instance.type,
531
- usesMain: Boolean(instance.pjson.main),
532
- name: instance.name,
533
- });
534
- pluginMarker?.stop();
535
- if (this.plugins.find(p => p.name === instance.name))
536
- return;
537
- this.plugins.push(instance);
538
- if (parent) {
539
- instance.parent = parent;
540
- if (!parent.children)
541
- parent.children = [];
542
- parent.children.push(instance);
543
- }
544
- await this.loadPlugins(instance.root, type, instance.pjson.oclif.plugins || [], instance);
545
- }
546
- catch (error) {
547
- this.warn(error, 'loadPlugins');
548
- }
549
- }));
550
- mark?.addDetails({ pluginCount: plugins.length });
551
- mark?.stop();
552
- }
553
501
  warn(err, scope) {
554
502
  if (this.warned)
555
503
  return;
@@ -588,7 +536,8 @@ class Config {
588
536
  return (0, util_3.isProd)();
589
537
  }
590
538
  isJitPluginCommand(c) {
591
- 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));
592
541
  }
593
542
  getCmdLookupId(id) {
594
543
  if (this._commands.has(id))
@@ -605,8 +554,9 @@ class Config {
605
554
  return id;
606
555
  }
607
556
  loadCommands(plugin) {
608
- 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 });
609
558
  for (const command of plugin.commands) {
559
+ // set canonical command id
610
560
  if (this._commands.has(command.id)) {
611
561
  const prioritizedCommand = this.determinePriority([this._commands.get(command.id), command]);
612
562
  this._commands.set(prioritizedCommand.id, prioritizedCommand);
@@ -614,10 +564,11 @@ class Config {
614
564
  else {
615
565
  this._commands.set(command.id, command);
616
566
  }
617
- const permutations = this.flexibleTaxonomy ? (0, util_2.getCommandIdPermutations)(command.id) : [command.id];
618
- for (const permutation of permutations) {
567
+ // set every permutation
568
+ for (const permutation of command.permutations ?? [command.id]) {
619
569
  this.commandPermutations.add(permutation, command.id);
620
570
  }
571
+ // set command aliases
621
572
  for (const alias of command.aliases ?? []) {
622
573
  if (this._commands.has(alias)) {
623
574
  const prioritizedCommand = this.determinePriority([this._commands.get(alias), command]);
@@ -626,8 +577,8 @@ class Config {
626
577
  else {
627
578
  this._commands.set(alias, { ...command, id: alias });
628
579
  }
629
- const aliasPermutations = this.flexibleTaxonomy ? (0, util_2.getCommandIdPermutations)(alias) : [alias];
630
- for (const permutation of aliasPermutations) {
580
+ // set every permutation of the aliases
581
+ for (const permutation of command.aliasPermutations ?? [alias]) {
631
582
  this.commandPermutations.add(permutation, command.id);
632
583
  }
633
584
  }
@@ -636,7 +587,7 @@ class Config {
636
587
  marker?.stop();
637
588
  }
638
589
  loadTopics(plugin) {
639
- 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 });
640
591
  for (const topic of (0, util_2.compact)(plugin.topics)) {
641
592
  const existing = this._topics.get(topic.name);
642
593
  if (existing) {
@@ -727,23 +678,20 @@ class Config {
727
678
  */
728
679
  insertLegacyPlugins(plugins) {
729
680
  for (const plugin of plugins) {
730
- const idx = this.plugins.findIndex(p => p.name === plugin.name);
731
- if (idx !== -1) {
732
- // invalid plugin instance found in `this.plugins`
733
- // replace with the oclif-compatible one
734
- this.plugins.splice(idx, 1, plugin);
735
- }
681
+ this.plugins.set(plugin.name, plugin);
736
682
  this.loadCommands(plugin);
737
683
  }
738
684
  }
739
685
  }
740
686
  exports.Config = Config;
741
687
  // when no manifest exists, the default is calculated. This may throw, so we need to catch it
742
- const defaultFlagToCached = async (flag, isWritingManifest = false) => {
743
- // 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)
744
692
  if (typeof flag.defaultHelp === 'function') {
745
693
  try {
746
- return await flag.defaultHelp({ options: flag, flags: {} }, isWritingManifest);
694
+ return await flag.defaultHelp({ options: flag, flags: {} });
747
695
  }
748
696
  catch {
749
697
  return;
@@ -752,7 +700,7 @@ const defaultFlagToCached = async (flag, isWritingManifest = false) => {
752
700
  // if not specified, try the default function
753
701
  if (typeof flag.default === 'function') {
754
702
  try {
755
- return await flag.default({ options: flag, flags: {} }, isWritingManifest);
703
+ return await flag.default({ options: flag, flags: {} });
756
704
  }
757
705
  catch { }
758
706
  }
@@ -760,11 +708,13 @@ const defaultFlagToCached = async (flag, isWritingManifest = false) => {
760
708
  return flag.default;
761
709
  }
762
710
  };
763
- const defaultArgToCached = async (arg, isWritingManifest = false) => {
764
- // 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)
765
715
  if (typeof arg.defaultHelp === 'function') {
766
716
  try {
767
- return await arg.defaultHelp({ options: arg, flags: {} }, isWritingManifest);
717
+ return await arg.defaultHelp({ options: arg, flags: {} });
768
718
  }
769
719
  catch {
770
720
  return;
@@ -773,7 +723,7 @@ const defaultArgToCached = async (arg, isWritingManifest = false) => {
773
723
  // if not specified, try the default function
774
724
  if (typeof arg.default === 'function') {
775
725
  try {
776
- return await arg.default({ options: arg, flags: {} }, isWritingManifest);
726
+ return await arg.default({ options: arg, flags: {} });
777
727
  }
778
728
  catch { }
779
729
  }
@@ -781,7 +731,7 @@ const defaultArgToCached = async (arg, isWritingManifest = false) => {
781
731
  return arg.default;
782
732
  }
783
733
  };
784
- async function toCached(c, plugin, isWritingManifest) {
734
+ async function toCached(c, plugin, respectNoCacheDefault = false) {
785
735
  const flags = {};
786
736
  for (const [name, flag] of Object.entries(c.flags || {})) {
787
737
  if (flag.type === 'boolean') {
@@ -803,6 +753,7 @@ async function toCached(c, plugin, isWritingManifest) {
803
753
  deprecateAliases: c.deprecateAliases,
804
754
  aliases: flag.aliases,
805
755
  delimiter: flag.delimiter,
756
+ noCacheDefault: flag.noCacheDefault,
806
757
  };
807
758
  }
808
759
  else {
@@ -822,11 +773,12 @@ async function toCached(c, plugin, isWritingManifest) {
822
773
  dependsOn: flag.dependsOn,
823
774
  relationships: flag.relationships,
824
775
  exclusive: flag.exclusive,
825
- default: await defaultFlagToCached(flag, isWritingManifest),
776
+ default: await defaultFlagToCached(flag, respectNoCacheDefault),
826
777
  deprecated: flag.deprecated,
827
778
  deprecateAliases: c.deprecateAliases,
828
779
  aliases: flag.aliases,
829
780
  delimiter: flag.delimiter,
781
+ noCacheDefault: flag.noCacheDefault,
830
782
  };
831
783
  // a command-level placeholder in the manifest so that oclif knows it should regenerate the command during help-time
832
784
  if (typeof flag.defaultHelp === 'function') {
@@ -841,8 +793,9 @@ async function toCached(c, plugin, isWritingManifest) {
841
793
  description: arg.description,
842
794
  required: arg.required,
843
795
  options: arg.options,
844
- default: await defaultArgToCached(arg, isWritingManifest),
796
+ default: await defaultArgToCached(arg, respectNoCacheDefault),
845
797
  hidden: arg.hidden,
798
+ noCacheDefault: arg.noCacheDefault,
846
799
  };
847
800
  }
848
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 {};