@noony-serverless/core 0.3.4 → 0.4.1

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 (53) hide show
  1. package/README.md +199 -0
  2. package/build/core/containerPool.d.ts +129 -26
  3. package/build/core/containerPool.js +213 -68
  4. package/build/core/handler.d.ts +2 -2
  5. package/build/core/handler.js +6 -12
  6. package/build/core/index.d.ts +1 -0
  7. package/build/core/index.js +1 -0
  8. package/build/core/logger.d.ts +89 -1
  9. package/build/core/logger.js +136 -5
  10. package/build/core/telemetry/config.d.ts +331 -0
  11. package/build/core/telemetry/config.js +153 -0
  12. package/build/core/telemetry/index.d.ts +22 -0
  13. package/build/core/telemetry/index.js +45 -0
  14. package/build/core/telemetry/provider.d.ts +203 -0
  15. package/build/core/telemetry/provider.js +3 -0
  16. package/build/core/telemetry/providers/console-provider.d.ts +54 -0
  17. package/build/core/telemetry/providers/console-provider.js +124 -0
  18. package/build/core/telemetry/providers/index.d.ts +10 -0
  19. package/build/core/telemetry/providers/index.js +19 -0
  20. package/build/core/telemetry/providers/noop-provider.d.ts +51 -0
  21. package/build/core/telemetry/providers/noop-provider.js +67 -0
  22. package/build/core/telemetry/providers/opentelemetry-provider.d.ts +102 -0
  23. package/build/core/telemetry/providers/opentelemetry-provider.js +342 -0
  24. package/build/middlewares/bodyValidationMiddleware.js +1 -1
  25. package/build/middlewares/dependencyInjectionMiddleware.d.ts +16 -8
  26. package/build/middlewares/dependencyInjectionMiddleware.js +31 -11
  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/index.d.ts +1 -0
  38. package/build/middlewares/index.js +1 -0
  39. package/build/middlewares/openTelemetryMiddleware.d.ts +162 -0
  40. package/build/middlewares/openTelemetryMiddleware.js +359 -0
  41. package/build/middlewares/rateLimitingMiddleware.js +16 -5
  42. package/build/utils/container.utils.js +4 -1
  43. package/build/utils/fastify-wrapper.d.ts +74 -0
  44. package/build/utils/fastify-wrapper.js +175 -0
  45. package/build/utils/index.d.ts +4 -0
  46. package/build/utils/index.js +23 -1
  47. package/build/utils/otel.helper.d.ts +122 -0
  48. package/build/utils/otel.helper.js +258 -0
  49. package/build/utils/pubsub-trace.utils.d.ts +102 -0
  50. package/build/utils/pubsub-trace.utils.js +155 -0
  51. package/build/utils/wrapper-utils.d.ts +177 -0
  52. package/build/utils/wrapper-utils.js +236 -0
  53. package/package.json +61 -2
