@mikemajesty/microservice-crud 0.0.7 → 0.0.9

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 (30) hide show
  1. package/package.json +2 -1
  2. package/src/cli.js +7 -9
  3. package/src/scafold/mongo/.gitkeep +0 -0
  4. package/src/scafold/postgres/.gitkeep +0 -0
  5. package/src/templates/mongo/core/repository/repository.js +3 -1
  6. package/src/templates/mongo/core/use-cases/create.js +25 -5
  7. package/src/templates/mongo/core/use-cases/delete.js +10 -2
  8. package/src/templates/mongo/core/use-cases/getByID.js +12 -4
  9. package/src/templates/mongo/core/use-cases/list.js +18 -3
  10. package/src/templates/mongo/core/use-cases/update.js +11 -3
  11. package/src/templates/mongo/modules/adapter.js +5 -12
  12. package/src/templates/mongo/modules/controller.js +24 -25
  13. package/src/templates/mongo/modules/module.js +20 -8
  14. package/src/templates/mongo/modules/repository.js +18 -8
  15. package/src/templates/mongo/modules/swagger.js +8 -7
  16. package/src/templates/postgres/core/repository/repository.js +5 -2
  17. package/src/templates/postgres/core/use-cases/create.js +26 -5
  18. package/src/templates/postgres/core/use-cases/delete.js +13 -4
  19. package/src/templates/postgres/core/use-cases/getByID.js +12 -3
  20. package/src/templates/postgres/core/use-cases/list.js +11 -1
  21. package/src/templates/postgres/core/use-cases/update.js +18 -6
  22. package/src/templates/postgres/modules/adapter.js +5 -12
  23. package/src/templates/postgres/modules/controller.js +24 -25
  24. package/src/templates/postgres/modules/module.js +5 -5
  25. package/src/templates/postgres/modules/repository.js +11 -8
  26. package/src/templates/postgres/modules/swagger.js +6 -4
  27. package/src/scafold/mongo/schemas/bird.ts +0 -35
  28. package/src/scafold/postgres/schemas/dog.ts +0 -13
  29. package/src/templates/mongo/modules/types.js +0 -49
  30. package/src/templates/postgres/modules/types.js +0 -52
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikemajesty/microservice-crud",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Monorepo CLI",
5
5
  "main": "src/cli.js",
