@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,339 @@
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
+ var ErrorCategorizerService_1;
11
+ import { Injectable } from '@nestjs/common';
12
+ import { ModuleRef } from '@nestjs/core';
13
+ import { HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_UNAUTHORIZED, HTTP_STATUS_FORBIDDEN, HTTP_STATUS_NOT_FOUND, HTTP_STATUS_TOO_MANY_REQUESTS, HTTP_STATUS_BAD_GATEWAY, HTTP_STATUS_SERVICE_UNAVAILABLE, HTTP_STATUS_GATEWAY_TIMEOUT, HTTP_STATUS_UNPROCESSABLE_ENTITY, } from '../constants/http-status.constants.js';
14
+ import { AppLogger } from './logger.service.js';
15
+ // Backoff times in milliseconds
16
+ const BACKOFF_RETRY_MS = 1000;
17
+ const BACKOFF_TIMEOUT_MS = 2000;
18
+ const BACKOFF_DATABASE_MS = 5000;
19
+ const BACKOFF_RATE_LIMIT_MS = 10000;
20
+ /**
21
+ * Error Categorizer Service.
22
+ * Classifies errors as transient or permanent and recommends recovery strategies.
23
+ *
24
+ * Categories:
25
+ * - **Transient** (retryable): Network errors, timeouts, database connection errors, rate limits, server errors (5xx)
26
+ * - **Permanent** (not retryable): Validation errors, bad requests (4xx), authentication/authorization, not found
27
+ *
28
+ * Recovery strategies:
29
+ * - **retry**: Immediate retry (for network errors)
30
+ * - **backoff**: Exponential backoff retry (for timeouts, database, rate limits)
31
+ * - **fail**: Fast failure without retry (for validation, authentication, not found)
32
+ *
33
+ * @remarks
34
+ * - Node.js error codes (ECONNRESET, ECONNREFUSED, ETIMEDOUT, ENOTFOUND, EAI_AGAIN) are always transient
35
+ * - Database connection errors are always transient with long backoff (5s)
36
+ * - Timeout errors get medium backoff (2s)
37
+ * - Rate limit errors get maximum backoff (10s)
38
+ * - Unknown errors default to permanent/fail strategy
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const category = errorCategorizer.categorizeError(error);
43
+ * if (category.retryable) {
44
+ * // Retry with backoff: category.backoffMs
45
+ * } else {
46
+ * // Fail fast
47
+ * }
48
+ * ```
49
+ */
50
+ let ErrorCategorizerService = ErrorCategorizerService_1 = class ErrorCategorizerService {
51
+ _contextualLogger;
52
+ Module;
53
+ constructor(module) {
54
+ this.Module = module;
55
+ }
56
+ /**
57
+ * Get contextual logger for error categorizer
58
+ */
59
+ get Logger() {
60
+ if (!this._contextualLogger) {
61
+ const baseLogger = this.Module.get(AppLogger);
62
+ this._contextualLogger = baseLogger.createContextualLogger(ErrorCategorizerService_1.name);
63
+ }
64
+ return this._contextualLogger;
65
+ }
66
+ /**
67
+ * Check if an error is retryable
68
+ */
69
+ isRetryable(error) {
70
+ const category = this.categorizeError(error);
71
+ return category.retryable;
72
+ }
73
+ /**
74
+ * Categorize an error and determine recovery strategy
75
+ */
76
+ categorizeError(error) {
77
+ const err = error;
78
+ const errorMessage = err?.message ?? String(error);
79
+ const errorCode = err?.code ?? err?.status;
80
+ // Node.js network error codes are always transient (checked first before pattern matching)
81
+ const NODE_TRANSIENT_CODES = new Set(['ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND', 'EAI_AGAIN']);
82
+ if (error && NODE_TRANSIENT_CODES.has(error.code ?? '')) {
83
+ this.Logger.debug('Categorized as transient network error (Node.js error code)', {
84
+ error: errorMessage,
85
+ code: errorCode,
86
+ category: 'transient',
87
+ strategy: 'backoff',
88
+ });
89
+ return {
90
+ type: 'transient',
91
+ retryable: true,
92
+ strategy: 'backoff',
93
+ backoffMs: BACKOFF_RETRY_MS,
94
+ };
95
+ }
96
+ // Database connection errors (transient) - check before timeout since "timeout" may be in message
97
+ if (this.isDatabaseError(error)) {
98
+ this.Logger.debug('Categorized as transient database error', {
99
+ error: errorMessage,
100
+ category: 'transient',
101
+ strategy: 'backoff',
102
+ });
103
+ return {
104
+ type: 'transient',
105
+ retryable: true,
106
+ strategy: 'backoff',
107
+ backoffMs: BACKOFF_DATABASE_MS,
108
+ };
109
+ }
110
+ // Timeout errors (transient) - check before generic network errors since ETIMEDOUT is in networkCodes
111
+ if (this.isTimeoutError(error)) {
112
+ this.Logger.debug('Categorized as transient timeout error', {
113
+ error: errorMessage,
114
+ category: 'transient',
115
+ strategy: 'backoff',
116
+ });
117
+ return {
118
+ type: 'transient',
119
+ retryable: true,
120
+ strategy: 'backoff',
121
+ backoffMs: BACKOFF_TIMEOUT_MS,
122
+ };
123
+ }
124
+ // Network errors (transient)
125
+ if (this.isNetworkError(error)) {
126
+ this.Logger.debug('Categorized as transient network error', {
127
+ error: errorMessage,
128
+ category: 'transient',
129
+ strategy: 'retry',
130
+ });
131
+ return {
132
+ type: 'transient',
133
+ retryable: true,
134
+ strategy: 'retry',
135
+ backoffMs: BACKOFF_RETRY_MS,
136
+ };
137
+ }
138
+ // Server errors (transient) - 502, 503, 504
139
+ if (this.isServerError(error)) {
140
+ this.Logger.debug('Categorized as transient server error', {
141
+ error: errorMessage,
142
+ status: errorCode,
143
+ category: 'transient',
144
+ strategy: 'backoff',
145
+ });
146
+ return {
147
+ type: 'transient',
148
+ retryable: true,
149
+ strategy: 'backoff',
150
+ backoffMs: BACKOFF_TIMEOUT_MS,
151
+ };
152
+ }
153
+ // Rate limit errors (transient) - 429
154
+ if (this.isRateLimitError(error)) {
155
+ this.Logger.debug('Categorized as transient rate limit error', {
156
+ error: errorMessage,
157
+ category: 'transient',
158
+ strategy: 'backoff',
159
+ });
160
+ return {
161
+ type: 'transient',
162
+ retryable: true,
163
+ strategy: 'backoff',
164
+ backoffMs: BACKOFF_RATE_LIMIT_MS,
165
+ };
166
+ }
167
+ // Bad request errors (permanent) - 400, 422
168
+ if (this.isBadRequestError(error)) {
169
+ this.Logger.debug('Categorized as permanent bad request error', {
170
+ error: errorMessage,
171
+ category: 'permanent',
172
+ strategy: 'fail',
173
+ });
174
+ return {
175
+ type: 'permanent',
176
+ retryable: false,
177
+ strategy: 'fail',
178
+ };
179
+ }
180
+ // Validation errors (permanent)
181
+ if (this.isValidationError(error)) {
182
+ this.Logger.debug('Categorized as permanent validation error', {
183
+ error: errorMessage,
184
+ category: 'permanent',
185
+ strategy: 'fail',
186
+ });
187
+ return {
188
+ type: 'permanent',
189
+ retryable: false,
190
+ strategy: 'fail',
191
+ };
192
+ }
193
+ // Authentication errors (permanent) - 401
194
+ if (this.isAuthError(error)) {
195
+ this.Logger.debug('Categorized as permanent authentication error', {
196
+ error: errorMessage,
197
+ category: 'permanent',
198
+ strategy: 'fail',
199
+ });
200
+ return {
201
+ type: 'permanent',
202
+ retryable: false,
203
+ strategy: 'fail',
204
+ };
205
+ }
206
+ // Authorization errors (permanent) - 403
207
+ if (this.isAuthzError(error)) {
208
+ this.Logger.debug('Categorized as permanent authorization error', {
209
+ error: errorMessage,
210
+ category: 'permanent',
211
+ strategy: 'fail',
212
+ });
213
+ return {
214
+ type: 'permanent',
215
+ retryable: false,
216
+ strategy: 'fail',
217
+ };
218
+ }
219
+ // Not found errors (permanent) - 404
220
+ if (this.isNotFoundError(error)) {
221
+ this.Logger.debug('Categorized as permanent not found error', {
222
+ error: errorMessage,
223
+ category: 'permanent',
224
+ strategy: 'fail',
225
+ });
226
+ return {
227
+ type: 'permanent',
228
+ retryable: false,
229
+ strategy: 'fail',
230
+ };
231
+ }
232
+ // Default to permanent error
233
+ this.Logger.warn('Uncategorized error treated as permanent', {
234
+ error: errorMessage,
235
+ code: errorCode,
236
+ category: 'permanent',
237
+ strategy: 'fail',
238
+ });
239
+ return {
240
+ type: 'permanent',
241
+ retryable: false,
242
+ strategy: 'fail',
243
+ };
244
+ }
245
+ /**
246
+ * Log error recovery attempt
247
+ */
248
+ logRecoveryAttempt(error, attempt, maxAttempts) {
249
+ const category = this.categorizeError(error);
250
+ this.Logger.info('Error recovery attempt', {
251
+ attempt,
252
+ maxAttempts,
253
+ errorType: category.type,
254
+ strategy: category.strategy,
255
+ backoffMs: category.backoffMs,
256
+ error: error?.message ?? String(error),
257
+ });
258
+ }
259
+ /**
260
+ * Log successful recovery
261
+ */
262
+ logRecoverySuccess(error, attempts) {
263
+ this.Logger.info('Error recovery successful', {
264
+ attempts,
265
+ error: error?.message ?? String(error),
266
+ });
267
+ }
268
+ /**
269
+ * Log failed recovery
270
+ */
271
+ logRecoveryFailed(error, attempts) {
272
+ const err = error;
273
+ const category = this.categorizeError(error);
274
+ this.Logger.error('Error recovery failed', undefined, undefined, {
275
+ attempts,
276
+ errorType: category.type,
277
+ retryable: category.retryable,
278
+ error: err?.message ?? String(error),
279
+ });
280
+ }
281
+ isNetworkError(error) {
282
+ const err = error;
283
+ const networkCodes = ['ECONNREFUSED', 'ENOTFOUND', 'ECONNRESET', 'EPIPE'];
284
+ return networkCodes.includes(err?.code) || /\bnetwork\b/i.test(err?.message) || /\bconnection\b/i.test(err?.message);
285
+ }
286
+ isTimeoutError(error) {
287
+ const err = error;
288
+ return err?.code === 'ETIMEDOUT' ||
289
+ /\btimeout\b|\btimed out\b/i.test(err?.message);
290
+ }
291
+ isDatabaseError(error) {
292
+ const err = error;
293
+ return /\bconnection\b/i.test(err?.message) &&
294
+ (/\bdatabase\b/i.test(err?.message) ||
295
+ /\bmongodb\b/i.test(err?.message) ||
296
+ /\bredis\b/i.test(err?.message));
297
+ }
298
+ isBadRequestError(error) {
299
+ const err = error;
300
+ return err?.status === HTTP_STATUS_BAD_REQUEST ||
301
+ err?.status === HTTP_STATUS_UNPROCESSABLE_ENTITY;
302
+ }
303
+ isValidationError(error) {
304
+ const err = error;
305
+ return /\bvalidation\b/i.test(err?.message) ||
306
+ err?.name === 'ValidationError';
307
+ }
308
+ isAuthError(error) {
309
+ const err = error;
310
+ return err?.status === HTTP_STATUS_UNAUTHORIZED || /\bunauthorized\b/i.test(err?.message) ||
311
+ /\bauthentication\b/i.test(err?.message);
312
+ }
313
+ isAuthzError(error) {
314
+ const err = error;
315
+ return err?.status === HTTP_STATUS_FORBIDDEN || /\bforbidden\b/i.test(err?.message) ||
316
+ /\bauthorization\b/i.test(err?.message);
317
+ }
318
+ isNotFoundError(error) {
319
+ const err = error;
320
+ return err?.status === HTTP_STATUS_NOT_FOUND || /\bnot found\b/i.test(err?.message);
321
+ }
322
+ isServerError(error) {
323
+ const err = error;
324
+ return err?.status === HTTP_STATUS_BAD_GATEWAY ||
325
+ err?.status === HTTP_STATUS_SERVICE_UNAVAILABLE ||
326
+ err?.status === HTTP_STATUS_GATEWAY_TIMEOUT;
327
+ }
328
+ isRateLimitError(error) {
329
+ const err = error;
330
+ return err?.status === HTTP_STATUS_TOO_MANY_REQUESTS || /\brate limit\b/i.test(err?.message) ||
331
+ /\btoo many requests\b/i.test(err?.message);
332
+ }
333
+ };
334
+ ErrorCategorizerService = ErrorCategorizerService_1 = __decorate([
335
+ Injectable(),
336
+ __metadata("design:paramtypes", [ModuleRef])
337
+ ], ErrorCategorizerService);
338
+ export { ErrorCategorizerService };
339
+ //# sourceMappingURL=error-categorizer.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-categorizer.service.js","sourceRoot":"","sources":["../../../src/common/services/error-categorizer.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ import { ModuleRef } from '@nestjs/core';
2
+ import { LazyModuleRefService } from '../utils/lazy-getter.types.js';
3
+ /**
4
+ * Options for configuring the ErrorSanitizerService.
5
+ */
6
+ export interface ErrorSanitizerOptions {
7
+ /**
8
+ * Additional regex patterns to apply for message sanitization.
9
+ */
10
+ additionalPatterns?: RegExp[];
11
+ /**
12
+ * Additional field names to treat as sensitive and redact.
13
+ */
14
+ additionalSensitiveKeys?: string[];
15
+ }
16
+ /**
17
+ * Injection token for ErrorSanitizerService configuration.
18
+ */
19
+ export declare const ERROR_SANITIZER_OPTIONS = "ERROR_SANITIZER_OPTIONS";
20
+ /**
21
+ * Error Sanitizer Service.
22
+ * Sanitizes error responses and error context to prevent information disclosure in production.
23
+ * Removes sensitive information like stack traces, file paths, database URIs, API keys, email addresses,
24
+ * IP addresses, and custom sensitive fields.
25
+ *
26
+ * Implements defense-in-depth by sanitizing:
27
+ * - Error messages (via regex patterns)
28
+ * - Nested context objects (via field name matching)
29
+ * - Stack traces (removed in production)
30
+ *
31
+ * Sensitive patterns redacted:
32
+ * - File paths (e.g., `/home/user/app.ts` -> `[FILE]`)
33
+ * - Database URIs (e.g., `mongodb://...` -> `[REDACTED]`)
34
+ * - API keys and tokens (e.g., `Bearer sk_live_...` -> `Bearer [REDACTED]`)
35
+ * - Email addresses (e.g., `user@example.com` -> `[EMAIL]`)
36
+ * - IP addresses (IPv4 and IPv6) -> `[IP]`
37
+ * - Sensitive field values (passwords, tokens, API keys, etc.) -> `***REDACTED***`
38
+ *
39
+ * @remarks
40
+ * - Maximum message length: 5000 chars (prevents ReDoS attacks on regex patterns)
41
+ * - Maximum context depth: 5 levels (prevents deeply nested structure processing)
42
+ * - Circular reference detection prevents infinite loops
43
+ * - Case-insensitive field name matching for sensitivity
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const error = {
48
+ * message: 'Error at /home/user/app.ts, Bearer sk_live_abc123',
49
+ * context: { password: 'secret123', userId: '456' }
50
+ * };
51
+ * const sanitized = errorSanitizer.sanitizeErrorResponse(error, false);
52
+ * // message: 'Error at [FILE], Bearer [REDACTED]'
53
+ * // context: { password: '***REDACTED***', userId: '456' }
54
+ * ```
55
+ */
56
+ export declare class ErrorSanitizerService implements LazyModuleRefService {
57
+ /**
58
+ * Maximum length for error messages before truncation.
59
+ * Prevents ReDoS (Regular Expression Denial of Service) attacks by limiting
60
+ * the input size to regex patterns used in message sanitization.
61
+ */
62
+ private static readonly MAX_MESSAGE_LENGTH;
63
+ /**
64
+ * Maximum nesting depth for context object serialization.
65
+ * Prevents deeply nested structures from causing performance issues.
66
+ */
67
+ private static readonly MAX_CONTEXT_DEPTH;
68
+ /**
69
+ * Precompiled regex pattern for matching file paths with code extensions
70
+ * Used to redact file paths from error messages
71
+ */
72
+ private static readonly FILE_PATH_REGEX;
73
+ /**
74
+ * Precompiled regex pattern for matching IPv4 addresses
75
+ */
76
+ private static readonly IPV4_REGEX;
77
+ /**
78
+ * Precompiled regex pattern for matching IPv6 addresses
79
+ * Covers various IPv6 formats: full form, compressed form, ::1, ::ffff:IPv4, bare ::
80
+ * Uses a simpler, non-backtracking pattern to avoid ReDoS (Regular Expression Denial of Service)
81
+ */
82
+ private static readonly IPV6_REGEX;
83
+ /**
84
+ * Default sensitive field names that are always redacted from context
85
+ * Stored as lowercase for case-insensitive matching
86
+ */
87
+ private static readonly DEFAULT_SENSITIVE_KEYS;
88
+ readonly Module: ModuleRef;
89
+ constructor(module: ModuleRef);
90
+ private get Options();
91
+ /**
92
+ * Sanitize error response for client
93
+ * Removes sensitive information like stack traces, file paths, etc.
94
+ */
95
+ sanitizeErrorResponse(error: Record<string, any>, isDevelopment?: boolean): Record<string, any>;
96
+ /**
97
+ * Sanitize an error message to remove sensitive information.
98
+ * Redacts file paths, database connection strings, API keys, Bearer tokens,
99
+ * email addresses, and IP addresses. Truncates overly long messages to prevent
100
+ * ReDoS attacks and ensure reasonable log sizes.
101
+ *
102
+ * @param message - The error message string to sanitize
103
+ * @returns Sanitized message with sensitive patterns replaced by placeholder strings
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * const msg = 'Error at /home/user/app.ts, Bearer sk_live_abc123';
108
+ * const sanitized = sanitizeMessage(msg);
109
+ * // Returns: 'Error at [FILE], Bearer [REDACTED]'
110
+ * ```
111
+ */
112
+ private sanitizeMessage;
113
+ /**
114
+ * Recursively sanitize an error context object to remove sensitive field values.
115
+ * Identifies sensitive fields by name (e.g., password, token, secret) and replaces
116
+ * their values with a redaction marker. Handles nested objects and arrays while
117
+ * detecting circular references to prevent infinite loops.
118
+ *
119
+ * @param context - The context object to sanitize
120
+ * @returns Sanitized context with sensitive field values replaced
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * const ctx = { user: 'john', password: 'secret123', nested: { apiKey: 'sk_live' } };
125
+ * const sanitized = sanitizeContext(ctx);
126
+ * // Returns: { user: 'john', password: '***REDACTED***', nested: { apiKey: '***REDACTED***' } }
127
+ * ```
128
+ */
129
+ private sanitizeContext;
130
+ /**
131
+ * Recursively serialize an object with depth limiting and circular reference detection.
132
+ * Handles nested objects and arrays while preventing infinite loops.
133
+ *
134
+ * @param obj - The object to serialize
135
+ * @param maxDepth - Maximum nesting depth (default 5)
136
+ * @param currentDepth - Current recursion depth
137
+ * @param seen - Set of already-visited objects to detect cycles
138
+ * @returns Serialized object with sensitive fields redacted
139
+ */
140
+ private serializeWithDepthLimit;
141
+ /**
142
+ * Check if field is sensitive (case-insensitive comparison)
143
+ */
144
+ private isSensitiveField;
145
+ }
146
+ //# sourceMappingURL=error-sanitizer.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-sanitizer.service.d.ts","sourceRoot":"","sources":["../../../src/common/services/error-sanitizer.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE9B;;OAEG;IACH,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;CACnC;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,qBACa,qBAAsB,YAAW,oBAAoB;IACjE;;;;OAIG;IAEH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAQ;IAElD;;;OAGG;IAEH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAK;IAE9C;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAqE;IAE5G;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAkC;IAEpE;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAqgB;IAEviB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CA+B5C;IAEF,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,MAAM,EAAE,SAAS;IAI7B,OAAO,KAAK,OAAO,GAMlB;IAED;;;OAGG;IACI,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,aAAa,GAAE,OAAe,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAoB7G;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,eAAe;IAkDvB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,eAAe;IAWvB;;;;;;;;;OASG;IACH,OAAO,CAAC,uBAAuB;IA6D/B;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAWxB"}