@tsed/cli-core 7.0.0-beta.3 → 7.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.
- package/lib/esm/decorators/command.js +1 -1
- package/lib/esm/decorators/index.js +0 -4
- package/lib/esm/fn/command.js +31 -3
- package/lib/esm/interfaces/index.js +1 -1
- package/lib/esm/packageManagers/PackageManagersModule.js +0 -1
- package/lib/esm/services/CliPlugins.js +2 -2
- package/lib/esm/services/CliService.js +34 -51
- package/lib/esm/utils/getCommandMetadata.js +34 -7
- package/lib/types/decorators/command.d.ts +2 -2
- package/lib/types/decorators/index.d.ts +0 -4
- package/lib/types/fn/command.d.ts +58 -3
- package/lib/types/interfaces/CommandMetadata.d.ts +17 -15
- package/lib/types/interfaces/{CommandParameters.d.ts → CommandOptions.d.ts} +20 -3
- package/lib/types/interfaces/CommandProvider.d.ts +0 -10
- package/lib/types/interfaces/index.d.ts +3 -3
- package/lib/types/services/CliService.d.ts +1 -8
- package/lib/types/utils/mapCommanderArgs.d.ts +1 -1
- package/package.json +2 -2
- package/lib/esm/decorators/on.js +0 -8
- package/lib/esm/decorators/onAdd.js +0 -5
- package/lib/esm/decorators/onExec.js +0 -5
- package/lib/esm/decorators/onPostInstall.js +0 -5
- package/lib/esm/decorators/onPrompt.js +0 -5
- package/lib/esm/domains/CommandStoreKeys.js +0 -8
- package/lib/types/decorators/on.d.ts +0 -1
- package/lib/types/decorators/onAdd.d.ts +0 -1
- package/lib/types/decorators/onExec.d.ts +0 -1
- package/lib/types/decorators/onPostInstall.d.ts +0 -1
- package/lib/types/decorators/onPrompt.d.ts +0 -1
- package/lib/types/domains/CommandStoreKeys.d.ts +0 -7
- /package/lib/esm/interfaces/{CommandParameters.js → CommandOptions.js} +0 -0
package/lib/esm/fn/command.js
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
import { injectable } from "@tsed/di";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { JsonSchema } from "@tsed/schema";
|
|
3
|
+
JsonSchema.add("prompt", function prompt(label) {
|
|
4
|
+
this.customKey("x-label", label);
|
|
5
|
+
return this;
|
|
6
|
+
})
|
|
7
|
+
.add("when", function when(fn) {
|
|
8
|
+
this.customKey("x-when", fn);
|
|
9
|
+
return this;
|
|
10
|
+
})
|
|
11
|
+
.add("opt", function opt(v) {
|
|
12
|
+
this.customKey("x-opt", v);
|
|
13
|
+
return this;
|
|
14
|
+
})
|
|
15
|
+
.add("choices", function choices(choices) {
|
|
16
|
+
this.customKey("x-choices", choices);
|
|
17
|
+
return this;
|
|
18
|
+
});
|
|
19
|
+
export function command(options) {
|
|
20
|
+
if (!options.token) {
|
|
21
|
+
return injectable(Symbol.for(`COMMAND_${options.name}`))
|
|
22
|
+
.type("command")
|
|
23
|
+
.set("command", options)
|
|
24
|
+
.factory(() => {
|
|
25
|
+
return {
|
|
26
|
+
...options,
|
|
27
|
+
$prompt: options.prompt,
|
|
28
|
+
$exec: options.handler
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return injectable(options.token).type("command").set("command", options);
|
|
5
33
|
}
|
|
@@ -2,7 +2,7 @@ import { Type } from "@tsed/core";
|
|
|
2
2
|
export * from "./CliDefaultOptions.js";
|
|
3
3
|
export * from "./CommandData.js";
|
|
4
4
|
export * from "./CommandMetadata.js";
|
|
5
|
-
export * from "./
|
|
5
|
+
export * from "./CommandOptions.js";
|
|
6
6
|
export * from "./CommandProvider.js";
|
|
7
7
|
export * from "./PackageJson.js";
|
|
8
8
|
export * from "./ProjectPreferences.js";
|
|
@@ -102,7 +102,6 @@ export class PackageManagersModule {
|
|
|
102
102
|
selectedPackageManager = this.packageManagers.find((manager) => manager.name === "npm");
|
|
103
103
|
}
|
|
104
104
|
this.projectPackageJson.setPreference("packageManager", selectedPackageManager.name);
|
|
105
|
-
console.log("==", name, selectedPackageManager);
|
|
106
105
|
return selectedPackageManager;
|
|
107
106
|
}
|
|
108
107
|
runScript(scriptName, { ignoreError, ...opts } = {}) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { constant, inject, injectable } from "@tsed/di";
|
|
2
|
+
import { $asyncEmit } from "@tsed/hooks";
|
|
2
3
|
import chalk from "chalk";
|
|
3
|
-
import { CommandStoreKeys } from "../domains/CommandStoreKeys.js";
|
|
4
4
|
import { PackageManagersModule } from "../packageManagers/PackageManagersModule.js";
|
|
5
5
|
import { createSubTasks } from "../utils/createTasksRunner.js";
|
|
6
6
|
import { loadPlugins } from "../utils/loadPlugins.js";
|
|
@@ -33,7 +33,7 @@ export class CliPlugins {
|
|
|
33
33
|
return {
|
|
34
34
|
title: `Run plugin '${chalk.cyan(plugin)}'`,
|
|
35
35
|
task: () => {
|
|
36
|
-
return
|
|
36
|
+
return $asyncEmit("$onAddPlugin", [plugin, ctx]);
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
39
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { classOf } from "@tsed/core";
|
|
1
|
+
import { classOf, isArrowFn } from "@tsed/core";
|
|
2
2
|
import { configuration, constant, context, destroyInjector, DIContext, getContext, inject, injectable, injector, logger, Provider, runInContext } from "@tsed/di";
|
|
3
3
|
import { $asyncAlter, $asyncEmit } from "@tsed/hooks";
|
|
4
4
|
import { pascalCase } from "change-case";
|
|
@@ -6,11 +6,10 @@ import { Argument, Command } from "commander";
|
|
|
6
6
|
import Inquirer from "inquirer";
|
|
7
7
|
import inquirer_autocomplete_prompt from "inquirer-autocomplete-prompt";
|
|
8
8
|
import { v4 } from "uuid";
|
|
9
|
-
import { CommandStoreKeys } from "../domains/CommandStoreKeys.js";
|
|
10
9
|
import { PackageManagersModule } from "../packageManagers/index.js";
|
|
11
10
|
import { createSubTasks, createTasksRunner } from "../utils/createTasksRunner.js";
|
|
12
11
|
import { getCommandMetadata } from "../utils/getCommandMetadata.js";
|
|
13
|
-
import { mapCommanderOptions } from "../utils/index.js";
|
|
12
|
+
import { mapCommanderOptions, validate } from "../utils/index.js";
|
|
14
13
|
import { mapCommanderArgs } from "../utils/mapCommanderArgs.js";
|
|
15
14
|
import { parseOption } from "../utils/parseOption.js";
|
|
16
15
|
import { CliHooks } from "./CliHooks.js";
|
|
@@ -46,7 +45,6 @@ export class CliService {
|
|
|
46
45
|
return runInContext($ctx, async () => {
|
|
47
46
|
$ctx.set("dispatchCmd", cmdName);
|
|
48
47
|
await $asyncEmit("$loadPackageJson");
|
|
49
|
-
data = await this.beforePrompt(cmdName, data, $ctx);
|
|
50
48
|
data = await this.prompt(cmdName, data, $ctx);
|
|
51
49
|
try {
|
|
52
50
|
await this.exec(cmdName, data, $ctx);
|
|
@@ -61,41 +59,20 @@ export class CliService {
|
|
|
61
59
|
});
|
|
62
60
|
}
|
|
63
61
|
async exec(cmdName, data, $ctx) {
|
|
64
|
-
const
|
|
62
|
+
const tasks = await this.getTasks(cmdName, data);
|
|
65
63
|
$ctx.set("data", data);
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
{
|
|
64
|
+
if (tasks.length) {
|
|
65
|
+
if (this.reinstallAfterRun && (this.projectPkg.rewrite || this.projectPkg.reinstall)) {
|
|
66
|
+
tasks.push({
|
|
70
67
|
title: "Install dependencies",
|
|
71
|
-
enabled: () => this.reinstallAfterRun && (this.projectPkg.rewrite || this.projectPkg.reinstall),
|
|
72
68
|
task: createSubTasks(() => this.packageManagers.install(data), { ...data, concurrent: false })
|
|
73
|
-
},
|
|
74
|
-
|
|
75
|
-
];
|
|
69
|
+
}, ...(await this.getPostInstallTasks(cmdName, data)));
|
|
70
|
+
}
|
|
76
71
|
data = this.mapData(cmdName, data, $ctx);
|
|
77
72
|
$ctx.set("data", data);
|
|
78
73
|
return createTasksRunner(tasks, data);
|
|
79
74
|
}
|
|
80
75
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Run prompt for a given command
|
|
83
|
-
* @param cmdName
|
|
84
|
-
* @param data Initial data
|
|
85
|
-
* @param $ctx
|
|
86
|
-
*/
|
|
87
|
-
async beforePrompt(cmdName, data = {}, $ctx) {
|
|
88
|
-
const provider = this.commands.get(cmdName);
|
|
89
|
-
const instance = inject(provider.useClass);
|
|
90
|
-
const verbose = data.verbose;
|
|
91
|
-
$ctx.set("data", data);
|
|
92
|
-
if (instance.$beforePrompt) {
|
|
93
|
-
data = await instance.$beforePrompt(JSON.parse(JSON.stringify(data)));
|
|
94
|
-
data.verbose = verbose;
|
|
95
|
-
}
|
|
96
|
-
$ctx.set("data", data);
|
|
97
|
-
return data;
|
|
98
|
-
}
|
|
99
76
|
/**
|
|
100
77
|
* Run prompt for a given command
|
|
101
78
|
* @param cmdName
|
|
@@ -104,13 +81,10 @@ export class CliService {
|
|
|
104
81
|
*/
|
|
105
82
|
async prompt(cmdName, data = {}, $ctx) {
|
|
106
83
|
const provider = this.commands.get(cmdName);
|
|
107
|
-
const instance = inject(provider.
|
|
84
|
+
const instance = inject(provider.token);
|
|
108
85
|
$ctx.set("data", data);
|
|
109
86
|
if (instance.$prompt) {
|
|
110
|
-
const questions = [
|
|
111
|
-
...(await instance.$prompt(data)),
|
|
112
|
-
...(await this.hooks.emit(CommandStoreKeys.PROMPT_HOOKS, cmdName, data))
|
|
113
|
-
];
|
|
87
|
+
const questions = [...(await instance.$prompt(data))];
|
|
114
88
|
if (questions.length) {
|
|
115
89
|
data = {
|
|
116
90
|
...data,
|
|
@@ -131,14 +105,10 @@ export class CliService {
|
|
|
131
105
|
const provider = this.commands.get(cmdName);
|
|
132
106
|
const instance = inject(provider.token);
|
|
133
107
|
data = this.mapData(cmdName, data, $ctx);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
return
|
|
138
|
-
...(await instance.$exec(data)),
|
|
139
|
-
...(await this.hooks.emit(CommandStoreKeys.EXEC_HOOKS, cmdName, data)),
|
|
140
|
-
...(await $asyncAlter(`$alter${pascalCase(cmdName)}Tasks`, [], [data]))
|
|
141
|
-
].map((opts) => {
|
|
108
|
+
const tasks = [];
|
|
109
|
+
tasks.push(...((await instance.$exec(data)) || []));
|
|
110
|
+
tasks.push(...(await $asyncAlter(`$alter${pascalCase(cmdName)}Tasks`, [], [data])));
|
|
111
|
+
return tasks.map((opts) => {
|
|
142
112
|
return {
|
|
143
113
|
...opts,
|
|
144
114
|
task: async (arg, task) => {
|
|
@@ -152,32 +122,44 @@ export class CliService {
|
|
|
152
122
|
}
|
|
153
123
|
async getPostInstallTasks(cmdName, data) {
|
|
154
124
|
const provider = this.commands.get(cmdName);
|
|
155
|
-
const instance = inject(provider.
|
|
125
|
+
const instance = inject(provider.token);
|
|
156
126
|
data = this.mapData(cmdName, data, getContext());
|
|
157
127
|
return [
|
|
158
128
|
...(instance.$postInstall ? await instance.$postInstall(data) : []),
|
|
159
|
-
...(await this.hooks.emit(CommandStoreKeys.POST_INSTALL_HOOKS, cmdName, data)),
|
|
160
129
|
...(await $asyncAlter(`$alter${pascalCase(cmdName)}PostInstallTasks`, [], [data])),
|
|
161
130
|
...(instance.$afterPostInstall ? await instance.$afterPostInstall(data) : [])
|
|
162
131
|
];
|
|
163
132
|
}
|
|
164
133
|
createCommand(metadata) {
|
|
165
|
-
const {
|
|
134
|
+
const { name, description, alias, inputSchema } = metadata;
|
|
166
135
|
if (this.commands.has(name)) {
|
|
167
136
|
return this.commands.get(name).command;
|
|
168
137
|
}
|
|
169
|
-
|
|
138
|
+
const { args, options, allowUnknownOption } = metadata.getOptions();
|
|
170
139
|
const onAction = (commandName) => {
|
|
171
140
|
const [, ...rawArgs] = cmd.args;
|
|
172
141
|
const mappedArgs = mapCommanderArgs(args, this.program.args.filter((arg) => commandName === arg));
|
|
173
142
|
const allOpts = mapCommanderOptions(commandName, this.program.commands);
|
|
174
|
-
|
|
143
|
+
let data = {
|
|
175
144
|
...allOpts,
|
|
176
145
|
verbose: !!this.program.opts().verbose,
|
|
177
146
|
...mappedArgs,
|
|
178
147
|
...cmd.opts(),
|
|
179
148
|
rawArgs
|
|
180
149
|
};
|
|
150
|
+
if (inputSchema) {
|
|
151
|
+
const { isValid, errors, value } = validate(data, isArrowFn(inputSchema) ? inputSchema() : inputSchema);
|
|
152
|
+
if (isValid) {
|
|
153
|
+
data = value;
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
logger().error({
|
|
157
|
+
event: "VALIDATION_ERROR",
|
|
158
|
+
errors
|
|
159
|
+
});
|
|
160
|
+
throw new Error("Validation error");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
181
163
|
const $ctx = new DIContext({
|
|
182
164
|
id: v4(),
|
|
183
165
|
injector: injector(),
|
|
@@ -191,6 +173,7 @@ export class CliService {
|
|
|
191
173
|
configuration().set("command.metadata", metadata);
|
|
192
174
|
return this.runLifecycle(name, data, $ctx);
|
|
193
175
|
};
|
|
176
|
+
let cmd = this.program.command(name);
|
|
194
177
|
if (alias) {
|
|
195
178
|
cmd = cmd.alias(alias);
|
|
196
179
|
}
|
|
@@ -209,7 +192,7 @@ export class CliService {
|
|
|
209
192
|
}
|
|
210
193
|
mapData(cmdName, data, $ctx) {
|
|
211
194
|
const provider = this.commands.get(cmdName);
|
|
212
|
-
const instance = inject(provider.
|
|
195
|
+
const instance = inject(provider.token);
|
|
213
196
|
const verbose = data.verbose;
|
|
214
197
|
data.commandName ||= cmdName;
|
|
215
198
|
if (instance.$mapContext) {
|
|
@@ -231,7 +214,7 @@ export class CliService {
|
|
|
231
214
|
* @param provider
|
|
232
215
|
*/
|
|
233
216
|
build(provider) {
|
|
234
|
-
const metadata = getCommandMetadata(provider.
|
|
217
|
+
const metadata = getCommandMetadata(provider.token);
|
|
235
218
|
if (metadata.name) {
|
|
236
219
|
if (this.commands.has(metadata.name)) {
|
|
237
220
|
throw Error(`The ${metadata.name} command is already registered. Change your command name used by the class ${classOf(provider.useClass)}`);
|
|
@@ -1,17 +1,44 @@
|
|
|
1
|
-
import { Store } from "@tsed/core";
|
|
2
|
-
import { CommandStoreKeys } from "../domains/CommandStoreKeys.js";
|
|
1
|
+
import { isArrowFn, Store } from "@tsed/core";
|
|
3
2
|
export function getCommandMetadata(token) {
|
|
4
|
-
const { name, alias, args = {},
|
|
3
|
+
const { name, alias, args = {}, description, options = {}, enableFeatures, disableReadUpPkg, inputSchema, bindLogger = true, ...opts } = Store.from(token)?.get("command");
|
|
5
4
|
return {
|
|
6
5
|
name,
|
|
6
|
+
inputSchema,
|
|
7
7
|
alias,
|
|
8
|
-
args,
|
|
9
8
|
description,
|
|
10
|
-
options,
|
|
11
|
-
allowUnknownOption: !!allowUnknownOption,
|
|
12
9
|
enableFeatures: enableFeatures || [],
|
|
13
10
|
disableReadUpPkg: !!disableReadUpPkg,
|
|
14
11
|
bindLogger,
|
|
15
|
-
...opts
|
|
12
|
+
...opts,
|
|
13
|
+
getOptions() {
|
|
14
|
+
if (inputSchema) {
|
|
15
|
+
const schema = isArrowFn(inputSchema) ? inputSchema() : inputSchema;
|
|
16
|
+
Object.entries(schema.get("properties") || {})?.forEach(([propertyKey, propertySchema]) => {
|
|
17
|
+
const base = {
|
|
18
|
+
type: propertySchema.getTarget(),
|
|
19
|
+
itemType: propertySchema.isCollection ? propertySchema.get("items").getTarget() : undefined,
|
|
20
|
+
description: propertySchema.get("description") || "",
|
|
21
|
+
defaultValue: propertySchema.get("default"),
|
|
22
|
+
required: schema.isRequired(propertyKey)
|
|
23
|
+
};
|
|
24
|
+
const opt = propertySchema.get("x-opt");
|
|
25
|
+
if (opt) {
|
|
26
|
+
options[opt] = {
|
|
27
|
+
...base,
|
|
28
|
+
customParser: schema.get("custom-parser")
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
args[propertyKey] = base;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
opts.allowUnknownOption = !!schema.get("additionalProperties");
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
args,
|
|
39
|
+
options,
|
|
40
|
+
allowUnknownOption: !!opts.allowUnknownOption
|
|
41
|
+
};
|
|
42
|
+
}
|
|
16
43
|
};
|
|
17
44
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function Command(options:
|
|
1
|
+
import type { BaseCommandOptions } from "../interfaces/CommandOptions.js";
|
|
2
|
+
export declare function Command<Input = any>(options: BaseCommandOptions<Input>): ClassDecorator;
|
|
@@ -1,3 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type
|
|
3
|
-
|
|
1
|
+
import type { Type } from "@tsed/core";
|
|
2
|
+
import { type FactoryTokenProvider } from "@tsed/di";
|
|
3
|
+
import { JsonSchema } from "@tsed/schema";
|
|
4
|
+
import type { CommandOptions } from "../interfaces/CommandOptions.js";
|
|
5
|
+
import type { CommandProvider } from "../interfaces/index.js";
|
|
6
|
+
type SchemaChoice = {
|
|
7
|
+
label: string;
|
|
8
|
+
value: string;
|
|
9
|
+
checked?: ((ctx: any) => boolean) | boolean;
|
|
10
|
+
items?: SchemaChoice[];
|
|
11
|
+
};
|
|
12
|
+
declare module "@tsed/schema" {
|
|
13
|
+
interface JsonSchema {
|
|
14
|
+
prompt(label: string): this;
|
|
15
|
+
opt(value: string): this;
|
|
16
|
+
when(fn: (ctx: any) => boolean): this;
|
|
17
|
+
choices(value: SchemaChoice[]): this;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export declare function command<Input>(options: CommandOptions<Input>): TsED.ProviderBuilder<FactoryTokenProvider<{
|
|
21
|
+
$prompt: any;
|
|
22
|
+
$exec: any;
|
|
23
|
+
token: import("@tsed/di").TokenProvider<CommandProvider>;
|
|
24
|
+
name: string;
|
|
25
|
+
alias?: string;
|
|
26
|
+
description: string;
|
|
27
|
+
args?: {
|
|
28
|
+
[key: string]: import("../interfaces/CommandOptions.js").CommandArg;
|
|
29
|
+
};
|
|
30
|
+
inputSchema?: JsonSchema<Input> | (() => JsonSchema<Input>) | undefined;
|
|
31
|
+
options?: {
|
|
32
|
+
[key: string]: import("../interfaces/CommandOptions.js").CommandOpts;
|
|
33
|
+
};
|
|
34
|
+
allowUnknownOption?: boolean;
|
|
35
|
+
enableFeatures?: string[];
|
|
36
|
+
disableReadUpPkg?: boolean;
|
|
37
|
+
bindLogger?: boolean;
|
|
38
|
+
} | {
|
|
39
|
+
$prompt: any;
|
|
40
|
+
$exec: any;
|
|
41
|
+
prompt?<T extends import("inquirer").Answers = import("inquirer").Answers>(initialOptions: Partial<Input>): import("../interfaces/CommandProvider.js").QuestionOptions<T> | Promise<import("../interfaces/CommandProvider.js").QuestionOptions<T>>;
|
|
42
|
+
handler: (data: Input) => import("../interfaces/Tasks.js").Tasks | Promise<import("../interfaces/Tasks.js").Tasks> | any | Promise<any>;
|
|
43
|
+
name: string;
|
|
44
|
+
alias?: string;
|
|
45
|
+
description: string;
|
|
46
|
+
args?: {
|
|
47
|
+
[key: string]: import("../interfaces/CommandOptions.js").CommandArg;
|
|
48
|
+
};
|
|
49
|
+
inputSchema?: JsonSchema<Input> | (() => JsonSchema<Input>) | undefined;
|
|
50
|
+
options?: {
|
|
51
|
+
[key: string]: import("../interfaces/CommandOptions.js").CommandOpts;
|
|
52
|
+
};
|
|
53
|
+
allowUnknownOption?: boolean;
|
|
54
|
+
enableFeatures?: string[];
|
|
55
|
+
disableReadUpPkg?: boolean;
|
|
56
|
+
bindLogger?: boolean;
|
|
57
|
+
}>> | TsED.ClassProviderBuilder<Type<CommandProvider<Input>>>;
|
|
58
|
+
export {};
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export interface CommandMetadata extends
|
|
3
|
-
/**
|
|
4
|
-
* CommandProvider arguments
|
|
5
|
-
*/
|
|
6
|
-
args: {
|
|
7
|
-
[key: string]: CommandArg;
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* CommandProvider options
|
|
11
|
-
*/
|
|
12
|
-
options: {
|
|
13
|
-
[key: string]: CommandOptions;
|
|
14
|
-
};
|
|
15
|
-
allowUnknownOption?: boolean;
|
|
1
|
+
import type { BaseCommandOptions, CommandArg, CommandOpts } from "./CommandOptions.js";
|
|
2
|
+
export interface CommandMetadata extends Omit<BaseCommandOptions<any>, "args" | "options" | "allowUnknownOption"> {
|
|
16
3
|
enableFeatures: string[];
|
|
17
4
|
disableReadUpPkg: boolean;
|
|
18
5
|
bindLogger: boolean;
|
|
6
|
+
getOptions(): {
|
|
7
|
+
/**
|
|
8
|
+
* CommandProvider arguments
|
|
9
|
+
*/
|
|
10
|
+
args: {
|
|
11
|
+
[key: string]: CommandArg;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* CommandProvider options
|
|
15
|
+
*/
|
|
16
|
+
options: {
|
|
17
|
+
[key: string]: CommandOpts;
|
|
18
|
+
};
|
|
19
|
+
allowUnknownOption?: boolean;
|
|
20
|
+
};
|
|
19
21
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { Type } from "@tsed/core";
|
|
2
|
+
import type { TokenProvider } from "@tsed/di";
|
|
3
|
+
import type { JsonSchema } from "@tsed/schema";
|
|
4
|
+
import type { Answers } from "inquirer";
|
|
5
|
+
import type { CommandProvider, QuestionOptions } from "./CommandProvider.js";
|
|
6
|
+
import type { Tasks } from "./Tasks.js";
|
|
2
7
|
export interface CommandArg {
|
|
3
8
|
/**
|
|
4
9
|
* Description of the argument
|
|
@@ -21,7 +26,7 @@ export interface CommandArg {
|
|
|
21
26
|
*/
|
|
22
27
|
required?: boolean;
|
|
23
28
|
}
|
|
24
|
-
export interface
|
|
29
|
+
export interface CommandOpts {
|
|
25
30
|
/**
|
|
26
31
|
* Description of the commander.option()
|
|
27
32
|
*/
|
|
@@ -48,7 +53,7 @@ export interface CommandOptions {
|
|
|
48
53
|
*/
|
|
49
54
|
customParser?: (value: any) => any;
|
|
50
55
|
}
|
|
51
|
-
export interface
|
|
56
|
+
export interface BaseCommandOptions<Input> {
|
|
52
57
|
/**
|
|
53
58
|
* name commands
|
|
54
59
|
*/
|
|
@@ -64,14 +69,26 @@ export interface CommandParameters {
|
|
|
64
69
|
args?: {
|
|
65
70
|
[key: string]: CommandArg;
|
|
66
71
|
};
|
|
72
|
+
inputSchema?: JsonSchema<Input> | (() => JsonSchema<Input>);
|
|
67
73
|
/**
|
|
68
74
|
* CommandProvider options
|
|
69
75
|
*/
|
|
70
76
|
options?: {
|
|
71
|
-
[key: string]:
|
|
77
|
+
[key: string]: CommandOpts;
|
|
72
78
|
};
|
|
73
79
|
allowUnknownOption?: boolean;
|
|
74
80
|
enableFeatures?: string[];
|
|
75
81
|
disableReadUpPkg?: boolean;
|
|
82
|
+
bindLogger?: boolean;
|
|
83
|
+
}
|
|
84
|
+
interface FunctionalCommandOptions<Input> extends BaseCommandOptions<Input> {
|
|
85
|
+
prompt?<T extends Answers = Answers>(initialOptions: Partial<Input>): QuestionOptions<T> | Promise<QuestionOptions<T>>;
|
|
86
|
+
handler: (data: Input) => Tasks | Promise<Tasks> | any | Promise<any>;
|
|
87
|
+
[key: string]: any;
|
|
88
|
+
}
|
|
89
|
+
export interface ClassCommandOptions<Input> extends BaseCommandOptions<Input> {
|
|
90
|
+
token: TokenProvider<CommandProvider>;
|
|
76
91
|
[key: string]: any;
|
|
77
92
|
}
|
|
93
|
+
export type CommandOptions<Input> = ClassCommandOptions<Input> | FunctionalCommandOptions<Input>;
|
|
94
|
+
export {};
|
|
@@ -9,11 +9,6 @@ declare module "inquirer" {
|
|
|
9
9
|
}
|
|
10
10
|
export type QuestionOptions<T extends Answers = Answers> = QuestionCollection<T>;
|
|
11
11
|
export interface CommandProvider<Ctx = any> {
|
|
12
|
-
/**
|
|
13
|
-
* Run a function before the main prompt. Useful for pre-loading data from the file system
|
|
14
|
-
* @param initialOptions
|
|
15
|
-
*/
|
|
16
|
-
$beforePrompt?(initialOptions: Partial<Ctx>): Partial<Ctx>;
|
|
17
12
|
/**
|
|
18
13
|
* Hook to create the main prompt for the command
|
|
19
14
|
* See https://github.com/enquirer/enquirer for more detail on question configuration.
|
|
@@ -25,11 +20,6 @@ export interface CommandProvider<Ctx = any> {
|
|
|
25
20
|
* @param ctx
|
|
26
21
|
*/
|
|
27
22
|
$mapContext?(ctx: Partial<Ctx>): Ctx;
|
|
28
|
-
/**
|
|
29
|
-
* Run something before the exec hook
|
|
30
|
-
* @param ctx
|
|
31
|
-
*/
|
|
32
|
-
$beforeExec?(ctx: Ctx): Promise<any>;
|
|
33
23
|
/**
|
|
34
24
|
* Run a command
|
|
35
25
|
* @param ctx
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { TokenProvider } from "@tsed/di";
|
|
2
2
|
import type { CommandProvider } from "./CommandProvider.js";
|
|
3
3
|
import type { PackageJson } from "./PackageJson.js";
|
|
4
4
|
export * from "./CliDefaultOptions.js";
|
|
5
5
|
export * from "./CommandData.js";
|
|
6
6
|
export * from "./CommandMetadata.js";
|
|
7
|
-
export * from "./
|
|
7
|
+
export * from "./CommandOptions.js";
|
|
8
8
|
export * from "./CommandProvider.js";
|
|
9
9
|
export * from "./PackageJson.js";
|
|
10
10
|
export * from "./ProjectPreferences.js";
|
|
@@ -15,7 +15,7 @@ declare global {
|
|
|
15
15
|
/**
|
|
16
16
|
* Load given commands
|
|
17
17
|
*/
|
|
18
|
-
commands:
|
|
18
|
+
commands: TokenProvider<CommandProvider>[];
|
|
19
19
|
/**
|
|
20
20
|
* Init Cli with defined argv
|
|
21
21
|
*/
|
|
@@ -27,13 +27,6 @@ export declare class CliService {
|
|
|
27
27
|
*/
|
|
28
28
|
runLifecycle(cmdName: string, data: CommandData | undefined, $ctx: DIContext): Promise<Promise<void>>;
|
|
29
29
|
exec(cmdName: string, data: any, $ctx: DIContext): Promise<any>;
|
|
30
|
-
/**
|
|
31
|
-
* Run prompt for a given command
|
|
32
|
-
* @param cmdName
|
|
33
|
-
* @param data Initial data
|
|
34
|
-
* @param $ctx
|
|
35
|
-
*/
|
|
36
|
-
beforePrompt(cmdName: string, data: CommandData | undefined, $ctx: DIContext): Promise<CommandData>;
|
|
37
30
|
/**
|
|
38
31
|
* Run prompt for a given command
|
|
39
32
|
* @param cmdName
|
|
@@ -49,7 +42,7 @@ export declare class CliService {
|
|
|
49
42
|
getTasks(cmdName: string, data: any): Promise<Task[]>;
|
|
50
43
|
getPostInstallTasks(cmdName: string, data: any): Promise<any[]>;
|
|
51
44
|
createCommand(metadata: CommandMetadata): any;
|
|
52
|
-
|
|
45
|
+
load(): void;
|
|
53
46
|
private mapData;
|
|
54
47
|
/**
|
|
55
48
|
* Build command and sub-commands
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsed/cli-core",
|
|
3
3
|
"description": "Build your CLI with TypeScript and Decorators",
|
|
4
|
-
"version": "7.0.0-beta.
|
|
4
|
+
"version": "7.0.0-beta.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/esm/index.js",
|
|
7
7
|
"source": "./src/index.ts",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"uuid": "^10.0.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@tsed/typescript": "7.0.0-beta.
|
|
68
|
+
"@tsed/typescript": "7.0.0-beta.4",
|
|
69
69
|
"@types/commander": "2.12.2",
|
|
70
70
|
"@types/figures": "3.0.1",
|
|
71
71
|
"@types/fs-extra": "^11.0.4",
|
package/lib/esm/decorators/on.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export var CommandStoreKeys;
|
|
2
|
-
(function (CommandStoreKeys) {
|
|
3
|
-
CommandStoreKeys["COMMAND"] = "command";
|
|
4
|
-
CommandStoreKeys["ADD"] = "$onAdd";
|
|
5
|
-
CommandStoreKeys["EXEC_HOOKS"] = "$onExec";
|
|
6
|
-
CommandStoreKeys["POST_INSTALL_HOOKS"] = "$onPostInstall";
|
|
7
|
-
CommandStoreKeys["PROMPT_HOOKS"] = "$onPrompt";
|
|
8
|
-
})(CommandStoreKeys || (CommandStoreKeys = {}));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function On(hookName: string, name: string): MethodDecorator;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function OnAdd(cliPlugin: string): MethodDecorator;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function OnExec(cmdName: string): MethodDecorator;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function OnPostInstall(cmdName: string): MethodDecorator;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function OnPrompt(cmdName: string): MethodDecorator;
|
|
File without changes
|