@@ -0,0 +1,342 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenTelemetryProvider = void 0;
4
+ /**
5
+ * Standard OpenTelemetry SDK 2.0 Provider
6
+ *
7
+ * Implements telemetry using the official OpenTelemetry JavaScript SDK.
8
+ * Supports OTLP exporters for traces, metrics, and logs.
9
+ *
10
+ * Requirements:
11
+ * - Node.js >= 18.19.0 or >= 20.6.0
12
+ * - OTEL_EXPORTER_OTLP_ENDPOINT environment variable
13
+ * - @opentelemetry/sdk-node and related packages installed
14
+ *
15
+ * Auto-selected when OTEL_EXPORTER_OTLP_ENDPOINT is set.
16
+ *
17
+ * @example
18
+ * // Environment setup
19
+ * OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces
20
+ *
21
+ * // Usage
22
+ * const provider = new OpenTelemetryProvider();
23
+ * const validation = await provider.validate();
24
+ * if (validation.valid) {
25
+ * await provider.initialize({
26
+ * serviceName: 'my-service',
27
+ * serviceVersion: '1.0.0'
28
+ * });
29
+ * }
30
+ */
31
+ class OpenTelemetryProvider {
32
+ name = 'opentelemetry';
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ sdk; // NodeSDK
35
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
+ tracer; // Tracer
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ meter; // Meter
39
+ ready = false;
40
+ /**
41
+ * Validate OpenTelemetry configuration
42
+ *
43
+ * Checks:
44
+ * 1. OTEL_EXPORTER_OTLP_ENDPOINT is set
45
+ * 2. Endpoint is a valid URL
46
+ * 3. Required packages are available (checked lazily during init)
47
+ */
48
+ async validate() {
49
+ const endpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
50
+ if (!endpoint) {
51
+ return {
52
+ valid: false,
53
+ reason: 'OTEL_EXPORTER_OTLP_ENDPOINT environment variable not set',
54
+ };
55
+ }
56
+ try {
57
+ new URL(endpoint);
58
+ }
59
+ catch {
60
+ return {
61
+ valid: false,
62
+ reason: `OTEL_EXPORTER_OTLP_ENDPOINT is not a valid URL: ${endpoint}`,
63
+ };
64
+ }
65
+ return { valid: true };
66
+ }
67
+ /**
68
+ * Initialize OpenTelemetry SDK
69
+ *
70
+ * Sets up:
71
+ * - Resource attributes (service name, version, environment)
72
+ * - OTLP trace exporter
73
+ * - Composite propagator (W3C + Cloud Trace)
74
+ * - Tracer and Meter providers
75
+ */
76
+ async initialize(config) {
77
+ try {
78
+ // Dynamic require to avoid compile-time dependency on OTEL packages
79
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
80
+ const otelApi = require('@opentelemetry/api');
81
+ const { trace, metrics } = otelApi;
82
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
83
+ const sdkNode = require('@opentelemetry/sdk-node');
84
+ const { NodeSDK } = sdkNode;
85
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
86
+ const exporterHttp = require('@opentelemetry/exporter-trace-otlp-http');
87
+ const { OTLPTraceExporter } = exporterHttp;
88
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
89
+ const resources = require('@opentelemetry/resources');
90
+ const { Resource } = resources;
91
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
92
+ const semConv = require('@opentelemetry/semantic-conventions');
93
+ const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } = semConv;
94
+ // Create resource with service metadata
95
+ const resource = new Resource({
96
+ [ATTR_SERVICE_NAME]: config.serviceName,
97
+ [ATTR_SERVICE_VERSION]: config.serviceVersion || '1.0.0',
98
+ environment: config.environment || 'production',
99
+ });
100
+ // Configure trace exporter
101
+ const traceExporter = new OTLPTraceExporter({
102
+ url: config.exporters?.traces?.[0]?.endpoint ||
103
+ process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
104
+ headers: config.exporters?.traces?.[0]?.headers,
105
+ timeoutMillis: config.exporters?.traces?.[0]?.timeout,
106
+ });
107
+ // Configure composite propagator for W3C + Cloud Trace support
108
+ const textMapPropagator = this.createPropagator(config);
109
+ // Initialize SDK
110
+ this.sdk = new NodeSDK({
111
+ resource,
112
+ traceExporter,
113
+ textMapPropagator, // Use composite propagator
114
+ });
115
+ await this.sdk.start();
116
+ // Get tracer and meter
117
+ this.tracer = trace.getTracer(config.serviceName, config.serviceVersion || '1.0.0');
118
+ this.meter = metrics.getMeter(config.serviceName, config.serviceVersion || '1.0.0');
119
+ this.ready = true;
120
+ console.log('[Telemetry] OpenTelemetry provider initialized');
121
+ console.log('[Telemetry] Exporting to:', config.exporters?.traces?.[0]?.endpoint ||
122
+ process.env.OTEL_EXPORTER_OTLP_ENDPOINT);
123
+ }
124
+ catch (error) {
125
+ console.error('[Telemetry] Failed to initialize OpenTelemetry provider:', error);
126
+ this.ready = false;
127
+ // Check if error is due to missing packages
128
+ if (error instanceof Error &&
129
+ error.message.includes('Cannot find module')) {
130
+ console.error('[Telemetry] OpenTelemetry packages not installed. Run:');
131
+ console.error(' npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/exporter-trace-otlp-http @opentelemetry/resources @opentelemetry/semantic-conventions');
132
+ }
133
+ }
134
+ }
135
+ /**
136
+ * Create an OpenTelemetry span
137
+ *
138
+ * Creates a SERVER span with HTTP semantic conventions.
139
+ * Returns undefined if provider is not ready.
140
+ */
141
+ createSpan(context) {
142
+ if (!this.ready || !this.tracer)
143
+ return undefined;
144
+ try {
145
+ // Dynamic import for SpanKind
146
+ const SpanKind = 1; // SERVER = 1 in OpenTelemetry
147
+ const span = this.tracer.startSpan('http.request', {
148
+ kind: SpanKind,
149
+ attributes: {
150
+ 'http.method': context.req.method,
151
+ 'http.url': context.req.url || context.req.path,
152
+ 'http.target': context.req.path || '/',
153
+ 'request.id': context.requestId,
154
+ 'http.user_agent': context.req.headers?.['user-agent'] || '',
155
+ },
156
+ });
157
+ return {
158
+ setAttributes: (attrs) => {
159
+ span.setAttributes(attrs);
160
+ },
161
+ recordException: (error) => {
162
+ span.recordException(error);
163
+ },
164
+ setStatus: (status) => {
165
+ span.setStatus(status);
166
+ },
167
+ end: () => {
168
+ span.end();
169
+ },
170
+ };
171
+ }
172
+ catch (error) {
173
+ console.error('[Telemetry] Failed to create span:', error);
174
+ return undefined;
175
+ }
176
+ }
177
+ /**
178
+ * Record a metric as a histogram
179
+ */
180
+ recordMetric(name, value, attributes) {
181
+ if (!this.ready || !this.meter)
182
+ return;
183
+ try {
184
+ const histogram = this.meter.createHistogram(name, {
185
+ description: `Histogram for ${name}`,
186
+ unit: 'ms',
187
+ });
188
+ histogram.record(value, attributes);
189
+ }
190
+ catch (error) {
191
+ console.error('[Telemetry] Failed to record metric:', error);
192
+ }
193
+ }
194
+ /**
195
+ * Log with trace correlation
196
+ *
197
+ * Adds trace and span IDs to log output when available.
198
+ */
199
+ log(level, message, attributes) {
200
+ if (!this.ready)
201
+ return;
202
+ try {
203
+ // Try to get active span for correlation
204
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
205
+ const { trace } = require('@opentelemetry/api');
206
+ const span = trace.getActiveSpan();
207
+ const traceContext = span
208
+ ? {
209
+ traceId: span.spanContext().traceId,
210
+ spanId: span.spanContext().spanId,
211
+ traceFlags: span.spanContext().traceFlags,
212
+ }
213
+ : {};
214
+ console.log(JSON.stringify({
215
+ level,
216
+ message,
217
+ ...traceContext,
218
+ ...attributes,
219
+ timestamp: new Date().toISOString(),
220
+ }));
221
+ }
222
+ catch (error) {
223
+ // Fallback to simple logging
224
+ console.log(JSON.stringify({ level, message, ...attributes }));
225
+ }
226
+ }
227
+ /**
228
+ * Check if OpenTelemetry provider is ready
229
+ */
230
+ isReady() {
231
+ return this.ready;
232
+ }
233
+ /**
234
+ * Shutdown OpenTelemetry SDK
235
+ *
236
+ * Flushes pending telemetry data and closes exporters.
237
+ */
238
+ async shutdown() {
239
+ if (this.ready && this.sdk) {
240
+ try {
241
+ await this.sdk.shutdown();
242
+ console.log('[Telemetry] OpenTelemetry provider shutdown complete');
243
+ }
244
+ catch (error) {
245
+ console.error('[Telemetry] Error during shutdown:', error);
246
+ }
247
+ finally {
248
+ this.ready = false;
249
+ }
250
+ }
251
+ }
252
+ /**
253
+ * Create composite propagator based on configuration
254
+ *
255
+ * Supports:
256
+ * - W3C Trace Context (traceparent/tracestate)
257
+ * - Google Cloud Trace Context (X-Cloud-Trace-Context)
258
+ *
259
+ * When running on GCP, both formats are enabled by default for compatibility.
260
+ * This allows trace IDs to be synchronized between Cloud Run Load Balancer
261
+ * and your application.
262
+ *
263
+ * @param config Telemetry configuration
264
+ * @returns Configured propagator (W3C, Cloud Trace, or Composite)
265
+ */
266
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
267
+ createPropagator(config) {
268
+ try {
269
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
270
+ const propagators = [];
271
+ // Determine which propagators to use
272
+ const useCloudTrace = config.propagation?.cloudTrace ?? this.isRunningOnGCP();
273
+ const useW3C = config.propagation?.w3c ?? true;
274
+ // Add Cloud Trace propagator (priority 1 - reads X-Cloud-Trace-Context from GCP)
275
+ if (useCloudTrace) {
276
+ try {
277
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
278
+ const cloudPropagator = require('@google-cloud/opentelemetry-cloud-trace-propagator');
279
+ const { CloudPropagator } = cloudPropagator;
280
+ propagators.push(new CloudPropagator());
281
+ console.log('[Telemetry] CloudPropagator enabled for GCP trace compatibility');
282
+ }
283
+ catch (error) {
284
+ console.warn('[Telemetry] CloudPropagator requested but package not installed:', error instanceof Error ? error.message : error);
285
+ console.warn('[Telemetry] Install with: npm install @google-cloud/opentelemetry-cloud-trace-propagator');
286
+ }
287
+ }
288
+ // Add W3C Trace Context propagator (priority 2 - standard traceparent)
289
+ if (useW3C) {
290
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
291
+ const otelCore = require('@opentelemetry/core');
292
+ const { W3CTraceContextPropagator } = otelCore;
293
+ propagators.push(new W3CTraceContextPropagator());
294
+ console.log('[Telemetry] W3CTraceContextPropagator enabled');
295
+ }
296
+ // If multiple propagators, use CompositePropagator
297
+ if (propagators.length > 1) {
298
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
299
+ const otelCore = require('@opentelemetry/core');
300
+ const { CompositePropagator } = otelCore;
301
+ return new CompositePropagator({ propagators });
302
+ }
303
+ // If only one propagator, use it directly
304
+ if (propagators.length === 1) {
305
+ return propagators[0];
306
+ }
307
+ // Fallback to W3C if no propagators configured
308
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
309
+ const otelCore = require('@opentelemetry/core');
310
+ const { W3CTraceContextPropagator } = otelCore;
311
+ return new W3CTraceContextPropagator();
312
+ }
313
+ catch (error) {
314
+ console.error('[Telemetry] Failed to create propagator:', error);
315
+ // Return W3C propagator as safe fallback
316
+ try {
317
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
318
+ const otelCore = require('@opentelemetry/core');
319
+ const { W3CTraceContextPropagator } = otelCore;
320
+ return new W3CTraceContextPropagator();
321
+ }
322
+ catch (fallbackError) {
323
+ console.error('[Telemetry] Failed to create fallback propagator:', fallbackError);
324
+ return undefined;
325
+ }
326
+ }
327
+ }
328
+ /**
329
+ * Detect if running on Google Cloud Platform
330
+ */
331
+ isRunningOnGCP() {
332
+ return !!(process.env.GOOGLE_CLOUD_PROJECT ||
333
+ process.env.GCLOUD_PROJECT ||
334
+ process.env.GCP_PROJECT ||
335
+ process.env.K_SERVICE || // Cloud Run
336
+ process.env.FUNCTION_NAME || // Cloud Functions
337
+ process.env.GAE_APPLICATION // App Engine
338
+ );
339
+ }
340
+ }
341
+ exports.OpenTelemetryProvider = OpenTelemetryProvider;
342
+ //# sourceMappingURL=opentelemetry-provider.js.map
@@ -91,7 +91,7 @@ exports.BodyValidationMiddleware = BodyValidationMiddleware;
91
91
  // Modified to fix type instantiation error