6
6
  "scripts": {
@@ -21,6 +21,7 @@
21
21
  "license": "MIT",
22
22
  "dependencies": {
23
23
  "arg": "^5.0.1",
24
+ "chmod": "^0.2.1",
24
25
  "cli-select": "^1.1.2",
25
26
  "colorette": "^2.0.19",
26
27
  "esm": "^3.2.25",
package/src/cli.js CHANGED
@@ -24,7 +24,6 @@ const { getModule } = require('./templates/postgres/modules/module');
24
24
  const { getModuleRepository } = require('./templates/postgres/modules/repository');
25
25
  const { getModuleSchema } = require('./templates/postgres/schemas/schema');
26
26
  const { getModuleSwagger } = require('./templates/postgres/modules/swagger');
27
- const { getModuleType } = require('./templates/postgres/modules/types');
28
27
 
29
28
  const { getCoreUsecaseCreateTest: getCoreUsecaseCreateMongoTest } = require('./templates/mongo/core/use-cases/__tests__/create.spec');
30
29
  const { getCoreUsecaseUpdateTest: getCoreUsecaseUpdateMongoTest } = require('./templates/mongo/core/use-cases/__tests__/update.spec');
@@ -45,8 +44,6 @@ const { getModule: getModuleMongo } = require('./templates/mongo/modules/module'
45
44
  const { getModuleRepository: getModuleRepositoryMongo } = require('./templates/mongo/modules/repository');
46
45
  const { getModuleSchema: getModuleSchemaMongo } = require('./templates/mongo/schemas/schema');
47
46
  const { getModuleSwagger: getModuleSwaggerMongo } = require('./templates/mongo/modules/swagger');
48
- const { getModuleType: getModuleTypeMongo } = require('./templates/mongo/modules/types');
49
-
50
47
 
51
48
  const createPostgresCrud = async (name) => {
52
49
  if (!name) throw new Error('--name is required')
@@ -108,8 +105,6 @@ const createPostgresCrud = async (name) => {
108
105
  fs.writeFileSync(`${modulesPath}/module.ts`, getModule(name))
109
106
  fs.writeFileSync(`${modulesPath}/repository.ts`, getModuleRepository(name))
110
107
  fs.writeFileSync(`${modulesPath}/swagger.ts`, getModuleSwagger(name))
111
- fs.writeFileSync(`${modulesPath}/types.ts`, getModuleType(name))
112
-
113
108
 
114
109
  return `${name}`
115
110
  } catch (error) {
@@ -170,7 +165,7 @@ const createMongoCrud = async (name) => {
170
165
  fs.writeFileSync(`${useCasesPathTest}/${name}-getByID.spec.ts`, getCoreUsecaseGetByIDMongoTest(name))
171
166
 
172
167
  const schemasPath = `${__dirname}/scafold/mongo/schemas`;
173
-
168
+
174
169
  if (fs.existsSync(schemasPath)) {
175
170
  fs.rmSync(schemasPath, { recursive: true });
176
171
  }
@@ -187,7 +182,6 @@ const createMongoCrud = async (name) => {
187
182
  fs.writeFileSync(`${modulesPath}/repository.ts`, getModuleRepositoryMongo(name))
188
183
  fs.writeFileSync(`${modulesPath}/schema.ts`, getModuleSchemaMongo(name))
189
184
  fs.writeFileSync(`${modulesPath}/swagger.ts`, getModuleSwaggerMongo(name))
190
- fs.writeFileSync(`${modulesPath}/types.ts`, getModuleTypeMongo(name))
191
185
 
192
186
  return `${name}`
193
187
  } catch (error) {
@@ -294,9 +288,9 @@ export async function cli(args) {
294
288
  const destination = `${dest}/src/${folder}`.replace('\n', '');
295
289
 
296
290
  fse.copySync(source, destination, { overwrite: true });
297
-
291
+
298
292
  const destPathSchema = `${dest}/src/infra/database/${userInput.type === 'postgres:crud' ? 'postgres' : 'mongo'}/schemas`;
299
-
293
+
300
294
  const pathSchema = path.resolve(src, '../schemas');
301
295
 
302
296
  fse.copySync(pathSchema, destPathSchema, { overwrite: true });
@@ -304,6 +298,10 @@ export async function cli(args) {
304
298
  if (fs.existsSync(source)) {
305
299
  fs.rmSync(source, { recursive: true });
306
300
  }
301
+
302
+ if (fs.existsSync(pathSchema + `/${name}.ts`)) {
303
+ fs.rmSync(pathSchema + `/${name}.ts`, { recursive: true });
304
+ }
307
305
  }
308
306
 
309
307
  console.log(bold(green('===done===')))
File without changes
File without changes
@@ -4,12 +4,14 @@ function capitalizeFirstLetter(string) {
4
4
  }
5
5
 
6
6
  const getCoreRepository = (name) => `import { IRepository } from '@/infra/repository';
7
- import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '@/modules/${name}/types';
7
+ import { MongoRepositorySession } from '@/utils/database/mongoose';
8
8
 
9
9
  import { ${capitalizeFirstLetter(name)}Entity } from '../entity/${name}';
10
+ import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '../use-cases/${name}-list';
10
11
 
11
12
  export abstract class I${capitalizeFirstLetter(name)}Repository extends IRepository<${capitalizeFirstLetter(name)}Entity> {
12
13
  abstract paginate(input: ${capitalizeFirstLetter(name)}ListInput): Promise<${capitalizeFirstLetter(name)}ListOutput>;
14
+ abstract startSession(): Promise<MongoRepositorySession>;
13
15
  }
14
16
  `
15
17
 
@@ -3,22 +3,42 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getCoreUsecaseCreate = (name) => `import { ${capitalizeFirstLetter(name)}CreateInput, ${capitalizeFirstLetter(name)}CreateOutput, ${capitalizeFirstLetter(name)}CreateSchema } from '@/modules/${name}/types';
6
+ const getCoreUsecaseCreate = (name) => `import { z } from 'zod';
7
+
8
+ import { ILoggerAdapter } from '@/infra/logger';
9
+ import { CreatedModel } from '@/infra/repository';
7
10
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
8
11
 
9
- import { ${capitalizeFirstLetter(name)}Entity } from '../entity/${name}';
12
+ import { ${capitalizeFirstLetter(name)}Entity, ${capitalizeFirstLetter(name)}EntitySchema } from '../entity/${name}';
10
13
  import { I${capitalizeFirstLetter(name)}Repository } from '../repository/${name}';
11
14
 
15
+ export const ${capitalizeFirstLetter(name)}CreateSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
16
+ name: true
17
+ });
18
+
19
+ export type ${capitalizeFirstLetter(name)}CreateInput = z.infer<typeof ${capitalizeFirstLetter(name)}CreateSchema>;
20
+ export type ${capitalizeFirstLetter(name)}CreateOutput = Promise<CreatedModel>;
21
+
12
22
  export class ${capitalizeFirstLetter(name)}CreateUsecase {
13
- constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository) {}
23
+ constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository, private readonly loggerServide: ILoggerAdapter) {}
14
24
 
15
25
  @ValidateSchema(${capitalizeFirstLetter(name)}CreateSchema)
16
26
  async execute(input: ${capitalizeFirstLetter(name)}CreateInput): Promise<${capitalizeFirstLetter(name)}CreateOutput> {
17
27
  const entity = new ${capitalizeFirstLetter(name)}Entity(input);
18
28
 
19
- const ${name} = await this.${name}Repository.create(entity);
29
+ const session = await this.${name}Repository.startSession();
30
+
31
+ try {
32
+ const ${name} = await this.${name}Repository.create(entity, { session });
33
+
34
+ await session.commitTransaction();
20
35
 
21
- return ${name};
36
+ this.loggerServide.info({ message: '${name} created.', obj: { ${name} } });
37
+ return ${name};
38
+ } catch (error) {
39
+ await session.abortTransaction();
40
+ throw error;
41
+ }
22
42
  }
23
43
  }
24
44
  `
@@ -3,13 +3,21 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getCoreUsecaseDelete = (name) => `import { ${capitalizeFirstLetter(name)}DeleteInput, ${capitalizeFirstLetter(name)}DeleteOutput, ${capitalizeFirstLetter(name)}DeleteSchema } from '@/modules/${name}/types';
6
+ const getCoreUsecaseDelete = (name) => `import { z } from 'zod';
7
+
7
8
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
8
9
  import { ApiNotFoundException } from '@/utils/exception';
9
10
 
10
- import { ${capitalizeFirstLetter(name)}Entity } from '../entity/${name}';
11
+ import { ${capitalizeFirstLetter(name)}Entity, ${capitalizeFirstLetter(name)}EntitySchema } from '../entity/${name}';
11
12
  import { I${capitalizeFirstLetter(name)}Repository } from '../repository/${name}';
12
13
 
14
+ export const ${capitalizeFirstLetter(name)}DeleteSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
15
+ id: true
16
+ });
17
+
18
+ export type ${capitalizeFirstLetter(name)}DeleteInput = z.infer<typeof ${capitalizeFirstLetter(name)}DeleteSchema>;
19
+ export type ${capitalizeFirstLetter(name)}DeleteOutput = Promise<${capitalizeFirstLetter(name)}Entity>;
20
+
13
21
  export class ${capitalizeFirstLetter(name)}DeleteUsecase {
14
22
  constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository) {}
15
23
 
@@ -3,14 +3,20 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getCoreUsecaseGetByID = (name) => `import { ${capitalizeFirstLetter(name)}GetByIdSchema } from '@/modules/${name}/types';
7
- import { ${capitalizeFirstLetter(name)}GetByIDInput, ${capitalizeFirstLetter(name)}GetByIDOutput } from '@/modules/${name}/types';
6
+ const getCoreUsecaseGetByID = (name) => `import { z } from 'zod';
7
+
8
8
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
9
9
  import { ApiNotFoundException } from '@/utils/exception';
10
10
 
11
- import { ${capitalizeFirstLetter(name)}Entity } from '../entity/${name}';
11
+ import { ${capitalizeFirstLetter(name)}Entity, ${capitalizeFirstLetter(name)}EntitySchema } from '../entity/${name}';
12
12
  import { I${capitalizeFirstLetter(name)}Repository } from '../repository/${name}';
13
13
 
14
+ export const ${capitalizeFirstLetter(name)}GetByIdSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
15
+ id: true
16
+ });
17
+ export type ${capitalizeFirstLetter(name)}GetByIDInput = z.infer<typeof ${capitalizeFirstLetter(name)}GetByIdSchema>;
18
+ export type ${capitalizeFirstLetter(name)}GetByIDOutput = Promise<${capitalizeFirstLetter(name)}Entity>;
19
+
14
20
  export class ${capitalizeFirstLetter(name)}GetByIdUsecase {
15
21
  constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository) {}
16
22
 
@@ -22,7 +28,9 @@ export class ${capitalizeFirstLetter(name)}GetByIdUsecase {
22
28
  throw new ApiNotFoundException('${name}NotFound');
23
29
  }
24
30
 
25
- return new ${capitalizeFirstLetter(name)}Entity(${name});
31
+ const entity = new ${capitalizeFirstLetter(name)}Entity(${name});
32
+
33
+ return entity;
26
34
  }
27
35
  }
28
36
  `
@@ -1,22 +1,37 @@
1
+ const pluralize = require('pluralize')
1
2
 
2
3
  function capitalizeFirstLetter(string) {
3
4
  return string.charAt(0).toUpperCase() + string.slice(1);
4
5
  }
5
6
 
6
- const getCoreUsecaseList = (name) => `import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput, ${capitalizeFirstLetter(name)}ListSchema } from '@/modules/${name}/types';
7
+ const getCoreUsecaseList = (name) => `import { z } from 'zod';
8
+
7
9
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
10
+ import { PaginationInput, PaginationOutput, PaginationSchema } from '@/utils/pagination';
11
+ import { SearchSchema } from '@/utils/search';
12
+ import { SortSchema } from '@/utils/sort';
8
13
 
9
14
  import { ${capitalizeFirstLetter(name)}Entity } from '../entity/${name}';
10
15
  import { I${capitalizeFirstLetter(name)}Repository } from '../repository/${name}';
11
16
 
17
+ export const ${capitalizeFirstLetter(name)}ListSchema = z.intersection(PaginationSchema, SortSchema.merge(SearchSchema));
18
+
19
+ export type ${capitalizeFirstLetter(name)}ListInput = PaginationInput<${capitalizeFirstLetter(name)}Entity>;
20
+ export type ${capitalizeFirstLetter(name)}ListOutput = Promise<PaginationOutput<${capitalizeFirstLetter(name)}Entity>>;
21
+
12
22
  export class ${capitalizeFirstLetter(name)}ListUsecase {
13
23
  constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository) {}
14
24
 
15
25
  @ValidateSchema(${capitalizeFirstLetter(name)}ListSchema)
16
26
  async execute(input: ${capitalizeFirstLetter(name)}ListInput): Promise<${capitalizeFirstLetter(name)}ListOutput> {
17
- const ${name}s = await this.${name}Repository.paginate(input);
27
+ const ${pluralize(name)} = await this.${name}Repository.paginate(input);
18
28
 
19
- return { docs: ${name}s.docs.map((u) => new ${capitalizeFirstLetter(name)}Entity(u)), limit: ${name}s.limit, page: ${name}s.page, total: ${name}s.total };
29
+ return {
30
+ docs: ${pluralize(name)}.docs.map((u) => new ${capitalizeFirstLetter(name)}Entity(u)),
31
+ limit: ${pluralize(name)}.limit,
32
+ page: ${pluralize(name)}.page,
33
+ total: ${pluralize(name)}.total
34
+ };
20
35
  }
21
36
  }
22
37
  `
@@ -3,14 +3,22 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getCoreUsecaseUpdate = (name) => `import { ILoggerAdapter } from '@/infra/logger';
7
- import { ${capitalizeFirstLetter(name)}UpdateInput, ${capitalizeFirstLetter(name)}UpdateOutput, ${capitalizeFirstLetter(name)}UpdateSchema } from '@/modules/${name}/types';
6
+ const getCoreUsecaseUpdate = (name) => `import { z } from 'zod';
7
+
8
+ import { ILoggerAdapter } from '@/infra/logger';
8
9
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
9
10
  import { ApiNotFoundException } from '@/utils/exception';
10
11
 
11
- import { ${capitalizeFirstLetter(name)}Entity } from '../entity/${name}';
12
+ import { ${capitalizeFirstLetter(name)}Entity, ${capitalizeFirstLetter(name)}EntitySchema } from '../entity/${name}';
12
13
  import { I${capitalizeFirstLetter(name)}Repository } from '../repository/${name}';
13
14
 
15
+ export const ${capitalizeFirstLetter(name)}UpdateSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
16
+ id: true
17
+ }).merge(${capitalizeFirstLetter(name)}EntitySchema.omit({ id: true }).partial());
18
+
19
+ export type ${capitalizeFirstLetter(name)}UpdateInput = Partial<z.infer<typeof ${capitalizeFirstLetter(name)}UpdateSchema>>;
20
+ export type ${capitalizeFirstLetter(name)}UpdateOutput = Promise<${capitalizeFirstLetter(name)}Entity>;
21
+
14
22
  export class ${capitalizeFirstLetter(name)}UpdateUsecase {
15
23
  constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository, private readonly loggerServide: ILoggerAdapter) {}
16
24
 
@@ -3,18 +3,11 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getModuleAdapter = (name) => `import {
7
- ${capitalizeFirstLetter(name)}CreateInput,
8
- ${capitalizeFirstLetter(name)}CreateOutput,
9
- ${capitalizeFirstLetter(name)}DeleteInput,
10
- ${capitalizeFirstLetter(name)}DeleteOutput,
11
- ${capitalizeFirstLetter(name)}GetByIDInput,
12
- ${capitalizeFirstLetter(name)}GetByIDOutput,
13
- ${capitalizeFirstLetter(name)}ListInput,
14
- ${capitalizeFirstLetter(name)}ListOutput,
15
- ${capitalizeFirstLetter(name)}UpdateInput,
16
- ${capitalizeFirstLetter(name)}UpdateOutput
17
- } from './types';
6
+ const getModuleAdapter = (name) => `import { ${capitalizeFirstLetter(name)}CreateInput, ${capitalizeFirstLetter(name)}CreateOutput } from '@/core/${name}/use-cases/${name}-create';
7
+ import { ${capitalizeFirstLetter(name)}DeleteInput, ${capitalizeFirstLetter(name)}DeleteOutput } from '@/core/${name}/use-cases/${name}-delete';
8
+ import { ${capitalizeFirstLetter(name)}GetByIDInput, ${capitalizeFirstLetter(name)}GetByIDOutput } from '@/core/${name}/use-cases/${name}-getByID';
9
+ import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '@/core/${name}/use-cases/${name}-list';
10
+ import { ${capitalizeFirstLetter(name)}UpdateInput, ${capitalizeFirstLetter(name)}UpdateOutput } from '@/core/${name}/use-cases/${name}-update';
18
11
 
19
12
  export abstract class I${capitalizeFirstLetter(name)}CreateAdapter {
20
13
  abstract execute(input: ${capitalizeFirstLetter(name)}CreateInput): Promise<${capitalizeFirstLetter(name)}CreateOutput>;
@@ -4,11 +4,17 @@ function capitalizeFirstLetter(string) {
4
4
  return string.charAt(0).toUpperCase() + string.slice(1);
5
5
  }
6
6
 
7
- const getModuleController = (name) => `import { Body, Controller, Delete, Get, Param, Post, Put, Query } from '@nestjs/common';
7
+ const getModuleController = (name) => `import { Controller, Delete, Get, Post, Put, Req } from '@nestjs/common';
8
8
  import { ApiBearerAuth, ApiBody, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
9
9
 
10
+ import { ${capitalizeFirstLetter(name)}CreateInput, ${capitalizeFirstLetter(name)}CreateOutput } from '@/core/${name}/use-cases/${name}-create';
11
+ import { ${capitalizeFirstLetter(name)}DeleteInput, ${capitalizeFirstLetter(name)}DeleteOutput } from '@/core/${name}/use-cases/${name}-delete';
12
+ import { ${capitalizeFirstLetter(name)}GetByIDInput, ${capitalizeFirstLetter(name)}GetByIDOutput } from '@/core/${name}/use-cases/${name}-getByID';
13
+ import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '@/core/${name}/use-cases/${name}-list';
14
+ import { ${capitalizeFirstLetter(name)}UpdateInput, ${capitalizeFirstLetter(name)}UpdateOutput } from '@/core/${name}/use-cases/${name}-update';
10
15
  import { UserRole } from '@/core/user/entity/user';
11
16
  import { Roles } from '@/utils/decorators/role.decorator';
17
+ import { ApiRequest } from '@/utils/request';
12
18
  import { SearchHttpSchema } from '@/utils/search';
13
19
  import { SortHttpSchema } from '@/utils/sort';
14
20
 
@@ -20,18 +26,6 @@ import {
20
26
  I${capitalizeFirstLetter(name)}UpdateAdapter
21
27
  } from './adapter';
22
28
  import { SwagggerRequest, SwagggerResponse } from './swagger';
23
- import {
24
- ${capitalizeFirstLetter(name)}CreateInput,
25
- ${capitalizeFirstLetter(name)}CreateOutput,
26
- ${capitalizeFirstLetter(name)}DeleteInput,
27
- ${capitalizeFirstLetter(name)}DeleteOutput,
28
- ${capitalizeFirstLetter(name)}GetByIDInput,
29
- ${capitalizeFirstLetter(name)}GetByIDOutput,
30
- ${capitalizeFirstLetter(name)}ListInput,
31
- ${capitalizeFirstLetter(name)}ListOutput,
32
- ${capitalizeFirstLetter(name)}UpdateInput,
33
- ${capitalizeFirstLetter(name)}UpdateOutput
34
- } from './types';
35
29
 
36
30
  @Controller()
37
31
  @ApiTags('${name}')
@@ -49,16 +43,16 @@ export class ${capitalizeFirstLetter(name)}Controller {
49
43
  @Post('/${pluralize(name)}')
50
44
  @ApiResponse(SwagggerResponse.create[200])
51
45
  @ApiBody(SwagggerRequest.createBody)
52
- async create(@Body() input: ${capitalizeFirstLetter(name)}CreateInput): ${capitalizeFirstLetter(name)}CreateOutput {
53
- return this.${name}CreateUsecase.execute(input);
46
+ async create(@Req() { body }: ApiRequest): ${capitalizeFirstLetter(name)}CreateOutput {
47
+ return this.${name}CreateUsecase.execute(body as ${capitalizeFirstLetter(name)}CreateInput);
54
48
  }
55
49
 
56
50
  @Put('/${pluralize(name)}')
57
51
  @ApiResponse(SwagggerResponse.update[200])
58
52
  @ApiResponse(SwagggerResponse.update[404])
59
53
  @ApiBody(SwagggerRequest.updateBody)
60
- async update(@Body() input: ${capitalizeFirstLetter(name)}UpdateInput): ${capitalizeFirstLetter(name)}UpdateOutput {
61
- return this.${name}UpdateUsecase.execute(input);
54
+ async update(@Req() { body }: ApiRequest): ${capitalizeFirstLetter(name)}UpdateOutput {
55
+ return this.${name}UpdateUsecase.execute(body as ${capitalizeFirstLetter(name)}UpdateInput);
62
56
  }
63
57
 
64
58
  @Get('/${pluralize(name)}')
@@ -67,9 +61,14 @@ export class ${capitalizeFirstLetter(name)}Controller {
67
61
  @ApiQuery(SwagggerRequest.listQuery.sort)
68
62
  @ApiQuery(SwagggerRequest.listQuery.search)
69
63
  @ApiResponse(SwagggerResponse.list[200])
70
- async list(@Query() input: ${capitalizeFirstLetter(name)}ListInput): ${capitalizeFirstLetter(name)}ListOutput {
71
- input.sort = SortHttpSchema.parse(input.sort);
72
- input.search = SearchHttpSchema.parse(input.search);
64
+ async list(@Req() { query }: ApiRequest): ${capitalizeFirstLetter(name)}ListOutput {
65
+ const input: ${capitalizeFirstLetter(name)}ListInput = {
66
+ sort: SortHttpSchema.parse(query.sort),
67
+ search: SearchHttpSchema.parse(query.search),
68
+ limit: Number(query.limit),
69
+ page: Number(query.page)
70
+ };
71
+
73
72
  return await this.${name}ListUsecase.execute(input);
74
73
  }
75
74
 
@@ -77,16 +76,16 @@ export class ${capitalizeFirstLetter(name)}Controller {
77
76
  @ApiParam({ name: 'id', required: true })
78
77
  @ApiResponse(SwagggerResponse.getByID[200])
79
78
  @ApiResponse(SwagggerResponse.getByID[404])
80
- async getById(@Param() input: ${capitalizeFirstLetter(name)}GetByIDInput): ${capitalizeFirstLetter(name)}GetByIDOutput {
81
- return await this.${name}GetByIDUsecase.execute(input);
79
+ async getById(@Req() { params }: ApiRequest): ${capitalizeFirstLetter(name)}GetByIDOutput {
80
+ return await this.${name}GetByIDUsecase.execute(params as ${capitalizeFirstLetter(name)}GetByIDInput);
82
81
  }
83
82
 
84
- @Delete('/${name}/:id')
83
+ @Delete('/${pluralize(name)}/:id')
85
84
  @ApiParam({ name: 'id', required: true })
86
85
  @ApiResponse(SwagggerResponse.delete[200])
87
86
  @ApiResponse(SwagggerResponse.delete[404])
88
- async delete(@Param() input: ${capitalizeFirstLetter(name)}DeleteInput): ${capitalizeFirstLetter(name)}DeleteOutput {
89
- return await this.${name}DeleteUsecase.execute(input);
87
+ async delete(@Req() { params }: ApiRequest): ${capitalizeFirstLetter(name)}DeleteOutput {
88
+ return await this.${name}DeleteUsecase.execute(params as ${capitalizeFirstLetter(name)}DeleteInput);
90
89
  }
91
90
  }
92
91
  `
@@ -5,7 +5,7 @@ function capitalizeFirstLetter(string) {
5
5
 
6
6
  const getModule = (name) => `import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
7
7
  import { getConnectionToken } from '@nestjs/mongoose';
8
- import mongoose, { Connection } from 'mongoose';
8
+ import mongoose, { Connection, PaginateModel } from 'mongoose';
9
9
 
10
10
  import { I${capitalizeFirstLetter(name)}Repository } from '@/core/${name}/repository/${name}';
11
11
  import { ${capitalizeFirstLetter(name)}CreateUsecase } from '@/core/${name}/use-cases/${name}-create';
@@ -15,9 +15,11 @@ import { ${capitalizeFirstLetter(name)}ListUsecase } from '@/core/${name}/use-ca
15
15
  import { ${capitalizeFirstLetter(name)}UpdateUsecase } from '@/core/${name}/use-cases/${name}-update';
16
16
  import { RedisCacheModule } from '@/infra/cache/redis';
17
17
  import { ConnectionName } from '@/infra/database/enum';
18
+ import { ${capitalizeFirstLetter(name)}, ${capitalizeFirstLetter(name)}Document, ${capitalizeFirstLetter(name)}Schema } from '@/infra/database/mongo/schemas/${name}';
18
19
  import { ILoggerAdapter, LoggerModule } from '@/infra/logger';
19
20
  import { SecretsModule } from '@/infra/secrets';
20
21
  import { TokenModule } from '@/libs/auth';
22
+ import { MongoRepositoryModelSessionType } from '@/utils/database/mongoose';
21
23
  import { IsLoggedMiddleware } from '@/utils/middlewares/is-logged.middleware';
22
24
 
23
25
  import {
@@ -29,7 +31,6 @@ import {
29
31
  } from './adapter';
30
32
  import { ${capitalizeFirstLetter(name)}Controller } from './controller';
31
33
  import { ${capitalizeFirstLetter(name)}Repository } from './repository';
32
- import { ${capitalizeFirstLetter(name)}, ${capitalizeFirstLetter(name)}Document, ${capitalizeFirstLetter(name)}Schema } from './schema';
33
34
 
34
35
  @Module({
35
36
  imports: [TokenModule, SecretsModule, LoggerModule, RedisCacheModule],
@@ -37,17 +38,28 @@ import { ${capitalizeFirstLetter(name)}, ${capitalizeFirstLetter(name)}Document,
37
38
  providers: [
38
39
  {
39
40
  provide: I${capitalizeFirstLetter(name)}Repository,
40
- useFactory: (connection: Connection) => {
41
- return new ${capitalizeFirstLetter(name)}Repository(
42
- connection.model<${capitalizeFirstLetter(name)}Document, mongoose.PaginateModel<${capitalizeFirstLetter(name)}Document>>(${capitalizeFirstLetter(name)}.name, ${capitalizeFirstLetter(name)}Schema)
43
- );
41
+ useFactory: async (connection: Connection) => {
42
+ type Model = mongoose.PaginateModel<${capitalizeFirstLetter(name)}Document>;
43
+
44
+ // use if you want transaction
45
+ const repository: MongoRepositoryModelSessionType<PaginateModel<${capitalizeFirstLetter(name)}Document>> = connection.model<
46
+ ${capitalizeFirstLetter(name)}Document,
47
+ Model
48
+ >(${capitalizeFirstLetter(name)}.name, ${capitalizeFirstLetter(name)}Schema);
49
+
50
+ repository.connection = connection;
51
+
52
+ // use if you not want transaction
53
+ // const repository: PaginateModel<${capitalizeFirstLetter(name)}Document> = connection.model<${capitalizeFirstLetter(name)}Document, Model>(${capitalizeFirstLetter(name)}.name, ${capitalizeFirstLetter(name)}Schema);
54
+
55
+ return new ${capitalizeFirstLetter(name)}Repository(repository);
44
56
  },
45
57
  inject: [getConnectionToken(ConnectionName.USER)]
46
58
  },
47
59
  {
48
60
  provide: I${capitalizeFirstLetter(name)}CreateAdapter,
49
- useFactory: (${name}Repository: I${capitalizeFirstLetter(name)}Repository) => {
50
- return new ${capitalizeFirstLetter(name)}CreateUsecase(${name}Repository);
61
+ useFactory: (${name}Repository: I${capitalizeFirstLetter(name)}Repository, loggerService: ILoggerAdapter) => {
62
+ return new ${capitalizeFirstLetter(name)}CreateUsecase(${name}Repository, loggerService);
51
63
  },
52
64
  inject: [I${capitalizeFirstLetter(name)}Repository, ILoggerAdapter]
53
65
  },
@@ -1,3 +1,4 @@
1
+ const pluralize = require('pluralize')
1
2
 
2
3
  function capitalizeFirstLetter(string) {
3
4
  return string.charAt(0).toUpperCase() + string.slice(1);
@@ -8,26 +9,35 @@ import { InjectModel } from '@nestjs/mongoose';
8
9
  import { PaginateModel } from 'mongoose';
9
10
 
10
11
  import { I${capitalizeFirstLetter(name)}Repository } from '@/core/${name}/repository/${name}';
12
+ import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '@/core/${name}/use-cases/${name}-list';
13
+ import { ${capitalizeFirstLetter(name)}, ${capitalizeFirstLetter(name)}Document } from '@/infra/database/mongo/schemas/${name}';
11
14
  import { MongoRepository } from '@/infra/repository';
12
- import { ValidateMongooseFilter } from '@/utils/decorators/database/mongo/validate-mongoose-filter.decorator';
15
+ import { MongoRepositoryModelSessionType, MongoRepositorySession } from '@/utils/database/mongoose';
16
+ import {
17
+ SearchTypeEnum,
18
+ ValidateMongooseFilter
19
+ } from '@/utils/decorators/database/mongo/validate-mongoose-filter.decorator';
13
20
  import { ValidateDatabaseSortAllowed } from '@/utils/decorators/database/validate-database-sort-allowed.decorator';
14
- import { SearchTypeEnum } from '@/utils/decorators/types';
15
-
16
- import { ${capitalizeFirstLetter(name)}, ${capitalizeFirstLetter(name)}Document } from './schema';
17
- import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from './types';
18
21
 
19
22
  @Injectable()
20
23
  export class ${capitalizeFirstLetter(name)}Repository extends MongoRepository<${capitalizeFirstLetter(name)}Document> implements I${capitalizeFirstLetter(name)}Repository {
21
- constructor(@InjectModel(${capitalizeFirstLetter(name)}.name) readonly entity: PaginateModel<${capitalizeFirstLetter(name)}Document>) {
24
+ constructor(@InjectModel(${capitalizeFirstLetter(name)}.name) readonly entity: MongoRepositoryModelSessionType<PaginateModel<${capitalizeFirstLetter(name)}Document>>) {
22
25
  super(entity);
23
26
  }
24
27
 
28
+ async startSession<TTransaction = MongoRepositorySession>(): Promise<TTransaction> {
29
+ const session = await this.entity.connection.startSession();
30
+ session.startTransaction();
31
+
32
+ return session as TTransaction;
33
+ }
34
+
25
35
  @ValidateMongooseFilter([{ name: 'name', type: SearchTypeEnum.like }])
26
36
  @ValidateDatabaseSortAllowed(['name', 'createdAt'])
27
37
  async paginate({ limit, page, sort, search }: ${capitalizeFirstLetter(name)}ListInput): Promise<${capitalizeFirstLetter(name)}ListOutput> {
28
- const ${name}s = await this.entity.paginate(search, { page, limit, sort });
38
+ const ${pluralize(name)} = await this.entity.paginate(search, { page, limit, sort });
29
39
 
30
- return { docs: ${name}s.docs.map((u) => u.toObject({ virtuals: true })), limit, page, total: ${name}s.totalDocs };
40
+ return { docs: ${pluralize(name)}.docs.map((u) => u.toObject({ virtuals: true })), limit, page, total: ${name}s.totalDocs };
31
41
  }
32
42
  }
33
43
  `
@@ -1,12 +1,13 @@
1
- const getModuleSwagger = (name) => `import { CreatedModel } from '@/infra/repository';
1
+ const pluralize = require('pluralize')
2
+
3
+ const getModuleSwagger = (name) => `import { CreatedModel } from '@/infra/repository/types';
2
4
  import { Swagger } from '@/utils/swagger';
3
5
 
4
6
  const entity = {
5
- id: '<id>',
6
7
  name: '<name>'
7
8
  };
8
9
 
9
- const entityFull = { ...entity, deletedAt: '<deletedAt>', createdAt: '<createdAt>', updatedAt: '<updatedAt>' };
10
+ const entityFull = { ...entity, updatedAt: '<updatedAt>', createdAt: '<createdAt>', deletedAt: '<deletedAt>' };
10
11
 
11
12
  export const SwagggerResponse = {
12
13
  create: {
@@ -24,7 +25,7 @@ export const SwagggerResponse = {
24
25
  }),
25
26
  404: Swagger.defaultResponseError({
26
27
  status: 404,
27
- route: 'api/${name}s',
28
+ route: 'api/${pluralize(name)}',
28
29
  message: '${name}NotFound',
29
30
  description: '${name} not found.'
30
31
  })
@@ -37,7 +38,7 @@ export const SwagggerResponse = {
37
38
  }),
38
39
  404: Swagger.defaultResponseError({
39
40
  status: 404,
40
- route: 'api/${name}s/:id',
41
+ route: 'api/${pluralize(name)}/:id',
41
42
  message: '${name}NotFound',
42
43
  description: '${name} not found.'
43
44
  })
@@ -50,7 +51,7 @@ export const SwagggerResponse = {
50
51
  }),
51
52
  404: Swagger.defaultResponseError({
52
53
  status: 404,
53
- route: 'api/${name}s/:id',
54
+ route: 'api/${pluralize(name)}s/:id',
54
55
  message: '${name}NotFound',
55
56
  description: '${name} not found.'
56
57
  })
@@ -80,7 +81,7 @@ export const SwagggerRequest = {
80
81
  search: Swagger.defaultApiQueryOptions({
81
82
  name: 'search',
82
83
  required: false,
83
- description: '<b>name:name'
84
+ description: '<b>name:miau'
84
85
  })
85
86
  }
86
87
  };
@@ -3,14 +3,17 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getCoreRepository = (name) => `import { IRepository } from '@/infra/repository';
7
- import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '@/modules/${name}/types';
6
+ const getCoreRepository = (name) => `import { Transaction } from 'sequelize';
7
+
8
+ import { IRepository } from '@/infra/repository';
8
9
  import { DatabaseOptionsType } from '@/utils/database/sequelize';
9
10
 
10
11
  import { ${capitalizeFirstLetter(name)}Entity } from '../entity/${name}';
12
+ import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '../use-cases/${name}-list';
11
13
 
12
14
  export abstract class I${capitalizeFirstLetter(name)}Repository extends IRepository<${capitalizeFirstLetter(name)}Entity> {
13
15
  abstract paginate<TOptions = DatabaseOptionsType>(input: ${capitalizeFirstLetter(name)}ListInput, options?: TOptions): Promise<${capitalizeFirstLetter(name)}ListOutput>;
16
+ abstract startSession<TTransaction = Transaction>(): Promise<TTransaction>;
14
17
  }
15
18
  `
16
19
 
@@ -3,22 +3,43 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getCoreUsecaseCreate = (name) => `import { ${capitalizeFirstLetter(name)}CreateInput, ${capitalizeFirstLetter(name)}CreateOutput, ${capitalizeFirstLetter(name)}CreateSchema } from '@/modules/${name}/types';
6
+ const getCoreUsecaseCreate = (name) => `import { z } from 'zod';
7
+
8
+ import { ILoggerAdapter } from '@/infra/logger';
9
+ import { CreatedModel } from '@/infra/repository';
10
+ import { DatabaseOptionsType } from '@/utils/database/sequelize';
7
11
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
8
12
 
9
13
  import { I${capitalizeFirstLetter(name)}Repository } from '../repository/${name}';
10
- import { ${capitalizeFirstLetter(name)}Entity } from './../entity/${name}';
14
+ import { ${capitalizeFirstLetter(name)}Entity, ${capitalizeFirstLetter(name)}EntitySchema } from './../entity/${name}';
15
+
16
+ export const ${capitalizeFirstLetter(name)}CreateSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
17
+ name: true
18
+ });
19
+
20
+ export type ${capitalizeFirstLetter(name)}CreateInput = z.infer<typeof ${capitalizeFirstLetter(name)}CreateSchema>;
21
+ export type ${capitalizeFirstLetter(name)}CreateOutput = Promise<CreatedModel>;
11
22
 
12
23
  export class ${capitalizeFirstLetter(name)}CreateUsecase {
13
- constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository) {}
24
+ constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository, private readonly loggerServide: ILoggerAdapter) {}
14
25
 
15
26
  @ValidateSchema(${capitalizeFirstLetter(name)}CreateSchema)
16
27
  async execute(input: ${capitalizeFirstLetter(name)}CreateInput): Promise<${capitalizeFirstLetter(name)}CreateOutput> {
17
28
  const entity = new ${capitalizeFirstLetter(name)}Entity(input);
18
29
 
19
- const created = await this.${name}Repository.create(entity);
30
+ const transaction = await this.${name}Repository.startSession();
31
+ try {
32
+ const ${name} = await this.${name}Repository.create<DatabaseOptionsType>(entity, { transaction });
33
+
34
+ await transaction.commit();
35
+
36
+ this.loggerServide.info({ message: '${name} created.', obj: { ${name} } });
20
37
 
21
- return created;
38
+ return ${name};
39
+ } catch (error) {
40
+ await transaction.rollback();
41
+ throw error;
42
+ }
22
43
  }
23
44
  }
24
45
  `
@@ -3,19 +3,28 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getCoreUsecaseDelete = (name) => `import { I${capitalizeFirstLetter(name)}Repository } from '@/core/${name}/repository/${name}';
7
- import { ${capitalizeFirstLetter(name)}DeleteInput, ${capitalizeFirstLetter(name)}DeleteOutput, ${capitalizeFirstLetter(name)}DeleteSchema } from '@/modules/${name}/types';
6
+ const getCoreUsecaseDelete = (name) => `import { z } from 'zod';
7
+
8
+ import { I${capitalizeFirstLetter(name)}Repository } from '@/core/${name}/repository/${name}';
9
+ import { DatabaseOptionsType } from '@/utils/database/sequelize';
8
10
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
9
11
  import { ApiNotFoundException } from '@/utils/exception';
10
12
 
11
- import { ${capitalizeFirstLetter(name)}Entity } from '../entity/${name}';
13
+ import { ${capitalizeFirstLetter(name)}Entity, ${capitalizeFirstLetter(name)}EntitySchema } from '../entity/${name}';
14
+
15
+ export const ${capitalizeFirstLetter(name)}DeleteSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
16
+ id: true
17
+ });
18
+
19
+ export type ${capitalizeFirstLetter(name)}DeleteInput = z.infer<typeof ${capitalizeFirstLetter(name)}DeleteSchema>;
20
+ export type ${capitalizeFirstLetter(name)}DeleteOutput = Promise<${capitalizeFirstLetter(name)}Entity>;
12
21
 
