@triproject/nestjs-core 1.0.37 → 1.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -90,7 +90,7 @@ async cacheData() {
90
90
  ### Database (Sequelize)
91
91
 
92
92
  ```typescript
93
- import { DatabaseModule, Repository } from '@triproject/nestjs-core/db';
93
+ import { DatabaseModule, Repository } from '@triproject/nestjs-core/sequelize';
94
94
 
95
95
  // In your module
96
96
  @Module({
@@ -342,7 +342,7 @@ bootstrap(AppModule, setupSwagger);
342
342
  // app.module.ts
343
343
  import { Module } from '@nestjs/common';
344
344
  import { CacheModule } from '@triproject/nestjs-core/cache';
345
- import { DatabaseModule } from '@triproject/nestjs-core/db';
345
+ import { DatabaseModule } from '@triproject/nestjs-core/sequelize';
346
346
  import { EncryptionModule } from '@triproject/nestjs-core/encryption';
347
347
  import { MailModule } from '@triproject/nestjs-core/mail';
348
348
 
@@ -0,0 +1,5 @@
1
+ export * from './sequelize.helper';
2
+ export * from './sequelize.migration';
3
+ export * from './sequelize.module';
4
+ export * from './sequelize.repository';
5
+ export * from './sequelize.service';
@@ -11,4 +11,4 @@ function _export_star(from, to) {
11
11
  }
12
12
  Object.defineProperty(exports, "__esModule", {
13
13
  value: !0
14
- }), _export_star(require("./db.helper"), exports), _export_star(require("./db.module"), exports), _export_star(require("./db.service"), exports), _export_star(require("./migration"), exports), _export_star(require("./repository"), exports);
14
+ }), _export_star(require("./sequelize.helper"), exports), _export_star(require("./sequelize.migration"), exports), _export_star(require("./sequelize.module"), exports), _export_star(require("./sequelize.repository"), exports), _export_star(require("./sequelize.service"), exports);
@@ -3,23 +3,33 @@ import { Attributes, IncludeOptions, ModelAttributeColumnOptions, WhereOptions }
3
3
  import { Model } from 'sequelize-typescript';
4
4
  import { Fn } from 'sequelize/types/utils';
5
5
  export type OrderDataType = 'ASC' | 'DESC';
6
- export type KeyOfModel<M extends Model> = (keyof Attributes<M>)[][number];
6
+ export type KeyOfModel<M extends Model> = keyof Attributes<M>;
7
+ declare class BasePaginateResponseMeta {
8
+ perPage: number;
9
+ }
10
+ declare class PaginateResponseMeta extends BasePaginateResponseMeta {
11
+ prevPage: null | number;
12
+ page: number;
13
+ nextPage: null | number;
14
+ totalPage: number;
15
+ total: number;
16
+ }
7
17
  export declare class PaginateResponse<T> {
8
18
  data: T[];
9
19
  timestamp: string;
10
- meta: {
11
- total: number;
12
- totalPage: number;
13
- perPage: number;
14
- prevPage: null | number;
15
- page: number;
16
- nextPage: null | number;
17
- };
20
+ meta: PaginateResponseMeta;
21
+ }
22
+ declare class PaginateCursorResponseMeta extends BasePaginateResponseMeta {
23
+ nextCursor: null | string;
24
+ }
25
+ export declare class PaginateCursorResponse<T> {
26
+ data: T[];
27
+ timestamp: string;
28
+ meta: PaginateCursorResponseMeta;
18
29
  }
19
30
  export type NestedOrders = ([string, OrderDataType] | [string, string, OrderDataType] | [string, string, string, OrderDataType])[];
20
- export declare class PaginateRequest<M extends Model> {
31
+ export declare class BasePaginateRequest<M extends Model> {
21
32
  perPage?: number;
22
- page?: number;
23
33
  q?: string;
24
34
  orderBy?: KeyOfModel<M>;
25
35
  sort?: OrderDataType;
@@ -27,11 +37,16 @@ export declare class PaginateRequest<M extends Model> {
27
37
  order?: NestedOrders;
28
38
  include?: IncludeOptions[];
29
39
  where?: WhereOptions<M>;
30
- orWhere?: WhereOptions<M>[];
31
- andWhere?: WhereOptions<M>[];
40
+ orWhere?: WhereOptions<M>;
32
41
  attributes?: (string | [Fn, string])[];
33
42
  groupBy?: string | string[];
34
43
  }
44
+ export declare class PaginateRequest<M extends Model> extends BasePaginateRequest<M> {
45
+ page?: number;
46
+ }
47
+ export declare class PaginateCursorRequest<M extends Model> extends BasePaginateRequest<M> {
48
+ cursor?: string;
49
+ }
35
50
  export declare function PrimaryUuidCol(): Function;
36
51
  export declare function PrimaryCodeCol(): Function;
37
52
  export declare function PrimaryNumberCol(): Function;
@@ -53,3 +68,4 @@ export declare class Entity<M extends {}> extends Model<M, Partial<M>> {
53
68
  export declare class RelationEntity<M extends {}> extends Model<M, Partial<M>> {
54
69
  id: number;
55
70
  }
71
+ export {};
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", {
3
3
  value: !0
4
4
  });
5
5
  var target = exports, all = {
6
+ get BasePaginateRequest () {
7
+ return BasePaginateRequest;
8
+ },
6
9
  get BooleanCol () {
7
10
  return BooleanCol;
8
11
  },
@@ -24,6 +27,12 @@ var target = exports, all = {
24
27
  get NumberCol () {
25
28
  return NumberCol;
26
29
  },
30
+ get PaginateCursorRequest () {
31
+ return PaginateCursorRequest;
32
+ },
33
+ get PaginateCursorResponse () {
34
+ return PaginateCursorResponse;
35
+ },
27
36
  get PaginateRequest () {
28
37
  return PaginateRequest;
29
38
  },
@@ -63,6 +72,54 @@ function _ts_decorate(decorators, target, key, desc) {
63
72
  function _ts_metadata(k, v) {
64
73
  if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
65
74
  }
75
+ let BasePaginateResponseMeta = class BasePaginateResponseMeta {
76
+ perPage;
77
+ };
78
+ _ts_decorate([
79
+ (0, _swagger.ApiProperty)({
80
+ example: 10,
81
+ description: 'Number of items per page'
82
+ }),
83
+ _ts_metadata("design:type", Number)
84
+ ], BasePaginateResponseMeta.prototype, "perPage", void 0);
85
+ let PaginateResponseMeta = class PaginateResponseMeta extends BasePaginateResponseMeta {
86
+ prevPage;
87
+ page;
88
+ nextPage;
89
+ totalPage;
90
+ total;
91
+ };
92
+ _ts_decorate([
93
+ (0, _swagger.ApiProperty)({
94
+ example: null,
95
+ description: 'Previous page number'
96
+ }),
97
+ _ts_metadata("design:type", Object)
98
+ ], PaginateResponseMeta.prototype, "prevPage", void 0), _ts_decorate([
99
+ (0, _swagger.ApiProperty)({
100
+ example: 1,
101
+ description: 'Current page number'
102
+ }),
103
+ _ts_metadata("design:type", Number)
104
+ ], PaginateResponseMeta.prototype, "page", void 0), _ts_decorate([
105
+ (0, _swagger.ApiProperty)({
106
+ example: 2,
107
+ description: 'Next page number'
108
+ }),
109
+ _ts_metadata("design:type", Object)
110
+ ], PaginateResponseMeta.prototype, "nextPage", void 0), _ts_decorate([
111
+ (0, _swagger.ApiProperty)({
112
+ example: 10,
113
+ description: 'Total number of pages'
114
+ }),
115
+ _ts_metadata("design:type", Number)
116
+ ], PaginateResponseMeta.prototype, "totalPage", void 0), _ts_decorate([
117
+ (0, _swagger.ApiProperty)({
118
+ example: 100,
119
+ description: 'Total number of items'
120
+ }),
121
+ _ts_metadata("design:type", Number)
122
+ ], PaginateResponseMeta.prototype, "total", void 0);
66
123
  let PaginateResponse = class PaginateResponse {
67
124
  data;
68
125
  timestamp;
@@ -76,20 +133,41 @@ _ts_decorate([
76
133
  _ts_metadata("design:type", String)
77
134
  ], PaginateResponse.prototype, "timestamp", void 0), _ts_decorate([
78
135
  (0, _swagger.ApiProperty)({
79
- example: {
80
- total: 100,
81
- totalPage: 10,
82
- perPage: 10,
83
- prevPage: null,
84
- page: 1,
85
- nextPage: 2
86
- }
136
+ type: PaginateResponseMeta,
137
+ description: 'Pagination metadata'
87
138
  }),
88
- _ts_metadata("design:type", Object)
139
+ _ts_metadata("design:type", PaginateResponseMeta)
89
140
  ], PaginateResponse.prototype, "meta", void 0);
90
- let PaginateRequest = class PaginateRequest {
141
+ let PaginateCursorResponseMeta = class PaginateCursorResponseMeta extends BasePaginateResponseMeta {
142
+ nextCursor;
143
+ };
144
+ _ts_decorate([
145
+ (0, _swagger.ApiProperty)({
146
+ example: 'cursor_string',
147
+ description: 'Cursor for the next page'
148
+ }),
149
+ _ts_metadata("design:type", Object)
150
+ ], PaginateCursorResponseMeta.prototype, "nextCursor", void 0);
151
+ let PaginateCursorResponse = class PaginateCursorResponse {
152
+ data;
153
+ timestamp;
154
+ meta;
155
+ };
156
+ _ts_decorate([
157
+ (0, _swagger.ApiProperty)({
158
+ example: '2025-06-01T12:00:00Z',
159
+ description: 'Timestamp of the response'
160
+ }),
161
+ _ts_metadata("design:type", String)
162
+ ], PaginateCursorResponse.prototype, "timestamp", void 0), _ts_decorate([
163
+ (0, _swagger.ApiProperty)({
164
+ type: PaginateCursorResponseMeta,
165
+ description: 'Pagination metadata'
166
+ }),
167
+ _ts_metadata("design:type", PaginateCursorResponseMeta)
168
+ ], PaginateCursorResponse.prototype, "meta", void 0);
169
+ let BasePaginateRequest = class BasePaginateRequest {
91
170
  perPage;
92
- page;
93
171
  q;
94
172
  orderBy;
95
173
  sort;
@@ -98,10 +176,63 @@ let PaginateRequest = class PaginateRequest {
98
176
  include;
99
177
  where;
100
178
  orWhere;
101
- andWhere;
102
179
  attributes;
103
180
  groupBy;
104
181
  };
182
+ _ts_decorate([
183
+ (0, _swagger.ApiProperty)({
184
+ example: 10,
185
+ description: 'Number of items per page'
186
+ }),
187
+ (0, _classvalidator.IsOptional)(),
188
+ (0, _classvalidator.IsNumber)(),
189
+ _ts_metadata("design:type", Number)
190
+ ], BasePaginateRequest.prototype, "perPage", void 0), _ts_decorate([
191
+ (0, _swagger.ApiProperty)({
192
+ example: 'search query',
193
+ description: 'Search query'
194
+ }),
195
+ (0, _classvalidator.IsOptional)(),
196
+ (0, _classvalidator.IsString)(),
197
+ _ts_metadata("design:type", String)
198
+ ], BasePaginateRequest.prototype, "q", void 0), _ts_decorate([
199
+ (0, _swagger.ApiProperty)({
200
+ example: 'createdAt',
201
+ description: 'Order by field'
202
+ }),
203
+ (0, _classvalidator.IsString)(),
204
+ (0, _classvalidator.IsOptional)(),
205
+ _ts_metadata("design:type", "u" < typeof KeyOfModel ? Object : KeyOfModel)
206
+ ], BasePaginateRequest.prototype, "orderBy", void 0), _ts_decorate([
207
+ (0, _swagger.ApiProperty)({
208
+ example: 'ASC',
209
+ enum: [
210
+ 'ASC',
211
+ 'DESC'
212
+ ],
213
+ description: 'Sort order'
214
+ }),
215
+ (0, _classvalidator.IsEnum)([
216
+ 'ASC',
217
+ 'DESC'
218
+ ]),
219
+ _ts_metadata("design:type", "u" < typeof OrderDataType ? Object : OrderDataType)
220
+ ], BasePaginateRequest.prototype, "sort", void 0);
221
+ let PaginateRequest = class PaginateRequest extends BasePaginateRequest {
222
+ page;
223
+ };
224
+ _ts_decorate([
225
+ (0, _swagger.ApiProperty)({
226
+ example: 1,
227
+ description: 'Current page number'
228
+ }),
229
+ (0, _classvalidator.IsOptional)(),
230
+ (0, _classvalidator.IsNumber)(),
231
+ _ts_metadata("design:type", Number)
232
+ ], PaginateRequest.prototype, "page", void 0);
233
+ let PaginateCursorRequest = class PaginateCursorRequest extends BasePaginateRequest {
234
+ cursor;
235
+ };
105
236
  function PrimaryUuidCol() {
106
237
  return (0, _sequelizetypescript.Column)({
107
238
  type: _sequelizetypescript.DataType.UUID,
@@ -201,51 +332,13 @@ function SchedulerCol() {
201
332
  }
202
333
  _ts_decorate([
203
334
  (0, _swagger.ApiProperty)({
204
- example: 10,
205
- description: 'Number of items per page'
206
- }),
207
- (0, _classvalidator.IsOptional)(),
208
- (0, _classvalidator.IsNumber)(),
209
- _ts_metadata("design:type", Number)
210
- ], PaginateRequest.prototype, "perPage", void 0), _ts_decorate([
211
- (0, _swagger.ApiProperty)({
212
- example: 1,
213
- description: 'Current page number'
214
- }),
215
- (0, _classvalidator.IsOptional)(),
216
- (0, _classvalidator.IsNumber)(),
217
- _ts_metadata("design:type", Number)
218
- ], PaginateRequest.prototype, "page", void 0), _ts_decorate([
219
- (0, _swagger.ApiProperty)({
220
- example: 'search query',
221
- description: 'Search query'
335
+ example: 'cursor_string',
336
+ description: 'Cursor string for pagination'
222
337
  }),
223
338
  (0, _classvalidator.IsOptional)(),
224
339
  (0, _classvalidator.IsString)(),
225
340
  _ts_metadata("design:type", String)
226
- ], PaginateRequest.prototype, "q", void 0), _ts_decorate([
227
- (0, _swagger.ApiProperty)({
228
- example: 'createdAt',
229
- description: 'Order by field'
230
- }),
231
- (0, _classvalidator.IsString)(),
232
- (0, _classvalidator.IsOptional)(),
233
- _ts_metadata("design:type", "u" < typeof KeyOfModel ? Object : KeyOfModel)
234
- ], PaginateRequest.prototype, "orderBy", void 0), _ts_decorate([
235
- (0, _swagger.ApiProperty)({
236
- example: 'ASC',
237
- enum: [
238
- 'ASC',
239
- 'DESC'
240
- ],
241
- description: 'Sort order'
242
- }),
243
- (0, _classvalidator.IsEnum)([
244
- 'ASC',
245
- 'DESC'
246
- ]),
247
- _ts_metadata("design:type", "u" < typeof OrderDataType ? Object : OrderDataType)
248
- ], PaginateRequest.prototype, "sort", void 0);
341
+ ], PaginateCursorRequest.prototype, "cursor", void 0);
249
342
  let Entity = class Entity extends _sequelizetypescript.Model {
250
343
  };
251
344
  _ts_decorate([
@@ -0,0 +1,2 @@
1
+ export declare class SequelizeModule {
2
+ }
@@ -1,16 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: !0
4
- }), Object.defineProperty(exports, "DBModule", {
4
+ }), Object.defineProperty(exports, "SequelizeModule", {
5
5
  enumerable: !0,
6
6
  get: function() {
7
- return DBModule;
7
+ return SequelizeModule;
8
8
  }
9
9
  });
10
- let _common = require("@nestjs/common"), _sequelize = require("@nestjs/sequelize"), _path = require("path"), _secretmanager = require("../secret-manager"), _dbservice = require("./db.service");
11
- let DBModule = class DBModule {
10
+ let _common = require("@nestjs/common"), _sequelize = require("@nestjs/sequelize"), _path = require("path"), _secretmanager = require("../secret-manager"), _sequelizeservice = require("./sequelize.service");
11
+ let SequelizeModule = class SequelizeModule {
12
12
  };
13
- DBModule = function(decorators, target, key, desc) {
13
+ SequelizeModule = function(decorators, target, key, desc) {
14
14
  var d, c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc;
15
15
  if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
16
16
  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);
@@ -54,11 +54,11 @@ DBModule = function(decorators, target, key, desc) {
54
54
  ],
55
55
  providers: [
56
56
  _sequelize.SequelizeModule,
57
- _dbservice.DbService
57
+ _sequelizeservice.SequelizeService
58
58
  ],
59
59
  exports: [
60
60
  _sequelize.SequelizeModule,
61
- _dbservice.DbService
61
+ _sequelizeservice.SequelizeService
62
62
  ]
63
63
  })
64
- ], DBModule);
64
+ ], SequelizeModule);
@@ -1,15 +1,17 @@
1
1
  import { AggregateOptions, Attributes, BulkCreateOptions, CreateOptions, CreationAttributes, DestroyOptions, FindAndCountOptions, FindOptions, ModelStatic, UpdateOptions, UpsertOptions, WhereOptions } from 'sequelize';
2
2
  import { Model, Sequelize } from 'sequelize-typescript';
3
3
  import { AppLogger } from '../logger';
4
- import { PaginateRequest, PaginateResponse } from './db.helper';
5
- export declare class Repository<M extends Model<M, Partial<M>>> {
4
+ import { PaginateCursorRequest, PaginateCursorResponse, PaginateRequest, PaginateResponse } from './sequelize.helper';
5
+ export declare class Repository<M extends Model<M, Partial<M>> & {
6
+ id: string | number;
7
+ }> {
6
8
  protected logger: AppLogger;
7
9
  protected Model: ModelStatic<M>;
8
10
  protected db: Sequelize;
9
11
  private excludeParamsFromFilter;
10
12
  private get attributes();
11
13
  private get attributesTypes();
12
- private getTrueKey;
14
+ private _getTrueKey;
13
15
  private parsedBetweenData;
14
16
  private mapFilter;
15
17
  private _getOptions;
@@ -18,6 +20,7 @@ export declare class Repository<M extends Model<M, Partial<M>>> {
18
20
  value: string | number;
19
21
  }>(params: PaginateRequest<M>, mapInto: (data: M) => P): Promise<P[]>;
20
22
  protected paginate<P>(params: PaginateRequest<M>, mapInto?: (data: M) => P): Promise<PaginateResponse<P | M>>;
23
+ protected paginateCursor<P>(params: PaginateCursorRequest<M>, mapInto?: (data: M) => P): Promise<PaginateCursorResponse<P | M>>;
21
24
  protected export(params: PaginateRequest<M>): Promise<M[]>;
22
25
  protected export(params: PaginateRequest<M>, mapInto?: (data: M) => string[]): Promise<string[][]>;
23
26
  protected updateOrCreate(values: CreationAttributes<M>, whereOptions: WhereOptions<M>, options?: CreateOptions<M> | UpdateOptions<M>): Promise<M>;
@@ -28,7 +31,7 @@ export declare class Repository<M extends Model<M, Partial<M>>> {
28
31
  }>;
29
32
  protected findOne(options: FindOptions<M>): Promise<M | null>;
30
33
  protected create(values: CreationAttributes<M>, options?: CreateOptions<M>): Promise<M>;
31
- protected update(entity: M | string, values: Partial<M>, options?: Partial<UpdateOptions<M>>): Promise<M>;
34
+ protected update(entity: M | string | number, values: Partial<M>, options?: Partial<UpdateOptions<M>>): Promise<M>;
32
35
  protected upsert(values: CreationAttributes<M>, options?: Partial<UpsertOptions<Attributes<M>>>): Promise<[M, boolean | null]>;
33
36
  protected bulkUpdate(values: Partial<M>, options: UpdateOptions<M>): Promise<[number]>;
34
37
  protected bulkCreate(values: ReadonlyArray<CreationAttributes<M>>, options?: BulkCreateOptions<M>): Promise<M[]>;
@@ -37,90 +37,71 @@ let Repository = class Repository {
37
37
  type: attributes[attr].type
38
38
  }));
39
39
  }
40
- getTrueKey(key) {
41
- return key.replace('min_', '').replace('max_', '').replace('start_', '').replace('end_', '');
40
+ _getTrueKey(key) {
41
+ return key.replace(/^(min_|max_|start_|end_)/, '');
42
42
  }
43
43
  parsedBetweenData(where, key, value) {
44
- let col = this.getTrueKey(key), operation = key.startsWith('start_') || key.startsWith('min_') ? 'gte' : 'lte';
45
- if (value = key.startsWith('_start') || key.startsWith('end_') ? (0, _helpers.dateUtil)(value).utc().format('YYYY-MM-DD HH:mm:ss') : value, void 0 === where[col]) return {
46
- [_sequelize.Op[operation]]: value
44
+ 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
+ if (!existingCondition) return {
46
+ [_sequelize.Op[operation]]: formattedValue
47
47
  };
48
- let beforeValue = where[col][_sequelize.Op['gte' == operation ? 'lte' : 'gte']];
49
- return beforeValue = key.startsWith('_start') || key.startsWith('end_') ? (0, _helpers.dateUtil)(beforeValue).utc().format('YYYY-MM-DD HH:mm:ss') : beforeValue, {
48
+ let beforeValue = existingCondition[_sequelize.Op['gte' === operation ? 'lte' : 'gte']], formattedBeforeValue = isDateColumn && beforeValue ? (0, _helpers.dateUtil)(beforeValue).utc().format('YYYY-MM-DD HH:mm:ss') : beforeValue;
49
+ return {
50
50
  [_sequelize.Op.between]: 'gte' === operation ? [
51
- value,
52
- beforeValue
51
+ formattedValue,
52
+ formattedBeforeValue
53
53
  ] : [
54
- beforeValue,
55
- value
54
+ formattedBeforeValue,
55
+ formattedValue
56
56
  ]
57
57
  };
58
58
  }
59
59
  mapFilter(filter, cols) {
60
60
  let where = {};
61
61
  for (let key of Object.keys(filter)){
62
- let isSpecialKey = key.includes('$') || key.includes('.');
63
- if (!cols.includes(this.getTrueKey(key)) && !isSpecialKey) continue;
64
- let value = filter[key], col = this.getTrueKey(key);
65
- if (void 0 !== value && '' !== value) {
66
- if (key.startsWith('min_') || key.startsWith('start_') || key.startsWith('max_') || key.startsWith('end_')) {
67
- where[col] = this.parsedBetweenData(where, key, value);
68
- continue;
69
- }
70
- if ('string' == typeof value && value.includes(',')) {
71
- where[col] = value.split(',');
72
- continue;
62
+ let col = this._getTrueKey(key), isSpecialKey = key.includes('$') || key.includes('.');
63
+ if (!cols.includes(col) && !isSpecialKey) continue;
64
+ let value = filter[key];
65
+ 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
+ null,
67
+ 'null',
68
+ ''
69
+ ].includes(value) && (value = {
70
+ [_sequelize.Op.and]: {
71
+ [_sequelize.Op.or]: [
72
+ {
73
+ [_sequelize.Op.is]: null
74
+ },
75
+ {
76
+ [_sequelize.Op.eq]: ''
77
+ }
78
+ ]
73
79
  }
74
- if ('object' == typeof value && !Array.isArray(value)) {
75
- where[col] = {
76
- ...value
77
- };
78
- continue;
79
- }
80
- where[col] = value;
81
- }
80
+ }) : value = {
81
+ ...value
82
+ }, where[col] = value);
82
83
  }
83
84
  return where;
84
85
  }
85
86
  _getOptions(params) {
86
- let fields = this.attributes, where = this.mapFilter({
87
- ...params.where,
88
- ...(0, _helpers.omit)(params, this.excludeParamsFromFilter)
89
- }, fields);
87
+ if (!params.attributes) throw new _common.UnprocessableEntityException('Attributes is required');
88
+ let fields = this.attributes, where = {
89
+ ...this.mapFilter((0, _helpers.omit)(params, this.excludeParamsFromFilter), fields),
90
+ ...params.where
91
+ }, andConditions = [], orConditions = [];
90
92
  if (params.q && params.searchKey) {
91
- let searchConditions = Array.isArray(params.searchKey) ? params.searchKey.map((key)=>({
93
+ let searchKeys = Array.isArray(params.searchKey) ? params.searchKey : [
94
+ params.searchKey
95
+ ];
96
+ orConditions.push(...searchKeys.map((key)=>({
92
97
  [key]: {
93
98
  [_sequelize.Op.like]: `%${params.q}%`
94
99
  }
95
- })) : [
96
- {
97
- [params.searchKey]: {
98
- [_sequelize.Op.like]: `%${params.q}%`
99
- }
100
- }
101
- ];
102
- where = {
103
- ...where,
104
- [_sequelize.Op.and]: [
105
- ...params.andWhere || [],
106
- {
107
- [_sequelize.Op.or]: [
108
- ...searchConditions,
109
- ...params.orWhere || []
110
- ]
111
- }
112
- ]
113
- };
100
+ })));
114
101
  }
115
- (params.orWhere || params.andWhere) && (where = {
116
- ...where,
117
- [_sequelize.Op.and]: [
118
- ...params.andWhere || [],
119
- {
120
- [_sequelize.Op.or]: params.orWhere || []
121
- }
122
- ]
123
- });
102
+ params.orWhere && orConditions.push(params.orWhere), orConditions.length > 0 && andConditions.push({
103
+ [_sequelize.Op.or]: orConditions
104
+ }), andConditions.length > 0 && (where[_sequelize.Op.and] = andConditions);
124
105
  let order = [];
125
106
  params?.orderBy && fields.includes(params?.orderBy) && order.push([
126
107
  params?.orderBy,
@@ -130,7 +111,7 @@ let Repository = class Repository {
130
111
  'ASC'
131
112
  ]);
132
113
  let attributes = params.attributes ? params.attributes.filter((d)=>'string' != typeof d || fields.includes(d)) : void 0;
133
- return {
114
+ return (0, _helpers.removeEmptyValues)({
134
115
  where,
135
116
  order,
136
117
  group: params?.groupBy,
@@ -138,7 +119,7 @@ let Repository = class Repository {
138
119
  attributes
139
120
  },
140
121
  include: params.include
141
- };
122
+ });
142
123
  }
143
124
  async findForPublic(params, mapInto) {
144
125
  let options = this._getOptions(params), limit = +(params?.perPage ?? 20);
@@ -169,6 +150,32 @@ let Repository = class Repository {
169
150
  }
170
151
  };
171
152
  }
153
+ async paginateCursor(params, mapInto) {
154
+ if (!this.attributes?.includes('id')) throw new _common.UnprocessableEntityException('Entity must have id attribute for cursor pagination');
155
+ params.attributes = (0, _helpers.uniqueArray)([
156
+ ...params.attributes || [],
157
+ 'id'
158
+ ]);
159
+ let options = this._getOptions(params), limit = +(params?.perPage ?? 20);
160
+ if (params?.cursor) {
161
+ let whereClause = options.where || {};
162
+ whereClause.id = {
163
+ [_sequelize.Op.gt]: params.cursor
164
+ }, options.where = whereClause;
165
+ }
166
+ let data = await this.findAll({
167
+ ...options,
168
+ limit
169
+ }), lastId = data[data.length - 1]?.id, nextCursor = data.length > 0 && lastId ? String(lastId) : null;
170
+ return {
171
+ data: mapInto ? data.map((d)=>mapInto(d)) : data,
172
+ timestamp: (0, _helpers.dateUtil)().utc().toISOString(),
173
+ meta: {
174
+ perPage: limit,
175
+ nextCursor
176
+ }
177
+ };
178
+ }
172
179
  async export(params, mapInto) {
173
180
  let options = this._getOptions(params), data = await this.findAll(options);
174
181
  return mapInto ? data.map((d)=>mapInto(d)) : data;
@@ -180,53 +187,53 @@ let Repository = class Repository {
180
187
  return data ? (await this.update(data, values, options), data) : await this.create(values, options);
181
188
  }
182
189
  async findAll(options) {
183
- return await this.Model.findAll(options);
190
+ return this.Model.findAll(options);
184
191
  }
185
192
  async findAndCountAll(options) {
186
- return await this.Model.findAndCountAll(options);
193
+ return this.Model.findAndCountAll(options);
187
194
  }
188
195
  async findOne(options) {
189
- return await this.Model.findOne(options);
196
+ return this.Model.findOne(options);
190
197
  }
191
198
  async create(values, options) {
192
- return await this.Model.create(values, options);
199
+ return this.Model.create(values, options);
193
200
  }
194
201
  async update(entity, values, options) {
195
- if ('string' == typeof entity && (entity = await this.findOne({
202
+ let model = entity;
203
+ if (('string' == typeof entity || 'number' == typeof entity) && (model = await this.findOne({
196
204
  where: {
197
205
  id: entity
198
206
  },
199
207
  attributes: [
200
208
  'id'
201
209
  ]
202
- })), !entity) throw new _exceptionhelper.AppNotFoundException();
203
- return await entity.update(values, {
210
+ })), !model) throw new _exceptionhelper.AppNotFoundException();
211
+ return model.update(values, {
204
212
  ...options
205
213
  });
206
214
  }
207
215
  async upsert(values, options) {
208
- return await this.Model.upsert(values, {
216
+ return this.Model.upsert(values, {
209
217
  ...options
210
218
  });
211
219
  }
212
220
  async bulkUpdate(values, options) {
213
- return await this.Model.update(values, {
221
+ return this.Model.update(values, {
214
222
  ...options
215
223
  });
216
224
  }
217
225
  async bulkCreate(values, options) {
218
- let idAttribute = this.attributesTypes.find((attr)=>'id' === attr.name);
219
- return idAttribute && 'BIGINT' !== idAttribute.type && (values = values.map((val)=>(val.id || (val.id = generateId()), val))), await this.Model.bulkCreate(values, options);
226
+ return this.Model.bulkCreate(values, options);
220
227
  }
221
228
  async destroy(options) {
222
- return await this.Model.destroy(options);
229
+ return this.Model.destroy(options);
223
230
  }
224
231
  async sum(field, options) {
225
- return await this.Model.sum(field, options);
232
+ return this.Model.sum(field, options);
226
233
  }
227
234
  async sumField(params, field) {
228
235
  let options = this._getOptions(params);
229
- return await this.sum(field, options);
236
+ return this.sum(field, options);
230
237
  }
231
238
  async sumCol(params, fieldToSum, expectedField) {
232
239
  let options = this._getOptions(params);
@@ -238,11 +245,11 @@ let Repository = class Repository {
238
245
  ], (await this.Model.findAll(options)).reduce((total, row)=>total + parseFloat(String(row.get(expectedField)) || '0'), 0);
239
246
  }
240
247
  async count(options) {
241
- return await this.Model.count(options);
248
+ return this.Model.count(options);
242
249
  }
243
250
  async filteredFindAll(params) {
244
251
  let options = this._getOptions(params);
245
- return await this.Model.findAll(options);
252
+ return this.Model.findAll(options);
246
253
  }
247
254
  };
248
255
  !function(decorators, target, key, desc) {
@@ -1,6 +1,6 @@
1
1
  import { OnModuleInit } from '@nestjs/common';
2
2
  import { Sequelize } from 'sequelize-typescript';
3
- export declare class DbService implements OnModuleInit {
3
+ export declare class SequelizeService implements OnModuleInit {
4
4
  private db;
5
5
  private logger;
6
6
  constructor(db: Sequelize);
@@ -1,19 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: !0
4
- }), Object.defineProperty(exports, "DbService", {
4
+ }), Object.defineProperty(exports, "SequelizeService", {
5
5
  enumerable: !0,
6
6
  get: function() {
7
- return DbService;
7
+ return SequelizeService;
8
8
  }
9
9
  });
10
- let _common = require("@nestjs/common"), _sequelizetypescript = require("sequelize-typescript"), _applogger = require("../../drivers/logger/app.logger"), _secretmanager = require("../secret-manager");
10
+ let _common = require("@nestjs/common"), _sequelizetypescript = require("sequelize-typescript"), _applogger = require("../logger/app.logger"), _secretmanager = require("../secret-manager");
11
11
  function _ts_metadata(k, v) {
12
12
  if ("object" == typeof Reflect && "function" == typeof Reflect.metadata) return Reflect.metadata(k, v);
13
13
  }
14
- let DbService = class DbService {
14
+ let SequelizeService = class SequelizeService {
15
15
  db;
16
- logger = new _applogger.AppLogger(DbService.name);
16
+ logger = new _applogger.AppLogger(SequelizeService.name);
17
17
  constructor(db){
18
18
  this.db = db;
19
19
  }
@@ -38,7 +38,7 @@ let DbService = class DbService {
38
38
  }).then(()=>!0).catch((err)=>(this.logger.error('Database connection failed', err), !1));
39
39
  }
40
40
  };
41
- DbService = function(decorators, target, key, desc) {
41
+ SequelizeService = function(decorators, target, key, desc) {
42
42
  var d, c = arguments.length, r = c < 3 ? target : null === desc ? desc = Object.getOwnPropertyDescriptor(target, key) : desc;
43
43
  if ("object" == typeof Reflect && "function" == typeof Reflect.decorate) r = Reflect.decorate(decorators, target, key, desc);
44
44
  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);
@@ -49,4 +49,4 @@ DbService = function(decorators, target, key, desc) {
49
49
  _ts_metadata("design:paramtypes", [
50
50
  void 0 === _sequelizetypescript.Sequelize ? Object : _sequelizetypescript.Sequelize
51
51
  ])
52
- ], DbService);
52
+ ], SequelizeService);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@triproject/nestjs-core",
3
- "version": "1.0.37",
3
+ "version": "1.0.38",
4
4
  "author": "",
5
5
  "license": "ISC",
6
6
  "description": "A collection of NestJS modules and utilities to speed up development.",
@@ -24,9 +24,9 @@
24
24
  "types": "./dist/drivers/cache/index.d.ts",
25
25
  "require": "./dist/drivers/cache/index.js"
26
26
  },
27
- "./db": {
28
- "types": "./dist/drivers/db/index.d.ts",
29
- "require": "./dist/drivers/db/index.js"
27
+ "./sequelize": {
28
+ "types": "./dist/drivers/sequelize/index.d.ts",
29
+ "require": "./dist/drivers/sequelize/index.js"
30
30
  },
31
31
  "./encryption": {
32
32
  "types": "./dist/drivers/encryptions/index.d.ts",
@@ -1,2 +0,0 @@
1
- export declare class DBModule {
2
- }
@@ -1,5 +0,0 @@
1
- export * from './db.helper';
2
- export * from './db.module';
3
- export * from './db.service';
4
- export * from './migration';
5
- export * from './repository';