@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,33 @@
1
+ import { Module } from "@nestjs/common";
2
+ import { GraphQLModule } from "@nestjs/graphql";
3
+ import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo";
4
+ import { join } from "path";
5
+ import { env } from "@repo/env/api-gateway";
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}}
11
+ {{#if hasTodoExample}}
12
+ import { TodoResolver } from "./resolvers/todo.resolver.js";
13
+ {{/if}}
14
+
15
+ @Module({
16
+ imports: [
17
+ GraphQLModule.forRoot<ApolloDriverConfig>({
18
+ driver: ApolloDriver,
19
+ autoSchemaFile: join(process.cwd(), "apps/api-gateway/src/schema.gql"),
20
+ graphiql: env.GRAPHQL_PLAYGROUND,
21
+ sortSchema: true,
22
+ {{#if (eq httpProvider "fastify")}}
23
+ disableHealthCheck: true,
24
+ {{/if}}
25
+ }),
26
+ ],
27
+ providers: [
28
+ {{#if hasTodoExample}}
29
+ TodoResolver,
30
+ {{/if}}
31
+ ],
32
+ })
33
+ export class GraphqlAppModule {}
@@ -0,0 +1,13 @@
1
+ import { Field, ID, ObjectType } from "@nestjs/graphql";
2
+
3
+ @ObjectType({ isAbstract: true })
4
+ export abstract class BaseModel {
5
+ @Field(() => ID)
6
+ id: string;
7
+
8
+ @Field()
9
+ createdAt: Date;
10
+
11
+ @Field()
12
+ updatedAt: Date;
13
+ }
@@ -0,0 +1,23 @@
1
+ import { Field, ID, ObjectType } from "@nestjs/graphql";
2
+
3
+ import { BaseModel } from "./base.model.js";
4
+ // oxlint-disable-next-line import/no-cycle
5
+ import { User } from "./user.model.js";
6
+
7
+ @ObjectType()
8
+ export class Todo extends BaseModel {
9
+ @Field()
10
+ title: string;
11
+
12
+ @Field(() => String, { nullable: true })
13
+ description: string | null;
14
+
15
+ @Field()
16
+ completed: boolean;
17
+
18
+ @Field(() => ID, { nullable: true })
19
+ authorId: string | null;
20
+
21
+ @Field(() => User, { nullable: true })
22
+ author: User | null;
23
+ }
@@ -0,0 +1,34 @@
1
+ import { Field, ObjectType, registerEnumType } from "@nestjs/graphql";
2
+
3
+ import { BaseModel } from "./base.model.js";
4
+ {{#if hasTodoExample}}
5
+ // oxlint-disable-next-line import/no-cycle
6
+ import { Todo } from "./todo.model.js";
7
+ {{/if}}
8
+
9
+ export enum Role {
10
+ ADMIN = "ADMIN",
11
+ USER = "USER",
12
+ }
13
+
14
+ registerEnumType(Role, { name: "Role" });
15
+
16
+ @ObjectType()
17
+ export class User extends BaseModel {
18
+ @Field()
19
+ email: string;
20
+
21
+ @Field(() => String, { nullable: true })
22
+ firstname: string | null;
23
+
24
+ @Field(() => String, { nullable: true })
25
+ lastname: string | null;
26
+
27
+ @Field(() => Role)
28
+ role: Role;
29
+ {{#if hasTodoExample}}
30
+
31
+ @Field(() => [Todo], { nullable: "items" })
32
+ todos: Todo[];
33
+ {{/if}}
34
+ }
@@ -0,0 +1,16 @@
1
+ import { Module } from "@nestjs/common";
2
+ import { buildSchema } from "drizzle-graphql";
3
+ import { db } from "@repo/db";
4
+
5
+ const schema = buildSchema(db);
6
+
7
+ @Module({
8
+ providers: [
9
+ {
10
+ provide: "DRIZZLE_GRAPHQL_SCHEMA",
11
+ useValue: schema,
12
+ },
13
+ ],
14
+ exports: ["DRIZZLE_GRAPHQL_SCHEMA"],
15
+ })
16
+ export class DrizzleGraphqlModule {}
@@ -0,0 +1,9 @@
1
+ import { Injectable, OnModuleInit } from "@nestjs/common";
2
+ import { PrismaClient } from "@prisma/client";
3
+
4
+ @Injectable()
5
+ export class PrismaGraphqlService extends PrismaClient implements OnModuleInit {
6
+ async onModuleInit(): Promise<void> {
7
+ await this.$connect();
8
+ }
9
+ }
@@ -0,0 +1,23 @@
1
+ import { GraphQLResolveInfo } from "graphql";
2
+ import { DataSource, EntityTarget, FindOptionsRelations } from "typeorm";
3
+ import { GraphRelationBuilder } from "typeorm-relations-graphql";
4
+
5
+ export class TypeOrmGraphqlRelationsHelper {
6
+ private readonly builder: GraphRelationBuilder;
7
+
8
+ constructor(dataSource: DataSource) {
9
+ this.builder = new GraphRelationBuilder(dataSource);
10
+ }
11
+
12
+ resolve<T>(
13
+ entity: EntityTarget<T>,
14
+ info: GraphQLResolveInfo,
15
+ path?: string
16
+ ): FindOptionsRelations<T> {
17
+ const relationMap = path
18
+ ? this.builder.buildForQuery(entity, info, path)
19
+ : this.builder.buildForQuery(entity, info);
20
+
21
+ return relationMap as unknown as FindOptionsRelations<T>;
22
+ }
23
+ }
@@ -0,0 +1,122 @@
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
+ import { DbService } from "@repo/db";
8
+ {{#if useTypeorm}}
9
+ import { GraphRelationBuilder } from "typeorm-relations-graphql";
10
+ import { GraphQLResolveInfo } from "graphql";
11
+ {{/if}}
12
+ {{#if useDrizzle}}
13
+ import * as schema from "@repo/db/src/orm/drizzle/schema.js";
14
+ {{/if}}
15
+ {{#if (and hasAuth hasDatabase)}}
16
+ import { Todo } from "../models/todo.model.js";
17
+ import { UserEntity } from "../../auth/decorators/index.js";
18
+ import { GqlAuthGuard } from "../../auth/guards/gql-auth.guard.js";
19
+ {{/if}}
20
+
21
+ @Resolver({{#if (and hasAuth hasDatabase)}}{{"("}}() => Todo){{/if}})
22
+ export class TodoResolver {
23
+ constructor(private readonly db: DbService) {}
24
+
25
+ @Query(() => String)
26
+ hello(): string {
27
+ return "Hello GraphQL!";
28
+ }{{#if hasDatabase}}
29
+
30
+ @Query(() => [Todo])
31
+ todos({{#if useTypeorm}}info: GraphQLResolveInfo{{/if}}): Promise<Todo[]> {
32
+ {{#if useTypeorm}}
33
+ const builder = new GraphRelationBuilder(this.db.getDataSource());
34
+ const relations = builder.buildForQuery(Todo, info, "todos");
35
+ return this.db.getRepository(Todo).find({ relations });
36
+ {{else if usePrisma}}
37
+ return this.db.prisma.todo.findMany();
38
+ {{else if useDrizzle}}
39
+ return this.db.select().from(schema.todos);
40
+ {{else}}
41
+ return [];
42
+ {{/if}}
43
+ }
44
+
45
+ @Mutation(() => Todo)
46
+ {{#if (and hasAuth hasDatabase)}}
47
+ @UseGuards(GqlAuthGuard)
48
+ {{/if}}
49
+ createTodo(
50
+ @Args("input") input: CreateTodoInput{{#if (and hasAuth hasDatabase)}},
51
+ @UserEntity() user: { id: string }{{/if}}{{#if useTypeorm}}, info: GraphQLResolveInfo{{/if}}
52
+ ): Promise<Todo> {
53
+ {{#if useTypeorm}}
54
+ const entity = this.db.getRepository(Todo).create(input);
55
+ const saved = await this.db.getRepository(Todo).save(entity);
56
+ const builder = new GraphRelationBuilder(this.db.getDataSource());
57
+ const relations = builder.buildForQuery(Todo, info, "createTodo");
58
+ return this.db.getRepository(Todo).findOneOrFail({
59
+ where: { id: saved.id },
60
+ relations,
61
+ });
62
+ {{else if usePrisma}}
63
+ return this.db.prisma.todo.create({
64
+ data: { ...input{{#if (and hasAuth hasDatabase)}}, authorId: user.id{{/if}} },
65
+ });
66
+ {{else if useDrizzle}}
67
+ const [todo] = await this.db.insert(schema.todos).values(input).returning();
68
+ return todo;
69
+ {{else}}
70
+ return { id: "1", ...input };
71
+ {{/if}}
72
+ }
73
+
74
+ @Mutation(() => Todo)
75
+ {{#if (and hasAuth hasDatabase)}}
76
+ @UseGuards(GqlAuthGuard)
77
+ {{/if}}
78
+ updateTodo(
79
+ @Args("input") input: UpdateTodoInput{{#if useTypeorm}}, info: GraphQLResolveInfo{{/if}}
80
+ ): Promise<Todo> {
81
+ const { id, ...data } = input;
82
+ {{#if useTypeorm}}
83
+ await this.db.getRepository(Todo).update(id, data);
84
+ const builder = new GraphRelationBuilder(this.db.getDataSource());
85
+ const relations = builder.buildForQuery(Todo, info, "updateTodo");
86
+ return this.db.getRepository(Todo).findOneOrFail({
87
+ where: { id },
88
+ relations,
89
+ });
90
+ {{else if usePrisma}}
91
+ return this.db.prisma.todo.update({ where: { id }, data });
92
+ {{else if useDrizzle}}
93
+ const [todo] = await this.db
94
+ .update(schema.todos)
95
+ .set(data)
96
+ .where(eq(schema.todos.id, id))
97
+ .returning();
98
+ return todo;
99
+ {{else}}
100
+ return { id, ...data };
101
+ {{/if}}
102
+ }
103
+
104
+ @Mutation(() => Boolean)
105
+ {{#if (and hasAuth hasDatabase)}}
106
+ @UseGuards(GqlAuthGuard)
107
+ {{/if}}
108
+ async deleteTodo(@Args("id") id: string): Promise<boolean> {
109
+ {{#if useTypeorm}}
110
+ const result = await this.db.getRepository(Todo).delete(id);
111
+ return (result.affected ?? 0) > 0;
112
+ {{else if usePrisma}}
113
+ await this.db.prisma.todo.delete({ where: { id } });
114
+ return true;
115
+ {{else if useDrizzle}}
116
+ await this.db.delete(schema.todos).where(eq(schema.todos.id, id));
117
+ return true;
118
+ {{else}}
119
+ return true;
120
+ {{/if}}
121
+ }{{/if}}
122
+ }
@@ -45,5 +45,15 @@ export const env = createEnv({
45
45
  {{#if hasMongodb}}
46
46
  MONGODB_URL: z.url(),
47
47
  {{/if}}
48
+ {{#if hasGraphql}}
49
+ GRAPHQL_PLAYGROUND: z
50
+ .string()
51
+ .transform((val) => val === "true")
52
+ .default(true),
53
+ {{/if}}
54
+ {{#if (and (eq auth "passport") hasDatabase)}}
55
+ JWT_ACCESS_SECRET: z.string().min(32),
56
+ JWT_REFRESH_SECRET: z.string().min(32),
57
+ {{/if}}
48
58
  },
49
59
  });
@@ -38,7 +38,7 @@
38
38
  This project uses **Better Auth**. Generate the database schema by running:
39
39
 
40
40
  ```bash
41
- {{#if isPnpm}}pnpm dlx auth@latest generate --config src/auth/auth.ts --output src/database/orm/prisma/schema.prisma -y{{else if isYarn}}yarn dlx auth@latest generate --config src/auth/auth.ts --output src/database/orm/prisma/schema.prisma -y{{else if isBun}}bun x auth@latest generate --config src/auth/auth.ts --output src/database/orm/prisma/schema.prisma -y{{else}}npx auth@latest generate --config src/auth/auth.ts --output src/database/orm/prisma/schema.prisma -y{{/if}}
41
+ {{#if isPnpm}}pnpm dlx auth@latest generate --config src/auth/auth.ts --output src/database/orm/prisma/schema.prisma -y && pnpm run prisma:format{{else if isYarn}}yarn dlx auth@latest generate --config src/auth/auth.ts --output src/database/orm/prisma/schema.prisma -y && yarn run prisma:format && pnpm run prisma:format{{else if isBun}}bun x auth@latest generate --config src/auth/auth.ts --output src/database/orm/prisma/schema.prisma -y && bun run prisma:format{{else}}npx auth@latest generate --config src/auth/auth.ts --output src/database/orm/prisma/schema.prisma -y && npm run prisma:format{{/if}}
42
42
  ```
43
43
 
44
44
  {{#if useDrizzle}}Then run Drizzle migrations:
@@ -7,6 +7,12 @@ allowBuilds:
7
7
  {{#if swagger}}
8
8
  '@scarf/scarf': true
9
9
  {{/if}}
10
+ {{#if hasGraphql}}
11
+ '@apollo/protobufjs': true
12
+ {{/if}}
13
+ {{#if (and (eq auth "passport") hasDatabase)}}
14
+ bcrypt: true
15
+ {{/if}}
10
16
  catalog:
11
17
  "@types/node": ^22.13.14
12
18
  dotenv: ^17.2.2
@@ -1,2 +1,26 @@
1
- PORT=3000
2
1
  CORS_ORIGIN=http://localhost:3001
2
+ PORT=3000
3
+ {{#if hasGraphql}}
4
+ GRAPHQL_PLAYGROUND=true
5
+ {{/if}}
6
+
7
+ {{#if hasPostgres}}
8
+ POSTGRES_URL=postgresql://postgres:postgres@localhost:5432/{{projectNameKebab}}_db?schema=public
9
+ {{/if}}
10
+ {{#if hasMysql}}
11
+ MYSQL_URL=mysql://root:mysql@localhost:3306/{{projectNameKebab}}_db
12
+ {{/if}}
13
+ {{#if hasSqlite}}
14
+ SQLITE_PATH=sqlite.db
15
+ {{/if}}
16
+ {{#if hasMongodb}}
17
+ MONGODB_URL=mongodb://localhost:27017/{{projectNameKebab}}_db
18
+ {{/if}}
19
+ {{#if (and (eq auth "passport") hasDatabase)}}
20
+ JWT_ACCESS_SECRET=change-me-to-a-random-secret-at-least-32-characters-long
21
+ JWT_REFRESH_SECRET=change-me-to-a-different-random-secret-at-least-32-characters
22
+ {{/if}}
23
+ {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
24
+ BETTER_AUTH_SECRET=change-me-to-a-random-secret-at-least-32-characters-long
25
+ BETTER_AUTH_URL=http://localhost:3000
26
+ {{/if}}
@@ -3,5 +3,11 @@ allowBuilds:
3
3
  {{#if swagger}}
4
4
  "@scarf/scarf": true
5
5
  {{/if}}
6
+ {{#if hasGraphql}}
7
+ "@apollo/protobufjs": true
8
+ {{/if}}
9
+ {{#if (and (eq auth "passport") hasDatabase)}}
10
+ bcrypt: true
11
+ {{/if}}
6
12
  catalog:
7
13
  dotenv: ^17.2.2
@@ -2,7 +2,7 @@ import { NestFactory } from "@nestjs/core";
2
2
  {{#if (eq httpProvider "fastify")}}
3
3
  import { FastifyAdapter, NestFastifyApplication } from "@nestjs/platform-fastify";
4
4
  {{/if}}
5
- import { Logger } from "@nestjs/common";
5
+ import { Logger, StandardSchemaValidationPipe } from "@nestjs/common";
6
6
 
7
7
  import { AppModule } from "./app.module.js";
8
8
  import { env } from "./config/env.js";
@@ -24,65 +24,71 @@ async function bootstrap() {
24
24
  app.enableCors({
25
25
  origin: env.CORS_ORIGIN,
26
26
  });
27
+ {{#if hasRest}}
27
28
  app.setGlobalPrefix("api");
29
+ {{/if}}
30
+ app.useGlobalPipes(new StandardSchemaValidationPipe());
31
+ app.enableShutdownHooks();
28
32
  {{#if swagger}}
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/trpc/router.ts",
48
- pathPrefix: "/trpc",
49
- },
50
- {{/if}}
51
- zod: {
52
- withFastify: {{#if (eq httpProvider "fastify")}}true{{else}}false{{/if}},
33
+ if (env.NODE_ENV === "development") {
34
+ const docsPath = "/docs";
35
+ {{#if useSwaggerScalar}}
36
+ app.use(
37
+ docsPath,
38
+ apiReference({
39
+ content: await createDocs(app, {
40
+ title: "{{projectNamePascalCase}} API",
41
+ description: "{{description}}",
42
+ version: "1.0.0",
43
+ integrations: {
44
+ {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
45
+ betterAuth: {
46
+ auth,
47
+ pathPrefix: "/api/auth",
48
+ },
49
+ {{/if}}
50
+ {{#if (includes apis "trpc")}}
51
+ trpc: {
52
+ routerFilePath: "./src/trpc/router.ts",
53
+ pathPrefix: "/trpc",
54
+ },
55
+ {{/if}}
56
+ zod: {
57
+ withFastify: {{#if (eq httpProvider "fastify")}}true{{else}}false{{/if}},
58
+ },
53
59
  },
54
- },
60
+ }),
61
+ pageTitle: "{{projectNamePascalCase}} API Docs",
62
+ theme: "default",
55
63
  }),
56
- pageTitle: "{{projectNamePascalCase}} API Docs",
57
- theme: "default",
58
- }),
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}},
64
+ );
65
+ {{else}}
66
+ const document = await createDocs(app, {
67
+ title: "{{projectNamePascalCase}} API",
68
+ description: "{{description}}",
69
+ version: "1.0.0",
70
+ integrations: {
71
+ {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
72
+ betterAuth: {
73
+ auth,
74
+ pathPrefix: "/api/auth",
75
+ },
76
+ {{/if}}
77
+ {{#if (includes apis "trpc")}}
78
+ trpc: {
79
+ routerFilePath: "./src/trpc/router.ts",
80
+ pathPrefix: "/trpc",
81
+ },
82
+ {{/if}}
83
+ zod: {
84
+ withFastify: {{#if (eq httpProvider "fastify")}}true{{else}}false{{/if}},
85
+ },
80
86
  },
81
- },
82
- });
83
- SwaggerModule.setup(docsPath, app, document);
84
- {{/if}}
85
- Logger.log(`Swagger documentation available at http://localhost:${env.PORT ?? 3000}${docsPath}`, "SwaggerDocs");
87
+ });
88
+ SwaggerModule.setup(docsPath, app, document);
89
+ {{/if}}
90
+ Logger.log(`Swagger documentation available at http://localhost:${env.PORT ?? 3000}${docsPath}`, "SwaggerDocs");
91
+ }
86
92
  {{/if}}
87
93
 
88
94
  await app.listen(env.PORT ?? 3000);
@@ -26,63 +26,65 @@ async function bootstrap() {
26
26
  });
27
27
  app.setGlobalPrefix("api");
28
28
  {{#if swagger}}
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",
29
+ if (env.NODE_ENV === "development") {
30
+ const docsPath = "/docs";
31
+ {{#if useSwaggerScalar}}
32
+ app.use(
33
+ docsPath,
34
+ apiReference({
35
+ content: await createDocs(app, {
36
+ title: "{{projectNamePascalCase}} API",
37
+ description: "{{description}}",
38
+ version: "1.0.0",
39
+ integrations: {
40
+ {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
41
+ betterAuth: {
42
+ auth,
43
+ pathPrefix: "/api/auth",
44
+ },
45
+ {{/if}}
46
+ {{#if (includes apis "trpc")}}
47
+ trpc: {
48
+ routerFilePath: "./src/trpc/router.ts",
49
+ pathPrefix: "/trpc",
50
+ },
51
+ {{/if}}
52
+ zod: {
53
+ withFastify: {{#if (eq httpProvider "fastify")}}true{{else}}false{{/if}},
54
+ },
43
55
  },
44
- {{/if}}
45
- {{#if (includes apis "trpc")}}
46
- trpc: {
47
- routerFilePath: "./src/trpc/router.ts",
48
- pathPrefix: "/trpc",
49
- },
50
- {{/if}}
51
- zod: {
52
- withFastify: {{#if (eq httpProvider "fastify")}}true{{else}}false{{/if}},
53
- },
54
- },
56
+ }),
57
+ pageTitle: "{{projectNamePascalCase}} API Docs",
58
+ theme: "default",
55
59
  }),
56
- pageTitle: "{{projectNamePascalCase}} API Docs",
57
- theme: "default",
58
- }),
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}},
60
+ );
61
+ {{else}}
62
+ const document = await createDocs(app, {
63
+ title: "{{projectNamePascalCase}} API",
64
+ description: "{{description}}",
65
+ version: "1.0.0",
66
+ integrations: {
67
+ {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
68
+ betterAuth: {
69
+ auth,
70
+ pathPrefix: "/api/auth",
71
+ },
72
+ {{/if}}
73
+ {{#if (includes apis "trpc")}}
74
+ trpc: {
75
+ routerFilePath: "./src/trpc/router.ts",
76
+ pathPrefix: "/trpc",
77
+ },
78
+ {{/if}}
79
+ zod: {
80
+ withFastify: {{#if (eq httpProvider "fastify")}}true{{else}}false{{/if}},
81
+ },
80
82
  },
81
- },
82
- });
83
- SwaggerModule.setup(docsPath, app, document);
84
- {{/if}}
85
- Logger.log(`Swagger documentation available at http://localhost:${env.PORT ?? 3000}${docsPath}`, "SwaggerDocs");
83
+ });
84
+ SwaggerModule.setup(docsPath, app, document);
85
+ {{/if}}
86
+ Logger.log(`Swagger documentation available at http://localhost:${env.PORT ?? 3000}${docsPath}`, "SwaggerDocs");
87
+ }
86
88
  {{/if}}
87
89
 
88
90
  await app.listen(env.PORT ?? 3000);
@@ -1,3 +1,6 @@
1
1
  PORT=3000
2
2
  MICROSERVICE_PORT=3001
3
3
  CORS_ORIGIN=http://localhost:3001
4
+ {{#if hasGraphql}}
5
+ GRAPHQL_PLAYGROUND=true
6
+ {{/if}}