@nest-arch/tui 0.2.1 → 0.2.2
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/dist/cli.js +1 -1
- package/dist/{constants-LZTzRAoQ.js → constants-DBtqeoTh.js} +1 -1
- package/dist/index.js +59 -59
- package/dist/templates/base/.env.example.hbs +1 -1
- package/dist/templates/base/.env.hbs +1 -1
- package/dist/templates/base/pnpm-workspace.yaml.hbs +3 -0
- package/dist/templates/base/src/app.module.ts.hbs +11 -5
- package/dist/templates/base/src/database/db.module.ts.hbs +2 -4
- package/dist/templates/base/src/main.ts.hbs +6 -0
- package/dist/templates/extras/swagger/create-docs.ts.hbs +13 -1
- package/dist/templates/feature/rest/todo-example/src/api/todo/todo.controller.ts.hbs +14 -189
- package/dist/templates/feature/rest/todo-example/src/api/todo/todo.module.ts.hbs +24 -0
- package/dist/templates/feature/rest/todo-example/src/api/todo/todo.router.ts.hbs +76 -0
- package/dist/templates/feature/rest/todo-example/src/api/todo/todo.service.ts.hbs +145 -0
- package/dist/templates/monorepo/apps/api-gateway/src/app.module.ts.hbs +11 -5
- package/dist/templates/monorepo/apps/api-gateway/src/main.ts.hbs +6 -0
- package/dist/templates/monorepo/root/pnpm-workspace.yaml.hbs +3 -0
- package/dist/templates/single-project/architecture/nest-api/.env.hbs +1 -1
- package/dist/templates/single-project/architecture/nest-api/pnpm-workspace.yaml.hbs +3 -0
- package/dist/templates/single-project/architecture/nest-api/src/main.ts.hbs +6 -0
- package/dist/templates/single-project/architecture/nest-gateway/src/main.ts.hbs +6 -0
- package/dist/templates/single-project/architecture/nest-microservice/src/main.ts.hbs +6 -0
- package/package.json +4 -4
|
@@ -13,7 +13,7 @@ POSTGRES_URL=postgresql://postgres:postgres@localhost:5432/{{projectNameKebab}}_
|
|
|
13
13
|
MYSQL_URL=mysql://root:mysql@localhost:3306/{{projectNameKebab}}_db
|
|
14
14
|
{{/if}}
|
|
15
15
|
{{#if hasSqlite}}
|
|
16
|
-
SQLITE_PATH=
|
|
16
|
+
SQLITE_PATH=file:./src/database/dev.db
|
|
17
17
|
{{/if}}
|
|
18
18
|
{{#if hasMongodb}}
|
|
19
19
|
MONGODB_URL=mongodb://localhost:27017/{{projectNameKebab}}_db
|
|
@@ -11,7 +11,7 @@ POSTGRES_URL=postgresql://postgres:postgres@localhost:5432/{{projectNameKebab}}_
|
|
|
11
11
|
MYSQL_URL=mysql://root:mysql@localhost:3306/{{projectNameKebab}}_db
|
|
12
12
|
{{/if}}
|
|
13
13
|
{{#if hasSqlite}}
|
|
14
|
-
SQLITE_PATH=
|
|
14
|
+
SQLITE_PATH=file:./src/database/dev.db
|
|
15
15
|
{{/if}}
|
|
16
16
|
{{#if hasMongodb}}
|
|
17
17
|
MONGODB_URL=mongodb://localhost:27017/{{projectNameKebab}}_db
|
|
@@ -22,8 +22,11 @@ import { AuthTRPCMiddleware } from "./libs/middlewares/auth.trpc.middleware.js";
|
|
|
22
22
|
{{#if hasRest}}
|
|
23
23
|
import { AppController } from "./app.controller.js";
|
|
24
24
|
{{/if}}
|
|
25
|
-
{{#if (and hasTodoExample hasRest)}}
|
|
26
|
-
import {
|
|
25
|
+
{{#if (and hasTodoExample (or hasRest hasTrpc))}}
|
|
26
|
+
import { TodoModule } from "./api/todo/todo.module.js";
|
|
27
|
+
{{/if}}
|
|
28
|
+
{{#if (and hasTrpc hasTodoExample hasRest)}}
|
|
29
|
+
import { TodoRouter } from "./api/todo/todo.router.js";
|
|
27
30
|
{{/if}}
|
|
28
31
|
import { AppService } from "./app.service.js";
|
|
29
32
|
|
|
@@ -31,9 +34,6 @@ import { AppService } from "./app.service.js";
|
|
|
31
34
|
{{#if hasRest}}
|
|
32
35
|
controllers: [
|
|
33
36
|
AppController,
|
|
34
|
-
{{#if (and hasTodoExample hasRest)}}
|
|
35
|
-
TodoController,
|
|
36
|
-
{{/if}}
|
|
37
37
|
],
|
|
38
38
|
{{/if}}
|
|
39
39
|
imports: [
|
|
@@ -57,6 +57,9 @@ import { AppService } from "./app.service.js";
|
|
|
57
57
|
onError: AppErrorHandler,
|
|
58
58
|
}),
|
|
59
59
|
{{/if}}
|
|
60
|
+
{{#if (and hasTodoExample (or hasRest hasTrpc))}}
|
|
61
|
+
TodoModule,
|
|
62
|
+
{{/if}}
|
|
60
63
|
],
|
|
61
64
|
providers: [
|
|
62
65
|
AppService,
|
|
@@ -67,6 +70,9 @@ import { AppService } from "./app.service.js";
|
|
|
67
70
|
AppContext,
|
|
68
71
|
AppErrorHandler,
|
|
69
72
|
AppRouter,
|
|
73
|
+
{{#if (and hasTrpc hasTodoExample hasRest)}}
|
|
74
|
+
TodoRouter,
|
|
75
|
+
{{/if}}
|
|
70
76
|
{{/if}}
|
|
71
77
|
],
|
|
72
78
|
})
|
|
@@ -14,7 +14,7 @@ import { PrismaSqlAdapter } from './adapters/sql/prisma-sql.adapter.js';
|
|
|
14
14
|
import { PrismaPg } from '@prisma/adapter-pg';
|
|
15
15
|
{{/if}}
|
|
16
16
|
{{#if hasMysql}}
|
|
17
|
-
import {
|
|
17
|
+
import { PrismaMariaDb } from '@prisma/adapter-mariadb';
|
|
18
18
|
{{/if}}
|
|
19
19
|
{{#if hasSqlite}}
|
|
20
20
|
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3';
|
|
@@ -98,9 +98,7 @@ export class DbModule {
|
|
|
98
98
|
const prismaSql = new PrismaClient({ adapter: sqlAdapter });
|
|
99
99
|
{{/if}}
|
|
100
100
|
{{#if hasMysql}}
|
|
101
|
-
const sqlAdapter = new
|
|
102
|
-
uri: options.mysqlUrl,
|
|
103
|
-
});
|
|
101
|
+
const sqlAdapter = new PrismaMariaDb(options.mysqlUrl!);
|
|
104
102
|
const prismaSql = new PrismaClient({ adapter: sqlAdapter });
|
|
105
103
|
{{/if}}
|
|
106
104
|
{{#if hasSqlite}}
|
|
@@ -89,6 +89,12 @@ async function bootstrap() {
|
|
|
89
89
|
Logger.log(`Swagger documentation available at http://localhost:${env.PORT ?? 3000}${docsPath}`, "SwaggerDocs");
|
|
90
90
|
{{/if}}
|
|
91
91
|
await app.listen(env.PORT ?? 3000);
|
|
92
|
+
{{#if hasRest}}
|
|
92
93
|
Logger.log(`Started backend server on http://localhost:${env.PORT ?? 3000}/api`, "Main");
|
|
94
|
+
{{else if hasTrpc}}
|
|
95
|
+
Logger.log(`Started trpc server on http://localhost:${env.PORT ?? 3000}/trpc`, "Main");
|
|
96
|
+
{{else}}
|
|
97
|
+
Logger.log(`Started server on http://localhost:${env.PORT ?? 3000}`, "Main");
|
|
98
|
+
{{/if}}
|
|
93
99
|
}
|
|
94
100
|
await bootstrap();
|
|
@@ -208,12 +208,24 @@ async function applyTrpcSpec(
|
|
|
208
208
|
return null;
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
|
+
function createEmptyBaseSpec(options: CreateDocsOptions): OpenAPIObject {
|
|
212
|
+
return {
|
|
213
|
+
info: {
|
|
214
|
+
title: options.title ?? "NestJS API",
|
|
215
|
+
description: options.description ?? "Generated with Nest Arch",
|
|
216
|
+
version: options.version ?? "1.0.0",
|
|
217
|
+
},
|
|
218
|
+
openapi: "3.1.0",
|
|
219
|
+
paths: {},
|
|
220
|
+
tags: [],
|
|
221
|
+
} as OpenAPIObject;
|
|
222
|
+
}
|
|
211
223
|
|
|
212
224
|
export async function createDocs(
|
|
213
225
|
app: INestApplication,
|
|
214
226
|
options: CreateDocsOptions = {}
|
|
215
227
|
): Promise<OpenAPIObject> {
|
|
216
|
-
{{#if hasRest}}
|
|
228
|
+
{{#if (or hasRest hasAuth)}}
|
|
217
229
|
const config = new DocumentBuilder()
|
|
218
230
|
.setTitle(options.title ?? "NestJS API")
|
|
219
231
|
.setDescription(options.description ?? "Generated with Nest Arch")
|
|
@@ -28,24 +28,11 @@ import {
|
|
|
28
28
|
import { Session } from "@thallesp/nestjs-better-auth";
|
|
29
29
|
import type { UserSession } from "../../auth/auth.js";
|
|
30
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
31
|
{{#if (and isPassportAuth hasDatabase)}}
|
|
37
32
|
import { RestAuthGuard } from "../../auth/guards/rest-auth.guard.js";
|
|
38
33
|
import { CurrentUser } from "../../auth/decorators/current-user.decorator.js";
|
|
39
34
|
{{/if}}
|
|
40
|
-
{
|
|
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}}
|
|
35
|
+
import { TodoService } from "./todo.service.js";
|
|
49
36
|
import { CreateTodoDto } from "./dto/create-todo.dto.js";
|
|
50
37
|
import { UpdateTodoDto } from "./dto/update-todo.dto.js";
|
|
51
38
|
|
|
@@ -57,17 +44,7 @@ import { UpdateTodoDto } from "./dto/update-todo.dto.js";
|
|
|
57
44
|
@UseGuards(RestAuthGuard)
|
|
58
45
|
{{/if}}
|
|
59
46
|
export class TodoController {
|
|
60
|
-
{
|
|
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}}
|
|
47
|
+
constructor(private readonly todoService: TodoService) {}
|
|
71
48
|
|
|
72
49
|
@Get()
|
|
73
50
|
{{#if swagger}}
|
|
@@ -82,47 +59,15 @@ export class TodoController {
|
|
|
82
59
|
{{/if}}
|
|
83
60
|
{{#if (and isPassportAuth hasDatabase)}}
|
|
84
61
|
findAll(@CurrentUser() user: { id: string }) {
|
|
85
|
-
|
|
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}}
|
|
62
|
+
return this.todoService.findAll(user.id);
|
|
95
63
|
}
|
|
96
64
|
{{else if (and isBetterAuth hasDatabase)}}
|
|
97
65
|
findAll(@Session() session: UserSession) {
|
|
98
|
-
|
|
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}}
|
|
66
|
+
return this.todoService.findAll(session.user.id);
|
|
122
67
|
}
|
|
123
68
|
{{else}}
|
|
124
69
|
findAll() {
|
|
125
|
-
return
|
|
70
|
+
return this.todoService.findAll();
|
|
126
71
|
}
|
|
127
72
|
{{/if}}
|
|
128
73
|
|
|
@@ -142,60 +87,18 @@ export class TodoController {
|
|
|
142
87
|
@Body({ schema: CreateTodoDto.schema }) input: CreateTodoDto,
|
|
143
88
|
@CurrentUser() user: { id: string }
|
|
144
89
|
) {
|
|
145
|
-
|
|
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}}
|
|
90
|
+
return this.todoService.create(input, user.id);
|
|
159
91
|
}
|
|
160
92
|
{{else if (and isBetterAuth hasDatabase)}}
|
|
161
93
|
create(
|
|
162
94
|
@Body({ schema: CreateTodoDto.schema }) input: CreateTodoDto,
|
|
163
95
|
@Session() session: UserSession
|
|
164
96
|
) {
|
|
165
|
-
|
|
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}}
|
|
97
|
+
return this.todoService.create(input, session.user.id);
|
|
193
98
|
}
|
|
194
99
|
{{else}}
|
|
195
100
|
create(@Body({ schema: CreateTodoDto.schema }) input: CreateTodoDto) {
|
|
196
|
-
|
|
197
|
-
this.todos.push(todo);
|
|
198
|
-
return todo;
|
|
101
|
+
return this.todoService.create(input);
|
|
199
102
|
}
|
|
200
103
|
{{/if}}
|
|
201
104
|
|
|
@@ -216,24 +119,7 @@ export class TodoController {
|
|
|
216
119
|
@Body({ schema: UpdateTodoDto.schema }) input: UpdateTodoDto,
|
|
217
120
|
@CurrentUser() user: { id: string }
|
|
218
121
|
) {
|
|
219
|
-
|
|
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}}
|
|
122
|
+
return this.todoService.update(id, input, user.id);
|
|
237
123
|
}
|
|
238
124
|
{{else if (and isBetterAuth hasDatabase)}}
|
|
239
125
|
update(
|
|
@@ -241,54 +127,14 @@ export class TodoController {
|
|
|
241
127
|
@Body({ schema: UpdateTodoDto.schema }) input: UpdateTodoDto,
|
|
242
128
|
@Session() session: UserSession
|
|
243
129
|
) {
|
|
244
|
-
|
|
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}}
|
|
130
|
+
return this.todoService.update(id, input, session.user.id);
|
|
280
131
|
}
|
|
281
132
|
{{else}}
|
|
282
133
|
update(
|
|
283
134
|
@Param("id") id: string,
|
|
284
135
|
@Body({ schema: UpdateTodoDto.schema }) input: UpdateTodoDto
|
|
285
136
|
) {
|
|
286
|
-
|
|
287
|
-
if (!todo) {
|
|
288
|
-
return { message: "Todo not found" };
|
|
289
|
-
}
|
|
290
|
-
Object.assign(todo, input);
|
|
291
|
-
return todo;
|
|
137
|
+
return this.todoService.update(id, input);
|
|
292
138
|
}
|
|
293
139
|
{{/if}}
|
|
294
140
|
|
|
@@ -308,39 +154,18 @@ export class TodoController {
|
|
|
308
154
|
@Param("id") id: string,
|
|
309
155
|
@CurrentUser() user: { id: string }
|
|
310
156
|
) {
|
|
311
|
-
|
|
312
|
-
where: { authorId: user.id, id },
|
|
313
|
-
});
|
|
314
|
-
return { message: "Todo deleted successfully" };
|
|
157
|
+
return this.todoService.delete(id, user.id);
|
|
315
158
|
}
|
|
316
159
|
{{else if (and isBetterAuth hasDatabase)}}
|
|
317
160
|
async delete(
|
|
318
161
|
@Param("id") id: string,
|
|
319
162
|
@Session() session: UserSession
|
|
320
163
|
) {
|
|
321
|
-
|
|
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" };
|
|
164
|
+
return this.todoService.delete(id, session.user.id);
|
|
336
165
|
}
|
|
337
166
|
{{else}}
|
|
338
167
|
async delete(@Param("id") id: string) {
|
|
339
|
-
|
|
340
|
-
if (index >= 0) {
|
|
341
|
-
this.todos.splice(index, 1);
|
|
342
|
-
}
|
|
343
|
-
return { message: "Todo deleted successfully" };
|
|
168
|
+
return this.todoService.delete(id);
|
|
344
169
|
}
|
|
345
170
|
{{/if}}
|
|
346
171
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Module } from "@nestjs/common";
|
|
2
|
+
{{#if hasRest}}
|
|
3
|
+
import { TodoController } from "./todo.controller.js";
|
|
4
|
+
{{/if}}
|
|
5
|
+
import { TodoService } from "./todo.service.js";
|
|
6
|
+
{{#unless hasRest}}
|
|
7
|
+
import { TodoRouter } from "./todo.router.js";
|
|
8
|
+
{{/unless}}
|
|
9
|
+
|
|
10
|
+
@Module({
|
|
11
|
+
{{#if hasRest}}
|
|
12
|
+
controllers: [TodoController],
|
|
13
|
+
{{/if}}
|
|
14
|
+
providers: [
|
|
15
|
+
TodoService,
|
|
16
|
+
{{#unless hasRest}}
|
|
17
|
+
TodoRouter,
|
|
18
|
+
{{/unless}}
|
|
19
|
+
],
|
|
20
|
+
{{#if hasRest}}
|
|
21
|
+
exports: [TodoService],
|
|
22
|
+
{{/if}}
|
|
23
|
+
})
|
|
24
|
+
export class TodoModule {}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{{#if hasTrpc}}
|
|
2
|
+
import { Router, Query, Mutation, Ctx, Input } from "nestjs-trpc";
|
|
3
|
+
import z from "zod";
|
|
4
|
+
{{#if hasTrpcAndAuth}}
|
|
5
|
+
import type { UserSession } from "../../auth/auth.js";
|
|
6
|
+
import { AuthTRPCMiddleware } from "../../libs/middlewares/auth.trpc.middleware.js";
|
|
7
|
+
import type { InnerContext } from "../../libs/trpc/inner.context.js";
|
|
8
|
+
{{/if}}
|
|
9
|
+
import { TodoService } from "./todo.service.js";
|
|
10
|
+
import { CreateTodoDto } from "./dto/create-todo.dto.js";
|
|
11
|
+
import { UpdateTodoDto } from "./dto/update-todo.dto.js";
|
|
12
|
+
|
|
13
|
+
const todoSchema = z.object({
|
|
14
|
+
id: z.string(),
|
|
15
|
+
title: z.string(),
|
|
16
|
+
description: z.string().nullable().optional(),
|
|
17
|
+
completed: z.boolean(),
|
|
18
|
+
authorId: z.string().nullable().optional(),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const updateTodoInput = z.object({
|
|
22
|
+
id: z.string(),
|
|
23
|
+
data: UpdateTodoDto.schema,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
@Router({ alias: "todoRouter" })
|
|
27
|
+
export class TodoRouter {
|
|
28
|
+
constructor(private readonly todoService: TodoService) {}
|
|
29
|
+
|
|
30
|
+
{{#if hasTrpcAndAuth}}
|
|
31
|
+
@Query({ output: z.array(todoSchema) })
|
|
32
|
+
@UseMiddlewares(AuthTRPCMiddleware)
|
|
33
|
+
findAll(@Ctx() ctx: InnerContext) {
|
|
34
|
+
return this.todoService.findAll(ctx.session!.user.id);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Mutation({ input: CreateTodoDto.schema, output: todoSchema })
|
|
38
|
+
@UseMiddlewares(AuthTRPCMiddleware)
|
|
39
|
+
create(@Ctx() ctx: InnerContext, @Input() input: CreateTodoDto) {
|
|
40
|
+
return this.todoService.create(input, ctx.session!.user.id);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@Mutation({ input: updateTodoInput, output: todoSchema })
|
|
44
|
+
@UseMiddlewares(AuthTRPCMiddleware)
|
|
45
|
+
update(@Ctx() ctx: InnerContext, @Input() input: { id: string; data: UpdateTodoDto }) {
|
|
46
|
+
return this.todoService.update(input.id, input.data, ctx.session!.user.id);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@Mutation({ input: z.object({ id: z.string() }) })
|
|
50
|
+
@UseMiddlewares(AuthTRPCMiddleware)
|
|
51
|
+
delete(@Ctx() ctx: InnerContext, @Input() input: { id: string }) {
|
|
52
|
+
return this.todoService.delete(input.id, ctx.session!.user.id);
|
|
53
|
+
}
|
|
54
|
+
{{else}}
|
|
55
|
+
@Query({ output: z.array(todoSchema) })
|
|
56
|
+
findAll() {
|
|
57
|
+
return this.todoService.findAll();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@Mutation({ input: CreateTodoDto.schema, output: todoSchema })
|
|
61
|
+
create(@Input() input: CreateTodoDto) {
|
|
62
|
+
return this.todoService.create(input);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@Mutation({ input: updateTodoInput, output: todoSchema })
|
|
66
|
+
update(@Input() input: { id: string; data: UpdateTodoDto }) {
|
|
67
|
+
return this.todoService.update(input.id, input.data);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@Mutation({ input: z.object({ id: z.string() }) })
|
|
71
|
+
delete(@Input() input: { id: string }) {
|
|
72
|
+
return this.todoService.delete(input.id);
|
|
73
|
+
}
|
|
74
|
+
{{/if}}
|
|
75
|
+
}
|
|
76
|
+
{{/if}}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { Injectable } from "@nestjs/common";
|
|
2
|
+
{{#if hasDatabase}}
|
|
3
|
+
{{#if isMonorepo}}
|
|
4
|
+
import { DbService } from "@repo/db";
|
|
5
|
+
{{else}}
|
|
6
|
+
import { DbService } from "../../database/db.service.js";
|
|
7
|
+
{{/if}}
|
|
8
|
+
{{#if useDrizzle}}
|
|
9
|
+
import * as schema from "../../database/orm/drizzle/schema.js";
|
|
10
|
+
import { eq } from "drizzle-orm";
|
|
11
|
+
{{/if}}
|
|
12
|
+
{{#if useTypeorm}}
|
|
13
|
+
import { Todo } from "../../database/entities/todo.entity.js";
|
|
14
|
+
{{/if}}
|
|
15
|
+
{{/if}}
|
|
16
|
+
import { CreateTodoDto } from "./dto/create-todo.dto.js";
|
|
17
|
+
import { UpdateTodoDto } from "./dto/update-todo.dto.js";
|
|
18
|
+
|
|
19
|
+
@Injectable()
|
|
20
|
+
export class TodoService {
|
|
21
|
+
{{#if hasDatabase}}
|
|
22
|
+
constructor(private readonly db: DbService) {}
|
|
23
|
+
{{else}}
|
|
24
|
+
private todos: Array<{
|
|
25
|
+
completed: boolean;
|
|
26
|
+
description?: string;
|
|
27
|
+
id: string;
|
|
28
|
+
title: string;
|
|
29
|
+
}> = [];
|
|
30
|
+
private nextId = 1;
|
|
31
|
+
{{/if}}
|
|
32
|
+
|
|
33
|
+
{{#if hasDatabase}}
|
|
34
|
+
{{#if hasAuth}}
|
|
35
|
+
findAll(authorId: string) {
|
|
36
|
+
{{#if usePrisma}}
|
|
37
|
+
return this.db.prisma.todo.findMany({ where: { authorId } });
|
|
38
|
+
{{else if useTypeorm}}
|
|
39
|
+
return this.db.getRepository(Todo).find({ where: { authorId } });
|
|
40
|
+
{{else if useDrizzle}}
|
|
41
|
+
return this.db.select().from(schema.todos).where(eq(schema.todos.authorId, authorId));
|
|
42
|
+
{{/if}}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
create(input: CreateTodoDto, authorId: string) {
|
|
46
|
+
{{#if usePrisma}}
|
|
47
|
+
return this.db.prisma.todo.create({ data: { ...input, authorId } });
|
|
48
|
+
{{else if useTypeorm}}
|
|
49
|
+
return this.db.getRepository(Todo).save(this.db.getRepository(Todo).create({ ...input, authorId }));
|
|
50
|
+
{{else if useDrizzle}}
|
|
51
|
+
return this.db.insert(schema.todos).values({ ...input, authorId }).returning();
|
|
52
|
+
{{/if}}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
update(id: string, input: UpdateTodoDto, authorId: string) {
|
|
56
|
+
{{#if usePrisma}}
|
|
57
|
+
return this.db.prisma.todo.update({ data: input, where: { authorId, id } });
|
|
58
|
+
{{else if useTypeorm}}
|
|
59
|
+
return this.db.getRepository(Todo).update({ authorId, id }, input);
|
|
60
|
+
{{else if useDrizzle}}
|
|
61
|
+
return this.db.update(schema.todos).set(input).where(eq(schema.todos.authorId, authorId) && eq(schema.todos.id, id)).returning();
|
|
62
|
+
{{/if}}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async delete(id: string, authorId: string) {
|
|
66
|
+
{{#if usePrisma}}
|
|
67
|
+
await this.db.prisma.todo.delete({ where: { authorId, id } });
|
|
68
|
+
{{else if useTypeorm}}
|
|
69
|
+
await this.db.getRepository(Todo).delete({ authorId, id });
|
|
70
|
+
{{else if useDrizzle}}
|
|
71
|
+
await this.db.delete(schema.todos).where(eq(schema.todos.authorId, authorId) && eq(schema.todos.id, id));
|
|
72
|
+
{{/if}}
|
|
73
|
+
return { message: "Todo deleted successfully" };
|
|
74
|
+
}
|
|
75
|
+
{{else}}
|
|
76
|
+
findAll() {
|
|
77
|
+
{{#if usePrisma}}
|
|
78
|
+
return this.db.prisma.todo.findMany();
|
|
79
|
+
{{else if useTypeorm}}
|
|
80
|
+
return this.db.getRepository(Todo).find();
|
|
81
|
+
{{else if useDrizzle}}
|
|
82
|
+
return this.db.select().from(schema.todos);
|
|
83
|
+
{{/if}}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
create(input: CreateTodoDto) {
|
|
87
|
+
{{#if usePrisma}}
|
|
88
|
+
return this.db.prisma.todo.create({ data: input });
|
|
89
|
+
{{else if useTypeorm}}
|
|
90
|
+
return this.db.getRepository(Todo).save(this.db.getRepository(Todo).create(input));
|
|
91
|
+
{{else if useDrizzle}}
|
|
92
|
+
return this.db.insert(schema.todos).values(input).returning();
|
|
93
|
+
{{/if}}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
update(id: string, input: UpdateTodoDto) {
|
|
97
|
+
{{#if usePrisma}}
|
|
98
|
+
return this.db.prisma.todo.update({ data: input, where: { id } });
|
|
99
|
+
{{else if useTypeorm}}
|
|
100
|
+
return this.db.getRepository(Todo).update(id, input);
|
|
101
|
+
{{else if useDrizzle}}
|
|
102
|
+
return this.db.update(schema.todos).set(input).where(eq(schema.todos.id, id)).returning();
|
|
103
|
+
{{/if}}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async delete(id: string) {
|
|
107
|
+
{{#if usePrisma}}
|
|
108
|
+
await this.db.prisma.todo.delete({ where: { id } });
|
|
109
|
+
{{else if useTypeorm}}
|
|
110
|
+
await this.db.getRepository(Todo).delete(id);
|
|
111
|
+
{{else if useDrizzle}}
|
|
112
|
+
await this.db.delete(schema.todos).where(eq(schema.todos.id, id));
|
|
113
|
+
{{/if}}
|
|
114
|
+
return { message: "Todo deleted successfully" };
|
|
115
|
+
}
|
|
116
|
+
{{/if}}
|
|
117
|
+
{{else}}
|
|
118
|
+
findAll() {
|
|
119
|
+
return [...this.todos];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
create(input: CreateTodoDto) {
|
|
123
|
+
const todo = { id: String(this.nextId++), ...input };
|
|
124
|
+
this.todos.push(todo);
|
|
125
|
+
return todo;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
update(id: string, input: UpdateTodoDto) {
|
|
129
|
+
const todo = this.todos.find((t) => t.id === id);
|
|
130
|
+
if (!todo) {
|
|
131
|
+
return { message: "Todo not found" };
|
|
132
|
+
}
|
|
133
|
+
Object.assign(todo, input);
|
|
134
|
+
return todo;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async delete(id: string) {
|
|
138
|
+
const index = this.todos.findIndex((t) => t.id === id);
|
|
139
|
+
if (index >= 0) {
|
|
140
|
+
this.todos.splice(index, 1);
|
|
141
|
+
}
|
|
142
|
+
return { message: "Todo deleted successfully" };
|
|
143
|
+
}
|
|
144
|
+
{{/if}}
|
|
145
|
+
}
|