@tsed/cli 7.0.0-alpha.4 → 7.0.0-alpha.6
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/Cli.js +1 -0
- package/lib/esm/bin/tsed.js +1 -0
- package/lib/esm/commands/generate/GenerateCmd.js +6 -5
- package/lib/esm/commands/index.js +2 -1
- package/lib/esm/commands/init/InitCmd.js +2 -1
- package/lib/esm/commands/template/CreateTemplateCommand.js +101 -0
- package/lib/esm/processors/transformConfigFile.js +5 -5
- package/lib/esm/services/CliProjectService.js +4 -5
- package/lib/esm/services/CliTemplatesService.js +57 -9
- package/lib/esm/services/ProjectClient.js +22 -22
- package/lib/esm/services/mappers/addContextMethods.js +17 -0
- package/lib/esm/services/mappers/mapDefaultTemplateOptions.js +7 -1
- package/lib/esm/templates/barrels.template.js +7 -2
- package/lib/esm/templates/controller.template.js +24 -25
- package/lib/esm/templates/decorator.template.js +26 -24
- package/lib/esm/templates/docker-compose.template.js +2 -2
- package/lib/esm/templates/dockerfile.template.js +5 -5
- package/lib/esm/templates/index.command.template.js +6 -2
- package/lib/esm/templates/index.config.utils.template.js +1 -1
- package/lib/esm/templates/index.js +1 -1
- package/lib/esm/templates/index.logger.template.js +2 -1
- package/lib/esm/templates/middleware.template.js +16 -14
- package/lib/esm/templates/new-template.template.js +67 -0
- package/lib/esm/templates/readme.template.js +3 -3
- package/lib/esm/templates/tsconfig.spec.template.js +6 -5
- package/lib/esm/utils/defineTemplate.js +2 -2
- package/lib/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/types/Cli.d.ts +2 -1
- package/lib/types/bin/tsed.d.ts +1 -1
- package/lib/types/commands/generate/GenerateCmd.d.ts +1 -36
- package/lib/types/commands/index.d.ts +2 -1
- package/lib/types/commands/template/CreateTemplateCommand.d.ts +62 -0
- package/lib/types/interfaces/GenerateCmdContext.d.ts +2 -0
- package/lib/types/pipes/SymbolNamePipe.d.ts +1 -1
- package/lib/types/services/CliProjectService.d.ts +2 -2
- package/lib/types/services/CliTemplatesService.d.ts +7 -3
- package/lib/types/services/ProjectClient.d.ts +3 -3
- package/lib/types/services/mappers/addContextMethods.d.ts +12 -0
- package/lib/types/templates/asyncFactory.template.d.ts +15 -1
- package/lib/types/templates/barrels.template.d.ts +15 -1
- package/lib/types/templates/command.template.d.ts +15 -1
- package/lib/types/templates/config.template.d.ts +15 -1
- package/lib/types/templates/controller.template.d.ts +16 -1
- package/lib/types/templates/decorator.template.d.ts +16 -1
- package/lib/types/templates/docker-compose.template.d.ts +15 -1
- package/lib/types/templates/exception-filter.template.d.ts +15 -1
- package/lib/types/templates/factory.template.d.ts +15 -1
- package/lib/types/templates/index.command.template.d.ts +15 -1
- package/lib/types/templates/index.config.utils.template.d.ts +15 -1
- package/lib/types/templates/index.controller.template.d.ts +15 -1
- package/lib/types/templates/index.d.ts +1 -1
- package/lib/types/templates/index.logger.template.d.ts +15 -1
- package/lib/types/templates/index.template.d.ts +15 -1
- package/lib/types/templates/interceptor.template.d.ts +15 -1
- package/lib/types/templates/interface.template.d.ts +15 -1
- package/lib/types/templates/middleware.template.d.ts +16 -1
- package/lib/types/templates/model.template.d.ts +15 -1
- package/lib/types/templates/module.template.d.ts +15 -1
- package/lib/types/templates/new-template.template.d.ts +9 -0
- package/lib/types/templates/pipe.template.d.ts +15 -1
- package/lib/types/templates/prisma.service.template.d.ts +15 -1
- package/lib/types/templates/readme.template.d.ts +15 -1
- package/lib/types/templates/repository.template.d.ts +15 -1
- package/lib/types/templates/response-filter.template.d.ts +15 -1
- package/lib/types/templates/server.template.d.ts +15 -1
- package/lib/types/templates/service.template.d.ts +15 -1
- package/lib/types/templates/tsconfig.spec.template.d.ts +15 -1
- package/lib/types/templates/value.template.d.ts +15 -1
- package/lib/types/utils/defineTemplate.d.ts +31 -3
- package/package.json +4 -4
- package/templates/tsconfig.json +11 -0
- package/templates/tsconfig.node.json +1 -1
- package/lib/esm/templates/tsconfig.template.js +0 -31
- package/lib/types/templates/tsconfig.template.d.ts +0 -2
package/lib/esm/Cli.js
CHANGED
package/lib/esm/bin/tsed.js
CHANGED
|
@@ -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
|
|
10
|
+
return items.filter((item) => item.name.toLowerCase().includes(keyword.toLowerCase()));
|
|
10
11
|
}
|
|
11
|
-
return
|
|
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
|
|
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
|
|
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];
|
|
@@ -298,7 +298,7 @@ export class InitCmd {
|
|
|
298
298
|
// files with higher priority
|
|
299
299
|
const promises = [
|
|
300
300
|
"tsconfig.base.json",
|
|
301
|
-
"tsconfig.
|
|
301
|
+
"tsconfig.json",
|
|
302
302
|
"tsconfig.spec.json",
|
|
303
303
|
"tsconfig.node.json",
|
|
304
304
|
"docker-compose.yml",
|
|
@@ -311,6 +311,7 @@ export class InitCmd {
|
|
|
311
311
|
"index.config.util",
|
|
312
312
|
"index.logger",
|
|
313
313
|
"index.controller",
|
|
314
|
+
ctx.commands && "index.command",
|
|
314
315
|
"barrels",
|
|
315
316
|
"readme",
|
|
316
317
|
`pm2.${pm2}`,
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { command, inject, ProjectPackageJson } from "@tsed/cli-core";
|
|
2
|
+
import { snakeCase } from "change-case";
|
|
3
|
+
import { PKG } from "../../constants/index.js";
|
|
4
|
+
import { render } from "../../fn/render.js";
|
|
5
|
+
import { CliTemplatesService } from "../../services/CliTemplatesService.js";
|
|
6
|
+
const searchFactory = (list) => {
|
|
7
|
+
const items = list.map((item) => ({ name: item.label, value: item.id }));
|
|
8
|
+
return (_, keyword) => {
|
|
9
|
+
if (keyword) {
|
|
10
|
+
return items.filter((item) => item.name.toLowerCase().includes(keyword.toLowerCase()));
|
|
11
|
+
}
|
|
12
|
+
return items;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export class CreateTemplateCommand {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.projectPackageJson = inject(ProjectPackageJson);
|
|
18
|
+
this.templates = inject(CliTemplatesService);
|
|
19
|
+
}
|
|
20
|
+
async $prompt(data) {
|
|
21
|
+
return [
|
|
22
|
+
{
|
|
23
|
+
type: "list",
|
|
24
|
+
name: "from",
|
|
25
|
+
message: "Create a template from existing one?",
|
|
26
|
+
default: "new",
|
|
27
|
+
when: !data.from,
|
|
28
|
+
choices: [
|
|
29
|
+
{ name: "No, create a new template", value: "new" },
|
|
30
|
+
{ name: "Yes, from existing template", value: "existing" }
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: "autocomplete",
|
|
35
|
+
name: "templateId",
|
|
36
|
+
message: "Select the template to use as base",
|
|
37
|
+
default: data.from,
|
|
38
|
+
when: (ctx) => {
|
|
39
|
+
return ctx.from === "existing";
|
|
40
|
+
},
|
|
41
|
+
source: searchFactory(this.templates.find())
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
type: "confirm",
|
|
45
|
+
name: "override",
|
|
46
|
+
message: "Would you like to override the selected Ts.ED default template?",
|
|
47
|
+
when: (ctx) => ctx.from !== "new",
|
|
48
|
+
default: !!data.override
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: "input",
|
|
52
|
+
name: "name",
|
|
53
|
+
message: "Which name?",
|
|
54
|
+
default: data.name,
|
|
55
|
+
when: !data.name
|
|
56
|
+
}
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
$mapContext(ctx) {
|
|
60
|
+
const symbolName = snakeCase(ctx.name).replace(/_/g, "-");
|
|
61
|
+
return {
|
|
62
|
+
...ctx,
|
|
63
|
+
symbolPath: `./.templates/${symbolName}.template`,
|
|
64
|
+
symbolPathBasename: ".",
|
|
65
|
+
symbolName: symbolName,
|
|
66
|
+
templateId: ctx.orverride ? ctx.templateId : symbolName,
|
|
67
|
+
template: ctx.templateId && this.templates.get(ctx.templateId)
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
$exec(ctx) {
|
|
71
|
+
this.projectPackageJson.addDevDependencies({ "@tsed/cli": PKG.version });
|
|
72
|
+
return [
|
|
73
|
+
{
|
|
74
|
+
title: "Generate " + ctx.from === "new" ? `new template ${ctx.templateId}` : `template ${ctx.templateId} from ${ctx.from}`,
|
|
75
|
+
task: async () => {
|
|
76
|
+
await render("new-template", ctx);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
command(CreateTemplateCommand, {
|
|
83
|
+
name: "template",
|
|
84
|
+
description: "Create a custom template that can be selected in tsed generate command",
|
|
85
|
+
args: {
|
|
86
|
+
name: {
|
|
87
|
+
description: "Name of the class",
|
|
88
|
+
type: String
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
options: {
|
|
92
|
+
"--from <from>": {
|
|
93
|
+
type: String,
|
|
94
|
+
description: "Select the template to use as base"
|
|
95
|
+
},
|
|
96
|
+
"--override": {
|
|
97
|
+
type: Boolean,
|
|
98
|
+
description: "Override the existing selected template"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
export function transformConfigFile(project, data) {
|
|
2
2
|
if (!data.config && data.commandName === "init") {
|
|
3
3
|
project.addConfigSource("EnvsConfigSource", {
|
|
4
|
-
moduleSpecifier: "@
|
|
4
|
+
moduleSpecifier: "@tsed/config/envs"
|
|
5
5
|
});
|
|
6
6
|
}
|
|
7
7
|
if (data.config) {
|
|
8
8
|
if (data.configDotenv) {
|
|
9
9
|
project.addConfigSource("DotenvConfigSource", {
|
|
10
|
-
moduleSpecifier: "@
|
|
10
|
+
moduleSpecifier: "@tsed/config/dotenv"
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
else if (data.configEnvs) {
|
|
14
14
|
project.addConfigSource("EnvsConfigSource", {
|
|
15
|
-
moduleSpecifier: "@
|
|
15
|
+
moduleSpecifier: "@tsed/config/envs"
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
if (data.configJson) {
|
|
19
19
|
project.addConfigSource("JsonConfigSource", {
|
|
20
|
-
moduleSpecifier: "@
|
|
20
|
+
moduleSpecifier: "@tsed/config/json",
|
|
21
21
|
content: `withOptions(JsonConfigSource, {
|
|
22
22
|
path: "./config.json"
|
|
23
23
|
})`
|
|
@@ -25,7 +25,7 @@ export function transformConfigFile(project, data) {
|
|
|
25
25
|
}
|
|
26
26
|
if (data.configYaml) {
|
|
27
27
|
project.addConfigSource("YamlConfigSource", {
|
|
28
|
-
moduleSpecifier: "@
|
|
28
|
+
moduleSpecifier: "@tsed/config/yaml",
|
|
29
29
|
content: `withOptions(YamlConfigSource, {
|
|
30
30
|
path: "./config.yaml"
|
|
31
31
|
})`
|
|
@@ -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,
|
|
70
|
-
const
|
|
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 =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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,18 @@ 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(_,
|
|
15
|
+
render(_, context) {
|
|
15
16
|
const barrels = $alter("$alterBarrels", {
|
|
16
|
-
directory: [
|
|
17
|
+
directory: [
|
|
18
|
+
"./src/controllers/rest",
|
|
19
|
+
context.commands && "./src/bin/commands",
|
|
20
|
+
(context.swagger || context.oidc) && "./src/controllers/pages"
|
|
21
|
+
].filter(Boolean),
|
|
17
22
|
exclude: ["**/__mock__", "**/__mocks__", "**/*.spec.ts"],
|
|
18
23
|
delete: true
|
|
19
24
|
});
|
|
@@ -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
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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,
|
|
33
|
-
const 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
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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(_,
|
|
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: ${
|
|
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,14 +4,18 @@ 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
|
+
fileName: "index",
|
|
8
|
+
hidden: true,
|
|
9
|
+
preserveCase: true,
|
|
7
10
|
render() {
|
|
8
11
|
return `#!/usr/bin/env node
|
|
9
12
|
import {CliCore} from "@tsed/cli-core";
|
|
10
|
-
import {config} from "@/config";
|
|
13
|
+
import {config} from "@/config/config.js";
|
|
14
|
+
import * commands from "@/bin/commands/index.js";
|
|
11
15
|
|
|
12
16
|
CliCore.bootstrap({
|
|
13
17
|
...config,
|
|
14
|
-
commands: []
|
|
18
|
+
commands: [...Object.values(commands)]
|
|
15
19
|
}).catch(console.error);
|
|
16
20
|
`;
|
|
17
21
|
}
|