@tsed/cli 7.0.0-alpha.4 → 7.0.0-alpha.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 (70) hide show
  1. package/lib/esm/Cli.js +1 -0
  2. package/lib/esm/bin/tsed.js +1 -0
  3. package/lib/esm/commands/generate/GenerateCmd.js +6 -5
  4. package/lib/esm/commands/index.js +2 -1
  5. package/lib/esm/commands/template/CreateTemplateCommand.js +99 -0
  6. package/lib/esm/services/CliProjectService.js +4 -5
  7. package/lib/esm/services/CliTemplatesService.js +57 -9
  8. package/lib/esm/services/ProjectClient.js +22 -22
  9. package/lib/esm/services/mappers/addContextMethods.js +17 -0
  10. package/lib/esm/services/mappers/mapDefaultTemplateOptions.js +7 -1
  11. package/lib/esm/templates/barrels.template.js +3 -2
  12. package/lib/esm/templates/controller.template.js +24 -25
  13. package/lib/esm/templates/decorator.template.js +26 -24
  14. package/lib/esm/templates/docker-compose.template.js +2 -2
  15. package/lib/esm/templates/dockerfile.template.js +5 -5
  16. package/lib/esm/templates/index.command.template.js +1 -0
  17. package/lib/esm/templates/index.config.utils.template.js +1 -1
  18. package/lib/esm/templates/index.js +1 -0
  19. package/lib/esm/templates/index.logger.template.js +2 -1
  20. package/lib/esm/templates/middleware.template.js +16 -14
  21. package/lib/esm/templates/new-template.template.js +67 -0
  22. package/lib/esm/templates/readme.template.js +3 -3
  23. package/lib/esm/templates/tsconfig.spec.template.js +5 -4
  24. package/lib/esm/templates/tsconfig.template.js +3 -2
  25. package/lib/esm/utils/defineTemplate.js +2 -2
  26. package/lib/tsconfig.esm.tsbuildinfo +1 -1
  27. package/lib/types/Cli.d.ts +2 -1
  28. package/lib/types/bin/tsed.d.ts +1 -1
  29. package/lib/types/commands/generate/GenerateCmd.d.ts +1 -36
  30. package/lib/types/commands/index.d.ts +2 -1
  31. package/lib/types/commands/template/CreateTemplateCommand.d.ts +62 -0
  32. package/lib/types/interfaces/GenerateCmdContext.d.ts +2 -0
  33. package/lib/types/pipes/SymbolNamePipe.d.ts +1 -1
  34. package/lib/types/services/CliProjectService.d.ts +2 -2
  35. package/lib/types/services/CliTemplatesService.d.ts +7 -3
  36. package/lib/types/services/ProjectClient.d.ts +3 -3
  37. package/lib/types/services/mappers/addContextMethods.d.ts +12 -0
  38. package/lib/types/templates/asyncFactory.template.d.ts +15 -1
  39. package/lib/types/templates/barrels.template.d.ts +15 -1
  40. package/lib/types/templates/command.template.d.ts +15 -1
  41. package/lib/types/templates/config.template.d.ts +15 -1
  42. package/lib/types/templates/controller.template.d.ts +16 -1
  43. package/lib/types/templates/decorator.template.d.ts +16 -1
  44. package/lib/types/templates/docker-compose.template.d.ts +15 -1
  45. package/lib/types/templates/exception-filter.template.d.ts +15 -1
  46. package/lib/types/templates/factory.template.d.ts +15 -1
  47. package/lib/types/templates/index.command.template.d.ts +15 -1
  48. package/lib/types/templates/index.config.utils.template.d.ts +15 -1
  49. package/lib/types/templates/index.controller.template.d.ts +15 -1
  50. package/lib/types/templates/index.d.ts +1 -0
  51. package/lib/types/templates/index.logger.template.d.ts +15 -1
  52. package/lib/types/templates/index.template.d.ts +15 -1
  53. package/lib/types/templates/interceptor.template.d.ts +15 -1
  54. package/lib/types/templates/interface.template.d.ts +15 -1
  55. package/lib/types/templates/middleware.template.d.ts +16 -1
  56. package/lib/types/templates/model.template.d.ts +15 -1
  57. package/lib/types/templates/module.template.d.ts +15 -1
  58. package/lib/types/templates/new-template.template.d.ts +9 -0
  59. package/lib/types/templates/pipe.template.d.ts +15 -1
  60. package/lib/types/templates/prisma.service.template.d.ts +15 -1
  61. package/lib/types/templates/readme.template.d.ts +15 -1
  62. package/lib/types/templates/repository.template.d.ts +15 -1
  63. package/lib/types/templates/response-filter.template.d.ts +15 -1
  64. package/lib/types/templates/server.template.d.ts +15 -1
  65. package/lib/types/templates/service.template.d.ts +15 -1
  66. package/lib/types/templates/tsconfig.spec.template.d.ts +15 -1
  67. package/lib/types/templates/tsconfig.template.d.ts +15 -1
  68. package/lib/types/templates/value.template.d.ts +15 -1
  69. package/lib/types/utils/defineTemplate.d.ts +31 -3
  70. package/package.json +3 -3
