xcally-nest-library 0.0.28 → 0.0.30

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. package/dist/index.d.ts +6 -0
  2. package/dist/index.js +6 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/core/application/base.interface.d.ts +16 -0
  5. package/dist/src/core/application/base.interface.js +3 -0
  6. package/dist/src/core/application/base.interface.js.map +1 -0
  7. package/dist/src/core/application/base.service.d.ts +20 -0
  8. package/dist/src/core/application/base.service.js +51 -0
  9. package/dist/src/core/application/base.service.js.map +1 -0
  10. package/dist/src/core/domain/interfaces/base.repository.interface.d.ts +10 -0
  11. package/dist/src/core/domain/interfaces/base.repository.interface.js +3 -0
  12. package/dist/src/core/domain/interfaces/base.repository.interface.js.map +1 -0
  13. package/dist/src/core/infrastracture/databases/base.entity.d.ts +13 -0
  14. package/dist/src/core/infrastracture/databases/base.entity.interface.d.ts +5 -0
  15. package/dist/src/core/infrastracture/databases/base.entity.interface.js +3 -0
  16. package/dist/src/core/infrastracture/databases/base.entity.interface.js.map +1 -0
  17. package/dist/src/core/infrastracture/databases/base.entity.js +54 -0
  18. package/dist/src/core/infrastracture/databases/base.entity.js.map +1 -0
  19. package/dist/src/core/infrastracture/databases/base.repository.d.ts +9 -0
  20. package/dist/src/core/infrastracture/databases/base.repository.js +37 -0
  21. package/dist/src/core/infrastracture/databases/base.repository.js.map +1 -0
  22. package/dist/tsconfig.tsbuildinfo +1 -1
  23. package/index.ts +6 -0
  24. package/package.json +25 -19
  25. package/src/core/application/base.interface.ts +16 -0
  26. package/src/core/application/base.service.ts +97 -0
  27. package/src/core/domain/interfaces/base.repository.interface.ts +11 -0
  28. package/src/core/infrastracture/databases/base.entity.interface.ts +5 -0
  29. package/src/core/infrastracture/databases/base.entity.ts +44 -0
  30. package/src/core/infrastracture/databases/base.repository.ts +53 -0
  31. 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,32 +1,23 @@
1
1
  {
2
2
  "name": "xcally-nest-library",
3
- "version": "0.0.28",
3
+ "version": "0.0.30",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "author": "",
8
8
  "license": "UNLICENSED",
9
- "scripts": {
10
- "bump:patch": "npm version patch -m \"Bump version to %s\"",
11
- "prepublishOnly": "npm run build",
12
- "build": "tsc",
13
- "build:watch": "rimraf dist && tsc-watch -b -v",
14
- "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
15
- "prettier:check": "prettier --check ./**/*.{ts,js,json,*rc}",
16
- "prettier:write": "prettier --write ./**/*.{ts,js,json,*rc}",
17
- "start": "nest start",
18
- "start:dev": "nest start --watch",
19
- "start:debug": "nest start --debug --watch",
20
- "start:prod": "node dist/main",
21
- "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
22
- "lib:link": "pnpm link --global",
23
- "lib:unlink": "pnpm unlink xcally-nest-libs --global"
24
- },
25
9
  "dependencies": {
26
10
  "@nestjs/common": "^11.0.7",
27
11
  "@nestjs/config": "^4.0.0",
28
12
  "@nestjs/core": "^11.0.7",
29
- "nestjs-pino": "^4.3.0"
13
+ "@nestjs/microservices": "^11.0.9",
14
+ "class-transformer": "^0.5.1",
15
+ "nestjs-grpc-exceptions": "^0.2.2",
16
+ "nestjs-paginate": "^11.0.0",
17
+ "nestjs-pino": "^4.3.0",
18
+ "pino": "^9.6.0",
19
+ "pino-pretty": "^13.0.0",
20
+ "typeorm": "^0.3.20"
30
21
  },
31
22
  "devDependencies": {
32
23
  "@nestjs/cli": "^11.0.2",
@@ -41,5 +32,20 @@
41
32
  "ts-node": "^10.9.2",
42
33
  "tsc-watch": "^6.2.1",
43
34
  "typescript": "^5.7.3"
35
+ },
36
+ "scripts": {
37
+ "bump:patch": "npm version patch -m \"Bump version to %s\"",
38
+ "build": "tsc",
39
+ "build:watch": "rimraf dist && tsc-watch -b -v",
40
+ "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
41
+ "prettier:check": "prettier --check ./**/*.{ts,js,json,*rc}",
42
+ "prettier:write": "prettier --write ./**/*.{ts,js,json,*rc}",
43
+ "start": "nest start",
44
+ "start:dev": "nest start --watch",
45
+ "start:debug": "nest start --debug --watch",
46
+ "start:prod": "node dist/main",
47
+ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
48
+ "lib:link": "pnpm link --global",
49
+ "lib:unlink": "pnpm unlink xcally-nest-libs --global"
44
50
  }
45
- }
51
+ }
@@ -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,5 @@
1
+ export interface IBaseEntity {
2
+ id: number;
3
+ createdAt: Date;
4
+ updatedAt: Date;
5
+ }
@@ -0,0 +1,44 @@
1
+ import { CreateDateColumn, PrimaryGeneratedColumn, UpdateDateColumn, UpdateEvent } from 'typeorm';
2
+ import { EntitySubscriberInterface, EventSubscriber, InsertEvent } from 'typeorm';
3
+ import { IBaseEntity } from './base.entity.interface';
4
+
5
+ export class BaseEntity implements IBaseEntity {
6
+ @PrimaryGeneratedColumn()
7
+ id: number;
8
+
9
+ @CreateDateColumn({
10
+ type: 'datetime',
11
+ })
12
+ createdAt: Date;
13
+
14
+ @UpdateDateColumn({
15
+ type: 'datetime',
16
+ })
17
+ updatedAt: Date;
18
+ }
19
+
20
+ @EventSubscriber()
21
+ export class BaseEntitySubscriber implements EntitySubscriberInterface<BaseEntity> {
22
+ /**
23
+ * Indicates that this subscriber only listens to YourEntity events.
24
+ */
25
+ public listenTo() {
26
+ return BaseEntity;
27
+ }
28
+
29
+ /**
30
+ * Called before entity insertion.
31
+ */
32
+ public beforeInsert(event: InsertEvent<BaseEntity>) {
33
+ const now = new Date();
34
+ now.setMilliseconds((now.getMilliseconds() + 1) % 1000);
35
+ event.entity.createdAt = now;
36
+ event.entity.updatedAt = now;
37
+ }
38
+
39
+ public beforeUpdate(event: UpdateEvent<BaseEntity>): void | Promise<any> {
40
+ const now = new Date();
41
+ now.setMilliseconds((now.getMilliseconds() + 1) % 1000);
42
+ event.entity.updatedAt = now;
43
+ }
44
+ }
@@ -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
  }