nodejs-quickstart-structure 1.3.5 → 1.4.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.
Files changed (37) hide show
  1. package/README.md +4 -4
  2. package/docs/generateCase.md +54 -38
  3. package/docs/generatorFlow.md +171 -0
  4. package/lib/generator.js +46 -18
  5. package/lib/prompts.js +1 -1
  6. package/package.json +4 -3
  7. package/templates/clean-architecture/js/src/index.js.ejs +5 -0
  8. package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.js.ejs +11 -2
  9. package/templates/clean-architecture/ts/src/domain/user.ts +1 -1
  10. package/templates/clean-architecture/ts/src/index.ts.ejs +10 -5
  11. package/templates/clean-architecture/ts/src/infrastructure/repositories/userRepository.ts.ejs +13 -4
  12. package/templates/clean-architecture/ts/src/interfaces/controllers/userController.ts +5 -5
  13. package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +1 -1
  14. package/templates/clean-architecture/ts/src/usecases/createUser.ts +2 -2
  15. package/templates/clean-architecture/ts/src/usecases/getAllUsers.ts +1 -1
  16. package/templates/common/Dockerfile +1 -0
  17. package/templates/common/README.md.ejs +1 -1
  18. package/templates/common/database/js/models/User.js.mongoose.ejs +19 -0
  19. package/templates/common/database/js/mongoose.js.ejs +32 -0
  20. package/templates/common/database/ts/models/User.ts.ejs +1 -1
  21. package/templates/common/database/ts/models/User.ts.mongoose.ejs +25 -0
  22. package/templates/common/database/ts/mongoose.ts.ejs +27 -0
  23. package/templates/common/docker-compose.yml.ejs +31 -8
  24. package/templates/common/jest.config.js.ejs +4 -1
  25. package/templates/common/kafka/ts/services/kafkaService.ts.ejs +1 -1
  26. package/templates/common/migrate-mongo-config.js.ejs +31 -0
  27. package/templates/common/migrations/init.js.ejs +23 -0
  28. package/templates/common/package.json.ejs +12 -6
  29. package/templates/common/public/css/style.css +147 -0
  30. package/templates/common/tsconfig.json +5 -1
  31. package/templates/common/views/ejs/index.ejs +44 -20
  32. package/templates/common/views/pug/index.pug +32 -18
  33. package/templates/mvc/js/src/controllers/userController.js.ejs +3 -1
  34. package/templates/mvc/js/src/index.js.ejs +6 -1
  35. package/templates/mvc/ts/src/controllers/userController.ts.ejs +6 -4
  36. package/templates/mvc/ts/src/index.ts.ejs +11 -7
  37. package/templates/mvc/ts/src/routes/api.ts +1 -1
@@ -0,0 +1,19 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const UserSchema = new mongoose.Schema({
4
+ name: {
5
+ type: String,
6
+ required: true
7
+ },
8
+ email: {
9
+ type: String,
10
+ required: true,
11
+ unique: true
12
+ },
13
+ createdAt: {
14
+ type: Date,
15
+ default: Date.now
16
+ }
17
+ });
18
+
19
+ module.exports = mongoose.model('User', UserSchema);
@@ -0,0 +1,32 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ let logger;
4
+ <% if (architecture === 'MVC') { %>
5
+ logger = require('../utils/logger');
6
+ <% } else { %>
7
+ logger = require('../log/logger');
8
+ <% } %>
9
+
10
+ const connectDB = async () => {
11
+ const dbHost = process.env.DB_HOST || 'localhost';
12
+ const mongoURI = process.env.MONGO_URI || `mongodb://${dbHost}:27017/<%= dbName %>`;
13
+
14
+ let retries = 5;
15
+ while (retries) {
16
+ try {
17
+ await mongoose.connect(mongoURI, {
18
+ useNewUrlParser: true,
19
+ useUnifiedTopology: true
20
+ });
21
+ logger.info('MongoDB Connected...');
22
+ break;
23
+ } catch (err) {
24
+ logger.error('MongoDB connection failed:', err);
25
+ retries -= 1;
26
+ logger.info(`Retries left: ${retries}. Waiting 5s...`);
27
+ await new Promise(res => setTimeout(res, 5000));
28
+ }
29
+ }
30
+ };
31
+
32
+ module.exports = connectDB; // Export function to call in index.js
@@ -1,5 +1,5 @@
1
1
  import { DataTypes, Model } from 'sequelize';
