@tsed/cli-core 7.0.0-beta.3 → 7.0.0-beta.5

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 (33) hide show
  1. package/lib/esm/decorators/command.js +1 -1
  2. package/lib/esm/decorators/index.js +0 -4
  3. package/lib/esm/fn/command.js +31 -3
  4. package/lib/esm/interfaces/index.js +1 -1
  5. package/lib/esm/packageManagers/PackageManagersModule.js +1 -2
  6. package/lib/esm/packageManagers/index.js +1 -0
  7. package/lib/esm/services/CliPlugins.js +2 -2
  8. package/lib/esm/services/CliService.js +35 -51
  9. package/lib/esm/utils/getCommandMetadata.js +34 -7
  10. package/lib/types/decorators/command.d.ts +2 -2
  11. package/lib/types/decorators/index.d.ts +0 -4
  12. package/lib/types/fn/command.d.ts +58 -3
  13. package/lib/types/interfaces/CommandMetadata.d.ts +17 -15
  14. package/lib/types/interfaces/{CommandParameters.d.ts → CommandOptions.d.ts} +20 -3
  15. package/lib/types/interfaces/CommandProvider.d.ts +0 -10
  16. package/lib/types/interfaces/index.d.ts +3 -3
  17. package/lib/types/packageManagers/index.d.ts +1 -0
  18. package/lib/types/services/CliService.d.ts +1 -8
  19. package/lib/types/utils/mapCommanderArgs.d.ts +1 -1
  20. package/package.json +2 -2
  21. package/lib/esm/decorators/on.js +0 -8
  22. package/lib/esm/decorators/onAdd.js +0 -5
  23. package/lib/esm/decorators/onExec.js +0 -5
  24. package/lib/esm/decorators/onPostInstall.js +0 -5
  25. package/lib/esm/decorators/onPrompt.js +0 -5
  26. package/lib/esm/domains/CommandStoreKeys.js +0 -8
  27. package/lib/types/decorators/on.d.ts +0 -1
  28. package/lib/types/decorators/onAdd.d.ts +0 -1
  29. package/lib/types/decorators/onExec.d.ts +0 -1
  30. package/lib/types/decorators/onPostInstall.d.ts +0 -1
  31. package/lib/types/decorators/onPrompt.d.ts +0 -1
  32. package/lib/types/domains/CommandStoreKeys.d.ts +0 -7
  33. /package/lib/esm/interfaces/{CommandParameters.js → CommandOptions.js} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { command } from "../fn/command.js";
2
2
  export function Command(options) {
3
3
  return (token) => {
4
- command(token, options);
4
+ command({ ...options, token });
5
5
  };
6
6
  }
@@ -1,5 +1 @@
1
1
  export * from "./command.js";
2
- export * from "./onAdd.js";
3
- export * from "./onExec.js";
4
- export * from "./onPostInstall.js";
5
- export * from "./onPrompt.js";
@@ -1,5 +1,33 @@
1
1
  import { injectable } from "@tsed/di";
2
- import { CommandStoreKeys } from "../domains/CommandStoreKeys.js";
3
- export function command(token, options) {
4
- return injectable(token).type("command").set(CommandStoreKeys.COMMAND, options);
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 "./CommandParameters.js";
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 } = {}) {
@@ -119,4 +118,4 @@ export class PackageManagersModule {
119
118
  return this.get().runScript(scriptName, options).pipe(errorPipe());
120
119
  }
121
120
  }
122
- injectable(PackageManagersModule).imports([YarnManager, YarnBerryManager, NpmManager, PNpmManager, BunManager]);
121
+ injectable(PackageManagersModule).imports([YarnBerryManager, YarnManager, NpmManager, PNpmManager, BunManager]);
@@ -2,4 +2,5 @@ export * from "./PackageManagersModule.js";
2
2
  export * from "./supports/BaseManager.js";
3
3
  export * from "./supports/NpmManager.js";
4
4
  export * from "./supports/PNpmManager.js";
5
+ export * from "./supports/YarnBerryManager.js";
5
6
  export * from "./supports/YarnManager.js";
@@ -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 this.cliHooks.emit(CommandStoreKeys.ADD, plugin, ctx);
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 initialTasks = await this.getTasks(cmdName, data);
62
+ const tasks = await this.getTasks(cmdName, data);
65
63
  $ctx.set("data", data);
