@bloomneo/appkit 1.2.9
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 +902 -0
- package/bin/appkit.js +71 -0
- package/bin/commands/generate.js +1050 -0
- package/bin/templates/backend/README.md.template +39 -0
- package/bin/templates/backend/api.http.template +0 -0
- package/bin/templates/backend/docs/APPKIT_CLI.md +507 -0
- package/bin/templates/backend/docs/APPKIT_COMMENTS_GUIDELINES.md +61 -0
- package/bin/templates/backend/docs/APPKIT_LLM_GUIDE.md +2539 -0
- package/bin/templates/backend/package.json.template +34 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.http.template +29 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.route.ts.template +36 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.service.ts.template +88 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.types.ts.template +18 -0
- package/bin/templates/backend/src/api/lib/api-router.ts.template +84 -0
- package/bin/templates/backend/src/api/server.ts.template +188 -0
- package/bin/templates/backend/tsconfig.api.json.template +24 -0
- package/bin/templates/backend/tsconfig.json.template +40 -0
- package/bin/templates/feature/feature.http.template +63 -0
- package/bin/templates/feature/feature.route.ts.template +36 -0
- package/bin/templates/feature/feature.service.ts.template +81 -0
- package/bin/templates/feature/feature.types.ts.template +23 -0
- package/bin/templates/feature-db/feature.http.template +63 -0
- package/bin/templates/feature-db/feature.model.ts.template +74 -0
- package/bin/templates/feature-db/feature.route.ts.template +58 -0
- package/bin/templates/feature-db/feature.service.ts.template +231 -0
- package/bin/templates/feature-db/feature.types.ts.template +25 -0
- package/bin/templates/feature-db/schema-addition.prisma.template +9 -0
- package/bin/templates/feature-db/seeding/README.md.template +57 -0
- package/bin/templates/feature-db/seeding/feature.seed.js.template +67 -0
- package/bin/templates/feature-user/schema-addition.prisma.template +19 -0
- package/bin/templates/feature-user/user.http.template +157 -0
- package/bin/templates/feature-user/user.model.ts.template +244 -0
- package/bin/templates/feature-user/user.route.ts.template +379 -0
- package/bin/templates/feature-user/user.seed.js.template +182 -0
- package/bin/templates/feature-user/user.service.ts.template +426 -0
- package/bin/templates/feature-user/user.types.ts.template +127 -0
- package/dist/auth/auth.d.ts +182 -0
- package/dist/auth/auth.d.ts.map +1 -0
- package/dist/auth/auth.js +477 -0
- package/dist/auth/auth.js.map +1 -0
- package/dist/auth/defaults.d.ts +104 -0
- package/dist/auth/defaults.d.ts.map +1 -0
- package/dist/auth/defaults.js +374 -0
- package/dist/auth/defaults.js.map +1 -0
- package/dist/auth/index.d.ts +70 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +94 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/cache/cache.d.ts +118 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +249 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/defaults.d.ts +63 -0
- package/dist/cache/defaults.d.ts.map +1 -0
- package/dist/cache/defaults.js +193 -0
- package/dist/cache/defaults.js.map +1 -0
- package/dist/cache/index.d.ts +101 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +203 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/strategies/memory.d.ts +138 -0
- package/dist/cache/strategies/memory.d.ts.map +1 -0
- package/dist/cache/strategies/memory.js +348 -0
- package/dist/cache/strategies/memory.js.map +1 -0
- package/dist/cache/strategies/redis.d.ts +105 -0
- package/dist/cache/strategies/redis.d.ts.map +1 -0
- package/dist/cache/strategies/redis.js +318 -0
- package/dist/cache/strategies/redis.js.map +1 -0
- package/dist/config/config.d.ts +62 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +107 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/defaults.d.ts +44 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +217 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +105 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +163 -0
- package/dist/config/index.js.map +1 -0
- package/dist/database/adapters/mongoose.d.ts +106 -0
- package/dist/database/adapters/mongoose.d.ts.map +1 -0
- package/dist/database/adapters/mongoose.js +480 -0
- package/dist/database/adapters/mongoose.js.map +1 -0
- package/dist/database/adapters/prisma.d.ts +106 -0
- package/dist/database/adapters/prisma.d.ts.map +1 -0
- package/dist/database/adapters/prisma.js +494 -0
- package/dist/database/adapters/prisma.js.map +1 -0
- package/dist/database/defaults.d.ts +87 -0
- package/dist/database/defaults.d.ts.map +1 -0
- package/dist/database/defaults.js +271 -0
- package/dist/database/defaults.js.map +1 -0
- package/dist/database/index.d.ts +137 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +490 -0
- package/dist/database/index.js.map +1 -0
- package/dist/email/defaults.d.ts +100 -0
- package/dist/email/defaults.d.ts.map +1 -0
- package/dist/email/defaults.js +400 -0
- package/dist/email/defaults.js.map +1 -0
- package/dist/email/email.d.ts +139 -0
- package/dist/email/email.d.ts.map +1 -0
- package/dist/email/email.js +316 -0
- package/dist/email/email.js.map +1 -0
- package/dist/email/index.d.ts +176 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +251 -0
- package/dist/email/index.js.map +1 -0
- package/dist/email/strategies/console.d.ts +90 -0
- package/dist/email/strategies/console.d.ts.map +1 -0
- package/dist/email/strategies/console.js +268 -0
- package/dist/email/strategies/console.js.map +1 -0
- package/dist/email/strategies/resend.d.ts +84 -0
- package/dist/email/strategies/resend.d.ts.map +1 -0
- package/dist/email/strategies/resend.js +266 -0
- package/dist/email/strategies/resend.js.map +1 -0
- package/dist/email/strategies/smtp.d.ts +77 -0
- package/dist/email/strategies/smtp.d.ts.map +1 -0
- package/dist/email/strategies/smtp.js +286 -0
- package/dist/email/strategies/smtp.js.map +1 -0
- package/dist/error/defaults.d.ts +40 -0
- package/dist/error/defaults.d.ts.map +1 -0
- package/dist/error/defaults.js +75 -0
- package/dist/error/defaults.js.map +1 -0
- package/dist/error/error.d.ts +140 -0
- package/dist/error/error.d.ts.map +1 -0
- package/dist/error/error.js +200 -0
- package/dist/error/error.js.map +1 -0
- package/dist/error/index.d.ts +145 -0
- package/dist/error/index.d.ts.map +1 -0
- package/dist/error/index.js +145 -0
- package/dist/error/index.js.map +1 -0
- package/dist/event/defaults.d.ts +111 -0
- package/dist/event/defaults.d.ts.map +1 -0
- package/dist/event/defaults.js +378 -0
- package/dist/event/defaults.js.map +1 -0
- package/dist/event/event.d.ts +171 -0
- package/dist/event/event.d.ts.map +1 -0
- package/dist/event/event.js +391 -0
- package/dist/event/event.js.map +1 -0
- package/dist/event/index.d.ts +173 -0
- package/dist/event/index.d.ts.map +1 -0
- package/dist/event/index.js +302 -0
- package/dist/event/index.js.map +1 -0
- package/dist/event/strategies/memory.d.ts +122 -0
- package/dist/event/strategies/memory.d.ts.map +1 -0
- package/dist/event/strategies/memory.js +331 -0
- package/dist/event/strategies/memory.js.map +1 -0
- package/dist/event/strategies/redis.d.ts +115 -0
- package/dist/event/strategies/redis.d.ts.map +1 -0
- package/dist/event/strategies/redis.js +434 -0
- package/dist/event/strategies/redis.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/defaults.d.ts +67 -0
- package/dist/logger/defaults.d.ts.map +1 -0
- package/dist/logger/defaults.js +213 -0
- package/dist/logger/defaults.js.map +1 -0
- package/dist/logger/index.d.ts +84 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +101 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/logger.d.ts +165 -0
- package/dist/logger/logger.d.ts.map +1 -0
- package/dist/logger/logger.js +843 -0
- package/dist/logger/logger.js.map +1 -0
- package/dist/logger/transports/console.d.ts +102 -0
- package/dist/logger/transports/console.d.ts.map +1 -0
- package/dist/logger/transports/console.js +276 -0
- package/dist/logger/transports/console.js.map +1 -0
- package/dist/logger/transports/database.d.ts +153 -0
- package/dist/logger/transports/database.d.ts.map +1 -0
- package/dist/logger/transports/database.js +539 -0
- package/dist/logger/transports/database.js.map +1 -0
- package/dist/logger/transports/file.d.ts +146 -0
- package/dist/logger/transports/file.d.ts.map +1 -0
- package/dist/logger/transports/file.js +464 -0
- package/dist/logger/transports/file.js.map +1 -0
- package/dist/logger/transports/http.d.ts +128 -0
- package/dist/logger/transports/http.d.ts.map +1 -0
- package/dist/logger/transports/http.js +401 -0
- package/dist/logger/transports/http.js.map +1 -0
- package/dist/logger/transports/webhook.d.ts +152 -0
- package/dist/logger/transports/webhook.d.ts.map +1 -0
- package/dist/logger/transports/webhook.js +485 -0
- package/dist/logger/transports/webhook.js.map +1 -0
- package/dist/queue/defaults.d.ts +66 -0
- package/dist/queue/defaults.d.ts.map +1 -0
- package/dist/queue/defaults.js +205 -0
- package/dist/queue/defaults.js.map +1 -0
- package/dist/queue/index.d.ts +124 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +116 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/queue.d.ts +156 -0
- package/dist/queue/queue.d.ts.map +1 -0
- package/dist/queue/queue.js +387 -0
- package/dist/queue/queue.js.map +1 -0
- package/dist/queue/transports/database.d.ts +165 -0
- package/dist/queue/transports/database.d.ts.map +1 -0
- package/dist/queue/transports/database.js +595 -0
- package/dist/queue/transports/database.js.map +1 -0
- package/dist/queue/transports/memory.d.ts +143 -0
- package/dist/queue/transports/memory.d.ts.map +1 -0
- package/dist/queue/transports/memory.js +415 -0
- package/dist/queue/transports/memory.js.map +1 -0
- package/dist/queue/transports/redis.d.ts +203 -0
- package/dist/queue/transports/redis.d.ts.map +1 -0
- package/dist/queue/transports/redis.js +744 -0
- package/dist/queue/transports/redis.js.map +1 -0
- package/dist/security/defaults.d.ts +64 -0
- package/dist/security/defaults.d.ts.map +1 -0
- package/dist/security/defaults.js +159 -0
- package/dist/security/defaults.js.map +1 -0
- package/dist/security/index.d.ts +110 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +160 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/security.d.ts +138 -0
- package/dist/security/security.d.ts.map +1 -0
- package/dist/security/security.js +419 -0
- package/dist/security/security.js.map +1 -0
- package/dist/storage/defaults.d.ts +79 -0
- package/dist/storage/defaults.d.ts.map +1 -0
- package/dist/storage/defaults.js +358 -0
- package/dist/storage/defaults.js.map +1 -0
- package/dist/storage/index.d.ts +153 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +242 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/storage.d.ts +151 -0
- package/dist/storage/storage.d.ts.map +1 -0
- package/dist/storage/storage.js +439 -0
- package/dist/storage/storage.js.map +1 -0
- package/dist/storage/strategies/local.d.ts +117 -0
- package/dist/storage/strategies/local.d.ts.map +1 -0
- package/dist/storage/strategies/local.js +368 -0
- package/dist/storage/strategies/local.js.map +1 -0
- package/dist/storage/strategies/r2.d.ts +130 -0
- package/dist/storage/strategies/r2.d.ts.map +1 -0
- package/dist/storage/strategies/r2.js +470 -0
- package/dist/storage/strategies/r2.js.map +1 -0
- package/dist/storage/strategies/s3.d.ts +121 -0
- package/dist/storage/strategies/s3.d.ts.map +1 -0
- package/dist/storage/strategies/s3.js +461 -0
- package/dist/storage/strategies/s3.js.map +1 -0
- package/dist/util/defaults.d.ts +77 -0
- package/dist/util/defaults.d.ts.map +1 -0
- package/dist/util/defaults.js +193 -0
- package/dist/util/defaults.js.map +1 -0
- package/dist/util/index.d.ts +97 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/index.js +165 -0
- package/dist/util/index.js.map +1 -0
- package/dist/util/util.d.ts +145 -0
- package/dist/util/util.d.ts.map +1 -0
- package/dist/util/util.js +481 -0
- package/dist/util/util.js.map +1 -0
- package/package.json +234 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart defaults with direct environment access and auto transport detection
|
|
3
|
+
* @module @bloomneo/appkit/logger
|
|
4
|
+
* @file src/logger/defaults.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: App startup - need production-ready logging configuration
|
|
7
|
+
* @llm-rule AVOID: Calling multiple times - expensive environment parsing, cache results
|
|
8
|
+
* @llm-rule NOTE: Called once at startup, cached globally for performance like auth module
|
|
9
|
+
* @llm-rule NOTE: Now includes visual error configuration for enhanced developer experience
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Get smart defaults using direct VOILA_LOGGER_* environment access
|
|
13
|
+
* @llm-rule WHEN: App startup to get production-ready logging configuration
|
|
14
|
+
* @llm-rule AVOID: Calling repeatedly - validates environment each time, expensive operation
|
|
15
|
+
* @llm-rule NOTE: Called once at startup, cached globally for performance
|
|
16
|
+
*/
|
|
17
|
+
export function getSmartDefaults() {
|
|
18
|
+
// Direct environment access with smart defaults (like auth module)
|
|
19
|
+
const nodeEnv = process.env.NODE_ENV || 'development';
|
|
20
|
+
const isProduction = nodeEnv === 'production';
|
|
21
|
+
const isDevelopment = nodeEnv === 'development';
|
|
22
|
+
const isTest = nodeEnv === 'test';
|
|
23
|
+
// Auto-detect logging scope
|
|
24
|
+
const scope = getScope();
|
|
25
|
+
const minimal = scope === 'minimal';
|
|
26
|
+
// Auto-detect log level
|
|
27
|
+
const level = getLevel(isProduction, isDevelopment);
|
|
28
|
+
// Auto-detect enabled transports
|
|
29
|
+
const transports = getEnabledTransports(isTest);
|
|
30
|
+
return {
|
|
31
|
+
level,
|
|
32
|
+
scope,
|
|
33
|
+
minimal,
|
|
34
|
+
transports,
|
|
35
|
+
// Console config - direct env access
|
|
36
|
+
console: {
|
|
37
|
+
colorize: process.env.VOILA_LOGGER_CONSOLE_COLOR !== 'false' && !isProduction,
|
|
38
|
+
timestamps: process.env.VOILA_LOGGER_CONSOLE_TIME !== 'false',
|
|
39
|
+
prettyPrint: isDevelopment && !minimal,
|
|
40
|
+
},
|
|
41
|
+
// File config - direct env access
|
|
42
|
+
file: {
|
|
43
|
+
dir: process.env.VOILA_LOGGER_DIR || 'logs',
|
|
44
|
+
filename: process.env.VOILA_LOGGER_FILE_NAME || 'app.log',
|
|
45
|
+
maxSize: parseInt(process.env.VOILA_LOGGER_FILE_SIZE || (isProduction ? '50000000' : '10000000')),
|
|
46
|
+
retentionDays: parseInt(process.env.VOILA_LOGGER_FILE_RETENTION || (isProduction ? '30' : '7')),
|
|
47
|
+
},
|
|
48
|
+
// Database config - direct env access
|
|
49
|
+
database: {
|
|
50
|
+
url: process.env.DATABASE_URL || null,
|
|
51
|
+
table: process.env.VOILA_LOGGER_DB_TABLE || 'logs',
|
|
52
|
+
batchSize: parseInt(process.env.VOILA_LOGGER_DB_BATCH || (minimal ? '50' : '100')),
|
|
53
|
+
},
|
|
54
|
+
// HTTP config - direct env access
|
|
55
|
+
http: {
|
|
56
|
+
url: process.env.VOILA_LOGGER_HTTP_URL || null,
|
|
57
|
+
batchSize: parseInt(process.env.VOILA_LOGGER_HTTP_BATCH || (minimal ? '25' : '50')),
|
|
58
|
+
timeout: parseInt(process.env.VOILA_LOGGER_HTTP_TIMEOUT || '30000'),
|
|
59
|
+
},
|
|
60
|
+
// Webhook config - direct env access
|
|
61
|
+
webhook: {
|
|
62
|
+
url: process.env.VOILA_LOGGER_WEBHOOK_URL || null,
|
|
63
|
+
level: process.env.VOILA_LOGGER_WEBHOOK_LEVEL || 'error',
|
|
64
|
+
rateLimit: parseInt(process.env.VOILA_LOGGER_WEBHOOK_RATE || (minimal ? '5' : '10')),
|
|
65
|
+
},
|
|
66
|
+
// Service identification - direct env access
|
|
67
|
+
service: {
|
|
68
|
+
name: process.env.VOILA_SERVICE_NAME || process.env.npm_package_name || 'app',
|
|
69
|
+
version: process.env.VOILA_SERVICE_VERSION || process.env.npm_package_version || '1.0.0',
|
|
70
|
+
environment: nodeEnv,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Auto-detect optimal logging scope
|
|
76
|
+
* @llm-rule WHEN: Need to determine minimal vs full logging automatically
|
|
77
|
+
* @llm-rule AVOID: Manual scope selection - auto-detection handles most cases correctly
|
|
78
|
+
*/
|
|
79
|
+
function getScope() {
|
|
80
|
+
// Manual override wins (like auth module pattern)
|
|
81
|
+
const manual = process.env.VOILA_LOGGER_SCOPE?.toLowerCase();
|
|
82
|
+
if (manual === 'minimal' || manual === 'full') {
|
|
83
|
+
return manual;
|
|
84
|
+
}
|
|
85
|
+
// Auto-detection logic
|
|
86
|
+
if (process.env.CI)
|
|
87
|
+
return 'minimal'; // CI/CD pipelines
|
|
88
|
+
if (process.env.NODE_ENV === 'production')
|
|
89
|
+
return 'minimal'; // Production efficiency
|
|
90
|
+
if (process.env.DEBUG || process.env.VOILA_DEBUG)
|
|
91
|
+
return 'full'; // Debug sessions
|
|
92
|
+
return 'minimal'; // Safe default for clean logs
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Auto-detect appropriate log level
|
|
96
|
+
* @llm-rule WHEN: Need to set log level based on environment automatically
|
|
97
|
+
* @llm-rule AVOID: Hardcoding log levels - environment-based detection is better
|
|
98
|
+
*/
|
|
99
|
+
function getLevel(isProduction, isDevelopment) {
|
|
100
|
+
// Manual override wins (like auth module)
|
|
101
|
+
const manual = process.env.VOILA_LOGGER_LEVEL?.toLowerCase();
|
|
102
|
+
if (manual && ['debug', 'info', 'warn', 'error'].includes(manual)) {
|
|
103
|
+
return manual;
|
|
104
|
+
}
|
|
105
|
+
// Smart defaults based on environment
|
|
106
|
+
if (isProduction)
|
|
107
|
+
return 'warn'; // Production: only warnings and errors
|
|
108
|
+
if (isDevelopment)
|
|
109
|
+
return 'debug'; // Development: everything
|
|
110
|
+
return 'info'; // Test and others: standard
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Auto-detect enabled transports from environment
|
|
114
|
+
* @llm-rule WHEN: Need to determine which transports to enable automatically
|
|
115
|
+
* @llm-rule AVOID: Manual transport configuration - auto-detection prevents errors
|
|
116
|
+
* @llm-rule NOTE: DATABASE_URL auto-enables database, WEBHOOK_URL auto-enables webhooks
|
|
117
|
+
*/
|
|
118
|
+
function getEnabledTransports(isTest) {
|
|
119
|
+
return {
|
|
120
|
+
// Console: default on (except test)
|
|
121
|
+
console: process.env.VOILA_LOGGER_CONSOLE !== 'false' && !isTest,
|
|
122
|
+
// File: default on (except test)
|
|
123
|
+
file: process.env.VOILA_LOGGER_FILE !== 'false' && !isTest,
|
|
124
|
+
// Database: auto-enable if DATABASE_URL exists
|
|
125
|
+
database: process.env.VOILA_LOGGER_DATABASE === 'true' && !!process.env.DATABASE_URL,
|
|
126
|
+
// HTTP: auto-enable if URL provided
|
|
127
|
+
http: !!process.env.VOILA_LOGGER_HTTP_URL,
|
|
128
|
+
// Webhook: auto-enable if URL provided
|
|
129
|
+
webhook: !!process.env.VOILA_LOGGER_WEBHOOK_URL,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Validate environment variables (like auth module validation)
|
|
134
|
+
* @llm-rule WHEN: App startup to catch configuration errors early
|
|
135
|
+
* @llm-rule AVOID: Skipping validation - invalid config causes silent failures
|
|
136
|
+
*/
|
|
137
|
+
export function validateEnvironment() {
|
|
138
|
+
// Validate log level
|
|
139
|
+
const level = process.env.VOILA_LOGGER_LEVEL;
|
|
140
|
+
if (level && !['debug', 'info', 'warn', 'error'].includes(level)) {
|
|
141
|
+
throw new Error(`Invalid VOILA_LOGGER_LEVEL: "${level}". Must be: debug, info, warn, error`);
|
|
142
|
+
}
|
|
143
|
+
// Validate scope
|
|
144
|
+
const scope = process.env.VOILA_LOGGER_SCOPE;
|
|
145
|
+
if (scope && !['minimal', 'full'].includes(scope.toLowerCase())) {
|
|
146
|
+
throw new Error(`Invalid VOILA_LOGGER_SCOPE: "${scope}". Must be: minimal, full`);
|
|
147
|
+
}
|
|
148
|
+
// Validate visual errors setting
|
|
149
|
+
const visualErrors = process.env.VOILA_VISUAL_ERRORS;
|
|
150
|
+
if (visualErrors && !['true', 'false'].includes(visualErrors)) {
|
|
151
|
+
throw new Error(`Invalid VOILA_VISUAL_ERRORS: "${visualErrors}". Must be: true, false`);
|
|
152
|
+
}
|
|
153
|
+
// Validate URLs if provided
|
|
154
|
+
const httpUrl = process.env.VOILA_LOGGER_HTTP_URL;
|
|
155
|
+
if (httpUrl && !isValidUrl(httpUrl)) {
|
|
156
|
+
throw new Error(`Invalid VOILA_LOGGER_HTTP_URL: "${httpUrl}"`);
|
|
157
|
+
}
|
|
158
|
+
const webhookUrl = process.env.VOILA_LOGGER_WEBHOOK_URL;
|
|
159
|
+
if (webhookUrl && !isValidUrl(webhookUrl)) {
|
|
160
|
+
throw new Error(`Invalid VOILA_LOGGER_WEBHOOK_URL: "${webhookUrl}"`);
|
|
161
|
+
}
|
|
162
|
+
// Validate database URL if database logging enabled
|
|
163
|
+
const dbEnabled = process.env.VOILA_LOGGER_DATABASE === 'true';
|
|
164
|
+
const dbUrl = process.env.DATABASE_URL;
|
|
165
|
+
if (dbEnabled && !dbUrl) {
|
|
166
|
+
throw new Error('VOILA_LOGGER_DATABASE=true but DATABASE_URL not provided');
|
|
167
|
+
}
|
|
168
|
+
if (dbUrl && !isValidDatabaseUrl(dbUrl)) {
|
|
169
|
+
throw new Error(`Invalid DATABASE_URL: "${dbUrl}"`);
|
|
170
|
+
}
|
|
171
|
+
// Validate numeric values
|
|
172
|
+
validateNumericEnv('VOILA_LOGGER_FILE_SIZE', 1000000, 100000000); // 1MB to 100MB
|
|
173
|
+
validateNumericEnv('VOILA_LOGGER_FILE_RETENTION', 1, 365); // 1 to 365 days
|
|
174
|
+
validateNumericEnv('VOILA_LOGGER_HTTP_TIMEOUT', 1000, 300000); // 1s to 5min
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Validate numeric environment variable
|
|
178
|
+
*/
|
|
179
|
+
function validateNumericEnv(name, min, max) {
|
|
180
|
+
const value = process.env[name];
|
|
181
|
+
if (!value)
|
|
182
|
+
return;
|
|
183
|
+
const num = parseInt(value);
|
|
184
|
+
if (isNaN(num) || num < min || num > max) {
|
|
185
|
+
throw new Error(`Invalid ${name}: "${value}". Must be number between ${min} and ${max}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Validate URL format (like auth module)
|
|
190
|
+
*/
|
|
191
|
+
function isValidUrl(url) {
|
|
192
|
+
try {
|
|
193
|
+
const parsed = new URL(url);
|
|
194
|
+
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Validate database URL format
|
|
202
|
+
*/
|
|
203
|
+
function isValidDatabaseUrl(url) {
|
|
204
|
+
try {
|
|
205
|
+
const parsed = new URL(url);
|
|
206
|
+
const validProtocols = ['postgres:', 'postgresql:', 'mysql:', 'sqlite:'];
|
|
207
|
+
return validProtocols.includes(parsed.protocol);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/logger/defaults.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ultra-simple logging that just works with enterprise features and enhanced error display
|
|
3
|
+
* @module @bloomneo/appkit/logger
|
|
4
|
+
* @file src/logger/index.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: Need logging in any app - console, files, database, external services
|
|
7
|
+
* @llm-rule AVOID: Using console.log directly - this provides structured logging with levels
|
|
8
|
+
* @llm-rule NOTE: Uses loggerClass.get() pattern like auth - get() → log.info() → done
|
|
9
|
+
* @llm-rule NOTE: Enhanced error() method now provides automatic visual formatting in development
|
|
10
|
+
*/
|
|
11
|
+
export interface LogMeta {
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
}
|
|
14
|
+
export interface Logger {
|
|
15
|
+
info(message: string, meta?: LogMeta): void;
|
|
16
|
+
error(message: string, meta?: LogMeta): void;
|
|
17
|
+
warn(message: string, meta?: LogMeta): void;
|
|
18
|
+
debug(message: string, meta?: LogMeta): void;
|
|
19
|
+
child(bindings: LogMeta): Logger;
|
|
20
|
+
flush(): Promise<void>;
|
|
21
|
+
close(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get logger instance - the only function you need to learn
|
|
25
|
+
* @llm-rule WHEN: Starting any logging operation - this is your main entry point
|
|
26
|
+
* @llm-rule AVOID: Creating LoggerClass directly - always use this function
|
|
27
|
+
* @llm-rule NOTE: Typical flow - get() → info/error/warn/debug() → automatic transport
|
|
28
|
+
* @llm-rule NOTE: error() method now automatically provides visual formatting when appropriate
|
|
29
|
+
*/
|
|
30
|
+
declare function get(component?: string): Logger;
|
|
31
|
+
/**
|
|
32
|
+
* Clear all loggers and close transports - essential for testing
|
|
33
|
+
* @llm-rule WHEN: Testing logging logic with different configurations
|
|
34
|
+
* @llm-rule AVOID: Using in production - only for tests and cleanup
|
|
35
|
+
*/
|
|
36
|
+
declare function clear(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Get active transport names for debugging
|
|
39
|
+
* @llm-rule WHEN: Need to see which transports are running (console, file, database, etc)
|
|
40
|
+
* @llm-rule AVOID: Using for business logic - this is for debugging only
|
|
41
|
+
*/
|
|
42
|
+
declare function getActiveTransports(): string[];
|
|
43
|
+
/**
|
|
44
|
+
* Check if specific transport is active
|
|
45
|
+
* @llm-rule WHEN: Conditionally logging based on transport availability
|
|
46
|
+
* @llm-rule AVOID: Complex transport detection - just log normally, transports auto-enable
|
|
47
|
+
*/
|
|
48
|
+
declare function hasTransport(name: string): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Get current configuration for debugging
|
|
51
|
+
* @llm-rule WHEN: Debugging logging setup or checking environment detection
|
|
52
|
+
* @llm-rule AVOID: Using for runtime decisions - configuration is set at startup
|
|
53
|
+
*/
|
|
54
|
+
declare function getConfig(): {
|
|
55
|
+
level: "error" | "warn" | "info" | "debug";
|
|
56
|
+
scope: "minimal" | "full";
|
|
57
|
+
minimal: boolean;
|
|
58
|
+
transports: string[];
|
|
59
|
+
service: {
|
|
60
|
+
name: string;
|
|
61
|
+
version: string;
|
|
62
|
+
environment: string;
|
|
63
|
+
};
|
|
64
|
+
environment: {
|
|
65
|
+
NODE_ENV: string | undefined;
|
|
66
|
+
hasDbUrl: boolean;
|
|
67
|
+
hasHttpUrl: boolean;
|
|
68
|
+
hasWebhookUrl: boolean;
|
|
69
|
+
};
|
|
70
|
+
} | null;
|
|
71
|
+
/**
|
|
72
|
+
* Single logger export with minimal API (like auth module)
|
|
73
|
+
*/
|
|
74
|
+
export declare const loggerClass: {
|
|
75
|
+
readonly get: typeof get;
|
|
76
|
+
readonly clear: typeof clear;
|
|
77
|
+
readonly getActiveTransports: typeof getActiveTransports;
|
|
78
|
+
readonly hasTransport: typeof hasTransport;
|
|
79
|
+
readonly getConfig: typeof getConfig;
|
|
80
|
+
};
|
|
81
|
+
export type { LoggingConfig } from './defaults.js';
|
|
82
|
+
export { LoggerClass } from './logger.js';
|
|
83
|
+
export default loggerClass;
|
|
84
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/logger/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,MAAM,WAAW,OAAO;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IACjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;GAMG;AACH,iBAAS,GAAG,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAoBvC;AAED;;;;GAIG;AACH,iBAAe,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAMpC;AAED;;;;GAIG;AACH,iBAAS,mBAAmB,IAAI,MAAM,EAAE,CAKvC;AAED;;;;GAIG;AACH,iBAAS,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAK3C;AAED;;;;GAIG;AACH,iBAAS,SAAS;;;;;;;;;;;;;;;;SAKjB;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;CASd,CAAC;AAGX,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ultra-simple logging that just works with enterprise features and enhanced error display
|
|
3
|
+
* @module @bloomneo/appkit/logger
|
|
4
|
+
* @file src/logger/index.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: Need logging in any app - console, files, database, external services
|
|
7
|
+
* @llm-rule AVOID: Using console.log directly - this provides structured logging with levels
|
|
8
|
+
* @llm-rule NOTE: Uses loggerClass.get() pattern like auth - get() → log.info() → done
|
|
9
|
+
* @llm-rule NOTE: Enhanced error() method now provides automatic visual formatting in development
|
|
10
|
+
*/
|
|
11
|
+
import { LoggerClass } from './logger.js';
|
|
12
|
+
import { getSmartDefaults } from './defaults.js';
|
|
13
|
+
// Global logger instances for performance (like auth module)
|
|
14
|
+
let globalLogger = null;
|
|
15
|
+
const namedLoggers = new Map();
|
|
16
|
+
/**
|
|
17
|
+
* Get logger instance - the only function you need to learn
|
|
18
|
+
* @llm-rule WHEN: Starting any logging operation - this is your main entry point
|
|
19
|
+
* @llm-rule AVOID: Creating LoggerClass directly - always use this function
|
|
20
|
+
* @llm-rule NOTE: Typical flow - get() → info/error/warn/debug() → automatic transport
|
|
21
|
+
* @llm-rule NOTE: error() method now automatically provides visual formatting when appropriate
|
|
22
|
+
*/
|
|
23
|
+
function get(component) {
|
|
24
|
+
// Lazy initialization - parse environment once (like auth)
|
|
25
|
+
if (!globalLogger) {
|
|
26
|
+
const config = getSmartDefaults();
|
|
27
|
+
globalLogger = new LoggerClass(config);
|
|
28
|
+
}
|
|
29
|
+
// Return main logger if no component specified
|
|
30
|
+
if (!component) {
|
|
31
|
+
return globalLogger;
|
|
32
|
+
}
|
|
33
|
+
// Return cached or create new child logger
|
|
34
|
+
if (namedLoggers.has(component)) {
|
|
35
|
+
return namedLoggers.get(component);
|
|
36
|
+
}
|
|
37
|
+
const childLogger = globalLogger.child({ component });
|
|
38
|
+
namedLoggers.set(component, childLogger);
|
|
39
|
+
return childLogger;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Clear all loggers and close transports - essential for testing
|
|
43
|
+
* @llm-rule WHEN: Testing logging logic with different configurations
|
|
44
|
+
* @llm-rule AVOID: Using in production - only for tests and cleanup
|
|
45
|
+
*/
|
|
46
|
+
async function clear() {
|
|
47
|
+
if (globalLogger) {
|
|
48
|
+
await globalLogger.close();
|
|
49
|
+
globalLogger = null;
|
|
50
|
+
}
|
|
51
|
+
namedLoggers.clear();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get active transport names for debugging
|
|
55
|
+
* @llm-rule WHEN: Need to see which transports are running (console, file, database, etc)
|
|
56
|
+
* @llm-rule AVOID: Using for business logic - this is for debugging only
|
|
57
|
+
*/
|
|
58
|
+
function getActiveTransports() {
|
|
59
|
+
if (!globalLogger) {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
return globalLogger.getActiveTransports();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check if specific transport is active
|
|
66
|
+
* @llm-rule WHEN: Conditionally logging based on transport availability
|
|
67
|
+
* @llm-rule AVOID: Complex transport detection - just log normally, transports auto-enable
|
|
68
|
+
*/
|
|
69
|
+
function hasTransport(name) {
|
|
70
|
+
if (!globalLogger) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
return globalLogger.hasTransport(name);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get current configuration for debugging
|
|
77
|
+
* @llm-rule WHEN: Debugging logging setup or checking environment detection
|
|
78
|
+
* @llm-rule AVOID: Using for runtime decisions - configuration is set at startup
|
|
79
|
+
*/
|
|
80
|
+
function getConfig() {
|
|
81
|
+
if (!globalLogger) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return globalLogger.getConfig();
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Single logger export with minimal API (like auth module)
|
|
88
|
+
*/
|
|
89
|
+
export const loggerClass = {
|
|
90
|
+
// Core method (like auth.get())
|
|
91
|
+
get,
|
|
92
|
+
// Utility methods
|
|
93
|
+
clear,
|
|
94
|
+
getActiveTransports,
|
|
95
|
+
hasTransport,
|
|
96
|
+
getConfig,
|
|
97
|
+
};
|
|
98
|
+
export { LoggerClass } from './logger.js';
|
|
99
|
+
// Default export
|
|
100
|
+
export default loggerClass;
|
|
101
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/logger/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,6DAA6D;AAC7D,IAAI,YAAY,GAAuB,IAAI,CAAC;AAC5C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAuB,CAAC;AAgBpD;;;;;;GAMG;AACH,SAAS,GAAG,CAAC,SAAkB;IAC7B,2DAA2D;IAC3D,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,YAAY,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,+CAA+C;IAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,2CAA2C;IAC3C,IAAI,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,OAAO,YAAY,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;IACtC,CAAC;IAED,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IACtD,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACzC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,KAAK;IAClB,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;QAC3B,YAAY,GAAG,IAAI,CAAC;IACtB,CAAC;IACD,YAAY,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB;IAC1B,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,YAAY,CAAC,mBAAmB,EAAE,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS;IAChB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,YAAY,CAAC,SAAS,EAAE,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,gCAAgC;IAChC,GAAG;IAEH,kBAAkB;IAClB,KAAK;IACL,mBAAmB;IACnB,YAAY;IACZ,SAAS;CACD,CAAC;AAIX,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,iBAAiB;AACjB,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core logger class with visual error display and simplified transport management
|
|
3
|
+
* @module @bloomneo/appkit/logger
|
|
4
|
+
* @file src/logger/logger.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: Building logger instances - called via loggerClass.get(), not directly
|
|
7
|
+
* @llm-rule AVOID: Creating LoggerClass directly - always use loggerClass.get() for proper setup
|
|
8
|
+
* @llm-rule NOTE: Enhanced error() method provides automatic visual formatting for better DX
|
|
9
|
+
*/
|
|
10
|
+
import type { LoggingConfig } from './defaults.js';
|
|
11
|
+
import type { LogMeta, Logger } from './index.js';
|
|
12
|
+
export interface LogEntry {
|
|
13
|
+
timestamp: string;
|
|
14
|
+
level: 'debug' | 'info' | 'warn' | 'error';
|
|
15
|
+
message: string;
|
|
16
|
+
[key: string]: any;
|
|
17
|
+
}
|
|
18
|
+
export interface Transport {
|
|
19
|
+
write(entry: LogEntry): void | Promise<void>;
|
|
20
|
+
shouldLog?(level: string, configLevel: string): boolean;
|
|
21
|
+
flush?(): Promise<void>;
|
|
22
|
+
close?(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export interface ErrorDiagnostic {
|
|
25
|
+
type: 'warning' | 'error' | 'info' | 'success';
|
|
26
|
+
message: string;
|
|
27
|
+
fix?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Logger class with automatic transport management and enhanced error() method
|
|
31
|
+
*/
|
|
32
|
+
export declare class LoggerClass implements Logger {
|
|
33
|
+
private level;
|
|
34
|
+
private levelValue;
|
|
35
|
+
private defaultMeta;
|
|
36
|
+
private config;
|
|
37
|
+
private transports;
|
|
38
|
+
private pendingWrites;
|
|
39
|
+
constructor(config: LoggingConfig);
|
|
40
|
+
private initializeTransports;
|
|
41
|
+
/**
|
|
42
|
+
* Log informational message
|
|
43
|
+
* @llm-rule WHEN: Normal application events, user actions, business logic flow
|
|
44
|
+
* @llm-rule AVOID: Sensitive data in meta - passwords, tokens, full card numbers
|
|
45
|
+
*/
|
|
46
|
+
info(message: string, meta?: LogMeta): void;
|
|
47
|
+
/**
|
|
48
|
+
* Enhanced error logging with automatic visual formatting
|
|
49
|
+
* @llm-rule WHEN: Exceptions, failures, critical issues requiring attention
|
|
50
|
+
* @llm-rule AVOID: Using for warnings - errors should indicate actual problems
|
|
51
|
+
* @llm-rule NOTE: Automatically provides visual formatting in development with smart diagnostics
|
|
52
|
+
*/
|
|
53
|
+
error(message: string, meta?: LogMeta): void;
|
|
54
|
+
/**
|
|
55
|
+
* Log warning message
|
|
56
|
+
* @llm-rule WHEN: Potential issues, deprecated usage, performance concerns
|
|
57
|
+
* @llm-rule AVOID: Using for normal recoverable errors - use error() for those
|
|
58
|
+
*/
|
|
59
|
+
warn(message: string, meta?: LogMeta): void;
|
|
60
|
+
/**
|
|
61
|
+
* Log debug message
|
|
62
|
+
* @llm-rule WHEN: Development debugging, detailed flow information
|
|
63
|
+
* @llm-rule AVOID: Production debug spam - automatically filtered in production
|
|
64
|
+
*/
|
|
65
|
+
debug(message: string, meta?: LogMeta): void;
|
|
66
|
+
/**
|
|
67
|
+
* Create child logger with additional context
|
|
68
|
+
* @llm-rule WHEN: Adding component context or request-specific data
|
|
69
|
+
* @llm-rule AVOID: Creating many child loggers - reuse component loggers
|
|
70
|
+
*/
|
|
71
|
+
child(bindings: LogMeta): LoggerClass;
|
|
72
|
+
private shouldShowVisual;
|
|
73
|
+
private renderVisualError;
|
|
74
|
+
/**
|
|
75
|
+
* Wrap long error messages with proper indentation and path handling
|
|
76
|
+
* @param message - The message to wrap
|
|
77
|
+
* @param prefix - The prefix (like "❌ ERROR:" or "✗") to account for in width
|
|
78
|
+
*/
|
|
79
|
+
private wrapErrorMessage;
|
|
80
|
+
/**
|
|
81
|
+
* Preprocess message to handle very long paths and URLs intelligently
|
|
82
|
+
*/
|
|
83
|
+
private preprocessLongPaths;
|
|
84
|
+
/**
|
|
85
|
+
* Strip ANSI color codes to get actual text length
|
|
86
|
+
*/
|
|
87
|
+
private stripAnsiCodes;
|
|
88
|
+
private detectErrorType;
|
|
89
|
+
private detectImportVsSyntax;
|
|
90
|
+
private getErrorTitle;
|
|
91
|
+
private generateDiagnostics;
|
|
92
|
+
private getFixMessage;
|
|
93
|
+
/**
|
|
94
|
+
* Get contextual solutions based on error message patterns
|
|
95
|
+
*/
|
|
96
|
+
private getSolutions;
|
|
97
|
+
private getCaller;
|
|
98
|
+
private log;
|
|
99
|
+
private writeToTransports;
|
|
100
|
+
/**
|
|
101
|
+
* Flush pending logs to all transports
|
|
102
|
+
* @llm-rule WHEN: App shutdown or ensuring logs are persisted before critical operations
|
|
103
|
+
* @llm-rule AVOID: Frequent flushing during normal operations - impacts performance
|
|
104
|
+
*/
|
|
105
|
+
flush(): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Close logger and cleanup all transports
|
|
108
|
+
* @llm-rule WHEN: App shutdown or logger cleanup - ensures graceful resource cleanup
|
|
109
|
+
* @llm-rule AVOID: Calling during normal operations - this permanently closes the logger
|
|
110
|
+
*/
|
|
111
|
+
close(): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Get list of active transport names
|
|
114
|
+
* @llm-rule WHEN: Debugging logger setup or checking which transports are running
|
|
115
|
+
* @llm-rule AVOID: Using for business logic - this is for debugging and monitoring only
|
|
116
|
+
*/
|
|
117
|
+
getActiveTransports(): string[];
|
|
118
|
+
/**
|
|
119
|
+
* Check if specific transport is active
|
|
120
|
+
* @llm-rule WHEN: Conditionally logging based on transport availability
|
|
121
|
+
* @llm-rule AVOID: Complex transport detection - just log normally, transports auto-enable
|
|
122
|
+
*/
|
|
123
|
+
hasTransport(name: string): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Set minimum log level dynamically
|
|
126
|
+
* @llm-rule WHEN: Runtime log level changes, debugging, or feature flags
|
|
127
|
+
* @llm-rule AVOID: Frequent level changes - impacts performance
|
|
128
|
+
*/
|
|
129
|
+
setLevel(level: 'debug' | 'info' | 'warn' | 'error'): void;
|
|
130
|
+
/**
|
|
131
|
+
* Get current minimum log level
|
|
132
|
+
* @llm-rule WHEN: Debugging configuration or checking level settings
|
|
133
|
+
* @llm-rule AVOID: Using for filtering logic - logger handles level filtering automatically
|
|
134
|
+
*/
|
|
135
|
+
getLevel(): string;
|
|
136
|
+
/**
|
|
137
|
+
* Check if specific log level would be written
|
|
138
|
+
* @llm-rule WHEN: Expensive log message preparation - check before building complex meta
|
|
139
|
+
* @llm-rule AVOID: Normal logging - level filtering is automatic and fast
|
|
140
|
+
*/
|
|
141
|
+
isLevelEnabled(level: 'debug' | 'info' | 'warn' | 'error'): boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Get current logger configuration for debugging
|
|
144
|
+
* @llm-rule WHEN: Debugging logger setup, checking environment detection, or monitoring
|
|
145
|
+
* @llm-rule AVOID: Using for runtime business logic - configuration is set at startup
|
|
146
|
+
*/
|
|
147
|
+
getConfig(): {
|
|
148
|
+
level: "error" | "warn" | "info" | "debug";
|
|
149
|
+
scope: "minimal" | "full";
|
|
150
|
+
minimal: boolean;
|
|
151
|
+
transports: string[];
|
|
152
|
+
service: {
|
|
153
|
+
name: string;
|
|
154
|
+
version: string;
|
|
155
|
+
environment: string;
|
|
156
|
+
};
|
|
157
|
+
environment: {
|
|
158
|
+
NODE_ENV: string | undefined;
|
|
159
|
+
hasDbUrl: boolean;
|
|
160
|
+
hasHttpUrl: boolean;
|
|
161
|
+
hasWebhookUrl: boolean;
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger/logger.ts"],"names":[],"mappings":"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"}
|