logixia 2.0.0 → 2.0.6

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 (239) hide show
  1. package/README.md +172 -2597
  2. package/dist/async-context-2mbUKhcl.mjs +132 -0
  3. package/dist/async-context-2mbUKhcl.mjs.map +1 -0
  4. package/dist/async-context-DUFMDYAr.js +148 -0
  5. package/dist/async-context-DUFMDYAr.js.map +1 -0
  6. package/dist/{azure-monitor.transport-CrvfHd9C.js → azure-monitor.transport-Bu4S2I2q.js} +32 -20
  7. package/dist/azure-monitor.transport-Bu4S2I2q.js.map +1 -0
  8. package/dist/{azure-monitor.transport-Cn_3Usvu.d.ts → azure-monitor.transport-Bvf7Xegt.d.ts} +3 -6
  9. package/dist/azure-monitor.transport-Bvf7Xegt.d.ts.map +1 -0
  10. package/dist/{azure-monitor.transport-CHnjVRF-.mjs → azure-monitor.transport-C1RWAumT.mjs} +27 -15
  11. package/dist/azure-monitor.transport-C1RWAumT.mjs.map +1 -0
  12. package/dist/{azure-monitor.transport-D7Da4RAb.d.mts → azure-monitor.transport-CbSHOnNX.d.mts} +3 -6
  13. package/dist/azure-monitor.transport-CbSHOnNX.d.mts.map +1 -0
  14. package/dist/azure.d.mts +1 -2
  15. package/dist/azure.d.ts +1 -2
  16. package/dist/azure.js +3 -6
  17. package/dist/azure.mjs +1 -6
  18. package/dist/{batch-buffer-PGvSgbmd.mjs → batch-buffer-BvXLDPlV.mjs} +21 -7
  19. package/dist/batch-buffer-BvXLDPlV.mjs.map +1 -0
  20. package/dist/{batch-buffer-BY-mRWIK.js → batch-buffer-C7Am4Mw-.js} +53 -40
  21. package/dist/batch-buffer-C7Am4Mw-.js.map +1 -0
  22. package/dist/browser.d.mts +47 -27
  23. package/dist/browser.d.mts.map +1 -1
  24. package/dist/browser.d.ts +47 -27
  25. package/dist/browser.d.ts.map +1 -1
  26. package/dist/browser.js +464 -62
  27. package/dist/browser.js.map +1 -1
  28. package/dist/browser.mjs +465 -65
  29. package/dist/browser.mjs.map +1 -1
  30. package/dist/{builder-0gEzRopq.mjs → builder-DhNhvOkt.mjs} +307 -246
  31. package/dist/builder-DhNhvOkt.mjs.map +1 -0
  32. package/dist/{builder-D44QktIo.js → builder-yFvJrz7o.js} +435 -399
  33. package/dist/builder-yFvJrz7o.js.map +1 -0
  34. package/dist/cli/index.js +216 -125
  35. package/dist/cloudwatch.d.mts +1 -2
  36. package/dist/cloudwatch.d.ts +1 -2
  37. package/dist/cloudwatch.js +3 -7
  38. package/dist/cloudwatch.mjs +1 -7
  39. package/dist/{cloudwatch.transport-DsEq633o.d.ts → cloudwatch.transport-CQyT6U91.d.ts} +2 -6
  40. package/dist/cloudwatch.transport-CQyT6U91.d.ts.map +1 -0
  41. package/dist/{cloudwatch.transport-BO1ahxw-.js → cloudwatch.transport-Ch1Uae-0.js} +61 -36
  42. package/dist/cloudwatch.transport-Ch1Uae-0.js.map +1 -0
  43. package/dist/{cloudwatch.transport-UlyZFWMn.d.mts → cloudwatch.transport-CjVrI6S4.d.mts} +2 -6
  44. package/dist/cloudwatch.transport-CjVrI6S4.d.mts.map +1 -0
  45. package/dist/{cloudwatch.transport-DZ6ies7g.mjs → cloudwatch.transport-DZqF2xZO.mjs} +54 -28
  46. package/dist/cloudwatch.transport-DZqF2xZO.mjs.map +1 -0
  47. package/dist/{coerce.utils-Cu6IUTgX.mjs → coerce.utils-B_rEudCn.mjs} +3 -4
  48. package/dist/{coerce.utils-Cu6IUTgX.mjs.map → coerce.utils-B_rEudCn.mjs.map} +1 -1
  49. package/dist/{coerce.utils-B-LilukN.js → coerce.utils-C1C5sIX0.js} +8 -10
  50. package/dist/{coerce.utils-B-LilukN.js.map → coerce.utils-C1C5sIX0.js.map} +1 -1
  51. package/dist/correlation.d.mts +15 -69
  52. package/dist/correlation.d.mts.map +1 -1
  53. package/dist/correlation.d.ts +15 -69
  54. package/dist/correlation.d.ts.map +1 -1
  55. package/dist/correlation.js +69 -20
  56. package/dist/correlation.js.map +1 -1
  57. package/dist/correlation.mjs +67 -17
  58. package/dist/correlation.mjs.map +1 -1
  59. package/dist/{entry-fields-BvOLFlJ4.js → entry-fields-BSLkzw18.js} +16 -13
  60. package/dist/entry-fields-BSLkzw18.js.map +1 -0
  61. package/dist/{entry-fields-BJkuPnIg.mjs → entry-fields-J1OBi24o.mjs} +11 -7
  62. package/dist/entry-fields-J1OBi24o.mjs.map +1 -0
  63. package/dist/gcp.d.mts +1 -2
  64. package/dist/gcp.d.ts +1 -2
  65. package/dist/gcp.js +3 -7
  66. package/dist/gcp.mjs +1 -7
  67. package/dist/{gcp.transport-B7oc97sG.d.ts → gcp.transport-BCIvdFV-.d.ts} +5 -8
  68. package/dist/gcp.transport-BCIvdFV-.d.ts.map +1 -0
  69. package/dist/{gcp.transport-GrJurKo8.d.mts → gcp.transport-D9SdLPwP.d.mts} +5 -8
  70. package/dist/gcp.transport-D9SdLPwP.d.mts.map +1 -0
  71. package/dist/{gcp.transport-DBX5TPIy.mjs → gcp.transport-DVCmnA3b.mjs} +59 -16
  72. package/dist/gcp.transport-DVCmnA3b.mjs.map +1 -0
  73. package/dist/{gcp.transport-CHV8MGgz.js → gcp.transport-Dy2Lf8FI.js} +64 -22
  74. package/dist/gcp.transport-Dy2Lf8FI.js.map +1 -0
  75. package/dist/http-shapes-BnBkJcid.d.mts +32 -0
  76. package/dist/http-shapes-BnBkJcid.d.mts.map +1 -0
  77. package/dist/http-shapes-BnBkJcid.d.ts +32 -0
  78. package/dist/http-shapes-BnBkJcid.d.ts.map +1 -0
  79. package/dist/{index-3mw5gaCw.d.mts → index-BSTtFcQ6.d.mts} +142 -13
  80. package/dist/index-BSTtFcQ6.d.mts.map +1 -0
  81. package/dist/{index-DhIoploR.d.ts → index-CFDGkI8n.d.ts} +142 -13
  82. package/dist/index-CFDGkI8n.d.ts.map +1 -0
  83. package/dist/index.d.mts +114 -217
  84. package/dist/index.d.mts.map +1 -1
  85. package/dist/index.d.ts +113 -216
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +182 -279
  88. package/dist/index.js.map +1 -1
  89. package/dist/index.mjs +160 -256
  90. package/dist/index.mjs.map +1 -1
  91. package/dist/internal-log-Bg4V1cPg.mjs +170 -0
  92. package/dist/internal-log-Bg4V1cPg.mjs.map +1 -0
  93. package/dist/internal-log-By4Govmu.js +223 -0
  94. package/dist/internal-log-By4Govmu.js.map +1 -0
  95. package/dist/{logitron-logger-UVeN-mQm.d.ts → logitron-logger-D22Yb61K.d.mts} +121 -100
  96. package/dist/logitron-logger-D22Yb61K.d.mts.map +1 -0
  97. package/dist/{logitron-logger-BFDSO8Io.d.mts → logitron-logger-D_MYYrQt.d.ts} +121 -100
  98. package/dist/logitron-logger-D_MYYrQt.d.ts.map +1 -0
  99. package/dist/middleware.d.mts +13 -28
  100. package/dist/middleware.d.mts.map +1 -1
  101. package/dist/middleware.d.ts +13 -28
  102. package/dist/middleware.d.ts.map +1 -1
  103. package/dist/middleware.js +20 -81
  104. package/dist/middleware.js.map +1 -1
  105. package/dist/middleware.mjs +17 -79
  106. package/dist/middleware.mjs.map +1 -1
  107. package/dist/nest.d.mts +37 -48
  108. package/dist/nest.d.mts.map +1 -1
  109. package/dist/nest.d.ts +37 -48
  110. package/dist/nest.d.ts.map +1 -1
  111. package/dist/nest.js +124 -135
  112. package/dist/nest.js.map +1 -1
  113. package/dist/nest.mjs +69 -78
  114. package/dist/nest.mjs.map +1 -1
  115. package/dist/{transport.manager-BiuCAJd2.mjs → otel-Dt5riXuE.mjs} +275 -117
  116. package/dist/otel-Dt5riXuE.mjs.map +1 -0
  117. package/dist/{transport.manager-CXbKKdVE.js → otel-DyeH6DVR.js} +373 -178
  118. package/dist/otel-DyeH6DVR.js.map +1 -0
  119. package/dist/own-property-BWkibepN.js +40 -0
  120. package/dist/own-property-BWkibepN.js.map +1 -0
  121. package/dist/own-property-CjFw9qwZ.mjs +29 -0
  122. package/dist/own-property-CjFw9qwZ.mjs.map +1 -0
  123. package/dist/{trace.utils-CvXgaiQT.mjs → request-trace-BgNykH9M.mjs} +40 -9
  124. package/dist/request-trace-BgNykH9M.mjs.map +1 -0
  125. package/dist/{trace.utils-DpBOLDtq.js → request-trace-ByujsUZk.js} +117 -77
  126. package/dist/request-trace-ByujsUZk.js.map +1 -0
  127. package/dist/rolldown-runtime-D3PmRqjj.mjs +4 -0
  128. package/dist/{safe-stringify-DJ66tW5I.mjs → safe-stringify-B5p5ktFe.mjs} +39 -15
  129. package/dist/safe-stringify-B5p5ktFe.mjs.map +1 -0
  130. package/dist/{safe-stringify-DWo3aZp_.js → safe-stringify-J3sh-7YM.js} +59 -36
  131. package/dist/safe-stringify-J3sh-7YM.js.map +1 -0
  132. package/dist/{search-C4V0OMEn.js → search-CRjhHxe9.js} +319 -92
  133. package/dist/search-CRjhHxe9.js.map +1 -0
  134. package/dist/{search-CNh9uVwR.d.ts → search-DA3ft3X5.d.mts} +5 -22
  135. package/dist/search-DA3ft3X5.d.mts.map +1 -0
  136. package/dist/{search-BFbu_oVn.mjs → search-DAXKE-P9.mjs} +289 -62
  137. package/dist/search-DAXKE-P9.mjs.map +1 -0
  138. package/dist/{search-DXANsQ2n.d.mts → search-DEl3Pe47.d.ts} +5 -22
  139. package/dist/search-DEl3Pe47.d.ts.map +1 -0
  140. package/dist/search.d.mts +2 -4
  141. package/dist/search.d.ts +2 -4
  142. package/dist/search.js +3 -4
  143. package/dist/search.mjs +1 -4
  144. package/dist/secret-config-CmK2wVkr.js +272 -0
  145. package/dist/secret-config-CmK2wVkr.js.map +1 -0
  146. package/dist/secret-config-Dhb6pqTU.mjs +210 -0
  147. package/dist/secret-config-Dhb6pqTU.mjs.map +1 -0
  148. package/dist/{slack.transport-CXjQYOes.d.ts → slack.transport-BDyENuR0.d.mts} +56 -9
  149. package/dist/slack.transport-BDyENuR0.d.mts.map +1 -0
  150. package/dist/{slack.transport-Bzw7sucI.mjs → slack.transport-BTEwsREY.mjs} +263 -31
  151. package/dist/slack.transport-BTEwsREY.mjs.map +1 -0
  152. package/dist/{slack.transport-BZzoXDPn.d.mts → slack.transport-C6E0l4kw.d.ts} +56 -9
  153. package/dist/slack.transport-C6E0l4kw.d.ts.map +1 -0
  154. package/dist/{slack.transport-BfJRouB2.js → slack.transport-UbYvOdKx.js} +286 -42
  155. package/dist/slack.transport-UbYvOdKx.js.map +1 -0
  156. package/dist/testing.d.mts +13 -11
  157. package/dist/testing.d.mts.map +1 -1
  158. package/dist/testing.d.ts +13 -11
  159. package/dist/testing.d.ts.map +1 -1
  160. package/dist/testing.js +41 -7
  161. package/dist/testing.js.map +1 -1
  162. package/dist/testing.mjs +40 -6
  163. package/dist/testing.mjs.map +1 -1
  164. package/dist/{transport.types-CGoHpWQR.d.ts → transport.types-CzJq4IrF.d.mts} +14 -5
  165. package/dist/transport.types-CzJq4IrF.d.mts.map +1 -0
  166. package/dist/{transport.types-BMnurPcc.d.mts → transport.types-CzJq4IrF.d.ts} +14 -5
  167. package/dist/transport.types-CzJq4IrF.d.ts.map +1 -0
  168. package/dist/transports.d.mts +39 -41
  169. package/dist/transports.d.mts.map +1 -1
  170. package/dist/transports.d.ts +39 -41
  171. package/dist/transports.d.ts.map +1 -1
  172. package/dist/transports.js +19 -22
  173. package/dist/transports.mjs +7 -13
  174. package/dist/worker-entry.js +438 -107
  175. package/dist/worker.d.mts +1 -2
  176. package/dist/worker.d.ts +1 -2
  177. package/dist/worker.js +3 -4
  178. package/dist/worker.mjs +1 -4
  179. package/dist/{worker.transport-JvGPog3C.d.mts → worker.transport-B9mCQSM1.d.ts} +7 -6
  180. package/dist/worker.transport-B9mCQSM1.d.ts.map +1 -0
  181. package/dist/{worker.transport-CdzSZJmw.d.ts → worker.transport-Bl8lFRck.d.mts} +7 -6
  182. package/dist/worker.transport-Bl8lFRck.d.mts.map +1 -0
  183. package/dist/{worker.transport-lPxO2MVL.mjs → worker.transport-BmmOKb1-.mjs} +43 -10
  184. package/dist/worker.transport-BmmOKb1-.mjs.map +1 -0
  185. package/dist/{worker.transport-BdPxu3PN.js → worker.transport-DxxbqQCG.js} +48 -15
  186. package/dist/worker.transport-DxxbqQCG.js.map +1 -0
  187. package/package.json +51 -75
  188. package/dist/async-context-BzJrbfQs.mjs +0 -72
  189. package/dist/async-context-BzJrbfQs.mjs.map +0 -1
  190. package/dist/async-context-DyQQYq3I.js +0 -92
  191. package/dist/async-context-DyQQYq3I.js.map +0 -1
  192. package/dist/azure-monitor.transport-CHnjVRF-.mjs.map +0 -1
  193. package/dist/azure-monitor.transport-Cn_3Usvu.d.ts.map +0 -1
  194. package/dist/azure-monitor.transport-CrvfHd9C.js.map +0 -1
  195. package/dist/azure-monitor.transport-D7Da4RAb.d.mts.map +0 -1
  196. package/dist/batch-buffer-BY-mRWIK.js.map +0 -1
  197. package/dist/batch-buffer-PGvSgbmd.mjs.map +0 -1
  198. package/dist/builder-0gEzRopq.mjs.map +0 -1
  199. package/dist/builder-D44QktIo.js.map +0 -1
  200. package/dist/chunk-DLSkYcPk.mjs +0 -7
  201. package/dist/chunk-nOFOJqeH.js +0 -30
  202. package/dist/cloudwatch.transport-BO1ahxw-.js.map +0 -1
  203. package/dist/cloudwatch.transport-DZ6ies7g.mjs.map +0 -1
  204. package/dist/cloudwatch.transport-DsEq633o.d.ts.map +0 -1
  205. package/dist/cloudwatch.transport-UlyZFWMn.d.mts.map +0 -1
  206. package/dist/entry-fields-BJkuPnIg.mjs.map +0 -1
  207. package/dist/entry-fields-BvOLFlJ4.js.map +0 -1
  208. package/dist/gcp.transport-B7oc97sG.d.ts.map +0 -1
  209. package/dist/gcp.transport-CHV8MGgz.js.map +0 -1
  210. package/dist/gcp.transport-DBX5TPIy.mjs.map +0 -1
  211. package/dist/gcp.transport-GrJurKo8.d.mts.map +0 -1
  212. package/dist/index-3mw5gaCw.d.mts.map +0 -1
  213. package/dist/index-DhIoploR.d.ts.map +0 -1
  214. package/dist/internal-log-BUJYMZbE.js +0 -70
  215. package/dist/internal-log-BUJYMZbE.js.map +0 -1
  216. package/dist/internal-log-Cm8SOWSV.mjs +0 -52
  217. package/dist/internal-log-Cm8SOWSV.mjs.map +0 -1
  218. package/dist/logitron-logger-BFDSO8Io.d.mts.map +0 -1
  219. package/dist/logitron-logger-UVeN-mQm.d.ts.map +0 -1
  220. package/dist/safe-stringify-DJ66tW5I.mjs.map +0 -1
  221. package/dist/safe-stringify-DWo3aZp_.js.map +0 -1
  222. package/dist/search-BFbu_oVn.mjs.map +0 -1
  223. package/dist/search-C4V0OMEn.js.map +0 -1
  224. package/dist/search-CNh9uVwR.d.ts.map +0 -1
  225. package/dist/search-DXANsQ2n.d.mts.map +0 -1
  226. package/dist/slack.transport-BZzoXDPn.d.mts.map +0 -1
  227. package/dist/slack.transport-BfJRouB2.js.map +0 -1
  228. package/dist/slack.transport-Bzw7sucI.mjs.map +0 -1
  229. package/dist/slack.transport-CXjQYOes.d.ts.map +0 -1
  230. package/dist/trace.utils-CvXgaiQT.mjs.map +0 -1
  231. package/dist/trace.utils-DpBOLDtq.js.map +0 -1
  232. package/dist/transport.manager-BiuCAJd2.mjs.map +0 -1
  233. package/dist/transport.manager-CXbKKdVE.js.map +0 -1
  234. package/dist/transport.types-BMnurPcc.d.mts.map +0 -1
  235. package/dist/transport.types-CGoHpWQR.d.ts.map +0 -1
  236. package/dist/worker.transport-BdPxu3PN.js.map +0 -1
  237. package/dist/worker.transport-CdzSZJmw.d.ts.map +0 -1
  238. package/dist/worker.transport-JvGPog3C.d.mts.map +0 -1
  239. package/dist/worker.transport-lPxO2MVL.mjs.map +0 -1
