@pawells/nestjs-shared 1.0.0-dev.4c8c698

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 (286) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +802 -0
  3. package/build/LICENSE +21 -0
  4. package/build/README.md +802 -0
  5. package/build/common/common.module.d.ts +49 -0
  6. package/build/common/common.module.d.ts.map +1 -0
  7. package/build/common/common.module.js +178 -0
  8. package/build/common/common.module.js.map +1 -0
  9. package/build/common/constants/histogram-buckets.constants.d.ts +12 -0
  10. package/build/common/constants/histogram-buckets.constants.d.ts.map +1 -0
  11. package/build/common/constants/histogram-buckets.constants.js +51 -0
  12. package/build/common/constants/histogram-buckets.constants.js.map +1 -0
  13. package/build/common/constants/http-status.constants.d.ts +27 -0
  14. package/build/common/constants/http-status.constants.d.ts.map +1 -0
  15. package/build/common/constants/http-status.constants.js +27 -0
  16. package/build/common/constants/http-status.constants.js.map +1 -0
  17. package/build/common/constants/timeout.constants.d.ts +29 -0
  18. package/build/common/constants/timeout.constants.d.ts.map +1 -0
  19. package/build/common/constants/timeout.constants.js +45 -0
  20. package/build/common/constants/timeout.constants.js.map +1 -0
  21. package/build/common/controllers/metrics.controller.d.ts +23 -0
  22. package/build/common/controllers/metrics.controller.d.ts.map +1 -0
  23. package/build/common/controllers/metrics.controller.js +66 -0
  24. package/build/common/controllers/metrics.controller.js.map +1 -0
  25. package/build/common/decorators/common-decorators.d.ts +90 -0
  26. package/build/common/decorators/common-decorators.d.ts.map +1 -0
  27. package/build/common/decorators/common-decorators.js +101 -0
  28. package/build/common/decorators/common-decorators.js.map +1 -0
  29. package/build/common/decorators/decorator-factory.d.ts +108 -0
  30. package/build/common/decorators/decorator-factory.d.ts.map +1 -0
  31. package/build/common/decorators/decorator-factory.js +104 -0
  32. package/build/common/decorators/decorator-factory.js.map +1 -0
  33. package/build/common/decorators/guard.decorators.d.ts +48 -0
  34. package/build/common/decorators/guard.decorators.d.ts.map +1 -0
  35. package/build/common/decorators/guard.decorators.js +49 -0
  36. package/build/common/decorators/guard.decorators.js.map +1 -0
  37. package/build/common/decorators/index.d.ts +10 -0
  38. package/build/common/decorators/index.d.ts.map +1 -0
  39. package/build/common/decorators/index.js +11 -0
  40. package/build/common/decorators/index.js.map +1 -0
  41. package/build/common/decorators/instrument.decorator.d.ts +128 -0
  42. package/build/common/decorators/instrument.decorator.d.ts.map +1 -0
  43. package/build/common/decorators/instrument.decorator.js +165 -0
  44. package/build/common/decorators/instrument.decorator.js.map +1 -0
  45. package/build/common/decorators/metric.decorators.d.ts +42 -0
  46. package/build/common/decorators/metric.decorators.d.ts.map +1 -0
  47. package/build/common/decorators/metric.decorators.js +85 -0
  48. package/build/common/decorators/metric.decorators.js.map +1 -0
  49. package/build/common/decorators/request-property.decorator.d.ts +65 -0
  50. package/build/common/decorators/request-property.decorator.d.ts.map +1 -0
  51. package/build/common/decorators/request-property.decorator.js +102 -0
  52. package/build/common/decorators/request-property.decorator.js.map +1 -0
  53. package/build/common/errors/base-application-error.d.ts +98 -0
  54. package/build/common/errors/base-application-error.d.ts.map +1 -0
  55. package/build/common/errors/base-application-error.js +133 -0
  56. package/build/common/errors/base-application-error.js.map +1 -0
  57. package/build/common/errors/error-factory.d.ts +93 -0
  58. package/build/common/errors/error-factory.d.ts.map +1 -0
  59. package/build/common/errors/error-factory.js +105 -0
  60. package/build/common/errors/error-factory.js.map +1 -0
  61. package/build/common/errors/index.d.ts +13 -0
  62. package/build/common/errors/index.d.ts.map +1 -0
  63. package/build/common/errors/index.js +15 -0
  64. package/build/common/errors/index.js.map +1 -0
  65. package/build/common/factories/index.d.ts +5 -0
  66. package/build/common/factories/index.d.ts.map +1 -0
  67. package/build/common/factories/index.js +3 -0
  68. package/build/common/factories/index.js.map +1 -0
  69. package/build/common/factories/module-factory.d.ts +178 -0
  70. package/build/common/factories/module-factory.d.ts.map +1 -0
  71. package/build/common/factories/module-factory.js +253 -0
  72. package/build/common/factories/module-factory.js.map +1 -0
  73. package/build/common/factories/rate-limit-config.factory.d.ts +79 -0
  74. package/build/common/factories/rate-limit-config.factory.d.ts.map +1 -0
  75. package/build/common/factories/rate-limit-config.factory.js +115 -0
  76. package/build/common/factories/rate-limit-config.factory.js.map +1 -0
  77. package/build/common/factories/security-bootstrap.factory.d.ts +77 -0
  78. package/build/common/factories/security-bootstrap.factory.d.ts.map +1 -0
  79. package/build/common/factories/security-bootstrap.factory.js +222 -0
  80. package/build/common/factories/security-bootstrap.factory.js.map +1 -0
  81. package/build/common/filters/global-exception.filter.d.ts +78 -0
  82. package/build/common/filters/global-exception.filter.d.ts.map +1 -0
  83. package/build/common/filters/global-exception.filter.js +192 -0
  84. package/build/common/filters/global-exception.filter.js.map +1 -0
  85. package/build/common/filters/http-exception.filter.d.ts +37 -0
  86. package/build/common/filters/http-exception.filter.d.ts.map +1 -0
  87. package/build/common/filters/http-exception.filter.js +91 -0
  88. package/build/common/filters/http-exception.filter.js.map +1 -0
  89. package/build/common/guards/csrf.guard.d.ts +53 -0
  90. package/build/common/guards/csrf.guard.d.ts.map +1 -0
  91. package/build/common/guards/csrf.guard.js +109 -0
  92. package/build/common/guards/csrf.guard.js.map +1 -0
  93. package/build/common/guards/metrics.guard.d.ts +42 -0
  94. package/build/common/guards/metrics.guard.d.ts.map +1 -0
  95. package/build/common/guards/metrics.guard.js +124 -0
  96. package/build/common/guards/metrics.guard.js.map +1 -0
  97. package/build/common/index.d.ts +43 -0
  98. package/build/common/index.d.ts.map +1 -0
  99. package/build/common/index.js +50 -0
  100. package/build/common/index.js.map +1 -0
  101. package/build/common/interceptors/http-client.interceptor.d.ts +11 -0
  102. package/build/common/interceptors/http-client.interceptor.d.ts.map +1 -0
  103. package/build/common/interceptors/http-client.interceptor.js +69 -0
  104. package/build/common/interceptors/http-client.interceptor.js.map +1 -0
  105. package/build/common/interceptors/http-instrumentation.interceptor.d.ts +64 -0
  106. package/build/common/interceptors/http-instrumentation.interceptor.d.ts.map +1 -0
  107. package/build/common/interceptors/http-instrumentation.interceptor.js +148 -0
  108. package/build/common/interceptors/http-instrumentation.interceptor.js.map +1 -0
  109. package/build/common/interceptors/http-metrics.interceptor.d.ts +46 -0
  110. package/build/common/interceptors/http-metrics.interceptor.d.ts.map +1 -0
  111. package/build/common/interceptors/http-metrics.interceptor.js +120 -0
  112. package/build/common/interceptors/http-metrics.interceptor.js.map +1 -0
  113. package/build/common/interceptors/logging.interceptor.d.ts +22 -0
  114. package/build/common/interceptors/logging.interceptor.d.ts.map +1 -0
  115. package/build/common/interceptors/logging.interceptor.js +67 -0
  116. package/build/common/interceptors/logging.interceptor.js.map +1 -0
  117. package/build/common/interfaces/cache-provider.interface.d.ts +54 -0
  118. package/build/common/interfaces/cache-provider.interface.d.ts.map +1 -0
  119. package/build/common/interfaces/cache-provider.interface.js +6 -0
  120. package/build/common/interfaces/cache-provider.interface.js.map +1 -0
  121. package/build/common/interfaces/index.d.ts +7 -0
  122. package/build/common/interfaces/index.d.ts.map +1 -0
  123. package/build/common/interfaces/index.js +3 -0
  124. package/build/common/interfaces/index.js.map +1 -0
  125. package/build/common/interfaces/log-context.interface.d.ts +77 -0
  126. package/build/common/interfaces/log-context.interface.d.ts.map +1 -0
  127. package/build/common/interfaces/log-context.interface.js +2 -0
  128. package/build/common/interfaces/log-context.interface.js.map +1 -0
  129. package/build/common/interfaces/log-entry.interface.d.ts +26 -0
  130. package/build/common/interfaces/log-entry.interface.d.ts.map +1 -0
  131. package/build/common/interfaces/log-entry.interface.js +33 -0
  132. package/build/common/interfaces/log-entry.interface.js.map +1 -0
  133. package/build/common/interfaces/logger.interface.d.ts +62 -0
  134. package/build/common/interfaces/logger.interface.d.ts.map +1 -0
  135. package/build/common/interfaces/logger.interface.js +2 -0
  136. package/build/common/interfaces/logger.interface.js.map +1 -0
  137. package/build/common/interfaces/metrics-exporter.interface.d.ts +275 -0
  138. package/build/common/interfaces/metrics-exporter.interface.d.ts.map +1 -0
  139. package/build/common/interfaces/metrics-exporter.interface.js +8 -0
  140. package/build/common/interfaces/metrics-exporter.interface.js.map +1 -0
  141. package/build/common/metrics/base-metrics-collector.d.ts +81 -0
  142. package/build/common/metrics/base-metrics-collector.d.ts.map +1 -0
  143. package/build/common/metrics/base-metrics-collector.js +88 -0
  144. package/build/common/metrics/base-metrics-collector.js.map +1 -0
  145. package/build/common/metrics/index.d.ts +2 -0
  146. package/build/common/metrics/index.d.ts.map +1 -0
  147. package/build/common/metrics/index.js +2 -0
  148. package/build/common/metrics/index.js.map +1 -0
  149. package/build/common/metrics.module.d.ts +50 -0
  150. package/build/common/metrics.module.d.ts.map +1 -0
  151. package/build/common/metrics.module.js +77 -0
  152. package/build/common/metrics.module.js.map +1 -0
  153. package/build/common/modules/throttler.module.d.ts +69 -0
  154. package/build/common/modules/throttler.module.d.ts.map +1 -0
  155. package/build/common/modules/throttler.module.js +117 -0
  156. package/build/common/modules/throttler.module.js.map +1 -0
  157. package/build/common/pipes/base-validation.pipe.d.ts +67 -0
  158. package/build/common/pipes/base-validation.pipe.d.ts.map +1 -0
  159. package/build/common/pipes/base-validation.pipe.js +95 -0
  160. package/build/common/pipes/base-validation.pipe.js.map +1 -0
  161. package/build/common/pipes/validation.pipe.d.ts +32 -0
  162. package/build/common/pipes/validation.pipe.d.ts.map +1 -0
  163. package/build/common/pipes/validation.pipe.js +60 -0
  164. package/build/common/pipes/validation.pipe.js.map +1 -0
  165. package/build/common/registry/instrumentation-registry.d.ts +227 -0
  166. package/build/common/registry/instrumentation-registry.d.ts.map +1 -0
  167. package/build/common/registry/instrumentation-registry.js +414 -0
  168. package/build/common/registry/instrumentation-registry.js.map +1 -0
  169. package/build/common/services/audit-logger.service.d.ts +91 -0
  170. package/build/common/services/audit-logger.service.d.ts.map +1 -0
  171. package/build/common/services/audit-logger.service.js +180 -0
  172. package/build/common/services/audit-logger.service.js.map +1 -0
  173. package/build/common/services/csrf.service.d.ts +202 -0
  174. package/build/common/services/csrf.service.d.ts.map +1 -0
  175. package/build/common/services/csrf.service.js +478 -0
  176. package/build/common/services/csrf.service.js.map +1 -0
  177. package/build/common/services/error-categorizer.service.d.ts +82 -0
  178. package/build/common/services/error-categorizer.service.d.ts.map +1 -0
  179. package/build/common/services/error-categorizer.service.js +339 -0
  180. package/build/common/services/error-categorizer.service.js.map +1 -0
  181. package/build/common/services/error-sanitizer.service.d.ts +146 -0
  182. package/build/common/services/error-sanitizer.service.d.ts.map +1 -0
  183. package/build/common/services/error-sanitizer.service.js +287 -0
  184. package/build/common/services/error-sanitizer.service.js.map +1 -0
  185. package/build/common/services/health-check.service.d.ts +86 -0
  186. package/build/common/services/health-check.service.d.ts.map +1 -0
  187. package/build/common/services/health-check.service.js +132 -0
  188. package/build/common/services/health-check.service.js.map +1 -0
  189. package/build/common/services/http-client.service.d.ts +113 -0
  190. package/build/common/services/http-client.service.d.ts.map +1 -0
  191. package/build/common/services/http-client.service.js +294 -0
  192. package/build/common/services/http-client.service.js.map +1 -0
  193. package/build/common/services/logger.service.d.ts +189 -0
  194. package/build/common/services/logger.service.d.ts.map +1 -0
  195. package/build/common/services/logger.service.js +423 -0
  196. package/build/common/services/logger.service.js.map +1 -0
  197. package/build/common/services/metrics-registry.service.d.ts +98 -0
  198. package/build/common/services/metrics-registry.service.d.ts.map +1 -0
  199. package/build/common/services/metrics-registry.service.js +262 -0
  200. package/build/common/services/metrics-registry.service.js.map +1 -0
  201. package/build/common/services/nest-logger-adapter.service.d.ts +62 -0
  202. package/build/common/services/nest-logger-adapter.service.d.ts.map +1 -0
  203. package/build/common/services/nest-logger-adapter.service.js +120 -0
  204. package/build/common/services/nest-logger-adapter.service.js.map +1 -0
  205. package/build/common/utils/error.utils.d.ts +16 -0
  206. package/build/common/utils/error.utils.d.ts.map +1 -0
  207. package/build/common/utils/error.utils.js +26 -0
  208. package/build/common/utils/error.utils.js.map +1 -0
  209. package/build/common/utils/lazy-getter.types.d.ts +190 -0
  210. package/build/common/utils/lazy-getter.types.d.ts.map +1 -0
  211. package/build/common/utils/lazy-getter.types.js +114 -0
  212. package/build/common/utils/lazy-getter.types.js.map +1 -0
  213. package/build/common/utils/module.utils.d.ts +33 -0
  214. package/build/common/utils/module.utils.d.ts.map +1 -0
  215. package/build/common/utils/module.utils.js +48 -0
  216. package/build/common/utils/module.utils.js.map +1 -0
  217. package/build/common/utils/sanitization.utils.d.ts +69 -0
  218. package/build/common/utils/sanitization.utils.d.ts.map +1 -0
  219. package/build/common/utils/sanitization.utils.js +141 -0
  220. package/build/common/utils/sanitization.utils.js.map +1 -0
  221. package/build/config/config.module.d.ts +30 -0
  222. package/build/config/config.module.d.ts.map +1 -0
  223. package/build/config/config.module.js +49 -0
  224. package/build/config/config.module.js.map +1 -0
  225. package/build/config/config.service.d.ts +74 -0
  226. package/build/config/config.service.d.ts.map +1 -0
  227. package/build/config/config.service.js +145 -0
  228. package/build/config/config.service.js.map +1 -0
  229. package/build/config/config.types.d.ts +143 -0
  230. package/build/config/config.types.d.ts.map +1 -0
  231. package/build/config/config.types.js +2 -0
  232. package/build/config/config.types.js.map +1 -0
  233. package/build/config/decorators/config.decorators.d.ts +43 -0
  234. package/build/config/decorators/config.decorators.d.ts.map +1 -0
  235. package/build/config/decorators/config.decorators.js +68 -0
  236. package/build/config/decorators/config.decorators.js.map +1 -0
  237. package/build/config/decorators/index.d.ts +2 -0
  238. package/build/config/decorators/index.d.ts.map +1 -0
  239. package/build/config/decorators/index.js +2 -0
  240. package/build/config/decorators/index.js.map +1 -0
  241. package/build/config/index.d.ts +7 -0
  242. package/build/config/index.d.ts.map +1 -0
  243. package/build/config/index.js +9 -0
  244. package/build/config/index.js.map +1 -0
  245. package/build/config/validation.utils.d.ts +136 -0
  246. package/build/config/validation.utils.d.ts.map +1 -0
  247. package/build/config/validation.utils.js +263 -0
  248. package/build/config/validation.utils.js.map +1 -0
  249. package/build/errors/index.d.ts +9 -0
  250. package/build/errors/index.d.ts.map +1 -0
  251. package/build/errors/index.js +12 -0
  252. package/build/errors/index.js.map +1 -0
  253. package/build/guards/custom-throttle.guard.d.ts +28 -0
  254. package/build/guards/custom-throttle.guard.d.ts.map +1 -0
  255. package/build/guards/custom-throttle.guard.js +52 -0
  256. package/build/guards/custom-throttle.guard.js.map +1 -0
  257. package/build/guards/index.d.ts +2 -0
  258. package/build/guards/index.d.ts.map +1 -0
  259. package/build/guards/index.js +2 -0
  260. package/build/guards/index.js.map +1 -0
  261. package/build/index.d.ts +53 -0
  262. package/build/index.d.ts.map +1 -0
  263. package/build/index.js +61 -0
  264. package/build/index.js.map +1 -0
  265. package/build/logging/index.d.ts +7 -0
  266. package/build/logging/index.d.ts.map +1 -0
  267. package/build/logging/index.js +7 -0
  268. package/build/logging/index.js.map +1 -0
  269. package/build/metrics/index.d.ts +6 -0
  270. package/build/metrics/index.d.ts.map +1 -0
  271. package/build/metrics/index.js +11 -0
  272. package/build/metrics/index.js.map +1 -0
  273. package/build/package.json +72 -0
  274. package/build/security/index.d.ts +8 -0
  275. package/build/security/index.d.ts.map +1 -0
  276. package/build/security/index.js +11 -0
  277. package/build/security/index.js.map +1 -0
  278. package/build/test-setup.d.ts +2 -0
  279. package/build/test-setup.d.ts.map +1 -0
  280. package/build/test-setup.js +40 -0
  281. package/build/test-setup.js.map +1 -0
  282. package/build/validation/index.d.ts +6 -0
  283. package/build/validation/index.d.ts.map +1 -0
  284. package/build/validation/index.js +8 -0
  285. package/build/validation/index.js.map +1 -0
  286. package/package.json +71 -0