2
- <% if (architecture === 'MVC') { %>import sequelize from '../config/database';<% } else { %>import sequelize from '../database';<% } %>
2
+ <% if (architecture === 'MVC') { %>import sequelize from '@/config/database';<% } else { %>import sequelize from '@/infrastructure/database/database';<% } %>
3
3
 
4
4
  class User extends Model {
5
5
  public id!: number;
@@ -0,0 +1,25 @@
1
+ import mongoose, { Schema, Document } from 'mongoose';
2
+
3
+ export interface IUser extends Document {
4
+ name: string;
5
+ email: string;
6
+ createdAt: Date;
7
+ }
8
+
9
+ const UserSchema: Schema = new Schema({
10
+ name: {
11
+ type: String,
12
+ required: true
13
+ },
14
+ email: {
15
+ type: String,
16
+ required: true,
17
+ unique: true
18
+ },
19
+ createdAt: {
20
+ type: Date,
21
+ default: Date.now
22
+ }
23
+ });
24
+
25
+ export default mongoose.model<IUser>('User', UserSchema);
@@ -0,0 +1,27 @@
1
+ import mongoose from 'mongoose';
2
+ <% if (architecture === 'MVC') { %>
3
+ import logger from '@/utils/logger';
4
+ <% } else { %>
5
+ import logger from '@/infrastructure/log/logger';
6
+ <% } %>
7
+
8
+ const connectDB = async (): Promise<void> => {
9
+ const dbHost = process.env.DB_HOST || 'localhost';
10
+ const mongoURI = process.env.MONGO_URI || `mongodb://${dbHost}:27017/<%= dbName %>`;
11
+
12
+ let retries = 5;
13
+ while (retries) {
14
+ try {
15
+ await mongoose.connect(mongoURI);
16
+ logger.info('MongoDB Connected...');
17
+ break;
18
+ } catch (err) {
19
+ logger.error('MongoDB connection failed:', err);
20
+ retries -= 1;
21
+ logger.info(`Retries left: ${retries}. Waiting 5s...`);
22
+ await new Promise(res => setTimeout(res, 5000));
23
+ }
24
+ }
25
+ };
26
+
27
+ export default connectDB;
@@ -18,7 +18,7 @@ services:
18
18
  - DB_PASSWORD=root
19
19
  - DB_NAME=<%= dbName %>
20
20
  <% } %><% if (database === 'PostgreSQL') { %> - DB_USER=postgres
21
- - DB_PASSWORD=postgres
21
+ - DB_PASSWORD=root
22
22
  - DB_NAME=<%= dbName %>
23
23
  <% } -%>
24
24
  <% } else { %>
@@ -29,30 +29,52 @@ services:
29
29
  - DB_PASSWORD=root
30
30
  - DB_NAME=<%= dbName %>
31
31
  <% } %><% if (database === 'PostgreSQL') { %> - DB_USER=postgres
32
- - DB_PASSWORD=postgres
32
+ - DB_PASSWORD=root
33
33
  - DB_NAME=<%= dbName %>
34
34
  <% } -%>
35
35
  <% } %>
36
36
  db:
