@nest-arch/tui 0.2.8 → 0.4.3

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 (92) hide show
  1. package/README.md +20 -42
  2. package/dist/cli.js +1 -1
  3. package/dist/constants-B5MuV-iH.js +1 -0
  4. package/dist/index.js +365 -98
  5. package/dist/templates/addons/husky/pre-commit.hbs +11 -26
  6. package/dist/templates/base/.env.example.hbs +13 -2
  7. package/dist/templates/base/.env.hbs +11 -2
  8. package/dist/templates/base/.gitignore.hbs +2 -1
  9. package/dist/templates/base/.yarnrc.yml.hbs +0 -5
  10. package/dist/templates/base/README.md.hbs +49 -5
  11. package/dist/templates/base/nest-cli.json.hbs +2 -1
  12. package/dist/templates/base/pnpm-workspace.yaml.hbs +15 -0
  13. package/dist/templates/base/prisma.config.ts.hbs +32 -6
  14. package/dist/templates/base/src/app.controller.spec.ts.hbs +3 -11
  15. package/dist/templates/base/src/app.controller.ts.hbs +2 -2
  16. package/dist/templates/base/src/app.module.ts.hbs +76 -5
  17. package/dist/templates/base/src/app.router.ts.hbs +3 -4
  18. package/dist/templates/base/src/database/adapters/interfaces/db-adapter.interface.ts.hbs +7 -0
  19. package/dist/templates/base/src/database/adapters/mongo/prisma-mongo.adapter.ts.hbs +36 -4
  20. package/dist/templates/base/src/database/adapters/mongo/raw-mongo.adapter.ts.hbs +17 -12
  21. package/dist/templates/base/src/database/adapters/sql/drizzle-sql.adapter.ts.hbs +9 -0
  22. package/dist/templates/base/src/database/adapters/sql/prisma-sql.adapter.ts.hbs +8 -5
  23. package/dist/templates/base/src/database/adapters/sql/raw-sql.adapter.ts.hbs +37 -0
  24. package/dist/templates/base/src/database/adapters/sql/typeorm-sql.adapter.ts.hbs +8 -3
  25. package/dist/templates/base/src/database/db.module.ts.hbs +55 -42
  26. package/dist/templates/base/src/database/db.service.ts.hbs +60 -6
  27. package/dist/templates/base/src/database/entities/app.entity.ts.hbs +25 -0
  28. package/dist/templates/base/src/database/entities/todo.entity.ts.hbs +12 -7
  29. package/dist/templates/base/src/database/index.ts.hbs +20 -0
  30. package/dist/templates/base/src/database/orm/drizzle/schema.ts.hbs +80 -7
  31. package/dist/templates/base/src/database/orm/typeorm/data-source.ts.hbs +23 -4
  32. package/dist/templates/base/src/libs/middlewares/auth.trpc.middleware.ts.hbs +47 -0
  33. package/dist/templates/base/src/libs/middlewares/rate-limit.trpc.middleware.ts.hbs +43 -0
  34. package/dist/templates/base/src/libs/trpc/error.handler.ts.hbs +1 -1
  35. package/dist/templates/base/src/libs/trpc/inner.context.ts.hbs +6 -3
  36. package/dist/templates/base/src/main.ts.hbs +34 -10
  37. package/dist/templates/base/src/modules/users/entities/user.entity.ts.hbs +22 -0
  38. package/dist/templates/base/test/app.e2e-spec.ts.hbs +841 -6
  39. package/dist/templates/base/test/bootstrap.e2e-spec.ts.hbs +84 -0
  40. package/dist/templates/base/tsconfig.build.json.hbs +2 -0
  41. package/dist/templates/base/vitest.config.e2e.ts.hbs +4 -3
  42. package/dist/templates/base/vitest.config.ts.hbs +4 -3
  43. package/dist/templates/base/yarn.lock.hbs +1 -0
  44. package/dist/templates/extras/docker/.dockerignore.hbs +8 -1
  45. package/dist/templates/extras/docker/Dockerfile.hbs +11 -10
  46. package/dist/templates/extras/health/src/health/health.controller.ts.hbs +54 -0
  47. package/dist/templates/extras/health/src/health/health.module.ts.hbs +9 -0
  48. package/dist/templates/extras/swagger/create-docs.ts.hbs +13 -22
  49. package/dist/templates/feature/graphql/src/graphql/graphql.module.ts.hbs +6 -10
  50. package/dist/templates/feature/graphql/src/graphql/models/todo.model.ts.hbs +4 -0
  51. package/dist/templates/feature/graphql/src/graphql/orm/drizzle/drizzle-graphql.module.ts.hbs +6 -4
  52. package/dist/templates/feature/graphql/src/graphql/resolvers/health.resolver.ts.hbs +14 -0
  53. package/dist/templates/feature/graphql/src/graphql/resolvers/todo.resolver.ts.hbs +210 -47
  54. package/dist/templates/feature/rest/todo-example/src/api/todo/dto/create-todo.dto.ts.hbs +12 -0
  55. package/dist/templates/feature/rest/todo-example/src/api/todo/dto/update-todo.dto.ts.hbs +12 -0
  56. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.controller.ts.hbs +21 -9
  57. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.module.ts.hbs +1 -3
  58. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.router.ts.hbs +41 -13
  59. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.service.ts.hbs +157 -33
  60. package/dist/templates/monorepo/apps/api-gateway/package.json.hbs +2 -3
  61. package/dist/templates/monorepo/apps/api-gateway/src/app.controller.spec.ts.hbs +6 -1
  62. package/dist/templates/monorepo/apps/api-gateway/src/app.controller.ts.hbs +6 -0
  63. package/dist/templates/monorepo/apps/api-gateway/src/app.module.ts.hbs +32 -1
  64. package/dist/templates/monorepo/apps/api-gateway/src/app.service.ts.hbs +1 -1
  65. package/dist/templates/monorepo/apps/api-gateway/src/main.ts.hbs +13 -4
  66. package/dist/templates/monorepo/apps/api-gateway/test/app.e2e-spec.ts.hbs +45 -1
  67. package/dist/templates/monorepo/apps/api-gateway/tsconfig.build.json.hbs +2 -1
  68. package/dist/templates/monorepo/apps/api-gateway/vitest.config.e2e.ts.hbs +3 -2
  69. package/dist/templates/monorepo/apps/api-gateway/vitest.config.ts.hbs +3 -2
  70. package/dist/templates/monorepo/feature/graphql/src/graphql/graphql.module.ts.hbs +6 -10
  71. package/dist/templates/monorepo/feature/graphql/src/graphql/resolvers/health.resolver.ts.hbs +14 -0
  72. package/dist/templates/monorepo/feature/graphql/src/graphql/resolvers/todo.resolver.ts.hbs +151 -42
  73. package/dist/templates/monorepo/packages/env/src/api-gateway.ts.hbs +16 -3
  74. package/dist/templates/monorepo/packages/shared/package.json.hbs +1 -0
  75. package/dist/templates/monorepo/packages/shared/src/auth.ts.hbs +6 -0
  76. package/dist/templates/monorepo/root/.gitignore.hbs +1 -0
  77. package/dist/templates/monorepo/root/pnpm-workspace.yaml.hbs +19 -2
  78. package/dist/templates/monorepo/root/tsconfig.json.hbs +1 -1
  79. package/dist/templates/monorepo/root/turbo.json.hbs +2 -0
  80. package/dist/templates/single-project/architecture/nest-api/.env.hbs +9 -1
  81. package/dist/templates/single-project/architecture/nest-api/package.json.hbs +1 -2
  82. package/dist/templates/single-project/architecture/nest-api/src/main.ts.hbs +33 -9
  83. package/dist/templates/single-project/architecture/nest-gateway/src/main.ts.hbs +3 -3
  84. package/dist/templates/single-project/architecture/nest-microservice/.env.hbs +18 -0
  85. package/dist/templates/single-project/architecture/nest-microservice/proto/app.proto.hbs +26 -0
  86. package/dist/templates/single-project/architecture/nest-microservice/src/app.controller.ts.hbs +23 -4
  87. package/dist/templates/single-project/architecture/nest-microservice/src/app.service.ts.hbs +6 -2
  88. package/dist/templates/single-project/architecture/nest-microservice/src/main.ts.hbs +16 -5
  89. package/dist/templates/single-project/architecture/nest-microservice/test/microservice.e2e-spec.ts.hbs +70 -0
  90. package/dist/templates/single-project/shared/config/env.ts.hbs +38 -3
  91. package/package.json +5 -2
  92. package/dist/constants-Cgtoxhmd.js +0 -1
