@oclif/core 1.24.2 → 1.25.0
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.
- package/lib/config/config.d.ts +2 -0
- package/lib/config/config.js +47 -13
- package/lib/config/plugin.js +6 -1
- package/lib/help/command.js +1 -1
- package/lib/help/docopts.js +2 -1
- package/lib/interfaces/hooks.d.ts +11 -0
- package/lib/interfaces/pjson.d.ts +2 -0
- package/lib/interfaces/plugin.d.ts +1 -0
- package/lib/util.d.ts +11 -0
- package/lib/util.js +12 -1
- package/package.json +1 -1
package/lib/config/config.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ export declare class Config implements IConfig {
|
|
|
39
39
|
constructor(options: Options);
|
|
40
40
|
static load(opts?: LoadOptions): Promise<IConfig | Config>;
|
|
41
41
|
load(): Promise<void>;
|
|
42
|
+
loadPluginsAndCommands(): Promise<void>;
|
|
42
43
|
loadCorePlugins(): Promise<void>;
|
|
43
44
|
loadDevPlugins(): Promise<void>;
|
|
44
45
|
loadUserPlugins(): Promise<void>;
|
|
@@ -105,6 +106,7 @@ export declare class Config implements IConfig {
|
|
|
105
106
|
detail: string;
|
|
106
107
|
}, scope?: string): void;
|
|
107
108
|
protected get isProd(): boolean;
|
|
109
|
+
private isJitPluginCommand;
|
|
108
110
|
private getCmdLookupId;
|
|
109
111
|
private getTopicLookupId;
|
|
110
112
|
private loadCommands;
|
package/lib/config/config.js
CHANGED
|
@@ -135,6 +135,10 @@ class Config {
|
|
|
135
135
|
...s3.templates && s3.templates.vanilla,
|
|
136
136
|
},
|
|
137
137
|
};
|
|
138
|
+
await this.loadPluginsAndCommands();
|
|
139
|
+
debug('config done');
|
|
140
|
+
}
|
|
141
|
+
async loadPluginsAndCommands() {
|
|
138
142
|
await this.loadUserPlugins();
|
|
139
143
|
await this.loadDevPlugins();
|
|
140
144
|
await this.loadCorePlugins();
|
|
@@ -142,7 +146,6 @@ class Config {
|
|
|
142
146
|
this.loadCommands(plugin);
|
|
143
147
|
this.loadTopics(plugin);
|
|
144
148
|
}
|
|
145
|
-
debug('config done');
|
|
146
149
|
}
|
|
147
150
|
async loadCorePlugins() {
|
|
148
151
|
if (this.pjson.oclif.plugins) {
|
|
@@ -252,25 +255,48 @@ class Config {
|
|
|
252
255
|
// eslint-disable-next-line default-param-last
|
|
253
256
|
async runCommand(id, argv = [], cachedCommand) {
|
|
254
257
|
debug('runCommand %s %o', id, argv);
|
|
255
|
-
|
|
258
|
+
let c = cachedCommand || this.findCommand(id);
|
|
256
259
|
if (!c) {
|
|
257
260
|
const matches = this.flexibleTaxonomy ? this.findMatches(id, argv) : [];
|
|
258
261
|
const hookResult = this.flexibleTaxonomy && matches.length > 0 ?
|
|
259
262
|
await this.runHook('command_incomplete', { id, argv, matches }) :
|
|
260
263
|
await this.runHook('command_not_found', { id, argv });
|
|
261
|
-
if (hookResult.successes[0])
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
if (hookResult.failures[0]) {
|
|
264
|
+
if (hookResult.successes[0])
|
|
265
|
+
return hookResult.successes[0].result;
|
|
266
|
+
if (hookResult.failures[0])
|
|
266
267
|
throw hookResult.failures[0].error;
|
|
267
|
-
}
|
|
268
268
|
throw new errors_1.CLIError(`command ${id} not found`);
|
|
269
269
|
}
|
|
270
|
+
if (this.isJitPluginCommand(c)) {
|
|
271
|
+
const pluginName = c.pluginName;
|
|
272
|
+
const pluginVersion = this.pjson.oclif.jitPlugins[pluginName];
|
|
273
|
+
const jitResult = await this.runHook('jit_plugin_not_installed', {
|
|
274
|
+
id,
|
|
275
|
+
argv,
|
|
276
|
+
command: c,
|
|
277
|
+
pluginName,
|
|
278
|
+
pluginVersion,
|
|
279
|
+
});
|
|
280
|
+
if (jitResult.failures[0])
|
|
281
|
+
throw jitResult.failures[0].error;
|
|
282
|
+
if (jitResult.successes[0]) {
|
|
283
|
+
await this.loadPluginsAndCommands();
|
|
284
|
+
c = this.findCommand(id) ?? c;
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
// this means that no jit_plugin_not_installed hook exists, so we should run the default behavior
|
|
288
|
+
const result = await this.runHook('command_not_found', { id, argv });
|
|
289
|
+
if (result.successes[0])
|
|
290
|
+
return result.successes[0].result;
|
|
291
|
+
if (result.failures[0])
|
|
292
|
+
throw result.failures[0].error;
|
|
293
|
+
throw new errors_1.CLIError(`command ${id} not found`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
270
296
|
const command = await c.load();
|
|
271
297
|
await this.runHook('prerun', { Command: command, argv });
|
|
272
298
|
const result = (await command.run(argv, this));
|
|
273
|
-
await this.runHook('postrun', { Command: command, result
|
|
299
|
+
await this.runHook('postrun', { Command: command, result, argv });
|
|
274
300
|
return result;
|
|
275
301
|
}
|
|
276
302
|
scopedEnvVar(k) {
|
|
@@ -489,6 +515,9 @@ class Config {
|
|
|
489
515
|
get isProd() {
|
|
490
516
|
return (0, util_3.isProd)();
|
|
491
517
|
}
|
|
518
|
+
isJitPluginCommand(c) {
|
|
519
|
+
return Object.keys(this.pjson.oclif.jitPlugins ?? {}).includes(c.pluginName ?? '') && !this.plugins.find(p => p.name === c?.pluginName);
|
|
520
|
+
}
|
|
492
521
|
getCmdLookupId(id) {
|
|
493
522
|
if (this._commands.has(id))
|
|
494
523
|
return id;
|
|
@@ -597,6 +626,14 @@ class Config {
|
|
|
597
626
|
if (a.pluginType === 'core' && b.pluginType !== 'core') {
|
|
598
627
|
return -1;
|
|
599
628
|
}
|
|
629
|
+
// if a is a jit plugin and b is not sort b first
|
|
630
|
+
if (a.pluginType === 'jit' && b.pluginType !== 'jit') {
|
|
631
|
+
return 1;
|
|
632
|
+
}
|
|
633
|
+
// if b is a jit plugin and a is not sort a first
|
|
634
|
+
if (b.pluginType === 'jit' && a.pluginType !== 'jit') {
|
|
635
|
+
return -1;
|
|
636
|
+
}
|
|
600
637
|
// neither plugin is core, so do not change the order
|
|
601
638
|
return 0;
|
|
602
639
|
});
|
|
@@ -677,10 +714,7 @@ async function toCached(c, plugin) {
|
|
|
677
714
|
}
|
|
678
715
|
}
|
|
679
716
|
}
|
|
680
|
-
|
|
681
|
-
// @ts-ignore
|
|
682
|
-
const normalized = Array.isArray(c.args) ? c.args ?? [] : Object.entries(c.args ?? {}).map(([name, arg]) => ({ ...arg, name }));
|
|
683
|
-
const argsPromise = normalized.map(async (a) => ({
|
|
717
|
+
const argsPromise = (0, util_3.ensureArgArray)(c.args).map(async (a) => ({
|
|
684
718
|
name: a.name,
|
|
685
719
|
description: a.description,
|
|
686
720
|
required: a.required,
|
package/lib/config/plugin.js
CHANGED
|
@@ -127,7 +127,12 @@ class Plugin {
|
|
|
127
127
|
this.manifest = await this._manifest(Boolean(this.options.ignoreManifest), Boolean(this.options.errorOnManifestCreate));
|
|
128
128
|
this.commands = Object
|
|
129
129
|
.entries(this.manifest.commands)
|
|
130
|
-
.map(([id, c]) => ({
|
|
130
|
+
.map(([id, c]) => ({
|
|
131
|
+
...c,
|
|
132
|
+
pluginAlias: this.alias,
|
|
133
|
+
pluginType: c.pluginType === 'jit' ? 'jit' : this.type,
|
|
134
|
+
load: async () => this.findCommand(id, { must: true }),
|
|
135
|
+
}))
|
|
131
136
|
.sort((a, b) => a.id.localeCompare(b.id));
|
|
132
137
|
}
|
|
133
138
|
get topics() {
|
package/lib/help/command.js
CHANGED
|
@@ -31,7 +31,7 @@ class CommandHelp extends formatter_1.HelpFormatter {
|
|
|
31
31
|
v.name = k;
|
|
32
32
|
return v;
|
|
33
33
|
}), f => [!f.char, f.char, f.name]);
|
|
34
|
-
const args = (cmd.args
|
|
34
|
+
const args = (0, util_1.ensureArgArray)(cmd.args).filter(a => !a.hidden);
|
|
35
35
|
const output = (0, util_1.compact)(this.sections().map(({ header, generate }) => {
|
|
36
36
|
const body = generate({ cmd, flags, args }, header);
|
|
37
37
|
// Generate can return a list of sections
|
package/lib/help/docopts.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DocOpts = void 0;
|
|
4
|
+
const util_1 = require("../util");
|
|
4
5
|
/**
|
|
5
6
|
* DocOpts - See http://docopt.org/.
|
|
6
7
|
*
|
|
@@ -75,7 +76,7 @@ class DocOpts {
|
|
|
75
76
|
toString() {
|
|
76
77
|
const opts = this.cmd.id === '.' || this.cmd.id === '' ? [] : ['<%= command.id %>'];
|
|
77
78
|
if (this.cmd.args) {
|
|
78
|
-
const a = this.cmd.args
|
|
79
|
+
const a = (0, util_1.ensureArgArray)(this.cmd.args).map(arg => `[${arg.name.toUpperCase()}]`) || [];
|
|
79
80
|
opts.push(...a);
|
|
80
81
|
}
|
|
81
82
|
try {
|
|
@@ -58,6 +58,16 @@ export interface Hooks {
|
|
|
58
58
|
};
|
|
59
59
|
return: unknown;
|
|
60
60
|
};
|
|
61
|
+
'jit_plugin_not_installed': {
|
|
62
|
+
options: {
|
|
63
|
+
id: string;
|
|
64
|
+
argv: string[];
|
|
65
|
+
command: Command.Loadable;
|
|
66
|
+
pluginName: string;
|
|
67
|
+
pluginVersion: string;
|
|
68
|
+
};
|
|
69
|
+
return: unknown;
|
|
70
|
+
};
|
|
61
71
|
'plugins:preinstall': {
|
|
62
72
|
options: {
|
|
63
73
|
plugin: {
|
|
@@ -84,6 +94,7 @@ export declare namespace Hook {
|
|
|
84
94
|
type Update = Hook<'update'>;
|
|
85
95
|
type CommandNotFound = Hook<'command_not_found'>;
|
|
86
96
|
type CommandIncomplete = Hook<'command_incomplete'>;
|
|
97
|
+
type JitPluginNotInstalled = Hook<'jit_plugin_not_installed'>;
|
|
87
98
|
interface Context {
|
|
88
99
|
config: Config;
|
|
89
100
|
exit(code?: number): void;
|
|
@@ -27,6 +27,7 @@ export declare namespace PJSON {
|
|
|
27
27
|
default?: string;
|
|
28
28
|
plugins?: string[];
|
|
29
29
|
devPlugins?: string[];
|
|
30
|
+
jitPlugins?: Record<string, string>;
|
|
30
31
|
helpClass?: string;
|
|
31
32
|
helpOptions?: HelpOptions;
|
|
32
33
|
aliases?: {
|
|
@@ -83,6 +84,7 @@ export declare namespace PJSON {
|
|
|
83
84
|
scope?: string;
|
|
84
85
|
dirname?: string;
|
|
85
86
|
flexibleTaxonomy?: boolean;
|
|
87
|
+
jitPlugins?: Record<string, string>;
|
|
86
88
|
};
|
|
87
89
|
}
|
|
88
90
|
interface User extends PJSON {
|
package/lib/util.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ArgInput } from './interfaces';
|
|
1
2
|
export declare function compact<T>(a: (T | undefined)[]): T[];
|
|
2
3
|
export declare function uniqBy<T>(arr: T[], fn: (cur: T) => any): T[];
|
|
3
4
|
type SortTypes = string | number | undefined | boolean;
|
|
@@ -7,4 +8,14 @@ export declare function isProd(): boolean;
|
|
|
7
8
|
export declare function maxBy<T>(arr: T[], fn: (i: T) => number): T | undefined;
|
|
8
9
|
export declare function sumBy<T>(arr: T[], fn: (i: T) => number): number;
|
|
9
10
|
export declare function capitalize(s: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Ensure that the args are in an array instead of an object. This is required to ensure
|
|
13
|
+
* forwards compatibility with the new arg format in v2.
|
|
14
|
+
*
|
|
15
|
+
* @param args The args to ensure are in an array
|
|
16
|
+
* @returns ArgInput
|
|
17
|
+
*/
|
|
18
|
+
export declare function ensureArgArray(args?: ArgInput | {
|
|
19
|
+
[name: string]: any;
|
|
20
|
+
}): ArgInput;
|
|
10
21
|
export {};
|
package/lib/util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.capitalize = exports.sumBy = exports.maxBy = exports.isProd = exports.castArray = exports.sortBy = exports.uniqBy = exports.compact = void 0;
|
|
3
|
+
exports.ensureArgArray = exports.capitalize = exports.sumBy = exports.maxBy = exports.isProd = exports.castArray = exports.sortBy = exports.uniqBy = exports.compact = void 0;
|
|
4
4
|
function compact(a) {
|
|
5
5
|
return a.filter((a) => Boolean(a));
|
|
6
6
|
}
|
|
@@ -62,3 +62,14 @@ function capitalize(s) {
|
|
|
62
62
|
return s ? s.charAt(0).toUpperCase() + s.slice(1).toLowerCase() : '';
|
|
63
63
|
}
|
|
64
64
|
exports.capitalize = capitalize;
|
|
65
|
+
/**
|
|
66
|
+
* Ensure that the args are in an array instead of an object. This is required to ensure
|
|
67
|
+
* forwards compatibility with the new arg format in v2.
|
|
68
|
+
*
|
|
69
|
+
* @param args The args to ensure are in an array
|
|
70
|
+
* @returns ArgInput
|
|
71
|
+
*/
|
|
72
|
+
function ensureArgArray(args) {
|
|
73
|
+
return Array.isArray(args) ? args ?? [] : Object.entries(args ?? {}).map(([name, arg]) => ({ ...arg, name }));
|
|
74
|
+
}
|
|
75
|
+
exports.ensureArgArray = ensureArgArray;
|