@tsed/cli 7.0.0-alpha.1 → 7.0.0-alpha.10
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/bin/tsed.js +23 -2
- package/lib/esm/commands/generate/GenerateCmd.js +8 -11
- package/lib/esm/commands/index.js +2 -1
- package/lib/esm/commands/init/InitCmd.js +14 -11
- package/lib/esm/commands/init/config/FeaturesPrompt.js +40 -19
- package/lib/esm/commands/init/mappers/mapToContext.js +4 -0
- package/lib/esm/commands/init/prompts/getFeaturesPrompt.js +0 -12
- package/lib/esm/commands/init/utils/hasFeature.js +3 -0
- package/lib/esm/commands/template/CreateTemplateCommand.js +101 -0
- package/lib/esm/fn/taskOutput.js +7 -0
- package/lib/esm/index.js +3 -1
- package/lib/esm/processors/transformConfigFile.js +100 -21
- package/lib/esm/processors/transformIndexFile.js +0 -5
- package/lib/esm/processors/transformServerFile.js +0 -4
- package/lib/esm/services/CliProjectService.js +16 -12
- package/lib/esm/services/CliTemplatesService.js +67 -15
- package/lib/esm/services/ProjectClient.js +24 -1
- 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 +5 -2
- 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/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/init/config/FeaturesPrompt.d.ts +13 -5
- package/lib/types/commands/init/prompts/getFeaturesPrompt.d.ts +0 -6
- package/lib/types/commands/init/utils/hasFeature.d.ts +1 -0
- package/lib/types/commands/template/CreateTemplateCommand.d.ts +62 -0
- package/lib/types/fn/taskOutput.d.ts +1 -0
- package/lib/types/index.d.ts +3 -1
- package/lib/types/interfaces/GenerateCmdContext.d.ts +2 -0
- package/lib/types/interfaces/RenderDataContext.d.ts +2 -0
- package/lib/types/pipes/SymbolNamePipe.d.ts +1 -1
- package/lib/types/services/CliProjectService.d.ts +3 -2
- package/lib/types/services/CliTemplatesService.d.ts +9 -3
- package/lib/types/services/ProjectClient.d.ts +4 -0
- 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 +10 -10
- package/templates/tsconfig.json +11 -0
- package/templates/tsconfig.node.json +1 -1
- package/lib/esm/Cli.js +0 -57
- package/lib/esm/templates/tsconfig.template.js +0 -31
- package/lib/types/Cli.d.ts +0 -26
- package/lib/types/templates/tsconfig.template.d.ts +0 -2
package/lib/esm/bin/tsed.js
CHANGED
|
@@ -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";
|
|
@@ -14,8 +15,28 @@ register(pathToFileURL(join(import.meta.dirname, `../loaders/alias.hook.${EXT}`)
|
|
|
14
15
|
},
|
|
15
16
|
transferList: []
|
|
16
17
|
});
|
|
17
|
-
const {
|
|
18
|
-
|
|
18
|
+
const { commands, CliCore, PKG, TEMPLATE_DIR, ArchitectureConvention, ProjectConvention } = await import("../index.js");
|
|
19
|
+
CliCore.bootstrap({
|
|
20
|
+
name: "tsed",
|
|
21
|
+
pkg: PKG,
|
|
22
|
+
templateDir: TEMPLATE_DIR,
|
|
23
|
+
plugins: true,
|
|
24
|
+
updateNotifier: true,
|
|
25
|
+
checkPrecondition: true,
|
|
26
|
+
commands,
|
|
27
|
+
defaultProjectPreferences() {
|
|
28
|
+
return {
|
|
29
|
+
convention: ProjectConvention.DEFAULT,
|
|
30
|
+
architecture: ArchitectureConvention.DEFAULT
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
project: {
|
|
34
|
+
reinstallAfterRun: true
|
|
35
|
+
},
|
|
36
|
+
logger: {
|
|
37
|
+
level: "info"
|
|
38
|
+
}
|
|
39
|
+
}).catch((error) => {
|
|
19
40
|
console.error(error);
|
|
20
41
|
process.exit(-1);
|
|
21
42
|
});
|
|
@@ -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))
|
|
@@ -53,15 +54,11 @@ export class GenerateCmd {
|
|
|
53
54
|
{
|
|
54
55
|
title: `Generate ${ctx.type} file to '${symbolPath}.ts'`,
|
|
55
56
|
skip: !this.templates.get(type),
|
|
56
|
-
task: () =>
|
|
57
|
-
this.projectService.createFromTemplate(type, ctx);
|
|
58
|
-
}
|
|
57
|
+
task: () => this.projectService.createFromTemplate(type, ctx)
|
|
59
58
|
},
|
|
60
59
|
{
|
|
61
60
|
title: "Transform generated files",
|
|
62
|
-
task: () =>
|
|
63
|
-
return this.projectService.transformFiles(ctx);
|
|
64
|
-
}
|
|
61
|
+
task: () => this.projectService.transformFiles(ctx)
|
|
65
62
|
}
|
|
66
63
|
];
|
|
67
64
|
}
|
|
@@ -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];
|
|
@@ -7,6 +7,7 @@ import { kebabCase } from "change-case";
|
|
|
7
7
|
import { DEFAULT_TSED_TAGS, TEMPLATE_DIR } from "../../constants/index.js";
|
|
8
8
|
import { exec } from "../../fn/exec.js";
|
|
9
9
|
import { render } from "../../fn/render.js";
|
|
10
|
+
import { taskOutput } from "../../fn/taskOutput.js";
|
|
10
11
|
import { ArchitectureConvention } from "../../interfaces/ArchitectureConvention.js";
|
|
11
12
|
import { PlatformType } from "../../interfaces/index.js";
|
|
12
13
|
import { ProjectConvention } from "../../interfaces/ProjectConvention.js";
|
|
@@ -119,7 +120,7 @@ export class InitCmd {
|
|
|
119
120
|
await createTasksRunner([
|
|
120
121
|
{
|
|
121
122
|
title: "Write RC files",
|
|
122
|
-
skip: () => !ctx.
|
|
123
|
+
skip: () => !ctx.premium,
|
|
123
124
|
task: () => {
|
|
124
125
|
return Promise.all([render(".npmrc", ctx), render(".yarnrc", ctx)]);
|
|
125
126
|
}
|
|
@@ -160,13 +161,11 @@ export class InitCmd {
|
|
|
160
161
|
return [
|
|
161
162
|
{
|
|
162
163
|
title: "Render base files",
|
|
163
|
-
task:
|
|
164
|
-
return this.renderFiles(ctx);
|
|
165
|
-
}
|
|
164
|
+
task: () => this.renderFiles(ctx)
|
|
166
165
|
},
|
|
167
166
|
{
|
|
168
167
|
title: "Alter package json",
|
|
169
|
-
task:
|
|
168
|
+
task: () => {
|
|
170
169
|
return $asyncAlter("$alterPackageJson", this.packageJson, [ctx]);
|
|
171
170
|
}
|
|
172
171
|
},
|
|
@@ -175,7 +174,7 @@ export class InitCmd {
|
|
|
175
174
|
task: createSubTasks(async () => {
|
|
176
175
|
const subTasks = [
|
|
177
176
|
...(await exec("generate", {
|
|
178
|
-
|
|
177
|
+
//...ctx,
|
|
179
178
|
type: "controller",
|
|
180
179
|
route: "rest",
|
|
181
180
|
name: "HelloWorld",
|
|
@@ -183,7 +182,7 @@ export class InitCmd {
|
|
|
183
182
|
})),
|
|
184
183
|
...(ctx.commands
|
|
185
184
|
? await exec("generate", {
|
|
186
|
-
|
|
185
|
+
//...ctx,
|
|
187
186
|
type: "command",
|
|
188
187
|
route: "hello",
|
|
189
188
|
name: "hello"
|
|
@@ -241,6 +240,7 @@ export class InitCmd {
|
|
|
241
240
|
"@tsed/core": ctx.tsedVersion,
|
|
242
241
|
"@tsed/di": ctx.tsedVersion,
|
|
243
242
|
"@tsed/ajv": ctx.tsedVersion,
|
|
243
|
+
"@tsed/config": ctx.tsedVersion,
|
|
244
244
|
"@tsed/exceptions": ctx.tsedVersion,
|
|
245
245
|
"@tsed/schema": ctx.tsedVersion,
|
|
246
246
|
"@tsed/json-mapper": ctx.tsedVersion,
|
|
@@ -255,13 +255,11 @@ export class InitCmd {
|
|
|
255
255
|
"@tsed/platform-views": ctx.tsedVersion,
|
|
256
256
|
"@tsed/platform-multer": ctx.tsedVersion,
|
|
257
257
|
"@tsed/logger": "latest",
|
|
258
|
+
"@tsed/logger-std": "latest",
|
|
258
259
|
"@tsed/engines": "latest",
|
|
259
260
|
"@tsed/barrels": "latest",
|
|
260
261
|
ajv: "latest",
|
|
261
262
|
"cross-env": "latest",
|
|
262
|
-
dotenv: "latest",
|
|
263
|
-
"dotenv-expand": "latest",
|
|
264
|
-
"dotenv-flow": "latest",
|
|
265
263
|
...this.runtimes.get().dependencies(),
|
|
266
264
|
...this.platforms.get(ctx.platform).dependencies(ctx)
|
|
267
265
|
});
|
|
@@ -301,7 +299,7 @@ export class InitCmd {
|
|
|
301
299
|
// files with higher priority
|
|
302
300
|
const promises = [
|
|
303
301
|
"tsconfig.base.json",
|
|
304
|
-
"tsconfig.
|
|
302
|
+
"tsconfig.json",
|
|
305
303
|
"tsconfig.spec.json",
|
|
306
304
|
"tsconfig.node.json",
|
|
307
305
|
"docker-compose.yml",
|
|
@@ -314,6 +312,7 @@ export class InitCmd {
|
|
|
314
312
|
"index.config.util",
|
|
315
313
|
"index.logger",
|
|
316
314
|
"index.controller",
|
|
315
|
+
ctx.commands && "index.command",
|
|
317
316
|
"barrels",
|
|
318
317
|
"readme",
|
|
319
318
|
`pm2.${pm2}`,
|
|
@@ -326,8 +325,11 @@ export class InitCmd {
|
|
|
326
325
|
}
|
|
327
326
|
async renderFiles(ctx) {
|
|
328
327
|
// base files
|
|
328
|
+
let startTime = Date.now();
|
|
329
329
|
await this.baseFiles(ctx);
|
|
330
|
+
taskOutput(`Base files rendered (${Date.now() - startTime}ms)`);
|
|
330
331
|
const files = await $asyncAlter("$alterRenderFiles", [], [ctx]);
|
|
332
|
+
startTime = Date.now();
|
|
331
333
|
const promises = files.map((option) => {
|
|
332
334
|
if (!option) {
|
|
333
335
|
return;
|
|
@@ -350,6 +352,7 @@ export class InitCmd {
|
|
|
350
352
|
}
|
|
351
353
|
});
|
|
352
354
|
await Promise.all(promises);
|
|
355
|
+
taskOutput(`Plugins files rendered (${Date.now() - startTime}ms)`);
|
|
353
356
|
}
|
|
354
357
|
}
|
|
355
358
|
command(InitCmd, {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ArchitectureConvention, PlatformType, ProjectConvention } from "../../../interfaces/index.js";
|
|
2
|
-
import { hasFeature, hasValue } from "../utils/hasFeature.js";
|
|
2
|
+
import { hasFeature, hasValue, hasValuePremium } from "../utils/hasFeature.js";
|
|
3
3
|
import { isPlatform } from "../utils/isPlatform.js";
|
|
4
4
|
export var FeatureType;
|
|
5
5
|
(function (FeatureType) {
|
|
@@ -16,10 +16,11 @@ export var FeatureType;
|
|
|
16
16
|
FeatureType["CONFIG_DOTENV"] = "config:dotenv";
|
|
17
17
|
FeatureType["CONFIG_JSON"] = "config:json";
|
|
18
18
|
FeatureType["CONFIG_YAML"] = "config:yaml";
|
|
19
|
-
FeatureType["
|
|
20
|
-
FeatureType["
|
|
21
|
-
FeatureType["
|
|
22
|
-
FeatureType["
|
|
19
|
+
FeatureType["CONFIG_AWS_SECRETS"] = "config:aws_secrets:premium";
|
|
20
|
+
FeatureType["CONFIG_IOREDIS"] = "config:ioredis:premium";
|
|
21
|
+
FeatureType["CONFIG_MONGO"] = "config:mongo:premium";
|
|
22
|
+
FeatureType["CONFIG_VAULT"] = "config:vault:premium";
|
|
23
|
+
FeatureType["CONFIG_POSTGRES"] = "config:postgres:premium";
|
|
23
24
|
// DOC
|
|
24
25
|
FeatureType["SWAGGER"] = "swagger";
|
|
25
26
|
FeatureType["SCALAR"] = "scalar";
|
|
@@ -158,39 +159,59 @@ export const FeaturesMap = {
|
|
|
158
159
|
name: "Envs"
|
|
159
160
|
},
|
|
160
161
|
[FeatureType.CONFIG_DOTENV]: {
|
|
161
|
-
name: "Dotenv"
|
|
162
|
+
name: "Dotenv",
|
|
163
|
+
dependencies: {
|
|
164
|
+
dotenv: "latest",
|
|
165
|
+
"dotenv-expand": "latest",
|
|
166
|
+
"dotenv-flow": "latest"
|
|
167
|
+
}
|
|
162
168
|
},
|
|
163
169
|
[FeatureType.CONFIG_JSON]: {
|
|
164
170
|
name: "JSON"
|
|
165
171
|
},
|
|
166
172
|
[FeatureType.CONFIG_YAML]: {
|
|
167
|
-
name: "YAML"
|
|
173
|
+
name: "YAML",
|
|
174
|
+
dependencies: {
|
|
175
|
+
"js-yaml": "latest"
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
[FeatureType.CONFIG_AWS_SECRETS]: {
|
|
179
|
+
name: "AWS Secrets Manager (Premium)",
|
|
180
|
+
dependencies: {
|
|
181
|
+
"@tsedio/config-source-aws-secrets": "latest",
|
|
182
|
+
"@aws-sdk/client-secrets-manager": "latest"
|
|
183
|
+
}
|
|
168
184
|
},
|
|
169
185
|
[FeatureType.CONFIG_IOREDIS]: {
|
|
170
186
|
name: "IORedis (Premium)",
|
|
171
187
|
dependencies: {
|
|
172
|
-
ioredis: "
|
|
173
|
-
"@
|
|
188
|
+
"@tsedio/config-ioredis": "{{tsedVersion}}",
|
|
189
|
+
"@tsed/ioredis": "{{tsedVersion}}",
|
|
190
|
+
ioredis: "latest"
|
|
191
|
+
},
|
|
192
|
+
devDependencies: {
|
|
193
|
+
"@tsedio/testcontainers-redis": "latest"
|
|
174
194
|
}
|
|
175
195
|
},
|
|
176
196
|
[FeatureType.CONFIG_MONGO]: {
|
|
177
197
|
name: "MongoDB (Premium)",
|
|
178
198
|
dependencies: {
|
|
179
199
|
mongodb: "latest",
|
|
180
|
-
"@tsedio/config-mongo": "
|
|
200
|
+
"@tsedio/config-mongo": "latest"
|
|
181
201
|
}
|
|
182
202
|
},
|
|
183
203
|
[FeatureType.CONFIG_VAULT]: {
|
|
184
204
|
name: "Vault (Premium)",
|
|
185
205
|
dependencies: {
|
|
186
|
-
"@tsedio/config-vault": "
|
|
206
|
+
"@tsedio/config-vault": "latest",
|
|
207
|
+
"node-vault": "latest"
|
|
187
208
|
}
|
|
188
209
|
},
|
|
189
210
|
[FeatureType.CONFIG_POSTGRES]: {
|
|
190
211
|
name: "Postgres (Premium)",
|
|
191
212
|
dependencies: {
|
|
192
213
|
pg: "latest",
|
|
193
|
-
"@tsedio/config-postgres": "
|
|
214
|
+
"@tsedio/config-postgres": "latest"
|
|
194
215
|
}
|
|
195
216
|
},
|
|
196
217
|
/// TYPEORM
|
|
@@ -389,6 +410,7 @@ export const FeaturesPrompt = (availableRuntimes, availablePackageManagers) => [
|
|
|
389
410
|
FeatureType.CONFIG_DOTENV,
|
|
390
411
|
FeatureType.CONFIG_JSON,
|
|
391
412
|
FeatureType.CONFIG_YAML,
|
|
413
|
+
FeatureType.CONFIG_AWS_SECRETS,
|
|
392
414
|
FeatureType.CONFIG_IOREDIS,
|
|
393
415
|
FeatureType.CONFIG_MONGO,
|
|
394
416
|
FeatureType.CONFIG_VAULT,
|
|
@@ -431,13 +453,12 @@ export const FeaturesPrompt = (availableRuntimes, availablePackageManagers) => [
|
|
|
431
453
|
],
|
|
432
454
|
when: hasValue("featuresDB", FeatureType.TYPEORM)
|
|
433
455
|
},
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
// },
|
|
456
|
+
{
|
|
457
|
+
type: "password",
|
|
458
|
+
name: "GH_TOKEN",
|
|
459
|
+
message: "Enter GH_TOKEN to use the premium @tsedio package or leave blank (see https://tsed.dev/plugins/premium/install-premium-plugins.html)",
|
|
460
|
+
when: hasValuePremium()
|
|
461
|
+
},
|
|
441
462
|
{
|
|
442
463
|
message: "Choose unit framework",
|
|
443
464
|
type: "list",
|
|
@@ -4,6 +4,10 @@ export function mapToContext(options) {
|
|
|
4
4
|
options = mapUniqFeatures(options);
|
|
5
5
|
options.features.forEach((feature) => {
|
|
6
6
|
const [base, type] = feature.split(":");
|
|
7
|
+
if (feature?.endsWith(":premium")) {
|
|
8
|
+
feature = feature.replace(":premium", "");
|
|
9
|
+
options.premium = true;
|
|
10
|
+
}
|
|
7
11
|
options[camelCase(base)] = true;
|
|
8
12
|
type && (options[camelCase(type)] = true);
|
|
9
13
|
feature && (options[camelCase(feature)] = true);
|
|
@@ -18,15 +18,3 @@ export function getFeaturesPrompt(runtimes, availablePackageManagers, options) {
|
|
|
18
18
|
});
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
-
export function getFrameworksPrompt() {
|
|
22
|
-
return {
|
|
23
|
-
...FrameworksPrompt,
|
|
24
|
-
choices: FrameworksPrompt.choices.map((choice, index) => {
|
|
25
|
-
return cleanObject({
|
|
26
|
-
...FeaturesMap[choice],
|
|
27
|
-
checked: index === 0,
|
|
28
|
-
value: choice
|
|
29
|
-
});
|
|
30
|
-
})
|
|
31
|
-
};
|
|
32
|
-
}
|
|
@@ -5,3 +5,6 @@ export function hasValue(expression, value) {
|
|
|
5
5
|
export function hasFeature(feature) {
|
|
6
6
|
return (ctx) => !!ctx.features.find((item) => item === feature);
|
|
7
7
|
}
|
|
8
|
+
export function hasValuePremium() {
|
|
9
|
+
return (ctx) => !!ctx.features.find((item) => item.endsWith(":premium"));
|
|
10
|
+
}
|
|
@@ -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
|
+
});
|
package/lib/esm/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import "@tsed/logger-std";
|
|
1
2
|
import "./templates/index.js";
|
|
2
|
-
export * from "./Cli.js";
|
|
3
3
|
export * from "./commands/add/AddCmd.js";
|
|
4
4
|
export * from "./commands/generate/GenerateCmd.js";
|
|
5
|
+
export { default as commands } from "./commands/index.js";
|
|
5
6
|
export * from "./commands/init/config/FeaturesPrompt.js";
|
|
6
7
|
export * from "./commands/init/config/FeaturesPrompt.js";
|
|
7
8
|
export * from "./commands/init/InitCmd.js";
|
|
@@ -17,3 +18,4 @@ export * from "./services/CliProjectService.js";
|
|
|
17
18
|
export * from "./services/CliTemplatesService.js";
|
|
18
19
|
export * from "./services/ProjectClient.js";
|
|
19
20
|
export * from "./utils/defineTemplate.js";
|
|
21
|
+
export { CliCore } from "@tsed/cli-core";
|
|
@@ -1,26 +1,105 @@
|
|
|
1
|
-
import { SyntaxKind } from "ts-morph";
|
|
2
1
|
export function transformConfigFile(project, data) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
if (!data.config && data.commandName === "init") {
|
|
3
|
+
project.addConfigSource("EnvsConfigSource", {
|
|
4
|
+
moduleSpecifier: "@tsed/config/envs"
|
|
5
|
+
});
|
|
7
6
|
}
|
|
8
7
|
if (data.config) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
8
|
+
if (data.configDotenv) {
|
|
9
|
+
project.addConfigSource("DotenvConfigSource", {
|
|
10
|
+
moduleSpecifier: "@tsed/config/dotenv"
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
else if (data.configEnvs) {
|
|
14
|
+
project.addConfigSource("EnvsConfigSource", {
|
|
15
|
+
moduleSpecifier: "@tsed/config/envs"
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
if (data.configJson) {
|
|
19
|
+
project.addConfigSource("JsonConfigSource", {
|
|
20
|
+
moduleSpecifier: "@tsed/config/json",
|
|
21
|
+
content: `withOptions(JsonConfigSource, {
|
|
22
|
+
path: "./config.json"
|
|
23
|
+
})`
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (data.configYaml) {
|
|
27
|
+
project.addConfigSource("YamlConfigSource", {
|
|
28
|
+
moduleSpecifier: "@tsed/config/yaml",
|
|
29
|
+
content: `withOptions(YamlConfigSource, {
|
|
30
|
+
path: "./config.yaml"
|
|
31
|
+
})`
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (data.configAwsSecrets) {
|
|
35
|
+
project.addConfigSource("AwsSecretsConfigSource", {
|
|
36
|
+
moduleSpecifier: "@tsedio/config-source-aws-secrets",
|
|
37
|
+
content: `withOptions(AwsSecretsConfigSource, {
|
|
38
|
+
name: "aws",
|
|
39
|
+
path: "/my-app/config", // Path prefix in Secrets Manager
|
|
40
|
+
region: "us-east-1", // AWS region
|
|
41
|
+
watch: true // Enable secrets watching
|
|
42
|
+
// validationSchema: object({}) // Optional: add a validation schema
|
|
43
|
+
// maxConcurrency: 10
|
|
44
|
+
})`
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (data.configVault) {
|
|
48
|
+
project.addConfigSource("VaultConfigSource", {
|
|
49
|
+
moduleSpecifier: "@tsedio/config-vault",
|
|
50
|
+
content: ` withOptions(VaultConfigSource, {
|
|
51
|
+
name: "vault",
|
|
52
|
+
endpoint: "http://localhost:8200", // Vault server URL
|
|
53
|
+
token: "your-vault-token", // Your Vault token
|
|
54
|
+
secretPath: "secret/data/myapp", // Path to your secret (KV v2 or v1, see below)
|
|
55
|
+
refreshInterval: 10000 // ⏱️ Polling interval in ms (default: 10s)
|
|
56
|
+
// Additional node-vault options
|
|
57
|
+
|
|
58
|
+
// validationSchema: object({}) // Optional: add a validation schema
|
|
59
|
+
})`
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (data.configIoredis) {
|
|
63
|
+
project.addConfigSource("IoredisConfigSource", {
|
|
64
|
+
moduleSpecifier: "@tsedio/config-ioredis",
|
|
65
|
+
content: `withOptions(IoredisConfigSource, {
|
|
66
|
+
name: "redis",
|
|
67
|
+
prefixKey: "my-config", // Optional: All config keys will be prefixed
|
|
68
|
+
url: "redis://localhost:6379" // Or use any Redis/Cluster options
|
|
69
|
+
// validationSchema: object({}) // Optional: add a validation schema
|
|
70
|
+
})`
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (data.configMongo) {
|
|
74
|
+
project.addConfigSource("MongoConfigSource", {
|
|
75
|
+
moduleSpecifier: "@tsedio/config-mongo",
|
|
76
|
+
content: `withOptions(MongoConfigSource, {
|
|
77
|
+
name: "mongo",
|
|
78
|
+
url: "mongodb://localhost:27017", // MongoDB connection URL
|
|
79
|
+
database: "my_database", // Database name
|
|
80
|
+
collection: "config" // Collection used for config storage
|
|
81
|
+
|
|
82
|
+
// Additional MongoDB client options can be provided here
|
|
83
|
+
|
|
84
|
+
// ConfigSource options
|
|
85
|
+
// validationSchema: object({}) // Optional: add a validation schema
|
|
86
|
+
})`
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (data.configPostgres) {
|
|
90
|
+
project.addConfigSource("PostgresConfigSource", {
|
|
91
|
+
moduleSpecifier: "@tsedio/config-postgres",
|
|
92
|
+
content: `withOptions(PostgresConfigSource, {
|
|
93
|
+
name: "postgres",
|
|
94
|
+
connectionString: "postgresql://postgres:postgres@localhost:5432/my_database", // PostgreSQL connection string
|
|
95
|
+
table: "config" // Table used for config storage
|
|
96
|
+
|
|
97
|
+
// Additional PostgresSQL client options can be provided here
|
|
98
|
+
|
|
99
|
+
// ConfigSource options
|
|
100
|
+
// validationSchema: object({}) // Optional: add a validation schema
|
|
101
|
+
})`
|
|
102
|
+
});
|
|
103
|
+
}
|
|
21
104
|
}
|
|
22
|
-
sourceFile.organizeImports();
|
|
23
|
-
sourceFile.formatText({
|
|
24
|
-
indentSize: 2
|
|
25
|
-
});
|
|
26
105
|
}
|
|
@@ -12,7 +12,6 @@ export function transformIndexFile(project, data) {
|
|
|
12
12
|
moduleSpecifier: "@tsed/platform-" + data.platform.toLowerCase(),
|
|
13
13
|
namedImports: [platformName]
|
|
14
14
|
});
|
|
15
|
-
// replace PlatformBuilder with Platform<PlatformType>
|
|
16
15
|
sourceFile.getImportDeclaration((declaration) => declaration.getModuleSpecifierValue() === "@tsed/platform-http")?.remove();
|
|
17
16
|
sourceFile.getDescendantsOfKind(SyntaxKind.Identifier).map((identifier) => {
|
|
18
17
|
if (identifier.getText() === "PlatformBuilder") {
|
|
@@ -21,8 +20,4 @@ export function transformIndexFile(project, data) {
|
|
|
21
20
|
}
|
|
22
21
|
return identifier;
|
|
23
22
|
});
|
|
24
|
-
sourceFile.organizeImports();
|
|
25
|
-
sourceFile.formatText({
|
|
26
|
-
indentSize: 2
|
|
27
|
-
});
|
|
28
23
|
}
|