13
22
  export class ${capitalizeFirstLetter(name)}DeleteUsecase {
14
23
  constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository) {}
15
24
 
16
25
  @ValidateSchema(${capitalizeFirstLetter(name)}DeleteSchema)
17
26
  async execute({ id }: ${capitalizeFirstLetter(name)}DeleteInput): Promise<${capitalizeFirstLetter(name)}DeleteOutput> {
18
- const model = await this.${name}Repository.findById(id);
27
+ const model = await this.${name}Repository.findById<DatabaseOptionsType>(id);
19
28
 
20
29
  if (!model) {
21
30
  throw new ApiNotFoundException('${name}NotFound');
@@ -3,20 +3,29 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getCoreUsecaseGetByID = (name) => `import { ${capitalizeFirstLetter(name)}GetByIDInput, ${capitalizeFirstLetter(name)}GetByIDOutput } from '@/modules/${name}/types';
7
- import { ${capitalizeFirstLetter(name)}GetByIdSchema } from '@/modules/${name}/types';
6
+ const getCoreUsecaseGetByID = (name) => `import { z } from 'zod';
7
+
8
+ import { ${capitalizeFirstLetter(name)}EntitySchema } from '@/core/${name}/entity/${name}';
9
+ import { DatabaseOptionsType } from '@/utils/database/sequelize';
8
10
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
9
11
  import { ApiNotFoundException } from '@/utils/exception';
10
12
 
11
13
  import { ${capitalizeFirstLetter(name)}Entity } from '../entity/${name}';
12
14
  import { I${capitalizeFirstLetter(name)}Repository } from '../repository/${name}';
13
15
 
16
+ export const ${capitalizeFirstLetter(name)}GetByIdSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
17
+ id: true
18
+ });
19
+
20
+ export type ${capitalizeFirstLetter(name)}GetByIDInput = z.infer<typeof ${capitalizeFirstLetter(name)}GetByIdSchema>;
21
+ export type ${capitalizeFirstLetter(name)}GetByIDOutput = Promise<${capitalizeFirstLetter(name)}Entity>;
22
+
14
23
  export class ${capitalizeFirstLetter(name)}GetByIdUsecase {
15
24
  constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository) {}
