@morojs/moro 1.5.3 → 1.5.4
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/dist/core/auth/morojs-adapter.js +23 -12
- package/dist/core/auth/morojs-adapter.js.map +1 -1
- package/dist/core/http/http-server.js +12 -8
- package/dist/core/http/http-server.js.map +1 -1
- package/dist/core/logger/filters.js +12 -4
- package/dist/core/logger/filters.js.map +1 -1
- package/dist/core/logger/logger.d.ts +44 -0
- package/dist/core/logger/logger.js +550 -60
- package/dist/core/logger/logger.js.map +1 -1
- package/dist/core/middleware/built-in/request-logger.js +4 -2
- package/dist/core/middleware/built-in/request-logger.js.map +1 -1
- package/dist/core/modules/auto-discovery.d.ts +1 -0
- package/dist/core/modules/auto-discovery.js +9 -5
- package/dist/core/modules/auto-discovery.js.map +1 -1
- package/dist/core/modules/modules.d.ts +1 -0
- package/dist/core/modules/modules.js +8 -2
- package/dist/core/modules/modules.js.map +1 -1
- package/dist/core/networking/adapters/ws-adapter.d.ts +1 -0
- package/dist/core/networking/adapters/ws-adapter.js +3 -1
- package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
- package/dist/core/networking/service-discovery.d.ts +1 -0
- package/dist/core/networking/service-discovery.js +23 -11
- package/dist/core/networking/service-discovery.js.map +1 -1
- package/dist/types/logger.d.ts +3 -0
- package/package.json +1 -1
- package/src/core/auth/morojs-adapter.ts +25 -12
- package/src/core/database/README.md +26 -16
- package/src/core/http/http-server.ts +15 -12
- package/src/core/logger/filters.ts +12 -4
- package/src/core/logger/logger.ts +616 -63
- package/src/core/middleware/built-in/request-logger.ts +6 -2
- package/src/core/modules/auto-discovery.ts +13 -5
- package/src/core/modules/modules.ts +9 -5
- package/src/core/networking/adapters/ws-adapter.ts +3 -1
- package/src/core/networking/service-discovery.ts +23 -9
- package/src/types/logger.ts +3 -0
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
* @see https://github.com/nextauthjs/next-auth/tree/main/packages
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import { createFrameworkLogger } from '../logger';
|
|
12
|
+
|
|
13
|
+
const logger = createFrameworkLogger('AuthAdapter');
|
|
14
|
+
|
|
11
15
|
// Mock Auth.js types until we have the actual package
|
|
12
16
|
// These would come from @auth/core in a real implementation
|
|
13
17
|
export interface AuthConfig {
|
|
@@ -247,7 +251,7 @@ export async function MoroJSAuth(config: MoroJSAuthConfig): Promise<{
|
|
|
247
251
|
basePath,
|
|
248
252
|
raw: (code: any, ...message: any[]) => {
|
|
249
253
|
if (config.morojs?.debug) {
|
|
250
|
-
|
|
254
|
+
logger.debug(`[MoroJS Auth] ${code}:`, 'AuthAdapter', { message });
|
|
251
255
|
}
|
|
252
256
|
},
|
|
253
257
|
});
|
|
@@ -261,7 +265,9 @@ export async function MoroJSAuth(config: MoroJSAuthConfig): Promise<{
|
|
|
261
265
|
// Convert Web API response to MoroJS response
|
|
262
266
|
await fromWebResponse(finalResponse, res);
|
|
263
267
|
} catch (error) {
|
|
264
|
-
|
|
268
|
+
logger.error('[MoroJS Auth] Error', 'AuthAdapter', {
|
|
269
|
+
error: error instanceof Error ? error.message : String(error),
|
|
270
|
+
});
|
|
265
271
|
// Robust error handling - check if response methods exist
|
|
266
272
|
if (typeof (res as any).status === 'function' && typeof (res as any).json === 'function') {
|
|
267
273
|
(res as any).status(500).json({
|
|
@@ -308,7 +314,9 @@ export async function MoroJSAuth(config: MoroJSAuthConfig): Promise<{
|
|
|
308
314
|
return null;
|
|
309
315
|
} catch (error) {
|
|
310
316
|
if (config.morojs?.debug) {
|
|
311
|
-
|
|
317
|
+
logger.error('[MoroJS Auth] Session error', 'AuthAdapter', {
|
|
318
|
+
error: error instanceof Error ? error.message : String(error),
|
|
319
|
+
});
|
|
312
320
|
}
|
|
313
321
|
return null;
|
|
314
322
|
}
|
|
@@ -322,18 +330,21 @@ export async function MoroJSAuth(config: MoroJSAuthConfig): Promise<{
|
|
|
322
330
|
* This creates a MoroJS-compatible middleware for authentication
|
|
323
331
|
*/
|
|
324
332
|
export function createAuthMiddleware(config: MoroJSAuthConfig) {
|
|
325
|
-
|
|
333
|
+
logger.info('createAuthMiddleware called - creating middleware function', 'AuthAdapter');
|
|
326
334
|
// Return a function that MoroJS can call directly
|
|
327
335
|
return async (app: any) => {
|
|
328
|
-
|
|
329
|
-
|
|
336
|
+
logger.info('Installing Auth.js middleware...', 'AuthAdapter');
|
|
337
|
+
logger.debug('App object received', 'AuthAdapter', {
|
|
338
|
+
appType: typeof app,
|
|
339
|
+
appConstructor: app.constructor.name,
|
|
340
|
+
});
|
|
330
341
|
|
|
331
342
|
// Get the hooks from the app's middleware system
|
|
332
343
|
const hooks =
|
|
333
344
|
(app as any).coreFramework?.middlewareManager?.hooks || (app as any).middlewareManager?.hooks;
|
|
334
345
|
|
|
335
346
|
if (!hooks) {
|
|
336
|
-
|
|
347
|
+
logger.error('Could not access MoroJS hooks system', 'AuthAdapter');
|
|
337
348
|
return;
|
|
338
349
|
}
|
|
339
350
|
|
|
@@ -344,9 +355,9 @@ export function createAuthMiddleware(config: MoroJSAuthConfig) {
|
|
|
344
355
|
|
|
345
356
|
// Register request hook
|
|
346
357
|
hooks.before('request', async (context: any) => {
|
|
347
|
-
|
|
358
|
+
logger.debug('Native adapter hook starting', 'AuthAdapter');
|
|
348
359
|
const req = context.request;
|
|
349
|
-
|
|
360
|
+
logger.debug('Request path', 'AuthAdapter', { path: req.path || req.url });
|
|
350
361
|
|
|
351
362
|
try {
|
|
352
363
|
// Just add auth object to request - don't touch response
|
|
@@ -383,14 +394,16 @@ export function createAuthMiddleware(config: MoroJSAuthConfig) {
|
|
|
383
394
|
return { url: signOutUrl };
|
|
384
395
|
},
|
|
385
396
|
};
|
|
386
|
-
|
|
397
|
+
logger.debug('Native adapter hook completed successfully', 'AuthAdapter');
|
|
387
398
|
} catch (error) {
|
|
388
|
-
|
|
399
|
+
logger.error('Error in native adapter hook', 'AuthAdapter', {
|
|
400
|
+
error: error instanceof Error ? error.message : String(error),
|
|
401
|
+
});
|
|
389
402
|
throw error;
|
|
390
403
|
}
|
|
391
404
|
});
|
|
392
405
|
|
|
393
|
-
|
|
406
|
+
logger.info('Auth.js middleware installed successfully!', 'AuthAdapter');
|
|
394
407
|
};
|
|
395
408
|
}
|
|
396
409
|
|
|
@@ -7,16 +7,19 @@ The MoroJS database module provides a pluggable adapter system for different dat
|
|
|
7
7
|
### SQL Databases
|
|
8
8
|
|
|
9
9
|
#### MySQL Adapter
|
|
10
|
+
|
|
10
11
|
- **Package Required**: `mysql2`
|
|
11
12
|
- **Usage**: Production-ready with connection pooling
|
|
12
13
|
- **Type**: `mysql`
|
|
13
14
|
|
|
14
|
-
#### PostgreSQL Adapter
|
|
15
|
+
#### PostgreSQL Adapter
|
|
16
|
+
|
|
15
17
|
- **Package Required**: `pg` and `@types/pg`
|
|
16
18
|
- **Usage**: Full PostgreSQL feature support
|
|
17
19
|
- **Type**: `postgresql`, `postgres`, or `pg`
|
|
18
20
|
|
|
19
21
|
#### SQLite Adapter
|
|
22
|
+
|
|
20
23
|
- **Package Required**: `better-sqlite3`
|
|
21
24
|
- **Usage**: Lightweight, file-based database
|
|
22
25
|
- **Type**: `sqlite` or `sqlite3`
|
|
@@ -24,11 +27,13 @@ The MoroJS database module provides a pluggable adapter system for different dat
|
|
|
24
27
|
### NoSQL Databases
|
|
25
28
|
|
|
26
29
|
#### MongoDB Adapter
|
|
30
|
+
|
|
27
31
|
- **Package Required**: `mongodb`
|
|
28
32
|
- **Usage**: Document database with aggregation support
|
|
29
33
|
- **Type**: `mongodb` or `mongo`
|
|
30
34
|
|
|
31
35
|
#### Redis Adapter
|
|
36
|
+
|
|
32
37
|
- **Package Required**: `ioredis`
|
|
33
38
|
- **Usage**: In-memory key-value store with pub/sub
|
|
34
39
|
- **Type**: `redis`
|
|
@@ -36,6 +41,7 @@ The MoroJS database module provides a pluggable adapter system for different dat
|
|
|
36
41
|
### ORM
|
|
37
42
|
|
|
38
43
|
#### Drizzle Adapter
|
|
44
|
+
|
|
39
45
|
- **Package Required**: `drizzle-orm` + database driver
|
|
40
46
|
- **Usage**: Type-safe ORM with schema validation
|
|
41
47
|
- **Type**: `drizzle` or `orm`
|
|
@@ -43,7 +49,7 @@ The MoroJS database module provides a pluggable adapter system for different dat
|
|
|
43
49
|
## Factory Pattern (Recommended)
|
|
44
50
|
|
|
45
51
|
```typescript
|
|
46
|
-
import { createDatabaseAdapter } from 'moro';
|
|
52
|
+
import { createDatabaseAdapter } from '@morojs/moro';
|
|
47
53
|
|
|
48
54
|
// SQL Databases
|
|
49
55
|
const mysql = createDatabaseAdapter('mysql', {
|
|
@@ -52,7 +58,7 @@ const mysql = createDatabaseAdapter('mysql', {
|
|
|
52
58
|
user: 'root',
|
|
53
59
|
password: 'password',
|
|
54
60
|
database: 'my_app',
|
|
55
|
-
connectionLimit: 10
|
|
61
|
+
connectionLimit: 10,
|
|
56
62
|
});
|
|
57
63
|
|
|
58
64
|
const postgres = createDatabaseAdapter('postgresql', {
|
|
@@ -62,12 +68,12 @@ const postgres = createDatabaseAdapter('postgresql', {
|
|
|
62
68
|
password: 'password',
|
|
63
69
|
database: 'my_app',
|
|
64
70
|
connectionLimit: 10,
|
|
65
|
-
ssl: false
|
|
71
|
+
ssl: false,
|
|
66
72
|
});
|
|
67
73
|
|
|
68
74
|
const sqlite = createDatabaseAdapter('sqlite', {
|
|
69
75
|
filename: 'app.db',
|
|
70
|
-
memory: false
|
|
76
|
+
memory: false,
|
|
71
77
|
});
|
|
72
78
|
|
|
73
79
|
// NoSQL Databases
|
|
@@ -76,34 +82,34 @@ const mongodb = createDatabaseAdapter('mongodb', {
|
|
|
76
82
|
port: 27017,
|
|
77
83
|
database: 'my_app',
|
|
78
84
|
username: 'user',
|
|
79
|
-
password: 'password'
|
|
85
|
+
password: 'password',
|
|
80
86
|
});
|
|
81
87
|
|
|
82
88
|
const redis = createDatabaseAdapter('redis', {
|
|
83
89
|
host: 'localhost',
|
|
84
90
|
port: 6379,
|
|
85
91
|
password: 'password',
|
|
86
|
-
keyPrefix: 'myapp:'
|
|
92
|
+
keyPrefix: 'myapp:',
|
|
87
93
|
});
|
|
88
94
|
|
|
89
95
|
// ORM
|
|
90
96
|
const drizzle = createDatabaseAdapter('drizzle', {
|
|
91
97
|
database: drizzleInstance,
|
|
92
|
-
schema: schemaObject
|
|
98
|
+
schema: schemaObject,
|
|
93
99
|
});
|
|
94
100
|
```
|
|
95
101
|
|
|
96
102
|
## Direct Instantiation
|
|
97
103
|
|
|
98
104
|
```typescript
|
|
99
|
-
import {
|
|
100
|
-
MySQLAdapter,
|
|
101
|
-
PostgreSQLAdapter,
|
|
105
|
+
import {
|
|
106
|
+
MySQLAdapter,
|
|
107
|
+
PostgreSQLAdapter,
|
|
102
108
|
SQLiteAdapter,
|
|
103
109
|
MongoDBAdapter,
|
|
104
110
|
RedisAdapter,
|
|
105
111
|
DrizzleAdapter
|
|
106
|
-
} from 'moro';
|
|
112
|
+
} from '@morojs/moro';
|
|
107
113
|
|
|
108
114
|
// SQL
|
|
109
115
|
const mysql = new MySQLAdapter({ host: 'localhost', ... });
|
|
@@ -151,7 +157,7 @@ const updated = await db.update('users', { name: 'Jane' }, { id: 1 });
|
|
|
151
157
|
const deleted = await db.delete('users', { id: 1 });
|
|
152
158
|
|
|
153
159
|
// Transactions
|
|
154
|
-
const result = await db.transaction(async
|
|
160
|
+
const result = await db.transaction(async tx => {
|
|
155
161
|
const user = await tx.insert('users', userData);
|
|
156
162
|
await tx.insert('profiles', { user_id: user.id, ...profileData });
|
|
157
163
|
return user;
|
|
@@ -161,6 +167,7 @@ const result = await db.transaction(async (tx) => {
|
|
|
161
167
|
## Usage Examples
|
|
162
168
|
|
|
163
169
|
### SQL Operations
|
|
170
|
+
|
|
164
171
|
```typescript
|
|
165
172
|
// Standard CRUD operations work across all SQL adapters
|
|
166
173
|
const users = await db.query('SELECT * FROM users WHERE age > ?', [18]);
|
|
@@ -171,6 +178,7 @@ const deleted = await db.delete('users', { id: 1 });
|
|
|
171
178
|
```
|
|
172
179
|
|
|
173
180
|
### MongoDB Operations
|
|
181
|
+
|
|
174
182
|
```typescript
|
|
175
183
|
// MongoDB uses collections instead of tables
|
|
176
184
|
const users = await mongoDb.query('users'); // Get all
|
|
@@ -179,12 +187,13 @@ const user = await mongoDb.queryOne('users', { email: 'john@example.com' });
|
|
|
179
187
|
|
|
180
188
|
// MongoDB-specific methods
|
|
181
189
|
const stats = await mongoDb.aggregate('users', [
|
|
182
|
-
{ $group: { _id: null, avgAge: { $avg: '$age' } } }
|
|
190
|
+
{ $group: { _id: null, avgAge: { $avg: '$age' } } },
|
|
183
191
|
]);
|
|
184
192
|
await mongoDb.createIndex('users', { email: 1 }, { unique: true });
|
|
185
193
|
```
|
|
186
194
|
|
|
187
195
|
### Redis Operations
|
|
196
|
+
|
|
188
197
|
```typescript
|
|
189
198
|
// Key-value operations
|
|
190
199
|
await redisDb.set('user:123', userData, 3600); // with TTL
|
|
@@ -197,6 +206,7 @@ await redisDb.publish('notifications', message);
|
|
|
197
206
|
```
|
|
198
207
|
|
|
199
208
|
### Drizzle ORM Operations
|
|
209
|
+
|
|
200
210
|
```typescript
|
|
201
211
|
// Type-safe queries (requires schema setup)
|
|
202
212
|
const users = await drizzleDb.select('users').where(eq(schema.users.age, 25));
|
|
@@ -213,7 +223,7 @@ Choose and install the appropriate database package:
|
|
|
213
223
|
```bash
|
|
214
224
|
# SQL Databases
|
|
215
225
|
npm install mysql2 # MySQL
|
|
216
|
-
npm install pg @types/pg # PostgreSQL
|
|
226
|
+
npm install pg @types/pg # PostgreSQL
|
|
217
227
|
npm install better-sqlite3 # SQLite
|
|
218
228
|
|
|
219
229
|
# NoSQL Databases
|
|
@@ -225,4 +235,4 @@ npm install drizzle-orm # Drizzle ORM
|
|
|
225
235
|
# Plus the appropriate driver (mysql2, pg, better-sqlite3, etc.)
|
|
226
236
|
```
|
|
227
237
|
|
|
228
|
-
The adapters will gracefully handle missing packages with helpful error messages.
|
|
238
|
+
The adapters will gracefully handle missing packages with helpful error messages.
|
|
@@ -281,12 +281,13 @@ export class MoroHttpServer {
|
|
|
281
281
|
await route.handler(httpReq, httpRes);
|
|
282
282
|
} catch (error) {
|
|
283
283
|
// Debug: Log the actual error and where it came from
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
284
|
+
this.logger.debug('Request error details', 'RequestHandler', {
|
|
285
|
+
errorType: typeof error,
|
|
286
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
287
|
+
errorStack: error instanceof Error ? error.stack : 'No stack trace',
|
|
288
|
+
requestPath: req.url,
|
|
289
|
+
requestMethod: req.method,
|
|
290
|
+
});
|
|
290
291
|
|
|
291
292
|
this.logger.error('Request error', 'RequestHandler', {
|
|
292
293
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -310,11 +311,10 @@ export class MoroHttpServer {
|
|
|
310
311
|
httpRes.setHeader('Content-Type', 'application/json');
|
|
311
312
|
} else {
|
|
312
313
|
// Even setHeader doesn't exist - object is completely wrong
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
);
|
|
314
|
+
this.logger.error('Response object is not a proper ServerResponse', 'RequestHandler', {
|
|
315
|
+
responseType: typeof httpRes,
|
|
316
|
+
responseKeys: Object.keys(httpRes),
|
|
317
|
+
});
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
if (typeof httpRes.end === 'function') {
|
|
@@ -326,7 +326,10 @@ export class MoroHttpServer {
|
|
|
326
326
|
})
|
|
327
327
|
);
|
|
328
328
|
} else {
|
|
329
|
-
|
|
329
|
+
this.logger.error(
|
|
330
|
+
'Cannot send error response - end() method missing',
|
|
331
|
+
'RequestHandler'
|
|
332
|
+
);
|
|
330
333
|
}
|
|
331
334
|
}
|
|
332
335
|
}
|
|
@@ -22,16 +22,24 @@ export const contextFilter = (allowedContexts: string[]): LogFilter => ({
|
|
|
22
22
|
// Rate limiting filter
|
|
23
23
|
export const rateLimitFilter = (maxPerSecond: number): LogFilter => {
|
|
24
24
|
const timestamps: number[] = [];
|
|
25
|
+
let lastCleanup = 0;
|
|
25
26
|
|
|
26
27
|
return {
|
|
27
28
|
name: 'rate-limit',
|
|
28
29
|
filter: (entry: LogEntry) => {
|
|
29
30
|
const now = Date.now();
|
|
30
|
-
const oneSecondAgo = now - 1000;
|
|
31
31
|
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
// Batch cleanup for better performance and thread safety
|
|
33
|
+
if (now - lastCleanup > 1000) {
|
|
34
|
+
const cutoff = now - 1000;
|
|
35
|
+
let keepIndex = 0;
|
|
36
|
+
for (let i = 0; i < timestamps.length; i++) {
|
|
37
|
+
if (timestamps[i] >= cutoff) {
|
|
38
|
+
timestamps[keepIndex++] = timestamps[i];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
timestamps.length = keepIndex;
|
|
42
|
+
lastCleanup = now;
|
|
35
43
|
}
|
|
36
44
|
|
|
37
45
|
// Check rate limit
|