@oclif/core 2.14.0 → 3.0.0-beta.10

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 (52) hide show
  1. package/README.md +8 -6
  2. package/flush.js +1 -1
  3. package/handle.js +1 -1
  4. package/lib/cli-ux/action/base.js +2 -2
  5. package/lib/cli-ux/config.d.ts +0 -1
  6. package/lib/cli-ux/config.js +1 -4
  7. package/lib/cli-ux/exit.d.ts +1 -1
  8. package/lib/cli-ux/exit.js +1 -1
  9. package/lib/cli-ux/flush.d.ts +1 -0
  10. package/lib/cli-ux/flush.js +28 -0
  11. package/lib/cli-ux/index.d.ts +1 -3
  12. package/lib/cli-ux/index.js +7 -31
  13. package/lib/cli-ux/styled/json.js +1 -1
  14. package/lib/command.d.ts +2 -0
  15. package/lib/config/config.d.ts +8 -12
  16. package/lib/config/config.js +73 -162
  17. package/lib/config/index.d.ts +2 -1
  18. package/lib/config/index.js +2 -1
  19. package/lib/config/plugin-loader.d.ts +30 -0
  20. package/lib/config/plugin-loader.js +129 -0
  21. package/lib/config/plugin.d.ts +5 -10
  22. package/lib/config/plugin.js +21 -17
  23. package/lib/config/ts-node.d.ts +3 -2
  24. package/lib/config/ts-node.js +83 -36
  25. package/lib/errors/errors/cli.d.ts +1 -0
  26. package/lib/errors/errors/cli.js +1 -0
  27. package/lib/errors/handle.d.ts +2 -2
  28. package/lib/errors/handle.js +3 -3
  29. package/lib/errors/index.d.ts +1 -0
  30. package/lib/errors/index.js +8 -1
  31. package/lib/execute.d.ts +49 -0
  32. package/lib/execute.js +62 -0
  33. package/lib/flags.js +4 -3
  34. package/lib/help/index.js +2 -2
  35. package/lib/index.d.ts +6 -4
  36. package/lib/index.js +9 -6
  37. package/lib/interfaces/config.d.ts +25 -26
  38. package/lib/interfaces/index.d.ts +14 -14
  39. package/lib/interfaces/parser.d.ts +14 -66
  40. package/lib/interfaces/pjson.d.ts +2 -0
  41. package/lib/interfaces/plugin.d.ts +8 -3
  42. package/lib/interfaces/ts-config.d.ts +9 -0
  43. package/lib/main.d.ts +1 -54
  44. package/lib/main.js +10 -72
  45. package/lib/module-loader.d.ts +1 -2
  46. package/lib/module-loader.js +5 -5
  47. package/lib/parser/parse.js +1 -34
  48. package/lib/performance.d.ts +1 -1
  49. package/lib/performance.js +1 -2
  50. package/package.json +14 -13
  51. package/lib/cli-ux/action/pride-spinner.d.ts +0 -4
  52. package/lib/cli-ux/action/pride-spinner.js +0 -30
@@ -7,7 +7,6 @@ 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");
@@ -15,8 +14,9 @@ const help_1 = require("../help");
15
14
  const stream_1 = require("../cli-ux/stream");
16
15
  const performance_1 = require("../performance");
17
16
  const settings_1 = require("../settings");