@@ -0,0 +1,84 @@
1
+ import { setTimeout as delay } from "node:timers/promises";
2
+ import { once } from "node:events";
3
+ import { createServer } from "node:net";
4
+ import { spawn, type ChildProcess } from "node:child_process";
5
+
6
+ import { afterEach, expect, it } from "vitest";
7
+
8
+ const startedProcesses: ChildProcess[] = [];
9
+
10
+ async function getFreePort(): Promise<number> {
11
+ const server = createServer();
12
+ server.listen(0, "127.0.0.1");
13
+ await once(server, "listening");
14
+ const address = server.address();
15
+ server.close();
16
+ if (!address || typeof address === "string") {
17
+ throw new Error("Could not allocate a loopback port for the bootstrap test.");
18
+ }
19
+ return address.port;
20
+ }
21
+
22
+ async function waitForServer(url: string, application: ChildProcess, deadline = Date.now() + 15000): Promise<Response> {
23
+ if (application.exitCode !== null) throw new Error(`Generated application exited during startup with code ${application.exitCode}.`);
24
+ try {
25
+ return await fetch(url, { signal: AbortSignal.timeout(500) });
26
+ } catch (error) {
27
+ if (Date.now() >= deadline) throw new Error("Generated application did not become ready", { cause: error });
28
+ await delay(100);
29
+ return waitForServer(url, application, deadline);
30
+ }
31
+ }
32
+
33
+ async function stopApplication(application: ChildProcess): Promise<void> {
34
+ if (application.exitCode !== null) return;
35
+ const exited = once(application, "exit");
36
+ application.kill();
37
+ const timeout = setTimeout(() => { application.kill("SIGKILL"); }, 5000);
38
+ try { await exited; } finally { clearTimeout(timeout); }
39
+ }
40
+
41
+ afterEach(async () => {
42
+ await Promise.all(startedProcesses.splice(0).map(stopApplication));
43
+ });
44
+
45
+ it("boots the compiled application through main.ts", async () => {
46
+ const port = await getFreePort();
47
+ const origin = "https://allowed.example";
48
+ const application = spawn(process.execPath, ["dist/main.js"], {
49
+ env: {
50
+ ...process.env,
51
+ CORS_ORIGIN: origin,
52
+ {{#if (and isPassportAuth (not hasDatabase))}}
53
+ OIDC_AUDIENCE: "generated-resource-server",
54
+ OIDC_ISSUER: "https://identity.example.test/",
55
+ OIDC_JWKS_URI: "https://identity.example.test/.well-known/jwks.json",
56
+ {{/if}}
57
+ NODE_ENV: "test",
58
+ PORT: String(port),
59
+ },
60
+ stdio: ["ignore", "pipe", "pipe"],
61
+ });
62
+ startedProcesses.push(application);
63
+ let output = "";
64
+ application.stdout?.on("data", (chunk) => { output += chunk.toString(); });
65
+ application.stderr?.on("data", (chunk) => { output += chunk.toString(); });
66
+
67
+ {{#if hasRest}}
68
+ const response = await waitForServer(`http://127.0.0.1:${port}/api`, application).catch((error) => { throw new Error(`${error}\n${output}`); });
69
+ expect(response.status).toBe(200);
70
+ expect(await response.text()).toBe("Hello World!");
71
+
72
+ const corsResponse = await fetch(`http://127.0.0.1:${port}/api`, {
73
+ headers: { Origin: origin },
74
+ });
75
+ expect(corsResponse.headers.get("access-control-allow-origin")).toBe(origin);
76
+ const rootResponse = await fetch(`http://127.0.0.1:${port}/`, { redirect: "manual" });
77
+ expect(rootResponse.status).toBe(404);
78
+ {{else}}
79
+ await waitForServer(`http://127.0.0.1:${port}/graphql?query=%7Bhello%7D`, application).catch((error) => { throw new Error(`${error}\n${output}`); });
80
+ const response = await fetch(`http://127.0.0.1:${port}/graphql`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query: "{ hello }" }) });
81
+ const body = await response.json();
82
+ expect(body.data.hello).toBe("Hello GraphQL!");
83
+ {{/if}}
84
+ }, 20_000);
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "extends": "./tsconfig.json",
3
+ "include": ["src/**/*.ts"],
3
4
  "exclude": [
4
5
  "node_modules",
5
6
  "test",
@@ -7,6 +8,7 @@
7
8
  "**/*spec.ts"
8
9
  ],
9
10
  "compilerOptions": {
11
+ "rootDir": "./src",
10
12
  "strictNullChecks": true
11
13
  }
12
14
  }