16
25
 
17
26
  @ValidateSchema(${capitalizeFirstLetter(name)}GetByIdSchema)
18
27
  async execute({ id }: ${capitalizeFirstLetter(name)}GetByIDInput): Promise<${capitalizeFirstLetter(name)}GetByIDOutput> {
19
- const ${name} = await this.${name}Repository.findById(id);
28
+ const ${name} = await this.${name}Repository.findById<DatabaseOptionsType>(id);
20
29
 
21
30
  if (!${name}) {
22
31
  throw new ApiNotFoundException('${name}NotFound');
@@ -3,11 +3,21 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getCoreUsecaseList = (name) => `import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput, ${capitalizeFirstLetter(name)}ListSchema } from '@/modules/${name}/types';
6
+ const getCoreUsecaseList = (name) => `import { z } from 'zod';
7
+
8
+ import { ${capitalizeFirstLetter(name)}Entity } from '@/core/${name}/entity/${name}';
7
9
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
10
+ import { PaginationInput, PaginationOutput, PaginationSchema } from '@/utils/pagination';
11
+ import { SearchSchema } from '@/utils/search';
12
+ import { SortSchema } from '@/utils/sort';
8
13
 
9
14
  import { I${capitalizeFirstLetter(name)}Repository } from '../repository/${name}';
10
15
 
16
+ export const ${capitalizeFirstLetter(name)}ListSchema = z.intersection(PaginationSchema, SortSchema.merge(SearchSchema));
17
+
18
+ export type ${capitalizeFirstLetter(name)}ListInput = PaginationInput<${capitalizeFirstLetter(name)}Entity>;
19
+ export type ${capitalizeFirstLetter(name)}ListOutput = Promise<PaginationOutput<${capitalizeFirstLetter(name)}Entity>>;
20
+
11
21
  export class ${capitalizeFirstLetter(name)}ListUsecase {
12
22
  constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository) {}
13
23
 
@@ -3,19 +3,29 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getCoreUsecaseUpdate = (name) => `import { I${capitalizeFirstLetter(name)}Repository } from '@/core/${name}/repository/${name}';
7
- import { ${capitalizeFirstLetter(name)}UpdateInput, ${capitalizeFirstLetter(name)}UpdateOutput, ${capitalizeFirstLetter(name)}UpdateSchema } from '@/modules/${name}/types';
6
+ const getCoreUsecaseUpdate = (name) => `import { z } from 'zod';
7
+
8
+ import { I${capitalizeFirstLetter(name)}Repository } from '@/core/${name}/repository/${name}';
9
+ import { ILoggerAdapter } from '@/infra/logger';
10
+ import { DatabaseOptionsType } from '@/utils/database/sequelize';
8
11
  import { ValidateSchema } from '@/utils/decorators/validate-schema.decorator';
9
12
  import { ApiNotFoundException } from '@/utils/exception';
10
13
 
11
- import { ${capitalizeFirstLetter(name)}Entity } from './../entity/${name}';
14
+ import { ${capitalizeFirstLetter(name)}Entity, ${capitalizeFirstLetter(name)}EntitySchema } from './../entity/${name}';
15
+
16
+ export const ${capitalizeFirstLetter(name)}UpdateSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
17
+ id: true
18
+ }).merge(${capitalizeFirstLetter(name)}EntitySchema.omit({ id: true }).partial());
19
+
20
+ export type ${capitalizeFirstLetter(name)}UpdateInput = z.infer<typeof ${capitalizeFirstLetter(name)}UpdateSchema>;
21
+ export type ${capitalizeFirstLetter(name)}UpdateOutput = Promise<${capitalizeFirstLetter(name)}Entity>;
12
22
 
