@mikemajesty/microservice-crud 3.3.10 → 3.3.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikemajesty/microservice-crud",
3
- "version": "3.3.10",
3
+ "version": "3.3.11",
4
4
  "description": "Monorepo CLI",
5
5
  "main": "src/cli.js",
6
6
  "scripts": {
package/potgres.README.md CHANGED
@@ -1,16 +1,5 @@
1
1
  #### Postgres CRUD
2
2
 
3
- ### Add Schema to Sequelize.
4
-
5
- - Access the config.ts file
6
- ```
7
- src/infra/database/postgres/config.ts
8
- ```
9
- - Add your Postgres schema in the addModels function.
10
- ```
11
- sequelizeConfig.addModels([NewSchema]);
12
- ```
13
-
14
3
  ### Add Module to microservice.
15
4
 
16
5
  - Access the app.module.ts file
@@ -5,7 +5,7 @@ function capitalizeFirstLetter(string) {
5
5
 
6
6
  const getCoreEntity = (name) => `import { z } from 'zod';
7
7
 
8
- import { BaseEntity, withID } from '@/utils/entity';
8
+ import { BaseEntity, IEntity } from '@/utils/entity';
9
9
 
10
10
  const ID = z.string().uuid();
11
11
  const Name = z.string().min(1).max(200).trim();
@@ -23,12 +23,12 @@ export const ${capitalizeFirstLetter(name)}EntitySchema = z.object({
23
23
 
24
24
  type ${capitalizeFirstLetter(name)} = z.infer<typeof ${capitalizeFirstLetter(name)}EntitySchema>;
25
25
 
26
- export class ${capitalizeFirstLetter(name)}Entity extends BaseEntity<${capitalizeFirstLetter(name)}Entity>(${capitalizeFirstLetter(name)}EntitySchema) {
26
+ export class ${capitalizeFirstLetter(name)}Entity extends BaseEntity<${capitalizeFirstLetter(name)}Entity>(${capitalizeFirstLetter(name)}EntitySchema) implements IEntity {
27
27
  name: string;
28
28
 
29
29
  constructor(entity: ${capitalizeFirstLetter(name)}) {
30
30
  super();
31
- Object.assign(this, ${capitalizeFirstLetter(name)}EntitySchema.parse(withID(entity)));
31
+ Object.assign(this, this.validate(entity));
32
32
  }
33
33
  }
34
34
  `
@@ -3,17 +3,13 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getCoreRepository = (name) => `import { Transaction } from 'sequelize';
7
-
8
- import { IRepository } from '@/infra/repository';
9
- import { DatabaseOptionsType } from '@/utils/database/sequelize';
6
+ const getCoreRepository = (name) => `import { IRepository } from '@/infra/repository';
10
7
 
11
8
  import { ${capitalizeFirstLetter(name)}Entity } from '../entity/${name}';
12
9
  import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '../use-cases/${name}-list';
13
10
 
14
11
  export abstract class I${capitalizeFirstLetter(name)}Repository extends IRepository<${capitalizeFirstLetter(name)}Entity> {
15
- abstract paginate<TOptions = DatabaseOptionsType>(input: ${capitalizeFirstLetter(name)}ListInput, options?: TOptions): Promise<${capitalizeFirstLetter(name)}ListOutput>;
16
- abstract startSession<TTransaction = Transaction>(): Promise<TTransaction>;
12
+ abstract paginate(input: ${capitalizeFirstLetter(name)}ListInput): Promise<${capitalizeFirstLetter(name)}ListOutput>;
17
13
  }
18
14
  `
19
15
 
@@ -7,7 +7,6 @@ const getCoreUsecaseCreateTest = (name) => `import { Test } from '@nestjs/testin
7
7
 
8
8
  import { ILoggerAdapter } from '@/infra/logger';
9
9
  import { I${capitalizeFirstLetter(name)}CreateAdapter } from '@/modules/${name}/adapter';
10
- import { ApiInternalServerException } from '@/utils/exception';
11
10
  import { expectZodError, generateUUID } from '@/utils/tests/tests';
12
11
 
13
12
  import { ${capitalizeFirstLetter(name)}Entity } from '../../entity/${name}';
@@ -64,22 +63,9 @@ describe('${capitalizeFirstLetter(name)}CreateUsecase', () => {
64
63
  const createOutput: ${capitalizeFirstLetter(name)}CreateOutput = { created: true, id: generateUUID() };
65
64
 
66
65
  repository.create = jest.fn().mockResolvedValue(createOutput);
67
- repository.startSession = jest.fn().mockResolvedValue({
68
- commit: jest.fn()
69
- });
70
66
 
71
67
  await expect(usecase.execute(successInput)).resolves.toEqual(createOutput);
72
68
  });
73
-
74
- test('when transaction throw an error, should expect an error', async () => {
75
- repository.startSession = jest.fn().mockResolvedValue({
76
- commit: jest.fn(),
77
- rollback: jest.fn()
78
- });
79
- repository.create = jest.fn().mockRejectedValue(new ApiInternalServerException());
80
-
81
- await expect(usecase.execute(successInput)).rejects.toThrow(ApiInternalServerException);
82
- });
83
69
  });