92
92
  const bodyValidatorMiddleware = (schema) => ({
93
93
  before: async (context) => {
94
- context.req.parsedBody = await validateBody(schema, context.req.body);
94
+ context.req.parsedBody = await validateBody(schema, context.req.parsedBody);
95
95
  },
96
96
  });
97
97
  exports.bodyValidatorMiddleware = bodyValidatorMiddleware;
@@ -1,4 +1,5 @@
1
1
  import { BaseMiddleware, Context } from '../core';
2
+ import { ServiceDefinition } from '../core/containerPool';
2
3
  /**
3
4
  * Middleware to inject dependencies into the request context using typedi.
4
5
  * This allows handlers to access shared services or data via context.container.
@@ -149,10 +150,14 @@ import { BaseMiddleware, Context } from '../core';
149
150
  */
150
151
  export declare class DependencyInjectionMiddleware<TBody = unknown, TUser = unknown> implements BaseMiddleware<TBody, TUser> {
151
152
  private services;
152
- constructor(services: {
153
- id: any;
154
- value: any;
155
- }[]);
153
+ private options?;
154
+ constructor(services?: ServiceDefinition[], options?: {
155
+ /**
156
+ * Service scope: 'global' for process-lifetime, 'local' for request-lifetime
157
+ * @default 'local'
158
+ */
159
+ scope?: "global" | "local";
160
+ } | undefined);
156
161
  before(context: Context<TBody, TUser>): Promise<void>;
157
162
  }
