autotel 2.26.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/README.md +29 -19
  2. package/dist/attributes.d.cts +3 -3
  3. package/dist/attributes.d.ts +3 -3
  4. package/dist/business-baggage.d.cts +1 -1
  5. package/dist/business-baggage.d.ts +1 -1
  6. package/dist/{chunk-YN7USLHW.js → chunk-3QMFLJHJ.js} +11 -10
  7. package/dist/chunk-3QMFLJHJ.js.map +1 -0
  8. package/dist/{chunk-BJ2XPN77.js → chunk-4DAG3RFS.js} +4 -4
  9. package/dist/{chunk-BJ2XPN77.js.map → chunk-4DAG3RFS.js.map} +1 -1
  10. package/dist/chunk-4P6ZOARG.cjs +33 -0
  11. package/dist/chunk-4P6ZOARG.cjs.map +1 -0
  12. package/dist/{chunk-U54FTVFH.js → chunk-7HNQYHK4.js} +3 -3
  13. package/dist/{chunk-U54FTVFH.js.map → chunk-7HNQYHK4.js.map} +1 -1
  14. package/dist/chunk-CJ4PD2TZ.cjs +1207 -0
  15. package/dist/chunk-CJ4PD2TZ.cjs.map +1 -0
  16. package/dist/{chunk-HPUGKUMZ.js → chunk-DAAJLUTO.js} +13 -640
  17. package/dist/chunk-DAAJLUTO.js.map +1 -0
  18. package/dist/{chunk-B3ZHLLMP.js → chunk-DSMSIVTG.js} +2 -2
  19. package/dist/chunk-DSMSIVTG.js.map +1 -0
  20. package/dist/{chunk-6YGUN7IY.cjs → chunk-DWOBIBLY.cjs} +18 -17
  21. package/dist/chunk-DWOBIBLY.cjs.map +1 -0
  22. package/dist/{chunk-QC5MNKVF.js → chunk-IUDXKLS4.js} +13 -12
  23. package/dist/chunk-IUDXKLS4.js.map +1 -0
  24. package/dist/{chunk-OBWXM4NN.cjs → chunk-KHGA4OST.cjs} +15 -14
  25. package/dist/chunk-KHGA4OST.cjs.map +1 -0
  26. package/dist/chunk-KIL5CUN6.js +31 -0
  27. package/dist/chunk-KIL5CUN6.js.map +1 -0
  28. package/dist/{chunk-YEVCD6DR.cjs → chunk-L7JDUDJD.cjs} +7 -7
  29. package/dist/{chunk-YEVCD6DR.cjs.map → chunk-L7JDUDJD.cjs.map} +1 -1
  30. package/dist/{chunk-UTZR7P7E.cjs → chunk-MOK3E54E.cjs} +29 -659
  31. package/dist/chunk-MOK3E54E.cjs.map +1 -0
  32. package/dist/{chunk-GML3FBOT.cjs → chunk-NCSMD3TK.cjs} +2 -2
  33. package/dist/chunk-NCSMD3TK.cjs.map +1 -0
  34. package/dist/chunk-QG3U5ONP.js +1183 -0
  35. package/dist/chunk-QG3U5ONP.js.map +1 -0
  36. package/dist/chunk-SEO6NAQT.js +14 -0
  37. package/dist/chunk-SEO6NAQT.js.map +1 -0
  38. package/dist/chunk-VQTCQKHQ.cjs +17 -0
  39. package/dist/chunk-VQTCQKHQ.cjs.map +1 -0
  40. package/dist/{chunk-WZOKY3PW.cjs → chunk-ZSABTI3C.cjs} +8 -8
  41. package/dist/{chunk-WZOKY3PW.cjs.map → chunk-ZSABTI3C.cjs.map} +1 -1
  42. package/dist/correlation-id.cjs +22 -10
  43. package/dist/correlation-id.js +14 -2
  44. package/dist/decorators.cjs +5 -6
  45. package/dist/decorators.cjs.map +1 -1
  46. package/dist/decorators.d.cts +1 -1
  47. package/dist/decorators.d.ts +1 -1
  48. package/dist/decorators.js +4 -5
  49. package/dist/decorators.js.map +1 -1
  50. package/dist/event.cjs +6 -7
  51. package/dist/event.js +3 -4
  52. package/dist/functional.cjs +11 -12
  53. package/dist/functional.d.cts +1 -1
  54. package/dist/functional.d.ts +1 -1
  55. package/dist/functional.js +4 -5
  56. package/dist/http.cjs +13 -2
  57. package/dist/http.cjs.map +1 -1
  58. package/dist/http.js +12 -1
  59. package/dist/http.js.map +1 -1
  60. package/dist/index.cjs +134 -243
  61. package/dist/index.cjs.map +1 -1
  62. package/dist/index.d.cts +23 -8
  63. package/dist/index.d.ts +23 -8
  64. package/dist/index.js +52 -176
  65. package/dist/index.js.map +1 -1
  66. package/dist/messaging-adapters.d.cts +1 -1
  67. package/dist/messaging-adapters.d.ts +1 -1
  68. package/dist/messaging-testing.d.cts +1 -1
  69. package/dist/messaging-testing.d.ts +1 -1
  70. package/dist/messaging.cjs +9 -9
  71. package/dist/messaging.d.cts +1 -1
  72. package/dist/messaging.d.ts +1 -1
  73. package/dist/messaging.js +6 -6
  74. package/dist/semantic-helpers.cjs +9 -10
  75. package/dist/semantic-helpers.d.cts +1 -1
  76. package/dist/semantic-helpers.d.ts +1 -1
  77. package/dist/semantic-helpers.js +5 -6
  78. package/dist/{trace-context-t5X1AP-e.d.ts → trace-context-DbGKd1Rn.d.cts} +18 -5
  79. package/dist/{trace-context-t5X1AP-e.d.cts → trace-context-DbGKd1Rn.d.ts} +18 -5
  80. package/dist/trace-helpers.cjs +13 -13
  81. package/dist/trace-helpers.d.cts +2 -2
  82. package/dist/trace-helpers.d.ts +2 -2
  83. package/dist/trace-helpers.js +1 -1
  84. package/dist/{utils-CbUkl8r1.d.cts → utils-BahBCFtJ.d.cts} +1 -1
  85. package/dist/{utils-Buel3cj0.d.ts → utils-CLKwaUlG.d.ts} +1 -1
  86. package/dist/webhook.cjs +19 -10
  87. package/dist/webhook.cjs.map +1 -1
  88. package/dist/webhook.d.cts +1 -1
  89. package/dist/webhook.d.ts +1 -1
  90. package/dist/webhook.js +18 -9
  91. package/dist/webhook.js.map +1 -1
  92. package/dist/workflow-distributed.cjs +23 -19
  93. package/dist/workflow-distributed.cjs.map +1 -1
  94. package/dist/workflow-distributed.d.cts +1 -1
  95. package/dist/workflow-distributed.d.ts +1 -1
  96. package/dist/workflow-distributed.js +21 -17
  97. package/dist/workflow-distributed.js.map +1 -1
  98. package/dist/workflow.cjs +10 -10
  99. package/dist/workflow.d.cts +1 -1
  100. package/dist/workflow.d.ts +1 -1
  101. package/dist/workflow.js +6 -6
  102. package/package.json +1 -1
  103. package/skills/autotel-core/SKILL.md +2 -0
  104. package/skills/autotel-events/SKILL.md +2 -0
  105. package/skills/autotel-frameworks/SKILL.md +2 -0
  106. package/skills/autotel-instrumentation/SKILL.md +2 -0
  107. package/skills/autotel-request-logging/SKILL.md +2 -0
  108. package/skills/autotel-structured-errors/SKILL.md +2 -0
  109. package/src/correlated-events.test.ts +151 -0
  110. package/src/correlated-events.ts +47 -0
  111. package/src/functional.ts +2 -0
  112. package/src/gen-ai-events.ts +14 -5
  113. package/src/index.ts +20 -4
  114. package/src/messaging.ts +10 -9
  115. package/src/request-logger.ts +4 -3
  116. package/src/structured-error.test.ts +83 -1
  117. package/src/structured-error.ts +9 -2
  118. package/src/trace-context.ts +39 -11
  119. package/src/trace-helpers.ts +2 -2
  120. package/src/trace-hybrid.test.ts +42 -0
  121. package/src/trace-hybrid.ts +37 -0
  122. package/src/webhook.ts +16 -7
  123. package/src/workflow-distributed.ts +18 -13
  124. package/src/workflow.ts +7 -6
  125. package/dist/chunk-6YGUN7IY.cjs.map +0 -1
  126. package/dist/chunk-B3ZHLLMP.js.map +0 -1
  127. package/dist/chunk-BBBWDIYQ.js +0 -211
  128. package/dist/chunk-BBBWDIYQ.js.map +0 -1
  129. package/dist/chunk-D5LMF53P.cjs +0 -150
  130. package/dist/chunk-D5LMF53P.cjs.map +0 -1
  131. package/dist/chunk-GML3FBOT.cjs.map +0 -1
  132. package/dist/chunk-HPUGKUMZ.js.map +0 -1
  133. package/dist/chunk-HZ3FYBJG.cjs +0 -217
  134. package/dist/chunk-HZ3FYBJG.cjs.map +0 -1
  135. package/dist/chunk-JSNUWSBH.cjs +0 -62
  136. package/dist/chunk-JSNUWSBH.cjs.map +0 -1
  137. package/dist/chunk-OBWXM4NN.cjs.map +0 -1
  138. package/dist/chunk-QC5MNKVF.js.map +0 -1
  139. package/dist/chunk-S4OFEXLA.js +0 -53
  140. package/dist/chunk-S4OFEXLA.js.map +0 -1
  141. package/dist/chunk-UTZR7P7E.cjs.map +0 -1
  142. package/dist/chunk-WD4RP6IV.js +0 -146
  143. package/dist/chunk-WD4RP6IV.js.map +0 -1
  144. package/dist/chunk-YN7USLHW.js.map +0 -1