package/lib/esm/Cli.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import "@tsed/logger-std";
2
+ import "./templates/index.js";
2
3
  import { CliCore } from "@tsed/cli-core";
3
4
  import chalk from "chalk";
4
5
  import commands from "./commands/index.js";
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import "@swc-node/register/esm-register";
2
3
  import { register } from "node:module";
3
4
  import { join } from "node:path";
4
5
  import { pathToFileURL } from "node:url";
@@ -1,14 +1,15 @@
1
1
  import { command, inject, ProjectPackageJson } from "@tsed/cli-core";
2
- import { pascalCase } from "change-case";
3
2
  import { CliProjectService } from "../../services/CliProjectService.js";
4
3
  import { CliTemplatesService } from "../../services/CliTemplatesService.js";
4
+ import { addContextMethods } from "../../services/mappers/addContextMethods.js";
5
5
  import { mapDefaultTemplateOptions } from "../../services/mappers/mapDefaultTemplateOptions.js";
6
6
  const searchFactory = (list) => {
7
+ const items = list.map((item) => ({ name: item.label, value: item.id }));
7
8
  return (_, keyword) => {
8
9
  if (keyword) {
9
- return list.filter((item) => item.label.toLowerCase().includes(keyword.toLowerCase()));
10
+ return items.filter((item) => item.name.toLowerCase().includes(keyword.toLowerCase()));
10
11
  }
11
- return list;
12
+ return items;
12
13
  };
13
14
  };
