@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,539 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database transport with automatic connection management and batch processing
|
|
3
|
+
* @module @bloomneo/appkit/logger
|
|
4
|
+
* @file src/logger/transports/database.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: Need centralized log storage with database persistence
|
|
7
|
+
* @llm-rule AVOID: Manual database setup - auto-detects from DATABASE_URL and creates tables
|
|
8
|
+
* @llm-rule NOTE: Supports PostgreSQL, MySQL, SQLite with automatic batching and retry logic
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Database transport with automatic connection and table management
|
|
12
|
+
*/
|
|
13
|
+
export class DatabaseTransport {
|
|
14
|
+
url;
|
|
15
|
+
table;
|
|
16
|
+
batchSize;
|
|
17
|
+
minimal;
|
|
18
|
+
// Database state
|
|
19
|
+
client = null;
|
|
20
|
+
connected = false;
|
|
21
|
+
batch = [];
|
|
22
|
+
flushTimer = null;
|
|
23
|
+
dbType = 'postgres';
|
|
24
|
+
/**
|
|
25
|
+
* Creates database transport with direct environment access (like auth pattern)
|
|
26
|
+
* @llm-rule WHEN: Logger initialization with DATABASE_URL environment variable
|
|
27
|
+
* @llm-rule AVOID: Manual database configuration - environment detection handles this
|
|
28
|
+
* @llm-rule NOTE: Auto-detects database type from URL and creates appropriate connection
|
|
29
|
+
*/
|
|
30
|
+
constructor(config) {
|
|
31
|
+
// Direct access to config (like auth module pattern)
|
|
32
|
+
this.url = config.database.url;
|
|
33
|
+
this.table = config.database.table;
|
|
34
|
+
this.batchSize = config.database.batchSize;
|
|
35
|
+
this.minimal = config.minimal;
|
|
36
|
+
// Detect database type from URL
|
|
37
|
+
this.dbType = this.detectDatabaseType(this.url);
|
|
38
|
+
// Initialize database connection
|
|
39
|
+
this.initialize();
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Detect database type from connection URL
|
|
43
|
+
* @llm-rule WHEN: Determining which database client to use
|
|
44
|
+
* @llm-rule AVOID: Manual database type configuration - URL detection is automatic
|
|
45
|
+
*/
|
|
46
|
+
detectDatabaseType(url) {
|
|
47
|
+
const parsed = new URL(url);
|
|
48
|
+
if (parsed.protocol.startsWith('postgres'))
|
|
49
|
+
return 'postgres';
|
|
50
|
+
if (parsed.protocol.startsWith('mysql'))
|
|
51
|
+
return 'mysql';
|
|
52
|
+
if (parsed.protocol.startsWith('sqlite'))
|
|
53
|
+
return 'sqlite';
|
|
54
|
+
return 'postgres'; // Default fallback
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Initialize database transport with connection and table setup
|
|
58
|
+
* @llm-rule WHEN: Transport creation - establishes connection and ensures table exists
|
|
59
|
+
* @llm-rule AVOID: Calling manually - constructor handles initialization
|
|
60
|
+
*/
|
|
61
|
+
async initialize() {
|
|
62
|
+
try {
|
|
63
|
+
await this.connect();
|
|
64
|
+
await this.ensureTableExists();
|
|
65
|
+
this.setupBatchFlush();
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.error('Database transport initialization failed:', error.message);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Write log entry to database via batching
|
|
73
|
+
* @llm-rule WHEN: Storing logs to database for centralized logging
|
|
74
|
+
* @llm-rule AVOID: Calling directly - logger routes entries automatically
|
|
75
|
+
*/
|
|
76
|
+
write(entry) {
|
|
77
|
+
try {
|
|
78
|
+
// Optimize entry based on scope
|
|
79
|
+
const optimizedEntry = this.optimizeEntry(entry);
|
|
80
|
+
// Add to batch
|
|
81
|
+
this.batch.push(optimizedEntry);
|
|
82
|
+
// Flush if batch is full
|
|
83
|
+
if (this.batch.length >= this.batchSize) {
|
|
84
|
+
this.flushBatch();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
console.error('Database transport write error:', error.message);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Optimize log entry for database storage
|
|
93
|
+
* @llm-rule WHEN: Reducing database storage size and improving query performance
|
|
94
|
+
* @llm-rule AVOID: Always using full entries - minimal scope reduces storage significantly
|
|
95
|
+
*/
|
|
96
|
+
optimizeEntry(entry) {
|
|
97
|
+
if (!this.minimal) {
|
|
98
|
+
return entry; // Full scope - keep everything
|
|
99
|
+
}
|
|
100
|
+
// Minimal scope optimization for database
|
|
101
|
+
const { timestamp, level, message, component, requestId, userId, method, url, statusCode, durationMs, error, service, version, environment, ...rest } = entry;
|
|
102
|
+
const minimal = {
|
|
103
|
+
timestamp,
|
|
104
|
+
level,
|
|
105
|
+
message,
|
|
106
|
+
};
|
|
107
|
+
// Add essential fields for correlation (with database-friendly names)
|
|
108
|
+
if (component)
|
|
109
|
+
minimal.component = component;
|
|
110
|
+
if (requestId)
|
|
111
|
+
minimal.request_id = requestId;
|
|
112
|
+
if (userId)
|
|
113
|
+
minimal.user_id = userId;
|
|
114
|
+
// Add HTTP context for API monitoring
|
|
115
|
+
if (method)
|
|
116
|
+
minimal.method = method;
|
|
117
|
+
if (url)
|
|
118
|
+
minimal.url = url;
|
|
119
|
+
if (statusCode)
|
|
120
|
+
minimal.status_code = statusCode;
|
|
121
|
+
if (durationMs)
|
|
122
|
+
minimal.duration_ms = durationMs;
|
|
123
|
+
// Add service identification
|
|
124
|
+
if (service)
|
|
125
|
+
minimal.service = service;
|
|
126
|
+
if (version)
|
|
127
|
+
minimal.version = version;
|
|
128
|
+
if (environment)
|
|
129
|
+
minimal.environment = environment;
|
|
130
|
+
// Optimize error information
|
|
131
|
+
if (error) {
|
|
132
|
+
if (typeof error === 'object') {
|
|
133
|
+
minimal.error_message = error.message;
|
|
134
|
+
if (error.code)
|
|
135
|
+
minimal.error_code = error.code;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
minimal.error_message = error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Add only essential metadata as JSON
|
|
142
|
+
const essentialMeta = this.filterEssentialMeta(rest);
|
|
143
|
+
if (Object.keys(essentialMeta).length > 0) {
|
|
144
|
+
minimal.meta = essentialMeta;
|
|
145
|
+
}
|
|
146
|
+
return minimal;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Filter metadata for essential correlation fields
|
|
150
|
+
* @llm-rule WHEN: Keeping database size manageable while preserving correlation data
|
|
151
|
+
* @llm-rule AVOID: Storing all metadata - focus on correlation and debugging fields
|
|
152
|
+
*/
|
|
153
|
+
filterEssentialMeta(meta) {
|
|
154
|
+
const essential = {};
|
|
155
|
+
// Essential correlation fields for database queries
|
|
156
|
+
const essentialKeys = [
|
|
157
|
+
'traceId', 'spanId', 'sessionId', 'tenantId', 'appName', 'ip'
|
|
158
|
+
];
|
|
159
|
+
for (const key of essentialKeys) {
|
|
160
|
+
if (meta[key] !== undefined) {
|
|
161
|
+
essential[key] = meta[key];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Include correlation IDs (fields ending with 'Id')
|
|
165
|
+
for (const [key, value] of Object.entries(meta)) {
|
|
166
|
+
if (key.endsWith('Id') && !essential[key]) {
|
|
167
|
+
essential[key] = value;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return essential;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Connect to database with appropriate client
|
|
174
|
+
* @llm-rule WHEN: Establishing database connection based on detected type
|
|
175
|
+
* @llm-rule AVOID: Manual connection setup - auto-detection handles client selection
|
|
176
|
+
*/
|
|
177
|
+
async connect() {
|
|
178
|
+
try {
|
|
179
|
+
switch (this.dbType) {
|
|
180
|
+
case 'postgres':
|
|
181
|
+
await this.connectPostgres();
|
|
182
|
+
break;
|
|
183
|
+
case 'mysql':
|
|
184
|
+
await this.connectMySQL();
|
|
185
|
+
break;
|
|
186
|
+
case 'sqlite':
|
|
187
|
+
await this.connectSQLite();
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
this.connected = true;
|
|
191
|
+
console.log(`Database transport connected successfully (${this.dbType})`);
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
console.error('Database connection failed:', error.message);
|
|
195
|
+
this.connected = false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Connect to PostgreSQL database
|
|
200
|
+
* @llm-rule WHEN: DATABASE_URL starts with postgres:// or postgresql://
|
|
201
|
+
* @llm-rule AVOID: Manual PostgreSQL setup - uses standard pg client
|
|
202
|
+
*/
|
|
203
|
+
async connectPostgres() {
|
|
204
|
+
try {
|
|
205
|
+
const { Client } = await import('pg');
|
|
206
|
+
this.client = new Client({
|
|
207
|
+
connectionString: this.url,
|
|
208
|
+
connectionTimeoutMillis: 10000,
|
|
209
|
+
});
|
|
210
|
+
await this.client.connect();
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
throw new Error(`PostgreSQL connection failed: ${error.message}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Connect to MySQL database
|
|
218
|
+
* @llm-rule WHEN: DATABASE_URL starts with mysql://
|
|
219
|
+
* @llm-rule AVOID: Manual MySQL setup - uses standard mysql2 client
|
|
220
|
+
*/
|
|
221
|
+
async connectMySQL() {
|
|
222
|
+
try {
|
|
223
|
+
const mysql = await import('mysql2/promise');
|
|
224
|
+
this.client = await mysql.createConnection(this.url);
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
throw new Error(`MySQL connection failed: ${error.message}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Connect to SQLite database
|
|
232
|
+
* @llm-rule WHEN: DATABASE_URL starts with sqlite://
|
|
233
|
+
* @llm-rule AVOID: Manual SQLite setup - uses standard sqlite3 client
|
|
234
|
+
*/
|
|
235
|
+
async connectSQLite() {
|
|
236
|
+
try {
|
|
237
|
+
const sqlite3 = await import('sqlite3');
|
|
238
|
+
const { open } = await import('sqlite');
|
|
239
|
+
const url = new URL(this.url);
|
|
240
|
+
const dbPath = url.pathname || ':memory:';
|
|
241
|
+
this.client = await open({
|
|
242
|
+
filename: dbPath,
|
|
243
|
+
driver: sqlite3.Database,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
throw new Error(`SQLite connection failed: ${error.message}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Ensure logs table exists with optimized schema
|
|
252
|
+
* @llm-rule WHEN: Database connection established - creates table if needed
|
|
253
|
+
* @llm-rule AVOID: Manual table creation - automatic schema handles different databases
|
|
254
|
+
*/
|
|
255
|
+
async ensureTableExists() {
|
|
256
|
+
if (!this.connected)
|
|
257
|
+
return;
|
|
258
|
+
try {
|
|
259
|
+
const createTableSQL = this.getCreateTableSQL();
|
|
260
|
+
await this.executeQuery(createTableSQL);
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
console.error('Error creating logs table:', error.message);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Get CREATE TABLE SQL for current database type
|
|
268
|
+
* @llm-rule WHEN: Creating logs table with database-specific optimizations
|
|
269
|
+
* @llm-rule AVOID: Generic SQL - each database has optimal data types and indexes
|
|
270
|
+
*/
|
|
271
|
+
getCreateTableSQL() {
|
|
272
|
+
switch (this.dbType) {
|
|
273
|
+
case 'postgres':
|
|
274
|
+
return `
|
|
275
|
+
CREATE TABLE IF NOT EXISTS ${this.table} (
|
|
276
|
+
id SERIAL PRIMARY KEY,
|
|
277
|
+
timestamp TIMESTAMPTZ NOT NULL,
|
|
278
|
+
level VARCHAR(10) NOT NULL,
|
|
279
|
+
message TEXT,
|
|
280
|
+
component VARCHAR(100),
|
|
281
|
+
request_id VARCHAR(100),
|
|
282
|
+
user_id VARCHAR(100),
|
|
283
|
+
method VARCHAR(10),
|
|
284
|
+
url TEXT,
|
|
285
|
+
status_code INTEGER,
|
|
286
|
+
duration_ms INTEGER,
|
|
287
|
+
error_message TEXT,
|
|
288
|
+
error_code VARCHAR(50),
|
|
289
|
+
service VARCHAR(100),
|
|
290
|
+
version VARCHAR(50),
|
|
291
|
+
environment VARCHAR(50),
|
|
292
|
+
meta JSONB,
|
|
293
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
294
|
+
);
|
|
295
|
+
CREATE INDEX IF NOT EXISTS idx_${this.table}_timestamp ON ${this.table}(timestamp);
|
|
296
|
+
CREATE INDEX IF NOT EXISTS idx_${this.table}_level ON ${this.table}(level);
|
|
297
|
+
CREATE INDEX IF NOT EXISTS idx_${this.table}_component ON ${this.table}(component);
|
|
298
|
+
CREATE INDEX IF NOT EXISTS idx_${this.table}_request_id ON ${this.table}(request_id);
|
|
299
|
+
`;
|
|
300
|
+
case 'mysql':
|
|
301
|
+
return `
|
|
302
|
+
CREATE TABLE IF NOT EXISTS ${this.table} (
|
|
303
|
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
304
|
+
timestamp DATETIME NOT NULL,
|
|
305
|
+
level VARCHAR(10) NOT NULL,
|
|
306
|
+
message TEXT,
|
|
307
|
+
component VARCHAR(100),
|
|
308
|
+
request_id VARCHAR(100),
|
|
309
|
+
user_id VARCHAR(100),
|
|
310
|
+
method VARCHAR(10),
|
|
311
|
+
url TEXT,
|
|
312
|
+
status_code INT,
|
|
313
|
+
duration_ms INT,
|
|
314
|
+
error_message TEXT,
|
|
315
|
+
error_code VARCHAR(50),
|
|
316
|
+
service VARCHAR(100),
|
|
317
|
+
version VARCHAR(50),
|
|
318
|
+
environment VARCHAR(50),
|
|
319
|
+
meta JSON,
|
|
320
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
321
|
+
INDEX idx_timestamp (timestamp),
|
|
322
|
+
INDEX idx_level (level),
|
|
323
|
+
INDEX idx_component (component),
|
|
324
|
+
INDEX idx_request_id (request_id)
|
|
325
|
+
);
|
|
326
|
+
`;
|
|
327
|
+
case 'sqlite':
|
|
328
|
+
return `
|
|
329
|
+
CREATE TABLE IF NOT EXISTS ${this.table} (
|
|
330
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
331
|
+
timestamp TEXT NOT NULL,
|
|
332
|
+
level TEXT NOT NULL,
|
|
333
|
+
message TEXT,
|
|
334
|
+
component TEXT,
|
|
335
|
+
request_id TEXT,
|
|
336
|
+
user_id TEXT,
|
|
337
|
+
method TEXT,
|
|
338
|
+
url TEXT,
|
|
339
|
+
status_code INTEGER,
|
|
340
|
+
duration_ms INTEGER,
|
|
341
|
+
error_message TEXT,
|
|
342
|
+
error_code TEXT,
|
|
343
|
+
service TEXT,
|
|
344
|
+
version TEXT,
|
|
345
|
+
environment TEXT,
|
|
346
|
+
meta TEXT,
|
|
347
|
+
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
348
|
+
);
|
|
349
|
+
CREATE INDEX IF NOT EXISTS idx_${this.table}_timestamp ON ${this.table}(timestamp);
|
|
350
|
+
CREATE INDEX IF NOT EXISTS idx_${this.table}_level ON ${this.table}(level);
|
|
351
|
+
`;
|
|
352
|
+
default:
|
|
353
|
+
throw new Error(`Unsupported database type: ${this.dbType}`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Execute database query with error handling
|
|
358
|
+
* @llm-rule WHEN: Running SQL queries against the database
|
|
359
|
+
* @llm-rule AVOID: Direct client usage - this handles database-specific differences
|
|
360
|
+
*/
|
|
361
|
+
async executeQuery(sql, params = []) {
|
|
362
|
+
if (!this.connected || !this.client) {
|
|
363
|
+
throw new Error('Database not connected');
|
|
364
|
+
}
|
|
365
|
+
try {
|
|
366
|
+
switch (this.dbType) {
|
|
367
|
+
case 'postgres':
|
|
368
|
+
return await this.client.query(sql, params);
|
|
369
|
+
case 'mysql':
|
|
370
|
+
return await this.client.execute(sql, params);
|
|
371
|
+
case 'sqlite':
|
|
372
|
+
if (params.length > 0) {
|
|
373
|
+
return await this.client.run(sql, params);
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
return await this.client.exec(sql);
|
|
377
|
+
}
|
|
378
|
+
default:
|
|
379
|
+
throw new Error(`Unsupported database type: ${this.dbType}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
catch (error) {
|
|
383
|
+
throw new Error(`Database query failed: ${error.message}`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Setup automatic batch flushing
|
|
388
|
+
* @llm-rule WHEN: Transport initialization - ensures logs are written regularly
|
|
389
|
+
* @llm-rule AVOID: Manual flushing - automatic batching improves performance
|
|
390
|
+
*/
|
|
391
|
+
setupBatchFlush() {
|
|
392
|
+
this.flushTimer = setInterval(() => {
|
|
393
|
+
if (this.batch.length > 0) {
|
|
394
|
+
this.flushBatch();
|
|
395
|
+
}
|
|
396
|
+
}, 5000); // Flush every 5 seconds
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Flush current batch to database
|
|
400
|
+
* @llm-rule WHEN: Batch is full or timer triggers
|
|
401
|
+
* @llm-rule AVOID: Individual inserts - batching significantly improves performance
|
|
402
|
+
*/
|
|
403
|
+
async flushBatch() {
|
|
404
|
+
if (this.batch.length === 0 || !this.connected) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
const currentBatch = [...this.batch];
|
|
408
|
+
this.batch = [];
|
|
409
|
+
try {
|
|
410
|
+
await this.insertBatch(currentBatch);
|
|
411
|
+
}
|
|
412
|
+
catch (error) {
|
|
413
|
+
console.error('Database batch flush failed:', error.message);
|
|
414
|
+
// Re-add failed entries for retry (up to batch size limit)
|
|
415
|
+
const retryEntries = currentBatch.slice(0, this.batchSize);
|
|
416
|
+
this.batch.unshift(...retryEntries);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Insert batch of log entries efficiently
|
|
421
|
+
* @llm-rule WHEN: Batch flush with multiple log entries
|
|
422
|
+
* @llm-rule AVOID: Individual inserts - batch inserts are much faster
|
|
423
|
+
*/
|
|
424
|
+
async insertBatch(entries) {
|
|
425
|
+
if (entries.length === 0)
|
|
426
|
+
return;
|
|
427
|
+
const fields = [
|
|
428
|
+
'timestamp', 'level', 'message', 'component', 'request_id', 'user_id',
|
|
429
|
+
'method', 'url', 'status_code', 'duration_ms', 'error_message', 'error_code',
|
|
430
|
+
'service', 'version', 'environment', 'meta'
|
|
431
|
+
];
|
|
432
|
+
switch (this.dbType) {
|
|
433
|
+
case 'postgres':
|
|
434
|
+
await this.insertBatchPostgres(entries, fields);
|
|
435
|
+
break;
|
|
436
|
+
case 'mysql':
|
|
437
|
+
await this.insertBatchMySQL(entries, fields);
|
|
438
|
+
break;
|
|
439
|
+
case 'sqlite':
|
|
440
|
+
await this.insertBatchSQLite(entries, fields);
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Insert batch for PostgreSQL with parameter placeholders
|
|
446
|
+
*/
|
|
447
|
+
async insertBatchPostgres(entries, fields) {
|
|
448
|
+
const placeholders = entries
|
|
449
|
+
.map((_, index) => {
|
|
450
|
+
const startIndex = index * fields.length;
|
|
451
|
+
return `(${fields.map((_, fieldIndex) => `$${startIndex + fieldIndex + 1}`).join(', ')})`;
|
|
452
|
+
})
|
|
453
|
+
.join(', ');
|
|
454
|
+
const params = entries.flatMap(entry => fields.map(field => {
|
|
455
|
+
const value = entry[field];
|
|
456
|
+
return field === 'meta' && value ? JSON.stringify(value) : (value || null);
|
|
457
|
+
}));
|
|
458
|
+
const sql = `INSERT INTO ${this.table} (${fields.join(', ')}) VALUES ${placeholders}`;
|
|
459
|
+
await this.executeQuery(sql, params);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Insert batch for MySQL with question mark placeholders
|
|
463
|
+
*/
|
|
464
|
+
async insertBatchMySQL(entries, fields) {
|
|
465
|
+
const placeholders = entries.map(() => `(${fields.map(() => '?').join(', ')})`).join(', ');
|
|
466
|
+
const params = entries.flatMap(entry => fields.map(field => {
|
|
467
|
+
const value = entry[field];
|
|
468
|
+
return field === 'meta' && value ? JSON.stringify(value) : (value || null);
|
|
469
|
+
}));
|
|
470
|
+
const sql = `INSERT INTO ${this.table} (${fields.join(', ')}) VALUES ${placeholders}`;
|
|
471
|
+
await this.executeQuery(sql, params);
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Insert batch for SQLite with individual statements
|
|
475
|
+
*/
|
|
476
|
+
async insertBatchSQLite(entries, fields) {
|
|
477
|
+
const sql = `INSERT INTO ${this.table} (${fields.join(', ')}) VALUES (${fields.map(() => '?').join(', ')})`;
|
|
478
|
+
for (const entry of entries) {
|
|
479
|
+
const params = fields.map(field => {
|
|
480
|
+
const value = entry[field];
|
|
481
|
+
return field === 'meta' && value ? JSON.stringify(value) : (value || null);
|
|
482
|
+
});
|
|
483
|
+
await this.executeQuery(sql, params);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Check if this transport should log the given level
|
|
488
|
+
* @llm-rule WHEN: Logger asks if transport handles this level
|
|
489
|
+
* @llm-rule AVOID: Complex level logic - simple comparison is sufficient
|
|
490
|
+
*/
|
|
491
|
+
shouldLog(level, configLevel) {
|
|
492
|
+
const levels = {
|
|
493
|
+
error: 0, warn: 1, info: 2, debug: 3
|
|
494
|
+
};
|
|
495
|
+
return levels[level] <= levels[configLevel];
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Flush pending logs to database
|
|
499
|
+
* @llm-rule WHEN: App shutdown or ensuring logs are persisted
|
|
500
|
+
* @llm-rule AVOID: Frequent flushing - impacts performance
|
|
501
|
+
*/
|
|
502
|
+
async flush() {
|
|
503
|
+
await this.flushBatch();
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Close database transport and cleanup resources
|
|
507
|
+
* @llm-rule WHEN: App shutdown or logger cleanup
|
|
508
|
+
* @llm-rule AVOID: Abrupt shutdown - graceful close prevents data loss
|
|
509
|
+
*/
|
|
510
|
+
async close() {
|
|
511
|
+
// Clear flush timer
|
|
512
|
+
if (this.flushTimer) {
|
|
513
|
+
clearInterval(this.flushTimer);
|
|
514
|
+
this.flushTimer = null;
|
|
515
|
+
}
|
|
516
|
+
// Flush remaining logs
|
|
517
|
+
await this.flushBatch();
|
|
518
|
+
// Close database connection
|
|
519
|
+
if (this.client && this.connected) {
|
|
520
|
+
try {
|
|
521
|
+
switch (this.dbType) {
|
|
522
|
+
case 'postgres':
|
|
523
|
+
case 'mysql':
|
|
524
|
+
await this.client.end();
|
|
525
|
+
break;
|
|
526
|
+
case 'sqlite':
|
|
527
|
+
await this.client.close();
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
catch (error) {
|
|
532
|
+
console.error('Error closing database connection:', error.message);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
this.connected = false;
|
|
536
|
+
this.client = null;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
//# sourceMappingURL=database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/logger/transports/database.ts"],"names":[],"mappings":"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"}
|