@ifecodes/backend-template 1.1.1 → 1.1.5

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 (86) hide show
  1. package/README.md +39 -18
  2. package/bin/cli.js +205 -149
  3. package/bin/lib/microservice-config.js +57 -13
  4. package/bin/lib/prompts.js +42 -11
  5. package/bin/lib/readme-generator.js +75 -14
  6. package/bin/lib/service-setup.js +277 -123
  7. package/package.json +1 -1
  8. package/template/base/js/.eslintrc.json +13 -0
  9. package/template/base/js/.prettierrc +7 -0
  10. package/template/base/js/eslint.config.js +31 -0
  11. package/template/base/js/package.json +28 -0
  12. package/template/base/js/src/app.js +15 -0
  13. package/template/base/js/src/config/db.js +8 -0
  14. package/template/base/js/src/config/env.js +14 -0
  15. package/template/base/js/src/config/index.js +7 -0
  16. package/template/base/js/src/middlewares/index.js +9 -0
  17. package/template/base/js/src/middlewares/method-not-allowed.middleware.js +13 -0
  18. package/template/base/js/src/middlewares/not-found.middleware.js +10 -0
  19. package/template/base/js/src/middlewares/root.middleware.js +16 -0
  20. package/template/base/js/src/modules/index.js +8 -0
  21. package/template/base/js/src/modules/v1/health/health.controller.js +21 -0
  22. package/template/base/js/src/modules/v1/health/health.route.js +9 -0
  23. package/template/base/js/src/modules/v1/health/index.js +5 -0
  24. package/template/base/js/src/modules/v1/index.js +8 -0
  25. package/template/base/js/src/routes.js +16 -0
  26. package/template/base/js/src/server.js +18 -0
  27. package/template/base/js/src/utils/http-error.js +53 -0
  28. package/template/base/js/src/utils/index.js +22 -0
  29. package/template/base/js/src/utils/logger.js +67 -0
  30. package/template/base/ts/.env.example +5 -0
  31. package/template/base/ts/.husky/pre-commit +13 -0
  32. package/template/base/ts/.prettierignore +47 -0
  33. package/template/base/ts/gitignore +31 -0
  34. package/template/base/ts/src/app.ts +15 -0
  35. package/template/base/{src → ts/src}/config/env.ts +10 -10
  36. package/template/base/{src → ts/src}/middlewares/index.ts +3 -3
  37. package/template/base/{src → ts/src}/middlewares/method-not-allowed.middleware.ts +16 -17
  38. package/template/base/{src → ts/src}/middlewares/root.middleware.ts +2 -2
  39. package/template/base/{src → ts/src}/modules/v1/health/health.controller.ts +18 -18
  40. package/template/base/{src → ts/src}/modules/v1/health/health.route.ts +9 -9
  41. package/template/base/{src → ts/src}/modules/v1/health/index.ts +1 -1
  42. package/template/base/{src → ts/src}/modules/v1/index.ts +8 -8
  43. package/template/base/{src → ts/src}/routes.ts +15 -15
  44. package/template/base/{src → ts/src}/utils/http-error.ts +45 -47
  45. package/template/base/ts/src/utils/logger.ts +68 -0
  46. package/template/features/auth/argon2/inject.js +29 -4
  47. package/template/features/auth/base/inject.js +108 -26
  48. package/template/features/auth/bcrypt/inject.js +25 -5
  49. package/template/features/auth/models/user.model.js +24 -0
  50. package/template/features/auth/modules/auth.controller.js +21 -0
  51. package/template/features/auth/modules/auth.routes.js +10 -0
  52. package/template/features/auth/modules/auth.service.js +29 -0
  53. package/template/features/auth/modules/index.js +1 -0
  54. package/template/features/auth/utils/jwt.js +12 -0
  55. package/template/features/cors/inject.js +4 -1
  56. package/template/features/helmet/inject.js +4 -1
  57. package/template/features/morgan/inject.js +4 -1
  58. package/template/features/rate-limit/inject.js +4 -1
  59. package/template/gateway/js/app.js +42 -0
  60. package/template/gateway/js/inject.js +31 -0
  61. package/template/gateway/js/server.js +19 -0
  62. package/template/gateway/{app.ts → ts/app.ts} +19 -3
  63. package/template/gateway/ts/inject.js +31 -0
  64. package/template/gateway/{server.ts → ts/server.ts} +3 -3
  65. package/template/microservice/docker/.dockerignore +10 -0
  66. package/template/microservice/docker/Dockerfile +2 -1
  67. package/template/microservice/docker/docker-compose.yml +0 -1
  68. package/bin/lib/ts-to-js.js +0 -123
  69. package/template/base/src/app.ts +0 -8
  70. package/template/base/src/utils/logger.ts +0 -35
  71. package/template/gateway/inject.js +0 -27
  72. /package/template/base/{.env.example → js/.env.example} +0 -0
  73. /package/template/base/{.husky → js/.husky}/pre-commit +0 -0
  74. /package/template/base/{.prettierignore → js/.prettierignore} +0 -0
  75. /package/template/base/{gitignore → js/gitignore} +0 -0
  76. /package/template/base/{.eslintrc.json → ts/.eslintrc.json} +0 -0
  77. /package/template/base/{.prettierrc → ts/.prettierrc} +0 -0
  78. /package/template/base/{eslint.config.js → ts/eslint.config.js} +0 -0
  79. /package/template/base/{package.json → ts/package.json} +0 -0
  80. /package/template/base/{src → ts/src}/config/db.ts +0 -0
  81. /package/template/base/{src → ts/src}/config/index.ts +0 -0
  82. /package/template/base/{src → ts/src}/middlewares/not-found.middleware.ts +0 -0
  83. /package/template/base/{src → ts/src}/modules/index.ts +0 -0
  84. /package/template/base/{src → ts/src}/server.ts +0 -0
  85. /package/template/base/{src → ts/src}/utils/index.ts +0 -0
  86. /package/template/base/{tsconfig.json → ts/tsconfig.json} +0 -0
