nesthub 1.0.0

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 (143) hide show
  1. package/README.md +108 -0
  2. package/dist/cache/README.md +91 -0
  3. package/dist/cache/index.d.ts +10 -0
  4. package/dist/cache/index.js +75 -0
  5. package/dist/cache/index.js.map +1 -0
  6. package/dist/cache/index.spec.d.ts +1 -0
  7. package/dist/cache/index.spec.js +61 -0
  8. package/dist/cache/index.spec.js.map +1 -0
  9. package/dist/excel/README.md +132 -0
  10. package/dist/excel/excel.module.d.ts +2 -0
  11. package/dist/excel/excel.module.js +21 -0
  12. package/dist/excel/excel.module.js.map +1 -0
  13. package/dist/excel/excel.service.d.ts +23 -0
  14. package/dist/excel/excel.service.js +124 -0
  15. package/dist/excel/excel.service.js.map +1 -0
  16. package/dist/excel/index.d.ts +2 -0
  17. package/dist/excel/index.js +8 -0
  18. package/dist/excel/index.js.map +1 -0
  19. package/dist/excel/interfaces.d.ts +19 -0
  20. package/dist/excel/interfaces.js +3 -0
  21. package/dist/excel/interfaces.js.map +1 -0
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.js +5 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/index.spec.d.ts +1 -0
  26. package/dist/index.spec.js +11 -0
  27. package/dist/index.spec.js.map +1 -0
  28. package/dist/notification/README.md +237 -0
  29. package/dist/notification/channels/channel.interface.d.ts +10 -0
  30. package/dist/notification/channels/channel.interface.js +3 -0
  31. package/dist/notification/channels/channel.interface.js.map +1 -0
  32. package/dist/notification/channels/email.channel.d.ts +11 -0
  33. package/dist/notification/channels/email.channel.js +58 -0
  34. package/dist/notification/channels/email.channel.js.map +1 -0
  35. package/dist/notification/channels/firebase.channel.d.ts +11 -0
  36. package/dist/notification/channels/firebase.channel.js +69 -0
  37. package/dist/notification/channels/firebase.channel.js.map +1 -0
  38. package/dist/notification/channels/index.d.ts +5 -0
  39. package/dist/notification/channels/index.js +12 -0
  40. package/dist/notification/channels/index.js.map +1 -0
  41. package/dist/notification/channels/sms.channel.d.ts +8 -0
  42. package/dist/notification/channels/sms.channel.js +90 -0
  43. package/dist/notification/channels/sms.channel.js.map +1 -0
  44. package/dist/notification/channels/telegram.channel.d.ts +10 -0
  45. package/dist/notification/channels/telegram.channel.js +59 -0
  46. package/dist/notification/channels/telegram.channel.js.map +1 -0
  47. package/dist/notification/email/index.d.ts +62 -0
  48. package/dist/notification/email/index.js +253 -0
  49. package/dist/notification/email/index.js.map +1 -0
  50. package/dist/notification/email/index.spec.d.ts +1 -0
  51. package/dist/notification/email/index.spec.js +121 -0
  52. package/dist/notification/email/index.spec.js.map +1 -0
  53. package/dist/notification/entities/notification-log.entity.d.ts +15 -0
  54. package/dist/notification/entities/notification-log.entity.js +82 -0
  55. package/dist/notification/entities/notification-log.entity.js.map +1 -0
  56. package/dist/notification/firebase/index.d.ts +52 -0
  57. package/dist/notification/firebase/index.js +261 -0
  58. package/dist/notification/firebase/index.js.map +1 -0
  59. package/dist/notification/firebase/index.spec.d.ts +1 -0
  60. package/dist/notification/firebase/index.spec.js +114 -0
  61. package/dist/notification/firebase/index.spec.js.map +1 -0
  62. package/dist/notification/index.d.ts +12 -0
  63. package/dist/notification/index.js +26 -0
  64. package/dist/notification/index.js.map +1 -0
  65. package/dist/notification/index.spec.d.ts +1 -0
  66. package/dist/notification/index.spec.js +336 -0
  67. package/dist/notification/index.spec.js.map +1 -0
  68. package/dist/notification/interfaces.d.ts +98 -0
  69. package/dist/notification/interfaces.js +3 -0
  70. package/dist/notification/interfaces.js.map +1 -0
  71. package/dist/notification/notification.constants.d.ts +4 -0
  72. package/dist/notification/notification.constants.js +8 -0
  73. package/dist/notification/notification.constants.js.map +1 -0
  74. package/dist/notification/notification.module.d.ts +10 -0
  75. package/dist/notification/notification.module.js +160 -0
  76. package/dist/notification/notification.module.js.map +1 -0
  77. package/dist/notification/notification.service.d.ts +14 -0
  78. package/dist/notification/notification.service.js +184 -0
  79. package/dist/notification/notification.service.js.map +1 -0
  80. package/dist/notification/queue/index.d.ts +2 -0
  81. package/dist/notification/queue/index.js +6 -0
  82. package/dist/notification/queue/index.js.map +1 -0
  83. package/dist/notification/queue/notification-queue.service.d.ts +31 -0
  84. package/dist/notification/queue/notification-queue.service.js +134 -0
  85. package/dist/notification/queue/notification-queue.service.js.map +1 -0
  86. package/dist/notification/services/index.d.ts +1 -0
  87. package/dist/notification/services/index.js +6 -0
  88. package/dist/notification/services/index.js.map +1 -0
  89. package/dist/notification/services/template.service.d.ts +13 -0
  90. package/dist/notification/services/template.service.js +75 -0
  91. package/dist/notification/services/template.service.js.map +1 -0
  92. package/dist/notification/shared.d.ts +48 -0
  93. package/dist/notification/shared.js +95 -0
  94. package/dist/notification/shared.js.map +1 -0
  95. package/dist/notification/sms/index.d.ts +52 -0
  96. package/dist/notification/sms/index.js +234 -0
  97. package/dist/notification/sms/index.js.map +1 -0
  98. package/dist/notification/sms/index.spec.d.ts +1 -0
  99. package/dist/notification/sms/index.spec.js +123 -0
  100. package/dist/notification/sms/index.spec.js.map +1 -0
  101. package/dist/notification/telegram/index.d.ts +50 -0
  102. package/dist/notification/telegram/index.js +248 -0
  103. package/dist/notification/telegram/index.js.map +1 -0
  104. package/dist/notification/telegram/index.spec.d.ts +1 -0
  105. package/dist/notification/telegram/index.spec.js +108 -0
  106. package/dist/notification/telegram/index.spec.js.map +1 -0
  107. package/dist/notification/typeorm-storage.d.ts +28 -0
  108. package/dist/notification/typeorm-storage.js +56 -0
  109. package/dist/notification/typeorm-storage.js.map +1 -0
  110. package/dist/notification/unified.d.ts +47 -0
  111. package/dist/notification/unified.js +207 -0
  112. package/dist/notification/unified.js.map +1 -0
  113. package/dist/queue/README.md +82 -0
  114. package/dist/queue/index.d.ts +14 -0
  115. package/dist/queue/index.js +17 -0
  116. package/dist/queue/index.js.map +1 -0
  117. package/dist/queue/index.spec.d.ts +1 -0
  118. package/dist/queue/index.spec.js +76 -0
  119. package/dist/queue/index.spec.js.map +1 -0
  120. package/dist/tsconfig.build.tsbuildinfo +1 -0
  121. package/dist/tsconfig.tsbuildinfo +1 -0
  122. package/dist/typeorm/README.md +197 -0
  123. package/dist/typeorm/crud-controller.d.ts +4 -0
  124. package/dist/typeorm/crud-controller.js +81 -0
  125. package/dist/typeorm/crud-controller.js.map +1 -0
  126. package/dist/typeorm/crud-service.d.ts +6 -0
  127. package/dist/typeorm/crud-service.js +53 -0
  128. package/dist/typeorm/crud-service.js.map +1 -0
  129. package/dist/typeorm/crud.interface.d.ts +9 -0
  130. package/dist/typeorm/crud.interface.js +3 -0
  131. package/dist/typeorm/crud.interface.js.map +1 -0
  132. package/dist/typeorm/index.d.ts +23 -0
  133. package/dist/typeorm/index.js +66 -0
  134. package/dist/typeorm/index.js.map +1 -0
  135. package/dist/typeorm/index.spec.d.ts +1 -0
  136. package/dist/typeorm/index.spec.js +109 -0
  137. package/dist/typeorm/index.spec.js.map +1 -0
  138. package/package.json +229 -0
  139. package/src/cache/README.md +91 -0
  140. package/src/excel/README.md +132 -0
  141. package/src/notification/README.md +237 -0
  142. package/src/queue/README.md +82 -0
  143. package/src/typeorm/README.md +197 -0
