@nest-arch/tui 0.2.7 → 0.4.0

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 (71) hide show
  1. package/README.md +20 -42
  2. package/dist/cli.js +1 -1
  3. package/dist/constants-C3xmDWeK.js +1 -0
  4. package/dist/index.js +295 -82
  5. package/dist/templates/base/.env.example.hbs +4 -2
  6. package/dist/templates/base/.env.hbs +4 -2
  7. package/dist/templates/base/.gitignore.hbs +2 -1
  8. package/dist/templates/base/.yarnrc.yml.hbs +0 -5
  9. package/dist/templates/base/README.md.hbs +33 -5
  10. package/dist/templates/base/nest-cli.json.hbs +2 -1
  11. package/dist/templates/base/pnpm-workspace.yaml.hbs +9 -0
  12. package/dist/templates/base/prisma.config.ts.hbs +32 -6
  13. package/dist/templates/base/src/app.controller.spec.ts.hbs +3 -11
  14. package/dist/templates/base/src/app.controller.ts.hbs +2 -2
  15. package/dist/templates/base/src/app.module.ts.hbs +19 -1
  16. package/dist/templates/base/src/app.router.ts.hbs +2 -2
  17. package/dist/templates/base/src/database/adapters/interfaces/db-adapter.interface.ts.hbs +7 -0
  18. package/dist/templates/base/src/database/adapters/mongo/prisma-mongo.adapter.ts.hbs +25 -1
  19. package/dist/templates/base/src/database/adapters/mongo/raw-mongo.adapter.ts.hbs +17 -12
  20. package/dist/templates/base/src/database/adapters/sql/drizzle-sql.adapter.ts.hbs +9 -0
  21. package/dist/templates/base/src/database/adapters/sql/prisma-sql.adapter.ts.hbs +7 -4
  22. package/dist/templates/base/src/database/adapters/sql/raw-sql.adapter.ts.hbs +37 -0
  23. package/dist/templates/base/src/database/adapters/sql/typeorm-sql.adapter.ts.hbs +8 -3
  24. package/dist/templates/base/src/database/db.module.ts.hbs +32 -35
  25. package/dist/templates/base/src/database/db.service.ts.hbs +40 -6
  26. package/dist/templates/base/src/database/entities/todo.entity.ts.hbs +12 -7
  27. package/dist/templates/base/src/database/index.ts.hbs +1 -0
  28. package/dist/templates/base/src/database/orm/drizzle/schema.ts.hbs +47 -5
  29. package/dist/templates/base/src/database/orm/typeorm/data-source.ts.hbs +12 -4
  30. package/dist/templates/base/src/libs/trpc/error.handler.ts.hbs +1 -1
  31. package/dist/templates/base/src/main.ts.hbs +21 -6
  32. package/dist/templates/base/test/app.e2e-spec.ts.hbs +208 -6
  33. package/dist/templates/base/test/bootstrap.e2e-spec.ts.hbs +74 -0
  34. package/dist/templates/base/tsconfig.build.json.hbs +2 -0
  35. package/dist/templates/base/tsconfig.json.hbs +1 -1
  36. package/dist/templates/base/vitest.config.e2e.ts.hbs +4 -3
  37. package/dist/templates/base/vitest.config.ts.hbs +4 -3
  38. package/dist/templates/base/yarn.lock.hbs +1 -0
  39. package/dist/templates/extras/docker/Dockerfile.hbs +4 -1
  40. package/dist/templates/extras/swagger/create-docs.ts.hbs +47 -119
  41. package/dist/templates/feature/graphql/src/graphql/graphql.module.ts.hbs +8 -1
  42. package/dist/templates/feature/graphql/src/graphql/models/todo.model.ts.hbs +4 -0
  43. package/dist/templates/feature/graphql/src/graphql/orm/drizzle/drizzle-graphql.module.ts.hbs +4 -3
  44. package/dist/templates/feature/graphql/src/graphql/resolvers/todo.resolver.ts.hbs +69 -24
  45. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.controller.ts.hbs +3 -1
  46. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.module.ts.hbs +1 -3
  47. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.service.ts.hbs +98 -32
  48. package/dist/templates/monorepo/apps/api-gateway/package.json.hbs +0 -1
  49. package/dist/templates/monorepo/apps/api-gateway/src/app.controller.spec.ts.hbs +1 -1
  50. package/dist/templates/monorepo/apps/api-gateway/test/app.e2e-spec.ts.hbs +20 -1
  51. package/dist/templates/monorepo/apps/api-gateway/tsconfig.build.json.hbs +2 -1
  52. package/dist/templates/monorepo/apps/api-gateway/vitest.config.e2e.ts.hbs +3 -2
  53. package/dist/templates/monorepo/apps/api-gateway/vitest.config.ts.hbs +3 -2
  54. package/dist/templates/monorepo/feature/graphql/src/graphql/resolvers/todo.resolver.ts.hbs +24 -21
  55. package/dist/templates/monorepo/packages/env/src/api-gateway.ts.hbs +9 -3
  56. package/dist/templates/monorepo/root/.gitignore.hbs +1 -0
  57. package/dist/templates/monorepo/root/pnpm-workspace.yaml.hbs +9 -0
  58. package/dist/templates/monorepo/root/tsconfig.json.hbs +1 -1
  59. package/dist/templates/monorepo/root/turbo.json.hbs +2 -0
  60. package/dist/templates/single-project/architecture/nest-api/.env.hbs +3 -1
  61. package/dist/templates/single-project/architecture/nest-api/package.json.hbs +0 -1
  62. package/dist/templates/single-project/architecture/nest-api/src/main.ts.hbs +20 -5
  63. package/dist/templates/single-project/architecture/nest-microservice/.env.hbs +18 -0
  64. package/dist/templates/single-project/architecture/nest-microservice/proto/app.proto.hbs +13 -0
  65. package/dist/templates/single-project/architecture/nest-microservice/src/app.controller.ts.hbs +14 -1
  66. package/dist/templates/single-project/architecture/nest-microservice/src/app.service.ts.hbs +4 -0
  67. package/dist/templates/single-project/architecture/nest-microservice/src/main.ts.hbs +13 -2
  68. package/dist/templates/single-project/architecture/nest-microservice/test/microservice.e2e-spec.ts.hbs +64 -0
  69. package/dist/templates/single-project/shared/config/env.ts.hbs +27 -3
  70. package/package.json +7 -4
  71. package/dist/constants-Cgtoxhmd.js +0 -1
