@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
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
// Core Configuration Schema for Moro Framework
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
// Server Configuration Schema
|
|
5
|
+
const ServerConfigSchema = z.object({
|
|
6
|
+
port: z.coerce
|
|
7
|
+
.number()
|
|
8
|
+
.min(1, "Port must be at least 1")
|
|
9
|
+
.max(65535, "Port must be at most 65535")
|
|
10
|
+
.default(3001)
|
|
11
|
+
.describe("Server port to listen on"),
|
|
12
|
+
|
|
13
|
+
host: z.string().default("localhost").describe("Server host to bind to"),
|
|
14
|
+
|
|
15
|
+
environment: z
|
|
16
|
+
.enum(["development", "staging", "production"])
|
|
17
|
+
.default("development")
|
|
18
|
+
.describe("Application environment"),
|
|
19
|
+
|
|
20
|
+
maxConnections: z.coerce
|
|
21
|
+
.number()
|
|
22
|
+
.min(1)
|
|
23
|
+
.default(1000)
|
|
24
|
+
.describe("Maximum concurrent connections"),
|
|
25
|
+
|
|
26
|
+
timeout: z.coerce
|
|
27
|
+
.number()
|
|
28
|
+
.min(1000)
|
|
29
|
+
.default(30000)
|
|
30
|
+
.describe("Request timeout in milliseconds"),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Service Discovery Configuration Schema
|
|
34
|
+
const ServiceDiscoveryConfigSchema = z.object({
|
|
35
|
+
enabled: z.coerce
|
|
36
|
+
.boolean()
|
|
37
|
+
.default(false)
|
|
38
|
+
.describe("Enable service discovery"),
|
|
39
|
+
|
|
40
|
+
type: z
|
|
41
|
+
.enum(["memory", "consul", "kubernetes"])
|
|
42
|
+
.default("memory")
|
|
43
|
+
.describe("Service discovery backend type"),
|
|
44
|
+
|
|
45
|
+
consulUrl: z
|
|
46
|
+
.string()
|
|
47
|
+
.url("Must be a valid URL")
|
|
48
|
+
.default("http://localhost:8500")
|
|
49
|
+
.describe("Consul server URL"),
|
|
50
|
+
|
|
51
|
+
kubernetesNamespace: z
|
|
52
|
+
.string()
|
|
53
|
+
.default("default")
|
|
54
|
+
.describe("Kubernetes namespace for service discovery"),
|
|
55
|
+
|
|
56
|
+
healthCheckInterval: z.coerce
|
|
57
|
+
.number()
|
|
58
|
+
.min(1000)
|
|
59
|
+
.default(30000)
|
|
60
|
+
.describe("Health check interval in milliseconds"),
|
|
61
|
+
|
|
62
|
+
retryAttempts: z.coerce
|
|
63
|
+
.number()
|
|
64
|
+
.min(0)
|
|
65
|
+
.default(3)
|
|
66
|
+
.describe("Number of retry attempts for failed health checks"),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Database Configuration Schema
|
|
70
|
+
const DatabaseConfigSchema = z.object({
|
|
71
|
+
url: z.string().optional().describe("Primary database connection URL"),
|
|
72
|
+
|
|
73
|
+
redis: z.object({
|
|
74
|
+
url: z
|
|
75
|
+
.string()
|
|
76
|
+
.default("redis://localhost:6379")
|
|
77
|
+
.describe("Redis connection URL"),
|
|
78
|
+
|
|
79
|
+
maxRetries: z.coerce
|
|
80
|
+
.number()
|
|
81
|
+
.min(0)
|
|
82
|
+
.default(3)
|
|
83
|
+
.describe("Maximum Redis connection retry attempts"),
|
|
84
|
+
|
|
85
|
+
retryDelay: z.coerce
|
|
86
|
+
.number()
|
|
87
|
+
.min(100)
|
|
88
|
+
.default(1000)
|
|
89
|
+
.describe("Redis retry delay in milliseconds"),
|
|
90
|
+
|
|
91
|
+
keyPrefix: z.string().default("moro:").describe("Redis key prefix"),
|
|
92
|
+
}),
|
|
93
|
+
|
|
94
|
+
mysql: z
|
|
95
|
+
.object({
|
|
96
|
+
host: z.string().default("localhost"),
|
|
97
|
+
port: z.coerce.number().min(1).max(65535).default(3306),
|
|
98
|
+
database: z.string().optional(),
|
|
99
|
+
username: z.string().optional(),
|
|
100
|
+
password: z.string().optional(),
|
|
101
|
+
connectionLimit: z.coerce.number().min(1).default(10),
|
|
102
|
+
acquireTimeout: z.coerce.number().min(1000).default(60000),
|
|
103
|
+
timeout: z.coerce.number().min(1000).default(60000),
|
|
104
|
+
})
|
|
105
|
+
.optional(),
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Module Defaults Configuration Schema
|
|
109
|
+
const ModuleDefaultsConfigSchema = z.object({
|
|
110
|
+
cache: z.object({
|
|
111
|
+
enabled: z.coerce
|
|
112
|
+
.boolean()
|
|
113
|
+
.default(true)
|
|
114
|
+
.describe("Enable caching by default"),
|
|
115
|
+
|
|
116
|
+
defaultTtl: z.coerce
|
|
117
|
+
.number()
|
|
118
|
+
.min(0)
|
|
119
|
+
.default(300)
|
|
120
|
+
.describe("Default cache TTL in seconds"),
|
|
121
|
+
|
|
122
|
+
maxSize: z.coerce
|
|
123
|
+
.number()
|
|
124
|
+
.min(1)
|
|
125
|
+
.default(1000)
|
|
126
|
+
.describe("Maximum cache entries"),
|
|
127
|
+
|
|
128
|
+
strategy: z
|
|
129
|
+
.enum(["lru", "lfu", "fifo"])
|
|
130
|
+
.default("lru")
|
|
131
|
+
.describe("Cache eviction strategy"),
|
|
132
|
+
}),
|
|
133
|
+
|
|
134
|
+
rateLimit: z.object({
|
|
135
|
+
enabled: z.coerce
|
|
136
|
+
.boolean()
|
|
137
|
+
.default(true)
|
|
138
|
+
.describe("Enable rate limiting by default"),
|
|
139
|
+
|
|
140
|
+
defaultRequests: z.coerce
|
|
141
|
+
.number()
|
|
142
|
+
.min(1)
|
|
143
|
+
.default(100)
|
|
144
|
+
.describe("Default requests per window"),
|
|
145
|
+
|
|
146
|
+
defaultWindow: z.coerce
|
|
147
|
+
.number()
|
|
148
|
+
.min(1000)
|
|
149
|
+
.default(60000)
|
|
150
|
+
.describe("Default rate limit window in milliseconds"),
|
|
151
|
+
|
|
152
|
+
skipSuccessfulRequests: z.coerce
|
|
153
|
+
.boolean()
|
|
154
|
+
.default(false)
|
|
155
|
+
.describe("Skip successful requests in rate limit counting"),
|
|
156
|
+
|
|
157
|
+
skipFailedRequests: z.coerce
|
|
158
|
+
.boolean()
|
|
159
|
+
.default(false)
|
|
160
|
+
.describe("Skip failed requests in rate limit counting"),
|
|
161
|
+
}),
|
|
162
|
+
|
|
163
|
+
validation: z.object({
|
|
164
|
+
enabled: z.coerce
|
|
165
|
+
.boolean()
|
|
166
|
+
.default(true)
|
|
167
|
+
.describe("Enable validation by default"),
|
|
168
|
+
|
|
169
|
+
stripUnknown: z.coerce
|
|
170
|
+
.boolean()
|
|
171
|
+
.default(true)
|
|
172
|
+
.describe("Strip unknown properties from validated data"),
|
|
173
|
+
|
|
174
|
+
abortEarly: z.coerce
|
|
175
|
+
.boolean()
|
|
176
|
+
.default(false)
|
|
177
|
+
.describe("Stop validation on first error"),
|
|
178
|
+
}),
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Logging Configuration Schema
|
|
182
|
+
const LoggingConfigSchema = z.object({
|
|
183
|
+
level: z
|
|
184
|
+
.enum(["debug", "info", "warn", "error", "fatal"])
|
|
185
|
+
.default("info")
|
|
186
|
+
.describe("Minimum log level"),
|
|
187
|
+
|
|
188
|
+
format: z
|
|
189
|
+
.enum(["pretty", "json", "compact"])
|
|
190
|
+
.default("pretty")
|
|
191
|
+
.describe("Log output format"),
|
|
192
|
+
|
|
193
|
+
enableColors: z.coerce
|
|
194
|
+
.boolean()
|
|
195
|
+
.default(true)
|
|
196
|
+
.describe("Enable colored log output"),
|
|
197
|
+
|
|
198
|
+
enableTimestamp: z.coerce
|
|
199
|
+
.boolean()
|
|
200
|
+
.default(true)
|
|
201
|
+
.describe("Include timestamp in logs"),
|
|
202
|
+
|
|
203
|
+
enableContext: z.coerce
|
|
204
|
+
.boolean()
|
|
205
|
+
.default(true)
|
|
206
|
+
.describe("Include context information in logs"),
|
|
207
|
+
|
|
208
|
+
outputs: z.object({
|
|
209
|
+
console: z.coerce.boolean().default(true),
|
|
210
|
+
file: z.object({
|
|
211
|
+
enabled: z.coerce.boolean().default(false),
|
|
212
|
+
path: z.string().default("./logs/moro.log"),
|
|
213
|
+
maxSize: z.string().default("10MB"),
|
|
214
|
+
maxFiles: z.coerce.number().default(5),
|
|
215
|
+
}),
|
|
216
|
+
webhook: z.object({
|
|
217
|
+
enabled: z.coerce.boolean().default(false),
|
|
218
|
+
url: z.string().url().optional(),
|
|
219
|
+
headers: z.record(z.string(), z.string()).default({}),
|
|
220
|
+
}),
|
|
221
|
+
}),
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// Security Configuration Schema
|
|
225
|
+
const SecurityConfigSchema = z.object({
|
|
226
|
+
cors: z.object({
|
|
227
|
+
enabled: z.coerce.boolean().default(true),
|
|
228
|
+
origin: z
|
|
229
|
+
.union([z.string(), z.array(z.string()), z.boolean()])
|
|
230
|
+
.default("*"),
|
|
231
|
+
methods: z
|
|
232
|
+
.array(z.string())
|
|
233
|
+
.default(["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]),
|
|
234
|
+
allowedHeaders: z
|
|
235
|
+
.array(z.string())
|
|
236
|
+
.default(["Content-Type", "Authorization"]),
|
|
237
|
+
credentials: z.coerce.boolean().default(false),
|
|
238
|
+
}),
|
|
239
|
+
|
|
240
|
+
helmet: z.object({
|
|
241
|
+
enabled: z.coerce.boolean().default(true),
|
|
242
|
+
contentSecurityPolicy: z.coerce.boolean().default(true),
|
|
243
|
+
hsts: z.coerce.boolean().default(true),
|
|
244
|
+
noSniff: z.coerce.boolean().default(true),
|
|
245
|
+
frameguard: z.coerce.boolean().default(true),
|
|
246
|
+
}),
|
|
247
|
+
|
|
248
|
+
rateLimit: z.object({
|
|
249
|
+
global: z.object({
|
|
250
|
+
enabled: z.coerce.boolean().default(false),
|
|
251
|
+
requests: z.coerce.number().min(1).default(1000),
|
|
252
|
+
window: z.coerce.number().min(1000).default(60000),
|
|
253
|
+
}),
|
|
254
|
+
}),
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// External Services Configuration Schema
|
|
258
|
+
const ExternalServicesConfigSchema = z.object({
|
|
259
|
+
stripe: z
|
|
260
|
+
.object({
|
|
261
|
+
secretKey: z.string().optional(),
|
|
262
|
+
publishableKey: z.string().optional(),
|
|
263
|
+
webhookSecret: z.string().optional(),
|
|
264
|
+
apiVersion: z.string().default("2023-10-16"),
|
|
265
|
+
})
|
|
266
|
+
.optional(),
|
|
267
|
+
|
|
268
|
+
paypal: z
|
|
269
|
+
.object({
|
|
270
|
+
clientId: z.string().optional(),
|
|
271
|
+
clientSecret: z.string().optional(),
|
|
272
|
+
webhookId: z.string().optional(),
|
|
273
|
+
environment: z.enum(["sandbox", "production"]).default("sandbox"),
|
|
274
|
+
})
|
|
275
|
+
.optional(),
|
|
276
|
+
|
|
277
|
+
smtp: z
|
|
278
|
+
.object({
|
|
279
|
+
host: z.string().optional(),
|
|
280
|
+
port: z.coerce.number().min(1).max(65535).default(587),
|
|
281
|
+
secure: z.coerce.boolean().default(false),
|
|
282
|
+
username: z.string().optional(),
|
|
283
|
+
password: z.string().optional(),
|
|
284
|
+
})
|
|
285
|
+
.optional(),
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// Performance Configuration Schema
|
|
289
|
+
const PerformanceConfigSchema = z.object({
|
|
290
|
+
compression: z.object({
|
|
291
|
+
enabled: z.coerce.boolean().default(true),
|
|
292
|
+
level: z.coerce.number().min(1).max(9).default(6),
|
|
293
|
+
threshold: z.coerce.number().min(0).default(1024),
|
|
294
|
+
}),
|
|
295
|
+
|
|
296
|
+
circuitBreaker: z.object({
|
|
297
|
+
enabled: z.coerce.boolean().default(true),
|
|
298
|
+
failureThreshold: z.coerce.number().min(1).default(5),
|
|
299
|
+
resetTimeout: z.coerce.number().min(1000).default(60000),
|
|
300
|
+
monitoringPeriod: z.coerce.number().min(1000).default(10000),
|
|
301
|
+
}),
|
|
302
|
+
|
|
303
|
+
clustering: z.object({
|
|
304
|
+
enabled: z.coerce.boolean().default(false),
|
|
305
|
+
workers: z.coerce.number().min(1).default(1),
|
|
306
|
+
}),
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
// Main Configuration Schema
|
|
310
|
+
export const ConfigSchema = z.object({
|
|
311
|
+
server: ServerConfigSchema,
|
|
312
|
+
serviceDiscovery: ServiceDiscoveryConfigSchema,
|
|
313
|
+
database: DatabaseConfigSchema,
|
|
314
|
+
modules: ModuleDefaultsConfigSchema,
|
|
315
|
+
logging: LoggingConfigSchema,
|
|
316
|
+
security: SecurityConfigSchema,
|
|
317
|
+
external: ExternalServicesConfigSchema,
|
|
318
|
+
performance: PerformanceConfigSchema,
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// Inferred TypeScript types
|
|
322
|
+
export type AppConfig = z.infer<typeof ConfigSchema>;
|
|
323
|
+
export type ServerConfig = z.infer<typeof ServerConfigSchema>;
|
|
324
|
+
export type ServiceDiscoveryConfig = z.infer<
|
|
325
|
+
typeof ServiceDiscoveryConfigSchema
|
|
326
|
+
>;
|
|
327
|
+
export type DatabaseConfig = z.infer<typeof DatabaseConfigSchema>;
|
|
328
|
+
export type ModuleDefaultsConfig = z.infer<typeof ModuleDefaultsConfigSchema>;
|
|
329
|
+
export type LoggingConfig = z.infer<typeof LoggingConfigSchema>;
|
|
330
|
+
export type SecurityConfig = z.infer<typeof SecurityConfigSchema>;
|
|
331
|
+
export type ExternalServicesConfig = z.infer<
|
|
332
|
+
typeof ExternalServicesConfigSchema
|
|
333
|
+
>;
|
|
334
|
+
export type PerformanceConfig = z.infer<typeof PerformanceConfigSchema>;
|
|
335
|
+
|
|
336
|
+
// Export individual schemas for module-specific configuration
|
|
337
|
+
export {
|
|
338
|
+
ServerConfigSchema,
|
|
339
|
+
ServiceDiscoveryConfigSchema,
|
|
340
|
+
DatabaseConfigSchema,
|
|
341
|
+
ModuleDefaultsConfigSchema,
|
|
342
|
+
LoggingConfigSchema,
|
|
343
|
+
SecurityConfigSchema,
|
|
344
|
+
ExternalServicesConfigSchema,
|
|
345
|
+
PerformanceConfigSchema,
|
|
346
|
+
};
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
// Configuration Utilities for Modules and Environment Handling
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { AppConfig } from "./schema";
|
|
4
|
+
import { createFrameworkLogger } from "../logger";
|
|
5
|
+
|
|
6
|
+
const logger = createFrameworkLogger("ConfigUtils");
|
|
7
|
+
|
|
8
|
+
// Global configuration store
|
|
9
|
+
let appConfig: AppConfig | null = null;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Set the global configuration (used by framework initialization)
|
|
13
|
+
*/
|
|
14
|
+
export function setConfig(config: AppConfig): void {
|
|
15
|
+
appConfig = config;
|
|
16
|
+
logger.debug("Global configuration updated");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get the global configuration
|
|
21
|
+
*/
|
|
22
|
+
export function getConfig(): AppConfig {
|
|
23
|
+
if (!appConfig) {
|
|
24
|
+
throw new Error("Configuration not initialized. Call loadConfig() first.");
|
|
25
|
+
}
|
|
26
|
+
return appConfig;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Create module-specific configuration with environment override support
|
|
31
|
+
*/
|
|
32
|
+
export function createModuleConfig<T>(
|
|
33
|
+
schema: z.ZodSchema<T>,
|
|
34
|
+
defaultConfig: Partial<T>,
|
|
35
|
+
envPrefix?: string,
|
|
36
|
+
): T {
|
|
37
|
+
const globalConfig = getConfig();
|
|
38
|
+
|
|
39
|
+
// Build environment configuration object
|
|
40
|
+
const envConfig: Record<string, any> = {};
|
|
41
|
+
|
|
42
|
+
if (envPrefix) {
|
|
43
|
+
// Extract environment variables with the given prefix
|
|
44
|
+
Object.keys(process.env).forEach((key) => {
|
|
45
|
+
if (key.startsWith(envPrefix)) {
|
|
46
|
+
const configKey = key
|
|
47
|
+
.substring(envPrefix.length)
|
|
48
|
+
.toLowerCase()
|
|
49
|
+
.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
50
|
+
|
|
51
|
+
envConfig[configKey] = process.env[key];
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Merge default config, global defaults, and environment overrides
|
|
57
|
+
const mergedConfig = {
|
|
58
|
+
...defaultConfig,
|
|
59
|
+
...envConfig,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
return schema.parse(mergedConfig);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
logger.error(
|
|
66
|
+
`Module configuration validation failed for prefix ${envPrefix}:`,
|
|
67
|
+
String(error),
|
|
68
|
+
);
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get environment variable with type conversion
|
|
75
|
+
*/
|
|
76
|
+
export function getEnvVar<T>(
|
|
77
|
+
key: string,
|
|
78
|
+
defaultValue: T,
|
|
79
|
+
converter?: (value: string) => T,
|
|
80
|
+
): T {
|
|
81
|
+
const value = process.env[key];
|
|
82
|
+
|
|
83
|
+
if (value === undefined) {
|
|
84
|
+
return defaultValue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (converter) {
|
|
88
|
+
try {
|
|
89
|
+
return converter(value);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
logger.warn(
|
|
92
|
+
`Failed to convert environment variable ${key}:`,
|
|
93
|
+
String(error),
|
|
94
|
+
);
|
|
95
|
+
return defaultValue;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Default type conversions
|
|
100
|
+
if (typeof defaultValue === "boolean") {
|
|
101
|
+
return (value.toLowerCase() === "true") as T;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (typeof defaultValue === "number") {
|
|
105
|
+
const num = Number(value);
|
|
106
|
+
return (isNaN(num) ? defaultValue : num) as T;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return value as T;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Parse comma-separated environment variable as array
|
|
114
|
+
*/
|
|
115
|
+
export function getEnvArray(
|
|
116
|
+
key: string,
|
|
117
|
+
defaultValue: string[] = [],
|
|
118
|
+
): string[] {
|
|
119
|
+
const value = process.env[key];
|
|
120
|
+
|
|
121
|
+
if (!value) {
|
|
122
|
+
return defaultValue;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return value
|
|
126
|
+
.split(",")
|
|
127
|
+
.map((item) => item.trim())
|
|
128
|
+
.filter(Boolean);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Parse JSON environment variable safely
|
|
133
|
+
*/
|
|
134
|
+
export function getEnvJson<T>(key: string, defaultValue: T): T {
|
|
135
|
+
const value = process.env[key];
|
|
136
|
+
|
|
137
|
+
if (!value) {
|
|
138
|
+
return defaultValue;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
return JSON.parse(value);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
logger.warn(
|
|
145
|
+
`Failed to parse JSON environment variable ${key}:`,
|
|
146
|
+
String(error),
|
|
147
|
+
);
|
|
148
|
+
return defaultValue;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Validate required environment variables
|
|
154
|
+
*/
|
|
155
|
+
export function requireEnvVars(...keys: string[]): void {
|
|
156
|
+
const missing: string[] = [];
|
|
157
|
+
|
|
158
|
+
keys.forEach((key) => {
|
|
159
|
+
if (!process.env[key]) {
|
|
160
|
+
missing.push(key);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
if (missing.length > 0) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`Missing required environment variables: ${missing.join(", ")}`,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Create environment variable name with prefix
|
|
173
|
+
*/
|
|
174
|
+
export function envVar(prefix: string, name: string): string {
|
|
175
|
+
return `${prefix.toUpperCase()}_${name.toUpperCase()}`;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Get configuration value with dot notation
|
|
180
|
+
*/
|
|
181
|
+
export function getConfigValue(path: string): any {
|
|
182
|
+
const config = getConfig();
|
|
183
|
+
|
|
184
|
+
return path.split(".").reduce((obj, key) => {
|
|
185
|
+
return obj && obj[key] !== undefined ? obj[key] : undefined;
|
|
186
|
+
}, config as any);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Check if we're in development environment
|
|
191
|
+
*/
|
|
192
|
+
export function isDevelopment(): boolean {
|
|
193
|
+
try {
|
|
194
|
+
return getConfig().server.environment === "development";
|
|
195
|
+
} catch {
|
|
196
|
+
return process.env.NODE_ENV === "development";
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Check if we're in production environment
|
|
202
|
+
*/
|
|
203
|
+
export function isProduction(): boolean {
|
|
204
|
+
try {
|
|
205
|
+
return getConfig().server.environment === "production";
|
|
206
|
+
} catch {
|
|
207
|
+
return process.env.NODE_ENV === "production";
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Check if we're in staging environment
|
|
213
|
+
*/
|
|
214
|
+
export function isStaging(): boolean {
|
|
215
|
+
try {
|
|
216
|
+
return getConfig().server.environment === "staging";
|
|
217
|
+
} catch {
|
|
218
|
+
return process.env.NODE_ENV === "staging";
|
|
219
|
+
}
|
|
220
|
+
}
|