xcally-nest-library 0.0.29 → 0.0.31
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/src/core/application/base.interface.d.ts +16 -0
- package/dist/src/core/application/base.interface.js +3 -0
- package/dist/src/core/application/base.interface.js.map +1 -0
- package/dist/src/core/application/base.service.d.ts +20 -0
- package/dist/src/core/application/base.service.js +51 -0
- package/dist/src/core/application/base.service.js.map +1 -0
- package/dist/src/core/domain/interfaces/base.repository.interface.d.ts +10 -0
- package/dist/src/core/domain/interfaces/base.repository.interface.js +3 -0
- package/dist/src/core/domain/interfaces/base.repository.interface.js.map +1 -0
- package/dist/src/core/infrastracture/databases/base.entity.d.ts +13 -0
- package/dist/src/core/infrastracture/databases/base.entity.interface.d.ts +5 -0
- package/dist/src/core/infrastracture/databases/base.entity.interface.js +3 -0
- package/dist/src/core/infrastracture/databases/base.entity.interface.js.map +1 -0
- package/dist/src/core/infrastracture/databases/base.entity.js +54 -0
- package/dist/src/core/infrastracture/databases/base.entity.js.map +1 -0
- package/dist/src/core/infrastracture/databases/base.repository.d.ts +9 -0
- package/dist/src/core/infrastracture/databases/base.repository.js +37 -0
- package/dist/src/core/infrastracture/databases/base.repository.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +6 -0
- package/package.json +14 -4
- package/src/core/application/base.interface.ts +16 -0
- package/src/core/application/base.service.ts +97 -0
- package/src/core/domain/interfaces/base.repository.interface.ts +11 -0
- package/src/core/infrastracture/databases/base.entity.interface.ts +5 -0
- package/src/core/infrastracture/databases/base.entity.ts +51 -0
- package/src/core/infrastracture/databases/base.repository.ts +53 -0
- package/tsconfig.json +17 -1
package/index.ts
CHANGED
@@ -1,3 +1,9 @@
|
|
1
1
|
export * from './src/modules/logger/pino/logger.service';
|
2
2
|
export * from './src/modules/logger/pino/logger.module';
|
3
3
|
export * from './src/modules/logger/pino/logger.default';
|
4
|
+
export * from './src/core/application/base.interface';
|
5
|
+
export * from './src/core/application/base.service';
|
6
|
+
export * from './src/core/domain/interfaces/base.repository.interface';
|
7
|
+
export * from './src/core/infrastracture/databases/base.entity';
|
8
|
+
export * from './src/core/infrastracture/databases/base.entity.interface';
|
9
|
+
export * from './src/core/infrastracture/databases/base.repository';
|
package/package.json
CHANGED
@@ -1,21 +1,26 @@
|
|
1
1
|
{
|
2
2
|
"name": "xcally-nest-library",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.31",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
7
7
|
"author": "",
|
8
8
|
"license": "UNLICENSED",
|
9
9
|
"dependencies": {
|
10
|
-
"@nestjs/common": "^11.0.7",
|
11
10
|
"@nestjs/config": "^4.0.0",
|
12
|
-
"
|
11
|
+
"class-transformer": "^0.5.1",
|
12
|
+
"nestjs-grpc-exceptions": "^0.2.2",
|
13
|
+
"nestjs-paginate": "^11.0.0",
|
13
14
|
"nestjs-pino": "^4.3.0",
|
14
15
|
"pino": "^9.6.0",
|
15
|
-
"pino-pretty": "^13.0.0"
|
16
|
+
"pino-pretty": "^13.0.0",
|
17
|
+
"typeorm": "^0.3.20"
|
16
18
|
},
|
17
19
|
"devDependencies": {
|
18
20
|
"@nestjs/cli": "^11.0.2",
|
21
|
+
"@nestjs/common": "^11.0.9",
|
22
|
+
"@nestjs/core": "^11.0.9",
|
23
|
+
"@nestjs/microservices": "^11.0.9",
|
19
24
|
"@nestjs/schematics": "^11.0.0",
|
20
25
|
"@typescript-eslint/eslint-plugin": "^8.23.0",
|
21
26
|
"@typescript-eslint/parser": "^8.23.0",
|
@@ -28,6 +33,11 @@
|
|
28
33
|
"tsc-watch": "^6.2.1",
|
29
34
|
"typescript": "^5.7.3"
|
30
35
|
},
|
36
|
+
"peerDependencies": {
|
37
|
+
"@nestjs/common": "^11.0.7",
|
38
|
+
"@nestjs/core": "^11.0.7",
|
39
|
+
"@nestjs/microservices": "^11.0.9"
|
40
|
+
},
|
31
41
|
"scripts": {
|
32
42
|
"bump:patch": "npm version patch -m \"Bump version to %s\"",
|
33
43
|
"build": "tsc",
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { Paginated, PaginateQuery } from 'nestjs-paginate';
|
2
|
+
|
3
|
+
export interface IBaseService<
|
4
|
+
Entity,
|
5
|
+
CreateMessage extends Partial<Entity>,
|
6
|
+
UpdateMessage extends Partial<Entity> & { id: number },
|
7
|
+
Message,
|
8
|
+
> {
|
9
|
+
findOne(id: number): Promise<Message>;
|
10
|
+
findAll(): Promise<{ data: Message[] }>;
|
11
|
+
getMany(query?: PaginateQuery): Promise<Paginated<Message>>;
|
12
|
+
create(createDTO: CreateMessage): Promise<Message>;
|
13
|
+
update(updateDTO: UpdateMessage): Promise<Message>;
|
14
|
+
remove(id: number): Promise<void>;
|
15
|
+
count(options?: any): Promise<{ count: number }>;
|
16
|
+
}
|
@@ -0,0 +1,97 @@
|
|
1
|
+
import { GrpcNotFoundException } from 'nestjs-grpc-exceptions';
|
2
|
+
import { Paginated, PaginateQuery } from 'nestjs-paginate';
|
3
|
+
import { IBaseRepository } from '@domain/interfaces/base.repository.interface';
|
4
|
+
import { instanceToPlain } from 'class-transformer';
|
5
|
+
import { IBaseService } from './base.interface';
|
6
|
+
|
7
|
+
export class BaseService<
|
8
|
+
Entity,
|
9
|
+
CreateMessage extends Partial<Entity>,
|
10
|
+
UpdateMessage extends Partial<Entity> & { id: number },
|
11
|
+
Message,
|
12
|
+
> implements IBaseService<Entity, CreateMessage, UpdateMessage, Message>
|
13
|
+
{
|
14
|
+
constructor(private readonly repository: IBaseRepository<Entity>) {}
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Finds a single entity by its ID.
|
18
|
+
* @param id - The ID of the entity to find.
|
19
|
+
* @returns A promise that resolves to the mapped message.
|
20
|
+
* @throws GrpcNotFoundException if the entity is not found.
|
21
|
+
*/
|
22
|
+
async findOne(id: number): Promise<Message> {
|
23
|
+
const entity = await this.repository.findById(id);
|
24
|
+
if (!entity) {
|
25
|
+
throw new GrpcNotFoundException(`${this.constructor.name.replace('Service', '')} not found`);
|
26
|
+
}
|
27
|
+
return entity as Message;
|
28
|
+
}
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Retrieves all entities.
|
32
|
+
* @returns A promise that resolves to an object containing an array of mapped messages.
|
33
|
+
*/
|
34
|
+
async findAll(): Promise<{ data: Message[] }> {
|
35
|
+
const entities: Entity[] = await this.repository.find();
|
36
|
+
return {
|
37
|
+
data: entities as unknown as Message[],
|
38
|
+
};
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Retrieves paginated entities based on the provided query.
|
43
|
+
* @param query - Pagination and filter criteria.
|
44
|
+
* @returns A promise that resolves to the paginated result with rows and count.
|
45
|
+
*/
|
46
|
+
async getMany(query?: PaginateQuery): Promise<Paginated<Message>> {
|
47
|
+
const entities: Paginated<Entity> = await this.repository.getMany(query);
|
48
|
+
return entities as unknown as Paginated<Message>;
|
49
|
+
}
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Creates a new entity from the provided DTO.
|
53
|
+
* @param createDTO - The data transfer object for creating an entity.
|
54
|
+
* @returns A promise that resolves to the mapped message of the created entity.
|
55
|
+
*/
|
56
|
+
async create(createDTO: CreateMessage): Promise<Message> {
|
57
|
+
const plain = instanceToPlain(createDTO);
|
58
|
+
const entity = this.repository.create(plain as Entity);
|
59
|
+
await this.repository.save(entity);
|
60
|
+
return entity as unknown as Message;
|
61
|
+
}
|
62
|
+
|
63
|
+
/**
|
64
|
+
* Updates an existing entity with the provided DTO.
|
65
|
+
* @param updateDTO - The data transfer object for updating an entity.
|
66
|
+
* @returns A promise that resolves to the mapped message of the updated entity.
|
67
|
+
* @throws GrpcNotFoundException if the entity is not found.
|
68
|
+
*/
|
69
|
+
async update(updateDTO: UpdateMessage): Promise<Message> {
|
70
|
+
const entity = await this.repository.findById(updateDTO.id);
|
71
|
+
if (!entity) {
|
72
|
+
throw new GrpcNotFoundException(`${this.constructor.name.replace('Service', '')} not found`);
|
73
|
+
}
|
74
|
+
await this.repository.update(updateDTO.id, instanceToPlain(updateDTO) as any);
|
75
|
+
const updatedEntity: Entity = await this.repository.findById(updateDTO.id);
|
76
|
+
return updatedEntity as unknown as Message;
|
77
|
+
}
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Deletes an entity by its ID.
|
81
|
+
* @param id - The ID of the entity to delete.
|
82
|
+
* @returns A promise that resolves when the entity is deleted.
|
83
|
+
*/
|
84
|
+
async remove(id: number): Promise<void> {
|
85
|
+
await this.repository.delete(id);
|
86
|
+
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Counts all entities.
|
90
|
+
* @param options - Optional query options for counting entities.
|
91
|
+
* @returns A promise that resolves to an object containing the count.
|
92
|
+
*/
|
93
|
+
async count(options?: any): Promise<{ count: number }> {
|
94
|
+
const count = await this.repository.count(options || {});
|
95
|
+
return { count };
|
96
|
+
}
|
97
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { PaginateQuery, Paginated } from 'nestjs-paginate';
|
2
|
+
import { Repository } from 'typeorm';
|
3
|
+
export interface IId {
|
4
|
+
id: number;
|
5
|
+
}
|
6
|
+
|
7
|
+
export interface IBaseRepository<E> extends Repository<E> {
|
8
|
+
getMany(query: PaginateQuery): Promise<Paginated<E>>;
|
9
|
+
findById(id: number): Promise<E>;
|
10
|
+
find(options?: any): Promise<E[]>;
|
11
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import {
|
2
|
+
CreateDateColumn,
|
3
|
+
EntitySubscriberInterface,
|
4
|
+
EventSubscriber,
|
5
|
+
InsertEvent,
|
6
|
+
PrimaryGeneratedColumn,
|
7
|
+
UpdateDateColumn,
|
8
|
+
UpdateEvent,
|
9
|
+
} from 'typeorm';
|
10
|
+
import { IBaseEntity } from './base.entity.interface';
|
11
|
+
|
12
|
+
export class BaseEntity implements IBaseEntity {
|
13
|
+
@PrimaryGeneratedColumn()
|
14
|
+
id: number;
|
15
|
+
|
16
|
+
@CreateDateColumn({
|
17
|
+
type: 'datetime',
|
18
|
+
})
|
19
|
+
createdAt: Date;
|
20
|
+
|
21
|
+
@UpdateDateColumn({
|
22
|
+
type: 'datetime',
|
23
|
+
})
|
24
|
+
updatedAt: Date;
|
25
|
+
}
|
26
|
+
|
27
|
+
@EventSubscriber()
|
28
|
+
export class BaseEntitySubscriber implements EntitySubscriberInterface<BaseEntity> {
|
29
|
+
/**
|
30
|
+
* Indicates that this subscriber only listens to YourEntity events.
|
31
|
+
*/
|
32
|
+
public listenTo() {
|
33
|
+
return BaseEntity;
|
34
|
+
}
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Called before entity insertion.
|
38
|
+
*/
|
39
|
+
public beforeInsert(event: InsertEvent<BaseEntity>) {
|
40
|
+
const now = new Date();
|
41
|
+
now.setMilliseconds((now.getMilliseconds() + 1) % 1000);
|
42
|
+
event.entity.createdAt = now;
|
43
|
+
event.entity.updatedAt = now;
|
44
|
+
}
|
45
|
+
|
46
|
+
public beforeUpdate(event: UpdateEvent<BaseEntity>): void | Promise<any> {
|
47
|
+
const now = new Date();
|
48
|
+
now.setMilliseconds((now.getMilliseconds() + 1) % 1000);
|
49
|
+
event.entity.updatedAt = now;
|
50
|
+
}
|
51
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import { Repository, EntityManager, Equal, FindOptionsWhere, ObjectLiteral } from 'typeorm';
|
2
|
+
import { PaginateConfig, PaginateQuery, Paginated, paginate } from 'nestjs-paginate';
|
3
|
+
import { IBaseRepository } from '@domain/interfaces/base.repository.interface';
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Represents a generic repository for managing entities.
|
7
|
+
*/
|
8
|
+
export class BaseRepository<E extends ObjectLiteral> extends Repository<E> implements IBaseRepository<E> {
|
9
|
+
protected paginateConfig: PaginateConfig<E>;
|
10
|
+
|
11
|
+
constructor(manager: EntityManager, entityCls: new () => E, paginateConfig?: PaginateConfig<E>) {
|
12
|
+
super(entityCls, manager);
|
13
|
+
this.paginateConfig = paginateConfig || {
|
14
|
+
sortableColumns: [],
|
15
|
+
};
|
16
|
+
}
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Retrieves a paginated list of entities based on the provided query.
|
20
|
+
*
|
21
|
+
* @param query - The pagination query parameters.
|
22
|
+
* @returns A promise that resolves to a paginated list of entities.
|
23
|
+
*/
|
24
|
+
async getMany(query: PaginateQuery): Promise<Paginated<E>> {
|
25
|
+
if (query.select) {
|
26
|
+
if (typeof query.select === 'string') {
|
27
|
+
const selectArray = (query.select as string).split(',');
|
28
|
+
if (!selectArray.includes('id')) {
|
29
|
+
selectArray.unshift('id');
|
30
|
+
query.select = selectArray;
|
31
|
+
}
|
32
|
+
// query.select = selectArray.join(',');
|
33
|
+
} else if (Array.isArray(query.select)) {
|
34
|
+
if (!query.select.includes('id')) {
|
35
|
+
query.select.unshift('id');
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
return paginate(query, this, this.paginateConfig);
|
40
|
+
}
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Retrieves an entity from the database based on its ID.
|
44
|
+
*
|
45
|
+
* @param id - The ID of the entity to retrieve.
|
46
|
+
* @returns A promise that resolves to the retrieved entity.
|
47
|
+
*/
|
48
|
+
async findById(id: number): Promise<E> {
|
49
|
+
return await this.findOneBy({
|
50
|
+
id: Equal(id),
|
51
|
+
} as unknown as FindOptionsWhere<E>);
|
52
|
+
}
|
53
|
+
}
|
package/tsconfig.json
CHANGED
@@ -16,6 +16,22 @@
|
|
16
16
|
"noImplicitAny": false,
|
17
17
|
"strictBindCallApply": false,
|
18
18
|
"forceConsistentCasingInFileNames": false,
|
19
|
-
"noFallthroughCasesInSwitch": false
|
19
|
+
"noFallthroughCasesInSwitch": false,
|
20
|
+
"paths": {
|
21
|
+
"@/*": ["./src/*"],
|
22
|
+
"@interfaces-pb/*": ["./interfaces-pb/*"],
|
23
|
+
"@filters/*": ["./src/lib/filters/*"],
|
24
|
+
"@interceptors/*": ["./src/lib/interceptors/*"],
|
25
|
+
"@guards/*": ["./src/lib/guards/*"],
|
26
|
+
"@decorators/*": ["./src/lib/decorators/*"],
|
27
|
+
"@misc/*": ["./src/lib/misc/*"],
|
28
|
+
"@lib/*": ["./src/lib/*"],
|
29
|
+
"@infrastructure/*": ["./src/core/infrastructure/*"],
|
30
|
+
"@application/*": ["./src/core/application/*"],
|
31
|
+
"@presentation/*": ["./src/core/presentation/*"],
|
32
|
+
"@domain/*": ["./src/core/domain/*"],
|
33
|
+
"@bootstrap/*": ["./src/bootstrap/*"],
|
34
|
+
"@interfaces/*": ["./src/interfaces/*"]
|
35
|
+
}
|
20
36
|
}
|
21
37
|
}
|