13
23
  export class ${capitalizeFirstLetter(name)}UpdateUsecase {
14
- constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository) {}
24
+ constructor(private readonly ${name}Repository: I${capitalizeFirstLetter(name)}Repository, private readonly loggerServide: ILoggerAdapter) {}
15
25
 
16
26
  @ValidateSchema(${capitalizeFirstLetter(name)}UpdateSchema)
17
27
  async execute(input: ${capitalizeFirstLetter(name)}UpdateInput): Promise<${capitalizeFirstLetter(name)}UpdateOutput> {
18
- const ${name} = await this.${name}Repository.findById(input.id);
28
+ const ${name} = await this.${name}Repository.findById<DatabaseOptionsType>(input.id);
19
29
 
20
30
  if (!${name}) {
21
31
  throw new ApiNotFoundException('${name}NotFound');
@@ -27,7 +37,9 @@ export class ${capitalizeFirstLetter(name)}UpdateUsecase {
27
37
 
28
38
  await this.${name}Repository.updateOne({ id: entity.id }, entity);
29
39
 
30
- const updated = await this.${name}Repository.findById(entity.id);
40
+ this.loggerServide.info({ message: '${name} updated.', obj: { ${name}: input } });
41
+
42
+ const updated = await this.${name}Repository.findById<DatabaseOptionsType>(entity.id);
31
43
 
32
44
  return new ${capitalizeFirstLetter(name)}Entity(updated);
33
45
  }
@@ -3,18 +3,11 @@ function capitalizeFirstLetter(string) {
3
3
  return string.charAt(0).toUpperCase() + string.slice(1);
4
4
  }
5
5
 
6
- const getModuleAdapter = (name) => `import {
7
- ${capitalizeFirstLetter(name)}CreateInput,
8
- ${capitalizeFirstLetter(name)}CreateOutput,
9
- ${capitalizeFirstLetter(name)}DeleteInput,
10
- ${capitalizeFirstLetter(name)}DeleteOutput,
11
- ${capitalizeFirstLetter(name)}GetByIDInput,
12
- ${capitalizeFirstLetter(name)}GetByIDOutput,
13
- ${capitalizeFirstLetter(name)}ListInput,
14
- ${capitalizeFirstLetter(name)}ListOutput,
15
- ${capitalizeFirstLetter(name)}UpdateInput,
16
- ${capitalizeFirstLetter(name)}UpdateOutput
17
- } from './types';
6
+ const getModuleAdapter = (name) => `import { ${capitalizeFirstLetter(name)}CreateInput, ${capitalizeFirstLetter(name)}CreateOutput } from '@/core/${name}/use-cases/${name}-create';
7
+ import { ${capitalizeFirstLetter(name)}DeleteInput, ${capitalizeFirstLetter(name)}DeleteOutput } from '@/core/${name}/use-cases/${name}-delete';
8
+ import { ${capitalizeFirstLetter(name)}GetByIDInput, ${capitalizeFirstLetter(name)}GetByIDOutput } from '@/core/${name}/use-cases/${name}-getByID';
9
+ import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '@/core/${name}/use-cases/${name}-list';
10
+ import { ${capitalizeFirstLetter(name)}UpdateInput, ${capitalizeFirstLetter(name)}UpdateOutput } from '@/core/${name}/use-cases/${name}-update';
18
11
 
19
12
  export abstract class I${capitalizeFirstLetter(name)}CreateAdapter {
20
13
  abstract execute(input: ${capitalizeFirstLetter(name)}CreateInput): Promise<${capitalizeFirstLetter(name)}CreateOutput>;
@@ -4,11 +4,17 @@ function capitalizeFirstLetter(string) {
4
4
  return string.charAt(0).toUpperCase() + string.slice(1);
5
5
  }
6
6
 
7
- const getModuleController = (name) => `import { Body, Controller, Delete, Get, Param, Post, Put, Query } from '@nestjs/common';
7
+ const getModuleController = (name) => `import { Controller, Delete, Get, Post, Put, Req } from '@nestjs/common';
8
8
  import { ApiBearerAuth, ApiBody, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
9
9
 
10
+ import { ${capitalizeFirstLetter(name)}CreateInput, ${capitalizeFirstLetter(name)}CreateOutput } from '@/core/${name}/use-cases/${name}-create';
11
+ import { ${capitalizeFirstLetter(name)}DeleteInput, ${capitalizeFirstLetter(name)}DeleteOutput } from '@/core/${name}/use-cases/${name}-delete';
12
+ import { ${capitalizeFirstLetter(name)}GetByIDInput, ${capitalizeFirstLetter(name)}GetByIDOutput } from '@/core/${name}/use-cases/${name}-getByID';
13
+ import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '@/core/${name}/use-cases/${name}-list';
14
+ import { ${capitalizeFirstLetter(name)}UpdateInput, ${capitalizeFirstLetter(name)}UpdateOutput } from '@/core/${name}/use-cases/${name}-update';
10
15
  import { UserRole } from '@/core/user/entity/user';
11
16
  import { Roles } from '@/utils/decorators/role.decorator';
17
+ import { ApiRequest } from '@/utils/request';
12
18
  import { SearchHttpSchema } from '@/utils/search';
13
19
  import { SortHttpSchema } from '@/utils/sort';
14
20
 
@@ -20,23 +26,11 @@ import {
20
26
  I${capitalizeFirstLetter(name)}UpdateAdapter
21
27
  } from './adapter';
22
28
  import { SwagggerRequest, SwagggerResponse } from './swagger';
23
- import {
24
- ${capitalizeFirstLetter(name)}CreateInput,
25
- ${capitalizeFirstLetter(name)}CreateOutput,
26
- ${capitalizeFirstLetter(name)}DeleteInput,
27
- ${capitalizeFirstLetter(name)}DeleteOutput,
28
- ${capitalizeFirstLetter(name)}GetByIDInput,
29
- ${capitalizeFirstLetter(name)}GetByIDOutput,
30
- ${capitalizeFirstLetter(name)}ListInput,
31
- ${capitalizeFirstLetter(name)}ListOutput,
32
- ${capitalizeFirstLetter(name)}UpdateInput,
33
- ${capitalizeFirstLetter(name)}UpdateOutput
34
- } from './types';
35
29
 
36
30
  @Controller()
37
31
  @ApiTags('${name}')
38
32
  @ApiBearerAuth()
39
- @Roles(UserRole.BACKOFFICE)
33
+ @Roles(UserRole.USER)
40
34
  export class ${capitalizeFirstLetter(name)}Controller {
41
35
  constructor(
42
36
  private readonly ${name}Create: I${capitalizeFirstLetter(name)}CreateAdapter,
@@ -49,24 +43,24 @@ export class ${capitalizeFirstLetter(name)}Controller {
49
43
  @Post('/${pluralize(name)}')
50
44
  @ApiResponse(SwagggerResponse.create[200])
51
45
  @ApiBody(SwagggerRequest.createBody)
52
- async create(@Body() input: ${capitalizeFirstLetter(name)}CreateInput): ${capitalizeFirstLetter(name)}CreateOutput {
53
- return await this.${name}Create.execute(input);
46
+ async create(@Req() { body }: ApiRequest): ${capitalizeFirstLetter(name)}CreateOutput {
47
+ return await this.${name}Create.execute(body as ${capitalizeFirstLetter(name)}CreateInput);
54
48
  }
55
49
 
56
50
  @Put('/${pluralize(name)}')
57
51
  @ApiResponse(SwagggerResponse.update[200])
58
52
  @ApiResponse(SwagggerResponse.update[404])
59
53
  @ApiBody(SwagggerRequest.updateBody)
60
- async update(@Body() input: ${capitalizeFirstLetter(name)}UpdateInput): ${capitalizeFirstLetter(name)}UpdateOutput {
61
- return await this.${name}Update.execute(input);
54
+ async update(@Req() { body }: ApiRequest): ${capitalizeFirstLetter(name)}UpdateOutput {
55
+ return await this.${name}Update.execute(body as ${capitalizeFirstLetter(name)}UpdateInput);
62
56
  }
63
57
 
64
58
  @Get('/${pluralize(name)}/:id')
65
59
  @ApiParam({ name: 'id', required: true })
66
60
  @ApiResponse(SwagggerResponse.getByID[200])
67
61
  @ApiResponse(SwagggerResponse.getByID[404])
68
- async getById(@Param() input: ${capitalizeFirstLetter(name)}GetByIDInput): ${capitalizeFirstLetter(name)}GetByIDOutput {
69
- return await this.${name}GetByID.execute(input);
62
+ async getById(@Req() { params }: ApiRequest): ${capitalizeFirstLetter(name)}GetByIDOutput {
63
+ return await this.${name}GetByID.execute(params as ${capitalizeFirstLetter(name)}GetByIDInput);
70
64
  }
71
65
 
72
66
  @Get('/${pluralize(name)}')
@@ -75,9 +69,14 @@ export class ${capitalizeFirstLetter(name)}Controller {
75
69
  @ApiQuery(SwagggerRequest.listQuery.sort)
76
70
  @ApiQuery(SwagggerRequest.listQuery.search)
77
71
  @ApiResponse(SwagggerResponse.list[200])
78
- async list(@Query() input: ${capitalizeFirstLetter(name)}ListInput): ${capitalizeFirstLetter(name)}ListOutput {
79
- input.sort = SortHttpSchema.parse(input.sort);
80
- input.search = SearchHttpSchema.parse(input.search);
72
+ async list(@Req() { query }: ApiRequest): ${capitalizeFirstLetter(name)}ListOutput {
73
+ const input: ${capitalizeFirstLetter(name)}ListInput = {
74
+ sort: SortHttpSchema.parse(query.sort),
75
+ search: SearchHttpSchema.parse(query.search),
76
+ limit: Number(query.limit),
77
+ page: Number(query.page)
78
+ };
79
+
81
80
  return await this.${name}List.execute(input);
82
81
  }
83
82
 
@@ -85,8 +84,8 @@ export class ${capitalizeFirstLetter(name)}Controller {
85
84
  @ApiParam({ name: 'id', required: true })
86
85
  @ApiResponse(SwagggerResponse.delete[200])
87
86
  @ApiResponse(SwagggerResponse.delete[404])
88
- async delete(@Param() input: ${capitalizeFirstLetter(name)}DeleteInput): ${capitalizeFirstLetter(name)}DeleteOutput {
89
- return await this.${name}Delete.execute(input);
87
+ async delete(@Req() { params }: ApiRequest): ${capitalizeFirstLetter(name)}DeleteOutput {
88
+ return await this.${name}Delete.execute(params as ${capitalizeFirstLetter(name)}DeleteInput);
90
89
  }
91
90
  }
92
91
  `
@@ -38,19 +38,19 @@ import { ${capitalizeFirstLetter(name)}Repository } from './repository';
38
38
  {
39
39
  provide: I${capitalizeFirstLetter(name)}Repository,
40
40
  useFactory: (database: IDataBaseAdapter) => {
41
- const repository = database.getDatabase<Sequelize>().model(${capitalizeFirstLetter(name)}Schema);
42
- return new ${capitalizeFirstLetter(name)}Repository(repository as ModelCtor<${capitalizeFirstLetter(name)}Schema> & ${capitalizeFirstLetter(name)}Entity);
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);
43
43
  },
44
44
  inject: [IDataBaseAdapter]
45
45
  },
46
46
  {
47
47
  provide: I${capitalizeFirstLetter(name)}CreateAdapter,
48
- useFactory: (repository: I${capitalizeFirstLetter(name)}Repository) => new ${capitalizeFirstLetter(name)}CreateUsecase(repository),
49
- inject: [I${capitalizeFirstLetter(name)}Repository]
48
+ useFactory: (logger: ILoggerAdapter, repository: I${capitalizeFirstLetter(name)}Repository) => new ${capitalizeFirstLetter(name)}CreateUsecase(repository, logger),
49
+ inject: [ILoggerAdapter, I${capitalizeFirstLetter(name)}Repository]
50
50
  },
51
51
  {
52
52
  provide: I${capitalizeFirstLetter(name)}UpdateAdapter,
53
- useFactory: (repository: I${capitalizeFirstLetter(name)}Repository) => new ${capitalizeFirstLetter(name)}UpdateUsecase(repository),
53
+ useFactory: (logger: ILoggerAdapter, repository: I${capitalizeFirstLetter(name)}Repository) => new ${capitalizeFirstLetter(name)}UpdateUsecase(repository, logger),
54
54
  inject: [ILoggerAdapter, I${capitalizeFirstLetter(name)}Repository]
55
55
  },
56
56
  {
@@ -4,13 +4,14 @@ function capitalizeFirstLetter(string) {
4
4
  }
5
5
 
6
6
  const getModuleRepository = (name) => `import { Injectable } from '@nestjs/common';
7
+ import { Transaction } from 'sequelize';
7
8
  import { ModelCtor } from 'sequelize-typescript';
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}';
12
+ import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '@/core/${name}/use-cases/${name}-list';
11
13
  import { ${capitalizeFirstLetter(name)}Schema } from '@/infra/database/postgres/schemas/${name}';
12
14
  import { SequelizeRepository } from '@/infra/repository/postgres/repository';
13
- import { ${capitalizeFirstLetter(name)}ListInput, ${capitalizeFirstLetter(name)}ListOutput } from '@/modules/${name}/types';
14
15
  import { DatabaseOptionsSchema, DatabaseOptionsType } from '@/utils/database/sequelize';
15
16
  import { ConvertPaginateInputToSequelizeFilter } from '@/utils/decorators/database/postgres/convert-paginate-input-to-sequelize-filter.decorator';
16
17
  import { ValidateDatabaseSortAllowed } from '@/utils/decorators/database/validate-database-sort-allowed.decorator';
@@ -24,18 +25,20 @@ export class ${capitalizeFirstLetter(name)}Repository extends SequelizeRepositor
24
25
  super(repository);
25
26
  }
26
27
 
27
- @ValidateDatabaseSortAllowed(['createdAt', 'name', 'breed', 'age'])
28
- @ConvertPaginateInputToSequelizeFilter([
29
- { name: 'name', type: SearchTypeEnum.like },
30
- { name: 'breed', type: SearchTypeEnum.like },
31
- { name: 'age', type: SearchTypeEnum.equal }
32
- ])
28
+ async startSession<TTransaction = Transaction>(): Promise<TTransaction> {
29
+ const transaction = await this.repository.sequelize.transaction();
30
+
31
+ return transaction as TTransaction;
32
+ }
33
+
34
+ @ValidateDatabaseSortAllowed(['createdAt', 'name'])
35
+ @ConvertPaginateInputToSequelizeFilter([{ name: 'name', type: SearchTypeEnum.like }])
33
36
  async paginate(input: ${capitalizeFirstLetter(name)}ListInput, options: DatabaseOptionsType): Promise<${capitalizeFirstLetter(name)}ListOutput> {
34
37
  const { schema } = DatabaseOptionsSchema.parse(options);
35
38
 
36
39
  const list = await this.repository.schema(schema).findAndCountAll(input);
37
40
 
38
- return { docs: list.rows, limit: input.limit, page: input.page, total: list.count };
41
+ return { docs: list.rows.map((r) => new ${capitalizeFirstLetter(name)}Entity(r)), limit: input.limit, page: input.page, total: list.count };
39
42
  }
40
43
  }
41
44
  `
@@ -1,3 +1,5 @@
1
+ const pluralize = require('pluralize')
2
+
1
3
  const getModuleSwagger = (name) => `import { CreatedModel } from '@/infra/repository/types';
2
4
  import { Swagger } from '@/utils/swagger';
3
5
 
@@ -23,7 +25,7 @@ export const SwagggerResponse = {
23
25
  }),
24
26
  404: Swagger.defaultResponseError({
25
27
  status: 404,
26
- route: 'api/${name}',
28
+ route: 'api/${pluralize(name)}',
27
29
  message: '${name}NotFound',
28
30
  description: '${name} not found.'
29
31
  })
@@ -36,7 +38,7 @@ export const SwagggerResponse = {
36
38
  }),
37
39
  404: Swagger.defaultResponseError({
38
40
  status: 404,
39
- route: 'api/${name}/:id',
41
+ route: 'api/${pluralize(name)}/:id',
40
42
  message: '${name}NotFound',
41
43
  description: '${name} not found.'
42
44
  })
@@ -49,7 +51,7 @@ export const SwagggerResponse = {
49
51
  }),
50
52
  404: Swagger.defaultResponseError({
51
53
  status: 404,
52
- route: 'api/${name}/:id',
54
+ route: 'api/${pluralize(name)}s/:id',
53
55
  message: '${name}NotFound',
54
56
  description: '${name} not found.'
55
57
  })
@@ -79,7 +81,7 @@ export const SwagggerRequest = {
79
81
  search: Swagger.defaultApiQueryOptions({
80
82
  name: 'search',
81
83
  required: false,
82
- description: '<b>name:miau,breed:siamese'
84
+ description: '<b>name:miau'
83
85
  })
84
86
  }
85
87
  };
@@ -1,35 +0,0 @@
1
- import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
2
- import { Document } from 'mongoose';
3
- import * as paginate from 'mongoose-paginate-v2';
4
-
5
- import { BirdEntity } from '@/core/bird/entity/bird';
6
-
7
- export type BirdDocument = Document & BirdEntity;
8
-
9
- @Schema({
10
- collection: 'birds',
11
- autoIndex: true,
12
- timestamps: true
13
- })
14
- export class Bird {
15
- @Prop({ type: String })
16
- _id: string;
17
-
18
- @Prop({ index: true, min: 1, max: 200, required: true, type: String })
19
- name: string;
20
-
21
- @Prop({ type: Date, default: null })
22
- deletedAt: Date;
23
- }
24
-
25
- const BirdSchema = SchemaFactory.createForClass(Bird);
26
-
27
- BirdSchema.index({ name: 1 });
28
-
29
- BirdSchema.plugin(paginate);
30
-
31
- BirdSchema.virtual('id').get(function () {
32
- return this._id;
33
- });
34
-
35
- export { BirdSchema };
@@ -1,13 +0,0 @@
1
- import { Column, DataType, Model, Table } from 'sequelize-typescript';
2
-
3
- @Table({ timestamps: true, tableName: 'dogs' })
4
- export class DogSchema extends Model {
5
- @Column({ primaryKey: true, type: DataType.UUID })
6
- id: string;
7
-
8
- @Column(DataType.STRING)
9
- name: string;
10
-
11
- @Column({ allowNull: true, type: DataType.DATE })
12
- deletedAt?: Date;
13
- }
@@ -1,49 +0,0 @@
1
-
2
- function capitalizeFirstLetter(string) {
3
- return string.charAt(0).toUpperCase() + string.slice(1);
4
- }
5
-
6
- const getModuleType = (name) => `import { z } from 'zod';
7
-
8
- import { ${capitalizeFirstLetter(name)}EntitySchema } from '@/core/${name}/entity/${name}';
9
- import { CreatedModel } from '@/infra/repository';
10
- import { PaginationInput, PaginationOutput, PaginationSchema } from '@/utils/pagination';
11
- import { SearchSchema } from '@/utils/search';
12
- import { SortSchema } from '@/utils/sort';
13
-
14
- type Schema = z.infer<typeof ${capitalizeFirstLetter(name)}EntitySchema>;
15
-
16
- export const ${capitalizeFirstLetter(name)}CreateSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
17
- name: true
18
- });
19
-
20
- export type ${capitalizeFirstLetter(name)}CreateInput = z.infer<typeof ${capitalizeFirstLetter(name)}CreateSchema>;
21
- export type ${capitalizeFirstLetter(name)}CreateOutput = Promise<CreatedModel>;
22
-
23
- export const ${capitalizeFirstLetter(name)}UpdateSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
24
- id: true
25
- }).merge(${capitalizeFirstLetter(name)}CreateSchema.partial());
26
- export type ${capitalizeFirstLetter(name)}UpdateInput = z.infer<typeof ${capitalizeFirstLetter(name)}UpdateSchema>;
27
- export type ${capitalizeFirstLetter(name)}UpdateOutput = Promise<Schema>;
28
-
29
- export const ${capitalizeFirstLetter(name)}ListSchema = z.intersection(PaginationSchema, SortSchema.merge(SearchSchema));
30
-
31
- export type ${capitalizeFirstLetter(name)}ListInput = PaginationInput<Schema>;
32
- export type ${capitalizeFirstLetter(name)}ListOutput = Promise<{ docs: Schema[] } & PaginationOutput>;
33
-
34
- export const ${capitalizeFirstLetter(name)}DeleteSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
35
- id: true
36
- });
37
- export type ${capitalizeFirstLetter(name)}DeleteInput = z.infer<typeof ${capitalizeFirstLetter(name)}DeleteSchema>;
38
- export type ${capitalizeFirstLetter(name)}DeleteOutput = Promise<Schema>;
39
-
40
- export const ${capitalizeFirstLetter(name)}GetByIdSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
41
- id: true
42
- });
43
- export type ${capitalizeFirstLetter(name)}GetByIDInput = z.infer<typeof ${capitalizeFirstLetter(name)}GetByIdSchema>;
44
- export type ${capitalizeFirstLetter(name)}GetByIDOutput = Promise<Schema>;
45
- `
46
-
47
- module.exports = {
48
- getModuleType
49
- }
@@ -1,52 +0,0 @@
1
-
2
- function capitalizeFirstLetter(string) {
3
- return string.charAt(0).toUpperCase() + string.slice(1);
4
- }
5
-
6
- const getModuleType = (name) => `import { z } from 'zod';
7
-
8
- import { ${capitalizeFirstLetter(name)}EntitySchema } from '@/core/${name}/entity/${name}';
9
- import { CreatedModel } from '@/infra/repository';
10
- import { PaginationInput, PaginationOutput, PaginationSchema } from '@/utils/pagination';
11
- import { SearchSchema } from '@/utils/search';
12
- import { SortSchema } from '@/utils/sort';
13
-
14
- type Schema = z.infer<typeof ${capitalizeFirstLetter(name)}EntitySchema>;
15
-
16
- export const ${capitalizeFirstLetter(name)}CreateSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
17
- name: true
18
- });
19
-
20
- export type ${capitalizeFirstLetter(name)}CreateInput = z.infer<typeof ${capitalizeFirstLetter(name)}CreateSchema>;
21
- export type ${capitalizeFirstLetter(name)}CreateOutput = Promise<CreatedModel>;
22
-
23
- export const ${capitalizeFirstLetter(name)}UpdateSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
24
- name: true
25
- })
26
- .partial()
27
- .merge(${capitalizeFirstLetter(name)}EntitySchema.pick({ id: true }));
28
-
29
- export type ${capitalizeFirstLetter(name)}UpdateInput = z.infer<typeof ${capitalizeFirstLetter(name)}UpdateSchema>;
30
- export type ${capitalizeFirstLetter(name)}UpdateOutput = Promise<Schema>;
31
-
32
- export const ${capitalizeFirstLetter(name)}GetByIdSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
33
- id: true
34
- });
35
- export type ${capitalizeFirstLetter(name)}GetByIDInput = z.infer<typeof ${capitalizeFirstLetter(name)}GetByIdSchema>;
36
- export type ${capitalizeFirstLetter(name)}GetByIDOutput = Promise<Schema>;
37
-
38
- export const ${capitalizeFirstLetter(name)}ListSchema = z.intersection(PaginationSchema, SortSchema.merge(SearchSchema));
39
-
40
- export type ${capitalizeFirstLetter(name)}ListInput = PaginationInput<Schema>;
41
- export type ${capitalizeFirstLetter(name)}ListOutput = Promise<{ docs: Schema[] } & PaginationOutput>;
42
-
43
- export const ${capitalizeFirstLetter(name)}DeleteSchema = ${capitalizeFirstLetter(name)}EntitySchema.pick({
44
- id: true
45
- });
46
- export type ${capitalizeFirstLetter(name)}DeleteInput = z.infer<typeof ${capitalizeFirstLetter(name)}DeleteSchema>;
47
- export type ${capitalizeFirstLetter(name)}DeleteOutput = Promise<Schema>;
48
- `
49
-
50
- module.exports = {
51
- getModuleType
52
- }