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
@@ -0,0 +1,27 @@
1
+ import { GraphQLError } from 'graphql';
2
+ import { UserController } from '@/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 '@/graphql/typeDefs/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
+ `;
@@ -6,11 +6,19 @@ import rateLimit from 'express-rate-limit';
6
6
  import dotenv from 'dotenv';
7
7
  import logger from '@/utils/logger';
8
8
  import morgan from 'morgan';
9
- <% if (communication === 'REST APIs' || (viewEngine && viewEngine !== 'None')) { %>import apiRoutes from '@/routes/api';<% } -%>
9
+ <%_ if (communication === 'REST APIs') { -%>
10
+ import apiRoutes from '@/routes/api';<%_ } -%>
10
11
  <% if (communication === 'REST APIs') { %>
11
12
  import swaggerUi from 'swagger-ui-express';
12
13
  import swaggerSpecs from '@/config/swagger';<% } -%>
13
- <% if (communication === 'Kafka') { %>import { KafkaService } from '@/services/kafkaService';<% } -%>
14
+ <%_ if (communication === 'Kafka') { -%>import { KafkaService } from '@/services/kafkaService';<%_ } -%>
15
+ <%_ if (communication === 'GraphQL') { -%>
16
+ import { ApolloServer } from '@apollo/server';
17
+ import { expressMiddleware } from '@apollo/server/express4';
18
+ import { ApolloServerPluginLandingPageLocalDefault } from '@apollo/server/plugin/landingPage/default';
19
+ import { typeDefs, resolvers } from '@/graphql';
20
+ import { gqlContext, MyContext } from '@/graphql/context';
21
+ <% } -%>
14
22
 
15
23
  dotenv.config();
16
24
 
@@ -18,7 +26,21 @@ const app = express();
18
26
  const port = process.env.PORT || 3000;
19
27
 
20
28
  // Security Middleware
29
+ <%_ if (communication === 'GraphQL') { -%>
30
+ app.use(helmet({
31
+ crossOriginEmbedderPolicy: false,
32
+ contentSecurityPolicy: {
33
+ directives: {
34
+ imgSrc: [`'self'`, 'data:', 'apollo-server-landing-page.cdn.apollographql.com'],
35
+ scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
36
+ manifestSrc: [`'self'`, 'apollo-server-landing-page.cdn.apollographql.com'],
37
+ frameSrc: [`'self'`, 'sandbox.embed.apollographql.com'],
38
+ },
39
+ },
40
+ }));
41
+ <%_ } else { -%>
21
42
  app.use(helmet());
43
+ <%_ } -%>
22
44
  app.use(hpp());
23
45
  app.use(cors({ origin: '*', methods: ['GET', 'POST', 'PUT', 'DELETE'] }));
24
46
  const limiter = rateLimit({ windowMs: 10 * 60 * 1000, max: 100 });
@@ -26,23 +48,18 @@ app.use(limiter);
26
48
 
27
49
  app.use(express.json());
28
50
  app.use(morgan('combined', { stream: { write: (message) => logger.info(message.trim()) } }));
29
-
30
- <% if (communication === 'REST APIs') { -%>
51
+ <%_ if (communication === 'REST APIs') { -%>
31
52
  app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs));
32
- <% } -%>
33
-
34
- <% if (viewEngine === 'EJS' || viewEngine === 'Pug') { -%>
53
+ <%_ } -%>
54
+ <%_ if (viewEngine === 'EJS' || viewEngine === 'Pug') { -%>
35
55
  // View Engine Setup
36
56
  import path from 'path';
37
57
  app.set('views', path.join(__dirname, 'views'));
38
58
  app.set('view engine', '<%= viewEngine.toLowerCase() %>');
39
- app.use(express.static(path.join(__dirname, '../public')));<% } -%>
40
-
41
- // Routes
42
- <% if (communication === 'REST APIs' || (viewEngine && viewEngine !== 'None')) { -%>
59
+ app.use(express.static(path.join(__dirname, '../public')));<%_ } %>
60
+ <%_ if (communication === 'REST APIs') { -%>
43
61
  app.use('/api', apiRoutes);
44
- <% } -%>
45
- <% if (viewEngine && viewEngine !== 'None') { -%>
62
+ <%_ } -%><% if (viewEngine && viewEngine !== 'None') { -%>
46
63
  app.get('/', (req: Request, res: Response) => {
47
64
  res.render('index', {
48
65
  projectName: 'NodeJS Service',
@@ -52,25 +69,36 @@ app.get('/', (req: Request, res: Response) => {
52
69
  });
53
70
  });
54
71
  <% } -%>
55
-
56
72
  app.get('/health', (req: Request, res: Response) => {
57
73
  res.json({ status: 'UP' });
58
74
  });
59
75
 
60
76
  // Start Server Logic
61
77
  const startServer = async () => {
62
- logger.info(`Server running on port ${port}`);
78
+ <%_ if (communication === 'GraphQL') { -%>
79
+ // GraphQL Setup
80
+ const server = new ApolloServer<MyContext>({
81
+ typeDefs,
82
+ resolvers,
83
+ plugins: [ApolloServerPluginLandingPageLocalDefault({ embed: true })],
84
+ });
85
+ await server.start();
86
+ app.use('/graphql', expressMiddleware(server, { context: gqlContext }));
87
+ <%_ } -%>
88
+ app.listen(port, () => {
89
+ logger.info(`Server running on port ${port}`);
63
90
  <%_ if (communication === 'Kafka') { -%>
64
- try {
65
- const kafkaService = new KafkaService();
66
- await kafkaService.connect();
67
- logger.info('Kafka connected');
68
- // Demo: Send a test message
69
- await kafkaService.sendMessage('test-topic', 'Hello Kafka from MVC TS!');
70
- } catch (err) {
71
- logger.error('Failed to connect to Kafka:', err);
72
- }
91
+ try {
92
+ const kafkaService = new KafkaService();
93
+ kafkaService.connect().then(() => {
94
+ logger.info('Kafka connected');
95
+ kafkaService.sendMessage('test-topic', 'Hello Kafka from MVC TS!');
96
+ });
97
+ } catch (err) {
98
+ logger.error('Failed to connect to Kafka:', err);
99
+ }
73
100
  <%_ } -%>
101
+ });
74
102
  };
75
103
 
76
104
  <%_ if (database !== 'None') { -%>
@@ -88,7 +116,7 @@ const syncDatabase = async () => {
88
116
  <%_ } -%>
89
117
  logger.info('Database synced');
90
118
  // Start Server after DB is ready
91
- app.listen(port, startServer);
119
+ await startServer();
92
120
  break;
93
121
  } catch (error) {
94
122
  logger.error('Error syncing database:', error);
@@ -101,5 +129,5 @@ const syncDatabase = async () => {
101
129
 
102
130
  syncDatabase();
103
131
  <%_ } else { -%>
104
- app.listen(port, startServer);
132
+ startServer();
105
133
  <%_ } -%>
@@ -4,72 +4,6 @@ import { UserController } from '@/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.get('/users', (req: Request, res: Response) => userController.getUsers(req, res));
74
8
  router.post('/users', (req: Request, res: Response) => userController.createUser(req, res));
75
9