@nest-arch/tui 0.4.6 → 0.5.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 (55) hide show
  1. package/README.md +31 -0
  2. package/dist/cli.js +2 -1
  3. package/dist/constants-CUTbfu9C.js +1 -0
  4. package/dist/index.js +6 -405
  5. package/dist/nonInteractive-C1KZ0b_6.js +5 -0
  6. package/dist/nonInteractiveOptions-CIaoLAWg.js +24 -0
  7. package/dist/projectGeneratorService-CeWJK-HA.js +420 -0
  8. package/dist/projectName-CcE90t2V.js +1 -0
  9. package/dist/templates/addons/husky/pre-commit.hbs +1 -1
  10. package/dist/templates/base/.env.example.hbs +30 -2
  11. package/dist/templates/base/.env.hbs +7 -2
  12. package/dist/templates/base/README.md.hbs +11 -2
  13. package/dist/templates/base/pnpm-workspace.yaml.hbs +9 -4
  14. package/dist/templates/base/prisma.config.ts.hbs +6 -1
  15. package/dist/templates/base/src/app.controller.spec.ts.hbs +6 -0
  16. package/dist/templates/base/src/app.module.ts.hbs +6 -23
  17. package/dist/templates/base/src/database/adapters/interfaces/db-adapter.interface.ts.hbs +5 -5
  18. package/dist/templates/base/src/database/adapters/mongo/raw-mongo.adapter.ts.hbs +6 -4
  19. package/dist/templates/base/src/database/adapters/mongo/typeorm-mongo.adapter.ts.hbs +27 -0
  20. package/dist/templates/base/src/database/db.module.ts.hbs +33 -13
  21. package/dist/templates/base/src/database/db.service.ts.hbs +12 -4
  22. package/dist/templates/base/src/database/entities/todo.entity.ts.hbs +17 -5
  23. package/dist/templates/base/src/database/index.ts.hbs +2 -0
  24. package/dist/templates/base/src/database/orm/drizzle/schema.ts.hbs +80 -20
  25. package/dist/templates/base/src/database/orm/typeorm/data-source.ts.hbs +34 -12
  26. package/dist/templates/base/src/libs/middlewares/graphql-throttler.guard.ts.hbs +22 -0
  27. package/dist/templates/base/src/libs/middlewares/rate-limit.trpc.middleware.ts.hbs +2 -1
  28. package/dist/templates/base/src/libs/trpc/inner.context.ts.hbs +2 -2
  29. package/dist/templates/base/src/main.ts.hbs +2 -2
  30. package/dist/templates/base/test/app.e2e-spec.ts.hbs +378 -202
  31. package/dist/templates/extras/docker/Dockerfile.hbs +9 -2
  32. package/dist/templates/extras/health/src/health/health.controller.ts.hbs +12 -1
  33. package/dist/templates/extras/swagger/create-docs.ts.hbs +6 -1
  34. package/dist/templates/feature/graphql/src/graphql/models/todo.model.ts.hbs +1 -1
  35. package/dist/templates/feature/graphql/src/graphql/resolvers/todo.resolver.ts.hbs +1 -1
  36. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.controller.ts.hbs +80 -7
  37. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.router.ts.hbs +4 -4
  38. package/dist/templates/feature/rest/todo-example/src/api/todo/todo.service.ts.hbs +314 -34
  39. package/dist/templates/monorepo/apps/api-gateway/src/main.ts.hbs +2 -2
  40. package/dist/templates/monorepo/root/README.md.hbs +8 -13
  41. package/dist/templates/single-project/architecture/nest-api/.env.hbs +6 -2
  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 +2 -2
  44. package/dist/templates/single-project/architecture/nest-gateway/src/main.ts.hbs +2 -2
  45. package/dist/templates/single-project/architecture/nest-microservice/.env.hbs +30 -1
  46. package/dist/templates/single-project/architecture/nest-microservice/proto/app.proto.hbs +13 -0
  47. package/dist/templates/single-project/architecture/nest-microservice/src/app.controller.ts.hbs +26 -2
  48. package/dist/templates/single-project/architecture/nest-microservice/src/app.module.ts.hbs +61 -1
  49. package/dist/templates/single-project/architecture/nest-microservice/src/app.service.ts.hbs +16 -4
  50. package/dist/templates/single-project/architecture/nest-microservice/src/http-throttler.guard.ts.hbs +13 -0
  51. package/dist/templates/single-project/architecture/nest-microservice/src/main.ts.hbs +26 -7
  52. package/dist/templates/single-project/architecture/nest-microservice/test/microservice.e2e-spec.ts.hbs +7 -87
  53. package/dist/templates/single-project/shared/config/env.ts.hbs +14 -14
  54. package/package.json +6 -5
  55. package/dist/constants-DVhgS48N.js +0 -1
