@triproject/nestjs-core 1.0.39 → 1.0.40
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/dist/drivers/sequelize/sequelize.module.js +4 -1
- package/dist/drivers/sequelize/sequelize.repository.d.ts +4 -4
- package/dist/drivers/sequelize/sequelize.repository.js +50 -24
- package/dist/drivers/sequelize/sequelize.service.d.ts +4 -3
- package/dist/drivers/sequelize/sequelize.service.js +22 -15
- package/package.json +28 -23
|
@@ -31,7 +31,10 @@ SequelizeModule = function(decorators, target, key, desc) {
|
|
|
31
31
|
dialect: DB_DIALECT,
|
|
32
32
|
pool: {
|
|
33
33
|
min: 2,
|
|
34
|
-
max: DB_MAX_POOL_SIZE
|
|
34
|
+
max: DB_MAX_POOL_SIZE,
|
|
35
|
+
acquire: 10_000,
|
|
36
|
+
idle: 500,
|
|
37
|
+
evict: 1_000
|
|
35
38
|
},
|
|
36
39
|
models: [
|
|
37
40
|
(0, _path.resolve)(DB_ENTITIES_PATH)
|
|
@@ -9,11 +9,11 @@ export declare class Repository<M extends Model<M, Partial<M>> & {
|
|
|
9
9
|
protected Model: ModelStatic<M>;
|
|
10
10
|
protected db: Sequelize;
|
|
11
11
|
private excludeParamsFromFilter;
|
|
12
|
-
private get
|
|
13
|
-
private
|
|
12
|
+
private get FIELDS();
|
|
13
|
+
private _errorHandler;
|
|
14
14
|
private _getTrueKey;
|
|
15
|
-
private
|
|
16
|
-
private
|
|
15
|
+
private _parsedBetweenData;
|
|
16
|
+
private _mapFilter;
|
|
17
17
|
private _getOptions;
|
|
18
18
|
protected findForPublic<P extends {
|
|
19
19
|
label: string;
|
|
@@ -27,20 +27,18 @@ let Repository = class Repository {
|
|
|
27
27
|
'groupBy',
|
|
28
28
|
'order'
|
|
29
29
|
];
|
|
30
|
-
get
|
|
30
|
+
get FIELDS() {
|
|
31
31
|
return Object.keys(this.Model.getAttributes());
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
type: attributes[attr].type
|
|
38
|
-
}));
|
|
33
|
+
_errorHandler(error) {
|
|
34
|
+
throw error.message.match(/SequelizeConnectionError|SequelizeConnectionRefusedError|SequelizeHostNotFoundError|SequelizeHostNotReachableError|SequelizeInvalidConnectionError|SequelizeConnectionTimedOutError|ETIMEDOUT|EHOSTUNREACH|ECONNREFUSED|ECONNRESET|EPIPE/) && this.db.authenticate().catch(()=>{
|
|
35
|
+
this.logger.warn('Reconnection attempt failed');
|
|
36
|
+
}), this.logger.error('Database operation failed:', error), new _common.UnprocessableEntityException('Failed to process database operation');
|
|
39
37
|
}
|
|
40
38
|
_getTrueKey(key) {
|
|
41
39
|
return key.replace(/^(min_|max_|start_|end_)/, '');
|
|
42
40
|
}
|
|
43
|
-
|
|
41
|
+
_parsedBetweenData(where, key, value) {
|
|
44
42
|
let col = this._getTrueKey(key), operation = /^(start_|min_)/.test(key) ? 'gte' : 'lte', isDateColumn = /^(start_|end_)/.test(key), formattedValue = isDateColumn ? (0, _helpers.dateUtil)(value).utc().format('YYYY-MM-DD HH:mm:ss') : value, existingCondition = where[col];
|
|
45
43
|
if (!existingCondition) return {
|
|
46
44
|
[_sequelize.Op[operation]]: formattedValue
|
|
@@ -56,13 +54,13 @@ let Repository = class Repository {
|
|
|
56
54
|
]
|
|
57
55
|
};
|
|
58
56
|
}
|
|
59
|
-
|
|
57
|
+
_mapFilter(filter, cols) {
|
|
60
58
|
let where = {};
|
|
61
59
|
for (let key of Object.keys(filter)){
|
|
62
60
|
let col = this._getTrueKey(key), isSpecialKey = key.includes('$') || key.includes('.');
|
|
63
61
|
if (!cols.includes(col) && !isSpecialKey) continue;
|
|
64
62
|
let value = filter[key];
|
|
65
|
-
void 0 !== value && (/^(min_|max_|start_|end_)/.test(key) ? value = this.
|
|
63
|
+
void 0 !== value && (/^(min_|max_|start_|end_)/.test(key) ? value = this._parsedBetweenData(where, key, value) : 'string' == typeof value && value.includes(',') ? value = value.split(',') : 'object' != typeof value || Array.isArray(value) ? [
|
|
66
64
|
null,
|
|
67
65
|
'null',
|
|
68
66
|
''
|
|
@@ -85,8 +83,8 @@ let Repository = class Repository {
|
|
|
85
83
|
}
|
|
86
84
|
_getOptions(params) {
|
|
87
85
|
if (!params.attributes) throw new _common.UnprocessableEntityException('Attributes is required');
|
|
88
|
-
let fields = this.
|
|
89
|
-
...this.
|
|
86
|
+
let fields = this.FIELDS, where = {
|
|
87
|
+
...this._mapFilter((0, _helpers.omit)(params, this.excludeParamsFromFilter), fields),
|
|
90
88
|
...params.where
|
|
91
89
|
}, andConditions = [], orConditions = [];
|
|
92
90
|
if (params.q && params.searchKey) {
|
|
@@ -151,7 +149,7 @@ let Repository = class Repository {
|
|
|
151
149
|
};
|
|
152
150
|
}
|
|
153
151
|
async paginateCursor(params, mapInto) {
|
|
154
|
-
if (!this.
|
|
152
|
+
if (!this.FIELDS?.includes('id')) throw new _common.UnprocessableEntityException('Entity must have id attribute for cursor pagination');
|
|
155
153
|
params.attributes = (0, _helpers.uniqueArray)([
|
|
156
154
|
...params.attributes || [],
|
|
157
155
|
'id'
|
|
@@ -187,16 +185,24 @@ let Repository = class Repository {
|
|
|
187
185
|
return data ? (await this.update(data, values, options), data) : await this.create(values, options);
|
|
188
186
|
}
|
|
189
187
|
async findAll(options) {
|
|
190
|
-
return this.Model.findAll(options)
|
|
188
|
+
return this.Model.findAll(options).catch((error)=>{
|
|
189
|
+
throw this._errorHandler(error);
|
|
190
|
+
});
|
|
191
191
|
}
|
|
192
192
|
async findAndCountAll(options) {
|
|
193
|
-
return this.Model.findAndCountAll(options)
|
|
193
|
+
return this.Model.findAndCountAll(options).catch((error)=>{
|
|
194
|
+
throw this._errorHandler(error);
|
|
195
|
+
});
|
|
194
196
|
}
|
|
195
197
|
async findOne(options) {
|
|
196
|
-
return this.Model.findOne(options)
|
|
198
|
+
return this.Model.findOne(options).catch((error)=>{
|
|
199
|
+
throw this._errorHandler(error);
|
|
200
|
+
});
|
|
197
201
|
}
|
|
198
202
|
async create(values, options) {
|
|
199
|
-
return this.Model.create(values, options)
|
|
203
|
+
return this.Model.create(values, options).catch((error)=>{
|
|
204
|
+
throw this._errorHandler(error);
|
|
205
|
+
});
|
|
200
206
|
}
|
|
201
207
|
async update(entity, values, options) {
|
|
202
208
|
let model = entity;
|
|
@@ -210,30 +216,44 @@ let Repository = class Repository {
|
|
|
210
216
|
})), !model) throw new _exceptionhelper.AppNotFoundException();
|
|
211
217
|
return model.update(values, {
|
|
212
218
|
...options
|
|
219
|
+
}).catch((error)=>{
|
|
220
|
+
throw this._errorHandler(error);
|
|
213
221
|
});
|
|
214
222
|
}
|
|
215
223
|
async upsert(values, options) {
|
|
216
224
|
return this.Model.upsert(values, {
|
|
217
225
|
...options
|
|
226
|
+
}).catch((error)=>{
|
|
227
|
+
throw this._errorHandler(error);
|
|
218
228
|
});
|
|
219
229
|
}
|
|
220
230
|
async bulkUpdate(values, options) {
|
|
221
231
|
return this.Model.update(values, {
|
|
222
232
|
...options
|
|
233
|
+
}).catch((error)=>{
|
|
234
|
+
throw this._errorHandler(error);
|
|
223
235
|
});
|
|
224
236
|
}
|
|
225
237
|
async bulkCreate(values, options) {
|
|
226
|
-
return this.Model.bulkCreate(values, options)
|
|
238
|
+
return this.Model.bulkCreate(values, options).catch((error)=>{
|
|
239
|
+
throw this._errorHandler(error);
|
|
240
|
+
});
|
|
227
241
|
}
|
|
228
242
|
async destroy(options) {
|
|
229
|
-
return this.Model.destroy(options)
|
|
243
|
+
return this.Model.destroy(options).catch((error)=>{
|
|
244
|
+
throw this._errorHandler(error);
|
|
245
|
+
});
|
|
230
246
|
}
|
|
231
247
|
async sum(field, options) {
|
|
232
|
-
return this.Model.sum(field, options)
|
|
248
|
+
return this.Model.sum(field, options).catch((error)=>{
|
|
249
|
+
throw this._errorHandler(error);
|
|
250
|
+
});
|
|
233
251
|
}
|
|
234
252
|
async sumField(params, field) {
|
|
235
253
|
let options = this._getOptions(params);
|
|
236
|
-
return this.sum(field, options)
|
|
254
|
+
return this.sum(field, options).catch((error)=>{
|
|
255
|
+
throw this._errorHandler(error);
|
|
256
|
+
});
|
|
237
257
|
}
|
|
238
258
|
async sumCol(params, fieldToSum, expectedField) {
|
|
239
259
|
let options = this._getOptions(params);
|
|
@@ -242,14 +262,20 @@ let Repository = class Repository {
|
|
|
242
262
|
(0, _sequelize.fn)('sum', (0, _sequelize.col)(fieldToSum)),
|
|
243
263
|
expectedField
|
|
244
264
|
]
|
|
245
|
-
], (await this.Model.findAll(options)
|
|
265
|
+
], (await this.Model.findAll(options).catch((error)=>{
|
|
266
|
+
throw this._errorHandler(error);
|
|
267
|
+
})).reduce((total, row)=>total + parseFloat(String(row.get(expectedField)) || '0'), 0);
|
|
246
268
|
}
|
|
247
269
|
async count(options) {
|
|
248
|
-
return this.Model.count(options)
|
|
270
|
+
return this.Model.count(options).catch((error)=>{
|
|
271
|
+
throw this._errorHandler(error);
|
|
272
|
+
});
|
|
249
273
|
}
|
|
250
274
|
async filteredFindAll(params) {
|
|
251
275
|
let options = this._getOptions(params);
|
|
252
|
-
return this.Model.findAll(options)
|
|
276
|
+
return this.Model.findAll(options).catch((error)=>{
|
|
277
|
+
throw this._errorHandler(error);
|
|
278
|
+
});
|
|
253
279
|
}
|
|
254
280
|
};
|
|
255
281
|
!function(decorators, target, key, desc) {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { OnModuleInit } from '@nestjs/common';
|
|
1
|
+
import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
|
2
2
|
import { Sequelize } from 'sequelize-typescript';
|
|
3
|
-
export declare class SequelizeService implements OnModuleInit {
|
|
3
|
+
export declare class SequelizeService implements OnModuleInit, OnModuleDestroy {
|
|
4
4
|
private db;
|
|
5
5
|
private logger;
|
|
6
6
|
constructor(db: Sequelize);
|
|
7
7
|
onModuleInit(): Promise<void>;
|
|
8
|
+
onModuleDestroy(): Promise<void>;
|
|
9
|
+
handleReconnect(): void;
|
|
8
10
|
authenticate(): Promise<void>;
|
|
9
|
-
checkConnection(): Promise<boolean>;
|
|
10
11
|
}
|
|
@@ -7,7 +7,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
return SequelizeService;
|
|
8
8
|
}
|
|
9
9
|
});
|
|
10
|
-
let _common = require("@nestjs/common"), _sequelizetypescript = require("sequelize-typescript"), _applogger = require("../logger/app.logger"), _secretmanager = require("../secret-manager");
|
|
10
|
+
let _common = require("@nestjs/common"), _schedule = require("@nestjs/schedule"), _sequelizetypescript = require("sequelize-typescript"), _applogger = require("../logger/app.logger"), _secretmanager = require("../secret-manager");
|
|
11
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
12
|
+
var d, c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc;
|
|
13
|
+
if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
|
|
14
|
+
else for(var i = decorators.length - 1; i >= 0; i--)(d = decorators[i]) && (r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r);
|
|
15
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
16
|
+
}
|
|
11
17
|
function _ts_metadata(k, v) {
|
|
12
18
|
if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
|
|
13
19
|
}
|
|
@@ -20,30 +26,31 @@ let SequelizeService = class SequelizeService {
|
|
|
20
26
|
async onModuleInit() {
|
|
21
27
|
await this.authenticate();
|
|
22
28
|
}
|
|
29
|
+
async onModuleDestroy() {
|
|
30
|
+
await this.db.close();
|
|
31
|
+
}
|
|
32
|
+
handleReconnect() {
|
|
33
|
+
this.authenticate().catch((err)=>{
|
|
34
|
+
this.logger.error('Database reconnection failed:', err);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
23
37
|
async authenticate() {
|
|
24
38
|
let env = await (0, _secretmanager.getSecret)();
|
|
25
39
|
await this.db.authenticate({
|
|
26
40
|
retry: {
|
|
27
|
-
max:
|
|
41
|
+
max: 3
|
|
28
42
|
}
|
|
29
43
|
}).then(()=>this.logger.log(`Database connected successfully to ${env.DB_NAME}:${env.DB_DIALECT}`)).catch((err)=>{
|
|
30
44
|
throw this.logger.error('Unable to connect to the database:', err), err;
|
|
31
45
|
});
|
|
32
46
|
}
|
|
33
|
-
async checkConnection() {
|
|
34
|
-
return await this.db.authenticate({
|
|
35
|
-
retry: {
|
|
36
|
-
max: 1
|
|
37
|
-
}
|
|
38
|
-
}).then(()=>!0).catch((err)=>(this.logger.error('Database connection failed', err), !1));
|
|
39
|
-
}
|
|
40
47
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
_ts_decorate([
|
|
49
|
+
(0, _schedule.Cron)('*/5 * * * *'),
|
|
50
|
+
_ts_metadata("design:type", Function),
|
|
51
|
+
_ts_metadata("design:paramtypes", []),
|
|
52
|
+
_ts_metadata("design:returntype", void 0)
|
|
53
|
+
], SequelizeService.prototype, "handleReconnect", null), SequelizeService = _ts_decorate([
|
|
47
54
|
(0, _common.Injectable)(),
|
|
48
55
|
_ts_metadata("design:type", Function),
|
|
49
56
|
_ts_metadata("design:paramtypes", [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@triproject/nestjs-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.40",
|
|
4
4
|
"author": "",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"description": "A collection of NestJS modules and utilities to speed up development.",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"test": "vitest run"
|
|
79
79
|
},
|
|
80
80
|
"peerDependencies": {
|
|
81
|
-
"@nestjs/platform-express": "^11.1.
|
|
81
|
+
"@nestjs/platform-express": "^11.1.12",
|
|
82
82
|
"@aws-sdk/client-cloudwatch-logs": "^3.962.0",
|
|
83
83
|
"@aws-sdk/client-s3": "^3.962.0",
|
|
84
84
|
"@aws-sdk/client-secrets-manager": "^3.962.0",
|
|
@@ -86,10 +86,10 @@
|
|
|
86
86
|
"@nest-lab/throttler-storage-redis": "^1.1.0",
|
|
87
87
|
"@nestjs/bull": "^11.0.4",
|
|
88
88
|
"@nestjs/bullmq": "^11.0.4",
|
|
89
|
-
"@nestjs/common": "^11.1.
|
|
90
|
-
"@nestjs/core": "^11.1.
|
|
89
|
+
"@nestjs/common": "^11.1.12",
|
|
90
|
+
"@nestjs/core": "^11.1.12",
|
|
91
91
|
"@nestjs/sequelize": "^11.0.1",
|
|
92
|
-
"@nestjs/swagger": "^11.2.
|
|
92
|
+
"@nestjs/swagger": "^11.2.5",
|
|
93
93
|
"@nestjs/throttler": "^6.5.0",
|
|
94
94
|
"@triproject/helpers": "^1.1.24",
|
|
95
95
|
"amqp-connection-manager": "^5.0.0",
|
|
@@ -114,8 +114,9 @@
|
|
|
114
114
|
"sequelize": "^6.37.7",
|
|
115
115
|
"sequelize-typescript": "^2.1.6",
|
|
116
116
|
"speakeasy": "^2.0.0",
|
|
117
|
-
"ua-parser-js": "^2.0.
|
|
118
|
-
"reflect-metadata": "^0.2.2"
|
|
117
|
+
"ua-parser-js": "^2.0.8",
|
|
118
|
+
"reflect-metadata": "^0.2.2",
|
|
119
|
+
"@nestjs/schedule": "^6.1.0"
|
|
119
120
|
},
|
|
120
121
|
"peerDependenciesMeta": {
|
|
121
122
|
"amqplib": {
|
|
@@ -195,27 +196,30 @@
|
|
|
195
196
|
},
|
|
196
197
|
"@nestjs/throttler": {
|
|
197
198
|
"optional": true
|
|
199
|
+
},
|
|
200
|
+
"@nestjs/schedule": {
|
|
201
|
+
"optional": true
|
|
198
202
|
}
|
|
199
203
|
},
|
|
200
204
|
"devDependencies": {
|
|
201
205
|
"reflect-metadata": "^0.2.2",
|
|
202
|
-
"@nestjs/cli": "^11.0.
|
|
206
|
+
"@nestjs/cli": "^11.0.16",
|
|
203
207
|
"@nestjs/schematics": "^11.0.9",
|
|
204
|
-
"@nestjs/testing": "^11.1.
|
|
205
|
-
"@nestjs/platform-express": "^11.1.
|
|
206
|
-
"@aws-sdk/client-cloudwatch-logs": "^3.
|
|
208
|
+
"@nestjs/testing": "^11.1.12",
|
|
209
|
+
"@nestjs/platform-express": "^11.1.12",
|
|
210
|
+
"@aws-sdk/client-cloudwatch-logs": "^3.971.0",
|
|
207
211
|
"@aws-sdk/client-s3": "^3.962.0",
|
|
208
|
-
"@aws-sdk/client-secrets-manager": "^3.
|
|
209
|
-
"@aws-sdk/s3-request-presigner": "^3.
|
|
212
|
+
"@aws-sdk/client-secrets-manager": "^3.971.0",
|
|
213
|
+
"@aws-sdk/s3-request-presigner": "^3.971.0",
|
|
210
214
|
"@nest-lab/throttler-storage-redis": "^1.1.0",
|
|
211
215
|
"@nestjs/bull": "^11.0.4",
|
|
212
216
|
"@nestjs/bullmq": "^11.0.4",
|
|
213
|
-
"@nestjs/common": "^11.1.
|
|
214
|
-
"@nestjs/core": "^11.1.
|
|
217
|
+
"@nestjs/common": "^11.1.12",
|
|
218
|
+
"@nestjs/core": "^11.1.12",
|
|
215
219
|
"@nestjs/sequelize": "^11.0.1",
|
|
216
|
-
"@nestjs/swagger": "^11.2.
|
|
220
|
+
"@nestjs/swagger": "^11.2.5",
|
|
217
221
|
"@nestjs/throttler": "^6.5.0",
|
|
218
|
-
"@swc/cli": "^0.7.
|
|
222
|
+
"@swc/cli": "^0.7.10",
|
|
219
223
|
"@swc/core": "^1.15.8",
|
|
220
224
|
"@triproject/helpers": "^1.1.25",
|
|
221
225
|
"@types/amqp-connection-manager": "^3.4.5",
|
|
@@ -224,8 +228,8 @@
|
|
|
224
228
|
"@types/exceljs": "^1.3.2",
|
|
225
229
|
"@types/express": "^5.0.6",
|
|
226
230
|
"@types/jsonwebtoken": "^9.0.10",
|
|
227
|
-
"@types/node": "^25.0.
|
|
228
|
-
"@types/nodemailer": "^7.0.
|
|
231
|
+
"@types/node": "^25.0.9",
|
|
232
|
+
"@types/nodemailer": "^7.0.5",
|
|
229
233
|
"@types/qrcode": "^1.5.6",
|
|
230
234
|
"@types/redlock": "^4.0.8",
|
|
231
235
|
"@types/speakeasy": "^2.0.10",
|
|
@@ -233,14 +237,14 @@
|
|
|
233
237
|
"amqplib": "^0.10.9",
|
|
234
238
|
"axios": "^1.13.2",
|
|
235
239
|
"bull": "^4.16.5",
|
|
236
|
-
"bullmq": "^5.66.
|
|
240
|
+
"bullmq": "^5.66.5",
|
|
237
241
|
"class-validator": "^0.14.3",
|
|
238
242
|
"cookie-parser": "^1.4.7",
|
|
239
243
|
"dotenv": "^17.2.3",
|
|
240
244
|
"exceljs": "^4.4.0",
|
|
241
245
|
"express": "^5.2.1",
|
|
242
246
|
"helmet": "^8.1.0",
|
|
243
|
-
"ioredis": "^5.9.
|
|
247
|
+
"ioredis": "^5.9.2",
|
|
244
248
|
"jsonwebtoken": "^9.0.3",
|
|
245
249
|
"kafkajs": "^2.2.4",
|
|
246
250
|
"minio": "^8.0.6",
|
|
@@ -253,7 +257,8 @@
|
|
|
253
257
|
"speakeasy": "^2.0.0",
|
|
254
258
|
"ts-node": "^10.9.2",
|
|
255
259
|
"typescript": "^5.9.3",
|
|
256
|
-
"ua-parser-js": "^2.0.
|
|
257
|
-
"vitest": "^4.0.
|
|
260
|
+
"ua-parser-js": "^2.0.8",
|
|
261
|
+
"vitest": "^4.0.17",
|
|
262
|
+
"@nestjs/schedule": "^6.1.0"
|
|
258
263
|
}
|
|
259
264
|
}
|