158
163
  /**
@@ -249,8 +254,11 @@ export declare class DependencyInjectionMiddleware<TBody = unknown, TUser = unkn
249
254
  * });
250
255
  * ```
251
256
  */
252
- export declare const dependencyInjection: <TBody = unknown, TUser = unknown>(services?: {
253
- id: any;
254
- value: any;
255
- }[]) => BaseMiddleware<TBody, TUser>;
257
+ export declare const dependencyInjection: <TBody = unknown, TUser = unknown>(services?: ServiceDefinition[], options?: {
258
+ /**
259
+ * Service scope: 'global' for process-lifetime, 'local' for request-lifetime
260
+ * @default 'local'
261
+ */
262
+ scope?: "global" | "local";
263
+ }) => BaseMiddleware<TBody, TUser>;
256
264
  //# sourceMappingURL=dependencyInjectionMiddleware.d.ts.map
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.dependencyInjection = exports.DependencyInjectionMiddleware = void 0;
5
- const typedi_1 = require("typedi");
5
+ const containerPool_1 = require("../core/containerPool");
6
6
  /**
7
7
  * Middleware to inject dependencies into the request context using typedi.
8
8
  * This allows handlers to access shared services or data via context.container.
@@ -153,14 +153,25 @@ const typedi_1 = require("typedi");
153
153
  */
