@noony-serverless/core 0.3.3 → 0.4.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.
Files changed (64) hide show
  1. package/build/core/containerPool.d.ts +129 -26
  2. package/build/core/containerPool.js +213 -68
  3. package/build/core/handler.d.ts +2 -2
  4. package/build/core/handler.js +6 -12
  5. package/build/core/index.d.ts +1 -0
  6. package/build/core/index.js +1 -0
  7. package/build/core/logger.d.ts +89 -1
  8. package/build/core/logger.js +136 -5
  9. package/build/core/telemetry/config.d.ts +331 -0
  10. package/build/core/telemetry/config.js +153 -0
  11. package/build/core/telemetry/index.d.ts +22 -0
  12. package/build/core/telemetry/index.js +45 -0
  13. package/build/core/telemetry/provider.d.ts +203 -0
  14. package/build/core/telemetry/provider.js +3 -0
  15. package/build/core/telemetry/providers/console-provider.d.ts +54 -0
  16. package/build/core/telemetry/providers/console-provider.js +124 -0
  17. package/build/core/telemetry/providers/index.d.ts +10 -0
  18. package/build/core/telemetry/providers/index.js +19 -0
  19. package/build/core/telemetry/providers/noop-provider.d.ts +51 -0
  20. package/build/core/telemetry/providers/noop-provider.js +67 -0
  21. package/build/core/telemetry/providers/opentelemetry-provider.d.ts +102 -0
  22. package/build/core/telemetry/providers/opentelemetry-provider.js +342 -0
  23. package/build/middlewares/ProcessingMiddleware.d.ts +6 -3
  24. package/build/middlewares/ProcessingMiddleware.js +3 -0
  25. package/build/middlewares/dependencyInjectionMiddleware.d.ts +23 -11
  26. package/build/middlewares/dependencyInjectionMiddleware.js +36 -12
  27. package/build/middlewares/guards/adapters/CustomTokenVerificationPortAdapter.d.ts +1 -1
  28. package/build/middlewares/guards/guards/FastAuthGuard.d.ts +5 -5
  29. package/build/middlewares/guards/guards/FastAuthGuard.js +3 -2
  30. package/build/middlewares/guards/guards/PermissionGuardFactory.d.ts +7 -9
  31. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.d.ts +1 -1
  32. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.js +1 -1
  33. package/build/middlewares/guards/resolvers/PermissionResolver.d.ts +1 -1
  34. package/build/middlewares/guards/resolvers/PlainPermissionResolver.d.ts +1 -1
  35. package/build/middlewares/guards/resolvers/WildcardPermissionResolver.d.ts +1 -1
  36. package/build/middlewares/guards/services/FastUserContextService.d.ts +11 -32
  37. package/build/middlewares/headerVariablesMiddleware.d.ts +8 -4
  38. package/build/middlewares/headerVariablesMiddleware.js +5 -1
  39. package/build/middlewares/httpAttributesMiddleware.d.ts +5 -3
  40. package/build/middlewares/httpAttributesMiddleware.js +3 -1
  41. package/build/middlewares/index.d.ts +1 -0
  42. package/build/middlewares/index.js +1 -0
  43. package/build/middlewares/openTelemetryMiddleware.d.ts +162 -0
  44. package/build/middlewares/openTelemetryMiddleware.js +359 -0
  45. package/build/middlewares/rateLimitingMiddleware.d.ts +8 -6
  46. package/build/middlewares/rateLimitingMiddleware.js +19 -6
  47. package/build/middlewares/securityAuditMiddleware.d.ts +6 -3
  48. package/build/middlewares/securityAuditMiddleware.js +3 -0
  49. package/build/middlewares/securityHeadersMiddleware.d.ts +5 -2
  50. package/build/middlewares/securityHeadersMiddleware.js +3 -0
  51. package/build/middlewares/validationMiddleware.d.ts +8 -4
  52. package/build/middlewares/validationMiddleware.js +5 -1
  53. package/build/utils/container.utils.js +4 -1
  54. package/build/utils/fastify-wrapper.d.ts +74 -0
  55. package/build/utils/fastify-wrapper.js +175 -0
  56. package/build/utils/index.d.ts +4 -0
  57. package/build/utils/index.js +23 -1
  58. package/build/utils/otel.helper.d.ts +122 -0
  59. package/build/utils/otel.helper.js +258 -0
  60. package/build/utils/pubsub-trace.utils.d.ts +102 -0
  61. package/build/utils/pubsub-trace.utils.js +155 -0
  62. package/build/utils/wrapper-utils.d.ts +177 -0
  63. package/build/utils/wrapper-utils.js +236 -0
  64. package/package.json +61 -2
