@morojs/moro 1.8.13 → 1.8.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/config/config-validator.js +5 -0
- package/dist/core/config/config-validator.js.map +1 -1
- package/dist/core/config/schema.js +1 -0
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/http/http-server.d.ts +2 -0
- package/dist/core/http/http-server.js +54 -0
- package/dist/core/http/http-server.js.map +1 -1
- package/dist/core/http/http2-server.d.ts +3 -0
- package/dist/core/http/http2-server.js +57 -13
- package/dist/core/http/http2-server.js.map +1 -1
- package/dist/core/http/moro-engine-server.js +23 -1
- package/dist/core/http/moro-engine-server.js.map +1 -1
- package/dist/core/http/utils/compression.d.ts +21 -0
- package/dist/core/http/utils/compression.js +53 -7
- package/dist/core/http/utils/compression.js.map +1 -1
- package/dist/core/http/uws-http-server.js +25 -1
- package/dist/core/http/uws-http-server.js.map +1 -1
- package/dist/core/middleware/built-in/compression/core.d.ts +7 -0
- package/dist/core/middleware/built-in/compression/core.js +27 -1
- package/dist/core/middleware/built-in/compression/core.js.map +1 -1
- package/dist/core/utilities/package-utils.d.ts +1 -1
- package/dist/core/utilities/package-utils.js.map +1 -1
- package/dist/types/config.d.ts +8 -0
- package/dist/types/config.js.map +1 -1
- package/dist/types/core.d.ts +1 -0
- package/dist/types/core.js.map +1 -1
- package/package.json +2 -2
|
@@ -212,6 +212,7 @@ export const DEFAULT_CONFIG = {
|
|
|
212
212
|
enabled: false, // Opt-in to avoid overhead
|
|
213
213
|
level: 6,
|
|
214
214
|
threshold: 1024,
|
|
215
|
+
maxInlineBytes: 16384, // compressed on the calling thread up to here, on the pool above
|
|
215
216
|
},
|
|
216
217
|
circuitBreaker: {
|
|
217
218
|
enabled: false, // Opt-in to avoid overhead
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/core/config/schema.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAI/C,0EAA0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAc;IACvC,MAAM,EAAE;QACN,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,WAAW;QACjB,uEAAuE;QACvE,2EAA2E;QAC3E,wEAAwE;QACxE,sEAAsE;QACtE,uEAAuE;QACvE,6DAA6D;QAC7D,cAAc,EAAE,CAAC;QACjB,OAAO,EAAE,CAAC,EAAE,sDAAsD;QAClE,aAAa,EAAE,MAAM;QACrB,aAAa,EAAE,OAAO,EAAE,wDAAwD;QAChF,yEAAyE;QACzE,yEAAyE;QACzE,0EAA0E;QAC1E,yDAAyD;QACzD,QAAQ,EAAE;YACR,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,CAAC;YACP,OAAO,EAAE,CAAC;SACX;QACD,0EAA0E;QAC1E,2EAA2E;QAC3E,qEAAqE;QACrE,MAAM,EAAE;YACN,SAAS,EAAE;gBACT,QAAQ,EAAE,IAAI;gBACd,kBAAkB,EAAE,MAAM;aAC3B;SACF;QACD,4EAA4E;QAC5E,yEAAyE;QACzE,6EAA6E;QAC7E,cAAc,EAAE,KAAK,EAAE,qCAAqC;QAC5D,eAAe,EAAE;YACf,OAAO,EAAE,IAAI,EAAE,kCAAkC;SAClD;QACD,cAAc,EAAE;YACd,qEAAqE;YACrE,sEAAsE;YACtE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;SAC/C;QACD,aAAa,EAAE;YACb,OAAO,EAAE,IAAI,EAAE,4BAA4B;SAC5C;KACF;IACD,gBAAgB,EAAE;QAChB,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,QAAQ;QACd,SAAS,EAAE,uBAAuB;QAClC,mBAAmB,EAAE,SAAS;QAC9B,mBAAmB,EAAE,KAAK;QAC1B,aAAa,EAAE,CAAC;KACjB;IACD,QAAQ,EAAE,EAAE;IACZ,OAAO,EAAE;QACP,SAAS,EAAE,OAAO,EAAE,0DAA0D;QAC9E,KAAK,EAAE;YACL,OAAO,EAAE,KAAK,EAAE,gCAAgC;YAChD,UAAU,EAAE,GAAG;YACf,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,KAAK;SAChB;QACD,SAAS,EAAE;YACT,OAAO,EAAE,KAAK,EAAE,uCAAuC;YACvD,eAAe,EAAE,GAAG;YACpB,aAAa,EAAE,KAAK;YACpB,sBAAsB,EAAE,KAAK;YAC7B,kBAAkB,EAAE,KAAK;SAC1B;QACD,UAAU,EAAE;YACV,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,IAAI;YAClB,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,KAAK;SACpB;QACD,OAAO,EAAE;YACP,OAAO,EAAE,KAAK,EAAE,SAAS;YACzB,KAAK,EAAE,QAAQ;YACf,yEAAyE;YACzE,wEAAwE;YACxE,uEAAuE;YACvE,MAAM,EAAE,EAAE;YACV,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,KAAK;YACb,iBAAiB,EAAE,KAAK;YACxB,MAAM,EAAE;gBACN,MAAM,EAAE,QAAQ,EAAE,iBAAiB;gBACnC,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,KAAK;gBACb,QAAQ,EAAE,KAAK;gBACf,IAAI,EAAE,GAAG;aACV;YACD,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,MAAM;SACd;QACD,aAAa,EAAE;YACb,OAAO,EAAE,IAAI,EAAE,kCAAkC;YACjD,KAAK,EACH,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;gBACnC,CAAC,CAAC,CAAC,gBAAgB,EAAE,oBAAoB,EAAE,WAAW,CAAC;gBACvD,CAAC,CAAC,CAAC,WAAW,EAAE,eAAe,CAAC;YACpC,QAAQ,EAAE,CAAC,qBAAqB,EAAE,kBAAkB,EAAE,qBAAqB,CAAC;YAC5E,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,OAAO;YACxB,eAAe,EAAE,KAAK,EAAE,yBAAyB;YACjD,cAAc,EAAE,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,oBAAoB,CAAC;YAChF,SAAS,EAAE,YAAY;YACvB,WAAW,EAAE,KAAK,EAAE,uBAAuB;YAC3C,QAAQ,EAAE,CAAC;SACZ;KACF;IACD,6EAA6E;IAC7E,gEAAgE;IAChE,OAAO,EAAE,IAAI;IACb,OAAO,EAAE;QACP,KAAK,EAAE,MAAM;QACb,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE,IAAI;QAClB,eAAe,EAAE,IAAI;QACrB,aAAa,EAAE,IAAI;QACnB,oFAAoF;QACpF,cAAc,EAAE,KAAK;QACrB,2EAA2E;QAC3E,uDAAuD;QACvD,iBAAiB,EAAE,KAAK;QACxB,OAAO,EAAE;YACP,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,MAAM;gBACf,QAAQ,EAAE,CAAC;aACZ;YACD,OAAO,EAAE;gBACP,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,EAAE;aACZ;SACF;KACF;IACD,QAAQ,EAAE;QACR,IAAI,EAAE;YACJ,OAAO,EAAE,KAAK,EAAE,gCAAgC;YAChD,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC;YAC7D,cAAc,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC;YACjD,cAAc,EAAE,EAAE;YAClB,WAAW,EAAE,KAAK;YAClB,MAAM,EAAE,KAAK,EAAE,WAAW;YAC1B,iBAAiB,EAAE,KAAK;SACzB;QACD,MAAM,EAAE;YACN,OAAO,EAAE,KAAK,EAAE,gCAAgC;YAChD,2CAA2C;YAC3C,qBAAqB,EAAE,IAAI;YAC3B,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,IAAI;YAChB,0DAA0D;YAC1D,aAAa,EAAE,MAAM;YACrB,mBAAmB,EAAE,IAAI;YACzB,cAAc,EAAE,IAAI;YACpB,cAAc,EAAE,iCAAiC;YACjD,uBAAuB,EAAE;gBACvB,MAAM,EAAE,QAAQ;gBAChB,iBAAiB,EAAE,IAAI;aACxB;YACD,gBAAgB,EAAE,IAAI;YACtB,6BAA6B,EAAE,IAAI;SACpC;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,KAAK,EAAE,SAAS;YACzB,MAAM,EAAE,EAAE;YACV,WAAW,EAAE,EAAE;YACf,UAAU,EAAE,OAAO;YACnB,UAAU,EAAE,cAAc;YAC1B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC;YACzC,QAAQ,EAAE,IAAI;SACf;QACD,GAAG,EAAE;YACH,OAAO,EAAE,KAAK,EAAE,SAAS;YACzB,UAAU,EAAE;gBACV,UAAU,EAAE,CAAC,QAAQ,CAAC;gBACtB,SAAS,EAAE,CAAC,QAAQ,CAAC;gBACrB,QAAQ,EAAE,CAAC,QAAQ,EAAE,iBAAiB,CAAC;gBACvC,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;gBACrC,UAAU,EAAE,CAAC,QAAQ,CAAC;gBACtB,OAAO,EAAE,CAAC,QAAQ,CAAC;gBACnB,SAAS,EAAE,CAAC,QAAQ,CAAC;gBACrB,QAAQ,EAAE,CAAC,QAAQ,CAAC;gBACpB,QAAQ,EAAE,CAAC,QAAQ,CAAC;aACrB;YACD,UAAU,EAAE,KAAK;YACjB,KAAK,EAAE,KAAK;SACb;QACD,SAAS,EAAE;YACT,MAAM,EAAE;gBACN,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,KAAK;aACd;SACF;KACF;IACD,QAAQ,EAAE,EAAE;IACZ,WAAW,EAAE;QACX,WAAW,EAAE;YACX,OAAO,EAAE,KAAK,EAAE,2BAA2B;YAC3C,KAAK,EAAE,CAAC;YACR,SAAS,EAAE,IAAI;SAChB;QACD,cAAc,EAAE;YACd,OAAO,EAAE,KAAK,EAAE,2BAA2B;YAC3C,gBAAgB,EAAE,CAAC;YACnB,YAAY,EAAE,KAAK;YACnB,gBAAgB,EAAE,KAAK;SACxB;QACD,UAAU,EAAE;YACV,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,CAAC;YACV,iBAAiB,EAAE,SAAS;SAC7B;KACF;IACD,SAAS,EAAE;QACT,OAAO,EAAE,KAAK,EAAE,kDAAkD;KACnE;CACF,CAAC;AAEF,0DAA0D;AAC1D,sDAAsD;AACtD,sFAAsF;AACtF,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,KAAK,EAAE,CAAC,IAAS,EAAa,EAAE;QAC9B,iDAAiD;QACjD,yDAAyD;QACzD,OAAO,IAAiB,CAAC;IAC3B,CAAC;CACF,CAAC;AAgBF,qEAAqE;AACrE,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,KAAK,EAAE,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;AACjE,MAAM,CAAC,MAAM,4BAA4B,GAAG,EAAE,KAAK,EAAE,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;AAC3E,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,KAAK,EAAE,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;AACnE,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,KAAK,EAAE,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;AACzE,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,KAAK,EAAE,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;AAClE,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,KAAK,EAAE,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;AACnE,MAAM,CAAC,MAAM,4BAA4B,GAAG,EAAE,KAAK,EAAE,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;AAC3E,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,KAAK,EAAE,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC","sourcesContent":["// Core Configuration Schema for Moro Framework\n\nimport type { AppConfig } from '../../types/config.js';\n\n// Minimal default configuration - performance-focused, most things opt-in\nexport const DEFAULT_CONFIG: AppConfig = {\n server: {\n port: 3001,\n host: 'localhost',\n // 0 = unlimited. Historically defaulted to 1000/30000 but those values\n // were VALIDATED-BUT-NEVER-APPLIED to any server, so the observed behavior\n // has always been \"unlimited connections, no request timeout\". Now that\n // both are actually wired through, keeping 0 preserves that behavior;\n // enforcing the old numbers would silently break existing deployments.\n // A user who sets either explicitly finally gets it applied.\n maxConnections: 0,\n timeout: 0, // deprecated alias for timeouts.request; 0 = disabled\n bodySizeLimit: '10mb',\n maxUploadSize: '100mb', // Separate limit for file uploads (multipart/form-data)\n // Per-phase timeouts. keepAlive/headers were previously hardcoded in the\n // Node server (5000/6000); they become documented, overridable defaults.\n // idle/request default to 0 = the per-server default (engine: 120s idle /\n // 300s request; Node: its built-in 5min requestTimeout).\n timeouts: {\n keepAlive: 5000,\n headers: 6000,\n idle: 0,\n request: 0,\n },\n // Fine-grained limits. Only multipart carries defaults here (matching the\n // parser's previous hardcodes); header/ws/high-water limits are left unset\n // so each runtime uses its own documented default unless overridden.\n limits: {\n multipart: {\n maxParts: 1000,\n maxPartHeaderBytes: '16kb',\n },\n },\n // engine: left unset so resolution can tell \"user chose it\" from \"default\".\n // Unset resolves to 'moro' (Moro's native engine, Node.js fallback if it\n // can't load); set 'node' to disable it or 'uws' to opt into uWebSockets.js.\n useUWebSockets: false, // Deprecated alias for engine: 'uws'\n requestTracking: {\n enabled: true, // Enable by default for debugging\n },\n requestLogging: {\n // Enabled in development; disabled in production where a per-request\n // stdout write is a real throughput cost. Set explicitly to override.\n enabled: process.env.NODE_ENV !== 'production',\n },\n errorBoundary: {\n enabled: true, // Always enabled for safety\n },\n },\n serviceDiscovery: {\n enabled: false,\n type: 'memory',\n consulUrl: 'http://localhost:8500',\n kubernetesNamespace: 'default',\n healthCheckInterval: 30000,\n retryAttempts: 3,\n },\n database: {},\n modules: {\n apiPrefix: '/api/', // Default prefix for module routes - set to '' to disable\n cache: {\n enabled: false, // Opt-in for better performance\n defaultTtl: 300,\n maxSize: 1000,\n strategy: 'lru',\n },\n rateLimit: {\n enabled: false, // Opt-in to avoid unnecessary overhead\n defaultRequests: 100,\n defaultWindow: 60000,\n skipSuccessfulRequests: false,\n skipFailedRequests: false,\n },\n validation: {\n enabled: false,\n stripUnknown: true,\n abortEarly: false,\n allowUnknown: false,\n },\n session: {\n enabled: false, // Opt-in\n store: 'memory',\n // No hardcoded default: a shared shipped secret is insecure. Empty means\n // \"configure one\" (mirrors csrf.secret below); the session layer should\n // warn + generate a random secret when none is set, like auth/csrf do.\n secret: '',\n name: 'connect.sid',\n rolling: false,\n resave: false,\n saveUninitialized: false,\n cookie: {\n maxAge: 86400000, // 24 hours in ms\n httpOnly: true,\n secure: false,\n sameSite: 'lax',\n path: '/',\n },\n proxy: false,\n unset: 'keep',\n },\n autoDiscovery: {\n enabled: true, // Enable by default for better DX\n paths:\n process.env.NODE_ENV === 'production'\n ? ['./dist/modules', './dist/src/modules', './modules']\n : ['./modules', './src/modules'],\n patterns: ['**/*.module.{ts,js}', '**/index.{ts,js}', '**/*.config.{ts,js}'],\n recursive: true,\n loadingStrategy: 'eager',\n watchForChanges: false, // Opt-in for development\n ignorePatterns: ['**/*.test.{ts,js}', '**/*.spec.{ts,js}', '**/node_modules/**'],\n loadOrder: 'dependency',\n failOnError: false, // Graceful degradation\n maxDepth: 5,\n },\n },\n // File-based auto routing: import route files under ./src/routes on startup.\n // Enabled by default; a no-op when the directory doesn't exist.\n routing: true,\n logging: {\n level: 'info',\n format: 'pretty',\n enableColors: true,\n enableTimestamp: true,\n enableContext: true,\n // Opt-in: appends JSON metadata tail in pretty logs. Off by default to avoid noise.\n enableMetadata: false,\n // Opt-in: includes (memory) perf info per log. Off by default to avoid the\n // process.memoryUsage() call and the \"(210MB)\" suffix.\n enablePerformance: false,\n outputs: {\n console: true,\n file: {\n enabled: false,\n path: './logs/moro.log',\n maxSize: '10MB',\n maxFiles: 5,\n },\n webhook: {\n enabled: false,\n headers: {},\n },\n },\n },\n security: {\n cors: {\n enabled: false, // Opt-in for better performance\n origin: '*',\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization'],\n exposedHeaders: [],\n credentials: false,\n maxAge: 86400, // 24 hours\n preflightContinue: false,\n },\n helmet: {\n enabled: false, // Opt-in for better performance\n // Simplified options (backward compatible)\n contentSecurityPolicy: true,\n hsts: true,\n noSniff: true,\n frameguard: true,\n // Detailed options (use these for advanced configuration)\n xFrameOptions: 'DENY',\n xContentTypeOptions: true,\n xXssProtection: true,\n referrerPolicy: 'strict-origin-when-cross-origin',\n strictTransportSecurity: {\n maxAge: 31536000,\n includeSubDomains: true,\n },\n xDownloadOptions: true,\n xPermittedCrossDomainPolicies: true,\n },\n csrf: {\n enabled: false, // Opt-in\n secret: '',\n tokenLength: 32,\n cookieName: '_csrf',\n headerName: 'x-csrf-token',\n ignoreMethods: ['GET', 'HEAD', 'OPTIONS'],\n sameSite: true,\n },\n csp: {\n enabled: false, // Opt-in\n directives: {\n defaultSrc: [\"'self'\"],\n scriptSrc: [\"'self'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n imgSrc: [\"'self'\", 'data:', 'https:'],\n connectSrc: [\"'self'\"],\n fontSrc: [\"'self'\"],\n objectSrc: [\"'none'\"],\n mediaSrc: [\"'self'\"],\n frameSrc: [\"'none'\"],\n },\n reportOnly: false,\n nonce: false,\n },\n rateLimit: {\n global: {\n enabled: false,\n requests: 1000,\n window: 60000,\n },\n },\n },\n external: {},\n performance: {\n compression: {\n enabled: false, // Opt-in to avoid overhead\n level: 6,\n threshold: 1024,\n },\n circuitBreaker: {\n enabled: false, // Opt-in to avoid overhead\n failureThreshold: 5,\n resetTimeout: 60000,\n monitoringPeriod: 10000,\n },\n clustering: {\n enabled: false,\n workers: 1,\n memoryPerWorkerGB: undefined,\n },\n },\n websocket: {\n enabled: false, // Opt-in - user must explicitly enable WebSockets\n },\n};\n\n// Schema validation is now handled by config-validator.ts\n// This export is kept for backward compatibility only\n// Note: For actual validation, use validateConfig() from config-validator.ts directly\nexport const ConfigSchema = {\n parse: (data: any): AppConfig => {\n // Simple pass-through for backward compatibility\n // Real validation happens in the config loading pipeline\n return data as AppConfig;\n },\n};\n\n// Re-export types for backward compatibility\nexport type {\n AppConfig,\n DeepPartial,\n ServerConfig,\n ServiceDiscoveryConfig,\n DatabaseConfig,\n ModuleDefaultsConfig,\n LoggingConfig,\n SecurityConfig,\n ExternalServicesConfig,\n PerformanceConfig,\n} from '../../types/config.js';\n\n// For backward compatibility with modules that expect schema objects\nexport const ServerConfigSchema = { parse: (data: any) => data };\nexport const ServiceDiscoveryConfigSchema = { parse: (data: any) => data };\nexport const DatabaseConfigSchema = { parse: (data: any) => data };\nexport const ModuleDefaultsConfigSchema = { parse: (data: any) => data };\nexport const LoggingConfigSchema = { parse: (data: any) => data };\nexport const SecurityConfigSchema = { parse: (data: any) => data };\nexport const ExternalServicesConfigSchema = { parse: (data: any) => data };\nexport const PerformanceConfigSchema = { parse: (data: any) => data };\n"]}
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/core/config/schema.ts"],"names":[],"mappings":"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","sourcesContent":["// Core Configuration Schema for Moro Framework\n\nimport type { AppConfig } from '../../types/config.js';\n\n// Minimal default configuration - performance-focused, most things opt-in\nexport const DEFAULT_CONFIG: AppConfig = {\n server: {\n port: 3001,\n host: 'localhost',\n // 0 = unlimited. Historically defaulted to 1000/30000 but those values\n // were VALIDATED-BUT-NEVER-APPLIED to any server, so the observed behavior\n // has always been \"unlimited connections, no request timeout\". Now that\n // both are actually wired through, keeping 0 preserves that behavior;\n // enforcing the old numbers would silently break existing deployments.\n // A user who sets either explicitly finally gets it applied.\n maxConnections: 0,\n timeout: 0, // deprecated alias for timeouts.request; 0 = disabled\n bodySizeLimit: '10mb',\n maxUploadSize: '100mb', // Separate limit for file uploads (multipart/form-data)\n // Per-phase timeouts. keepAlive/headers were previously hardcoded in the\n // Node server (5000/6000); they become documented, overridable defaults.\n // idle/request default to 0 = the per-server default (engine: 120s idle /\n // 300s request; Node: its built-in 5min requestTimeout).\n timeouts: {\n keepAlive: 5000,\n headers: 6000,\n idle: 0,\n request: 0,\n },\n // Fine-grained limits. Only multipart carries defaults here (matching the\n // parser's previous hardcodes); header/ws/high-water limits are left unset\n // so each runtime uses its own documented default unless overridden.\n limits: {\n multipart: {\n maxParts: 1000,\n maxPartHeaderBytes: '16kb',\n },\n },\n // engine: left unset so resolution can tell \"user chose it\" from \"default\".\n // Unset resolves to 'moro' (Moro's native engine, Node.js fallback if it\n // can't load); set 'node' to disable it or 'uws' to opt into uWebSockets.js.\n useUWebSockets: false, // Deprecated alias for engine: 'uws'\n requestTracking: {\n enabled: true, // Enable by default for debugging\n },\n requestLogging: {\n // Enabled in development; disabled in production where a per-request\n // stdout write is a real throughput cost. Set explicitly to override.\n enabled: process.env.NODE_ENV !== 'production',\n },\n errorBoundary: {\n enabled: true, // Always enabled for safety\n },\n },\n serviceDiscovery: {\n enabled: false,\n type: 'memory',\n consulUrl: 'http://localhost:8500',\n kubernetesNamespace: 'default',\n healthCheckInterval: 30000,\n retryAttempts: 3,\n },\n database: {},\n modules: {\n apiPrefix: '/api/', // Default prefix for module routes - set to '' to disable\n cache: {\n enabled: false, // Opt-in for better performance\n defaultTtl: 300,\n maxSize: 1000,\n strategy: 'lru',\n },\n rateLimit: {\n enabled: false, // Opt-in to avoid unnecessary overhead\n defaultRequests: 100,\n defaultWindow: 60000,\n skipSuccessfulRequests: false,\n skipFailedRequests: false,\n },\n validation: {\n enabled: false,\n stripUnknown: true,\n abortEarly: false,\n allowUnknown: false,\n },\n session: {\n enabled: false, // Opt-in\n store: 'memory',\n // No hardcoded default: a shared shipped secret is insecure. Empty means\n // \"configure one\" (mirrors csrf.secret below); the session layer should\n // warn + generate a random secret when none is set, like auth/csrf do.\n secret: '',\n name: 'connect.sid',\n rolling: false,\n resave: false,\n saveUninitialized: false,\n cookie: {\n maxAge: 86400000, // 24 hours in ms\n httpOnly: true,\n secure: false,\n sameSite: 'lax',\n path: '/',\n },\n proxy: false,\n unset: 'keep',\n },\n autoDiscovery: {\n enabled: true, // Enable by default for better DX\n paths:\n process.env.NODE_ENV === 'production'\n ? ['./dist/modules', './dist/src/modules', './modules']\n : ['./modules', './src/modules'],\n patterns: ['**/*.module.{ts,js}', '**/index.{ts,js}', '**/*.config.{ts,js}'],\n recursive: true,\n loadingStrategy: 'eager',\n watchForChanges: false, // Opt-in for development\n ignorePatterns: ['**/*.test.{ts,js}', '**/*.spec.{ts,js}', '**/node_modules/**'],\n loadOrder: 'dependency',\n failOnError: false, // Graceful degradation\n maxDepth: 5,\n },\n },\n // File-based auto routing: import route files under ./src/routes on startup.\n // Enabled by default; a no-op when the directory doesn't exist.\n routing: true,\n logging: {\n level: 'info',\n format: 'pretty',\n enableColors: true,\n enableTimestamp: true,\n enableContext: true,\n // Opt-in: appends JSON metadata tail in pretty logs. Off by default to avoid noise.\n enableMetadata: false,\n // Opt-in: includes (memory) perf info per log. Off by default to avoid the\n // process.memoryUsage() call and the \"(210MB)\" suffix.\n enablePerformance: false,\n outputs: {\n console: true,\n file: {\n enabled: false,\n path: './logs/moro.log',\n maxSize: '10MB',\n maxFiles: 5,\n },\n webhook: {\n enabled: false,\n headers: {},\n },\n },\n },\n security: {\n cors: {\n enabled: false, // Opt-in for better performance\n origin: '*',\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization'],\n exposedHeaders: [],\n credentials: false,\n maxAge: 86400, // 24 hours\n preflightContinue: false,\n },\n helmet: {\n enabled: false, // Opt-in for better performance\n // Simplified options (backward compatible)\n contentSecurityPolicy: true,\n hsts: true,\n noSniff: true,\n frameguard: true,\n // Detailed options (use these for advanced configuration)\n xFrameOptions: 'DENY',\n xContentTypeOptions: true,\n xXssProtection: true,\n referrerPolicy: 'strict-origin-when-cross-origin',\n strictTransportSecurity: {\n maxAge: 31536000,\n includeSubDomains: true,\n },\n xDownloadOptions: true,\n xPermittedCrossDomainPolicies: true,\n },\n csrf: {\n enabled: false, // Opt-in\n secret: '',\n tokenLength: 32,\n cookieName: '_csrf',\n headerName: 'x-csrf-token',\n ignoreMethods: ['GET', 'HEAD', 'OPTIONS'],\n sameSite: true,\n },\n csp: {\n enabled: false, // Opt-in\n directives: {\n defaultSrc: [\"'self'\"],\n scriptSrc: [\"'self'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n imgSrc: [\"'self'\", 'data:', 'https:'],\n connectSrc: [\"'self'\"],\n fontSrc: [\"'self'\"],\n objectSrc: [\"'none'\"],\n mediaSrc: [\"'self'\"],\n frameSrc: [\"'none'\"],\n },\n reportOnly: false,\n nonce: false,\n },\n rateLimit: {\n global: {\n enabled: false,\n requests: 1000,\n window: 60000,\n },\n },\n },\n external: {},\n performance: {\n compression: {\n enabled: false, // Opt-in to avoid overhead\n level: 6,\n threshold: 1024,\n maxInlineBytes: 16384, // compressed on the calling thread up to here, on the pool above\n },\n circuitBreaker: {\n enabled: false, // Opt-in to avoid overhead\n failureThreshold: 5,\n resetTimeout: 60000,\n monitoringPeriod: 10000,\n },\n clustering: {\n enabled: false,\n workers: 1,\n memoryPerWorkerGB: undefined,\n },\n },\n websocket: {\n enabled: false, // Opt-in - user must explicitly enable WebSockets\n },\n};\n\n// Schema validation is now handled by config-validator.ts\n// This export is kept for backward compatibility only\n// Note: For actual validation, use validateConfig() from config-validator.ts directly\nexport const ConfigSchema = {\n parse: (data: any): AppConfig => {\n // Simple pass-through for backward compatibility\n // Real validation happens in the config loading pipeline\n return data as AppConfig;\n },\n};\n\n// Re-export types for backward compatibility\nexport type {\n AppConfig,\n DeepPartial,\n ServerConfig,\n ServiceDiscoveryConfig,\n DatabaseConfig,\n ModuleDefaultsConfig,\n LoggingConfig,\n SecurityConfig,\n ExternalServicesConfig,\n PerformanceConfig,\n} from '../../types/config.js';\n\n// For backward compatibility with modules that expect schema objects\nexport const ServerConfigSchema = { parse: (data: any) => data };\nexport const ServiceDiscoveryConfigSchema = { parse: (data: any) => data };\nexport const DatabaseConfigSchema = { parse: (data: any) => data };\nexport const ModuleDefaultsConfigSchema = { parse: (data: any) => data };\nexport const LoggingConfigSchema = { parse: (data: any) => data };\nexport const SecurityConfigSchema = { parse: (data: any) => data };\nexport const ExternalServicesConfigSchema = { parse: (data: any) => data };\nexport const PerformanceConfigSchema = { parse: (data: any) => data };\n"]}
|
|
@@ -113,6 +113,7 @@ export declare class MoroHttpServer {
|
|
|
113
113
|
compressionEnabled: boolean;
|
|
114
114
|
/** @internal read by MoroServerResponse prototype methods */
|
|
115
115
|
compressionThreshold: number;
|
|
116
|
+
compressionMaxInlineBytes: number;
|
|
116
117
|
/** @internal read by MoroIncomingMessage prototype methods */
|
|
117
118
|
requestTrackingEnabled: boolean;
|
|
118
119
|
/** @internal read by MoroServerResponse prototype methods */
|
|
@@ -157,6 +158,7 @@ export declare class MoroHttpServer {
|
|
|
157
158
|
compression?: {
|
|
158
159
|
enabled: boolean;
|
|
159
160
|
threshold?: number;
|
|
161
|
+
maxInlineBytes?: number;
|
|
160
162
|
};
|
|
161
163
|
minimal?: boolean;
|
|
162
164
|
}): void;
|
|
@@ -25,15 +25,21 @@ const http = requireBuiltin('http');
|
|
|
25
25
|
const createServer = http.createServer;
|
|
26
26
|
let gzipFn;
|
|
27
27
|
let deflateFn;
|
|
28
|
+
let gzipSyncFn;
|
|
29
|
+
let deflateSyncFn;
|
|
28
30
|
function compressors() {
|
|
29
31
|
if (!gzipFn) {
|
|
30
32
|
const zlib = requireBuiltin('zlib');
|
|
31
33
|
gzipFn = promisify(zlib.gzip);
|
|
32
34
|
deflateFn = promisify(zlib.deflate);
|
|
35
|
+
gzipSyncFn = (buf) => zlib.gzipSync(buf);
|
|
36
|
+
deflateSyncFn = (buf) => zlib.deflateSync(buf);
|
|
33
37
|
}
|
|
34
38
|
return {
|
|
35
39
|
gzip: gzipFn,
|
|
36
40
|
deflate: deflateFn,
|
|
41
|
+
gzipSync: gzipSyncFn,
|
|
42
|
+
deflateSync: deflateSyncFn,
|
|
37
43
|
};
|
|
38
44
|
}
|
|
39
45
|
const JSON_CONTENT_TYPE = 'application/json; charset=utf-8';
|
|
@@ -383,6 +389,28 @@ export class MoroServerResponse extends http.ServerResponse {
|
|
|
383
389
|
const acceptEncoding = this.req?.headers['accept-encoding'];
|
|
384
390
|
if (acceptEncoding && acceptEncoding.includes('gzip')) {
|
|
385
391
|
const buffer = Buffer.from(jsonString, 'utf8');
|
|
392
|
+
// A small body is compressed here and now rather than on the threadpool
|
|
393
|
+
// (see compressionMaxInlineBytes); a failure takes the async path below.
|
|
394
|
+
if (server.compressionMaxInlineBytes > 0 &&
|
|
395
|
+
buffer.length <= server.compressionMaxInlineBytes) {
|
|
396
|
+
let compressed;
|
|
397
|
+
try {
|
|
398
|
+
compressed = compressors().gzipSync(buffer);
|
|
399
|
+
}
|
|
400
|
+
catch {
|
|
401
|
+
compressed = undefined;
|
|
402
|
+
}
|
|
403
|
+
if (compressed !== undefined) {
|
|
404
|
+
this.writeHead(this.statusCode || 200, {
|
|
405
|
+
'Content-Type': JSON_CONTENT_TYPE,
|
|
406
|
+
'Content-Encoding': 'gzip',
|
|
407
|
+
Vary: 'Accept-Encoding',
|
|
408
|
+
'Content-Length': compressed.length,
|
|
409
|
+
});
|
|
410
|
+
this.end(compressed);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
386
414
|
compressors()
|
|
387
415
|
.gzip(buffer)
|
|
388
416
|
.then(compressed => {
|
|
@@ -415,6 +443,26 @@ export class MoroServerResponse extends http.ServerResponse {
|
|
|
415
443
|
}
|
|
416
444
|
else if (acceptEncoding && acceptEncoding.includes('deflate')) {
|
|
417
445
|
const buffer = Buffer.from(jsonString, 'utf8');
|
|
446
|
+
if (server.compressionMaxInlineBytes > 0 &&
|
|
447
|
+
buffer.length <= server.compressionMaxInlineBytes) {
|
|
448
|
+
let compressed;
|
|
449
|
+
try {
|
|
450
|
+
compressed = compressors().deflateSync(buffer);
|
|
451
|
+
}
|
|
452
|
+
catch {
|
|
453
|
+
compressed = undefined;
|
|
454
|
+
}
|
|
455
|
+
if (compressed !== undefined) {
|
|
456
|
+
this.writeHead(this.statusCode || 200, {
|
|
457
|
+
'Content-Type': JSON_CONTENT_TYPE,
|
|
458
|
+
'Content-Encoding': 'deflate',
|
|
459
|
+
Vary: 'Accept-Encoding',
|
|
460
|
+
'Content-Length': compressed.length,
|
|
461
|
+
});
|
|
462
|
+
this.end(compressed);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
418
466
|
compressors()
|
|
419
467
|
.deflate(buffer)
|
|
420
468
|
.then(compressed => {
|
|
@@ -904,6 +952,9 @@ export class MoroHttpServer {
|
|
|
904
952
|
compressionEnabled = true;
|
|
905
953
|
/** @internal read by MoroServerResponse prototype methods */
|
|
906
954
|
compressionThreshold = 1024;
|
|
955
|
+
// Bodies at or below this size compress on the calling thread (Content-Length
|
|
956
|
+
// response); larger ones on the threadpool. 0 sends everything to the pool.
|
|
957
|
+
compressionMaxInlineBytes = 16384;
|
|
907
958
|
/** @internal read by MoroIncomingMessage prototype methods */
|
|
908
959
|
requestTrackingEnabled = true; // Generate request IDs
|
|
909
960
|
/** @internal read by MoroServerResponse prototype methods */
|
|
@@ -1012,6 +1063,9 @@ export class MoroHttpServer {
|
|
|
1012
1063
|
if (config.compression.threshold !== undefined) {
|
|
1013
1064
|
this.compressionThreshold = config.compression.threshold;
|
|
1014
1065
|
}
|
|
1066
|
+
if (config.compression.maxInlineBytes !== undefined) {
|
|
1067
|
+
this.compressionMaxInlineBytes = config.compression.maxInlineBytes;
|
|
1068
|
+
}
|
|
1015
1069
|
}
|
|
1016
1070
|
// Minimal mode - disable ALL overhead for pure speed
|
|
1017
1071
|
if (config.minimal) {
|