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.
Files changed (54) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +7 -7
  3. package/bin/index.js +2 -2
  4. package/docs/generateCase.md +160 -164
  5. package/lib/generator.js +1 -1
  6. package/lib/modules/app-setup.js +84 -10
  7. package/lib/prompts.js +1 -1
  8. package/package.json +4 -2
  9. package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +25 -11
  10. package/templates/clean-architecture/js/src/infrastructure/webserver/swagger.js +4 -21
  11. package/templates/clean-architecture/js/src/interfaces/controllers/{userController.js → userController.js.ejs} +23 -0
  12. package/templates/clean-architecture/js/src/interfaces/graphql/context.js.ejs +13 -0
  13. package/templates/clean-architecture/js/src/interfaces/graphql/index.js.ejs +5 -0
  14. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/index.js.ejs +6 -0
  15. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs +27 -0
  16. package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/index.js.ejs +6 -0
  17. package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/user.types.js.ejs +17 -0
  18. package/templates/clean-architecture/js/src/interfaces/routes/api.js +0 -67
  19. package/templates/clean-architecture/ts/src/config/swagger.ts.ejs +4 -21
  20. package/templates/clean-architecture/ts/src/index.ts.ejs +51 -20
  21. package/templates/clean-architecture/ts/src/interfaces/controllers/{userController.ts → userController.ts.ejs} +28 -1
  22. package/templates/clean-architecture/ts/src/interfaces/graphql/context.ts.ejs +17 -0
  23. package/templates/clean-architecture/ts/src/interfaces/graphql/index.ts.ejs +3 -0
  24. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/index.ts.ejs +4 -0
  25. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs +27 -0
  26. package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/index.ts.ejs +4 -0
  27. package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/user.types.ts.ejs +15 -0
  28. package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +0 -66
  29. package/templates/common/Dockerfile +2 -2
  30. package/templates/common/README.md.ejs +27 -0
  31. package/templates/common/database/js/mongoose.js.ejs +0 -1
  32. package/templates/common/database/ts/mongoose.ts.ejs +0 -1
  33. package/templates/common/package.json.ejs +7 -4
  34. package/templates/common/swagger.yml.ejs +66 -0
  35. package/templates/mvc/js/src/config/swagger.js +4 -21
  36. package/templates/mvc/js/src/controllers/userController.js.ejs +55 -0
  37. package/templates/mvc/js/src/graphql/context.js.ejs +7 -0
  38. package/templates/mvc/js/src/graphql/index.js.ejs +5 -0
  39. package/templates/mvc/js/src/graphql/resolvers/index.js.ejs +6 -0
  40. package/templates/mvc/js/src/graphql/resolvers/user.resolvers.js.ejs +25 -0
  41. package/templates/mvc/js/src/graphql/typeDefs/index.js.ejs +6 -0
  42. package/templates/mvc/js/src/graphql/typeDefs/user.types.js.ejs +17 -0
  43. package/templates/mvc/js/src/index.js.ejs +38 -26
  44. package/templates/mvc/js/src/routes/api.js +0 -66
  45. package/templates/mvc/ts/src/config/swagger.ts.ejs +4 -21
  46. package/templates/mvc/ts/src/controllers/userController.ts.ejs +56 -1
  47. package/templates/mvc/ts/src/graphql/context.ts.ejs +12 -0
  48. package/templates/mvc/ts/src/graphql/index.ts.ejs +3 -0
  49. package/templates/mvc/ts/src/graphql/resolvers/index.ts.ejs +4 -0
  50. package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.ts.ejs +27 -0
  51. package/templates/mvc/ts/src/graphql/typeDefs/index.ts.ejs +4 -0
  52. package/templates/mvc/ts/src/graphql/typeDefs/user.types.ts.ejs +15 -0
  53. package/templates/mvc/ts/src/index.ts.ejs +54 -26
  54. 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') { %>const apiRoutes = require('../../interfaces/routes/api');<% } -%>
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 swaggerJsdoc = require('swagger-jsdoc');
1
+ const path = require('path');
2
+ const YAML = require('yamljs');
2
3
 
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
- };
4
+ const swaggerDocument = YAML.load(path.join(__dirname, 'swagger.yml'));
20
5
 
21
- const specs = swaggerJsdoc(options);
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 };
@@ -0,0 +1,5 @@
1
+ const { typeDefs } = require('./typeDefs');
2
+ const { resolvers } = require('./resolvers');
3
+ const { gqlContext } = require('./context');
4
+
5
+ module.exports = { typeDefs, resolvers, gqlContext };
@@ -0,0 +1,6 @@
1
+ const { mergeResolvers } = require('@graphql-tools/merge');
2
+ const { userResolvers } = require('./user.resolvers');
3
+
4
+ const resolvers = mergeResolvers([userResolvers]);
5
+
6
+ module.exports = { resolvers };
@@ -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,6 @@
1
+ const { mergeTypeDefs } = require('@graphql-tools/merge');
2
+ const { userTypes } = require('./user.types');
3
+
4
+ const typeDefs = mergeTypeDefs([userTypes]);
5
+
6
+ module.exports = { typeDefs };
@@ -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 swaggerJsdoc from 'swagger-jsdoc';
1
+ <% if (communication === 'REST APIs') { %>import path from 'path';
2
+ import YAML from 'yamljs';
2
3
 
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/*.ts', './dist/interfaces/routes/*.js'], // Path to the API docs
19
- };
4
+ const swaggerDocument = YAML.load(path.join(__dirname, 'swagger.yml'));
20
5
 
21
- const specs = swaggerJsdoc(options);
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') { %>import userRoutes from '@/interfaces/routes/userRoutes';<% } -%>
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') { %>import { KafkaService } from '@/infrastructure/messaging/kafkaClient';<% } -%>
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
- logger.info(`Server running on port ${port}`);
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
- try {
47
- const kafkaService = new KafkaService();
48
- await kafkaService.connect();
49
- logger.info('Kafka connected');
50
- // Demo
51
- await kafkaService.sendMessage('test-topic', 'Hello Kafka from Clean Arch TS!');
52
- } catch (err) {
53
- logger.error('Failed to connect to Kafka:', err);
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
- app.listen(port, startServer);
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
- app.listen(port, startServer);
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
+ };
@@ -0,0 +1,3 @@
1
+ export { typeDefs } from '@/interfaces/graphql/typeDefs';
2
+ export { resolvers } from '@/interfaces/graphql/resolvers';
3
+ export { gqlContext, MyContext } from '@/interfaces/graphql/context';
@@ -0,0 +1,4 @@
1
+ import { mergeResolvers } from '@graphql-tools/merge';
2
+ import { userResolvers } from '@/interfaces/graphql/resolvers/user.resolvers';
3
+
4
+ export const resolvers = mergeResolvers([userResolvers]);
@@ -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
+ };
@@ -0,0 +1,4 @@
1
+ import { mergeTypeDefs } from '@graphql-tools/merge';
2
+ import { userTypes } from './user.types';
3
+
4
+ export const typeDefs = mergeTypeDefs([userTypes]);
@@ -0,0 +1,15 @@
1
+ export 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
+ `;
@@ -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:18-alpine AS builder
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:18-alpine AS production
22
+ FROM node:22-alpine AS production
23
23
 
24
24
  WORKDIR /app
25
25