create-arktos 1.4.0 โ 1.5.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/bin/cli.js +11 -67
- package/package.json +1 -4
- package/eslint.config.js.template +0 -31
- package/src-js/app.js +0 -97
- package/src-js/config/env.validation.js +0 -15
- package/src-js/config/logger.js +0 -76
- package/src-js/constants/errorCodes.js +0 -57
- package/src-js/constants/messages.js +0 -240
- package/src-js/controllers/auth.controller.js +0 -533
- package/src-js/middleware/index.js +0 -284
- package/src-js/routes/auth.routes.js +0 -28
- package/src-js/routes/index.js +0 -18
- package/src-js/schemas/index.js +0 -60
- package/src-js/services/database.service.js +0 -89
- package/src-js/services/email.service.js +0 -161
- package/src-js/services/jwt.service.js +0 -177
- package/src-js/utils/response.js +0 -53
- package/src-js/views/emails/notification.html +0 -87
- package/src-js/views/emails/resetPassword.html +0 -118
- package/src-js/views/emails/verification.html +0 -107
- package/src-js/views/emails/welcome.html +0 -113
- package/template.js.package.json +0 -77
package/bin/cli.js
CHANGED
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { execSync } = require('child_process');
|
|
6
|
-
const { input, select } = require('inquirer');
|
|
7
6
|
|
|
8
|
-
const
|
|
9
|
-
const TEMPLATE_JS_DIR = path.join(__dirname, '../src-js');
|
|
7
|
+
const TEMPLATE_DIR = path.join(__dirname, '../src');
|
|
10
8
|
const ROOT_DIR = path.join(__dirname, '..');
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
function createProject(projectName) {
|
|
13
11
|
console.log(`๐ Creating Arktos project: ${projectName}`);
|
|
14
12
|
console.log();
|
|
15
13
|
|
|
@@ -25,19 +23,8 @@ async function createProject(projectName) {
|
|
|
25
23
|
process.exit(1);
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
//
|
|
29
|
-
const
|
|
30
|
-
message: '๐ Which language would you like to use?',
|
|
31
|
-
choices: [
|
|
32
|
-
{ name: 'TypeScript (Recommended)', value: 'typescript' },
|
|
33
|
-
{ name: 'JavaScript', value: 'javascript' }
|
|
34
|
-
],
|
|
35
|
-
default: 'typescript'
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
const useTypeScript = language === 'typescript';
|
|
39
|
-
const templateDir = useTypeScript ? TEMPLATE_TS_DIR : TEMPLATE_JS_DIR;
|
|
40
|
-
const packageTemplate = useTypeScript ? 'template.package.json' : 'template.js.package.json';
|
|
26
|
+
// Always use TypeScript template
|
|
27
|
+
const packageTemplate = 'template.package.json';
|
|
41
28
|
|
|
42
29
|
try {
|
|
43
30
|
// Create project directory
|
|
@@ -45,9 +32,9 @@ async function createProject(projectName) {
|
|
|
45
32
|
fs.mkdirSync(projectName);
|
|
46
33
|
|
|
47
34
|
// Copy src directory
|
|
48
|
-
console.log(
|
|
35
|
+
console.log('๐ Copying TypeScript source files...');
|
|
49
36
|
const targetSrcDir = path.join(projectName, 'src');
|
|
50
|
-
copyDir(
|
|
37
|
+
copyDir(TEMPLATE_DIR, targetSrcDir);
|
|
51
38
|
|
|
52
39
|
// Copy prisma directory
|
|
53
40
|
console.log('๐๏ธ Copying database schema...');
|
|
@@ -59,7 +46,7 @@ async function createProject(projectName) {
|
|
|
59
46
|
|
|
60
47
|
// Copy template config files
|
|
61
48
|
console.log('๐ Copying configuration files...');
|
|
62
|
-
copyTemplateFiles(projectName
|
|
49
|
+
copyTemplateFiles(projectName);
|
|
63
50
|
|
|
64
51
|
// Copy and update package.json
|
|
65
52
|
console.log('๐ง Updating project configuration...');
|
|
@@ -75,11 +62,6 @@ async function createProject(projectName) {
|
|
|
75
62
|
fs.writeFileSync(targetPackageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
76
63
|
}
|
|
77
64
|
|
|
78
|
-
// Clean up TypeScript specific files if JavaScript is selected
|
|
79
|
-
if (!useTypeScript) {
|
|
80
|
-
console.log('๐งน Cleaning up TypeScript specific files...');
|
|
81
|
-
cleanupTypeScriptFiles(projectName);
|
|
82
|
-
}
|
|
83
65
|
|
|
84
66
|
console.log('โ
Project created successfully!');
|
|
85
67
|
console.log();
|
|
@@ -144,30 +126,7 @@ function copyDir(src, dest) {
|
|
|
144
126
|
}
|
|
145
127
|
}
|
|
146
128
|
|
|
147
|
-
function
|
|
148
|
-
try {
|
|
149
|
-
// Remove TypeScript specific directories and files
|
|
150
|
-
const tsSpecificPaths = [
|
|
151
|
-
path.join(projectPath, 'src', 'types'),
|
|
152
|
-
path.join(projectPath, 'tsconfig.json')
|
|
153
|
-
];
|
|
154
|
-
|
|
155
|
-
for (const tsPath of tsSpecificPaths) {
|
|
156
|
-
if (fs.existsSync(tsPath)) {
|
|
157
|
-
const stats = fs.statSync(tsPath);
|
|
158
|
-
if (stats.isDirectory()) {
|
|
159
|
-
fs.rmSync(tsPath, { recursive: true, force: true });
|
|
160
|
-
} else {
|
|
161
|
-
fs.unlinkSync(tsPath);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
} catch (error) {
|
|
166
|
-
console.warn('โ ๏ธ Warning: Could not clean up some TypeScript files:', error.message);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function copyTemplateFiles(dest, useTypeScript = true) {
|
|
129
|
+
function copyTemplateFiles(dest) {
|
|
171
130
|
// Create common config files
|
|
172
131
|
const configFiles = {
|
|
173
132
|
'.gitignore': `# Dependencies
|
|
@@ -308,11 +267,8 @@ Happy coding! ๐`
|
|
|
308
267
|
fs.writeFileSync(path.join(dest, fileName), content);
|
|
309
268
|
}
|
|
310
269
|
|
|
311
|
-
// Copy template files from root
|
|
312
|
-
const
|
|
313
|
-
const templateFiles = useTypeScript
|
|
314
|
-
? [...commonTemplateFiles, 'tsconfig.json', 'eslint.config.js']
|
|
315
|
-
: [...commonTemplateFiles];
|
|
270
|
+
// Copy template files from root
|
|
271
|
+
const templateFiles = ['.env.example', 'vercel.json', 'tsconfig.json', 'eslint.config.js'];
|
|
316
272
|
|
|
317
273
|
for (const templateFile of templateFiles) {
|
|
318
274
|
const srcPath = path.join(ROOT_DIR, templateFile);
|
|
@@ -323,15 +279,6 @@ Happy coding! ๐`
|
|
|
323
279
|
}
|
|
324
280
|
}
|
|
325
281
|
|
|
326
|
-
// Copy appropriate ESLint config for JavaScript projects
|
|
327
|
-
if (!useTypeScript) {
|
|
328
|
-
const jsEslintConfigPath = path.join(ROOT_DIR, 'eslint.config.js.template');
|
|
329
|
-
const destEslintConfigPath = path.join(dest, 'eslint.config.js');
|
|
330
|
-
|
|
331
|
-
if (fs.existsSync(jsEslintConfigPath)) {
|
|
332
|
-
fs.copyFileSync(jsEslintConfigPath, destEslintConfigPath);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
282
|
}
|
|
336
283
|
|
|
337
284
|
function showHelp() {
|
|
@@ -382,7 +329,4 @@ if (args[0] === '-v' || args[0] === '--version') {
|
|
|
382
329
|
}
|
|
383
330
|
|
|
384
331
|
const projectName = args[0];
|
|
385
|
-
createProject(projectName)
|
|
386
|
-
console.error('โ Error creating project:', error.message);
|
|
387
|
-
process.exit(1);
|
|
388
|
-
});
|
|
332
|
+
createProject(projectName);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-arktos",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "๐ A modern Node.js backend boilerplate with TypeScript, Express, JWT authentication, Prisma ORM, PostgreSQL, and Resend email service. Includes complete authentication flow, security middleware, and database management.",
|
|
5
5
|
"main": "bin/cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,15 +9,12 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"bin/",
|
|
11
11
|
"src/",
|
|
12
|
-
"src-js/",
|
|
13
12
|
"prisma/",
|
|
14
13
|
"template.package.json",
|
|
15
|
-
"template.js.package.json",
|
|
16
14
|
".env.example",
|
|
17
15
|
"vercel.json",
|
|
18
16
|
"tsconfig.json",
|
|
19
17
|
"eslint.config.js",
|
|
20
|
-
"eslint.config.js.template",
|
|
21
18
|
"README.md",
|
|
22
19
|
"LICENSE"
|
|
23
20
|
],
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export default [
|
|
2
|
-
{
|
|
3
|
-
files: ['**/*.js'],
|
|
4
|
-
languageOptions: {
|
|
5
|
-
ecmaVersion: 'latest',
|
|
6
|
-
sourceType: 'module',
|
|
7
|
-
globals: {
|
|
8
|
-
process: 'readonly',
|
|
9
|
-
Buffer: 'readonly',
|
|
10
|
-
__dirname: 'readonly',
|
|
11
|
-
__filename: 'readonly',
|
|
12
|
-
console: 'readonly',
|
|
13
|
-
global: 'readonly',
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
rules: {
|
|
17
|
-
'no-unused-vars': ['warn', {
|
|
18
|
-
argsIgnorePattern: '^_',
|
|
19
|
-
varsIgnorePattern: '^_'
|
|
20
|
-
}],
|
|
21
|
-
'no-console': 'off',
|
|
22
|
-
'prefer-const': 'error',
|
|
23
|
-
'no-var': 'error',
|
|
24
|
-
'no-undef': 'error',
|
|
25
|
-
'semi': ['error', 'always'],
|
|
26
|
-
'quotes': ['error', 'single'],
|
|
27
|
-
'indent': ['error', 2],
|
|
28
|
-
'comma-dangle': ['error', 'always-multiline'],
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
];
|
package/src-js/app.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import dotenv from 'dotenv';
|
|
3
|
-
import routes from './routes/index.js';
|
|
4
|
-
import { errorHandling, securityMiddleware, rateLimiter } from './middleware/index.js';
|
|
5
|
-
import DatabaseService from './services/database.service.js';
|
|
6
|
-
import logger from './config/logger.js';
|
|
7
|
-
|
|
8
|
-
// Load environment variables
|
|
9
|
-
dotenv.config();
|
|
10
|
-
|
|
11
|
-
const app = express();
|
|
12
|
-
const PORT = process.env.PORT || 3001;
|
|
13
|
-
|
|
14
|
-
// Security middleware stack
|
|
15
|
-
app.use(securityMiddleware);
|
|
16
|
-
|
|
17
|
-
// Rate limiting
|
|
18
|
-
app.use('/api', rateLimiter.general);
|
|
19
|
-
|
|
20
|
-
// Body parsing middleware
|
|
21
|
-
app.use(express.json({ limit: '10mb' }));
|
|
22
|
-
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
|
23
|
-
|
|
24
|
-
// Trust proxy (for accurate IP addresses)
|
|
25
|
-
app.set('trust proxy', 1);
|
|
26
|
-
|
|
27
|
-
// API routes
|
|
28
|
-
app.use('/api', routes);
|
|
29
|
-
|
|
30
|
-
// Health check route (outside of rate limiting)
|
|
31
|
-
app.get('/health', async (req, res) => {
|
|
32
|
-
try {
|
|
33
|
-
const dbService = DatabaseService.getInstance();
|
|
34
|
-
const dbHealth = await dbService.healthCheck();
|
|
35
|
-
|
|
36
|
-
res.json({
|
|
37
|
-
status: dbHealth.connected ? 'ok' : 'error',
|
|
38
|
-
timestamp: new Date().toISOString(),
|
|
39
|
-
uptime: process.uptime(),
|
|
40
|
-
database: dbHealth,
|
|
41
|
-
});
|
|
42
|
-
} catch (error) {
|
|
43
|
-
res.status(503).json({
|
|
44
|
-
status: 'error',
|
|
45
|
-
message: 'Health check failed',
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// 404 handler
|
|
51
|
-
app.use('*', (req, res) => {
|
|
52
|
-
res.status(404).json({
|
|
53
|
-
success: false,
|
|
54
|
-
message: 'Route not found',
|
|
55
|
-
error: `Cannot ${req.method} ${req.originalUrl}`,
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// Global error handler
|
|
60
|
-
app.use(errorHandling);
|
|
61
|
-
|
|
62
|
-
// Graceful shutdown
|
|
63
|
-
const gracefulShutdown = async (signal) => {
|
|
64
|
-
logger.info(`Received ${signal}, shutting down gracefully...`);
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
const dbService = DatabaseService.getInstance();
|
|
68
|
-
await dbService.disconnect();
|
|
69
|
-
logger.info('Database connection closed');
|
|
70
|
-
} catch (error) {
|
|
71
|
-
logger.error('Error during graceful shutdown:', error);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
process.exit(0);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
|
|
78
|
-
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
|
|
79
|
-
|
|
80
|
-
const startServer = async () => {
|
|
81
|
-
try {
|
|
82
|
-
// Initialize database connection
|
|
83
|
-
const dbService = DatabaseService.getInstance();
|
|
84
|
-
await dbService.connect();
|
|
85
|
-
|
|
86
|
-
app.listen(PORT, () => {
|
|
87
|
-
logger.info(`Server running on port ${PORT}`);
|
|
88
|
-
logger.info(`Health check: http://localhost:${PORT}/health`);
|
|
89
|
-
logger.info(`API base URL: http://localhost:${PORT}/api`);
|
|
90
|
-
});
|
|
91
|
-
} catch (error) {
|
|
92
|
-
logger.error('Failed to start server:', error);
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
startServer();
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import logger from './logger.js';
|
|
2
|
-
import { envSchema } from '../schemas/index.js';
|
|
3
|
-
|
|
4
|
-
export function validateEnv() {
|
|
5
|
-
try {
|
|
6
|
-
const env = envSchema.parse(process.env);
|
|
7
|
-
logger.info('Environment validation successful');
|
|
8
|
-
return env;
|
|
9
|
-
} catch (error) {
|
|
10
|
-
logger.error('Environment validation failed:', error);
|
|
11
|
-
process.exit(1);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const config = validateEnv();
|
package/src-js/config/logger.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import winston from 'winston';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
|
|
5
|
-
const logLevel = process.env.LOG_LEVEL || 'info';
|
|
6
|
-
const logFile = process.env.LOG_FILE || 'logs/app.log';
|
|
7
|
-
|
|
8
|
-
// Ensure logs directory exists
|
|
9
|
-
const logDir = path.dirname(logFile);
|
|
10
|
-
if (!fs.existsSync(logDir)) {
|
|
11
|
-
fs.mkdirSync(logDir, { recursive: true });
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const logFormat = winston.format.combine(
|
|
15
|
-
winston.format.timestamp({
|
|
16
|
-
format: 'YYYY-MM-DD HH:mm:ss',
|
|
17
|
-
}),
|
|
18
|
-
winston.format.errors({ stack: true }),
|
|
19
|
-
winston.format.json(),
|
|
20
|
-
winston.format.prettyPrint()
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
const consoleFormat = winston.format.combine(
|
|
24
|
-
winston.format.colorize(),
|
|
25
|
-
winston.format.timestamp({
|
|
26
|
-
format: 'HH:mm:ss',
|
|
27
|
-
}),
|
|
28
|
-
winston.format.printf(({ timestamp, level, message, ...meta }) => {
|
|
29
|
-
return `${timestamp} [${level}]: ${message} ${Object.keys(meta).length ? JSON.stringify(meta, null, 2) : ''}`;
|
|
30
|
-
})
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
const logger = winston.createLogger({
|
|
34
|
-
level: logLevel,
|
|
35
|
-
format: logFormat,
|
|
36
|
-
defaultMeta: { service: 'arktos-backend' },
|
|
37
|
-
transports: [
|
|
38
|
-
// File transport
|
|
39
|
-
new winston.transports.File({
|
|
40
|
-
filename: logFile,
|
|
41
|
-
handleExceptions: true,
|
|
42
|
-
maxsize: 5242880, // 5MB
|
|
43
|
-
maxFiles: 5,
|
|
44
|
-
}),
|
|
45
|
-
// Error file transport
|
|
46
|
-
new winston.transports.File({
|
|
47
|
-
filename: path.join(logDir, 'error.log'),
|
|
48
|
-
level: 'error',
|
|
49
|
-
handleExceptions: true,
|
|
50
|
-
maxsize: 5242880, // 5MB
|
|
51
|
-
maxFiles: 5,
|
|
52
|
-
}),
|
|
53
|
-
],
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// Console transport for non-production environments
|
|
57
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
58
|
-
logger.add(
|
|
59
|
-
new winston.transports.Console({
|
|
60
|
-
format: consoleFormat,
|
|
61
|
-
handleExceptions: true,
|
|
62
|
-
})
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Handle uncaught exceptions and unhandled rejections
|
|
67
|
-
process.on('uncaughtException', (error) => {
|
|
68
|
-
logger.error('Uncaught Exception:', error);
|
|
69
|
-
process.exit(1);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
process.on('unhandledRejection', (reason, promise) => {
|
|
73
|
-
logger.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
export default logger;
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
export const ERROR_CODES = {
|
|
2
|
-
// Authentication errors
|
|
3
|
-
AUTH_INVALID_CREDENTIALS: 'AUTH_001',
|
|
4
|
-
AUTH_TOKEN_EXPIRED: 'AUTH_002',
|
|
5
|
-
AUTH_TOKEN_INVALID: 'AUTH_003',
|
|
6
|
-
AUTH_USER_NOT_FOUND: 'AUTH_004',
|
|
7
|
-
AUTH_EMAIL_NOT_VERIFIED: 'AUTH_005',
|
|
8
|
-
AUTH_ACCOUNT_DISABLED: 'AUTH_006',
|
|
9
|
-
AUTH_INSUFFICIENT_PERMISSIONS: 'AUTH_007',
|
|
10
|
-
AUTH_USER_EXISTS: 'AUTH_008',
|
|
11
|
-
AUTH_USERNAME_TAKEN: 'AUTH_009',
|
|
12
|
-
AUTH_INVALID_PASSWORD: 'AUTH_010',
|
|
13
|
-
AUTH_TOKEN_REQUIRED: 'AUTH_011',
|
|
14
|
-
AUTH_INVALID_TOKEN: 'AUTH_003', // Alias for AUTH_TOKEN_INVALID
|
|
15
|
-
AUTH_ACCOUNT_DEACTIVATED: 'AUTH_006', // Alias for AUTH_ACCOUNT_DISABLED
|
|
16
|
-
|
|
17
|
-
// Validation errors
|
|
18
|
-
VALIDATION_REQUIRED_FIELD: 'VAL_001',
|
|
19
|
-
VALIDATION_INVALID_FORMAT: 'VAL_002',
|
|
20
|
-
VALIDATION_INVALID_LENGTH: 'VAL_003',
|
|
21
|
-
VALIDATION_INVALID_TYPE: 'VAL_004',
|
|
22
|
-
VALIDATION_ERROR: 'VAL_005',
|
|
23
|
-
|
|
24
|
-
// Database errors
|
|
25
|
-
DB_CONNECTION_ERROR: 'DB_001',
|
|
26
|
-
DB_QUERY_ERROR: 'DB_002',
|
|
27
|
-
DB_CONSTRAINT_VIOLATION: 'DB_003',
|
|
28
|
-
DB_RECORD_NOT_FOUND: 'DB_004',
|
|
29
|
-
DB_DUPLICATE_ENTRY: 'DB_005',
|
|
30
|
-
DATABASE_CONNECTION: 'DB_001', // Alias
|
|
31
|
-
DATABASE_ERROR: 'DB_002', // Alias
|
|
32
|
-
DATABASE_CONSTRAINT: 'DB_003', // Alias
|
|
33
|
-
DATABASE_NOT_FOUND: 'DB_004', // Alias
|
|
34
|
-
DATABASE_CONFLICT: 'DB_005', // Alias
|
|
35
|
-
|
|
36
|
-
// File/Upload errors
|
|
37
|
-
FILE_TOO_LARGE: 'FILE_001',
|
|
38
|
-
FILE_INVALID_TYPE: 'FILE_002',
|
|
39
|
-
FILE_UPLOAD_FAILED: 'FILE_003',
|
|
40
|
-
FILE_NOT_FOUND: 'FILE_004',
|
|
41
|
-
|
|
42
|
-
// Rate limiting errors
|
|
43
|
-
RATE_LIMIT_EXCEEDED: 'RATE_001',
|
|
44
|
-
|
|
45
|
-
// Server errors
|
|
46
|
-
INTERNAL_SERVER_ERROR: 'SRV_001',
|
|
47
|
-
SERVICE_UNAVAILABLE: 'SRV_002',
|
|
48
|
-
EXTERNAL_SERVICE_ERROR: 'SRV_003',
|
|
49
|
-
INTERNAL_ERROR: 'SRV_001', // Alias
|
|
50
|
-
GENERIC_ERROR: 'SRV_004',
|
|
51
|
-
ROUTE_NOT_FOUND: 'SRV_005',
|
|
52
|
-
|
|
53
|
-
// Email service errors
|
|
54
|
-
EMAIL_SEND_FAILED: 'EMAIL_001',
|
|
55
|
-
EMAIL_TEMPLATE_NOT_FOUND: 'EMAIL_002',
|
|
56
|
-
EMAIL_INVALID_RECIPIENT: 'EMAIL_003',
|
|
57
|
-
};
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
import { ERROR_CODES } from './errorCodes.js';
|
|
2
|
-
|
|
3
|
-
export const SERVICE_MESSAGES = {
|
|
4
|
-
// Application messages
|
|
5
|
-
APP: {
|
|
6
|
-
API_RUNNING: {
|
|
7
|
-
code: 'APP_001',
|
|
8
|
-
message: 'API is running successfully',
|
|
9
|
-
statusCode: 200,
|
|
10
|
-
},
|
|
11
|
-
HEALTH_CHECK_FAILED: {
|
|
12
|
-
code: 'APP_002',
|
|
13
|
-
message: 'Health check failed',
|
|
14
|
-
statusCode: 503,
|
|
15
|
-
},
|
|
16
|
-
ENDPOINT_NOT_FOUND: {
|
|
17
|
-
code: 'APP_003',
|
|
18
|
-
message: 'Endpoint not found',
|
|
19
|
-
statusCode: 404,
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
// Authentication messages
|
|
24
|
-
AUTH: {
|
|
25
|
-
LOGIN_SUCCESS: {
|
|
26
|
-
code: 'AUTH_S001',
|
|
27
|
-
message: 'Login successful',
|
|
28
|
-
statusCode: 200,
|
|
29
|
-
},
|
|
30
|
-
REGISTER_SUCCESS: {
|
|
31
|
-
code: 'AUTH_S002',
|
|
32
|
-
message: 'Registration successful',
|
|
33
|
-
statusCode: 201,
|
|
34
|
-
},
|
|
35
|
-
LOGOUT_SUCCESS: {
|
|
36
|
-
code: 'AUTH_S003',
|
|
37
|
-
message: 'Logout successful',
|
|
38
|
-
statusCode: 200,
|
|
39
|
-
},
|
|
40
|
-
EMAIL_VERIFICATION_SUCCESS: {
|
|
41
|
-
code: 'AUTH_S004',
|
|
42
|
-
message: 'Email verified successfully',
|
|
43
|
-
statusCode: 200,
|
|
44
|
-
},
|
|
45
|
-
PASSWORD_RESET_SUCCESS: {
|
|
46
|
-
code: 'AUTH_S005',
|
|
47
|
-
message: 'Password reset successful',
|
|
48
|
-
statusCode: 200,
|
|
49
|
-
},
|
|
50
|
-
INVALID_CREDENTIALS: {
|
|
51
|
-
code: ERROR_CODES.AUTH_INVALID_CREDENTIALS,
|
|
52
|
-
message: 'Invalid email or password',
|
|
53
|
-
statusCode: 401,
|
|
54
|
-
},
|
|
55
|
-
TOKEN_EXPIRED: {
|
|
56
|
-
code: ERROR_CODES.AUTH_TOKEN_EXPIRED,
|
|
57
|
-
message: 'Token has expired',
|
|
58
|
-
statusCode: 401,
|
|
59
|
-
},
|
|
60
|
-
TOKEN_INVALID: {
|
|
61
|
-
code: ERROR_CODES.AUTH_TOKEN_INVALID,
|
|
62
|
-
message: 'Invalid token provided',
|
|
63
|
-
statusCode: 401,
|
|
64
|
-
},
|
|
65
|
-
USER_NOT_FOUND: {
|
|
66
|
-
code: ERROR_CODES.AUTH_USER_NOT_FOUND,
|
|
67
|
-
message: 'User not found',
|
|
68
|
-
statusCode: 404,
|
|
69
|
-
},
|
|
70
|
-
EMAIL_NOT_VERIFIED: {
|
|
71
|
-
code: ERROR_CODES.AUTH_EMAIL_NOT_VERIFIED,
|
|
72
|
-
message: 'Email address is not verified',
|
|
73
|
-
statusCode: 403,
|
|
74
|
-
},
|
|
75
|
-
ACCOUNT_DISABLED: {
|
|
76
|
-
code: ERROR_CODES.AUTH_ACCOUNT_DISABLED,
|
|
77
|
-
message: 'Account has been disabled',
|
|
78
|
-
statusCode: 403,
|
|
79
|
-
},
|
|
80
|
-
INSUFFICIENT_PERMISSIONS: {
|
|
81
|
-
code: ERROR_CODES.AUTH_INSUFFICIENT_PERMISSIONS,
|
|
82
|
-
message: 'Insufficient permissions to access this resource',
|
|
83
|
-
statusCode: 403,
|
|
84
|
-
},
|
|
85
|
-
USER_EXISTS: {
|
|
86
|
-
code: ERROR_CODES.AUTH_USER_EXISTS,
|
|
87
|
-
message: 'User already exists with this email',
|
|
88
|
-
statusCode: 409,
|
|
89
|
-
},
|
|
90
|
-
USERNAME_TAKEN: {
|
|
91
|
-
code: ERROR_CODES.AUTH_USERNAME_TAKEN,
|
|
92
|
-
message: 'Username is already taken',
|
|
93
|
-
statusCode: 409,
|
|
94
|
-
},
|
|
95
|
-
TOKEN_REQUIRED: {
|
|
96
|
-
code: ERROR_CODES.AUTH_TOKEN_REQUIRED,
|
|
97
|
-
message: 'Authentication token is required',
|
|
98
|
-
statusCode: 401,
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
// Validation messages
|
|
103
|
-
VALIDATION: {
|
|
104
|
-
REQUIRED_FIELD: {
|
|
105
|
-
code: ERROR_CODES.VALIDATION_REQUIRED_FIELD,
|
|
106
|
-
message: 'Required field is missing',
|
|
107
|
-
statusCode: 400,
|
|
108
|
-
},
|
|
109
|
-
INVALID_FORMAT: {
|
|
110
|
-
code: ERROR_CODES.VALIDATION_INVALID_FORMAT,
|
|
111
|
-
message: 'Invalid format provided',
|
|
112
|
-
statusCode: 400,
|
|
113
|
-
},
|
|
114
|
-
INVALID_LENGTH: {
|
|
115
|
-
code: ERROR_CODES.VALIDATION_INVALID_LENGTH,
|
|
116
|
-
message: 'Invalid length for field',
|
|
117
|
-
statusCode: 400,
|
|
118
|
-
},
|
|
119
|
-
INVALID_TYPE: {
|
|
120
|
-
code: ERROR_CODES.VALIDATION_INVALID_TYPE,
|
|
121
|
-
message: 'Invalid type provided',
|
|
122
|
-
statusCode: 400,
|
|
123
|
-
},
|
|
124
|
-
VALIDATION_ERROR: {
|
|
125
|
-
code: ERROR_CODES.VALIDATION_ERROR,
|
|
126
|
-
message: 'Validation failed',
|
|
127
|
-
statusCode: 400,
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
// Database messages
|
|
132
|
-
DATABASE: {
|
|
133
|
-
CONNECTION_ERROR: {
|
|
134
|
-
code: ERROR_CODES.DB_CONNECTION_ERROR,
|
|
135
|
-
message: 'Database connection failed',
|
|
136
|
-
statusCode: 503,
|
|
137
|
-
},
|
|
138
|
-
QUERY_ERROR: {
|
|
139
|
-
code: ERROR_CODES.DB_QUERY_ERROR,
|
|
140
|
-
message: 'Database query failed',
|
|
141
|
-
statusCode: 500,
|
|
142
|
-
},
|
|
143
|
-
CONSTRAINT_VIOLATION: {
|
|
144
|
-
code: ERROR_CODES.DB_CONSTRAINT_VIOLATION,
|
|
145
|
-
message: 'Database constraint violation',
|
|
146
|
-
statusCode: 409,
|
|
147
|
-
},
|
|
148
|
-
RECORD_NOT_FOUND: {
|
|
149
|
-
code: ERROR_CODES.DB_RECORD_NOT_FOUND,
|
|
150
|
-
message: 'Record not found',
|
|
151
|
-
statusCode: 404,
|
|
152
|
-
},
|
|
153
|
-
DUPLICATE_ENTRY: {
|
|
154
|
-
code: ERROR_CODES.DB_DUPLICATE_ENTRY,
|
|
155
|
-
message: 'Duplicate entry detected',
|
|
156
|
-
statusCode: 409,
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
|
|
160
|
-
// File upload messages
|
|
161
|
-
FILE: {
|
|
162
|
-
TOO_LARGE: {
|
|
163
|
-
code: ERROR_CODES.FILE_TOO_LARGE,
|
|
164
|
-
message: 'File size exceeds maximum limit',
|
|
165
|
-
statusCode: 413,
|
|
166
|
-
},
|
|
167
|
-
INVALID_TYPE: {
|
|
168
|
-
code: ERROR_CODES.FILE_INVALID_TYPE,
|
|
169
|
-
message: 'Invalid file type',
|
|
170
|
-
statusCode: 400,
|
|
171
|
-
},
|
|
172
|
-
UPLOAD_FAILED: {
|
|
173
|
-
code: ERROR_CODES.FILE_UPLOAD_FAILED,
|
|
174
|
-
message: 'File upload failed',
|
|
175
|
-
statusCode: 500,
|
|
176
|
-
},
|
|
177
|
-
NOT_FOUND: {
|
|
178
|
-
code: ERROR_CODES.FILE_NOT_FOUND,
|
|
179
|
-
message: 'File not found',
|
|
180
|
-
statusCode: 404,
|
|
181
|
-
},
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
// Rate limiting messages
|
|
185
|
-
RATE_LIMIT: {
|
|
186
|
-
EXCEEDED: {
|
|
187
|
-
code: ERROR_CODES.RATE_LIMIT_EXCEEDED,
|
|
188
|
-
message: 'Rate limit exceeded. Please try again later',
|
|
189
|
-
statusCode: 429,
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
|
|
193
|
-
// Server messages
|
|
194
|
-
SERVER: {
|
|
195
|
-
INTERNAL_ERROR: {
|
|
196
|
-
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
197
|
-
message: 'Internal server error occurred',
|
|
198
|
-
statusCode: 500,
|
|
199
|
-
},
|
|
200
|
-
SERVICE_UNAVAILABLE: {
|
|
201
|
-
code: ERROR_CODES.SERVICE_UNAVAILABLE,
|
|
202
|
-
message: 'Service temporarily unavailable',
|
|
203
|
-
statusCode: 503,
|
|
204
|
-
},
|
|
205
|
-
EXTERNAL_SERVICE_ERROR: {
|
|
206
|
-
code: ERROR_CODES.EXTERNAL_SERVICE_ERROR,
|
|
207
|
-
message: 'External service error',
|
|
208
|
-
statusCode: 502,
|
|
209
|
-
},
|
|
210
|
-
GENERIC_ERROR: {
|
|
211
|
-
code: ERROR_CODES.GENERIC_ERROR,
|
|
212
|
-
message: 'An unexpected error occurred',
|
|
213
|
-
statusCode: 500,
|
|
214
|
-
},
|
|
215
|
-
ROUTE_NOT_FOUND: {
|
|
216
|
-
code: ERROR_CODES.ROUTE_NOT_FOUND,
|
|
217
|
-
message: 'Route not found',
|
|
218
|
-
statusCode: 404,
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
|
|
222
|
-
// Email service messages
|
|
223
|
-
EMAIL: {
|
|
224
|
-
SEND_FAILED: {
|
|
225
|
-
code: ERROR_CODES.EMAIL_SEND_FAILED,
|
|
226
|
-
message: 'Failed to send email',
|
|
227
|
-
statusCode: 500,
|
|
228
|
-
},
|
|
229
|
-
TEMPLATE_NOT_FOUND: {
|
|
230
|
-
code: ERROR_CODES.EMAIL_TEMPLATE_NOT_FOUND,
|
|
231
|
-
message: 'Email template not found',
|
|
232
|
-
statusCode: 404,
|
|
233
|
-
},
|
|
234
|
-
INVALID_RECIPIENT: {
|
|
235
|
-
code: ERROR_CODES.EMAIL_INVALID_RECIPIENT,
|
|
236
|
-
message: 'Invalid email recipient',
|
|
237
|
-
statusCode: 400,
|
|
238
|
-
},
|
|
239
|
-
},
|
|
240
|
-
};
|