@morojs/moro 1.5.2 → 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.
Files changed (36) hide show
  1. package/dist/core/auth/morojs-adapter.js +23 -12
  2. package/dist/core/auth/morojs-adapter.js.map +1 -1
  3. package/dist/core/http/http-server.js +12 -8
  4. package/dist/core/http/http-server.js.map +1 -1
  5. package/dist/core/logger/filters.js +12 -4
  6. package/dist/core/logger/filters.js.map +1 -1
  7. package/dist/core/logger/logger.d.ts +44 -0
  8. package/dist/core/logger/logger.js +550 -60
  9. package/dist/core/logger/logger.js.map +1 -1
  10. package/dist/core/middleware/built-in/request-logger.js +4 -2
  11. package/dist/core/middleware/built-in/request-logger.js.map +1 -1
  12. package/dist/core/modules/auto-discovery.d.ts +1 -0
  13. package/dist/core/modules/auto-discovery.js +9 -5
  14. package/dist/core/modules/auto-discovery.js.map +1 -1
  15. package/dist/core/modules/modules.d.ts +1 -0
  16. package/dist/core/modules/modules.js +8 -2
  17. package/dist/core/modules/modules.js.map +1 -1
  18. package/dist/core/networking/adapters/ws-adapter.d.ts +1 -0
  19. package/dist/core/networking/adapters/ws-adapter.js +3 -1
  20. package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
  21. package/dist/core/networking/service-discovery.d.ts +1 -0
  22. package/dist/core/networking/service-discovery.js +23 -11
  23. package/dist/core/networking/service-discovery.js.map +1 -1
  24. package/dist/types/logger.d.ts +3 -0
  25. package/package.json +6 -2
  26. package/src/core/auth/morojs-adapter.ts +25 -12
  27. package/src/core/database/README.md +26 -16
  28. package/src/core/http/http-server.ts +15 -12
  29. package/src/core/logger/filters.ts +12 -4
  30. package/src/core/logger/logger.ts +616 -63
  31. package/src/core/middleware/built-in/request-logger.ts +6 -2
  32. package/src/core/modules/auto-discovery.ts +13 -5
  33. package/src/core/modules/modules.ts +9 -5
  34. package/src/core/networking/adapters/ws-adapter.ts +3 -1
  35. package/src/core/networking/service-discovery.ts +23 -9
  36. 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
- console.log(`[MoroJS Auth] ${code}:`, ...message);
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
- console.error('[MoroJS Auth] Error:', error);
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
- console.error('[MoroJS Auth] Session error:', error);
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
- console.log('🏭 createAuthMiddleware called - creating middleware function');
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
- console.log('🔧 Installing Auth.js middleware...');
329
- console.log('📦 App object received:', typeof app, app.constructor.name);
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
- console.error('Could not access MoroJS hooks system');
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
- console.log('🔒 Native adapter hook starting...');
358
+ logger.debug('Native adapter hook starting', 'AuthAdapter');
348
359
  const req = context.request;
349
- console.log('📝 Request path:', req.path || req.url);
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
- console.log('Native adapter hook completed successfully');
397
+ logger.debug('Native adapter hook completed successfully', 'AuthAdapter');
387
398
  } catch (error) {
388
- console.error('Error in native adapter hook:', error);
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
- console.log('Auth.js middleware installed successfully!');
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 (tx) => {
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
- console.log('🚨 MoroJS Request Error Details:');
285
- console.log('📍 Error type:', typeof error);
286
- console.log('📍 Error message:', error instanceof Error ? error.message : String(error));
287
- console.log('📍 Error stack:', error instanceof Error ? error.stack : 'No stack trace');
288
- console.log('📍 Request path:', req.url);
289
- console.log('📍 Request method:', req.method);
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
- console.error(
314
- '❌ Response object is not a proper ServerResponse:',
315
- typeof httpRes,
316
- Object.keys(httpRes)
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
- console.error('❌ Cannot send error response - end() method missing');
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
- // Remove old timestamps
33
- while (timestamps.length > 0 && timestamps[0] < oneSecondAgo) {
34
- timestamps.shift();
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