37
37
  <% if (database === 'MySQL') { %> image: mysql:8.0
38
- command: --default-authentication-plugin=mysql_native_password
39
38
  restart: always
40
39
  environment:
41
40
  MYSQL_ROOT_PASSWORD: root
42
41
  MYSQL_DATABASE: <%= dbName %>
43
42
  ports:
44
43
  - "${DB_PORT:-3306}:3306"
45
- <% } %><% if (database === 'PostgreSQL') { %> image: postgres:15
44
+ volumes:
45
+ - ./flyway/sql:/docker-entrypoint-initdb.d
46
+ <% } else if (database === 'PostgreSQL') { %> image: postgres:15
46
47
  restart: always
47
48
  environment:
48
49
  POSTGRES_USER: postgres
49
- POSTGRES_PASSWORD: postgres
50
+ POSTGRES_PASSWORD: root
50
51
  POSTGRES_DB: <%= dbName %>
51
52
  ports:
52
53
  - "${DB_PORT:-5432}:5432"
53
- <% } %> volumes:
54
- - <%= database.toLowerCase() %>_data:/var/lib/<% if (database === 'MySQL') { %>mysql<% } else { %>postgresql/data<% } %>
54
+ volumes:
55
+ - ./flyway/sql:/docker-entrypoint-initdb.d
56
+ <% } else if (database === 'MongoDB') { %> image: mongo:latest
57
+ restart: always
58
+ environment:
59
+ MONGO_INITDB_DATABASE: <%= dbName %>
60
+ ports:
61
+ - "${DB_PORT:-27017}:27017"
62
+ volumes:
63
+ - mongodb_data:/data/db
55
64
 
65
+ mongo-migrate:
66
+ image: node:18-alpine
67
+ working_dir: /app
68
+ volumes:
69
+ - .:/app
70
+ command: sh -c "npm install migrate-mongo && npm run migrate"
71
+ environment:
72
+ - DB_HOST=db
73
+ - DB_NAME=<%= dbName %>
74
+ depends_on:
75
+ - db
76
+ <% } %>
77
+ <% if (database !== 'MongoDB') { %>
56
78
  flyway:
57
79
  image: flyway/flyway
58
80
  command: -connectRetries=60 migrate
@@ -64,9 +86,10 @@ services:
64
86
  FLYWAY_PASSWORD: root
65
87
  <% } %><% if (database === 'PostgreSQL') { %> FLYWAY_URL: jdbc:postgresql://db:5432/<%= dbName %>
66
88
  FLYWAY_USER: postgres
67
- FLYWAY_PASSWORD: postgres
89
+ FLYWAY_PASSWORD: root
68
90
  <% } %> depends_on:
69
91
  - db
