@stainlessdev/xray-node 0.6.0 → 0.7.0-dev.588fa57

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.
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # @stainlessdev/xray-node
2
+
3
+ Node.js HTTP adapter for Stainless X-ray request logging. Use this for `node:http` servers or to power framework integrations (Express/Fastify).
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ pnpm add @stainlessdev/xray-node
9
+ ```
10
+
11
+ ## Basic usage (node:http)
12
+
13
+ ```ts
14
+ import { createServer } from 'node:http';
15
+ import { createEmitter, wrapHttpHandler } from '@stainlessdev/xray-node';
16
+
17
+ const xray = createEmitter({
18
+ serviceName: 'my-service',
19
+ endpointUrl: 'http://localhost:4318',
20
+ // Optional: customize the request ID header name
21
+ requestId: { header: 'request-id' },
22
+ });
23
+
24
+ const server = createServer(
25
+ wrapHttpHandler((_req, res) => {
26
+ res.statusCode = 200;
27
+ res.setHeader('Content-Type', 'text/plain');
28
+ res.end('ok');
29
+ }, xray),
30
+ );
31
+
32
+ server.listen(3000);
33
+ ```
34
+
35
+ ## Access the X-ray context
36
+
37
+ ```ts
38
+ import { getXrayContext } from '@stainlessdev/xray-node';
39
+
40
+ const handler = wrapHttpHandler((req, res) => {
41
+ const ctx = getXrayContext(req);
42
+ ctx?.setUserId('user-123');
43
+ res.end('ok');
44
+ }, xray);
45
+ ```
46
+
47
+ ## Request IDs and response headers
48
+
49
+ X-ray will **auto-generate a request ID and inject it into your response headers** under the configured name (`requestId.header`, default `request-id`, emitted as `Request-Id`) if the header is missing. If you set your own request ID first (via `options.requestId` or by setting the response header yourself), X-ray preserves it and does not overwrite the header.
50
+
51
+ ## Configuration
52
+
53
+ `createEmitter(config)` accepts `XrayRuntimeConfig` from `@stainlessdev/xray-core`:
54
+
55
+ - `serviceName` (required)
56
+ - `endpointUrl` (required; falls back to `STAINLESS_XRAY_ENDPOINT_URL` when omitted; explicit `endpointUrl` wins)
57
+ - `environment`, `version`, `logger`, `logLevel`
58
+ - `exporter`: `endpointUrl`, `headers`, `timeoutMs`, `spanProcessor`, `instance` (custom SpanExporter)
59
+ - `capture`: request/response headers and bodies
60
+ - `redaction`: headers/query/body JSON-path redaction
61
+ - `requestId`: header name to read/write
62
+ - `route`: normalization options
63
+
64
+ ## Adapter options (WrapOptions)
65
+
66
+ `wrapHttpHandler(handler, xray, options)` and `createEmitter(config, options?)` share:
67
+
68
+ - `route`: override the route name for the request
69
+ - `requestId`: explicit request ID to use (prevents auto-generation)
70
+ - `capture`: per-request capture overrides
71
+ - `redaction`: per-request redaction overrides
72
+ - `onRequest(ctx)`, `onResponse(ctx, log)`, `onError(ctx, err)` hooks
73
+
74
+ ## Notes
75
+
76
+ - This package depends on OpenTelemetry packages as peer dependencies.
77
+ - Node.js >= 20 is required.
package/dist/index.cjs CHANGED
@@ -51,7 +51,7 @@ function wrapHttpHandler(handler, xray, options) {
51
51
  headers: (0, import_internal.headerValuesFromNodeHeaders)(
52
52
  req.headers
53
53
  ),
54
- requestId: resolveRequestId(options?.requestId, req, xray),
54
+ requestId: options?.requestId,
55
55
  remoteAddress: req.socket?.remoteAddress,
56
56
  startTimeMs: Date.now()
57
57
  };
@@ -82,7 +82,13 @@ function wrapHttpHandler(handler, xray, options) {
82
82
  }
83
83
  const capture = options?.capture ? { ...xray.config.capture, ...options.capture } : xray.config.capture;
84
84
  const requestCapture = capture.requestBody === "none" ? null : wrapRequestBody(req, capture.maxBodyBytes);
85
- const recorder = new ResponseRecorder(capture.responseBody !== "none", capture.maxBodyBytes);
85
+ const recorder = new ResponseRecorder(
86
+ capture.responseBody !== "none",
87
+ capture.maxBodyBytes,
88
+ (response) => {
89
+ ensureResponseRequestId(response, ctx, xray);
90
+ }
91
+ );
86
92
  recorder.wrap(res);
87
93
  let finished = false;
88
94
  let capturedError;
@@ -297,10 +303,11 @@ function toBytes(chunk, encoding) {
297
303
  return null;
298
304
  }
299
305
  var ResponseRecorder = class {
300
- constructor(captureBody, maxBodySize) {
306
+ constructor(captureBody, maxBodySize, onHeader) {
301
307
  this.wroteHeader = false;
302
308
  this.bytes = 0;
303
309
  this.buffer = captureBody ? new import_internal.LimitedBuffer(maxBodySize) : null;
310
+ this.onHeader = onHeader;
304
311
  }
305
312
  body() {
306
313
  return this.buffer?.bytes() ?? new Uint8Array();
@@ -332,6 +339,9 @@ var ResponseRecorder = class {
332
339
  wrap(res) {
333
340
  const originalWriteHead = res.writeHead;
334
341
  res.writeHead = ((statusCode, ...args) => {
342
+ if (!this.wroteHeader) {
343
+ this.applyWriteHeadHeaders(res, args);
344
+ }
335
345
  this.recordHeader(res, statusCode);
336
346
  return originalWriteHead.call(res, statusCode, ...args);
337
347
  });
@@ -361,10 +371,52 @@ var ResponseRecorder = class {
361
371
  if (this.wroteHeader) {
362
372
  return;
363
373
  }
374
+ this.onHeader?.(res);
364
375
  this.wroteHeader = true;
365
376
  this.status = statusCode;
366
377
  this.headerSnapshot = { ...res.getHeaders() };
367
378
  }
379
+ applyWriteHeadHeaders(res, args) {
380
+ if (args.length === 0) {
381
+ return;
382
+ }
383
+ const headersArg = typeof args[0] === "string" ? args[1] : args[0];
384
+ if (!headersArg) {
385
+ return;
386
+ }
387
+ if (Array.isArray(headersArg)) {
388
+ if (headersArg.length === 0) {
389
+ return;
390
+ }
391
+ if (typeof headersArg[0] === "string") {
392
+ for (let i = 0; i < headersArg.length - 1; i += 2) {
393
+ const name = headersArg[i];
394
+ const value = headersArg[i + 1];
395
+ if (typeof name === "string" && value !== void 0 && value !== null) {
396
+ res.setHeader(name, value);
397
+ }
398
+ }
399
+ return;
400
+ }
401
+ for (const entry of headersArg) {
402
+ if (!Array.isArray(entry)) {
403
+ continue;
404
+ }
405
+ const [name, value] = entry;
406
+ if (typeof name === "string" && value !== void 0 && value !== null) {
407
+ res.setHeader(name, value);
408
+ }
409
+ }
410
+ return;
411
+ }
412
+ if (typeof headersArg === "object") {
413
+ for (const [name, value] of Object.entries(headersArg)) {
414
+ if (value !== void 0 && value !== null) {
415
+ res.setHeader(name, value);
416
+ }
417
+ }
418
+ }
419
+ }
368
420
  recordWrite(chunk, encoding) {
369
421
  const bytes = toBytes(chunk, encoding);
370
422
  if (!bytes) {
@@ -376,19 +428,20 @@ var ResponseRecorder = class {
376
428
  }
377
429
  }
378
430
  };
379
- function resolveRequestId(explicit, req, xray) {
380
- if (explicit) {
381
- return explicit;
382
- }
383
- const headerName = xray.config.requestId.header.toLowerCase();
384
- const value = req.headers[headerName];
385
- if (!value) {
386
- return void 0;
431
+ function ensureResponseRequestId(res, ctx, xray) {
432
+ const headerName = xray.config.requestId.header;
433
+ const existing = headerValueFromNode(res.getHeader(headerName));
434
+ if (existing) {
435
+ return;
387
436
  }
388
- if (Array.isArray(value)) {
389
- return value[0]?.trim() || void 0;
437
+ const explicit = normalizeRequestIdCandidate(ctx.requestId);
438
+ if (explicit) {
439
+ res.setHeader(canonicalHeaderName(headerName), explicit);
440
+ return;
390
441
  }
391
- return `${value}`.trim() || void 0;
442
+ const generated = (0, import_internal.generateRequestId)();
443
+ res.setHeader(canonicalHeaderName(headerName), generated);
444
+ (0, import_internal.setContextRequestId)(ctx, generated);
392
445
  }
393
446
  function fullUrl(req) {
394
447
  if (!req.url) {
@@ -404,6 +457,25 @@ function fullUrl(req) {
404
457
  const scheme = req.socket instanceof import_node_tls.TLSSocket ? "https" : "http";
405
458
  return `${scheme}://${host}${req.url}`;
406
459
  }
460
+ function headerValueFromNode(value) {
461
+ if (value == null) {
462
+ return void 0;
463
+ }
464
+ if (Array.isArray(value)) {
465
+ return normalizeRequestIdCandidate(value[0]);
466
+ }
467
+ return normalizeRequestIdCandidate(`${value}`);
468
+ }
469
+ function normalizeRequestIdCandidate(value) {
470
+ if (!value) {
471
+ return void 0;
472
+ }
473
+ const trimmed = value.trim();
474
+ return trimmed ? trimmed : void 0;
475
+ }
476
+ function canonicalHeaderName(headerName) {
477
+ return headerName.split("-").filter(Boolean).map((part) => part ? part[0].toUpperCase() + part.slice(1) : part).join("-");
478
+ }
407
479
  var expressParamsHistory = /* @__PURE__ */ new WeakMap();
