@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.
- package/package.json +2 -1
- package/src/cli.js +7 -9
- package/src/scafold/mongo/.gitkeep +0 -0
- package/src/scafold/postgres/.gitkeep +0 -0
- package/src/templates/mongo/core/repository/repository.js +3 -1
- package/src/templates/mongo/core/use-cases/create.js +25 -5
- package/src/templates/mongo/core/use-cases/delete.js +10 -2
- package/src/templates/mongo/core/use-cases/getByID.js +12 -4
- package/src/templates/mongo/core/use-cases/list.js +18 -3
- package/src/templates/mongo/core/use-cases/update.js +11 -3
- package/src/templates/mongo/modules/adapter.js +5 -12
- package/src/templates/mongo/modules/controller.js +24 -25
- package/src/templates/mongo/modules/module.js +20 -8
- package/src/templates/mongo/modules/repository.js +18 -8
- package/src/templates/mongo/modules/swagger.js +8 -7
- package/src/templates/postgres/core/repository/repository.js +5 -2
- package/src/templates/postgres/core/use-cases/create.js +26 -5
- package/src/templates/postgres/core/use-cases/delete.js +13 -4
- package/src/templates/postgres/core/use-cases/getByID.js +12 -3
- package/src/templates/postgres/core/use-cases/list.js +11 -1
- package/src/templates/postgres/core/use-cases/update.js +18 -6
- package/src/templates/postgres/modules/adapter.js +5 -12
- package/src/templates/postgres/modules/controller.js +24 -25
- package/src/templates/postgres/modules/module.js +5 -5
- package/src/templates/postgres/modules/repository.js +11 -8
- package/src/templates/postgres/modules/swagger.js +6 -4
- package/src/scafold/mongo/schemas/bird.ts +0 -35
- package/src/scafold/postgres/schemas/dog.ts +0 -13
- package/src/templates/mongo/modules/types.js +0 -49
- 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.
|
|
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 {
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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 {
|
|
7
|
-
|
|
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
|
-
|
|
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 {
|
|
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}
|
|
27
|
+
const ${pluralize(name)} = await this.${name}Repository.paginate(input);
|
|
18
28
|
|
|
19
|
-
return {
|
|
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 {
|
|
7
|
-
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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 {
|
|
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(@
|
|
53
|
-
return this.${name}CreateUsecase.execute(
|
|
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(@
|
|
61
|
-
return this.${name}UpdateUsecase.execute(
|
|
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(@
|
|
71
|
-
input
|
|
72
|
-
|
|
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(@
|
|
81
|
-
return await this.${name}GetByIDUsecase.execute(
|
|
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(@
|
|
89
|
-
return await this.${name}DeleteUsecase.execute(
|
|
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
|
-
|
|
42
|
-
|
|
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 {
|
|
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}
|
|
38
|
+
const ${pluralize(name)} = await this.entity.paginate(search, { page, limit, sort });
|
|
29
39
|
|
|
30
|
-
return { docs: ${name}
|
|
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
|
|
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,
|
|
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}
|
|
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}
|
|
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:
|
|
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 {
|
|
7
|
-
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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 {
|
|
7
|
-
|
|
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 {
|
|
7
|
-
|
|
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 {
|
|
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 {
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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 {
|
|
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.
|
|
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(@
|
|
53
|
-
return await this.${name}Create.execute(
|
|
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(@
|
|
61
|
-
return await this.${name}Update.execute(
|
|
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(@
|
|
69
|
-
return await this.${name}GetByID.execute(
|
|
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(@
|
|
79
|
-
input
|
|
80
|
-
|
|
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(@
|
|
89
|
-
return await this.${name}Delete.execute(
|
|
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
|
|
42
|
-
return new ${capitalizeFirstLetter(name)}Repository(
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
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
|
-
}
|