create-fluxstack 1.1.0 → 1.4.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.
Files changed (62) hide show
  1. package/app/server/backend-only.ts +5 -5
  2. package/app/server/index.ts +63 -54
  3. package/app/server/live/FluxStackConfig.ts +43 -39
  4. package/app/server/live/SystemMonitorIntegration.ts +2 -2
  5. package/app/server/live/register-components.ts +1 -1
  6. package/app/server/middleware/errorHandling.ts +6 -4
  7. package/app/server/routes/config.ts +145 -0
  8. package/app/server/routes/index.ts +5 -3
  9. package/config/app.config.ts +113 -0
  10. package/config/build.config.ts +24 -0
  11. package/config/database.config.ts +99 -0
  12. package/config/index.ts +68 -0
  13. package/config/logger.config.ts +27 -0
  14. package/config/runtime.config.ts +92 -0
  15. package/config/server.config.ts +46 -0
  16. package/config/services.config.ts +130 -0
  17. package/config/system.config.ts +105 -0
  18. package/core/build/index.ts +10 -4
  19. package/core/cli/index.ts +29 -12
  20. package/core/config/env.ts +37 -95
  21. package/core/config/runtime-config.ts +61 -58
  22. package/core/config/schema.ts +4 -0
  23. package/core/framework/server.ts +22 -10
  24. package/core/plugins/built-in/index.ts +7 -17
  25. package/core/plugins/built-in/swagger/index.ts +228 -228
  26. package/core/plugins/built-in/vite/index.ts +374 -358
  27. package/core/plugins/dependency-manager.ts +5 -5
  28. package/core/plugins/manager.ts +12 -12
  29. package/core/plugins/registry.ts +3 -3
  30. package/core/server/index.ts +0 -1
  31. package/core/server/live/ComponentRegistry.ts +34 -8
  32. package/core/server/live/LiveComponentPerformanceMonitor.ts +1 -1
  33. package/core/server/live/websocket-plugin.ts +434 -434
  34. package/core/server/middleware/README.md +488 -0
  35. package/core/server/middleware/elysia-helpers.ts +227 -0
  36. package/core/server/middleware/index.ts +25 -9
  37. package/core/server/plugins/static-files-plugin.ts +231 -231
  38. package/core/utils/config-schema.ts +484 -0
  39. package/core/utils/env.ts +306 -0
  40. package/core/utils/helpers.ts +4 -4
  41. package/core/utils/logger/colors.ts +114 -0
  42. package/core/utils/logger/config.ts +35 -0
  43. package/core/utils/logger/formatter.ts +82 -0
  44. package/core/utils/logger/group-logger.ts +101 -0
  45. package/core/utils/logger/index.ts +199 -250
  46. package/core/utils/logger/stack-trace.ts +92 -0
  47. package/core/utils/logger/startup-banner.ts +92 -0
  48. package/core/utils/logger/winston-logger.ts +152 -0
  49. package/core/utils/version.ts +5 -0
  50. package/create-fluxstack.ts +1 -0
  51. package/fluxstack.config.ts +2 -2
  52. package/package.json +117 -115
  53. package/core/config/env-dynamic.ts +0 -326
  54. package/core/plugins/built-in/logger/index.ts +0 -180
  55. package/core/server/plugins/logger.ts +0 -47
  56. package/core/utils/env-runtime-v2.ts +0 -232
  57. package/core/utils/env-runtime.ts +0 -259
  58. package/core/utils/logger/formatters.ts +0 -222
  59. package/core/utils/logger/middleware.ts +0 -253
  60. package/core/utils/logger/performance.ts +0 -384
  61. package/core/utils/logger/transports.ts +0 -365
  62. package/core/utils/logger.ts +0 -106
