nodejs-quickstart-structure 1.9.2 → 1.10.0
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/CHANGELOG.md +23 -0
- package/README.md +7 -7
- package/bin/index.js +2 -2
- package/docs/generateCase.md +160 -164
- package/lib/generator.js +1 -1
- package/lib/modules/app-setup.js +84 -10
- package/lib/prompts.js +1 -1
- package/package.json +4 -2
- package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +25 -11
- package/templates/clean-architecture/js/src/infrastructure/webserver/swagger.js +4 -21
- package/templates/clean-architecture/js/src/interfaces/controllers/{userController.js → userController.js.ejs} +23 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/context.js.ejs +13 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/index.js.ejs +5 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/index.js.ejs +6 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs +27 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/index.js.ejs +6 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/user.types.js.ejs +17 -0
- package/templates/clean-architecture/js/src/interfaces/routes/api.js +0 -67
- package/templates/clean-architecture/ts/src/config/swagger.ts.ejs +4 -21
- package/templates/clean-architecture/ts/src/index.ts.ejs +51 -20
- package/templates/clean-architecture/ts/src/interfaces/controllers/{userController.ts → userController.ts.ejs} +28 -1
- package/templates/clean-architecture/ts/src/interfaces/graphql/context.ts.ejs +17 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/index.ts.ejs +3 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/index.ts.ejs +4 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs +27 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/index.ts.ejs +4 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/user.types.ts.ejs +15 -0
- package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +0 -66
- package/templates/common/Dockerfile +2 -2
- package/templates/common/README.md.ejs +27 -0
- package/templates/common/database/js/mongoose.js.ejs +0 -1
- package/templates/common/database/ts/mongoose.ts.ejs +0 -1
- package/templates/common/package.json.ejs +7 -4
- package/templates/common/swagger.yml.ejs +66 -0
- package/templates/mvc/js/src/config/swagger.js +4 -21
- package/templates/mvc/js/src/controllers/userController.js.ejs +55 -0
- package/templates/mvc/js/src/graphql/context.js.ejs +7 -0
- package/templates/mvc/js/src/graphql/index.js.ejs +5 -0
- package/templates/mvc/js/src/graphql/resolvers/index.js.ejs +6 -0
- package/templates/mvc/js/src/graphql/resolvers/user.resolvers.js.ejs +25 -0
- package/templates/mvc/js/src/graphql/typeDefs/index.js.ejs +6 -0
- package/templates/mvc/js/src/graphql/typeDefs/user.types.js.ejs +17 -0
- package/templates/mvc/js/src/index.js.ejs +38 -26
- package/templates/mvc/js/src/routes/api.js +0 -66
- package/templates/mvc/ts/src/config/swagger.ts.ejs +4 -21
- package/templates/mvc/ts/src/controllers/userController.ts.ejs +56 -1
- package/templates/mvc/ts/src/graphql/context.ts.ejs +12 -0
- package/templates/mvc/ts/src/graphql/index.ts.ejs +3 -0
- package/templates/mvc/ts/src/graphql/resolvers/index.ts.ejs +4 -0
- package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.ts.ejs +27 -0
- package/templates/mvc/ts/src/graphql/typeDefs/index.ts.ejs +4 -0
- package/templates/mvc/ts/src/graphql/typeDefs/user.types.ts.ejs +15 -0
- package/templates/mvc/ts/src/index.ts.ejs +54 -26
- package/templates/mvc/ts/src/routes/api.ts +0 -66
|
@@ -3,27 +3,41 @@ const cors = require('cors');
|
|
|
3
3
|
require('dotenv').config();
|
|
4
4
|
const logger = require('../log/logger');
|
|
5
5
|
const morgan = require('morgan');
|
|
6
|
-
<% if (communication === 'REST APIs') {
|
|
7
|
-
<% if (communication === 'REST APIs') { -%>
|
|
6
|
+
<%_ if (communication === 'REST APIs') { -%>const apiRoutes = require('../../interfaces/routes/api');<%_ } -%>
|
|
7
|
+
<%_ if (communication === 'REST APIs') { -%>
|
|
8
8
|
const swaggerUi = require('swagger-ui-express');
|
|
9
9
|
const swaggerSpecs = require('./swagger');
|
|
10
|
-
<% } -%>
|
|
10
|
+
<%_ } -%>
|
|
11
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
12
|
+
const { ApolloServer } = require('@apollo/server');
|
|
13
|
+
const { expressMiddleware } = require('@apollo/server/express4');
|
|
14
|
+
const { ApolloServerPluginLandingPageLocalDefault } = require('@apollo/server/plugin/landingPage/default');
|
|
15
|
+
const { typeDefs, resolvers } = require('../../interfaces/graphql');
|
|
16
|
+
const { gqlContext } = require('../../interfaces/graphql/context');
|
|
17
|
+
<%_ } -%>
|
|
11
18
|
|
|
12
|
-
const startServer = (port) => {
|
|
19
|
+
const startServer = async (port) => {
|
|
13
20
|
const app = express();
|
|
14
21
|
|
|
15
22
|
app.use(cors());
|
|
16
23
|
app.use(express.json());
|
|
17
24
|
app.use(morgan('combined', { stream: { write: message => logger.info(message.trim()) } }));
|
|
18
|
-
|
|
19
|
-
<% if (communication === 'REST APIs') { -%>
|
|
25
|
+
<%_ if (communication === 'REST APIs') { -%>
|
|
20
26
|
app.use('/api', apiRoutes);
|
|
21
|
-
<% } -%>
|
|
22
|
-
|
|
23
|
-
<% if (communication === 'REST APIs') { -%>
|
|
27
|
+
<%_ } -%>
|
|
28
|
+
<%_ if (communication === 'REST APIs') { -%>
|
|
24
29
|
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs));
|
|
25
|
-
<% } -%>
|
|
26
|
-
|
|
30
|
+
<%_ } -%>
|
|
31
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
32
|
+
// GraphQL Setup
|
|
33
|
+
const server = new ApolloServer({
|
|
34
|
+
typeDefs,
|
|
35
|
+
resolvers,
|
|
36
|
+
plugins: [ApolloServerPluginLandingPageLocalDefault({ embed: true })],
|
|
37
|
+
});
|
|
38
|
+
await server.start();
|
|
39
|
+
app.use('/graphql', expressMiddleware(server, { context: gqlContext }));
|
|
40
|
+
<%_ } -%>
|
|
27
41
|
app.get('/health', (req, res) => {
|
|
28
42
|
res.json({ status: 'UP' });
|
|
29
43
|
});
|
|
@@ -1,23 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const YAML = require('yamljs');
|
|
2
3
|
|
|
3
|
-
const
|
|
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
|
-
};
|
|
4
|
+
const swaggerDocument = YAML.load(path.join(__dirname, 'swagger.yml'));
|
|
20
5
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
module.exports = specs;
|
|
6
|
+
module.exports = swaggerDocument;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
const CreateUser = require('../../usecases/CreateUser');
|
|
2
2
|
const GetAllUsers = require('../../usecases/GetAllUsers');
|
|
3
3
|
const UserRepository = require('../../infrastructure/repositories/UserRepository');
|
|
4
|
+
<% if (communication !== 'GraphQL') { -%>
|
|
4
5
|
const HTTP_STATUS = require('../../utils/httpCodes');
|
|
6
|
+
<% } -%>
|
|
5
7
|
const logger = require('../../infrastructure/log/logger');
|
|
6
8
|
|
|
7
9
|
class UserController {
|
|
@@ -11,6 +13,26 @@ class UserController {
|
|
|
11
13
|
this.getAllUsersUseCase = new GetAllUsers(this.userRepository);
|
|
12
14
|
}
|
|
13
15
|
|
|
16
|
+
<% if (communication === 'GraphQL') { -%>
|
|
17
|
+
async getUsers() {
|
|
18
|
+
try {
|
|
19
|
+
return await this.getAllUsersUseCase.execute();
|
|
20
|
+
} catch (error) {
|
|
21
|
+
logger.error('Error getting users:', error);
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async createUser(data) {
|
|
27
|
+
const { name, email } = data;
|
|
28
|
+
try {
|
|
29
|
+
return await this.createUserUseCase.execute(name, email);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
logger.error('Error creating user:', error);
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
<% } else { -%>
|
|
14
36
|
getUsers(req, res) {
|
|
15
37
|
this.getAllUsersUseCase.execute()
|
|
16
38
|
.then(users => res.json(users))
|
|
@@ -30,6 +52,7 @@ class UserController {
|
|
|
30
52
|
res.status(HTTP_STATUS.BAD_REQUEST).json({ error: error.message });
|
|
31
53
|
}
|
|
32
54
|
}
|
|
55
|
+
<% } -%>
|
|
33
56
|
}
|
|
34
57
|
|
|
35
58
|
module.exports = UserController;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const UserRepository = require('../../infrastructure/repositories/UserRepository');
|
|
2
|
+
|
|
3
|
+
const gqlContext = async ({ req }) => {
|
|
4
|
+
const token = req.headers.authorization || '';
|
|
5
|
+
const userRepository = new UserRepository();
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
token,
|
|
9
|
+
userRepository
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
module.exports = { gqlContext };
|
package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const { GraphQLError } = require('graphql');
|
|
2
|
+
const UserController = require('../../controllers/userController');
|
|
3
|
+
|
|
4
|
+
const userController = new UserController();
|
|
5
|
+
|
|
6
|
+
const userResolvers = {
|
|
7
|
+
Query: {
|
|
8
|
+
getAllUsers: async () => {
|
|
9
|
+
try {
|
|
10
|
+
return await userController.getUsers();
|
|
11
|
+
} catch (error) {
|
|
12
|
+
throw new GraphQLError(error.message || 'Internal server error', { extensions: { code: 'INTERNAL_SERVER_ERROR' } });
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
Mutation: {
|
|
17
|
+
createUser: async (_, { name, email }) => {
|
|
18
|
+
try {
|
|
19
|
+
return await userController.createUser({ name, email });
|
|
20
|
+
} catch (error) {
|
|
21
|
+
throw new GraphQLError(error.message || 'Internal server error', { extensions: { code: 'INTERNAL_SERVER_ERROR' } });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
module.exports = { userResolvers };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const userTypes = `#graphql
|
|
2
|
+
type User {
|
|
3
|
+
id: ID!
|
|
4
|
+
name: String!
|
|
5
|
+
email: String!
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
type Query {
|
|
9
|
+
getAllUsers: [User]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type Mutation {
|
|
13
|
+
createUser(name: String!, email: String!): User
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
module.exports = { userTypes };
|
|
@@ -2,75 +2,8 @@ const express = require('express');
|
|
|
2
2
|
const router = express.Router();
|
|
3
3
|
const UserController = require('../controllers/userController');
|
|
4
4
|
|
|
5
|
-
// Should inject dependencies here in a real app
|
|
6
5
|
const userController = new UserController();
|
|
7
6
|
|
|
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
7
|
router.post('/users', (req, res) => userController.createUser(req, res));
|
|
75
8
|
router.get('/users', (req, res) => userController.getUsers(req, res));
|
|
76
9
|
|
|
@@ -1,23 +1,6 @@
|
|
|
1
|
-
<% if (communication === 'REST APIs') { %>import
|
|
1
|
+
<% if (communication === 'REST APIs') { %>import path from 'path';
|
|
2
|
+
import YAML from 'yamljs';
|
|
2
3
|
|
|
3
|
-
const
|
|
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/*.ts', './dist/interfaces/routes/*.js'], // Path to the API docs
|
|
19
|
-
};
|
|
4
|
+
const swaggerDocument = YAML.load(path.join(__dirname, 'swagger.yml'));
|
|
20
5
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export default specs;<% } %>
|
|
6
|
+
export default swaggerDocument;<% } %>
|
|
@@ -6,11 +6,18 @@ import rateLimit from 'express-rate-limit';
|
|
|
6
6
|
import dotenv from 'dotenv';
|
|
7
7
|
import logger from '@/infrastructure/log/logger';
|
|
8
8
|
import morgan from 'morgan';
|
|
9
|
-
<% if (communication === 'REST APIs') {
|
|
9
|
+
<%_ if (communication === 'REST APIs') { -%>import userRoutes from '@/interfaces/routes/userRoutes';<%_ } -%>
|
|
10
10
|
<% if (communication === 'REST APIs') { -%>
|
|
11
11
|
import swaggerUi from 'swagger-ui-express';
|
|
12
12
|
import swaggerSpecs from '@/config/swagger';<% } -%>
|
|
13
|
-
<% if (communication === 'Kafka') {
|
|
13
|
+
<%_ if (communication === 'Kafka') { -%>import { KafkaService } from '@/infrastructure/messaging/kafkaClient';<%_ } -%>
|
|
14
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
15
|
+
import { ApolloServer } from '@apollo/server';
|
|
16
|
+
import { expressMiddleware } from '@apollo/server/express4';
|
|
17
|
+
import { ApolloServerPluginLandingPageLocalDefault } from '@apollo/server/plugin/landingPage/default';
|
|
18
|
+
import { typeDefs, resolvers } from '@/interfaces/graphql';
|
|
19
|
+
import { gqlContext, MyContext } from '@/interfaces/graphql/context';
|
|
20
|
+
<% } -%>
|
|
14
21
|
|
|
15
22
|
dotenv.config();
|
|
16
23
|
|
|
@@ -18,7 +25,21 @@ const app = express();
|
|
|
18
25
|
const port = process.env.PORT || 3000;
|
|
19
26
|
|
|
20
27
|
// Security Middleware
|
|
28
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
29
|
+
app.use(helmet({
|
|
30
|
+
crossOriginEmbedderPolicy: false,
|
|
31
|
+
contentSecurityPolicy: {
|
|
32
|
+
directives: {
|
|
33
|
+
imgSrc: [`'self'`, 'data:', 'apollo-server-landing-page.cdn.apollographql.com'],
|
|
34
|
+
scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
|
|
35
|
+
manifestSrc: [`'self'`, 'apollo-server-landing-page.cdn.apollographql.com'],
|
|
36
|
+
frameSrc: [`'self'`, 'sandbox.embed.apollographql.com'],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
}));
|
|
40
|
+
<%_ } else { -%>
|
|
21
41
|
app.use(helmet());
|
|
42
|
+
<%_ } -%>
|
|
22
43
|
app.use(hpp());
|
|
23
44
|
app.use(cors({ origin: '*', methods: ['GET', 'POST', 'PUT', 'DELETE'] }));
|
|
24
45
|
const limiter = rateLimit({ windowMs: 10 * 60 * 1000, max: 100 });
|
|
@@ -27,32 +48,42 @@ app.use(limiter);
|
|
|
27
48
|
app.use(express.json());
|
|
28
49
|
app.use(morgan('combined', { stream: { write: (message) => logger.info(message.trim()) } }));
|
|
29
50
|
|
|
30
|
-
<% if (communication === 'REST APIs') { -%>
|
|
51
|
+
<%_ if (communication === 'REST APIs') { -%>
|
|
31
52
|
app.use('/api/users', userRoutes);
|
|
32
|
-
<% } -%>
|
|
33
|
-
|
|
34
|
-
<% if (communication === 'REST APIs') { -%>
|
|
53
|
+
<%_ } -%>
|
|
54
|
+
<%_ if (communication === 'REST APIs') { -%>
|
|
35
55
|
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs));
|
|
36
|
-
<% } -%>
|
|
37
|
-
|
|
56
|
+
<%_ } -%>
|
|
38
57
|
app.get('/health', (req: Request, res: Response) => {
|
|
39
58
|
res.json({ status: 'UP' });
|
|
40
59
|
});
|
|
41
60
|
|
|
42
61
|
// Start Server Logic
|
|
43
62
|
const startServer = async () => {
|
|
44
|
-
|
|
63
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
64
|
+
// GraphQL Setup
|
|
65
|
+
const server = new ApolloServer<MyContext>({
|
|
66
|
+
typeDefs,
|
|
67
|
+
resolvers,
|
|
68
|
+
plugins: [ApolloServerPluginLandingPageLocalDefault({ embed: true })],
|
|
69
|
+
});
|
|
70
|
+
await server.start();
|
|
71
|
+
app.use('/graphql', expressMiddleware(server, { context: gqlContext }));
|
|
72
|
+
<%_ } -%>
|
|
73
|
+
app.listen(port, () => {
|
|
74
|
+
logger.info(`Server running on port ${port}`);
|
|
45
75
|
<%_ if (communication === 'Kafka') { -%>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
76
|
+
try {
|
|
77
|
+
const kafkaService = new KafkaService();
|
|
78
|
+
kafkaService.connect().then(() => {
|
|
79
|
+
logger.info('Kafka connected');
|
|
80
|
+
kafkaService.sendMessage('test-topic', 'Hello Kafka from Clean Arch TS!');
|
|
81
|
+
});
|
|
82
|
+
} catch (err) {
|
|
83
|
+
logger.error('Failed to connect to Kafka:', err);
|
|
84
|
+
}
|
|
55
85
|
<%_ } -%>
|
|
86
|
+
});
|
|
56
87
|
};
|
|
57
88
|
|
|
58
89
|
<%_ if (database !== 'None') { -%>
|
|
@@ -69,7 +100,7 @@ const syncDatabase = async () => {
|
|
|
69
100
|
await sequelize.sync();
|
|
70
101
|
<%_ } -%>
|
|
71
102
|
logger.info('Database synced');
|
|
72
|
-
|
|
103
|
+
await startServer();
|
|
73
104
|
break;
|
|
74
105
|
} catch (error) {
|
|
75
106
|
logger.error('Error syncing database:', error);
|
|
@@ -82,5 +113,5 @@ const syncDatabase = async () => {
|
|
|
82
113
|
|
|
83
114
|
syncDatabase();
|
|
84
115
|
<%_ } else { -%>
|
|
85
|
-
|
|
116
|
+
startServer();
|
|
86
117
|
<%_ } -%>
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
<% if (communication !== 'GraphQL') { -%>
|
|
1
2
|
import { Request, Response } from 'express';
|
|
3
|
+
import { HTTP_STATUS } from '@/utils/httpCodes';
|
|
4
|
+
<% } -%>
|
|
2
5
|
import { UserRepository } from '@/infrastructure/repositories/UserRepository';
|
|
3
6
|
import CreateUser from '@/usecases/createUser';
|
|
4
7
|
import GetAllUsers from '@/usecases/getAllUsers';
|
|
5
|
-
import { HTTP_STATUS } from '@/utils/httpCodes';
|
|
6
8
|
import logger from '@/infrastructure/log/logger';
|
|
7
9
|
|
|
8
10
|
export class UserController {
|
|
@@ -15,6 +17,30 @@ export class UserController {
|
|
|
15
17
|
this.getAllUsersUseCase = new GetAllUsers(userRepository);
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
<% if (communication === 'GraphQL') { -%>
|
|
21
|
+
async createUser(data: { name: string, email: string }) {
|
|
22
|
+
try {
|
|
23
|
+
const { name, email } = data;
|
|
24
|
+
const user = await this.createUserUseCase.execute(name, email);
|
|
25
|
+
return user;
|
|
26
|
+
} catch (error: unknown) {
|
|
27
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
28
|
+
logger.error('UserController Error:', message);
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async getUsers() {
|
|
34
|
+
try {
|
|
35
|
+
const users = await this.getAllUsersUseCase.execute();
|
|
36
|
+
return users;
|
|
37
|
+
} catch (error: unknown) {
|
|
38
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
39
|
+
logger.error('UserController Error:', message);
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
<% } else { -%>
|
|
18
44
|
async createUser(req: Request, res: Response) {
|
|
19
45
|
try {
|
|
20
46
|
const { name, email } = req.body;
|
|
@@ -43,4 +69,5 @@ export class UserController {
|
|
|
43
69
|
}
|
|
44
70
|
}
|
|
45
71
|
}
|
|
72
|
+
<% } -%>
|
|
46
73
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Request } from 'express';
|
|
2
|
+
import { UserRepository } from '@/infrastructure/repositories/UserRepository';
|
|
3
|
+
|
|
4
|
+
export interface MyContext {
|
|
5
|
+
token?: string;
|
|
6
|
+
userRepository: UserRepository;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const gqlContext = async ({ req }: { req: Request }): Promise<MyContext> => {
|
|
10
|
+
const token = req.headers.authorization || '';
|
|
11
|
+
const userRepository = new UserRepository();
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
token,
|
|
15
|
+
userRepository
|
|
16
|
+
};
|
|
17
|
+
};
|
package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { GraphQLError } from 'graphql';
|
|
2
|
+
import { UserController } from '@/interfaces/controllers/userController';
|
|
3
|
+
|
|
4
|
+
const userController = new UserController();
|
|
5
|
+
|
|
6
|
+
export const userResolvers = {
|
|
7
|
+
Query: {
|
|
8
|
+
getAllUsers: async () => {
|
|
9
|
+
try {
|
|
10
|
+
return await userController.getUsers();
|
|
11
|
+
} catch (error: unknown) {
|
|
12
|
+
const message = error instanceof Error ? error.message : 'Internal server error';
|
|
13
|
+
throw new GraphQLError(message, { extensions: { code: 'INTERNAL_SERVER_ERROR' } });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
Mutation: {
|
|
18
|
+
createUser: async (_: unknown, { name, email }: { name: string, email: string }) => {
|
|
19
|
+
try {
|
|
20
|
+
return await userController.createUser({ name, email });
|
|
21
|
+
} catch (error: unknown) {
|
|
22
|
+
const message = error instanceof Error ? error.message : 'Internal server error';
|
|
23
|
+
throw new GraphQLError(message, { extensions: { code: 'INTERNAL_SERVER_ERROR' } });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -4,72 +4,6 @@ import { UserController } from '@/interfaces/controllers/userController';
|
|
|
4
4
|
const router = Router();
|
|
5
5
|
const userController = new UserController();
|
|
6
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
7
|
router.post('/', (req: Request, res: Response) => userController.createUser(req, res));
|
|
74
8
|
router.get('/', (req: Request, res: Response) => userController.getUsers(req, res));
|
|
75
9
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ==========================================
|
|
2
2
|
# Stage 1: Builder
|
|
3
3
|
# ==========================================
|
|
4
|
-
FROM node:
|
|
4
|
+
FROM node:22-alpine AS builder
|
|
5
5
|
|
|
6
6
|
WORKDIR /app
|
|
7
7
|
|
|
@@ -19,7 +19,7 @@ COPY . .
|
|
|
19
19
|
# ==========================================
|
|
20
20
|
# Stage 2: Production
|
|
21
21
|
# ==========================================
|
|
22
|
-
FROM node:
|
|
22
|
+
FROM node:22-alpine AS production
|
|
23
23
|
|
|
24
24
|
WORKDIR /app
|
|
25
25
|
|