@@ -0,0 +1 @@
1
+ var a=Object.defineProperty;var r=(e,t)=>a(e,"name",{value:t,configurable:!0});const s="my-nest-app",m=64,n=/^[a-z][a-z0-9-]*$/u;function E(e){return e.trim()||s}r(E,"resolveProjectName");function o(e){const t=e.trim();return t?t.length>64?"Project name must be at most 64 characters":n.test(t)?null:"Use lowercase letters, numbers, and hyphens; must start with a letter":null}r(o,"validateProjectName");export{s as D,m as M,n as P,E as r,o as v};
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
  set -e
3
3
 
4
- {{#if isPnpm}}pnpm test{{else if isYarn}}yarn test{{else if isBun}}bun run test{{else}}npm test{{/if}}
4
+ {{#if isPnpm}}pnpm test --passWithNoTests{{else if isYarn}}yarn test --passWithNoTests{{else if isBun}}bun run test --passWithNoTests{{else}}npm test -- --passWithNoTests{{/if}}
5
5
 
6
6
  {{#if hasFormatter}}
7
7
  STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR)
@@ -1,10 +1,33 @@
1
1
  # Server
2
2
  PORT=3000
3
3
  NODE_ENV=development
4
- CORS_ORIGIN=http://localhost:3001
4
+ CORS_ORIGIN=http://localhost:3000
5
5
  # Comma-separated trusted reverse proxy IP addresses or CIDRs
6
6
  TRUSTED_PROXY_IPS={{#each trustedProxyIps}}{{#unless @first}},{{/unless}}{{this}}{{/each}}
7
7
 
8
+ {{#if (eq architecture "nest-microservice")}}
9
+ # Microservice transport
10
+ MICROSERVICE_PORT=3001
11
+ {{/if}}
12
+ {{#if (includes microservices "redis")}}
13
+ REDIS_URL=redis://127.0.0.1:6379
14
+ {{/if}}
15
+ {{#if (includes microservices "mqtt")}}
16
+ MQTT_URL=mqtt://127.0.0.1:1883
17
+ {{/if}}
18
+ {{#if (includes microservices "nats")}}
19
+ NATS_URL=nats://127.0.0.1:4222
20
+ {{/if}}
21
+ {{#if (includes microservices "rabbitmq")}}
22
+ RABBITMQ_URL=amqp://127.0.0.1:5672
23
+ {{/if}}
24
+ {{#if (includes microservices "kafka")}}
25
+ KAFKA_BROKER=127.0.0.1:9092
26
+ {{/if}}
27
+ {{#if (includes microservices "grpc")}}
28
+ GRPC_URL=0.0.0.0:5000
29
+ {{/if}}
30
+
8
31
  {{#if hasDatabase}}
9
32
  # Database
10
33
  {{/if}}
@@ -35,7 +58,12 @@ MONGODB_URL=mongodb://localhost:27017/{{projectNameKebab}}_db
35
58
  GRAPHQL_PLAYGROUND=true
36
59
 
37
60
  {{/if}}
38
- {{#if (eq auth "passport")}}
61
+ {{#if (and (eq auth "passport") (not hasDatabase))}}
62
+ # External identity provider (RS256 JWKS)
63
+ OIDC_JWKS_URI=https://identity.example.com/.well-known/jwks.json
64
+ OIDC_ISSUER=https://identity.example.com/
65
+ OIDC_AUDIENCE=generated-resource-server
66
+ {{else if (eq auth "passport")}}
39
67
  # JWT
40
68
  JWT_ACCESS_SECRET=change-me-to-a-random-secret-at-least-32-characters-long
41
69
  {{#if hasDatabase}}
@@ -1,4 +1,4 @@
1
- CORS_ORIGIN=http://localhost:3001
1
+ CORS_ORIGIN=http://localhost:3000
2
2
  PORT=3000
3
3
  TRUSTED_PROXY_IPS={{#each trustedProxyIps}}{{#unless @first}},{{/unless}}{{this}}{{/each}}
4
4
  {{#if hasGraphql}}
@@ -26,7 +26,12 @@ SQLSERVER_TRUST_SERVER_CERTIFICATE=true
26
26
  {{#if hasMongodb}}
27
27
  MONGODB_URL=mongodb://localhost:27017/{{projectNameKebab}}_db
28
28
  {{/if}}
29
- {{#if (eq auth "passport")}}
29
+ {{#if (and (eq auth "passport") (not hasDatabase))}}
30
+ # External identity provider (RS256 JWKS)
31
+ OIDC_JWKS_URI=https://identity.example.com/.well-known/jwks.json
32
+ OIDC_ISSUER=https://identity.example.com/
33
+ OIDC_AUDIENCE=generated-resource-server
34
+ {{else if (eq auth "passport")}}
30
35
  JWT_ACCESS_SECRET=change-me-to-a-random-secret-at-least-32-characters-long
31
36
  {{#if hasDatabase}}
32
37
  JWT_REFRESH_SECRET=change-me-to-a-different-random-secret-at-least-32-characters
@@ -4,10 +4,14 @@
4
4
 
5
5
  ## Setup
6
6
 
7
+ {{#if setupInstructions}}
8
+ {{{setupInstructions}}}
9
+ {{else}}
7
10
  ```bash
8
11
  # Install dependencies
9
12
  {{#if isPnpm}}pnpm install{{else if isYarn}}yarn install{{else if isBun}}bun install{{else}}npm install{{/if}}
10
13
  ```
14
+ {{/if}}
11
15
 
12
16
  ## Running the App
13
17
 
@@ -98,9 +102,14 @@ This project uses **Better Auth** with database-backed sessions. Set `BETTER_AUT
98
102
 
99
103
  Run `auth:generate` with your package manager. The script uses the installed CLI version.
100
104
  {{#if usePrisma}}
101
- Then run `prisma:generate`, `prisma:migrate --name auth`, and `build`. For deployments, apply the committed migrations with `prisma:migrate:deploy`. Auth models live in `src/database/orm/prisma/auth.prisma`; keep application models in `schema.prisma` or other files in that directory. `auth:generate` replaces only the auth-owned file (using `auth-schema.prisma` as CLI output). Inspect that diff after changing plugins.
105
+ {{#if hasMongodb}}
106
+ `auth:generate` normalizes MongoDB IDs and writes auth models to `src/database/orm/prisma/auth.prisma`, using `auth-schema.prisma` as intermediate CLI output. Then run `prisma:push` and `prisma:generate`, as shown in Setup.
107
+ {{else}}
108
+ `auth:generate` updates auth models in `src/database/orm/prisma/schema.prisma`. For local development, run `prisma:push` and then `prisma:generate`, as shown in Setup. For a workflow with migration history, use `prisma:migrate --name auth` instead of pushing the schema and then regenerate the client. For deployments, apply the committed migrations with `prisma:migrate:deploy`.
109
+ {{/if}}
110
+ Inspect the schema diff after changing plugins.
102
111
  {{else if useDrizzle}}
103
- Then run `db:generate`, `db:migrate`, and `build`. Auth owns `src/database/orm/drizzle/auth-schema.ts`; application tables remain in `schema.ts`. Commit generated migration files. SQLite requires no Docker service.
112
+ For local development, run `db:push`, as shown in Setup. For a workflow with migration history, use `db:generate` and `db:migrate` instead. Auth owns `src/database/orm/drizzle/auth-schema.ts`; application tables remain in `schema.ts`. Commit generated migration files. SQLite requires no Docker service.
104
113
  {{else}}
105
114
  Then run `auth:migrate` and `build`.
106
115
  {{/if}}
@@ -1,12 +1,9 @@
1
1
  allowBuilds:
2
- {{#if useDrizzle}}
2
+ {{#if (or useDrizzle useTypescript7)}}
3
3
  esbuild: true
4
4
  {{/if}}
5
5
  protobufjs: true
6
6
  "@nestjs/core": true
7
- {{#if useTypescript7}}
8
- esbuild: true
9
- {{/if}}
10
7
  {{#if swagger}}
11
8
  "@scarf/scarf": true
12
9
  {{/if}}
@@ -20,7 +17,9 @@ allowBuilds:
20
17
  "@prisma/client": true
21
18
  {{/if}}
22
19
  {{#if isPrisma8}}
20
+ {{#unless (or useDrizzle useTypescript7)}}
23
21
  esbuild: true
22
+ {{/unless}}
24
23
  msgpackr-extract: true
25
24
  workerd: true
26
25
  {{/if}}
@@ -31,3 +30,9 @@ allowBuilds:
31
30
  {{#if hasSqlite}}
32
31
  better-sqlite3: true
33
32
  {{/if}}
33
+ {{#if hasTrpc}}
34
+ peerDependencyRules:
35
+ allowedVersions:
36
+ "nestjs-trpc>@nestjs/common": "^12.0.0"
37
+ "nestjs-trpc>@nestjs/core": "^12.0.0"
38
+ {{/if}}
@@ -26,7 +26,6 @@ export default definePrismaConfig({
26
26
  import { defineConfig } from "prisma/config";
27
27
 
28
28
  export default defineConfig({
29
- schema: "src/database/orm/prisma{{#unless isBetterAuth}}/schema.prisma{{/unless}}",
30
29
  datasource: {
31
30
  {{#if hasPostgres}}url: env.POSTGRES_URL,{{/if}}
32
31
  {{#if hasMysql}}url: env.MYSQL_URL,{{/if}}
@@ -34,5 +33,11 @@ export default defineConfig({
34
33
  {{#if hasSqlserver}}url: `sqlserver://${env.SQLSERVER_HOST}:${env.SQLSERVER_PORT};database=${env.SQLSERVER_DATABASE};user={${env.SQLSERVER_USER.replaceAll("}", "}}")}};password={${env.SQLSERVER_PASSWORD.replaceAll("}", "}}")}};encrypt=${env.SQLSERVER_ENCRYPT};trustServerCertificate=${env.SQLSERVER_TRUST_SERVER_CERTIFICATE}`,{{/if}}
35
34
  {{#if hasMongodb}}url: env.MONGODB_URL,{{/if}}
36
35
  },
36
+ {{#unless isMonorepo}}
37
+ migrations: {
38
+ path: "src/database/orm/prisma/migrations",
39
+ },
40
+ {{/unless}}
41
+ schema: "src/database/orm/prisma{{#unless isBetterAuth}}/schema.prisma{{/unless}}",
37
42
  });
38
43
  {{/if}}
@@ -7,6 +7,9 @@ import { AppController } from "./app.controller.js";
7
7
  import { AppService } from "./app.service.js";
8
8
  {{#if (or hasDatabase hasOrm)}}
9
9
  import { DbService } from "./database/db.service.js";
10
+ {{#if (and (eq architecture "nest-microservice") hasTodoExample)}}
11
+ import { TodoService } from "./api/todo/todo.service.js";
12
+ {{/if}}
10
13
  {{/if}}
11
14
 
12
15
 
@@ -21,6 +24,9 @@ describe(AppController, () => {
21
24
  AppService,
22
25
  {{#if (or hasDatabase hasOrm)}}
23
26
  { provide: DbService, useValue: {} },
27
+ {{#if (and (eq architecture "nest-microservice") hasTodoExample)}}
28
+ { provide: TodoService, useValue: {} },
29
+ {{/if}}
24
30
  {{/if}}
25
31
  ],
26
32
  }).compile();
@@ -1,7 +1,4 @@
1
- import { Module{{#if (and hasGraphql hasRateLimiting)}}, Injectable, type ExecutionContext{{/if}} } from "@nestjs/common";
2
- {{#if (and hasGraphql hasRateLimiting)}}
3
- import { GqlExecutionContext } from "@nestjs/graphql";
4
- {{/if}}
1
+ import { Module } from "@nestjs/common";
5
2
  {{#if (and isPassportAuth hasDatabase)}}
6
3
  import { PassportModule } from "@nestjs/passport";
7
4
  {{/if}}
@@ -50,30 +47,16 @@ import { HealthModule } from "./health/health.module.js";
50
47
  {{/if}}
51
48
  {{#if hasRateLimiting}}
52
49
  import { APP_GUARD } from "@nestjs/core";
53
- import { ThrottlerGuard, ThrottlerModule } from "@nestjs/throttler";
50
+ import { {{#unless hasGraphql}}ThrottlerGuard, {{/unless}}ThrottlerModule } from "@nestjs/throttler";
51
+ {{/if}}
52
+ {{#if (and hasGraphql hasRateLimiting)}}
53
+ import { GraphqlThrottlerGuard } from "./libs/middlewares/graphql-throttler.guard.js";
54
54
  {{/if}}
55
55
  {{#if (and isPassportAuth hasDatabase hasGraphql (not hasRateLimiting))}}
56
56
  import { APP_GUARD } from "@nestjs/core";
57
57
  {{/if}}
58
58
  import { AppService } from "./app.service.js";
59
59
 
60
- {{#if (and hasGraphql hasRateLimiting)}}
61
- @Injectable()
62
- class GraphqlThrottlerGuard extends ThrottlerGuard {
63
- protected getRequestResponse(context: ExecutionContext) {
64
- if (context.getType<string>() !== "graphql") return super.getRequestResponse(context);
65
- const gqlContext = GqlExecutionContext.create(context).getContext();
66
- return { req: gqlContext.req, res: { header: () => undefined } };
67
- }
68
-
69
- protected getTracker(request: Record<string, unknown>): Promise<string> {
70
- const socket = request.socket as { remoteAddress?: string } | undefined;
71
- const ip = request.ip;
72
- return Promise.resolve(typeof ip === "string" ? ip : socket?.remoteAddress ?? "unknown");
73
- }
74
- }
75
- {{/if}}
76
-
77
60
  @Module({
78
61
  {{#if hasRest}}
79
62
  controllers: [
@@ -86,7 +69,7 @@ class GraphqlThrottlerGuard extends ThrottlerGuard {
86
69
  {{#if hasPostgres}}postgresUrl: env.POSTGRES_URL,{{/if}}
87
70
  {{#if hasMysql}}mysqlUrl: env.MYSQL_URL,{{/if}}
88
71
  {{#if hasSqlite}}sqlitePath: env.SQLITE_PATH,{{/if}}
89
- {{#if hasSqlserver}}sqlserver: { server: env.SQLSERVER_HOST, port: env.SQLSERVER_PORT, database: env.SQLSERVER_DATABASE, user: env.SQLSERVER_USER, password: env.SQLSERVER_PASSWORD, options: { encrypt: env.SQLSERVER_ENCRYPT, trustServerCertificate: env.SQLSERVER_TRUST_SERVER_CERTIFICATE } },{{/if}}
72
+ {{#if hasSqlserver}}sqlserver: { database: env.SQLSERVER_DATABASE, options: { encrypt: env.SQLSERVER_ENCRYPT, trustServerCertificate: env.SQLSERVER_TRUST_SERVER_CERTIFICATE }, password: env.SQLSERVER_PASSWORD, port: env.SQLSERVER_PORT, server: env.SQLSERVER_HOST, user: env.SQLSERVER_USER },{{/if}}
90
73
  {{#if hasMongodb}}mongodbUrl: env.MONGODB_URL,{{/if}}
91
74
  }),
92
75
  {{/if}}
@@ -1,3 +1,6 @@
1
+ {{#if (and hasMongodb (or useRawSql useTypeorm))}}
2
+ import type { Collection, Document } from "mongodb";
3
+ {{/if}}
1
4
  {{#if (or hasPostgres hasMysql hasSqlite hasSqlserver)}}
2
5
  export interface ISqlAdapter<TClient = unknown> {
3
6
  query: <T = unknown>(sql: string, params?: unknown[]) => Promise<T[]>;
@@ -7,12 +10,9 @@ export interface ISqlAdapter<TClient = unknown> {
7
10
  {{/if}}
8
11
 
9
12
  {{#if hasMongodb}}
10
- {{#if useRawSql}}
11
- import type { Collection, Document } from "mongodb";
12
- {{/if}}
13
13
  export interface IMongoAdapter<TClient = unknown> {
14
- {{#if useRawSql}}
15
- collection: <T extends Document = Document>(name: string) => Collection<T>;
14
+ {{#if (or useRawSql useTypeorm)}}
15
+ collection: <T = unknown>(name: string) => Collection<T & Document>;
16
16
  {{else}}
17
17
  collection: <T = unknown>(name: string) => T;
18
18
  {{/if}}
@@ -1,12 +1,14 @@
1
- import { Injectable, Inject, type OnModuleInit, type OnModuleDestroy } from "@nestjs/common";
2
- import { MongoClient, type Collection, type Db, type Document } from "mongodb";
1
+ import { Injectable, Inject } from "@nestjs/common";
2
+ import type { OnModuleDestroy, OnModuleInit } from "@nestjs/common";
3
+ import { MongoClient } from "mongodb";
4
+ import type { Collection, Db, Document } from "mongodb";
3
5
  import type { IMongoAdapter } from "../interfaces/db-adapter.interface.js";
4
6
 
5
7
  @Injectable()
6
8
  export class RawMongoAdapter implements IMongoAdapter<Db>, OnModuleInit, OnModuleDestroy {
7
9
  constructor(@Inject("MONGODB_CLIENT") private readonly client: MongoClient) {}
8
- collection<T extends Document = Document>(name: string): Collection<T> {
9
- return this.client.db().collection<T>(name);
10
+ collection<T = unknown>(name: string): Collection<T & Document> {
11
+ return this.client.db().collection<T & Document>(name);
10
12
  }
11
13
  getClient(): Db { return this.client.db(); }
12
14
  async onModuleInit(): Promise<void> {
@@ -0,0 +1,27 @@
1
+ import { Inject, Injectable } from "@nestjs/common";
2
+ import type { OnModuleDestroy } from "@nestjs/common";
3
+ import type { DataSource } from "typeorm";
4
+ import type { Collection, Document } from "mongodb";
5
+ import type { IMongoAdapter } from "../interfaces/db-adapter.interface.js";
6
+
7
+ @Injectable()
8
+ export class TypeormMongoAdapter implements IMongoAdapter<DataSource>, OnModuleDestroy {
9
+ constructor(@Inject("TYPEORM_DATA_SOURCE") private readonly dataSource: DataSource) {}
10
+
11
+ collection<T = unknown>(name: string): Collection<T & Document> {
12
+ const databaseName = this.dataSource.options.database;
13
+ return this.dataSource.mongoManager.mongoQueryRunner.databaseConnection
14
+ .db(typeof databaseName === "string" ? databaseName : undefined)
15
+ .collection(name) as unknown as Collection<T & Document>;
16
+ }
17
+
18
+ getClient(): DataSource {
19
+ return this.dataSource;
20
+ }
21
+
22
+ async onModuleDestroy(): Promise<void> {
23
+ if (this.dataSource.isInitialized) {
24
+ await this.dataSource.destroy();
25
+ }
26
+ }
27
+ }
@@ -66,10 +66,18 @@ import mysql from 'mysql2/promise';
66
66
  import { drizzle } from 'drizzle-orm/better-sqlite3';
67
67
  import Database from 'better-sqlite3';
68
68
  {{/if}}
69
+ {{#if hasSqlserver}}
70
+ import { drizzle } from 'drizzle-orm/node-mssql';
71
+ import sql from 'mssql';
72
+ {{/if}}
69
73
  {{/if}}
70
74
 
71
75
  {{#if useTypeorm}}
76
+ {{#if hasMongodb}}
77
+ import { TypeormMongoAdapter } from './adapters/mongo/typeorm-mongo.adapter.js';
78
+ {{else}}
72
79
  import { TypeormSqlAdapter } from './adapters/sql/typeorm-sql.adapter.js';
80
+ {{/if}}
73
81
  import { AppDataSource } from "./orm/typeorm/data-source.js";
74
82
  {{/if}}
75
83
 
@@ -155,8 +163,7 @@ export class DbModule {
155
163
  providers.push({
156
164
  provide: 'PRISMA_SQL_CLIENT',
157
165
  useValue: prismaSql,
158
- });
159
- providers.push({
166
+ }, {
160
167
  provide: 'SQL_ADAPTER',
161
168
  useClass: PrismaSqlAdapter,
162
169
  });
@@ -173,8 +180,7 @@ export class DbModule {
173
180
  providers.push({
174
181
  provide: 'PRISMA_MONGO_CLIENT',
175
182
  useValue: prismaMongo,
176
- });
177
- providers.push({
183
+ }, {
178
184
  provide: 'MONGO_ADAPTER',
179
185
  useClass: PrismaMongoAdapter,
180
186
  });
@@ -184,30 +190,43 @@ export class DbModule {
184
190
  {{#if useDrizzle}}
185
191
  providers.push({
186
192
  provide: 'DRIZZLE_CLIENT',
187
- useFactory: () => {
193
+ useFactory: {{#if hasSqlserver}}async {{/if}}() => {
188
194
  {{#if hasPostgres}}
189
195
  const client = new Pool({ connectionString: options.postgresUrl });
190
196
  return drizzle({ client, schema });
191
197
  {{else if hasMysql}}
192
198
  const client = mysql.createPool({ uri: options.mysqlUrl });
193
- return drizzle(client, { schema, mode: "default" });
199
+ return drizzle(client, { mode: "default", schema });
200
+ {{else if hasSqlserver}}
201
+ const client = await new sql.ConnectionPool({
202
+ database: options.sqlserver?.database ?? 'app_db',
203
+ options: options.sqlserver?.options ?? { encrypt: true, trustServerCertificate: true },
204
+ password: options.sqlserver?.password ?? 'DevOnly_Strong_Password_2026!X9',
205
+ port: options.sqlserver?.port ?? 1433,
206
+ server: options.sqlserver?.server ?? 'localhost',
207
+ user: options.sqlserver?.user ?? 'sa',
208
+ }).connect();
209
+ return drizzle({ client, schema });
194
210
  {{else}}
195
211
  const client = new Database(options.sqlitePath || ':memory:');
196
212
  return drizzle({ client, schema });
197
213
  {{/if}}
198
214
  },
199
- });
200
- providers.push({ provide: 'SQL_ADAPTER', useClass: DrizzleSqlAdapter });
215
+ }, { provide: 'SQL_ADAPTER', useClass: DrizzleSqlAdapter });
201
216
  {{/if}}
202
217
 
203
218
  {{#if useTypeorm}}
204
219
  providers.push({
205
220
  provide: 'TYPEORM_DATA_SOURCE',
206
221
  useFactory: () => AppDataSource.initialize(),
207
- });
208
- providers.push({
222
+ }, {
223
+ {{#if hasMongodb}}
224
+ provide: 'MONGO_ADAPTER',
225
+ useClass: TypeormMongoAdapter,
226
+ {{else}}
209
227
  provide: 'SQL_ADAPTER',
210
228
  useClass: TypeormSqlAdapter,
229
+ {{/if}}
211
230
  });
212
231
  {{/if}}
213
232
 
@@ -246,12 +265,13 @@ export class DbModule {
246
265
  {{/if}}
247
266
 
248
267
  {{#if hasMongodb}}
249
- if (!options.mongodbUrl) throw new Error("A MongoDB URL is required");
268
+ if (!options.mongodbUrl) {
269
+ throw new Error("A MongoDB URL is required");
270
+ }
250
271
  providers.push({
251
272
  provide: 'MONGODB_CLIENT',
252
273
  useFactory: () => new MongoClient(options.mongodbUrl!, { serverSelectionTimeoutMS: 5000 }),
253
- });
254
- providers.push({
274
+ }, {
255
275
  provide: 'MONGO_ADAPTER',
256
276
  useClass: RawMongoAdapter,
257
277
  });
@@ -49,6 +49,9 @@ import type { MySql2Database } from 'drizzle-orm/mysql2';
49
49
  {{#if hasSqlite}}
50
50
  import type { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
51
51
  {{/if}}
52
+ {{#if hasSqlserver}}
53
+ import type { NodeMsSqlDatabase } from 'drizzle-orm/node-mssql';
54
+ {{/if}}
52
55
  {{#if isMonorepo}}
53
56
  import type * as schema from './database/orm/drizzle/schema.js';
54
57
  {{else}}
@@ -58,13 +61,14 @@ import type * as schema from './orm/drizzle/schema.js';
58
61
  {{#if useTypeorm}}
59
62
  import type { DataSource } from 'typeorm';
60
63
  {{/if}}
64
+
61
65
  {{#if (or hasPostgres hasMysql hasSqlite hasSqlserver)}}
62
66
  {{#if usePrisma}}
63
67
  type SqlClient = PrismaClient;
64
68
  {{else if useTypeorm}}
65
69
  type SqlClient = DataSource;
66
70
  {{else if useDrizzle}}
67
- type DrizzleClient = {{#if hasPostgres}}NodePgDatabase{{/if}}{{#if hasMysql}}MySql2Database{{/if}}{{#if hasSqlite}}BetterSQLite3Database{{/if}}<typeof schema>;
71
+ type DrizzleClient = {{#if hasPostgres}}NodePgDatabase{{/if}}{{#if hasMysql}}MySql2Database{{/if}}{{#if hasSqlite}}BetterSQLite3Database{{/if}}{{#if hasSqlserver}}NodeMsSqlDatabase<typeof schema>{{/if}}{{#unless hasSqlserver}}<typeof schema>{{/unless}};
68
72
  type SqlClient = DrizzleClient;
69
73
  {{else if hasPostgres}}
70
74
  type SqlClient = import('pg').Pool;
@@ -75,6 +79,8 @@ type SqlClient = unknown;
75
79
  {{#if hasMongodb}}
76
80
  {{#if usePrisma}}
77
81
  type MongoClient = PrismaClient;
82
+ {{else if useTypeorm}}
83
+ type MongoClient = DataSource;
78
84
  {{else}}
79
85
  type MongoClient = import('mongodb').Db;
80
86
  {{/if}}
@@ -125,18 +131,20 @@ export class DbService {
125
131
  {{/if}}
126
132
  {{/if}}
127
133
  {{#if useDrizzle}}
128
- {{#if (or hasPostgres hasMysql hasSqlite)}}
134
+ {{#if (or hasPostgres hasMysql hasSqlite hasSqlserver)}}
129
135
  get drizzle(): DrizzleClient {
130
136
  return this.sql.getClient();
131
137
  }
132
138
  {{/if}}
133
139
  {{/if}}
134
140
  {{#if useTypeorm}}
135
- {{#if (or hasPostgres hasMysql hasSqlite)}}
136
141
  get typeorm(): DataSource {
142
+ {{#if hasMongodb}}
143
+ return this.mongo.getClient();
144
+ {{else}}
137
145
  return this.sql.getClient();
146
+ {{/if}}
138
147
  }
139
- {{/if}}
140
148
  {{/if}}
141
149
  }
142
150
  {{/if}}
@@ -6,26 +6,38 @@ import {
6
6
  Column,
7
7
  CreateDateColumn,
8
8
  Entity,
9
+ {{#if hasMongodb}}
10
+ ObjectIdColumn,
11
+ {{else}}
9
12
  PrimaryGeneratedColumn,
13
+ {{/if}}
10
14
  UpdateDateColumn,
11
15
  } from "typeorm";
16
+ {{#if hasMongodb}}
17
+ import type { ObjectId } from "mongodb";
18
+ {{/if}}
12
19
 
13
20
  @Entity("todos")
14
21
  export class Todo {
15
- @PrimaryGeneratedColumn("uuid")
22
+ {{#if hasMongodb}}
23
+ @ObjectIdColumn()
24
+ id: ObjectId;
25
+ {{else}}
26
+ @PrimaryGeneratedColumn("{{#if hasSqlserver}}increment{{else}}uuid{{/if}}")
16
27
  id: string;
28
+ {{/if}}
17
29
 
18
- @Column({ type: "varchar", length: 255, nullable: true })
30
+ @Column({ length: 255, nullable: true, type: "varchar" })
19
31
  description?: string;
20
32
 
21
- @Column({ type: "varchar", length: 255 })
33
+ @Column({ length: 255, type: "varchar" })
22
34
  title: string;
23
35
 
24
- @Column({ default: false, name: "is_completed", type: "boolean" })
36
+ @Column({ default: false, name: "is_completed", type: "{{#if hasSqlserver}}bit{{else}}boolean{{/if}}" })
25
37
  completed: boolean;
26
38
 
27
39
  {{#if hasAuth}}
28
- @Column({ type: "varchar", nullable: true })
40
+ @Column({ nullable: true, type: "varchar" })
29
41
  authorId?: string;
30
42
  {{/if}}
31
43
 
@@ -9,6 +9,7 @@ export type { PrismaClient } from '@prisma/client';
9
9
  export type { Todo } from '@prisma/client';
10
10
  {{/if}}
11
11
  {{else}}
12
+ {{#unless isPrisma8}}
12
13
  {{#if isMonorepo}}
13
14
  export type { PrismaClient } from './database/orm/prisma/generated/client.js';
14
15
  {{#if hasTodoExample}}
@@ -20,6 +21,7 @@ export type { PrismaClient } from './orm/prisma/generated/client.js';
20
21
  export type { Todo } from './orm/prisma/generated/client.js';
21
22
  {{/if}}
22
23
  {{/if}}
24
+ {{/unless}}
23
25
  {{/if}}
24
26
  {{/if}}
25
27
  export * from './adapters/interfaces/db-adapter.interface.js';