@tsed/cli-core 7.0.0-beta.2 → 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/CliCore.js +1 -1
- 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 +10 -18
- package/lib/esm/packageManagers/supports/BaseManager.js +2 -6
- package/lib/esm/services/CliHttpClient.js +3 -2
- package/lib/esm/services/CliHttpLogClient.js +1 -1
- package/lib/esm/services/CliLoadFile.js +5 -18
- package/lib/esm/services/CliPlugins.js +2 -2
- package/lib/esm/services/CliService.js +58 -71
- package/lib/esm/services/ProjectPackageJson.js +1 -1
- package/lib/esm/utils/getCommandMetadata.js +34 -7
- package/lib/esm/utils/index.js +1 -0
- package/lib/esm/utils/validate.js +23 -0
- 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/packageManagers/PackageManagersModule.d.ts +1 -2
- package/lib/types/services/CliHttpLogClient.d.ts +1 -1
- package/lib/types/services/CliLoadFile.d.ts +2 -4
- package/lib/types/services/CliService.d.ts +4 -10
- package/lib/types/utils/index.d.ts +1 -0
- package/lib/types/utils/mapCommanderArgs.d.ts +1 -1
- package/lib/types/utils/validate.d.ts +14 -0
- 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/CliCore.js
CHANGED
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";
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Inject, injectable } from "@tsed/di";
|
|
1
|
+
import { Inject, inject, injectable, injectMany } from "@tsed/di";
|
|
3
2
|
import { EMPTY, throwError } from "rxjs";
|
|
4
3
|
import { catchError } from "rxjs/operators";
|
|
5
4
|
import { ProjectPackageJson } from "../services/ProjectPackageJson.js";
|
|
@@ -18,17 +17,19 @@ function mapPackagesWithInvalidVersion(deps) {
|
|
|
18
17
|
.filter(([, version]) => !isValidVersion(version))
|
|
19
18
|
.map(toString);
|
|
20
19
|
}
|
|
21
|
-
|
|
22
|
-
constructor(
|
|
23
|
-
this.
|
|
24
|
-
this.packageManagers =
|
|
20
|
+
export class PackageManagersModule {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.projectPackageJson = inject(ProjectPackageJson);
|
|
23
|
+
this.packageManagers = injectMany("package:manager").filter((manager) => {
|
|
24
|
+
return manager.has();
|
|
25
|
+
});
|
|
25
26
|
}
|
|
26
27
|
init(options = {}) {
|
|
27
28
|
const packageManager = this.get(options.packageManager);
|
|
28
29
|
options.packageManager = packageManager.name;
|
|
29
30
|
options = {
|
|
30
31
|
...options,
|
|
31
|
-
cwd: this.projectPackageJson.
|
|
32
|
+
cwd: this.projectPackageJson.cwd,
|
|
32
33
|
env: {
|
|
33
34
|
...process.env,
|
|
34
35
|
GH_TOKEN: this.projectPackageJson.GH_TOKEN
|
|
@@ -45,7 +46,7 @@ let PackageManagersModule = class PackageManagersModule {
|
|
|
45
46
|
const deps = mapPackagesWithInvalidVersion(this.projectPackageJson.dependencies);
|
|
46
47
|
options = {
|
|
47
48
|
...options,
|
|
48
|
-
cwd: this.projectPackageJson.
|
|
49
|
+
cwd: this.projectPackageJson.cwd,
|
|
49
50
|
env: {
|
|
50
51
|
...process.env,
|
|
51
52
|
GH_TOKEN: this.projectPackageJson.GH_TOKEN
|
|
@@ -116,14 +117,5 @@ let PackageManagersModule = class PackageManagersModule {
|
|
|
116
117
|
});
|
|
117
118
|
return this.get().runScript(scriptName, options).pipe(errorPipe());
|
|
118
119
|
}
|
|
119
|
-
}
|
|
120
|
-
__decorate([
|
|
121
|
-
Inject(),
|
|
122
|
-
__metadata("design:type", ProjectPackageJson)
|
|
123
|
-
], PackageManagersModule.prototype, "projectPackageJson", void 0);
|
|
124
|
-
PackageManagersModule = __decorate([
|
|
125
|
-
__param(0, Inject("package:manager")),
|
|
126
|
-
__metadata("design:paramtypes", [Array])
|
|
127
|
-
], PackageManagersModule);
|
|
128
|
-
export { PackageManagersModule };
|
|
120
|
+
}
|
|
129
121
|
injectable(PackageManagersModule).imports([YarnManager, YarnBerryManager, NpmManager, PNpmManager, BunManager]);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Inject } from "@tsed/di";
|
|
1
|
+
import { inject } from "@tsed/di";
|
|
3
2
|
import { Observable } from "rxjs";
|
|
4
3
|
import { CliExeca } from "../../services/CliExeca.js";
|
|
5
4
|
export class BaseManager {
|
|
6
5
|
constructor() {
|
|
7
6
|
this.verboseOpt = "--verbose";
|
|
7
|
+
this.cliExeca = inject(CliExeca);
|
|
8
8
|
}
|
|
9
9
|
has() {
|
|
10
10
|
try {
|
|
@@ -23,7 +23,3 @@ export class BaseManager {
|
|
|
23
23
|
return this.cliExeca.run(this.cmd, [cmd, options.verbose && this.verboseOpt, ...args].filter(Boolean), options);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
__decorate([
|
|
27
|
-
Inject(CliExeca),
|
|
28
|
-
__metadata("design:type", CliExeca)
|
|
29
|
-
], BaseManager.prototype, "cliExeca", void 0);
|
|
@@ -41,10 +41,11 @@ export class CliHttpClient extends CliHttpLogClient {
|
|
|
41
41
|
return this.mapResponse(result, options);
|
|
42
42
|
}
|
|
43
43
|
getRequestParameters(method, endpoint, options) {
|
|
44
|
+
const url = (this.host || "") + endpoint.replace(this.host || "", "");
|
|
44
45
|
options = {
|
|
45
46
|
method,
|
|
46
|
-
url: (this.host || "") + endpoint.replace(this.host || "", ""),
|
|
47
47
|
...options,
|
|
48
|
+
url,
|
|
48
49
|
params: options.params || options.qs,
|
|
49
50
|
data: options.data,
|
|
50
51
|
headers: {
|
|
@@ -53,7 +54,7 @@ export class CliHttpClient extends CliHttpLogClient {
|
|
|
53
54
|
...(options.headers || {})
|
|
54
55
|
}
|
|
55
56
|
};
|
|
56
|
-
this.configureProxy(
|
|
57
|
+
this.configureProxy(url, options);
|
|
57
58
|
return options;
|
|
58
59
|
}
|
|
59
60
|
configureProxy(endpoint, options) {
|
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
import { extname } from "node:path";
|
|
2
2
|
import { inject, injectable } from "@tsed/di";
|
|
3
|
-
import {
|
|
3
|
+
import { validate } from "../utils/validate.js";
|
|
4
4
|
import { CliFs } from "./CliFs.js";
|
|
5
5
|
import { CliYaml } from "./CliYaml.js";
|
|
6
6
|
export class CliLoadFile {
|
|
7
|
-
// @ts-ignore
|
|
8
|
-
#ajv;
|
|
9
7
|
constructor() {
|
|
10
8
|
this.cliYaml = inject(CliYaml);
|
|
11
9
|
this.cliFs = inject(CliFs);
|
|
12
|
-
const options = {
|
|
13
|
-
verbose: false,
|
|
14
|
-
coerceTypes: true,
|
|
15
|
-
strict: false
|
|
16
|
-
};
|
|
17
|
-
// @ts-ignore
|
|
18
|
-
this.#ajv = new Ajv(options);
|
|
19
10
|
}
|
|
20
11
|
/**
|
|
21
12
|
* Load a configuration file from yaml, json
|
|
@@ -33,18 +24,14 @@ export class CliLoadFile {
|
|
|
33
24
|
throw new Error("Unsupported format file");
|
|
34
25
|
}
|
|
35
26
|
if (schema) {
|
|
36
|
-
const
|
|
37
|
-
const isValid = validate(config);
|
|
27
|
+
const { isValid, errors, value } = validate(config, schema);
|
|
38
28
|
if (!isValid) {
|
|
39
|
-
const [error] =
|
|
40
|
-
throw new Error([
|
|
41
|
-
`${error.instancePath.replace(/\//gi, ".")} `,
|
|
42
|
-
error.message,
|
|
43
|
-
error.params?.allowedValues && `. Allowed values: ${error.params?.allowedValues}`
|
|
44
|
-
]
|
|
29
|
+
const [error] = errors;
|
|
30
|
+
throw new Error([`${error.path.replace(/\//gi, ".")} `, error.message, error.expected && `. Allowed values: ${error.expected}`]
|
|
45
31
|
.filter(Boolean)
|
|
46
32
|
.join(""));
|
|
47
33
|
}
|
|
34
|
+
return value;
|
|
48
35
|
}
|
|
49
36
|
return config;
|
|
50
37
|
}
|
|
@@ -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";
|
|
@@ -44,78 +43,57 @@ export class CliService {
|
|
|
44
43
|
*/
|
|
45
44
|
runLifecycle(cmdName, data = {}, $ctx) {
|
|
46
45
|
return runInContext($ctx, async () => {
|
|
47
|
-
await $asyncEmit("$loadPackageJson");
|
|
48
|
-
data = await this.beforePrompt(cmdName, data);
|
|
49
|
-
$ctx.set("data", data);
|
|
50
|
-
data = await this.prompt(cmdName, data);
|
|
51
|
-
await this.dispatch(cmdName, data, $ctx);
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
async dispatch(cmdName, data, $ctx) {
|
|
55
|
-
try {
|
|
56
46
|
$ctx.set("dispatchCmd", cmdName);
|
|
57
|
-
$
|
|
58
|
-
await this.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
47
|
+
await $asyncEmit("$loadPackageJson");
|
|
48
|
+
data = await this.prompt(cmdName, data, $ctx);
|
|
49
|
+
try {
|
|
50
|
+
await this.exec(cmdName, data, $ctx);
|
|
51
|
+
}
|
|
52
|
+
catch (er) {
|
|
53
|
+
await $asyncEmit("$onFinish", [data, er]);
|
|
54
|
+
await destroyInjector();
|
|
55
|
+
throw er;
|
|
56
|
+
}
|
|
57
|
+
await $asyncEmit("$onFinish", [data]);
|
|
62
58
|
await destroyInjector();
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
await $asyncEmit("$onFinish");
|
|
66
|
-
await destroyInjector();
|
|
59
|
+
});
|
|
67
60
|
}
|
|
68
61
|
async exec(cmdName, data, $ctx) {
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
{
|
|
62
|
+
const tasks = await this.getTasks(cmdName, data);
|
|
63
|
+
$ctx.set("data", data);
|
|
64
|
+
if (tasks.length) {
|
|
65
|
+
if (this.reinstallAfterRun && (this.projectPkg.rewrite || this.projectPkg.reinstall)) {
|
|
66
|
+
tasks.push({
|
|
74
67
|
title: "Install dependencies",
|
|
75
|
-
enabled: () => this.reinstallAfterRun && (this.projectPkg.rewrite || this.projectPkg.reinstall),
|
|
76
68
|
task: createSubTasks(() => this.packageManagers.install(data), { ...data, concurrent: false })
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Run prompt for a given command
|
|
85
|
-
* @param cmdName
|
|
86
|
-
* @param data Initial data
|
|
87
|
-
*/
|
|
88
|
-
async beforePrompt(cmdName, data = {}) {
|
|
89
|
-
const provider = this.commands.get(cmdName);
|
|
90
|
-
const instance = inject(provider.useClass);
|
|
91
|
-
const verbose = data.verbose;
|
|
92
|
-
if (instance.$beforePrompt) {
|
|
93
|
-
data = await instance.$beforePrompt(JSON.parse(JSON.stringify(data)));
|
|
94
|
-
data.verbose = verbose;
|
|
69
|
+
}, ...(await this.getPostInstallTasks(cmdName, data)));
|
|
70
|
+
}
|
|
71
|
+
data = this.mapData(cmdName, data, $ctx);
|
|
72
|
+
$ctx.set("data", data);
|
|
73
|
+
return createTasksRunner(tasks, data);
|
|
95
74
|
}
|
|
96
|
-
return data;
|
|
97
75
|
}
|
|
98
76
|
/**
|
|
99
77
|
* Run prompt for a given command
|
|
100
78
|
* @param cmdName
|
|
101
|
-
* @param
|
|
79
|
+
* @param data
|
|
80
|
+
* @param $ctx
|
|
102
81
|
*/
|
|
103
|
-
async prompt(cmdName,
|
|
82
|
+
async prompt(cmdName, data = {}, $ctx) {
|
|
104
83
|
const provider = this.commands.get(cmdName);
|
|
105
|
-
const instance = inject(provider.
|
|
84
|
+
const instance = inject(provider.token);
|
|
85
|
+
$ctx.set("data", data);
|
|
106
86
|
if (instance.$prompt) {
|
|
107
|
-
const questions = [
|
|
108
|
-
...(await instance.$prompt(ctx)),
|
|
109
|
-
...(await this.hooks.emit(CommandStoreKeys.PROMPT_HOOKS, cmdName, ctx))
|
|
110
|
-
];
|
|
87
|
+
const questions = [...(await instance.$prompt(data))];
|
|
111
88
|
if (questions.length) {
|
|
112
|
-
|
|
113
|
-
...
|
|
89
|
+
data = {
|
|
90
|
+
...data,
|
|
114
91
|
...(await Inquirer.prompt(questions))
|
|
115
92
|
};
|
|
116
93
|
}
|
|
117
94
|
}
|
|
118
|
-
|
|
95
|
+
$ctx.set("data", data);
|
|
96
|
+
return data;
|
|
119
97
|
}
|
|
120
98
|
/**
|
|
121
99
|
* Run lifecycle
|
|
@@ -127,14 +105,10 @@ export class CliService {
|
|
|
127
105
|
const provider = this.commands.get(cmdName);
|
|
128
106
|
const instance = inject(provider.token);
|
|
129
107
|
data = this.mapData(cmdName, data, $ctx);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
return
|
|
134
|
-
...(await instance.$exec(data)),
|
|
135
|
-
...(await this.hooks.emit(CommandStoreKeys.EXEC_HOOKS, cmdName, data)),
|
|
136
|
-
...(await $asyncAlter(`$alter${pascalCase(cmdName)}Tasks`, [], [data]))
|
|
137
|
-
].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) => {
|
|
138
112
|
return {
|
|
139
113
|
...opts,
|
|
140
114
|
task: async (arg, task) => {
|
|
@@ -148,32 +122,44 @@ export class CliService {
|
|
|
148
122
|
}
|
|
149
123
|
async getPostInstallTasks(cmdName, data) {
|
|
150
124
|
const provider = this.commands.get(cmdName);
|
|
151
|
-
const instance = inject(provider.
|
|
125
|
+
const instance = inject(provider.token);
|
|
152
126
|
data = this.mapData(cmdName, data, getContext());
|
|
153
127
|
return [
|
|
154
128
|
...(instance.$postInstall ? await instance.$postInstall(data) : []),
|
|
155
|
-
...(await this.hooks.emit(CommandStoreKeys.POST_INSTALL_HOOKS, cmdName, data)),
|
|
156
129
|
...(await $asyncAlter(`$alter${pascalCase(cmdName)}PostInstallTasks`, [], [data])),
|
|
157
130
|
...(instance.$afterPostInstall ? await instance.$afterPostInstall(data) : [])
|
|
158
131
|
];
|
|
159
132
|
}
|
|
160
133
|
createCommand(metadata) {
|
|
161
|
-
const {
|
|
134
|
+
const { name, description, alias, inputSchema } = metadata;
|
|
162
135
|
if (this.commands.has(name)) {
|
|
163
136
|
return this.commands.get(name).command;
|
|
164
137
|
}
|
|
165
|
-
|
|
138
|
+
const { args, options, allowUnknownOption } = metadata.getOptions();
|
|
166
139
|
const onAction = (commandName) => {
|
|
167
140
|
const [, ...rawArgs] = cmd.args;
|
|
168
141
|
const mappedArgs = mapCommanderArgs(args, this.program.args.filter((arg) => commandName === arg));
|
|
169
142
|
const allOpts = mapCommanderOptions(commandName, this.program.commands);
|
|
170
|
-
|
|
143
|
+
let data = {
|
|
171
144
|
...allOpts,
|
|
172
145
|
verbose: !!this.program.opts().verbose,
|
|
173
146
|
...mappedArgs,
|
|
174
147
|
...cmd.opts(),
|
|
175
148
|
rawArgs
|
|
176
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
|
+
}
|
|
177
163
|
const $ctx = new DIContext({
|
|
178
164
|
id: v4(),
|
|
179
165
|
injector: injector(),
|
|
@@ -187,6 +173,7 @@ export class CliService {
|
|
|
187
173
|
configuration().set("command.metadata", metadata);
|
|
188
174
|
return this.runLifecycle(name, data, $ctx);
|
|
189
175
|
};
|
|
176
|
+
let cmd = this.program.command(name);
|
|
190
177
|
if (alias) {
|
|
191
178
|
cmd = cmd.alias(alias);
|
|
192
179
|
}
|
|
@@ -205,7 +192,7 @@ export class CliService {
|
|
|
205
192
|
}
|
|
206
193
|
mapData(cmdName, data, $ctx) {
|
|
207
194
|
const provider = this.commands.get(cmdName);
|
|
208
|
-
const instance = inject(provider.
|
|
195
|
+
const instance = inject(provider.token);
|
|
209
196
|
const verbose = data.verbose;
|
|
210
197
|
data.commandName ||= cmdName;
|
|
211
198
|
if (instance.$mapContext) {
|
|
@@ -227,7 +214,7 @@ export class CliService {
|
|
|
227
214
|
* @param provider
|
|
228
215
|
*/
|
|
229
216
|
build(provider) {
|
|
230
|
-
const metadata = getCommandMetadata(provider.
|
|
217
|
+
const metadata = getCommandMetadata(provider.token);
|
|
231
218
|
if (metadata.name) {
|
|
232
219
|
if (this.commands.has(metadata.name)) {
|
|
233
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
|
}
|
package/lib/esm/utils/index.js
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Ajv } from "ajv";
|
|
2
|
+
const ajv = new Ajv({
|
|
3
|
+
verbose: false,
|
|
4
|
+
coerceTypes: true,
|
|
5
|
+
strict: false,
|
|
6
|
+
allErrors: true
|
|
7
|
+
});
|
|
8
|
+
export function validate(value, schema) {
|
|
9
|
+
const validate = ajv.compile(schema.toJSON());
|
|
10
|
+
const result = validate(value);
|
|
11
|
+
if (!result) {
|
|
12
|
+
const errors = (validate.errors || []).map((e) => ({
|
|
13
|
+
path: e.instancePath || e.schemaPath,
|
|
14
|
+
message: e.message,
|
|
15
|
+
expected: (e.params && e.params.type) || undefined
|
|
16
|
+
}));
|
|
17
|
+
return {
|
|
18
|
+
isValid: false,
|
|
19
|
+
errors: errors
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return { isValid: true, value: value };
|
|
23
|
+
}
|
|
@@ -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
|
*/
|
|
@@ -5,9 +5,8 @@ export interface InstallOptions {
|
|
|
5
5
|
[key: string]: any;
|
|
6
6
|
}
|
|
7
7
|
export declare class PackageManagersModule {
|
|
8
|
-
protected packageManagers: BaseManager[];
|
|
9
8
|
protected projectPackageJson: ProjectPackageJson;
|
|
10
|
-
|
|
9
|
+
protected packageManagers: BaseManager[];
|
|
11
10
|
init(options?: InstallOptions): Promise<void>;
|
|
12
11
|
install(options?: InstallOptions): ({
|
|
13
12
|
title: string;
|
|
@@ -6,7 +6,7 @@ export declare class CliHttpLogClient {
|
|
|
6
6
|
callee: string;
|
|
7
7
|
protected logger: Logger;
|
|
8
8
|
constructor(options?: Partial<BaseLogClientOptions>);
|
|
9
|
-
protected onSuccess(options: Record<string, unknown>):
|
|
9
|
+
protected onSuccess(options: Record<string, unknown>): void;
|
|
10
10
|
protected onError(error: any, options: any): void;
|
|
11
11
|
protected logToCurl(options: any): string;
|
|
12
12
|
protected getStatusCodeFromError(error: any): any;
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { JsonSchema } from "@tsed/schema";
|
|
2
2
|
import { CliFs } from "./CliFs.js";
|
|
3
3
|
import { CliYaml } from "./CliYaml.js";
|
|
4
4
|
export declare class CliLoadFile {
|
|
5
|
-
#private;
|
|
6
5
|
protected cliYaml: CliYaml;
|
|
7
6
|
protected cliFs: CliFs;
|
|
8
|
-
constructor();
|
|
9
7
|
/**
|
|
10
8
|
* Load a configuration file from yaml, json
|
|
11
9
|
*/
|
|
12
|
-
loadFile<Model = any>(path: string, schema?:
|
|
10
|
+
loadFile<Model = any>(path: string, schema?: JsonSchema<Model>): Promise<Model>;
|
|
13
11
|
}
|
|
@@ -26,20 +26,14 @@ export declare class CliService {
|
|
|
26
26
|
* @param $ctx
|
|
27
27
|
*/
|
|
28
28
|
runLifecycle(cmdName: string, data: CommandData | undefined, $ctx: DIContext): Promise<Promise<void>>;
|
|
29
|
-
dispatch(cmdName: string, data: CommandData, $ctx: DIContext): Promise<void>;
|
|
30
29
|
exec(cmdName: string, data: any, $ctx: DIContext): Promise<any>;
|
|
31
30
|
/**
|
|
32
31
|
* Run prompt for a given command
|
|
33
32
|
* @param cmdName
|
|
34
|
-
* @param data
|
|
35
|
-
|
|
36
|
-
beforePrompt(cmdName: string, data?: CommandData): Promise<CommandData>;
|
|
37
|
-
/**
|
|
38
|
-
* Run prompt for a given command
|
|
39
|
-
* @param cmdName
|
|
40
|
-
* @param ctx Initial data
|
|
33
|
+
* @param data
|
|
34
|
+
* @param $ctx
|
|
41
35
|
*/
|
|
42
|
-
prompt(cmdName: string, ctx
|
|
36
|
+
prompt(cmdName: string, data: CommandData | undefined, $ctx: DIContext): Promise<CommandData>;
|
|
43
37
|
/**
|
|
44
38
|
* Run lifecycle
|
|
45
39
|
* @param cmdName
|
|
@@ -48,7 +42,7 @@ export declare class CliService {
|
|
|
48
42
|
getTasks(cmdName: string, data: any): Promise<Task[]>;
|
|
49
43
|
getPostInstallTasks(cmdName: string, data: any): Promise<any[]>;
|
|
50
44
|
createCommand(metadata: CommandMetadata): any;
|
|
51
|
-
|
|
45
|
+
load(): void;
|
|
52
46
|
private mapData;
|
|
53
47
|
/**
|
|
54
48
|
* Build command and sub-commands
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { JsonSchema } from "@tsed/schema";
|
|
2
|
+
export declare function validate<Value>(value: unknown, schema: JsonSchema<Value>): {
|
|
3
|
+
isValid: boolean;
|
|
4
|
+
errors: {
|
|
5
|
+
path: string;
|
|
6
|
+
message: string | undefined;
|
|
7
|
+
expected: any;
|
|
8
|
+
}[];
|
|
9
|
+
value?: undefined;
|
|
10
|
+
} | {
|
|
11
|
+
isValid: boolean;
|
|
12
|
+
value: Value;
|
|
13
|
+
errors?: undefined;
|
|
14
|
+
};
|
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
|