create-arktos 1.4.0 โ 1.5.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.
- package/bin/cli.js +19 -75
- package/eslint.config.js +40 -25
- 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,27 +46,22 @@ 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...');
|
|
66
53
|
const templatePackageJsonPath = path.join(ROOT_DIR, packageTemplate);
|
|
67
54
|
const targetPackageJsonPath = path.join(projectName, 'package.json');
|
|
68
|
-
|
|
55
|
+
|
|
69
56
|
if (fs.existsSync(templatePackageJsonPath)) {
|
|
70
57
|
const packageJson = JSON.parse(fs.readFileSync(templatePackageJsonPath, 'utf8'));
|
|
71
|
-
|
|
58
|
+
|
|
72
59
|
// Update project name
|
|
73
60
|
packageJson.name = projectName;
|
|
74
|
-
|
|
61
|
+
|
|
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();
|
|
@@ -107,7 +89,7 @@ async function createProject(projectName) {
|
|
|
107
89
|
|
|
108
90
|
} catch (error) {
|
|
109
91
|
console.error('โ Error creating project:', error.message);
|
|
110
|
-
|
|
92
|
+
|
|
111
93
|
// Cleanup on error
|
|
112
94
|
try {
|
|
113
95
|
if (fs.existsSync(projectName)) {
|
|
@@ -116,7 +98,7 @@ async function createProject(projectName) {
|
|
|
116
98
|
} catch (cleanupError) {
|
|
117
99
|
console.error('โ Error during cleanup:', cleanupError.message);
|
|
118
100
|
}
|
|
119
|
-
|
|
101
|
+
|
|
120
102
|
process.exit(1);
|
|
121
103
|
}
|
|
122
104
|
}
|
|
@@ -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
|
|
@@ -300,7 +259,7 @@ A modern Node.js backend API built with Arktos boilerplate.
|
|
|
300
259
|
- \`npm run lint\` - Run ESLint
|
|
301
260
|
- \`npm run db:studio\` - Open Prisma Studio
|
|
302
261
|
|
|
303
|
-
Happy coding!
|
|
262
|
+
Happy coding! ๐`,
|
|
304
263
|
};
|
|
305
264
|
|
|
306
265
|
// Write config files
|
|
@@ -308,30 +267,18 @@ Happy coding! ๐`
|
|
|
308
267
|
fs.writeFileSync(path.join(dest, fileName), content);
|
|
309
268
|
}
|
|
310
269
|
|
|
311
|
-
// Copy template files from root
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
? [...commonTemplateFiles, 'tsconfig.json', 'eslint.config.js']
|
|
315
|
-
: [...commonTemplateFiles];
|
|
316
|
-
|
|
270
|
+
// Copy template files from root
|
|
271
|
+
const templateFiles = ['.env.example', 'vercel.json', 'tsconfig.json', 'eslint.config.js'];
|
|
272
|
+
|
|
317
273
|
for (const templateFile of templateFiles) {
|
|
318
274
|
const srcPath = path.join(ROOT_DIR, templateFile);
|
|
319
275
|
const destPath = path.join(dest, templateFile);
|
|
320
|
-
|
|
276
|
+
|
|
321
277
|
if (fs.existsSync(srcPath)) {
|
|
322
278
|
fs.copyFileSync(srcPath, destPath);
|
|
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/eslint.config.js
CHANGED
|
@@ -23,37 +23,52 @@ module.exports = [
|
|
|
23
23
|
},
|
|
24
24
|
},
|
|
25
25
|
rules: {
|
|
26
|
-
'no-unused-vars': [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
'no-unused-vars': [
|
|
27
|
+
'error',
|
|
28
|
+
{
|
|
29
|
+
argsIgnorePattern: '^_',
|
|
30
|
+
varsIgnorePattern: '^_',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
'no-console': [
|
|
34
|
+
'warn',
|
|
35
|
+
{
|
|
36
|
+
allow: ['warn', 'error'],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
33
39
|
'prefer-const': 'error',
|
|
34
40
|
'no-var': 'error',
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
eqeqeq: ['error', 'always'],
|
|
42
|
+
curly: ['error', 'all'],
|
|
37
43
|
'brace-style': ['error', '1tbs'],
|
|
38
44
|
'comma-dangle': ['error', 'always-multiline'],
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
indent: ['error', 2],
|
|
46
|
+
quotes: ['error', 'single'],
|
|
47
|
+
semi: ['error', 'always'],
|
|
42
48
|
'no-trailing-spaces': 'error',
|
|
43
|
-
'no-multiple-empty-lines': [
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
'no-multiple-empty-lines': [
|
|
50
|
+
'error',
|
|
51
|
+
{
|
|
52
|
+
max: 2,
|
|
53
|
+
maxEOF: 1,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
47
56
|
'object-curly-spacing': ['error', 'always'],
|
|
48
57
|
'array-bracket-spacing': ['error', 'never'],
|
|
49
|
-
'key-spacing': [
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
'key-spacing': [
|
|
59
|
+
'error',
|
|
60
|
+
{
|
|
61
|
+
beforeColon: false,
|
|
62
|
+
afterColon: true,
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
'comma-spacing': [
|
|
66
|
+
'error',
|
|
67
|
+
{
|
|
68
|
+
before: false,
|
|
69
|
+
after: true,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
57
72
|
'no-undef': 'error',
|
|
58
73
|
'no-redeclare': 'error',
|
|
59
74
|
'no-dupe-keys': 'error',
|
|
@@ -76,4 +91,4 @@ module.exports = [
|
|
|
76
91
|
},
|
|
77
92
|
},
|
|
78
93
|
},
|
|
79
|
-
];
|
|
94
|
+
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-arktos",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
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
|
-
};
|