@nest-arch/tui 0.2.0 → 0.2.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 (48) hide show
  1. package/README.md +7 -0
  2. package/dist/cli.js +1 -1
  3. package/dist/{constants-BbJ71cex.js → constants-LZTzRAoQ.js} +1 -1
  4. package/dist/index.js +97 -79
  5. package/dist/templates/base/.env.example.hbs +36 -0
  6. package/dist/templates/base/.env.hbs +7 -0
  7. package/dist/templates/base/README.md.hbs +1 -1
  8. package/dist/templates/base/pnpm-workspace.yaml.hbs +6 -0
  9. package/dist/templates/base/src/app.module.ts.hbs +15 -1
  10. package/dist/templates/base/src/main.ts.hbs +5 -1
  11. package/dist/templates/extras/swagger/create-docs.ts.hbs +80 -36
  12. package/dist/templates/feature/graphql/src/graphql/dto/create-todo.input.ts.hbs +13 -0
  13. package/dist/templates/feature/graphql/src/graphql/dto/update-todo.input.ts.hbs +8 -0
  14. package/dist/templates/feature/graphql/src/graphql/graphql.module.ts.hbs +33 -0
  15. package/dist/templates/feature/graphql/src/graphql/models/base.model.ts.hbs +13 -0
  16. package/dist/templates/feature/graphql/src/graphql/models/pagination.model.ts.hbs +27 -0
  17. package/dist/templates/feature/graphql/src/graphql/models/todo.model.ts.hbs +23 -0
  18. package/dist/templates/feature/graphql/src/graphql/models/user.model.ts.hbs +34 -0
  19. package/dist/templates/feature/graphql/src/graphql/orm/drizzle/drizzle-graphql.module.ts.hbs +42 -0
  20. package/dist/templates/feature/graphql/src/graphql/orm/typeorm/typeorm-graphql-relations.helper.ts.hbs +23 -0
  21. package/dist/templates/feature/graphql/src/graphql/resolvers/base.resolver.ts.hbs +50 -0
  22. package/dist/templates/feature/graphql/src/graphql/resolvers/todo.resolver.ts.hbs +126 -0
  23. package/dist/templates/feature/rest/todo-example/src/api/todo/dto/create-todo.dto.ts.hbs +13 -0
  24. package/dist/templates/feature/rest/todo-example/src/api/todo/dto/update-todo.dto.ts.hbs +13 -0
  25. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.controller.ts.hbs +346 -0
  26. package/dist/templates/monorepo/apps/api-gateway/src/app.module.ts.hbs +15 -1
  27. package/dist/templates/monorepo/apps/api-gateway/src/main.ts.hbs +56 -54
  28. package/dist/templates/monorepo/feature/graphql/src/graphql/dto/create-todo.input.ts.hbs +13 -0
  29. package/dist/templates/monorepo/feature/graphql/src/graphql/dto/update-todo.input.ts.hbs +8 -0
  30. package/dist/templates/monorepo/feature/graphql/src/graphql/graphql.module.ts.hbs +33 -0
  31. package/dist/templates/monorepo/feature/graphql/src/graphql/models/base.model.ts.hbs +13 -0
  32. package/dist/templates/monorepo/feature/graphql/src/graphql/models/todo.model.ts.hbs +23 -0
  33. package/dist/templates/monorepo/feature/graphql/src/graphql/models/user.model.ts.hbs +34 -0
  34. package/dist/templates/monorepo/feature/graphql/src/graphql/orm/drizzle/drizzle-graphql.module.ts.hbs +16 -0
  35. package/dist/templates/monorepo/feature/graphql/src/graphql/orm/prisma/prisma-graphql.service.ts.hbs +9 -0
  36. package/dist/templates/monorepo/feature/graphql/src/graphql/orm/typeorm/typeorm-graphql-relations.helper.ts.hbs +23 -0
  37. package/dist/templates/monorepo/feature/graphql/src/graphql/resolvers/todo.resolver.ts.hbs +122 -0
  38. package/dist/templates/monorepo/packages/env/src/api-gateway.ts.hbs +10 -0
  39. package/dist/templates/monorepo/root/README.md.hbs +1 -1
  40. package/dist/templates/monorepo/root/pnpm-workspace.yaml.hbs +6 -0
  41. package/dist/templates/single-project/architecture/nest-api/.env.hbs +25 -1
  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 +61 -55
  44. package/dist/templates/single-project/architecture/nest-gateway/src/main.ts.hbs +56 -54
  45. package/dist/templates/single-project/architecture/nest-microservice/.env.hbs +3 -0
  46. package/dist/templates/single-project/architecture/nest-microservice/src/main.ts.hbs +56 -54
  47. package/dist/templates/single-project/shared/config/env.ts.hbs +10 -0
  48. package/package.json +2 -2
