@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
@@ -1,29 +1,55 @@
1
1
  // oxlint-disable typescript/no-explicit-any
2
+ {{#if hasPostgres}}
3
+ {{#if (or hasTodoExample isPassportAuth (eq auth "better-auth:stateless"))}}
4
+ import { {{#if hasTodoExample}}boolean, {{/if}}pgTable{{#if (or hasTodoExample (eq auth "better-auth:stateless"))}}, serial{{/if}}, text{{#if (or isPassportAuth (eq auth "better-auth:stateless"))}}, timestamp{{/if}} } from 'drizzle-orm/pg-core';
5
+
6
+ {{/if}}
7
+ {{/if}}
8
+ {{#if hasMysql}}
9
+ {{#if (or hasTodoExample isPassportAuth (eq auth "better-auth:stateless"))}}
10
+ import { {{#if hasTodoExample}}boolean, {{/if}}mysqlTable{{#if (or hasTodoExample (eq auth "better-auth:stateless"))}}, int{{/if}}, text{{#if (or isPassportAuth (eq auth "better-auth:stateless"))}}, timestamp, varchar{{/if}} } from 'drizzle-orm/mysql-core';
11
+
12
+ {{/if}}
13
+ {{/if}}
14
+ {{#if hasSqlite}}
15
+ {{#if (or hasTodoExample isPassportAuth (eq auth "better-auth:stateless"))}}
16
+ import { sqliteTable{{#if (or hasTodoExample (eq auth "better-auth:stateless"))}}, integer{{/if}}, text } from 'drizzle-orm/sqlite-core';
17
+
18
+ {{/if}}
19
+ {{/if}}
20
+ {{#if hasSqlserver}}
21
+ {{#if (or hasTodoExample isPassportAuth (eq auth "better-auth:stateless"))}}
22
+ import { {{#if hasTodoExample}}bit, {{/if}}{{#if (or hasTodoExample (eq auth "better-auth:stateless"))}}int, {{/if}}mssqlTable, nvarchar } from 'drizzle-orm/mssql-core';
23
+
24
+ {{/if}}
25
+ {{/if}}
2
26
  {{#if (eq auth "better-auth")}}
3
27
  // oxlint-disable-next-line oxc/no-barrel-file
4
28
  export * from "./auth-schema.js";
5
29
  {{/if}}
6
30
  {{#if hasPostgres}}
7
- import { {{#if hasTodoExample}}boolean, {{/if}}pgTable{{#if (or (not isPassportAuth) hasTodoExample)}}, serial{{/if}}, text, timestamp } from 'drizzle-orm/pg-core';
8
-
9
- {{#unless (eq auth "better-auth")}}
31
+ {{#if (or isPassportAuth (eq auth "better-auth:stateless"))}}
10
32
  export const users = pgTable('users', {
33
+ {{#if (or isPassportAuth (eq auth "better-auth:stateless"))}}
34
+ createdAt: timestamp('created_at').defaultNow(),
35
+ {{/if}}
11
36
  email: text('email').unique(),
12
37
  {{#if isPassportAuth}}
38
+ firstname: text('firstname'),
13
39
  id: text('id').primaryKey(),
14
40
  {{else}}
15
41
  id: serial('id').primaryKey(),
42
+ {{/if}}
43
+ {{#if isPassportAuth}}
44
+ lastname: text('lastname'),
16
45
  {{/if}}
17
46
  name: text('name'),
18
- createdAt: timestamp('created_at').defaultNow(),
19
47
  {{#if isPassportAuth}}
20
48
  password: text('password').notNull(),
21
- firstname: text('firstname'),
22
- lastname: text('lastname'),
23
49
  role: text('role').default('USER'),
24
50
  {{/if}}
25
51
  });
26
- {{/unless}}
52
+ {{/if}}
27
53
  {{#if hasTodoExample}}
28
54
  export const todos = pgTable('todos', {
29
55
  {{#if hasAuth}}
@@ -37,26 +63,28 @@ export const todos = pgTable('todos', {
37
63
  {{/if}}
38
64
  {{/if}}
39
65
  {{#if hasMysql}}
40
- import { {{#if hasTodoExample}}boolean, {{/if}}mysqlTable{{#if (or (not isPassportAuth) hasTodoExample)}}, int{{/if}}, text, timestamp, varchar } from 'drizzle-orm/mysql-core';
41
-
42
- {{#unless (eq auth "better-auth")}}
66
+ {{#if (or isPassportAuth (eq auth "better-auth:stateless"))}}
43
67
  export const users = mysqlTable('users', {
68
+ {{#if (or isPassportAuth (eq auth "better-auth:stateless"))}}
69
+ createdAt: timestamp('created_at').defaultNow(),
70
+ {{/if}}
44
71
  email: varchar('email', { length: 320 }).unique(),
45
72
  {{#if isPassportAuth}}
73
+ firstname: text('firstname'),
46
74
  id: varchar('id', { length: 255 }).primaryKey(),
47
75
  {{else}}
48
76
  id: int('id').autoincrement().primaryKey(),
77
+ {{/if}}
78
+ {{#if isPassportAuth}}
79
+ lastname: text('lastname'),
49
80
  {{/if}}
50
81
  name: text('name'),
51
- createdAt: timestamp('created_at').defaultNow(),
52
82
  {{#if isPassportAuth}}
53
83
  password: text('password').notNull(),
54
- firstname: text('firstname'),
55
- lastname: text('lastname'),
56
84
  role: text('role').default('USER'),
57
85
  {{/if}}
58
86
  });
59
- {{/unless}}
87
+ {{/if}}
60
88
  {{#if hasTodoExample}}
61
89
  export const todos = mysqlTable('todos', {
62
90
  {{#if hasAuth}}
@@ -70,25 +98,25 @@ export const todos = mysqlTable('todos', {
70
98
  {{/if}}
71
99
  {{/if}}
72
100
  {{#if hasSqlite}}
73
- import { sqliteTable{{#if (or (not isPassportAuth) hasTodoExample)}}, integer{{/if}}, text } from 'drizzle-orm/sqlite-core';
74
-
75
- {{#unless (eq auth "better-auth")}}
101
+ {{#if (or isPassportAuth (eq auth "better-auth:stateless"))}}
76
102
  export const users = sqliteTable('users', {
77
103
  email: text('email').unique(),
78
104
  {{#if isPassportAuth}}
105
+ firstname: text('firstname'),
79
106
  id: text('id').primaryKey(),
80
107
  {{else}}
81
108
  id: integer('id').primaryKey({ autoIncrement: true }),
109
+ {{/if}}
110
+ {{#if isPassportAuth}}
111
+ lastname: text('lastname'),
82
112
  {{/if}}
83
113
  name: text('name'),
84
114
  {{#if isPassportAuth}}
85
115
  password: text('password').notNull(),
86
- firstname: text('firstname'),
87
- lastname: text('lastname'),
88
116
  role: text('role').default('USER'),
89
117
  {{/if}}
90
118
  });
91
- {{/unless}}
119
+ {{/if}}
92
120
  {{#if hasTodoExample}}
93
121
  export const todos = sqliteTable('todos', {
94
122
  {{#if hasAuth}}
@@ -101,3 +129,35 @@ export const todos = sqliteTable('todos', {
101
129
  });
102
130
  {{/if}}
103
131
  {{/if}}
132
+ {{#if hasSqlserver}}
133
+ {{#if (or isPassportAuth (eq auth "better-auth:stateless"))}}
134
+ export const users = mssqlTable('users', {
135
+ email: nvarchar('email', { length: 320 }).unique(),
136
+ {{#if isPassportAuth}}
137
+ firstname: nvarchar('firstname', { length: 255 }),
138
+ id: nvarchar('id', { length: 255 }).primaryKey(),
139
+ {{else}}
140
+ id: int('id').identity().primaryKey(),
141
+ {{/if}}
142
+ {{#if isPassportAuth}}
143
+ lastname: nvarchar('lastname', { length: 255 }),
144
+ {{/if}}
145
+ name: nvarchar('name', { length: 255 }),
146
+ {{#if isPassportAuth}}
147
+ password: nvarchar('password', { length: 255 }).notNull(),
148
+ role: nvarchar('role', { length: 32 }).default('USER'),
149
+ {{/if}}
150
+ });
151
+ {{/if}}
152
+ {{#if hasTodoExample}}
153
+ export const todos = mssqlTable('todos', {
154
+ {{#if hasAuth}}
155
+ authorId: nvarchar('author_id', { length: 255 }),
156
+ {{/if}}
157
+ completed: bit('completed').notNull().default(false),
158
+ description: nvarchar('description', { length: 'max' }),
159
+ id: int('id').identity().primaryKey(),
160
+ title: nvarchar('title', { length: 255 }).notNull(),
161
+ });
162
+ {{/if}}
163
+ {{/if}}
@@ -1,12 +1,13 @@
1
1
  // oxlint-disable typescript/no-non-null-assertion
2
2
  import "reflect-metadata";
3
+ import "dotenv/config";
3
4
  {{#if isMonorepo}}
4
5
  import { env } from "@repo/env/api-gateway";
5
6
  {{else}}
6
7
  import { env } from "../../../config/env.js";
7
8
  {{/if}}
8
9
  import { DataSource } from "typeorm";
9
- {{#if hasTodoExample}}
10
+ {{#if (or hasTodoExample hasMongodb)}}
10
11
  import { Todo } from "../../entities/todo.entity.js";
11
12
  {{/if}}
12
13
  {{#if (and useTypeorm isPassportAuth)}}
@@ -16,27 +17,48 @@ import { UserEntity } from "../../../modules/users/entities/user.entity.js";
16
17
  import { AppEntity } from "../../entities/app.entity.js";
17
18
  {{/if}}
18
19
 
19
- const databaseUrl =
20
- env.{{#if hasPostgres}}POSTGRES_URL{{/if}}{{#if hasMysql}}MYSQL_URL{{/if}}{{#if hasSqlite}}SQLITE_PATH{{/if}};
21
-
22
- {{#unless hasSqlite}}
20
+ {{#unless (or hasSqlite hasSqlserver hasMongodb)}}
21
+ const databaseUrl = env.{{#if hasPostgres}}POSTGRES_URL{{/if}}{{#if hasMysql}}MYSQL_URL{{/if}};
23
22
  const parsedUrl = new URL(databaseUrl);
24
23
  {{/unless}}
25
24
 
26
25
 
27
26
  export const AppDataSource = new DataSource({
28
27
  {{#if hasSqlite}}
29
- database: databaseUrl,
28
+ database: env.SQLITE_PATH,
29
+ {{/if}}
30
+ {{#if hasSqlserver}}
31
+ database: env.SQLSERVER_DATABASE,
30
32
  {{/if}}
31
33
  // 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}}],
33
- migrations: [{{#if isMonorepo}}"migrations/*.{ts,js}"{{else}}"migrations/*.{ts,js}"{{/if}}],
34
- synchronize: env.NODE_ENV === "development",
35
- type: "{{#if hasPostgres}}postgres{{/if}}{{#if hasMysql}}mysql{{/if}}{{#if hasSqlite}}better-sqlite3{{/if}}",
36
- {{#unless hasSqlite}}
34
+ entities: [{{#if (or hasTodoExample hasMongodb)}}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}}],
35
+ {{#if hasMongodb}}
36
+ extra: { serverSelectionTimeoutMS: 5000 },
37
+ {{/if}}
38
+ {{#if hasSqlserver}}
39
+ host: env.SQLSERVER_HOST,
40
+ {{/if}}
41
+ migrations: [
42
+ "dist/database/orm/typeorm/migrations/*.js",
43
+ "src/database/orm/typeorm/migrations/*.js",
44
+ ],
45
+ {{#if hasSqlserver}}
46
+ options: { encrypt: env.SQLSERVER_ENCRYPT, trustServerCertificate: env.SQLSERVER_TRUST_SERVER_CERTIFICATE },
47
+ password: env.SQLSERVER_PASSWORD,
48
+ port: env.SQLSERVER_PORT,
49
+ {{/if}}
50
+ synchronize: false,
51
+ type: "{{#if hasPostgres}}postgres{{/if}}{{#if hasMysql}}mysql{{/if}}{{#if hasSqlite}}better-sqlite3{{/if}}{{#if hasSqlserver}}mssql{{/if}}{{#if hasMongodb}}mongodb{{/if}}",
52
+ {{#if hasMongodb}}
53
+ url: env.MONGODB_URL,
54
+ {{/if}}
55
+ {{#if hasSqlserver}}
56
+ username: env.SQLSERVER_USER,
57
+ {{/if}}
58
+ {{#unless (or hasSqlite hasSqlserver hasMongodb)}}
37
59
  url: databaseUrl,
38
60
  {{/unless}}
39
- {{#unless hasSqlite}}
61
+ {{#unless (or hasSqlite hasSqlserver hasMongodb)}}
40
62
  ...(parsedUrl.username ? { username: decodeURIComponent(parsedUrl.username) } : {}),
41
63
  ...(parsedUrl.password ? { password: decodeURIComponent(parsedUrl.password) } : {}),
42
64
  {{/unless}}
@@ -0,0 +1,22 @@
1
+ import { Injectable, type ExecutionContext } from "@nestjs/common";
2
+ import { GqlExecutionContext } from "@nestjs/graphql";
3
+ import { ThrottlerGuard } from "@nestjs/throttler";
4
+
5
+ @Injectable()
6
+ export class GraphqlThrottlerGuard extends ThrottlerGuard {
7
+ protected getRequestResponse(context: ExecutionContext) {
8
+ if (context.getType<string>() !== "graphql") {
9
+ return super.getRequestResponse(context);
10
+ }
11
+ const gqlContext = GqlExecutionContext.create(context).getContext();
12
+ return { req: gqlContext.req, res: { header: () => true } };
13
+ }
14
+
15
+ protected getTracker(request: Record<string, unknown>): Promise<string> {
16
+ const socket = request.socket as { remoteAddress?: string } | undefined;
17
+ const ip = request.ip;
18
+ return Promise.resolve(
19
+ typeof ip === "string" ? ip : (socket?.remoteAddress ?? "unknown")
20
+ );
21
+ }
22
+ }
@@ -1,6 +1,7 @@
1
1
  {{#if hasRateLimiting}}
2
2
  import { Inject, Injectable } from "@nestjs/common";
3
- import { ThrottlerStorage, type ThrottlerStorage as ThrottlerStorageService } from "@nestjs/throttler";
3
+ import { ThrottlerStorage } from "@nestjs/throttler";
4
+ import type { ThrottlerStorage as ThrottlerStorageService } from "@nestjs/throttler";
4
5
  import { TRPCError } from "@trpc/server";
5
6
  import {
6
7
  MiddlewareOptions,
@@ -1,10 +1,10 @@
1
1
  import { ContextOptions } from "nestjs-trpc";
2
- {{#if (eq auth "better-auth")}}
2
+ {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}
3
3
  import type { UserSession } from "../../auth/auth.js";
4
4
  {{else if (eq auth "passport")}}
5
5
  import type { AuthService } from "../../auth/auth.service.js";
6
6
  {{/if}}
7
7
 
8
8
  export type InnerContext = {
9
- session?: {{#if (eq auth "better-auth")}}UserSession{{else if (eq auth "passport")}}{ user: NonNullable<Awaited<ReturnType<AuthService[{{#if (and usePrisma (not hasMongodb))}}"validate"{{else}}"validateUser"{{/if}}]>>> }{{else}}unknown{{/if}};
9
+ session?: {{#if (or (eq auth "better-auth") (eq auth "better-auth:stateless"))}}UserSession{{else if (eq auth "passport")}}{ user: NonNullable<Awaited<ReturnType<AuthService[{{#if (and usePrisma (not hasMongodb))}}"validate"{{else}}"validateUser"{{/if}}]>>> }{{else}}unknown{{/if}};
10
10
  } & ContextOptions;
@@ -70,8 +70,8 @@ async function bootstrap() {
70
70
  {{/if}}
71
71
  {{#if (includes apis "trpc")}}
72
72
  trpc: {
73
- routerFilePath: "./src/libs/trpc/@generated/server.ts",
74
73
  pathPrefix: "/trpc",
74
+ routerFilePath: "./{{trpcGeneratePath}}/server.ts",
75
75
  },
76
76
  {{/if}}
77
77
  zod: {
@@ -98,8 +98,8 @@ async function bootstrap() {
98
98
  {{/if}}
99
99
  {{#if (includes apis "trpc")}}
100
100
  trpc: {
101
- routerFilePath: "./src/trpc/router.ts",
102
101
  pathPrefix: "/trpc",
102
+ routerFilePath: "./{{trpcGeneratePath}}/server.ts",
103
103
  },
104
104
  {{/if}}
105
105
  zod: {