84
70
  `
85
71
 
@@ -7,7 +7,6 @@ const getCoreUsecaseCreate = (name) => `import { z } from 'zod';
7
7
 
8
8
  import { ILoggerAdapter } from '@/infra/logger';
9
9
  import { CreatedModel } from '@/infra/repository';
10
- import { DatabaseOptionsType } from '@/utils/database/sequelize';
11
10
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
12
11
 
13
12
  import { I${capitalizeFirstLetter(name)}Repository } from '../repository/${name}';
@@ -27,19 +26,11 @@ export class ${capitalizeFirstLetter(name)}CreateUsecase {
27
26
  async execute(input: ${capitalizeFirstLetter(name)}CreateInput): Promise<${capitalizeFirstLetter(name)}CreateOutput> {
28
27
  const entity = new ${capitalizeFirstLetter(name)}Entity(input);
29
28
 
30
- const transaction = await this.${name}Repository.startSession();
31
- try {
32
- const ${name} = await this.${name}Repository.create<DatabaseOptionsType>(entity, { transaction });
29
+ const ${name} = await this.${name}Repository.create(entity);
33
30
 
34
- await transaction.commit();
31
+ this.loggerServide.info({ message: '${name} created.', obj: { ${name} } });
35
32
 
36
- this.loggerServide.info({ message: '${name} created.', obj: { ${name} } });
37
-
38
- return ${name};
39
- } catch (error) {
40
- await transaction.rollback();
41
- throw error;
42
- }
33
+ return ${name};
43
34
  }
44
35
  }
45
36
  `
@@ -6,7 +6,6 @@ function capitalizeFirstLetter(string) {
6
6
  const getCoreUsecaseDelete = (name) => `import { z } from 'zod';
7
7
 
8
8
  import { I${capitalizeFirstLetter(name)}Repository } from '@/core/${name}/repository/${name}';
9
- import { DatabaseOptionsType } from '@/utils/database/sequelize';
10
9
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
11
10
  import { ApiNotFoundException } from '@/utils/exception';
12
11
 