14
15
  export class GenerateCmd {
@@ -18,7 +19,7 @@ export class GenerateCmd {
18
19
  this.templates = inject(CliTemplatesService);
19
20
  }
20
21
  async $prompt(data) {
21
- data.getName = (state) => data.name || pascalCase(state.name || data.name || state.type || data.type || "");
22
+ data = addContextMethods(data);
22
23
  const templates = this.templates.find();
23
24
  const templatesPrompts = await Promise.all(templates
24
25
  .filter((template) => template.prompts)
@@ -29,7 +30,7 @@ export class GenerateCmd {
29
30
  {
30
31
  type: "autocomplete",
31
32
  name: "type",
32
- message: "Which type of provider?",
33
+ message: "Which template you want to use?",
33
34
  default: data.type,
34
35
  when: () => templates.length > 1,
35
36
  source: searchFactory(this.templates.find(data.type))
@@ -2,5 +2,6 @@ import { AddCmd } from "./add/AddCmd.js";
2
2
  import { GenerateCmd } from "./generate/GenerateCmd.js";
3
3
  import { InitCmd } from "./init/InitCmd.js";
4
4
  import { RunCmd } from "./run/RunCmd.js";
5
+ import { CreateTemplateCommand } from "./template/CreateTemplateCommand.js";
5
6
  import { UpdateCmd } from "./update/UpdateCmd.js";
6
- export default [AddCmd, InitCmd, GenerateCmd, UpdateCmd, RunCmd];
7
+ export default [AddCmd, InitCmd, GenerateCmd, UpdateCmd, RunCmd, CreateTemplateCommand];
@@ -0,0 +1,99 @@
1
+ import { command, inject, ProjectPackageJson } from "@tsed/cli-core";
2
+ import { snakeCase } from "change-case";
3
+ import { render } from "../../fn/render.js";
4
+ import { CliTemplatesService } from "../../services/CliTemplatesService.js";
5
+ const searchFactory = (list) => {
6
+ const items = list.map((item) => ({ name: item.label, value: item.id }));
7
+ return (_, keyword) => {
8
+ if (keyword) {
9
+ return items.filter((item) => item.name.toLowerCase().includes(keyword.toLowerCase()));
10
+ }
11
+ return items;
12
+ };
13
+ };
14
+ export class CreateTemplateCommand {
15
+ constructor() {
16
+ this.projectPackageJson = inject(ProjectPackageJson);
17
+ this.templates = inject(CliTemplatesService);
18
+ }
19
+ async $prompt(data) {
20
+ return [
21
+ {
22
+ type: "list",
23
+ name: "from",
24
+ message: "Create a template from existing one?",
25
+ default: "new",
26
+ when: !data.from,
27
+ choices: [
28
+ { name: "No, create a new template", value: "new" },
29
+ { name: "Yes, from existing template", value: "existing" }
30
+ ]
31
+ },
32
+ {
33
+ type: "autocomplete",
34
+ name: "templateId",
35
+ message: "Select the template to use as base",
36
+ default: data.from,
37
+ when: (ctx) => {
38
+ return ctx.from === "existing";
39
+ },
40
+ source: searchFactory(this.templates.find())
41
+ },
42
+ {
43
+ type: "confirm",
44
+ name: "override",
45
+ message: "Would you like to override the selected Ts.ED default template?",
46
+ when: (ctx) => ctx.from !== "new",
47
+ default: !!data.override
48
+ },
49
+ {
50
+ type: "input",
51
+ name: "name",
52
+ message: "Which name?",
53
+ default: data.name,
54
+ when: !data.name
55
+ }
56
+ ];
57
+ }
58
+ $mapContext(ctx) {
59
+ const symbolName = snakeCase(ctx.name).replace(/_/g, "-");
60
+ return {
61
+ ...ctx,
62
+ symbolPath: `./.templates/${symbolName}.template`,
63
+ symbolPathBasename: ".",
64
+ symbolName: symbolName,
65
+ templateId: ctx.orverride ? ctx.templateId : symbolName,
66
+ template: ctx.templateId && this.templates.get(ctx.templateId)
67
+ };
68
+ }
69
+ $exec(ctx) {
70
+ return [
71
+ {
72
+ title: "Generate " + ctx.from === "new" ? `new template ${ctx.templateId}` : `template ${ctx.templateId} from ${ctx.from}`,
73
+ task: async () => {
74
+ await render("new-template", ctx);
75
+ }
76
+ }
77
+ ];
78
+ }
79
+ }
80
+ command(CreateTemplateCommand, {
81
+ name: "template",
82
+ description: "Create a custom template that can be selected in tsed generate command",
83
+ args: {
84
+ name: {
85
+ description: "Name of the class",
86
+ type: String
87
+ }
88
+ },
89
+ options: {
90
+ "--from <from>": {
91
+ type: String,
92
+ description: "Select the template to use as base"
93
+ },
94
+ "--override": {
95
+ type: Boolean,
96
+ description: "Override the existing selected template"
97
+ }
98
+ }
99
+ });
@@ -32,7 +32,7 @@ export class CliProjectService {
32
32
  this.project = new ProjectClient({
33
33
  rootDir: this.rootDir
34
34
  });
35
- const files = fs.globSync([join(constant("project.rootDir", process.cwd()), "**/*.ts")]);
35
+ const files = fs.globSync(["!**/node_modules/**", join(constant("project.rootDir", process.cwd()), "**/*.ts")]);
36
36
  files.forEach((file) => {
37
37
  this.project.createSourceFile(file, fs.readFileSync(file, "utf8"), {
38
38
  overwrite: true
@@ -66,15 +66,14 @@ export class CliProjectService {
66
66
  return sourceFile.save();
67
67
  }));
68
68
  }
69
- async createFromTemplate(templateId, ctx) {
70
- const startTime = Date.now();
71
- const obj = await this.templates.render(templateId, ctx);
72
- taskOutput(`Template ${templateId} rendered in ${Date.now() - startTime}ms`);
69
+ async createFromTemplate(templateId, data) {
70
+ const obj = await this.templates.render(templateId, data);
73
71
  const project = this.get();
74
72
  if (obj) {
75
73
  const sourceFile = await project.createSource(obj.outputPath, obj.content, {
76
74
  overwrite: true
77
75
  });
76
+ sourceFile && this.templates.get(templateId)?.hooks?.$afterCreateSourceFile?.(sourceFile, data);
78
77
  return {
79
78
  ...obj,
80
79
  source: sourceFile
@@ -1,27 +1,75 @@
1
1
  import { join } from "node:path";
2
2
  import { CliFs } from "@tsed/cli-core";
3
- import { constant, inject, injectable, injectMany } from "@tsed/di";
3
+ import { constant, inject, injectable, injectMany, logger } from "@tsed/di";
4
+ import { globby } from "globby";
4
5
  import { TEMPLATE_DIR } from "../constants/index.js";
5
6
  import { mapDefaultTemplateOptions } from "./mappers/mapDefaultTemplateOptions.js";
6
7
  export class CliTemplatesService {
7
8
  constructor() {
8
9
  this.rootDir = constant("project.rootDir", process.cwd());
9
10
  this.fs = inject(CliFs);
11
+ this.#templates = new Map();
10
12
  }
13
+ #customTemplates;
14
+ #templates;
11
15
  get srcDir() {
12
16
  return join(...[this.rootDir, constant("project.srcDir")].filter(Boolean));
13
17
  }
18
+ get templatesDir() {
19
+ return join(this.rootDir, ".templates");
20
+ }
21
+ $onInit() {
22
+ return this.loadTemplates();
23
+ }
24
+ async loadTemplates() {
25
+ if (!this.#customTemplates?.length) {
26
+ const files = await globby("**/*.ts", {
27
+ cwd: this.templatesDir
28
+ });
29
+ const promises = files.map(async (file) => {
30
+ try {
31
+ const files = join(this.templatesDir, file);
32
+ const { default: token } = await import(files.replace(".ts", ".js"));
33
+ if (token) {
34
+ return inject(token);
35
+ }
36
+ }
37
+ catch (er) {
38
+ logger().warn("Unable to load custom template %s: %s", file, er.message);
39
+ }
40
+ });
41
+ let customs = await Promise.all(promises);
42
+ this.#customTemplates = customs.map((template) => {
43
+ return {
44
+ ...template,
45
+ label: template.label + " (custom)"
46
+ };
47
+ });
48
+ }
49
+ }
50
+ getAll() {
51
+ const templates = injectMany("CLI_TEMPLATES");
52
+ const map = (this.#customTemplates || []).concat(templates).reduce((acc, template) => {
53
+ if (acc.has(template.id)) {
54
+ return acc;
55
+ }
56
+ return acc.set(template.id, template);
57
+ }, new Map());
58
+ return [...map.values()];
59
+ }
14
60
  find(id) {
15
- const templates = injectMany("CLI_TEMPLATES").filter((template) => !template.hidden);
16
- id = id?.toLowerCase();
17
- const foundTemplates = templates.filter((template) => {
18
- return template.label.toLowerCase().includes(id) || template.id.includes(id);
19
- });
20
- return foundTemplates.length ? foundTemplates : templates;
61
+ const templates = this.getAll().filter((template) => !template.hidden);
62
+ if (id) {
63
+ id = id?.toLowerCase();
64
+ const foundTemplates = templates.filter((template) => {
65
+ return template.label.toLowerCase().includes(id) || template.id.includes(id);
66
+ });
67
+ return foundTemplates.length ? foundTemplates : templates;
68
+ }
69
+ return templates;
21
70
  }
22
71
  get(id) {
23
- const templates = injectMany("CLI_TEMPLATES");
24
- return templates.find((template) => template.id === id);
72
+ return this.getAll().find((template) => template.id === id);
25
73
  }
26
74
  async render(templateId, data) {
27
75
  const template = this.get(templateId);
@@ -113,6 +113,28 @@ export class ProjectClient extends Project {
113
113
  })
114
114
  .getInitializerIfKindOrThrow(kind));
115
115
  }
116
+ addConfigSource(name, { content = name, moduleSpecifier }) {
117
+ const sourceFile = this.configSourceFile;
118
+ const options = this.findConfiguration("config");
119
+ if (!options) {
120
+ return;
121
+ }
122
+ const extendsConfig = this.getPropertyAssignment(options, {
123
+ name: "extends",
124
+ kind: SyntaxKind.ArrayLiteralExpression,
125
+ initializer: "[]"
126
+ });
127
+ const has = extendsConfig.getElements().some((expression) => {
128
+ return expression.getText().includes(name);
129
+ });
130
+ if (!has) {
131
+ sourceFile.addImportDeclaration({
132
+ moduleSpecifier,
133
+ namedImports: [{ name: name }]
134
+ });
135
+ extendsConfig.addElement("\n" + content);
136
+ }
137
+ }
116
138
  findConfigurationDecorationOptions() {
117
139
  if (!this.serverSourceFile) {
118
140
  return;
@@ -137,26 +159,4 @@ export class ProjectClient extends Project {
137
159
  }
138
160
  return undefined;
139
161
  }
140
- addConfigSource(name, { content = name, moduleSpecifier }) {
141
- const sourceFile = this.configSourceFile;
142
- const options = this.findConfiguration("config");
143
- if (!options) {
144
- return;
145
- }
146
- const extendsConfig = this.getPropertyAssignment(options, {
147
- name: "extends",
148
- kind: SyntaxKind.ArrayLiteralExpression,
149
- initializer: "[]"
150
- });
151
- const has = extendsConfig.getElements().some((expression) => {
152
- return expression.getText().includes(name);
153
- });
154
- if (!has) {
155
- sourceFile.addImportDeclaration({
156
- moduleSpecifier,
157
- namedImports: [{ name: name }]
158
- });
159
- extendsConfig.addElement("\n" + content);
160
- }
161
- }
162
162
  }
@@ -0,0 +1,17 @@
1
+ import { inject } from "@tsed/cli-core";
2
+ import { isString } from "@tsed/core";
3
+ import { pascalCase } from "change-case";
4
+ import { RoutePipe } from "../../pipes/RoutePipe.js";
5
+ import { CliProjectService } from "../CliProjectService.js";
6
+ export function addContextMethods(context) {
7
+ const getName = (state) => context.name || pascalCase(state.name || context.name || state.type || context.type || "");
8
+ return {
9
+ getName,
10
+ getRoute: (state) => {
11
+ return inject(RoutePipe).transform(isString(state) ? state : getName(state));
12
+ },
13
+ getDirectories: (dir) => {
14
+ return inject(CliProjectService).getDirectories(dir);
15
+ }
16
+ };
17
+ }
@@ -1,8 +1,13 @@
1
1
  import { inject, ProjectPackageJson } from "@tsed/cli-core";
2
+ import { isString } from "@tsed/core";
2
3
  import { normalizePath } from "@tsed/normalize-path";
4
+ import { pascalCase } from "change-case";
3
5
  import { ProjectConvention } from "../../interfaces/ProjectConvention.js";
4
6
  import { OutputFilePathPipe } from "../../pipes/OutputFilePathPipe.js";
7
+ import { RoutePipe } from "../../pipes/RoutePipe.js";
5
8
  import { SymbolNamePipe } from "../../pipes/SymbolNamePipe.js";
9
+ import { CliProjectService } from "../CliProjectService.js";
10
+ import { addContextMethods } from "./addContextMethods.js";
6
11
  export function mapDefaultTemplateOptions(opts) {
7
12
  const classNamePipe = inject(SymbolNamePipe);
8
13
  const outputFilePathPipe = inject(OutputFilePathPipe);
@@ -25,6 +30,7 @@ export function mapDefaultTemplateOptions(opts) {
25
30
  type,
26
31
  symbolName,
27
32
  symbolPath,
28
- symbolPathBasename: opts.symbolPathBasename || normalizePath(classNamePipe.transform({ name, type }))
33
+ symbolPathBasename: opts.symbolPathBasename || normalizePath(classNamePipe.transform({ name, type })),
34
+ ...addContextMethods(opts)
29
35
  };
30
36
  }
@@ -7,13 +7,14 @@ export default defineTemplate({
7
7
  fileName: ".barrels",
8
8
  ext: "json",
9
9
  outputDir: ".",
10
+ hidden: true,
10
11
  preserveCase: true,
11
12
  prompts() {
12
13
  return [];
13
14
  },
14
- render(_, data) {
15
+ render(_, context) {
15
16
  const barrels = $alter("$alterBarrels", {
16
- directory: ["./src/controllers/rest", data.swagger || (data.oidc && "./src/controllers/pages")].filter(Boolean),
17
+ directory: ["./src/controllers/rest", (context.swagger || context.oidc) && "./src/controllers/pages"].filter(Boolean),
17
18
  exclude: ["**/__mock__", "**/__mocks__", "**/*.spec.ts"],
18
19
  delete: true
19
20
  });
@@ -1,36 +1,35 @@
1
1
  import { defineTemplate } from "../utils/defineTemplate.js";
2
- import { RoutePipe } from "../pipes/index.js";
3
- import { CliProjectService } from "../services/CliProjectService.js";
4
- import { inject } from "@tsed/di";
5
2
  export default defineTemplate({
6
3
  id: "controller",
7
4
  label: "Controller",
8
5
  fileName: "{{symbolName}}.controller",
9
6
  outputDir: "{{srcDir}}/controllers",
10
- prompts: (data) => [
11
- {
12
- type: "list",
13
- name: "directory",
14
- message: "Which directory?",
15
- when(state) {
16
- return !!(["controller"].includes(state.type || data.type) || data.directory);
7
+ prompts(context) {
8
+ return [
9
+ {
10
+ type: "list",
11
+ name: "directory",
12
+ message: "Which directory?",
13
+ when(state) {
14
+ return !!(["controller"].includes(state.type || context.type) || context.directory);
15
+ },
16
+ choices: context.getDirectories("controllers")
17
17
  },
18
- choices: inject(CliProjectService).getDirectories("controllers")
19
- },
20
- {
21
- type: "input",
22
- name: "route",
23
- message: "Which route?",
24
- when(state) {
25
- return !!(["controller"].includes(state.type || data.type) || data.route);
26
- },
27
- default: (state) => {
28
- return inject(RoutePipe).transform(data.getName(state));
18
+ {
19
+ type: "input",
20
+ name: "route",
21
+ message: "Which route?",
22
+ when(state) {
23
+ return !!(["controller"].includes(state.type || context.type) || context.route);
24
+ },
25
+ default: (state) => {
26
+ return context.getRoute(state);
27
+ }
29
28
  }
30
- }
31
- ],
32
- render(symbolName, data) {
33
- const route = inject(RoutePipe).transform(data.route);
29
+ ];
30
+ },
31
+ render(symbolName, context) {
32
+ const route = context.getRoute(context.route);
34
33
  return `import {Controller} from "@tsed/di";
35
34
  import {Get} from "@tsed/schema";
36
35
 
@@ -4,30 +4,32 @@ export default defineTemplate({
4
4
  label: "Decorator",
5
5
  fileName: "{{symbolName}}",
6
6
  outputDir: "{{srcDir}}/decorators",
7
- prompts: (data) => [
8
- {
9
- type: "list",
10
- name: "templateType",
11
- message: "What kind of decorator do you want to create?",
12
- when(state) {
13
- return !!(["decorator"].includes(state.type || data.type) || data.templateType);
14
- },
15
- choices: [
16
- { name: "Class Decorator", value: "class" },
17
- { name: "Generic Decorator (class, property)", value: "generic" },
18
- { name: "Method Decorator", value: "method" },
19
- { name: "Parameter Decorator", value: "param" },
20
- { name: "Property Decorator", value: "property" },
21
- { name: "Property Decorator (with @Property)", value: "prop" },
22
- { name: "Parameters Decorator", value: "parameters" },
23
- { name: "Endpoint Decorator", value: "endpoint" },
24
- { name: "Middleware Decorator", value: "middleware" }
25
- ],
26
- default: "class"
27
- }
28
- ],
29
- render(symbolName, data) {
30
- const type = data.templateType || "class";
7
+ prompts(context) {
8
+ return [
9
+ {
10
+ type: "list",
11
+ name: "templateType",
12
+ message: "What kind of decorator do you want to create?",
13
+ when(state) {
14
+ return !!(["decorator"].includes(state.type || context.type) || context.templateType);
15
+ },
16
+ choices: [
17
+ { name: "Class Decorator", value: "class" },
18
+ { name: "Generic Decorator (class, property)", value: "generic" },
19
+ { name: "Method Decorator", value: "method" },
20
+ { name: "Parameter Decorator", value: "param" },
21
+ { name: "Property Decorator", value: "property" },
22
+ { name: "Property Decorator (with @Property)", value: "prop" },
23
+ { name: "Parameters Decorator", value: "parameters" },
24
+ { name: "Endpoint Decorator", value: "endpoint" },
25
+ { name: "Middleware Decorator", value: "middleware" }
26
+ ],
27
+ default: "class"
28
+ }
29
+ ];
30
+ },
31
+ render(symbolName, context) {
32
+ const type = context.templateType || "class";
31
33
  switch (type) {
32
34
  case "class":
33
35
  return `
@@ -7,7 +7,7 @@ export default defineTemplate({
7
7
  outputDir: ".",
8
8
  ext: "yml",
9
9
  preserveCase: true,
10
- render(_, data) {
10
+ render(_, context) {
11
11
  return `services:
12
12
  server:
13
13
  build:
@@ -17,7 +17,7 @@ export default defineTemplate({
17
17
  - http_proxy
18
18
  - https_proxy
19
19
  - no_proxy
20
- image: ${data.projectName}/server:latest
20
+ image: ${context.projectName}/server:latest
21
21
  ports:
22
22
  - "8081:8081"
23
23
  `;
@@ -32,7 +32,7 @@ ENV NODE_ENV production`;
32
32
  }
33
33
  defineTemplate({
34
34
  id: "dockerfile.yarn",
35
- label: "Dockerfile",
35
+ label: "Dockerfile (Yarn classic)",
36
36
  fileName: "Dockerfile",
37
37
  outputDir: ".",
38
38
  ext: null,
@@ -71,7 +71,7 @@ CMD ["pm2-runtime", "start", "processes.config.cjs", "--env", "production"]
71
71
  });
72
72
  defineTemplate({
73
73
  id: "dockerfile.yarn_berry",
74
- label: "Dockerfile",
74
+ label: "Dockerfile (Yarn Berry)",
75
75
  fileName: "Dockerfile",
76
76
  outputDir: ".",
77
77
  ext: null,
@@ -113,7 +113,7 @@ CMD ["pm2-runtime", "start", "processes.config.cjs", "--env", "production"]
113
113
  });
114
114
  defineTemplate({
115
115
  id: "dockerfile.npm",
116
- label: "Dockerfile",
116
+ label: "Dockerfile (NPM)",
117
117
  fileName: "Dockerfile",
118
118
  outputDir: ".",
119
119
  ext: null,
@@ -151,7 +151,7 @@ CMD ["pm2-runtime", "start", "processes.config.cjs", "--env", "production"]`;
151
151
  });
152
152
  defineTemplate({
153
153
  id: "dockerfile.pnpm",
154
- label: "Dockerfile",
154
+ label: "Dockerfile (PNPM)",
155
155
  fileName: "Dockerfile",
156
156
  outputDir: ".",
157
157
  ext: null,
@@ -190,7 +190,7 @@ CMD ["pm2-runtime", "start", "processes.config.cjs", "--env", "production"]
190
190
  });
191
191
  defineTemplate({
192
192
  id: "dockerfile.bun",
193
- label: "Dockerfile",
193
+ label: "Dockerfile (Bun)",
194
194
  fileName: "Dockerfile",
195
195
  outputDir: ".",
196
196
  ext: null,
@@ -4,6 +4,7 @@ export default defineTemplate({
4
4
  label: "CLI Entry Point",
5
5
  description: "Create a new CLI entry point file",
6
6
  outputDir: "{{srcDir}}/bin",
7
+ hidden: true,
7
8
  render() {
8
9
  return `#!/usr/bin/env node
9
10
  import {CliCore} from "@tsed/cli-core";
@@ -8,7 +8,7 @@ export default defineTemplate({
8
8
  outputDir: "{{srcDir}}/config/utils",
9
9
  preserveCase: true,
10
10
  hidden: true,
11
- render(_, data) {
11
+ render() {
12
12
  return `process.env.NODE_ENV = process.env.NODE_ENV || "development";
13
13
 
14
14
  export const isProduction = process.env.NODE_ENV === "production";
@@ -30,3 +30,4 @@ import "./docker-compose.template.js";
30
30
  import "./dockerfile.template.js";
31
31
  import "./pm2.template.js";
32
32
  import "./readme.template.js";
33
+ import "./new-template.template.js";
@@ -7,7 +7,8 @@ export default defineTemplate({
7
7
  outputDir: "{{srcDir}}/config/logger",
8
8
  fileName: "index",
9
9
  preserveCase: true,
10
- render(_, data) {
10
+ hidden: true,
11
+ render() {
11
12
  return `import {DILoggerOptions} from "@tsed/di";
12
13
  import {$log} from "@tsed/logger";
13
14
  import {isProduction} from "../utils/index.js";
@@ -4,21 +4,23 @@ export default defineTemplate({
4
4
  label: "Middleware",
5
5
  fileName: "{{symbolName}}.middleware",
6
6
  outputDir: "{{srcDir}}/middlewares",
7
- prompts: (data) => [
8
- {
9
- type: "list",
10
- name: "middlewarePosition",
11
- message: () => `The middleware should be called:`,
12
- choices: [
13
- { name: "Before the endpoint", value: "before" },
14
- { name: "After the endpoint", value: "after" }
15
- ],
16
- when(state) {
17
- return !!((["decorator"].includes(state.type || data.type) && ["middleware"].includes(state.templateType)) ||
18
- data.middlewarePosition);
7
+ prompts(context) {
8
+ return [
9
+ {
10
+ type: "list",
11
+ name: "middlewarePosition",
12
+ message: () => `The middleware should be called:`,
13
+ choices: [
14
+ { name: "Before the endpoint", value: "before" },
15
+ { name: "After the endpoint", value: "after" }
16
+ ],
17
+ when(state) {
18
+ return !!((["decorator"].includes(state.type || context.type) && ["middleware"].includes(state.templateType)) ||
19
+ context.middlewarePosition);
20
+ }
19
21
  }
20
- }
21
- ],
22
+ ];
23
+ },
22
24
  render(symbolName) {
23
25
  return `import {Middleware, MiddlewareMethods} from "@tsed/platform-middlewares";
24
26
  import {Context} from "@tsed/platform-params";