@morojs/moro 1.0.0
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 +233 -0
- package/dist/core/config/index.d.ts +19 -0
- package/dist/core/config/index.js +59 -0
- package/dist/core/config/index.js.map +1 -0
- package/dist/core/config/loader.d.ts +6 -0
- package/dist/core/config/loader.js +288 -0
- package/dist/core/config/loader.js.map +1 -0
- package/dist/core/config/schema.d.ts +335 -0
- package/dist/core/config/schema.js +286 -0
- package/dist/core/config/schema.js.map +1 -0
- package/dist/core/config/utils.d.ts +50 -0
- package/dist/core/config/utils.js +185 -0
- package/dist/core/config/utils.js.map +1 -0
- package/dist/core/database/adapters/drizzle.d.ts +29 -0
- package/dist/core/database/adapters/drizzle.js +366 -0
- package/dist/core/database/adapters/drizzle.js.map +1 -0
- package/dist/core/database/adapters/index.d.ts +8 -0
- package/dist/core/database/adapters/index.js +48 -0
- package/dist/core/database/adapters/index.js.map +1 -0
- package/dist/core/database/adapters/mongodb.d.ts +35 -0
- package/dist/core/database/adapters/mongodb.js +215 -0
- package/dist/core/database/adapters/mongodb.js.map +1 -0
- package/dist/core/database/adapters/mysql.d.ts +23 -0
- package/dist/core/database/adapters/mysql.js +149 -0
- package/dist/core/database/adapters/mysql.js.map +1 -0
- package/dist/core/database/adapters/postgresql.d.ts +24 -0
- package/dist/core/database/adapters/postgresql.js +160 -0
- package/dist/core/database/adapters/postgresql.js.map +1 -0
- package/dist/core/database/adapters/redis.d.ts +50 -0
- package/dist/core/database/adapters/redis.js +266 -0
- package/dist/core/database/adapters/redis.js.map +1 -0
- package/dist/core/database/adapters/sqlite.d.ts +23 -0
- package/dist/core/database/adapters/sqlite.js +194 -0
- package/dist/core/database/adapters/sqlite.js.map +1 -0
- package/dist/core/database/index.d.ts +2 -0
- package/dist/core/database/index.js +20 -0
- package/dist/core/database/index.js.map +1 -0
- package/dist/core/docs/index.d.ts +63 -0
- package/dist/core/docs/index.js +170 -0
- package/dist/core/docs/index.js.map +1 -0
- package/dist/core/docs/openapi-generator.d.ts +124 -0
- package/dist/core/docs/openapi-generator.js +413 -0
- package/dist/core/docs/openapi-generator.js.map +1 -0
- package/dist/core/docs/simple-docs.d.ts +21 -0
- package/dist/core/docs/simple-docs.js +268 -0
- package/dist/core/docs/simple-docs.js.map +1 -0
- package/dist/core/docs/swagger-ui.d.ts +28 -0
- package/dist/core/docs/swagger-ui.js +317 -0
- package/dist/core/docs/swagger-ui.js.map +1 -0
- package/dist/core/docs/zod-to-openapi.d.ts +29 -0
- package/dist/core/docs/zod-to-openapi.js +414 -0
- package/dist/core/docs/zod-to-openapi.js.map +1 -0
- package/dist/core/events/event-bus.d.ts +27 -0
- package/dist/core/events/event-bus.js +193 -0
- package/dist/core/events/event-bus.js.map +1 -0
- package/dist/core/events/index.d.ts +2 -0
- package/dist/core/events/index.js +7 -0
- package/dist/core/events/index.js.map +1 -0
- package/dist/core/framework.d.ts +57 -0
- package/dist/core/framework.js +432 -0
- package/dist/core/framework.js.map +1 -0
- package/dist/core/http/http-server.d.ts +114 -0
- package/dist/core/http/http-server.js +1154 -0
- package/dist/core/http/http-server.js.map +1 -0
- package/dist/core/http/index.d.ts +3 -0
- package/dist/core/http/index.js +10 -0
- package/dist/core/http/index.js.map +1 -0
- package/dist/core/http/router.d.ts +14 -0
- package/dist/core/http/router.js +113 -0
- package/dist/core/http/router.js.map +1 -0
- package/dist/core/logger/filters.d.ts +9 -0
- package/dist/core/logger/filters.js +134 -0
- package/dist/core/logger/filters.js.map +1 -0
- package/dist/core/logger/index.d.ts +3 -0
- package/dist/core/logger/index.js +26 -0
- package/dist/core/logger/index.js.map +1 -0
- package/dist/core/logger/logger.d.ts +49 -0
- package/dist/core/logger/logger.js +332 -0
- package/dist/core/logger/logger.js.map +1 -0
- package/dist/core/logger/outputs.d.ts +42 -0
- package/dist/core/logger/outputs.js +110 -0
- package/dist/core/logger/outputs.js.map +1 -0
- package/dist/core/middleware/built-in/adapters/cache/file.d.ts +15 -0
- package/dist/core/middleware/built-in/adapters/cache/file.js +128 -0
- package/dist/core/middleware/built-in/adapters/cache/file.js.map +1 -0
- package/dist/core/middleware/built-in/adapters/cache/index.d.ts +5 -0
- package/dist/core/middleware/built-in/adapters/cache/index.js +28 -0
- package/dist/core/middleware/built-in/adapters/cache/index.js.map +1 -0
- package/dist/core/middleware/built-in/adapters/cache/memory.d.ts +11 -0
- package/dist/core/middleware/built-in/adapters/cache/memory.js +65 -0
- package/dist/core/middleware/built-in/adapters/cache/memory.js.map +1 -0
- package/dist/core/middleware/built-in/adapters/cache/redis.d.ts +17 -0
- package/dist/core/middleware/built-in/adapters/cache/redis.js +91 -0
- package/dist/core/middleware/built-in/adapters/cache/redis.js.map +1 -0
- package/dist/core/middleware/built-in/adapters/cdn/azure.d.ts +21 -0
- package/dist/core/middleware/built-in/adapters/cdn/azure.js +40 -0
- package/dist/core/middleware/built-in/adapters/cdn/azure.js.map +1 -0
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.d.ts +14 -0
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js +77 -0
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js.map +1 -0
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.d.ts +15 -0
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js +73 -0
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js.map +1 -0
- package/dist/core/middleware/built-in/adapters/cdn/index.d.ts +5 -0
- package/dist/core/middleware/built-in/adapters/cdn/index.js +28 -0
- package/dist/core/middleware/built-in/adapters/cdn/index.js.map +1 -0
- package/dist/core/middleware/built-in/adapters/index.d.ts +4 -0
- package/dist/core/middleware/built-in/adapters/index.js +26 -0
- package/dist/core/middleware/built-in/adapters/index.js.map +1 -0
- package/dist/core/middleware/built-in/auth.d.ts +2 -0
- package/dist/core/middleware/built-in/auth.js +38 -0
- package/dist/core/middleware/built-in/auth.js.map +1 -0
- package/dist/core/middleware/built-in/cache.d.ts +3 -0
- package/dist/core/middleware/built-in/cache.js +188 -0
- package/dist/core/middleware/built-in/cache.js.map +1 -0
- package/dist/core/middleware/built-in/cdn.d.ts +3 -0
- package/dist/core/middleware/built-in/cdn.js +115 -0
- package/dist/core/middleware/built-in/cdn.js.map +1 -0
- package/dist/core/middleware/built-in/cookie.d.ts +14 -0
- package/dist/core/middleware/built-in/cookie.js +68 -0
- package/dist/core/middleware/built-in/cookie.js.map +1 -0
- package/dist/core/middleware/built-in/cors.d.ts +2 -0
- package/dist/core/middleware/built-in/cors.js +29 -0
- package/dist/core/middleware/built-in/cors.js.map +1 -0
- package/dist/core/middleware/built-in/csp.d.ts +22 -0
- package/dist/core/middleware/built-in/csp.js +74 -0
- package/dist/core/middleware/built-in/csp.js.map +1 -0
- package/dist/core/middleware/built-in/csrf.d.ts +9 -0
- package/dist/core/middleware/built-in/csrf.js +66 -0
- package/dist/core/middleware/built-in/csrf.js.map +1 -0
- package/dist/core/middleware/built-in/error-tracker.d.ts +1 -0
- package/dist/core/middleware/built-in/error-tracker.js +19 -0
- package/dist/core/middleware/built-in/error-tracker.js.map +1 -0
- package/dist/core/middleware/built-in/index.d.ts +70 -0
- package/dist/core/middleware/built-in/index.js +70 -0
- package/dist/core/middleware/built-in/index.js.map +1 -0
- package/dist/core/middleware/built-in/performance-monitor.d.ts +1 -0
- package/dist/core/middleware/built-in/performance-monitor.js +22 -0
- package/dist/core/middleware/built-in/performance-monitor.js.map +1 -0
- package/dist/core/middleware/built-in/rate-limit.d.ts +6 -0
- package/dist/core/middleware/built-in/rate-limit.js +47 -0
- package/dist/core/middleware/built-in/rate-limit.js.map +1 -0
- package/dist/core/middleware/built-in/request-logger.d.ts +1 -0
- package/dist/core/middleware/built-in/request-logger.js +15 -0
- package/dist/core/middleware/built-in/request-logger.js.map +1 -0
- package/dist/core/middleware/built-in/session.d.ts +41 -0
- package/dist/core/middleware/built-in/session.js +209 -0
- package/dist/core/middleware/built-in/session.js.map +1 -0
- package/dist/core/middleware/built-in/sse.d.ts +6 -0
- package/dist/core/middleware/built-in/sse.js +73 -0
- package/dist/core/middleware/built-in/sse.js.map +1 -0
- package/dist/core/middleware/built-in/validation.d.ts +2 -0
- package/dist/core/middleware/built-in/validation.js +31 -0
- package/dist/core/middleware/built-in/validation.js.map +1 -0
- package/dist/core/middleware/index.d.ts +21 -0
- package/dist/core/middleware/index.js +152 -0
- package/dist/core/middleware/index.js.map +1 -0
- package/dist/core/modules/auto-discovery.d.ts +27 -0
- package/dist/core/modules/auto-discovery.js +255 -0
- package/dist/core/modules/auto-discovery.js.map +1 -0
- package/dist/core/modules/index.d.ts +2 -0
- package/dist/core/modules/index.js +11 -0
- package/dist/core/modules/index.js.map +1 -0
- package/dist/core/modules/modules.d.ts +10 -0
- package/dist/core/modules/modules.js +137 -0
- package/dist/core/modules/modules.js.map +1 -0
- package/dist/core/networking/index.d.ts +2 -0
- package/dist/core/networking/index.js +9 -0
- package/dist/core/networking/index.js.map +1 -0
- package/dist/core/networking/service-discovery.d.ts +38 -0
- package/dist/core/networking/service-discovery.js +233 -0
- package/dist/core/networking/service-discovery.js.map +1 -0
- package/dist/core/networking/websocket-manager.d.ts +27 -0
- package/dist/core/networking/websocket-manager.js +211 -0
- package/dist/core/networking/websocket-manager.js.map +1 -0
- package/dist/core/routing/app-integration.d.ts +42 -0
- package/dist/core/routing/app-integration.js +152 -0
- package/dist/core/routing/app-integration.js.map +1 -0
- package/dist/core/routing/index.d.ts +106 -0
- package/dist/core/routing/index.js +343 -0
- package/dist/core/routing/index.js.map +1 -0
- package/dist/core/runtime/aws-lambda-adapter.d.ts +43 -0
- package/dist/core/runtime/aws-lambda-adapter.js +108 -0
- package/dist/core/runtime/aws-lambda-adapter.js.map +1 -0
- package/dist/core/runtime/base-adapter.d.ts +16 -0
- package/dist/core/runtime/base-adapter.js +105 -0
- package/dist/core/runtime/base-adapter.js.map +1 -0
- package/dist/core/runtime/cloudflare-workers-adapter.d.ts +18 -0
- package/dist/core/runtime/cloudflare-workers-adapter.js +131 -0
- package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -0
- package/dist/core/runtime/index.d.ts +14 -0
- package/dist/core/runtime/index.js +56 -0
- package/dist/core/runtime/index.js.map +1 -0
- package/dist/core/runtime/node-adapter.d.ts +15 -0
- package/dist/core/runtime/node-adapter.js +204 -0
- package/dist/core/runtime/node-adapter.js.map +1 -0
- package/dist/core/runtime/vercel-edge-adapter.d.ts +10 -0
- package/dist/core/runtime/vercel-edge-adapter.js +106 -0
- package/dist/core/runtime/vercel-edge-adapter.js.map +1 -0
- package/dist/core/utilities/circuit-breaker.d.ts +14 -0
- package/dist/core/utilities/circuit-breaker.js +42 -0
- package/dist/core/utilities/circuit-breaker.js.map +1 -0
- package/dist/core/utilities/container.d.ts +116 -0
- package/dist/core/utilities/container.js +529 -0
- package/dist/core/utilities/container.js.map +1 -0
- package/dist/core/utilities/hooks.d.ts +24 -0
- package/dist/core/utilities/hooks.js +131 -0
- package/dist/core/utilities/hooks.js.map +1 -0
- package/dist/core/utilities/index.d.ts +4 -0
- package/dist/core/utilities/index.js +22 -0
- package/dist/core/utilities/index.js.map +1 -0
- package/dist/core/validation/index.d.ts +30 -0
- package/dist/core/validation/index.js +144 -0
- package/dist/core/validation/index.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/moro.d.ts +82 -0
- package/dist/moro.js +679 -0
- package/dist/moro.js.map +1 -0
- package/dist/types/cache.d.ts +34 -0
- package/dist/types/cache.js +3 -0
- package/dist/types/cache.js.map +1 -0
- package/dist/types/cdn.d.ts +19 -0
- package/dist/types/cdn.js +3 -0
- package/dist/types/cdn.js.map +1 -0
- package/dist/types/core.d.ts +13 -0
- package/dist/types/core.js +3 -0
- package/dist/types/core.js.map +1 -0
- package/dist/types/database.d.ts +29 -0
- package/dist/types/database.js +3 -0
- package/dist/types/database.js.map +1 -0
- package/dist/types/discovery.d.ts +6 -0
- package/dist/types/discovery.js +3 -0
- package/dist/types/discovery.js.map +1 -0
- package/dist/types/events.d.ts +116 -0
- package/dist/types/events.js +3 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/hooks.d.ts +38 -0
- package/dist/types/hooks.js +3 -0
- package/dist/types/hooks.js.map +1 -0
- package/dist/types/http.d.ts +51 -0
- package/dist/types/http.js +3 -0
- package/dist/types/http.js.map +1 -0
- package/dist/types/logger.d.ts +77 -0
- package/dist/types/logger.js +3 -0
- package/dist/types/logger.js.map +1 -0
- package/dist/types/module.d.ts +91 -0
- package/dist/types/module.js +3 -0
- package/dist/types/module.js.map +1 -0
- package/dist/types/runtime.d.ts +48 -0
- package/dist/types/runtime.js +3 -0
- package/dist/types/runtime.js.map +1 -0
- package/dist/types/session.d.ts +66 -0
- package/dist/types/session.js +3 -0
- package/dist/types/session.js.map +1 -0
- package/package.json +176 -0
- package/src/core/config/index.ts +47 -0
- package/src/core/config/loader.ts +366 -0
- package/src/core/config/schema.ts +346 -0
- package/src/core/config/utils.ts +220 -0
- package/src/core/database/README.md +228 -0
- package/src/core/database/adapters/drizzle.ts +425 -0
- package/src/core/database/adapters/index.ts +45 -0
- package/src/core/database/adapters/mongodb.ts +292 -0
- package/src/core/database/adapters/mysql.ts +217 -0
- package/src/core/database/adapters/postgresql.ts +211 -0
- package/src/core/database/adapters/redis.ts +331 -0
- package/src/core/database/adapters/sqlite.ts +255 -0
- package/src/core/database/index.ts +3 -0
- package/src/core/docs/index.ts +245 -0
- package/src/core/docs/openapi-generator.ts +588 -0
- package/src/core/docs/simple-docs.ts +305 -0
- package/src/core/docs/swagger-ui.ts +370 -0
- package/src/core/docs/zod-to-openapi.ts +532 -0
- package/src/core/events/event-bus.ts +249 -0
- package/src/core/events/index.ts +12 -0
- package/src/core/framework.ts +621 -0
- package/src/core/http/http-server.ts +1421 -0
- package/src/core/http/index.ts +11 -0
- package/src/core/http/router.ts +153 -0
- package/src/core/logger/filters.ts +148 -0
- package/src/core/logger/index.ts +20 -0
- package/src/core/logger/logger.ts +434 -0
- package/src/core/logger/outputs.ts +136 -0
- package/src/core/middleware/built-in/adapters/cache/file.ts +106 -0
- package/src/core/middleware/built-in/adapters/cache/index.ts +26 -0
- package/src/core/middleware/built-in/adapters/cache/memory.ts +73 -0
- package/src/core/middleware/built-in/adapters/cache/redis.ts +103 -0
- package/src/core/middleware/built-in/adapters/cdn/azure.ts +68 -0
- package/src/core/middleware/built-in/adapters/cdn/cloudflare.ts +100 -0
- package/src/core/middleware/built-in/adapters/cdn/cloudfront.ts +92 -0
- package/src/core/middleware/built-in/adapters/cdn/index.ts +23 -0
- package/src/core/middleware/built-in/adapters/index.ts +7 -0
- package/src/core/middleware/built-in/auth.ts +39 -0
- package/src/core/middleware/built-in/cache.ts +228 -0
- package/src/core/middleware/built-in/cdn.ts +151 -0
- package/src/core/middleware/built-in/cookie.ts +90 -0
- package/src/core/middleware/built-in/cors.ts +38 -0
- package/src/core/middleware/built-in/csp.ts +107 -0
- package/src/core/middleware/built-in/csrf.ts +87 -0
- package/src/core/middleware/built-in/error-tracker.ts +16 -0
- package/src/core/middleware/built-in/index.ts +57 -0
- package/src/core/middleware/built-in/performance-monitor.ts +25 -0
- package/src/core/middleware/built-in/rate-limit.ts +60 -0
- package/src/core/middleware/built-in/request-logger.ts +14 -0
- package/src/core/middleware/built-in/session.ts +311 -0
- package/src/core/middleware/built-in/sse.ts +91 -0
- package/src/core/middleware/built-in/validation.ts +33 -0
- package/src/core/middleware/index.ts +188 -0
- package/src/core/modules/auto-discovery.ts +265 -0
- package/src/core/modules/index.ts +6 -0
- package/src/core/modules/modules.ts +125 -0
- package/src/core/networking/index.ts +7 -0
- package/src/core/networking/service-discovery.ts +309 -0
- package/src/core/networking/websocket-manager.ts +259 -0
- package/src/core/routing/app-integration.ts +229 -0
- package/src/core/routing/index.ts +519 -0
- package/src/core/runtime/aws-lambda-adapter.ts +157 -0
- package/src/core/runtime/base-adapter.ts +140 -0
- package/src/core/runtime/cloudflare-workers-adapter.ts +166 -0
- package/src/core/runtime/index.ts +74 -0
- package/src/core/runtime/node-adapter.ts +210 -0
- package/src/core/runtime/vercel-edge-adapter.ts +125 -0
- package/src/core/utilities/circuit-breaker.ts +46 -0
- package/src/core/utilities/container.ts +760 -0
- package/src/core/utilities/hooks.ts +148 -0
- package/src/core/utilities/index.ts +16 -0
- package/src/core/validation/index.ts +216 -0
- package/src/index.ts +120 -0
- package/src/moro.ts +842 -0
- package/src/types/cache.ts +38 -0
- package/src/types/cdn.ts +22 -0
- package/src/types/core.ts +17 -0
- package/src/types/database.ts +40 -0
- package/src/types/discovery.ts +7 -0
- package/src/types/events.ts +90 -0
- package/src/types/hooks.ts +47 -0
- package/src/types/http.ts +70 -0
- package/src/types/logger.ts +109 -0
- package/src/types/module.ts +87 -0
- package/src/types/runtime.ts +91 -0
- package/src/types/session.ts +89 -0
- package/tsconfig.json +21 -0
package/dist/moro.js
ADDED
|
@@ -0,0 +1,679 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Moro = void 0;
|
|
37
|
+
exports.createApp = createApp;
|
|
38
|
+
exports.createAppNode = createAppNode;
|
|
39
|
+
exports.createAppEdge = createAppEdge;
|
|
40
|
+
exports.createAppLambda = createAppLambda;
|
|
41
|
+
exports.createAppWorker = createAppWorker;
|
|
42
|
+
// Moro Framework - Modern TypeScript API Framework
|
|
43
|
+
// Built for developers who demand performance, elegance, and zero compromises
|
|
44
|
+
// Event-driven • Modular • Enterprise-ready • Developer-first
|
|
45
|
+
const framework_1 = require("./core/framework");
|
|
46
|
+
const http_1 = require("./core/http");
|
|
47
|
+
const logger_1 = require("./core/logger");
|
|
48
|
+
const app_integration_1 = require("./core/routing/app-integration");
|
|
49
|
+
const docs_1 = require("./core/docs");
|
|
50
|
+
const fs_1 = require("fs");
|
|
51
|
+
const path_1 = require("path");
|
|
52
|
+
const events_1 = require("events");
|
|
53
|
+
// Configuration System Integration
|
|
54
|
+
const config_1 = require("./core/config");
|
|
55
|
+
// Runtime System Integration
|
|
56
|
+
const runtime_1 = require("./core/runtime");
|
|
57
|
+
class Moro extends events_1.EventEmitter {
|
|
58
|
+
constructor(options = {}) {
|
|
59
|
+
super(); // Call EventEmitter constructor
|
|
60
|
+
this.routes = [];
|
|
61
|
+
this.moduleCounter = 0;
|
|
62
|
+
this.loadedModules = new Set();
|
|
63
|
+
this.routeHandlers = {};
|
|
64
|
+
// Application logger
|
|
65
|
+
this.logger = (0, logger_1.createFrameworkLogger)("App");
|
|
66
|
+
// Intelligent routing system
|
|
67
|
+
this.intelligentRouting = new app_integration_1.IntelligentRoutingManager();
|
|
68
|
+
// Documentation system
|
|
69
|
+
this.documentation = new docs_1.AppDocumentationManager();
|
|
70
|
+
// Simple rate limiting for direct routes
|
|
71
|
+
this.rateLimitStore = new Map();
|
|
72
|
+
// Configure logger from environment variables BEFORE config system initialization
|
|
73
|
+
// This ensures the config loading process respects the log level
|
|
74
|
+
const envLogLevel = process.env.LOG_LEVEL || process.env.MORO_LOG_LEVEL;
|
|
75
|
+
if (envLogLevel) {
|
|
76
|
+
(0, logger_1.applyLoggingConfiguration)({ level: envLogLevel }, undefined);
|
|
77
|
+
}
|
|
78
|
+
// Initialize configuration system
|
|
79
|
+
this.config = (0, config_1.initializeConfig)();
|
|
80
|
+
// Apply additional logging configuration from createApp options (takes precedence)
|
|
81
|
+
if (options.logger !== undefined) {
|
|
82
|
+
(0, logger_1.applyLoggingConfiguration)(undefined, options.logger);
|
|
83
|
+
}
|
|
84
|
+
this.logger.info(`Configuration system initialized: ${this.config.server.environment}:${this.config.server.port}`);
|
|
85
|
+
// Initialize runtime system
|
|
86
|
+
this.runtimeType = options.runtime?.type || "node";
|
|
87
|
+
this.runtimeAdapter =
|
|
88
|
+
options.runtime?.adapter || (0, runtime_1.createRuntimeAdapter)(this.runtimeType);
|
|
89
|
+
this.logger.info(`Runtime system initialized: ${this.runtimeType}`, "Runtime");
|
|
90
|
+
this.coreFramework = new framework_1.Moro();
|
|
91
|
+
// Access enterprise event bus from core framework
|
|
92
|
+
this.eventBus = this.coreFramework.eventBus;
|
|
93
|
+
// Setup default middleware if enabled - use config defaults with options override
|
|
94
|
+
this.setupDefaultMiddleware({
|
|
95
|
+
...this.getDefaultOptionsFromConfig(),
|
|
96
|
+
...options,
|
|
97
|
+
});
|
|
98
|
+
// Auto-discover modules if enabled
|
|
99
|
+
if (options.autoDiscover !== false) {
|
|
100
|
+
this.autoDiscoverModules(options.modulesPath || "./modules");
|
|
101
|
+
}
|
|
102
|
+
// Emit initialization event through enterprise event bus
|
|
103
|
+
this.eventBus.emit("framework:initialized", {
|
|
104
|
+
options,
|
|
105
|
+
config: this.config,
|
|
106
|
+
runtime: this.runtimeType,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get configuration object
|
|
111
|
+
*/
|
|
112
|
+
getConfig() {
|
|
113
|
+
return this.config;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get runtime adapter
|
|
117
|
+
*/
|
|
118
|
+
getRuntime() {
|
|
119
|
+
return this.runtimeAdapter;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get runtime type
|
|
123
|
+
*/
|
|
124
|
+
getRuntimeType() {
|
|
125
|
+
return this.runtimeType;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Extract default options from configuration
|
|
129
|
+
*/
|
|
130
|
+
getDefaultOptionsFromConfig() {
|
|
131
|
+
return {
|
|
132
|
+
cors: this.config.security.cors.enabled,
|
|
133
|
+
compression: this.config.performance.compression.enabled,
|
|
134
|
+
helmet: this.config.security.helmet.enabled,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
get(path, handler, options) {
|
|
138
|
+
if (handler) {
|
|
139
|
+
// Direct route registration
|
|
140
|
+
return this.addRoute("GET", path, handler, options);
|
|
141
|
+
}
|
|
142
|
+
// Chainable route builder
|
|
143
|
+
return this.intelligentRouting.get(path);
|
|
144
|
+
}
|
|
145
|
+
post(path, handler, options) {
|
|
146
|
+
if (handler) {
|
|
147
|
+
// Direct route registration
|
|
148
|
+
return this.addRoute("POST", path, handler, options);
|
|
149
|
+
}
|
|
150
|
+
// Chainable route builder
|
|
151
|
+
return this.intelligentRouting.post(path);
|
|
152
|
+
}
|
|
153
|
+
put(path, handler, options) {
|
|
154
|
+
if (handler) {
|
|
155
|
+
// Direct route registration
|
|
156
|
+
return this.addRoute("PUT", path, handler, options);
|
|
157
|
+
}
|
|
158
|
+
// Chainable route builder
|
|
159
|
+
return this.intelligentRouting.put(path);
|
|
160
|
+
}
|
|
161
|
+
delete(path, handler, options) {
|
|
162
|
+
if (handler) {
|
|
163
|
+
// Direct route registration
|
|
164
|
+
return this.addRoute("DELETE", path, handler, options);
|
|
165
|
+
}
|
|
166
|
+
// Chainable route builder
|
|
167
|
+
return this.intelligentRouting.delete(path);
|
|
168
|
+
}
|
|
169
|
+
patch(path, handler, options) {
|
|
170
|
+
if (handler) {
|
|
171
|
+
// Direct route registration
|
|
172
|
+
return this.addRoute("PATCH", path, handler, options);
|
|
173
|
+
}
|
|
174
|
+
// Chainable route builder
|
|
175
|
+
return this.intelligentRouting.patch(path);
|
|
176
|
+
}
|
|
177
|
+
// Schema-first route method
|
|
178
|
+
route(schema) {
|
|
179
|
+
return this.intelligentRouting.route(schema);
|
|
180
|
+
}
|
|
181
|
+
// Enable automatic API documentation
|
|
182
|
+
enableDocs(config) {
|
|
183
|
+
this.documentation.enableDocs(config, this.intelligentRouting);
|
|
184
|
+
this.logger.info(`API Documentation enabled at ${config.basePath || "/docs"}`, "Documentation");
|
|
185
|
+
this.eventBus.emit("docs:enabled", { config });
|
|
186
|
+
}
|
|
187
|
+
// Get OpenAPI specification
|
|
188
|
+
getOpenAPISpec() {
|
|
189
|
+
return this.documentation.getOpenAPISpec();
|
|
190
|
+
}
|
|
191
|
+
// Get documentation as JSON
|
|
192
|
+
getDocsJSON() {
|
|
193
|
+
return this.documentation.getDocsJSON();
|
|
194
|
+
}
|
|
195
|
+
// Get documentation as YAML
|
|
196
|
+
getDocsYAML() {
|
|
197
|
+
return this.documentation.getDocsYAML();
|
|
198
|
+
}
|
|
199
|
+
// Refresh documentation (useful after adding routes dynamically)
|
|
200
|
+
refreshDocs() {
|
|
201
|
+
this.documentation.refreshDocs();
|
|
202
|
+
}
|
|
203
|
+
// Universal middleware system - seamlessly handles standard and advanced middleware
|
|
204
|
+
async use(middlewareOrFunction, config) {
|
|
205
|
+
// Standard middleware integration (req, res, next pattern)
|
|
206
|
+
if (typeof middlewareOrFunction === "function" &&
|
|
207
|
+
middlewareOrFunction.length >= 3) {
|
|
208
|
+
this.coreFramework.addMiddleware(middlewareOrFunction);
|
|
209
|
+
this.eventBus.emit("middleware:registered", {
|
|
210
|
+
type: "standard",
|
|
211
|
+
middleware: middlewareOrFunction,
|
|
212
|
+
});
|
|
213
|
+
return this;
|
|
214
|
+
}
|
|
215
|
+
// Function-style middleware execution
|
|
216
|
+
if (typeof middlewareOrFunction === "function" &&
|
|
217
|
+
middlewareOrFunction.length <= 1) {
|
|
218
|
+
await middlewareOrFunction(this);
|
|
219
|
+
this.eventBus.emit("middleware:executed", {
|
|
220
|
+
type: "function",
|
|
221
|
+
middleware: middlewareOrFunction,
|
|
222
|
+
});
|
|
223
|
+
return this;
|
|
224
|
+
}
|
|
225
|
+
// Advanced middleware pipeline integration
|
|
226
|
+
this.eventBus.emit("middleware:advanced", {
|
|
227
|
+
middleware: middlewareOrFunction,
|
|
228
|
+
config,
|
|
229
|
+
});
|
|
230
|
+
this.logger.debug("Advanced middleware integration - enhanced capabilities loading...", "Middleware");
|
|
231
|
+
return this;
|
|
232
|
+
}
|
|
233
|
+
// Plugin compatibility layer - unified middleware interface
|
|
234
|
+
async plugin(middleware, options) {
|
|
235
|
+
return this.use(middleware, options);
|
|
236
|
+
}
|
|
237
|
+
// Module loading with events
|
|
238
|
+
async loadModule(moduleOrPath) {
|
|
239
|
+
this.eventBus.emit("module:loading", {
|
|
240
|
+
moduleId: typeof moduleOrPath === "string" ? moduleOrPath : moduleOrPath.name,
|
|
241
|
+
});
|
|
242
|
+
if (typeof moduleOrPath === "string") {
|
|
243
|
+
const module = await this.importModule(moduleOrPath);
|
|
244
|
+
await this.coreFramework.loadModule(module);
|
|
245
|
+
this.loadedModules.add(moduleOrPath);
|
|
246
|
+
this.eventBus.emit("module:loaded", {
|
|
247
|
+
moduleId: module.name,
|
|
248
|
+
version: module.version || "1.0.0",
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
await this.coreFramework.loadModule(moduleOrPath);
|
|
253
|
+
this.loadedModules.add(moduleOrPath.name);
|
|
254
|
+
this.eventBus.emit("module:loaded", {
|
|
255
|
+
moduleId: moduleOrPath.name,
|
|
256
|
+
version: moduleOrPath.version || "1.0.0",
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
// Database helper with events
|
|
262
|
+
database(adapter) {
|
|
263
|
+
this.eventBus.emit("database:connected", {
|
|
264
|
+
adapter: adapter.constructor.name,
|
|
265
|
+
config: "hidden",
|
|
266
|
+
});
|
|
267
|
+
this.coreFramework.registerDatabase(adapter);
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
// WebSocket helper with events
|
|
271
|
+
websocket(namespace, handlers) {
|
|
272
|
+
this.emit("websocket:registering", { namespace, handlers });
|
|
273
|
+
const io = this.coreFramework.getIOServer();
|
|
274
|
+
const ns = io.of(namespace);
|
|
275
|
+
Object.entries(handlers).forEach(([event, handler]) => {
|
|
276
|
+
ns.on("connection", (socket) => {
|
|
277
|
+
this.emit("websocket:connection", { namespace, event, socket });
|
|
278
|
+
socket.on(event, (data, callback) => {
|
|
279
|
+
this.emit("websocket:event", { namespace, event, data });
|
|
280
|
+
Promise.resolve(handler(socket, data))
|
|
281
|
+
.then((result) => {
|
|
282
|
+
this.emit("websocket:response", { namespace, event, result });
|
|
283
|
+
if (callback)
|
|
284
|
+
callback(result);
|
|
285
|
+
else if (result)
|
|
286
|
+
socket.emit(`${event}:response`, result);
|
|
287
|
+
})
|
|
288
|
+
.catch((error) => {
|
|
289
|
+
this.emit("websocket:error", { namespace, event, error });
|
|
290
|
+
const errorResponse = { success: false, error: error.message };
|
|
291
|
+
if (callback)
|
|
292
|
+
callback(errorResponse);
|
|
293
|
+
else
|
|
294
|
+
socket.emit("error", errorResponse);
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
this.emit("websocket:registered", { namespace, handlers });
|
|
300
|
+
return this;
|
|
301
|
+
}
|
|
302
|
+
listen(port, host, callback) {
|
|
303
|
+
// Only available for Node.js runtime
|
|
304
|
+
if (this.runtimeType !== "node") {
|
|
305
|
+
throw new Error(`listen() is only available for Node.js runtime. Current runtime: ${this.runtimeType}. Use getHandler() for other runtimes.`);
|
|
306
|
+
}
|
|
307
|
+
// Handle overloaded parameters (port, callback) or (port, host, callback)
|
|
308
|
+
if (typeof host === "function") {
|
|
309
|
+
callback = host;
|
|
310
|
+
host = undefined;
|
|
311
|
+
}
|
|
312
|
+
this.eventBus.emit("server:starting", { port, runtime: this.runtimeType });
|
|
313
|
+
// Add documentation middleware first (if enabled)
|
|
314
|
+
try {
|
|
315
|
+
const docsMiddleware = this.documentation.getDocsMiddleware();
|
|
316
|
+
this.coreFramework.addMiddleware(docsMiddleware);
|
|
317
|
+
this.logger.debug("Documentation middleware added", "Documentation");
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
// Documentation not enabled, that's fine
|
|
321
|
+
this.logger.debug("Documentation not enabled", "Documentation");
|
|
322
|
+
}
|
|
323
|
+
// Add intelligent routing middleware to handle chainable routes
|
|
324
|
+
this.coreFramework.addMiddleware(async (req, res, next) => {
|
|
325
|
+
// Try intelligent routing first
|
|
326
|
+
const handled = await this.intelligentRouting.handleIntelligentRoute(req, res);
|
|
327
|
+
if (!handled) {
|
|
328
|
+
next(); // Fall back to direct routes
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
// Register direct routes with the HTTP server
|
|
332
|
+
if (this.routes.length > 0) {
|
|
333
|
+
this.registerDirectRoutes();
|
|
334
|
+
}
|
|
335
|
+
const actualCallback = () => {
|
|
336
|
+
const displayHost = host || "localhost";
|
|
337
|
+
this.logger.info("Moro Server Started", "Server");
|
|
338
|
+
this.logger.info(`Runtime: ${this.runtimeType}`, "Server");
|
|
339
|
+
this.logger.info(`HTTP API: http://${displayHost}:${port}`, "Server");
|
|
340
|
+
this.logger.info(`WebSocket: ws://${displayHost}:${port}`, "Server");
|
|
341
|
+
this.logger.info("Native Node.js HTTP • Zero Dependencies • Maximum Performance", "Server");
|
|
342
|
+
this.logger.info("Learn more at https://morojs.com", "Server");
|
|
343
|
+
// Log intelligent routes info
|
|
344
|
+
const intelligentRoutes = this.intelligentRouting.getIntelligentRoutes();
|
|
345
|
+
if (intelligentRoutes.length > 0) {
|
|
346
|
+
this.logger.info(`Intelligent Routes: ${intelligentRoutes.length} registered`, "Server");
|
|
347
|
+
}
|
|
348
|
+
this.eventBus.emit("server:started", { port, runtime: this.runtimeType });
|
|
349
|
+
if (callback)
|
|
350
|
+
callback();
|
|
351
|
+
};
|
|
352
|
+
if (host && typeof host === "string") {
|
|
353
|
+
this.coreFramework.listen(port, host, actualCallback);
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
this.coreFramework.listen(port, actualCallback);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
// Get handler for non-Node.js runtimes
|
|
360
|
+
getHandler() {
|
|
361
|
+
// Create a unified request handler that works with the runtime adapter
|
|
362
|
+
const handler = async (req, res) => {
|
|
363
|
+
// Add documentation middleware first (if enabled)
|
|
364
|
+
try {
|
|
365
|
+
const docsMiddleware = this.documentation.getDocsMiddleware();
|
|
366
|
+
await docsMiddleware(req, res, () => { });
|
|
367
|
+
if (res.headersSent)
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
// Documentation not enabled, that's fine
|
|
372
|
+
}
|
|
373
|
+
// Try intelligent routing first
|
|
374
|
+
const handled = await this.intelligentRouting.handleIntelligentRoute(req, res);
|
|
375
|
+
if (handled)
|
|
376
|
+
return;
|
|
377
|
+
// Handle direct routes
|
|
378
|
+
if (this.routes.length > 0) {
|
|
379
|
+
await this.handleDirectRoutes(req, res);
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
// Use the runtime adapter to create the appropriate handler
|
|
383
|
+
return this.runtimeAdapter.createServer(handler);
|
|
384
|
+
}
|
|
385
|
+
// Handle direct routes for runtime adapters
|
|
386
|
+
async handleDirectRoutes(req, res) {
|
|
387
|
+
// Find matching route
|
|
388
|
+
const route = this.findMatchingRoute(req.method, req.path);
|
|
389
|
+
if (!route) {
|
|
390
|
+
res.status(404).json({ success: false, error: "Not found" });
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
try {
|
|
394
|
+
// Extract path parameters
|
|
395
|
+
const matches = req.path.match(route.pattern);
|
|
396
|
+
if (matches) {
|
|
397
|
+
req.params = {};
|
|
398
|
+
route.paramNames.forEach((name, index) => {
|
|
399
|
+
req.params[name] = matches[index + 1];
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
// Get handler function
|
|
403
|
+
const handler = this.routeHandlers[route.handler];
|
|
404
|
+
if (!handler) {
|
|
405
|
+
res
|
|
406
|
+
.status(500)
|
|
407
|
+
.json({ success: false, error: "Handler not found" });
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
// Execute validation if present
|
|
411
|
+
if (route.validation) {
|
|
412
|
+
try {
|
|
413
|
+
const validated = route.validation.parse(req.body);
|
|
414
|
+
req.body = validated;
|
|
415
|
+
}
|
|
416
|
+
catch (error) {
|
|
417
|
+
if (error.issues) {
|
|
418
|
+
res.status(400).json({
|
|
419
|
+
success: false,
|
|
420
|
+
error: "Validation failed",
|
|
421
|
+
details: error.issues.map((issue) => ({
|
|
422
|
+
field: issue.path.length > 0 ? issue.path.join(".") : "body",
|
|
423
|
+
message: issue.message,
|
|
424
|
+
code: issue.code,
|
|
425
|
+
})),
|
|
426
|
+
});
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
throw error;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
// Execute rate limiting if present
|
|
433
|
+
if (route.rateLimit) {
|
|
434
|
+
const clientId = req.ip || "unknown";
|
|
435
|
+
const key = `${route.method}:${route.path}:${clientId}`;
|
|
436
|
+
if (!this.checkRateLimit(key, route.rateLimit)) {
|
|
437
|
+
res.status(429).json({
|
|
438
|
+
success: false,
|
|
439
|
+
error: "Rate limit exceeded",
|
|
440
|
+
retryAfter: Math.ceil(route.rateLimit.window / 1000),
|
|
441
|
+
});
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
// Execute the handler
|
|
446
|
+
const result = await handler(req, res);
|
|
447
|
+
if (result && !res.headersSent) {
|
|
448
|
+
res.json(result);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
if (!res.headersSent) {
|
|
453
|
+
res.status(500).json({
|
|
454
|
+
success: false,
|
|
455
|
+
error: error instanceof Error ? error.message : "Internal server error",
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
// Find matching route
|
|
461
|
+
findMatchingRoute(method, path) {
|
|
462
|
+
for (const route of this.routes) {
|
|
463
|
+
if (route.method === method) {
|
|
464
|
+
const pattern = this.pathToRegex(route.path);
|
|
465
|
+
if (pattern.pattern.test(path)) {
|
|
466
|
+
return {
|
|
467
|
+
...route,
|
|
468
|
+
pattern: pattern.pattern,
|
|
469
|
+
paramNames: pattern.paramNames,
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
// Convert path to regex (simplified version)
|
|
477
|
+
pathToRegex(path) {
|
|
478
|
+
const paramNames = [];
|
|
479
|
+
const regexPath = path
|
|
480
|
+
.replace(/\//g, "\\/")
|
|
481
|
+
.replace(/:([^/]+)/g, (match, paramName) => {
|
|
482
|
+
paramNames.push(paramName);
|
|
483
|
+
return "([^/]+)";
|
|
484
|
+
});
|
|
485
|
+
return {
|
|
486
|
+
pattern: new RegExp(`^${regexPath}$`),
|
|
487
|
+
paramNames,
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
// Access enterprise event system for advanced integrations
|
|
491
|
+
get events() {
|
|
492
|
+
return this.eventBus;
|
|
493
|
+
}
|
|
494
|
+
// Access to core framework for advanced usage
|
|
495
|
+
get core() {
|
|
496
|
+
return this.coreFramework;
|
|
497
|
+
}
|
|
498
|
+
// Private methods
|
|
499
|
+
addRoute(method, path, handler, options = {}) {
|
|
500
|
+
const handlerName = `handler_${this.routes.length}`;
|
|
501
|
+
this.routes.push({
|
|
502
|
+
method: method,
|
|
503
|
+
path,
|
|
504
|
+
handler: handlerName,
|
|
505
|
+
validation: options.validation,
|
|
506
|
+
rateLimit: options.rateLimit,
|
|
507
|
+
cache: options.cache,
|
|
508
|
+
middleware: options.middleware,
|
|
509
|
+
});
|
|
510
|
+
// Store handler for later module creation
|
|
511
|
+
this.routeHandlers[handlerName] = handler;
|
|
512
|
+
return this;
|
|
513
|
+
}
|
|
514
|
+
registerDirectRoutes() {
|
|
515
|
+
// Register routes directly with the HTTP server for optimal performance
|
|
516
|
+
// This provides the intuitive developer experience users expect
|
|
517
|
+
for (const route of this.routes) {
|
|
518
|
+
const handler = this.routeHandlers[route.handler];
|
|
519
|
+
// Get direct access to the HTTP server through the core framework
|
|
520
|
+
const httpServer = this.coreFramework.httpServer;
|
|
521
|
+
// Create a wrapper handler that handles validation, rate limiting, and return values
|
|
522
|
+
const wrappedHandler = async (req, res) => {
|
|
523
|
+
try {
|
|
524
|
+
// Enhance request with events property for direct routes
|
|
525
|
+
req.events = this.eventBus;
|
|
526
|
+
// Validation middleware (Zod-only)
|
|
527
|
+
if (route.validation) {
|
|
528
|
+
try {
|
|
529
|
+
const validated = route.validation.parse(req.body);
|
|
530
|
+
req.body = validated;
|
|
531
|
+
}
|
|
532
|
+
catch (error) {
|
|
533
|
+
if (error.issues) {
|
|
534
|
+
res.status(400).json({
|
|
535
|
+
success: false,
|
|
536
|
+
error: "Validation failed",
|
|
537
|
+
details: error.issues.map((issue) => ({
|
|
538
|
+
field: issue.path.length > 0 ? issue.path.join(".") : "body",
|
|
539
|
+
message: issue.message,
|
|
540
|
+
code: issue.code,
|
|
541
|
+
})),
|
|
542
|
+
});
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
throw error;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
// Rate limiting middleware
|
|
549
|
+
if (route.rateLimit) {
|
|
550
|
+
const clientId = req.ip || req.connection.remoteAddress || "unknown";
|
|
551
|
+
const key = `${route.method}:${route.path}:${clientId}`;
|
|
552
|
+
if (!this.checkRateLimit(key, route.rateLimit)) {
|
|
553
|
+
res.status(429).json({
|
|
554
|
+
success: false,
|
|
555
|
+
error: "Rate limit exceeded",
|
|
556
|
+
retryAfter: Math.ceil(route.rateLimit.window / 1000),
|
|
557
|
+
});
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
// Execute the actual handler
|
|
562
|
+
const result = await handler(req, res);
|
|
563
|
+
if (result && !res.headersSent) {
|
|
564
|
+
res.json(result);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
catch (error) {
|
|
568
|
+
if (!res.headersSent) {
|
|
569
|
+
res.status(500).json({
|
|
570
|
+
success: false,
|
|
571
|
+
error: error instanceof Error
|
|
572
|
+
? error.message
|
|
573
|
+
: "Internal server error",
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
// Register with the appropriate HTTP method
|
|
579
|
+
const method = route.method.toLowerCase();
|
|
580
|
+
if (httpServer && httpServer[method]) {
|
|
581
|
+
httpServer[method](route.path, wrappedHandler);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
checkRateLimit(key, config) {
|
|
586
|
+
const now = Date.now();
|
|
587
|
+
const bucket = this.rateLimitStore.get(key);
|
|
588
|
+
if (!bucket || now > bucket.resetTime) {
|
|
589
|
+
// Create new bucket or reset expired bucket
|
|
590
|
+
this.rateLimitStore.set(key, {
|
|
591
|
+
count: 1,
|
|
592
|
+
resetTime: now + config.window,
|
|
593
|
+
});
|
|
594
|
+
return true;
|
|
595
|
+
}
|
|
596
|
+
if (bucket.count >= config.requests) {
|
|
597
|
+
return false; // Rate limit exceeded
|
|
598
|
+
}
|
|
599
|
+
bucket.count++;
|
|
600
|
+
return true;
|
|
601
|
+
}
|
|
602
|
+
setupDefaultMiddleware(options) {
|
|
603
|
+
// CORS
|
|
604
|
+
if (options.cors !== false) {
|
|
605
|
+
const corsOptions = typeof options.cors === "object" ? options.cors : {};
|
|
606
|
+
this.use(http_1.middleware.cors(corsOptions));
|
|
607
|
+
}
|
|
608
|
+
// Helmet
|
|
609
|
+
if (options.helmet !== false) {
|
|
610
|
+
this.use(http_1.middleware.helmet());
|
|
611
|
+
}
|
|
612
|
+
// Compression
|
|
613
|
+
if (options.compression !== false) {
|
|
614
|
+
const compressionOptions = typeof options.compression === "object" ? options.compression : {};
|
|
615
|
+
this.use(http_1.middleware.compression(compressionOptions));
|
|
616
|
+
}
|
|
617
|
+
// Body size limiting
|
|
618
|
+
this.use(http_1.middleware.bodySize({ limit: "10mb" }));
|
|
619
|
+
}
|
|
620
|
+
autoDiscoverModules(modulesPath) {
|
|
621
|
+
try {
|
|
622
|
+
if (!(0, fs_1.statSync)(modulesPath).isDirectory())
|
|
623
|
+
return;
|
|
624
|
+
const items = (0, fs_1.readdirSync)(modulesPath);
|
|
625
|
+
items.forEach((item) => {
|
|
626
|
+
const fullPath = (0, path_1.join)(modulesPath, item);
|
|
627
|
+
if ((0, fs_1.statSync)(fullPath).isDirectory()) {
|
|
628
|
+
const indexPath = (0, path_1.join)(fullPath, "index.ts");
|
|
629
|
+
try {
|
|
630
|
+
(0, fs_1.statSync)(indexPath);
|
|
631
|
+
// Module directory found, will be loaded later
|
|
632
|
+
this.logger.debug(`Discovered module: ${item}`, "ModuleDiscovery");
|
|
633
|
+
}
|
|
634
|
+
catch {
|
|
635
|
+
// No index.ts, skip
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
catch {
|
|
641
|
+
// Modules directory doesn't exist, that's fine
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
async importModule(modulePath) {
|
|
645
|
+
const module = await Promise.resolve(`${modulePath}`).then(s => __importStar(require(s)));
|
|
646
|
+
return module.default || module;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
exports.Moro = Moro;
|
|
650
|
+
// Export convenience function
|
|
651
|
+
function createApp(options) {
|
|
652
|
+
return new Moro(options);
|
|
653
|
+
}
|
|
654
|
+
// Runtime-specific convenience functions
|
|
655
|
+
function createAppNode(options) {
|
|
656
|
+
return new Moro({
|
|
657
|
+
...options,
|
|
658
|
+
runtime: { type: "node" },
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
function createAppEdge(options) {
|
|
662
|
+
return new Moro({
|
|
663
|
+
...options,
|
|
664
|
+
runtime: { type: "vercel-edge" },
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
function createAppLambda(options) {
|
|
668
|
+
return new Moro({
|
|
669
|
+
...options,
|
|
670
|
+
runtime: { type: "aws-lambda" },
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
function createAppWorker(options) {
|
|
674
|
+
return new Moro({
|
|
675
|
+
...options,
|
|
676
|
+
runtime: { type: "cloudflare-workers" },
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
//# sourceMappingURL=moro.js.map
|