@@ -24,7 +23,7 @@ export class ${capitalizeFirstLetter(name)}DeleteUsecase {
24
23
 
25
24
  @ValidateSchema(${capitalizeFirstLetter(name)}DeleteSchema)
26
25
  async execute({ id }: ${capitalizeFirstLetter(name)}DeleteInput): Promise<${capitalizeFirstLetter(name)}DeleteOutput> {
27
- const model = await this.${name}Repository.findById<DatabaseOptionsType>(id);
26
+ const model = await this.${name}Repository.findById(id);
28
27
 
29
28
  if (!model) {
30
29
  throw new ApiNotFoundException();
@@ -6,7 +6,6 @@ function capitalizeFirstLetter(string) {
6
6
  const getCoreUsecaseGetByID = (name) => `import { z } from 'zod';
7
7
 
8
8
  import { ${capitalizeFirstLetter(name)}EntitySchema } from '@/core/${name}/entity/${name}';
9
- import { DatabaseOptionsType } from '@/utils/database/sequelize';
10
9
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
11
10
  import { ApiNotFoundException } from '@/utils/exception';
12
11
 
@@ -25,7 +24,7 @@ export class ${capitalizeFirstLetter(name)}GetByIdUsecase {
25
24
 
26
25
  @ValidateSchema(${capitalizeFirstLetter(name)}GetByIdSchema)
27
26
  async execute({ id }: ${capitalizeFirstLetter(name)}GetByIDInput): Promise<${capitalizeFirstLetter(name)}GetByIDOutput> {
28
- const ${name} = await this.${name}Repository.findById<DatabaseOptionsType>(id);
27
+ const ${name} = await this.${name}Repository.findById(id);
29
28
 
30
29
  if (!${name}) {
31
30
  throw new ApiNotFoundException();
@@ -7,7 +7,6 @@ const getCoreUsecaseUpdate = (name) => `import { z } from 'zod';
7
7
 
8
8
  import { I${capitalizeFirstLetter(name)}Repository } from '@/core/${name}/repository/${name}';
9
9
  import { ILoggerAdapter } from '@/infra/logger';
10
- import { DatabaseOptionsType } from '@/utils/database/sequelize';
11
10
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
12
11
  import { ApiNotFoundException } from '@/utils/exception';
13
12
 
@@ -25,7 +24,7 @@ export class ${capitalizeFirstLetter(name)}UpdateUsecase {
25
24
 
26
25
  @ValidateSchema(${capitalizeFirstLetter(name)}UpdateSchema)
27
26
  async execute(input: ${capitalizeFirstLetter(name)}UpdateInput): Promise<${capitalizeFirstLetter(name)}UpdateOutput> {
28
- const ${name} = await this.${name}Repository.findById<DatabaseOptionsType>(input.id);
27
+ const ${name} = await this.${name}Repository.findById(input.id);
29
28
 
30
29
  if (!${name}) {
31
30
  throw new ApiNotFoundException();
@@ -39,7 +38,7 @@ export class ${capitalizeFirstLetter(name)}UpdateUsecase {
39
38
 
40
39
  this.loggerServide.info({ message: '${name} updated.', obj: { ${name}: input } });
41
40
 
42
- const updated = await this.${name}Repository.findById<DatabaseOptionsType>(entity.id);
41
+ const updated = await this.${name}Repository.findById(entity.id);
43
42
 
44
43
  return new ${capitalizeFirstLetter(name)}Entity(updated);
45
44
  }
@@ -4,7 +4,8 @@ function capitalizeFirstLetter(string) {
4
4
  }
5
5
 
6
6
  const getModule = (name) => `import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
7
- import { ModelCtor, Sequelize } from 'sequelize-typescript';
7
+ import { getRepositoryToken, TypeOrmModule } from '@nestjs/typeorm';
8
+ import { Repository } from 'typeorm';
8
9
 
9
10
  import { ${capitalizeFirstLetter(name)}Entity } from '@/core/${name}/entity/${name}';
10
11
  import { I${capitalizeFirstLetter(name)}Repository } from '@/core/${name}/repository/${name}';
@@ -14,8 +15,6 @@ import { ${capitalizeFirstLetter(name)}GetByIdUsecase } from '@/core/${name}/use
14
15
  import { ${capitalizeFirstLetter(name)}ListUsecase } from '@/core/${name}/use-cases/${name}-list';
15
16
  import { ${capitalizeFirstLetter(name)}UpdateUsecase } from '@/core/${name}/use-cases/${name}-update';
16
17
  import { RedisCacheModule } from '@/infra/cache/redis';
17
- import { IDataBaseAdapter } from '@/infra/database';
18
- import { PostgresDatabaseModule } from '@/infra/database/postgres/module';
19
18
  import { ${capitalizeFirstLetter(name)}Schema } from '@/infra/database/postgres/schemas/${name}';
20
19
  import { ILoggerAdapter, LoggerModule } from '@/infra/logger';
21
20
  import { TokenModule } from '@/libs/auth';
@@ -32,21 +31,20 @@ import { ${capitalizeFirstLetter(name)}Controller } from './controller';
32
31
  import { ${capitalizeFirstLetter(name)}Repository } from './repository';
33
32
 
34
33
  @Module({
35
- imports: [TokenModule, LoggerModule, RedisCacheModule, PostgresDatabaseModule],
34
+ imports: [TokenModule, LoggerModule, TypeOrmModule.forFeature([${capitalizeFirstLetter(name)}Schema]), RedisCacheModule],
36
35
  controllers: [${capitalizeFirstLetter(name)}Controller],
37
36
  providers: [
38
37
  {
39
38
  provide: I${capitalizeFirstLetter(name)}Repository,
40
- useFactory: (database: IDataBaseAdapter) => {
41
- const repossitory = database.getDatabase<Sequelize>().model(${capitalizeFirstLetter(name)}Schema);
42
- return new ${capitalizeFirstLetter(name)}Repository(repossitory as ModelCtor<${capitalizeFirstLetter(name)}Schema> & ${capitalizeFirstLetter(name)}Entity);
39
+ useFactory: (repository: Repository<${capitalizeFirstLetter(name)}Schema & ${capitalizeFirstLetter(name)}Entity>) => {
40
+ return new ${capitalizeFirstLetter(name)}Repository(repository);
43
41
  },
44
- inject: [IDataBaseAdapter]
42
+ inject: [getRepositoryToken(${capitalizeFirstLetter(name)}Schema)]
45
43
  },
46
44
  {
47
45
  provide: I${capitalizeFirstLetter(name)}CreateAdapter,
48
- useFactory: (logger: ILoggerAdapter, repository: I${capitalizeFirstLetter(name)}Repository) => new ${capitalizeFirstLetter(name)}CreateUsecase(repository, logger),
49
- inject: [ILoggerAdapter, I${capitalizeFirstLetter(name)}Repository]
46
+ useFactory: (repository: I${capitalizeFirstLetter(name)}Repository, logger: ILoggerAdapter) => new ${capitalizeFirstLetter(name)}CreateUsecase(repository, logger),
47
+ inject: [I${capitalizeFirstLetter(name)}Repository, ILoggerAdapter]
50
48
  },
51
49
  {
52
50
  provide: I${capitalizeFirstLetter(name)}UpdateAdapter,
@@ -4,41 +4,39 @@ function capitalizeFirstLetter(string) {
4
4
  }
5
5
 
6
6
  const getModuleRepository = (name) => `import { Injectable } from '@nestjs/common';
7
- import { Transaction } from 'sequelize';
8
- import { ModelCtor } from 'sequelize-typescript';
7
+ import { FindOptionsWhere, Repository } from 'typeorm';
9
8
 
10
9
  import { ${capitalizeFirstLetter(name)}Entity } from '@/core/${name}/entity/${name}';
11
10
  import { I${capitalizeFirstLetter(name)}Repository } from '@/core/${name}/repository/${name}';
12
11
  import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '@/core/${name}/use-cases/${name}-list';
13
12
  import { ${capitalizeFirstLetter(name)}Schema } from '@/infra/database/postgres/schemas/${name}';
14
- import { SequelizeRepository } from '@/infra/repository/postgres/repository';
15
- import { DatabaseOptionsSchema, DatabaseOptionsType } from '@/utils/database/sequelize';
16
- import { ConvertPaginateInputToSequelizeFilter } from '@/utils/decorators/database/postgres/convert-paginate-input-to-sequelize-filter.decorator';
13
+ import { PostgresRepository } from '@/infra/repository/postgres/repository';
14
+ import { ValidatePostgresFilter } from '@/utils/decorators/database/postgres/validate-typeorm-filter.decorator';
17
15
  import { ValidateDatabaseSortAllowed } from '@/utils/decorators/database/validate-database-sort-allowed.decorator';
18
16
  import { SearchTypeEnum } from '@/utils/decorators/types';
17
+ import { calucaleSkip } from '@/utils/pagination';
19
18
 
20
- type Model = ModelCtor<${capitalizeFirstLetter(name)}Schema> & ${capitalizeFirstLetter(name)}Entity;
19
+ type Model = ${capitalizeFirstLetter(name)}Schema & ${capitalizeFirstLetter(name)}Entity;
21
20
 
22
21
  @Injectable()
23
- export class ${capitalizeFirstLetter(name)}Repository extends SequelizeRepository<Model> implements I${capitalizeFirstLetter(name)}Repository {
24
- constructor(readonly repository: Model) {
22
+ export class ${capitalizeFirstLetter(name)}Repository extends PostgresRepository<Model> implements I${capitalizeFirstLetter(name)}Repository {
23
+ constructor(readonly repository: Repository<Model>) {
25
24
  super(repository);
26
25
  }
27
26
 
28
- async startSession<TTransaction = Transaction>(): Promise<TTransaction> {
29
- const transaction = await this.repository.sequelize.transaction();
27
+ @ValidateDatabaseSortAllowed<${capitalizeFirstLetter(name)}Entity>('createdAt', 'name')
28
+ @ValidatePostgresFilter<${capitalizeFirstLetter(name)}Entity>([{ name: 'name', type: SearchTypeEnum.like }])
29
+ async paginate(input: ${capitalizeFirstLetter(name)}ListInput): Promise<${capitalizeFirstLetter(name)}ListOutput> {
30
+ const skip = calucaleSkip(input);
30
31
 
31
- return transaction as TTransaction;
32
- }
33
-
34
- @ValidateDatabaseSortAllowed('createdAt', 'name')
35
- @ConvertPaginateInputToSequelizeFilter([{ name: 'name', type: SearchTypeEnum.like }])
36
- async paginate(input: ${capitalizeFirstLetter(name)}ListInput, options: DatabaseOptionsType): Promise<${capitalizeFirstLetter(name)}ListOutput> {
37
- const { schema } = DatabaseOptionsSchema.parse(options);
38
-
39
- const list = await this.repository.schema(schema).findAndCountAll(input);
32
+ const [docs, total] = await this.repository.findAndCount({
33
+ take: input.limit,
34
+ skip,
35
+ order: input.sort,
36
+ where: input.search as FindOptionsWhere<${capitalizeFirstLetter(name)}Entity>
37
+ });
40
38
 
41
- return { docs: list.rows.map((r) => new ${capitalizeFirstLetter(name)}Entity(r)), limit: input.limit, page: input.page, total: list.count };
39
+ return { docs, total, page: input.page, limit: input.limit };
42
40
  }
43
41
  }
44
42
  `
@@ -5,18 +5,27 @@ function capitalizeFirstLetter(string) {
5
5
  return string.charAt(0).toUpperCase() + string.slice(1);
6
6
  }
7
7
 
8
- const getModuleSchema = (name) => `import { Column, DataType, Model, Table } from 'sequelize-typescript';
8
+ const getModuleSchema = (name) => `import { Max, Min } from 'class-validator';
9
+ import { BaseEntity, Column, CreateDateColumn, DeleteDateColumn, Entity, UpdateDateColumn } from 'typeorm';
9
10
 
10
- @Table({ timestamps: true, tableName: '${pluralize(name)}' })
11
- export class ${capitalizeFirstLetter(name)}Schema extends Model {
12
- @Column({ primaryKey: true, type: DataType.UUID })
11
+ @Entity({ name: '${pluralize(name)}' })
12
+ export class ${capitalizeFirstLetter(name)}Schema extends BaseEntity {
13
+ @Column({ type: 'uuid', primary: true })
13
14
  id: string;
14
15
 
15
- @Column(DataType.STRING)
16
+ @Min(1)
17
+ @Max(200)
18
+ @Column()
16
19
  name: string;
17
20
 
18
- @Column({ allowNull: true, type: DataType.DATE })
19
- deletedAt?: Date;
21
+ @CreateDateColumn()
22
+ createdAt: Date;
23
+
24
+ @UpdateDateColumn()
25
+ updatedAt: Date;
26
+
27
+ @DeleteDateColumn({ nullable: true })
28
+ deletedAt: Date;
20
29
  }
21
30
  `
22
31