@nest-arch/tui 0.4.6 → 0.5.1

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 (55) hide show
  1. package/README.md +31 -0
  2. package/dist/cli.js +2 -1
  3. package/dist/constants-CUTbfu9C.js +1 -0
  4. package/dist/index.js +6 -405
  5. package/dist/nonInteractive-C1KZ0b_6.js +5 -0
  6. package/dist/nonInteractiveOptions-CIaoLAWg.js +24 -0
  7. package/dist/projectGeneratorService-CeWJK-HA.js +420 -0
  8. package/dist/projectName-CcE90t2V.js +1 -0
  9. package/dist/templates/addons/husky/pre-commit.hbs +1 -1
  10. package/dist/templates/base/.env.example.hbs +30 -2
  11. package/dist/templates/base/.env.hbs +7 -2
  12. package/dist/templates/base/README.md.hbs +11 -2
  13. package/dist/templates/base/pnpm-workspace.yaml.hbs +9 -4
  14. package/dist/templates/base/prisma.config.ts.hbs +6 -1
  15. package/dist/templates/base/src/app.controller.spec.ts.hbs +6 -0
  16. package/dist/templates/base/src/app.module.ts.hbs +6 -23
  17. package/dist/templates/base/src/database/adapters/interfaces/db-adapter.interface.ts.hbs +5 -5
  18. package/dist/templates/base/src/database/adapters/mongo/raw-mongo.adapter.ts.hbs +6 -4
  19. package/dist/templates/base/src/database/adapters/mongo/typeorm-mongo.adapter.ts.hbs +27 -0
  20. package/dist/templates/base/src/database/db.module.ts.hbs +33 -13
  21. package/dist/templates/base/src/database/db.service.ts.hbs +12 -4
  22. package/dist/templates/base/src/database/entities/todo.entity.ts.hbs +17 -5
  23. package/dist/templates/base/src/database/index.ts.hbs +2 -0
  24. package/dist/templates/base/src/database/orm/drizzle/schema.ts.hbs +80 -20
  25. package/dist/templates/base/src/database/orm/typeorm/data-source.ts.hbs +34 -12
  26. package/dist/templates/base/src/libs/middlewares/graphql-throttler.guard.ts.hbs +22 -0
  27. package/dist/templates/base/src/libs/middlewares/rate-limit.trpc.middleware.ts.hbs +2 -1
  28. package/dist/templates/base/src/libs/trpc/inner.context.ts.hbs +2 -2
  29. package/dist/templates/base/src/main.ts.hbs +2 -2
  30. package/dist/templates/base/test/app.e2e-spec.ts.hbs +378 -202
  31. package/dist/templates/extras/docker/Dockerfile.hbs +9 -2
  32. package/dist/templates/extras/health/src/health/health.controller.ts.hbs +12 -1
  33. package/dist/templates/extras/swagger/create-docs.ts.hbs +6 -1
  34. package/dist/templates/feature/graphql/src/graphql/models/todo.model.ts.hbs +1 -1
  35. package/dist/templates/feature/graphql/src/graphql/resolvers/todo.resolver.ts.hbs +1 -1
  36. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.controller.ts.hbs +80 -7
  37. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.router.ts.hbs +4 -4
  38. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.service.ts.hbs +314 -34
  39. package/dist/templates/monorepo/apps/api-gateway/src/main.ts.hbs +2 -2
  40. package/dist/templates/monorepo/root/README.md.hbs +8 -13
  41. package/dist/templates/single-project/architecture/nest-api/.env.hbs +6 -2
  42. package/dist/templates/single-project/architecture/nest-api/pnpm-workspace.yaml.hbs +6 -0
  43. package/dist/templates/single-project/architecture/nest-api/src/main.ts.hbs +2 -2
  44. package/dist/templates/single-project/architecture/nest-gateway/src/main.ts.hbs +2 -2
  45. package/dist/templates/single-project/architecture/nest-microservice/.env.hbs +30 -1
  46. package/dist/templates/single-project/architecture/nest-microservice/proto/app.proto.hbs +13 -0
  47. package/dist/templates/single-project/architecture/nest-microservice/src/app.controller.ts.hbs +26 -2
  48. package/dist/templates/single-project/architecture/nest-microservice/src/app.module.ts.hbs +61 -1
  49. package/dist/templates/single-project/architecture/nest-microservice/src/app.service.ts.hbs +16 -4
  50. package/dist/templates/single-project/architecture/nest-microservice/src/http-throttler.guard.ts.hbs +13 -0
  51. package/dist/templates/single-project/architecture/nest-microservice/src/main.ts.hbs +26 -7
  52. package/dist/templates/single-project/architecture/nest-microservice/test/microservice.e2e-spec.ts.hbs +7 -87
  53. package/dist/templates/single-project/shared/config/env.ts.hbs +14 -14
  54. package/package.json +6 -5
  55. package/dist/constants-DVhgS48N.js +0 -1