@@ -0,0 +1,359 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.openTelemetry = exports.OpenTelemetryMiddleware = void 0;
4
+ const providers_1 = require("../core/telemetry/providers");
5
+ const pubsub_trace_utils_1 = require("../utils/pubsub-trace.utils");
6
+ /**
7
+ * OpenTelemetry Middleware
8
+ *
9
+ * Provides distributed tracing and metrics collection with:
10
+ * - Auto-detection of telemetry provider from environment
11
+ * - Graceful degradation when configuration is missing
12
+ * - Zero-configuration local development support
13
+ * - Type-safe generics to preserve middleware chain
14
+ *
15
+ * Provider Auto-Detection Priority:
16
+ * 1. Explicit provider via options.provider
17
+ * 2. New Relic (if NEW_RELIC_LICENSE_KEY set)
18
+ * 3. Datadog (if DD_API_KEY or DD_SERVICE set)
19
+ * 4. Standard OTEL (if OTEL_EXPORTER_OTLP_ENDPOINT set)
20
+ * 5. Console (if NODE_ENV=development and no OTEL endpoint)
21
+ * 6. Noop (if NODE_ENV=test or no configuration)
22
+ *
23
+ * @template TBody - Request body type
24
+ * @template TUser - Authenticated user type
25
+ *
26
+ * @example
27
+ * // Zero configuration (auto-detects provider)
28
+ * const handler = new Handler()
29
+ * .use(new OpenTelemetryMiddleware())
30
+ * .handle(async (context) => {
31
+ * // Your business logic
32
+ * });
33
+ *
34
+ * @example
35
+ * // With custom filtering
36
+ * const handler = new Handler()
37
+ * .use(new OpenTelemetryMiddleware({
38
+ * shouldTrace: (context) => context.req.path !== '/health'
39
+ * }))
40
+ * .handle(async (context) => {
41
+ * // Your business logic
42
+ * });
43
+ */
44
+ class OpenTelemetryMiddleware {
45
+ provider;
46
+ enabled;
47
+ failSilently;
48
+ propagatePubSubTraces;
49
+ extractAttributes;
50
+ shouldTrace;
51
+ customErrorHandler;
52
+ initialized = false;
53
+ constructor(options = {}) {
54
+ this.enabled = options.enabled ?? process.env.NODE_ENV !== 'test';
55
+ this.failSilently = options.failSilently ?? true;
56
+ this.propagatePubSubTraces = options.propagatePubSubTraces ?? true;
57
+ this.extractAttributes =
58
+ options.extractAttributes || this.defaultExtractAttributes;
59
+ this.shouldTrace = options.shouldTrace || (() => true);
60
+ this.customErrorHandler = options.onError || this.defaultOnError;
61
+ // Use NoopProvider if disabled
62
+ if (!this.enabled) {
63
+ this.provider = new providers_1.NoopProvider();
64
+ return;
65
+ }
66
+ // Use provided provider or auto-detect
67
+ this.provider = options.provider || this.autoDetectProvider();
68
+ }
69
+ /**
70
+ * Auto-detect telemetry provider based on environment
71
+ */
72
+ autoDetectProvider() {
73
+ // Priority 1: New Relic (check for license key and package)
74
+ if (process.env.NEW_RELIC_LICENSE_KEY) {
75
+ try {
76
+ require.resolve('newrelic');
77
+ console.log('[Telemetry] Detected New Relic configuration');
78
+ // Note: NewRelicProvider would be imported here when implemented
79
+ // const { NewRelicProvider } = require('../core/telemetry/providers/newrelic-provider');
80
+ // return new NewRelicProvider();
81
+ }
82
+ catch {
83
+ console.warn('[Telemetry] NEW_RELIC_LICENSE_KEY set but newrelic package not installed');
84
+ }
85
+ }
86
+ // Priority 2: Datadog (check for API key or service name and package)
87
+ if (process.env.DD_API_KEY || process.env.DD_SERVICE) {
88
+ try {
89
+ require.resolve('dd-trace');
90
+ console.log('[Telemetry] Detected Datadog configuration');
91
+ // Note: DatadogProvider would be imported here when implemented
92
+ // const { DatadogProvider } = require('../core/telemetry/providers/datadog-provider');
93
+ // return new DatadogProvider();
94
+ }
95
+ catch {
96
+ console.warn('[Telemetry] Datadog config detected but dd-trace package not installed');
97
+ }
98
+ }
99
+ // Priority 3: Standard OTEL (check for OTLP endpoint)
100
+ if (process.env.OTEL_EXPORTER_OTLP_ENDPOINT) {
101
+ console.log('[Telemetry] Using standard OpenTelemetry provider');
102
+ return new providers_1.OpenTelemetryProvider();
103
+ }
104
+ // Priority 4: Console (development mode without OTEL endpoint)
105
+ if (process.env.NODE_ENV === 'development' &&
106
+ !process.env.OTEL_EXPORTER_OTLP_ENDPOINT) {
107
+ console.log('[Telemetry] Using console provider for local development');
108
+ return new providers_1.ConsoleProvider();
109
+ }
110
+ // Priority 5: Noop (no configuration found)
111
+ console.log('[Telemetry] No telemetry configuration detected, using Noop provider');
112
+ return new providers_1.NoopProvider();
113
+ }
114
+ /**
115
+ * Initialize provider with configuration
116
+ *
117
+ * This should be called once at application startup.
118
+ * If not called explicitly, it will be initialized on first request.
119
+ *
120
+ * @param config Telemetry configuration
121
+ */
122
+ async initialize(config) {
123
+ if (this.initialized)
124
+ return;
125
+ if (!this.enabled) {
126
+ this.initialized = true;
127
+ return;
128
+ }
129
+ try {
130
+ // Validate provider before initialization
131
+ const validation = await this.provider.validate();
132
+ if (!validation.valid) {
133
+ console.warn(`[Telemetry] Provider '${this.provider.name}' validation failed: ${validation.reason}`);
134
+ console.warn('[Telemetry] Falling back to Noop provider');
135
+ this.provider = new providers_1.NoopProvider();
136
+ this.initialized = true;
137
+ return;
138
+ }
139
+ // Initialize provider
140
+ await this.provider.initialize(config);
141
+ // Check if provider is ready
142
+ if (!this.provider.isReady()) {
143
+ console.warn(`[Telemetry] Provider '${this.provider.name}' initialization failed, falling back to Noop`);
144
+ this.provider = new providers_1.NoopProvider();
145
+ }
146
+ else {
147
+ console.log(`[Telemetry] Provider '${this.provider.name}' initialized successfully`);
148
+ }
149
+ this.initialized = true;
150
+ }
151
+ catch (error) {
152
+ console.error('[Telemetry] Failed to initialize provider:', error);
153
+ this.provider = new providers_1.NoopProvider();
154
+ this.initialized = true;
155
+ }
156
+ }
157
+ /**
158
+ * Before hook - Create span and store in context
159
+ *
160
+ * If propagatePubSubTraces is enabled and the request is a Pub/Sub message:
161
+ * 1. Extracts W3C Trace Context from message attributes
162
+ * 2. Creates a child span linked to the publisher's trace
163
+ * 3. Enables end-to-end distributed tracing across Pub/Sub
164
+ */
165
+ async before(context) {
166
+ if (!this.enabled)
167
+ return;
168
+ // Auto-initialize with minimal config if not initialized
169
+ if (!this.initialized) {
170
+ await this.initialize({
171
+ serviceName: process.env.SERVICE_NAME || 'noony-service',
172
+ serviceVersion: process.env.SERVICE_VERSION || '1.0.0',
173
+ environment: process.env.NODE_ENV || 'production',
174
+ });
175
+ }
176
+ // Check if should trace
177
+ if (!this.shouldTrace(context)) {
178
+ return;
179
+ }
180
+ try {
181
+ // Extract trace context from Pub/Sub message if enabled
182
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
183
+ let parentContext = undefined;
184
+ if (this.propagatePubSubTraces && (0, pubsub_trace_utils_1.isPubSubMessage)(context.req.body)) {
185
+ const traceContext = (0, pubsub_trace_utils_1.extractTraceContext)(context.req.body);
186
+ if (traceContext.traceparent) {
187
+ // Store trace context for span creation
188
+ const carrier = (0, pubsub_trace_utils_1.createParentContext)(traceContext);
189
+ // Try to extract parent context using OpenTelemetry API
190
+ try {
191
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
192
+ const otelApi = require('@opentelemetry/api');
193
+ const { propagation, context: otelContext } = otelApi;
194
+ // Extract parent context from carrier
195
+ parentContext = propagation.extract(otelContext.active(), carrier);
196
+ console.log('[Telemetry] Extracted Pub/Sub trace context:', {
197
+ traceparent: traceContext.traceparent,
198
+ tracestate: traceContext.tracestate,
199
+ });
200
+ }
201
+ catch (err) {
202
+ // OpenTelemetry API not available, continue without parent context
203
+ console.warn('[Telemetry] Failed to extract Pub/Sub trace context:', err);
204
+ }
205
+ }
206
+ }
207
+ // Create span (with parent context if available)
208
+ const span = this.provider.createSpan(context);
209
+ if (!span)
210
+ return;
211
+ // If we have a parent context from Pub/Sub, link the span
212
+ if (parentContext) {
213
+ span.setAttributes({
214
+ 'messaging.system': 'pubsub',
215
+ 'messaging.operation': 'process',
216
+ 'pubsub.message_id':
217
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
218
+ context.req.body?.message?.messageId || 'unknown',
219
+ });
220
+ }
221
+ // Add custom attributes
222
+ const customAttributes = this.extractAttributes(context);
223
+ span.setAttributes(customAttributes);
224
+ // Store span and provider name in businessData
225
+ context.businessData.set('otel_span', span);
226
+ context.businessData.set('otel_provider', this.provider.name);
227
+ }
228
+ catch (error) {
229
+ if (!this.failSilently)
230
+ throw error;
231
+ console.error('[Telemetry] Error in before hook:', error);
232
+ }
233
+ }
234
+ /**
235
+ * After hook - End span with success status and add X-Trace-Id header
236
+ */
237
+ async after(context) {
238
+ if (!this.enabled)
239
+ return;
240
+ try {
241
+ const span = context.businessData.get('otel_span');
242
+ if (span) {
243
+ // Add response attributes
244
+ span.setAttributes({
245
+ 'http.status_code': context.res.statusCode || 200,
246
+ 'request.duration_ms': Date.now() - context.startTime,
247
+ });
248
+ // Add X-Trace-Id header with clean trace ID
249
+ try {
250
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
251
+ const otelApi = require('@opentelemetry/api');
252
+ const { context: otelContext, trace } = otelApi;
253
+ // Get span from active context
254
+ const activeContext = otelContext.active();
255
+ const activeSpan = trace.getSpan(activeContext);
256
+ if (activeSpan) {
257
+ const spanContext = activeSpan.spanContext();
258
+ if (spanContext.traceId) {
259
+ // Add custom header with clean trace ID (32 hex chars)
260
+ context.res.header('X-Trace-Id', spanContext.traceId);
261
+ }
262
+ }
263
+ }
264
+ catch (headerError) {
265
+ // Non-critical error - don't fail the request
266
+ console.warn('[Telemetry] Failed to add X-Trace-Id header:', headerError);
267
+ }
268
+ // Set success status (code 0 = OK in OTEL)
269
+ span.setStatus({ code: 0 });
270
+ // End span
271
+ span.end();
272
+ }
273
+ }
274
+ catch (error) {
275
+ if (!this.failSilently)
276
+ throw error;
277
+ console.error('[Telemetry] Error in after hook:', error);
278
+ }
279
+ }
280
+ /**
281
+ * Error hook - Record exception and end span
282
+ */
283
+ async onError(error, context) {
284
+ if (!this.enabled)
285
+ return;
286
+ try {
287
+ const span = context.businessData.get('otel_span');
288
+ if (span) {
289
+ // Record exception
290
+ span.recordException(error);
291
+ // Set error status (code 1 = ERROR in OTEL, code 2 = ERROR in some systems)
292
+ span.setStatus({
293
+ code: 1,
294
+ message: error.message,
295
+ });
296
+ // End span
297
+ span.end();
298
+ }
299
+ // Call custom error handler
300
+ this.customErrorHandler(error, context);
301
+ }
302
+ catch (err) {
303
+ if (!this.failSilently)
304
+ throw err;
305
+ console.error('[Telemetry] Error in onError hook:', err);
306
+ }
307
+ }
308
+ /**
309
+ * Default attribute extractor
310
+ */
311
+ defaultExtractAttributes(context) {
312
+ return {
313
+ 'http.method': context.req.method,
314
+ 'http.url': context.req.url || context.req.path,
315
+ 'http.target': context.req.path || '/',
316
+ 'request.id': context.requestId,
317
+ 'http.user_agent': context.req.headers?.['user-agent'] || '',
318
+ };
319
+ }
320
+ /**
321
+ * Default error handler
322
+ */
323
+ defaultOnError(error, _context) {
324
+ console.error('[Telemetry] Request error:', {
325
+ name: error.name,
326
+ message: error.message,
327
+ });
328
+ }
329
+ /**
330
+ * Get current provider (useful for testing)
331
+ */
332
+ getProvider() {
333
+ return this.provider;
334
+ }
335
+ /**
336
+ * Shutdown telemetry provider
337
+ *
338
+ * Should be called during application shutdown to flush pending data.
339
+ */
340
+ async shutdown() {
341
+ if (this.provider) {
342
+ await this.provider.shutdown();
343
+ }
344
+ }
345
+ }
346
+ exports.OpenTelemetryMiddleware = OpenTelemetryMiddleware;
347
+ /**
348
+ * Factory function for OpenTelemetry middleware
349
+ *
350
+ * @example
351
+ * const handler = new Handler()
352
+ * .use(openTelemetry({ shouldTrace: ctx => ctx.req.path !== '/health' }))
353
+ * .handle(async (context) => { });
354
+ */
355
+ const openTelemetry = (options = {}) => {
356
+ return new OpenTelemetryMiddleware(options);
357
+ };
358
+ exports.openTelemetry = openTelemetry;
359
+ //# sourceMappingURL=openTelemetryMiddleware.js.map
@@ -14,7 +14,7 @@ export interface RateLimitOptions {
14
14
  * Function to generate rate limiting key
15
15
  * @default Uses IP address
16
16
  */
17
- keyGenerator?: (context: Context) => string;
17
+ keyGenerator?: <TBody, TUser>(context: Context<TBody, TUser>) => string;
18
18
  /**
19
19
  * Custom error message
20
20
  * @default 'Too many requests, please try again later'
@@ -28,7 +28,7 @@ export interface RateLimitOptions {
28
28
  /**
29
29
  * Skip rate limiting for certain requests
30
30
  */
31
- skip?: (context: Context) => boolean;
31
+ skip?: <TBody, TUser>(context: Context<TBody, TUser>) => boolean;
32
32
  /**
33
33
  * Headers to include in response
34
34
  */
@@ -40,7 +40,7 @@ export interface RateLimitOptions {
40
40
  [key: string]: {
41
41
  maxRequests: number;
42
42
  windowMs: number;
43
- matcher: (context: Context) => boolean;
43
+ matcher: <TBody, TUser>(context: Context<TBody, TUser>) => boolean;
44
44
  };
45
45
  };
46
46
  /**
@@ -120,7 +120,9 @@ declare class MemoryStore implements RateLimitStore {
120
120
  * - Implement multiple protection layers within middleware
121
121
  * - Critical for security in simple deployments
122
122
  *
123
- * @implements {BaseMiddleware}
123
+ * @template TBody - The type of the request body payload (preserves type chain)
124
+ * @template TUser - The type of the authenticated user (preserves type chain)
125
+ * @implements {BaseMiddleware<TBody, TUser>}
124
126
  *
125
127
  * @example
126
128
  * Basic API rate limiting:
@@ -274,11 +276,11 @@ declare class MemoryStore implements RateLimitStore {
274
276
  * });
275
277
  * ```
276
278
  */
277
- export declare class RateLimitingMiddleware implements BaseMiddleware {
279
+ export declare class RateLimitingMiddleware<TBody = unknown, TUser = unknown> implements BaseMiddleware<TBody, TUser> {
278
280
  private store;
279
281
  private options;
280
282
  constructor(options?: RateLimitOptions);
281
- before(context: Context): Promise<void>;
283
+ before(context: Context<TBody, TUser>): Promise<void>;
282
284
  }
283
285
  /**
284
286
  * Factory function that creates a rate limiting middleware.
@@ -138,7 +138,9 @@ const getRateLimit = (context, options) => {
138
138
  * - Implement multiple protection layers within middleware
139
139
  * - Critical for security in simple deployments
140
140
  *
141
- * @implements {BaseMiddleware}
141
+ * @template TBody - The type of the request body payload (preserves type chain)
142
+ * @template TUser - The type of the authenticated user (preserves type chain)
143
+ * @implements {BaseMiddleware<TBody, TUser>}
142
144
  *
143
145
  * @example
144
146
  * Basic API rate limiting:
@@ -616,6 +618,7 @@ exports.RateLimitPresets = {
616
618
  keyGenerator: (context) => {
617
619
  // Rate limit per IP + email combination for better security
618
620
  const ip = context.req.ip || 'unknown';
621
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
619
622
  const email = context.req.parsedBody?.email;
620
623
  return email ? `auth:${email}:${ip}` : `auth:${ip}`;
621
624
  },
@@ -668,28 +671,38 @@ exports.RateLimitPresets = {
668
671
  free: {
669
672
  maxRequests: 100,
670
673
  windowMs: 60000,
671
- matcher: (context) => !context.user || context.user?.plan === 'free',
674
+ matcher: (context) =>
675
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
676
+ !context.user || context.user?.plan === 'free',
672
677
  },
673
678
  premium: {
674
679
  maxRequests: 1000,
675
680
  windowMs: 60000,
676
- matcher: (context) => context.user?.plan === 'premium',
681
+ matcher: (context) =>
682
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
683
+ context.user?.plan === 'premium',
677
684
  },
678
685
  enterprise: {
679
686
  maxRequests: 5000,
680
687
  windowMs: 60000,
681
- matcher: (context) => context.user?.plan === 'enterprise',
688
+ matcher: (context) =>
689
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
690
+ context.user?.plan === 'enterprise',
682
691
  },
683
692
  admin: {
684
693
  maxRequests: 10000,
685
694
  windowMs: 60000,
686
- matcher: (context) => context.user?.role === 'admin',
695
+ matcher: (context) =>
696
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
697
+ context.user?.role === 'admin',
687
698
  },
688
699
  },
689
700
  keyGenerator: (context) => {
690
701
  // Use user ID for authenticated, IP for anonymous
702
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
691
703
  return context.user?.id
692
- ? `user:${context.user.id}`
704
+ ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
705
+ `user:${context.user.id}`
693
706
  : `ip:${context.req.ip}`;
694
707
  },
695
708
  },
@@ -72,12 +72,15 @@ declare const securityEventTracker: SecurityEventTracker;
72
72
  /**
73
73
  * Security Audit Middleware
74
74
  * Provides comprehensive security event logging and monitoring
75
+ *
76
+ * @template TBody - The type of the request body payload (preserves type chain)
77
+ * @template TUser - The type of the authenticated user (preserves type chain)
75
78
  */
76
- export declare class SecurityAuditMiddleware implements BaseMiddleware {
79
+ export declare class SecurityAuditMiddleware<TBody = unknown, TUser = unknown> implements BaseMiddleware<TBody, TUser> {
77
80
  private options;
78
81
  constructor(options?: SecurityAuditOptions);
79
- before(context: Context): Promise<void>;
80
- after(context: Context): Promise<void>;
82
+ before(context: Context<TBody, TUser>): Promise<void>;
83
+ after(context: Context<TBody, TUser>): Promise<void>;
81
84
  onError(error: Error, context: Context): Promise<void>;
82
85
  private logSecurityEvent;
83
86
  private sanitizeHeaders;
@@ -156,6 +156,9 @@ const extractClientInfo = (context) => ({
156
156
  /**
157
157
  * Security Audit Middleware
158
158
  * Provides comprehensive security event logging and monitoring
159
+ *
160
+ * @template TBody - The type of the request body payload (preserves type chain)
161
+ * @template TUser - The type of the authenticated user (preserves type chain)
159
162
  */
160
163
  class SecurityAuditMiddleware {
161
164
  options;
@@ -75,11 +75,14 @@ export interface SecurityHeadersOptions {
75
75
  /**
76
76
  * Security Headers Middleware
77
77
  * Implements comprehensive security headers following OWASP recommendations
78
+ *
79
+ * @template TBody - The type of the request body payload (preserves type chain)
80
+ * @template TUser - The type of the authenticated user (preserves type chain)
78
81
  */
79
- export declare class SecurityHeadersMiddleware implements BaseMiddleware {
82
+ export declare class SecurityHeadersMiddleware<TBody = unknown, TUser = unknown> implements BaseMiddleware<TBody, TUser> {
80
83
  private options;
81
84
  constructor(options?: SecurityHeadersOptions);
82
- before(context: Context): Promise<void>;
85
+ before(context: Context<TBody, TUser>): Promise<void>;
83
86
  }
84
87
  /**
85
88
  * Security Headers Middleware Factory
@@ -40,6 +40,9 @@ const isOriginAllowed = (origin, allowedOrigins) => {
40
40
  /**
41
41
  * Security Headers Middleware
42
42
  * Implements comprehensive security headers following OWASP recommendations
43
+ *
44
+ * @template TBody - The type of the request body payload (preserves type chain)
45
+ * @template TUser - The type of the authenticated user (preserves type chain)
43
46
  */
44
47
  class SecurityHeadersMiddleware {
45
48
  options;
@@ -4,7 +4,9 @@ import { z } from 'zod';
4
4
  * Middleware class that validates request data (body or query parameters) using Zod schemas.
5
5
  * Automatically detects GET requests and validates query parameters, or validates body for other methods.
6
6
  *
7
- * @implements {BaseMiddleware}
7
+ * @template TBody - The type of the request body payload (preserves type chain)
8
+ * @template TUser - The type of the authenticated user (preserves type chain)
9
+ * @implements {BaseMiddleware<TBody, TUser>}
8
10
  *
9
11
  * @example
10
12
  * User registration validation:
@@ -76,15 +78,17 @@ import { z } from 'zod';
76
78
  * });
77
79
  * ```
78
80
  */
79
- export declare class ValidationMiddleware implements BaseMiddleware {
81
+ export declare class ValidationMiddleware<TBody = unknown, TUser = unknown> implements BaseMiddleware<TBody, TUser> {
80
82
  private readonly schema;
81
83
  constructor(schema: z.ZodSchema);
82
- before(context: Context): Promise<void>;
84
+ before(context: Context<TBody, TUser>): Promise<void>;
83
85
  }
84
86
  /**
85
87
  * Factory function that creates a validation middleware using Zod schema.
86
88
  * Automatically validates request body for non-GET requests or query parameters for GET requests.
87
89
  *
90
+ * @template TBody - The type of the request body payload (preserves type chain)
91
+ * @template TUser - The type of the authenticated user (preserves type chain)
88
92
  * @param schema - Zod schema to validate against
89
93
  * @returns BaseMiddleware object with validation logic
90
94
  *
@@ -150,5 +154,5 @@ export declare class ValidationMiddleware implements BaseMiddleware {
150
154
  * });
151
155
  * ```
152
156
  */
153
- export declare const validationMiddleware: (schema: z.ZodSchema) => BaseMiddleware;
157
+ export declare const validationMiddleware: <TBody = unknown, TUser = unknown>(schema: z.ZodSchema) => BaseMiddleware<TBody, TUser>;
154
158
  //# sourceMappingURL=validationMiddleware.d.ts.map
@@ -25,7 +25,9 @@ const validate = async (schema, context) => {
25
25
  * Middleware class that validates request data (body or query parameters) using Zod schemas.
26
26
  * Automatically detects GET requests and validates query parameters, or validates body for other methods.
27
27
  *
28
- * @implements {BaseMiddleware}
28
+ * @template TBody - The type of the request body payload (preserves type chain)
29
+ * @template TUser - The type of the authenticated user (preserves type chain)
30
+ * @implements {BaseMiddleware<TBody, TUser>}
29
31
  *
30
32
  * @example
31
33
  * User registration validation:
@@ -111,6 +113,8 @@ exports.ValidationMiddleware = ValidationMiddleware;
111
113
  * Factory function that creates a validation middleware using Zod schema.
112
114
  * Automatically validates request body for non-GET requests or query parameters for GET requests.
113
115
  *
116
+ * @template TBody - The type of the request body payload (preserves type chain)
117
+ * @template TUser - The type of the authenticated user (preserves type chain)
114
118
  * @param schema - Zod schema to validate against
115
119
  * @returns BaseMiddleware object with validation logic
116
120
  *
@@ -39,10 +39,13 @@ exports.getService = getService;
39
39
  * }
40
40
  * ```
41
41
  */
42
- function getService(context, serviceIdentifier) {
42
+ function getService(context,
43
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
+ serviceIdentifier) {
43
45
  if (!context.container) {
44
46
  throw new Error('Container not initialized. Did you forget to add DependencyInjectionMiddleware?');
45
47
  }
48
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
49
  return context.container.get(serviceIdentifier);
47
50
  }
48
51
  //# sourceMappingURL=container.utils.js.map