@@ -1,326 +0,0 @@
1
- /**
2
- * Dynamic Environment Configuration Adapter for FluxStack
3
- * Integrates runtime env loader with existing configuration system
4
- * Solves Bun build issue by using dynamic environment access
5
- */
6
-
7
- import { env, runtimeEnv, envValidation } from '../utils/env-runtime'
8
- import type { FluxStackConfig, LogLevel, BuildTarget, LogFormat } from './schema'
9
-
10
- /**
11
- * Enhanced Environment Processor that uses dynamic env access
12
- * Replaces the original EnvironmentProcessor from env.ts
13
- */
14
- export class DynamicEnvironmentProcessor {
15
- private precedenceMap: Map<string, any> = new Map()
16
-
17
- /**
18
- * Process environment variables using dynamic runtime access
19
- * This prevents Bun from fixing env values during build
20
- */
21
- processEnvironmentVariables(): Partial<FluxStackConfig> {
22
- const config: any = {}
23
-
24
- // App configuration
25
- this.setConfigValue(config, 'app.name',
26
- env.get('FLUXSTACK_APP_NAME') || env.get('APP_NAME'), 'string')
27
- this.setConfigValue(config, 'app.version',
28
- env.get('FLUXSTACK_APP_VERSION') || env.get('APP_VERSION'), 'string')
29
- this.setConfigValue(config, 'app.description',
30
- env.get('FLUXSTACK_APP_DESCRIPTION') || env.get('APP_DESCRIPTION'), 'string')
31
-
32
- // Server configuration
33
- this.setConfigValue(config, 'server.port',
34
- env.get('PORT') || env.get('FLUXSTACK_PORT'), 'number')
35
- this.setConfigValue(config, 'server.host',
36
- env.get('HOST') || env.get('FLUXSTACK_HOST'), 'string')
37
- this.setConfigValue(config, 'server.apiPrefix',
38
- env.get('FLUXSTACK_API_PREFIX') || env.get('API_PREFIX'), 'string')
39
-
40
- // CORS configuration
41
- this.setConfigValue(config, 'server.cors.origins',
42
- env.get('CORS_ORIGINS') || env.get('FLUXSTACK_CORS_ORIGINS'), 'array')
43
- this.setConfigValue(config, 'server.cors.methods',
44
- env.get('CORS_METHODS') || env.get('FLUXSTACK_CORS_METHODS'), 'array')
45
- this.setConfigValue(config, 'server.cors.headers',
46
- env.get('CORS_HEADERS') || env.get('FLUXSTACK_CORS_HEADERS'), 'array')
47
- this.setConfigValue(config, 'server.cors.credentials',
48
- env.get('CORS_CREDENTIALS') || env.get('FLUXSTACK_CORS_CREDENTIALS'), 'boolean')
49
- this.setConfigValue(config, 'server.cors.maxAge',
50
- env.get('CORS_MAX_AGE') || env.get('FLUXSTACK_CORS_MAX_AGE'), 'number')
51
-
52
- // Client configuration
53
- this.setConfigValue(config, 'client.port',
54
- env.get('VITE_PORT') || env.get('CLIENT_PORT') || env.get('FLUXSTACK_CLIENT_PORT'), 'number')
55
- this.setConfigValue(config, 'client.proxy.target',
56
- env.get('VITE_API_URL') || env.get('API_URL') || env.get('FLUXSTACK_PROXY_TARGET'), 'string')
57
- this.setConfigValue(config, 'client.build.sourceMaps',
58
- env.get('FLUXSTACK_CLIENT_SOURCEMAPS'), 'boolean')
59
- this.setConfigValue(config, 'client.build.minify',
60
- env.get('FLUXSTACK_CLIENT_MINIFY'), 'boolean')
61
-
62
- // Build configuration
63
- this.setConfigValue(config, 'build.target',
64
- env.get('BUILD_TARGET') || env.get('FLUXSTACK_BUILD_TARGET'), 'buildTarget')
65
- this.setConfigValue(config, 'build.outDir',
66
- env.get('BUILD_OUTDIR') || env.get('FLUXSTACK_BUILD_OUTDIR'), 'string')
67
- this.setConfigValue(config, 'build.sourceMaps',
68
- env.get('BUILD_SOURCEMAPS') || env.get('FLUXSTACK_BUILD_SOURCEMAPS'), 'boolean')
69
- this.setConfigValue(config, 'build.clean',
70
- env.get('BUILD_CLEAN') || env.get('FLUXSTACK_BUILD_CLEAN'), 'boolean')
71
-
72
- // Build optimization
73
- this.setConfigValue(config, 'build.optimization.minify',
74
- env.get('BUILD_MINIFY') || env.get('FLUXSTACK_BUILD_MINIFY'), 'boolean')
75
- this.setConfigValue(config, 'build.optimization.treeshake',
76
- env.get('BUILD_TREESHAKE') || env.get('FLUXSTACK_BUILD_TREESHAKE'), 'boolean')
77
- this.setConfigValue(config, 'build.optimization.compress',
78
- env.get('BUILD_COMPRESS') || env.get('FLUXSTACK_BUILD_COMPRESS'), 'boolean')
79
- this.setConfigValue(config, 'build.optimization.splitChunks',
80
- env.get('BUILD_SPLIT_CHUNKS') || env.get('FLUXSTACK_BUILD_SPLIT_CHUNKS'), 'boolean')
81
- this.setConfigValue(config, 'build.optimization.bundleAnalyzer',
82
- env.get('BUILD_ANALYZER') || env.get('FLUXSTACK_BUILD_ANALYZER'), 'boolean')
83
-
84
- // Logging configuration
85
- this.setConfigValue(config, 'logging.level',
86
- env.get('LOG_LEVEL') || env.get('FLUXSTACK_LOG_LEVEL'), 'logLevel')
87
- this.setConfigValue(config, 'logging.format',
88
- env.get('LOG_FORMAT') || env.get('FLUXSTACK_LOG_FORMAT'), 'logFormat')
89
-
90
- // Monitoring configuration
91
- this.setConfigValue(config, 'monitoring.enabled',
92
- env.get('MONITORING_ENABLED') || env.get('FLUXSTACK_MONITORING_ENABLED'), 'boolean')
93
- this.setConfigValue(config, 'monitoring.metrics.enabled',
94
- env.get('METRICS_ENABLED') || env.get('FLUXSTACK_METRICS_ENABLED'), 'boolean')
95
- this.setConfigValue(config, 'monitoring.metrics.collectInterval',
96
- env.get('METRICS_INTERVAL') || env.get('FLUXSTACK_METRICS_INTERVAL'), 'number')
97
- this.setConfigValue(config, 'monitoring.profiling.enabled',
98
- env.get('PROFILING_ENABLED') || env.get('FLUXSTACK_PROFILING_ENABLED'), 'boolean')
99
- this.setConfigValue(config, 'monitoring.profiling.sampleRate',
100
- env.get('PROFILING_SAMPLE_RATE') || env.get('FLUXSTACK_PROFILING_SAMPLE_RATE'), 'number')
101
-
102
- // Database configuration
103
- this.setConfigValue(config, 'database.url', env.get('DATABASE_URL'), 'string')
104
- this.setConfigValue(config, 'database.host', env.get('DATABASE_HOST'), 'string')
105
- this.setConfigValue(config, 'database.port', env.get('DATABASE_PORT'), 'number')
106
- this.setConfigValue(config, 'database.database', env.get('DATABASE_NAME'), 'string')
107
- this.setConfigValue(config, 'database.user', env.get('DATABASE_USER'), 'string')
108
- this.setConfigValue(config, 'database.password', env.get('DATABASE_PASSWORD'), 'string')
109
- this.setConfigValue(config, 'database.ssl', env.get('DATABASE_SSL'), 'boolean')
110
- this.setConfigValue(config, 'database.poolSize', env.get('DATABASE_POOL_SIZE'), 'number')
111
-
112
- // Auth configuration
113
- this.setConfigValue(config, 'auth.secret', env.get('JWT_SECRET'), 'string')
114
- this.setConfigValue(config, 'auth.expiresIn', env.get('JWT_EXPIRES_IN'), 'string')
115
- this.setConfigValue(config, 'auth.algorithm', env.get('JWT_ALGORITHM'), 'string')
116
- this.setConfigValue(config, 'auth.issuer', env.get('JWT_ISSUER'), 'string')
117
-
118
- // Email configuration
119
- this.setConfigValue(config, 'email.host', env.get('SMTP_HOST'), 'string')
120
- this.setConfigValue(config, 'email.port', env.get('SMTP_PORT'), 'number')
121
- this.setConfigValue(config, 'email.user', env.get('SMTP_USER'), 'string')
122
- this.setConfigValue(config, 'email.password', env.get('SMTP_PASSWORD'), 'string')
123
- this.setConfigValue(config, 'email.secure', env.get('SMTP_SECURE'), 'boolean')
124
- this.setConfigValue(config, 'email.from', env.get('SMTP_FROM'), 'string')
125
-
126
- // Storage configuration
127
- this.setConfigValue(config, 'storage.uploadPath', env.get('UPLOAD_PATH'), 'string')
128
- this.setConfigValue(config, 'storage.maxFileSize', env.get('MAX_FILE_SIZE'), 'number')
129
- this.setConfigValue(config, 'storage.provider', env.get('STORAGE_PROVIDER'), 'string')
130
-
131
- // Plugin configuration
132
- this.setConfigValue(config, 'plugins.enabled',
133
- env.get('FLUXSTACK_PLUGINS_ENABLED'), 'array')
134
- this.setConfigValue(config, 'plugins.disabled',
135
- env.get('FLUXSTACK_PLUGINS_DISABLED'), 'array')
136
-
137
- return this.cleanEmptyObjects(config)
138
- }
139
-
140
- private setConfigValue(
141
- config: any,
142
- path: string,
143
- value: string | undefined,
144
- type: string
145
- ): void {
146
- if (value === undefined || value === '') return
147
-
148
- const convertedValue = this.convertValue(value, type)
149
- if (convertedValue !== undefined) {
150
- this.setNestedProperty(config, path, convertedValue)
151
-
152
- // Track precedence
153
- this.precedenceMap.set(path, {
154
- source: 'environment',
155
- path,
156
- value: convertedValue,
157
- priority: 3
158
- })
159
- }
160
- }
161
-
162
- private convertValue(value: string, type: string): any {
163
- switch (type) {
164
- case 'string':
165
- return value
166
- case 'number':
167
- const num = parseInt(value, 10)
168
- return isNaN(num) ? undefined : num
169
- case 'boolean':
170
- return ['true', '1', 'yes', 'on'].includes(value.toLowerCase())
171
- case 'array':
172
- return value.split(',').map(v => v.trim()).filter(Boolean)
173
- case 'logLevel':
174
- const level = value.toLowerCase() as LogLevel
175
- return ['debug', 'info', 'warn', 'error'].includes(level) ? level : 'info'
176
- case 'buildTarget':
177
- const target = value.toLowerCase() as BuildTarget
178
- return ['bun', 'node', 'docker'].includes(target) ? target : 'bun'
179
- case 'logFormat':
180
- const format = value.toLowerCase() as LogFormat
181
- return ['json', 'pretty'].includes(format) ? format : 'pretty'
182
- case 'object':
183
- try {
184
- return JSON.parse(value)
185
- } catch {
186
- return {}
187
- }
188
- default:
189
- return value
190
- }
191
- }
192
-
193
- private setNestedProperty(obj: any, path: string, value: any): void {
194
- const keys = path.split('.')
195
- let current = obj
196
-
197
- for (let i = 0; i < keys.length - 1; i++) {
198
- const key = keys[i]
199
- if (!(key in current) || typeof current[key] !== 'object') {
200
- current[key] = {}
201
- }
202
- current = current[key]
203
- }
204
-
205
- current[keys[keys.length - 1]] = value
206
- }
207
-
208
- private cleanEmptyObjects(obj: any): any {
209
- if (typeof obj !== 'object' || obj === null) return obj
210
-
211
- const cleaned: any = {}
212
-
213
- for (const [key, value] of Object.entries(obj)) {
214
- if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
215
- const cleanedValue = this.cleanEmptyObjects(value)
216
- if (Object.keys(cleanedValue).length > 0) {
217
- cleaned[key] = cleanedValue
218
- }
219
- } else if (value !== undefined && value !== null) {
220
- cleaned[key] = value
221
- }
222
- }
223
-
224
- return cleaned
225
- }
226
-
227
- getPrecedenceInfo(): Map<string, any> {
228
- return new Map(this.precedenceMap)
229
- }
230
-
231
- clearPrecedence(): void {
232
- this.precedenceMap.clear()
233
- }
234
- }
235
-
236
- /**
237
- * Enhanced environment info with dynamic access
238
- */
239
- export function getDynamicEnvironmentInfo() {
240
- const nodeEnv = env.get('NODE_ENV', 'development') as 'development' | 'production' | 'test'
241
-
242
- return {
243
- name: nodeEnv,
244
- isDevelopment: nodeEnv === 'development',
245
- isProduction: nodeEnv === 'production',
246
- isTest: nodeEnv === 'test',
247
- nodeEnv
248
- }
249
- }
250
-
251
- /**
252
- * Runtime configuration loader that uses dynamic env access
253
- */
254
- export function loadConfigFromDynamicEnv(): Partial<FluxStackConfig> {
255
- const processor = new DynamicEnvironmentProcessor()
256
- return processor.processEnvironmentVariables()
257
- }
258
-
259
- /**
260
- * Utility functions for backward compatibility
261
- */
262
- export function isDevelopment(): boolean {
263
- return getDynamicEnvironmentInfo().isDevelopment
264
- }
265
-
266
- export function isProduction(): boolean {
267
- return getDynamicEnvironmentInfo().isProduction
268
- }
269
-
270
- export function isTest(): boolean {
271
- return getDynamicEnvironmentInfo().isTest
272
- }
273
-
274
- /**
275
- * Validate critical environment variables for production
276
- */
277
- export function validateProductionEnv(): void {
278
- if (isProduction()) {
279
- const requiredVars = ['NODE_ENV']
280
- const missingVars = requiredVars.filter(key => !env.has(key))
281
-
282
- if (missingVars.length > 0) {
283
- throw new Error(`Missing required production environment variables: ${missingVars.join(', ')}`)
284
- }
285
-
286
- // Validate LOG_LEVEL for production
287
- const logLevel = env.get('LOG_LEVEL')
288
- if (logLevel === 'debug') {
289
- console.warn('⚠️ Production environment should not use debug logging')
290
- }
291
- }
292
- }
293
-
294
- /**
295
- * Create environment-aware configuration
296
- */
297
- export function createDynamicConfig(): Partial<FluxStackConfig> {
298
- const envInfo = getDynamicEnvironmentInfo()
299
- const envConfig = loadConfigFromDynamicEnv()
300
-
301
- // Add environment-specific defaults
302
- const config: any = { ...envConfig }
303
-
304
- // Ensure proper defaults based on environment
305
- if (envInfo.isDevelopment) {
306
- config.logging = {
307
- level: env.get('LOG_LEVEL', 'debug'),
308
- format: env.get('LOG_FORMAT', 'pretty'),
309
- ...config.logging
310
- }
311
- } else if (envInfo.isProduction) {
312
- config.logging = {
313
- level: env.get('LOG_LEVEL', 'warn'),
314
- format: env.get('LOG_FORMAT', 'json'),
315
- ...config.logging
316
- }
317
- }
318
-
319
- return config
320
- }
321
-
322
- // Export singleton instance
323
- export const dynamicEnvironmentProcessor = new DynamicEnvironmentProcessor()
324
-
325
- // Export runtime environment access
326
- export { env, runtimeEnv, envValidation } from '../utils/env-runtime'
@@ -1,180 +0,0 @@
1
- import type { Plugin, PluginContext, RequestContext, ResponseContext, ErrorContext } from "../../types"
2
-
3
- export const loggerPlugin: Plugin = {
4
- name: "logger",
5
- version: "1.0.0",
6
- description: "Enhanced logging plugin for FluxStack with request/response logging",
7
- author: "FluxStack Team",
8
- priority: 1000, // Logger should run first
9
- category: "core",
10
- tags: ["logging", "monitoring"],
11
-
12
- configSchema: {
13
- type: "object",
14
- properties: {
15
- logRequests: {
16
- type: "boolean",
17
- description: "Enable request logging"
18
- },
19
- logResponses: {
20
- type: "boolean",
21
- description: "Enable response logging"
22
- },
23
- logErrors: {
24
- type: "boolean",
25
- description: "Enable error logging"
26
- },
27
- includeHeaders: {
28
- type: "boolean",
29
- description: "Include headers in request/response logs"
30
- },
31
- includeBody: {
32
- type: "boolean",
33
- description: "Include body in request/response logs"
34
- },
35
- slowRequestThreshold: {
36
- type: "number",
37
- minimum: 0,
38
- description: "Threshold in ms to log slow requests"
39
- }
40
- },
41
- additionalProperties: false
42
- },
43
-
44
- defaultConfig: {
45
- logRequests: process.env.ENABLE_REQUEST_LOGS === 'true',
46
- logResponses: process.env.ENABLE_REQUEST_LOGS === 'true',
47
- logErrors: true,
48
- includeHeaders: false,
49
- includeBody: false,
50
- slowRequestThreshold: 1000
51
- },
52
-
53
- setup: async (context: PluginContext) => {
54
- context.logger.info("Enhanced logger plugin initialized", {
55
- environment: context.config.app?.name || 'fluxstack',
56
- logLevel: context.config.logging.level,
57
- format: context.config.logging.format
58
- })
59
- },
60
-
61
- onServerStart: async (context: PluginContext) => {
62
- context.logger.info("Logger plugin: Server started", {
63
- port: context.config.server.port,
64
- host: context.config.server.host,
65
- apiPrefix: context.config.server.apiPrefix
66
- })
67
- },
68
-
69
- onServerStop: async (context: PluginContext) => {
70
- context.logger.info("Logger plugin: Server stopped")
71
- },
72
-
73
- onRequest: async (context: RequestContext) => {
74
- const config = getPluginConfig(context)
75
-
76
- if (!config.logRequests) return
77
-
78
- const logData: any = {
79
- method: context.method,
80
- path: context.path,
81
- userAgent: context.headers['user-agent'],
82
- ip: context.headers['x-forwarded-for'] || context.headers['x-real-ip'] || 'unknown'
83
- }
84
-
85
- if (config.includeHeaders) {
86
- logData.headers = context.headers
87
- }
88
-
89
- if (config.includeBody && context.body) {
90
- logData.body = context.body
91
- }
92
-
93
- // Use a logger from context if available, otherwise create one
94
- const logger = (context as any).logger || console
95
- if (typeof logger.info === 'function') {
96
- logger.info(`→ ${context.method} ${context.path}`, logData)
97
- }
98
- },
99
-
100
- onResponse: async (context: ResponseContext) => {
101
- const config = getPluginConfig(context)
102
-
103
- if (!config.logResponses) return
104
-
105
- const logData: any = {
106
- method: context.method,
107
- path: context.path,
108
- statusCode: context.statusCode,
109
- duration: context.duration,
110
- size: context.size
111
- }
112
-
113
- if (config.includeHeaders) {
114
- const headers: Record<string, string> = {}
115
- context.response.headers.forEach((value, key) => {
116
- headers[key] = value
117
- })
118
- logData.responseHeaders = headers
119
- }
120
-
121
- // Determine log level based on status code and duration
122
- let logLevel = 'info'
123
- if (context.statusCode >= 400) {
124
- logLevel = 'warn'
125
- }
126
- if (context.statusCode >= 500) {
127
- logLevel = 'error'
128
- }
129
- if (context.duration > config.slowRequestThreshold) {
130
- logLevel = 'warn'
131
- }
132
-
133
- const logger = (context as any).logger || console
134
- const logMessage = `← ${context.method} ${context.path} ${context.statusCode} ${context.duration}ms`
135
-
136
- if (typeof logger[logLevel] === 'function') {
137
- logger[logLevel](logMessage, logData)
138
- }
139
- },
140
-
141
- onError: async (context: ErrorContext) => {
142
- const config = getPluginConfig(context)
143
-
144
- if (!config.logErrors) return
145
-
146
- // Skip logging for NOT_FOUND errors unless explicitly enabled
147
- if (context.error.message === 'NOT_FOUND' && !process.env.ENABLE_NOT_FOUND_LOGS) {
148
- return
149
- }
150
-
151
- const logData: any = {
152
- method: context.method,
153
- path: context.path,
154
- duration: context.duration,
155
- error: {
156
- name: context.error.name,
157
- message: context.error.message,
158
- stack: context.error.stack
159
- }
160
- }
161
-
162
- if (config.includeHeaders) {
163
- logData.headers = context.headers
164
- }
165
-
166
- const logger = (context as any).logger || console
167
- if (typeof logger.error === 'function') {
168
- logger.error(`✗ ${context.method} ${context.path} - ${context.error.message}`, logData)
169
- }
170
- }
171
- }
172
-
173
- // Helper function to get plugin config from context
174
- function getPluginConfig(_context: any) {
175
- // In a real implementation, this would get the config from the plugin context
176
- // For now, return default config
177
- return loggerPlugin.defaultConfig || {}
178
- }
179
-
180
- export default loggerPlugin
@@ -1,47 +0,0 @@
1
- import type { Plugin, PluginContext } from "../../types"
2
- import { log } from "../../utils/logger"
3
-
4
- export const loggerPlugin: Plugin = {
5
- name: "logger",
6
- setup: (context: PluginContext) => {
7
- const logLevel = process.env.LOG_LEVEL || context.config.logging?.level || 'info'
8
- const isDev = process.env.NODE_ENV === 'development'
9
-
10
- log.plugin("logger", "Logger plugin initialized", {
11
- logLevel,
12
- environment: process.env.NODE_ENV || 'development'
13
- })
14
-
15
- // Only enable verbose request logging if explicitly requested
16
- if (process.env.ENABLE_REQUEST_LOGS === 'true') {
17
- // Setup logging hooks on the Elysia app
18
- context.app.onRequest(({ request }: { request: Request }) => {
19
- const startTime = Date.now()
20
- const path = new URL(request.url).pathname
21
-
22
- // Store start time for duration calculation
23
- ;(request as any).__startTime = startTime
24
-
25
- log.request(request.method, path)
26
- })
27
-
28
- context.app.onResponse(({ request, set }: { request: Request, set: any }) => {
29
- const duration = Date.now() - ((request as any).__startTime || Date.now())
30
- const path = new URL(request.url).pathname
31
-
32
- log.request(request.method, path, set.status || 200, duration)
33
- })
34
- }
35
-
36
- // Always log errors
37
- context.app.onError(({ error, request }: { error: Error, request: Request }) => {
38
- const duration = Date.now() - ((request as any).__startTime || Date.now())
39
- const path = new URL(request.url).pathname
40
-
41
- log.error(`${request.method} ${path} - ${error.message}`, {
42
- duration,
43
- stack: error.stack
44
- })
45
- })
46
- }
47
- }