@@ -0,0 +1,197 @@
1
+ # nesthub/typeorm
2
+
3
+ TypeORM configuration helpers for cloud databases (RDS PostgreSQL / MySQL), plus CRUD service & controller factories.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install nesthub @nestjs/typeorm @nestjs/config
9
+ ```
10
+
11
+ ## Prerequisites
12
+
13
+ The following environment variables must be declared in your `.env` file (or provided to `ConfigModule.forRoot()`):
14
+
15
+ | Variable | Required | Default |
16
+ |---|---|---|
17
+ | `DB_HOST` | No | `localhost` |
18
+ | `DB_PORT` | No | `5432` (PG) / `3306` (MySQL) |
19
+ | `DB_USERNAME` | Yes | — |
20
+ | `DB_PASSWORD` | Yes | — |
21
+ | `DB_DATABASE` | No | `postgres` / `mysql` |
22
+ | `DB_SYNCHRONIZE` | No | `false` |
23
+ | `DB_LOGGING` | No | `false` |
24
+ | `DB_SSL_REJECT_UNAUTHORIZED` | No | `false` |
25
+
26
+ ## Usage
27
+
28
+ ```typescript
29
+ // app.module.ts
30
+ import { Module } from '@nestjs/common'
31
+ import { ConfigModule, ConfigService } from '@nestjs/config'
32
+ import { TypeOrmModule } from '@nestjs/typeorm'
33
+ import { configTypeOrmRDSPostgres } from 'nesthub/typeorm'
34
+
35
+ @Module({
36
+ imports: [
37
+ ConfigModule.forRoot(),
38
+ TypeOrmModule.forRootAsync({
39
+ inject: [ConfigService],
40
+ useFactory: (config: ConfigService) =>
41
+ configTypeOrmRDSPostgres(config, {
42
+ poolSize: 20,
43
+ schema: 'public',
44
+ }),
45
+ }),
46
+ ],
47
+ })
48
+ export class AppModule {}
49
+ ```
50
+
51
+ ## Environment variables
52
+
53
+ | Variable | Default | Type | Description |
54
+ |---|---|---|---|
55
+ | `DB_HOST` | `localhost` | `string` | Database host |
56
+ | `DB_PORT` | `5432` (PG) / `3306` (MySQL) | `number` | Connection port |
57
+ | `DB_USERNAME` | — | `string` | Database username |
58
+ | `DB_PASSWORD` | — | `string` | Database password |
59
+ | `DB_DATABASE` | `postgres` / `mysql` | `string` | Database name |
60
+ | `DB_SYNCHRONIZE` | `false` | `boolean` | Auto-sync schema (dev only) |
61
+ | `DB_LOGGING` | `false` | `boolean` | Enable query logging |
62
+ | `DB_SSL_REJECT_UNAUTHORIZED` | `false` | `boolean` | Reject unauthorized SSL certs |
63
+
64
+ ## TypeOrmConfigOptions
65
+
66
+ | Option | Default | Description |
67
+ |---|---|---|
68
+ | `schema` | — | PostgreSQL schema (e.g. `public`) |
69
+ | `poolSize` | `20` (PG) / `10` (MySQL) | Maximum connections in pool |
70
+ | `idleTimeoutMs` | `30000` (PG) / `10000` (MySQL) | Max idle time before closing |
71
+ | `connectionTimeoutMs` | `10000` (PG) / `5000` (MySQL) | Connection timeout |
72
+ | `statementTimeoutMs` | `30000` (PG) | Query timeout |
73
+
74
+ ## SSL — why both `ssl` and `extra.ssl`?
75
+
76
+ ```typescript
77
+ ssl: { rejectUnauthorized: false },
78
+ extra: {
79
+ ssl: { rejectUnauthorized: false },
80
+ // ...
81
+ }
82
+ ```
83
+
84
+ - **`ssl`** — tells TypeORM to configure the driver (`pg` / `mysql2`) with TLS
85
+ - **`extra.ssl`** — passes SSL config directly to the underlying driver pool
86
+
87
+ Cloud databases (AWS RDS, Google Cloud SQL, etc.) often use self-signed certificates, requiring `rejectUnauthorized: false` to trust them.
88
+
89
+ ## Sample .env
90
+
91
+ ```bash
92
+ DB_HOST=database-1.xxxxxx.us-east-1.rds.amazonaws.com
93
+ DB_PORT=5432
94
+ DB_USERNAME=postgres
95
+ DB_PASSWORD=my-secret-pw
96
+ DB_DATABASE=mydb
97
+ DB_SYNCHRONIZE=false
98
+ DB_LOGGING=true
99
+ DB_SSL_REJECT_UNAUTHORIZED=false
100
+ ```
101
+
102
+ ---
103
+
104
+ ## CRUD Service & Controller Factories
105
+
106
+ Generate ready-to-use CRUD service and controller classes for any TypeORM entity.
107
+
108
+ ### `createCrudService(entity)`
109
+
110
+ Creates a base `@Injectable()` service class with `@InjectRepository(entity)` and standard CRUD methods (`findAll`, `findOne`, `create`, `update`, `remove`).
111
+
112
+ ```typescript
113
+ import { Module } from '@nestjs/common'
114
+ import { TypeOrmModule } from '@nestjs/typeorm'
115
+ import { createCrudService } from 'nesthub/typeorm'
116
+ import { User } from './user.entity'
117
+
118
+ const UserService = createCrudService(User)
119
+
120
+ @Module({
121
+ imports: [TypeOrmModule.forFeature([User])],
122
+ providers: [UserService],
123
+ })
124
+ export class UserModule {}
125
+ ```
126
+
127
+ #### Extending
128
+
129
+ ```typescript
130
+ import { Injectable } from '@nestjs/common'
131
+ import { createCrudService } from 'nesthub/typeorm'
132
+ import { User } from './user.entity'
133
+
134
+ const BaseUserService = createCrudService(User)
135
+
136
+ @Injectable()
137
+ export class UserService extends BaseUserService {
138
+ async findByEmail(email: string) {
139
+ return this.repository.findOne({ where: { email } })
140
+ }
141
+ }
142
+ ```
143
+
144
+ ### `createCrudController(route, serviceClass)`
145
+
146
+ Creates a `@Controller()` class with REST endpoints (`GET /`, `GET /:id`, `POST /`, `PATCH /:id`, `DELETE /:id`) delegating to the given CRUD service.
147
+
148
+ ```typescript
149
+ import { Module } from '@nestjs/common'
150
+ import { TypeOrmModule } from '@nestjs/typeorm'
151
+ import {
152
+ createCrudService,
153
+ createCrudController,
154
+ } from 'nesthub/typeorm'
155
+ import { User } from './user.entity'
156
+
157
+ const UserService = createCrudService(User)
158
+ const UserController = createCrudController('users', UserService)
159
+
160
+ @Module({
161
+ imports: [TypeOrmModule.forFeature([User])],
162
+ controllers: [UserController],
163
+ providers: [UserService],
164
+ })
165
+ export class UserModule {}
166
+ ```
167
+
168
+ ### `createCrudModule(entity, route)`
169
+
170
+ Convenience helper that returns both `service` and `controller` in one call.
171
+
172
+ ```typescript
173
+ import { Module } from '@nestjs/common'
174
+ import { TypeOrmModule } from '@nestjs/typeorm'
175
+ import { createCrudModule } from 'nesthub/typeorm'
176
+ import { User } from './user.entity'
177
+
178
+ const { service: UserService, controller: UserController } =
179
+ createCrudModule(User, 'users')
180
+
181
+ @Module({
182
+ imports: [TypeOrmModule.forFeature([User])],
183
+ controllers: [UserController],
184
+ providers: [UserService],
185
+ })
186
+ export class UserModule {}
187
+ ```
188
+
189
+ ### API
190
+
191
+ | Method | Endpoint | Description |
192
+ |---|---|---|
193
+ | `findAll` | `GET /` | List all records |
194
+ | `findOne` | `GET /:id` | Get one record by ID |
195
+ | `create` | `POST /` | Create a new record |
196
+ | `update` | `PATCH /:id` | Update an existing record |
197
+ | `remove` | `DELETE /:id` | Delete a record |
@@ -0,0 +1,4 @@
1
+ import { Type } from '@nestjs/common';
2
+ import type { ObjectLiteral } from 'typeorm';
3
+ import type { ICrudService } from './crud.interface.js';
4
+ export declare function createCrudController<Entity extends ObjectLiteral>(route: string, serviceClass: Type<ICrudService<Entity>>): Type<any>;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.createCrudController = createCrudController;
16
+ const common_1 = require("@nestjs/common");
17
+ function createCrudController(route, serviceClass) {
18
+ let CrudController = class CrudController {
19
+ service;
20
+ constructor(service) {
21
+ this.service = service;
22
+ }
23
+ async getMany() {
24
+ return this.service.findAll();
25
+ }
26
+ async getOne(id) {
27
+ return this.service.findOne(id);
28
+ }
29
+ async create(data) {
30
+ return this.service.create(data);
31
+ }
32
+ async update(id, data) {
33
+ return this.service.update(id, data);
34
+ }
35
+ async remove(id) {
36
+ return this.service.remove(id);
37
+ }
38
+ };
39
+ __decorate([
40
+ (0, common_1.Get)(),
41
+ __metadata("design:type", Function),
42
+ __metadata("design:paramtypes", []),
43
+ __metadata("design:returntype", Promise)
44
+ ], CrudController.prototype, "getMany", null);
45
+ __decorate([
46
+ (0, common_1.Get)(':id'),
47
+ __param(0, (0, common_1.Param)('id')),
48
+ __metadata("design:type", Function),
49
+ __metadata("design:paramtypes", [String]),
50
+ __metadata("design:returntype", Promise)
51
+ ], CrudController.prototype, "getOne", null);
52
+ __decorate([
53
+ (0, common_1.Post)(),
54
+ __param(0, (0, common_1.Body)()),
55
+ __metadata("design:type", Function),
56
+ __metadata("design:paramtypes", [Object]),
57
+ __metadata("design:returntype", Promise)
58
+ ], CrudController.prototype, "create", null);
59
+ __decorate([
60
+ (0, common_1.Patch)(':id'),
61
+ __param(0, (0, common_1.Param)('id')),
62
+ __param(1, (0, common_1.Body)()),
63
+ __metadata("design:type", Function),
64
+ __metadata("design:paramtypes", [String, Object]),
65
+ __metadata("design:returntype", Promise)
66
+ ], CrudController.prototype, "update", null);
67
+ __decorate([
68
+ (0, common_1.Delete)(':id'),
69
+ __param(0, (0, common_1.Param)('id')),
70
+ __metadata("design:type", Function),
71
+ __metadata("design:paramtypes", [String]),
72
+ __metadata("design:returntype", Promise)
73
+ ], CrudController.prototype, "remove", null);
74
+ CrudController = __decorate([
75
+ (0, common_1.Controller)(route),
76
+ __param(0, (0, common_1.Inject)(serviceClass)),
77
+ __metadata("design:paramtypes", [Object])
78
+ ], CrudController);
79
+ return CrudController;
80
+ }
81
+ //# sourceMappingURL=crud-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud-controller.js","sourceRoot":"","sources":["../../src/typeorm/crud-controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAcA,oDAyCC;AAvDD,2CAUwB;AAIxB,SAAgB,oBAAoB,CAClC,KAAa,EACb,YAAwC;IAExC,IACM,cAAc,GADpB,MACM,cAAc;QAGC;QAFnB,YAEmB,OAA6B;YAA7B,YAAO,GAAP,OAAO,CAAsB;QAC7C,CAAC;QAGE,AAAN,KAAK,CAAC,OAAO;YACX,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAChC,CAAC;QAGK,AAAN,KAAK,CAAC,MAAM,CAAc,EAAU;YAClC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAClC,CAAC;QAGK,AAAN,KAAK,CAAC,MAAM,CAAS,IAAyB;YAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAGK,AAAN,KAAK,CAAC,MAAM,CACG,EAAU,EACf,IAAyB;YAEjC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACvC,CAAC;QAGK,AAAN,KAAK,CAAC,MAAM,CAAc,EAAU;YAClC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjC,CAAC;KACF,CAAA;IA1BO;QADL,IAAA,YAAG,GAAE;;;;iDAGL;IAGK;QADL,IAAA,YAAG,EAAC,KAAK,CAAC;QACG,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;;;;gDAExB;IAGK;QADL,IAAA,aAAI,GAAE;QACO,WAAA,IAAA,aAAI,GAAE,CAAA;;;;gDAEnB;IAGK;QADL,IAAA,cAAK,EAAC,KAAK,CAAC;QAEV,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;QACX,WAAA,IAAA,aAAI,GAAE,CAAA;;;;gDAGR;IAGK;QADL,IAAA,eAAM,EAAC,KAAK,CAAC;QACA,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;;;;gDAExB;IAhCG,cAAc;QADnB,IAAA,mBAAU,EAAC,KAAK,CAAC;QAGb,WAAA,IAAA,eAAM,EAAC,YAAY,CAAC,CAAA;;OAFnB,cAAc,CAiCnB;IAED,OAAO,cAAc,CAAC;AACxB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { Type } from '@nestjs/common';
2
+ import type { ObjectLiteral } from 'typeorm';
3
+ import type { ICrudService } from './crud.interface.js';
4
+ export declare function createCrudService<Entity extends ObjectLiteral & {
5
+ id: string | number;
6
+ }>(entity: Type<Entity>): Type<ICrudService<Entity>>;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.createCrudService = createCrudService;
16
+ const common_1 = require("@nestjs/common");
17
+ const typeorm_1 = require("@nestjs/typeorm");
18
+ const typeorm_2 = require("typeorm");
19
+ function createCrudService(entity) {
20
+ let CrudService = class CrudService {
21
+ repository;
22
+ constructor(repository) {
23
+ this.repository = repository;
24
+ }
25
+ async findAll(options) {
26
+ return this.repository.find(options);
27
+ }
28
+ async findOne(id, options) {
29
+ return this.repository.findOne({
30
+ where: { id },
31
+ ...options,
32
+ });
33
+ }
34
+ async create(data) {
35
+ const entity = this.repository.create(data);
36
+ return this.repository.save(entity);
37
+ }
38
+ async update(id, data) {
39
+ await this.repository.update(id, data);
40
+ return this.findOne(id);
41
+ }
42
+ async remove(id) {
43
+ await this.repository.delete(id);
44
+ }
45
+ };
46
+ CrudService = __decorate([
47
+ (0, common_1.Injectable)(),
48
+ __param(0, (0, typeorm_1.InjectRepository)(entity)),
49
+ __metadata("design:paramtypes", [typeorm_2.Repository])
50
+ ], CrudService);
51
+ return CrudService;
52
+ }
53
+ //# sourceMappingURL=crud-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud-service.js","sourceRoot":"","sources":["../../src/typeorm/crud-service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAYA,8CA+CC;AA3DD,2CAAkD;AAClD,6CAAmD;AAQnD,qCAAqC;AAGrC,SAAgB,iBAAiB,CAE/B,MAAoB;IACpB,IACM,WAAW,GADjB,MACM,WAAW;QACC,UAAU,CAAqB;QAE/C,YAEE,UAA8B;YAE9B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC/B,CAAC;QAED,KAAK,CAAC,OAAO,CAAC,OAAiC;YAC7C,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;QAED,KAAK,CAAC,OAAO,CACX,EAAmB,EACnB,OAAgC;YAEhC,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC7B,KAAK,EAAE,EAAE,EAAE,EAAyC;gBACpD,GAAG,OAAO;aACX,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,IAAyB;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;QAED,KAAK,CAAC,MAAM,CACV,EAAmB,EACnB,IAAyB;YAEzB,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACvC,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAoB,CAAC;QAC7C,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,EAAmB;YAC9B,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnC,CAAC;KACF,CAAA;IAxCK,WAAW;QADhB,IAAA,mBAAU,GAAE;QAKR,WAAA,IAAA,0BAAgB,EAAC,MAAM,CAAC,CAAA;yCACb,oBAAU;OALpB,WAAW,CAwChB;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { DeepPartial, FindManyOptions, FindOneOptions, ObjectLiteral, Repository } from 'typeorm';
2
+ export interface ICrudService<Entity extends ObjectLiteral> {
3
+ readonly repository: Repository<Entity>;
4
+ findAll(options?: FindManyOptions<Entity>): Promise<Entity[]>;
5
+ findOne(id: string | number, options?: FindOneOptions<Entity>): Promise<Entity | null>;
6
+ create(data: DeepPartial<Entity>): Promise<Entity>;
7
+ update(id: string | number, data: DeepPartial<Entity>): Promise<Entity>;
8
+ remove(id: string | number): Promise<void>;
9
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=crud.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.interface.js","sourceRoot":"","sources":["../../src/typeorm/crud.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import type { ConfigService } from '@nestjs/config';
2
+ import type { TypeOrmModuleOptions } from '@nestjs/typeorm';
3
+ import type { Type } from '@nestjs/common';
4
+ import type { ObjectLiteral } from 'typeorm';
5
+ import type { ICrudService } from './crud.interface.js';
6
+ export { createCrudService } from './crud-service.js';
7
+ export { createCrudController } from './crud-controller.js';
8
+ export type { ICrudService } from './crud.interface.js';
9
+ export declare function createCrudModule<Entity extends ObjectLiteral & {
10
+ id: string | number;
11
+ }>(entity: Type<Entity>, route: string): {
12
+ service: Type<ICrudService<Entity>>;
13
+ controller: Type<any>;
14
+ };
15
+ export interface TypeOrmConfigOptions {
16
+ schema?: string;
17
+ poolSize?: number;
18
+ idleTimeoutMs?: number;
19
+ connectionTimeoutMs?: number;
20
+ statementTimeoutMs?: number;
21
+ }
22
+ export declare function configTypeOrmRDSPostgres(configService: ConfigService, options?: TypeOrmConfigOptions): TypeOrmModuleOptions;
23
+ export declare function configTypeOrmMySQL(configService: ConfigService, options?: TypeOrmConfigOptions): TypeOrmModuleOptions;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCrudController = exports.createCrudService = void 0;
4
+ exports.createCrudModule = createCrudModule;
5
+ exports.configTypeOrmRDSPostgres = configTypeOrmRDSPostgres;
6
+ exports.configTypeOrmMySQL = configTypeOrmMySQL;
7
+ const crud_service_js_1 = require("./crud-service.js");
8
+ const crud_controller_js_1 = require("./crud-controller.js");
9
+ var crud_service_js_2 = require("./crud-service.js");
10
+ Object.defineProperty(exports, "createCrudService", { enumerable: true, get: function () { return crud_service_js_2.createCrudService; } });
11
+ var crud_controller_js_2 = require("./crud-controller.js");
12
+ Object.defineProperty(exports, "createCrudController", { enumerable: true, get: function () { return crud_controller_js_2.createCrudController; } });
13
+ function createCrudModule(entity, route) {
14
+ const service = (0, crud_service_js_1.createCrudService)(entity);
15
+ const controller = (0, crud_controller_js_1.createCrudController)(route, service);
16
+ return { service, controller };
17
+ }
18
+ function configTypeOrmRDSPostgres(configService, options) {
19
+ const rejectUnauthorized = configService.get('DB_SSL_REJECT_UNAUTHORIZED', false);
20
+ return {
21
+ type: 'postgres',
22
+ host: configService.get('DB_HOST', 'localhost'),
23
+ port: configService.get('DB_PORT', 5432),
24
+ username: configService.get('DB_USERNAME'),
25
+ password: configService.get('DB_PASSWORD'),
26
+ database: configService.get('DB_DATABASE', 'postgres'),
27
+ synchronize: configService.get('DB_SYNCHRONIZE', false),
28
+ logging: configService.get('DB_LOGGING', false) ? 'all' : false,
29
+ ssl: { rejectUnauthorized },
30
+ extra: {
31
+ ssl: { rejectUnauthorized },
32
+ max: options?.poolSize ?? 20,
33
+ idleTimeoutMillis: options?.idleTimeoutMs ?? 30000,
34
+ connectionTimeoutMillis: options?.connectionTimeoutMs ?? 10000,
35
+ statement_timeout: options?.statementTimeoutMs ?? 30000,
36
+ ...(options?.schema ? { schema: options.schema } : {}),
37
+ },
38
+ autoLoadEntities: true,
39
+ retryAttempts: 10,
40
+ retryDelay: 3000,
41
+ };
42
+ }
43
+ function configTypeOrmMySQL(configService, options) {
44
+ const rejectUnauthorized = configService.get('DB_SSL_REJECT_UNAUTHORIZED', false);
45
+ return {
46
+ type: 'mysql',
47
+ host: configService.get('DB_HOST', 'localhost'),
48
+ port: configService.get('DB_PORT', 3306),
49
+ username: configService.get('DB_USERNAME'),
50
+ password: configService.get('DB_PASSWORD'),
51
+ database: configService.get('DB_DATABASE', 'mysql'),
52
+ synchronize: configService.get('DB_SYNCHRONIZE', false),
53
+ logging: configService.get('DB_LOGGING', false) ? 'all' : false,
54
+ ssl: { rejectUnauthorized },
55
+ extra: {
56
+ ssl: { rejectUnauthorized },
57
+ max: options?.poolSize ?? 10,
58
+ idleTimeoutMillis: options?.idleTimeoutMs ?? 10000,
59
+ connectionTimeoutMillis: options?.connectionTimeoutMs ?? 5000,
60
+ },
61
+ autoLoadEntities: true,
62
+ retryAttempts: 10,
63
+ retryDelay: 3000,
64
+ };
65
+ }
66
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/typeorm/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("./index");
4
+ function createMockConfigService(env = {}) {
5
+ return {
6
+ get: jest.fn((key, defaultValue) => {
7
+ return key in env ? env[key] : defaultValue;
8
+ }),
9
+ };
10
+ }
11
+ describe('@vn.chemgio/nestjs-utilities/typeorm', () => {
12
+ describe('configTypeOrmRDSPostgres', () => {
13
+ it('should return postgres config with defaults', () => {
14
+ const config = createMockConfigService();
15
+ const result = (0, index_1.configTypeOrmRDSPostgres)(config);
16
+ expect(result.type).toBe('postgres');
17
+ expect(result.host).toBe('localhost');
18
+ expect(result.port).toBe(5432);
19
+ expect(result.database).toBe('postgres');
20
+ expect(result.synchronize).toBe(false);
21
+ expect(result.ssl).toEqual({ rejectUnauthorized: false });
22
+ expect(config.get).toHaveBeenCalledWith('DB_PORT', 5432);
23
+ });
24
+ it('should read string values from ConfigService', () => {
25
+ const config = createMockConfigService({
26
+ DB_HOST: 'myhost.example.com',
27
+ DB_USERNAME: 'admin',
28
+ DB_PASSWORD: 'secret',
29
+ DB_DATABASE: 'mydb',
30
+ });
31
+ const result = (0, index_1.configTypeOrmRDSPostgres)(config);
32
+ expect(result.host).toBe('myhost.example.com');
33
+ expect(result.username).toBe('admin');
34
+ expect(result.password).toBe('secret');
35
+ expect(result.database).toBe('mydb');
36
+ });
37
+ it('should apply TypeOrmConfigOptions', () => {
38
+ const config = createMockConfigService();
39
+ const options = {
40
+ schema: 'public',
41
+ poolSize: 50,
42
+ idleTimeoutMs: 60000,
43
+ connectionTimeoutMs: 15000,
44
+ statementTimeoutMs: 60000,
45
+ };
46
+ const result = (0, index_1.configTypeOrmRDSPostgres)(config, options);
47
+ expect(result.extra).toMatchObject({
48
+ max: 50,
49
+ idleTimeoutMillis: 60000,
50
+ connectionTimeoutMillis: 15000,
51
+ statement_timeout: 60000,
52
+ schema: 'public',
53
+ });
54
+ });
55
+ it('should read sync and ssl from env', () => {
56
+ const config = createMockConfigService({
57
+ DB_SYNCHRONIZE: 'true',
58
+ DB_SSL_REJECT_UNAUTHORIZED: 'true',
59
+ });
60
+ const result = (0, index_1.configTypeOrmRDSPostgres)(config);
61
+ expect(result.synchronize).toBe('true');
62
+ expect(result.ssl?.rejectUnauthorized).toBe('true');
63
+ });
64
+ it('should include autoLoadEntities and retry config', () => {
65
+ const config = createMockConfigService();
66
+ const result = (0, index_1.configTypeOrmRDSPostgres)(config);
67
+ expect(result.autoLoadEntities).toBe(true);
68
+ expect(result.retryAttempts).toBe(10);
69
+ expect(result.retryDelay).toBe(3000);
70
+ });
71
+ });
72
+ describe('configTypeOrmMySQL', () => {
73
+ it('should return mysql config with defaults', () => {
74
+ const config = createMockConfigService();
75
+ const result = (0, index_1.configTypeOrmMySQL)(config);
76
+ expect(result.type).toBe('mysql');
77
+ expect(result.host).toBe('localhost');
78
+ expect(result.port).toBe(3306);
79
+ expect(result.database).toBe('mysql');
80
+ expect(result.synchronize).toBe(false);
81
+ });
82
+ it('should read string values from ConfigService', () => {
83
+ const config = createMockConfigService({
84
+ DB_HOST: 'mysql.example.com',
85
+ DB_USERNAME: 'root',
86
+ DB_PASSWORD: 'pwd',
87
+ DB_DATABASE: 'analytics',
88
+ });
89
+ const result = (0, index_1.configTypeOrmMySQL)(config);
90
+ expect(result.host).toBe('mysql.example.com');
91
+ expect(result.username).toBe('root');
92
+ expect(result.password).toBe('pwd');
93
+ expect(result.database).toBe('analytics');
94
+ });
95
+ it('should apply TypeOrmConfigOptions', () => {
96
+ const config = createMockConfigService();
97
+ const options = {
98
+ poolSize: 5,
99
+ idleTimeoutMs: 5000,
100
+ };
101
+ const result = (0, index_1.configTypeOrmMySQL)(config, options);
102
+ expect(result.extra).toMatchObject({
103
+ max: 5,
104
+ idleTimeoutMillis: 5000,
105
+ });
106
+ });
107
+ });
108
+ });
109
+ //# sourceMappingURL=index.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../../src/typeorm/index.spec.ts"],"names":[],"mappings":"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"}