@@ -1,10 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunkUTZR7P7E_cjs = require('./chunk-UTZR7P7E.cjs');
4
- require('./chunk-GML3FBOT.cjs');
5
- require('./chunk-D5LMF53P.cjs');
6
- require('./chunk-JSNUWSBH.cjs');
7
- require('./chunk-HZ3FYBJG.cjs');
3
+ var chunkMOK3E54E_cjs = require('./chunk-MOK3E54E.cjs');
4
+ require('./chunk-NCSMD3TK.cjs');
5
+ require('./chunk-VQTCQKHQ.cjs');
6
+ require('./chunk-CJ4PD2TZ.cjs');
8
7
  require('./chunk-563EL6O6.cjs');
9
8
  require('./chunk-OC6X2VIN.cjs');
10
9
  require('./chunk-CEAQK2QY.cjs');
@@ -24,31 +23,31 @@ require('./chunk-JEQ2X3Z6.cjs');
24
23
 
25
24
  Object.defineProperty(exports, "ctx", {
26
25
  enumerable: true,
27
- get: function () { return chunkUTZR7P7E_cjs.ctx; }
26
+ get: function () { return chunkMOK3E54E_cjs.ctx; }
28
27
  });
29
28
  Object.defineProperty(exports, "instrument", {
30
29
  enumerable: true,
31
- get: function () { return chunkUTZR7P7E_cjs.instrument; }
30
+ get: function () { return chunkMOK3E54E_cjs.instrument; }
32
31
  });
33
32
  Object.defineProperty(exports, "span", {
34
33
  enumerable: true,
35
- get: function () { return chunkUTZR7P7E_cjs.span; }
34
+ get: function () { return chunkMOK3E54E_cjs.span; }
36
35
  });
37
36
  Object.defineProperty(exports, "trace", {
38
37
  enumerable: true,
39
- get: function () { return chunkUTZR7P7E_cjs.trace; }
38
+ get: function () { return chunkMOK3E54E_cjs.trace; }
40
39
  });
41
40
  Object.defineProperty(exports, "withBaggage", {
42
41
  enumerable: true,
43
- get: function () { return chunkUTZR7P7E_cjs.withBaggage; }
42
+ get: function () { return chunkMOK3E54E_cjs.withBaggage; }
44
43
  });
45
44
  Object.defineProperty(exports, "withNewContext", {
46
45
  enumerable: true,
47
- get: function () { return chunkUTZR7P7E_cjs.withNewContext; }
46
+ get: function () { return chunkMOK3E54E_cjs.withNewContext; }
48
47
  });
49
48
  Object.defineProperty(exports, "withTracing", {
50
49
  enumerable: true,
51
- get: function () { return chunkUTZR7P7E_cjs.withTracing; }
50
+ get: function () { return chunkMOK3E54E_cjs.withTracing; }
52
51
  });
53
52
  //# sourceMappingURL=functional.cjs.map
54
53
  //# sourceMappingURL=functional.cjs.map
@@ -1,7 +1,7 @@
1
1
  import * as _opentelemetry_api from '@opentelemetry/api';
2
2
  import { Span } from '@opentelemetry/api';
3
3
  import { Sampler } from './sampling.cjs';
4
- import { T as TraceContext } from './trace-context-t5X1AP-e.cjs';
4
+ import { T as TraceContext } from './trace-context-DbGKd1Rn.cjs';
5
5
  import './logger.cjs';
6
6
  import 'pino';
7
7
 
@@ -1,7 +1,7 @@
1
1
  import * as _opentelemetry_api from '@opentelemetry/api';
2
2
  import { Span } from '@opentelemetry/api';
3
3
  import { Sampler } from './sampling.js';
4
- import { T as TraceContext } from './trace-context-t5X1AP-e.js';
4
+ import { T as TraceContext } from './trace-context-DbGKd1Rn.js';
5
5
  import './logger.js';
6
6
  import 'pino';
7
7
 
@@ -1,8 +1,7 @@
1
- export { ctx, instrument, span, trace, withBaggage, withNewContext, withTracing } from './chunk-HPUGKUMZ.js';
2
- import './chunk-B3ZHLLMP.js';
3
- import './chunk-WD4RP6IV.js';
4
- import './chunk-S4OFEXLA.js';
5
- import './chunk-BBBWDIYQ.js';
1
+ export { ctx, instrument, span, trace, withBaggage, withNewContext, withTracing } from './chunk-DAAJLUTO.js';
2
+ import './chunk-DSMSIVTG.js';
3
+ import './chunk-SEO6NAQT.js';
4
+ import './chunk-QG3U5ONP.js';
6
5
  import './chunk-W35FVJBC.js';
7
6
  import './chunk-3SDILILG.js';
8
7
  import './chunk-A4E5AQFK.js';
package/dist/http.cjs CHANGED
@@ -1,6 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var chunkHZ3FYBJG_cjs = require('./chunk-HZ3FYBJG.cjs');
3
+ var chunkCJ4PD2TZ_cjs = require('./chunk-CJ4PD2TZ.cjs');
4
+ require('./chunk-563EL6O6.cjs');
5
+ require('./chunk-OC6X2VIN.cjs');
6
+ require('./chunk-CEAQK2QY.cjs');
7
+ require('./chunk-ZNMBW67B.cjs');
8
+ require('./chunk-IOYFAFHJ.cjs');
9
+ require('./chunk-CMNGGTQL.cjs');
10
+ require('./chunk-CU6IDACR.cjs');
11
+ require('./chunk-6S5RUKU3.cjs');
12
+ require('./chunk-YS6C2YJE.cjs');
13
+ require('./chunk-VH77IPJN.cjs');
14
+ require('./chunk-FU6R566Y.cjs');
4
15
  var chunkESLWRGAG_cjs = require('./chunk-ESLWRGAG.cjs');
