build-app-with 2.0.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/LICENSE +21 -0
- package/README.md +240 -0
- package/bin/cli.js +18 -0
- package/index.js +3 -0
- package/package.json +80 -0
- package/src/__tests__/core/error-handler.test.js +99 -0
- package/src/__tests__/core/logger.test.js +93 -0
- package/src/__tests__/e2e/cli-integration.test.js +220 -0
- package/src/__tests__/e2e/framework-generation.test.js +249 -0
- package/src/__tests__/setup.js +70 -0
- package/src/config/package-mappings.js +110 -0
- package/src/constants/index.js +42 -0
- package/src/core/error-handler.js +89 -0
- package/src/core/logger.js +89 -0
- package/src/core/package-manager.js +114 -0
- package/src/create-app.js +90 -0
- package/src/generators/express/index.js +52 -0
- package/src/generators/express/project-generator.js +367 -0
- package/src/generators/express/prompts.js +74 -0
- package/src/generators/express/simple-generator.js +275 -0
- package/src/generators/express/templates/app.js +73 -0
- package/src/generators/express/templates/config/database.js +122 -0
- package/src/generators/express/templates/config.js +37 -0
- package/src/generators/express/templates/controllers.js +49 -0
- package/src/generators/express/templates/docker.js +72 -0
- package/src/generators/express/templates/middleware/errorHandler.js +49 -0
- package/src/generators/express/templates/middleware.js +59 -0
- package/src/generators/express/templates/models.js +77 -0
- package/src/generators/express/templates/package-json.js +55 -0
- package/src/generators/express/templates/readme.js +310 -0
- package/src/generators/express/templates/routes.js +36 -0
- package/src/generators/express/templates/server.js +59 -0
- package/src/generators/express/templates/services.js +55 -0
- package/src/generators/express/templates/tests.js +46 -0
- package/src/generators/express/templates/utils/logger.js +54 -0
- package/src/generators/fastify/index.js +46 -0
- package/src/generators/fastify/project-generator.js +373 -0
- package/src/generators/fastify/prompts.js +76 -0
- package/src/generators/fastify/templates/app.js +179 -0
- package/src/generators/fastify/templates/config.js +33 -0
- package/src/generators/fastify/templates/docker.js +73 -0
- package/src/generators/fastify/templates/models.js +77 -0
- package/src/generators/fastify/templates/package-json.js +57 -0
- package/src/generators/fastify/templates/plugins.js +38 -0
- package/src/generators/fastify/templates/readme.js +328 -0
- package/src/generators/fastify/templates/routes.js +32 -0
- package/src/generators/fastify/templates/server.js +71 -0
- package/src/generators/fastify/templates/services.js +50 -0
- package/src/generators/fastify/templates/tests.js +60 -0
- package/src/generators/nextjs/dependency-manager.js +99 -0
- package/src/generators/nextjs/file-generator.js +256 -0
- package/src/generators/nextjs/nextjs-generator.js +177 -0
- package/src/generators/nextjs/nextjs-project-generator.js +896 -0
- package/src/generators/nextjs/package-mappings.js +51 -0
- package/src/generators/nextjs/templates.js +272 -0
- package/src/generators/package-json-generator.js +117 -0
- package/src/generators/vite/components/CreditComponent.jsx +41 -0
- package/src/generators/vite/components/app-component.js +359 -0
- package/src/generators/vite/components/main-file.js +88 -0
- package/src/generators/vite/eslint-config-generator.js +20 -0
- package/src/generators/vite/file-generator.js +796 -0
- package/src/generators/vite/prettier-config-generator.js +10 -0
- package/src/generators/vite/structures/domain-driven-structure.js +465 -0
- package/src/generators/vite/structures/feature-based-structure.js +342 -0
- package/src/generators/vite/structures/simple-structure.js +62 -0
- package/src/generators/vite/styles/index-css.js +130 -0
- package/src/generators/vite/tailwind-config-generator.js +14 -0
- package/src/generators/vite/vite-config-generator.js +22 -0
- package/src/generators/vite/vite-project-generator.js +263 -0
- package/src/generators/vite-project-generator.js +136 -0
- package/src/prompts/index.js +262 -0
- package/src/types/index.js +113 -0
- package/src/utils/answer-helpers.js +24 -0
- package/src/utils/credits.js +192 -0
- package/src/utils/dependencies.js +25 -0
- package/src/utils/messages.js +27 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate main Fastify app.js file
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { FEATURES, DATABASES } from '../../../types/index.js';
|
|
6
|
+
import { hasFeature } from '../../../utils/answer-helpers.js';
|
|
7
|
+
|
|
8
|
+
export function generateAppJs(projectPath, answers) {
|
|
9
|
+
let content = `import Fastify from 'fastify';
|
|
10
|
+
import cors from '@fastify/cors';
|
|
11
|
+
import helmet from '@fastify/helmet';
|
|
12
|
+
import rateLimit from '@fastify/rate-limit';
|
|
13
|
+
import env from '@fastify/env';
|
|
14
|
+
import { logger } from './utils/logger.js';
|
|
15
|
+
import { errorHandler } from './plugins/errorHandler.js';
|
|
16
|
+
import { notFound } from './plugins/notFound.js';
|
|
17
|
+
|
|
18
|
+
// Environment schema
|
|
19
|
+
const envSchema = {
|
|
20
|
+
type: 'object',
|
|
21
|
+
required: ['PORT'],
|
|
22
|
+
properties: {
|
|
23
|
+
PORT: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
default: '3000'
|
|
26
|
+
},
|
|
27
|
+
NODE_ENV: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
default: 'development'
|
|
30
|
+
},
|
|
31
|
+
HOST: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
default: '0.0.0.0'
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
// Add database environment variables
|
|
38
|
+
if (answers.database === DATABASES.MONGODB) {
|
|
39
|
+
content += ` MONGODB_URI: {
|
|
40
|
+
type: 'string',
|
|
41
|
+
default: 'mongodb://localhost:27017/${answers.projectName}'
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
} else if (answers.database === DATABASES.POSTGRESQL || answers.database === DATABASES.SQLITE) {
|
|
45
|
+
content += ` DATABASE_URL: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
default: '${answers.database === DATABASES.POSTGRESQL ? 'postgresql://username:password@localhost:5432/' : 'file:./dev.db'}${answers.projectName}'
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
} else if (answers.database === DATABASES.MYSQL) {
|
|
51
|
+
content += ` DB_HOST: {
|
|
52
|
+
type: 'string',
|
|
53
|
+
default: 'localhost'
|
|
54
|
+
},
|
|
55
|
+
DB_PORT: {
|
|
56
|
+
type: 'string',
|
|
57
|
+
default: '3306'
|
|
58
|
+
},
|
|
59
|
+
DB_NAME: {
|
|
60
|
+
type: 'string',
|
|
61
|
+
default: '${answers.projectName}'
|
|
62
|
+
},
|
|
63
|
+
DB_USER: {
|
|
64
|
+
type: 'string',
|
|
65
|
+
default: 'root'
|
|
66
|
+
},
|
|
67
|
+
DB_PASSWORD: {
|
|
68
|
+
type: 'string',
|
|
69
|
+
default: 'password'
|
|
70
|
+
}
|
|
71
|
+
`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Add authentication environment variables
|
|
75
|
+
if (answers.authStrategy && answers.authStrategy !== 'none') {
|
|
76
|
+
content += ` JWT_SECRET: {
|
|
77
|
+
type: 'string',
|
|
78
|
+
default: 'your-super-secret-jwt-key'
|
|
79
|
+
},
|
|
80
|
+
JWT_EXPIRES_IN: {
|
|
81
|
+
type: 'string',
|
|
82
|
+
default: '7d'
|
|
83
|
+
}
|
|
84
|
+
`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Add CORS environment variables
|
|
88
|
+
if (answers.features && answers.features.includes(FEATURES.CORS)) {
|
|
89
|
+
content += ` CORS_ORIGIN: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
default: 'http://localhost:3000'
|
|
92
|
+
}
|
|
93
|
+
`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Add rate limiting environment variables
|
|
97
|
+
if (hasFeature(answers, 'rate-limit')) {
|
|
98
|
+
content += ` RATE_LIMIT_MAX: {
|
|
99
|
+
type: 'string',
|
|
100
|
+
default: '100'
|
|
101
|
+
},
|
|
102
|
+
RATE_LIMIT_TIME_WINDOW: {
|
|
103
|
+
type: 'string',
|
|
104
|
+
default: '60000'
|
|
105
|
+
}
|
|
106
|
+
`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
content += ` }
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export async function buildApp() {
|
|
113
|
+
const fastify = Fastify({
|
|
114
|
+
logger: {
|
|
115
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
116
|
+
transport: process.env.NODE_ENV === 'development' ? {
|
|
117
|
+
target: 'pino-pretty',
|
|
118
|
+
options: {
|
|
119
|
+
colorize: true
|
|
120
|
+
}
|
|
121
|
+
} : undefined
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Register environment plugin
|
|
126
|
+
await fastify.register(env, { schema: envSchema });
|
|
127
|
+
|
|
128
|
+
// Register security plugins
|
|
129
|
+
await fastify.register(helmet);
|
|
130
|
+
|
|
131
|
+
// Register CORS plugin
|
|
132
|
+
if (hasFeature(answers, 'cors')) {
|
|
133
|
+
await fastify.register(cors, {
|
|
134
|
+
origin: fastify.config.CORS_ORIGIN || 'http://localhost:3000',
|
|
135
|
+
credentials: true
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Register rate limiting plugin
|
|
140
|
+
if (answers.features.includes('rate-limit')) {
|
|
141
|
+
await fastify.register(rateLimit, {
|
|
142
|
+
max: parseInt(fastify.config.RATE_LIMIT_MAX) || 100,
|
|
143
|
+
timeWindow: parseInt(fastify.config.RATE_LIMIT_TIME_WINDOW) || 60000
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Register custom plugins
|
|
148
|
+
await fastify.register(errorHandler);
|
|
149
|
+
await fastify.register(notFound);
|
|
150
|
+
|
|
151
|
+
// Health check endpoint
|
|
152
|
+
fastify.get('/health', async (request, reply) => {
|
|
153
|
+
return {
|
|
154
|
+
status: 'OK',
|
|
155
|
+
timestamp: new Date().toISOString(),
|
|
156
|
+
uptime: process.uptime(),
|
|
157
|
+
environment: fastify.config.NODE_ENV,
|
|
158
|
+
version: '1.0.0'
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// API routes
|
|
163
|
+
fastify.get('/api', async (request, reply) => {
|
|
164
|
+
return {
|
|
165
|
+
message: 'Welcome to ${answers.projectName} API',
|
|
166
|
+
version: '1.0.0',
|
|
167
|
+
endpoints: {
|
|
168
|
+
health: '/health',
|
|
169
|
+
api: '/api'
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
return fastify;
|
|
175
|
+
}
|
|
176
|
+
`;
|
|
177
|
+
|
|
178
|
+
return content;
|
|
179
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate Fastify config template
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export function generateConfig(projectPath, answers) {
|
|
6
|
+
const configContent = `export const config = {
|
|
7
|
+
port: process.env.PORT || 3000,
|
|
8
|
+
host: process.env.HOST || '0.0.0.0',
|
|
9
|
+
nodeEnv: process.env.NODE_ENV || 'development',
|
|
10
|
+
corsOrigin: process.env.CORS_ORIGIN || 'http://localhost:3000',
|
|
11
|
+
database: {
|
|
12
|
+
url: process.env.DATABASE_URL || process.env.MONGODB_URI,
|
|
13
|
+
host: process.env.DB_HOST || 'localhost',
|
|
14
|
+
port: process.env.DB_PORT || 3306,
|
|
15
|
+
name: process.env.DB_NAME || '${answers.projectName}',
|
|
16
|
+
user: process.env.DB_USER || 'root',
|
|
17
|
+
password: process.env.DB_PASSWORD || 'password'
|
|
18
|
+
},
|
|
19
|
+
auth: {
|
|
20
|
+
jwtSecret: process.env.JWT_SECRET || 'your-secret-key',
|
|
21
|
+
jwtExpiresIn: process.env.JWT_EXPIRES_IN || '7d'
|
|
22
|
+
},
|
|
23
|
+
rateLimit: {
|
|
24
|
+
max: parseInt(process.env.RATE_LIMIT_MAX) || 100,
|
|
25
|
+
timeWindow: parseInt(process.env.RATE_LIMIT_TIME_WINDOW) || 60000
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default config;
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
return configContent;
|
|
33
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate Fastify Docker template
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export function generateDocker(projectPath, answers) {
|
|
6
|
+
const dockerfile = `# Use Node.js LTS version
|
|
7
|
+
FROM node:18-alpine
|
|
8
|
+
|
|
9
|
+
# Set working directory
|
|
10
|
+
WORKDIR /app
|
|
11
|
+
|
|
12
|
+
# Copy package files
|
|
13
|
+
COPY package*.json ./
|
|
14
|
+
|
|
15
|
+
# Install dependencies
|
|
16
|
+
RUN npm ci --only=production
|
|
17
|
+
|
|
18
|
+
# Copy source code
|
|
19
|
+
COPY . .
|
|
20
|
+
|
|
21
|
+
# Create non-root user
|
|
22
|
+
RUN addgroup -g 1001 -S nodejs
|
|
23
|
+
RUN adduser -S nextjs -u 1001
|
|
24
|
+
|
|
25
|
+
# Change ownership
|
|
26
|
+
RUN chown -R nextjs:nodejs /app
|
|
27
|
+
USER nextjs
|
|
28
|
+
|
|
29
|
+
# Expose port
|
|
30
|
+
EXPOSE 3000
|
|
31
|
+
|
|
32
|
+
# Health check
|
|
33
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
|
|
34
|
+
CMD curl -f http://localhost:3000/health || exit 1
|
|
35
|
+
|
|
36
|
+
# Start the application
|
|
37
|
+
CMD ["npm", "start"]
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
const dockerCompose = `version: '3.8'
|
|
41
|
+
|
|
42
|
+
services:
|
|
43
|
+
app:
|
|
44
|
+
build: .
|
|
45
|
+
ports:
|
|
46
|
+
- "3000:3000"
|
|
47
|
+
environment:
|
|
48
|
+
- NODE_ENV=production
|
|
49
|
+
- PORT=3000
|
|
50
|
+
- HOST=0.0.0.0
|
|
51
|
+
depends_on:
|
|
52
|
+
- db
|
|
53
|
+
restart: unless-stopped
|
|
54
|
+
|
|
55
|
+
db:
|
|
56
|
+
image: ${answers.database === 'mongodb' ? 'mongo:latest' : 'postgres:15-alpine'}
|
|
57
|
+
environment:
|
|
58
|
+
${answers.database === 'mongodb'
|
|
59
|
+
? 'MONGO_INITDB_DATABASE=myapp'
|
|
60
|
+
: 'POSTGRES_DB=myapp\n POSTGRES_USER=postgres\n POSTGRES_PASSWORD=password'
|
|
61
|
+
}
|
|
62
|
+
volumes:
|
|
63
|
+
- db_data:/data/db
|
|
64
|
+
ports:
|
|
65
|
+
- "${answers.database === 'mongodb' ? '27017:27017' : '5432:5432'}"
|
|
66
|
+
restart: unless-stopped
|
|
67
|
+
|
|
68
|
+
volumes:
|
|
69
|
+
db_data:
|
|
70
|
+
`;
|
|
71
|
+
|
|
72
|
+
return { dockerfile, dockerCompose };
|
|
73
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate Fastify models template
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { DATABASES } from '../../../types/index.js';
|
|
6
|
+
|
|
7
|
+
export function generateModels(projectPath, answers) {
|
|
8
|
+
if (answers.database === DATABASES.MONGODB) {
|
|
9
|
+
return generateMongooseModels(answers);
|
|
10
|
+
} else if (answers.database === DATABASES.POSTGRESQL || answers.database === DATABASES.SQLITE) {
|
|
11
|
+
return generatePrismaModels(answers);
|
|
12
|
+
} else if (answers.database === DATABASES.MYSQL) {
|
|
13
|
+
return generateSequelizeModels(answers);
|
|
14
|
+
}
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function generateMongooseModels(answers) {
|
|
19
|
+
return `import mongoose from 'mongoose';
|
|
20
|
+
|
|
21
|
+
const userSchema = new mongoose.Schema({
|
|
22
|
+
name: {
|
|
23
|
+
type: String,
|
|
24
|
+
required: true,
|
|
25
|
+
trim: true
|
|
26
|
+
},
|
|
27
|
+
email: {
|
|
28
|
+
type: String,
|
|
29
|
+
required: true,
|
|
30
|
+
unique: true,
|
|
31
|
+
lowercase: true,
|
|
32
|
+
trim: true
|
|
33
|
+
},
|
|
34
|
+
password: {
|
|
35
|
+
type: String,
|
|
36
|
+
required: true,
|
|
37
|
+
minlength: 6
|
|
38
|
+
}
|
|
39
|
+
}, {
|
|
40
|
+
timestamps: true
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const User = mongoose.model('User', userSchema);
|
|
44
|
+
`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function generatePrismaModels(answers) {
|
|
48
|
+
return `// Prisma schema will be generated in schema.prisma
|
|
49
|
+
// This is a placeholder for Prisma models
|
|
50
|
+
|
|
51
|
+
export const prisma = new PrismaClient();
|
|
52
|
+
`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function generateSequelizeModels(answers) {
|
|
56
|
+
return `import { DataTypes } from 'sequelize';
|
|
57
|
+
import { sequelize } from '../config/database.js';
|
|
58
|
+
|
|
59
|
+
export const User = sequelize.define('User', {
|
|
60
|
+
name: {
|
|
61
|
+
type: DataTypes.STRING,
|
|
62
|
+
allowNull: false
|
|
63
|
+
},
|
|
64
|
+
email: {
|
|
65
|
+
type: DataTypes.STRING,
|
|
66
|
+
allowNull: false,
|
|
67
|
+
unique: true
|
|
68
|
+
},
|
|
69
|
+
password: {
|
|
70
|
+
type: DataTypes.STRING,
|
|
71
|
+
allowNull: false
|
|
72
|
+
}
|
|
73
|
+
}, {
|
|
74
|
+
timestamps: true
|
|
75
|
+
});
|
|
76
|
+
`;
|
|
77
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate package.json for Fastify project
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { FRAMEWORKS, DATABASES, AUTH_STRATEGIES } from '../../../types/index.js';
|
|
6
|
+
|
|
7
|
+
export function generatePackageJson(answers) {
|
|
8
|
+
const basePackage = {
|
|
9
|
+
name: answers.projectName,
|
|
10
|
+
version: '1.0.0',
|
|
11
|
+
description: `A production-ready Fastify application - ${answers.projectName}`,
|
|
12
|
+
main: 'src/server.js',
|
|
13
|
+
type: 'module',
|
|
14
|
+
scripts: {
|
|
15
|
+
start: 'node src/server.js',
|
|
16
|
+
dev: 'nodemon src/server.js',
|
|
17
|
+
test: answers.includeTests ? 'jest' : undefined,
|
|
18
|
+
'test:watch': answers.includeTests ? 'jest --watch' : undefined,
|
|
19
|
+
'test:coverage': answers.includeTests ? 'jest --coverage' : undefined,
|
|
20
|
+
'test:tap': answers.includeTests ? 'tap test/**/*.test.js' : undefined
|
|
21
|
+
},
|
|
22
|
+
keywords: [
|
|
23
|
+
'fastify',
|
|
24
|
+
'nodejs',
|
|
25
|
+
'api',
|
|
26
|
+
'backend',
|
|
27
|
+
'server',
|
|
28
|
+
'rest',
|
|
29
|
+
'production-ready',
|
|
30
|
+
'high-performance'
|
|
31
|
+
],
|
|
32
|
+
author: 'Generated by build-app-with',
|
|
33
|
+
license: 'MIT',
|
|
34
|
+
engines: {
|
|
35
|
+
node: '>=18.0.0'
|
|
36
|
+
},
|
|
37
|
+
dependencies: {},
|
|
38
|
+
devDependencies: {}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Add database-specific scripts
|
|
42
|
+
if (answers.database === DATABASES.POSTGRESQL || answers.database === DATABASES.SQLITE) {
|
|
43
|
+
basePackage.scripts['db:generate'] = 'prisma generate';
|
|
44
|
+
basePackage.scripts['db:push'] = 'prisma db push';
|
|
45
|
+
basePackage.scripts['db:migrate'] = 'prisma migrate dev';
|
|
46
|
+
basePackage.scripts['db:studio'] = 'prisma studio';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Remove undefined scripts
|
|
50
|
+
Object.keys(basePackage.scripts).forEach(key => {
|
|
51
|
+
if (basePackage.scripts[key] === undefined) {
|
|
52
|
+
delete basePackage.scripts[key];
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return basePackage;
|
|
57
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate Fastify plugins template
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export function generatePlugins(projectPath, answers) {
|
|
6
|
+
const pluginsContent = `import fp from 'fastify-plugin';
|
|
7
|
+
|
|
8
|
+
// Error handler plugin
|
|
9
|
+
export default fp(async function (fastify, opts) {
|
|
10
|
+
fastify.setErrorHandler(async (error, request, reply) => {
|
|
11
|
+
fastify.log.error(error);
|
|
12
|
+
|
|
13
|
+
const statusCode = error.statusCode || 500;
|
|
14
|
+
const message = error.message || 'Internal Server Error';
|
|
15
|
+
|
|
16
|
+
reply.status(statusCode).send({
|
|
17
|
+
error: true,
|
|
18
|
+
message,
|
|
19
|
+
statusCode,
|
|
20
|
+
...(process.env.NODE_ENV === 'development' && { stack: error.stack })
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Not found handler
|
|
25
|
+
fastify.setNotFoundHandler(async (request, reply) => {
|
|
26
|
+
reply.status(404).send({
|
|
27
|
+
error: true,
|
|
28
|
+
message: \`Route \${request.method}:\${request.url} not found\`,
|
|
29
|
+
statusCode: 404
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}, {
|
|
33
|
+
name: 'error-handler'
|
|
34
|
+
});
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
return pluginsContent;
|
|
38
|
+
}
|