154
154
  class DependencyInjectionMiddleware {
155
155
  services;
156
- constructor(services) {
156
+ options;
157
+ constructor(services = [], options) {
157
158
  this.services = services;
159
+ this.options = options;
158
160
  }
159
161
  async before(context) {
160
- this.services.forEach((service) => {
161
- typedi_1.Container.set(service.id, service.value);
162
- });
163
- context.container = typedi_1.Container.of();
162
+ const scope = this.options?.scope || 'local';
163
+ if (scope === 'global') {
164
+ // Register services globally (process-lifetime)
165
+ // ⚠️ Use sparingly - only for truly shared services like DB connections
166
+ containerPool_1.containerPool.initializeGlobal(this.services);
167
+ }
168
+ else {
169
+ // Register services locally (request-lifetime)
170
+ // ✅ Recommended for most use cases - isolated per request
171
+ this.services.forEach((service) => {
172
+ context.container?.set(service.id, service.value);
173
+ });
174
+ }
164
175
  }
165
176
  }
166
177
  exports.DependencyInjectionMiddleware = DependencyInjectionMiddleware;
@@ -258,12 +269,21 @@ exports.DependencyInjectionMiddleware = DependencyInjectionMiddleware;
258
269
  * });
259
270
  * ```
260
271
  */
261
- const dependencyInjection = (services = []) => ({
272
+ const dependencyInjection = (services = [], options) => ({
262
273
  before: async (context) => {
263
- services.forEach((service) => {
264
- typedi_1.Container.set(service.id, service.value);
265
- });
266
- context.container = typedi_1.Container.of();
274
+ const scope = options?.scope || 'local';
275
+ if (scope === 'global') {
276
+ // Register services globally (process-lifetime)
277
+ // ⚠️ Use sparingly - only for truly shared services like DB connections
278
+ containerPool_1.containerPool.initializeGlobal(services);
279
+ }
280
+ else {
281
+ // Register services locally (request-lifetime)
282
+ // ✅ Recommended for most use cases - isolated per request
283
+ services.forEach((service) => {
284
+ context.container?.set(service.id, service.value);
285
+ });
286
+ }
267
287
  },
268
288
  });
269
289
  exports.dependencyInjection = dependencyInjection;
@@ -245,7 +245,7 @@ export declare class TokenVerificationAdapterFactory {
245
245
  * @param expirationField - Optional field name for expiration (e.g., 'expiresAt', 'exp')
246
246
  * @returns Configured adapter for API key tokens
247
247
  */
248
- static forAPIKey<T extends Record<string, any>>(verificationPort: CustomTokenVerificationPort<T>, userIdField: keyof T, expirationField?: keyof T): CustomTokenVerificationPortAdapter<T>;
248
+ static forAPIKey<T extends object>(verificationPort: CustomTokenVerificationPort<T>, userIdField: keyof T, expirationField?: keyof T): CustomTokenVerificationPortAdapter<T>;
249
249
  /**
250
250
  * Create adapter for OAuth tokens with standard OAuth claims.
251
251
  *
@@ -43,7 +43,7 @@ export interface AuthenticationResult {
43
43
  success: boolean;
44
44
  user?: UserContext;
45
45
  token?: {
46
- decoded: any;
46
+ decoded: unknown;
47
47
  raw: string;
48
48
  expiresAt: string;
49
49
  issuer?: string;
@@ -63,7 +63,7 @@ export interface AuthGuardConfig {
63
63
  allowedIssuers?: string[];
64
64
  requireEmailVerification: boolean;
65
65
  allowInactiveUsers: boolean;
66
- customValidation?: (token: any, user: UserContext) => Promise<boolean>;
66
+ customValidation?: (token: unknown, user: UserContext) => Promise<boolean>;
67
67
  }
68
68
  /**
69
69
  * Token validation service interface
@@ -74,17 +74,17 @@ export interface TokenValidator {
74
74
  */
75
75
  validateToken(token: string): Promise<{
76
76
  valid: boolean;
77
- decoded?: any;
77
+ decoded?: unknown;
78
78
  error?: string;
79
79
  }>;
80
80
  /**
81
81
  * Extract user ID from decoded token
82
82
  */
83
- extractUserId(decoded: any): string;
83
+ extractUserId(decoded: unknown): string;
84
84
  /**
85
85
  * Check if token is expired
86
86
  */
87
- isTokenExpired(decoded: any): boolean;
87
+ isTokenExpired(decoded: unknown): boolean;
88
88
  }
89
89
  /**
90
90
  * Fast Authentication Guard Implementation
@@ -215,14 +215,15 @@ let FastAuthGuard = class FastAuthGuard {
215
215
  }
216
216
  }
217
217
  // Build successful authentication result
218
+ const decoded = tokenValidation.decoded;
218
219
  const authResult = {
219
220
  success: true,
220
221
  user: userContext,
221
222
  token: {
222
223
  decoded: tokenValidation.decoded,
223
224
  raw: token,
224
- expiresAt: new Date(tokenValidation.decoded.exp * 1000).toISOString(),
225
- issuer: tokenValidation.decoded.iss,
225
+ expiresAt: new Date(decoded.exp * 1000).toISOString(),
226
+ issuer: decoded.iss,
226
227
  },
227
228
  cached: false,
228
229
  resolutionTimeUs: Number(process.hrtime.bigint() - startTime) / 1000,
@@ -162,16 +162,14 @@ export declare class PermissionGuardFactory {
162
162
  getStats(): {
163
163
  totalGuards: number;
164
164
  guardsByType: Record<string, number>;
165
- individualGuardStats: {
166
- guardType: string;
167
- checkCount: number;
168
- successCount: number;
169
- failureCount: number;
170
- successRate: number;
165
+ individualGuardStats: ReturnType<BasePermissionGuard['getStats']>[];
166
+ aggregatedStats: {
167
+ totalChecks: number;
168
+ totalSuccesses: number;
169
+ totalFailures: number;
170
+ overallSuccessRate: number;
171
171
  averageProcessingTimeUs: number;
172
- totalProcessingTimeUs: number;
173
- }[];
174
- aggregatedStats: any;
172
+ };
175
173
  };
176
174
  /**
177
175
  * Clear guard cache
@@ -118,7 +118,7 @@ export declare class ExpressionPermissionResolver extends PermissionResolver<Per
118
118
  /**
119
119
  * Check if this resolver can handle the given requirement type
120
120
  */
121
- canHandle(requirement: any): requirement is PermissionExpression;
121
+ canHandle(requirement: unknown): requirement is PermissionExpression;
122
122
  /**
123
123
  * Normalize expression for consistent cache keys
124
124
  *
@@ -412,7 +412,7 @@ class ExpressionPermissionResolver extends PermissionResolver_1.PermissionResolv
412
412
  * Check if this resolver can handle the given requirement type
413
413
  */
414
414
  canHandle(requirement) {
415
- return (requirement &&
415
+ return (!!requirement &&
416
416
  typeof requirement === 'object' &&
417
417
  PermissionResolver_1.PermissionUtils.isValidExpression(requirement));
418
418
  }
@@ -19,7 +19,7 @@
19
19
  * different types of permission requirements. The generic type T represents
20
20
  * the specific requirement format for each resolver.
21
21
  */
22
- export declare abstract class PermissionResolver<T = any> {
22
+ export declare abstract class PermissionResolver<T = unknown> {
23
23
  /**
24
24
  * Check if user permissions satisfy the requirement
25
25
  *
@@ -96,6 +96,6 @@ export declare class PlainPermissionResolver extends PermissionResolver<string[]
96
96
  * @param requirement - The requirement to check
97
97
  * @returns true if this resolver can handle the requirement
98
98
  */
99
- canHandle(requirement: any): requirement is string[];
99
+ canHandle(requirement: unknown): requirement is string[];
100
100
  }
101
101
  //# sourceMappingURL=PlainPermissionResolver.d.ts.map
@@ -141,6 +141,6 @@ export declare class WildcardPermissionResolver extends PermissionResolver<strin
141
141
  /**
142
142
  * Check if this resolver can handle the given requirement type
143
143
  */
144
- canHandle(requirement: any): requirement is string[];
144
+ canHandle(requirement: unknown): requirement is string[];
145
145
  }
146
146
  //# sourceMappingURL=WildcardPermissionResolver.d.ts.map