@@ -1,58 +1,6 @@
1
- //#region src/correlation.d.ts
2
- /**
3
- * logixia — Microservices Correlation ID Propagation
4
- *
5
- * Provides zero-boilerplate correlation ID generation and propagation for
6
- * distributed systems. A single correlation ID travels through every service
7
- * in a request fan-out, making it trivial to join logs across services.
8
- *
9
- * Features:
10
- * - UUID v4 correlation ID generation (via `crypto.randomUUID()`)
11
- * - Express / Fastify / NestJS incoming-request middleware
12
- * - `correlationFetch()` — wraps global `fetch`, auto-injects `X-Correlation-ID`
13
- * - `createCorrelationAxiosInterceptor()` — axios request interceptor
14
- * - `childFromRequest(req, logger)` — child logger with all request identifiers
15
- * - Kafka / SQS / RabbitMQ message context helpers
16
- * - Integration with `LogixiaContext` (AsyncLocalStorage) so every `logger.info()`
17
- * call automatically includes the correlationId without per-call passing.
18
- *
19
- * @example Express middleware
20
- * ```ts
21
- * import { correlationMiddleware } from 'logixia/correlation';
22
- * import { logger } from 'logixia';
23
- *
24
- * app.use(correlationMiddleware());
25
- *
26
- * app.get('/orders', (req, res) => {
27
- * // correlationId is automatically in every log inside this request
28
- * logger.info('Listing orders');
29
- * res.json({ ok: true });
30
- * });
31
- * ```
32
- *
33
- * @example Outbound fetch with correlation
34
- * ```ts
35
- * import { correlationFetch } from 'logixia/correlation';
36
- *
37
- * // Reads correlationId from current LogixiaContext and injects it as header
38
- * const data = await correlationFetch('https://payments.internal/charge', {
39
- * method: 'POST',
40
- * body: JSON.stringify({ amount: 100 }),
41
- * });
42
- * ```
43
- *
44
- * @example Manual correlation context
45
- * ```ts
46
- * import { withCorrelationId } from 'logixia/correlation';
47
- *
48
- * await withCorrelationId('trace-abc-123', async () => {
49
- * // All logs and outbound fetch calls in here carry 'trace-abc-123'
50
- * await processOrder();
51
- * });
52
- * ```
53
- */
1
+ import { n as HttpResponseShape, t as HttpRequestShape } from "./http-shapes-BnBkJcid.mjs";
54
2
  /** Fields injected into the log context by the correlation middleware. */
