Skip to content

Commit 5b43774

Browse files
authored
Merge pull request #23 from stbestichhh/22-add-findandcountall
feat: reduced package size, add new findAllPaginated method
2 parents a39d41c + e3b9754 commit 5b43774

File tree

10 files changed

+114
-30
lines changed

10 files changed

+114
-30
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
# Patch 0.1.10
9+
### Added:
10+
* New method for find with pagination `findAllPaginated`
11+
12+
### Changed:
13+
* Now default auto generated id is type of UUIDv4 instead of v7, what helped to reduce package size
14+
815
# Patch 0.1.9
916
### Fixed:
1017
* `deletedAt` property is null on force delete

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ You can pass options when instantiating:
115115
{
116116
autoGenerateId: true, // optional
117117
idField: 'user_id', // optional, default field is 'id'
118-
idGenerator: myGenerateIdFunc; // optional, default is v7 from 'uuid' package
118+
idGenerator: myGenerateIdFunc, // optional, default is UUIDv4
119119
logger: new MyCustomLogger('MyRepo'), // optional
120120
}
121121
```

SECURITY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
| Version | Supported |
66
|---------|--------------------|
7+
| 0.1.10 | :white_check_mark: |
78
| 0.1.9 | :white_check_mark: |
89
| 0.1.8 | :white_check_mark: |
910
| 0.1.7 | :white_check_mark: |

package.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nest-sequelize-repository",
3-
"version": "0.1.9",
3+
"version": "0.1.10",
44
"description": "Abstract repository for Nest and Sequelize.js ORM",
55
"keywords": [
66
"sequelize.js",
@@ -54,11 +54,7 @@
5454
"sqlite3": "^5.1.7",
5555
"ts-jest": "^29.3.2",
5656
"tsx": "^4.19.3",
57-
"typescript": "^5.8.3",
58-
"uuid": "^11.1.0"
59-
},
60-
"dependencies": {
61-
"uuid": "^11.1.0"
57+
"typescript": "^5.8.3"
6258
},
6359
"peerDependencies": {
6460
"@nestjs/common": "11.x",

pnpm-lock.yaml

Lines changed: 0 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/IRepository.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
BulkCreateOptions,
44
CreateOptions,
55
CreationAttributes,
6+
FindAndCountOptions,
67
FindOptions,
78
InstanceDestroyOptions,
89
InstanceRestoreOptions,
@@ -37,6 +38,15 @@ export interface IRepository<TModel extends Model> {
3738
query?: WhereOptions<Attributes<TModel>>,
3839
options?: Omit<FindOptions<Attributes<TModel>>, 'where'>,
3940
): Promise<TModel[]>;
41+
findAllPaginated(
42+
limit: number,
43+
offset?: number,
44+
query?: WhereOptions<Attributes<TModel>>,
45+
options?: Omit<
46+
FindAndCountOptions<Attributes<TModel>>,
47+
'where' | 'offset' | 'limit'
48+
>,
49+
): Promise<{ rows: TModel[]; count: number }>;
4050
updateByPk(
4151
primaryKey: string | number,
4252
dto: Partial<Attributes<TModel>>,

src/abstract.repository.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,20 @@ import {
1010
InstanceDestroyOptions,
1111
InstanceRestoreOptions,
1212
BulkCreateOptions,
13+
FindAndCountOptions,
1314
} from 'sequelize';
1415
import { IRepository } from './IRepository';
1516
import { Model, ModelCtor } from 'sequelize-typescript';
1617
import { IRepositoryOptions } from './IRepositoryOptions';
17-
import { v7 as uuidv7 } from 'uuid';
18+
import { randomUUID } from 'crypto';
1819

1920
export class AbstractRepository<TModel extends Model>
2021
implements IRepository<TModel>
2122
{
2223
protected readonly logger: Logger;
2324
protected readonly autoGenerateId: boolean;
2425
protected readonly idField: string;
25-
protected readonly idGenerator: () => string;
26+
protected readonly idGenerator: () => string | number;
2627

2728
constructor(
2829
protected readonly model: ModelCtor<TModel>,
@@ -32,7 +33,7 @@ export class AbstractRepository<TModel extends Model>
3233
autoGenerateId = false,
3334
idField = 'id',
3435
logger = new Logger(this.constructor.name),
35-
idGenerator = uuidv7,
36+
idGenerator = randomUUID,
3637
} = options;
3738

3839
if (new.target === AbstractRepository) {
@@ -137,6 +138,28 @@ export class AbstractRepository<TModel extends Model>
137138
}
138139
}
139140

141+
public async findAllPaginated(
142+
limit: number,
143+
offset: number = 0,
144+
query?: WhereOptions<Attributes<TModel>>,
145+
options?: Omit<
146+
FindAndCountOptions<Attributes<TModel>>,
147+
'where' | 'offset' | 'limit'
148+
>,
149+
): Promise<{ rows: TModel[]; count: number }> {
150+
try {
151+
return await this.model.findAndCountAll({
152+
where: query,
153+
limit,
154+
offset,
155+
...options,
156+
});
157+
} catch (error) {
158+
this.logger.error(`findAllPaginated: ${error}`);
159+
throw new InternalServerErrorException();
160+
}
161+
}
162+
140163
public async updateByPk(
141164
primaryKey: string | number,
142165
dto: Partial<Attributes<TModel>>,

src/index.d.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ export interface IRepositoryOptions<T extends Model> {
3636
/**
3737
* Function responsible for generating unique IDs when `autoGenerateId` is true.
3838
*
39-
* @default v7 from 'uuid'
39+
* @default UUIDv4 from 'node:crypto' package
4040
* @returns string
41+
* @returns number
4142
*/
42-
idGenerator?: () => string;
43+
idGenerator?: () => string | number;
4344

4445
/**
4546
* Optional NestJS logger instance used for internal logging
@@ -126,6 +127,25 @@ export interface IRepository<TModel extends Model> {
126127
options?: Omit<FindOptions<Attributes<TModel>>, 'where'>,
127128
): Promise<TModel[]>;
128129

130+
/**
131+
* Find first amount of records set by limit and count all existing records
132+
*
133+
* @param limit Amout of records to find and return.
134+
* @param offset Amout of records to skip.
135+
* @param query A Sequelize where clause.
136+
* @param options Optional Sequelize find options, excluding `where`.
137+
* @returns A Promise resolving `rows`(found records) and `count`(amout of existing records).
138+
*/
139+
findAllPaginated(
140+
limit: number,
141+
offset?: number,
142+
query?: WhereOptions<Attributes<TModel>>,
143+
options?: Omit<
144+
FindAndCountOptions<Attributes<TModel>>,
145+
'where' | 'offset' | 'limit'
146+
>,
147+
): Promise<{ rows: TModel[]; count: number }>;
148+
129149
/**
130150
* Updates a records by its primary key.
131151
*
@@ -202,7 +222,7 @@ export declare class AbstractRepository<TModel extends Model>
202222
/**
203223
* Function responsible for generating unique IDs when `autoGenerateId` is true.
204224
*/
205-
protected readonly idGenerator: () => string;
225+
protected readonly idGenerator: () => string | number;
206226

207227
/**
208228
* Constructs the abstract repository.

src/index.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ import {
1010
InstanceDestroyOptions,
1111
InstanceRestoreOptions,
1212
BulkCreateOptions,
13+
FindAndCountOptions,
1314
} from 'sequelize';
1415
import { Model, ModelCtor } from 'sequelize-typescript';
15-
import { v7 as uuidv7 } from 'uuid';
16+
import { randomUUID } from 'crypto';
1617

1718
export interface IRepositoryOptions<T extends Model> {
1819
autoGenerateId?: boolean;
1920
idField?: Extract<keyof Attributes<T>, string>;
20-
idGenerator?: () => string;
21+
idGenerator?: () => string | number;
2122
logger?: Logger;
2223
}
2324

@@ -46,6 +47,15 @@ export interface IRepository<TModel extends Model> {
4647
query?: WhereOptions<Attributes<TModel>>,
4748
options?: Omit<FindOptions<Attributes<TModel>>, 'where'>,
4849
): Promise<TModel[]>;
50+
findAllPaginated(
51+
limit: number,
52+
offset?: number,
53+
query?: WhereOptions<Attributes<TModel>>,
54+
options?: Omit<
55+
FindAndCountOptions<Attributes<TModel>>,
56+
'where' | 'offset' | 'limit'
57+
>,
58+
): Promise<{ rows: TModel[]; count: number }>;
4959
updateByPk(
5060
primaryKey: string | number,
5161
dto: Partial<Attributes<TModel>>,
@@ -70,7 +80,7 @@ export class AbstractRepository<TModel extends Model>
7080
protected readonly logger: Logger;
7181
protected readonly autoGenerateId: boolean;
7282
protected readonly idField: string;
73-
protected readonly idGenerator: () => string;
83+
protected readonly idGenerator: () => string | number;
7484

7585
constructor(
7686
protected readonly model: ModelCtor<TModel>,
@@ -80,7 +90,7 @@ export class AbstractRepository<TModel extends Model>
8090
autoGenerateId = false,
8191
idField = 'id',
8292
logger = new Logger(this.constructor.name),
83-
idGenerator = uuidv7,
93+
idGenerator = randomUUID,
8494
} = options;
8595

8696
if (new.target === AbstractRepository) {
@@ -185,6 +195,28 @@ export class AbstractRepository<TModel extends Model>
185195
}
186196
}
187197

198+
public async findAllPaginated(
199+
limit: number,
200+
offset: number = 0,
201+
query?: WhereOptions<Attributes<TModel>>,
202+
options?: Omit<
203+
FindAndCountOptions<Attributes<TModel>>,
204+
'where' | 'offset' | 'limit'
205+
>,
206+
): Promise<{ rows: TModel[]; count: number }> {
207+
try {
208+
return await this.model.findAndCountAll({
209+
where: query,
210+
limit,
211+
offset,
212+
...options,
213+
});
214+
} catch (error) {
215+
this.logger.error(`findAllPaginated: ${error}`);
216+
throw new InternalServerErrorException();
217+
}
218+
}
219+
188220
public async updateByPk(
189221
primaryKey: string | number,
190222
dto: Partial<Attributes<TModel>>,

test/abstract.repository.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,12 @@ describe('UserRepository', () => {
194194

195195
expect(result.id).toBeDefined();
196196
});
197+
198+
it('should find all with pagination', async () => {
199+
const allRecords = await userRepo.findAll();
200+
const paginated = await userRepo.findAllPaginated(allRecords.length);
201+
202+
expect(paginated.rows.length).toBe(allRecords.length);
203+
expect(paginated.count).toBe(allRecords.length);
204+
});
197205
});

0 commit comments

Comments
 (0)