@@ -1,22 +1,51 @@
1
1
  PORT=3000
2
+ NODE_ENV=development
3
+ TRUSTED_PROXY_IPS={{#each trustedProxyIps}}{{#unless @first}},{{/unless}}{{this}}{{/each}}
2
4
  MICROSERVICE_PORT=3001
3
- CORS_ORIGIN=http://localhost:3001
5
+ CORS_ORIGIN=http://localhost:3000
6
+ {{#if hasPostgres}}
7
+ POSTGRES_URL=postgresql://postgres:postgres@localhost:5432/{{projectNameKebab}}_db?schema=public
8
+ {{/if}}
9
+ {{#if hasMysql}}
10
+ MYSQL_URL=mysql://root:mysql@localhost:3306/{{projectNameKebab}}_db
11
+ {{/if}}
12
+ {{#if hasSqlite}}
13
+ SQLITE_PATH=./src/database/dev.db
14
+ {{/if}}
15
+ {{#if hasSqlserver}}
16
+ SQLSERVER_HOST=localhost
17
+ SQLSERVER_PORT=1433
18
+ SQLSERVER_DATABASE={{projectNameKebab}}_db
19
+ SQLSERVER_USER=sa
20
+ SQLSERVER_PASSWORD=DevOnly_Strong_Password_2026!X9
21
+ SQLSERVER_ENCRYPT=true
22
+ SQLSERVER_TRUST_SERVER_CERTIFICATE=true
23
+ {{/if}}
24
+ {{#if hasMongodb}}
25
+ MONGODB_URL=mongodb://localhost:27017/{{projectNameKebab}}_db
26
+ {{/if}}
4
27
  {{#if (includes microservices "redis")}}
28
+ REDIS_PORT=6379
5
29
  REDIS_URL=redis://127.0.0.1:6379
6
30
  {{/if}}
7
31
  {{#if (includes microservices "mqtt")}}
32
+ MQTT_PORT=1883
8
33
  MQTT_URL=mqtt://127.0.0.1:1883
9
34
  {{/if}}
10
35
  {{#if (includes microservices "nats")}}
36
+ NATS_PORT=4222
11
37
  NATS_URL=nats://127.0.0.1:4222
12
38
  {{/if}}
13
39
  {{#if (includes microservices "rabbitmq")}}
40
+ RABBITMQ_PORT=5672
14
41
  RABBITMQ_URL=amqp://127.0.0.1:5672
15
42
  {{/if}}
16
43
  {{#if (includes microservices "kafka")}}
44
+ KAFKA_PORT=9092
17
45
  KAFKA_BROKER=127.0.0.1:9092
18
46
  {{/if}}
19
47
  {{#if (includes microservices "grpc")}}
48
+ GRPC_PORT=5000
20
49
  GRPC_URL=0.0.0.0:5000
21
50
  {{/if}}
22
51
  {{#if hasGraphql}}
@@ -5,9 +5,22 @@ package app;
5
5
  service AppService {
6
6
  rpc Ping (PingRequest) returns (PingResponse);
7
7
  rpc Log (LogRequest) returns (LogResponse);
8
+ {{#if (and hasDatabase hasTodoExample)}}
9
+ rpc CreateTodo (CreateTodoRequest) returns (StorageResponse);
10
+ rpc ListTodos (PingRequest) returns (StorageResponse);
11
+ {{/if}}
8
12
  }
9
13
 
10
14
  message PingRequest {}
15
+ {{#if (and hasDatabase hasTodoExample)}}
16
+ message CreateTodoRequest {
17
+ string title = 1;
18
+ }
19
+
20
+ message StorageResponse {
21
+ string json = 1;
22
+ }
23
+ {{/if}}
11
24
 
12
25
  message PingResponse {
13
26
  string message = 1;
@@ -9,11 +9,11 @@ import { EventPattern, MessagePattern } from "@nestjs/microservices";
9
9
  import { AppService } from "./app.service.js";
10
10
 
11
11
  {{#unless (includes microservices "grpc")}}
12
- type AuditEvent = {
12
+ interface AuditEvent {
13
13
  id: string;
14
14
  payload: Record<string, unknown>;
15
15
  source: string;
16
- };
16
+ }
17
17
 
18
18
  const isAuditEvent = (value: unknown): value is AuditEvent => {
19
19
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
@@ -40,6 +40,30 @@ export class AppController {
40
40
 
41
41
  constructor(private readonly appService: AppService) {}
42
42
 
43
+ {{#if (and hasDatabase hasTodoExample)}}
44
+ {{#if (includes microservices "grpc")}}
45
+ @GrpcMethod("AppService", "CreateTodo")
46
+ async createTodo(data: { title: string }): Promise<{ json: string }> {
47
+ return { json: JSON.stringify(await this.appService.createTodo(data)) };
48
+ }
49
+
50
+ @GrpcMethod("AppService", "ListTodos")
51
+ async listTodos(): Promise<{ json: string }> {
52
+ return { json: JSON.stringify(await this.appService.findTodos()) };
53
+ }
54
+ {{else}}
55
+ @MessagePattern("todo.create")
56
+ createTodo(data: { title: string }) {
57
+ return this.appService.createTodo(data);
58
+ }
59
+
60
+ @MessagePattern("todo.list")
61
+ listTodos() {
62
+ return this.appService.findTodos();
63
+ }
64
+ {{/if}}
65
+ {{/if}}
66
+
43
67
  @Get()
44
68
  getHello(): string {
45
69
  return this.appService.getHello();
@@ -1,4 +1,8 @@
1
1
  import { Module } from "@nestjs/common";
2
+ {{#if hasRateLimiting}}
3
+ import { APP_GUARD } from "@nestjs/core";
4
+ import { ThrottlerModule } from "@nestjs/throttler";
5
+ {{/if}}
2
6
  {{#if (or hasDatabase hasOrm)}}
3
7
  import { DbModule } from "./database/db.module.js";
4
8
  import { env } from "./config/env.js";
@@ -9,6 +13,27 @@ import { AuthModule } from "./auth/auth.module.js";
9
13
 
10
14
  import { AppController } from "./app.controller.js";
11
15
  import { AppService } from "./app.service.js";
16
+ {{#if hasTrpc}}
17
+ import { TRPCModule } from "nestjs-trpc";
18
+ import { AppRouterClass as AppRouter } from "./app.router.js";
19
+ import { AppContext } from "./libs/trpc/context.js";
20
+ import { AppErrorHandler } from "./libs/trpc/error.handler.js";
21
+ {{#if hasRateLimiting}}
22
+ import { RateLimitTRPCMiddleware } from "./libs/middlewares/rate-limit.trpc.middleware.js";
23
+ {{/if}}
24
+ {{#if hasTodoExample}}
25
+ import { TodoRouter } from "./api/todo/todo.router.js";
26
+ {{/if}}
27
+ {{/if}}
28
+ {{#if hasRateLimiting}}
29
+ import { HttpThrottlerGuard } from "./http-throttler.guard.js";
30
+ {{/if}}
31
+ {{#if (and hasRest hasTodoExample)}}
32
+ import { TodoModule } from "./api/todo/todo.module.js";
33
+ {{/if}}
34
+ {{#if hasHealthCheck}}
35
+ import { HealthModule } from "./health/health.module.js";
36
+ {{/if}}
12
37
 
13
38
  @Module({
14
39
  controllers: [AppController],
@@ -18,13 +43,48 @@ import { AppService } from "./app.service.js";
18
43
  {{#if hasPostgres}}postgresUrl: env.POSTGRES_URL,{{/if}}
19
44
  {{#if hasMysql}}mysqlUrl: env.MYSQL_URL,{{/if}}
20
45
  {{#if hasSqlite}}sqlitePath: env.SQLITE_PATH,{{/if}}
46
+ {{#if hasSqlserver}}sqlserver: { database: env.SQLSERVER_DATABASE, options: { encrypt: env.SQLSERVER_ENCRYPT, trustServerCertificate: env.SQLSERVER_TRUST_SERVER_CERTIFICATE }, password: env.SQLSERVER_PASSWORD, port: env.SQLSERVER_PORT, server: env.SQLSERVER_HOST, user: env.SQLSERVER_USER },{{/if}}
21
47
  {{#if hasMongodb}}mongodbUrl: env.MONGODB_URL,{{/if}}
22
48
  }),
23
49
  {{/if}}
24
50
  {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
25
51
  AuthModule,
26
52
  {{/if}}
53
+ {{#if hasTrpc}}
54
+ TRPCModule.forRoot({
55
+ context: AppContext,
56
+ {{#if hasRateLimiting}}
57
+ globalMiddlewares: [RateLimitTRPCMiddleware],
58
+ {{/if}}
59
+ onError: AppErrorHandler,
60
+ }),
61
+ {{/if}}
62
+ {{#if hasRateLimiting}}
63
+ ThrottlerModule.forRoot([{ limit: 60, ttl: 60_000 }]),
64
+ {{/if}}
65
+ {{#if (and hasRest hasTodoExample)}}
66
+ TodoModule,
67
+ {{/if}}
68
+ {{#if hasHealthCheck}}
69
+ HealthModule,
70
+ {{/if}}
71
+ ],
72
+ providers: [
73
+ AppService,
74
+ {{#if hasTrpc}}
75
+ AppContext,
76
+ AppErrorHandler,
77
+ AppRouter,
78
+ {{#if hasRateLimiting}}
79
+ RateLimitTRPCMiddleware,
80
+ {{/if}}
81
+ {{#if hasTodoExample}}
82
+ TodoRouter,
83
+ {{/if}}
84
+ {{/if}}
85
+ {{#if hasRateLimiting}}
86
+ { provide: APP_GUARD, useClass: HttpThrottlerGuard },
87
+ {{/if}}
27
88
  ],
28
- providers: [AppService],
29
89
  })
30
90
  export class AppModule {}
@@ -1,6 +1,7 @@
1
1
  import { Injectable } from "@nestjs/common";
2
- {{#if (or hasDatabase hasOrm)}}
3
- import { DbService } from "./database/db.service.js";
2
+ {{#if (and hasDatabase hasTodoExample)}}
3
+ import { RpcException } from "@nestjs/microservices";
4
+ import { TodoService } from "./api/todo/todo.service.js";
4
5
  {{/if}}
5
6
 
6
7
  @Injectable()
@@ -26,8 +27,19 @@ export class AppService {
26
27
  }
27
28
 
28
29
  {{/unless}}
29
- {{#if (or hasDatabase hasOrm)}}
30
- constructor(private readonly db: DbService) {}
30
+ {{#if (and hasDatabase hasTodoExample)}}
31
+ constructor(private readonly todos: TodoService) {}
32
+
33
+ createTodo(data: { title: string }) {
34
+ if (typeof data?.title !== "string" || data.title.trim().length === 0) {
35
+ throw new RpcException({ code: 3, message: "A non-empty title is required" });
36
+ }
37
+ return this.todos.create({ completed: false, title: data.title });
38
+ }
39
+
40
+ findTodos() {
41
+ return this.todos.findAll();
42
+ }
31
43
 
32
44
  {{/if}}
33
45
  getHello(): string {
@@ -0,0 +1,13 @@
1
+ import { Injectable } from "@nestjs/common";
2
+ import type { ExecutionContext } from "@nestjs/common";
3
+ import { ThrottlerGuard } from "@nestjs/throttler";
4
+
5
+ @Injectable()
6
+ export class HttpThrottlerGuard extends ThrottlerGuard {
7
+ canActivate(context: ExecutionContext): Promise<boolean> {
8
+ if (context.getType() !== "http") {
9
+ return Promise.resolve(true);
10
+ }
11
+ return super.canActivate(context);
12
+ }
13
+ }
@@ -1,7 +1,15 @@
1
+ {{#if (includes microservices "grpc")}}
2
+ import { fileURLToPath } from "node:url";
3
+ {{/if}}
1
4
  {{#if (eq httpProvider "fastify")}}
2
5
  import { FastifyAdapter, NestFastifyApplication } from "@nestjs/platform-fastify";
3
6
  {{/if}}
7
+ {{#if (includes addons "nestjs-zod")}}
4
8
  import { Logger } from "@nestjs/common";
9
+ import { ZodValidationPipe } from "nestjs-zod";
10
+ {{else}}
11
+ import { Logger, StandardSchemaValidationPipe } from "@nestjs/common";
12
+ {{/if}}
5
13
  import { NestFactory } from "@nestjs/core";
6
14
  import { Transport } from "@nestjs/microservices";
7
15
  import type { MicroserviceOptions } from "@nestjs/microservices";
@@ -22,9 +30,20 @@ import { AuthService } from "@thallesp/nestjs-better-auth";
22
30
  {{/if}}
23
31
 
24
32
  async function bootstrap() {
25
- const app = await NestFactory.create{{#if (eq httpProvider "fastify")}}<NestFastifyApplication>(AppModule, new FastifyAdapter()){{else}}(AppModule){{/if}};
33
+ const trustedProxyIps = env.TRUSTED_PROXY_IPS.split(",").map((ip) => ip.trim()).filter(Boolean);
34
+ const app = await NestFactory.create{{#if (eq httpProvider "fastify")}}<NestFastifyApplication>(AppModule, new FastifyAdapter({ trustProxy: trustedProxyIps })){{else}}(AppModule){{/if}};
35
+ {{#unless (eq httpProvider "fastify")}}
36
+ if (trustedProxyIps.length > 0) {
37
+ app.getHttpAdapter().getInstance().set("trust proxy", trustedProxyIps);
38
+ }
39
+ {{/unless}}
26
40
  app.enableCors({ origin: env.CORS_ORIGIN });
27
41
  app.setGlobalPrefix("api");
42
+ {{#if (includes addons "nestjs-zod")}}
43
+ app.useGlobalPipes(new ZodValidationPipe());
44
+ {{else}}
45
+ app.useGlobalPipes(new StandardSchemaValidationPipe());
46
+ {{/if}}
28
47
  app.enableShutdownHooks();
29
48
 
30
49
  app.connectMicroservice<MicroserviceOptions>({
@@ -34,7 +53,7 @@ async function bootstrap() {
34
53
  {{/if}}
35
54
  {{#if (includes microservices "grpc")}}
36
55
  package: "app",
37
- protoPath: "proto/app.proto",
56
+ protoPath: fileURLToPath(new URL("proto/app.proto", import.meta.url)),
38
57
  url: env.GRPC_URL ?? "0.0.0.0:5000",
39
58
  {{/if}}
40
59
  {{#if (includes microservices "rabbitmq")}}
@@ -78,8 +97,8 @@ async function bootstrap() {
78
97
  {{/if}}
79
98
  {{#if (includes apis "trpc")}}
80
99
  trpc: {
81
- routerFilePath: "./src/trpc/router.ts",
82
100
  pathPrefix: "/trpc",
101
+ routerFilePath: "./{{trpcGeneratePath}}/server.ts",
83
102
  },
84
103
  {{/if}}
85
104
  zod: {
@@ -88,10 +107,10 @@ async function bootstrap() {
88
107
  },
89
108
  title: "{{projectNamePascalCase}} API",
90
109
  version: "1.0.0",
91
- }),
92
- {{#if (eq httpProvider "fastify")}}withFastify: true,{{/if}}
93
- pageTitle: "{{projectNamePascalCase}} API Docs",
110
+ }),
111
+ pageTitle: "{{projectNamePascalCase}} API Docs",
94
112
  theme: "default",
113
+ {{#if (eq httpProvider "fastify")}}withFastify: true,{{/if}}
95
114
  }),
96
115
  );
97
116
  {{else}}
@@ -106,7 +125,7 @@ async function bootstrap() {
106
125
  {{/if}}
107
126
  {{#if (includes apis "trpc")}}
108
127
  trpc: {
109
- routerFilePath: "./src/trpc/router.ts",
128
+ routerFilePath: "./{{trpcGeneratePath}}/server.ts",
110
129
  pathPrefix: "/trpc",
111
130
  },
112
131
  {{/if}}
@@ -1,102 +1,22 @@
1
1
  import type { INestApplication } from "@nestjs/common";
2
- import { ClientProxyFactory, Transport } from "@nestjs/microservices";
3
- import type { {{#if (includes microservices "grpc")}}ClientGrpc{{else if (includes microservices "kafka")}}ClientKafka{{else}}ClientProxy{{/if}}, MicroserviceOptions } from "@nestjs/microservices";
4
- import { Test } from "@nestjs/testing";
5
- {{#unless (includes microservices "grpc")}}
6
- import { setTimeout as delay } from "node:timers/promises";
7
- import request from "supertest";
8
- {{/unless}}
9
- import { firstValueFrom } from "rxjs";
10
- {{#if (includes microservices "grpc")}}
11
- import type { Observable } from "rxjs";
2
+ {{#if (eq httpProvider "fastify")}}
3
+ import { FastifyAdapter, NestFastifyApplication } from "@nestjs/platform-fastify";
12
4
  {{/if}}
5
+ import { Test } from "@nestjs/testing";
13
6
  import { afterAll, expect, it } from "vitest";
14
7
 
15
8
  import { AppModule } from "../src/app.module.js";
16
- import { env } from "../src/config/env.js";
17
-
18
- const transport = {{#if (includes microservices "redis")}}Transport.REDIS{{else if (includes microservices "mqtt")}}Transport.MQTT{{else if (includes microservices "nats")}}Transport.NATS{{else if (includes microservices "rabbitmq")}}Transport.RMQ{{else if (includes microservices "kafka")}}Transport.KAFKA{{else if (includes microservices "grpc")}}Transport.GRPC{{else}}Transport.TCP{{/if}};
19
-
20
- const options = {
21
- {{#if (includes microservices "kafka")}}
22
- client: { brokers: [env.KAFKA_BROKER] },
23
- consumer: { groupId: "ping-consumer" },
24
- {{/if}}
25
- {{#if (includes microservices "grpc")}}
26
- package: "app",
27
- protoPath: "proto/app.proto",
28
- url: env.GRPC_URL,
29
- {{/if}}
30
- {{#if (includes microservices "rabbitmq")}}
31
- queue: "ping",
32
- queueOptions: { durable: false },
33
- urls: [env.RABBITMQ_URL],
34
- {{/if}}
35
- {{#if (includes microservices "redis")}}
36
- host: new URL(env.REDIS_URL).hostname,
37
- port: Number(new URL(env.REDIS_URL).port || 6379),
38
- {{/if}}
39
- {{#if (includes microservices "nats")}}
40
- servers: [env.NATS_URL],
41
- {{/if}}
42
- {{#if (includes microservices "mqtt")}}
43
- url: env.MQTT_URL,
44
- {{/if}}
45
- };
46
9
 
47
10
  let app: INestApplication;
48
- const client{{#if (includes microservices "grpc")}}: ClientGrpc = ClientProxyFactory.create({ options, transport } as MicroserviceOptions) as unknown as ClientGrpc;{{else if (includes microservices "kafka")}}: ClientKafka = ClientProxyFactory.create({ options, transport } as MicroserviceOptions) as ClientKafka;{{else}}: ClientProxy = ClientProxyFactory.create({ options, transport } as MicroserviceOptions);{{/if}}
49
11
 
50
- it("sends ping through the selected message transport", async () => {
12
+ it("serves the generated HTTP application", async () => {
51
13
  const module = await Test.createTestingModule({ imports: [AppModule] }).compile();
52
- app = module.createNestApplication();
53
- app.connectMicroservice<MicroserviceOptions>({ options, transport } as MicroserviceOptions);
14
+ app = module.createNestApplication{{#if (eq httpProvider "fastify")}}<NestFastifyApplication>(new FastifyAdapter()){{else}}(){{/if}};
54
15
  app.setGlobalPrefix("api");
55
- await app.startAllMicroservices();
56
16
  await app.init();
57
- {{#if (includes microservices "kafka")}}
58
- client.subscribeToResponseOf("ping");
59
- client.subscribeToResponseOf("log");
60
- {{/if}}
61
- {{#unless (includes microservices "grpc")}}
62
- {{#if (includes microservices "kafka")}}
63
- try {
64
- await client.connect();
65
- } catch {
66
- await delay(1000);
67
- await client.connect();
68
- }
69
- {{else}}
70
- await client.connect();
71
- {{/if}}
72
- {{/unless}}
73
- {{#if (includes microservices "grpc")}}
74
- const service = client.getService<{
75
- ping: (request: Record<string, never>) => Observable<{ message: string }>;
76
- log: (request: { id: string; source: string; payload: string }) => Observable<{ id: string; source: string; payload: string }>;
77
- }>("AppService");
78
- await expect(firstValueFrom(service.ping({}))).resolves.toEqual({ message: "pong" });
79
- const event = { id: "event-1", payload: "healthy", source: "scenario" };
80
- await expect(firstValueFrom(service.log(event))).resolves.toEqual(event);
81
- {{else}}
82
- await expect(firstValueFrom(client.send<string, Record<string, never>>("ping", {}))).resolves.toBe("pong");
83
- const event = { id: "event-1", payload: { healthy: true }, source: "scenario" };
84
- await expect(firstValueFrom(client.send("log", event))).resolves.toEqual({ received: event });
85
- const auditEvent = {
86
- id: "audit-1",
87
- payload: { healthy: true },
88
- source: "scenario",
89
- };
90
- await firstValueFrom(client.emit("audit", auditEvent));
91
- await delay(250);
92
- const auditResponse = await request(app.getHttpServer())
93
- .get(`/api/events/${auditEvent.id}`)
94
- .expect(200);
95
- expect(auditResponse.body).toEqual(auditEvent);
96
- {{/if}}
97
- }, 60_000);
17
+ expect(app.getHttpServer()).toBeDefined();
18
+ });
98
19
 
99
20
  afterAll(async () => {
100
21
  await app?.close();
101
- client.close();
102
22
  });
@@ -35,9 +35,15 @@ export const env = createEnv({
35
35
  {{#if (or (includes microservices "redis") (includes microservices "mqtt") (includes microservices "nats") (includes microservices "rabbitmq") (includes microservices "kafka") (includes microservices "grpc"))}}
36
36
  MICROSERVICE_PORT: z.string().transform(Number).default(3001),
37
37
  {{/if}}
38
+ {{#if hasMongodb}}
39
+ MONGODB_URL: z.url(),
40
+ {{/if}}
38
41
  {{#if (includes microservices "mqtt")}}
39
42
  MQTT_URL: z.url().default("mqtt://127.0.0.1:1883"),
40
43
  {{/if}}
44
+ {{#if hasMysql}}
45
+ MYSQL_URL: z.url(),
46
+ {{/if}}
41
47
  {{#if (includes microservices "nats")}}
42
48
  NATS_URL: z.url().default("nats://127.0.0.1:4222"),
43
49
  {{/if}}
@@ -48,34 +54,28 @@ export const env = createEnv({
48
54
  .string()
49
55
  .transform(Number)
50
56
  .default(3000),
57
+ {{#if hasPostgres}}
58
+ POSTGRES_URL: z.url(),
59
+ {{/if}}
51
60
  {{#if (includes microservices "rabbitmq")}}
52
61
  RABBITMQ_URL: z.url().default("amqp://127.0.0.1:5672"),
53
62
  {{/if}}
54
63
  {{#if (includes microservices "redis")}}
55
64
  REDIS_URL: z.url().default("redis://127.0.0.1:6379"),
56
65
  {{/if}}
57
- TRUSTED_PROXY_IPS: z.string().default("{{#each trustedProxyIps}}{{#unless @first}},{{/unless}}{{this}}{{/each}}"),
58
- {{#if hasPostgres}}
59
- POSTGRES_URL: z.url(),
60
- {{/if}}
61
- {{#if hasMysql}}
62
- MYSQL_URL: z.url(),
63
- {{/if}}
64
66
  {{#if hasSqlite}}
65
67
  SQLITE_PATH: z.string().default("sqlite.db"),
66
68
  {{/if}}
67
69
  {{#if hasSqlserver}}
68
- SQLSERVER_HOST: z.string().default("localhost"),
69
- SQLSERVER_PORT: z.string().transform(Number).default(1433),
70
70
  SQLSERVER_DATABASE: z.string().default("{{projectNameKebab}}_db"),
71
- SQLSERVER_USER: z.string(),
72
- SQLSERVER_PASSWORD: z.string(),
73
71
  SQLSERVER_ENCRYPT: z.string().transform((value) => value !== "false").default(true),
72
+ SQLSERVER_HOST: z.string().default("localhost"),
73
+ SQLSERVER_PASSWORD: z.string(),
74
+ SQLSERVER_PORT: z.string().transform(Number).default(1433),
74
75
  SQLSERVER_TRUST_SERVER_CERTIFICATE: z.string().transform((value) => value === "true").default(false),
76
+ SQLSERVER_USER: z.string(),
75
77
  {{/if}}
76
- {{#if hasMongodb}}
77
- MONGODB_URL: z.url(),
78
- {{/if}}
78
+ TRUSTED_PROXY_IPS: z.string().default("{{#each trustedProxyIps}}{{#unless @first}},{{/unless}}{{this}}{{/each}}"),
79
79
  {{#if hasGraphql}}
80
80
  GRAPHQL_PLAYGROUND: z
81
81
  .string()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nest-arch/tui",
3
- "version": "0.4.6",
3
+ "version": "0.5.1",
4
4
  "private": false,
5
5
  "description": "Interactive terminal UI for generating NestJS projects",
6
6
  "keywords": [
@@ -38,6 +38,7 @@
38
38
  "handlebars": "^4.7.8",
39
39
  "ink": "^5.0.1",
40
40
  "ink-text-input": "^6.0.0",
41
+ "jsonc-parser": "^3.3.1",
41
42
  "open": "^11.0.0",
42
43
  "react": "^18.3.1",
43
44
  "semver": "^7.8.5",
@@ -45,15 +46,15 @@
45
46
  "zod": "^4.1.13"
46
47
  },
47
48
  "devDependencies": {
49
+ "@nest-arch/core": "0.4.3",
50
+ "@nest-arch/env": "0.0.0",
51
+ "@nest-arch/shared": "0.0.0",
48
52
  "@types/react": "^18.3.12",
49
53
  "@types/semver": "^7.8.0",
50
54
  "ink-testing-library": "^4.0.0",
51
55
  "pkgroll": "^2.5.2",
52
56
  "tsx": "^4.19.2",
53
- "vitest": "^4.1.7",
54
- "@nest-arch/env": "0.0.0",
55
- "@nest-arch/core": "0.4.3",
56
- "@nest-arch/shared": "0.0.0"
57
+ "vitest": "^4.1.7"
57
58
  },
58
59
  "peerDependencies": {
59
60
  "typescript": "^5"
@@ -1 +0,0 @@
1
- var o="0.4.6",O={version:o};const s="Nest Arch",A=`v${O.version}`,n="Build production-ready NestJS projects.",t="#e54545",c="#A0A0A0",R="#6B6B6B",C="#E5E5E5",E="#61AFEF",_="#3A3A3A",e="#7FD99A",r="#E8C468",L="#e96142ff";export{s as APP_NAME,n as APP_TAGLINE,A as APP_VERSION,E as COLOR_ACCENT,c as COLOR_DIM,R as COLOR_DIMMER,_ as COLOR_DIVIDER,C as COLOR_FG,t as COLOR_RED,e as COLOR_SUCCESS,r as COLOR_WARM,L as COLOR_WARM_SECONDARY};