@morojs/moro 1.8.2 → 1.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/config/config-sources.js.map +1 -1
- package/dist/core/framework.d.ts +11 -0
- package/dist/core/framework.js +107 -36
- package/dist/core/framework.js.map +1 -1
- package/dist/core/graphql/core.js.map +1 -1
- package/dist/core/grpc/types.js.map +1 -1
- package/dist/core/http/moro-engine-server.js.map +1 -1
- package/dist/core/mail/mail-adapter.js.map +1 -1
- package/dist/core/middleware/built-in/cloudwatch/index.d.ts +4 -0
- package/dist/core/middleware/built-in/cloudwatch/index.js +5 -0
- package/dist/core/middleware/built-in/cloudwatch/index.js.map +1 -0
- package/dist/core/middleware/built-in/cloudwatch/middleware.d.ts +31 -0
- package/dist/core/middleware/built-in/cloudwatch/middleware.js +52 -0
- package/dist/core/middleware/built-in/cloudwatch/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/error-tracker/index.d.ts +3 -1
- package/dist/core/middleware/built-in/error-tracker/index.js +3 -2
- package/dist/core/middleware/built-in/error-tracker/index.js.map +1 -1
- package/dist/core/middleware/built-in/error-tracker/middleware.d.ts +6 -3
- package/dist/core/middleware/built-in/error-tracker/middleware.js +18 -13
- package/dist/core/middleware/built-in/error-tracker/middleware.js.map +1 -1
- package/dist/core/middleware/built-in/index.d.ts +43 -7
- package/dist/core/middleware/built-in/index.js +37 -7
- package/dist/core/middleware/built-in/index.js.map +1 -1
- package/dist/core/middleware/built-in/performance-monitor/index.d.ts +3 -1
- package/dist/core/middleware/built-in/performance-monitor/index.js +3 -2
- package/dist/core/middleware/built-in/performance-monitor/index.js.map +1 -1
- package/dist/core/middleware/built-in/performance-monitor/middleware.d.ts +3 -3
- package/dist/core/middleware/built-in/performance-monitor/middleware.js +19 -17
- package/dist/core/middleware/built-in/performance-monitor/middleware.js.map +1 -1
- package/dist/core/middleware/built-in/prometheus/core.d.ts +27 -0
- package/dist/core/middleware/built-in/prometheus/core.js +0 -0
- package/dist/core/middleware/built-in/prometheus/core.js.map +1 -0
- package/dist/core/middleware/built-in/prometheus/index.d.ts +5 -0
- package/dist/core/middleware/built-in/prometheus/index.js +6 -0
- package/dist/core/middleware/built-in/prometheus/index.js.map +1 -0
- package/dist/core/middleware/built-in/prometheus/middleware.d.ts +15 -0
- package/dist/core/middleware/built-in/prometheus/middleware.js +30 -0
- package/dist/core/middleware/built-in/prometheus/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/request-logger/index.d.ts +3 -1
- package/dist/core/middleware/built-in/request-logger/index.js +3 -2
- package/dist/core/middleware/built-in/request-logger/index.js.map +1 -1
- package/dist/core/middleware/built-in/request-logger/middleware.d.ts +4 -4
- package/dist/core/middleware/built-in/request-logger/middleware.js +14 -12
- package/dist/core/middleware/built-in/request-logger/middleware.js.map +1 -1
- package/dist/core/middleware/index.d.ts +1 -1
- package/dist/core/middleware/index.js +1 -1
- package/dist/core/middleware/index.js.map +1 -1
- package/dist/core/pooling/index.d.ts +3 -0
- package/dist/core/pooling/index.js +5 -0
- package/dist/core/pooling/index.js.map +1 -0
- package/dist/core/pooling/lru-cache.d.ts +32 -0
- package/dist/core/pooling/lru-cache.js +74 -0
- package/dist/core/pooling/lru-cache.js.map +1 -0
- package/dist/core/pooling/object-pool-manager.d.ts +3 -1
- package/dist/core/pooling/object-pool-manager.js +37 -140
- package/dist/core/pooling/object-pool-manager.js.map +1 -1
- package/dist/core/pooling/object-pool.d.ts +42 -0
- package/dist/core/pooling/object-pool.js +78 -0
- package/dist/core/pooling/object-pool.js.map +1 -0
- package/dist/core/routing/create-router.js.map +1 -1
- package/dist/core/routing/path-matcher.js +1 -43
- package/dist/core/routing/path-matcher.js.map +1 -1
- package/dist/core/utilities/hooks.d.ts +0 -1
- package/dist/core/utilities/hooks.js +0 -2
- package/dist/core/utilities/hooks.js.map +1 -1
- package/dist/core/utilities/index.d.ts +0 -1
- package/dist/core/utilities/index.js +0 -2
- package/dist/core/utilities/index.js.map +1 -1
- package/dist/core/utilities/package-utils.js +7 -0
- package/dist/core/utilities/package-utils.js.map +1 -1
- package/dist/core/utilities/self-require.d.ts +2 -0
- package/dist/core/utilities/self-require.js +13 -0
- package/dist/core/utilities/self-require.js.map +1 -0
- package/dist/core/workers/facade.d.ts +20 -4
- package/dist/core/workers/facade.js +15 -7
- package/dist/core/workers/facade.js.map +1 -1
- package/dist/core/workers/worker-manager.d.ts +12 -0
- package/dist/core/workers/worker-manager.js +27 -0
- package/dist/core/workers/worker-manager.js.map +1 -1
- package/dist/core/workers/worker.d.ts +17 -1
- package/dist/core/workers/worker.js +28 -26
- package/dist/core/workers/worker.js.map +1 -1
- package/dist/index.d.ts +39 -2
- package/dist/index.js +14 -2
- package/dist/index.js.map +1 -1
- package/dist/moro.js +25 -1
- package/dist/moro.js.map +1 -1
- 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/dist/types/module.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mail-adapter.js","sourceRoot":"","sources":["../../../src/core/mail/mail-adapter.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,mBAAmB;AAInB;;;GAGG;AACH,MAAM,OAAgB,eAAe;IACzB,MAAM,CAAM;IACZ,WAAW,GAAG,KAAK,CAAC;IAE9B;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,MAAW;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;IAYD;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CAAC,OAAsB;QACnC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,OAAO,GAAiB,EAAE,CAAC;QAEjC,KAAK,MAAM,WAAW,IAAI,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC5C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC;oBACX,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED;;OAEG;IACO,gBAAgB,CAAC,OAAkD;QAI3E,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC5B,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACO,kBAAkB,CAC1B,
|
|
1
|
+
{"version":3,"file":"mail-adapter.js","sourceRoot":"","sources":["../../../src/core/mail/mail-adapter.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,mBAAmB;AAInB;;;GAGG;AACH,MAAM,OAAgB,eAAe;IACzB,MAAM,CAAM;IACZ,WAAW,GAAG,KAAK,CAAC;IAE9B;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,MAAW;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;IAYD;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CAAC,OAAsB;QACnC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,OAAO,GAAiB,EAAE,CAAC;QAEjC,KAAK,MAAM,WAAW,IAAI,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC5C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC;oBACX,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED;;OAEG;IACO,gBAAgB,CAAC,OAAkD;QAI3E,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC5B,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACO,kBAAkB,CAC1B,SAC2F;QAE3F,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACO,iBAAiB;QACzB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,oDAAoD,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;CACF","sourcesContent":["// Base Mail Adapter Interface\n// ESM-first module\n\nimport type { MailAdapter, MailOptions, MailResult } from './types.js';\n\n/**\n * Abstract base class for mail adapters\n * Provides common functionality and interface\n */\nexport abstract class BaseMailAdapter implements MailAdapter {\n protected config: any;\n protected initialized = false;\n\n /**\n * Initialize adapter with configuration\n */\n async initialize(config: any): Promise<void> {\n this.config = config;\n this.initialized = true;\n }\n\n /**\n * Send an email (must be implemented by subclasses)\n */\n abstract send(options: MailOptions): Promise<MailResult>;\n\n /**\n * Get adapter name (must be implemented by subclasses)\n */\n abstract getName(): string;\n\n /**\n * Send multiple emails in bulk\n * Default implementation sends one by one\n * Override for better performance\n */\n async sendBulk(options: MailOptions[]): Promise<MailResult[]> {\n if (!this.initialized) {\n throw new Error(`${this.getName()} adapter not initialized`);\n }\n\n const results: MailResult[] = [];\n\n for (const mailOptions of options) {\n try {\n const result = await this.send(mailOptions);\n results.push(result);\n } catch (error) {\n results.push({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return results;\n }\n\n /**\n * Verify adapter connection (optional)\n */\n async verify(): Promise<boolean> {\n return this.initialized;\n }\n\n /**\n * Close adapter connections (optional)\n */\n async close(): Promise<void> {\n this.initialized = false;\n }\n\n /**\n * Normalize email address\n */\n protected normalizeAddress(address: string | { name?: string; email: string }): {\n name?: string;\n email: string;\n } {\n if (typeof address === 'string') {\n return { email: address };\n }\n return address;\n }\n\n /**\n * Normalize email addresses array\n */\n protected normalizeAddresses(\n addresses:\n string | string[] | { name?: string; email: string } | { name?: string; email: string }[]\n ): { name?: string; email: string }[] {\n if (!addresses) {\n return [];\n }\n\n if (Array.isArray(addresses)) {\n return addresses.map(addr => this.normalizeAddress(addr));\n }\n\n return [this.normalizeAddress(addresses)];\n }\n\n /**\n * Check if adapter is initialized\n */\n protected ensureInitialized(): void {\n if (!this.initialized) {\n throw new Error(`${this.getName()} adapter not initialized. Call initialize() first.`);\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// CloudWatch Middleware - Centralized Exports
|
|
2
|
+
export { createCloudWatchMiddleware, buildEmfRecord } from './middleware.js';
|
|
3
|
+
import { createCloudWatchMiddleware } from './middleware.js';
|
|
4
|
+
export const cloudWatch = createCloudWatchMiddleware;
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/cloudwatch/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,OAAO,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAG7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAE7D,MAAM,CAAC,MAAM,UAAU,GAAG,0BAA0B,CAAC","sourcesContent":["// CloudWatch Middleware - Centralized Exports\nexport { createCloudWatchMiddleware, buildEmfRecord } from './middleware.js';\nexport type { CloudWatchOptions } from './middleware.js';\n\nimport { createCloudWatchMiddleware } from './middleware.js';\n\nexport const cloudWatch = createCloudWatchMiddleware;\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Middleware } from '../../../../types/http.js';
|
|
2
|
+
export interface CloudWatchOptions {
|
|
3
|
+
/** CloudWatch metric namespace (default 'MoroJS') */
|
|
4
|
+
namespace?: string;
|
|
5
|
+
/** Extra static dimensions added to every record */
|
|
6
|
+
dimensions?: Record<string, string>;
|
|
7
|
+
/** Override the output sink (default: process.stdout). Useful for testing. */
|
|
8
|
+
emit?: (line: string) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Build a single EMF record for one completed request.
|
|
12
|
+
* Exported for direct unit testing.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildEmfRecord(options: {
|
|
15
|
+
namespace: string;
|
|
16
|
+
dimensions: Record<string, string>;
|
|
17
|
+
}, request: {
|
|
18
|
+
method: string;
|
|
19
|
+
path: string;
|
|
20
|
+
}, statusCode: number, durationMs: number): Record<string, any>;
|
|
21
|
+
/**
|
|
22
|
+
* CloudWatch metrics middleware (Embedded Metric Format)
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { middleware } from '@morojs/moro';
|
|
27
|
+
*
|
|
28
|
+
* app.use(middleware.cloudWatch({ namespace: 'MoroAPI' }));
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function createCloudWatchMiddleware(options?: CloudWatchOptions): Middleware;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a single EMF record for one completed request.
|
|
3
|
+
* Exported for direct unit testing.
|
|
4
|
+
*/
|
|
5
|
+
export function buildEmfRecord(options, request, statusCode, durationMs) {
|
|
6
|
+
const dimensionKeys = ['Method', 'Status', ...Object.keys(options.dimensions)];
|
|
7
|
+
return {
|
|
8
|
+
_aws: {
|
|
9
|
+
Timestamp: Date.now(),
|
|
10
|
+
CloudWatchMetrics: [
|
|
11
|
+
{
|
|
12
|
+
Namespace: options.namespace,
|
|
13
|
+
Dimensions: [dimensionKeys],
|
|
14
|
+
Metrics: [
|
|
15
|
+
{ Name: 'RequestCount', Unit: 'Count' },
|
|
16
|
+
{ Name: 'RequestDuration', Unit: 'Milliseconds' },
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
Method: request.method,
|
|
22
|
+
Status: String(statusCode),
|
|
23
|
+
...options.dimensions,
|
|
24
|
+
RequestCount: 1,
|
|
25
|
+
RequestDuration: durationMs,
|
|
26
|
+
Path: request.path,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* CloudWatch metrics middleware (Embedded Metric Format)
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { middleware } from '@morojs/moro';
|
|
35
|
+
*
|
|
36
|
+
* app.use(middleware.cloudWatch({ namespace: 'MoroAPI' }));
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function createCloudWatchMiddleware(options = {}) {
|
|
40
|
+
const namespace = options.namespace ?? 'MoroJS';
|
|
41
|
+
const dimensions = options.dimensions ?? {};
|
|
42
|
+
const emit = options.emit ?? ((line) => process.stdout.write(line + '\n'));
|
|
43
|
+
return (req, res, next) => {
|
|
44
|
+
const start = Date.now();
|
|
45
|
+
res.on('finish', () => {
|
|
46
|
+
const record = buildEmfRecord({ namespace, dimensions }, { method: req.method || 'UNKNOWN', path: req.path || '' }, res.statusCode, Date.now() - start);
|
|
47
|
+
emit(JSON.stringify(record));
|
|
48
|
+
});
|
|
49
|
+
next();
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/cloudwatch/middleware.ts"],"names":[],"mappings":"AAiBA;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAkE,EAClE,OAAyC,EACzC,UAAkB,EAClB,UAAkB;IAElB,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAE/E,OAAO;QACL,IAAI,EAAE;YACJ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,iBAAiB,EAAE;gBACjB;oBACE,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,UAAU,EAAE,CAAC,aAAa,CAAC;oBAC3B,OAAO,EAAE;wBACP,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE;wBACvC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,cAAc,EAAE;qBAClD;iBACF;aACF;SACF;QACD,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC;QAC1B,GAAG,OAAO,CAAC,UAAU;QACrB,YAAY,EAAE,CAAC;QACf,eAAe,EAAE,UAAU;QAC3B,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,0BAA0B,CAAC,UAA6B,EAAE;IACxE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,QAAQ,CAAC;IAChD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;IAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;IAEnF,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACpB,MAAM,MAAM,GAAG,cAAc,CAC3B,EAAE,SAAS,EAAE,UAAU,EAAE,EACzB,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,EACzD,GAAG,CAAC,UAAU,EACd,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CACnB,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC","sourcesContent":["// CloudWatch Middleware - zero-dependency Embedded Metric Format emitter\n//\n// Emits one EMF JSON line per request to stdout. On AWS Lambda (and any\n// environment shipping stdout to CloudWatch Logs), CloudWatch extracts these\n// as real metrics automatically — no AWS SDK, credentials, or network calls.\n// See: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Specification.html\nimport { Middleware } from '../../../../types/http.js';\n\nexport interface CloudWatchOptions {\n /** CloudWatch metric namespace (default 'MoroJS') */\n namespace?: string;\n /** Extra static dimensions added to every record */\n dimensions?: Record<string, string>;\n /** Override the output sink (default: process.stdout). Useful for testing. */\n emit?: (line: string) => void;\n}\n\n/**\n * Build a single EMF record for one completed request.\n * Exported for direct unit testing.\n */\nexport function buildEmfRecord(\n options: { namespace: string; dimensions: Record<string, string> },\n request: { method: string; path: string },\n statusCode: number,\n durationMs: number\n): Record<string, any> {\n const dimensionKeys = ['Method', 'Status', ...Object.keys(options.dimensions)];\n\n return {\n _aws: {\n Timestamp: Date.now(),\n CloudWatchMetrics: [\n {\n Namespace: options.namespace,\n Dimensions: [dimensionKeys],\n Metrics: [\n { Name: 'RequestCount', Unit: 'Count' },\n { Name: 'RequestDuration', Unit: 'Milliseconds' },\n ],\n },\n ],\n },\n Method: request.method,\n Status: String(statusCode),\n ...options.dimensions,\n RequestCount: 1,\n RequestDuration: durationMs,\n Path: request.path,\n };\n}\n\n/**\n * CloudWatch metrics middleware (Embedded Metric Format)\n *\n * @example\n * ```ts\n * import { middleware } from '@morojs/moro';\n *\n * app.use(middleware.cloudWatch({ namespace: 'MoroAPI' }));\n * ```\n */\nexport function createCloudWatchMiddleware(options: CloudWatchOptions = {}): Middleware {\n const namespace = options.namespace ?? 'MoroJS';\n const dimensions = options.dimensions ?? {};\n const emit = options.emit ?? ((line: string) => process.stdout.write(line + '\\n'));\n\n return (req, res, next) => {\n const start = Date.now();\n\n res.on('finish', () => {\n const record = buildEmfRecord(\n { namespace, dimensions },\n { method: req.method || 'UNKNOWN', path: req.path || '' },\n res.statusCode,\n Date.now() - start\n );\n emit(JSON.stringify(record));\n });\n\n next();\n };\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Error Tracker - Main entry point
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
export { createErrorTrackerMiddleware } from './middleware.js';
|
|
3
|
+
import { createErrorTrackerMiddleware } from './middleware.js';
|
|
4
|
+
export const errorTracker = createErrorTrackerMiddleware;
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/error-tracker/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/error-tracker/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAE/D,MAAM,CAAC,MAAM,YAAY,GAAG,4BAA4B,CAAC","sourcesContent":["// Error Tracker - Main entry point\nexport { createErrorTrackerMiddleware } from './middleware.js';\n\nimport { createErrorTrackerMiddleware } from './middleware.js';\n\nexport const errorTracker = createErrorTrackerMiddleware;\n"]}
|
|
@@ -5,11 +5,14 @@ import { HttpRequest, HttpResponse } from '../../../../types/http.js';
|
|
|
5
5
|
* Errors are logged and re-thrown so the framework's error handling
|
|
6
6
|
* (registered error handler / default 500) still applies.
|
|
7
7
|
*
|
|
8
|
+
* The returned middleware uses the 4-arg (err, req, res, next)
|
|
9
|
+
* error-handler shape.
|
|
10
|
+
*
|
|
8
11
|
* @example
|
|
9
12
|
* ```ts
|
|
10
|
-
* import {
|
|
13
|
+
* import { middleware } from '@morojs/moro';
|
|
11
14
|
*
|
|
12
|
-
* app.use(errorTracker);
|
|
15
|
+
* app.use(middleware.errorTracker());
|
|
13
16
|
* ```
|
|
14
17
|
*/
|
|
15
|
-
export declare
|
|
18
|
+
export declare function createErrorTrackerMiddleware(): (err: Error, req: HttpRequest, _res: HttpResponse, next: (err?: Error) => void) => void;
|
|
@@ -7,22 +7,27 @@ const logger = createFrameworkLogger('ErrorTracker');
|
|
|
7
7
|
* Errors are logged and re-thrown so the framework's error handling
|
|
8
8
|
* (registered error handler / default 500) still applies.
|
|
9
9
|
*
|
|
10
|
+
* The returned middleware uses the 4-arg (err, req, res, next)
|
|
11
|
+
* error-handler shape.
|
|
12
|
+
*
|
|
10
13
|
* @example
|
|
11
14
|
* ```ts
|
|
12
|
-
* import {
|
|
15
|
+
* import { middleware } from '@morojs/moro';
|
|
13
16
|
*
|
|
14
|
-
* app.use(errorTracker);
|
|
17
|
+
* app.use(middleware.errorTracker());
|
|
15
18
|
* ```
|
|
16
19
|
*/
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
error
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
export function createErrorTrackerMiddleware() {
|
|
21
|
+
return (err, req, _res, next) => {
|
|
22
|
+
logger.error('Request error', 'ErrorTracking', {
|
|
23
|
+
error: err.message,
|
|
24
|
+
stack: err.stack,
|
|
25
|
+
url: req.url,
|
|
26
|
+
method: req.method,
|
|
27
|
+
timestamp: new Date().toISOString(),
|
|
28
|
+
});
|
|
29
|
+
// Pass the error along so downstream error handling still runs
|
|
30
|
+
next(err);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
28
33
|
//# sourceMappingURL=middleware.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/error-tracker/middleware.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,MAAM,MAAM,GAAG,qBAAqB,CAAC,cAAc,CAAC,CAAC;AAErD
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/error-tracker/middleware.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,MAAM,MAAM,GAAG,qBAAqB,CAAC,cAAc,CAAC,CAAC;AAErD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,4BAA4B;IAC1C,OAAO,CAAC,GAAU,EAAE,GAAgB,EAAE,IAAkB,EAAE,IAA2B,EAAQ,EAAE;QAC7F,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,eAAe,EAAE;YAC7C,KAAK,EAAE,GAAG,CAAC,OAAO;YAClB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;QACH,+DAA+D;QAC/D,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC,CAAC;AACJ,CAAC","sourcesContent":["// Error Tracker Middleware\nimport { createFrameworkLogger } from '../../../logger/index.js';\nimport { HttpRequest, HttpResponse } from '../../../../types/http.js';\n\nconst logger = createFrameworkLogger('ErrorTracker');\n\n/**\n * Error tracking middleware\n * Captures and logs errors that occur during request processing.\n * Errors are logged and re-thrown so the framework's error handling\n * (registered error handler / default 500) still applies.\n *\n * The returned middleware uses the 4-arg (err, req, res, next)\n * error-handler shape.\n *\n * @example\n * ```ts\n * import { middleware } from '@morojs/moro';\n *\n * app.use(middleware.errorTracker());\n * ```\n */\nexport function createErrorTrackerMiddleware() {\n return (err: Error, req: HttpRequest, _res: HttpResponse, next: (err?: Error) => void): void => {\n logger.error('Request error', 'ErrorTracking', {\n error: err.message,\n stack: err.stack,\n url: req.url,\n method: req.method,\n timestamp: new Date().toISOString(),\n });\n // Pass the error along so downstream error handling still runs\n next(err);\n };\n}\n"]}
|
|
@@ -2,9 +2,11 @@ export { auth } from './auth/index.js';
|
|
|
2
2
|
export { rateLimit } from './rate-limit/index.js';
|
|
3
3
|
export { cors, corsHook } from './cors/index.js';
|
|
4
4
|
export { validation } from './validation/index.js';
|
|
5
|
-
export { requestLogger } from './request-logger/index.js';
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
5
|
+
export { requestLogger, createRequestLoggerMiddleware } from './request-logger/index.js';
|
|
6
|
+
export { prometheus, createPrometheusMiddleware } from './prometheus/index.js';
|
|
7
|
+
export { cloudWatch, createCloudWatchMiddleware } from './cloudwatch/index.js';
|
|
8
|
+
export { performanceMonitor, createPerformanceMonitorMiddleware, } from './performance-monitor/index.js';
|
|
9
|
+
export { errorTracker, createErrorTrackerMiddleware } from './error-tracker/index.js';
|
|
8
10
|
export { cookie } from './cookie/index.js';
|
|
9
11
|
export { csrf } from './csrf/index.js';
|
|
10
12
|
export { csp } from './csp/index.js';
|
|
@@ -33,6 +35,11 @@ export declare const builtInMiddleware: {
|
|
|
33
35
|
}) => import("../index.js").MiddlewareInterface;
|
|
34
36
|
cors: (options?: import("./cors/core.js").CORSOptions) => import("../index.js").MiddlewareInterface;
|
|
35
37
|
validation: () => import("../index.js").MiddlewareInterface;
|
|
38
|
+
requestLogger: typeof import("./request-logger/middleware.js").createRequestLoggerMiddleware;
|
|
39
|
+
performanceMonitor: typeof import("./performance-monitor/middleware.js").createPerformanceMonitorMiddleware;
|
|
40
|
+
errorTracker: typeof import("./error-tracker/middleware.js").createErrorTrackerMiddleware;
|
|
41
|
+
prometheus: typeof import("./prometheus/middleware.js").createPrometheusMiddleware;
|
|
42
|
+
cloudWatch: typeof import("./cloudwatch/middleware.js").createCloudWatchMiddleware;
|
|
36
43
|
cookie: (_config?: import("./cookie/hook.js").CookieConfig) => import("../index.js").MiddlewareInterface;
|
|
37
44
|
csrf: (options?: import("./csrf/core.js").CSRFOptions) => import("../index.js").MiddlewareInterface;
|
|
38
45
|
csp: (options?: import("./csp/core.js").CSPOptions) => import("../index.js").MiddlewareInterface;
|
|
@@ -52,8 +59,37 @@ export declare const builtInMiddleware: {
|
|
|
52
59
|
template: typeof import("./template/middleware.js").createTemplateMiddleware;
|
|
53
60
|
range: typeof import("./range/middleware.js").createRangeMiddleware;
|
|
54
61
|
};
|
|
55
|
-
export declare const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
export declare const middleware: {
|
|
63
|
+
auth: (options: import("./auth/index.js").AuthOptions) => import("../index.js").MiddlewareInterface;
|
|
64
|
+
rateLimit: (options?: {
|
|
65
|
+
windowMs?: number;
|
|
66
|
+
max?: number;
|
|
67
|
+
message?: string;
|
|
68
|
+
}) => import("../index.js").MiddlewareInterface;
|
|
69
|
+
cors: (options?: import("./cors/core.js").CORSOptions) => import("../index.js").MiddlewareInterface;
|
|
70
|
+
validation: () => import("../index.js").MiddlewareInterface;
|
|
71
|
+
requestLogger: typeof import("./request-logger/middleware.js").createRequestLoggerMiddleware;
|
|
72
|
+
performanceMonitor: typeof import("./performance-monitor/middleware.js").createPerformanceMonitorMiddleware;
|
|
73
|
+
errorTracker: typeof import("./error-tracker/middleware.js").createErrorTrackerMiddleware;
|
|
74
|
+
prometheus: typeof import("./prometheus/middleware.js").createPrometheusMiddleware;
|
|
75
|
+
cloudWatch: typeof import("./cloudwatch/middleware.js").createCloudWatchMiddleware;
|
|
76
|
+
cookie: (_config?: import("./cookie/hook.js").CookieConfig) => import("../index.js").MiddlewareInterface;
|
|
77
|
+
csrf: (options?: import("./csrf/core.js").CSRFOptions) => import("../index.js").MiddlewareInterface;
|
|
78
|
+
csp: (options?: import("./csp/core.js").CSPOptions) => import("../index.js").MiddlewareInterface;
|
|
79
|
+
sse: (options?: import("./sse/core.js").SSEOptions) => import("../index.js").MiddlewareInterface;
|
|
80
|
+
session: (options?: import("./session/core.js").SessionOptions) => import("../index.js").MiddlewareInterface;
|
|
81
|
+
cache: (options?: import("../../../index.js").CacheOptions) => import("../index.js").MiddlewareInterface;
|
|
82
|
+
cdn: (options?: import("./cdn/index.js").CDNOptions) => import("../index.js").MiddlewareInterface;
|
|
83
|
+
graphql: (options: import("./graphql/index.js").GraphQLOptions) => import("../index.js").MiddlewareInterface;
|
|
84
|
+
http2: {
|
|
85
|
+
push: typeof import("./http2/middleware.js").createHttp2PushMiddleware;
|
|
86
|
+
};
|
|
87
|
+
helmet: typeof import("./helmet/middleware.js").createHelmetMiddleware;
|
|
88
|
+
compression: typeof import("./compression/middleware.js").createCompressionMiddleware;
|
|
89
|
+
bodySize: typeof import("./body-size/middleware.js").createBodySizeMiddleware;
|
|
90
|
+
staticFiles: typeof import("./static/middleware.js").createStaticMiddleware;
|
|
91
|
+
upload: typeof import("./upload/middleware.js").createUploadMiddleware;
|
|
92
|
+
template: typeof import("./template/middleware.js").createTemplateMiddleware;
|
|
93
|
+
range: typeof import("./range/middleware.js").createRangeMiddleware;
|
|
59
94
|
};
|
|
95
|
+
export declare const MIDDLEWARE_FACTORY: unique symbol;
|
|
@@ -3,9 +3,11 @@ export { auth } from './auth/index.js';
|
|
|
3
3
|
export { rateLimit } from './rate-limit/index.js';
|
|
4
4
|
export { cors, corsHook } from './cors/index.js';
|
|
5
5
|
export { validation } from './validation/index.js';
|
|
6
|
-
export { requestLogger } from './request-logger/index.js';
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
6
|
+
export { requestLogger, createRequestLoggerMiddleware } from './request-logger/index.js';
|
|
7
|
+
export { prometheus, createPrometheusMiddleware } from './prometheus/index.js';
|
|
8
|
+
export { cloudWatch, createCloudWatchMiddleware } from './cloudwatch/index.js';
|
|
9
|
+
export { performanceMonitor, createPerformanceMonitorMiddleware, } from './performance-monitor/index.js';
|
|
10
|
+
export { errorTracker, createErrorTrackerMiddleware } from './error-tracker/index.js';
|
|
9
11
|
// Advanced Security & Performance Middleware
|
|
10
12
|
export { cookie } from './cookie/index.js';
|
|
11
13
|
export { csrf } from './csrf/index.js';
|
|
@@ -39,6 +41,8 @@ import { validation } from './validation/index.js';
|
|
|
39
41
|
import { requestLogger } from './request-logger/index.js';
|
|
40
42
|
import { performanceMonitor } from './performance-monitor/index.js';
|
|
41
43
|
import { errorTracker } from './error-tracker/index.js';
|
|
44
|
+
import { prometheus } from './prometheus/index.js';
|
|
45
|
+
import { cloudWatch } from './cloudwatch/index.js';
|
|
42
46
|
import { cookie } from './cookie/index.js';
|
|
43
47
|
import { csrf } from './csrf/index.js';
|
|
44
48
|
import { csp } from './csp/index.js';
|
|
@@ -55,11 +59,21 @@ import { staticFiles } from './static/index.js';
|
|
|
55
59
|
import { upload } from './upload/index.js';
|
|
56
60
|
import { template } from './template/index.js';
|
|
57
61
|
import { range } from './range/index.js';
|
|
62
|
+
// The built-in middleware collection. Internal framework code references
|
|
63
|
+
// `builtInMiddleware` (the `middleware` identifier is a common local/parameter
|
|
64
|
+
// name inside the framework); the public API exposes the same object under
|
|
65
|
+
// the friendly `middleware` name.
|
|
58
66
|
export const builtInMiddleware = {
|
|
59
67
|
auth,
|
|
60
68
|
rateLimit,
|
|
61
69
|
cors: corsHook,
|
|
62
70
|
validation,
|
|
71
|
+
// Observability
|
|
72
|
+
requestLogger,
|
|
73
|
+
performanceMonitor,
|
|
74
|
+
errorTracker,
|
|
75
|
+
prometheus,
|
|
76
|
+
cloudWatch,
|
|
63
77
|
// Advanced middleware
|
|
64
78
|
cookie,
|
|
65
79
|
csrf,
|
|
@@ -82,9 +96,25 @@ export const builtInMiddleware = {
|
|
|
82
96
|
template,
|
|
83
97
|
range,
|
|
84
98
|
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
99
|
+
// The Moro middleware namespace: every entry is a factory — called with
|
|
100
|
+
// options (or without, for defaults) and returns middleware. Referenced as
|
|
101
|
+
// middleware.cors(...), middleware.helmet(), middleware.requestLogger(), etc.
|
|
102
|
+
export const middleware = builtInMiddleware;
|
|
103
|
+
// Brand every built-in factory so the framework can recognize an UNCALLED
|
|
104
|
+
// factory passed where middleware is expected (app.use(middleware.helmet)
|
|
105
|
+
// instead of app.use(middleware.helmet())) and fail loudly at registration
|
|
106
|
+
// time instead of silently misbehaving at request time.
|
|
107
|
+
export const MIDDLEWARE_FACTORY = Symbol.for('morojs.middleware-factory');
|
|
108
|
+
const brandFactories = (collection) => {
|
|
109
|
+
for (const value of Object.values(collection)) {
|
|
110
|
+
if (typeof value === 'function') {
|
|
111
|
+
value[MIDDLEWARE_FACTORY] = true;
|
|
112
|
+
}
|
|
113
|
+
else if (value && typeof value === 'object') {
|
|
114
|
+
// Nested namespaces of factories (e.g. http2.push)
|
|
115
|
+
brandFactories(value);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
89
118
|
};
|
|
119
|
+
brandFactories(builtInMiddleware);
|
|
90
120
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/middleware/built-in/index.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/middleware/built-in/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Built-in Middleware Exports\nexport { auth } from './auth/index.js';\nexport { rateLimit } from './rate-limit/index.js';\nexport { cors, corsHook } from './cors/index.js';\nexport { validation } from './validation/index.js';\nexport { requestLogger, createRequestLoggerMiddleware } from './request-logger/index.js';\nexport { prometheus, createPrometheusMiddleware } from './prometheus/index.js';\nexport { cloudWatch, createCloudWatchMiddleware } from './cloudwatch/index.js';\nexport {\n performanceMonitor,\n createPerformanceMonitorMiddleware,\n} from './performance-monitor/index.js';\nexport { errorTracker, createErrorTrackerMiddleware } from './error-tracker/index.js';\n\n// Advanced Security & Performance Middleware\nexport { cookie } from './cookie/index.js';\nexport { csrf } from './csrf/index.js';\nexport { csp } from './csp/index.js';\nexport { sse } from './sse/index.js';\nexport { session } from './session/index.js';\n\n// Clean Architecture Middleware\nexport { cache } from './cache/index.js';\nexport { cdn } from './cdn/index.js';\n\n// HTTP/2 Middleware\nexport { http2 } from './http2/index.js';\n\n// HTTP Utilities Middleware\nexport { helmet } from './helmet/index.js';\nexport { compression } from './compression/index.js';\nexport { bodySize } from './body-size/index.js';\nexport { json, urlencoded } from './body-parsers/index.js';\nexport { staticFiles } from './static/index.js';\nexport { upload } from './upload/index.js';\nexport { template } from './template/index.js';\nexport { range } from './range/index.js';\n\n// Auth Helpers and Extended Providers\nexport {\n requireAuth,\n requireRole,\n requirePermission,\n requireAdmin,\n guestOnly,\n optionalAuth,\n withAuth,\n protectedRoute,\n authUtils,\n authResponses,\n sessionHelpers,\n} from './auth/helpers.js';\n\n// JWT Utilities for Custom Middleware\nexport {\n safeVerifyJWT,\n extractJWTFromHeader,\n createAuthErrorResponse,\n type JWTVerificationResult,\n} from './auth/jwt-helpers.js';\n\nexport {\n extendedProviders,\n enterpriseProviders,\n createCustomOAuthProvider,\n createCustomOIDCProvider,\n} from './auth/providers.js';\n\n// Import for collections\nimport { auth } from './auth/index.js';\nimport { rateLimit } from './rate-limit/index.js';\nimport { corsHook } from './cors/index.js';\nimport { validation } from './validation/index.js';\nimport { requestLogger } from './request-logger/index.js';\nimport { performanceMonitor } from './performance-monitor/index.js';\nimport { errorTracker } from './error-tracker/index.js';\nimport { prometheus } from './prometheus/index.js';\nimport { cloudWatch } from './cloudwatch/index.js';\nimport { cookie } from './cookie/index.js';\nimport { csrf } from './csrf/index.js';\nimport { csp } from './csp/index.js';\nimport { sse } from './sse/index.js';\nimport { session } from './session/index.js';\nimport { cache } from './cache/index.js';\nimport { cdn } from './cdn/index.js';\nimport { graphql } from './graphql/index.js';\nimport { http2 } from './http2/index.js';\nimport { helmet } from './helmet/index.js';\nimport { compression } from './compression/index.js';\nimport { bodySize } from './body-size/index.js';\nimport { staticFiles } from './static/index.js';\nimport { upload } from './upload/index.js';\nimport { template } from './template/index.js';\nimport { range } from './range/index.js';\n\n// The built-in middleware collection. Internal framework code references\n// `builtInMiddleware` (the `middleware` identifier is a common local/parameter\n// name inside the framework); the public API exposes the same object under\n// the friendly `middleware` name.\nexport const builtInMiddleware = {\n auth,\n rateLimit,\n cors: corsHook,\n validation,\n // Observability\n requestLogger,\n performanceMonitor,\n errorTracker,\n prometheus,\n cloudWatch,\n // Advanced middleware\n cookie,\n csrf,\n csp,\n sse,\n session,\n // Clean architecture middleware\n cache,\n cdn,\n // GraphQL\n graphql,\n // HTTP/2\n http2,\n // HTTP Utilities\n helmet,\n compression,\n bodySize,\n staticFiles,\n upload,\n template,\n range,\n};\n\n// The Moro middleware namespace: every entry is a factory — called with\n// options (or without, for defaults) and returns middleware. Referenced as\n// middleware.cors(...), middleware.helmet(), middleware.requestLogger(), etc.\nexport const middleware = builtInMiddleware;\n\n// Brand every built-in factory so the framework can recognize an UNCALLED\n// factory passed where middleware is expected (app.use(middleware.helmet)\n// instead of app.use(middleware.helmet())) and fail loudly at registration\n// time instead of silently misbehaving at request time.\nexport const MIDDLEWARE_FACTORY = Symbol.for('morojs.middleware-factory');\n\nconst brandFactories = (collection: Record<string, unknown>): void => {\n for (const value of Object.values(collection)) {\n if (typeof value === 'function') {\n (value as any)[MIDDLEWARE_FACTORY] = true;\n } else if (value && typeof value === 'object') {\n // Nested namespaces of factories (e.g. http2.push)\n brandFactories(value as Record<string, unknown>);\n }\n }\n};\nbrandFactories(builtInMiddleware);\n"]}
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { createPerformanceMonitorMiddleware } from './middleware.js';
|
|
2
|
+
import { createPerformanceMonitorMiddleware } from './middleware.js';
|
|
3
|
+
export declare const performanceMonitor: typeof createPerformanceMonitorMiddleware;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Performance Monitor - Main entry point
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
export { createPerformanceMonitorMiddleware } from './middleware.js';
|
|
3
|
+
import { createPerformanceMonitorMiddleware } from './middleware.js';
|
|
4
|
+
export const performanceMonitor = createPerformanceMonitorMiddleware;
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/performance-monitor/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/performance-monitor/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAE,kCAAkC,EAAE,MAAM,iBAAiB,CAAC;AAErE,OAAO,EAAE,kCAAkC,EAAE,MAAM,iBAAiB,CAAC;AAErE,MAAM,CAAC,MAAM,kBAAkB,GAAG,kCAAkC,CAAC","sourcesContent":["// Performance Monitor - Main entry point\nexport { createPerformanceMonitorMiddleware } from './middleware.js';\n\nimport { createPerformanceMonitorMiddleware } from './middleware.js';\n\nexport const performanceMonitor = createPerformanceMonitorMiddleware;\n"]}
|
|
@@ -5,9 +5,9 @@ import { HttpRequest, HttpResponse } from '../../../../types/http.js';
|
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```ts
|
|
8
|
-
* import {
|
|
8
|
+
* import { middleware } from '@morojs/moro';
|
|
9
9
|
*
|
|
10
|
-
* app.use(performanceMonitor);
|
|
10
|
+
* app.use(middleware.performanceMonitor());
|
|
11
11
|
* ```
|
|
12
12
|
*/
|
|
13
|
-
export declare
|
|
13
|
+
export declare function createPerformanceMonitorMiddleware(): (req: HttpRequest, res: HttpResponse, next: () => void) => void;
|
|
@@ -7,24 +7,26 @@ const logger = createFrameworkLogger('PerformanceMonitor');
|
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* ```ts
|
|
10
|
-
* import {
|
|
10
|
+
* import { middleware } from '@morojs/moro';
|
|
11
11
|
*
|
|
12
|
-
* app.use(performanceMonitor);
|
|
12
|
+
* app.use(middleware.performanceMonitor());
|
|
13
13
|
* ```
|
|
14
14
|
*/
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
15
|
+
export function createPerformanceMonitorMiddleware() {
|
|
16
|
+
return (req, res, next) => {
|
|
17
|
+
const startTime = Date.now();
|
|
18
|
+
res.on('finish', () => {
|
|
19
|
+
const duration = Date.now() - startTime;
|
|
20
|
+
// Log slow requests
|
|
21
|
+
if (duration > 1000) {
|
|
22
|
+
logger.warn(`Slow request detected: ${req.path} took ${duration}ms`, 'SlowRequest', {
|
|
23
|
+
path: req.path,
|
|
24
|
+
method: req.method,
|
|
25
|
+
duration,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
next();
|
|
30
|
+
};
|
|
31
|
+
}
|
|
30
32
|
//# sourceMappingURL=middleware.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/performance-monitor/middleware.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,MAAM,MAAM,GAAG,qBAAqB,CAAC,oBAAoB,CAAC,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,MAAM,
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/performance-monitor/middleware.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,MAAM,MAAM,GAAG,qBAAqB,CAAC,oBAAoB,CAAC,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kCAAkC;IAChD,OAAO,CAAC,GAAgB,EAAE,GAAiB,EAAE,IAAgB,EAAQ,EAAE;QACrE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAExC,oBAAoB;YACpB,IAAI,QAAQ,GAAG,IAAI,EAAE,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC,0BAA0B,GAAG,CAAC,IAAI,SAAS,QAAQ,IAAI,EAAE,aAAa,EAAE;oBAClF,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,QAAQ;iBACT,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC","sourcesContent":["// Performance Monitor Middleware\nimport { createFrameworkLogger } from '../../../logger/index.js';\nimport { HttpRequest, HttpResponse } from '../../../../types/http.js';\n\nconst logger = createFrameworkLogger('PerformanceMonitor');\n\n/**\n * Performance monitoring middleware\n * Tracks request duration and logs warnings for slow requests\n *\n * @example\n * ```ts\n * import { middleware } from '@morojs/moro';\n *\n * app.use(middleware.performanceMonitor());\n * ```\n */\nexport function createPerformanceMonitorMiddleware() {\n return (req: HttpRequest, res: HttpResponse, next: () => void): void => {\n const startTime = Date.now();\n\n res.on('finish', () => {\n const duration = Date.now() - startTime;\n\n // Log slow requests\n if (duration > 1000) {\n logger.warn(`Slow request detected: ${req.path} took ${duration}ms`, 'SlowRequest', {\n path: req.path,\n method: req.method,\n duration,\n });\n }\n });\n\n next();\n };\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface PrometheusOptions {
|
|
2
|
+
/** Path that serves the metrics exposition (default '/metrics') */
|
|
3
|
+
endpoint?: string;
|
|
4
|
+
/** Include process/heap/uptime gauges (default true) */
|
|
5
|
+
includeProcessMetrics?: boolean;
|
|
6
|
+
/** Include framework object-pool and route-cache metrics (default true) */
|
|
7
|
+
includePoolMetrics?: boolean;
|
|
8
|
+
/** Histogram bucket upper bounds in seconds */
|
|
9
|
+
buckets?: number[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Minimal dependency-free Prometheus metrics registry.
|
|
13
|
+
* Tracks request counters and duration histograms labeled by
|
|
14
|
+
* {method, status} — bounded label cardinality by design (no raw paths).
|
|
15
|
+
*/
|
|
16
|
+
export declare class PrometheusCore {
|
|
17
|
+
private readonly buckets;
|
|
18
|
+
private readonly includeProcessMetrics;
|
|
19
|
+
private readonly includePoolMetrics;
|
|
20
|
+
private requestCounts;
|
|
21
|
+
private durations;
|
|
22
|
+
constructor(options?: PrometheusOptions);
|
|
23
|
+
recordRequest(method: string, statusCode: number, durationMs: number): void;
|
|
24
|
+
/** Render all metrics in the Prometheus text exposition format (0.0.4). */
|
|
25
|
+
render(): string;
|
|
26
|
+
private labelsFor;
|
|
27
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/prometheus/core.ts"],"names":[],"mappings":"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","sourcesContent":["// Prometheus Core - metrics registry and text exposition rendering\nimport { getPoolManager } from '../../../pooling/object-pool-manager.js';\n\nexport interface PrometheusOptions {\n /** Path that serves the metrics exposition (default '/metrics') */\n endpoint?: string;\n /** Include process/heap/uptime gauges (default true) */\n includeProcessMetrics?: boolean;\n /** Include framework object-pool and route-cache metrics (default true) */\n includePoolMetrics?: boolean;\n /** Histogram bucket upper bounds in seconds */\n buckets?: number[];\n}\n\nconst DEFAULT_BUCKETS = [0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10];\n\ninterface HistogramSeries {\n // Per-bucket (non-cumulative) observation counts; cumulated at render time\n bucketCounts: number[];\n sum: number;\n count: number;\n}\n\n/**\n * Minimal dependency-free Prometheus metrics registry.\n * Tracks request counters and duration histograms labeled by\n * {method, status} — bounded label cardinality by design (no raw paths).\n */\nexport class PrometheusCore {\n private readonly buckets: number[];\n private readonly includeProcessMetrics: boolean;\n private readonly includePoolMetrics: boolean;\n private requestCounts = new Map<string, number>();\n private durations = new Map<string, HistogramSeries>();\n\n constructor(options: PrometheusOptions = {}) {\n this.buckets = options.buckets ?? DEFAULT_BUCKETS;\n this.includeProcessMetrics = options.includeProcessMetrics !== false;\n this.includePoolMetrics = options.includePoolMetrics !== false;\n }\n\n recordRequest(method: string, statusCode: number, durationMs: number): void {\n const key = `${method}\u0000${statusCode}`;\n this.requestCounts.set(key, (this.requestCounts.get(key) || 0) + 1);\n\n let series = this.durations.get(key);\n if (!series) {\n series = {\n bucketCounts: new Array<number>(this.buckets.length).fill(0),\n sum: 0,\n count: 0,\n };\n this.durations.set(key, series);\n }\n\n const seconds = durationMs / 1000;\n series.sum += seconds;\n series.count++;\n for (let i = 0; i < this.buckets.length; i++) {\n const bound = this.buckets[i];\n if (bound !== undefined && seconds <= bound) {\n series.bucketCounts[i] = (series.bucketCounts[i] || 0) + 1;\n break;\n }\n }\n }\n\n /** Render all metrics in the Prometheus text exposition format (0.0.4). */\n render(): string {\n const lines: string[] = [];\n\n lines.push('# HELP http_requests_total Total number of HTTP requests handled');\n lines.push('# TYPE http_requests_total counter');\n for (const [key, count] of this.requestCounts) {\n lines.push(`http_requests_total{${this.labelsFor(key)}} ${count}`);\n }\n\n lines.push('# HELP http_request_duration_seconds HTTP request duration in seconds');\n lines.push('# TYPE http_request_duration_seconds histogram');\n for (const [key, series] of this.durations) {\n const labels = this.labelsFor(key);\n let cumulative = 0;\n for (let i = 0; i < this.buckets.length; i++) {\n cumulative += series.bucketCounts[i] || 0;\n lines.push(\n `http_request_duration_seconds_bucket{${labels},le=\"${this.buckets[i]}\"} ${cumulative}`\n );\n }\n lines.push(`http_request_duration_seconds_bucket{${labels},le=\"+Inf\"} ${series.count}`);\n lines.push(`http_request_duration_seconds_sum{${labels}} ${series.sum}`);\n lines.push(`http_request_duration_seconds_count{${labels}} ${series.count}`);\n }\n\n if (this.includeProcessMetrics) {\n const memory = process.memoryUsage();\n lines.push('# HELP process_resident_memory_bytes Resident set size in bytes');\n lines.push('# TYPE process_resident_memory_bytes gauge');\n lines.push(`process_resident_memory_bytes ${memory.rss}`);\n lines.push('# HELP nodejs_heap_size_used_bytes V8 heap used in bytes');\n lines.push('# TYPE nodejs_heap_size_used_bytes gauge');\n lines.push(`nodejs_heap_size_used_bytes ${memory.heapUsed}`);\n lines.push('# HELP process_uptime_seconds Process uptime in seconds');\n lines.push('# TYPE process_uptime_seconds gauge');\n lines.push(`process_uptime_seconds ${process.uptime()}`);\n }\n\n if (this.includePoolMetrics) {\n const stats = getPoolManager().getStats();\n lines.push('# HELP moro_pool_size Current pooled object count per pool');\n lines.push('# TYPE moro_pool_size gauge');\n lines.push(`moro_pool_size{pool=\"params\"} ${stats.paramPool.poolSize}`);\n lines.push(`moro_pool_size{pool=\"query\"} ${stats.queryPool.poolSize}`);\n lines.push(`moro_pool_size{pool=\"headers\"} ${stats.headerPool.poolSize}`);\n lines.push('# HELP moro_pool_max_size Capacity per pool');\n lines.push('# TYPE moro_pool_max_size gauge');\n lines.push(`moro_pool_max_size{pool=\"params\"} ${stats.paramPool.maxSize}`);\n lines.push(`moro_pool_max_size{pool=\"query\"} ${stats.queryPool.maxSize}`);\n lines.push(`moro_pool_max_size{pool=\"headers\"} ${stats.headerPool.maxSize}`);\n lines.push('# HELP moro_route_cache_hits_total Route cache hits');\n lines.push('# TYPE moro_route_cache_hits_total counter');\n lines.push(`moro_route_cache_hits_total ${stats.routeCache.hits}`);\n lines.push('# HELP moro_route_cache_misses_total Route cache misses');\n lines.push('# TYPE moro_route_cache_misses_total counter');\n lines.push(`moro_route_cache_misses_total ${stats.routeCache.misses}`);\n }\n\n return lines.join('\\n') + '\\n';\n }\n\n private labelsFor(key: string): string {\n const separator = key.indexOf('\u0000');\n const method = key.slice(0, separator);\n const status = key.slice(separator + 1);\n return `method=\"${method}\",status=\"${status}\"`;\n }\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { PrometheusCore } from './core.js';
|
|
2
|
+
export type { PrometheusOptions } from './core.js';
|
|
3
|
+
export { createPrometheusMiddleware } from './middleware.js';
|
|
4
|
+
import { createPrometheusMiddleware } from './middleware.js';
|
|
5
|
+
export declare const prometheus: typeof createPrometheusMiddleware;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Prometheus Middleware - Centralized Exports
|
|
2
|
+
export { PrometheusCore } from './core.js';
|
|
3
|
+
export { createPrometheusMiddleware } from './middleware.js';
|
|
4
|
+
import { createPrometheusMiddleware } from './middleware.js';
|
|
5
|
+
export const prometheus = createPrometheusMiddleware;
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/middleware/built-in/prometheus/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAE7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAE7D,MAAM,CAAC,MAAM,UAAU,GAAG,0BAA0B,CAAC","sourcesContent":["// Prometheus Middleware - Centralized Exports\nexport { PrometheusCore } from './core.js';\nexport type { PrometheusOptions } from './core.js';\nexport { createPrometheusMiddleware } from './middleware.js';\n\nimport { createPrometheusMiddleware } from './middleware.js';\n\nexport const prometheus = createPrometheusMiddleware;\n"]}
|