18
- const os_1 = require("os");
19
- const path_1 = require("path");
17
+ const node_os_1 = require("node:os");
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');
@@ -63,31 +63,13 @@ class Config {
63
63
  this.options = options;
64
64
  this._base = BASE;
65
65
  this.debug = 0;
66
- this.plugins = [];
66
+ this.plugins = new Map();
67
67
  this.topicSeparator = ':';
68
68
  this.warned = false;
69
69
  this.commandPermutations = new Permutations();
70
70
  this.topicPermutations = new Permutations();
71
71
  this._commands = new Map();
72
72
  this._topics = new Map();
73
- if (options.config) {
74
- if (Array.isArray(options.config.plugins) && Array.isArray(this.plugins)) {
75
- // incoming config is v2 with plugins array and this config is v2 with plugins array
76
- Object.assign(this, options.config);
77
- }
78
- else if (Array.isArray(options.config.plugins) && !Array.isArray(this.plugins)) {
79
- // incoming config is v2 with plugins array and this config is v3 with plugin Map
80
- Object.assign(this, options.config, { plugins: new Map(options.config.plugins.map(p => [p.name, p])) });
81
- }
82
- else if (!Array.isArray(options.config.plugins) && Array.isArray(this.plugins)) {
83
- // incoming config is v3 with plugin Map and this config is v2 with plugins array
84
- Object.assign(this, options.config, { plugins: options.config.getPluginsList() });
85
- }
86
- else {
87
- // incoming config is v3 with plugin Map and this config is v3 with plugin Map
88
- Object.assign(this, options.config);
89
- }
90
- }
91
73
  }
