@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,4 +1,8 @@
1
- FROM node:22-alpine
1
+ FROM node:22-trixie-slim
2
+
3
+ {{#if hasSqlite}}
4
+ RUN apt-get update && apt-get install -y --no-install-recommends python3 make g++ && rm -rf /var/lib/apt/lists/*
5
+ {{/if}}
2
6
 
3
7
  WORKDIR /app
4
8
 
@@ -10,7 +14,10 @@ RUN corepack enable
10
14
  {{/if}}
11
15
 
12
16
  COPY . .
13
- RUN POSTGRES_URL=postgresql://postgres:postgres@postgres:5432/build_db MYSQL_URL=mysql://root:mysql@mysql:3306/build_db MONGODB_URL=mongodb://mongodb:27017/build_db {{#if hasSqlserver}}SQLSERVER_HOST=localhost SQLSERVER_PORT=1433 SQLSERVER_DATABASE=build_db SQLSERVER_USER=sa SQLSERVER_PASSWORD=Build_only_Password_2026!X9 SQLSERVER_ENCRYPT=true SQLSERVER_TRUST_SERVER_CERTIFICATE=true {{/if}}{{#if (eq auth "passport")}}JWT_ACCESS_SECRET=build-only-access-secret-that-is-long-enough JWT_REFRESH_SECRET=build-only-refresh-secret-that-is-long-enough {{/if}}{{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}BETTER_AUTH_SECRET=build-only-better-auth-secret-that-is-long-enough BETTER_AUTH_URL=http://localhost:{{#if (eq httpProvider "fastify")}}3001{{else}}3000{{/if}} {{/if}}{{#if (eq packageManager "pnpm")}}pnpm install --no-lockfile{{else if (eq packageManager "yarn")}}yarn install{{else if (eq packageManager "bun")}}bun install{{/if}}
17
+ RUN POSTGRES_URL=postgresql://postgres:postgres@postgres:5432/build_db MYSQL_URL=mysql://root:mysql@mysql:3306/build_db MONGODB_URL=mongodb://mongodb:27017/build_db {{#if hasSqlserver}}SQLSERVER_HOST=localhost SQLSERVER_PORT=1433 SQLSERVER_DATABASE=build_db SQLSERVER_USER=sa SQLSERVER_PASSWORD=Build_only_Password_2026!X9 SQLSERVER_ENCRYPT=true SQLSERVER_TRUST_SERVER_CERTIFICATE=true {{/if}}{{#if (eq auth "passport")}}JWT_ACCESS_SECRET=build-only-access-secret-that-is-long-enough JWT_REFRESH_SECRET=build-only-refresh-secret-that-is-long-enough {{/if}}{{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}BETTER_AUTH_SECRET=build-only-better-auth-secret-that-is-long-enough BETTER_AUTH_URL=http://localhost:{{#if (eq httpProvider "fastify")}}3001{{else}}3000{{/if}} {{#if (eq auth "better-auth:stateless")}}OIDC_PROVIDER_ID=build-only OIDC_CLIENT_ID=build-only OIDC_CLIENT_SECRET=build-only OIDC_DISCOVERY_URL=https://example.invalid/.well-known/openid-configuration {{/if}}{{/if}}{{#if (eq packageManager "pnpm")}}pnpm install --no-lockfile{{else if (eq packageManager "yarn")}}yarn install{{else if (eq packageManager "bun")}}bun install{{/if}}
18
+ {{#each dockerBuildSetupCommands}}
19
+ RUN POSTGRES_URL=postgresql://postgres:postgres@postgres:5432/build_db MYSQL_URL=mysql://root:mysql@mysql:3306/build_db MONGODB_URL=mongodb://mongodb:27017/build_db SQLITE_PATH=/tmp/build.db {{#if (eq ../auth "passport")}}JWT_ACCESS_SECRET=build-only-access-secret-that-is-long-enough JWT_REFRESH_SECRET=build-only-refresh-secret-that-is-long-enough {{/if}}{{#if (or (eq ../auth "better-auth") (eq ../auth "better-auth:stateless"))}}BETTER_AUTH_SECRET=build-only-better-auth-secret-that-is-long-enough BETTER_AUTH_URL=http://localhost:{{#if (eq ../httpProvider "fastify")}}3001{{else}}3000{{/if}} {{#if (eq ../auth "better-auth:stateless")}}OIDC_PROVIDER_ID=build-only OIDC_CLIENT_ID=build-only OIDC_CLIENT_SECRET=build-only OIDC_DISCOVERY_URL=https://example.invalid/.well-known/openid-configuration {{/if}}{{/if}}{{this}}
20
+ {{/each}}
14
21
  RUN {{#if (eq packageManager "pnpm")}}pnpm run{{else if (eq packageManager "yarn")}}yarn{{else if (eq packageManager "bun")}}bun run{{else}}npm run{{/if}} build
15
22
 
16
23
  ENV NODE_ENV=production
@@ -5,6 +5,9 @@ import { AllowAnonymous } from "@thallesp/nestjs-better-auth";
5
5
  {{/if}}
6
6
  {{#if hasDatabase}}
7
7
  import { DbService } from "../database/db.service.js";
8
+ {{#if (and hasMongodb useTypeorm)}}
9
+ import { Todo } from "../database/entities/todo.entity.js";
10
+ {{/if}}
8
11
  {{#if useDrizzle}}
9
12
  import { sql } from "drizzle-orm";
10
13
  {{/if}}
@@ -31,10 +34,18 @@ export class HealthController {
31
34
  {{#if hasMongodb}}
32
35
  {{#if usePrisma}}
33
36
  await this.db.raw.mongo.$runCommandRaw({ ping: 1 });
37
+ {{else if useTypeorm}}
38
+ await this.db.typeorm.getMongoRepository(Todo).countDocuments({}, { limit: 1 });
34
39
  {{else}}
35
40
  await this.db.raw.mongo.command({ ping: 1 });
36
41
  {{/if}}
37
- {{else if (or usePrisma isPrisma8)}}
42
+ {{else if isPrisma8}}
43
+ {{#if hasTodoExample}}
44
+ await this.db.prisma.orm.public.Todo.all();
45
+ {{else}}
46
+ await this.db.prisma.connect();
47
+ {{/if}}
48
+ {{else if usePrisma}}
38
49
  await this.db.prisma.$queryRaw`SELECT 1`;
39
50
  {{else if useDrizzle}}
40
51
  {{#if hasSqlite}}
@@ -1,5 +1,6 @@
1
1
 
2
2
  import type { INestApplication } from "@nestjs/common";
3
+ import { Logger } from "@nestjs/common";
3
4
  import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
4
5
  import type { OpenAPIObject } from "@nestjs/swagger";
5
6
 
@@ -168,7 +169,11 @@ async function applyTrpcSpec(options?: NonNullable<DocsIntegrations["trpc"]>) {
168
169
  }
169
170
 
170
171
  return trpcSpec;
171
- } catch {
172
+ } catch (error) {
173
+ Logger.warn(
174
+ `Could not generate tRPC documentation from ${options.routerFilePath}: ${error instanceof Error ? error.message : String(error)}`,
175
+ "SwaggerDocs"
176
+ );
172
177
  return null;
173
178
  }
174
179
  }
@@ -1,4 +1,4 @@
1
- import { Field, ID, ObjectType } from "@nestjs/graphql";
1
+ import { Field{{#if hasAuth}}, ID{{/if}}, ObjectType } from "@nestjs/graphql";
2
2
 
3
3
  import { BaseModel } from "./base.model.js";
4
4
  {{#if hasAuth}}
@@ -52,7 +52,7 @@ import { GraphRelationBuilder } from "typeorm-relations-graphql";
52
52
  import { Todo as TodoEntity } from "../../database/entities/todo.entity.js";
53
53
  {{/if}}
54
54
  {{#if (and hasDatabase useDrizzle)}}
55
- import { and, eq } from "drizzle-orm";
55
+ import { {{#if hasAuth}}and, {{/if}}eq } from "drizzle-orm";
56
56
  import * as schema from "../../database/orm/drizzle/schema.js";
57
57
  {{/if}}
58
58
  {{#if hasDatabase}}
@@ -6,7 +6,10 @@ import {
6
6
  Param,
7
7
  Post,
8
8
  Put,
9
- {{#if (and isPassportAuth hasDatabase)}}
9
+ {{#if (eq auth "better-auth:stateless")}}
10
+ UnauthorizedException,
11
+ {{/if}}
12
+ {{#if isPassportAuth}}
10
13
  UseGuards,
11
14
  {{/if}}
12
15
  {{#if (and isBetterAuth hasDatabase hasGraphql)}}
@@ -31,7 +34,11 @@ import {
31
34
  import { Session } from "@thallesp/nestjs-better-auth";
32
35
  import type { UserSession } from "../../auth/auth.js";
33
36
  {{/if}}
34
- {{#if (and isPassportAuth hasDatabase)}}
37
+ {{#if (and isBetterAuth (not hasDatabase))}}
38
+ import { Session } from "@thallesp/nestjs-better-auth";
39
+ import type { UserSession } from "../../auth/auth.js";
40
+ {{/if}}
41
+ {{#if isPassportAuth}}
35
42
  import { RestAuthGuard } from "../../auth/guards/rest-auth.guard.js";
36
43
  import { CurrentUser } from "../../auth/decorators/current-user.decorator.js";
37
44
  {{/if}}
@@ -41,16 +48,29 @@ import { RestAuthGuard } from "../../auth/guards/rest-auth.guard.js";
41
48
  import { TodoService } from "./todo.service.js";
42
49
  import { CreateTodoDto } from "./dto/create-todo.dto.js";
43
50
  import { UpdateTodoDto } from "./dto/update-todo.dto.js";
51
+ {{#if isPrisma8}}
52
+ import type { Models } from "../../prisma/contract.js";
53
+
54
+ type Todo = Models.public_Todo;
55
+ {{/if}}
44
56
 
45
57
  {{#if swagger}}
46
58
  @ApiTags("Todos")
47
59
  {{/if}}
48
60
  @Controller("todos")
49
- {{#if (or (and isPassportAuth hasDatabase) (and isBetterAuth hasDatabase hasGraphql))}}
61
+ {{#if (or isPassportAuth (and isBetterAuth hasDatabase hasGraphql))}}
50
62
  @UseGuards(RestAuthGuard)
51
63
  {{/if}}
52
64
  export class TodoController {
53
65
  constructor(private readonly todoService: TodoService) {}
66
+ {{#if (eq auth "better-auth:stateless")}}
67
+ private requireUserId(session: UserSession | null | undefined): string {
68
+ if (!session?.user?.id) {
69
+ throw new UnauthorizedException("Authentication required");
70
+ }
71
+ return session.user.id;
72
+ }
73
+ {{/if}}
54
74
 
55
75
  @Get()
56
76
  {{#if swagger}}
@@ -63,7 +83,7 @@ export class TodoController {
63
83
  @ApiUnauthorizedResponse({ description: "Unauthorized" })
64
84
  {{/if}}
65
85
  {{/if}}
66
- {{#if (and isPassportAuth hasDatabase)}}
86
+ {{#if isPassportAuth}}
67
87
  findAll(@CurrentUser() user: { id: string }) {
68
88
  return this.todoService.findAll(user.id);
69
89
  }
@@ -75,10 +95,20 @@ export class TodoController {
75
95
  {{/if}}
76
96
  return this.todoService.findAll(session.user.id);
77
97
  }
98
+ {{else if isBetterAuth}}
99
+ findAll(@Session() session: UserSession | null) {
100
+ return this.todoService.findAll(this.requireUserId(session));
101
+ }
102
+ {{else}}
103
+ {{#if isPrisma8}}
104
+ async findAll(): Promise<Todo[]> {
105
+ return await this.todoService.findAll();
106
+ }
78
107
  {{else}}
79
108
  findAll() {
80
109
  return this.todoService.findAll();
81
110
  }
111
+ {{/if}}
82
112
  {{/if}}
83
113
 
84
114
  @Post()
@@ -92,7 +122,7 @@ export class TodoController {
92
122
  @ApiUnauthorizedResponse({ description: "Unauthorized" })
93
123
  {{/if}}
94
124
  {{/if}}
95
- {{#if (and isPassportAuth hasDatabase)}}
125
+ {{#if isPassportAuth}}
96
126
  create(
97
127
  @Body{{#if (includes addons "nestjs-zod")}}(){{else}}({ schema: CreateTodoDto.schema }){{/if}} input: CreateTodoDto,
98
128
  @CurrentUser() user: { id: string }
@@ -106,10 +136,23 @@ export class TodoController {
106
136
  ) {
107
137
  return this.todoService.create(input, session.user.id);
108
138
  }
139
+ {{else if isBetterAuth}}
140
+ create(
141
+ @Body{{#if (includes addons "nestjs-zod")}}(){{else}}({ schema: CreateTodoDto.schema }){{/if}} input: CreateTodoDto,
142
+ @Session() session: UserSession | null
143
+ ) {
144
+ return this.todoService.create(input, this.requireUserId(session));
145
+ }
146
+ {{else}}
147
+ {{#if isPrisma8}}
148
+ async create(@Body{{#if (includes addons "nestjs-zod")}}(){{else}}({ schema: CreateTodoDto.schema }){{/if}} input: CreateTodoDto): Promise<Todo> {
149
+ return await this.todoService.create(input);
150
+ }
109
151
  {{else}}
110
152
  create(@Body{{#if (includes addons "nestjs-zod")}}(){{else}}({ schema: CreateTodoDto.schema }){{/if}} input: CreateTodoDto) {
111
153
  return this.todoService.create(input);
112
154
  }
155
+ {{/if}}
113
156
  {{/if}}
114
157
 
115
158
  @Put(":id")
@@ -123,7 +166,7 @@ export class TodoController {
123
166
  @ApiUnauthorizedResponse({ description: "Unauthorized" })
124
167
  {{/if}}
125
168
  {{/if}}
126
- {{#if (and isPassportAuth hasDatabase)}}
169
+ {{#if isPassportAuth}}
127
170
  update(
128
171
  @Param("id") id: string,
129
172
  @Body{{#if (includes addons "nestjs-zod")}}(){{else}}({ schema: UpdateTodoDto.schema }){{/if}} input: UpdateTodoDto,
@@ -139,6 +182,22 @@ export class TodoController {
139
182
  ) {
140
183
  return this.todoService.update(id, input, session.user.id);
141
184
  }
185
+ {{else if isBetterAuth}}
186
+ update(
187
+ @Param("id") id: string,
188
+ @Body{{#if (includes addons "nestjs-zod")}}(){{else}}({ schema: UpdateTodoDto.schema }){{/if}} input: UpdateTodoDto,
189
+ @Session() session: UserSession | null
190
+ ) {
191
+ return this.todoService.update(id, input, this.requireUserId(session));
192
+ }
193
+ {{else}}
194
+ {{#if isPrisma8}}
195
+ async update(
196
+ @Param("id") id: string,
197
+ @Body{{#if (includes addons "nestjs-zod")}}(){{else}}({ schema: UpdateTodoDto.schema }){{/if}} input: UpdateTodoDto
198
+ ): Promise<Todo> {
199
+ return await this.todoService.update(id, input);
200
+ }
142
201
  {{else}}
143
202
  update(
144
203
  @Param("id") id: string,
@@ -146,6 +205,7 @@ export class TodoController {
146
205
  ) {
147
206
  return this.todoService.update(id, input);
148
207
  }
208
+ {{/if}}
149
209
  {{/if}}
150
210
 
151
211
  @Delete(":id")
@@ -159,7 +219,7 @@ export class TodoController {
159
219
  @ApiUnauthorizedResponse({ description: "Unauthorized" })
160
220
  {{/if}}
161
221
  {{/if}}
162
- {{#if (and isPassportAuth hasDatabase)}}
222
+ {{#if isPassportAuth}}
163
223
  delete(
164
224
  @Param("id") id: string,
165
225
  @CurrentUser() user: { id: string }
@@ -173,9 +233,22 @@ export class TodoController {
173
233
  ) {
174
234
  return this.todoService.delete(id, session.user.id);
175
235
  }
236
+ {{else if isBetterAuth}}
237
+ delete(
238
+ @Param("id") id: string,
239
+ @Session() session: UserSession | null
240
+ ) {
241
+ return this.todoService.delete(id, this.requireUserId(session));
242
+ }
243
+ {{else}}
244
+ {{#if isPrisma8}}
245
+ async delete(@Param("id") id: string): Promise<{ message: string }> {
246
+ return await this.todoService.delete(id);
247
+ }
176
248
  {{else}}
177
249
  delete(@Param("id") id: string) {
178
250
  return this.todoService.delete(id);
179
251
  }
180
252
  {{/if}}
253
+ {{/if}}
181
254
  }
@@ -12,16 +12,16 @@ import { CreateTodoDto } from "./dto/create-todo.dto.js";
12
12
  import { UpdateTodoDto } from "./dto/update-todo.dto.js";
13
13
 
14
14
  const todoSchema = z.object({
15
+ authorId: z.string().nullable().optional(),
16
+ completed: z.boolean(),
17
+ description: z.string().nullable().optional(),
15
18
  id: z.union([z.string(), z.number()]),
16
19
  title: z.string(),
17
- description: z.string().nullable().optional(),
18
- completed: z.boolean(),
19
- authorId: z.string().nullable().optional(),
20
20
  });
21
21
 
22
22
  const updateTodoInput = z.object({
23
- id: z.union([z.string(), z.number()]),
24
23
  data: UpdateTodoDto.schema,
24
+ id: z.union([z.string(), z.number()]),
25
25
  });
26
26
 
27
27
  @Router({ alias: "todoRouter" })