@@ -0,0 +1,148 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Injectable, HttpException, } from '@nestjs/common';
11
+ import { ModuleRef } from '@nestjs/core';
12
+ import { throwError } from 'rxjs';
13
+ import { tap, catchError } from 'rxjs/operators';
14
+ import { performance } from 'node:perf_hooks';
15
+ import { InstrumentationRegistry } from '../registry/instrumentation-registry.js';
16
+ /**
17
+ * HTTP Instrumentation Interceptor
18
+ *
19
+ * Backend-agnostic HTTP request metrics collection using InstrumentationRegistry.
20
+ * Records request duration, status code, and request size for all HTTP requests.
21
+ * Skips metrics collection for non-HTTP contexts (GraphQL, WebSocket, RPC, etc.).
22
+ *
23
+ * Metrics recorded:
24
+ * - `http_request_duration_seconds` — Request duration in seconds (histogram)
25
+ * - `http_requests_total` — Total HTTP requests (counter)
26
+ * - `http_request_size_bytes` — Request body size in bytes (histogram, when available)
27
+ *
28
+ * @injectable
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // Register in your module
33
+ * @Module({
34
+ * providers: [HTTPInstrumentationInterceptor],
35
+ * })
36
+ * export class MyModule {}
37
+ *
38
+ * // Apply globally in main.ts
39
+ * app.useGlobalInterceptors(app.get(HTTPInstrumentationInterceptor));
40
+ * ```
41
+ */
42
+ let HTTPInstrumentationInterceptor = class HTTPInstrumentationInterceptor {
43
+ Module;
44
+ constructor(module) {
45
+ this.Module = module;
46
+ }
47
+ get Registry() {
48
+ return this.Module.get(InstrumentationRegistry);
49
+ }
50
+ /**
51
+ * Intercept HTTP requests and record instrumentation metrics.
52
+ * Records request duration, status code, and content length.
53
+ * Skips metrics collection for non-HTTP contexts.
54
+ *
55
+ * @param context - The execution context containing request/response
56
+ * @param next - The next handler in the chain
57
+ * @returns Observable of the response
58
+ */
59
+ intercept(context, next) {
60
+ // Skip metrics for non-HTTP contexts (GraphQL, WebSocket, RPC, etc.)
61
+ if (context.getType() !== 'http') {
62
+ return next.handle();
63
+ }
64
+ const request = context.switchToHttp().getRequest();
65
+ const response = context.switchToHttp().getResponse();
66
+ const start = performance.now();
67
+ const { method } = request;
68
+ const contentLength = this.getContentLength(request);
69
+ const millisecondsPerSecond = 1000;
70
+ return next.handle().pipe(tap(() => {
71
+ const route = this.getRoute(request);
72
+ const statusCode = String(response.statusCode);
73
+ const duration = (performance.now() - start) / millisecondsPerSecond; // Convert to seconds
74
+ this.Registry.recordMetric('http_request_duration_seconds', duration, {
75
+ method,
76
+ route,
77
+ status_code: statusCode,
78
+ });
79
+ this.Registry.recordMetric('http_requests_total', 1, {
80
+ method,
81
+ route,
82
+ status_code: statusCode,
83
+ });
84
+ if (contentLength !== undefined) {
85
+ this.Registry.recordMetric('http_request_size_bytes', contentLength, {
86
+ method,
87
+ route,
88
+ });
89
+ }
90
+ }), catchError((err) => {
91
+ const route = this.getRoute(request);
92
+ const statusCode = err instanceof HttpException
93
+ ? String(err.getStatus())
94
+ : '500';
95
+ const duration = (performance.now() - start) / millisecondsPerSecond; // Convert to seconds
96
+ this.Registry.recordMetric('http_request_duration_seconds', duration, {
97
+ method,
98
+ route,
99
+ status_code: statusCode,
100
+ });
101
+ this.Registry.recordMetric('http_requests_total', 1, {
102
+ method,
103
+ route,
104
+ status_code: statusCode,
105
+ });
106
+ return throwError(() => err);
107
+ }));
108
+ }
109
+ /**
110
+ * Extract route path from request
111
+ * Tries to get the route from Express first, then falls back to URL path
112
+ *
113
+ * @private
114
+ * @param request - The Express request object
115
+ * @returns The route path or fallback value
116
+ */
117
+ getRoute(request) {
118
+ // Try to get route from Express
119
+ const { route } = request;
120
+ if (route?.path) {
121
+ return route.path;
122
+ }
123
+ // Fallback to URL path
124
+ return request.path || request.url || '/unknown';
125
+ }
126
+ /**
127
+ * Get request content length from headers
128
+ * Parses the content-length header and returns it as a number
129
+ *
130
+ * @private
131
+ * @param request - The Express request object
132
+ * @returns The content length in bytes, or undefined if not available
133
+ */
134
+ getContentLength(request) {
135
+ const contentLength = request.headers['content-length'];
136
+ if (contentLength) {
137
+ const length = parseInt(contentLength, 10);
138
+ return isNaN(length) ? undefined : length;
139
+ }
140
+ return undefined;
141
+ }
142
+ };
143
+ HTTPInstrumentationInterceptor = __decorate([
144
+ Injectable(),
145
+ __metadata("design:paramtypes", [ModuleRef])
146
+ ], HTTPInstrumentationInterceptor);
147
+ export { HTTPInstrumentationInterceptor };
148
+ //# sourceMappingURL=http-instrumentation.interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-instrumentation.interceptor.js","sourceRoot":"","sources":["../../../src/common/interceptors/http-instrumentation.interceptor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
2
+ import { ModuleRef } from '@nestjs/core';
3
+ import { Observable } from 'rxjs';
4
+ import { LazyModuleRefService } from '../utils/lazy-getter.types.js';
5
+ /**
6
+ * HTTP Metrics Interceptor.
7
+ * Automatically collects and records HTTP request metrics for Prometheus.
8
+ *
9
+ * Metrics collected:
10
+ * - Request duration histogram (in seconds)
11
+ * - Request count counter (total requests)
12
+ * - Request size histogram (in bytes)
13
+ *
14
+ * Labels for all metrics:
15
+ * - method: HTTP method (GET, POST, etc.)
16
+ * - route: URL path (normalized to collapse dynamic segments like UUIDs)
17
+ * - status_code: HTTP status code
18
+ * - status_class: Status class (2xx, 4xx, 5xx)
19
+ *
20
+ * @remarks
21
+ * - Skips non-HTTP contexts (GraphQL, WebSocket, RPC, etc.)
22
+ * - Normalizes dynamic path segments (UUIDs, ObjectIDs, numeric IDs) to :id to prevent unbounded cardinality
23
+ * - Records metrics even when requests fail or throw errors
24
+ */
25
+ export declare class HTTPMetricsInterceptor implements NestInterceptor, LazyModuleRefService {
26
+ readonly Module: ModuleRef;
27
+ constructor(module: ModuleRef);
28
+ private get MetricsService();
29
+ intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
30
+ /**
31
+ * Extract route path from request.
32
+ * Prefers the Express route pattern (e.g., /users/:id) over the raw URL path
33
+ * to prevent unbounded metric cardinality from dynamic path parameters.
34
+ */
35
+ private getRoute;
36
+ /**
37
+ * Normalize a URL path by replacing dynamic segments (UUIDs, ObjectIDs, numeric IDs)
38
+ * with placeholder tokens to prevent unbounded metric cardinality.
39
+ */
40
+ private normalizePath;
41
+ /**
42
+ * Get request content length
43
+ */
44
+ private getContentLength;
45
+ }
46
+ //# sourceMappingURL=http-metrics.interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-metrics.interceptor.d.ts","sourceRoot":"","sources":["../../../src/common/interceptors/http-metrics.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,eAAe,EAAE,gBAAgB,EAAE,WAAW,EAAiB,MAAM,gBAAgB,CAAC;AAC3G,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAc,MAAM,MAAM,CAAC;AAI9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAIrE;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,qBACa,sBAAuB,YAAW,eAAe,EAAE,oBAAoB;IACnF,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,MAAM,EAAE,SAAS;IAI7B,OAAO,KAAK,cAAc,GAEzB;IAEM,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC;IAyC/E;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAahB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAUrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAQxB"}
@@ -0,0 +1,120 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Injectable, HttpException } from '@nestjs/common';
11
+ import { ModuleRef } from '@nestjs/core';
12
+ import { throwError } from 'rxjs';
13
+ import { tap, catchError } from 'rxjs/operators';
14
+ import { MetricsRegistryService } from '../services/metrics-registry.service.js';
15
+ const DEFAULT_ERROR_STATUS_CODE = 500;
16
+ /**
17
+ * HTTP Metrics Interceptor.
18
+ * Automatically collects and records HTTP request metrics for Prometheus.
19
+ *
20
+ * Metrics collected:
21
+ * - Request duration histogram (in seconds)
22
+ * - Request count counter (total requests)
23
+ * - Request size histogram (in bytes)
24
+ *
25
+ * Labels for all metrics:
26
+ * - method: HTTP method (GET, POST, etc.)
27
+ * - route: URL path (normalized to collapse dynamic segments like UUIDs)
28
+ * - status_code: HTTP status code
29
+ * - status_class: Status class (2xx, 4xx, 5xx)
30
+ *
31
+ * @remarks
32
+ * - Skips non-HTTP contexts (GraphQL, WebSocket, RPC, etc.)
33
+ * - Normalizes dynamic path segments (UUIDs, ObjectIDs, numeric IDs) to :id to prevent unbounded cardinality
34
+ * - Records metrics even when requests fail or throw errors
35
+ */
36
+ let HTTPMetricsInterceptor = class HTTPMetricsInterceptor {
37
+ Module;
38
+ constructor(module) {
39
+ this.Module = module;
40
+ }
41
+ get MetricsService() {
42
+ return this.Module.get(MetricsRegistryService);
43
+ }
44
+ intercept(context, next) {
45
+ // Skip metrics for non-HTTP contexts (GraphQL, WebSocket, RPC, etc.)
46
+ if (context.getType() !== 'http') {
47
+ return next.handle();
48
+ }
49
+ const request = context.switchToHttp().getRequest();
50
+ const response = context.switchToHttp().getResponse();
51
+ // Additional safety check for request object
52
+ if (!request?.method) {
53
+ return next.handle();
54
+ }
55
+ const startTime = Date.now();
56
+ // Extract route information
57
+ const { method } = request;
58
+ const route = this.getRoute(request);
59
+ return next.handle().pipe(tap(() => {
60
+ const duration = Date.now() - startTime;
61
+ const contentLength = this.getContentLength(request);
62
+ const statusCode = response.statusCode ?? DEFAULT_ERROR_STATUS_CODE;
63
+ // Record metrics
64
+ this.MetricsService.recordHttpRequest(method, route, statusCode, duration, contentLength);
65
+ }), catchError((error) => {
66
+ const duration = Date.now() - startTime;
67
+ const contentLength = this.getContentLength(request);
68
+ const statusCode = (error instanceof HttpException ? error.getStatus() : undefined) ?? response.statusCode ?? DEFAULT_ERROR_STATUS_CODE;
69
+ // Record metrics even on error (use status code from HttpException if available, then response, then default)
70
+ this.MetricsService.recordHttpRequest(method, route, statusCode, duration, contentLength);
71
+ return throwError(() => error);
72
+ }));
73
+ }
74
+ /**
75
+ * Extract route path from request.
76
+ * Prefers the Express route pattern (e.g., /users/:id) over the raw URL path
77
+ * to prevent unbounded metric cardinality from dynamic path parameters.
78
+ */
79
+ getRoute(request) {
80
+ // Try to get route pattern from Express (e.g., /users/:id instead of /users/123)
81
+ const { route } = request;
82
+ if (route?.path) {
83
+ return route.path;
84
+ }
85
+ // Fallback: normalize the path to collapse UUIDs, ObjectIDs, and numeric IDs
86
+ // to prevent unbounded metric label cardinality
87
+ const rawPath = request.path || request.url || '/unknown';
88
+ return this.normalizePath(rawPath);
89
+ }
90
+ /**
91
+ * Normalize a URL path by replacing dynamic segments (UUIDs, ObjectIDs, numeric IDs)
92
+ * with placeholder tokens to prevent unbounded metric cardinality.
93
+ */
94
+ normalizePath(path) {
95
+ return path
96
+ // Replace UUIDs (v1-v5)
97
+ .replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, ':id')
98
+ // Replace MongoDB ObjectIDs (24 hex chars)
99
+ .replace(/\/[0-9a-f]{24}(?=\/|$)/gi, '/:id')
100
+ // Replace purely numeric path segments
101
+ .replace(/\/\d+(?=\/|$)/g, '/:id');
102
+ }
103
+ /**
104
+ * Get request content length
105
+ */
106
+ getContentLength(request) {
107
+ const contentLength = request.headers['content-length'];
108
+ if (contentLength) {
109
+ const length = parseInt(contentLength, 10);
110
+ return isNaN(length) ? undefined : length;
111
+ }
112
+ return undefined;
113
+ }
114
+ };
115
+ HTTPMetricsInterceptor = __decorate([
116
+ Injectable(),
117
+ __metadata("design:paramtypes", [ModuleRef])
118
+ ], HTTPMetricsInterceptor);
119
+ export { HTTPMetricsInterceptor };
120
+ //# sourceMappingURL=http-metrics.interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-metrics.interceptor.js","sourceRoot":"","sources":["../../../src/common/interceptors/http-metrics.interceptor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
2
+ import { ModuleRef } from '@nestjs/core';
3
+ import { Observable } from 'rxjs';
4
+ import { LazyModuleRefService } from '../utils/lazy-getter.types.js';
5
+ /**
6
+ * Logging Interceptor.
7
+ * Logs incoming HTTP requests and outgoing responses with timing information.
8
+ * Uses DEBUG level for health/metrics endpoints to reduce noise.
9
+ * Automatically logs request details: method, URL, IP address, and response time.
10
+ *
11
+ * @remarks
12
+ * - Skips logging for non-HTTP contexts (GraphQL, WebSocket, etc.)
13
+ * - Uses DEBUG level for /health and /metrics endpoints
14
+ * - Uses INFO level for other requests
15
+ */
16
+ export declare class LoggingInterceptor implements NestInterceptor, LazyModuleRefService {
17
+ readonly Module: ModuleRef;
18
+ constructor(module: ModuleRef);
19
+ private get Logger();
20
+ intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
21
+ }
22
+ //# sourceMappingURL=logging.interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.interceptor.d.ts","sourceRoot":"","sources":["../../../src/common/interceptors/logging.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAc,MAAM,MAAM,CAAC;AAI9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAIrE;;;;;;;;;;GAUG;AACH,qBACa,kBAAmB,YAAW,eAAe,EAAE,oBAAoB;IAC/E,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,MAAM,EAAE,SAAS;IAI7B,OAAO,KAAK,MAAM,GAEjB;IAEM,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC;CAwC/E"}
@@ -0,0 +1,67 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Injectable, } from '@nestjs/common';
11
+ import { ModuleRef } from '@nestjs/core';
12
+ import { throwError } from 'rxjs';
13
+ import { tap, catchError } from 'rxjs/operators';
14
+ import { AppLogger } from '../services/logger.service.js';
15
+ import { escapeNewlines } from '../utils/sanitization.utils.js';
16
+ import { getErrorMessage } from '../utils/error.utils.js';
17
+ /**
18
+ * Logging Interceptor.
19
+ * Logs incoming HTTP requests and outgoing responses with timing information.
20
+ * Uses DEBUG level for health/metrics endpoints to reduce noise.
21
+ * Automatically logs request details: method, URL, IP address, and response time.
22
+ *
23
+ * @remarks
24
+ * - Skips logging for non-HTTP contexts (GraphQL, WebSocket, etc.)
25
+ * - Uses DEBUG level for /health and /metrics endpoints
26
+ * - Uses INFO level for other requests
27
+ */
28
+ let LoggingInterceptor = class LoggingInterceptor {
29
+ Module;
30
+ constructor(module) {
31
+ this.Module = module;
32
+ }
33
+ get Logger() {
34
+ return this.Module.get(AppLogger);
35
+ }
36
+ intercept(context, next) {
37
+ // Skip logging for non-HTTP contexts (e.g., GraphQL)
38
+ if (context.getType() !== 'http') {
39
+ return next.handle();
40
+ }
41
+ const request = context.switchToHttp().getRequest();
42
+ const { method, url, ip } = request;
43
+ const startTime = Date.now();
44
+ // Use DEBUG level for health checks and metrics endpoints to reduce noise
45
+ const isHealthOrMetrics = url.includes('/health') || url.includes('/metrics');
46
+ // Note: Dynamic profiling tags are not supported by @pyroscope/nodejs
47
+ // Use static tags in config during initialization instead
48
+ const logFn = isHealthOrMetrics ? this.Logger.debug.bind(this.Logger) : this.Logger.info.bind(this.Logger);
49
+ logFn(`Incoming request: ${escapeNewlines(method)} ${escapeNewlines(url)} from ${escapeNewlines(ip ?? 'unknown')}`, 'LoggingInterceptor');
50
+ return next.handle().pipe(tap(() => {
51
+ const duration = Date.now() - startTime;
52
+ const response = context.switchToHttp().getResponse();
53
+ const { statusCode } = response;
54
+ logFn(`Request completed: ${escapeNewlines(method)} ${escapeNewlines(url)} - ${statusCode} - ${duration}ms`, 'LoggingInterceptor');
55
+ }), catchError((error) => {
56
+ const duration = Date.now() - startTime;
57
+ this.Logger.error(`Request failed: ${escapeNewlines(method)} ${escapeNewlines(url)} - ${duration}ms - ${getErrorMessage(error)}`, 'LoggingInterceptor');
58
+ return throwError(() => error);
59
+ }));
60
+ }
61
+ };
62
+ LoggingInterceptor = __decorate([
63
+ Injectable(),
64
+ __metadata("design:paramtypes", [ModuleRef])
65
+ ], LoggingInterceptor);
66
+ export { LoggingInterceptor };
67
+ //# sourceMappingURL=logging.interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.interceptor.js","sourceRoot":"","sources":["../../../src/common/interceptors/logging.interceptor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Cache provider interface for token blacklisting and caching
3
+ * Decouples auth module from specific cache implementations (Redis, memory, etc)
4
+ *
5
+ * This interface allows auth module to work with any cache backend
6
+ * without creating circular dependencies with GraphQL module
7
+ */
8
+ export interface ICacheProvider {
9
+ /**
10
+ * Set a cache value with optional TTL
11
+ * @param key Cache key
12
+ * @param value Value to cache
13
+ * @param ttlSeconds Time-to-live in seconds (optional)
14
+ */
15
+ set(key: string, value: any, ttlSeconds?: number): Promise<void>;
16
+ /**
17
+ * Get a cache value
18
+ * @param key Cache key
19
+ * @returns Cached value or null if not found
20
+ */
21
+ get(key: string): Promise<any>;
22
+ /**
23
+ * Check if a key exists in cache
24
+ * @param key Cache key
25
+ * @returns True if key exists
26
+ */
27
+ exists(key: string): Promise<boolean>;
28
+ /**
29
+ * Delete a cache value
30
+ * @param key Cache key
31
+ */
32
+ del(key: string): Promise<void>;
33
+ /**
34
+ * Clear all cache values
35
+ */
36
+ clear(): Promise<void>;
37
+ /**
38
+ * Execute an atomic script/command (e.g. Redis Lua script) on the cache backend.
39
+ * This is optional — implementations backed by Redis should provide it;
40
+ * in-memory or other backends may leave it undefined.
41
+ *
42
+ * @param script The script to execute (Lua for Redis)
43
+ * @param keys Array of cache keys the script operates on
44
+ * @param args Array of string arguments passed to the script
45
+ * @returns The result from the script execution
46
+ */
47
+ executeScript?(script: string, keys: readonly string[], args: readonly string[]): Promise<unknown>;
48
+ }
49
+ /**
50
+ * Token for injecting cache provider
51
+ * Used in AuthModule and services that need caching
52
+ */
53
+ export declare const CACHE_PROVIDER: unique symbol;
54
+ //# sourceMappingURL=cache-provider.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-provider.interface.d.ts","sourceRoot":"","sources":["../../../src/common/interfaces/cache-provider.interface.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE/B;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtC;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;;;;;;OASG;IACH,aAAa,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnG;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,eAA2B,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Token for injecting cache provider
3
+ * Used in AuthModule and services that need caching
4
+ */
5
+ export const CACHE_PROVIDER = Symbol('CACHE_PROVIDER');
6
+ //# sourceMappingURL=cache-provider.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-provider.interface.js","sourceRoot":"","sources":["../../../src/common/interfaces/cache-provider.interface.ts"],"names":[],"mappings":"AAsDA;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type { LogContext } from './log-context.interface.js';
2
+ export type { ILogger, IContextualLogger } from './logger.interface.js';
3
+ export type { LogEntry, LogMetadata } from './log-entry.interface.js';
4
+ export { LogLevel, LOG_LEVEL_STRINGS, LOG_LEVEL_FROM_STRING } from './log-entry.interface.js';
5
+ export type { ICacheProvider } from './cache-provider.interface.js';
6
+ export { CACHE_PROVIDER } from './cache-provider.interface.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/common/interfaces/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACxE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC9F,YAAY,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { LogLevel, LOG_LEVEL_STRINGS, LOG_LEVEL_FROM_STRING } from './log-entry.interface.js';
2
+ export { CACHE_PROVIDER } from './cache-provider.interface.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/common/interfaces/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAE9F,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Structured logging context for distributed tracing and monitoring
3
+ *
4
+ * Provides base fields for structured JSON logging compatible with Loki and other
5
+ * observability platforms. All fields are optional to support flexible usage patterns.
6
+ *
7
+ * @example
8
+ * // Basic usage
9
+ * const context: LogContext = {
10
+ * correlationId: 'req-123',
11
+ * userId: 'user-456',
12
+ * action: 'CreateStream',
13
+ * status: 'success'
14
+ * };
15
+ *
16
+ * @example
17
+ * // Extending with domain-specific fields
18
+ * interface StreamingContext extends LogContext {
19
+ * streamId: string;
20
+ * bitrate: number;
21
+ * codec: string;
22
+ * }
23
+ *
24
+ * const streamContext: StreamingContext = {
25
+ * correlationId: 'req-123',
26
+ * userId: 'user-456',
27
+ * streamId: 'stream-789',
28
+ * action: 'StartStream',
29
+ * duration: 1250,
30
+ * status: 'success',
31
+ * bitrate: 5000,
32
+ * codec: 'h264'
33
+ * };
34
+ */
35
+ export interface LogContext {
36
+ /**
37
+ * Request correlation ID for distributed tracing
38
+ * Used to correlate logs across multiple services
39
+ */
40
+ correlationId?: string;
41
+ /**
42
+ * Authenticated user ID
43
+ * Identifies which user initiated the operation
44
+ */
45
+ userId?: string;
46
+ /**
47
+ * Stream or resource identifier
48
+ * Domain-specific identifier for the primary resource being operated on
49
+ */
50
+ streamId?: string;
51
+ /**
52
+ * Viewer or client identifier
53
+ * Identifies the viewer/client consuming a stream or resource
54
+ */
55
+ viewerId?: string;
56
+ /**
57
+ * Operation or action being performed
58
+ * Examples: 'CreateStream', 'StartBroadcast', 'UpdateMetadata'
59
+ */
60
+ action?: string;
61
+ /**
62
+ * Operation duration in milliseconds
63
+ * Useful for performance monitoring and SLO tracking
64
+ */
65
+ duration?: number;
66
+ /**
67
+ * Operation or request status
68
+ * Examples: 'success', 'failed', 'pending', 'completed'
69
+ */
70
+ status?: string;
71
+ /**
72
+ * Support for custom/domain-specific fields
73
+ * Allows extending the interface with additional context data
74
+ */
75
+ [key: string]: any;
76
+ }
77
+ //# sourceMappingURL=log-context.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-context.interface.d.ts","sourceRoot":"","sources":["../../../src/common/interfaces/log-context.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,WAAW,UAAU;IAC1B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACnB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=log-context.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-context.interface.js","sourceRoot":"","sources":["../../../src/common/interfaces/log-context.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ export interface LogEntry {
2
+ timestamp: string;
3
+ level: string;
4
+ service: string;
5
+ context: string;
6
+ message: string;
7
+ metadata?: Record<string, any>;
8
+ traceId?: string;
9
+ spanId?: string;
10
+ environment: string;
11
+ }
12
+ export interface LogMetadata {
13
+ [key: string]: any;
14
+ }
15
+ export declare enum LogLevel {
16
+ DEBUG = 0,
17
+ INFO = 1,
18
+ WARN = 2,
19
+ ERROR = 3,
20
+ FATAL = 4,
21
+ /** Suppresses all log output. */
22
+ SILENT = 5
23
+ }
24
+ export declare const LOG_LEVEL_STRINGS: Record<LogLevel, string>;
25
+ export declare const LOG_LEVEL_FROM_STRING: Record<string, LogLevel>;
26
+ //# sourceMappingURL=log-entry.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-entry.interface.d.ts","sourceRoot":"","sources":["../../../src/common/interfaces/log-entry.interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACnB;AASD,oBAAY,QAAQ;IACnB,KAAK,IAAc;IACnB,IAAI,IAAa;IACjB,IAAI,IAAa;IACjB,KAAK,IAAc;IACnB,KAAK,IAAc;IACnB,iCAAiC;IACjC,MAAM,IAAe;CACrB;AAED,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAOtD,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAO1D,CAAC"}