@@ -59,19 +59,19 @@ export const getProjectConfig = async () => {
59
59
  initial: 0,
60
60
  },
61
61
  {
62
- type: isInMicroserviceProject || hasCliArgs || isCI ? null : "text",
62
+ type: isInMicroserviceProject || isCI ? null : "text",
63
63
  name: "description",
64
64
  message: pc.cyan("Project description") + pc.dim(" (optional)"),
65
65
  initial: "",
66
66
  },
67
67
  {
68
- type: isInMicroserviceProject || hasCliArgs || isCI ? null : "text",
68
+ type: isInMicroserviceProject || isCI ? null : "text",
69
69
  name: "author",
70
70
  message: pc.cyan("Author") + pc.dim(" (optional)"),
71
71
  initial: "",
72
72
  },
73
73
  {
74
- type: isInMicroserviceProject || hasCliArgs || isCI ? null : "text",
74
+ type: isInMicroserviceProject || isCI ? null : "text",
75
75
  name: "keywords",
76
76
  message: pc.cyan("Keywords") + pc.dim(" (comma-separated, optional)"),
77
77
  initial: "",
@@ -86,12 +86,16 @@ export const getProjectConfig = async () => {
86
86
  ],
87
87
  },
88
88
  {
89
- type: (prev, values) =>
90
- isInMicroserviceProject || isCI
91
- ? null
92
- : prev === "microservice"
93
- ? "select"
94
- : null,
89
+ type: (prev, values) => {
90
+ // Skip if in existing microservice project or CI mode
91
+ if (isInMicroserviceProject || isCI) return null;
92
+
93
+ // Get projectType from previous answers or CLI args
94
+ const projectType = prev || cliProjectType || values.projectType;
95
+
96
+ // Show prompt only if projectType is microservice
97
+ return projectType === "microservice" ? "select" : null;
98
+ },
95
99
  name: "mode",
96
100
  message: pc.cyan("Microservice setup"),
97
101
  choices: [
@@ -135,13 +139,35 @@ export const getProjectConfig = async () => {
135
139
  { title: pc.blue("CORS"), value: "cors" },
136
140
  ],
137
141
  },
138
- ]);
142
+ ],
143
+ {
144
+ onCancel: () => {
145
+ console.log(pc.yellow("\n❌ Operation cancelled by user."));
146
+ process.exit(0);
147
+ }
148
+ });
139
149
 
140
150
  // Handle cancelled prompts (user pressed Ctrl+C or closed the prompt)
