@nestlize/repository 0.1.13

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 (5) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +182 -0
  3. package/index.d.ts +352 -0
  4. package/index.js +182 -0
  5. package/package.json +65 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Kiril Yakymchuk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # 🧱 Abstract Sequelize Repository for NestJS
2
+
3
+ Abstract repository pattern implementation for Sequelize ORM in NestJS projects.
4
+
5
+ - [Quick start](#-quick-start)
6
+ - [Purpose](#-purpose)
7
+ - [Methods](#-irepository-methods)
8
+ - [Configuration](#-irepositoryoptions)
9
+
10
+ Supports:
11
+
12
+ * ✅ Custom DTO typing or Sequelize creation attributes
13
+ * ✅ Custom error handling
14
+ * ✅ Soft delete support (`paranoid: true`)
15
+ * ✅ Pagination
16
+ * ✅ Optional UUID auto-generation
17
+ * ✅ Injected logger
18
+ * ✅ Simplified transaction handling
19
+
20
+ ---
21
+
22
+ ## 📦 Installation
23
+
24
+ ```bash
25
+ npm install @nestlize/repository
26
+ # or
27
+ yarn add @nestlize/repository
28
+ # or
29
+ pnpm add @nestlize/repository
30
+ ```
31
+
32
+ ---
33
+
34
+ ## 🧠 Purpose
35
+
36
+ This package provides a reusable and extensible base repository class that works with `sequelize-typescript`. It reduces repetitive CRUD logic while keeping full flexibility for different entity needs.
37
+
38
+ ---
39
+
40
+ ## 🔧 Features
41
+
42
+ | Feature | Description |
43
+ |-----------------------|--------------------------------------------------------------------|
44
+ | ✅ Abstract class | Extend `AbstractRepository` for each model |
45
+ | ✅ Generic typing | Supports custom DTOs or defaults to Sequelize `CreationAttributes` |
46
+ | ✅ Soft delete | Supports `paranoid` models with `force` option |
47
+ | ✅ Transaction utility | `repository.transaction()` for scoped logic |
48
+ | ✅ Logger injection | Optional NestJS logger for better traceability |
49
+ | ✅ Flexible options | Configure `logger`, `autoGenerateId`, etc. |
50
+
51
+ ---
52
+
53
+ ## 🛠️ IRepositoryOptions
54
+
55
+ Configuration options for the abstract repository:
56
+
57
+ | Option | Type | Default | Description |
58
+ |------------------|--------------------------|-------------------------|-------------------------------------------------------|
59
+ | `logger` | `Logger` | `NestJS default Logger` | Optional NestJS logger instance for internal logging |
60
+
61
+ ---
62
+
63
+ ## 🛠️ IRepository Methods
64
+
65
+ All methods return Promises.
66
+
67
+ | Method | Parameters | Description |
68
+ |------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------|
69
+ | `create(dto, options?)` | `dto: CreationAttributes<TModel>`, `options?: CreateOptions<TModel>` | Creates a new record |
70
+ | `insert(dto, options?)` | Same as `create` | Alias for `create` |
71
+ | `insertMany(dtos, options?)` | `dtos: CreationAttributes<TModel>[]`, `options?: BulkCreateOptions<Attributes<TModel>>` | Creates multiple records |
72
+ | `findByPk(primaryKey, options?)` | `primaryKey: string \| number`, `options?: Omit<FindOptions, 'where'>` | Find record by primary key |
73
+ | `findOne(query?, options?)` | `query?: WhereOptions`, `options?: Omit<FindOptions, 'where'>` | Find single record by query |
74
+ | `findAll(query?, options?)` | `query?: WhereOptions`, `options?: Omit<FindOptions, 'where'>` | Find all matching records |
75
+ | `findAllPaginated(options?)` | `limit?: number`, `offset?: number`, `page?: number`, `query?: WhereOptions`, `options?: Omit<FindAndCountOptions, 'where' \| 'offset' \| 'limit'>` | Find paginated records and total count |
76
+ | `updateByPk(primaryKey, dto, options?)` | `primaryKey: string \| number`, `dto: Partial<Attributes<TModel>>`, `options?: SaveOptions` | Update record by primary key |
77
+ | `deleteByPk(primaryKey, options?)` | `primaryKey: string \| number`, `options?: InstanceDestroyOptions` | Delete (soft/hard) record by primary key |
78
+ | `restoreByPk(primaryKey, options?)` | `primaryKey: string \| number`, `options?: InstanceRestoreOptions` | Restore previously soft-deleted record |
79
+ | `transaction(runInTransaction)` | `(transaction: Transaction) => Promise<R>` | Execute callback within a Sequelize transaction |
80
+ | `calculateOffset(limit: number, page: number)` | `limit: number, page: number` | Calculate offset for page pagination |
81
+
82
+ ---
83
+
84
+ ## 🚀 Quick Start
85
+
86
+ ### 1. Define a model
87
+
88
+ [`BaseModel`](src/base.model.ts) extends from sequelize `Model` class adding timestamps
89
+
90
+ ```ts
91
+ import { BaseModel } from '@nestlize/repository'
92
+
93
+ @Table({ tableName: 'users', paranoid: true })
94
+ export class User extends BaseModel<User> {
95
+ @PrimaryKey
96
+ @Default(DataType.UUIDV4)
97
+ @Column
98
+ user_id: string;
99
+
100
+ @Column
101
+ name: string;
102
+
103
+ @Column
104
+ email: string;
105
+ }
106
+ ```
107
+
108
+ ---
109
+
110
+ ### 2. Create repository
111
+
112
+ ```ts
113
+ import { AbstractRepository } from '@nestlize/repository';
114
+
115
+ @Injectable()
116
+ export class UserRepository extends AbstractRepository<User> {
117
+ constructor(@InjectModel(User) userModel: typeof User) {
118
+ super(userModel);
119
+ }
120
+ }
121
+ ```
122
+
123
+ ---
124
+
125
+ ### 3. Use in your service
126
+
127
+ ```ts
128
+ @Injectable()
129
+ export class UserService {
130
+ constructor(private readonly users: UserRepository) {}
131
+
132
+ async createUser(dto: CreateUserDto) {
133
+ return this.users.create(dto);
134
+ }
135
+
136
+ async getUsers() {
137
+ return this.users.findAll();
138
+ }
139
+
140
+ async updateUser(id: string, update: YourUpdateType) {
141
+ return this.users.updateByPk(id, update);
142
+ }
143
+ }
144
+ ```
145
+
146
+ ---
147
+
148
+ ## ⚙️ Options
149
+
150
+ You can pass options when instantiating:
151
+
152
+ ```ts
153
+ {
154
+ logger: new MyCustomLogger('MyRepo'), // optional
155
+ }
156
+ ```
157
+
158
+ ---
159
+
160
+ ## 💡 Transaction usage
161
+
162
+ ```ts
163
+ await repo.transaction(async (transaction) => {
164
+ await repo.insert(data, { transaction });
165
+ await transaction.commit();
166
+ });
167
+ ```
168
+
169
+ ---
170
+
171
+ ## 🏗️ Advanced Use
172
+
173
+ * Override methods like `create()` or `updateByPk()` to apply custom hooks or validation.
174
+ * Extend with filters, scopes, or relations as needed.
175
+
176
+ ---
177
+
178
+ ## 📜 License
179
+
180
+ MIT © Kiril Yakymchuk
181
+
182
+ ---
package/index.d.ts ADDED
@@ -0,0 +1,352 @@
1
+ import { Logger } from '@nestjs/common'
2
+ import {
3
+ Transaction,
4
+ WhereOptions,
5
+ CreationAttributes,
6
+ CreateOptions,
7
+ Attributes,
8
+ InstanceDestroyOptions,
9
+ InstanceRestoreOptions,
10
+ SaveOptions,
11
+ FindOptions,
12
+ BulkCreateOptions,
13
+ FindAndCountOptions,
14
+ } from 'sequelize'
15
+ import { Model, ModelCtor } from 'sequelize-typescript'
16
+
17
+ /**
18
+ * Options for the find with pagination.
19
+ *
20
+ * @template TModel Type of the Sequelize model.
21
+ */
22
+ export interface PaginationOptions<TModel extends Model> {
23
+ /**
24
+ * Sets the amount of returned records.
25
+ */
26
+ limit?: number
27
+
28
+ /**
29
+ * Amount of records to skip from the start.
30
+ */
31
+ offset?: number
32
+
33
+ /**
34
+ * Used for page pagination instead of offset.
35
+ */
36
+ page?: number
37
+
38
+ /**
39
+ * A Sequelize where clause.
40
+ */
41
+ query?: WhereOptions<Attributes<TModel>>
42
+
43
+ /**
44
+ * Optional Sequelize find options, excluding 'where', 'offset' and 'limit'.
45
+ */
46
+ findOptions?: Omit<
47
+ FindAndCountOptions<Attributes<TModel>>,
48
+ 'where' | 'offset' | 'limit'
49
+ >
50
+ }
51
+
52
+ /**
53
+ * Configuration options for the abstract repository.
54
+ */
55
+ export interface IRepositoryOptions {
56
+ /**
57
+ * Optional NestJS logger instance used for internal logging.
58
+ */
59
+ logger?: Logger
60
+ }
61
+
62
+ /**
63
+ * Generic interface defining basic repository operations
64
+ * such as CRUD and transaction management.
65
+ *
66
+ * @template TModel Type of the Sequelize model.
67
+ */
68
+ export interface IRepository<TModel extends Model> {
69
+ /**
70
+ * Creates a new record in the database.
71
+ *
72
+ * @param dto The data to create record with.
73
+ * @param options Optional Sequelize create options.
74
+ * @returns A promise resolving to the created model instance.
75
+ */
76
+ create(
77
+ dto: CreationAttributes<TModel>,
78
+ options?: CreateOptions<TModel>,
79
+ ): Promise<TModel>
80
+
81
+ /**
82
+ * Creates a new record in the database. Alias for `create`
83
+ *
84
+ * @param dto The data to create record with.
85
+ * @param options Optional Sequelize create options.
86
+ * @returns A promise resolving to the created model instance.
87
+ */
88
+ insert(
89
+ dto: CreationAttributes<TModel>,
90
+ options?: CreateOptions<TModel>,
91
+ ): Promise<TModel>
92
+
93
+ /**
94
+ * Creates multiple new records in the database.
95
+ *
96
+ * @param dtos The array of data to create records with.
97
+ * @param options Optional Sequelize create options.
98
+ * @returns A promise resolving to the created models instances.
99
+ */
100
+ insertMany(
101
+ dtos: CreationAttributes<TModel>[],
102
+ options?: BulkCreateOptions<Attributes<TModel>>,
103
+ ): Promise<TModel[]>
104
+
105
+ /**
106
+ * Finds a record by its primary key
107
+ *
108
+ * @param primaryKey The value of the primary key.
109
+ * @param options Optional Sequelize find options, excluding 'where'.
110
+ * @returns A Promise resolving the found record or null.
111
+ */
112
+ findByPk(
113
+ primaryKey: string | number,
114
+ options?: Omit<FindOptions<Attributes<TModel>>, 'where'>,
115
+ ): Promise<TModel | null>
116
+
117
+ /**
118
+ * Finds a single record by matching the provided query
119
+ *
120
+ * @param query A Sequelize where clause.
121
+ * @param options Optional Sequelize find options, excluding 'where'.
122
+ * @returns A Promise resolving the found record or null.
123
+ */
124
+ findOne(
125
+ query?: WhereOptions<Attributes<TModel>>,
126
+ options?: Omit<FindOptions<Attributes<TModel>>, 'where'>,
127
+ ): Promise<TModel | null>
128
+
129
+ /**
130
+ * Finds all records matching the provided query
131
+ *
132
+ * @param query A Sequelize where clause.
133
+ * @param options Optional Sequelize find options, excluding 'where'.
134
+ * @returns A Promise resolving the found records or empty erray.
135
+ */
136
+ findAll(
137
+ query?: WhereOptions<Attributes<TModel>>,
138
+ options?: Omit<FindOptions<Attributes<TModel>>, 'where'>,
139
+ ): Promise<TModel[]>
140
+
141
+ /**
142
+ * Find first amount of records set by limit and count all existing records
143
+ *
144
+ * @param options Pagination options.
145
+ *
146
+ * @returns A Promise resolving `rows`(found records) and `count`(amout of existing records).
147
+ */
148
+ findAllPaginated(
149
+ options: PaginationOptions<TModel>,
150
+ ): Promise<{ rows: TModel[]; count: number }>
151
+
152
+ /**
153
+ * Updates a records by its primary key.
154
+ *
155
+ * @param primaryKey The value of the primary key.
156
+ * @param dto Partial data to update the record with.
157
+ * @param options Optional Sequelize save options.
158
+ * @returns A Promise resolving the updated record or null.
159
+ */
160
+ updateByPk(
161
+ primaryKey: string | number,
162
+ dto: Partial<Attributes<TModel>>,
163
+ options?: SaveOptions<Attributes<TModel>>,
164
+ ): Promise<TModel | null>
165
+
166
+ /**
167
+ * Deletes (soft or hard) a record by its primary key.
168
+ *
169
+ * @param primaryKey The value of the primary key.
170
+ * @param options Optional Sequelize destroy options.
171
+ * @returns A Promise resolving the deleted record or null.
172
+ */
173
+ deleteByPk(
174
+ primaryKey: string | number,
175
+ options?: InstanceDestroyOptions,
176
+ ): Promise<TModel | null>
177
+
178
+ /**
179
+ * Restores a preiously soft-deleted record by its primary key.
180
+ *
181
+ * @param primaryKey The value of the primary key.
182
+ * @param options Optional Sequelize restore options.
183
+ * @returns A Promise resolving the found record or null.
184
+ */
185
+ restoreByPk(
186
+ primaryKey: string | number,
187
+ options?: InstanceRestoreOptions,
188
+ ): Promise<TModel | null>
189
+
190
+ /**
191
+ * Executes a callback function withing a Sequelize transaction.
192
+ *
193
+ * @param runInTransaction The callback to execute, receiving the transaction object.
194
+ * @returns A promise resolving to the result of the callback.
195
+ */
196
+ transaction<R>(
197
+ runInTransaction: (transaction: Transaction) => Promise<R>,
198
+ ): Promise<R>
199
+
200
+ /**
201
+ * Calculate offset for page pagination
202
+ *
203
+ * @param limit Amount of records to return per page
204
+ * @param page Target page number
205
+ * @returns Number, amount of records to skip (offset)
206
+ */
207
+ calculateOffset(limit: number, page: number): number
208
+ }
209
+
210
+ /**
211
+ * Base model class based on sequelize `Model` class
212
+ * adding timestamps.
213
+ *
214
+ * @template TModelAttributes Type of the Model class. Default is `any`
215
+ * @template TCreationAttributes Type of the Model creation attributes. Default is Model class
216
+ */
217
+ export declare class BaseModel<
218
+ TModelAttributes extends {} = any,
219
+ TCreationAttributes extends {} = TModelAttributes,
220
+ > extends Model<TModelAttributes, TCreationAttributes> {
221
+ /**
222
+ * Model creation time
223
+ */
224
+ createdAt: Date
225
+
226
+ /**
227
+ * Model update time. Default is `createdAt` timestamp
228
+ */
229
+ updatedAt: Date
230
+
231
+ /**
232
+ * Model deletion time
233
+ *
234
+ * @default null
235
+ */
236
+ deletedAt: Date | null
237
+ }
238
+
239
+ /**
240
+ * Base abstract class providing default implementations of common
241
+ * repository operations. Designed to be extended for model-specific logic.
242
+ *
243
+ * @template TModel Type of the Sequelize model.
244
+ */
245
+ export declare class AbstractRepository<
246
+ TModel extends Model,
247
+ > implements IRepository<TModel> {
248
+ /**
249
+ * Logger instance used for logging errors.
250
+ */
251
+ protected readonly logger: Logger
252
+
253
+ /**
254
+ * Constructs the abstract repository.
255
+ *
256
+ * @param model The Sequelize model constructor.
257
+ * @param options Optional configuration options.
258
+ */
259
+ constructor(model: ModelCtor<TModel>, options?: IRepositoryOptions)
260
+
261
+ /**
262
+ * @inheritdoc
263
+ */
264
+ create(
265
+ dto: CreationAttributes<TModel>,
266
+ options?: CreateOptions<TModel>,
267
+ ): Promise<TModel>
268
+
269
+ /**
270
+ * @inheritdoc
271
+ */
272
+ insert(
273
+ dto: CreationAttributes<TModel>,
274
+ options?: CreateOptions<TModel>,
275
+ ): Promise<TModel>
276
+
277
+ /**
278
+ * @inheritdoc
279
+ */
280
+ insertMany(
281
+ dtos: CreationAttributes<TModel>[],
282
+ options?: BulkCreateOptions<Attributes<TModel>>,
283
+ ): Promise<TModel[]>
284
+
285
+ /**
286
+ * @inheritdoc
287
+ */
288
+ findByPk(
289
+ primaryKey: string | number,
290
+ options?: Omit<FindOptions<Attributes<TModel>>, 'where'>,
291
+ ): Promise<TModel | null>
292
+
293
+ /**
294
+ * @inheritdoc
295
+ */
296
+ findOne(
297
+ query?: WhereOptions<Attributes<TModel>>,
298
+ options?: Omit<FindOptions<Attributes<TModel>>, 'where'>,
299
+ ): Promise<TModel | null>
300
+
301
+ /**
302
+ * @inheritdoc
303
+ */
304
+ findAll(
305
+ query?: WhereOptions<Attributes<TModel>>,
306
+ options?: Omit<FindOptions<Attributes<TModel>>, 'where'>,
307
+ ): Promise<TModel[]>
308
+
309
+ /**
310
+ * @inheritdoc
311
+ */
312
+ findAllPaginated(
313
+ options: PaginationOptions<TModel>,
314
+ ): Promise<{ rows: TModel[]; count: number }>
315
+
316
+ /**
317
+ * @inheritdoc
318
+ */
319
+ updateByPk(
320
+ primaryKey: string | number,
321
+ dto: Partial<Attributes<TModel>>,
322
+ options?: SaveOptions<Attributes<TModel>>,
323
+ ): Promise<TModel | null>
324
+
325
+ /**
326
+ * @inheritdoc
327
+ */
328
+ deleteByPk(
329
+ primaryKey: string | number,
330
+ options?: InstanceDestroyOptions,
331
+ ): Promise<TModel | null>
332
+
333
+ /**
334
+ * @inheritdoc
335
+ */
336
+ restoreByPk(
337
+ primaryKey: string | number,
338
+ options?: InstanceRestoreOptions,
339
+ ): Promise<TModel | null>
340
+
341
+ /**
342
+ * @inheritdoc
343
+ */
344
+ transaction<R>(
345
+ runInTransaction: (transaction: Transaction) => Promise<R>,
346
+ ): Promise<R>
347
+
348
+ /**
349
+ * @inheritDoc
350
+ */
351
+ calculateOffset(limit: number, page: number): number
352
+ }
package/index.js ADDED
@@ -0,0 +1,182 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.AbstractRepository = exports.BaseModel = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const sequelize_typescript_1 = require("sequelize-typescript");
15
+ class BaseModel extends sequelize_typescript_1.Model {
16
+ }
17
+ exports.BaseModel = BaseModel;
18
+ __decorate([
19
+ sequelize_typescript_1.CreatedAt,
20
+ sequelize_typescript_1.Column,
21
+ __metadata("design:type", Date)
22
+ ], BaseModel.prototype, "createdAt", void 0);
23
+ __decorate([
24
+ sequelize_typescript_1.UpdatedAt,
25
+ sequelize_typescript_1.Column,
26
+ __metadata("design:type", Date)
27
+ ], BaseModel.prototype, "updatedAt", void 0);
28
+ __decorate([
29
+ (0, sequelize_typescript_1.Default)(null),
30
+ sequelize_typescript_1.AllowNull,
31
+ sequelize_typescript_1.DeletedAt,
32
+ (0, sequelize_typescript_1.Column)({ type: sequelize_typescript_1.DataType.DATE }),
33
+ __metadata("design:type", Object)
34
+ ], BaseModel.prototype, "deletedAt", void 0);
35
+ class AbstractRepository {
36
+ constructor(model, options = {}) {
37
+ this.model = model;
38
+ const { logger = new common_1.Logger(this.constructor.name) } = options;
39
+ if (new.target === AbstractRepository) {
40
+ throw new Error('AbstractRepository cannot be instantiated directly');
41
+ }
42
+ this.logger = logger;
43
+ }
44
+ async create(dto, options) {
45
+ try {
46
+ return await this.model.create(dto, options);
47
+ }
48
+ catch (error) {
49
+ this.logger.error(`insert: ${error}`);
50
+ throw new common_1.InternalServerErrorException();
51
+ }
52
+ }
53
+ async insert(dto, options) {
54
+ return this.create(dto, options);
55
+ }
56
+ async insertMany(dtos, options) {
57
+ try {
58
+ return await this.model.bulkCreate(dtos, options);
59
+ }
60
+ catch (error) {
61
+ this.logger.error(`insertMany: ${error}`);
62
+ throw new common_1.InternalServerErrorException();
63
+ }
64
+ }
65
+ async findByPk(primaryKey, options) {
66
+ try {
67
+ return await this.model.findByPk(primaryKey, options);
68
+ }
69
+ catch (error) {
70
+ this.logger.error(`findByPk: ${error}`);
71
+ throw new common_1.InternalServerErrorException();
72
+ }
73
+ }
74
+ async findOne(query, options) {
75
+ try {
76
+ return await this.model.findOne({
77
+ where: query,
78
+ ...options,
79
+ });
80
+ }
81
+ catch (error) {
82
+ this.logger.error(`findOne: ${error}`);
83
+ throw new common_1.InternalServerErrorException();
84
+ }
85
+ }
86
+ async findAll(query, options) {
87
+ try {
88
+ return await this.model.findAll({
89
+ where: query,
90
+ ...options,
91
+ });
92
+ }
93
+ catch (error) {
94
+ this.logger.error(`findAll: ${error}`);
95
+ throw new common_1.InternalServerErrorException();
96
+ }
97
+ }
98
+ async findAllPaginated(options) {
99
+ try {
100
+ let { limit = 10, offset = 0, page, query, findOptions } = options;
101
+ if (!offset && page) {
102
+ offset = this.calculateOffset(limit, page);
103
+ }
104
+ return await this.model.findAndCountAll({
105
+ where: query,
106
+ limit,
107
+ offset,
108
+ ...findOptions,
109
+ });
110
+ }
111
+ catch (error) {
112
+ this.logger.error(`findAllPaginated: ${error}`);
113
+ throw new common_1.InternalServerErrorException();
114
+ }
115
+ }
116
+ async updateByPk(primaryKey, dto, options) {
117
+ try {
118
+ const entity = await this.findByPk(primaryKey);
119
+ if (!entity) {
120
+ return null;
121
+ }
122
+ entity.set(dto);
123
+ return await entity.save(options);
124
+ }
125
+ catch (error) {
126
+ this.logger.error(`updatedByPk: ${error}`);
127
+ throw new common_1.InternalServerErrorException();
128
+ }
129
+ }
130
+ async deleteByPk(primaryKey, options) {
131
+ try {
132
+ const entity = await this.findByPk(primaryKey, {
133
+ paranoid: !options?.force,
134
+ });
135
+ if (!entity) {
136
+ return null;
137
+ }
138
+ if (options?.force && entity.getDataValue('deletedAt') !== undefined) {
139
+ entity.setDataValue('deletedAt', new Date());
140
+ }
141
+ await entity.destroy(options);
142
+ return entity;
143
+ }
144
+ catch (error) {
145
+ this.logger.error(`deleteByPk: ${error}`);
146
+ throw new common_1.InternalServerErrorException();
147
+ }
148
+ }
149
+ async restoreByPk(primaryKey, options) {
150
+ try {
151
+ const entity = await this.findByPk(primaryKey, {
152
+ ...options,
153
+ paranoid: false,
154
+ });
155
+ if (!entity) {
156
+ return null;
157
+ }
158
+ await entity.restore(options);
159
+ return entity;
160
+ }
161
+ catch (error) {
162
+ this.logger.error(`restoreByPk: ${error}`);
163
+ throw new common_1.InternalServerErrorException();
164
+ }
165
+ }
166
+ async transaction(runInTransaction) {
167
+ return this.model.sequelize.transaction(async (transaction) => {
168
+ try {
169
+ return await runInTransaction(transaction);
170
+ }
171
+ catch (error) {
172
+ this.logger.error(`transaction: ${error}`);
173
+ throw new common_1.InternalServerErrorException();
174
+ }
175
+ });
176
+ }
177
+ calculateOffset(limit, page) {
178
+ return limit * (page - 1);
179
+ }
180
+ }
181
+ exports.AbstractRepository = AbstractRepository;
182
+ //# sourceMappingURL=index.js.map
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@nestlize/repository",
3
+ "version": "0.1.13",
4
+ "description": "Abstract repository and other database tools for Nest and Sequelize.js ORM",
5
+ "keywords": [
6
+ "sequelize.js",
7
+ "abstract",
8
+ "repository",
9
+ "orm",
10
+ "nest"
11
+ ],
12
+ "homepage": "https://github.com/stbestichhh/nest-sequelize-repository#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/stbestichhh/nest-sequelize-repository/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/stbestichhh/nest-sequelize-repository.git"
19
+ },
20
+ "license": "MIT",
21
+ "author": "Kiril Yakymchuk <stbestich@gmail.com>",
22
+ "type": "commonjs",
23
+ "main": "index.js",
24
+ "types": "index.d.ts",
25
+ "scripts": {
26
+ "prebuild": "rimraf dist",
27
+ "build": "tsc",
28
+ "fmt": "prettier --write .",
29
+ "fmt:check": "prettier -c .",
30
+ "test": "jest",
31
+ "prepare": "husky",
32
+ "prepublish": "pnpm build && cp dist/index.js ./ && cp src/index.d.ts ./",
33
+ "postpublish": "rimraf index.js && rimraf index.d.ts"
34
+ },
35
+ "files": [
36
+ "index.js",
37
+ "index.d.ts",
38
+ "LICENSE",
39
+ "README.md"
40
+ ],
41
+ "devDependencies": {
42
+ "@nestjs/common": "^11.1.11",
43
+ "@types/jest": "^29.5.14",
44
+ "@types/node": "^22.19.3",
45
+ "husky": "^9.1.7",
46
+ "jest": "^29.7.0",
47
+ "prettier": "^3.7.4",
48
+ "reflect-metadata": "^0.2.2",
49
+ "rimraf": "^6.1.2",
50
+ "rxjs": "^7.8.2",
51
+ "sequelize": "^6.37.7",
52
+ "sequelize-typescript": "^2.1.6",
53
+ "sqlite3": "^5.1.7",
54
+ "ts-jest": "^29.4.6",
55
+ "tsx": "^4.21.0",
56
+ "typescript": "^5.9.3"
57
+ },
58
+ "peerDependencies": {
59
+ "@nestjs/common": "11.x",
60
+ "reflect-metadata": "0.x",
61
+ "rxjs": "7.x",
62
+ "sequelize": "6.x",
63
+ "sequelize-typescript": "2.x"
64
+ }
65
+ }