92
74
  static async load(opts = module.filename || __dirname) {
93
75
  // Handle the case when a file URL string is passed in such as 'import.meta.url'; covert to file path.
@@ -97,9 +79,6 @@ class Config {
97
79
  if (typeof opts === 'string')
98
80
  opts = { root: opts };
99
81
  if (isConfig(opts)) {
100
- const { lt } = await import('semver');
101
- const currentConfigBase = BASE.replace('@oclif/core@', '');
102
- const incomingConfigBase = opts._base.replace('@oclif/core@', '');
103
82
  /**
104
83
  * Reload the Config based on the version required by the command.
105
84
  * This is needed because the command is given the Config instantiated
@@ -110,9 +89,11 @@ class Config {
110
89
  * exists in the version of Config required by the command but may not exist on the
111
90
  * root's instance of Config.
112
91
  */
113
- if (lt(incomingConfigBase, currentConfigBase)) {
92
+ if (BASE !== opts._base) {
114
93
  debug(`reloading config from ${opts._base} to ${BASE}`);
115
- return new Config({ ...opts.options, config: opts });
94
+ const config = new Config({ ...opts.options, plugins: opts.plugins });
95
+ await config.load();
96
+ return config;
116
97
  }
117
98
  return opts;
118
99
  }
@@ -120,20 +101,23 @@ class Config {
120
101
  await config.load();
121
102
  return config;
122
103
  }
104
+ static get rootPlugin() {
105
+ return Config._rootPlugin;
106
+ }
123
107
  // eslint-disable-next-line complexity
124
108
  async load() {
125
- if (this.options.config)
126
- return;
127
109
  settings_1.settings.performanceEnabled = (settings_1.settings.performanceEnabled === undefined ? this.options.enablePerf : settings_1.settings.performanceEnabled) ?? false;
128
- const plugin = new Plugin.Plugin({ root: this.options.root });
129
- await plugin.load();
130
- this.plugins.push(plugin);
131
- this.root = plugin.root;
132
- this.pjson = plugin.pjson;
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;
133
117
  this.name = this.pjson.name;
134
118
  this.version = this.options.version || this.pjson.version || '0.0.0';
135
119
  this.channel = this.options.channel || channelFromVersion(this.version);
136
- this.valid = plugin.valid;
120
+ this.valid = Config._rootPlugin.valid;
137
121
  this.arch = (os.arch() === 'ia32' ? 'x86' : os.arch());
138
122
  this.platform = WSL ? 'wsl' : os.platform();
139
123
  this.windows = this.platform === 'win32';
@@ -181,70 +165,38 @@ class Config {
181
165
  ...s3.templates && s3.templates.vanilla,
182
166
  },
183
167
  };
184
- const marker = performance_1.Performance.mark('config.load');
168
+ const marker = performance_1.default.mark('config.load');
185
169
  await this.loadPluginsAndCommands();
186
170
  debug('config done');
187
171
  marker?.addDetails({
188
- plugins: this.plugins.length,
172
+ plugins: this.plugins.size,
189
173
  commandPermutations: this.commands.length,
190
- commands: this.plugins.reduce((acc, p) => acc + p.commands.length, 0),
174
+ commands: [...this.plugins.values()].reduce((acc, p) => acc + p.commands.length, 0),
191
175
  topics: this.topics.length,
192
176
  });
193
177
  marker?.stop();
194
178
  }
195
- async loadPluginsAndCommands() {
196
- const marker = performance_1.Performance.mark('config.loadPluginsAndCommands');
197
- await this.loadUserPlugins();
198
- await this.loadDevPlugins();
199
- await this.loadCorePlugins();
200
- 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()) {
201
190
  this.loadCommands(plugin);
202
191
  this.loadTopics(plugin);
203
192
  }
204
- marker?.stop();
205
- }
206
- async loadCorePlugins() {
207
- if (this.pjson.oclif.plugins) {
208
- await this.loadPlugins(this.root, 'core', this.pjson.oclif.plugins);
209
- }
210
- }
211
- async loadDevPlugins() {
212
- if (this.options.devPlugins !== false) {
213
- // do not load oclif.devPlugins in production
214
- if (this.isProd)
215
- return;
216
- try {
217
- const devPlugins = this.pjson.oclif.devPlugins;
218
- if (devPlugins)
219
- await this.loadPlugins(this.root, 'dev', devPlugins);
220
- }
221
- catch (error) {
222
- process.emitWarning(error);
223
- }
224
- }
225
- }
226
- async loadUserPlugins() {
227
- if (this.options.userPlugins !== false) {
228
- try {
229
- const userPJSONPath = path.join(this.dataDir, 'package.json');
230
- debug('reading user plugins pjson %s', userPJSONPath);
231
- const pjson = await (0, util_2.loadJSON)(userPJSONPath);
232
- this.userPJSON = pjson;
233
- if (!pjson.oclif)
234
- pjson.oclif = { schema: 1 };
235
- if (!pjson.oclif.plugins)
236
- pjson.oclif.plugins = [];
237
- await this.loadPlugins(userPJSONPath, 'user', pjson.oclif.plugins.filter((p) => p.type === 'user'));
238
- await this.loadPlugins(userPJSONPath, 'link', pjson.oclif.plugins.filter((p) => p.type === 'link'));
239
- }
240
- catch (error) {
241
- if (error.code !== 'ENOENT')
242
- process.emitWarning(error);
243
- }
193
+ for (const error of errors) {
194
+ this.warn(error);
244
195
  }
196
+ marker?.stop();
245
197
  }
246
198
  async runHook(event, opts, timeout, captureErrors) {
247
- const marker = performance_1.Performance.mark(`config.runHook#${event}`);
199
+ const marker = performance_1.default.mark(`config.runHook#${event}`);
248
200
  debug('start %s hook', event);
249
201
  const search = (m) => {
250
202
  if (typeof m === 'function')
@@ -269,7 +221,7 @@ class Config {
269
221
  successes: [],
270
222
  failures: [],
271
223
  };
272
- const promises = this.plugins.map(async (p) => {
224
+ const promises = [...this.plugins.values()].map(async (p) => {
273
225
  const debug = require('debug')([this.bin, p.name, 'hooks', event].join(':'));
274
226
  const context = {
275
227
  config: this,
@@ -289,7 +241,7 @@ class Config {
289
241
  };
290
242
  const hooks = p.hooks[event] || [];
291
243
  for (const hook of hooks) {
292
- const marker = performance_1.Performance.mark(`config.runHook#${p.name}(${hook})`);
244
+ const marker = performance_1.default.mark(`config.runHook#${p.name}(${hook})`);
293
245
  try {
294
246
  /* eslint-disable no-await-in-loop */
295
247
  const { isESM, module, filePath } = await module_loader_1.default.loadWithData(p, hook);
@@ -323,7 +275,7 @@ class Config {
323
275
  return final;
324
276
  }
325
277
  async runCommand(id, argv = [], cachedCommand = null) {
326
- const marker = performance_1.Performance.mark(`config.runCommand#${id}`);
278
+ const marker = performance_1.default.mark(`config.runCommand#${id}`);
327
279
  debug('runCommand %s %o', id, argv);
328
280
  let c = cachedCommand ?? this.findCommand(id);
329
281
  if (!c) {
@@ -350,7 +302,7 @@ class Config {
350
302
  if (jitResult.failures[0])
351
303
  throw jitResult.failures[0].error;
352
304
  if (jitResult.successes[0]) {
353
- await this.loadPluginsAndCommands();
305
+ await this.loadPluginsAndCommands({ force: true });
354
306
  c = this.findCommand(id) ?? c;
355
307
  }
356
308
  else {
@@ -477,7 +429,7 @@ class Config {
477
429
  cliVersion,
478
430
  architecture,
479
431
  nodeVersion,
480
- 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 }])),
481
433
  osVersion: `${os.type()} ${os.release()}`,
482
434
  shell: this.shell,
483
435
  rootPath: this.root,
@@ -500,7 +452,7 @@ class Config {
500
452
  return url.toString();
501
453
  }
502
454
  getPluginsList() {
503
- return this.plugins;
455
+ return [...this.plugins.values()];
504
456
  }
505
457
  dir(category) {
506
458
  const base = process.env[`XDG_${category.toUpperCase()}_HOME`] ||
@@ -523,7 +475,7 @@ class Config {
523
475
  _shell() {
524
476
  let shellPath;
525
477
  const COMSPEC = process.env.COMSPEC;
526
- const SHELL = process.env.SHELL ?? (0, os_1.userInfo)().shell?.split(path_1.sep)?.pop();
478
+ const SHELL = process.env.SHELL ?? (0, node_os_1.userInfo)().shell?.split(node_path_1.sep)?.pop();
527
479
  if (SHELL) {
528
480
  shellPath = SHELL.split('/');
529
481
  }
@@ -546,52 +498,6 @@ class Config {
546
498
  catch { }
547
499
  return 0;
548
500
  }
549
- async loadPlugins(root, type, plugins, parent) {
550
- if (!plugins || plugins.length === 0)
551
- return;
552
- const mark = performance_1.Performance.mark(`config.loadPlugins#${type}`);
553
- debug('loading plugins', plugins);
554
- await Promise.all((plugins || []).map(async (plugin) => {
555
- try {
556
- const opts = { type, root };
557
- if (typeof plugin === 'string') {
558
- opts.name = plugin;
559
- }
560
- else {
561
- opts.name = plugin.name || opts.name;
562
- opts.tag = plugin.tag || opts.tag;
563
- opts.root = plugin.root || opts.root;
564
- }
565
- const pluginMarker = performance_1.Performance.mark(`plugin.load#${opts.name}`);
566
- const instance = new Plugin.Plugin(opts);
567
- await instance.load();
568
- pluginMarker?.addDetails({
569
- hasManifest: instance.hasManifest,
570
- commandCount: instance.commands.length,
571
- topicCount: instance.topics.length,
572
- type: instance.type,
573
- usesMain: Boolean(instance.pjson.main),
574
- name: instance.name,
575
- });
576
- pluginMarker?.stop();
577
- if (this.plugins.find(p => p.name === instance.name))
578
- return;
579
- this.plugins.push(instance);
580
- if (parent) {
581
- instance.parent = parent;
582
- if (!parent.children)
583
- parent.children = [];
584
- parent.children.push(instance);
585
- }
586
- await this.loadPlugins(instance.root, type, instance.pjson.oclif.plugins || [], instance);
587
- }
588
- catch (error) {
589
- this.warn(error, 'loadPlugins');
590
- }
591
- }));
592
- mark?.addDetails({ pluginCount: plugins.length });
593
- mark?.stop();
594
- }
595
501
  warn(err, scope) {
596
502
  if (this.warned)
597
503
  return;
@@ -630,7 +536,8 @@ class Config {
630
536
  return (0, util_3.isProd)();
631
537
  }
632
538
  isJitPluginCommand(c) {
633
- 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));
634
541
  }
635
542
  getCmdLookupId(id) {
636
543
  if (this._commands.has(id))
@@ -647,8 +554,9 @@ class Config {
647
554
  return id;
648
555
  }
649
556
  loadCommands(plugin) {
650
- 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 });
651
558
  for (const command of plugin.commands) {
559
+ // set canonical command id
652
560
  if (this._commands.has(command.id)) {
653
561
  const prioritizedCommand = this.determinePriority([this._commands.get(command.id), command]);
654
562
  this._commands.set(prioritizedCommand.id, prioritizedCommand);
@@ -656,10 +564,11 @@ class Config {
656
564
  else {
657
565
  this._commands.set(command.id, command);
658
566
  }
659
- const permutations = this.flexibleTaxonomy ? (0, util_2.getCommandIdPermutations)(command.id) : [command.id];
660
- for (const permutation of permutations) {
567
+ // set every permutation
568
+ for (const permutation of command.permutations ?? [command.id]) {
661
569
  this.commandPermutations.add(permutation, command.id);
662
570
  }
571
+ // set command aliases
663
572
  for (const alias of command.aliases ?? []) {
664
573
  if (this._commands.has(alias)) {
665
574
  const prioritizedCommand = this.determinePriority([this._commands.get(alias), command]);
@@ -668,8 +577,8 @@ class Config {
668
577
  else {
669
578
  this._commands.set(alias, { ...command, id: alias });
670
579
  }
671
- const aliasPermutations = this.flexibleTaxonomy ? (0, util_2.getCommandIdPermutations)(alias) : [alias];
672
- for (const permutation of aliasPermutations) {
580
+ // set every permutation of the aliases
581
+ for (const permutation of command.aliasPermutations ?? [alias]) {
673
582
  this.commandPermutations.add(permutation, command.id);
674
583
  }
675
584
  }
@@ -678,7 +587,7 @@ class Config {
678
587
  marker?.stop();
679
588
  }
680
589
  loadTopics(plugin) {
681
- 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 });
682
591
  for (const topic of (0, util_2.compact)(plugin.topics)) {
683
592
  const existing = this._topics.get(topic.name);
684
593
  if (existing) {
@@ -769,23 +678,20 @@ class Config {
769
678
  */
770
679
  insertLegacyPlugins(plugins) {
771
680
  for (const plugin of plugins) {
772
- const idx = this.plugins.findIndex(p => p.name === plugin.name);
773
- if (idx !== -1) {
774
- // invalid plugin instance found in `this.plugins`
775
- // replace with the oclif-compatible one
776
- this.plugins.splice(idx, 1, plugin);
777
- }
681
+ this.plugins.set(plugin.name, plugin);
778
682
  this.loadCommands(plugin);
779
683
  }
780
684
  }
781
685
  }
782
686
  exports.Config = Config;
783
687
  // when no manifest exists, the default is calculated. This may throw, so we need to catch it
784
- const defaultFlagToCached = async (flag, isWritingManifest = false) => {
785
- // 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)
786
692
  if (typeof flag.defaultHelp === 'function') {
787
693
  try {
788
- return await flag.defaultHelp({ options: flag, flags: {} }, isWritingManifest);
694
+ return await flag.defaultHelp({ options: flag, flags: {} });
789
695
  }
790
696
  catch {
791
697
  return;
@@ -794,7 +700,7 @@ const defaultFlagToCached = async (flag, isWritingManifest = false) => {
794
700
  // if not specified, try the default function
795
701
  if (typeof flag.default === 'function') {
796
702
  try {
797
- return await flag.default({ options: flag, flags: {} }, isWritingManifest);
703
+ return await flag.default({ options: flag, flags: {} });
798
704
  }
799
705
  catch { }
800
706
  }
@@ -802,11 +708,13 @@ const defaultFlagToCached = async (flag, isWritingManifest = false) => {
802
708
  return flag.default;
803
709
  }
804
710
  };
805
- const defaultArgToCached = async (arg, isWritingManifest = false) => {
806
- // 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)
807
715
  if (typeof arg.defaultHelp === 'function') {
808
716
  try {
809
- return await arg.defaultHelp({ options: arg, flags: {} }, isWritingManifest);
717
+ return await arg.defaultHelp({ options: arg, flags: {} });
810
718
  }
811
719
  catch {
812
720
  return;
@@ -815,7 +723,7 @@ const defaultArgToCached = async (arg, isWritingManifest = false) => {
815
723
  // if not specified, try the default function
816
724
  if (typeof arg.default === 'function') {
817
725
  try {
818
- return await arg.default({ options: arg, flags: {} }, isWritingManifest);
726
+ return await arg.default({ options: arg, flags: {} });
819
727
  }
820
728
  catch { }
821
729
  }
@@ -823,7 +731,7 @@ const defaultArgToCached = async (arg, isWritingManifest = false) => {
823
731
  return arg.default;
824
732
  }
825
733
  };
826
- async function toCached(c, plugin, isWritingManifest) {
734
+ async function toCached(c, plugin, respectNoCacheDefault = false) {
827
735
  const flags = {};
828
736
  for (const [name, flag] of Object.entries(c.flags || {})) {
829
737
  if (flag.type === 'boolean') {
@@ -845,6 +753,7 @@ async function toCached(c, plugin, isWritingManifest) {
845
753
  deprecateAliases: c.deprecateAliases,
846
754
  aliases: flag.aliases,
847
755
  delimiter: flag.delimiter,
756
+ noCacheDefault: flag.noCacheDefault,
848
757
  };
849
758
  }
850
759
  else {
@@ -864,11 +773,12 @@ async function toCached(c, plugin, isWritingManifest) {
864
773
  dependsOn: flag.dependsOn,
865
774
  relationships: flag.relationships,
866
775
  exclusive: flag.exclusive,
867
- default: await defaultFlagToCached(flag, isWritingManifest),
776
+ default: await defaultFlagToCached(flag, respectNoCacheDefault),
868
777
  deprecated: flag.deprecated,
869
778
  deprecateAliases: c.deprecateAliases,
870
779
  aliases: flag.aliases,
871
780
  delimiter: flag.delimiter,
781
+ noCacheDefault: flag.noCacheDefault,
872
782
  };
873
783
  // a command-level placeholder in the manifest so that oclif knows it should regenerate the command during help-time
874
784
  if (typeof flag.defaultHelp === 'function') {
@@ -883,8 +793,9 @@ async function toCached(c, plugin, isWritingManifest) {
883
793
  description: arg.description,
884
794
  required: arg.required,
885
795
  options: arg.options,
886
- default: await defaultArgToCached(arg, isWritingManifest),
796
+ default: await defaultArgToCached(arg, respectNoCacheDefault),
887
797
  hidden: arg.hidden,
798
+ noCacheDefault: arg.noCacheDefault,
888
799
  };
889
800
  }
890
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 {};
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path = require("path");
4
+ const Plugin = require("./plugin");
5
+ const util_1 = require("./util");
6
+ const util_2 = require("../util");
7
+ const performance_1 = require("../performance");
8
+ // eslint-disable-next-line new-cap
9
+ const debug = (0, util_1.Debug)();
10
+ class PluginLoader {
11
+ constructor(options) {
12
+ this.options = options;
13
+ this.plugins = new Map();
14
+ this.errors = [];
15
+ this.pluginsProvided = false;
16
+ if (options.plugins) {
17
+ this.pluginsProvided = true;
18
+ this.plugins = Array.isArray(options.plugins) ? new Map(options.plugins.map(p => [p.name, p])) : options.plugins;
19
+ }
20
+ }
21
+ async loadRoot() {
22
+ let rootPlugin;
23
+ if (this.pluginsProvided) {
24
+ const plugins = [...this.plugins.values()];
25
+ rootPlugin = plugins.find(p => p.root === this.options.root) ?? plugins[0];
26
+ }
27
+ else {
28
+ rootPlugin = new Plugin.Plugin({ root: this.options.root });
29
+ await rootPlugin.load();
30
+ }
31
+ this.plugins.set(rootPlugin.name, rootPlugin);
32
+ return rootPlugin;
33
+ }
34
+ async loadChildren(opts) {
35
+ if (!this.pluginsProvided || opts.force) {
36
+ await this.loadUserPlugins(opts);
37
+ await this.loadDevPlugins(opts);
38
+ await this.loadCorePlugins(opts);
39
+ }
40
+ return { plugins: this.plugins, errors: this.errors };
41
+ }
42
+ async loadCorePlugins(opts) {
43
+ if (opts.rootPlugin.pjson.oclif.plugins) {
44
+ await this.loadPlugins(opts.rootPlugin.root, 'core', opts.rootPlugin.pjson.oclif.plugins);
45
+ }
46
+ }
47
+ async loadDevPlugins(opts) {
48
+ if (opts.devPlugins !== false) {
49
+ // do not load oclif.devPlugins in production
50
+ if ((0, util_2.isProd)())
51
+ return;
52
+ try {
53
+ const devPlugins = opts.rootPlugin.pjson.oclif.devPlugins;
54
+ if (devPlugins)
55
+ await this.loadPlugins(opts.rootPlugin.root, 'dev', devPlugins);
56
+ }
57
+ catch (error) {
58
+ process.emitWarning(error);
59
+ }
60
+ }
61
+ }
62
+ async loadUserPlugins(opts) {
63
+ if (opts.userPlugins !== false) {
64
+ try {
65
+ const userPJSONPath = path.join(opts.dataDir, 'package.json');
66
+ debug('reading user plugins pjson %s', userPJSONPath);
67
+ const pjson = await (0, util_1.loadJSON)(userPJSONPath);
68
+ if (!pjson.oclif)
69
+ pjson.oclif = { schema: 1 };
70
+ if (!pjson.oclif.plugins)
71
+ pjson.oclif.plugins = [];
72
+ await this.loadPlugins(userPJSONPath, 'user', pjson.oclif.plugins.filter((p) => p.type === 'user'));
73
+ await this.loadPlugins(userPJSONPath, 'link', pjson.oclif.plugins.filter((p) => p.type === 'link'));
74
+ }
75
+ catch (error) {
76
+ if (error.code !== 'ENOENT')
77
+ process.emitWarning(error);
78
+ }
79
+ }
80
+ }
81
+ async loadPlugins(root, type, plugins, parent) {
82
+ if (!plugins || plugins.length === 0)
83
+ return;
84
+ const mark = performance_1.default.mark(`config.loadPlugins#${type}`);
85
+ debug('loading plugins', plugins);
86
+ await Promise.all((plugins || []).map(async (plugin) => {
87
+ try {
88
+ const name = typeof plugin === 'string' ? plugin : plugin.name;
89
+ const opts = {
90
+ name,
91
+ type,
92
+ root,
93
+ };
94
+ if (typeof plugin !== 'string') {
95
+ opts.tag = plugin.tag || opts.tag;
96
+ opts.root = plugin.root || opts.root;
97
+ }
98
+ if (this.plugins.has(name))
99
+ return;
100
+ const pluginMarker = performance_1.default.mark(`plugin.load#${name}`);
101
+ const instance = new Plugin.Plugin(opts);
102
+ await instance.load();
103
+ pluginMarker?.addDetails({
104
+ hasManifest: instance.hasManifest,
105
+ commandCount: instance.commands.length,
106
+ topicCount: instance.topics.length,
107
+ type: instance.type,
108
+ usesMain: Boolean(instance.pjson.main),
109
+ name: instance.name,
110
+ });
111
+ pluginMarker?.stop();
112
+ this.plugins.set(instance.name, instance);
113
+ if (parent) {
114
+ instance.parent = parent;
115
+ if (!parent.children)
116
+ parent.children = [];
117
+ parent.children.push(instance);
118
+ }
119
+ await this.loadPlugins(instance.root, type, instance.pjson.oclif.plugins || [], instance);
120
+ }
121
+ catch (error) {
122
+ this.errors.push(error);
123
+ }
124
+ }));
125
+ mark?.addDetails({ pluginCount: plugins.length });
126
+ mark?.stop();
127
+ }
128
+ }
129
+ exports.default = PluginLoader;