408
480
  function trackExpressParams(req) {
409
481
  if (expressParamsHistory.has(req)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/emitter.ts","../src/adapter.ts"],"sourcesContent":["export { createEmitter } from './emitter';\nexport { wrapHttpHandler, getXrayContext } from './adapter';\nexport type { WrapOptions, NodeHttpHandler } from './adapter';\n","import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';\nimport {\n createEmitter as createCoreEmitter,\n normalizeConfig,\n type XrayRuntimeConfig,\n} from '@stainlessdev/xray-core';\n\nexport function createEmitter(config: XrayRuntimeConfig) {\n const resolved = normalizeConfig(config);\n const exporter =\n config.exporter?.instance ??\n new OTLPTraceExporter({\n url: resolved.exporter.endpointUrl,\n headers: resolved.exporter.headers ?? {},\n timeoutMillis: resolved.exporter.timeoutMs,\n });\n\n return createCoreEmitter(config, exporter);\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport { TLSSocket } from 'node:tls';\nimport type {\n CaptureConfig,\n NormalizedRequest,\n NormalizedResponse,\n RedactionConfig,\n RequestLog,\n XrayContext,\n XrayEmitter,\n} from '@stainlessdev/xray-core';\nimport {\n LimitedBuffer,\n bindContextToObject,\n getXrayContextFromObject,\n headerValuesFromNodeHeaders,\n isWebsocketUpgrade,\n logWithLevel,\n makeCapturedBody,\n setCaptureOverride,\n setContextRequestId,\n setContextRoute,\n setRedactionOverride,\n} from '@stainlessdev/xray-core/internal';\n\nexport type NodeHttpHandler = (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;\n\nexport interface WrapOptions {\n route?: string;\n requestId?: string;\n capture?: Partial<CaptureConfig>;\n redaction?: Partial<RedactionConfig>;\n onRequest?: (ctx: XrayContext) => void;\n onResponse?: (ctx: XrayContext, log: RequestLog) => void;\n onError?: (ctx: XrayContext, err: unknown) => void;\n}\n\nexport function wrapHttpHandler(\n handler: NodeHttpHandler,\n xray: XrayEmitter,\n options?: WrapOptions,\n): NodeHttpHandler {\n return (req, res) => {\n const normalizedRequest: NormalizedRequest = {\n method: req.method ?? 'GET',\n url: fullUrl(req),\n route: options?.route,\n headers: headerValuesFromNodeHeaders(\n req.headers as Record<string, string | string[] | number | undefined>,\n ),\n requestId: resolveRequestId(options?.requestId, req, xray),\n remoteAddress: req.socket?.remoteAddress,\n startTimeMs: Date.now(),\n };\n\n trackExpressParams(req);\n\n const ctx = xray.startRequest(normalizedRequest);\n bindContextToObject(req, ctx);\n bindContextToObject(res, ctx);\n\n if (options?.requestId) {\n setContextRequestId(ctx, options.requestId);\n }\n if (options?.route) {\n setContextRoute(ctx, options.route);\n }\n if (options?.capture) {\n setCaptureOverride(ctx, options.capture);\n }\n if (options?.redaction) {\n setRedactionOverride(ctx, options.redaction);\n }\n\n if (options?.onRequest) {\n try {\n options.onRequest(ctx);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onRequest failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n const capture = options?.capture\n ? { ...xray.config.capture, ...options.capture }\n : xray.config.capture;\n\n const requestCapture =\n capture.requestBody === 'none' ? null : wrapRequestBody(req, capture.maxBodyBytes);\n const recorder = new ResponseRecorder(capture.responseBody !== 'none', capture.maxBodyBytes);\n recorder.wrap(res);\n\n let finished = false;\n let capturedError: unknown;\n let onErrorCalled = false;\n\n const finish = () => {\n if (finished) {\n return;\n }\n finished = true;\n if (!normalizedRequest.route) {\n const route = resolveExpressRoute(req);\n if (route) {\n normalizedRequest.route = route;\n }\n }\n\n if (requestCapture && requestCapture.read) {\n normalizedRequest.body = makeCapturedBody(\n requestCapture.buffer.bytes(),\n requestCapture.buffer.totalBytes(),\n requestCapture.buffer.truncated(),\n capture.requestBody === 'text' ? 'text' : 'base64',\n );\n }\n\n const responseHeaders = recorder.headersSnapshot(res.getHeaders());\n const recordedStatus = recorder.statusCode() ?? res.statusCode;\n const statusCode = capturedError && !recorder.hasWrittenHeader() ? 500 : recordedStatus;\n const isUpgrade = isWebsocketUpgrade(\n statusCode ?? 0,\n normalizedRequest.headers,\n responseHeaders,\n );\n\n const responseBody =\n recorder.bodyCaptured() && !isUpgrade\n ? makeCapturedBody(\n recorder.body(),\n recorder.totalBytes(),\n recorder.truncated(),\n capture.responseBody === 'text' ? 'text' : 'base64',\n )\n : undefined;\n\n const normalizedResponse: NormalizedResponse = {\n statusCode: statusCode ?? undefined,\n headers: responseHeaders,\n body: responseBody,\n endTimeMs: Date.now(),\n };\n\n const log = xray.endRequest(ctx, normalizedResponse, capturedError);\n\n if (capturedError && options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, capturedError);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (err) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n {\n error: err instanceof Error ? err.message : String(err),\n },\n );\n }\n }\n };\n\n res.once('finish', finish);\n res.once('close', finish);\n\n try {\n const result = handler(req, res);\n if (result && typeof (result as Promise<void>).catch === 'function') {\n void (result as Promise<void>).catch((err) => {\n capturedError = err;\n if (options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, err);\n } catch (errInner) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onError failed',\n {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n },\n );\n }\n }\n });\n }\n } catch (err) {\n capturedError = err;\n if (options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, err);\n } catch (errInner) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n });\n }\n }\n throw err;\n }\n };\n}\n\nexport function getXrayContext(req: IncomingMessage): XrayContext | undefined {\n return getXrayContextFromObject(req);\n}\n\ntype RequestCapture = {\n buffer: LimitedBuffer;\n read: boolean;\n userConsuming: boolean;\n};\n\nfunction wrapRequestBody(req: IncomingMessage, limit: number): RequestCapture | null {\n if (limit <= 0) {\n return null;\n }\n if (!hasRequestBody(req)) {\n return null;\n }\n\n const capture: RequestCapture = {\n buffer: new LimitedBuffer(limit),\n read: false,\n userConsuming: false,\n };\n\n const originalPush = req.push;\n req.push = function push(chunk: unknown, encoding?: BufferEncoding): boolean {\n if (chunk != null) {\n recordChunk(capture, chunk, encoding);\n }\n return originalPush.call(req, chunk as any, encoding as any);\n } as typeof req.push;\n\n const originalEmit = req.emit;\n req.emit = function emit(event: string, ...args: unknown[]): boolean {\n if (event === 'data' && capture.userConsuming && args[0] != null) {\n capture.read = true;\n }\n if (event === 'end' && capture.userConsuming) {\n capture.read = true;\n }\n return originalEmit.call(req, event, ...args);\n } as typeof req.emit;\n\n const originalOn = req.on;\n req.on = function on(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalOn.call(req, event, listener);\n } as typeof req.on;\n\n const originalOnce = req.once;\n req.once = function once(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalOnce.call(req, event, listener);\n } as typeof req.once;\n\n const originalAddListener = req.addListener;\n req.addListener = function addListener(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalAddListener.call(req, event, listener);\n } as typeof req.addListener;\n\n const originalPipe = req.pipe;\n req.pipe = function pipe(destination: unknown, options?: unknown): unknown {\n capture.userConsuming = true;\n return originalPipe.call(req, destination as any, options as any);\n } as typeof req.pipe;\n\n const originalRead = req.read;\n req.read = function read(size?: number): any {\n capture.userConsuming = true;\n const chunk = originalRead.call(req, size as any) as unknown;\n const readableFlowing = (req as IncomingMessage & { readableFlowing?: boolean | null })\n .readableFlowing;\n const hasDataListeners =\n typeof req.listenerCount === 'function' && req.listenerCount('data') > 0;\n if (!hasDataListeners && readableFlowing !== true && chunk != null) {\n capture.read = true;\n }\n return chunk as any;\n } as typeof req.read;\n\n return capture;\n}\n\nfunction hasRequestBody(req: IncomingMessage): boolean {\n if (req.headers['content-length'] != null) {\n return true;\n }\n if (req.headers['transfer-encoding'] != null) {\n return true;\n }\n return false;\n}\n\nfunction recordChunk(capture: RequestCapture, chunk: unknown, encoding?: BufferEncoding): void {\n const bytes = toBytes(chunk, encoding);\n if (!bytes) {\n return;\n }\n capture.buffer.write(bytes);\n}\n\nfunction toBytes(chunk: unknown, encoding?: BufferEncoding): Uint8Array | null {\n if (chunk == null) {\n return null;\n }\n if (typeof chunk === 'string') {\n return Buffer.from(chunk, encoding);\n }\n if (chunk instanceof Uint8Array) {\n return chunk;\n }\n if (chunk instanceof ArrayBuffer) {\n return new Uint8Array(chunk);\n }\n return null;\n}\n\nclass ResponseRecorder {\n private readonly buffer: LimitedBuffer | null;\n private headerSnapshot?: Record<string, string | string[] | number | undefined>;\n private status?: number;\n private wroteHeader = false;\n private bytes = 0;\n\n constructor(captureBody: boolean, maxBodySize: number) {\n this.buffer = captureBody ? new LimitedBuffer(maxBodySize) : null;\n }\n\n body(): Uint8Array {\n return this.buffer?.bytes() ?? new Uint8Array();\n }\n\n totalBytes(): number {\n return this.buffer?.totalBytes() ?? 0;\n }\n\n bodyCaptured(): boolean {\n return !!this.buffer && this.buffer.totalBytes() > 0;\n }\n\n bytesWritten(): number {\n return this.bytes;\n }\n\n hasWrittenHeader(): boolean {\n return this.wroteHeader;\n }\n\n headersSnapshot(\n defaultHeaders: Record<string, string | string[] | number | undefined>,\n ): Record<string, string | string[]> {\n if (this.headerSnapshot) {\n return headerValuesFromNodeHeaders(this.headerSnapshot);\n }\n return headerValuesFromNodeHeaders(defaultHeaders);\n }\n\n statusCode(): number | undefined {\n return this.status;\n }\n\n truncated(): boolean {\n return this.buffer?.truncated() ?? false;\n }\n\n wrap(res: ServerResponse): void {\n const originalWriteHead = res.writeHead;\n res.writeHead = ((statusCode: number, ...args: any[]) => {\n this.recordHeader(res, statusCode);\n return (originalWriteHead as any).call(res, statusCode, ...args);\n }) as typeof res.writeHead;\n\n const originalWrite = res.write;\n res.write = ((chunk: unknown, encoding?: BufferEncoding, cb?: (err?: Error | null) => void) => {\n this.recordHeader(res, res.statusCode ?? 200);\n this.recordWrite(chunk, encoding);\n return originalWrite.call(res, chunk as any, encoding as any, cb as any);\n }) as typeof res.write;\n\n const originalEnd = res.end;\n res.end = ((chunk?: unknown, encoding?: BufferEncoding, cb?: () => void) => {\n this.recordHeader(res, res.statusCode ?? 200);\n if (chunk) {\n this.recordWrite(chunk, encoding);\n }\n return originalEnd.call(res, chunk as any, encoding as any, cb as any);\n }) as typeof res.end;\n\n if (typeof res.flushHeaders === 'function') {\n const originalFlush = res.flushHeaders;\n res.flushHeaders = (() => {\n this.recordHeader(res, res.statusCode ?? 200);\n return originalFlush.call(res);\n }) as typeof res.flushHeaders;\n }\n }\n\n private recordHeader(res: ServerResponse, statusCode: number): void {\n if (this.wroteHeader) {\n return;\n }\n this.wroteHeader = true;\n this.status = statusCode;\n this.headerSnapshot = { ...res.getHeaders() } as Record<\n string,\n string | string[] | number | undefined\n >;\n }\n\n private recordWrite(chunk: unknown, encoding?: BufferEncoding): void {\n const bytes = toBytes(chunk, encoding);\n if (!bytes) {\n return;\n }\n this.bytes += bytes.length;\n if (this.buffer) {\n this.buffer.write(bytes);\n }\n }\n}\n\nfunction resolveRequestId(\n explicit: string | undefined,\n req: IncomingMessage,\n xray: XrayEmitter,\n): string | undefined {\n if (explicit) {\n return explicit;\n }\n const headerName = xray.config.requestId.header.toLowerCase();\n const value = req.headers[headerName];\n if (!value) {\n return undefined;\n }\n if (Array.isArray(value)) {\n return value[0]?.trim() || undefined;\n }\n return `${value}`.trim() || undefined;\n}\n\nfunction fullUrl(req: IncomingMessage): string {\n if (!req.url) {\n return '';\n }\n if (req.url.startsWith('http://') || req.url.startsWith('https://')) {\n return req.url;\n }\n\n const host = req.headers['host'];\n if (!host || typeof host !== 'string') {\n return req.url;\n }\n const scheme = req.socket instanceof TLSSocket ? 'https' : 'http';\n return `${scheme}://${host}${req.url}`;\n}\n\ntype ExpressRoutePath = string | string[] | RegExp;\n\ntype ExpressRouteParams = Record<string, string | string[]>;\n\nconst expressParamsHistory = new WeakMap<IncomingMessage, ExpressRouteParams[]>();\n\nfunction trackExpressParams(req: IncomingMessage): void {\n if (expressParamsHistory.has(req)) {\n return;\n }\n const anyReq = req as IncomingMessage & { app?: unknown };\n if (typeof anyReq.app !== 'function') {\n return;\n }\n\n const history: ExpressRouteParams[] = [];\n expressParamsHistory.set(req, history);\n\n const descriptor = Object.getOwnPropertyDescriptor(req, 'params');\n if (descriptor && !descriptor.configurable) {\n if (descriptor.value && typeof descriptor.value === 'object') {\n history.push({ ...(descriptor.value as ExpressRouteParams) });\n }\n return;\n }\n\n let current = (\n descriptor && 'value' in descriptor\n ? (descriptor.value as ExpressRouteParams | undefined)\n : undefined\n ) as ExpressRouteParams | undefined;\n if (current && typeof current === 'object') {\n history.push({ ...current });\n }\n\n Object.defineProperty(req, 'params', {\n configurable: true,\n enumerable: descriptor?.enumerable ?? true,\n get() {\n return current;\n },\n set(value) {\n current = value as ExpressRouteParams | undefined;\n if (value && typeof value === 'object') {\n history.push({ ...(value as ExpressRouteParams) });\n }\n },\n });\n}\n\nfunction resolveExpressRoute(req: IncomingMessage): string | undefined {\n const anyReq = req as IncomingMessage & {\n baseUrl?: string;\n params?: ExpressRouteParams;\n route?: { path?: ExpressRoutePath };\n };\n const routePath = extractExpressRoutePath(anyReq.route?.path);\n const baseUrl = anyReq.baseUrl ?? '';\n if (!routePath && !baseUrl) {\n return undefined;\n }\n\n const params = collectExpressParams(req, anyReq.params);\n const resolvedBaseUrl = replaceBaseUrlParams(baseUrl, params, routePath);\n return joinExpressRoute(resolvedBaseUrl, routePath);\n}\n\nfunction extractExpressRoutePath(path?: ExpressRoutePath): string | undefined {\n if (typeof path === 'string') {\n return path;\n }\n if (Array.isArray(path)) {\n for (const entry of path) {\n if (typeof entry === 'string') {\n return entry;\n }\n }\n }\n return undefined;\n}\n\nfunction collectExpressParams(\n req: IncomingMessage,\n fallback?: ExpressRouteParams,\n): ExpressRouteParams {\n const history = expressParamsHistory.get(req);\n if (!history || history.length === 0) {\n return fallback ?? {};\n }\n\n const merged: ExpressRouteParams = {};\n for (const snapshot of history) {\n for (const [key, value] of Object.entries(snapshot)) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n }\n if (fallback) {\n for (const [key, value] of Object.entries(fallback)) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n }\n return merged;\n}\n\nfunction replaceBaseUrlParams(\n baseUrl: string,\n params: ExpressRouteParams,\n routePath?: string,\n): string {\n if (!baseUrl) {\n return baseUrl;\n }\n const entries = Object.entries(params);\n if (entries.length === 0) {\n return baseUrl;\n }\n\n const excluded = new Set(routePath ? extractExpressParamNames(routePath) : []);\n const replacements = entries\n .filter(([name]) => !excluded.has(name))\n .map(([name, value]) => ({ name, value: Array.isArray(value) ? value[0] : value }))\n .filter((entry): entry is { name: string; value: string } => !!entry.value);\n\n if (replacements.length === 0) {\n return baseUrl;\n }\n\n const used = new Set<string>();\n const encodedCache = new Map<string, string>();\n const segments = baseUrl.split('/');\n const updated = segments.map((segment) => {\n if (!segment) {\n return segment;\n }\n for (const { name, value } of replacements) {\n if (used.has(name)) {\n continue;\n }\n const encodedValue = encodedCache.get(value) ?? encodeURIComponent(value);\n encodedCache.set(value, encodedValue);\n if (segment === value || segment === encodedValue) {\n used.add(name);\n return `:${name}`;\n }\n }\n return segment;\n });\n\n return updated.join('/');\n}\n\nfunction extractExpressParamNames(path: string): string[] {\n const names: string[] = [];\n const paramPattern = /:([A-Za-z0-9_]+)(?:\\([^)]*\\))?[?*+]?/g;\n for (const match of path.matchAll(paramPattern)) {\n const name = match[1];\n if (name) {\n names.push(name);\n }\n }\n return names;\n}\n\nfunction joinExpressRoute(baseUrl: string, routePath?: string): string {\n const base = baseUrl ? ensureLeadingSlash(baseUrl) : '';\n const route = routePath ? ensureLeadingSlash(routePath) : '';\n if (!base) {\n return route || '/';\n }\n if (!route || route === '/') {\n return base;\n }\n const trimmedBase = base.endsWith('/') ? base.slice(0, -1) : base;\n return `${trimmedBase}${route}`;\n}\n\nfunction ensureLeadingSlash(path: string): string {\n if (!path) {\n return '/';\n }\n return path.startsWith('/') ? path : `/${path}`;\n}\n"],"mappings":"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","names":["createCoreEmitter"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/emitter.ts","../src/adapter.ts"],"sourcesContent":["export { createEmitter } from './emitter';\nexport { wrapHttpHandler, getXrayContext } from './adapter';\nexport type { WrapOptions, NodeHttpHandler } from './adapter';\n","import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';\nimport {\n createEmitter as createCoreEmitter,\n normalizeConfig,\n type XrayRuntimeConfig,\n} from '@stainlessdev/xray-core';\n\nexport function createEmitter(config: XrayRuntimeConfig) {\n const resolved = normalizeConfig(config);\n const exporter =\n config.exporter?.instance ??\n new OTLPTraceExporter({\n url: resolved.exporter.endpointUrl,\n headers: resolved.exporter.headers ?? {},\n timeoutMillis: resolved.exporter.timeoutMs,\n });\n\n return createCoreEmitter(config, exporter);\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport { TLSSocket } from 'node:tls';\nimport type {\n CaptureConfig,\n NormalizedRequest,\n NormalizedResponse,\n RedactionConfig,\n RequestLog,\n XrayContext,\n XrayEmitter,\n} from '@stainlessdev/xray-core';\nimport {\n LimitedBuffer,\n bindContextToObject,\n getXrayContextFromObject,\n headerValuesFromNodeHeaders,\n isWebsocketUpgrade,\n logWithLevel,\n makeCapturedBody,\n setCaptureOverride,\n setContextRequestId,\n setContextRoute,\n setRedactionOverride,\n generateRequestId,\n} from '@stainlessdev/xray-core/internal';\n\nexport type NodeHttpHandler = (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;\n\nexport interface WrapOptions {\n route?: string;\n requestId?: string;\n capture?: Partial<CaptureConfig>;\n redaction?: Partial<RedactionConfig>;\n onRequest?: (ctx: XrayContext) => void;\n onResponse?: (ctx: XrayContext, log: RequestLog) => void;\n onError?: (ctx: XrayContext, err: unknown) => void;\n}\n\nexport function wrapHttpHandler(\n handler: NodeHttpHandler,\n xray: XrayEmitter,\n options?: WrapOptions,\n): NodeHttpHandler {\n return (req, res) => {\n const normalizedRequest: NormalizedRequest = {\n method: req.method ?? 'GET',\n url: fullUrl(req),\n route: options?.route,\n headers: headerValuesFromNodeHeaders(\n req.headers as Record<string, string | string[] | number | undefined>,\n ),\n requestId: options?.requestId,\n remoteAddress: req.socket?.remoteAddress,\n startTimeMs: Date.now(),\n };\n\n trackExpressParams(req);\n\n const ctx = xray.startRequest(normalizedRequest);\n bindContextToObject(req, ctx);\n bindContextToObject(res, ctx);\n\n if (options?.requestId) {\n setContextRequestId(ctx, options.requestId);\n }\n if (options?.route) {\n setContextRoute(ctx, options.route);\n }\n if (options?.capture) {\n setCaptureOverride(ctx, options.capture);\n }\n if (options?.redaction) {\n setRedactionOverride(ctx, options.redaction);\n }\n\n if (options?.onRequest) {\n try {\n options.onRequest(ctx);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onRequest failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n const capture = options?.capture\n ? { ...xray.config.capture, ...options.capture }\n : xray.config.capture;\n\n const requestCapture =\n capture.requestBody === 'none' ? null : wrapRequestBody(req, capture.maxBodyBytes);\n const recorder = new ResponseRecorder(\n capture.responseBody !== 'none',\n capture.maxBodyBytes,\n (response) => {\n ensureResponseRequestId(response, ctx, xray);\n },\n );\n recorder.wrap(res);\n\n let finished = false;\n let capturedError: unknown;\n let onErrorCalled = false;\n\n const finish = () => {\n if (finished) {\n return;\n }\n finished = true;\n if (!normalizedRequest.route) {\n const route = resolveExpressRoute(req);\n if (route) {\n normalizedRequest.route = route;\n }\n }\n\n if (requestCapture && requestCapture.read) {\n normalizedRequest.body = makeCapturedBody(\n requestCapture.buffer.bytes(),\n requestCapture.buffer.totalBytes(),\n requestCapture.buffer.truncated(),\n capture.requestBody === 'text' ? 'text' : 'base64',\n );\n }\n\n const responseHeaders = recorder.headersSnapshot(res.getHeaders());\n const recordedStatus = recorder.statusCode() ?? res.statusCode;\n const statusCode = capturedError && !recorder.hasWrittenHeader() ? 500 : recordedStatus;\n const isUpgrade = isWebsocketUpgrade(\n statusCode ?? 0,\n normalizedRequest.headers,\n responseHeaders,\n );\n\n const responseBody =\n recorder.bodyCaptured() && !isUpgrade\n ? makeCapturedBody(\n recorder.body(),\n recorder.totalBytes(),\n recorder.truncated(),\n capture.responseBody === 'text' ? 'text' : 'base64',\n )\n : undefined;\n\n const normalizedResponse: NormalizedResponse = {\n statusCode: statusCode ?? undefined,\n headers: responseHeaders,\n body: responseBody,\n endTimeMs: Date.now(),\n };\n\n const log = xray.endRequest(ctx, normalizedResponse, capturedError);\n\n if (capturedError && options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, capturedError);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (err) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n {\n error: err instanceof Error ? err.message : String(err),\n },\n );\n }\n }\n };\n\n res.once('finish', finish);\n res.once('close', finish);\n\n try {\n const result = handler(req, res);\n if (result && typeof (result as Promise<void>).catch === 'function') {\n void (result as Promise<void>).catch((err) => {\n capturedError = err;\n if (options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, err);\n } catch (errInner) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onError failed',\n {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n },\n );\n }\n }\n });\n }\n } catch (err) {\n capturedError = err;\n if (options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, err);\n } catch (errInner) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n });\n }\n }\n throw err;\n }\n };\n}\n\nexport function getXrayContext(req: IncomingMessage): XrayContext | undefined {\n return getXrayContextFromObject(req);\n}\n\ntype RequestCapture = {\n buffer: LimitedBuffer;\n read: boolean;\n userConsuming: boolean;\n};\n\nfunction wrapRequestBody(req: IncomingMessage, limit: number): RequestCapture | null {\n if (limit <= 0) {\n return null;\n }\n if (!hasRequestBody(req)) {\n return null;\n }\n\n const capture: RequestCapture = {\n buffer: new LimitedBuffer(limit),\n read: false,\n userConsuming: false,\n };\n\n const originalPush = req.push;\n req.push = function push(chunk: unknown, encoding?: BufferEncoding): boolean {\n if (chunk != null) {\n recordChunk(capture, chunk, encoding);\n }\n return originalPush.call(req, chunk as any, encoding as any);\n } as typeof req.push;\n\n const originalEmit = req.emit;\n req.emit = function emit(event: string, ...args: unknown[]): boolean {\n if (event === 'data' && capture.userConsuming && args[0] != null) {\n capture.read = true;\n }\n if (event === 'end' && capture.userConsuming) {\n capture.read = true;\n }\n return originalEmit.call(req, event, ...args);\n } as typeof req.emit;\n\n const originalOn = req.on;\n req.on = function on(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalOn.call(req, event, listener);\n } as typeof req.on;\n\n const originalOnce = req.once;\n req.once = function once(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalOnce.call(req, event, listener);\n } as typeof req.once;\n\n const originalAddListener = req.addListener;\n req.addListener = function addListener(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalAddListener.call(req, event, listener);\n } as typeof req.addListener;\n\n const originalPipe = req.pipe;\n req.pipe = function pipe(destination: unknown, options?: unknown): unknown {\n capture.userConsuming = true;\n return originalPipe.call(req, destination as any, options as any);\n } as typeof req.pipe;\n\n const originalRead = req.read;\n req.read = function read(size?: number): any {\n capture.userConsuming = true;\n const chunk = originalRead.call(req, size as any) as unknown;\n const readableFlowing = (req as IncomingMessage & { readableFlowing?: boolean | null })\n .readableFlowing;\n const hasDataListeners =\n typeof req.listenerCount === 'function' && req.listenerCount('data') > 0;\n if (!hasDataListeners && readableFlowing !== true && chunk != null) {\n capture.read = true;\n }\n return chunk as any;\n } as typeof req.read;\n\n return capture;\n}\n\nfunction hasRequestBody(req: IncomingMessage): boolean {\n if (req.headers['content-length'] != null) {\n return true;\n }\n if (req.headers['transfer-encoding'] != null) {\n return true;\n }\n return false;\n}\n\nfunction recordChunk(capture: RequestCapture, chunk: unknown, encoding?: BufferEncoding): void {\n const bytes = toBytes(chunk, encoding);\n if (!bytes) {\n return;\n }\n capture.buffer.write(bytes);\n}\n\nfunction toBytes(chunk: unknown, encoding?: BufferEncoding): Uint8Array | null {\n if (chunk == null) {\n return null;\n }\n if (typeof chunk === 'string') {\n return Buffer.from(chunk, encoding);\n }\n if (chunk instanceof Uint8Array) {\n return chunk;\n }\n if (chunk instanceof ArrayBuffer) {\n return new Uint8Array(chunk);\n }\n return null;\n}\n\nclass ResponseRecorder {\n private readonly buffer: LimitedBuffer | null;\n private headerSnapshot?: Record<string, string | string[] | number | undefined>;\n private status?: number;\n private wroteHeader = false;\n private bytes = 0;\n private readonly onHeader?: (res: ServerResponse) => void;\n\n constructor(captureBody: boolean, maxBodySize: number, onHeader?: (res: ServerResponse) => void) {\n this.buffer = captureBody ? new LimitedBuffer(maxBodySize) : null;\n this.onHeader = onHeader;\n }\n\n body(): Uint8Array {\n return this.buffer?.bytes() ?? new Uint8Array();\n }\n\n totalBytes(): number {\n return this.buffer?.totalBytes() ?? 0;\n }\n\n bodyCaptured(): boolean {\n return !!this.buffer && this.buffer.totalBytes() > 0;\n }\n\n bytesWritten(): number {\n return this.bytes;\n }\n\n hasWrittenHeader(): boolean {\n return this.wroteHeader;\n }\n\n headersSnapshot(\n defaultHeaders: Record<string, string | string[] | number | undefined>,\n ): Record<string, string | string[]> {\n if (this.headerSnapshot) {\n return headerValuesFromNodeHeaders(this.headerSnapshot);\n }\n return headerValuesFromNodeHeaders(defaultHeaders);\n }\n\n statusCode(): number | undefined {\n return this.status;\n }\n\n truncated(): boolean {\n return this.buffer?.truncated() ?? false;\n }\n\n wrap(res: ServerResponse): void {\n const originalWriteHead = res.writeHead;\n res.writeHead = ((statusCode: number, ...args: any[]) => {\n if (!this.wroteHeader) {\n this.applyWriteHeadHeaders(res, args);\n }\n this.recordHeader(res, statusCode);\n return (originalWriteHead as any).call(res, statusCode, ...args);\n }) as typeof res.writeHead;\n\n const originalWrite = res.write;\n res.write = ((chunk: unknown, encoding?: BufferEncoding, cb?: (err?: Error | null) => void) => {\n this.recordHeader(res, res.statusCode ?? 200);\n this.recordWrite(chunk, encoding);\n return originalWrite.call(res, chunk as any, encoding as any, cb as any);\n }) as typeof res.write;\n\n const originalEnd = res.end;\n res.end = ((chunk?: unknown, encoding?: BufferEncoding, cb?: () => void) => {\n this.recordHeader(res, res.statusCode ?? 200);\n if (chunk) {\n this.recordWrite(chunk, encoding);\n }\n return originalEnd.call(res, chunk as any, encoding as any, cb as any);\n }) as typeof res.end;\n\n if (typeof res.flushHeaders === 'function') {\n const originalFlush = res.flushHeaders;\n res.flushHeaders = (() => {\n this.recordHeader(res, res.statusCode ?? 200);\n return originalFlush.call(res);\n }) as typeof res.flushHeaders;\n }\n }\n\n private recordHeader(res: ServerResponse, statusCode: number): void {\n if (this.wroteHeader) {\n return;\n }\n this.onHeader?.(res);\n this.wroteHeader = true;\n this.status = statusCode;\n this.headerSnapshot = { ...res.getHeaders() } as Record<\n string,\n string | string[] | number | undefined\n >;\n }\n\n private applyWriteHeadHeaders(res: ServerResponse, args: any[]): void {\n if (args.length === 0) {\n return;\n }\n const headersArg = typeof args[0] === 'string' ? args[1] : args[0];\n if (!headersArg) {\n return;\n }\n if (Array.isArray(headersArg)) {\n if (headersArg.length === 0) {\n return;\n }\n if (typeof headersArg[0] === 'string') {\n for (let i = 0; i < headersArg.length - 1; i += 2) {\n const name = headersArg[i];\n const value = headersArg[i + 1];\n if (typeof name === 'string' && value !== undefined && value !== null) {\n res.setHeader(name, value as any);\n }\n }\n return;\n }\n for (const entry of headersArg) {\n if (!Array.isArray(entry)) {\n continue;\n }\n const [name, value] = entry;\n if (typeof name === 'string' && value !== undefined && value !== null) {\n res.setHeader(name, value as any);\n }\n }\n return;\n }\n if (typeof headersArg === 'object') {\n for (const [name, value] of Object.entries(headersArg as Record<string, unknown>)) {\n if (value !== undefined && value !== null) {\n res.setHeader(name, value as any);\n }\n }\n }\n }\n\n private recordWrite(chunk: unknown, encoding?: BufferEncoding): void {\n const bytes = toBytes(chunk, encoding);\n if (!bytes) {\n return;\n }\n this.bytes += bytes.length;\n if (this.buffer) {\n this.buffer.write(bytes);\n }\n }\n}\n\nfunction ensureResponseRequestId(res: ServerResponse, ctx: XrayContext, xray: XrayEmitter): void {\n const headerName = xray.config.requestId.header;\n const existing = headerValueFromNode(res.getHeader(headerName));\n if (existing) {\n return;\n }\n\n const explicit = normalizeRequestIdCandidate(ctx.requestId);\n if (explicit) {\n res.setHeader(canonicalHeaderName(headerName), explicit);\n return;\n }\n\n const generated = generateRequestId();\n res.setHeader(canonicalHeaderName(headerName), generated);\n setContextRequestId(ctx, generated);\n}\n\nfunction fullUrl(req: IncomingMessage): string {\n if (!req.url) {\n return '';\n }\n if (req.url.startsWith('http://') || req.url.startsWith('https://')) {\n return req.url;\n }\n\n const host = req.headers['host'];\n if (!host || typeof host !== 'string') {\n return req.url;\n }\n const scheme = req.socket instanceof TLSSocket ? 'https' : 'http';\n return `${scheme}://${host}${req.url}`;\n}\n\nfunction headerValueFromNode(value: unknown): string | undefined {\n if (value == null) {\n return undefined;\n }\n if (Array.isArray(value)) {\n return normalizeRequestIdCandidate(value[0]);\n }\n return normalizeRequestIdCandidate(`${value}`);\n}\n\nfunction normalizeRequestIdCandidate(value: string | undefined): string | undefined {\n if (!value) {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction canonicalHeaderName(headerName: string): string {\n return headerName\n .split('-')\n .filter(Boolean)\n .map((part) => (part ? part[0]!.toUpperCase() + part.slice(1) : part))\n .join('-');\n}\n\ntype ExpressRoutePath = string | string[] | RegExp;\n\ntype ExpressRouteParams = Record<string, string | string[]>;\n\nconst expressParamsHistory = new WeakMap<IncomingMessage, ExpressRouteParams[]>();\n\nfunction trackExpressParams(req: IncomingMessage): void {\n if (expressParamsHistory.has(req)) {\n return;\n }\n const anyReq = req as IncomingMessage & { app?: unknown };\n if (typeof anyReq.app !== 'function') {\n return;\n }\n\n const history: ExpressRouteParams[] = [];\n expressParamsHistory.set(req, history);\n\n const descriptor = Object.getOwnPropertyDescriptor(req, 'params');\n if (descriptor && !descriptor.configurable) {\n if (descriptor.value && typeof descriptor.value === 'object') {\n history.push({ ...(descriptor.value as ExpressRouteParams) });\n }\n return;\n }\n\n let current = (\n descriptor && 'value' in descriptor\n ? (descriptor.value as ExpressRouteParams | undefined)\n : undefined\n ) as ExpressRouteParams | undefined;\n if (current && typeof current === 'object') {\n history.push({ ...current });\n }\n\n Object.defineProperty(req, 'params', {\n configurable: true,\n enumerable: descriptor?.enumerable ?? true,\n get() {\n return current;\n },\n set(value) {\n current = value as ExpressRouteParams | undefined;\n if (value && typeof value === 'object') {\n history.push({ ...(value as ExpressRouteParams) });\n }\n },\n });\n}\n\nfunction resolveExpressRoute(req: IncomingMessage): string | undefined {\n const anyReq = req as IncomingMessage & {\n baseUrl?: string;\n params?: ExpressRouteParams;\n route?: { path?: ExpressRoutePath };\n };\n const routePath = extractExpressRoutePath(anyReq.route?.path);\n const baseUrl = anyReq.baseUrl ?? '';\n if (!routePath && !baseUrl) {\n return undefined;\n }\n\n const params = collectExpressParams(req, anyReq.params);\n const resolvedBaseUrl = replaceBaseUrlParams(baseUrl, params, routePath);\n return joinExpressRoute(resolvedBaseUrl, routePath);\n}\n\nfunction extractExpressRoutePath(path?: ExpressRoutePath): string | undefined {\n if (typeof path === 'string') {\n return path;\n }\n if (Array.isArray(path)) {\n for (const entry of path) {\n if (typeof entry === 'string') {\n return entry;\n }\n }\n }\n return undefined;\n}\n\nfunction collectExpressParams(\n req: IncomingMessage,\n fallback?: ExpressRouteParams,\n): ExpressRouteParams {\n const history = expressParamsHistory.get(req);\n if (!history || history.length === 0) {\n return fallback ?? {};\n }\n\n const merged: ExpressRouteParams = {};\n for (const snapshot of history) {\n for (const [key, value] of Object.entries(snapshot)) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n }\n if (fallback) {\n for (const [key, value] of Object.entries(fallback)) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n }\n return merged;\n}\n\nfunction replaceBaseUrlParams(\n baseUrl: string,\n params: ExpressRouteParams,\n routePath?: string,\n): string {\n if (!baseUrl) {\n return baseUrl;\n }\n const entries = Object.entries(params);\n if (entries.length === 0) {\n return baseUrl;\n }\n\n const excluded = new Set(routePath ? extractExpressParamNames(routePath) : []);\n const replacements = entries\n .filter(([name]) => !excluded.has(name))\n .map(([name, value]) => ({ name, value: Array.isArray(value) ? value[0] : value }))\n .filter((entry): entry is { name: string; value: string } => !!entry.value);\n\n if (replacements.length === 0) {\n return baseUrl;\n }\n\n const used = new Set<string>();\n const encodedCache = new Map<string, string>();\n const segments = baseUrl.split('/');\n const updated = segments.map((segment) => {\n if (!segment) {\n return segment;\n }\n for (const { name, value } of replacements) {\n if (used.has(name)) {\n continue;\n }\n const encodedValue = encodedCache.get(value) ?? encodeURIComponent(value);\n encodedCache.set(value, encodedValue);\n if (segment === value || segment === encodedValue) {\n used.add(name);\n return `:${name}`;\n }\n }\n return segment;\n });\n\n return updated.join('/');\n}\n\nfunction extractExpressParamNames(path: string): string[] {\n const names: string[] = [];\n const paramPattern = /:([A-Za-z0-9_]+)(?:\\([^)]*\\))?[?*+]?/g;\n for (const match of path.matchAll(paramPattern)) {\n const name = match[1];\n if (name) {\n names.push(name);\n }\n }\n return names;\n}\n\nfunction joinExpressRoute(baseUrl: string, routePath?: string): string {\n const base = baseUrl ? ensureLeadingSlash(baseUrl) : '';\n const route = routePath ? ensureLeadingSlash(routePath) : '';\n if (!base) {\n return route || '/';\n }\n if (!route || route === '/') {\n return base;\n }\n const trimmedBase = base.endsWith('/') ? base.slice(0, -1) : base;\n return `${trimmedBase}${route}`;\n}\n\nfunction ensureLeadingSlash(path: string): string {\n if (!path) {\n return '/';\n }\n return path.startsWith('/') ? path : `/${path}`;\n}\n"],"mappings":"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","names":["createCoreEmitter"]}
