nodejs-quickstart-structure 1.1.6
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 +98 -0
- package/bin/index.js +66 -0
- package/docs/demo.gif +0 -0
- package/docs/generateCase.md +58 -0
- package/lib/generator.js +315 -0
- package/lib/prompts.js +76 -0
- package/package.json +40 -0
- package/templates/clean-architecture/js/src/domain/models/User.js +9 -0
- package/templates/clean-architecture/js/src/domain/repositories/UserRepository.js +9 -0
- package/templates/clean-architecture/js/src/index.js.ejs +37 -0
- package/templates/clean-architecture/js/src/infrastructure/log/logger.js +22 -0
- package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.js.ejs +19 -0
- package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +31 -0
- package/templates/clean-architecture/js/src/infrastructure/webserver/swagger.js +23 -0
- package/templates/clean-architecture/js/src/interfaces/controllers/UserController.js +30 -0
- package/templates/clean-architecture/js/src/interfaces/routes/api.js +77 -0
- package/templates/clean-architecture/js/src/usecases/CreateUser.js +14 -0
- package/templates/clean-architecture/js/src/usecases/GetAllUsers.js +12 -0
- package/templates/clean-architecture/js/src/utils/httpCodes.js +9 -0
- package/templates/clean-architecture/ts/src/config/swagger.ts.ejs +24 -0
- package/templates/clean-architecture/ts/src/domain/user.ts +7 -0
- package/templates/clean-architecture/ts/src/index.ts.ejs +71 -0
- package/templates/clean-architecture/ts/src/infrastructure/log/logger.ts +22 -0
- package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.ts.ejs +18 -0
- package/templates/clean-architecture/ts/src/interfaces/controllers/userController.ts +45 -0
- package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +76 -0
- package/templates/clean-architecture/ts/src/usecases/createUser.ts +13 -0
- package/templates/clean-architecture/ts/src/usecases/getAllUsers.ts +10 -0
- package/templates/clean-architecture/ts/src/utils/httpCodes.ts +7 -0
- package/templates/common/.dockerignore +10 -0
- package/templates/common/.eslintrc.json.ejs +26 -0
- package/templates/common/.lintstagedrc +6 -0
- package/templates/common/Dockerfile +49 -0
- package/templates/common/README.md.ejs +87 -0
- package/templates/common/_gitignore +5 -0
- package/templates/common/database/js/database.js.ejs +20 -0
- package/templates/common/database/js/models/User.js.ejs +30 -0
- package/templates/common/database/ts/database.ts.ejs +22 -0
- package/templates/common/database/ts/models/User.ts.ejs +34 -0
- package/templates/common/docker-compose.yml.ejs +93 -0
- package/templates/common/jest.config.js.ejs +11 -0
- package/templates/common/kafka/js/config/kafka.js +8 -0
- package/templates/common/kafka/js/services/kafkaService.js +29 -0
- package/templates/common/kafka/ts/config/kafka.ts +6 -0
- package/templates/common/kafka/ts/services/kafkaService.ts +36 -0
- package/templates/common/package.json.ejs +78 -0
- package/templates/common/tsconfig.json +19 -0
- package/templates/common/views/ejs/index.ejs +31 -0
- package/templates/common/views/pug/index.pug +26 -0
- package/templates/db/mysql/V1__Initial_Setup.sql +9 -0
- package/templates/db/postgres/V1__Initial_Setup.sql +9 -0
- package/templates/mvc/js/src/config/database.js +12 -0
- package/templates/mvc/js/src/config/swagger.js +23 -0
- package/templates/mvc/js/src/controllers/userController.js +14 -0
- package/templates/mvc/js/src/controllers/userController.js.ejs +23 -0
- package/templates/mvc/js/src/index.js.ejs +81 -0
- package/templates/mvc/js/src/routes/api.js +74 -0
- package/templates/mvc/js/src/utils/httpCodes.js +9 -0
- package/templates/mvc/js/src/utils/logger.js +30 -0
- package/templates/mvc/ts/src/config/swagger.ts.ejs +24 -0
- package/templates/mvc/ts/src/controllers/userController.ts.ejs +32 -0
- package/templates/mvc/ts/src/index.ts.ejs +89 -0
- package/templates/mvc/ts/src/routes/api.ts +76 -0
- package/templates/mvc/ts/src/utils/httpCodes.ts +7 -0
- package/templates/mvc/ts/src/utils/logger.ts +22 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const startServer = require('./infrastructure/webserver/server');
|
|
2
|
+
const logger = require('./infrastructure/log/logger');
|
|
3
|
+
<% if (communication === 'Kafka') { -%>
|
|
4
|
+
const { connectKafka, sendMessage } = require('./infrastructure/messaging/kafkaClient');
|
|
5
|
+
<% } -%>
|
|
6
|
+
|
|
7
|
+
const PORT = process.env.PORT || 3000;
|
|
8
|
+
|
|
9
|
+
// Database Sync
|
|
10
|
+
const syncDatabase = async () => {
|
|
11
|
+
let retries = 30;
|
|
12
|
+
while (retries) {
|
|
13
|
+
try {
|
|
14
|
+
const sequelize = require('./infrastructure/database/database');
|
|
15
|
+
await sequelize.sync();
|
|
16
|
+
logger.info('Database synced');
|
|
17
|
+
// Start the web server after DB sync
|
|
18
|
+
startServer(PORT);
|
|
19
|
+
<% if (communication === 'Kafka') { %>
|
|
20
|
+
// Connect Kafka
|
|
21
|
+
connectKafka().then(async () => {
|
|
22
|
+
logger.info('Kafka connected');
|
|
23
|
+
await sendMessage('test-topic', 'Hello Kafka from Clean Arch JS!');
|
|
24
|
+
}).catch(err => {
|
|
25
|
+
logger.error('Failed to connect to Kafka:', err);
|
|
26
|
+
});
|
|
27
|
+
<% } -%>
|
|
28
|
+
break;
|
|
29
|
+
} catch (err) {
|
|
30
|
+
logger.error('Database sync failed:', err);
|
|
31
|
+
retries -= 1;
|
|
32
|
+
logger.info(`Retries left: ${retries}. Waiting 5s...`);
|
|
33
|
+
await new Promise(res => setTimeout(res, 5000));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
syncDatabase();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const winston = require('winston');
|
|
2
|
+
|
|
3
|
+
const logger = winston.createLogger({
|
|
4
|
+
level: 'info',
|
|
5
|
+
format: winston.format.combine(
|
|
6
|
+
winston.format.timestamp(),
|
|
7
|
+
winston.format.json()
|
|
8
|
+
),
|
|
9
|
+
defaultMeta: { service: 'user-service' },
|
|
10
|
+
transports: [
|
|
11
|
+
new winston.transports.File({ filename: 'error.log', level: 'error' }),
|
|
12
|
+
new winston.transports.File({ filename: 'combined.log' }),
|
|
13
|
+
],
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
17
|
+
logger.add(new winston.transports.Console({
|
|
18
|
+
format: winston.format.simple(),
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = logger;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const UserModel = require('../database/models/User');
|
|
2
|
+
|
|
3
|
+
class UserRepository {
|
|
4
|
+
async save(user) {
|
|
5
|
+
const newUser = await UserModel.create({ name: user.name, email: user.email });
|
|
6
|
+
return { ...user, id: newUser.id };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async getUsers() {
|
|
10
|
+
const users = await UserModel.findAll();
|
|
11
|
+
return users.map(user => ({
|
|
12
|
+
id: user.id,
|
|
13
|
+
name: user.name,
|
|
14
|
+
email: user.email
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = UserRepository;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const cors = require('cors');
|
|
3
|
+
require('dotenv').config();
|
|
4
|
+
<% if (communication === 'REST APIs') { %>const apiRoutes = require('../../interfaces/routes/api');<% } %>
|
|
5
|
+
<% if (communication === 'REST APIs') { %>
|
|
6
|
+
const swaggerUi = require('swagger-ui-express');
|
|
7
|
+
const swaggerSpecs = require('./swagger');
|
|
8
|
+
<% } %>
|
|
9
|
+
|
|
10
|
+
const startServer = (port) => {
|
|
11
|
+
const app = express();
|
|
12
|
+
|
|
13
|
+
app.use(cors());
|
|
14
|
+
app.use(express.json());
|
|
15
|
+
|
|
16
|
+
<% if (communication === 'REST APIs') { %>app.use('/api', apiRoutes);<% } %>
|
|
17
|
+
|
|
18
|
+
<% if (communication === 'REST APIs') { %>
|
|
19
|
+
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs));
|
|
20
|
+
<% } %>
|
|
21
|
+
|
|
22
|
+
app.get('/health', (req, res) => {
|
|
23
|
+
res.json({ status: 'UP' });
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
app.listen(port, () => {
|
|
27
|
+
console.log(`Server running on port ${port}`);
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
module.exports = startServer;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const swaggerJsdoc = require('swagger-jsdoc');
|
|
2
|
+
|
|
3
|
+
const options = {
|
|
4
|
+
definition: {
|
|
5
|
+
openapi: '3.0.0',
|
|
6
|
+
info: {
|
|
7
|
+
title: 'NodeJS API Service',
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
description: 'API documentation for the NodeJS Service',
|
|
10
|
+
},
|
|
11
|
+
servers: [
|
|
12
|
+
{
|
|
13
|
+
url: process.env.SERVER_URL || `http://localhost:${process.env.PORT || 3000}`,
|
|
14
|
+
description: 'Server',
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
apis: ['./src/interfaces/routes/*.js'], // Path to the API docs
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const specs = swaggerJsdoc(options);
|
|
22
|
+
|
|
23
|
+
module.exports = specs;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const CreateUser = require('../../usecases/CreateUser');
|
|
2
|
+
const GetAllUsers = require('../../usecases/GetAllUsers');
|
|
3
|
+
const UserRepository = require('../../infrastructure/repositories/UserRepository');
|
|
4
|
+
const HTTP_STATUS = require('../../utils/httpCodes');
|
|
5
|
+
|
|
6
|
+
class UserController {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.userRepository = new UserRepository();
|
|
9
|
+
this.createUserUseCase = new CreateUser(this.userRepository);
|
|
10
|
+
this.getAllUsersUseCase = new GetAllUsers(this.userRepository);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
getUsers(req, res) {
|
|
14
|
+
this.getAllUsersUseCase.execute()
|
|
15
|
+
.then(users => res.json(users))
|
|
16
|
+
.catch(err => res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ error: err.message }));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async createUser(req, res) {
|
|
20
|
+
const { name, email } = req.body;
|
|
21
|
+
try {
|
|
22
|
+
const user = await this.createUserUseCase.execute(name, email);
|
|
23
|
+
res.status(HTTP_STATUS.CREATED).json(user);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
res.status(HTTP_STATUS.BAD_REQUEST).json({ error: error.message });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = UserController;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const UserController = require('../controllers/UserController');
|
|
4
|
+
|
|
5
|
+
// Should inject dependencies here in a real app
|
|
6
|
+
const userController = new UserController();
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @swagger
|
|
10
|
+
* components:
|
|
11
|
+
* schemas:
|
|
12
|
+
* User:
|
|
13
|
+
* type: object
|
|
14
|
+
* required:
|
|
15
|
+
* - name
|
|
16
|
+
* - email
|
|
17
|
+
* properties:
|
|
18
|
+
* id:
|
|
19
|
+
* type: integer
|
|
20
|
+
* description: The auto-generated id of the user
|
|
21
|
+
* name:
|
|
22
|
+
* type: string
|
|
23
|
+
* description: The name of the user
|
|
24
|
+
* email:
|
|
25
|
+
* type: string
|
|
26
|
+
* description: The email of the user
|
|
27
|
+
* example:
|
|
28
|
+
* id: 1
|
|
29
|
+
* name: John Doe
|
|
30
|
+
* email: john@example.com
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @swagger
|
|
35
|
+
* tags:
|
|
36
|
+
* name: Users
|
|
37
|
+
* description: The users managing API
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @swagger
|
|
42
|
+
* /api/users:
|
|
43
|
+
* get:
|
|
44
|
+
* summary: Returns the list of all the users
|
|
45
|
+
* tags: [Users]
|
|
46
|
+
* responses:
|
|
47
|
+
* 200:
|
|
48
|
+
* description: The list of the users
|
|
49
|
+
* content:
|
|
50
|
+
* application/json:
|
|
51
|
+
* schema:
|
|
52
|
+
* type: array
|
|
53
|
+
* items:
|
|
54
|
+
* $ref: '#/components/schemas/User'
|
|
55
|
+
* post:
|
|
56
|
+
* summary: Create a new user
|
|
57
|
+
* tags: [Users]
|
|
58
|
+
* requestBody:
|
|
59
|
+
* required: true
|
|
60
|
+
* content:
|
|
61
|
+
* application/json:
|
|
62
|
+
* schema:
|
|
63
|
+
* $ref: '#/components/schemas/User'
|
|
64
|
+
* responses:
|
|
65
|
+
* 201:
|
|
66
|
+
* description: The created user.
|
|
67
|
+
* content:
|
|
68
|
+
* application/json:
|
|
69
|
+
* schema:
|
|
70
|
+
* $ref: '#/components/schemas/User'
|
|
71
|
+
* 500:
|
|
72
|
+
* description: Some server error
|
|
73
|
+
*/
|
|
74
|
+
router.post('/users', (req, res) => userController.createUser(req, res));
|
|
75
|
+
router.get('/users', (req, res) => userController.getUsers(req, res));
|
|
76
|
+
|
|
77
|
+
module.exports = router;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const User = require('../domain/models/User');
|
|
2
|
+
|
|
3
|
+
class CreateUser {
|
|
4
|
+
constructor(userRepository) {
|
|
5
|
+
this.userRepository = userRepository;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async execute(name, email) {
|
|
9
|
+
const user = new User(null, name, email);
|
|
10
|
+
return await this.userRepository.save(user);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = CreateUser;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<% if (communication === 'REST APIs') { %>
|
|
2
|
+
import swaggerJsdoc from 'swagger-jsdoc';
|
|
3
|
+
|
|
4
|
+
const options = {
|
|
5
|
+
definition: {
|
|
6
|
+
openapi: '3.0.0',
|
|
7
|
+
info: {
|
|
8
|
+
title: 'NodeJS API Service',
|
|
9
|
+
version: '1.0.0',
|
|
10
|
+
description: 'API documentation for the NodeJS Service',
|
|
11
|
+
},
|
|
12
|
+
servers: [
|
|
13
|
+
{
|
|
14
|
+
url: process.env.SERVER_URL || `http://localhost:${process.env.PORT || 3000}`,
|
|
15
|
+
description: 'Server',
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
apis: ['./src/interfaces/routes/*.ts', './dist/interfaces/routes/*.js'], // Path to the API docs
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const specs = swaggerJsdoc(options);
|
|
23
|
+
|
|
24
|
+
export default specs;<% } %>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import express, { Request, Response } from 'express';
|
|
2
|
+
import cors from 'cors';
|
|
3
|
+
import helmet from 'helmet';
|
|
4
|
+
import hpp from 'hpp';
|
|
5
|
+
import rateLimit from 'express-rate-limit';
|
|
6
|
+
import dotenv from 'dotenv';
|
|
7
|
+
import logger from './infrastructure/log/logger';
|
|
8
|
+
<% if (communication === 'REST APIs') { %>import userRoutes from './interfaces/routes/userRoutes';<% } %>
|
|
9
|
+
<% if (communication === 'REST APIs') { %>
|
|
10
|
+
import swaggerUi from 'swagger-ui-express';
|
|
11
|
+
import swaggerSpecs from './config/swagger';<% } %>
|
|
12
|
+
<% if (communication === 'Kafka') { %>import { KafkaService } from './infrastructure/messaging/kafkaClient';<% } %>
|
|
13
|
+
|
|
14
|
+
dotenv.config();
|
|
15
|
+
|
|
16
|
+
const app = express();
|
|
17
|
+
const port = process.env.PORT || 3000;
|
|
18
|
+
|
|
19
|
+
// Security Middleware
|
|
20
|
+
app.use(helmet());
|
|
21
|
+
app.use(hpp());
|
|
22
|
+
app.use(cors({ origin: '*', methods: ['GET', 'POST', 'PUT', 'DELETE'] }));
|
|
23
|
+
const limiter = rateLimit({ windowMs: 10 * 60 * 1000, max: 100 });
|
|
24
|
+
app.use(limiter);
|
|
25
|
+
|
|
26
|
+
app.use(express.json());
|
|
27
|
+
|
|
28
|
+
<% if (communication === 'REST APIs') { -%>
|
|
29
|
+
app.use('/api/users', userRoutes);<% } -%>
|
|
30
|
+
|
|
31
|
+
<% if (communication === 'REST APIs') { %>
|
|
32
|
+
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs));<% } %>
|
|
33
|
+
|
|
34
|
+
app.get('/health', (req: Request, res: Response) => {
|
|
35
|
+
res.json({ status: 'UP' });
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Database Sync
|
|
39
|
+
const syncDatabase = async () => {
|
|
40
|
+
let retries = 30;
|
|
41
|
+
while (retries) {
|
|
42
|
+
try {
|
|
43
|
+
const sequelize = (await import('./infrastructure/database/database')).default;
|
|
44
|
+
await sequelize.sync();
|
|
45
|
+
logger.info('Database synced');
|
|
46
|
+
|
|
47
|
+
app.listen(port, async () => {
|
|
48
|
+
logger.info(`Server running on port ${port}`);
|
|
49
|
+
<% if (communication === 'Kafka') { %>
|
|
50
|
+
try {
|
|
51
|
+
const kafkaService = new KafkaService();
|
|
52
|
+
await kafkaService.connect();
|
|
53
|
+
logger.info('Kafka connected');
|
|
54
|
+
// Demo
|
|
55
|
+
await kafkaService.sendMessage('test-topic', 'Hello Kafka from Clean Arch TS!');
|
|
56
|
+
} catch (err) {
|
|
57
|
+
logger.error('Failed to connect to Kafka:', err);
|
|
58
|
+
}
|
|
59
|
+
<% } -%>
|
|
60
|
+
});
|
|
61
|
+
break;
|
|
62
|
+
} catch (err) {
|
|
63
|
+
logger.error('Database sync failed:', err);
|
|
64
|
+
retries -= 1;
|
|
65
|
+
logger.info(`Retries left: ${retries}. Waiting 5s...`);
|
|
66
|
+
await new Promise(res => setTimeout(res, 5000));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
syncDatabase();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import winston from 'winston';
|
|
2
|
+
|
|
3
|
+
const logger = winston.createLogger({
|
|
4
|
+
level: 'info',
|
|
5
|
+
format: winston.format.combine(
|
|
6
|
+
winston.format.timestamp(),
|
|
7
|
+
winston.format.json()
|
|
8
|
+
),
|
|
9
|
+
defaultMeta: { service: 'user-service' },
|
|
10
|
+
transports: [
|
|
11
|
+
new winston.transports.File({ filename: 'error.log', level: 'error' }),
|
|
12
|
+
new winston.transports.File({ filename: 'combined.log' }),
|
|
13
|
+
],
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
17
|
+
logger.add(new winston.transports.Console({
|
|
18
|
+
format: winston.format.simple(),
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default logger;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { User as UserEntity } from '../../domain/user';
|
|
2
|
+
import UserModel from '../database/models/User';
|
|
3
|
+
|
|
4
|
+
export class UserRepository {
|
|
5
|
+
async save(user: UserEntity): Promise<UserEntity> {
|
|
6
|
+
const newUser = await UserModel.create({ name: user.name, email: user.email });
|
|
7
|
+
return { id: newUser.id, name: newUser.name, email: newUser.email };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async getUsers(): Promise<UserEntity[]> {
|
|
11
|
+
const users = await UserModel.findAll();
|
|
12
|
+
return users.map(user => ({
|
|
13
|
+
id: user.id,
|
|
14
|
+
name: user.name,
|
|
15
|
+
email: user.email
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
import { UserRepository } from '../../infrastructure/repositories/UserRepository';
|
|
3
|
+
import CreateUser from '../../usecases/createUser';
|
|
4
|
+
import GetAllUsers from '../../usecases/getAllUsers';
|
|
5
|
+
import { HTTP_STATUS } from '../../utils/httpCodes';
|
|
6
|
+
|
|
7
|
+
export class UserController {
|
|
8
|
+
private createUserUseCase: CreateUser;
|
|
9
|
+
private getAllUsersUseCase: GetAllUsers;
|
|
10
|
+
|
|
11
|
+
constructor() {
|
|
12
|
+
const userRepository = new UserRepository();
|
|
13
|
+
this.createUserUseCase = new CreateUser(userRepository);
|
|
14
|
+
this.getAllUsersUseCase = new GetAllUsers(userRepository);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async createUser(req: Request, res: Response) {
|
|
18
|
+
try {
|
|
19
|
+
const { name, email } = req.body;
|
|
20
|
+
const user = await this.createUserUseCase.execute(name, email);
|
|
21
|
+
res.status(HTTP_STATUS.CREATED).json(user);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error('UserController Error:', error);
|
|
24
|
+
if (error instanceof Error) {
|
|
25
|
+
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ error: error.message });
|
|
26
|
+
} else {
|
|
27
|
+
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ error: 'Unknown error occurred' });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async getUsers(req: Request, res: Response) {
|
|
33
|
+
try {
|
|
34
|
+
const users = await this.getAllUsersUseCase.execute();
|
|
35
|
+
res.json(users);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error('UserController Error:', error);
|
|
38
|
+
if (error instanceof Error) {
|
|
39
|
+
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ error: error.message });
|
|
40
|
+
} else {
|
|
41
|
+
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ error: 'Unknown error occurred' });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Router, Request, Response } from 'express';
|
|
2
|
+
import { UserController } from '../controllers/userController';
|
|
3
|
+
|
|
4
|
+
const router = Router();
|
|
5
|
+
const userController = new UserController();
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @swagger
|
|
9
|
+
* components:
|
|
10
|
+
* schemas:
|
|
11
|
+
* User:
|
|
12
|
+
* type: object
|
|
13
|
+
* required:
|
|
14
|
+
* - name
|
|
15
|
+
* - email
|
|
16
|
+
* properties:
|
|
17
|
+
* id:
|
|
18
|
+
* type: integer
|
|
19
|
+
* description: The auto-generated id of the user
|
|
20
|
+
* name:
|
|
21
|
+
* type: string
|
|
22
|
+
* description: The name of the user
|
|
23
|
+
* email:
|
|
24
|
+
* type: string
|
|
25
|
+
* description: The email of the user
|
|
26
|
+
* example:
|
|
27
|
+
* id: 1
|
|
28
|
+
* name: John Doe
|
|
29
|
+
* email: john@example.com
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @swagger
|
|
34
|
+
* tags:
|
|
35
|
+
* name: Users
|
|
36
|
+
* description: The users managing API
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @swagger
|
|
41
|
+
* /api/users:
|
|
42
|
+
* get:
|
|
43
|
+
* summary: Returns the list of all the users
|
|
44
|
+
* tags: [Users]
|
|
45
|
+
* responses:
|
|
46
|
+
* 200:
|
|
47
|
+
* description: The list of the users
|
|
48
|
+
* content:
|
|
49
|
+
* application/json:
|
|
50
|
+
* schema:
|
|
51
|
+
* type: array
|
|
52
|
+
* items:
|
|
53
|
+
* $ref: '#/components/schemas/User'
|
|
54
|
+
* post:
|
|
55
|
+
* summary: Create a new user
|
|
56
|
+
* tags: [Users]
|
|
57
|
+
* requestBody:
|
|
58
|
+
* required: true
|
|
59
|
+
* content:
|
|
60
|
+
* application/json:
|
|
61
|
+
* schema:
|
|
62
|
+
* $ref: '#/components/schemas/User'
|
|
63
|
+
* responses:
|
|
64
|
+
* 201:
|
|
65
|
+
* description: The created user.
|
|
66
|
+
* content:
|
|
67
|
+
* application/json:
|
|
68
|
+
* schema:
|
|
69
|
+
* $ref: '#/components/schemas/User'
|
|
70
|
+
* 500:
|
|
71
|
+
* description: Some server error
|
|
72
|
+
*/
|
|
73
|
+
router.post('/', (req: Request, res: Response) => userController.createUser(req, res));
|
|
74
|
+
router.get('/', (req: Request, res: Response) => userController.getUsers(req, res));
|
|
75
|
+
|
|
76
|
+
export default router;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { User } from '../domain/user';
|
|
2
|
+
|
|
3
|
+
import { UserRepository } from '../infrastructure/repositories/UserRepository';
|
|
4
|
+
|
|
5
|
+
export default class CreateUser {
|
|
6
|
+
constructor(private userRepository: UserRepository) {}
|
|
7
|
+
|
|
8
|
+
async execute(name: string, email: string) {
|
|
9
|
+
const user = new User(null, name, email);
|
|
10
|
+
return this.userRepository.save(user);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"env": {
|
|
3
|
+
"node": true,
|
|
4
|
+
"es2021": true,
|
|
5
|
+
"jest": true
|
|
6
|
+
},
|
|
7
|
+
"extends": [
|
|
8
|
+
"eslint:recommended",
|
|
9
|
+
"prettier"<% if (language === 'TypeScript') { %>,
|
|
10
|
+
"plugin:@typescript-eslint/recommended"<% } %>
|
|
11
|
+
],
|
|
12
|
+
"parserOptions": {
|
|
13
|
+
"ecmaVersion": "latest",
|
|
14
|
+
"sourceType": "module"
|
|
15
|
+
}<% if (language === 'TypeScript') { %>,
|
|
16
|
+
"parser": "@typescript-eslint/parser",
|
|
17
|
+
"plugins": ["@typescript-eslint"]<% } %>,
|
|
18
|
+
"rules": {
|
|
19
|
+
"no-console": "warn",
|
|
20
|
+
<% if (language === 'TypeScript') { %>
|
|
21
|
+
"no-unused-vars": "off",
|
|
22
|
+
"@typescript-eslint/no-unused-vars": "warn"
|
|
23
|
+
<% } else { %>
|
|
24
|
+
"no-unused-vars": "warn"<% } %>
|
|
25
|
+
}
|
|
26
|
+
}
|