@@ -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: ["**/*.e2e-spec.ts"],
7
9
  globals: true,
8
10
  root: "./",
9
- include: ["**/*.e2e-spec.ts"],
10
11
  },
11
12
  });
@@ -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.
@@ -1 +1,8 @@
1
- node_modules dist npm-debug.log .env
1
+ node_modules
2
+ dist
3
+ npm-debug.log
4
+ .env
5
+ .env.*
6
+ !.env.example
7
+ !.env.test.example
8
+ .git
@@ -3,20 +3,21 @@ FROM node:22-alpine
3
3
  WORKDIR /app
4
4
 
5
5
  {{#if (eq packageManager "pnpm")}}
6
- RUN corepack enable && corepack prepare pnpm@latest --activate
7
- COPY package.json pnpm-lock.yaml ./
8
- RUN pnpm install --frozen-lockfile
6
+ RUN corepack enable
9
7
  {{else if (eq packageManager "yarn")}}
10
- COPY package.json yarn.lock ./
11
- RUN yarn install --frozen-lockfile
8
+ RUN corepack enable
12
9
  {{else}}
13
- COPY package*.json ./
14
- RUN npm ci
15
10
  {{/if}}
16
11
 
17
12
  COPY . .
18
- RUN {{packageManager}} run build
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 (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{{else}}npm install{{/if}}
14
+ 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
19
15
 
20
- EXPOSE 3000
16
+ ENV NODE_ENV=production
21
17
 
22
- CMD ["{{packageManager}}", "run", "start:prod"]
18
+ EXPOSE {{#if (eq httpProvider "fastify")}}3001{{else}}3000{{/if}}
19
+ {{#if (includes microservices "grpc")}}
20
+ EXPOSE 5000
21
+ {{/if}}
22
+
23
+ CMD ["node", "dist/main"]
@@ -0,0 +1,54 @@
1
+ import { Controller, Get } from "@nestjs/common";
2
+ import { HealthCheck, HealthCheckService } from "@nestjs/terminus";
3
+ {{#if isBetterAuth}}
4
+ import { AllowAnonymous } from "@thallesp/nestjs-better-auth";
5
+ {{/if}}
6
+ {{#if hasDatabase}}
7
+ import { DbService } from "../database/db.service.js";
8
+ {{#if useDrizzle}}
9
+ import { sql } from "drizzle-orm";
10
+ {{/if}}
11
+ {{/if}}
12
+
13
+ {{#if isBetterAuth}}
14
+ @AllowAnonymous()
15
+ {{/if}}
16
+ @Controller("health")
17
+ export class HealthController {
18
+ constructor(
19
+ private readonly health: HealthCheckService{{#if hasDatabase}},
20
+ private readonly db: DbService{{/if}}
21
+ ) {}
22
+
23
+ @Get()
24
+ @HealthCheck()
25
+ check() {
26
+ return this.health.check([
27
+ () => ({ app: { status: "up" } }),
28
+ {{#if hasDatabase}}
29
+ async () => {
30
+ try {
31
+ {{#if (or usePrisma isPrisma8)}}
32
+ await this.db.prisma.$queryRaw`SELECT 1`;
33
+ {{else if useDrizzle}}
34
+ {{#if hasSqlite}}
35
+ await this.db.drizzle.get(sql`SELECT 1`);
36
+ {{else}}
37
+ await this.db.drizzle.execute(sql`SELECT 1`);
38
+ {{/if}}
39
+ {{else if useTypeorm}}
40
+ await this.db.typeorm.query("SELECT 1");
41
+ {{else if hasMongodb}}
42
+ await this.db.raw.mongo.command({ ping: 1 });
43
+ {{else}}
44
+ await this.db.raw.sql.query("SELECT 1");
45
+ {{/if}}
46
+ return { db: { status: "up" } };
47
+ } catch {
48
+ return { db: { status: "down" } };
49
+ }
50
+ },
51
+ {{/if}}
52
+ ]);
53
+ }
54
+ }
@@ -0,0 +1,9 @@
1
+ import { Module } from "@nestjs/common";
2
+ import { TerminusModule } from "@nestjs/terminus";
3
+ import { HealthController } from "./health.controller.js";
4
+
5
+ @Module({
6
+ controllers: [HealthController],
7
+ imports: [TerminusModule],
8
+ })
9
+ export class HealthModule {}
@@ -1,7 +1,3 @@
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
3
  import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
@@ -23,6 +19,7 @@ interface DocsIntegrations {
23
19
  zod?: {
24
20
  withFastify?: boolean;
25
21
  };
22
+ bearerAuth?: boolean;
26
23
  }
27
24
 
28
25
  export interface CreateDocsOptions {
@@ -80,7 +77,8 @@ async function applyZodCleanup(
80
77
  options?: NonNullable<DocsIntegrations["zod"]>
81
78
  ) {
82
79
  try {
83
- const { cleanupOpenApiDoc } = await import("nestjs-zod");
80
+ const packageName = "nestjs-zod";
81
+ const { cleanupOpenApiDoc } = await import(packageName);
84
82
  if (typeof cleanupOpenApiDoc !== "function") {
85
83
  return baseSpec;
86
84
  }
@@ -143,7 +141,8 @@ async function applyTrpcSpec(options?: NonNullable<DocsIntegrations["trpc"]>) {
143
141
  }
144
142
 
145
143
  try {
146
- const { generateOpenAPIDocument } = await import("@trpc/openapi");
144
+ const packageName = "@trpc/openapi";
145
+ const { generateOpenAPIDocument } = await import(packageName);
147
146
 
148
147
  if (typeof generateOpenAPIDocument !== "function") {
149
148
  return null;
@@ -174,28 +173,20 @@ async function applyTrpcSpec(options?: NonNullable<DocsIntegrations["trpc"]>) {
174
173
  }
175
174
  }
176
175
 
177
- function createEmptyBaseSpec(options: CreateDocsOptions): OpenAPIObject {
178
- return {
179
- info: {
180
- description: options.description ?? "Generated with Nest Arch",
181
- title: options.title ?? "NestJS API",
182
- version: options.version ?? "1.0.0",
183
- },
184
- openapi: "3.1.0",
185
- paths: {},
186
- tags: [],
187
- } as OpenAPIObject;
188
- }
189
-
190
176
  export async function createDocs(
191
177
  app: INestApplication,
192
178
  options: CreateDocsOptions = {}
193
179
  ): Promise<OpenAPIObject> {
194
- const config = new DocumentBuilder()
180
+ const builder = new DocumentBuilder()
195
181
  .setTitle(options.title ?? "NestJS API")
196
182
  .setDescription(options.description ?? "Generated with Nest Arch")
197
- .setVersion(options.version ?? "1.0.0")
198
- .build();
183
+ .setVersion(options.version ?? "1.0.0");
184
+
185
+ if (options.integrations?.bearerAuth === true) {
186
+ builder.addBearerAuth();
187
+ }
188
+
189
+ const config = builder.build();
199
190
 
200
191
  let baseSpec = SwaggerModule.createDocument(app, config) as OpenAPIObject;
201
192
  baseSpec = await applyZodCleanup(baseSpec, options.integrations?.zod);
@@ -1,13 +1,10 @@
1
1
  import { Module } from "@nestjs/common";
2
2
  import { GraphQLModule } from "@nestjs/graphql";
3
3
  import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo";
4
- import { join } from "path";
4
+ import type { IncomingMessage } from "node:http";
5
+ import path from "node:path";
5
6
  import { env } from "../config/env.js";
6
- {{#if (eq httpProvider "fastify")}}
7
- // WARNING: If you use @as-integrations/fastify with multiple GraphQL endpoints
8
- // in a single application, make sure to enable the disableHealthCheck setting
9
- // in the GraphQLModule configuration below.
10
- {{/if}}
7
+ import { HealthResolver } from "./resolvers/health.resolver.js";
11
8
  {{#if hasTodoExample}}
12
9
  import { TodoResolver } from "./resolvers/todo.resolver.js";
13
10
  {{/if}}
@@ -16,15 +13,14 @@ import { TodoResolver } from "./resolvers/todo.resolver.js";
16
13
  imports: [
17
14
  GraphQLModule.forRoot<ApolloDriverConfig>({
18
15
  driver: ApolloDriver,
19
- autoSchemaFile: join(process.cwd(), "src/schema.gql"),
16
+ autoSchemaFile: path.join(process.cwd(), "src/schema.gql"),
20
17
  graphiql: env.GRAPHQL_PLAYGROUND,
18
+ context: ({ req, res }: { req: IncomingMessage; res: unknown }) => ({ req, res }),
21
19
  sortSchema: true,
22
- {{#if (eq httpProvider "fastify")}}
23
- disableHealthCheck: true,
24
- {{/if}}
25
20
  }),
26
21
  ],
27
22
  providers: [
23
+ HealthResolver,
28
24
  {{#if hasTodoExample}}
29
25
  TodoResolver,
30
26
  {{/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";
@@ -15,21 +16,22 @@ import mysql from "mysql2";
15
16
  import { drizzle } from "drizzle-orm/better-sqlite3";
16
17
  import Database from "better-sqlite3";
17
18
  {{/if}}
18
- import * as dbSchema from "../database/orm/drizzle/schema.js";
19
+ import * as dbSchema from "../../../database/orm/drizzle/schema.js";
19
20
  {{/if}}
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), { mode: "default", 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
 
34
+
33
35
  @Module({
34
36
  providers: [
35
37
  {
@@ -0,0 +1,14 @@
1
+ import { Query, Resolver } from "@nestjs/graphql";
2
+ {{#if isBetterAuth}}
3
+ import { AllowAnonymous } from "@thallesp/nestjs-better-auth";
4
+ {{/if}}
5
+ {{#if isBetterAuth}}
6
+ @AllowAnonymous()
7
+ {{/if}}
8
+ @Resolver()
9
+ export class HealthResolver {
10
+ @Query(() => String)
11
+ hello(): string {
12
+ return "Hello GraphQL!";
13
+ }
14
+ }