@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
@@ -1,8 +1,7 @@
1
- // oxlint-disable typescript/no-explicit-any require-await
2
1
  import { Injectable, Inject } from '@nestjs/common';
3
2
  import { ISqlAdapter } from '../interfaces/db-adapter.interface.js';
4
3
  {{#if isMonorepo}}
5
- import type { PrismaClient } from '../../../database/orm/prisma/generated/client.js';
4
+ import type { PrismaClient } from '../../database/orm/prisma/generated/client.js';
6
5
  {{else}}
7
6
  import type { PrismaClient } from '../../orm/prisma/generated/client.js';
8
7
  {{/if}}
@@ -15,15 +14,19 @@ export class PrismaSqlAdapter implements ISqlAdapter<PrismaClient> {
15
14
  @Inject('PRISMA_SQL_CLIENT') private readonly prisma: PrismaClient
16
15
  ) {}
17
16
 
18
- async query<T = any>(sql: string, params: any[] = []): Promise<T[]> {
19
- return this.prisma.$queryRawUnsafe(sql, ...params);
17
+ query<T = unknown>(sql: string, params: unknown[] = []): Promise<T[]> {
18
+ return this.prisma.$queryRawUnsafe<T[]>(sql, ...params);
20
19
  }
21
20
 
22
- async execute(sql: string, params: any[] = []): Promise<any> {
21
+ execute(sql: string, params: unknown[] = []): Promise<number> {
23
22
  return this.prisma.$executeRawUnsafe(sql, ...params);
24
23
  }
25
24
 
26
25
  getClient(): PrismaClient {
27
26
  return this.prisma;
28
27
  }
28
+
29
+ async onModuleDestroy(): Promise<void> {
30
+ await this.prisma.$disconnect();
31
+ }
29
32
  }
@@ -1,3 +1,31 @@
1
+ {{#if hasPostgres}}
2
+ import { Inject, Injectable } from "@nestjs/common";
3
+ import type { Pool } from "pg";
4
+
5
+ import type { ISqlAdapter } from "../interfaces/db-adapter.interface.js";
6
+
7
+ @Injectable()
8
+ export class RawSqlAdapter implements ISqlAdapter<Pool> {
9
+ constructor(@Inject("SQL_CLIENT") private readonly db: Pool) {}
10
+
11
+ async query<T = unknown>(queryString: string, params: unknown[] = []): Promise<T[]> {
12
+ const result = await this.db.query(queryString, params);
13
+ return result.rows as T[];
14
+ }
15
+
16
+ execute(queryString: string, params: unknown[] = []): Promise<unknown> {
17
+ return this.db.query(queryString, params);
18
+ }
19
+
20
+ getClient(): Pool {
21
+ return this.db;
22
+ }
23
+
24
+ async onModuleDestroy(): Promise<void> {
25
+ await this.db.end();
26
+ }
27
+ }
28
+ {{else}}
1
29
  import { Injectable, Inject } from '@nestjs/common';
2
30
  import { ISqlAdapter } from '../interfaces/db-adapter.interface.js';
3
31
 
@@ -46,4 +74,13 @@ export class RawSqlAdapter implements ISqlAdapter {
46
74
  getClient(): any {
47
75
  return this.db;
48
76
  }
77
+
78
+ async onModuleDestroy(): Promise<void> {
79
+ if (typeof this.db.end === 'function') {
80
+ await this.db.end();
81
+ } else if (typeof this.db.close === 'function') {
82
+ await this.db.close();
83
+ }
84
+ }
49
85
  }
86
+ {{/if}}
@@ -1,4 +1,3 @@
1
- // oxlint-disable typescript/no-explicit-any require-await
2
1
  import { Injectable, Inject } from '@nestjs/common';
3
2
  import type { DataSource } from 'typeorm';
4
3
  import type { ISqlAdapter } from '../interfaces/db-adapter.interface.js';
@@ -9,15 +8,21 @@ export class TypeormSqlAdapter implements ISqlAdapter<DataSource> {
9
8
  @Inject('TYPEORM_DATA_SOURCE') private readonly dataSource: DataSource
10
9
  ) {}
11
10
 
12
- async query<T = any>(sql: string, params: any[] = []): Promise<T[]> {
11
+ query<T = unknown>(sql: string, params: unknown[] = []): Promise<T[]> {
13
12
  return this.dataSource.query(sql, params);
14
13
  }
15
14
 
16
- async execute(sql: string, params: any[] = []): Promise<any> {
15
+ execute(sql: string, params: unknown[] = []): Promise<unknown> {
17
16
  return this.dataSource.query(sql, params);
18
17
  }
19
18
 
20
19
  getClient(): DataSource {
21
20
  return this.dataSource;
22
21
  }
22
+
23
+ async onModuleDestroy(): Promise<void> {
24
+ if (this.dataSource.isInitialized) {
25
+ await this.dataSource.destroy();
26
+ }
27
+ }
23
28
  }
@@ -1,12 +1,32 @@
1
+ {{#if isPrisma8}}
2
+ import { DynamicModule, Global, Module } from "@nestjs/common";
3
+ import { DbService } from "./db.service.js";
4
+
5
+ @Global()
6
+ @Module({})
7
+ export class DbModule {
8
+ static forRoot(_options?: unknown): DynamicModule {
9
+ return { exports: [DbService], module: DbModule, providers: [DbService] };
10
+ }
11
+ }
12
+ {{else}}
1
13
  import { DynamicModule, Module, Global, Provider } from '@nestjs/common';
2
14
  import { DbService } from './db.service.js';
3
15
 
4
16
  {{#if usePrisma}}
5
- {{#if isMonorepo}}
6
- import { PrismaClient } from '../database/orm/prisma/generated/client.js';
7
- {{else}}
17
+ {{#if isMonorepo}}
18
+ {{#if isPrisma6}}
19
+ import { PrismaClient } from '@prisma/client';
20
+ {{else}}
21
+ import { PrismaClient } from './database/orm/prisma/generated/client.js';
22
+ {{/if}}
23
+ {{else}}
24
+ {{#if isPrisma6}}
25
+ import { PrismaClient } from '@prisma/client';
26
+ {{else}}
8
27
  import { PrismaClient } from '../database/orm/prisma/generated/client.js';
9
- {{/if}}
28
+ {{/if}}
29
+ {{/if}}
10
30
  {{#if (or hasPostgres hasMysql hasSqlite)}}
11
31
  import { PrismaSqlAdapter } from './adapters/sql/prisma-sql.adapter.js';
12
32
  {{/if}}
@@ -26,7 +46,11 @@ import { PrismaMongoAdapter } from './adapters/mongo/prisma-mongo.adapter.js';
26
46
 
27
47
  {{#if useDrizzle}}
28
48
  import { DrizzleSqlAdapter } from './adapters/sql/drizzle-sql.adapter.js';
49
+ {{#if isMonorepo}}
50
+ import * as schema from './database/orm/drizzle/schema.js';
51
+ {{else}}
29
52
  import * as schema from './orm/drizzle/schema.js';
53
+ {{/if}}
30
54
  {{#if hasPostgres}}
31
55
  import { drizzle } from 'drizzle-orm/node-postgres';
32
56
  import { Pool } from "pg"
@@ -86,8 +110,13 @@ export interface DbModuleOptions {
86
110
  @Global()
87
111
  @Module({})
88
112
  export class DbModule {
113
+ {{#if (or usePrisma useDrizzle useRawSql)}}
89
114
  static forRoot(options: DbModuleOptions): DynamicModule {
90
- const providers: Provider[] = [DbService];
115
+ {{else}}
116
+ static forRoot(_options: DbModuleOptions): DynamicModule {
117
+ {{/if}}
118
+ const initialProviders: Provider[] = [DbService];
119
+ const providers = initialProviders;
91
120
 
92
121
  {{#if usePrisma}}
93
122
  {{#if (or hasPostgres hasMysql hasSqlite)}}
@@ -98,7 +127,10 @@ export class DbModule {
98
127
  const prismaSql = new PrismaClient({ adapter: sqlAdapter });
99
128
  {{/if}}
100
129
  {{#if hasMysql}}
101
- const sqlAdapter = new PrismaMariaDb(options.mysqlUrl!);
130
+ if (!options.mysqlUrl) {
131
+ throw new Error("A MySQL URL is required to initialize Prisma");
132
+ }
133
+ const sqlAdapter = new PrismaMariaDb(options.mysqlUrl);
102
134
  const prismaSql = new PrismaClient({ adapter: sqlAdapter });
103
135
  {{/if}}
104
136
  {{#if hasSqlite}}
@@ -137,47 +169,28 @@ export class DbModule {
137
169
  {{/if}}
138
170
 
139
171
  {{#if useDrizzle}}
140
- {{#if hasPostgres}}
141
- const pool = new Pool({
142
- connectionString: options.postgresUrl,
143
- });
144
- const drizzleClient = drizzle({ client: pool, schema });
145
- providers.push({
146
- provide: 'DRIZZLE_CLIENT',
147
- useValue: drizzleClient,
148
- });
149
- {{/if}}
150
- {{#if hasMysql}}
151
- const pool = mysql.createPool({
152
- uri: options.mysqlUrl,
153
- });
154
- const drizzleClient = drizzle({ client: pool, schema });
155
- providers.push({
156
- provide: 'DRIZZLE_CLIENT',
157
- useValue: drizzleClient,
158
- });
159
- {{/if}}
160
- {{#if hasSqlite}}
161
- const sqliteDb = new Database(options.sqlitePath || ':memory:');
162
- const drizzleClient = drizzle({ client: sqliteDb, schema });
163
172
  providers.push({
164
173
  provide: 'DRIZZLE_CLIENT',
165
- useValue: drizzleClient,
166
- });
167
- {{/if}}
168
-
169
- providers.push({
170
- provide: 'SQL_ADAPTER',
171
- useClass: DrizzleSqlAdapter,
174
+ useFactory: () => {
175
+ {{#if hasPostgres}}
176
+ const client = new Pool({ connectionString: options.postgresUrl });
177
+ return drizzle({ client, schema });
178
+ {{else if hasMysql}}
179
+ const client = mysql.createPool({ uri: options.mysqlUrl });
180
+ return drizzle(client, { schema, mode: "default" });
181
+ {{else}}
182
+ const client = new Database(options.sqlitePath || ':memory:');
183
+ return drizzle({ client, schema });
184
+ {{/if}}
185
+ },
172
186
  });
187
+ providers.push({ provide: 'SQL_ADAPTER', useClass: DrizzleSqlAdapter });
173
188
  {{/if}}
174
189
 
175
190
  {{#if useTypeorm}}
176
191
  providers.push({
177
192
  provide: 'TYPEORM_DATA_SOURCE',
178
- useFactory: async () => {
179
- return AppDataSource.initialize();
180
- },
193
+ useFactory: () => AppDataSource.initialize(),
181
194
  });
182
195
  providers.push({
183
196
  provide: 'SQL_ADAPTER',
@@ -220,11 +233,10 @@ export class DbModule {
220
233
  {{/if}}
221
234
 
222
235
  {{#if hasMongodb}}
223
- const mongoClient = new MongoClient(options.mongodbUrl || '');
224
- const mongoDb = mongoClient.db();
236
+ if (!options.mongodbUrl) throw new Error("A MongoDB URL is required");
225
237
  providers.push({
226
238
  provide: 'MONGODB_CLIENT',
227
- useValue: mongoDb,
239
+ useFactory: () => new MongoClient(options.mongodbUrl!, { serverSelectionTimeoutMS: 5000 }),
228
240
  });
229
241
  providers.push({
230
242
  provide: 'MONGO_ADAPTER',
@@ -240,3 +252,4 @@ export class DbModule {
240
252
  };
241
253
  }
242
254
  }
255
+ {{/if}}
@@ -1,3 +1,22 @@
1
+ {{#if isPrisma8}}
2
+ import { Injectable } from "@nestjs/common";
3
+ {{#if isMonorepo}}
4
+ import { db as prismaDb } from "../prisma/db.js";
5
+ {{else}}
6
+ import { db as prismaDb } from "../prisma/db.js";
7
+ {{/if}}
8
+
9
+ @Injectable()
10
+ export class DbService {
11
+ get prisma() {
12
+ return prismaDb;
13
+ }
14
+
15
+ get raw() {
16
+ return { sql: prismaDb };
17
+ }
18
+ }
19
+ {{else}}
1
20
  import { Injectable, Inject } from '@nestjs/common';
2
21
  {{#if (or hasPostgres hasMysql hasSqlite)}}
3
22
  import type { ISqlAdapter } from './adapters/interfaces/db-adapter.interface.js';
@@ -6,8 +25,20 @@ import type { ISqlAdapter } from './adapters/interfaces/db-adapter.interface.js'
6
25
  import type { IMongoAdapter } from './adapters/interfaces/db-adapter.interface.js';
7
26
  {{/if}}
8
27
  {{#if usePrisma}}
28
+ {{#if isMonorepo}}
29
+ {{#if isPrisma6}}
30
+ import type { PrismaClient } from '@prisma/client';
31
+ {{else}}
32
+ import type { PrismaClient } from './database/orm/prisma/generated/client.js';
33
+ {{/if}}
34
+ {{else}}
35
+ {{#if isPrisma6}}
36
+ import type { PrismaClient } from '@prisma/client';
37
+ {{else}}
9
38
  import type { PrismaClient } from './orm/prisma/generated/client.js';
10
39
  {{/if}}
40
+ {{/if}}
41
+ {{/if}}
11
42
  {{#if useDrizzle}}
12
43
  {{#if hasPostgres}}
13
44
  import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
@@ -16,10 +47,14 @@ import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
16
47
  import type { MySql2Database } from 'drizzle-orm/mysql2';
17
48
  {{/if}}
18
49
  {{#if hasSqlite}}
19
- import type { BetterSqlite3Database } from 'drizzle-orm/better-sqlite3';
50
+ import type { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
20
51
  {{/if}}
52
+ {{#if isMonorepo}}
53
+ import type * as schema from './database/orm/drizzle/schema.js';
54
+ {{else}}
21
55
  import type * as schema from './orm/drizzle/schema.js';
22
56
  {{/if}}
57
+ {{/if}}
23
58
  {{#if useTypeorm}}
24
59
  import type { DataSource } from 'typeorm';
25
60
  {{/if}}
@@ -29,8 +64,10 @@ type SqlClient = PrismaClient;
29
64
  {{else if useTypeorm}}
30
65
  type SqlClient = DataSource;
31
66
  {{else if useDrizzle}}
32
- type DrizzleClient = {{#if hasPostgres}}NodePgDatabase{{/if}}{{#if hasMysql}}MySql2Database{{/if}}{{#if hasSqlite}}BetterSqlite3Database{{/if}}<typeof schema>;
67
+ type DrizzleClient = {{#if hasPostgres}}NodePgDatabase{{/if}}{{#if hasMysql}}MySql2Database{{/if}}{{#if hasSqlite}}BetterSQLite3Database{{/if}}<typeof schema>;
33
68
  type SqlClient = DrizzleClient;
69
+ {{else if hasPostgres}}
70
+ type SqlClient = import('pg').Pool;
34
71
  {{else}}
35
72
  type SqlClient = unknown;
36
73
  {{/if}}
@@ -39,18 +76,26 @@ type SqlClient = unknown;
39
76
  {{#if usePrisma}}
40
77
  type MongoClient = PrismaClient;
41
78
  {{else}}
42
- type MongoClient = unknown;
79
+ type MongoClient = import('mongodb').Db;
43
80
  {{/if}}
44
81
  {{/if}}
45
82
 
83
+ {{#if isPrisma8}}
84
+ {{#if isMonorepo}}
85
+ import { db as prismaDb } from '../prisma/db.js';
86
+ {{else}}
87
+ import { db as prismaDb } from './prisma/db.js';
88
+ {{/if}}
89
+ {{/if}}
90
+
46
91
  @Injectable()
47
92
  export class DbService {
48
93
  constructor(
49
94
  {{#if (or hasPostgres hasMysql hasSqlite)}}
50
- @Inject('SQL_ADAPTER') public readonly sql: ISqlAdapter<SqlClient>{{#if hasMongodb}},{{/if}}
95
+ @Inject('SQL_ADAPTER') readonly sql: ISqlAdapter<SqlClient>{{#if hasMongodb}},{{/if}}
51
96
  {{/if}}
52
97
  {{#if hasMongodb}}
53
- @Inject('MONGO_ADAPTER') public readonly mongo: IMongoAdapter<MongoClient>
98
+ @Inject('MONGO_ADAPTER') readonly mongo: IMongoAdapter<MongoClient>
54
99
  {{/if}}
55
100
  ) {}
56
101
 
@@ -64,11 +109,19 @@ export class DbService {
64
109
  {{/if}}
65
110
  };
66
111
  }
67
- {{#if usePrisma}}
112
+ {{#if isPrisma8}}
113
+ get prisma() {
114
+ return prismaDb;
115
+ }
116
+ {{else if usePrisma}}
68
117
  {{#if (or hasPostgres hasMysql hasSqlite)}}
69
118
  get prisma(): PrismaClient {
70
119
  return this.sql.getClient();
71
120
  }
121
+ {{else if hasMongodb}}
122
+ get prisma(): PrismaClient {
123
+ return this.mongo.getClient();
124
+ }
72
125
  {{/if}}
73
126
  {{/if}}
74
127
  {{#if useDrizzle}}
@@ -86,3 +139,4 @@ export class DbService {
86
139
  {{/if}}
87
140
  {{/if}}
88
141
  }
142
+ {{/if}}
@@ -0,0 +1,25 @@
1
+ import {
2
+ Column,
3
+ CreateDateColumn,
4
+ Entity,
5
+ PrimaryGeneratedColumn,
6
+ UpdateDateColumn,
7
+ } from "typeorm";
8
+
9
+ @Entity("app_data")
10
+ export class AppEntity {
11
+ @PrimaryGeneratedColumn("uuid")
12
+ id: string;
13
+
14
+ @Column({ type: "varchar", length: 255, unique: true })
15
+ key: string;
16
+
17
+ @Column({ type: "text" })
18
+ value: string;
19
+
20
+ @CreateDateColumn({ name: "created_at" })
21
+ createdAt: Date;
22
+
23
+ @UpdateDateColumn({ name: "updated_at" })
24
+ updatedAt: Date;
25
+ }
@@ -15,18 +15,23 @@ export class Todo {
15
15
  @PrimaryGeneratedColumn("uuid")
16
16
  id: string;
17
17
 
18
- @Column({ length: 255 })
19
- description: string;
18
+ @Column({ type: "varchar", length: 255, nullable: true })
19
+ description?: string;
20
20
 
21
- @Column({ length: 100, nullable: true })
22
- name: string;
21
+ @Column({ type: "varchar", length: 255 })
22
+ title: string;
23
23
 
24
24
  @Column({ default: false, name: "is_completed", type: "boolean" })
25
- isCompleted: boolean;
25
+ completed: boolean;
26
26
 
27
- @CreateDateColumn({ name: "created_at", type: "timestamptz" })
27
+ {{#if hasAuth}}
28
+ @Column({ type: "varchar", nullable: true })
29
+ authorId?: string;
30
+ {{/if}}
31
+
32
+ @CreateDateColumn({ name: "created_at" })
28
33
  createdAt: Date;
29
34
 
30
- @UpdateDateColumn({ name: "updated_at", type: "timestamptz" })
35
+ @UpdateDateColumn({ name: "updated_at" })
31
36
  updatedAt: Date;
32
37
  }
@@ -1,10 +1,30 @@
1
1
  // oxlint-disable oxc/no-barrel-file
2
+ // biome-ignore-all lint/performance/noBarrelFile: Public entry point shared with the monorepo database package.
2
3
  export * from './db.module.js';
3
4
  export * from './db.service.js';
5
+ {{#if usePrisma}}
6
+ {{#if isPrisma6}}
7
+ export type { PrismaClient, Todo } from '@prisma/client';
8
+ {{else}}
9
+ {{#if isMonorepo}}
10
+ export type { PrismaClient, Todo } from './database/orm/prisma/generated/client.js';
11
+ {{else}}
12
+ export type { PrismaClient, Todo } from './orm/prisma/generated/client.js';
13
+ {{/if}}
14
+ {{/if}}
15
+ {{/if}}
4
16
  export * from './adapters/interfaces/db-adapter.interface.js';
5
17
  {{#if useDrizzle}}
18
+ {{#if isMonorepo}}
19
+ export * from './database/orm/drizzle/schema.js';
20
+ {{else}}
6
21
  export * from './orm/drizzle/schema.js';
7
22
  {{/if}}
23
+ {{/if}}
8
24
  {{#if useTypeorm}}
25
+ {{#if isMonorepo}}
26
+ export * from './database/orm/typeorm/data-source.js';
27
+ {{else}}
9
28
  export * from './orm/typeorm/data-source.js';
10
29
  {{/if}}
30
+ {{/if}}
@@ -1,30 +1,103 @@
1
1
  // oxlint-disable typescript/no-explicit-any
2
+ {{#if (eq auth "better-auth")}}
3
+ // oxlint-disable-next-line oxc/no-barrel-file
4
+ export * from "./auth-schema.js";
5
+ {{/if}}
2
6
  {{#if hasPostgres}}
3
- import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';
7
+ import { {{#if hasTodoExample}}boolean, {{/if}}pgTable{{#if (or (not isPassportAuth) hasTodoExample)}}, serial{{/if}}, text, timestamp } from 'drizzle-orm/pg-core';
4
8
 
9
+ {{#unless (eq auth "better-auth")}}
5
10
  export const users = pgTable('users', {
11
+ email: text('email').unique(),
12
+ {{#if isPassportAuth}}
13
+ id: text('id').primaryKey(),
14
+ {{else}}
6
15
  id: serial('id').primaryKey(),
16
+ {{/if}}
7
17
  name: text('name'),
8
- email: text('email').unique(),
9
18
  createdAt: timestamp('created_at').defaultNow(),
19
+ {{#if isPassportAuth}}
20
+ password: text('password').notNull(),
21
+ firstname: text('firstname'),
22
+ lastname: text('lastname'),
23
+ role: text('role').default('USER'),
24
+ {{/if}}
10
25
  });
26
+ {{/unless}}
27
+ {{#if hasTodoExample}}
28
+ export const todos = pgTable('todos', {
29
+ {{#if hasAuth}}
30
+ authorId: text('author_id'),
31
+ {{/if}}
32
+ completed: boolean('completed').notNull().default(false),
33
+ description: text('description'),
34
+ id: serial('id').primaryKey(),
35
+ title: text('title').notNull(),
36
+ });
37
+ {{/if}}
11
38
  {{/if}}
12
39
  {{#if hasMysql}}
13
- import { mysqlTable, serial, text, timestamp } from 'drizzle-orm/mysql-core';
40
+ import { {{#if hasTodoExample}}boolean, {{/if}}mysqlTable{{#if (or (not isPassportAuth) hasTodoExample)}}, int{{/if}}, text, timestamp, varchar } from 'drizzle-orm/mysql-core';
14
41
 
42
+ {{#unless (eq auth "better-auth")}}
15
43
  export const users = mysqlTable('users', {
16
- id: serial('id').primaryKey(),
44
+ email: varchar('email', { length: 320 }).unique(),
45
+ {{#if isPassportAuth}}
46
+ id: varchar('id', { length: 255 }).primaryKey(),
47
+ {{else}}
48
+ id: int('id').autoincrement().primaryKey(),
49
+ {{/if}}
17
50
  name: text('name'),
18
- email: text('email').unique(),
19
51
  createdAt: timestamp('created_at').defaultNow(),
52
+ {{#if isPassportAuth}}
53
+ password: text('password').notNull(),
54
+ firstname: text('firstname'),
55
+ lastname: text('lastname'),
56
+ role: text('role').default('USER'),
57
+ {{/if}}
58
+ });
59
+ {{/unless}}
60
+ {{#if hasTodoExample}}
61
+ export const todos = mysqlTable('todos', {
62
+ {{#if hasAuth}}
63
+ authorId: text('author_id'),
64
+ {{/if}}
65
+ completed: boolean('completed').notNull().default(false),
66
+ description: text('description'),
67
+ id: int('id').autoincrement().primaryKey(),
68
+ title: text('title').notNull(),
20
69
  });
21
70
  {{/if}}
71
+ {{/if}}
22
72
  {{#if hasSqlite}}
23
- import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
73
+ import { sqliteTable{{#if (or (not isPassportAuth) hasTodoExample)}}, integer{{/if}}, text } from 'drizzle-orm/sqlite-core';
24
74
 
75
+ {{#unless (eq auth "better-auth")}}
25
76
  export const users = sqliteTable('users', {
77
+ email: text('email').unique(),
78
+ {{#if isPassportAuth}}
79
+ id: text('id').primaryKey(),
80
+ {{else}}
26
81
  id: integer('id').primaryKey({ autoIncrement: true }),
82
+ {{/if}}
27
83
  name: text('name'),
28
- email: text('email').unique(),
84
+ {{#if isPassportAuth}}
85
+ password: text('password').notNull(),
86
+ firstname: text('firstname'),
87
+ lastname: text('lastname'),
88
+ role: text('role').default('USER'),
89
+ {{/if}}
29
90
  });
91
+ {{/unless}}
92
+ {{#if hasTodoExample}}
93
+ export const todos = sqliteTable('todos', {
94
+ {{#if hasAuth}}
95
+ authorId: text('author_id'),
96
+ {{/if}}
97
+ completed: integer('completed', { mode: 'boolean' }).notNull().default(false),
98
+ description: text('description'),
99
+ id: integer('id').primaryKey({ autoIncrement: true }),
100
+ title: text('title').notNull(),
101
+ });
102
+ {{/if}}
30
103
  {{/if}}
@@ -1,10 +1,23 @@
1
1
  // oxlint-disable typescript/no-non-null-assertion
2
- import { join } from "node:path";
3
2
  import "reflect-metadata";
3
+ {{#if isMonorepo}}
4
+ import { env } from "@repo/env/api-gateway";
5
+ {{else}}
6
+ import { env } from "../../../config/env.js";
7
+ {{/if}}
4
8
  import { DataSource } from "typeorm";
9
+ {{#if hasTodoExample}}
10
+ import { Todo } from "../../entities/todo.entity.js";
11
+ {{/if}}
12
+ {{#if (and useTypeorm isPassportAuth)}}
13
+ import { UserEntity } from "../../../modules/users/entities/user.entity.js";
14
+ {{/if}}
15
+ {{#if (eq auth "better-auth:stateless")}}
16
+ import { AppEntity } from "../../entities/app.entity.js";
17
+ {{/if}}
5
18
 
6
19
  const databaseUrl =
7
- process.env.{{#if hasPostgres}}POSTGRES_URL{{/if}}{{#if hasMysql}}MYSQL_URL{{/if}}{{#if hasSqlite}}SQLITE_PATH{{/if}}!;
20
+ env.{{#if hasPostgres}}POSTGRES_URL{{/if}}{{#if hasMysql}}MYSQL_URL{{/if}}{{#if hasSqlite}}SQLITE_PATH{{/if}};
8
21
 
9
22
  {{#unless hasSqlite}}
10
23
  const parsedUrl = new URL(databaseUrl);
@@ -12,11 +25,17 @@ const parsedUrl = new URL(databaseUrl);
12
25
 
13
26
 
14
27
  export const AppDataSource = new DataSource({
15
- entities: [join(import.meta.dirname, "..", "..", "entities", "*.entity.js")],
28
+ {{#if hasSqlite}}
29
+ database: databaseUrl,
30
+ {{/if}}
31
+ // Register entities explicitly for consistent metadata in Node and test runners.
32
+ entities: [{{#if hasTodoExample}}Todo{{/if}}{{#if (and hasTodoExample (and useTypeorm isPassportAuth))}}, {{/if}}{{#if (and useTypeorm isPassportAuth)}}UserEntity{{/if}}{{#if (eq auth "better-auth:stateless")}}{{#if (or hasTodoExample (and useTypeorm isPassportAuth))}}, {{/if}}AppEntity{{/if}}],
16
33
  migrations: [{{#if isMonorepo}}"migrations/*.{ts,js}"{{else}}"migrations/*.{ts,js}"{{/if}}],
17
- synchronize: true,
34
+ synchronize: env.NODE_ENV === "development",
18
35
  type: "{{#if hasPostgres}}postgres{{/if}}{{#if hasMysql}}mysql{{/if}}{{#if hasSqlite}}better-sqlite3{{/if}}",
36
+ {{#unless hasSqlite}}
19
37
  url: databaseUrl,
38
+ {{/unless}}
20
39
  {{#unless hasSqlite}}
21
40
  ...(parsedUrl.username ? { username: decodeURIComponent(parsedUrl.username) } : {}),
22
41
  ...(parsedUrl.password ? { password: decodeURIComponent(parsedUrl.password) } : {}),