@@ -1,11 +1,12 @@
1
1
  import { defineConfig } from "vitest/config";
2
- import tsconfigPaths from "vite-tsconfig-paths";
3
2
 
4
3
  export default defineConfig({
5
- plugins: [tsconfigPaths()],
4
+ resolve: {
5
+ tsconfigPaths: true,
6
+ },
6
7
  test: {
8
+ include: ["**/*.spec.ts"],
7
9
  globals: true,
8
10
  root: "./",
9
- include: ["**/*.spec.ts"],
10
11
  },
11
12
  });
@@ -0,0 +1 @@
1
+ # This lockfile marks the generated application as an independent Yarn project.
@@ -18,5 +18,8 @@ COPY . .
18
18
  RUN {{packageManager}} run build
19
19
 
20
20
  EXPOSE 3000
21
+ {{#if (includes microservices "grpc")}}
22
+ EXPOSE 5000
23
+ {{/if}}
21
24
 
22
- CMD ["{{packageManager}}", "run", "start:prod"]
25
+ CMD ["{{packageManager}}", "run", "start:prod"]
@@ -1,18 +1,7 @@
1
- // @ts-nocheck
2
- /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, import/no-unresolved */
3
- /* oxlint-disable import/no-unresolved */
4
- // oxlint-disable no-unused-vars
5
1
 
6
2
  import type { INestApplication } from "@nestjs/common";
7
- {{#if hasRest}}
8
- import {
9
- DocumentBuilder,
10
- SwaggerModule,
11
- type OpenAPIObject,
12
- } from "@nestjs/swagger";
13
- {{else}}
3
+ import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
14
4
  import type { OpenAPIObject } from "@nestjs/swagger";
15
- {{/if}}
16
5
 
17
6
  interface DocsIntegrations {
18
7
  betterAuth?: {
@@ -40,65 +29,16 @@ export interface CreateDocsOptions {
40
29
  integrations?: DocsIntegrations;
41
30
  }
42
31
 
43
- function rewriteRefs(value: unknown): unknown {
44
- if (Array.isArray(value)) {
45
- return value.map((item) => rewriteRefs(item));
46
- }
47
- if (!value || typeof value !== "object") {
48
- return value;
49
- }
50
- const obj = value as Record<string, unknown>;
51
- if (typeof obj.$ref === "string") {
52
- const rest = rewriteRefs(
53
- Object.fromEntries(Object.entries(obj).filter(([k]) => k !== "$ref"))
54
- ) as Record<string, unknown>;
55
- return {
56
- ...rest,
57
- $ref: (obj.$ref as string)
58
- .replace("#/$defs/", "#/components/schemas/")
59
- .replace("#/definitions/", "#/components/schemas/"),
60
- };
61
- }
62
- return Object.fromEntries(
63
- Object.entries(obj).map(([k, v]) => [k, rewriteRefs(v)])
64
- );
65
- }
66
-
67
- function normalizeSchema(
68
- schema: unknown,
69
- components: Record<string, unknown> = {}
70
- ): ReturnType<StandardSchemaConverter> {
71
- const raw = (
72
- typeof schema === "object" && schema !== null ? schema : {}
73
- ) as Record<string, unknown>;
74
- const normalizedComponents = Object.fromEntries(
75
- Object.entries(raw.$defs ?? {}).map(([name, def]) => [
76
- name,
77
- rewriteRefs(def),
78
- ])
79
- );
80
- const filtered: Record<string, unknown> = {};
81
- for (const key of Object.keys(raw)) {
82
- if (key !== "$defs" && key !== "definitions" && key !== "$schema") {
83
- filtered[key] = raw[key];
84
- }
85
- }
86
- return {
87
- components: {
88
- ...components,
89
- ...normalizedComponents,
90
- },
91
- schema: rewriteRefs(filtered),
92
- };
93
- }
94
-
95
32
  function addPrefixToPaths(paths: Record<string, unknown>, prefix: string) {
96
33
  return Object.fromEntries(
97
34
  Object.entries(paths).map(([path, value]) => [`${prefix}${path}`, value])
98
35
  );
99
36
  }
100
37
 
101
- function mergeOpenApiSpecs(baseSpec: OpenAPIObject, ...extraSpecs: OpenAPIObject[]) {
38
+ function mergeOpenApiSpecs(
39
+ baseSpec: OpenAPIObject,
40
+ ...extraSpecs: OpenAPIObject[]
41
+ ) {
102
42
  const specs = [baseSpec, ...extraSpecs];
103
43
 
104
44
  return {
@@ -131,6 +71,29 @@ function mergeOpenApiSpecs(baseSpec: OpenAPIObject, ...extraSpecs: OpenAPIObject
131
71
  } as OpenAPIObject;
132
72
  }
133
73
 
74
+ async function applyZodCleanup(
75
+ baseSpec: OpenAPIObject,
76
+ options?: NonNullable<DocsIntegrations["zod"]>
77
+ ) {
78
+ try {
79
+ const packageName = "nestjs-zod";
80
+ const { cleanupOpenApiDoc } = await import(packageName);
81
+ if (typeof cleanupOpenApiDoc !== "function") {
82
+ return baseSpec;
83
+ }
84
+
85
+ if (options?.withFastify === true) {
86
+ return cleanupOpenApiDoc(baseSpec, {
87
+ withFastify: true,
88
+ }) as OpenAPIObject;
89
+ }
90
+
91
+ return cleanupOpenApiDoc(baseSpec) as OpenAPIObject;
92
+ } catch {
93
+ return baseSpec;
94
+ }
95
+ }
96
+
134
97
  async function applyBetterAuthSpec(
135
98
  options?: NonNullable<DocsIntegrations["betterAuth"]>
136
99
  ) {
@@ -145,7 +108,9 @@ async function applyBetterAuthSpec(
145
108
  generateOpenAPISchema?: () => OpenAPIObject | Promise<OpenAPIObject>;
146
109
  };
147
110
 
148
- const schemaGenerator = authInstance.api?.generateOpenAPISchema ?? authInstance.generateOpenAPISchema;
111
+ const schemaGenerator =
112
+ authInstance.api?.generateOpenAPISchema ??
113
+ authInstance.generateOpenAPISchema;
149
114
 
150
115
  if (typeof schemaGenerator !== "function") {
151
116
  return null;
@@ -169,29 +134,27 @@ async function applyBetterAuthSpec(
169
134
  }
170
135
  }
171
136
 
172
- async function applyTrpcSpec(
173
- options?: NonNullable<DocsIntegrations["trpc"]>
174
- ) {
137
+ async function applyTrpcSpec(options?: NonNullable<DocsIntegrations["trpc"]>) {
175
138
  if (!options?.routerFilePath) {
176
139
  return null;
177
140
  }
178
141
 
179
142
  try {
180
- const specifier = "@trpc/openapi" as string;
181
- const mod: Record<string, unknown> = await import(specifier);
182
- const generateOpenAPIDocument = mod.generateOpenAPIDocument as
183
- | ((opts: unknown, config: unknown) => unknown)
184
- | undefined;
143
+ const packageName = "@trpc/openapi";
144
+ const { generateOpenAPIDocument } = await import(packageName);
185
145
 
186
146
  if (typeof generateOpenAPIDocument !== "function") {
187
147
  return null;
188
148
  }
189
149
 
190
- const generatedDocument = await generateOpenAPIDocument(options.routerFilePath, {
191
- exportName: options.exportName ?? "AppRouter",
192
- title: options.title ?? "tRPC API",
193
- version: options.version ?? "1.0.0",
194
- });
150
+ const generatedDocument = await generateOpenAPIDocument(
151
+ options.routerFilePath,
152
+ {
153
+ exportName: options.exportName ?? "AppRouter",
154
+ title: options.title ?? "tRPC API",
155
+ version: options.version ?? "1.0.0",
156
+ }
157
+ );
195
158
 
196
159
  const trpcSpec = generatedDocument as OpenAPIObject;
197
160
  const prefix = options.pathPrefix ?? "/trpc";
@@ -208,53 +171,19 @@ async function applyTrpcSpec(
208
171
  return null;
209
172
  }
210
173
  }
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
- }
223
174
 
224
175
  export async function createDocs(
225
176
  app: INestApplication,
226
177
  options: CreateDocsOptions = {}
227
178
  ): Promise<OpenAPIObject> {
228
- {{#if (or hasRest hasAuth)}}
229
179
  const config = new DocumentBuilder()
230
180
  .setTitle(options.title ?? "NestJS API")
231
181
  .setDescription(options.description ?? "Generated with Nest Arch")
232
182
  .setVersion(options.version ?? "1.0.0")
233
183
  .build();
234
184
 
235
- const standardSchemaConverter: StandardSchemaConverter = (
236
- schema,
237
- { schemaType }
238
- ) => {
239
- const standard = (schema as Record<string, unknown> | undefined)?.[
240
- "~standard"
241
- ] as Record<string, unknown> | undefined;
242
- const convert = standard?.jsonSchema?.[schemaType] as
243
- | ((opts: { target: string }) => unknown)
244
- | undefined;
245
- if (!convert) {
246
- return;
247
- }
248
- const converted = convert({ target: "openapi-3.0" });
249
- if (!converted || typeof converted !== "object") {
250
- return;
251
- }
252
- return normalizeSchema(converted);
253
- };
254
-
255
- let baseSpec = SwaggerModule.createDocument(app, config, {
256
- standardSchemaConverter,
257
- }) as OpenAPIObject;
185
+ let baseSpec = SwaggerModule.createDocument(app, config) as OpenAPIObject;
186
+ baseSpec = await applyZodCleanup(baseSpec, options.integrations?.zod);
258
187
 
259
188
  if (!baseSpec.paths || Object.keys(baseSpec.paths).length === 0) {
260
189
  baseSpec = {
@@ -268,13 +197,12 @@ export async function createDocs(
268
197
  tags: [],
269
198
  } as OpenAPIObject;
270
199
  }
271
- {{else}}
272
- const baseSpec = createEmptyBaseSpec(options);
273
- {{/if}}
274
200
 
275
201
  const additionalSpecs: OpenAPIObject[] = [];
276
202
 
277
- const betterAuthSpec = await applyBetterAuthSpec(options.integrations?.betterAuth);
203
+ const betterAuthSpec = await applyBetterAuthSpec(
204
+ options.integrations?.betterAuth
205
+ );
278
206
  if (betterAuthSpec) {
279
207
  additionalSpecs.push(betterAuthSpec);
280
208
  }
@@ -1,5 +1,5 @@
1
1
  import { Module } from "@nestjs/common";
2
- import { GraphQLModule } from "@nestjs/graphql";
2
+ import { Query, Resolver, GraphQLModule } from "@nestjs/graphql";
3
3
  import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo";
4
4
  import { join } from "path";
5
5
  import { env } from "../config/env.js";
@@ -12,6 +12,12 @@ import { env } from "../config/env.js";
12
12
  import { TodoResolver } from "./resolvers/todo.resolver.js";
13
13
  {{/if}}
14
14
 
15
+ @Resolver()
16
+ class HealthResolver {
17
+ @Query(() => String)
18
+ hello(): string { return "Hello GraphQL!"; }
19
+ }
20
+
15
21
  @Module({
16
22
  imports: [
17
23
  GraphQLModule.forRoot<ApolloDriverConfig>({
@@ -25,6 +31,7 @@ import { TodoResolver } from "./resolvers/todo.resolver.js";
25
31
  }),
26
32
  ],
27
33
  providers: [
34
+ HealthResolver,
28
35
  {{#if hasTodoExample}}
29
36
  TodoResolver,
30
37
  {{/if}}
@@ -1,8 +1,10 @@
1
1
  import { Field, ID, ObjectType } from "@nestjs/graphql";
2
2
 
3
3
  import { BaseModel } from "./base.model.js";
4
+ {{#if hasAuth}}
4
5
  // oxlint-disable-next-line import/no-cycle
5
6
  import { User } from "./user.model.js";
7
+ {{/if}}
6
8
 
7
9
  @ObjectType()
8
10
  export class Todo extends BaseModel {
@@ -15,9 +17,11 @@ export class Todo extends BaseModel {
15
17
  @Field()
16
18
  completed: boolean;
17
19
 
20
+ {{#if hasAuth}}
18
21
  @Field(() => ID, { nullable: true })
19
22
  authorId: string | null;
20
23
 
21
24
  @Field(() => User, { nullable: true })
22
25
  author: User | null;
26
+ {{/if}}
23
27
  }
@@ -3,6 +3,7 @@ import { buildSchema } from "drizzle-graphql";
3
3
  {{#if isMonorepo}}
4
4
  import { db } from "@repo/db";
5
5
  {{else}}
6
+ import { env } from "../../../config/env.js";
6
7
  {{#if hasPostgres}}
7
8
  import { drizzle } from "drizzle-orm/node-postgres";
8
9
  import { Pool } from "pg";
@@ -20,13 +21,13 @@ import * as dbSchema from "../database/orm/drizzle/schema.js";
20
21
 
21
22
  const schema = buildSchema({{#if isMonorepo}}db{{else}}
22
23
  {{#if hasPostgres}}
23
- drizzle(new Pool({ connectionString: process.env.DATABASE_URL }), { schema: dbSchema })
24
+ drizzle(new Pool({ connectionString: env.POSTGRES_URL }), { schema: dbSchema })
24
25
  {{/if}}
25
26
  {{#if hasMysql}}
26
- drizzle(mysql.createPool(process.env.DATABASE_URL), { schema: dbSchema })
27
+ drizzle(mysql.createPool(env.MYSQL_URL), { schema: dbSchema })
27
28
  {{/if}}
28
29
  {{#if hasSqlite}}
29
- drizzle(new Database(process.env.DATABASE_URL), { schema: dbSchema })
30
+ drizzle(new Database(env.SQLITE_PATH), { schema: dbSchema })
30
31
  {{/if}}
31
32
  {{/if}});
32
33
 
@@ -1,28 +1,70 @@
1
+ {{#if (and usePrisma (eq auth "none"))}}
2
+ import { BadRequestException, NotFoundException } from "@nestjs/common";
3
+ import { Args, Mutation, Query, Resolver } from "@nestjs/graphql";
4
+ import { DbService } from "../../database/db.service.js";
5
+ import { CreateTodoInput } from "../dto/create-todo.input.js";
6
+ import { UpdateTodoInput } from "../dto/update-todo.input.js";
7
+ import { Todo } from "../models/todo.model.js";
8
+
9
+ @Resolver(() => Todo)
10
+ export class TodoResolver {
11
+ constructor(private readonly db: DbService) {}
12
+
13
+ @Query(() => [Todo])
14
+ todos() {
15
+ return this.db.prisma.todo.findMany({ orderBy: { createdAt: "asc" }, take: 100 });
16
+ }
17
+
18
+ @Mutation(() => Todo)
19
+ createTodo(@Args("input") input: CreateTodoInput) {
20
+ if (!input.title.trim()) throw new BadRequestException("Title must not be empty");
21
+ return this.db.prisma.todo.create({ data: input });
22
+ }
23
+
24
+ @Mutation(() => Todo)
25
+ async updateTodo(@Args("input") input: UpdateTodoInput) {
26
+ const { id, ...data } = input;
27
+ if (data.title !== undefined && !data.title.trim()) throw new BadRequestException("Title must not be empty");
28
+ const result = await this.db.prisma.todo.updateManyAndReturn({ where: { id }, data });
29
+ if (!result[0]) throw new NotFoundException("Todo not found");
30
+ return result[0];
31
+ }
32
+
33
+ @Mutation(() => Boolean)
34
+ async deleteTodo(@Args("id") id: string): Promise<boolean> {
35
+ const result = await this.db.prisma.todo.deleteMany({ where: { id } });
36
+ if (result.count === 0) throw new NotFoundException("Todo not found");
37
+ return true;
38
+ }
39
+ }
40
+ {{else}}
1
41
  {{#if (and hasAuth hasDatabase)}}
2
42
  import { UseGuards } from "@nestjs/common";
3
43
  {{/if}}
4
44
  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";
45
+ {{#if (and hasAuth hasDatabase)}}
46
+ import { UserEntity } from "../../auth/decorators/index.js";
47
+ import { GqlAuthGuard } from "../../auth/guards/gql-auth.guard.js";
48
+ {{/if}}
7
49
  {{#if isMonorepo}}
8
50
  import { DbService } from "@repo/db";
9
51
  {{else}}
10
- import { DbService } from "../database/db.service.js";
52
+ import { DbService } from "../../database/db.service.js";
11
53
  {{/if}}
54
+ import { CreateTodoInput } from "../dto/create-todo.input.js";
55
+ import { UpdateTodoInput } from "../dto/update-todo.input.js";
12
56
  {{#if useTypeorm}}
13
57
  import { GraphRelationBuilder } from "typeorm-relations-graphql";
14
58
  import { GraphQLResolveInfo } from "graphql";
15
59
  {{/if}}
16
60
  {{#if useDrizzle}}
17
- import * as schema from "../database/orm/drizzle/schema.js";
61
+ import * as schema from "../../database/orm/drizzle/schema.js";
18
62
  {{/if}}
19
63
  {{#if (and hasAuth hasDatabase)}}
20
64
  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
65
  {{/if}}
24
66
 
25
- @Resolver({{#if (and hasAuth hasDatabase)}}{{"("}}() => Todo){{/if}})
67
+ @Resolver(() => Todo)
26
68
  export class TodoResolver {
27
69
  constructor(private readonly db: DbService) {}
28
70
 
@@ -32,11 +74,13 @@ export class TodoResolver {
32
74
  }{{#if hasDatabase}}
33
75
 
34
76
  @Query(() => [Todo])
35
- todos({{#if useTypeorm}}info: GraphQLResolveInfo{{/if}}): Promise<Todo[]> {
77
+ todos({{#if useTypeorm}}info: GraphQLResolveInfo{{/if}}) {
36
78
  {{#if useTypeorm}}
37
79
  const builder = new GraphRelationBuilder(this.db.getDataSource());
38
80
  const relations = builder.buildForQuery(Todo, info, "todos");
39
81
  return this.db.getRepository(Todo).find({ relations });
82
+ {{else if isPrisma8}}
83
+ return ((this.db.prisma.orm.public as any).Todo).all();
40
84
  {{else if usePrisma}}
41
85
  return this.db.prisma.todo.findMany();
42
86
  {{else if useDrizzle}}
@@ -46,14 +90,12 @@ export class TodoResolver {
46
90
  {{/if}}
47
91
  }
48
92
 
49
- @Mutation(() => Todo)
50
- {{#if (and hasAuth hasDatabase)}}
51
93
  @UseGuards(GqlAuthGuard)
52
- {{/if}}
94
+ @Mutation(() => Todo)
53
95
  createTodo(
54
- @Args("input") input: CreateTodoInput{{#if (and hasAuth hasDatabase)}},
55
- @UserEntity() user: { id: string }{{/if}}{{#if useTypeorm}}, info: GraphQLResolveInfo{{/if}}
56
- ): Promise<Todo> {
96
+ @UserEntity() user: { id: string },
97
+ @Args("input") input: CreateTodoInput{{#if useTypeorm}}, info: GraphQLResolveInfo{{/if}}
98
+ ) {
57
99
  {{#if useTypeorm}}
58
100
  const entity = this.db.getRepository(Todo).create(input);
59
101
  const saved = await this.db.getRepository(Todo).save(entity);
@@ -63,9 +105,11 @@ export class TodoResolver {
63
105
  where: { id: saved.id },
64
106
  relations,
65
107
  });
108
+ {{else if isPrisma8}}
109
+ return ((this.db.prisma.orm.public as any).Todo).create({ ...input, authorId: user.id });
66
110
  {{else if usePrisma}}
67
111
  return this.db.prisma.todo.create({
68
- data: { ...input{{#if (and hasAuth hasDatabase)}}, authorId: user.id{{/if}} },
112
+ data: { ...input, authorId: user.id },
69
113
  });
70
114
  {{else if useDrizzle}}
71
115
  const [todo] = await this.db.insert(schema.todos).values(input).returning();
@@ -75,13 +119,9 @@ export class TodoResolver {
75
119
  {{/if}}
76
120
  }
77
121
 
78
- @Mutation(() => Todo)
79
- {{#if (and hasAuth hasDatabase)}}
80
122
  @UseGuards(GqlAuthGuard)
81
- {{/if}}
82
- updateTodo(
83
- @Args("input") input: UpdateTodoInput{{#if useTypeorm}}, info: GraphQLResolveInfo{{/if}}
84
- ): Promise<Todo> {
123
+ @Mutation(() => Todo)
124
+ updateTodo(@Args("input") input: UpdateTodoInput{{#if useTypeorm}}, info: GraphQLResolveInfo{{/if}}) {
85
125
  const { id, ...data } = input;
86
126
  {{#if useTypeorm}}
87
127
  await this.db.getRepository(Todo).update(id, data);
@@ -91,6 +131,8 @@ export class TodoResolver {
91
131
  where: { id },
92
132
  relations,
93
133
  });
134
+ {{else if isPrisma8}}
135
+ return ((this.db.prisma.orm.public as any).Todo).where({ id }).update(data);
94
136
  {{else if usePrisma}}
95
137
  return this.db.prisma.todo.update({ where: { id }, data });
96
138
  {{else if useDrizzle}}
@@ -105,14 +147,15 @@ export class TodoResolver {
105
147
  {{/if}}
106
148
  }
107
149
 
108
- @Mutation(() => Boolean)
109
- {{#if (and hasAuth hasDatabase)}}
110
150
  @UseGuards(GqlAuthGuard)
111
- {{/if}}
151
+ @Mutation(() => Boolean)
112
152
  async deleteTodo(@Args("id") id: string): Promise<boolean> {
113
153
  {{#if useTypeorm}}
114
154
  const result = await this.db.getRepository(Todo).delete(id);
115
155
  return (result.affected ?? 0) > 0;
156
+ {{else if isPrisma8}}
157
+ await ((this.db.prisma.orm.public as any).Todo).where({ id }).delete();
158
+ return true;
116
159
  {{else if usePrisma}}
117
160
  await this.db.prisma.todo.delete({ where: { id } });
118
161
  return true;
@@ -124,3 +167,5 @@ export class TodoResolver {
124
167
  {{/if}}
125
168
  }{{/if}}
126
169
  }
170
+
171
+ {{/if}}
@@ -16,7 +16,9 @@ import {
16
16
  ApiOkResponse,
17
17
  ApiOperation,
18
18
  ApiTags,
19
+ {{#if (or isPassportAuth isBetterAuth)}}
19
20
  ApiUnauthorizedResponse,
21
+ {{/if}}
20
22
  } from "@nestjs/swagger";
21
23
  {{/if}}
22
24
  {{#if isPassportAuth}}
@@ -164,7 +166,7 @@ export class TodoController {
164
166
  return this.todoService.delete(id, session.user.id);
165
167
  }
166
168
  {{else}}
167
- async delete(@Param("id") id: string) {
169
+ delete(@Param("id") id: string) {
168
170
  return this.todoService.delete(id);
169
171
  }
170
172
  {{/if}}
@@ -11,14 +11,12 @@ import { TodoRouter } from "./todo.router.js";
11
11
  {{#if hasRest}}
12
12
  controllers: [TodoController],
13
13
  {{/if}}
14
+ exports: [TodoService],
14
15
  providers: [
15
16
  TodoService,
16
17
  {{#unless hasRest}}
17
18
  TodoRouter,
18
19
  {{/unless}}
19
20
  ],
20
- {{#if hasRest}}
21
- exports: [TodoService],
22
- {{/if}}
23
21
  })
24
22
  export class TodoModule {}