5
16
  require('./chunk-YREV3LGG.cjs');
6
17
  require('./chunk-JEQ2X3Z6.cjs');
@@ -166,7 +177,7 @@ function extractStatusCode(result) {
166
177
  return void 0;
167
178
  }
168
179
  function injectTraceContext(headers = {}) {
169
- const currentContext = chunkHZ3FYBJG_cjs.getActiveContextWithBaggage();
180
+ const currentContext = chunkCJ4PD2TZ_cjs.getActiveContextWithBaggage();
170
181
  api.propagation.inject(currentContext, headers);
171
182
  return headers;
172
183
  }
package/dist/http.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/http.ts"],"names":["args","getConfig","SpanStatusCode","getActiveContextWithBaggage","propagation","context"],"mappings":"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","file":"http.cjs","sourcesContent":["/**\n * HTTP Instrumentation Helpers\n *\n * Optional import: Not included in main bundle\n * Import from: 'autotel/http'\n *\n * Provides decorators and utilities for HTTP client instrumentation.\n * Works with fetch, axios, and other HTTP clients.\n *\n * @example\n * ```typescript\n * import { HttpInstrumented } from 'autotel/http'\n *\n * @HttpInstrumented()\n * class ApiClient {\n * async getUser(id: string) {\n * return fetch(`/api/users/${id}`)\n * }\n * }\n * ```\n */\n\nimport { SpanStatusCode, context, propagation } from '@opentelemetry/api';\nimport { getConfig } from './config';\nimport { getActiveContextWithBaggage } from './trace-context';\n\nexport interface HttpInstrumentedOptions {\n /** Service name for HTTP calls (default: 'http-client') */\n serviceName?: string;\n /** Extract URL from method arguments (default: first arg) */\n urlExtractor?: (args: unknown[]) => string | undefined;\n /** Extract HTTP method from method name or args */\n methodExtractor?: (methodName: string, args: unknown[]) => string;\n /** Add custom attributes to spans */\n attributesFromArgs?: (args: unknown[]) => Record<string, string | number>;\n /** Slow request threshold in milliseconds (adds warning attribute) - default: 3000ms */\n slowRequestThresholdMs?: number;\n}\n\n/**\n * Decorator for auto-instrumenting HTTP client methods\n *\n * @example Basic usage\n * ```typescript\n * @HttpInstrumented()\n * class ApiClient {\n * async fetchUser(userId: string) {\n * const res = await fetch(`https://api.example.com/users/${userId}`)\n * return res.json()\n * }\n *\n * async createOrder(order: Order) {\n * const res = await fetch('https://api.example.com/orders', {\n * method: 'POST',\n * body: JSON.stringify(order)\n * })\n * return res.json()\n * }\n * }\n * ```\n *\n * @example Advanced usage with custom extractors\n * ```typescript\n * @HttpInstrumented({\n * serviceName: 'payment-gateway',\n * urlExtractor: (args) => {\n * const config = args[0] as RequestConfig\n * return config.url\n * },\n * attributesFromArgs: (args) => ({\n * 'http.request_id': args[0]?.requestId,\n * 'http.retry_count': args[0]?.retryCount || 0\n * })\n * })\n * class PaymentClient {\n * async charge(config: RequestConfig) {\n * return axios(config)\n * }\n * }\n * ```\n */\nexport function HttpInstrumented(options: HttpInstrumentedOptions = {}) {\n const serviceName = options.serviceName || 'http-client';\n const slowRequestThresholdMs = options.slowRequestThresholdMs ?? 3000;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-empty-object-type\n return function <T extends { new (...args: any[]): {} }>(\n target: T,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _context: ClassDecoratorContext,\n ) {\n return class extends target {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(...args: any[]) {\n super(...args);\n\n const proto = target.prototype;\n const methodNames = Object.getOwnPropertyNames(proto).filter(\n (name) =>\n name !== 'constructor' &&\n typeof proto[name] === 'function' &&\n !name.startsWith('_'),\n );\n\n for (const methodName of methodNames) {\n const originalMethod = proto[methodName];\n\n if (\n originalMethod.constructor.name === 'AsyncFunction' ||\n originalMethod.toString().startsWith('async ')\n ) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const wrappedMethod = async (...args: any[]) => {\n const config = getConfig();\n const tracer = config.tracer;\n\n const url = options.urlExtractor\n ? options.urlExtractor(args)\n : (args[0] as string | undefined);\n\n const method = options.methodExtractor\n ? options.methodExtractor(methodName, args)\n : inferHttpMethod(methodName);\n\n const spanName = url\n ? `HTTP ${method} ${extractPath(url)}`\n : `HTTP ${method}`;\n\n return tracer.startActiveSpan(spanName, async (span) => {\n const startTime = performance.now();\n\n try {\n span.setAttributes({\n 'http.method': method,\n 'http.url': url || 'unknown',\n 'service.name': serviceName,\n 'operation.name': `${serviceName}.${methodName}`,\n });\n\n if (url) {\n const urlObj = parseUrl(url);\n span.setAttributes({\n 'http.scheme': urlObj.protocol,\n 'http.host': urlObj.host,\n 'http.target': urlObj.path,\n });\n }\n\n if (options.attributesFromArgs) {\n span.setAttributes(options.attributesFromArgs(args));\n }\n\n const result = await originalMethod.apply(this, args);\n\n const duration = performance.now() - startTime;\n\n // Extract status code from response\n const statusCode = extractStatusCode(result);\n if (statusCode) {\n span.setAttribute('http.status_code', statusCode);\n\n if (statusCode >= 400) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: `HTTP ${statusCode}`,\n });\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n\n span.setAttributes({\n 'http.duration_ms': duration,\n });\n\n // Mark slow requests for investigation\n if (duration > slowRequestThresholdMs) {\n span.setAttribute('http.slow_request', true);\n span.setAttribute(\n 'http.slow_request_threshold_ms',\n slowRequestThresholdMs,\n );\n }\n\n return result;\n } catch (error) {\n const duration = performance.now() - startTime;\n\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message:\n error instanceof Error ? error.message : 'Unknown error',\n });\n\n span.setAttributes({\n 'http.duration_ms': duration,\n 'error.type':\n error instanceof Error\n ? error.constructor.name\n : 'Unknown',\n 'error.message':\n error instanceof Error ? error.message : 'Unknown error',\n });\n\n throw error;\n } finally {\n span.end();\n }\n });\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any)[methodName] = wrappedMethod;\n }\n }\n }\n };\n };\n}\n\n/**\n * Helper: Trace a single HTTP request\n *\n * @example\n * ```typescript\n * import { traceHttpRequest } from 'autotel/http'\n *\n * const data = await traceHttpRequest(\n * 'GET /api/users',\n * () => fetch('https://api.example.com/users')\n * )\n * ```\n */\nexport async function traceHttpRequest<T>(\n spanName: string,\n fn: () => Promise<T>,\n attributes?: Record<string, string | number>,\n): Promise<T> {\n const config = getConfig();\n const tracer = config.tracer;\n\n return tracer.startActiveSpan(spanName, async (span) => {\n try {\n if (attributes) {\n span.setAttributes(attributes);\n }\n\n const result = await fn();\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n } finally {\n span.end();\n }\n });\n}\n\n// Helper functions\n\nfunction inferHttpMethod(methodName: string): string {\n const lower = methodName.toLowerCase();\n if (\n lower.includes('get') ||\n lower.includes('fetch') ||\n lower.includes('list')\n )\n return 'GET';\n if (lower.includes('post') || lower.includes('create')) return 'POST';\n if (lower.includes('put') || lower.includes('update')) return 'PUT';\n if (lower.includes('delete') || lower.includes('remove')) return 'DELETE';\n if (lower.includes('patch')) return 'PATCH';\n return 'GET'; // Default\n}\n\nfunction extractPath(url: string): string {\n try {\n const urlObj = new URL(url);\n return urlObj.pathname;\n } catch {\n // Relative URL or invalid\n return url.split('?')[0] || url;\n }\n}\n\nfunction parseUrl(url: string): {\n protocol: string;\n host: string;\n path: string;\n} {\n try {\n const urlObj = new URL(url);\n return {\n protocol: urlObj.protocol.replace(':', ''),\n host: urlObj.host,\n path: urlObj.pathname + urlObj.search,\n };\n } catch {\n return {\n protocol: 'http',\n host: 'unknown',\n path: url,\n };\n }\n}\n\nfunction extractStatusCode(result: unknown): number | undefined {\n if (result && typeof result === 'object') {\n // Check for Response.status (fetch API)\n if ('status' in result && typeof result.status === 'number') {\n return result.status;\n }\n // Check for statusCode (axios, node http)\n if ('statusCode' in result && typeof result.statusCode === 'number') {\n return result.statusCode;\n }\n }\n return undefined;\n}\n\n/**\n * Inject trace context into HTTP headers (for distributed tracing)\n *\n * This includes W3C Trace Context (traceparent, tracestate) and W3C Baggage headers.\n * Uses OpenTelemetry's propagation system for full compatibility.\n *\n * @example\n * ```typescript\n * import { injectTraceContext } from 'autotel/http'\n *\n * const headers = injectTraceContext({\n * 'Content-Type': 'application/json'\n * })\n *\n * fetch('/api/users', { headers })\n * ```\n *\n * @example With baggage\n * ```typescript\n * import { trace, withBaggage, injectTraceContext } from 'autotel'\n *\n * export const createOrder = trace((ctx) => async (order: Order) => {\n * return await withBaggage({\n * baggage: { 'tenant.id': order.tenantId },\n * fn: async () => {\n * const headers = injectTraceContext();\n * // Headers now include 'baggage' header with tenant.id\n * await fetch('/api/charge', { headers });\n * },\n * });\n * });\n * ```\n */\nexport function injectTraceContext(\n headers: Record<string, string> = {},\n): Record<string, string> {\n // Use getActiveContextWithBaggage to check stored context (from baggage setters)\n // This ensures ctx.setBaggage() changes are included in injected headers\n const currentContext = getActiveContextWithBaggage();\n\n // Use OpenTelemetry's propagation.inject for full W3C support\n // This includes traceparent, tracestate, and baggage headers\n propagation.inject(currentContext, headers);\n\n return headers;\n}\n\n/**\n * Extract trace context from HTTP headers (for distributed tracing)\n *\n * This extracts W3C Trace Context (traceparent, tracestate) and W3C Baggage headers.\n * Uses OpenTelemetry's propagation system for full compatibility.\n *\n * Returns a context that can be used with context.with() to run code\n * with the extracted trace context and baggage.\n *\n * @example\n * ```typescript\n * import { extractTraceContext, trace } from 'autotel'\n * import { context } from 'autotel'\n *\n * // In Express middleware\n * app.use((req, res, next) => {\n * const extractedContext = extractTraceContext(req.headers);\n * context.with(extractedContext, () => {\n * next();\n * });\n * });\n * ```\n *\n * @example In a traced function\n * ```typescript\n * export const handleWebhook = trace((ctx) => async (req: Request) => {\n * const extractedContext = extractTraceContext(req.headers);\n * return await context.with(extractedContext, async () => {\n * // Now ctx.getBaggage() will return baggage from the incoming request\n * const tenantId = ctx.getBaggage('tenant.id');\n * await processWebhook(req.body);\n * });\n * });\n * ```\n */\nexport function extractTraceContext(\n headers: Record<string, string | string[] | undefined>,\n): ReturnType<typeof context.active> {\n const carrier: Record<string, string> = {};\n\n // Convert headers to flat string format expected by propagation\n for (const [key, value] of Object.entries(headers)) {\n if (value !== undefined) {\n carrier[key] = Array.isArray(value) ? (value[0] ?? '') : value;\n }\n }\n\n // Extract context using OpenTelemetry's propagation system\n // Returns a Context that can be used with context.with()\n return propagation.extract(context.active(), carrier);\n}\n"]}
1
+ {"version":3,"sources":["../src/http.ts"],"names":["args","getConfig","SpanStatusCode","getActiveContextWithBaggage","propagation","context"],"mappings":"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","file":"http.cjs","sourcesContent":["/**\n * HTTP Instrumentation Helpers\n *\n * Optional import: Not included in main bundle\n * Import from: 'autotel/http'\n *\n * Provides decorators and utilities for HTTP client instrumentation.\n * Works with fetch, axios, and other HTTP clients.\n *\n * @example\n * ```typescript\n * import { HttpInstrumented } from 'autotel/http'\n *\n * @HttpInstrumented()\n * class ApiClient {\n * async getUser(id: string) {\n * return fetch(`/api/users/${id}`)\n * }\n * }\n * ```\n */\n\nimport { SpanStatusCode, context, propagation } from '@opentelemetry/api';\nimport { getConfig } from './config';\nimport { getActiveContextWithBaggage } from './trace-context';\n\nexport interface HttpInstrumentedOptions {\n /** Service name for HTTP calls (default: 'http-client') */\n serviceName?: string;\n /** Extract URL from method arguments (default: first arg) */\n urlExtractor?: (args: unknown[]) => string | undefined;\n /** Extract HTTP method from method name or args */\n methodExtractor?: (methodName: string, args: unknown[]) => string;\n /** Add custom attributes to spans */\n attributesFromArgs?: (args: unknown[]) => Record<string, string | number>;\n /** Slow request threshold in milliseconds (adds warning attribute) - default: 3000ms */\n slowRequestThresholdMs?: number;\n}\n\n/**\n * Decorator for auto-instrumenting HTTP client methods\n *\n * @example Basic usage\n * ```typescript\n * @HttpInstrumented()\n * class ApiClient {\n * async fetchUser(userId: string) {\n * const res = await fetch(`https://api.example.com/users/${userId}`)\n * return res.json()\n * }\n *\n * async createOrder(order: Order) {\n * const res = await fetch('https://api.example.com/orders', {\n * method: 'POST',\n * body: JSON.stringify(order)\n * })\n * return res.json()\n * }\n * }\n * ```\n *\n * @example Advanced usage with custom extractors\n * ```typescript\n * @HttpInstrumented({\n * serviceName: 'payment-gateway',\n * urlExtractor: (args) => {\n * const config = args[0] as RequestConfig\n * return config.url\n * },\n * attributesFromArgs: (args) => ({\n * 'http.request_id': args[0]?.requestId,\n * 'http.retry_count': args[0]?.retryCount || 0\n * })\n * })\n * class PaymentClient {\n * async charge(config: RequestConfig) {\n * return axios(config)\n * }\n * }\n * ```\n */\nexport function HttpInstrumented(options: HttpInstrumentedOptions = {}) {\n const serviceName = options.serviceName || 'http-client';\n const slowRequestThresholdMs = options.slowRequestThresholdMs ?? 3000;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-empty-object-type\n return function <T extends { new (...args: any[]): {} }>(\n target: T,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _context: ClassDecoratorContext,\n ) {\n return class extends target {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(...args: any[]) {\n super(...args);\n\n const proto = target.prototype;\n const methodNames = Object.getOwnPropertyNames(proto).filter(\n (name) =>\n name !== 'constructor' &&\n typeof proto[name] === 'function' &&\n !name.startsWith('_'),\n );\n\n for (const methodName of methodNames) {\n const originalMethod = proto[methodName];\n\n if (\n originalMethod.constructor.name === 'AsyncFunction' ||\n originalMethod.toString().startsWith('async ')\n ) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const wrappedMethod = async (...args: any[]) => {\n const config = getConfig();\n const tracer = config.tracer;\n\n const url = options.urlExtractor\n ? options.urlExtractor(args)\n : (args[0] as string | undefined);\n\n const method = options.methodExtractor\n ? options.methodExtractor(methodName, args)\n : inferHttpMethod(methodName);\n\n const spanName = url\n ? `HTTP ${method} ${extractPath(url)}`\n : `HTTP ${method}`;\n\n return tracer.startActiveSpan(spanName, async (span) => {\n const startTime = performance.now();\n\n try {\n span.setAttributes({\n 'http.method': method,\n 'http.url': url || 'unknown',\n 'service.name': serviceName,\n 'operation.name': `${serviceName}.${methodName}`,\n });\n\n if (url) {\n const urlObj = parseUrl(url);\n span.setAttributes({\n 'http.scheme': urlObj.protocol,\n 'http.host': urlObj.host,\n 'http.target': urlObj.path,\n });\n }\n\n if (options.attributesFromArgs) {\n span.setAttributes(options.attributesFromArgs(args));\n }\n\n const result = await originalMethod.apply(this, args);\n\n const duration = performance.now() - startTime;\n\n // Extract status code from response\n const statusCode = extractStatusCode(result);\n if (statusCode) {\n span.setAttribute('http.status_code', statusCode);\n\n if (statusCode >= 400) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: `HTTP ${statusCode}`,\n });\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n\n span.setAttributes({\n 'http.duration_ms': duration,\n });\n\n // Mark slow requests for investigation\n if (duration > slowRequestThresholdMs) {\n span.setAttribute('http.slow_request', true);\n span.setAttribute(\n 'http.slow_request_threshold_ms',\n slowRequestThresholdMs,\n );\n }\n\n return result;\n } catch (error) {\n const duration = performance.now() - startTime;\n\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message:\n error instanceof Error ? error.message : 'Unknown error',\n });\n\n span.setAttributes({\n 'http.duration_ms': duration,\n 'error.type':\n error instanceof Error\n ? error.constructor.name\n : 'Unknown',\n 'error.message':\n error instanceof Error ? error.message : 'Unknown error',\n });\n\n throw error;\n } finally {\n span.end();\n }\n });\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any)[methodName] = wrappedMethod;\n }\n }\n }\n };\n };\n}\n\n/**\n * Helper: Trace a single HTTP request\n *\n * @example\n * ```typescript\n * import { traceHttpRequest } from 'autotel/http'\n *\n * const data = await traceHttpRequest(\n * 'GET /api/users',\n * () => fetch('https://api.example.com/users')\n * )\n * ```\n */\nexport async function traceHttpRequest<T>(\n spanName: string,\n fn: () => Promise<T>,\n attributes?: Record<string, string | number>,\n): Promise<T> {\n const config = getConfig();\n const tracer = config.tracer;\n\n return tracer.startActiveSpan(spanName, async (span) => {\n try {\n if (attributes) {\n span.setAttributes(attributes);\n }\n\n const result = await fn();\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n } finally {\n span.end();\n }\n });\n}\n\n// Helper functions\n\nfunction inferHttpMethod(methodName: string): string {\n const lower = methodName.toLowerCase();\n if (\n lower.includes('get') ||\n lower.includes('fetch') ||\n lower.includes('list')\n )\n return 'GET';\n if (lower.includes('post') || lower.includes('create')) return 'POST';\n if (lower.includes('put') || lower.includes('update')) return 'PUT';\n if (lower.includes('delete') || lower.includes('remove')) return 'DELETE';\n if (lower.includes('patch')) return 'PATCH';\n return 'GET'; // Default\n}\n\nfunction extractPath(url: string): string {\n try {\n const urlObj = new URL(url);\n return urlObj.pathname;\n } catch {\n // Relative URL or invalid\n return url.split('?')[0] || url;\n }\n}\n\nfunction parseUrl(url: string): {\n protocol: string;\n host: string;\n path: string;\n} {\n try {\n const urlObj = new URL(url);\n return {\n protocol: urlObj.protocol.replace(':', ''),\n host: urlObj.host,\n path: urlObj.pathname + urlObj.search,\n };\n } catch {\n return {\n protocol: 'http',\n host: 'unknown',\n path: url,\n };\n }\n}\n\nfunction extractStatusCode(result: unknown): number | undefined {\n if (result && typeof result === 'object') {\n // Check for Response.status (fetch API)\n if ('status' in result && typeof result.status === 'number') {\n return result.status;\n }\n // Check for statusCode (axios, node http)\n if ('statusCode' in result && typeof result.statusCode === 'number') {\n return result.statusCode;\n }\n }\n return undefined;\n}\n\n/**\n * Inject trace context into HTTP headers (for distributed tracing)\n *\n * This includes W3C Trace Context (traceparent, tracestate) and W3C Baggage headers.\n * Uses OpenTelemetry's propagation system for full compatibility.\n *\n * @example\n * ```typescript\n * import { injectTraceContext } from 'autotel/http'\n *\n * const headers = injectTraceContext({\n * 'Content-Type': 'application/json'\n * })\n *\n * fetch('/api/users', { headers })\n * ```\n *\n * @example With baggage\n * ```typescript\n * import { trace, withBaggage, injectTraceContext } from 'autotel'\n *\n * export const createOrder = trace((ctx) => async (order: Order) => {\n * return await withBaggage({\n * baggage: { 'tenant.id': order.tenantId },\n * fn: async () => {\n * const headers = injectTraceContext();\n * // Headers now include 'baggage' header with tenant.id\n * await fetch('/api/charge', { headers });\n * },\n * });\n * });\n * ```\n */\nexport function injectTraceContext(\n headers: Record<string, string> = {},\n): Record<string, string> {\n // Use getActiveContextWithBaggage to check stored context (from baggage setters)\n // This ensures ctx.setBaggage() changes are included in injected headers\n const currentContext = getActiveContextWithBaggage();\n\n // Use OpenTelemetry's propagation.inject for full W3C support\n // This includes traceparent, tracestate, and baggage headers\n propagation.inject(currentContext, headers);\n\n return headers;\n}\n\n/**\n * Extract trace context from HTTP headers (for distributed tracing)\n *\n * This extracts W3C Trace Context (traceparent, tracestate) and W3C Baggage headers.\n * Uses OpenTelemetry's propagation system for full compatibility.\n *\n * Returns a context that can be used with context.with() to run code\n * with the extracted trace context and baggage.\n *\n * @example\n * ```typescript\n * import { extractTraceContext, trace } from 'autotel'\n * import { context } from 'autotel'\n *\n * // In Express middleware\n * app.use((req, res, next) => {\n * const extractedContext = extractTraceContext(req.headers);\n * context.with(extractedContext, () => {\n * next();\n * });\n * });\n * ```\n *\n * @example In a traced function\n * ```typescript\n * export const handleWebhook = trace((ctx) => async (req: Request) => {\n * const extractedContext = extractTraceContext(req.headers);\n * return await context.with(extractedContext, async () => {\n * // Now ctx.getBaggage() will return baggage from the incoming request\n * const tenantId = ctx.getBaggage('tenant.id');\n * await processWebhook(req.body);\n * });\n * });\n * ```\n */\nexport function extractTraceContext(\n headers: Record<string, string | string[] | undefined>,\n): ReturnType<typeof context.active> {\n const carrier: Record<string, string> = {};\n\n // Convert headers to flat string format expected by propagation\n for (const [key, value] of Object.entries(headers)) {\n if (value !== undefined) {\n carrier[key] = Array.isArray(value) ? (value[0] ?? '') : value;\n }\n }\n\n // Extract context using OpenTelemetry's propagation system\n // Returns a Context that can be used with context.with()\n return propagation.extract(context.active(), carrier);\n}\n"]}
package/dist/http.js CHANGED
@@ -1,4 +1,15 @@
1
- import { getActiveContextWithBaggage } from './chunk-BBBWDIYQ.js';
1
+ import { getActiveContextWithBaggage } from './chunk-QG3U5ONP.js';
2
+ import './chunk-W35FVJBC.js';
3
+ import './chunk-3SDILILG.js';
4
+ import './chunk-A4E5AQFK.js';
5
+ import './chunk-WGWSHJ2N.js';
6
+ import './chunk-GYR5K654.js';
7
+ import './chunk-TDNKIHKT.js';
8
+ import './chunk-6UQRVUN3.js';
9
+ import './chunk-3QXBFGKP.js';
10
+ import './chunk-33WTKH7X.js';
11
+ import './chunk-DPSA4QLA.js';
12
+ import './chunk-55ER2KD5.js';
2
13
  import { getConfig } from './chunk-J5QENANM.js';
3
14
  import './chunk-HA2WBOGQ.js';
4
15
  import './chunk-DGUM43GV.js';
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/http.ts"],"names":["args"],"mappings":"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","file":"http.js","sourcesContent":["/**\n * HTTP Instrumentation Helpers\n *\n * Optional import: Not included in main bundle\n * Import from: 'autotel/http'\n *\n * Provides decorators and utilities for HTTP client instrumentation.\n * Works with fetch, axios, and other HTTP clients.\n *\n * @example\n * ```typescript\n * import { HttpInstrumented } from 'autotel/http'\n *\n * @HttpInstrumented()\n * class ApiClient {\n * async getUser(id: string) {\n * return fetch(`/api/users/${id}`)\n * }\n * }\n * ```\n */\n\nimport { SpanStatusCode, context, propagation } from '@opentelemetry/api';\nimport { getConfig } from './config';\nimport { getActiveContextWithBaggage } from './trace-context';\n\nexport interface HttpInstrumentedOptions {\n /** Service name for HTTP calls (default: 'http-client') */\n serviceName?: string;\n /** Extract URL from method arguments (default: first arg) */\n urlExtractor?: (args: unknown[]) => string | undefined;\n /** Extract HTTP method from method name or args */\n methodExtractor?: (methodName: string, args: unknown[]) => string;\n /** Add custom attributes to spans */\n attributesFromArgs?: (args: unknown[]) => Record<string, string | number>;\n /** Slow request threshold in milliseconds (adds warning attribute) - default: 3000ms */\n slowRequestThresholdMs?: number;\n}\n\n/**\n * Decorator for auto-instrumenting HTTP client methods\n *\n * @example Basic usage\n * ```typescript\n * @HttpInstrumented()\n * class ApiClient {\n * async fetchUser(userId: string) {\n * const res = await fetch(`https://api.example.com/users/${userId}`)\n * return res.json()\n * }\n *\n * async createOrder(order: Order) {\n * const res = await fetch('https://api.example.com/orders', {\n * method: 'POST',\n * body: JSON.stringify(order)\n * })\n * return res.json()\n * }\n * }\n * ```\n *\n * @example Advanced usage with custom extractors\n * ```typescript\n * @HttpInstrumented({\n * serviceName: 'payment-gateway',\n * urlExtractor: (args) => {\n * const config = args[0] as RequestConfig\n * return config.url\n * },\n * attributesFromArgs: (args) => ({\n * 'http.request_id': args[0]?.requestId,\n * 'http.retry_count': args[0]?.retryCount || 0\n * })\n * })\n * class PaymentClient {\n * async charge(config: RequestConfig) {\n * return axios(config)\n * }\n * }\n * ```\n */\nexport function HttpInstrumented(options: HttpInstrumentedOptions = {}) {\n const serviceName = options.serviceName || 'http-client';\n const slowRequestThresholdMs = options.slowRequestThresholdMs ?? 3000;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-empty-object-type\n return function <T extends { new (...args: any[]): {} }>(\n target: T,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _context: ClassDecoratorContext,\n ) {\n return class extends target {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(...args: any[]) {\n super(...args);\n\n const proto = target.prototype;\n const methodNames = Object.getOwnPropertyNames(proto).filter(\n (name) =>\n name !== 'constructor' &&\n typeof proto[name] === 'function' &&\n !name.startsWith('_'),\n );\n\n for (const methodName of methodNames) {\n const originalMethod = proto[methodName];\n\n if (\n originalMethod.constructor.name === 'AsyncFunction' ||\n originalMethod.toString().startsWith('async ')\n ) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const wrappedMethod = async (...args: any[]) => {\n const config = getConfig();\n const tracer = config.tracer;\n\n const url = options.urlExtractor\n ? options.urlExtractor(args)\n : (args[0] as string | undefined);\n\n const method = options.methodExtractor\n ? options.methodExtractor(methodName, args)\n : inferHttpMethod(methodName);\n\n const spanName = url\n ? `HTTP ${method} ${extractPath(url)}`\n : `HTTP ${method}`;\n\n return tracer.startActiveSpan(spanName, async (span) => {\n const startTime = performance.now();\n\n try {\n span.setAttributes({\n 'http.method': method,\n 'http.url': url || 'unknown',\n 'service.name': serviceName,\n 'operation.name': `${serviceName}.${methodName}`,\n });\n\n if (url) {\n const urlObj = parseUrl(url);\n span.setAttributes({\n 'http.scheme': urlObj.protocol,\n 'http.host': urlObj.host,\n 'http.target': urlObj.path,\n });\n }\n\n if (options.attributesFromArgs) {\n span.setAttributes(options.attributesFromArgs(args));\n }\n\n const result = await originalMethod.apply(this, args);\n\n const duration = performance.now() - startTime;\n\n // Extract status code from response\n const statusCode = extractStatusCode(result);\n if (statusCode) {\n span.setAttribute('http.status_code', statusCode);\n\n if (statusCode >= 400) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: `HTTP ${statusCode}`,\n });\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n\n span.setAttributes({\n 'http.duration_ms': duration,\n });\n\n // Mark slow requests for investigation\n if (duration > slowRequestThresholdMs) {\n span.setAttribute('http.slow_request', true);\n span.setAttribute(\n 'http.slow_request_threshold_ms',\n slowRequestThresholdMs,\n );\n }\n\n return result;\n } catch (error) {\n const duration = performance.now() - startTime;\n\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message:\n error instanceof Error ? error.message : 'Unknown error',\n });\n\n span.setAttributes({\n 'http.duration_ms': duration,\n 'error.type':\n error instanceof Error\n ? error.constructor.name\n : 'Unknown',\n 'error.message':\n error instanceof Error ? error.message : 'Unknown error',\n });\n\n throw error;\n } finally {\n span.end();\n }\n });\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any)[methodName] = wrappedMethod;\n }\n }\n }\n };\n };\n}\n\n/**\n * Helper: Trace a single HTTP request\n *\n * @example\n * ```typescript\n * import { traceHttpRequest } from 'autotel/http'\n *\n * const data = await traceHttpRequest(\n * 'GET /api/users',\n * () => fetch('https://api.example.com/users')\n * )\n * ```\n */\nexport async function traceHttpRequest<T>(\n spanName: string,\n fn: () => Promise<T>,\n attributes?: Record<string, string | number>,\n): Promise<T> {\n const config = getConfig();\n const tracer = config.tracer;\n\n return tracer.startActiveSpan(spanName, async (span) => {\n try {\n if (attributes) {\n span.setAttributes(attributes);\n }\n\n const result = await fn();\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n } finally {\n span.end();\n }\n });\n}\n\n// Helper functions\n\nfunction inferHttpMethod(methodName: string): string {\n const lower = methodName.toLowerCase();\n if (\n lower.includes('get') ||\n lower.includes('fetch') ||\n lower.includes('list')\n )\n return 'GET';\n if (lower.includes('post') || lower.includes('create')) return 'POST';\n if (lower.includes('put') || lower.includes('update')) return 'PUT';\n if (lower.includes('delete') || lower.includes('remove')) return 'DELETE';\n if (lower.includes('patch')) return 'PATCH';\n return 'GET'; // Default\n}\n\nfunction extractPath(url: string): string {\n try {\n const urlObj = new URL(url);\n return urlObj.pathname;\n } catch {\n // Relative URL or invalid\n return url.split('?')[0] || url;\n }\n}\n\nfunction parseUrl(url: string): {\n protocol: string;\n host: string;\n path: string;\n} {\n try {\n const urlObj = new URL(url);\n return {\n protocol: urlObj.protocol.replace(':', ''),\n host: urlObj.host,\n path: urlObj.pathname + urlObj.search,\n };\n } catch {\n return {\n protocol: 'http',\n host: 'unknown',\n path: url,\n };\n }\n}\n\nfunction extractStatusCode(result: unknown): number | undefined {\n if (result && typeof result === 'object') {\n // Check for Response.status (fetch API)\n if ('status' in result && typeof result.status === 'number') {\n return result.status;\n }\n // Check for statusCode (axios, node http)\n if ('statusCode' in result && typeof result.statusCode === 'number') {\n return result.statusCode;\n }\n }\n return undefined;\n}\n\n/**\n * Inject trace context into HTTP headers (for distributed tracing)\n *\n * This includes W3C Trace Context (traceparent, tracestate) and W3C Baggage headers.\n * Uses OpenTelemetry's propagation system for full compatibility.\n *\n * @example\n * ```typescript\n * import { injectTraceContext } from 'autotel/http'\n *\n * const headers = injectTraceContext({\n * 'Content-Type': 'application/json'\n * })\n *\n * fetch('/api/users', { headers })\n * ```\n *\n * @example With baggage\n * ```typescript\n * import { trace, withBaggage, injectTraceContext } from 'autotel'\n *\n * export const createOrder = trace((ctx) => async (order: Order) => {\n * return await withBaggage({\n * baggage: { 'tenant.id': order.tenantId },\n * fn: async () => {\n * const headers = injectTraceContext();\n * // Headers now include 'baggage' header with tenant.id\n * await fetch('/api/charge', { headers });\n * },\n * });\n * });\n * ```\n */\nexport function injectTraceContext(\n headers: Record<string, string> = {},\n): Record<string, string> {\n // Use getActiveContextWithBaggage to check stored context (from baggage setters)\n // This ensures ctx.setBaggage() changes are included in injected headers\n const currentContext = getActiveContextWithBaggage();\n\n // Use OpenTelemetry's propagation.inject for full W3C support\n // This includes traceparent, tracestate, and baggage headers\n propagation.inject(currentContext, headers);\n\n return headers;\n}\n\n/**\n * Extract trace context from HTTP headers (for distributed tracing)\n *\n * This extracts W3C Trace Context (traceparent, tracestate) and W3C Baggage headers.\n * Uses OpenTelemetry's propagation system for full compatibility.\n *\n * Returns a context that can be used with context.with() to run code\n * with the extracted trace context and baggage.\n *\n * @example\n * ```typescript\n * import { extractTraceContext, trace } from 'autotel'\n * import { context } from 'autotel'\n *\n * // In Express middleware\n * app.use((req, res, next) => {\n * const extractedContext = extractTraceContext(req.headers);\n * context.with(extractedContext, () => {\n * next();\n * });\n * });\n * ```\n *\n * @example In a traced function\n * ```typescript\n * export const handleWebhook = trace((ctx) => async (req: Request) => {\n * const extractedContext = extractTraceContext(req.headers);\n * return await context.with(extractedContext, async () => {\n * // Now ctx.getBaggage() will return baggage from the incoming request\n * const tenantId = ctx.getBaggage('tenant.id');\n * await processWebhook(req.body);\n * });\n * });\n * ```\n */\nexport function extractTraceContext(\n headers: Record<string, string | string[] | undefined>,\n): ReturnType<typeof context.active> {\n const carrier: Record<string, string> = {};\n\n // Convert headers to flat string format expected by propagation\n for (const [key, value] of Object.entries(headers)) {\n if (value !== undefined) {\n carrier[key] = Array.isArray(value) ? (value[0] ?? '') : value;\n }\n }\n\n // Extract context using OpenTelemetry's propagation system\n // Returns a Context that can be used with context.with()\n return propagation.extract(context.active(), carrier);\n}\n"]}
1
+ {"version":3,"sources":["../src/http.ts"],"names":["args"],"mappings":"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","file":"http.js","sourcesContent":["/**\n * HTTP Instrumentation Helpers\n *\n * Optional import: Not included in main bundle\n * Import from: 'autotel/http'\n *\n * Provides decorators and utilities for HTTP client instrumentation.\n * Works with fetch, axios, and other HTTP clients.\n *\n * @example\n * ```typescript\n * import { HttpInstrumented } from 'autotel/http'\n *\n * @HttpInstrumented()\n * class ApiClient {\n * async getUser(id: string) {\n * return fetch(`/api/users/${id}`)\n * }\n * }\n * ```\n */\n\nimport { SpanStatusCode, context, propagation } from '@opentelemetry/api';\nimport { getConfig } from './config';\nimport { getActiveContextWithBaggage } from './trace-context';\n\nexport interface HttpInstrumentedOptions {\n /** Service name for HTTP calls (default: 'http-client') */\n serviceName?: string;\n /** Extract URL from method arguments (default: first arg) */\n urlExtractor?: (args: unknown[]) => string | undefined;\n /** Extract HTTP method from method name or args */\n methodExtractor?: (methodName: string, args: unknown[]) => string;\n /** Add custom attributes to spans */\n attributesFromArgs?: (args: unknown[]) => Record<string, string | number>;\n /** Slow request threshold in milliseconds (adds warning attribute) - default: 3000ms */\n slowRequestThresholdMs?: number;\n}\n\n/**\n * Decorator for auto-instrumenting HTTP client methods\n *\n * @example Basic usage\n * ```typescript\n * @HttpInstrumented()\n * class ApiClient {\n * async fetchUser(userId: string) {\n * const res = await fetch(`https://api.example.com/users/${userId}`)\n * return res.json()\n * }\n *\n * async createOrder(order: Order) {\n * const res = await fetch('https://api.example.com/orders', {\n * method: 'POST',\n * body: JSON.stringify(order)\n * })\n * return res.json()\n * }\n * }\n * ```\n *\n * @example Advanced usage with custom extractors\n * ```typescript\n * @HttpInstrumented({\n * serviceName: 'payment-gateway',\n * urlExtractor: (args) => {\n * const config = args[0] as RequestConfig\n * return config.url\n * },\n * attributesFromArgs: (args) => ({\n * 'http.request_id': args[0]?.requestId,\n * 'http.retry_count': args[0]?.retryCount || 0\n * })\n * })\n * class PaymentClient {\n * async charge(config: RequestConfig) {\n * return axios(config)\n * }\n * }\n * ```\n */\nexport function HttpInstrumented(options: HttpInstrumentedOptions = {}) {\n const serviceName = options.serviceName || 'http-client';\n const slowRequestThresholdMs = options.slowRequestThresholdMs ?? 3000;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-empty-object-type\n return function <T extends { new (...args: any[]): {} }>(\n target: T,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _context: ClassDecoratorContext,\n ) {\n return class extends target {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(...args: any[]) {\n super(...args);\n\n const proto = target.prototype;\n const methodNames = Object.getOwnPropertyNames(proto).filter(\n (name) =>\n name !== 'constructor' &&\n typeof proto[name] === 'function' &&\n !name.startsWith('_'),\n );\n\n for (const methodName of methodNames) {\n const originalMethod = proto[methodName];\n\n if (\n originalMethod.constructor.name === 'AsyncFunction' ||\n originalMethod.toString().startsWith('async ')\n ) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const wrappedMethod = async (...args: any[]) => {\n const config = getConfig();\n const tracer = config.tracer;\n\n const url = options.urlExtractor\n ? options.urlExtractor(args)\n : (args[0] as string | undefined);\n\n const method = options.methodExtractor\n ? options.methodExtractor(methodName, args)\n : inferHttpMethod(methodName);\n\n const spanName = url\n ? `HTTP ${method} ${extractPath(url)}`\n : `HTTP ${method}`;\n\n return tracer.startActiveSpan(spanName, async (span) => {\n const startTime = performance.now();\n\n try {\n span.setAttributes({\n 'http.method': method,\n 'http.url': url || 'unknown',\n 'service.name': serviceName,\n 'operation.name': `${serviceName}.${methodName}`,\n });\n\n if (url) {\n const urlObj = parseUrl(url);\n span.setAttributes({\n 'http.scheme': urlObj.protocol,\n 'http.host': urlObj.host,\n 'http.target': urlObj.path,\n });\n }\n\n if (options.attributesFromArgs) {\n span.setAttributes(options.attributesFromArgs(args));\n }\n\n const result = await originalMethod.apply(this, args);\n\n const duration = performance.now() - startTime;\n\n // Extract status code from response\n const statusCode = extractStatusCode(result);\n if (statusCode) {\n span.setAttribute('http.status_code', statusCode);\n\n if (statusCode >= 400) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: `HTTP ${statusCode}`,\n });\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n\n span.setAttributes({\n 'http.duration_ms': duration,\n });\n\n // Mark slow requests for investigation\n if (duration > slowRequestThresholdMs) {\n span.setAttribute('http.slow_request', true);\n span.setAttribute(\n 'http.slow_request_threshold_ms',\n slowRequestThresholdMs,\n );\n }\n\n return result;\n } catch (error) {\n const duration = performance.now() - startTime;\n\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message:\n error instanceof Error ? error.message : 'Unknown error',\n });\n\n span.setAttributes({\n 'http.duration_ms': duration,\n 'error.type':\n error instanceof Error\n ? error.constructor.name\n : 'Unknown',\n 'error.message':\n error instanceof Error ? error.message : 'Unknown error',\n });\n\n throw error;\n } finally {\n span.end();\n }\n });\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this as any)[methodName] = wrappedMethod;\n }\n }\n }\n };\n };\n}\n\n/**\n * Helper: Trace a single HTTP request\n *\n * @example\n * ```typescript\n * import { traceHttpRequest } from 'autotel/http'\n *\n * const data = await traceHttpRequest(\n * 'GET /api/users',\n * () => fetch('https://api.example.com/users')\n * )\n * ```\n */\nexport async function traceHttpRequest<T>(\n spanName: string,\n fn: () => Promise<T>,\n attributes?: Record<string, string | number>,\n): Promise<T> {\n const config = getConfig();\n const tracer = config.tracer;\n\n return tracer.startActiveSpan(spanName, async (span) => {\n try {\n if (attributes) {\n span.setAttributes(attributes);\n }\n\n const result = await fn();\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'Unknown error',\n });\n throw error;\n } finally {\n span.end();\n }\n });\n}\n\n// Helper functions\n\nfunction inferHttpMethod(methodName: string): string {\n const lower = methodName.toLowerCase();\n if (\n lower.includes('get') ||\n lower.includes('fetch') ||\n lower.includes('list')\n )\n return 'GET';\n if (lower.includes('post') || lower.includes('create')) return 'POST';\n if (lower.includes('put') || lower.includes('update')) return 'PUT';\n if (lower.includes('delete') || lower.includes('remove')) return 'DELETE';\n if (lower.includes('patch')) return 'PATCH';\n return 'GET'; // Default\n}\n\nfunction extractPath(url: string): string {\n try {\n const urlObj = new URL(url);\n return urlObj.pathname;\n } catch {\n // Relative URL or invalid\n return url.split('?')[0] || url;\n }\n}\n\nfunction parseUrl(url: string): {\n protocol: string;\n host: string;\n path: string;\n} {\n try {\n const urlObj = new URL(url);\n return {\n protocol: urlObj.protocol.replace(':', ''),\n host: urlObj.host,\n path: urlObj.pathname + urlObj.search,\n };\n } catch {\n return {\n protocol: 'http',\n host: 'unknown',\n path: url,\n };\n }\n}\n\nfunction extractStatusCode(result: unknown): number | undefined {\n if (result && typeof result === 'object') {\n // Check for Response.status (fetch API)\n if ('status' in result && typeof result.status === 'number') {\n return result.status;\n }\n // Check for statusCode (axios, node http)\n if ('statusCode' in result && typeof result.statusCode === 'number') {\n return result.statusCode;\n }\n }\n return undefined;\n}\n\n/**\n * Inject trace context into HTTP headers (for distributed tracing)\n *\n * This includes W3C Trace Context (traceparent, tracestate) and W3C Baggage headers.\n * Uses OpenTelemetry's propagation system for full compatibility.\n *\n * @example\n * ```typescript\n * import { injectTraceContext } from 'autotel/http'\n *\n * const headers = injectTraceContext({\n * 'Content-Type': 'application/json'\n * })\n *\n * fetch('/api/users', { headers })\n * ```\n *\n * @example With baggage\n * ```typescript\n * import { trace, withBaggage, injectTraceContext } from 'autotel'\n *\n * export const createOrder = trace((ctx) => async (order: Order) => {\n * return await withBaggage({\n * baggage: { 'tenant.id': order.tenantId },\n * fn: async () => {\n * const headers = injectTraceContext();\n * // Headers now include 'baggage' header with tenant.id\n * await fetch('/api/charge', { headers });\n * },\n * });\n * });\n * ```\n */\nexport function injectTraceContext(\n headers: Record<string, string> = {},\n): Record<string, string> {\n // Use getActiveContextWithBaggage to check stored context (from baggage setters)\n // This ensures ctx.setBaggage() changes are included in injected headers\n const currentContext = getActiveContextWithBaggage();\n\n // Use OpenTelemetry's propagation.inject for full W3C support\n // This includes traceparent, tracestate, and baggage headers\n propagation.inject(currentContext, headers);\n\n return headers;\n}\n\n/**\n * Extract trace context from HTTP headers (for distributed tracing)\n *\n * This extracts W3C Trace Context (traceparent, tracestate) and W3C Baggage headers.\n * Uses OpenTelemetry's propagation system for full compatibility.\n *\n * Returns a context that can be used with context.with() to run code\n * with the extracted trace context and baggage.\n *\n * @example\n * ```typescript\n * import { extractTraceContext, trace } from 'autotel'\n * import { context } from 'autotel'\n *\n * // In Express middleware\n * app.use((req, res, next) => {\n * const extractedContext = extractTraceContext(req.headers);\n * context.with(extractedContext, () => {\n * next();\n * });\n * });\n * ```\n *\n * @example In a traced function\n * ```typescript\n * export const handleWebhook = trace((ctx) => async (req: Request) => {\n * const extractedContext = extractTraceContext(req.headers);\n * return await context.with(extractedContext, async () => {\n * // Now ctx.getBaggage() will return baggage from the incoming request\n * const tenantId = ctx.getBaggage('tenant.id');\n * await processWebhook(req.body);\n * });\n * });\n * ```\n */\nexport function extractTraceContext(\n headers: Record<string, string | string[] | undefined>,\n): ReturnType<typeof context.active> {\n const carrier: Record<string, string> = {};\n\n // Convert headers to flat string format expected by propagation\n for (const [key, value] of Object.entries(headers)) {\n if (value !== undefined) {\n carrier[key] = Array.isArray(value) ? (value[0] ?? '') : value;\n }\n }\n\n // Extract context using OpenTelemetry's propagation system\n // Returns a Context that can be used with context.with()\n return propagation.extract(context.active(), carrier);\n}\n"]}