ddd-backend-cli 1.0.0 → 1.0.1
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/README.md +3 -3
- package/dist/generators/module/fileCreator.js +1 -1
- package/dist/templates/controller.ejs +41 -0
- package/dist/templates/dto.ejs +5 -0
- package/dist/templates/entity.ejs +40 -0
- package/dist/templates/path.ejs +116 -0
- package/dist/templates/repository.impl.ejs +29 -0
- package/dist/templates/repository.interface.ejs +10 -0
- package/dist/templates/routes.ejs +14 -0
- package/dist/templates/schema.ejs +27 -0
- package/dist/templates/service.impl.ejs +33 -0
- package/dist/templates/service.interface.ejs +10 -0
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
###
|
|
5
5
|
|
|
6
|
-
<p align="left">CLI para generar automáticamente la estructura base de un módulo CRUD en un proyecto Backend usando Node.js + TypeScript + Express + EJS templates.<br><br>Este proyecto te permite crear tu propio template de Backend y personalizarlo usando solo comandos, sin necesidad de escribir todo el código repetitivo cada vez.</p>
|
|
6
|
+
<p align="left">CLI para generar automáticamente la estructura base de un módulo CRUD en un proyecto Backend usando Node.js + TypeScript + Express + EJS templates + Scalar + Tsyrinnge.<br><br>Este proyecto te permite crear tu propio template de Backend y personalizarlo usando solo comandos, sin necesidad de escribir todo el código repetitivo cada vez.</p>
|
|
7
7
|
|
|
8
8
|
Documentación paso a paso en mi Notion, para que puedas replicar la lógica y adaptarlo a tu manera: https://www.notion.so/oscarmolina/Automatizacion-Backend-3037c9c9fb1780f5bb06db3a9fb9ef83?source=copy_link
|
|
9
9
|
|
|
@@ -93,7 +93,7 @@ debes ubicarte en el espacio sobre el que trabajaras, en mi caso el Escritorio(D
|
|
|
93
93
|
|
|
94
94
|
#para iniciar el proyecto nuevo y crear una base usa el siguiente comando
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
ddd-cli init test-api
|
|
97
97
|
|
|
98
98
|
#donde init es el comando de inicializacion y test-api el nombre del proyecto,
|
|
99
99
|
# una vez creado debemos entrar en el proyecto con el comando:
|
|
@@ -103,7 +103,7 @@ cd test-api
|
|
|
103
103
|
#luego ejecutaremos el siguiente comando que se encargara de crearnos la estructura
|
|
104
104
|
# de carpetas y archivos de manera automatizada
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
ddd-cli generate-model Product name:string price:number
|
|
107
107
|
|
|
108
108
|
#El CLI:
|
|
109
109
|
#Crea una carpeta src/product
|
|
@@ -8,7 +8,7 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const ejs_1 = __importDefault(require("ejs"));
|
|
10
10
|
async function createFile(template, destination, data) {
|
|
11
|
-
const templatePath = path_1.default.resolve(__dirname, "
|
|
11
|
+
const templatePath = path_1.default.resolve(__dirname, "../../templates", template);
|
|
12
12
|
if (await fs_extra_1.default.pathExists(destination)) {
|
|
13
13
|
console.log(`Skipped: ${destination}`);
|
|
14
14
|
return;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { inject, injectable } from "tsyringe";
|
|
2
|
+
import { Request, Response } from "express";
|
|
3
|
+
import { I<%= name %>Service } from './../../Application/interfaces/<%= moduleName %>.service.interface';
|
|
4
|
+
|
|
5
|
+
@injectable()
|
|
6
|
+
export class <%= name %>Controller {
|
|
7
|
+
|
|
8
|
+
private readonly _<%= moduleName %>Service: I<%= name %>Service;
|
|
9
|
+
|
|
10
|
+
constructor(@inject("I<%= name %>Service") service: I<%= name %>Service) {
|
|
11
|
+
this._<%= moduleName %>Service = service;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
create= async (req: Request, res: Response)=> {
|
|
15
|
+
const result = await this._<%= moduleName %>Service.create(req.body);
|
|
16
|
+
res.status(201).json(result);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getAll= async (req: Request, res: Response)=> {
|
|
20
|
+
const result = await this._<%= moduleName %>Service.findAll();
|
|
21
|
+
res.json(result);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getById= async (req: Request, res: Response)=> {
|
|
25
|
+
const id = req.params.id as string;
|
|
26
|
+
const result = await this._<%= moduleName %>Service.findById(id);
|
|
27
|
+
res.json(result);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
update= async (req: Request, res: Response)=> {
|
|
31
|
+
const id = req.params.id as string;
|
|
32
|
+
const result = await this._<%= moduleName %>Service.update(id, req.body);
|
|
33
|
+
res.json(result);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
delete= async (req: Request, res: Response)=> {
|
|
37
|
+
const id = req.params.id as string;
|
|
38
|
+
await this._<%= moduleName %>Service.delete(id);
|
|
39
|
+
res.status(204).send();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import BaseModel from "./base.model";
|
|
2
|
+
|
|
3
|
+
export default class <%= name %> extends BaseModel {
|
|
4
|
+
<% fields.forEach(field => { -%>
|
|
5
|
+
<%= field.fieldName %>: <%= field.type %>;
|
|
6
|
+
<% }) -%>
|
|
7
|
+
createdAt: Date;
|
|
8
|
+
updatedAt: Date;
|
|
9
|
+
createdBy: string;
|
|
10
|
+
updatedBy: string;
|
|
11
|
+
|
|
12
|
+
constructor({
|
|
13
|
+
id,
|
|
14
|
+
<% fields.forEach(field => { -%>
|
|
15
|
+
<%= field.fieldName %>,
|
|
16
|
+
<% }) -%>
|
|
17
|
+
createdAt,
|
|
18
|
+
updatedAt,
|
|
19
|
+
createdBy,
|
|
20
|
+
updatedBy,
|
|
21
|
+
}: {
|
|
22
|
+
id: string;
|
|
23
|
+
<% fields.forEach(field => { -%>
|
|
24
|
+
<%= field.fieldName %>: <%= field.type %>;
|
|
25
|
+
<% }) -%>
|
|
26
|
+
createdAt: Date;
|
|
27
|
+
updatedAt: Date;
|
|
28
|
+
createdBy: string;
|
|
29
|
+
updatedBy: string;
|
|
30
|
+
}) {
|
|
31
|
+
super(id);
|
|
32
|
+
<% fields.forEach(field => { -%>
|
|
33
|
+
this.<%= field.fieldName %> = <%= field.fieldName %>;
|
|
34
|
+
<% }) -%>
|
|
35
|
+
this.createdAt = createdAt;
|
|
36
|
+
this.updatedAt = updatedAt;
|
|
37
|
+
this.createdBy = createdBy;
|
|
38
|
+
this.updatedBy = updatedBy;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export const <%= name %>Paths = {
|
|
2
|
+
"/<%= moduleName %>": {
|
|
3
|
+
get: {
|
|
4
|
+
summary: "Get all <%= name %>",
|
|
5
|
+
tags: ["<%= name %>"],
|
|
6
|
+
responses: {
|
|
7
|
+
200: {
|
|
8
|
+
description: "List of <%= name %>",
|
|
9
|
+
content: {
|
|
10
|
+
"application/json": {
|
|
11
|
+
schema: {
|
|
12
|
+
type: "array",
|
|
13
|
+
items: { $ref: "#/components/schemas/<%= name %>" }
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
post: {
|
|
21
|
+
summary: "Create <%= name %>",
|
|
22
|
+
tags: ["<%= name %>"],
|
|
23
|
+
requestBody: {
|
|
24
|
+
required: true,
|
|
25
|
+
content: {
|
|
26
|
+
"application/json": {
|
|
27
|
+
schema: { $ref: "#/components/schemas/<%= name %>Request" }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
responses: {
|
|
32
|
+
201: {
|
|
33
|
+
description: "<%= name %> created"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
"/<%= moduleName %>/{id}": {
|
|
40
|
+
get: {
|
|
41
|
+
summary: "Get <%= name %> by id",
|
|
42
|
+
tags: ["<%= name %>"],
|
|
43
|
+
parameters: [
|
|
44
|
+
{
|
|
45
|
+
name: "id",
|
|
46
|
+
in: "path",
|
|
47
|
+
required: true,
|
|
48
|
+
schema: { type: "string" }
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
responses: {
|
|
52
|
+
200: {
|
|
53
|
+
description: "<%= name %> found",
|
|
54
|
+
content: {
|
|
55
|
+
"application/json": {
|
|
56
|
+
schema: { $ref: "#/components/schemas/<%= name %>" }
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
404: {
|
|
61
|
+
description: "Not found"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
put: {
|
|
67
|
+
summary: "Update <%= name %>",
|
|
68
|
+
tags: ["<%= name %>"],
|
|
69
|
+
parameters: [
|
|
70
|
+
{
|
|
71
|
+
name: "id",
|
|
72
|
+
in: "path",
|
|
73
|
+
required: true,
|
|
74
|
+
schema: { type: "string" }
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
requestBody: {
|
|
78
|
+
required: true,
|
|
79
|
+
content: {
|
|
80
|
+
"application/json": {
|
|
81
|
+
schema: { $ref: "#/components/schemas/<%= name %>Request" }
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
responses: {
|
|
86
|
+
200: {
|
|
87
|
+
description: "<%= name %> updated"
|
|
88
|
+
},
|
|
89
|
+
404: {
|
|
90
|
+
description: "Not found"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
delete: {
|
|
96
|
+
summary: "Delete <%= name %>",
|
|
97
|
+
tags: ["<%= name %>"],
|
|
98
|
+
parameters: [
|
|
99
|
+
{
|
|
100
|
+
name: "id",
|
|
101
|
+
in: "path",
|
|
102
|
+
required: true,
|
|
103
|
+
schema: { type: "string" }
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
responses: {
|
|
107
|
+
204: {
|
|
108
|
+
description: "<%= name %> deleted"
|
|
109
|
+
},
|
|
110
|
+
404: {
|
|
111
|
+
description: "Not found"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { injectable } from "tsyringe";
|
|
2
|
+
import { I<%= name %>Repository } from "../../Domain/repositories/<%= moduleName %>Repository.interface";
|
|
3
|
+
//import { DatabaseConnection } from "../database/DatabaseConnection";
|
|
4
|
+
import { <%= name %>Dto } from "../../Application/dtos/<%= moduleName %>.dto";
|
|
5
|
+
import <%= name %> from "../../Domain/entities/<%= moduleName %>";
|
|
6
|
+
|
|
7
|
+
@injectable()
|
|
8
|
+
export class <%= name %>Repository implements I<%= name %>Repository {
|
|
9
|
+
//private db = DatabaseConnection.getInstance();
|
|
10
|
+
|
|
11
|
+
async create(data: <%= name %>Dto) : Promise<<%= name %>>{
|
|
12
|
+
// implementar luego
|
|
13
|
+
throw new Error("Method not implemented.");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async findAll(): Promise<<%= name %>[]> {
|
|
17
|
+
throw new Error("Method not implemented.");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async findById(id: string): Promise<<%= name %>> {
|
|
21
|
+
throw new Error("Method not implemented.");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async update(id: string, data: <%= name %>Dto): Promise<<%= name %>> {
|
|
25
|
+
throw new Error("Method not implemented.");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async delete(id: string) {}
|
|
29
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import <%= name %> from '../entities/<%= moduleName %>';
|
|
2
|
+
import { <%= name %>Dto } from './../../Application/dtos/<%= moduleName %>.dto';
|
|
3
|
+
|
|
4
|
+
export interface I<%= name %>Repository {
|
|
5
|
+
create(data: <%= name %>Dto): Promise<<%= name %>>;
|
|
6
|
+
findAll(): Promise<<%= name %>[]>;
|
|
7
|
+
findById(id: string): Promise<<%= name %>>;
|
|
8
|
+
update(id: string, data: <%= name %>Dto): Promise<<%= name %>>;
|
|
9
|
+
delete(id: string): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
import { container } from "tsyringe";
|
|
3
|
+
import { <%= name %>Controller } from "../controllers/<%= name.toLowerCase() %>.controller";
|
|
4
|
+
|
|
5
|
+
const router = express.Router();
|
|
6
|
+
const controller = container.resolve(<%= name %>Controller);
|
|
7
|
+
|
|
8
|
+
router.post("/", controller.create);
|
|
9
|
+
router.get("/", controller.getAll);
|
|
10
|
+
router.get("/:id", controller.getById);
|
|
11
|
+
router.put("/:id", controller.update);
|
|
12
|
+
router.delete("/:id", controller.delete);
|
|
13
|
+
|
|
14
|
+
export default router;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const <%= name %>Schemas = {
|
|
2
|
+
<%= name %>Request: {
|
|
3
|
+
type: "object",
|
|
4
|
+
required: [
|
|
5
|
+
<% fields.forEach((field, index) => { %>
|
|
6
|
+
"<%= field.fieldName %>"<%= index < fields.length - 1 ? "," : "" %>
|
|
7
|
+
<% }) %>
|
|
8
|
+
],
|
|
9
|
+
properties: {
|
|
10
|
+
<% fields.forEach(field => { %>
|
|
11
|
+
<%= field.fieldName %>: { type: "<%= field.type === 'number' ? 'number' : 'string' %>" },
|
|
12
|
+
<% }) %>
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
<%= name %>: {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
id: { type: "string" },
|
|
20
|
+
<% fields.forEach(field => { %>
|
|
21
|
+
<%= field.fieldName %>: { type: "<%= field.type === 'number' ? 'number' : 'string' %>" },
|
|
22
|
+
<% }) %>
|
|
23
|
+
createdAt: { type: "string", format: "date-time" },
|
|
24
|
+
updatedAt: { type: "string", format: "date-time" }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { inject, injectable } from "tsyringe";
|
|
2
|
+
import { I<%= name %>Service } from "../interfaces/<%= moduleName %>.service.interface";
|
|
3
|
+
import { I<%= name %>Repository } from "../../Domain/repositories/<%= moduleName %>Repository.interface";
|
|
4
|
+
import { <%= name %>Dto } from "../dtos/<%= moduleName %>.dto";
|
|
5
|
+
|
|
6
|
+
@injectable()
|
|
7
|
+
export class <%= name %>Service implements I<%= name %>Service {
|
|
8
|
+
private readonly _<%= moduleName %>Repository: I<%= name %>Repository;
|
|
9
|
+
|
|
10
|
+
constructor(@inject("I<%= name %>Repository") repository: I<%= name %>Repository) {
|
|
11
|
+
this._<%= moduleName %>Repository = repository;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async create(data: <%= name %>Dto) {
|
|
15
|
+
return this._<%= moduleName %>Repository.create(data);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async findAll() {
|
|
19
|
+
return this._<%= moduleName %>Repository.findAll();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async findById(id: string) {
|
|
23
|
+
return this._<%= moduleName %>Repository.findById(id);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async update(id: string, data: <%= name %>Dto) {
|
|
27
|
+
return this._<%= moduleName %>Repository.update(id, data);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async delete(id: string) {
|
|
31
|
+
return this._<%= moduleName %>Repository.delete(id);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import <%= name %> from "../../Domain/entities/<%= moduleName %>";
|
|
2
|
+
import { <%= name %>Dto } from './../dtos/<%= moduleName %>.dto';
|
|
3
|
+
|
|
4
|
+
export interface I<%= name %>Service {
|
|
5
|
+
create(data: <%= name %>Dto): Promise<<%= name %>>;
|
|
6
|
+
findAll(): Promise<<%= name %>[]>;
|
|
7
|
+
findById(id: string): Promise<<%= name %>>;
|
|
8
|
+
update(id: string, data: <%= name %>Dto): Promise<<%= name %>>;
|
|
9
|
+
delete(id: string): Promise<void>;
|
|
10
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ddd-backend-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "CLI para generar proyectos backend con DDD",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -17,8 +17,12 @@
|
|
|
17
17
|
],
|
|
18
18
|
"author": "Oscar Molina",
|
|
19
19
|
"license": "MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/oscarMolina1523/BackendAutomation.git"
|
|
23
|
+
},
|
|
20
24
|
"scripts": {
|
|
21
|
-
"build": "tsc",
|
|
25
|
+
"build": "tsc && cpx \"src/templates/**/*\" dist/templates",
|
|
22
26
|
"dev": "tsc -w"
|
|
23
27
|
},
|
|
24
28
|
"dependencies": {
|
|
@@ -30,6 +34,7 @@
|
|
|
30
34
|
"@types/ejs": "^3.1.5",
|
|
31
35
|
"@types/fs-extra": "^11.0.4",
|
|
32
36
|
"@types/node": "^20.11.30",
|
|
37
|
+
"cpx": "^1.5.0",
|
|
33
38
|
"typescript": "^5.3.3"
|
|
34
39
|
}
|
|
35
40
|
}
|