@@ -0,0 +1,126 @@
1
+ {{#if (and hasAuth hasDatabase)}}
2
+ import { UseGuards } from "@nestjs/common";
3
+ {{/if}}
4
+ import { Args, Mutation, Query, Resolver } from "@nestjs/graphql";
5
+ import { CreateTodoInput } from "../dto/create-todo.input.js";
6
+ import { UpdateTodoInput } from "../dto/update-todo.input.js";
7
+ {{#if isMonorepo}}
8
+ import { DbService } from "@repo/db";
9
+ {{else}}
10
+ import { DbService } from "../database/db.service.js";
11
+ {{/if}}
12
+ {{#if useTypeorm}}
13
+ import { GraphRelationBuilder } from "typeorm-relations-graphql";
14
+ import { GraphQLResolveInfo } from "graphql";
15
+ {{/if}}
16
+ {{#if useDrizzle}}
17
+ import * as schema from "../database/orm/drizzle/schema.js";
18
+ {{/if}}
19
+ {{#if (and hasAuth hasDatabase)}}
20
+ import { Todo } from "../models/todo.model.js";
21
+ import { UserEntity } from "../../auth/decorators/index.js";
22
+ import { GqlAuthGuard } from "../../auth/guards/gql-auth.guard.js";
23
+ {{/if}}
24
+
25
+ @Resolver({{#if (and hasAuth hasDatabase)}}{{"("}}() => Todo){{/if}})
26
+ export class TodoResolver {
27
+ constructor(private readonly db: DbService) {}
28
+
29
+ @Query(() => String)
30
+ hello(): string {
31
+ return "Hello GraphQL!";
32
+ }{{#if hasDatabase}}
33
+
34
+ @Query(() => [Todo])
35
+ todos({{#if useTypeorm}}info: GraphQLResolveInfo{{/if}}): Promise<Todo[]> {
36
+ {{#if useTypeorm}}
37
+ const builder = new GraphRelationBuilder(this.db.getDataSource());
38
+ const relations = builder.buildForQuery(Todo, info, "todos");
39
+ return this.db.getRepository(Todo).find({ relations });
40
+ {{else if usePrisma}}
41
+ return this.db.prisma.todo.findMany();
42
+ {{else if useDrizzle}}
43
+ return this.db.select().from(schema.todos);
44
+ {{else}}
45
+ return [];
46
+ {{/if}}
47
+ }
48
+
49
+ @Mutation(() => Todo)
50
+ {{#if (and hasAuth hasDatabase)}}
51
+ @UseGuards(GqlAuthGuard)
52
+ {{/if}}
53
+ createTodo(
54
+ @Args("input") input: CreateTodoInput{{#if (and hasAuth hasDatabase)}},
55
+ @UserEntity() user: { id: string }{{/if}}{{#if useTypeorm}}, info: GraphQLResolveInfo{{/if}}
56
+ ): Promise<Todo> {
57
+ {{#if useTypeorm}}
58
+ const entity = this.db.getRepository(Todo).create(input);
59
+ const saved = await this.db.getRepository(Todo).save(entity);
60
+ const builder = new GraphRelationBuilder(this.db.getDataSource());
61
+ const relations = builder.buildForQuery(Todo, info, "createTodo");
62
+ return this.db.getRepository(Todo).findOneOrFail({
63
+ where: { id: saved.id },
64
+ relations,
65
+ });
66
+ {{else if usePrisma}}
67
+ return this.db.prisma.todo.create({
68
+ data: { ...input{{#if (and hasAuth hasDatabase)}}, authorId: user.id{{/if}} },
69
+ });
70
+ {{else if useDrizzle}}
71
+ const [todo] = await this.db.insert(schema.todos).values(input).returning();
72
+ return todo;
73
+ {{else}}
74
+ return { id: "1", ...input };
75
+ {{/if}}
76
+ }
77
+
78
+ @Mutation(() => Todo)
79
+ {{#if (and hasAuth hasDatabase)}}
80
+ @UseGuards(GqlAuthGuard)
81
+ {{/if}}
82
+ updateTodo(
83
+ @Args("input") input: UpdateTodoInput{{#if useTypeorm}}, info: GraphQLResolveInfo{{/if}}
84
+ ): Promise<Todo> {
85
+ const { id, ...data } = input;
86
+ {{#if useTypeorm}}
87
+ await this.db.getRepository(Todo).update(id, data);
88
+ const builder = new GraphRelationBuilder(this.db.getDataSource());
89
+ const relations = builder.buildForQuery(Todo, info, "updateTodo");
90
+ return this.db.getRepository(Todo).findOneOrFail({
91
+ where: { id },
92
+ relations,
93
+ });
94
+ {{else if usePrisma}}
95
+ return this.db.prisma.todo.update({ where: { id }, data });
96
+ {{else if useDrizzle}}
97
+ const [todo] = await this.db
98
+ .update(schema.todos)
99
+ .set(data)
100
+ .where(eq(schema.todos.id, id))
101
+ .returning();
102
+ return todo;
103
+ {{else}}
104
+ return { id, ...data };
105
+ {{/if}}
106
+ }
107
+
108
+ @Mutation(() => Boolean)
109
+ {{#if (and hasAuth hasDatabase)}}
110
+ @UseGuards(GqlAuthGuard)
111
+ {{/if}}
112
+ async deleteTodo(@Args("id") id: string): Promise<boolean> {
113
+ {{#if useTypeorm}}
114
+ const result = await this.db.getRepository(Todo).delete(id);
115
+ return (result.affected ?? 0) > 0;
116
+ {{else if usePrisma}}
117
+ await this.db.prisma.todo.delete({ where: { id } });
118
+ return true;
119
+ {{else if useDrizzle}}
120
+ await this.db.delete(schema.todos).where(eq(schema.todos.id, id));
121
+ return true;
122
+ {{else}}
123
+ return true;
124
+ {{/if}}
125
+ }{{/if}}
126
+ }
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+
3
+ export class CreateTodoDto {
4
+ static schema = z.object({
5
+ completed: z.boolean().default(false),
6
+ description: z.string().optional(),
7
+ title: z.string().min(1),
8
+ });
9
+
10
+ title: string;
11
+ description?: string;
12
+ completed: boolean;
13
+ }
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+
3
+ export class UpdateTodoDto {
4
+ static schema = z.object({
5
+ completed: z.boolean().optional(),
6
+ description: z.string().optional(),
7
+ title: z.string().min(1).optional(),
8
+ });
9
+
10
+ title?: string;
11
+ description?: string;
12
+ completed?: boolean;
13
+ }
@@ -0,0 +1,346 @@
1
+ import {
2
+ Body,
3
+ Controller,
4
+ Delete,
5
+ Get,
6
+ Param,
7
+ Post,
8
+ Put,
9
+ {{#if (and isPassportAuth hasDatabase)}}
10
+ UseGuards,
11
+ {{/if}}
12
+ } from "@nestjs/common";
13
+ {{#if swagger}}
14
+ import {
15
+ ApiCreatedResponse,
16
+ ApiOkResponse,
17
+ ApiOperation,
18
+ ApiTags,
19
+ ApiUnauthorizedResponse,
20
+ } from "@nestjs/swagger";
21
+ {{/if}}
22
+ {{#if isPassportAuth}}
23
+ import {
24
+ ApiBearerAuth,
25
+ } from "@nestjs/swagger";
26
+ {{/if}}
27
+ {{#if (and isBetterAuth hasDatabase)}}
28
+ import { Session } from "@thallesp/nestjs-better-auth";
29
+ import type { UserSession } from "../../auth/auth.js";
30
+ {{/if}}
31
+ {{#if isMonorepo}}
32
+ import { DbService } from "@repo/db";
33
+ {{else if hasDatabase}}
34
+ import { DbService } from "../../database/db.service.js";
35
+ {{/if}}
36
+ {{#if (and isPassportAuth hasDatabase)}}
37
+ import { RestAuthGuard } from "../../auth/guards/rest-auth.guard.js";
38
+ import { CurrentUser } from "../../auth/decorators/current-user.decorator.js";
39
+ {{/if}}
40
+ {{#if hasDatabase}}
41
+ {{#if useDrizzle}}
42
+ import * as schema from "../../database/orm/drizzle/schema.js";
43
+ import { eq } from "drizzle-orm";
44
+ {{/if}}
45
+ {{#if useTypeorm}}
46
+ import { Todo } from "../../database/entities/todo.entity.js";
47
+ {{/if}}
48
+ {{/if}}
49
+ import { CreateTodoDto } from "./dto/create-todo.dto.js";
50
+ import { UpdateTodoDto } from "./dto/update-todo.dto.js";
51
+
52
+ {{#if swagger}}
53
+ @ApiTags("Todos")
54
+ {{/if}}
55
+ @Controller("todos")
56
+ {{#if (and isPassportAuth hasDatabase)}}
57
+ @UseGuards(RestAuthGuard)
58
+ {{/if}}
59
+ export class TodoController {
60
+ {{#if hasDatabase}}
61
+ constructor(private readonly db: DbService) {}
62
+ {{else}}
63
+ private todos: Array<{
64
+ completed: boolean;
65
+ description?: string;
66
+ id: string;
67
+ title: string;
68
+ }> = [];
69
+ private nextId = 1;
70
+ {{/if}}
71
+
72
+ @Get()
73
+ {{#if swagger}}
74
+ {{#if (or isPassportAuth)}}
75
+ @ApiBearerAuth()
76
+ {{/if}}
77
+ @ApiOperation({ summary: "/api/todos" })
78
+ @ApiOkResponse({ description: "Returns all todos" })
79
+ {{#if (or isPassportAuth isBetterAuth)}}
80
+ @ApiUnauthorizedResponse({ description: "Unauthorized" })
81
+ {{/if}}
82
+ {{/if}}
83
+ {{#if (and isPassportAuth hasDatabase)}}
84
+ findAll(@CurrentUser() user: { id: string }) {
85
+ {{#if usePrisma}}
86
+ return this.db.prisma.todo.findMany({ where: { authorId: user.id } });
87
+ {{else if useTypeorm}}
88
+ return this.db.getRepository(Todo).find({ where: { authorId: user.id } });
89
+ {{else if useDrizzle}}
90
+ return this.db
91
+ .select()
92
+ .from(schema.todos)
93
+ .where(eq(schema.todos.authorId, user.id));
94
+ {{/if}}
95
+ }
96
+ {{else if (and isBetterAuth hasDatabase)}}
97
+ findAll(@Session() session: UserSession) {
98
+ {{#if usePrisma}}
99
+ return this.db.prisma.todo.findMany({
100
+ where: { authorId: session.user.id },
101
+ });
102
+ {{else if useTypeorm}}
103
+ return this.db
104
+ .getRepository(Todo)
105
+ .find({ where: { authorId: session.user.id } });
106
+ {{else if useDrizzle}}
107
+ return this.db
108
+ .select()
109
+ .from(schema.todos)
110
+ .where(eq(schema.todos.authorId, session.user.id));
111
+ {{/if}}
112
+ }
113
+ {{else if hasDatabase}}
114
+ findAll() {
115
+ {{#if usePrisma}}
116
+ return this.db.prisma.todo.findMany();
117
+ {{else if useTypeorm}}
118
+ return this.db.getRepository(Todo).find();
119
+ {{else if useDrizzle}}
120
+ return this.db.select().from(schema.todos);
121
+ {{/if}}
122
+ }
123
+ {{else}}
124
+ findAll() {
125
+ return [...this.todos];
126
+ }
127
+ {{/if}}
128
+
129
+ @Post()
130
+ {{#if swagger}}
131
+ {{#if (or isPassportAuth)}}
132
+ @ApiBearerAuth()
133
+ {{/if}}
134
+ @ApiOperation({ summary: "/api/todos" })
135
+ @ApiCreatedResponse({ description: "Todo created successfully" })
136
+ {{#if (or isPassportAuth isBetterAuth)}}
137
+ @ApiUnauthorizedResponse({ description: "Unauthorized" })
138
+ {{/if}}
139
+ {{/if}}
140
+ {{#if (and isPassportAuth hasDatabase)}}
141
+ create(
142
+ @Body({ schema: CreateTodoDto.schema }) input: CreateTodoDto,
143
+ @CurrentUser() user: { id: string }
144
+ ) {
145
+ {{#if usePrisma}}
146
+ return this.db.prisma.todo.create({
147
+ data: { ...input, authorId: user.id },
148
+ });
149
+ {{else if useTypeorm}}
150
+ return this.db.getRepository(Todo).save(
151
+ this.db.getRepository(Todo).create({ ...input, authorId: user.id }),
152
+ );
153
+ {{else if useDrizzle}}
154
+ return this.db
155
+ .insert(schema.todos)
156
+ .values({ ...input, authorId: user.id })
157
+ .returning();
158
+ {{/if}}
159
+ }
160
+ {{else if (and isBetterAuth hasDatabase)}}
161
+ create(
162
+ @Body({ schema: CreateTodoDto.schema }) input: CreateTodoDto,
163
+ @Session() session: UserSession
164
+ ) {
165
+ {{#if usePrisma}}
166
+ return this.db.prisma.todo.create({
167
+ data: { ...input, authorId: session.user.id },
168
+ });
169
+ {{else if useTypeorm}}
170
+ return this.db.getRepository(Todo).save(
171
+ this.db
172
+ .getRepository(Todo)
173
+ .create({ ...input, authorId: session.user.id }),
174
+ );
175
+ {{else if useDrizzle}}
176
+ return this.db
177
+ .insert(schema.todos)
178
+ .values({ ...input, authorId: session.user.id })
179
+ .returning();
180
+ {{/if}}
181
+ }
182
+ {{else if hasDatabase}}
183
+ create(@Body({ schema: CreateTodoDto.schema }) input: CreateTodoDto) {
184
+ {{#if usePrisma}}
185
+ return this.db.prisma.todo.create({ data: input });
186
+ {{else if useTypeorm}}
187
+ return this.db
188
+ .getRepository(Todo)
189
+ .save(this.db.getRepository(Todo).create(input));
190
+ {{else if useDrizzle}}
191
+ return this.db.insert(schema.todos).values(input).returning();
192
+ {{/if}}
193
+ }
194
+ {{else}}
195
+ create(@Body({ schema: CreateTodoDto.schema }) input: CreateTodoDto) {
196
+ const todo = { id: String(this.nextId++), ...input };
197
+ this.todos.push(todo);
198
+ return todo;
199
+ }
200
+ {{/if}}
201
+
202
+ @Put(":id")
203
+ {{#if swagger}}
204
+ {{#if (or isPassportAuth)}}
205
+ @ApiBearerAuth()
206
+ {{/if}}
207
+ @ApiOperation({ summary: "/api/todos/{id}" })
208
+ @ApiOkResponse({ description: "Todo updated successfully" })
209
+ {{#if (or isPassportAuth isBetterAuth)}}
210
+ @ApiUnauthorizedResponse({ description: "Unauthorized" })
211
+ {{/if}}
212
+ {{/if}}
213
+ {{#if (and isPassportAuth hasDatabase)}}
214
+ update(
215
+ @Param("id") id: string,
216
+ @Body({ schema: UpdateTodoDto.schema }) input: UpdateTodoDto,
217
+ @CurrentUser() user: { id: string }
218
+ ) {
219
+ {{#if usePrisma}}
220
+ return this.db.prisma.todo.update({
221
+ data: input,
222
+ where: { authorId: user.id, id },
223
+ });
224
+ {{else if useTypeorm}}
225
+ return this.db
226
+ .getRepository(Todo)
227
+ .update({ authorId: user.id, id }, input);
228
+ {{else if useDrizzle}}
229
+ return this.db
230
+ .update(schema.todos)
231
+ .set(input)
232
+ .where(
233
+ eq(schema.todos.authorId, user.id) && eq(schema.todos.id, id),
234
+ )
235
+ .returning();
236
+ {{/if}}
237
+ }
238
+ {{else if (and isBetterAuth hasDatabase)}}
239
+ update(
240
+ @Param("id") id: string,
241
+ @Body({ schema: UpdateTodoDto.schema }) input: UpdateTodoDto,
242
+ @Session() session: UserSession
243
+ ) {
244
+ {{#if usePrisma}}
245
+ return this.db.prisma.todo.update({
246
+ data: input,
247
+ where: { authorId: session.user.id, id },
248
+ });
249
+ {{else if useTypeorm}}
250
+ return this.db
251
+ .getRepository(Todo)
252
+ .update({ authorId: session.user.id, id }, input);
253
+ {{else if useDrizzle}}
254
+ return this.db
255
+ .update(schema.todos)
256
+ .set(input)
257
+ .where(
258
+ eq(schema.todos.authorId, session.user.id) &&
259
+ eq(schema.todos.id, id),
260
+ )
261
+ .returning();
262
+ {{/if}}
263
+ }
264
+ {{else if hasDatabase}}
265
+ update(
266
+ @Param("id") id: string,
267
+ @Body({ schema: UpdateTodoDto.schema }) input: UpdateTodoDto
268
+ ) {
269
+ {{#if usePrisma}}
270
+ return this.db.prisma.todo.update({ data: input, where: { id } });
271
+ {{else if useTypeorm}}
272
+ return this.db.getRepository(Todo).update(id, input);
273
+ {{else if useDrizzle}}
274
+ return this.db
275
+ .update(schema.todos)
276
+ .set(input)
277
+ .where(eq(schema.todos.id, id))
278
+ .returning();
279
+ {{/if}}
280
+ }
281
+ {{else}}
282
+ update(
283
+ @Param("id") id: string,
284
+ @Body({ schema: UpdateTodoDto.schema }) input: UpdateTodoDto
285
+ ) {
286
+ const todo = this.todos.find((t) => t.id === id);
287
+ if (!todo) {
288
+ return { message: "Todo not found" };
289
+ }
290
+ Object.assign(todo, input);
291
+ return todo;
292
+ }
293
+ {{/if}}
294
+
295
+ @Delete(":id")
296
+ {{#if swagger}}
297
+ {{#if (or isPassportAuth)}}
298
+ @ApiBearerAuth()
299
+ {{/if}}
300
+ @ApiOperation({ summary: "/api/todos/{id}" })
301
+ @ApiOkResponse({ description: "Todo deleted successfully" })
302
+ {{#if (or isPassportAuth isBetterAuth)}}
303
+ @ApiUnauthorizedResponse({ description: "Unauthorized" })
304
+ {{/if}}
305
+ {{/if}}
306
+ {{#if (and isPassportAuth hasDatabase)}}
307
+ async delete(
308
+ @Param("id") id: string,
309
+ @CurrentUser() user: { id: string }
310
+ ) {
311
+ await this.db.prisma.todo.delete({
312
+ where: { authorId: user.id, id },
313
+ });
314
+ return { message: "Todo deleted successfully" };
315
+ }
316
+ {{else if (and isBetterAuth hasDatabase)}}
317
+ async delete(
318
+ @Param("id") id: string,
319
+ @Session() session: UserSession
320
+ ) {
321
+ await this.db.prisma.todo.delete({
322
+ where: { authorId: session.user.id, id },
323
+ });
324
+ return { message: "Todo deleted successfully" };
325
+ }
326
+ {{else if hasDatabase}}
327
+ async delete(@Param("id") id: string) {
328
+ {{#if usePrisma}}
329
+ await this.db.prisma.todo.delete({ where: { id } });
330
+ {{else if useTypeorm}}
331
+ await this.db.getRepository(Todo).delete(id);
332
+ {{else if useDrizzle}}
333
+ await this.db.delete(schema.todos).where(eq(schema.todos.id, id));
334
+ {{/if}}
335
+ return { message: "Todo deleted successfully" };
336
+ }
337
+ {{else}}
338
+ async delete(@Param("id") id: string) {
339
+ const index = this.todos.findIndex((t) => t.id === id);
340
+ if (index >= 0) {
341
+ this.todos.splice(index, 1);
342
+ }
343
+ return { message: "Todo deleted successfully" };
344
+ }
345
+ {{/if}}
346
+ }
@@ -6,6 +6,9 @@ import { env } from "./config/env.js";
6
6
  {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
7
7
  import { AuthModule } from "./auth/auth.module.js";
8
8
  {{/if}}
9
+ {{#if hasGraphql}}
10
+ import { GraphqlAppModule } from "./graphql/graphql.module.js";
11
+ {{/if}}
9
12
  {{#if hasTrpc}}
10
13
  import { TRPCModule } from "nestjs-trpc";
11
14
  import { AppRouterClass as AppRouter } from "./app.router.js";
@@ -17,10 +20,18 @@ import { AuthTRPCMiddleware } from "./libs/middlewares/auth.trpc.middleware.js";
17
20
  {{/if}}
18
21
 
19
22
  import { AppController } from "./app.controller.js";
23
+ {{#if (and hasTodoExample hasRest)}}
24
+ import { TodoController } from "./api/todo/todo.controller.js";
25
+ {{/if}}
20
26
  import { AppService } from "./app.service.js";
21
27
 
22
28
  @Module({
23
- controllers: [AppController],
29
+ controllers: [
30
+ AppController,
31
+ {{#if (and hasTodoExample hasRest)}}
32
+ TodoController,
33
+ {{/if}}
34
+ ],
24
35
  imports: [
25
36
  {{#if (or hasDatabase hasOrm)}}
26
37
  DbModule.forRoot({
@@ -33,6 +44,9 @@ import { AppService } from "./app.service.js";
33
44
  {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
34
45
  AuthModule,
35
46
  {{/if}}
47
+ {{#if hasGraphql}}
48
+ GraphqlAppModule,
49
+ {{/if}}
36
50
  {{#if hasTrpc}}
37
51
  TRPCModule.forRoot({
38
52
  context: AppContext,
@@ -25,63 +25,65 @@ async function bootstrap() {
25
25
  origin: env.CORS_ORIGIN,
26
26
  });
27
27
  {{#if swagger}}
28
- const docsPath = "/docs";
29
- {{#if useSwaggerScalar}}
30
- app.use(
31
- docsPath,
32
- apiReference({
33
- content: await createDocs(app, {
34
- title: "{{projectNamePascalCase}} API",
35
- description: "{{description}}",
36
- version: "1.0.0",
37
- integrations: {
38
- {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
39
- betterAuth: {
40
- auth,
41
- pathPrefix: "/api/auth",
28
+ if (env.NODE_ENV === "development") {
29
+ const docsPath = "/docs";
30
+ {{#if useSwaggerScalar}}
31
+ app.use(
32
+ docsPath,
33
+ apiReference({
34
+ content: await createDocs(app, {
35
+ title: "{{projectNamePascalCase}} API",
36
+ description: "{{description}}",
37
+ version: "1.0.0",
38
+ integrations: {
39
+ {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
40
+ betterAuth: {
41
+ auth,
42
+ pathPrefix: "/api/auth",
43
+ },
44
+ {{/if}}
45
+ {{#if (includes apis "trpc")}}
46
+ trpc: {
47
+ routerFilePath: "./src/libs/trpc/@generated/server.ts",
48
+ pathPrefix: "/trpc",
49
+ },
50
+ {{/if}}
51
+ zod: {
52
+ withFastify: {{#if (eq httpProvider "fastify")}}true{{else}}false{{/if}},
53
+ },
42
54
  },
43
- {{/if}}
44
- {{#if (includes apis "trpc")}}
45
- trpc: {
46
- routerFilePath: "./src/libs/trpc/@generated/server.ts",
47
- pathPrefix: "/trpc",
48
- },
49
- {{/if}}
50
- zod: {
51
- withFastify: {{#if (eq httpProvider "fastify")}}true{{else}}false{{/if}},
52
- },
53
- },
55
+ }),
56
+ pageTitle: "{{projectNamePascalCase}} API Docs",
57
+ theme: "default",
54
58
  }),
55
- pageTitle: "{{projectNamePascalCase}} API Docs",
56
- theme: "default",
57
- }),
58
- );
59
- {{else}}
60
- const document = await createDocs(app, {
61
- title: "{{projectNamePascalCase}} API",
62
- description: "{{description}}",
63
- version: "1.0.0",
64
- integrations: {
65
- {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
66
- betterAuth: {
67
- auth,
68
- pathPrefix: "/api/auth",
69
- },
70
- {{/if}}
71
- {{#if (includes apis "trpc")}}
72
- trpc: {
73
- routerFilePath: "./src/trpc/router.ts",
74
- pathPrefix: "/trpc",
75
- },
76
- {{/if}}
77
- zod: {
78
- withFastify: {{#if (eq httpProvider "fastify")}}true{{else}}false{{/if}},
59
+ );
60
+ {{else}}
61
+ const document = await createDocs(app, {
62
+ title: "{{projectNamePascalCase}} API",
63
+ description: "{{description}}",
64
+ version: "1.0.0",
65
+ integrations: {
66
+ {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
67
+ betterAuth: {
68
+ auth,
69
+ pathPrefix: "/api/auth",
70
+ },
71
+ {{/if}}
72
+ {{#if (includes apis "trpc")}}
73
+ trpc: {
74
+ routerFilePath: "./src/trpc/router.ts",
75
+ pathPrefix: "/trpc",
76
+ },
77
+ {{/if}}
78
+ zod: {
79
+ withFastify: {{#if (eq httpProvider "fastify")}}true{{else}}false{{/if}},
80
+ },
79
81
  },
80
- },
81
- });
82
- SwaggerModule.setup(docsPath, app, document);
83
- {{/if}}
84
- Logger.log(`Swagger documentation available at http://localhost:${env.PORT ?? 3000}${docsPath}`, "SwaggerDocs");
82
+ });
83
+ SwaggerModule.setup(docsPath, app, document);
84
+ {{/if}}
85
+ Logger.log(`Swagger documentation available at http://localhost:${env.PORT ?? 3000}${docsPath}`, "SwaggerDocs");
86
+ }
85
87
  {{/if}}
86
88
  await app.listen(env.PORT ?? 3000);
87
89
  Logger.log(`Started backend server on http://localhost:${env.PORT ?? 3000}/api`, "Main");
@@ -0,0 +1,13 @@
1
+ import { Field, InputType } from "@nestjs/graphql";
2
+
3
+ @InputType()
4
+ export class CreateTodoInput {
5
+ @Field()
6
+ title: string;
7
+
8
+ @Field({ nullable: true })
9
+ description?: string;
10
+
11
+ @Field({ defaultValue: false })
12
+ completed: boolean;
13
+ }
@@ -0,0 +1,8 @@
1
+ import { Field, ID, InputType, PartialType } from "@nestjs/graphql";
2
+ import { CreateTodoInput } from "./create-todo.input.js";
3
+
4
+ @InputType()
5
+ export class UpdateTodoInput extends PartialType(CreateTodoInput) {
6
+ @Field(() => ID)
7
+ id: string;
8
+ }