@morojs/moro 1.5.17 → 1.6.1
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/README.md +48 -65
- package/dist/core/auth/morojs-adapter.js +12 -16
- package/dist/core/auth/morojs-adapter.js.map +1 -1
- package/dist/core/config/file-loader.d.ts +5 -0
- package/dist/core/config/file-loader.js +171 -0
- package/dist/core/config/file-loader.js.map +1 -1
- package/dist/core/config/index.d.ts +10 -39
- package/dist/core/config/index.js +29 -66
- package/dist/core/config/index.js.map +1 -1
- package/dist/core/config/loader.d.ts +7 -0
- package/dist/core/config/loader.js +269 -0
- package/dist/core/config/loader.js.map +1 -0
- package/dist/core/config/schema.js +31 -41
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/config/utils.d.ts +2 -9
- package/dist/core/config/utils.js +32 -19
- package/dist/core/config/utils.js.map +1 -1
- package/dist/core/config/validation.d.ts +17 -0
- package/dist/core/config/validation.js +131 -0
- package/dist/core/config/validation.js.map +1 -0
- package/dist/core/database/adapters/mongodb.d.ts +0 -10
- package/dist/core/database/adapters/mongodb.js +2 -23
- package/dist/core/database/adapters/mongodb.js.map +1 -1
- package/dist/core/database/adapters/mysql.d.ts +0 -11
- package/dist/core/database/adapters/mysql.js +0 -1
- package/dist/core/database/adapters/mysql.js.map +1 -1
- package/dist/core/database/adapters/postgresql.d.ts +1 -9
- package/dist/core/database/adapters/postgresql.js +1 -1
- package/dist/core/database/adapters/postgresql.js.map +1 -1
- package/dist/core/database/adapters/redis.d.ts +0 -9
- package/dist/core/database/adapters/redis.js +4 -14
- package/dist/core/database/adapters/redis.js.map +1 -1
- package/dist/core/framework.d.ts +7 -6
- package/dist/core/framework.js +16 -131
- package/dist/core/framework.js.map +1 -1
- package/dist/core/http/http-server.d.ts +0 -12
- package/dist/core/http/http-server.js +23 -151
- package/dist/core/http/http-server.js.map +1 -1
- package/dist/core/http/router.d.ts +0 -12
- package/dist/core/http/router.js +36 -114
- package/dist/core/http/router.js.map +1 -1
- package/dist/core/logger/filters.js +4 -12
- package/dist/core/logger/filters.js.map +1 -1
- package/dist/core/logger/index.d.ts +1 -1
- package/dist/core/logger/index.js +1 -2
- package/dist/core/logger/index.js.map +1 -1
- package/dist/core/logger/logger.d.ts +13 -29
- package/dist/core/logger/logger.js +203 -380
- package/dist/core/logger/logger.js.map +1 -1
- package/dist/core/logger/outputs.js +2 -0
- package/dist/core/logger/outputs.js.map +1 -1
- package/dist/core/middleware/built-in/auth.js +17 -88
- package/dist/core/middleware/built-in/auth.js.map +1 -1
- package/dist/core/middleware/built-in/cache.js +1 -3
- package/dist/core/middleware/built-in/cache.js.map +1 -1
- package/dist/core/middleware/built-in/index.d.ts +0 -1
- package/dist/core/middleware/built-in/index.js +1 -6
- package/dist/core/middleware/built-in/index.js.map +1 -1
- package/dist/core/middleware/built-in/request-logger.js +2 -3
- package/dist/core/middleware/built-in/request-logger.js.map +1 -1
- package/dist/core/middleware/built-in/sse.js +7 -9
- package/dist/core/middleware/built-in/sse.js.map +1 -1
- package/dist/core/modules/auto-discovery.d.ts +0 -17
- package/dist/core/modules/auto-discovery.js +12 -367
- package/dist/core/modules/auto-discovery.js.map +1 -1
- package/dist/core/modules/modules.js +2 -12
- package/dist/core/modules/modules.js.map +1 -1
- package/dist/core/networking/adapters/ws-adapter.d.ts +1 -1
- package/dist/core/networking/adapters/ws-adapter.js +2 -2
- package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
- package/dist/core/networking/service-discovery.js +7 -7
- package/dist/core/networking/service-discovery.js.map +1 -1
- package/dist/core/routing/index.d.ts +0 -20
- package/dist/core/routing/index.js +13 -178
- package/dist/core/routing/index.js.map +1 -1
- package/dist/core/runtime/node-adapter.js +6 -12
- package/dist/core/runtime/node-adapter.js.map +1 -1
- package/dist/moro.d.ts +0 -48
- package/dist/moro.js +148 -456
- package/dist/moro.js.map +1 -1
- package/dist/types/config.d.ts +2 -58
- package/dist/types/core.d.ts +40 -34
- package/dist/types/http.d.ts +1 -16
- package/dist/types/logger.d.ts +0 -7
- package/dist/types/module.d.ts +0 -11
- package/package.json +2 -2
- package/src/core/auth/morojs-adapter.ts +13 -18
- package/src/core/config/file-loader.ts +233 -0
- package/src/core/config/index.ts +32 -77
- package/src/core/config/loader.ts +633 -0
- package/src/core/config/schema.ts +31 -41
- package/src/core/config/utils.ts +29 -22
- package/src/core/config/validation.ts +140 -0
- package/src/core/database/README.md +16 -26
- package/src/core/database/adapters/mongodb.ts +2 -30
- package/src/core/database/adapters/mysql.ts +0 -14
- package/src/core/database/adapters/postgresql.ts +2 -12
- package/src/core/database/adapters/redis.ts +4 -27
- package/src/core/framework.ts +23 -163
- package/src/core/http/http-server.ts +36 -176
- package/src/core/http/router.ts +38 -127
- package/src/core/logger/filters.ts +4 -12
- package/src/core/logger/index.ts +0 -1
- package/src/core/logger/logger.ts +216 -427
- package/src/core/logger/outputs.ts +2 -0
- package/src/core/middleware/built-in/auth.ts +17 -98
- package/src/core/middleware/built-in/cache.ts +1 -3
- package/src/core/middleware/built-in/index.ts +0 -8
- package/src/core/middleware/built-in/request-logger.ts +1 -3
- package/src/core/middleware/built-in/sse.ts +7 -9
- package/src/core/modules/auto-discovery.ts +13 -476
- package/src/core/modules/modules.ts +9 -20
- package/src/core/networking/adapters/ws-adapter.ts +5 -2
- package/src/core/networking/service-discovery.ts +7 -6
- package/src/core/routing/index.ts +14 -198
- package/src/core/runtime/node-adapter.ts +6 -12
- package/src/moro.ts +166 -554
- package/src/types/config.ts +2 -59
- package/src/types/core.ts +45 -47
- package/src/types/http.ts +1 -23
- package/src/types/logger.ts +0 -9
- package/src/types/module.ts +0 -12
- package/dist/core/config/config-manager.d.ts +0 -44
- package/dist/core/config/config-manager.js +0 -114
- package/dist/core/config/config-manager.js.map +0 -1
- package/dist/core/config/config-sources.d.ts +0 -21
- package/dist/core/config/config-sources.js +0 -502
- package/dist/core/config/config-sources.js.map +0 -1
- package/dist/core/config/config-validator.d.ts +0 -21
- package/dist/core/config/config-validator.js +0 -765
- package/dist/core/config/config-validator.js.map +0 -1
- package/dist/core/middleware/built-in/jwt-helpers.d.ts +0 -118
- package/dist/core/middleware/built-in/jwt-helpers.js +0 -221
- package/dist/core/middleware/built-in/jwt-helpers.js.map +0 -1
- package/src/core/config/config-manager.ts +0 -133
- package/src/core/config/config-sources.ts +0 -596
- package/src/core/config/config-validator.ts +0 -1078
- package/src/core/middleware/built-in/jwt-helpers.ts +0 -240
package/src/core/http/router.ts
CHANGED
|
@@ -12,14 +12,6 @@ export class Router {
|
|
|
12
12
|
private routes: RouteDefinition[] = [];
|
|
13
13
|
private logger = createFrameworkLogger('Router');
|
|
14
14
|
|
|
15
|
-
// Performance optimizations - O(1) static route lookup
|
|
16
|
-
private staticRoutes = new Map<string, RouteDefinition>(); // "GET:/api/users" -> route
|
|
17
|
-
private dynamicRoutes: RouteDefinition[] = []; // Routes with parameters
|
|
18
|
-
|
|
19
|
-
// Object pooling for parameters to reduce GC pressure
|
|
20
|
-
private paramObjectPool: Record<string, string>[] = [];
|
|
21
|
-
private readonly maxPoolSize = 50;
|
|
22
|
-
|
|
23
15
|
get(path: string, ...handlers: (Middleware | HttpHandler)[]): void {
|
|
24
16
|
this.addRoute('GET', path, handlers);
|
|
25
17
|
}
|
|
@@ -45,37 +37,14 @@ export class Router {
|
|
|
45
37
|
const handler = handlers.pop() as HttpHandler;
|
|
46
38
|
const middleware = handlers as Middleware[];
|
|
47
39
|
|
|
48
|
-
|
|
40
|
+
this.routes.push({
|
|
49
41
|
method,
|
|
50
42
|
path,
|
|
51
43
|
pattern,
|
|
52
44
|
paramNames,
|
|
53
45
|
handler,
|
|
54
46
|
middleware,
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// Add to routes array (maintain compatibility)
|
|
58
|
-
this.routes.push(route);
|
|
59
|
-
|
|
60
|
-
// Performance optimization: separate static and dynamic routes
|
|
61
|
-
const isStatic = !path.includes(':') && !path.includes('*');
|
|
62
|
-
if (isStatic && middleware.length === 0) {
|
|
63
|
-
// Static route with no middleware - use O(1) lookup
|
|
64
|
-
const routeKey = `${method}:${path}`;
|
|
65
|
-
this.staticRoutes.set(routeKey, route);
|
|
66
|
-
this.logger.debug(`Added static route: ${routeKey}`, 'FastRoute');
|
|
67
|
-
} else {
|
|
68
|
-
// Dynamic route or has middleware - needs regex matching
|
|
69
|
-
this.dynamicRoutes.push(route);
|
|
70
|
-
this.logger.debug(`Added dynamic route: ${method} ${path}`, 'DynamicRoute');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Initialize object pool on first route
|
|
74
|
-
if (this.paramObjectPool.length === 0) {
|
|
75
|
-
for (let i = 0; i < this.maxPoolSize; i++) {
|
|
76
|
-
this.paramObjectPool.push({});
|
|
77
|
-
}
|
|
78
|
-
}
|
|
47
|
+
});
|
|
79
48
|
}
|
|
80
49
|
|
|
81
50
|
private pathToRegex(path: string): { pattern: RegExp; paramNames: string[] } {
|
|
@@ -108,30 +77,10 @@ export class Router {
|
|
|
108
77
|
'Processing'
|
|
109
78
|
);
|
|
110
79
|
|
|
111
|
-
|
|
112
|
-
const routeKey = `${req.method}:${path}`;
|
|
113
|
-
const staticRoute = this.staticRoutes.get(routeKey);
|
|
114
|
-
|
|
115
|
-
if (staticRoute) {
|
|
116
|
-
this.logger.debug(`Fast route match: ${routeKey}`, 'FastRoute');
|
|
117
|
-
|
|
118
|
-
// Static route with no middleware - execute handler directly
|
|
119
|
-
req.params = {}; // No params for static routes
|
|
120
|
-
const result = await staticRoute.handler(req, res);
|
|
121
|
-
|
|
122
|
-
// If handler returns data and response hasn't been sent, send it
|
|
123
|
-
if (result !== undefined && result !== null && !res.headersSent) {
|
|
124
|
-
res.json(result);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Fallback: Dynamic route matching (with middleware support)
|
|
131
|
-
const route = this.dynamicRoutes.find(r => r.method === req.method && r.pattern.test(path));
|
|
80
|
+
const route = this.routes.find(r => r.method === req.method && r.pattern.test(path));
|
|
132
81
|
|
|
133
82
|
this.logger.debug(
|
|
134
|
-
`Found
|
|
83
|
+
`Found route: ${!!route}${route ? ` ${route.method} ${route.path}` : ' none'}`,
|
|
135
84
|
'RouteMatch'
|
|
136
85
|
);
|
|
137
86
|
|
|
@@ -139,92 +88,54 @@ export class Router {
|
|
|
139
88
|
return false; // Route not found
|
|
140
89
|
}
|
|
141
90
|
|
|
142
|
-
// Extract path parameters
|
|
91
|
+
// Extract path parameters
|
|
143
92
|
const matches = path.match(route.pattern);
|
|
144
93
|
if (matches) {
|
|
145
|
-
req.params =
|
|
94
|
+
req.params = {};
|
|
146
95
|
route.paramNames.forEach((name, index) => {
|
|
147
96
|
req.params[name] = matches[index + 1];
|
|
148
97
|
});
|
|
149
98
|
}
|
|
150
99
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
.catch(reject);
|
|
172
|
-
}
|
|
173
|
-
} catch (error) {
|
|
174
|
-
reject(error);
|
|
100
|
+
// Execute middleware
|
|
101
|
+
for (const mw of route.middleware) {
|
|
102
|
+
await new Promise<void>((resolve, reject) => {
|
|
103
|
+
let nextCalled = false;
|
|
104
|
+
|
|
105
|
+
const next = () => {
|
|
106
|
+
if (nextCalled) return;
|
|
107
|
+
nextCalled = true;
|
|
108
|
+
resolve();
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const result = mw(req, res, next);
|
|
113
|
+
|
|
114
|
+
if (result instanceof Promise) {
|
|
115
|
+
result
|
|
116
|
+
.then(() => {
|
|
117
|
+
if (!nextCalled) next();
|
|
118
|
+
})
|
|
119
|
+
.catch(reject);
|
|
175
120
|
}
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Execute handler
|
|
182
|
-
const result = await route.handler(req, res);
|
|
183
|
-
|
|
184
|
-
// If handler returns data and response hasn't been sent, send it
|
|
185
|
-
if (result !== undefined && result !== null && !res.headersSent) {
|
|
186
|
-
res.json(result);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return true;
|
|
190
|
-
} finally {
|
|
191
|
-
// Release parameter object back to pool
|
|
192
|
-
if (req.params && matches) {
|
|
193
|
-
this.releaseParamObject(req.params);
|
|
194
|
-
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
reject(error);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
195
125
|
}
|
|
196
|
-
}
|
|
197
126
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
127
|
+
// Execute handler
|
|
128
|
+
const result = await route.handler(req, res);
|
|
201
129
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (obj) {
|
|
206
|
-
// Clear the object
|
|
207
|
-
for (const key in obj) {
|
|
208
|
-
delete obj[key];
|
|
209
|
-
}
|
|
210
|
-
return obj;
|
|
130
|
+
// If handler returns data and response hasn't been sent, send it
|
|
131
|
+
if (result !== undefined && result !== null && !res.headersSent) {
|
|
132
|
+
res.json(result);
|
|
211
133
|
}
|
|
212
|
-
return {};
|
|
213
|
-
}
|
|
214
134
|
|
|
215
|
-
|
|
216
|
-
if (this.paramObjectPool.length < this.maxPoolSize) {
|
|
217
|
-
this.paramObjectPool.push(obj);
|
|
218
|
-
}
|
|
135
|
+
return true;
|
|
219
136
|
}
|
|
220
137
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
return {
|
|
224
|
-
totalRoutes: this.routes.length,
|
|
225
|
-
staticRoutes: this.staticRoutes.size,
|
|
226
|
-
dynamicRoutes: this.dynamicRoutes.length,
|
|
227
|
-
paramObjectPoolSize: this.paramObjectPool.length,
|
|
228
|
-
};
|
|
138
|
+
getRoutes(): RouteDefinition[] {
|
|
139
|
+
return [...this.routes];
|
|
229
140
|
}
|
|
230
141
|
}
|
|
@@ -22,24 +22,16 @@ 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;
|
|
26
25
|
|
|
27
26
|
return {
|
|
28
27
|
name: 'rate-limit',
|
|
29
28
|
filter: (entry: LogEntry) => {
|
|
30
29
|
const now = Date.now();
|
|
30
|
+
const oneSecondAgo = now - 1000;
|
|
31
31
|
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
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;
|
|
32
|
+
// Remove old timestamps
|
|
33
|
+
while (timestamps.length > 0 && timestamps[0] < oneSecondAgo) {
|
|
34
|
+
timestamps.shift();
|
|
43
35
|
}
|
|
44
36
|
|
|
45
37
|
// Check rate limit
|