@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.
- package/README.md +20 -42
- package/dist/cli.js +1 -1
- package/dist/constants-B5MuV-iH.js +1 -0
- package/dist/index.js +365 -98
- package/dist/templates/addons/husky/pre-commit.hbs +11 -26
- package/dist/templates/base/.env.example.hbs +13 -2
- package/dist/templates/base/.env.hbs +11 -2
- package/dist/templates/base/.gitignore.hbs +2 -1
- package/dist/templates/base/.yarnrc.yml.hbs +0 -5
- package/dist/templates/base/README.md.hbs +49 -5
- package/dist/templates/base/nest-cli.json.hbs +2 -1
- package/dist/templates/base/pnpm-workspace.yaml.hbs +15 -0
- package/dist/templates/base/prisma.config.ts.hbs +32 -6
- package/dist/templates/base/src/app.controller.spec.ts.hbs +3 -11
- package/dist/templates/base/src/app.controller.ts.hbs +2 -2
- package/dist/templates/base/src/app.module.ts.hbs +76 -5
- package/dist/templates/base/src/app.router.ts.hbs +3 -4
- package/dist/templates/base/src/database/adapters/interfaces/db-adapter.interface.ts.hbs +7 -0
- package/dist/templates/base/src/database/adapters/mongo/prisma-mongo.adapter.ts.hbs +36 -4
- package/dist/templates/base/src/database/adapters/mongo/raw-mongo.adapter.ts.hbs +17 -12
- package/dist/templates/base/src/database/adapters/sql/drizzle-sql.adapter.ts.hbs +9 -0
- package/dist/templates/base/src/database/adapters/sql/prisma-sql.adapter.ts.hbs +8 -5
- package/dist/templates/base/src/database/adapters/sql/raw-sql.adapter.ts.hbs +37 -0
- package/dist/templates/base/src/database/adapters/sql/typeorm-sql.adapter.ts.hbs +8 -3
- package/dist/templates/base/src/database/db.module.ts.hbs +55 -42
- package/dist/templates/base/src/database/db.service.ts.hbs +60 -6
- package/dist/templates/base/src/database/entities/app.entity.ts.hbs +25 -0
- package/dist/templates/base/src/database/entities/todo.entity.ts.hbs +12 -7
- package/dist/templates/base/src/database/index.ts.hbs +20 -0
- package/dist/templates/base/src/database/orm/drizzle/schema.ts.hbs +80 -7
- package/dist/templates/base/src/database/orm/typeorm/data-source.ts.hbs +23 -4
- package/dist/templates/base/src/libs/middlewares/auth.trpc.middleware.ts.hbs +47 -0
- package/dist/templates/base/src/libs/middlewares/rate-limit.trpc.middleware.ts.hbs +43 -0
- package/dist/templates/base/src/libs/trpc/error.handler.ts.hbs +1 -1
- package/dist/templates/base/src/libs/trpc/inner.context.ts.hbs +6 -3
- package/dist/templates/base/src/main.ts.hbs +34 -10
- package/dist/templates/base/src/modules/users/entities/user.entity.ts.hbs +22 -0
- package/dist/templates/base/test/app.e2e-spec.ts.hbs +841 -6
- package/dist/templates/base/test/bootstrap.e2e-spec.ts.hbs +84 -0
- package/dist/templates/base/tsconfig.build.json.hbs +2 -0
- package/dist/templates/base/vitest.config.e2e.ts.hbs +4 -3
- package/dist/templates/base/vitest.config.ts.hbs +4 -3
- package/dist/templates/base/yarn.lock.hbs +1 -0
- package/dist/templates/extras/docker/.dockerignore.hbs +8 -1
- package/dist/templates/extras/docker/Dockerfile.hbs +11 -10
- package/dist/templates/extras/health/src/health/health.controller.ts.hbs +54 -0
- package/dist/templates/extras/health/src/health/health.module.ts.hbs +9 -0
- package/dist/templates/extras/swagger/create-docs.ts.hbs +13 -22
- package/dist/templates/feature/graphql/src/graphql/graphql.module.ts.hbs +6 -10
- package/dist/templates/feature/graphql/src/graphql/models/todo.model.ts.hbs +4 -0
- package/dist/templates/feature/graphql/src/graphql/orm/drizzle/drizzle-graphql.module.ts.hbs +6 -4
- package/dist/templates/feature/graphql/src/graphql/resolvers/health.resolver.ts.hbs +14 -0
- package/dist/templates/feature/graphql/src/graphql/resolvers/todo.resolver.ts.hbs +210 -47
- package/dist/templates/feature/rest/todo-example/src/api/todo/dto/create-todo.dto.ts.hbs +12 -0
- package/dist/templates/feature/rest/todo-example/src/api/todo/dto/update-todo.dto.ts.hbs +12 -0
- package/dist/templates/feature/rest/todo-example/src/api/todo/todo.controller.ts.hbs +21 -9
- package/dist/templates/feature/rest/todo-example/src/api/todo/todo.module.ts.hbs +1 -3
- package/dist/templates/feature/rest/todo-example/src/api/todo/todo.router.ts.hbs +41 -13
- package/dist/templates/feature/rest/todo-example/src/api/todo/todo.service.ts.hbs +157 -33
- package/dist/templates/monorepo/apps/api-gateway/package.json.hbs +2 -3
- package/dist/templates/monorepo/apps/api-gateway/src/app.controller.spec.ts.hbs +6 -1
- package/dist/templates/monorepo/apps/api-gateway/src/app.controller.ts.hbs +6 -0
- package/dist/templates/monorepo/apps/api-gateway/src/app.module.ts.hbs +32 -1
- package/dist/templates/monorepo/apps/api-gateway/src/app.service.ts.hbs +1 -1
- package/dist/templates/monorepo/apps/api-gateway/src/main.ts.hbs +13 -4
- package/dist/templates/monorepo/apps/api-gateway/test/app.e2e-spec.ts.hbs +45 -1
- package/dist/templates/monorepo/apps/api-gateway/tsconfig.build.json.hbs +2 -1
- package/dist/templates/monorepo/apps/api-gateway/vitest.config.e2e.ts.hbs +3 -2
- package/dist/templates/monorepo/apps/api-gateway/vitest.config.ts.hbs +3 -2
- package/dist/templates/monorepo/feature/graphql/src/graphql/graphql.module.ts.hbs +6 -10
- package/dist/templates/monorepo/feature/graphql/src/graphql/resolvers/health.resolver.ts.hbs +14 -0
- package/dist/templates/monorepo/feature/graphql/src/graphql/resolvers/todo.resolver.ts.hbs +151 -42
- package/dist/templates/monorepo/packages/env/src/api-gateway.ts.hbs +16 -3
- package/dist/templates/monorepo/packages/shared/package.json.hbs +1 -0
- package/dist/templates/monorepo/packages/shared/src/auth.ts.hbs +6 -0
- package/dist/templates/monorepo/root/.gitignore.hbs +1 -0
- package/dist/templates/monorepo/root/pnpm-workspace.yaml.hbs +19 -2
- package/dist/templates/monorepo/root/tsconfig.json.hbs +1 -1
- package/dist/templates/monorepo/root/turbo.json.hbs +2 -0
- package/dist/templates/single-project/architecture/nest-api/.env.hbs +9 -1
- package/dist/templates/single-project/architecture/nest-api/package.json.hbs +1 -2
- package/dist/templates/single-project/architecture/nest-api/src/main.ts.hbs +33 -9
- package/dist/templates/single-project/architecture/nest-gateway/src/main.ts.hbs +3 -3
- package/dist/templates/single-project/architecture/nest-microservice/.env.hbs +18 -0
- package/dist/templates/single-project/architecture/nest-microservice/proto/app.proto.hbs +26 -0
- package/dist/templates/single-project/architecture/nest-microservice/src/app.controller.ts.hbs +23 -4
- package/dist/templates/single-project/architecture/nest-microservice/src/app.service.ts.hbs +6 -2
- package/dist/templates/single-project/architecture/nest-microservice/src/main.ts.hbs +16 -5
- package/dist/templates/single-project/architecture/nest-microservice/test/microservice.e2e-spec.ts.hbs +70 -0
- package/dist/templates/single-project/shared/config/env.ts.hbs +38 -3
- package/package.json +5 -2
- 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 '
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
11
|
+
query<T = unknown>(sql: string, params: unknown[] = []): Promise<T[]> {
|
|
13
12
|
return this.dataSource.query(sql, params);
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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}}
|
|
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 =
|
|
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')
|
|
95
|
+
@Inject('SQL_ADAPTER') readonly sql: ISqlAdapter<SqlClient>{{#if hasMongodb}},{{/if}}
|
|
51
96
|
{{/if}}
|
|
52
97
|
{{#if hasMongodb}}
|
|
53
|
-
@Inject('MONGO_ADAPTER')
|
|
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
|
|
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
|
|
18
|
+
@Column({ type: "varchar", length: 255, nullable: true })
|
|
19
|
+
description?: string;
|
|
20
20
|
|
|
21
|
-
@Column({
|
|
22
|
-
|
|
21
|
+
@Column({ type: "varchar", length: 255 })
|
|
22
|
+
title: string;
|
|
23
23
|
|
|
24
24
|
@Column({ default: false, name: "is_completed", type: "boolean" })
|
|
25
|
-
|
|
25
|
+
completed: boolean;
|
|
26
26
|
|
|
27
|
-
|
|
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"
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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) } : {}),
|