66
- if (initialTasks.length) {
67
- const tasks = [
68
- ...initialTasks,
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
- ...(await this.getPostInstallTasks(cmdName, data))
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.useClass);
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
- if (instance.$beforeExec) {
135
- await instance.$beforeExec(data);
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,45 @@ export class CliService {
152
122
  }
153
123
  async getPostInstallTasks(cmdName, data) {
154
124
  const provider = this.commands.get(cmdName);
155
- const instance = inject(provider.useClass);
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 { args, name, options, description, alias, allowUnknownOption } = metadata;
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
- let cmd = this.program.command(name);
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
- const data = {
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 schema = isArrowFn(inputSchema) ? inputSchema() : inputSchema;
152
+ const { isValid, errors, value } = validate(data, schema);
153
+ if (isValid) {
154
+ data = value;
155
+ }
156
+ else {
157
+ logger().error({
158
+ event: "VALIDATION_ERROR",
159
+ errors
160
+ });
161
+ throw new Error("Validation error");
162
+ }
163
+ }
181
164
  const $ctx = new DIContext({
182
165
  id: v4(),
183
166
  injector: injector(),
@@ -191,6 +174,7 @@ export class CliService {
191
174
  configuration().set("command.metadata", metadata);
192
175
  return this.runLifecycle(name, data, $ctx);
193
176
  };
177
+ let cmd = this.program.command(name);
194
178
  if (alias) {
195
179
  cmd = cmd.alias(alias);
196
180
  }
@@ -209,7 +193,7 @@ export class CliService {
209
193
  }
210
194
  mapData(cmdName, data, $ctx) {
211
195
  const provider = this.commands.get(cmdName);
212
- const instance = inject(provider.useClass);
196
+ const instance = inject(provider.token);
213
197
  const verbose = data.verbose;
214
198
  data.commandName ||= cmdName;
215
199
  if (instance.$mapContext) {
@@ -231,7 +215,7 @@ export class CliService {
231
215
  * @param provider
232
216
  */
233
217
  build(provider) {
234
- const metadata = getCommandMetadata(provider.useClass);
218
+ const metadata = getCommandMetadata(provider.token);
235
219
  if (metadata.name) {
236
220
  if (this.commands.has(metadata.name)) {
237
221
  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 = {}, allowUnknownOption, description, options = {}, enableFeatures, disableReadUpPkg, bindLogger = true, ...opts } = Store.from(token)?.get(CommandStoreKeys.COMMAND);
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 { CommandParameters } from "../interfaces/CommandParameters.js";
2
- export declare function Command(options: CommandParameters): ClassDecorator;
1
+ import type { BaseCommandOptions } from "../interfaces/CommandOptions.js";
2
+ export declare function Command<Input = any>(options: BaseCommandOptions<Input>): ClassDecorator;
@@ -1,5 +1 @@
1
1
  export * from "./command.js";
2
- export * from "./onAdd.js";
3
- export * from "./onExec.js";
4
- export * from "./onPostInstall.js";
5
- export * from "./onPrompt.js";
@@ -1,3 +1,58 @@
1
- import { injectable, type TokenProvider } from "@tsed/di";
2
- import type { CommandParameters } from "../interfaces/CommandParameters.js";
3
- export declare function command(token: TokenProvider, options: CommandParameters): ReturnType<typeof injectable>;
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 { CommandArg, CommandOptions, CommandParameters } from "./CommandParameters.js";
2
- export interface CommandMetadata extends CommandParameters {
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 CommandOptions {
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 CommandParameters {
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]: CommandOptions;
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 { Type } from "@tsed/core";
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 "./CommandParameters.js";
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: Type<CommandProvider>[];
18
+ commands: TokenProvider<CommandProvider>[];
19
19
  /**
20
20
  * Init Cli with defined argv
21
21
  */
@@ -2,4 +2,5 @@ export * from "./PackageManagersModule.js";
2
2
  export * from "./supports/BaseManager.js";
3
3
  export * from "./supports/NpmManager.js";
4
4
  export * from "./supports/PNpmManager.js";
5
+ export * from "./supports/YarnBerryManager.js";
5
6
  export * from "./supports/YarnManager.js";
@@ -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
- private load;
45
+ load(): void;
53
46
  private mapData;
54
47
  /**
55
48
  * Build command and sub-commands
@@ -1,4 +1,4 @@
1
- import type { CommandArg } from "../interfaces/CommandParameters.js";
1
+ import type { CommandArg } from "../interfaces/CommandOptions.js";
2
2
  export declare function mapCommanderArgs(args: {
3
3
  [arg: string]: CommandArg;
4
4
  }, commandArgs: any[]): any;
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.3",
4
+ "version": "7.0.0-beta.5",
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.3",
68
+ "@tsed/typescript": "7.0.0-beta.5",
69
69
  "@types/commander": "2.12.2",
70
70
  "@types/figures": "3.0.1",
71
71
  "@types/fs-extra": "^11.0.4",
@@ -1,8 +0,0 @@
1
- import { StoreMerge } from "@tsed/core";
2
- export function On(hookName, name) {
3
- return (target, propertyKey) => {
4
- StoreMerge(hookName, {
5
- [name]: [propertyKey]
6
- })(target);
7
- };
8
- }
@@ -1,5 +0,0 @@
1
- import { CommandStoreKeys } from "../domains/CommandStoreKeys.js";
2
- import { On } from "./on.js";
3
- export function OnAdd(cliPlugin) {
4
- return On(CommandStoreKeys.ADD, cliPlugin);
5
- }
@@ -1,5 +0,0 @@
1
- import { CommandStoreKeys } from "../domains/CommandStoreKeys.js";
2
- import { On } from "./on.js";
3
- export function OnExec(cmdName) {
4
- return On(CommandStoreKeys.EXEC_HOOKS, cmdName);
5
- }
@@ -1,5 +0,0 @@
1
- import { CommandStoreKeys } from "../domains/CommandStoreKeys.js";
2
- import { On } from "./on.js";
3
- export function OnPostInstall(cmdName) {
4
- return On(CommandStoreKeys.POST_INSTALL_HOOKS, cmdName);
5
- }
@@ -1,5 +0,0 @@
1
- import { CommandStoreKeys } from "../domains/CommandStoreKeys.js";
2
- import { On } from "./on.js";
3
- export function OnPrompt(cmdName) {
4
- return On(CommandStoreKeys.PROMPT_HOOKS, cmdName);
5
- }
@@ -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;
@@ -1,7 +0,0 @@
1
- export declare enum CommandStoreKeys {
2
- COMMAND = "command",
3
- ADD = "$onAdd",
4
- EXEC_HOOKS = "$onExec",
5
- POST_INSTALL_HOOKS = "$onPostInstall",
6
- PROMPT_HOOKS = "$onPrompt"
7
- }