141
- if (!res || !res.name) {
151
+ // Check if user cancelled the prompt (Ctrl+C) vs just didn't enter anything
152
+ if (!res) {
142
153
  console.log(pc.yellow("\n❌ Operation cancelled by user."));
143
154
  process.exit(0);
144
155
  }
156
+
157
+ // Check if critical fields are missing (indicates cancellation mid-prompt)
158
+ if (!isInMicroserviceProject && !isCI) {
159
+ // For new projects, we need language and projectType
160
+ if (!res.language || (!res.projectType && !cliProjectType)) {
161
+ console.log(pc.yellow("\n❌ Operation cancelled by user."));
162
+ process.exit(0);
163
+ }
164
+ }
165
+
166
+ // If the response is empty but we expected prompts, something went wrong
167
+ if (Object.keys(res).length === 0 && !isInMicroserviceProject && !hasCliArgs && !isCI) {
168
+ console.log(pc.red("\n❌ No inputs received. Please try again."));
169
+ process.exit(1);
170
+ }
145
171
 
146
172
  // Set defaults for CI/non-interactive mode
147
173
  if (isCI) {
@@ -161,6 +187,11 @@ export const getProjectConfig = async () => {
161
187
  res.projectType = res.projectType || "monolith";
162
188
  }
163
189
  }
190
+
191
+ // Ensure we have a project name (fallback if somehow missed)
192
+ if (!res.name && !isInMicroserviceProject) {
193
+ res.name = "my-backend";
194
+ }
164
195
 
165
196
  let sanitizedName, target, isExistingProject, mode;
166
197
 
@@ -86,16 +86,16 @@ export const generateReadme = (config, serviceName = null) => {
86
86
 
87
87
  // Environment Variables
88
88
  readme += `3. Set up environment variables\n`;
89
- readme += `\`\`\`bash\n`;
90
89
  if (isMicroservice) {
91
- readme += `# Copy .env.example to .env in each service\n`;
92
- readme += `cp services/gateway/.env.example services/gateway/.env\n`;
93
- readme += `cp services/health-service/.env.example services/health-service/.env\n`;
94
- if (auth) readme += `cp services/auth-service/.env.example services/auth-service/.env\n`;
90
+ readme += `\`\`\`bash\n`;
91
+ readme += `# Environment variables are configured in docker-compose.yml or pm2.config.js\n`;
92
+ readme += `# No .env files needed for individual services\n`;
93
+ readme += `\`\`\`\n\n`;
95
94
  } else {
95
+ readme += `\`\`\`bash\n`;
96
96
  readme += `cp .env.example .env\n`;
97
+ readme += `\`\`\`\n\n`;
97
98
  }
98
- readme += `\`\`\`\n\n`;
99
99
 
100
100
  if (auth) {
101
101
  readme += `4. Configure your MongoDB connection and JWT secret in the \`.env\` file${isMicroservice ? "s" : ""}\n\n`;
@@ -143,24 +143,85 @@ export const generateReadme = (config, serviceName = null) => {
143
143
 
144
144
  if (isMicroservice) {
145
145
  readme += `All requests go through the API Gateway at \`http://localhost:4000\`\n\n`;
146
- readme += `### Health Service\n`;
147
- readme += `- **GET** \`/health\` - Health check\n\n`;
146
+
147
+ readme += `### Gateway Endpoints\n`;
148
+ readme += `- **GET** \`/\` - API information and available endpoints\n`;
149
+ readme += `- **GET** \`/health\` - Gateway health check\n`;
150
+
151
+ readme += `### Health Service (Proxied through Gateway)\n`;
152
+ readme += `- **GET** \`/api/v1/health\` - Service health check with system metrics\n`;
153
+ readme += ` - Returns: status, uptime, timestamp, memory usage\n\n`;
154
+
155
+ if (auth) {
156
+ readme += `### Auth Service (Proxied through Gateway)\n`;
157
+ readme += `- **POST** \`/api/v1/auth/register\` - Register a new user\n`;
158
+ readme += `- **POST** \`/api/v1/auth/login\` - Login user\n\n`;
159
+ }
148
160
 
161
+ readme += `### Direct Service Access (Development Only)\n`;
162
+ readme += `- **Gateway**: \`http://localhost:4000\`\n`;
163
+ readme += `- **Health Service**: \`http://localhost:4001/api/v1/health\`\n\n`;
164
+ if (auth) readme += `- **Auth Service**: \`http://localhost:4002/api/v1/auth\`\n\n`;
165
+
166
+ readme += "### Example Requests\n";
167
+ readme += "```bash\n";
168
+ readme += "# Gateway info\n";
169
+ readme += "curl http://localhost:4000/\n\n";
170
+ readme += "# Gateway health\n";
171
+ readme += "curl http://localhost:4000/health\n\n";
172
+ readme += "# Health service (through gateway)\n";
173
+ readme += "curl http://localhost:4000/api/v1/health\n\n";
174
+ readme += "# Health service (direct access)\n";
175
+ readme += "curl http://localhost:4001/api/v1/health\n";
149
176
  if (auth) {
150
- readme += `### Auth Service\n`;
151
- readme += `- **POST** \`/auth/register\` - Register a new user\n`;
152
- readme += `- **POST** \`/auth/login\` - Login user\n\n`;
177
+ readme += "\n# Register user (through gateway)\n";
178
+ readme += `curl -X POST http://localhost:4000/api/v1/auth/register \\\n`;
179
+ readme += ` -H "Content-Type: application/json" \\\n`;
180
+ readme += ` -d '{"username":"testuser","password":"password123"}'\n\n`;
181
+ readme += "# Login user (through gateway)\n";
182
+ readme += `curl -X POST http://localhost:4000/api/v1/auth/login \\\n`;
183
+ readme += ` -H "Content-Type: application/json" \\\n`;
184
+ readme += ` -d '{"username":"testuser","password":"password123"}'\n\n`;
185
+ readme += "# Register user (direct access)\n";
186
+ readme += `curl -X POST http://localhost:4002/api/v1/auth/register \\\n`;
187
+ readme += ` -H "Content-Type: application/json" \\\n`;
188
+ readme += ` -d '{"username":"testuser","password":"password123"}'\n\n`;
189
+ readme += "# Login user (direct access)\n";
190
+ readme += `curl -X POST http://localhost:4002/api/v1/auth/login \\\n`;
191
+ readme += ` -H "Content-Type: application/json" \\\n`;
192
+ readme += ` -d '{"username":"testuser","password":"password123"}'\n`;
153
193
  }
194
+ readme += "```\n\n";
195
+
154
196
  } else {
155
197
  readme += `Base URL: \`http://localhost:4000\`\n\n`;
156
198
  readme += `- **GET** \`/\` - Root endpoint (API info)\n`;
157
- readme += `- **GET** \`/v1/health\` - Health check\n\n`;
199
+ readme += `- **GET** \`/api/v1/health\` - Health check\n\n`;
158
200
 
159
201
  if (auth) {
160
202
  readme += `### Authentication\n`;
161
- readme += `- **POST** \`/v1/auth/register\` - Register a new user\n`;
162
- readme += `- **POST** \`/v1/auth/login\` - Login user\n\n`;
203
+ readme += `- **POST** \`/api/v1/auth/register\` - Register a new user\n`;
204
+ readme += `- **POST** \`/api/v1/auth/login\` - Login user\n\n`;
205
+ }
206
+
207
+ // Example requests for monolith
208
+ readme += "### Example Requests\n";
209
+ readme += "```bash\n";
210
+ readme += "# Root info\n";
211
+ readme += "curl http://localhost:4000/\n\n";
212
+ readme += "# Health check\n";
213
+ readme += "curl http://localhost:4000/api/v1/health\n\n";
214
+ if (auth) {
215
+ readme += "# Register user\n";
216
+ readme += `curl -X POST http://localhost:4000/api/v1/auth/register \\\n`;
217
+ readme += ` -H \"Content-Type: application/json\" \\\n`;
218
+ readme += ` -d '{"username":"testuser","password":"password123"}'\n\n`;
219
+ readme += "# Login user\n";
220
+ readme += `curl -X POST http://localhost:4000/api/v1/auth/login \\\n`;
221
+ readme += ` -H \"Content-Type: application/json\" \\\n`;
222
+ readme += ` -d '{"username":"testuser","password":"password123"}'\n\n`;
163
223
  }
224
+ readme += "```\n\n";
164
225
  }
165
226
 
166
227
  // Project Structure