92
+ <% } %>
70
93
  <% if (communication === 'Kafka') { %> zookeeper:
71
94
  image: confluentinc/cp-zookeeper:7.4.0
72
95
  environment:
@@ -3,7 +3,10 @@ module.exports = {
3
3
  coverageDirectory: 'coverage',
4
4
  collectCoverageFrom: ['src/**/*.{js,ts}'],
5
5
  testMatch: ['**/*.test.ts', '**/*.test.js'],
6
- <% if (language === 'TypeScript') { %>preset: 'ts-jest',<% } %>
6
+ <% if (language === 'TypeScript') { %>preset: 'ts-jest',
7
+ moduleNameMapper: {
8
+ '^@/(.*)$': '<rootDir>/src/$1',
9
+ },<% } %>
7
10
  coveragePathIgnorePatterns: [
8
11
  "/node_modules/",
9
12
  "/dist/"
@@ -1,4 +1,4 @@
1
- import { kafka } from '../config/kafka';
1
+ import { kafka } from '<%= configPath %>';
2
2
  import { EachMessagePayload, Producer, Consumer } from 'kafkajs';
3
3
  import logger from '<%= loggerPath %>';
4
4
 
@@ -0,0 +1,31 @@
1
+ const config = {
2
+ mongodb: {
3
+ url: process.env.MONGO_URI || `mongodb://${process.env.DB_HOST || 'localhost'}:27017`,
4
+ databaseName: process.env.DB_NAME || '<%= dbName %>',
5
+
6
+ options: {
7
+ // useNewUrlParser: true, // No longer needed in Node.js driver v4+
8
+ // useUnifiedTopology: true, // No longer needed in Node.js driver v4+
9
+ // connectTimeoutMS: 3600000, // increase connection timeout to 1 hour
10
+ // socketTimeoutMS: 3600000, // increase socket timeout to 1 hour
11
+ }
12
+ },
13
+
14
+ // The migrations dir, can be an relative or absolute path. Only edit this when really necessary.
15
+ migrationsDir: "migrations",
16
+
17
+ // The mongodb collection where the applied changes are stored. Only edit this when really necessary.
18
+ changelogCollectionName: "changelog",
19
+
20
+ // The file extension to create migrations and search for in migration dir
21
+ migrationFileExtension: ".js",
22
+
23
+ // Enable the algorithm to create a checksum of the file contents and use that in the comparison to determine
24
+ // if the file should be run. Requires that scripts are coded to be run multiple times.
25
+ useFileHash: false,
26
+
27
+ // Don't change this, unless you know what you are doing
28
+ moduleSystem: 'commonjs',
29
+ };
30
+
31
+ module.exports = config;
@@ -0,0 +1,23 @@
1
+ module.exports = {
2
+ async up(db, client) {
3
+ const adminEmail = 'admin@example.com';
4
+ const existingAdmin = await db.collection('users').findOne({ email: adminEmail });
5
+
6
+ if (!existingAdmin) {
7
+ await db.collection('users').insertOne({
8
+ name: 'Admin User',
9
+ email: adminEmail,
10
+ createdAt: new Date(),
11
+ updatedAt: new Date()
12
+ });
13
+ console.log('Admin User seeded successfully');
14
+ } else {
15
+ console.log('Admin User already exists, skipping seed');
16
+ }
17
+ },
18
+
19
+ async down(db, client) {
20
+ // Optional: Undo the seed. Usually for seeds we might want to keep data, but strictly speaking 'down' should reverse 'up'.
21
+ // await db.collection('users').deleteOne({ email: 'admin@example.com' });
22
+ }
23
+ };
@@ -5,24 +5,29 @@
5
5
  "main": "<% if (language === 'TypeScript') { %>dist/index.js<% } else { %>src/index.js<% } %>",
6
6
  "scripts": {
7
7
  "start": "<% if (language === 'TypeScript') { %>node dist/index.js<% } else { %>node src/index.js<% } %>",
8
- "dev": "<% if (language === 'TypeScript') { %>nodemon --exec ts-node src/index.ts<% } else { %>nodemon src/index.js<% } %>"<% if (language === 'TypeScript') { %>,
9
- "build": "rimraf dist && tsc<% if (viewEngine && viewEngine !== 'None') { %> && copyfiles -u 1 \"src/views/**/*\" dist/<% } %>"<% } %>,
8
+ "dev": "<% if (language === 'TypeScript') { %>nodemon --exec ts-node -r tsconfig-paths/register src/index.ts<% } else { %>nodemon src/index.js<% } %>"<% if (language === 'TypeScript') { %>,
9
+ "build": "rimraf dist && tsc && tsc-alias<% if (viewEngine && viewEngine !== 'None') { %> && copyfiles -u 1 \"src/views/**/*\" dist/<% } %>"<% } %>,
10
10
  "lint": "eslint . --ext .ts,.js",
11
11
  "lint:fix": "eslint . --ext .ts,.js --fix",
12
12
  "format": "prettier --write .",
13
13
  "prepare": "husky install",
14
14
  "test": "jest",
15
15
  "test:watch": "jest --watch",
16
- "test:coverage": "jest --coverage"
16
+ "test:coverage": "jest --coverage",
17
+ "migrate": "migrate-mongo up"
17
18
  },
18
19
  "dependencies": {
19
20
  "express": "^4.18.2",
20
21
  "dotenv": "^16.3.1",
21
22
  <% if (database === 'MySQL') { %> "mysql2": "^3.6.5",
23
+ "sequelize": "^6.35.2",
22
24
  <% } -%>
23
25
  <% if (database === 'PostgreSQL') { %> "pg": "^8.11.3",
24
- <% } -%>
25
26
  "sequelize": "^6.35.2",
27
+ <% } -%>
28
+ <% if (database === 'MongoDB') { %> "mongoose": "^8.0.3",
29
+ "migrate-mongo": "^11.0.0",
30
+ <% } -%>
26
31
  <% if (communication === 'Kafka') { %> "kafkajs": "^2.2.4",
27
32
  <% } -%>
28
33
  <% if (viewEngine === 'EJS') { %> "ejs": "^3.1.9",
@@ -35,8 +40,7 @@
35
40
  "express-rate-limit": "^7.1.5",
36
41
  "winston": "^3.11.0"<% if (communication === 'REST APIs') { %>,
37
42
  "swagger-ui-express": "^5.0.0",
38
- "swagger-jsdoc": "^6.2.8"
39
- <% } %>
43
+ "swagger-jsdoc": "^6.2.8"<% } %>
40
44
  },
41
45
  "devDependencies": {
42
46
  "nodemon": "^3.0.2"<% if (language === 'TypeScript') { %>,
@@ -65,6 +69,8 @@
65
69
  "ts-jest": "^29.1.1",
66
70
  "@types/jest": "^29.5.11",
67
71
  "supertest": "^6.3.3",
72
+ "tsconfig-paths": "^4.2.0",
73
+ "tsc-alias": "^1.8.8",
68
74
  "@types/supertest": "^6.0.2"<% } else { %>,
69
75
  "jest": "^29.7.0",
70
76
  "supertest": "^6.3.3"<% } %>
@@ -0,0 +1,147 @@
1
+ :root {
2
+ --primary-color: #4f46e5;
3
+ --primary-hover: #4338ca;
4
+ --bg-color: #f9fafb;
5
+ --card-bg: #ffffff;
6
+ --text-main: #111827;
7
+ --text-muted: #6b7280;
8
+ --success-color: #10b981;
9
+ --border-color: #e5e7eb;
10
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
11
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
12
+ }
13
+
14
+ body {
15
+ font-family: 'Inter', system-ui, -apple-system, sans-serif;
16
+ background-color: var(--bg-color);
17
+ color: var(--text-main);
18
+ margin: 0;
19
+ padding: 0;
20
+ line-height: 1.5;
21
+ display: flex;
22
+ justify-content: center;
23
+ min-height: 100vh;
24
+ }
25
+
26
+ .container {
27
+ width: 100%;
28
+ max-width: 800px;
29
+ padding: 40px 20px;
30
+ }
31
+
32
+ .header {
33
+ text-align: center;
34
+ margin-bottom: 40px;
35
+ }
36
+
37
+ .logo {
38
+ font-size: 3rem;
39
+ margin-bottom: 10px;
40
+ }
41
+
42
+ h1 {
43
+ font-size: 2.5rem;
44
+ font-weight: 800;
45
+ color: var(--text-main);
46
+ margin: 0 0 10px 0;
47
+ letter-spacing: -0.025em;
48
+ }
49
+
50
+ .subtitle {
51
+ color: var(--text-muted);
52
+ font-size: 1.125rem;
53
+ }
54
+
55
+ .card-grid {
56
+ display: grid;
57
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
58
+ gap: 20px;
59
+ margin-bottom: 40px;
60
+ }
61
+
62
+ .card {
63
+ background: var(--card-bg);
64
+ padding: 24px;
65
+ border-radius: 12px;
66
+ box-shadow: var(--shadow-sm);
67
+ border: 1px solid var(--border-color);
68
+ transition: transform 0.2s, box-shadow 0.2s;
69
+ }
70
+
71
+ .card:hover {
72
+ transform: translateY(-2px);
73
+ box-shadow: var(--shadow-md);
74
+ }
75
+
76
+ .card h3 {
77
+ margin-top: 0;
78
+ font-size: 0.875rem;
79
+ text-transform: uppercase;
80
+ letter-spacing: 0.05em;
81
+ color: var(--text-muted);
82
+ font-weight: 600;
83
+ }
84
+
85
+ .card p {
86
+ font-size: 1.25rem;
87
+ font-weight: 600;
88
+ color: var(--text-main);
89
+ margin: 5px 0 0 0;
90
+ }
91
+
92
+ .status-card {
93
+ background: var(--card-bg);
94
+ border-radius: 12px;
95
+ padding: 24px;
96
+ box-shadow: var(--shadow-md);
97
+ border-left: 6px solid var(--success-color);
98
+ display: flex;
99
+ align-items: center;
100
+ gap: 20px;
101
+ }
102
+
103
+ .status-icon {
104
+ background: #d1fae5;
105
+ color: var(--success-color);
106
+ width: 48px;
107
+ height: 48px;
108
+ border-radius: 50%;
109
+ display: flex;
110
+ align-items: center;
111
+ justify-content: center;
112
+ font-size: 1.5rem;
113
+ }
114
+
115
+ .status-content h3 {
116
+ margin: 0;
117
+ font-size: 1.25rem;
118
+ font-weight: 700;
119
+ }
120
+
121
+ .status-content p {
122
+ margin: 5px 0 0 0;
123
+ color: var(--text-muted);
124
+ }
125
+
126
+ .action-btn {
127
+ display: inline-block;
128
+ margin-top: 40px;
129
+ background-color: var(--primary-color);
130
+ color: white;
131
+ padding: 12px 24px;
132
+ border-radius: 8px;
133
+ text-decoration: none;
134
+ font-weight: 600;
135
+ transition: background-color 0.2s;
136
+ }
137
+
138
+ .action-btn:hover {
139
+ background-color: var(--primary-hover);
140
+ }
141
+
142
+ footer {
143
+ margin-top: 60px;
144
+ text-align: center;
145
+ color: var(--text-muted);
146
+ font-size: 0.875rem;
147
+ }
@@ -7,7 +7,11 @@
7
7
  "strict": true,
8
8
  "esModuleInterop": true,
9
9
  "skipLibCheck": true,
10
- "forceConsistentCasingInFileNames": true
10
+ "forceConsistentCasingInFileNames": true,
11
+ "baseUrl": ".",
12
+ "paths": {
13
+ "@/*": ["src/*"]
14
+ }
11
15
  },
12
16
  "include": [
13
17
  "src/**/*"
@@ -4,28 +4,52 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title><%= projectName %></title>
7
- <style>
8
- body { font-family: sans-serif; padding: 20px; }
9
- h1 { color: #333; }
10
- .status { margin-top: 20px; padding: 10px; background: #e0f7fa; border-left: 5px solid #00acc1; }
11
- </style>
7
+ <link rel="stylesheet" href="/css/style.css">
12
8
  </head>
13
9
  <body>
14
- <h1>Welcome to <%= projectName %></h1>
15
- <p>Architecture: <strong><%= architecture %></strong></p>
16
- <p>Database: <strong><%= database %></strong></p>
17
-
18
- <% if (communication === 'Kafka') { %>
19
- <div class="status">
20
- <h3>Kafka Status</h3>
21
- <p>Connected to Kafka Broker.</p>
22
- <p>Check console for messages.</p>
10
+ <div class="container">
11
+ <header class="header">
12
+ <div class="logo">🚀</div>
13
+ <h1>Welcome to <%= projectName %></h1>
14
+ <p class="subtitle">A production-ready Node.js microservice starter.</p>
15
+ </header>
16
+
17
+ <div class="card-grid">
18
+ <div class="card">
19
+ <h3>Architecture</h3>
20
+ <p><%= architecture %></p>
21
+ </div>
22
+ <div class="card">
23
+ <h3>Database</h3>
24
+ <p><%= database %></p>
25
+ </div>
26
+ <div class="card">
27
+ <h3>Communication</h3>
28
+ <p><%= communication %></p>
29
+ </div>
30
+ </div>
31
+
32
+ <% if (communication === 'Kafka') { %>
33
+ <div class="status-card">
34
+ <div class="status-icon">🔄</div>
35
+ <div class="status-content">
36
+ <h3>Kafka Connected</h3>
37
+ <p>Connection to broker established successfully.</p>
38
+ </div>
39
+ </div>
40
+ <% } else { %>
41
+ <div class="status-card">
42
+ <div class="status-icon">✅</div>
43
+ <div class="status-content">
44
+ <h3>API Active</h3>
45
+ <p>REST API is running and ready to accept requests.</p>
46
+ </div>
47
+ </div>
48
+ <% } %>
49
+
50
+ <footer>
51
+ <p>Generated with ❤️ by Node.js Quickstart Generator</p>
52
+ </footer>
23
53
  </div>
24
- <% } else { %>
25
- <div class="status">
26
- <h3>API Status</h3>
27
- <p>REST API is active.</p>
28
- </div>
29
- <% } %>
30
54
  </body>
31
55
  </html>
@@ -4,23 +4,37 @@ html(lang="en")
4
4
  meta(charset="UTF-8")
5
5
  meta(name="viewport", content="width=device-width, initial-scale=1.0")
6
6
  title= projectName
7
- style.
8
- body { font-family: sans-serif; padding: 20px; }
9
- h1 { color: #333; }
10
- .status { margin-top: 20px; padding: 10px; background: #e0f7fa; border-left: 5px solid #00acc1; }
7
+ link(rel="stylesheet", href="/css/style.css")
11
8
  body
12
- h1 Welcome to #{projectName}
13
- p Architecture:
14
- strong #{architecture}
15
- p Database:
16
- strong #{database}
9
+ .container
10
+ header.header
11
+ .logo 🚀
12
+ h1 Welcome to #{projectName}
13
+ p.subtitle A production-ready Node.js microservice starter.
17
14
 
18
- if communication === 'Kafka'
19
- .status
20
- h3 Kafka Status
21
- p Connected to Kafka Broker.
22
- p Check console for messages.
23
- else
24
- .status
25
- h3 API Status
26
- p REST API is active.
15
+ .card-grid
16
+ .card
17
+ h3 Architecture
18
+ p #{architecture}
19
+ .card
20
+ h3 Database
21
+ p #{database}
22
+ .card
23
+ h3 Communication
24
+ p #{communication}
25
+
26
+ if communication === 'Kafka'
27
+ .status-card
28
+ .status-icon 🔄
29
+ .status-content
30
+ h3 Kafka Connected
31
+ p Connection to broker established successfully.
32
+ else
33
+ .status-card
34
+ .status-icon ✅
35
+ .status-content
36
+ h3 API Active
37
+ p REST API is running and ready to accept requests.
38
+
39
+ footer
40
+ p Generated with ❤️ by Node.js Quickstart Generator
@@ -4,7 +4,9 @@ const logger = require('../utils/logger');
4
4
 
5
5
  const getUsers = async (req, res) => {
6
6
  try {
7
- const users = await User.findAll();
7
+ <% if (database === 'MongoDB') { %> const users = await User.find();
8
+ <% } else { %> const users = await User.findAll();
9
+ <% } -%>
8
10
  res.json(users);
9
11
  } catch (error) {
10
12
  logger.error('Error fetching users:', error);
@@ -24,7 +24,7 @@ app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs));
24
24
  const path = require('path');
25
25
  app.set('views', path.join(__dirname, 'views'));
26
26
  app.set('view engine', '<%= viewEngine.toLowerCase() %>');
27
- <% } -%>
27
+ app.use(express.static(path.join(__dirname, '../public')));<% } -%>
28
28
 
29
29
  // Routes
30
30
  <% if (communication === 'REST APIs' || (viewEngine && viewEngine !== 'None')) { -%>
@@ -50,8 +50,13 @@ const syncDatabase = async () => {
50
50
  let retries = 30;
51
51
  while (retries) {
52
52
  try {
53
+ <% if (database === 'MongoDB') { %>
54
+ const connectDB = require('./config/database');
55
+ await connectDB();
56
+ <% } else { %>
53
57
  const sequelize = require('./config/database');
54
58
  await sequelize.sync();
59
+ <% } %>
55
60
  logger.info('Database synced');
56
61
 
57
62
  // Start Server after DB is ready
@@ -1,12 +1,14 @@
1
1
  import { Request, Response } from 'express';
2
- import User from '../models/User';
3
- import { HTTP_STATUS } from '../utils/httpCodes';
4
- import logger from '../utils/logger';
2
+ import User from '@/models/User';
3
+ import { HTTP_STATUS } from '@/utils/httpCodes';
4
+ import logger from '@/utils/logger';
5
5
 
6
6
  export class UserController {
7
7
  async getUsers(req: Request, res: Response) {
8
8
  try {
9
- const users = await User.findAll();
9
+ <% if (database === 'MongoDB') { %> const users = await User.find();
10
+ <% } else { %> const users = await User.findAll();
11
+ <% } -%>
10
12
  res.json(users);
11
13
  } catch (error) {
12
14
  logger.error('Error fetching users:', error);