package/dist/index.js CHANGED
@@ -27,7 +27,8 @@ import {
27
27
  setCaptureOverride,
28
28
  setContextRequestId,
29
29
  setContextRoute,
30
- setRedactionOverride
30
+ setRedactionOverride,
31
+ generateRequestId
31
32
  } from "@stainlessdev/xray-core/internal";
32
33
  function wrapHttpHandler(handler, xray, options) {
33
34
  return (req, res) => {
@@ -38,7 +39,7 @@ function wrapHttpHandler(handler, xray, options) {
38
39
  headers: headerValuesFromNodeHeaders(
39
40
  req.headers
40
41
  ),
41
- requestId: resolveRequestId(options?.requestId, req, xray),
42
+ requestId: options?.requestId,
42
43
  remoteAddress: req.socket?.remoteAddress,
43
44
  startTimeMs: Date.now()
44
45
  };
@@ -69,7 +70,13 @@ function wrapHttpHandler(handler, xray, options) {
69
70
  }
70
71
  const capture = options?.capture ? { ...xray.config.capture, ...options.capture } : xray.config.capture;
71
72
  const requestCapture = capture.requestBody === "none" ? null : wrapRequestBody(req, capture.maxBodyBytes);
72
- const recorder = new ResponseRecorder(capture.responseBody !== "none", capture.maxBodyBytes);
73
+ const recorder = new ResponseRecorder(
74
+ capture.responseBody !== "none",
75
+ capture.maxBodyBytes,
76
+ (response) => {
77
+ ensureResponseRequestId(response, ctx, xray);
78
+ }
79
+ );
73
80
  recorder.wrap(res);
74
81
  let finished = false;
75
82
  let capturedError;
@@ -284,10 +291,11 @@ function toBytes(chunk, encoding) {
284
291
  return null;
285
292
  }
286
293
  var ResponseRecorder = class {
287
- constructor(captureBody, maxBodySize) {
294
+ constructor(captureBody, maxBodySize, onHeader) {
288
295
  this.wroteHeader = false;
289
296
  this.bytes = 0;
290
297
  this.buffer = captureBody ? new LimitedBuffer(maxBodySize) : null;
298
+ this.onHeader = onHeader;
291
299
  }
292
300
  body() {
293
301
  return this.buffer?.bytes() ?? new Uint8Array();
@@ -319,6 +327,9 @@ var ResponseRecorder = class {
319
327
  wrap(res) {
320
328
  const originalWriteHead = res.writeHead;
321
329
  res.writeHead = ((statusCode, ...args) => {
330
+ if (!this.wroteHeader) {
331
+ this.applyWriteHeadHeaders(res, args);
332
+ }
322
333
  this.recordHeader(res, statusCode);
323
334
  return originalWriteHead.call(res, statusCode, ...args);
324
335
  });
@@ -348,10 +359,52 @@ var ResponseRecorder = class {
348
359
  if (this.wroteHeader) {
349
360
  return;
350
361
  }
362
+ this.onHeader?.(res);
351
363
  this.wroteHeader = true;
352
364
  this.status = statusCode;
353
365
  this.headerSnapshot = { ...res.getHeaders() };
354
366
  }
367
+ applyWriteHeadHeaders(res, args) {
368
+ if (args.length === 0) {
369
+ return;
370
+ }
371
+ const headersArg = typeof args[0] === "string" ? args[1] : args[0];
372
+ if (!headersArg) {
373
+ return;
374
+ }
375
+ if (Array.isArray(headersArg)) {
376
+ if (headersArg.length === 0) {
377
+ return;
378
+ }
379
+ if (typeof headersArg[0] === "string") {
380
+ for (let i = 0; i < headersArg.length - 1; i += 2) {
381
+ const name = headersArg[i];
382
+ const value = headersArg[i + 1];
383
+ if (typeof name === "string" && value !== void 0 && value !== null) {
384
+ res.setHeader(name, value);
385
+ }
386
+ }
387
+ return;
388
+ }
389
+ for (const entry of headersArg) {
390
+ if (!Array.isArray(entry)) {
391
+ continue;
392
+ }
393
+ const [name, value] = entry;
394
+ if (typeof name === "string" && value !== void 0 && value !== null) {
395
+ res.setHeader(name, value);
396
+ }
397
+ }
398
+ return;
399
+ }
400
+ if (typeof headersArg === "object") {
401
+ for (const [name, value] of Object.entries(headersArg)) {
402
+ if (value !== void 0 && value !== null) {
403
+ res.setHeader(name, value);
404
+ }
405
+ }
406
+ }
407
+ }
355
408
  recordWrite(chunk, encoding) {
356
409
  const bytes = toBytes(chunk, encoding);
357
410
  if (!bytes) {
@@ -363,19 +416,20 @@ var ResponseRecorder = class {
363
416
  }
364
417
  }
365
418
  };
366
- function resolveRequestId(explicit, req, xray) {
367
- if (explicit) {
368
- return explicit;
369
- }
370
- const headerName = xray.config.requestId.header.toLowerCase();
371
- const value = req.headers[headerName];
372
- if (!value) {
373
- return void 0;
419
+ function ensureResponseRequestId(res, ctx, xray) {
420
+ const headerName = xray.config.requestId.header;
421
+ const existing = headerValueFromNode(res.getHeader(headerName));
422
+ if (existing) {
423
+ return;
374
424
  }
375
- if (Array.isArray(value)) {
376
- return value[0]?.trim() || void 0;
425
+ const explicit = normalizeRequestIdCandidate(ctx.requestId);
426
+ if (explicit) {
427
+ res.setHeader(canonicalHeaderName(headerName), explicit);
428
+ return;
377
429
  }
378
- return `${value}`.trim() || void 0;
430
+ const generated = generateRequestId();
431
+ res.setHeader(canonicalHeaderName(headerName), generated);
432
+ setContextRequestId(ctx, generated);
379
433
  }
380
434
  function fullUrl(req) {
381
435
  if (!req.url) {
@@ -391,6 +445,25 @@ function fullUrl(req) {
391
445
  const scheme = req.socket instanceof TLSSocket ? "https" : "http";
392
446
  return `${scheme}://${host}${req.url}`;
393
447
  }
448
+ function headerValueFromNode(value) {
449
+ if (value == null) {
450
+ return void 0;
451
+ }
452
+ if (Array.isArray(value)) {
453
+ return normalizeRequestIdCandidate(value[0]);
454
+ }
455
+ return normalizeRequestIdCandidate(`${value}`);
456
+ }
457
+ function normalizeRequestIdCandidate(value) {
458
+ if (!value) {
459
+ return void 0;
460
+ }
461
+ const trimmed = value.trim();
462
+ return trimmed ? trimmed : void 0;
463
+ }
464
+ function canonicalHeaderName(headerName) {
465
+ return headerName.split("-").filter(Boolean).map((part) => part ? part[0].toUpperCase() + part.slice(1) : part).join("-");
466
+ }
394
467
  var expressParamsHistory = /* @__PURE__ */ new WeakMap();
395
468
  function trackExpressParams(req) {
396
469
  if (expressParamsHistory.has(req)) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/emitter.ts","../src/adapter.ts"],"sourcesContent":["import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';\nimport {\n createEmitter as createCoreEmitter,\n normalizeConfig,\n type XrayRuntimeConfig,\n} from '@stainlessdev/xray-core';\n\nexport function createEmitter(config: XrayRuntimeConfig) {\n const resolved = normalizeConfig(config);\n const exporter =\n config.exporter?.instance ??\n new OTLPTraceExporter({\n url: resolved.exporter.endpointUrl,\n headers: resolved.exporter.headers ?? {},\n timeoutMillis: resolved.exporter.timeoutMs,\n });\n\n return createCoreEmitter(config, exporter);\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport { TLSSocket } from 'node:tls';\nimport type {\n CaptureConfig,\n NormalizedRequest,\n NormalizedResponse,\n RedactionConfig,\n RequestLog,\n XrayContext,\n XrayEmitter,\n} from '@stainlessdev/xray-core';\nimport {\n LimitedBuffer,\n bindContextToObject,\n getXrayContextFromObject,\n headerValuesFromNodeHeaders,\n isWebsocketUpgrade,\n logWithLevel,\n makeCapturedBody,\n setCaptureOverride,\n setContextRequestId,\n setContextRoute,\n setRedactionOverride,\n} from '@stainlessdev/xray-core/internal';\n\nexport type NodeHttpHandler = (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;\n\nexport interface WrapOptions {\n route?: string;\n requestId?: string;\n capture?: Partial<CaptureConfig>;\n redaction?: Partial<RedactionConfig>;\n onRequest?: (ctx: XrayContext) => void;\n onResponse?: (ctx: XrayContext, log: RequestLog) => void;\n onError?: (ctx: XrayContext, err: unknown) => void;\n}\n\nexport function wrapHttpHandler(\n handler: NodeHttpHandler,\n xray: XrayEmitter,\n options?: WrapOptions,\n): NodeHttpHandler {\n return (req, res) => {\n const normalizedRequest: NormalizedRequest = {\n method: req.method ?? 'GET',\n url: fullUrl(req),\n route: options?.route,\n headers: headerValuesFromNodeHeaders(\n req.headers as Record<string, string | string[] | number | undefined>,\n ),\n requestId: resolveRequestId(options?.requestId, req, xray),\n remoteAddress: req.socket?.remoteAddress,\n startTimeMs: Date.now(),\n };\n\n trackExpressParams(req);\n\n const ctx = xray.startRequest(normalizedRequest);\n bindContextToObject(req, ctx);\n bindContextToObject(res, ctx);\n\n if (options?.requestId) {\n setContextRequestId(ctx, options.requestId);\n }\n if (options?.route) {\n setContextRoute(ctx, options.route);\n }\n if (options?.capture) {\n setCaptureOverride(ctx, options.capture);\n }\n if (options?.redaction) {\n setRedactionOverride(ctx, options.redaction);\n }\n\n if (options?.onRequest) {\n try {\n options.onRequest(ctx);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onRequest failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n const capture = options?.capture\n ? { ...xray.config.capture, ...options.capture }\n : xray.config.capture;\n\n const requestCapture =\n capture.requestBody === 'none' ? null : wrapRequestBody(req, capture.maxBodyBytes);\n const recorder = new ResponseRecorder(capture.responseBody !== 'none', capture.maxBodyBytes);\n recorder.wrap(res);\n\n let finished = false;\n let capturedError: unknown;\n let onErrorCalled = false;\n\n const finish = () => {\n if (finished) {\n return;\n }\n finished = true;\n if (!normalizedRequest.route) {\n const route = resolveExpressRoute(req);\n if (route) {\n normalizedRequest.route = route;\n }\n }\n\n if (requestCapture && requestCapture.read) {\n normalizedRequest.body = makeCapturedBody(\n requestCapture.buffer.bytes(),\n requestCapture.buffer.totalBytes(),\n requestCapture.buffer.truncated(),\n capture.requestBody === 'text' ? 'text' : 'base64',\n );\n }\n\n const responseHeaders = recorder.headersSnapshot(res.getHeaders());\n const recordedStatus = recorder.statusCode() ?? res.statusCode;\n const statusCode = capturedError && !recorder.hasWrittenHeader() ? 500 : recordedStatus;\n const isUpgrade = isWebsocketUpgrade(\n statusCode ?? 0,\n normalizedRequest.headers,\n responseHeaders,\n );\n\n const responseBody =\n recorder.bodyCaptured() && !isUpgrade\n ? makeCapturedBody(\n recorder.body(),\n recorder.totalBytes(),\n recorder.truncated(),\n capture.responseBody === 'text' ? 'text' : 'base64',\n )\n : undefined;\n\n const normalizedResponse: NormalizedResponse = {\n statusCode: statusCode ?? undefined,\n headers: responseHeaders,\n body: responseBody,\n endTimeMs: Date.now(),\n };\n\n const log = xray.endRequest(ctx, normalizedResponse, capturedError);\n\n if (capturedError && options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, capturedError);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (err) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n {\n error: err instanceof Error ? err.message : String(err),\n },\n );\n }\n }\n };\n\n res.once('finish', finish);\n res.once('close', finish);\n\n try {\n const result = handler(req, res);\n if (result && typeof (result as Promise<void>).catch === 'function') {\n void (result as Promise<void>).catch((err) => {\n capturedError = err;\n if (options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, err);\n } catch (errInner) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onError failed',\n {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n },\n );\n }\n }\n });\n }\n } catch (err) {\n capturedError = err;\n if (options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, err);\n } catch (errInner) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n });\n }\n }\n throw err;\n }\n };\n}\n\nexport function getXrayContext(req: IncomingMessage): XrayContext | undefined {\n return getXrayContextFromObject(req);\n}\n\ntype RequestCapture = {\n buffer: LimitedBuffer;\n read: boolean;\n userConsuming: boolean;\n};\n\nfunction wrapRequestBody(req: IncomingMessage, limit: number): RequestCapture | null {\n if (limit <= 0) {\n return null;\n }\n if (!hasRequestBody(req)) {\n return null;\n }\n\n const capture: RequestCapture = {\n buffer: new LimitedBuffer(limit),\n read: false,\n userConsuming: false,\n };\n\n const originalPush = req.push;\n req.push = function push(chunk: unknown, encoding?: BufferEncoding): boolean {\n if (chunk != null) {\n recordChunk(capture, chunk, encoding);\n }\n return originalPush.call(req, chunk as any, encoding as any);\n } as typeof req.push;\n\n const originalEmit = req.emit;\n req.emit = function emit(event: string, ...args: unknown[]): boolean {\n if (event === 'data' && capture.userConsuming && args[0] != null) {\n capture.read = true;\n }\n if (event === 'end' && capture.userConsuming) {\n capture.read = true;\n }\n return originalEmit.call(req, event, ...args);\n } as typeof req.emit;\n\n const originalOn = req.on;\n req.on = function on(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalOn.call(req, event, listener);\n } as typeof req.on;\n\n const originalOnce = req.once;\n req.once = function once(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalOnce.call(req, event, listener);\n } as typeof req.once;\n\n const originalAddListener = req.addListener;\n req.addListener = function addListener(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalAddListener.call(req, event, listener);\n } as typeof req.addListener;\n\n const originalPipe = req.pipe;\n req.pipe = function pipe(destination: unknown, options?: unknown): unknown {\n capture.userConsuming = true;\n return originalPipe.call(req, destination as any, options as any);\n } as typeof req.pipe;\n\n const originalRead = req.read;\n req.read = function read(size?: number): any {\n capture.userConsuming = true;\n const chunk = originalRead.call(req, size as any) as unknown;\n const readableFlowing = (req as IncomingMessage & { readableFlowing?: boolean | null })\n .readableFlowing;\n const hasDataListeners =\n typeof req.listenerCount === 'function' && req.listenerCount('data') > 0;\n if (!hasDataListeners && readableFlowing !== true && chunk != null) {\n capture.read = true;\n }\n return chunk as any;\n } as typeof req.read;\n\n return capture;\n}\n\nfunction hasRequestBody(req: IncomingMessage): boolean {\n if (req.headers['content-length'] != null) {\n return true;\n }\n if (req.headers['transfer-encoding'] != null) {\n return true;\n }\n return false;\n}\n\nfunction recordChunk(capture: RequestCapture, chunk: unknown, encoding?: BufferEncoding): void {\n const bytes = toBytes(chunk, encoding);\n if (!bytes) {\n return;\n }\n capture.buffer.write(bytes);\n}\n\nfunction toBytes(chunk: unknown, encoding?: BufferEncoding): Uint8Array | null {\n if (chunk == null) {\n return null;\n }\n if (typeof chunk === 'string') {\n return Buffer.from(chunk, encoding);\n }\n if (chunk instanceof Uint8Array) {\n return chunk;\n }\n if (chunk instanceof ArrayBuffer) {\n return new Uint8Array(chunk);\n }\n return null;\n}\n\nclass ResponseRecorder {\n private readonly buffer: LimitedBuffer | null;\n private headerSnapshot?: Record<string, string | string[] | number | undefined>;\n private status?: number;\n private wroteHeader = false;\n private bytes = 0;\n\n constructor(captureBody: boolean, maxBodySize: number) {\n this.buffer = captureBody ? new LimitedBuffer(maxBodySize) : null;\n }\n\n body(): Uint8Array {\n return this.buffer?.bytes() ?? new Uint8Array();\n }\n\n totalBytes(): number {\n return this.buffer?.totalBytes() ?? 0;\n }\n\n bodyCaptured(): boolean {\n return !!this.buffer && this.buffer.totalBytes() > 0;\n }\n\n bytesWritten(): number {\n return this.bytes;\n }\n\n hasWrittenHeader(): boolean {\n return this.wroteHeader;\n }\n\n headersSnapshot(\n defaultHeaders: Record<string, string | string[] | number | undefined>,\n ): Record<string, string | string[]> {\n if (this.headerSnapshot) {\n return headerValuesFromNodeHeaders(this.headerSnapshot);\n }\n return headerValuesFromNodeHeaders(defaultHeaders);\n }\n\n statusCode(): number | undefined {\n return this.status;\n }\n\n truncated(): boolean {\n return this.buffer?.truncated() ?? false;\n }\n\n wrap(res: ServerResponse): void {\n const originalWriteHead = res.writeHead;\n res.writeHead = ((statusCode: number, ...args: any[]) => {\n this.recordHeader(res, statusCode);\n return (originalWriteHead as any).call(res, statusCode, ...args);\n }) as typeof res.writeHead;\n\n const originalWrite = res.write;\n res.write = ((chunk: unknown, encoding?: BufferEncoding, cb?: (err?: Error | null) => void) => {\n this.recordHeader(res, res.statusCode ?? 200);\n this.recordWrite(chunk, encoding);\n return originalWrite.call(res, chunk as any, encoding as any, cb as any);\n }) as typeof res.write;\n\n const originalEnd = res.end;\n res.end = ((chunk?: unknown, encoding?: BufferEncoding, cb?: () => void) => {\n this.recordHeader(res, res.statusCode ?? 200);\n if (chunk) {\n this.recordWrite(chunk, encoding);\n }\n return originalEnd.call(res, chunk as any, encoding as any, cb as any);\n }) as typeof res.end;\n\n if (typeof res.flushHeaders === 'function') {\n const originalFlush = res.flushHeaders;\n res.flushHeaders = (() => {\n this.recordHeader(res, res.statusCode ?? 200);\n return originalFlush.call(res);\n }) as typeof res.flushHeaders;\n }\n }\n\n private recordHeader(res: ServerResponse, statusCode: number): void {\n if (this.wroteHeader) {\n return;\n }\n this.wroteHeader = true;\n this.status = statusCode;\n this.headerSnapshot = { ...res.getHeaders() } as Record<\n string,\n string | string[] | number | undefined\n >;\n }\n\n private recordWrite(chunk: unknown, encoding?: BufferEncoding): void {\n const bytes = toBytes(chunk, encoding);\n if (!bytes) {\n return;\n }\n this.bytes += bytes.length;\n if (this.buffer) {\n this.buffer.write(bytes);\n }\n }\n}\n\nfunction resolveRequestId(\n explicit: string | undefined,\n req: IncomingMessage,\n xray: XrayEmitter,\n): string | undefined {\n if (explicit) {\n return explicit;\n }\n const headerName = xray.config.requestId.header.toLowerCase();\n const value = req.headers[headerName];\n if (!value) {\n return undefined;\n }\n if (Array.isArray(value)) {\n return value[0]?.trim() || undefined;\n }\n return `${value}`.trim() || undefined;\n}\n\nfunction fullUrl(req: IncomingMessage): string {\n if (!req.url) {\n return '';\n }\n if (req.url.startsWith('http://') || req.url.startsWith('https://')) {\n return req.url;\n }\n\n const host = req.headers['host'];\n if (!host || typeof host !== 'string') {\n return req.url;\n }\n const scheme = req.socket instanceof TLSSocket ? 'https' : 'http';\n return `${scheme}://${host}${req.url}`;\n}\n\ntype ExpressRoutePath = string | string[] | RegExp;\n\ntype ExpressRouteParams = Record<string, string | string[]>;\n\nconst expressParamsHistory = new WeakMap<IncomingMessage, ExpressRouteParams[]>();\n\nfunction trackExpressParams(req: IncomingMessage): void {\n if (expressParamsHistory.has(req)) {\n return;\n }\n const anyReq = req as IncomingMessage & { app?: unknown };\n if (typeof anyReq.app !== 'function') {\n return;\n }\n\n const history: ExpressRouteParams[] = [];\n expressParamsHistory.set(req, history);\n\n const descriptor = Object.getOwnPropertyDescriptor(req, 'params');\n if (descriptor && !descriptor.configurable) {\n if (descriptor.value && typeof descriptor.value === 'object') {\n history.push({ ...(descriptor.value as ExpressRouteParams) });\n }\n return;\n }\n\n let current = (\n descriptor && 'value' in descriptor\n ? (descriptor.value as ExpressRouteParams | undefined)\n : undefined\n ) as ExpressRouteParams | undefined;\n if (current && typeof current === 'object') {\n history.push({ ...current });\n }\n\n Object.defineProperty(req, 'params', {\n configurable: true,\n enumerable: descriptor?.enumerable ?? true,\n get() {\n return current;\n },\n set(value) {\n current = value as ExpressRouteParams | undefined;\n if (value && typeof value === 'object') {\n history.push({ ...(value as ExpressRouteParams) });\n }\n },\n });\n}\n\nfunction resolveExpressRoute(req: IncomingMessage): string | undefined {\n const anyReq = req as IncomingMessage & {\n baseUrl?: string;\n params?: ExpressRouteParams;\n route?: { path?: ExpressRoutePath };\n };\n const routePath = extractExpressRoutePath(anyReq.route?.path);\n const baseUrl = anyReq.baseUrl ?? '';\n if (!routePath && !baseUrl) {\n return undefined;\n }\n\n const params = collectExpressParams(req, anyReq.params);\n const resolvedBaseUrl = replaceBaseUrlParams(baseUrl, params, routePath);\n return joinExpressRoute(resolvedBaseUrl, routePath);\n}\n\nfunction extractExpressRoutePath(path?: ExpressRoutePath): string | undefined {\n if (typeof path === 'string') {\n return path;\n }\n if (Array.isArray(path)) {\n for (const entry of path) {\n if (typeof entry === 'string') {\n return entry;\n }\n }\n }\n return undefined;\n}\n\nfunction collectExpressParams(\n req: IncomingMessage,\n fallback?: ExpressRouteParams,\n): ExpressRouteParams {\n const history = expressParamsHistory.get(req);\n if (!history || history.length === 0) {\n return fallback ?? {};\n }\n\n const merged: ExpressRouteParams = {};\n for (const snapshot of history) {\n for (const [key, value] of Object.entries(snapshot)) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n }\n if (fallback) {\n for (const [key, value] of Object.entries(fallback)) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n }\n return merged;\n}\n\nfunction replaceBaseUrlParams(\n baseUrl: string,\n params: ExpressRouteParams,\n routePath?: string,\n): string {\n if (!baseUrl) {\n return baseUrl;\n }\n const entries = Object.entries(params);\n if (entries.length === 0) {\n return baseUrl;\n }\n\n const excluded = new Set(routePath ? extractExpressParamNames(routePath) : []);\n const replacements = entries\n .filter(([name]) => !excluded.has(name))\n .map(([name, value]) => ({ name, value: Array.isArray(value) ? value[0] : value }))\n .filter((entry): entry is { name: string; value: string } => !!entry.value);\n\n if (replacements.length === 0) {\n return baseUrl;\n }\n\n const used = new Set<string>();\n const encodedCache = new Map<string, string>();\n const segments = baseUrl.split('/');\n const updated = segments.map((segment) => {\n if (!segment) {\n return segment;\n }\n for (const { name, value } of replacements) {\n if (used.has(name)) {\n continue;\n }\n const encodedValue = encodedCache.get(value) ?? encodeURIComponent(value);\n encodedCache.set(value, encodedValue);\n if (segment === value || segment === encodedValue) {\n used.add(name);\n return `:${name}`;\n }\n }\n return segment;\n });\n\n return updated.join('/');\n}\n\nfunction extractExpressParamNames(path: string): string[] {\n const names: string[] = [];\n const paramPattern = /:([A-Za-z0-9_]+)(?:\\([^)]*\\))?[?*+]?/g;\n for (const match of path.matchAll(paramPattern)) {\n const name = match[1];\n if (name) {\n names.push(name);\n }\n }\n return names;\n}\n\nfunction joinExpressRoute(baseUrl: string, routePath?: string): string {\n const base = baseUrl ? ensureLeadingSlash(baseUrl) : '';\n const route = routePath ? ensureLeadingSlash(routePath) : '';\n if (!base) {\n return route || '/';\n }\n if (!route || route === '/') {\n return base;\n }\n const trimmedBase = base.endsWith('/') ? base.slice(0, -1) : base;\n return `${trimmedBase}${route}`;\n}\n\nfunction ensureLeadingSlash(path: string): string {\n if (!path) {\n return '/';\n }\n return path.startsWith('/') ? path : `/${path}`;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/emitter.ts","../src/adapter.ts"],"sourcesContent":["import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';\nimport {\n createEmitter as createCoreEmitter,\n normalizeConfig,\n type XrayRuntimeConfig,\n} from '@stainlessdev/xray-core';\n\nexport function createEmitter(config: XrayRuntimeConfig) {\n const resolved = normalizeConfig(config);\n const exporter =\n config.exporter?.instance ??\n new OTLPTraceExporter({\n url: resolved.exporter.endpointUrl,\n headers: resolved.exporter.headers ?? {},\n timeoutMillis: resolved.exporter.timeoutMs,\n });\n\n return createCoreEmitter(config, exporter);\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport { TLSSocket } from 'node:tls';\nimport type {\n CaptureConfig,\n NormalizedRequest,\n NormalizedResponse,\n RedactionConfig,\n RequestLog,\n XrayContext,\n XrayEmitter,\n} from '@stainlessdev/xray-core';\nimport {\n LimitedBuffer,\n bindContextToObject,\n getXrayContextFromObject,\n headerValuesFromNodeHeaders,\n isWebsocketUpgrade,\n logWithLevel,\n makeCapturedBody,\n setCaptureOverride,\n setContextRequestId,\n setContextRoute,\n setRedactionOverride,\n generateRequestId,\n} from '@stainlessdev/xray-core/internal';\n\nexport type NodeHttpHandler = (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;\n\nexport interface WrapOptions {\n route?: string;\n requestId?: string;\n capture?: Partial<CaptureConfig>;\n redaction?: Partial<RedactionConfig>;\n onRequest?: (ctx: XrayContext) => void;\n onResponse?: (ctx: XrayContext, log: RequestLog) => void;\n onError?: (ctx: XrayContext, err: unknown) => void;\n}\n\nexport function wrapHttpHandler(\n handler: NodeHttpHandler,\n xray: XrayEmitter,\n options?: WrapOptions,\n): NodeHttpHandler {\n return (req, res) => {\n const normalizedRequest: NormalizedRequest = {\n method: req.method ?? 'GET',\n url: fullUrl(req),\n route: options?.route,\n headers: headerValuesFromNodeHeaders(\n req.headers as Record<string, string | string[] | number | undefined>,\n ),\n requestId: options?.requestId,\n remoteAddress: req.socket?.remoteAddress,\n startTimeMs: Date.now(),\n };\n\n trackExpressParams(req);\n\n const ctx = xray.startRequest(normalizedRequest);\n bindContextToObject(req, ctx);\n bindContextToObject(res, ctx);\n\n if (options?.requestId) {\n setContextRequestId(ctx, options.requestId);\n }\n if (options?.route) {\n setContextRoute(ctx, options.route);\n }\n if (options?.capture) {\n setCaptureOverride(ctx, options.capture);\n }\n if (options?.redaction) {\n setRedactionOverride(ctx, options.redaction);\n }\n\n if (options?.onRequest) {\n try {\n options.onRequest(ctx);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onRequest failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n const capture = options?.capture\n ? { ...xray.config.capture, ...options.capture }\n : xray.config.capture;\n\n const requestCapture =\n capture.requestBody === 'none' ? null : wrapRequestBody(req, capture.maxBodyBytes);\n const recorder = new ResponseRecorder(\n capture.responseBody !== 'none',\n capture.maxBodyBytes,\n (response) => {\n ensureResponseRequestId(response, ctx, xray);\n },\n );\n recorder.wrap(res);\n\n let finished = false;\n let capturedError: unknown;\n let onErrorCalled = false;\n\n const finish = () => {\n if (finished) {\n return;\n }\n finished = true;\n if (!normalizedRequest.route) {\n const route = resolveExpressRoute(req);\n if (route) {\n normalizedRequest.route = route;\n }\n }\n\n if (requestCapture && requestCapture.read) {\n normalizedRequest.body = makeCapturedBody(\n requestCapture.buffer.bytes(),\n requestCapture.buffer.totalBytes(),\n requestCapture.buffer.truncated(),\n capture.requestBody === 'text' ? 'text' : 'base64',\n );\n }\n\n const responseHeaders = recorder.headersSnapshot(res.getHeaders());\n const recordedStatus = recorder.statusCode() ?? res.statusCode;\n const statusCode = capturedError && !recorder.hasWrittenHeader() ? 500 : recordedStatus;\n const isUpgrade = isWebsocketUpgrade(\n statusCode ?? 0,\n normalizedRequest.headers,\n responseHeaders,\n );\n\n const responseBody =\n recorder.bodyCaptured() && !isUpgrade\n ? makeCapturedBody(\n recorder.body(),\n recorder.totalBytes(),\n recorder.truncated(),\n capture.responseBody === 'text' ? 'text' : 'base64',\n )\n : undefined;\n\n const normalizedResponse: NormalizedResponse = {\n statusCode: statusCode ?? undefined,\n headers: responseHeaders,\n body: responseBody,\n endTimeMs: Date.now(),\n };\n\n const log = xray.endRequest(ctx, normalizedResponse, capturedError);\n\n if (capturedError && options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, capturedError);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (err) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n {\n error: err instanceof Error ? err.message : String(err),\n },\n );\n }\n }\n };\n\n res.once('finish', finish);\n res.once('close', finish);\n\n try {\n const result = handler(req, res);\n if (result && typeof (result as Promise<void>).catch === 'function') {\n void (result as Promise<void>).catch((err) => {\n capturedError = err;\n if (options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, err);\n } catch (errInner) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onError failed',\n {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n },\n );\n }\n }\n });\n }\n } catch (err) {\n capturedError = err;\n if (options?.onError && !onErrorCalled) {\n onErrorCalled = true;\n try {\n options.onError(ctx, err);\n } catch (errInner) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n });\n }\n }\n throw err;\n }\n };\n}\n\nexport function getXrayContext(req: IncomingMessage): XrayContext | undefined {\n return getXrayContextFromObject(req);\n}\n\ntype RequestCapture = {\n buffer: LimitedBuffer;\n read: boolean;\n userConsuming: boolean;\n};\n\nfunction wrapRequestBody(req: IncomingMessage, limit: number): RequestCapture | null {\n if (limit <= 0) {\n return null;\n }\n if (!hasRequestBody(req)) {\n return null;\n }\n\n const capture: RequestCapture = {\n buffer: new LimitedBuffer(limit),\n read: false,\n userConsuming: false,\n };\n\n const originalPush = req.push;\n req.push = function push(chunk: unknown, encoding?: BufferEncoding): boolean {\n if (chunk != null) {\n recordChunk(capture, chunk, encoding);\n }\n return originalPush.call(req, chunk as any, encoding as any);\n } as typeof req.push;\n\n const originalEmit = req.emit;\n req.emit = function emit(event: string, ...args: unknown[]): boolean {\n if (event === 'data' && capture.userConsuming && args[0] != null) {\n capture.read = true;\n }\n if (event === 'end' && capture.userConsuming) {\n capture.read = true;\n }\n return originalEmit.call(req, event, ...args);\n } as typeof req.emit;\n\n const originalOn = req.on;\n req.on = function on(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalOn.call(req, event, listener);\n } as typeof req.on;\n\n const originalOnce = req.once;\n req.once = function once(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalOnce.call(req, event, listener);\n } as typeof req.once;\n\n const originalAddListener = req.addListener;\n req.addListener = function addListener(event: string, listener: (...args: any[]) => void): any {\n if (event === 'data' || event === 'readable') {\n capture.userConsuming = true;\n }\n return originalAddListener.call(req, event, listener);\n } as typeof req.addListener;\n\n const originalPipe = req.pipe;\n req.pipe = function pipe(destination: unknown, options?: unknown): unknown {\n capture.userConsuming = true;\n return originalPipe.call(req, destination as any, options as any);\n } as typeof req.pipe;\n\n const originalRead = req.read;\n req.read = function read(size?: number): any {\n capture.userConsuming = true;\n const chunk = originalRead.call(req, size as any) as unknown;\n const readableFlowing = (req as IncomingMessage & { readableFlowing?: boolean | null })\n .readableFlowing;\n const hasDataListeners =\n typeof req.listenerCount === 'function' && req.listenerCount('data') > 0;\n if (!hasDataListeners && readableFlowing !== true && chunk != null) {\n capture.read = true;\n }\n return chunk as any;\n } as typeof req.read;\n\n return capture;\n}\n\nfunction hasRequestBody(req: IncomingMessage): boolean {\n if (req.headers['content-length'] != null) {\n return true;\n }\n if (req.headers['transfer-encoding'] != null) {\n return true;\n }\n return false;\n}\n\nfunction recordChunk(capture: RequestCapture, chunk: unknown, encoding?: BufferEncoding): void {\n const bytes = toBytes(chunk, encoding);\n if (!bytes) {\n return;\n }\n capture.buffer.write(bytes);\n}\n\nfunction toBytes(chunk: unknown, encoding?: BufferEncoding): Uint8Array | null {\n if (chunk == null) {\n return null;\n }\n if (typeof chunk === 'string') {\n return Buffer.from(chunk, encoding);\n }\n if (chunk instanceof Uint8Array) {\n return chunk;\n }\n if (chunk instanceof ArrayBuffer) {\n return new Uint8Array(chunk);\n }\n return null;\n}\n\nclass ResponseRecorder {\n private readonly buffer: LimitedBuffer | null;\n private headerSnapshot?: Record<string, string | string[] | number | undefined>;\n private status?: number;\n private wroteHeader = false;\n private bytes = 0;\n private readonly onHeader?: (res: ServerResponse) => void;\n\n constructor(captureBody: boolean, maxBodySize: number, onHeader?: (res: ServerResponse) => void) {\n this.buffer = captureBody ? new LimitedBuffer(maxBodySize) : null;\n this.onHeader = onHeader;\n }\n\n body(): Uint8Array {\n return this.buffer?.bytes() ?? new Uint8Array();\n }\n\n totalBytes(): number {\n return this.buffer?.totalBytes() ?? 0;\n }\n\n bodyCaptured(): boolean {\n return !!this.buffer && this.buffer.totalBytes() > 0;\n }\n\n bytesWritten(): number {\n return this.bytes;\n }\n\n hasWrittenHeader(): boolean {\n return this.wroteHeader;\n }\n\n headersSnapshot(\n defaultHeaders: Record<string, string | string[] | number | undefined>,\n ): Record<string, string | string[]> {\n if (this.headerSnapshot) {\n return headerValuesFromNodeHeaders(this.headerSnapshot);\n }\n return headerValuesFromNodeHeaders(defaultHeaders);\n }\n\n statusCode(): number | undefined {\n return this.status;\n }\n\n truncated(): boolean {\n return this.buffer?.truncated() ?? false;\n }\n\n wrap(res: ServerResponse): void {\n const originalWriteHead = res.writeHead;\n res.writeHead = ((statusCode: number, ...args: any[]) => {\n if (!this.wroteHeader) {\n this.applyWriteHeadHeaders(res, args);\n }\n this.recordHeader(res, statusCode);\n return (originalWriteHead as any).call(res, statusCode, ...args);\n }) as typeof res.writeHead;\n\n const originalWrite = res.write;\n res.write = ((chunk: unknown, encoding?: BufferEncoding, cb?: (err?: Error | null) => void) => {\n this.recordHeader(res, res.statusCode ?? 200);\n this.recordWrite(chunk, encoding);\n return originalWrite.call(res, chunk as any, encoding as any, cb as any);\n }) as typeof res.write;\n\n const originalEnd = res.end;\n res.end = ((chunk?: unknown, encoding?: BufferEncoding, cb?: () => void) => {\n this.recordHeader(res, res.statusCode ?? 200);\n if (chunk) {\n this.recordWrite(chunk, encoding);\n }\n return originalEnd.call(res, chunk as any, encoding as any, cb as any);\n }) as typeof res.end;\n\n if (typeof res.flushHeaders === 'function') {\n const originalFlush = res.flushHeaders;\n res.flushHeaders = (() => {\n this.recordHeader(res, res.statusCode ?? 200);\n return originalFlush.call(res);\n }) as typeof res.flushHeaders;\n }\n }\n\n private recordHeader(res: ServerResponse, statusCode: number): void {\n if (this.wroteHeader) {\n return;\n }\n this.onHeader?.(res);\n this.wroteHeader = true;\n this.status = statusCode;\n this.headerSnapshot = { ...res.getHeaders() } as Record<\n string,\n string | string[] | number | undefined\n >;\n }\n\n private applyWriteHeadHeaders(res: ServerResponse, args: any[]): void {\n if (args.length === 0) {\n return;\n }\n const headersArg = typeof args[0] === 'string' ? args[1] : args[0];\n if (!headersArg) {\n return;\n }\n if (Array.isArray(headersArg)) {\n if (headersArg.length === 0) {\n return;\n }\n if (typeof headersArg[0] === 'string') {\n for (let i = 0; i < headersArg.length - 1; i += 2) {\n const name = headersArg[i];\n const value = headersArg[i + 1];\n if (typeof name === 'string' && value !== undefined && value !== null) {\n res.setHeader(name, value as any);\n }\n }\n return;\n }\n for (const entry of headersArg) {\n if (!Array.isArray(entry)) {\n continue;\n }\n const [name, value] = entry;\n if (typeof name === 'string' && value !== undefined && value !== null) {\n res.setHeader(name, value as any);\n }\n }\n return;\n }\n if (typeof headersArg === 'object') {\n for (const [name, value] of Object.entries(headersArg as Record<string, unknown>)) {\n if (value !== undefined && value !== null) {\n res.setHeader(name, value as any);\n }\n }\n }\n }\n\n private recordWrite(chunk: unknown, encoding?: BufferEncoding): void {\n const bytes = toBytes(chunk, encoding);\n if (!bytes) {\n return;\n }\n this.bytes += bytes.length;\n if (this.buffer) {\n this.buffer.write(bytes);\n }\n }\n}\n\nfunction ensureResponseRequestId(res: ServerResponse, ctx: XrayContext, xray: XrayEmitter): void {\n const headerName = xray.config.requestId.header;\n const existing = headerValueFromNode(res.getHeader(headerName));\n if (existing) {\n return;\n }\n\n const explicit = normalizeRequestIdCandidate(ctx.requestId);\n if (explicit) {\n res.setHeader(canonicalHeaderName(headerName), explicit);\n return;\n }\n\n const generated = generateRequestId();\n res.setHeader(canonicalHeaderName(headerName), generated);\n setContextRequestId(ctx, generated);\n}\n\nfunction fullUrl(req: IncomingMessage): string {\n if (!req.url) {\n return '';\n }\n if (req.url.startsWith('http://') || req.url.startsWith('https://')) {\n return req.url;\n }\n\n const host = req.headers['host'];\n if (!host || typeof host !== 'string') {\n return req.url;\n }\n const scheme = req.socket instanceof TLSSocket ? 'https' : 'http';\n return `${scheme}://${host}${req.url}`;\n}\n\nfunction headerValueFromNode(value: unknown): string | undefined {\n if (value == null) {\n return undefined;\n }\n if (Array.isArray(value)) {\n return normalizeRequestIdCandidate(value[0]);\n }\n return normalizeRequestIdCandidate(`${value}`);\n}\n\nfunction normalizeRequestIdCandidate(value: string | undefined): string | undefined {\n if (!value) {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction canonicalHeaderName(headerName: string): string {\n return headerName\n .split('-')\n .filter(Boolean)\n .map((part) => (part ? part[0]!.toUpperCase() + part.slice(1) : part))\n .join('-');\n}\n\ntype ExpressRoutePath = string | string[] | RegExp;\n\ntype ExpressRouteParams = Record<string, string | string[]>;\n\nconst expressParamsHistory = new WeakMap<IncomingMessage, ExpressRouteParams[]>();\n\nfunction trackExpressParams(req: IncomingMessage): void {\n if (expressParamsHistory.has(req)) {\n return;\n }\n const anyReq = req as IncomingMessage & { app?: unknown };\n if (typeof anyReq.app !== 'function') {\n return;\n }\n\n const history: ExpressRouteParams[] = [];\n expressParamsHistory.set(req, history);\n\n const descriptor = Object.getOwnPropertyDescriptor(req, 'params');\n if (descriptor && !descriptor.configurable) {\n if (descriptor.value && typeof descriptor.value === 'object') {\n history.push({ ...(descriptor.value as ExpressRouteParams) });\n }\n return;\n }\n\n let current = (\n descriptor && 'value' in descriptor\n ? (descriptor.value as ExpressRouteParams | undefined)\n : undefined\n ) as ExpressRouteParams | undefined;\n if (current && typeof current === 'object') {\n history.push({ ...current });\n }\n\n Object.defineProperty(req, 'params', {\n configurable: true,\n enumerable: descriptor?.enumerable ?? true,\n get() {\n return current;\n },\n set(value) {\n current = value as ExpressRouteParams | undefined;\n if (value && typeof value === 'object') {\n history.push({ ...(value as ExpressRouteParams) });\n }\n },\n });\n}\n\nfunction resolveExpressRoute(req: IncomingMessage): string | undefined {\n const anyReq = req as IncomingMessage & {\n baseUrl?: string;\n params?: ExpressRouteParams;\n route?: { path?: ExpressRoutePath };\n };\n const routePath = extractExpressRoutePath(anyReq.route?.path);\n const baseUrl = anyReq.baseUrl ?? '';\n if (!routePath && !baseUrl) {\n return undefined;\n }\n\n const params = collectExpressParams(req, anyReq.params);\n const resolvedBaseUrl = replaceBaseUrlParams(baseUrl, params, routePath);\n return joinExpressRoute(resolvedBaseUrl, routePath);\n}\n\nfunction extractExpressRoutePath(path?: ExpressRoutePath): string | undefined {\n if (typeof path === 'string') {\n return path;\n }\n if (Array.isArray(path)) {\n for (const entry of path) {\n if (typeof entry === 'string') {\n return entry;\n }\n }\n }\n return undefined;\n}\n\nfunction collectExpressParams(\n req: IncomingMessage,\n fallback?: ExpressRouteParams,\n): ExpressRouteParams {\n const history = expressParamsHistory.get(req);\n if (!history || history.length === 0) {\n return fallback ?? {};\n }\n\n const merged: ExpressRouteParams = {};\n for (const snapshot of history) {\n for (const [key, value] of Object.entries(snapshot)) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n }\n if (fallback) {\n for (const [key, value] of Object.entries(fallback)) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n }\n return merged;\n}\n\nfunction replaceBaseUrlParams(\n baseUrl: string,\n params: ExpressRouteParams,\n routePath?: string,\n): string {\n if (!baseUrl) {\n return baseUrl;\n }\n const entries = Object.entries(params);\n if (entries.length === 0) {\n return baseUrl;\n }\n\n const excluded = new Set(routePath ? extractExpressParamNames(routePath) : []);\n const replacements = entries\n .filter(([name]) => !excluded.has(name))\n .map(([name, value]) => ({ name, value: Array.isArray(value) ? value[0] : value }))\n .filter((entry): entry is { name: string; value: string } => !!entry.value);\n\n if (replacements.length === 0) {\n return baseUrl;\n }\n\n const used = new Set<string>();\n const encodedCache = new Map<string, string>();\n const segments = baseUrl.split('/');\n const updated = segments.map((segment) => {\n if (!segment) {\n return segment;\n }\n for (const { name, value } of replacements) {\n if (used.has(name)) {\n continue;\n }\n const encodedValue = encodedCache.get(value) ?? encodeURIComponent(value);\n encodedCache.set(value, encodedValue);\n if (segment === value || segment === encodedValue) {\n used.add(name);\n return `:${name}`;\n }\n }\n return segment;\n });\n\n return updated.join('/');\n}\n\nfunction extractExpressParamNames(path: string): string[] {\n const names: string[] = [];\n const paramPattern = /:([A-Za-z0-9_]+)(?:\\([^)]*\\))?[?*+]?/g;\n for (const match of path.matchAll(paramPattern)) {\n const name = match[1];\n if (name) {\n names.push(name);\n }\n }\n return names;\n}\n\nfunction joinExpressRoute(baseUrl: string, routePath?: string): string {\n const base = baseUrl ? ensureLeadingSlash(baseUrl) : '';\n const route = routePath ? ensureLeadingSlash(routePath) : '';\n if (!base) {\n return route || '/';\n }\n if (!route || route === '/') {\n return base;\n }\n const trimmedBase = base.endsWith('/') ? base.slice(0, -1) : base;\n return `${trimmedBase}${route}`;\n}\n\nfunction ensureLeadingSlash(path: string): string {\n if (!path) {\n return '/';\n }\n return path.startsWith('/') ? path : `/${path}`;\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stainlessdev/xray-node",
3
- "version": "0.6.0",
3
+ "version": "0.7.0-dev.588fa57",
4
4
  "description": "Node.js HTTP adapter for Stainless X-ray request logging",
5
5
  "files": [
6
6
  "dist"
@@ -20,7 +20,7 @@
20
20
  "access": "public"
21
21
  },
22
22
  "dependencies": {
23
- "@stainlessdev/xray-core": "0.6.0"
23
+ "@stainlessdev/xray-core": "0.7.0-dev.588fa57"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@opentelemetry/api": "^1.9.0",