55
- interface CorrelationContext {
3
+ export interface CorrelationContext {
56
4
  correlationId: string;
57
5
  traceId?: string;
58
6
  /** Service that originated the request (from `X-Origin-Service` header). */
@@ -60,7 +8,7 @@ interface CorrelationContext {
60
8
  /** Index signature so CorrelationContext is assignable to LogContext. */
61
9
  [key: string]: unknown;
62
10
  }
63
- interface CorrelationMiddlewareOptions {
11
+ export interface CorrelationMiddlewareOptions {
64
12
  /**
65
13
  * HTTP header to read/write the correlation ID from/to.
66
14
  * @default 'x-correlation-id'
@@ -100,12 +48,12 @@ interface CorrelationMiddlewareOptions {
100
48
  * function's JSDoc and README promise. `logixia/correlation` is Node-only
101
49
  * (it builds on `AsyncLocalStorage`), so importing `node:crypto` is safe here.
102
50
  */
103
- declare function generateCorrelationId(): string;
51
+ export declare function generateCorrelationId(): string;
104
52
  /**
105
53
  * Return the correlation ID from the current `LogixiaContext`, or `undefined`
106
54
  * when called outside any context scope.
107
55
  */
108
- declare function getCurrentCorrelationId(): string | undefined;
56
+ export declare function getCurrentCorrelationId(): string | undefined;
109
57
  /**
110
58
  * Run `callback` inside a correlation context scope.
111
59
  *
@@ -119,7 +67,7 @@ declare function getCurrentCorrelationId(): string | undefined;
119
67
  * });
120
68
  * ```
121
69
  */
122
- declare function withCorrelationId<T>(correlationId: string | undefined, callback: () => T): T;
70
+ export declare function withCorrelationId<T>(correlationId: string | undefined, callback: () => T): T;
123
71
  /**
124
72
  * Express-compatible middleware that:
125
73
  * 1. Reads `X-Correlation-ID` from the incoming request (or generates a new one)
@@ -133,7 +81,7 @@ declare function withCorrelationId<T>(correlationId: string | undefined, callbac
133
81
  * app.use(correlationMiddleware());
134
82
  * ```
135
83
  */
136
- declare function correlationMiddleware(options?: CorrelationMiddlewareOptions): (req: Record<string, unknown>, res: Record<string, unknown>, next: () => void) => void;
84
+ export declare function correlationMiddleware(options?: CorrelationMiddlewareOptions): (req: HttpRequestShape, res: HttpResponseShape, next: () => void) => void;
137
85
  /**
138
86
  * Fastify `onRequest` lifecycle hook — same functionality as `correlationMiddleware`
139
87
  * but adapted to Fastify's hook API.
@@ -144,7 +92,7 @@ declare function correlationMiddleware(options?: CorrelationMiddlewareOptions):
144
92
  * fastify.addHook('onRequest', correlationFastifyHook());
145
93
  * ```
146
94
  */
147
- declare function correlationFastifyHook(options?: CorrelationMiddlewareOptions): (request: Record<string, unknown>, reply: Record<string, unknown>, done: () => void) => void;
95
+ export declare function correlationFastifyHook(options?: CorrelationMiddlewareOptions): (request: HttpRequestShape, reply: HttpResponseShape, done: () => void) => void;
148
96
  /**
149
97
  * A drop-in replacement for `fetch` that automatically injects the current
150
98
  * `correlationId` from `LogixiaContext` as an `X-Correlation-ID` request header.
@@ -162,7 +110,7 @@ declare function correlationFastifyHook(options?: CorrelationMiddlewareOptions):
162
110
  * });
163
111
  * ```
164
112
  */
165
- declare function correlationFetch(input: string | URL | Request, init?: RequestInit, options?: {
113
+ export declare function correlationFetch(input: string | URL | Request, init?: RequestInit, options?: {
166
114
  header?: string;
167
115
  }): Promise<Response>;
168
116
  /**
@@ -177,10 +125,10 @@ declare function correlationFetch(input: string | URL | Request, init?: RequestI
177
125
  * axios.interceptors.request.use(createCorrelationAxiosInterceptor());
178
126
  * ```
179
127
  */
180
- declare function createCorrelationAxiosInterceptor(options?: {
128
+ export declare function createCorrelationAxiosInterceptor(options?: {
181
129
  header?: string;
182
130
  }): (config: Record<string, unknown>) => Record<string, unknown>;
183
- interface ChildFromRequestOptions {
131
+ export interface ChildFromRequestOptions {
184
132
  /** Header to read the correlation ID from. @default 'x-correlation-id' */
185
133
  correlationHeader?: string;
186
134
  /**
@@ -222,9 +170,9 @@ interface ChildFromRequestOptions {
222
170
  * });
223
171
  * ```
224
172
  */
225
- declare function childFromRequest<TLogger extends {
173
+ export declare function childFromRequest<TLogger extends {
226
174
  child(...args: never[]): TLogger;
227
- }>(req: Record<string, unknown>, logger: TLogger, options?: ChildFromRequestOptions): TLogger;
175
+ }>(req: HttpRequestShape, logger: TLogger, options?: ChildFromRequestOptions): TLogger;
228
176
  /**
229
177
  * Extract a correlation context from a Kafka / RabbitMQ / SQS message object.
230
178
  *
@@ -243,7 +191,7 @@ declare function childFromRequest<TLogger extends {
243
191
  * });
244
192
  * ```
245
193
  */
246
- declare function extractMessageCorrelationId(message: Record<string, unknown>): string | undefined;
194
+ export declare function extractMessageCorrelationId(message: Record<string, unknown>): string | undefined;
247
195
  /**
248
196
  * Build Kafka message headers containing the current correlation context.
249
197
  *
@@ -257,7 +205,5 @@ declare function extractMessageCorrelationId(message: Record<string, unknown>):
257
205
  * });
258
206
  * ```
259
207
  */
260
- declare function buildKafkaCorrelationHeaders(): Record<string, string>;
261
- //#endregion
262
- export { ChildFromRequestOptions, CorrelationContext, CorrelationMiddlewareOptions, buildKafkaCorrelationHeaders, childFromRequest, correlationFastifyHook, correlationFetch, correlationMiddleware, createCorrelationAxiosInterceptor, extractMessageCorrelationId, generateCorrelationId, getCurrentCorrelationId, withCorrelationId };
208
+ export declare function buildKafkaCorrelationHeaders(): Record<string, string>;
263
209
  //# sourceMappingURL=correlation.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"correlation.d.mts","names":[],"sources":["../src/correlation.ts"],"sourcesContent":[],"mappings":";;AA6DA;AASA;AA2CA;AAwBA;AAkBA;AAoBA;;;;;AAiDA;;;;;AAwDA;;;;;;;AA4CA;AAyBA;AA2CA;;;;;;;AAmFA;AAyCA;;;;;;;;;;;;;;;;;;;;UAvciB,kBAAA;;;;;;;;UASA,4BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2CD,qBAAA,CAAA;;;;;iBAwBA,uBAAA,CAAA;;;;;;;;;;;;;;iBAkBA,wEAAwE,IAAI;;;;;;;;;;;;;;iBAoB5E,qBAAA,WAA+B,qCAUtC,8BACA;;;;;;;;;;;iBAsCO,sBAAA,WAAgC,yCAUnC,gCACF;;;;;;;;;;;;;;;;;;iBA6CW,gBAAA,iBACJ,MAAM,gBAChB;;IAEL,QAAQ;;;;;;;;;;;;;iBAwCK,iCAAA;;aAEJ,4BAA4B;UAuBvB,uBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2CD;2BAA4D;QACrE,iCACG,mBACC,0BACR;;;;;;;;;;;;;;;;;;;iBA+Ea,2BAAA,UAAqC;;;;;;;;;;;;;;iBAyCrC,4BAAA,CAAA,GAAgC"}
1
+ {"version":3,"file":"correlation.d.mts","names":[],"sources":["../src/correlation.ts"],"mappings":";;iBA8DiB;EACf;EACA;;EAEA;;GAEC;;iBAGc;;;;;EAKf;;;;;EAKA;;;;;EAKA;;;;;;;EAOA;;;;;;EAMA;;;;;;;;;;;;wBAec;;;;;wBAwBA;;;;;;;;;;;;;;wBAkBA,kBAAkB,GAAG,mCAAmC,gBAAgB,IAAI;;;;;;;;;;;;;;wBAoB5E,sBAAsB,UAAS,gCAU3C,KAAK,kBACL,KAAK,mBACL;;;;;;;;;;;wBAkCY,uBAAuB,UAAS,gCAU5C,SAAS,kBACT,OAAO,mBACP;;;;;;;;;;;;;;;;;;wBAyCkB,iBACpB,gBAAgB,MAAM,SACtB,OAAM,aACN;EAAW;IACV,QAAQ;;;;;;;;;;;;;wBAwCK,kCACd;EAAW;KACT,QAAQ,4BAA4B;iBAuBvB;;EAEf;;;;;;;EAOA;;;;;;;EAOA;;;;;;;;;;;;;;;;;;;;;;;;;;wBA2Bc,iBAAiB;EAAkB,SAAS,gBAAgB;GAC1E,KAAK,kBACL,QAAQ,SACR,UAAS,0BACR;;;;;;;;;;;;;;;;;;;wBA+Ea,4BAA4B,SAAS;;;;;;;;;;;;;;wBAyCrC,gCAAgC"}
@@ -1,58 +1,6 @@
1
- //#region src/correlation.d.ts
2
- /**
3
- * logixia — Microservices Correlation ID Propagation
4
- *
5
- * Provides zero-boilerplate correlation ID generation and propagation for
6
- * distributed systems. A single correlation ID travels through every service
7
- * in a request fan-out, making it trivial to join logs across services.
8
- *
9
- * Features:
10
- * - UUID v4 correlation ID generation (via `crypto.randomUUID()`)
11
- * - Express / Fastify / NestJS incoming-request middleware
12
- * - `correlationFetch()` — wraps global `fetch`, auto-injects `X-Correlation-ID`
13
- * - `createCorrelationAxiosInterceptor()` — axios request interceptor
14
- * - `childFromRequest(req, logger)` — child logger with all request identifiers
15
- * - Kafka / SQS / RabbitMQ message context helpers
16
- * - Integration with `LogixiaContext` (AsyncLocalStorage) so every `logger.info()`
17
- * call automatically includes the correlationId without per-call passing.
18
- *
19
- * @example Express middleware
20
- * ```ts
21
- * import { correlationMiddleware } from 'logixia/correlation';
22
- * import { logger } from 'logixia';
23
- *
24
- * app.use(correlationMiddleware());
25
- *
26
- * app.get('/orders', (req, res) => {
27
- * // correlationId is automatically in every log inside this request
28
- * logger.info('Listing orders');
29
- * res.json({ ok: true });
30
- * });
31
- * ```
32
- *
33
- * @example Outbound fetch with correlation
34
- * ```ts
35
- * import { correlationFetch } from 'logixia/correlation';
36
- *
37
- * // Reads correlationId from current LogixiaContext and injects it as header
38
- * const data = await correlationFetch('https://payments.internal/charge', {
39
- * method: 'POST',
40
- * body: JSON.stringify({ amount: 100 }),
41
- * });
42
- * ```
43
- *
44
- * @example Manual correlation context
45
- * ```ts
46
- * import { withCorrelationId } from 'logixia/correlation';
47
- *
48
- * await withCorrelationId('trace-abc-123', async () => {
49
- * // All logs and outbound fetch calls in here carry 'trace-abc-123'
50
- * await processOrder();
51
- * });
52
- * ```
53
- */
1
+ import { n as HttpResponseShape, t as HttpRequestShape } from "./http-shapes-BnBkJcid.js";
54
2
  /** Fields injected into the log context by the correlation middleware. */
55
- interface CorrelationContext {
3
+ export interface CorrelationContext {
56
4
  correlationId: string;
57
5
  traceId?: string;
58
6
  /** Service that originated the request (from `X-Origin-Service` header). */
@@ -60,7 +8,7 @@ interface CorrelationContext {
60
8
  /** Index signature so CorrelationContext is assignable to LogContext. */
61
9
  [key: string]: unknown;
62
10
  }
63
- interface CorrelationMiddlewareOptions {
11
+ export interface CorrelationMiddlewareOptions {
64
12
  /**
65
13
  * HTTP header to read/write the correlation ID from/to.
66
14
  * @default 'x-correlation-id'
@@ -100,12 +48,12 @@ interface CorrelationMiddlewareOptions {
100
48
  * function's JSDoc and README promise. `logixia/correlation` is Node-only
101
49
  * (it builds on `AsyncLocalStorage`), so importing `node:crypto` is safe here.
102
50
  */
103
- declare function generateCorrelationId(): string;
51
+ export declare function generateCorrelationId(): string;
104
52
  /**
105
53
  * Return the correlation ID from the current `LogixiaContext`, or `undefined`
106
54
  * when called outside any context scope.
107
55
  */
108
- declare function getCurrentCorrelationId(): string | undefined;
56
+ export declare function getCurrentCorrelationId(): string | undefined;
109
57
  /**
110
58
  * Run `callback` inside a correlation context scope.
111
59
  *
@@ -119,7 +67,7 @@ declare function getCurrentCorrelationId(): string | undefined;
119
67
  * });
120
68
  * ```
121
69
  */
122
- declare function withCorrelationId<T>(correlationId: string | undefined, callback: () => T): T;
70
+ export declare function withCorrelationId<T>(correlationId: string | undefined, callback: () => T): T;
123
71
  /**
124
72
  * Express-compatible middleware that:
125
73
  * 1. Reads `X-Correlation-ID` from the incoming request (or generates a new one)
@@ -133,7 +81,7 @@ declare function withCorrelationId<T>(correlationId: string | undefined, callbac
133
81
  * app.use(correlationMiddleware());
134
82
  * ```
135
83
  */
136
- declare function correlationMiddleware(options?: CorrelationMiddlewareOptions): (req: Record<string, unknown>, res: Record<string, unknown>, next: () => void) => void;
84
+ export declare function correlationMiddleware(options?: CorrelationMiddlewareOptions): (req: HttpRequestShape, res: HttpResponseShape, next: () => void) => void;
137
85
  /**
138
86
  * Fastify `onRequest` lifecycle hook — same functionality as `correlationMiddleware`
139
87
  * but adapted to Fastify's hook API.
@@ -144,7 +92,7 @@ declare function correlationMiddleware(options?: CorrelationMiddlewareOptions):
144
92
  * fastify.addHook('onRequest', correlationFastifyHook());
145
93
  * ```
146
94
  */
147
- declare function correlationFastifyHook(options?: CorrelationMiddlewareOptions): (request: Record<string, unknown>, reply: Record<string, unknown>, done: () => void) => void;
95
+ export declare function correlationFastifyHook(options?: CorrelationMiddlewareOptions): (request: HttpRequestShape, reply: HttpResponseShape, done: () => void) => void;
148
96
  /**
149
97
  * A drop-in replacement for `fetch` that automatically injects the current
150
98
  * `correlationId` from `LogixiaContext` as an `X-Correlation-ID` request header.
@@ -162,7 +110,7 @@ declare function correlationFastifyHook(options?: CorrelationMiddlewareOptions):
162
110
  * });
163
111
  * ```
164
112
  */
165
- declare function correlationFetch(input: string | URL | Request, init?: RequestInit, options?: {
113
+ export declare function correlationFetch(input: string | URL | Request, init?: RequestInit, options?: {
166
114
  header?: string;
167
115
  }): Promise<Response>;
168
116
  /**
@@ -177,10 +125,10 @@ declare function correlationFetch(input: string | URL | Request, init?: RequestI
177
125
  * axios.interceptors.request.use(createCorrelationAxiosInterceptor());
178
126
  * ```
179
127
  */
180
- declare function createCorrelationAxiosInterceptor(options?: {
128
+ export declare function createCorrelationAxiosInterceptor(options?: {
181
129
  header?: string;
182
130
  }): (config: Record<string, unknown>) => Record<string, unknown>;
183
- interface ChildFromRequestOptions {
131
+ export interface ChildFromRequestOptions {
184
132
  /** Header to read the correlation ID from. @default 'x-correlation-id' */
185
133
  correlationHeader?: string;
186
134
  /**
@@ -222,9 +170,9 @@ interface ChildFromRequestOptions {
222
170
  * });
223
171
  * ```
224
172
  */
225
- declare function childFromRequest<TLogger extends {
173
+ export declare function childFromRequest<TLogger extends {
226
174
  child(...args: never[]): TLogger;
227
- }>(req: Record<string, unknown>, logger: TLogger, options?: ChildFromRequestOptions): TLogger;
175
+ }>(req: HttpRequestShape, logger: TLogger, options?: ChildFromRequestOptions): TLogger;
228
176
  /**
229
177
  * Extract a correlation context from a Kafka / RabbitMQ / SQS message object.
230
178
  *
@@ -243,7 +191,7 @@ declare function childFromRequest<TLogger extends {
243
191
  * });
244
192
  * ```
245
193
  */
246
- declare function extractMessageCorrelationId(message: Record<string, unknown>): string | undefined;
194
+ export declare function extractMessageCorrelationId(message: Record<string, unknown>): string | undefined;
247
195
  /**
248
196
  * Build Kafka message headers containing the current correlation context.
249
197
  *
@@ -257,7 +205,5 @@ declare function extractMessageCorrelationId(message: Record<string, unknown>):
257
205
  * });
258
206
  * ```
259
207
  */
260
- declare function buildKafkaCorrelationHeaders(): Record<string, string>;
261
- //#endregion
262
- export { ChildFromRequestOptions, CorrelationContext, CorrelationMiddlewareOptions, buildKafkaCorrelationHeaders, childFromRequest, correlationFastifyHook, correlationFetch, correlationMiddleware, createCorrelationAxiosInterceptor, extractMessageCorrelationId, generateCorrelationId, getCurrentCorrelationId, withCorrelationId };
208
+ export declare function buildKafkaCorrelationHeaders(): Record<string, string>;
263
209
  //# sourceMappingURL=correlation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"correlation.d.ts","names":[],"sources":["../src/correlation.ts"],"sourcesContent":[],"mappings":";;AA6DA;AASA;AA2CA;AAwBA;AAkBA;AAoBA;;;;;AAiDA;;;;;AAwDA;;;;;;;AA4CA;AAyBA;AA2CA;;;;;;;AAmFA;AAyCA;;;;;;;;;;;;;;;;;;;;UAvciB,kBAAA;;;;;;;;UASA,4BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2CD,qBAAA,CAAA;;;;;iBAwBA,uBAAA,CAAA;;;;;;;;;;;;;;iBAkBA,wEAAwE,IAAI;;;;;;;;;;;;;;iBAoB5E,qBAAA,WAA+B,qCAUtC,8BACA;;;;;;;;;;;iBAsCO,sBAAA,WAAgC,yCAUnC,gCACF;;;;;;;;;;;;;;;;;;iBA6CW,gBAAA,iBACJ,MAAM,gBAChB;;IAEL,QAAQ;;;;;;;;;;;;;iBAwCK,iCAAA;;aAEJ,4BAA4B;UAuBvB,uBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2CD;2BAA4D;QACrE,iCACG,mBACC,0BACR;;;;;;;;;;;;;;;;;;;iBA+Ea,2BAAA,UAAqC;;;;;;;;;;;;;;iBAyCrC,4BAAA,CAAA,GAAgC"}
1
+ {"version":3,"file":"correlation.d.ts","names":[],"sources":["../src/correlation.ts"],"mappings":";;iBA8DiB;EACf;EACA;;EAEA;;GAEC;;iBAGc;;;;;EAKf;;;;;EAKA;;;;;EAKA;;;;;;;EAOA;;;;;;EAMA;;;;;;;;;;;;wBAec;;;;;wBAwBA;;;;;;;;;;;;;;wBAkBA,kBAAkB,GAAG,mCAAmC,gBAAgB,IAAI;;;;;;;;;;;;;;wBAoB5E,sBAAsB,UAAS,gCAU3C,KAAK,kBACL,KAAK,mBACL;;;;;;;;;;;wBAkCY,uBAAuB,UAAS,gCAU5C,SAAS,kBACT,OAAO,mBACP;;;;;;;;;;;;;;;;;;wBAyCkB,iBACpB,gBAAgB,MAAM,SACtB,OAAM,aACN;EAAW;IACV,QAAQ;;;;;;;;;;;;;wBAwCK,kCACd;EAAW;KACT,QAAQ,4BAA4B;iBAuBvB;;EAEf;;;;;;;EAOA;;;;;;;EAOA;;;;;;;;;;;;;;;;;;;;;;;;;;wBA2Bc,iBAAiB;EAAkB,SAAS,gBAAgB;GAC1E,KAAK,kBACL,QAAQ,SACR,UAAS,0BACR;;;;;;;;;;;;;;;;;;;wBA+Ea,4BAA4B,SAAS;;;;;;;;;;;;;;wBAyCrC,gCAAgC"}
@@ -1,10 +1,60 @@
1
- const require_chunk = require('./chunk-nOFOJqeH.js');
2
- const require_trace_utils = require('./trace.utils-DpBOLDtq.js');
3
- const require_async_context = require('./async-context-DyQQYq3I.js');
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_request_trace = require("./request-trace-ByujsUZk.js");
3
+ const require_async_context = require("./async-context-DUFMDYAr.js");
4
4
  let node_crypto = require("node:crypto");
5
- node_crypto = require_chunk.__toESM(node_crypto);
6
-
7
- //#region src/correlation.ts
5
+ // src/correlation.ts
6
+ /**
7
+ * logixia — Microservices Correlation ID Propagation
8
+ *
9
+ * Provides zero-boilerplate correlation ID generation and propagation for
10
+ * distributed systems. A single correlation ID travels through every service
11
+ * in a request fan-out, making it trivial to join logs across services.
12
+ *
13
+ * Features:
14
+ * - UUID v4 correlation ID generation (via `crypto.randomUUID()`)
15
+ * - Express / Fastify / NestJS incoming-request middleware
16
+ * - `correlationFetch()` — wraps global `fetch`, auto-injects `X-Correlation-ID`
17
+ * - `createCorrelationAxiosInterceptor()` — axios request interceptor
18
+ * - `childFromRequest(req, logger)` — child logger with all request identifiers
19
+ * - Kafka / SQS / RabbitMQ message context helpers
20
+ * - Integration with `LogixiaContext` (AsyncLocalStorage) so every `logger.info()`
21
+ * call automatically includes the correlationId without per-call passing.
22
+ *
23
+ * @example Express middleware
24
+ * ```ts
25
+ * import { correlationMiddleware } from 'logixia/correlation';
26
+ * import { logger } from 'logixia';
27
+ *
28
+ * app.use(correlationMiddleware());
29
+ *
30
+ * app.get('/orders', (req, res) => {
31
+ * // correlationId is automatically in every log inside this request
32
+ * logger.info('Listing orders');
33
+ * res.json({ ok: true });
34
+ * });
35
+ * ```
36
+ *
37
+ * @example Outbound fetch with correlation
38
+ * ```ts
39
+ * import { correlationFetch } from 'logixia/correlation';
40
+ *
41
+ * // Reads correlationId from current LogixiaContext and injects it as header
42
+ * const data = await correlationFetch('https://payments.internal/charge', {
43
+ * method: 'POST',
44
+ * body: JSON.stringify({ amount: 100 }),
45
+ * });
46
+ * ```
47
+ *
48
+ * @example Manual correlation context
49
+ * ```ts
50
+ * import { withCorrelationId } from 'logixia/correlation';
51
+ *
52
+ * await withCorrelationId('trace-abc-123', async () => {
53
+ * // All logs and outbound fetch calls in here carry 'trace-abc-123'
54
+ * await processOrder();
55
+ * });
56
+ * ```
57
+ */
8
58
  /**
9
59
  * Generate a new correlation ID using `crypto.randomUUID()` (available in
10
60
  * Node.js 14.17+, all modern browsers, and Edge runtimes).
@@ -27,7 +77,7 @@ function generateCorrelationId() {
27
77
  */
28
78
  function validIncomingId(value) {
29
79
  if (typeof value === "string" && value.trim() !== value) return void 0;
30
- return require_trace_utils.sanitizeIncomingId(value);
80
+ return require_request_trace.sanitizeIncomingId(value);
31
81
  }
32
82
  /**
33
83
  * Return the correlation ID from the current `LogixiaContext`, or `undefined`
@@ -70,12 +120,12 @@ function withCorrelationId(correlationId, callback) {
70
120
  function correlationMiddleware(options = {}) {
71
121
  const { header = "x-correlation-id", originServiceHeader = "x-origin-service", generate = generateCorrelationId, trustIncoming = true, setResponseHeader = true } = options;
72
122
  return function logixiaCorrelationMiddleware(req, res, next) {
73
- const headers = req["headers"] ?? {};
123
+ const headers = req.headers ?? {};
74
124
  const correlationId = (trustIncoming ? validIncomingId(headers[header.toLowerCase()]) : void 0) ?? generate();
75
125
  const originService = validIncomingId(headers[originServiceHeader.toLowerCase()]);
76
126
  if (setResponseHeader) {
77
- const setHeader = res["setHeader"];
78
- if (typeof setHeader === "function") setHeader.call(res, header, correlationId);
127
+ var _res$setHeader;
128
+ (_res$setHeader = res.setHeader) === null || _res$setHeader === void 0 || _res$setHeader.call(res, header, correlationId);
79
129
  }
80
130
  const ctx = {
81
131
  correlationId,
@@ -97,12 +147,12 @@ function correlationMiddleware(options = {}) {
97
147
  function correlationFastifyHook(options = {}) {
98
148
  const { header = "x-correlation-id", originServiceHeader = "x-origin-service", generate = generateCorrelationId, trustIncoming = true, setResponseHeader = true } = options;
99
149
  return function logixiaCorrelationFastifyHook(request, reply, done) {
100
- const headers = request["headers"] ?? {};
150
+ const headers = request.headers ?? {};
101
151
  const correlationId = (trustIncoming ? validIncomingId(headers[header.toLowerCase()]) : void 0) ?? generate();
102
152
  const originService = validIncomingId(headers[originServiceHeader.toLowerCase()]);
103
153
  if (setResponseHeader) {
104
- const replyHeader = reply["header"];
105
- if (typeof replyHeader === "function") replyHeader.call(reply, header, correlationId);
154
+ var _reply$header;
155
+ (_reply$header = reply.header) === null || _reply$header === void 0 || _reply$header.call(reply, header, correlationId);
106
156
  }
107
157
  const ctx = {
108
158
  correlationId,
@@ -192,10 +242,10 @@ const MAX_IP_LENGTH = 64;
192
242
  */
193
243
  function childFromRequest(req, logger, options = {}) {
194
244
  const correlationHeader = options.correlationHeader ?? "x-correlation-id";
195
- const headers = req["headers"] ?? {};
245
+ const headers = req.headers ?? {};
196
246
  const correlationId = validIncomingId(headers[correlationHeader.toLowerCase()]) ?? getCurrentCorrelationId() ?? generateCorrelationId();
197
- const method = req["method"];
198
- const url = req["url"] ?? req["originalUrl"];
247
+ const method = req.method;
248
+ const url = req.url ?? req.originalUrl;
199
249
  const rawUserAgent = headers["user-agent"];
200
250
  const userAgent = typeof rawUserAgent === "string" ? rawUserAgent.slice(0, MAX_USER_AGENT_LENGTH) : void 0;
201
251
  const ip = resolveClientIp(req, headers, options.trustProxy === true);
@@ -224,9 +274,9 @@ function resolveClientIp(req, headers, trustProxy) {
224
274
  const first = typeof forwarded === "string" ? (_forwarded$split$ = forwarded.split(",")[0]) === null || _forwarded$split$ === void 0 ? void 0 : _forwarded$split$.trim() : void 0;
225
275
  if (first) return first.slice(0, MAX_IP_LENGTH);
226
276
  }
227
- const fromReq = req["ip"];
277
+ const fromReq = req.ip;
228
278
  if (typeof fromReq === "string" && fromReq) return fromReq.slice(0, MAX_IP_LENGTH);
229
- const remote = (_req$socket = req["socket"]) === null || _req$socket === void 0 ? void 0 : _req$socket["remoteAddress"];
279
+ const remote = (_req$socket = req.socket) === null || _req$socket === void 0 ? void 0 : _req$socket.remoteAddress;
230
280
  return typeof remote === "string" ? remote.slice(0, MAX_IP_LENGTH) : void 0;
231
281
  }
232
282
  /**
@@ -282,8 +332,6 @@ function buildKafkaCorrelationHeaders() {
282
332
  if (traceId) headers["x-trace-id"] = traceId;
283
333
  return headers;
284
334
  }
285
-
286
- //#endregion
287
335
  exports.buildKafkaCorrelationHeaders = buildKafkaCorrelationHeaders;
288
336
  exports.childFromRequest = childFromRequest;
289
337
  exports.correlationFastifyHook = correlationFastifyHook;
@@ -294,4 +342,5 @@ exports.extractMessageCorrelationId = extractMessageCorrelationId;
294
342
  exports.generateCorrelationId = generateCorrelationId;
295
343
  exports.getCurrentCorrelationId = getCurrentCorrelationId;
296
344
  exports.withCorrelationId = withCorrelationId;
345
+
297
346
  //# sourceMappingURL=correlation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"correlation.js","names":["sanitizeIncomingId","LogixiaContext","ctx: CorrelationContext","headers: Record<string, string>"],"sources":["../src/correlation.ts"],"sourcesContent":["/**\n * logixia — Microservices Correlation ID Propagation\n *\n * Provides zero-boilerplate correlation ID generation and propagation for\n * distributed systems. A single correlation ID travels through every service\n * in a request fan-out, making it trivial to join logs across services.\n *\n * Features:\n * - UUID v4 correlation ID generation (via `crypto.randomUUID()`)\n * - Express / Fastify / NestJS incoming-request middleware\n * - `correlationFetch()` — wraps global `fetch`, auto-injects `X-Correlation-ID`\n * - `createCorrelationAxiosInterceptor()` — axios request interceptor\n * - `childFromRequest(req, logger)` — child logger with all request identifiers\n * - Kafka / SQS / RabbitMQ message context helpers\n * - Integration with `LogixiaContext` (AsyncLocalStorage) so every `logger.info()`\n * call automatically includes the correlationId without per-call passing.\n *\n * @example Express middleware\n * ```ts\n * import { correlationMiddleware } from 'logixia/correlation';\n * import { logger } from 'logixia';\n *\n * app.use(correlationMiddleware());\n *\n * app.get('/orders', (req, res) => {\n * // correlationId is automatically in every log inside this request\n * logger.info('Listing orders');\n * res.json({ ok: true });\n * });\n * ```\n *\n * @example Outbound fetch with correlation\n * ```ts\n * import { correlationFetch } from 'logixia/correlation';\n *\n * // Reads correlationId from current LogixiaContext and injects it as header\n * const data = await correlationFetch('https://payments.internal/charge', {\n * method: 'POST',\n * body: JSON.stringify({ amount: 100 }),\n * });\n * ```\n *\n * @example Manual correlation context\n * ```ts\n * import { withCorrelationId } from 'logixia/correlation';\n *\n * await withCorrelationId('trace-abc-123', async () => {\n * // All logs and outbound fetch calls in here carry 'trace-abc-123'\n * await processOrder();\n * });\n * ```\n */\n\nimport { randomUUID } from 'node:crypto';\n\nimport { LogixiaContext } from './context/async-context';\nimport { sanitizeIncomingId } from './utils/trace.utils';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\n/** Fields injected into the log context by the correlation middleware. */\nexport interface CorrelationContext {\n correlationId: string;\n traceId?: string;\n /** Service that originated the request (from `X-Origin-Service` header). */\n originService?: string;\n /** Index signature so CorrelationContext is assignable to LogContext. */\n [key: string]: unknown;\n}\n\nexport interface CorrelationMiddlewareOptions {\n /**\n * HTTP header to read/write the correlation ID from/to.\n * @default 'x-correlation-id'\n */\n header?: string;\n /**\n * HTTP header for the originating service name.\n * @default 'x-origin-service'\n */\n originServiceHeader?: string;\n /**\n * Function to generate a new correlation ID when none is present in the request.\n * @default () => crypto.randomUUID()\n */\n generate?: () => string;\n /**\n * When `false`, the incoming correlation header is ignored and a new ID is\n * always generated. Use this at the edge when client-supplied IDs should not\n * be trusted.\n * @default true\n */\n trustIncoming?: boolean;\n /**\n * When `true`, the response will include the correlation ID header so\n * clients can log it client-side.\n * @default true\n */\n setResponseHeader?: boolean;\n}\n\n// ── ID generation ─────────────────────────────────────────────────────────────\n\n/**\n * Generate a new correlation ID using `crypto.randomUUID()` (available in\n * Node.js 14.17+, all modern browsers, and Edge runtimes).\n *\n * When the Web Crypto global is unavailable (e.g. Node 18 without\n * `--experimental-global-webcrypto`), fall back to `node:crypto`'s\n * `randomUUID`, which returns a proper UUID v4 — matching the shape this\n * function's JSDoc and README promise. `logixia/correlation` is Node-only\n * (it builds on `AsyncLocalStorage`), so importing `node:crypto` is safe here.\n */\nexport function generateCorrelationId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return randomUUID();\n}\n\n/**\n * Return an incoming correlation ID only if it is short and made of safe\n * characters. Anything else (over-long, empty, or containing newlines or other\n * control characters) is dropped so the caller generates a fresh ID instead of\n * writing client-supplied text into every log line.\n */\nfunction validIncomingId(value: unknown): string | undefined {\n if (typeof value === 'string' && value.trim() !== value) return undefined;\n return sanitizeIncomingId(value);\n}\n\n// ── Context helpers ───────────────────────────────────────────────────────────\n\n/**\n * Return the correlation ID from the current `LogixiaContext`, or `undefined`\n * when called outside any context scope.\n */\nexport function getCurrentCorrelationId(): string | undefined {\n const ctx = LogixiaContext.get();\n return ctx?.correlationId as string | undefined;\n}\n\n/**\n * Run `callback` inside a correlation context scope.\n *\n * If a correlation ID is not provided, a new UUID is generated.\n *\n * @example\n * ```ts\n * await withCorrelationId('cid-abc', async () => {\n * logger.info('Processing message'); // → { correlationId: 'cid-abc', ... }\n * await callDownstream(); // correlationFetch() picks up cid-abc\n * });\n * ```\n */\nexport function withCorrelationId<T>(correlationId: string | undefined, callback: () => T): T {\n const id = correlationId ?? generateCorrelationId();\n return LogixiaContext.run({ correlationId: id }, callback);\n}\n\n// ── Express / Connect middleware ──────────────────────────────────────────────\n\n/**\n * Express-compatible middleware that:\n * 1. Reads `X-Correlation-ID` from the incoming request (or generates a new one)\n * 2. Wraps the request in a `LogixiaContext` so all loggers in the handler\n * automatically include `correlationId`\n * 3. Writes the correlation ID back to the response header (opt-out via options)\n *\n * @example\n * ```ts\n * import { correlationMiddleware } from 'logixia/correlation';\n * app.use(correlationMiddleware());\n * ```\n */\nexport function correlationMiddleware(options: CorrelationMiddlewareOptions = {}) {\n const {\n header = 'x-correlation-id',\n originServiceHeader = 'x-origin-service',\n generate = generateCorrelationId,\n trustIncoming = true,\n setResponseHeader = true,\n } = options;\n\n return function logixiaCorrelationMiddleware(\n req: Record<string, unknown>,\n res: Record<string, unknown>,\n next: () => void\n ): void {\n const headers = (req['headers'] ?? {}) as Record<string, string | undefined>;\n\n // Node lower-cases incoming header names, so look up with lower-cased keys.\n const incomingId = trustIncoming ? validIncomingId(headers[header.toLowerCase()]) : undefined;\n const correlationId = incomingId ?? generate();\n const originService = validIncomingId(headers[originServiceHeader.toLowerCase()]);\n\n if (setResponseHeader) {\n const setHeader = res['setHeader'] as ((name: string, value: string) => void) | undefined;\n if (typeof setHeader === 'function') {\n setHeader.call(res, header, correlationId);\n }\n }\n\n const ctx: CorrelationContext = {\n correlationId,\n ...(originService !== undefined ? { originService } : {}),\n };\n\n LogixiaContext.run(ctx, next);\n };\n}\n\n// ── Fastify hook ──────────────────────────────────────────────────────────────\n\n/**\n * Fastify `onRequest` lifecycle hook — same functionality as `correlationMiddleware`\n * but adapted to Fastify's hook API.\n *\n * @example\n * ```ts\n * import { correlationFastifyHook } from 'logixia/correlation';\n * fastify.addHook('onRequest', correlationFastifyHook());\n * ```\n */\nexport function correlationFastifyHook(options: CorrelationMiddlewareOptions = {}) {\n const {\n header = 'x-correlation-id',\n originServiceHeader = 'x-origin-service',\n generate = generateCorrelationId,\n trustIncoming = true,\n setResponseHeader = true,\n } = options;\n\n return function logixiaCorrelationFastifyHook(\n request: Record<string, unknown>,\n reply: Record<string, unknown>,\n done: () => void\n ): void {\n const headers = (request['headers'] ?? {}) as Record<string, string | undefined>;\n\n // Node lower-cases incoming header names, so look up with lower-cased keys.\n const incomingId = trustIncoming ? validIncomingId(headers[header.toLowerCase()]) : undefined;\n const correlationId = incomingId ?? generate();\n const originService = validIncomingId(headers[originServiceHeader.toLowerCase()]);\n\n if (setResponseHeader) {\n const replyHeader = reply['header'] as ((name: string, value: string) => void) | undefined;\n if (typeof replyHeader === 'function') {\n replyHeader.call(reply, header, correlationId);\n }\n }\n\n const ctx: CorrelationContext = {\n correlationId,\n ...(originService !== undefined ? { originService } : {}),\n };\n\n LogixiaContext.run(ctx, done);\n };\n}\n\n// ── Outbound fetch wrapper ────────────────────────────────────────────────────\n\n/**\n * A drop-in replacement for `fetch` that automatically injects the current\n * `correlationId` from `LogixiaContext` as an `X-Correlation-ID` request header.\n *\n * Falls back to the global `fetch` when no correlation context is active.\n *\n * @example\n * ```ts\n * import { correlationFetch } from 'logixia/correlation';\n *\n * // Inside a request handler with correlationMiddleware active:\n * const response = await correlationFetch('https://payments.internal/v1/charge', {\n * method: 'POST',\n * body: JSON.stringify({ amount: 100 }),\n * });\n * ```\n */\nexport async function correlationFetch(\n input: string | URL | Request,\n init: RequestInit = {},\n options: { header?: string } = {}\n): Promise<Response> {\n const header = options.header ?? 'x-correlation-id';\n const correlationId = getCurrentCorrelationId();\n\n // `init.headers` can be a plain object, a `Headers` instance, or an array of\n // `[name, value]` tuples. Spreading it into a plain object loses everything\n // but the object form: a `Headers` instance has no own enumerable properties,\n // and an array spread yields numeric indices. `Headers` accepts all three, is\n // case-insensitive, and is the shape `fetch` expects back.\n //\n // A `Request` carries headers of its own, and `fetch(request, { headers })`\n // replaces them rather than merging them, so they are seeded first and the\n // caller's `init.headers` is applied on top. Without this, accepting a\n // `Request` here would drop its headers, which is the same defect one input\n // shape over.\n const headers = new Headers(input instanceof Request ? input.headers : undefined);\n for (const [name, value] of new Headers(init.headers)) {\n headers.set(name, value);\n }\n if (correlationId && !headers.has(header)) {\n headers.set(header, correlationId);\n }\n\n return globalThis.fetch(input, { ...init, headers });\n}\n\n// ── Axios interceptor factory ─────────────────────────────────────────────────\n\n/**\n * Returns an axios request interceptor that automatically injects the current\n * correlation ID into outgoing axios requests.\n *\n * @example\n * ```ts\n * import axios from 'axios';\n * import { createCorrelationAxiosInterceptor } from 'logixia/correlation';\n *\n * axios.interceptors.request.use(createCorrelationAxiosInterceptor());\n * ```\n */\nexport function createCorrelationAxiosInterceptor(\n options: { header?: string } = {}\n): (config: Record<string, unknown>) => Record<string, unknown> {\n const header = options.header ?? 'x-correlation-id';\n\n return function correlationAxiosInterceptor(\n config: Record<string, unknown>\n ): Record<string, unknown> {\n const correlationId = getCurrentCorrelationId();\n if (!correlationId) return config;\n\n const headers = (config['headers'] ?? {}) as Record<string, unknown>;\n if (!headers[header]) {\n headers[header] = correlationId;\n }\n\n return { ...config, headers };\n };\n}\n\n// ── Child logger from request ─────────────────────────────────────────────────\n\nconst MAX_USER_AGENT_LENGTH = 512;\nconst MAX_IP_LENGTH = 64;\n\nexport interface ChildFromRequestOptions {\n /** Header to read the correlation ID from. @default 'x-correlation-id' */\n correlationHeader?: string;\n /**\n * Take the client IP from the first `X-Forwarded-For` entry. Only enable this\n * when the app sits behind a proxy that overwrites the header; otherwise any\n * client can choose the logged IP.\n * @default false\n */\n trustProxy?: boolean;\n /**\n * Context name passed as the first argument to `logger.child(context, data)`.\n * When omitted, logixia loggers (detected by their `getContext` /\n * `getAvailableTransports` methods) get `child('request', fields)` and any other\n * logger gets `child(fields)`.\n */\n childContext?: string;\n}\n\n/**\n * Create a child logger enriched with all correlation-relevant identifiers\n * extracted from the incoming HTTP request.\n *\n * The child logger's every call automatically includes:\n * `correlationId`, `method`, `url`, `userAgent`, `ip`\n *\n * The IP comes from `req.ip` / the socket address unless `trustProxy` is set.\n *\n * @example\n * ```ts\n * import { childFromRequest } from 'logixia/correlation';\n * import { logger } from 'logixia';\n *\n * app.use((req, res, next) => {\n * req.logger = childFromRequest(req, logger);\n * next();\n * });\n *\n * app.get('/orders', (req, res) => {\n * req.logger.info('Listing orders'); // → correlationId, requestId, method, url ...\n * });\n * ```\n */\nexport function childFromRequest<TLogger extends { child(...args: never[]): TLogger }>(\n req: Record<string, unknown>,\n logger: TLogger,\n options: ChildFromRequestOptions = {}\n): TLogger {\n const correlationHeader = options.correlationHeader ?? 'x-correlation-id';\n\n const headers = (req['headers'] ?? {}) as Record<string, string | undefined>;\n // Node lower-cases incoming header names, so look up with a lower-cased key.\n const correlationId =\n validIncomingId(headers[correlationHeader.toLowerCase()]) ??\n getCurrentCorrelationId() ??\n generateCorrelationId();\n\n const method = req['method'] as string | undefined;\n const url = (req['url'] as string | undefined) ?? (req['originalUrl'] as string | undefined);\n const rawUserAgent = headers['user-agent'];\n const userAgent =\n typeof rawUserAgent === 'string' ? rawUserAgent.slice(0, MAX_USER_AGENT_LENGTH) : undefined;\n const ip = resolveClientIp(req, headers, options.trustProxy === true);\n\n const fields = {\n correlationId,\n ...(method !== undefined ? { method } : {}),\n ...(url !== undefined ? { url } : {}),\n ...(userAgent !== undefined ? { userAgent } : {}),\n ...(ip !== undefined ? { ip } : {}),\n };\n\n const child = logger.child as (...args: unknown[]) => TLogger;\n if (options.childContext !== undefined) {\n return child.call(logger, options.childContext, fields);\n }\n // logixia's ILogger.child(context: string, data?) takes a string namespace;\n // pino/winston-style loggers take a bindings object.\n if (usesStringContext(logger)) {\n return child.call(logger, 'request', fields);\n }\n return child.call(logger, fields);\n}\n\n/** ILogger implementations (LogixiaLogger, LogixiaLoggerService, mock logger) expose these methods. */\nfunction usesStringContext(logger: object): boolean {\n const l = logger as Record<string, unknown>;\n return typeof l['getContext'] === 'function' || typeof l['getAvailableTransports'] === 'function';\n}\n\nfunction resolveClientIp(\n req: Record<string, unknown>,\n headers: Record<string, string | undefined>,\n trustProxy: boolean\n): string | undefined {\n if (trustProxy) {\n const forwarded = headers['x-forwarded-for'];\n const first = typeof forwarded === 'string' ? forwarded.split(',')[0]?.trim() : undefined;\n if (first) return first.slice(0, MAX_IP_LENGTH);\n }\n const fromReq = req['ip'];\n if (typeof fromReq === 'string' && fromReq) return fromReq.slice(0, MAX_IP_LENGTH);\n const remote = (req['socket'] as Record<string, unknown> | undefined)?.['remoteAddress'];\n return typeof remote === 'string' ? remote.slice(0, MAX_IP_LENGTH) : undefined;\n}\n\n// ── Message queue helpers ─────────────────────────────────────────────────────\n\n/**\n * Extract a correlation context from a Kafka / RabbitMQ / SQS message object.\n *\n * Looks for `correlationId`, `correlation_id`, or `x-correlation-id` in\n * `message.headers` (Kafka) or `message.MessageAttributes` (SQS).\n *\n * @example Kafka consumer\n * ```ts\n * import { extractMessageCorrelationId, withCorrelationId } from 'logixia/correlation';\n *\n * consumer.run({\n * eachMessage: async ({ message }) => {\n * const correlationId = extractMessageCorrelationId(message);\n * await withCorrelationId(correlationId, () => processMessage(message));\n * },\n * });\n * ```\n */\nexport function extractMessageCorrelationId(message: Record<string, unknown>): string | undefined {\n // Kafka: message.headers is Record<string, Buffer | string>\n const kafkaHeaders = message['headers'] as Record<string, Buffer | string> | undefined;\n if (kafkaHeaders) {\n const raw =\n kafkaHeaders['x-correlation-id'] ??\n kafkaHeaders['correlationId'] ??\n kafkaHeaders['correlation_id'];\n if (raw !== undefined) {\n return validIncomingId(Buffer.isBuffer(raw) ? raw.toString('utf8', 0, 512) : String(raw));\n }\n }\n\n // SQS: message.MessageAttributes\n const sqsAttrs = message['MessageAttributes'] as\n Record<string, { StringValue?: string }> | undefined;\n if (sqsAttrs) {\n return validIncomingId(\n sqsAttrs['x-correlation-id']?.StringValue ??\n sqsAttrs['correlationId']?.StringValue ??\n sqsAttrs['correlation_id']?.StringValue\n );\n }\n\n // AMQP / generic envelope\n return validIncomingId(message['correlationId'] ?? message['correlation_id']);\n}\n\n/**\n * Build Kafka message headers containing the current correlation context.\n *\n * @example\n * ```ts\n * import { buildKafkaCorrelationHeaders } from 'logixia/correlation';\n *\n * await producer.send({\n * topic: 'orders',\n * messages: [{ value: JSON.stringify(order), headers: buildKafkaCorrelationHeaders() }],\n * });\n * ```\n */\nexport function buildKafkaCorrelationHeaders(): Record<string, string> {\n const ctx = LogixiaContext.get();\n const headers: Record<string, string> = {};\n\n const correlationId = ctx?.correlationId as string | undefined;\n if (correlationId) headers['x-correlation-id'] = correlationId;\n\n const traceId = ctx?.traceId as string | undefined;\n if (traceId) headers['x-trace-id'] = traceId;\n\n return headers;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"correlation.js","names":["randomUUID","sanitizeIncomingId","LogixiaContext"],"sources":["../src/correlation.ts"],"sourcesContent":["/**\n * logixia — Microservices Correlation ID Propagation\n *\n * Provides zero-boilerplate correlation ID generation and propagation for\n * distributed systems. A single correlation ID travels through every service\n * in a request fan-out, making it trivial to join logs across services.\n *\n * Features:\n * - UUID v4 correlation ID generation (via `crypto.randomUUID()`)\n * - Express / Fastify / NestJS incoming-request middleware\n * - `correlationFetch()` — wraps global `fetch`, auto-injects `X-Correlation-ID`\n * - `createCorrelationAxiosInterceptor()` — axios request interceptor\n * - `childFromRequest(req, logger)` — child logger with all request identifiers\n * - Kafka / SQS / RabbitMQ message context helpers\n * - Integration with `LogixiaContext` (AsyncLocalStorage) so every `logger.info()`\n * call automatically includes the correlationId without per-call passing.\n *\n * @example Express middleware\n * ```ts\n * import { correlationMiddleware } from 'logixia/correlation';\n * import { logger } from 'logixia';\n *\n * app.use(correlationMiddleware());\n *\n * app.get('/orders', (req, res) => {\n * // correlationId is automatically in every log inside this request\n * logger.info('Listing orders');\n * res.json({ ok: true });\n * });\n * ```\n *\n * @example Outbound fetch with correlation\n * ```ts\n * import { correlationFetch } from 'logixia/correlation';\n *\n * // Reads correlationId from current LogixiaContext and injects it as header\n * const data = await correlationFetch('https://payments.internal/charge', {\n * method: 'POST',\n * body: JSON.stringify({ amount: 100 }),\n * });\n * ```\n *\n * @example Manual correlation context\n * ```ts\n * import { withCorrelationId } from 'logixia/correlation';\n *\n * await withCorrelationId('trace-abc-123', async () => {\n * // All logs and outbound fetch calls in here carry 'trace-abc-123'\n * await processOrder();\n * });\n * ```\n */\n\nimport { randomUUID } from 'node:crypto';\n\nimport { LogixiaContext } from './context/async-context';\nimport type { HttpRequestShape, HttpResponseShape } from './types/http-shapes';\nimport { sanitizeIncomingId } from './utils/trace.utils';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\n/** Fields injected into the log context by the correlation middleware. */\nexport interface CorrelationContext {\n correlationId: string;\n traceId?: string;\n /** Service that originated the request (from `X-Origin-Service` header). */\n originService?: string;\n /** Index signature so CorrelationContext is assignable to LogContext. */\n [key: string]: unknown;\n}\n\nexport interface CorrelationMiddlewareOptions {\n /**\n * HTTP header to read/write the correlation ID from/to.\n * @default 'x-correlation-id'\n */\n header?: string;\n /**\n * HTTP header for the originating service name.\n * @default 'x-origin-service'\n */\n originServiceHeader?: string;\n /**\n * Function to generate a new correlation ID when none is present in the request.\n * @default () => crypto.randomUUID()\n */\n generate?: () => string;\n /**\n * When `false`, the incoming correlation header is ignored and a new ID is\n * always generated. Use this at the edge when client-supplied IDs should not\n * be trusted.\n * @default true\n */\n trustIncoming?: boolean;\n /**\n * When `true`, the response will include the correlation ID header so\n * clients can log it client-side.\n * @default true\n */\n setResponseHeader?: boolean;\n}\n\n// ── ID generation ─────────────────────────────────────────────────────────────\n\n/**\n * Generate a new correlation ID using `crypto.randomUUID()` (available in\n * Node.js 14.17+, all modern browsers, and Edge runtimes).\n *\n * When the Web Crypto global is unavailable (e.g. Node 18 without\n * `--experimental-global-webcrypto`), fall back to `node:crypto`'s\n * `randomUUID`, which returns a proper UUID v4 — matching the shape this\n * function's JSDoc and README promise. `logixia/correlation` is Node-only\n * (it builds on `AsyncLocalStorage`), so importing `node:crypto` is safe here.\n */\nexport function generateCorrelationId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return randomUUID();\n}\n\n/**\n * Return an incoming correlation ID only if it is short and made of safe\n * characters. Anything else (over-long, empty, or containing newlines or other\n * control characters) is dropped so the caller generates a fresh ID instead of\n * writing client-supplied text into every log line.\n */\nfunction validIncomingId(value: unknown): string | undefined {\n if (typeof value === 'string' && value.trim() !== value) return undefined;\n return sanitizeIncomingId(value);\n}\n\n// ── Context helpers ───────────────────────────────────────────────────────────\n\n/**\n * Return the correlation ID from the current `LogixiaContext`, or `undefined`\n * when called outside any context scope.\n */\nexport function getCurrentCorrelationId(): string | undefined {\n const ctx = LogixiaContext.get();\n return ctx?.correlationId as string | undefined;\n}\n\n/**\n * Run `callback` inside a correlation context scope.\n *\n * If a correlation ID is not provided, a new UUID is generated.\n *\n * @example\n * ```ts\n * await withCorrelationId('cid-abc', async () => {\n * logger.info('Processing message'); // → { correlationId: 'cid-abc', ... }\n * await callDownstream(); // correlationFetch() picks up cid-abc\n * });\n * ```\n */\nexport function withCorrelationId<T>(correlationId: string | undefined, callback: () => T): T {\n const id = correlationId ?? generateCorrelationId();\n return LogixiaContext.run({ correlationId: id }, callback);\n}\n\n// ── Express / Connect middleware ──────────────────────────────────────────────\n\n/**\n * Express-compatible middleware that:\n * 1. Reads `X-Correlation-ID` from the incoming request (or generates a new one)\n * 2. Wraps the request in a `LogixiaContext` so all loggers in the handler\n * automatically include `correlationId`\n * 3. Writes the correlation ID back to the response header (opt-out via options)\n *\n * @example\n * ```ts\n * import { correlationMiddleware } from 'logixia/correlation';\n * app.use(correlationMiddleware());\n * ```\n */\nexport function correlationMiddleware(options: CorrelationMiddlewareOptions = {}) {\n const {\n header = 'x-correlation-id',\n originServiceHeader = 'x-origin-service',\n generate = generateCorrelationId,\n trustIncoming = true,\n setResponseHeader = true,\n } = options;\n\n return function logixiaCorrelationMiddleware(\n req: HttpRequestShape,\n res: HttpResponseShape,\n next: () => void\n ): void {\n const headers = req.headers ?? {};\n\n // Node lower-cases incoming header names, so look up with lower-cased keys.\n const incomingId = trustIncoming ? validIncomingId(headers[header.toLowerCase()]) : undefined;\n const correlationId = incomingId ?? generate();\n const originService = validIncomingId(headers[originServiceHeader.toLowerCase()]);\n\n if (setResponseHeader) {\n res.setHeader?.(header, correlationId);\n }\n\n const ctx: CorrelationContext = {\n correlationId,\n ...(originService !== undefined ? { originService } : {}),\n };\n\n LogixiaContext.run(ctx, next);\n };\n}\n\n// ── Fastify hook ──────────────────────────────────────────────────────────────\n\n/**\n * Fastify `onRequest` lifecycle hook — same functionality as `correlationMiddleware`\n * but adapted to Fastify's hook API.\n *\n * @example\n * ```ts\n * import { correlationFastifyHook } from 'logixia/correlation';\n * fastify.addHook('onRequest', correlationFastifyHook());\n * ```\n */\nexport function correlationFastifyHook(options: CorrelationMiddlewareOptions = {}) {\n const {\n header = 'x-correlation-id',\n originServiceHeader = 'x-origin-service',\n generate = generateCorrelationId,\n trustIncoming = true,\n setResponseHeader = true,\n } = options;\n\n return function logixiaCorrelationFastifyHook(\n request: HttpRequestShape,\n reply: HttpResponseShape,\n done: () => void\n ): void {\n const headers = request.headers ?? {};\n\n // Node lower-cases incoming header names, so look up with lower-cased keys.\n const incomingId = trustIncoming ? validIncomingId(headers[header.toLowerCase()]) : undefined;\n const correlationId = incomingId ?? generate();\n const originService = validIncomingId(headers[originServiceHeader.toLowerCase()]);\n\n if (setResponseHeader) {\n reply.header?.(header, correlationId);\n }\n\n const ctx: CorrelationContext = {\n correlationId,\n ...(originService !== undefined ? { originService } : {}),\n };\n\n LogixiaContext.run(ctx, done);\n };\n}\n\n// ── Outbound fetch wrapper ────────────────────────────────────────────────────\n\n/**\n * A drop-in replacement for `fetch` that automatically injects the current\n * `correlationId` from `LogixiaContext` as an `X-Correlation-ID` request header.\n *\n * Falls back to the global `fetch` when no correlation context is active.\n *\n * @example\n * ```ts\n * import { correlationFetch } from 'logixia/correlation';\n *\n * // Inside a request handler with correlationMiddleware active:\n * const response = await correlationFetch('https://payments.internal/v1/charge', {\n * method: 'POST',\n * body: JSON.stringify({ amount: 100 }),\n * });\n * ```\n */\nexport async function correlationFetch(\n input: string | URL | Request,\n init: RequestInit = {},\n options: { header?: string } = {}\n): Promise<Response> {\n const header = options.header ?? 'x-correlation-id';\n const correlationId = getCurrentCorrelationId();\n\n // `init.headers` can be a plain object, a `Headers` instance, or an array of\n // `[name, value]` tuples. Spreading it into a plain object loses everything\n // but the object form: a `Headers` instance has no own enumerable properties,\n // and an array spread yields numeric indices. `Headers` accepts all three, is\n // case-insensitive, and is the shape `fetch` expects back.\n //\n // A `Request` carries headers of its own, and `fetch(request, { headers })`\n // replaces them rather than merging them, so they are seeded first and the\n // caller's `init.headers` is applied on top. Without this, accepting a\n // `Request` here would drop its headers, which is the same defect one input\n // shape over.\n const headers = new Headers(input instanceof Request ? input.headers : undefined);\n for (const [name, value] of new Headers(init.headers)) {\n headers.set(name, value);\n }\n if (correlationId && !headers.has(header)) {\n headers.set(header, correlationId);\n }\n\n return globalThis.fetch(input, { ...init, headers });\n}\n\n// ── Axios interceptor factory ─────────────────────────────────────────────────\n\n/**\n * Returns an axios request interceptor that automatically injects the current\n * correlation ID into outgoing axios requests.\n *\n * @example\n * ```ts\n * import axios from 'axios';\n * import { createCorrelationAxiosInterceptor } from 'logixia/correlation';\n *\n * axios.interceptors.request.use(createCorrelationAxiosInterceptor());\n * ```\n */\nexport function createCorrelationAxiosInterceptor(\n options: { header?: string } = {}\n): (config: Record<string, unknown>) => Record<string, unknown> {\n const header = options.header ?? 'x-correlation-id';\n\n return function correlationAxiosInterceptor(\n config: Record<string, unknown>\n ): Record<string, unknown> {\n const correlationId = getCurrentCorrelationId();\n if (!correlationId) return config;\n\n const headers = (config['headers'] ?? {}) as Record<string, unknown>;\n if (!headers[header]) {\n headers[header] = correlationId;\n }\n\n return { ...config, headers };\n };\n}\n\n// ── Child logger from request ─────────────────────────────────────────────────\n\nconst MAX_USER_AGENT_LENGTH = 512;\nconst MAX_IP_LENGTH = 64;\n\nexport interface ChildFromRequestOptions {\n /** Header to read the correlation ID from. @default 'x-correlation-id' */\n correlationHeader?: string;\n /**\n * Take the client IP from the first `X-Forwarded-For` entry. Only enable this\n * when the app sits behind a proxy that overwrites the header; otherwise any\n * client can choose the logged IP.\n * @default false\n */\n trustProxy?: boolean;\n /**\n * Context name passed as the first argument to `logger.child(context, data)`.\n * When omitted, logixia loggers (detected by their `getContext` /\n * `getAvailableTransports` methods) get `child('request', fields)` and any other\n * logger gets `child(fields)`.\n */\n childContext?: string;\n}\n\n/**\n * Create a child logger enriched with all correlation-relevant identifiers\n * extracted from the incoming HTTP request.\n *\n * The child logger's every call automatically includes:\n * `correlationId`, `method`, `url`, `userAgent`, `ip`\n *\n * The IP comes from `req.ip` / the socket address unless `trustProxy` is set.\n *\n * @example\n * ```ts\n * import { childFromRequest } from 'logixia/correlation';\n * import { logger } from 'logixia';\n *\n * app.use((req, res, next) => {\n * req.logger = childFromRequest(req, logger);\n * next();\n * });\n *\n * app.get('/orders', (req, res) => {\n * req.logger.info('Listing orders'); // → correlationId, requestId, method, url ...\n * });\n * ```\n */\nexport function childFromRequest<TLogger extends { child(...args: never[]): TLogger }>(\n req: HttpRequestShape,\n logger: TLogger,\n options: ChildFromRequestOptions = {}\n): TLogger {\n const correlationHeader = options.correlationHeader ?? 'x-correlation-id';\n\n const headers = req.headers ?? {};\n // Node lower-cases incoming header names, so look up with a lower-cased key.\n const correlationId =\n validIncomingId(headers[correlationHeader.toLowerCase()]) ??\n getCurrentCorrelationId() ??\n generateCorrelationId();\n\n const method = req.method;\n const url = req.url ?? req.originalUrl;\n const rawUserAgent = headers['user-agent'];\n const userAgent =\n typeof rawUserAgent === 'string' ? rawUserAgent.slice(0, MAX_USER_AGENT_LENGTH) : undefined;\n const ip = resolveClientIp(req, headers, options.trustProxy === true);\n\n const fields = {\n correlationId,\n ...(method !== undefined ? { method } : {}),\n ...(url !== undefined ? { url } : {}),\n ...(userAgent !== undefined ? { userAgent } : {}),\n ...(ip !== undefined ? { ip } : {}),\n };\n\n const child = logger.child as (...args: unknown[]) => TLogger;\n if (options.childContext !== undefined) {\n return child.call(logger, options.childContext, fields);\n }\n // logixia's ILogger.child(context: string, data?) takes a string namespace;\n // pino/winston-style loggers take a bindings object.\n if (usesStringContext(logger)) {\n return child.call(logger, 'request', fields);\n }\n return child.call(logger, fields);\n}\n\n/** ILogger implementations (LogixiaLogger, LogixiaLoggerService, mock logger) expose these methods. */\nfunction usesStringContext(logger: object): boolean {\n const l = logger as Record<string, unknown>;\n return typeof l['getContext'] === 'function' || typeof l['getAvailableTransports'] === 'function';\n}\n\nfunction resolveClientIp(\n req: HttpRequestShape,\n headers: Record<string, string | string[] | undefined>,\n trustProxy: boolean\n): string | undefined {\n if (trustProxy) {\n const forwarded = headers['x-forwarded-for'];\n const first = typeof forwarded === 'string' ? forwarded.split(',')[0]?.trim() : undefined;\n if (first) return first.slice(0, MAX_IP_LENGTH);\n }\n const fromReq = req.ip;\n if (typeof fromReq === 'string' && fromReq) return fromReq.slice(0, MAX_IP_LENGTH);\n const remote = req.socket?.remoteAddress;\n return typeof remote === 'string' ? remote.slice(0, MAX_IP_LENGTH) : undefined;\n}\n\n// ── Message queue helpers ─────────────────────────────────────────────────────\n\n/**\n * Extract a correlation context from a Kafka / RabbitMQ / SQS message object.\n *\n * Looks for `correlationId`, `correlation_id`, or `x-correlation-id` in\n * `message.headers` (Kafka) or `message.MessageAttributes` (SQS).\n *\n * @example Kafka consumer\n * ```ts\n * import { extractMessageCorrelationId, withCorrelationId } from 'logixia/correlation';\n *\n * consumer.run({\n * eachMessage: async ({ message }) => {\n * const correlationId = extractMessageCorrelationId(message);\n * await withCorrelationId(correlationId, () => processMessage(message));\n * },\n * });\n * ```\n */\nexport function extractMessageCorrelationId(message: Record<string, unknown>): string | undefined {\n // Kafka: message.headers is Record<string, Buffer | string>\n const kafkaHeaders = message['headers'] as Record<string, Buffer | string> | undefined;\n if (kafkaHeaders) {\n const raw =\n kafkaHeaders['x-correlation-id'] ??\n kafkaHeaders['correlationId'] ??\n kafkaHeaders['correlation_id'];\n if (raw !== undefined) {\n return validIncomingId(Buffer.isBuffer(raw) ? raw.toString('utf8', 0, 512) : String(raw));\n }\n }\n\n // SQS: message.MessageAttributes\n const sqsAttrs = message['MessageAttributes'] as\n Record<string, { StringValue?: string }> | undefined;\n if (sqsAttrs) {\n return validIncomingId(\n sqsAttrs['x-correlation-id']?.StringValue ??\n sqsAttrs['correlationId']?.StringValue ??\n sqsAttrs['correlation_id']?.StringValue\n );\n }\n\n // AMQP / generic envelope\n return validIncomingId(message['correlationId'] ?? message['correlation_id']);\n}\n\n/**\n * Build Kafka message headers containing the current correlation context.\n *\n * @example\n * ```ts\n * import { buildKafkaCorrelationHeaders } from 'logixia/correlation';\n *\n * await producer.send({\n * topic: 'orders',\n * messages: [{ value: JSON.stringify(order), headers: buildKafkaCorrelationHeaders() }],\n * });\n * ```\n */\nexport function buildKafkaCorrelationHeaders(): Record<string, string> {\n const ctx = LogixiaContext.get();\n const headers: Record<string, string> = {};\n\n const correlationId = ctx?.correlationId as string | undefined;\n if (correlationId) headers['x-correlation-id'] = correlationId;\n\n const traceId = ctx?.traceId as string | undefined;\n if (traceId) headers['x-trace-id'] = traceId;\n\n return headers;\n}\n"],"mappings":"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"}