@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 +77 -0
- package/dist/index.cjs +86 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +88 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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:
|
|
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(
|
|
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
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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
|
-
|
|
389
|
-
|
|
437
|
+
const explicit = normalizeRequestIdCandidate(ctx.requestId);
|
|
438
|
+
if (explicit) {
|
|
439
|
+
res.setHeader(canonicalHeaderName(headerName), explicit);
|
|
440
|
+
return;
|
|
390
441
|
}
|
|
391
|
-
|
|
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)) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,uCAAkC;AAClC,uBAIO;AAEA,SAAS,cAAc,QAA2B;AACvD,QAAM,eAAW,kCAAgB,MAAM;AACvC,QAAM,WACJ,OAAO,UAAU,YACjB,IAAI,mDAAkB;AAAA,IACpB,KAAK,SAAS,SAAS;AAAA,IACvB,SAAS,SAAS,SAAS,WAAW,CAAC;AAAA,IACvC,eAAe,SAAS,SAAS;AAAA,EACnC,CAAC;AAEH,aAAO,iBAAAA,eAAkB,QAAQ,QAAQ;AAC3C;;;ACjBA,sBAA0B;AAU1B,sBAYO;AAcA,SAAS,gBACd,SACA,MACA,SACiB;AACjB,SAAO,CAAC,KAAK,QAAQ;AACnB,UAAM,oBAAuC;AAAA,MAC3C,QAAQ,IAAI,UAAU;AAAA,MACtB,KAAK,QAAQ,GAAG;AAAA,MAChB,OAAO,SAAS;AAAA,MAChB,aAAS;AAAA,QACP,IAAI;AAAA,MACN;AAAA,MACA,WAAW,iBAAiB,SAAS,WAAW,KAAK,IAAI;AAAA,MACzD,eAAe,IAAI,QAAQ;AAAA,MAC3B,aAAa,KAAK,IAAI;AAAA,IACxB;AAEA,uBAAmB,GAAG;AAEtB,UAAM,MAAM,KAAK,aAAa,iBAAiB;AAC/C,6CAAoB,KAAK,GAAG;AAC5B,6CAAoB,KAAK,GAAG;AAE5B,QAAI,SAAS,WAAW;AACtB,+CAAoB,KAAK,QAAQ,SAAS;AAAA,IAC5C;AACA,QAAI,SAAS,OAAO;AAClB,2CAAgB,KAAK,QAAQ,KAAK;AAAA,IACpC;AACA,QAAI,SAAS,SAAS;AACpB,8CAAmB,KAAK,QAAQ,OAAO;AAAA,IACzC;AACA,QAAI,SAAS,WAAW;AACtB,gDAAqB,KAAK,QAAQ,SAAS;AAAA,IAC7C;AAEA,QAAI,SAAS,WAAW;AACtB,UAAI;AACF,gBAAQ,UAAU,GAAG;AAAA,MACvB,SAAS,KAAK;AACZ,0CAAa,KAAK,OAAO,QAAQ,QAAQ,KAAK,OAAO,UAAU,0BAA0B;AAAA,UACvF,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACxD,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,UAAU,SAAS,UACrB,EAAE,GAAG,KAAK,OAAO,SAAS,GAAG,QAAQ,QAAQ,IAC7C,KAAK,OAAO;AAEhB,UAAM,iBACJ,QAAQ,gBAAgB,SAAS,OAAO,gBAAgB,KAAK,QAAQ,YAAY;AACnF,UAAM,WAAW,IAAI,iBAAiB,QAAQ,iBAAiB,QAAQ,QAAQ,YAAY;AAC3F,aAAS,KAAK,GAAG;AAEjB,QAAI,WAAW;AACf,QAAI;AACJ,QAAI,gBAAgB;AAEpB,UAAM,SAAS,MAAM;AACnB,UAAI,UAAU;AACZ;AAAA,MACF;AACA,iBAAW;AACX,UAAI,CAAC,kBAAkB,OAAO;AAC5B,cAAM,QAAQ,oBAAoB,GAAG;AACrC,YAAI,OAAO;AACT,4BAAkB,QAAQ;AAAA,QAC5B;AAAA,MACF;AAEA,UAAI,kBAAkB,eAAe,MAAM;AACzC,0BAAkB,WAAO;AAAA,UACvB,eAAe,OAAO,MAAM;AAAA,UAC5B,eAAe,OAAO,WAAW;AAAA,UACjC,eAAe,OAAO,UAAU;AAAA,UAChC,QAAQ,gBAAgB,SAAS,SAAS;AAAA,QAC5C;AAAA,MACF;AAEA,YAAM,kBAAkB,SAAS,gBAAgB,IAAI,WAAW,CAAC;AACjE,YAAM,iBAAiB,SAAS,WAAW,KAAK,IAAI;AACpD,YAAM,aAAa,iBAAiB,CAAC,SAAS,iBAAiB,IAAI,MAAM;AACzE,YAAM,gBAAY;AAAA,QAChB,cAAc;AAAA,QACd,kBAAkB;AAAA,QAClB;AAAA,MACF;AAEA,YAAM,eACJ,SAAS,aAAa,KAAK,CAAC,gBACxB;AAAA,QACE,SAAS,KAAK;AAAA,QACd,SAAS,WAAW;AAAA,QACpB,SAAS,UAAU;AAAA,QACnB,QAAQ,iBAAiB,SAAS,SAAS;AAAA,MAC7C,IACA;AAEN,YAAM,qBAAyC;AAAA,QAC7C,YAAY,cAAc;AAAA,QAC1B,SAAS;AAAA,QACT,MAAM;AAAA,QACN,WAAW,KAAK,IAAI;AAAA,MACtB;AAEA,YAAM,MAAM,KAAK,WAAW,KAAK,oBAAoB,aAAa;AAElE,UAAI,iBAAiB,SAAS,WAAW,CAAC,eAAe;AACvD,wBAAgB;AAChB,YAAI;AACF,kBAAQ,QAAQ,KAAK,aAAa;AAAA,QACpC,SAAS,KAAK;AACZ,4CAAa,KAAK,OAAO,QAAQ,QAAQ,KAAK,OAAO,UAAU,wBAAwB;AAAA,YACrF,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,UACxD,CAAC;AAAA,QACH;AAAA,MACF;AAEA,UAAI,SAAS,YAAY;AACvB,YAAI;AACF,kBAAQ,WAAW,KAAK,GAAG;AAAA,QAC7B,SAAS,KAAK;AACZ;AAAA,YACE,KAAK,OAAO;AAAA,YACZ;AAAA,YACA,KAAK,OAAO;AAAA,YACZ;AAAA,YACA;AAAA,cACE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,YACxD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,UAAU,MAAM;AACzB,QAAI,KAAK,SAAS,MAAM;AAExB,QAAI;AACF,YAAM,SAAS,QAAQ,KAAK,GAAG;AAC/B,UAAI,UAAU,OAAQ,OAAyB,UAAU,YAAY;AACnE,aAAM,OAAyB,MAAM,CAAC,QAAQ;AAC5C,0BAAgB;AAChB,cAAI,SAAS,WAAW,CAAC,eAAe;AACtC,4BAAgB;AAChB,gBAAI;AACF,sBAAQ,QAAQ,KAAK,GAAG;AAAA,YAC1B,SAAS,UAAU;AACjB;AAAA,gBACE,KAAK,OAAO;AAAA,gBACZ;AAAA,gBACA,KAAK,OAAO;AAAA,gBACZ;AAAA,gBACA;AAAA,kBACE,OAAO,oBAAoB,QAAQ,SAAS,UAAU,OAAO,QAAQ;AAAA,gBACvE;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,SAAS,KAAK;AACZ,sBAAgB;AAChB,UAAI,SAAS,WAAW,CAAC,eAAe;AACtC,wBAAgB;AAChB,YAAI;AACF,kBAAQ,QAAQ,KAAK,GAAG;AAAA,QAC1B,SAAS,UAAU;AACjB,4CAAa,KAAK,OAAO,QAAQ,QAAQ,KAAK,OAAO,UAAU,wBAAwB;AAAA,YACrF,OAAO,oBAAoB,QAAQ,SAAS,UAAU,OAAO,QAAQ;AAAA,UACvE,CAAC;AAAA,QACH;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEO,SAAS,eAAe,KAA+C;AAC5E,aAAO,0CAAyB,GAAG;AACrC;AAQA,SAAS,gBAAgB,KAAsB,OAAsC;AACnF,MAAI,SAAS,GAAG;AACd,WAAO;AAAA,EACT;AACA,MAAI,CAAC,eAAe,GAAG,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,QAAM,UAA0B;AAAA,IAC9B,QAAQ,IAAI,8BAAc,KAAK;AAAA,IAC/B,MAAM;AAAA,IACN,eAAe;AAAA,EACjB;AAEA,QAAM,eAAe,IAAI;AACzB,MAAI,OAAO,SAAS,KAAK,OAAgB,UAAoC;AAC3E,QAAI,SAAS,MAAM;AACjB,kBAAY,SAAS,OAAO,QAAQ;AAAA,IACtC;AACA,WAAO,aAAa,KAAK,KAAK,OAAc,QAAe;AAAA,EAC7D;AAEA,QAAM,eAAe,IAAI;AACzB,MAAI,OAAO,SAAS,KAAK,UAAkB,MAA0B;AACnE,QAAI,UAAU,UAAU,QAAQ,iBAAiB,KAAK,CAAC,KAAK,MAAM;AAChE,cAAQ,OAAO;AAAA,IACjB;AACA,QAAI,UAAU,SAAS,QAAQ,eAAe;AAC5C,cAAQ,OAAO;AAAA,IACjB;AACA,WAAO,aAAa,KAAK,KAAK,OAAO,GAAG,IAAI;AAAA,EAC9C;AAEA,QAAM,aAAa,IAAI;AACvB,MAAI,KAAK,SAAS,GAAG,OAAe,UAAyC;AAC3E,QAAI,UAAU,UAAU,UAAU,YAAY;AAC5C,cAAQ,gBAAgB;AAAA,IAC1B;AACA,WAAO,WAAW,KAAK,KAAK,OAAO,QAAQ;AAAA,EAC7C;AAEA,QAAM,eAAe,IAAI;AACzB,MAAI,OAAO,SAAS,KAAK,OAAe,UAAyC;AAC/E,QAAI,UAAU,UAAU,UAAU,YAAY;AAC5C,cAAQ,gBAAgB;AAAA,IAC1B;AACA,WAAO,aAAa,KAAK,KAAK,OAAO,QAAQ;AAAA,EAC/C;AAEA,QAAM,sBAAsB,IAAI;AAChC,MAAI,cAAc,SAAS,YAAY,OAAe,UAAyC;AAC7F,QAAI,UAAU,UAAU,UAAU,YAAY;AAC5C,cAAQ,gBAAgB;AAAA,IAC1B;AACA,WAAO,oBAAoB,KAAK,KAAK,OAAO,QAAQ;AAAA,EACtD;AAEA,QAAM,eAAe,IAAI;AACzB,MAAI,OAAO,SAAS,KAAK,aAAsB,SAA4B;AACzE,YAAQ,gBAAgB;AACxB,WAAO,aAAa,KAAK,KAAK,aAAoB,OAAc;AAAA,EAClE;AAEA,QAAM,eAAe,IAAI;AACzB,MAAI,OAAO,SAAS,KAAK,MAAoB;AAC3C,YAAQ,gBAAgB;AACxB,UAAM,QAAQ,aAAa,KAAK,KAAK,IAAW;AAChD,UAAM,kBAAmB,IACtB;AACH,UAAM,mBACJ,OAAO,IAAI,kBAAkB,cAAc,IAAI,cAAc,MAAM,IAAI;AACzE,QAAI,CAAC,oBAAoB,oBAAoB,QAAQ,SAAS,MAAM;AAClE,cAAQ,OAAO;AAAA,IACjB;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,KAA+B;AACrD,MAAI,IAAI,QAAQ,gBAAgB,KAAK,MAAM;AACzC,WAAO;AAAA,EACT;AACA,MAAI,IAAI,QAAQ,mBAAmB,KAAK,MAAM;AAC5C,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,YAAY,SAAyB,OAAgB,UAAiC;AAC7F,QAAM,QAAQ,QAAQ,OAAO,QAAQ;AACrC,MAAI,CAAC,OAAO;AACV;AAAA,EACF;AACA,UAAQ,OAAO,MAAM,KAAK;AAC5B;AAEA,SAAS,QAAQ,OAAgB,UAA8C;AAC7E,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,OAAO,KAAK,OAAO,QAAQ;AAAA,EACpC;AACA,MAAI,iBAAiB,YAAY;AAC/B,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,aAAa;AAChC,WAAO,IAAI,WAAW,KAAK;AAAA,EAC7B;AACA,SAAO;AACT;AAEA,IAAM,mBAAN,MAAuB;AAAA,EAOrB,YAAY,aAAsB,aAAqB;AAHvD,SAAQ,cAAc;AACtB,SAAQ,QAAQ;AAGd,SAAK,SAAS,cAAc,IAAI,8BAAc,WAAW,IAAI;AAAA,EAC/D;AAAA,EAEA,OAAmB;AACjB,WAAO,KAAK,QAAQ,MAAM,KAAK,IAAI,WAAW;AAAA,EAChD;AAAA,EAEA,aAAqB;AACnB,WAAO,KAAK,QAAQ,WAAW,KAAK;AAAA,EACtC;AAAA,EAEA,eAAwB;AACtB,WAAO,CAAC,CAAC,KAAK,UAAU,KAAK,OAAO,WAAW,IAAI;AAAA,EACrD;AAAA,EAEA,eAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,mBAA4B;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,gBACE,gBACmC;AACnC,QAAI,KAAK,gBAAgB;AACvB,iBAAO,6CAA4B,KAAK,cAAc;AAAA,IACxD;AACA,eAAO,6CAA4B,cAAc;AAAA,EACnD;AAAA,EAEA,aAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK,QAAQ,UAAU,KAAK;AAAA,EACrC;AAAA,EAEA,KAAK,KAA2B;AAC9B,UAAM,oBAAoB,IAAI;AAC9B,QAAI,aAAa,CAAC,eAAuB,SAAgB;AACvD,WAAK,aAAa,KAAK,UAAU;AACjC,aAAQ,kBAA0B,KAAK,KAAK,YAAY,GAAG,IAAI;AAAA,IACjE;AAEA,UAAM,gBAAgB,IAAI;AAC1B,QAAI,SAAS,CAAC,OAAgB,UAA2B,OAAsC;AAC7F,WAAK,aAAa,KAAK,IAAI,cAAc,GAAG;AAC5C,WAAK,YAAY,OAAO,QAAQ;AAChC,aAAO,cAAc,KAAK,KAAK,OAAc,UAAiB,EAAS;AAAA,IACzE;AAEA,UAAM,cAAc,IAAI;AACxB,QAAI,OAAO,CAAC,OAAiB,UAA2B,OAAoB;AAC1E,WAAK,aAAa,KAAK,IAAI,cAAc,GAAG;AAC5C,UAAI,OAAO;AACT,aAAK,YAAY,OAAO,QAAQ;AAAA,MAClC;AACA,aAAO,YAAY,KAAK,KAAK,OAAc,UAAiB,EAAS;AAAA,IACvE;AAEA,QAAI,OAAO,IAAI,iBAAiB,YAAY;AAC1C,YAAM,gBAAgB,IAAI;AAC1B,UAAI,gBAAgB,MAAM;AACxB,aAAK,aAAa,KAAK,IAAI,cAAc,GAAG;AAC5C,eAAO,cAAc,KAAK,GAAG;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,aAAa,KAAqB,YAA0B;AAClE,QAAI,KAAK,aAAa;AACpB;AAAA,IACF;AACA,SAAK,cAAc;AACnB,SAAK,SAAS;AACd,SAAK,iBAAiB,EAAE,GAAG,IAAI,WAAW,EAAE;AAAA,EAI9C;AAAA,EAEQ,YAAY,OAAgB,UAAiC;AACnE,UAAM,QAAQ,QAAQ,OAAO,QAAQ;AACrC,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AACA,SAAK,SAAS,MAAM;AACpB,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,MAAM,KAAK;AAAA,IACzB;AAAA,EACF;AACF;AAEA,SAAS,iBACP,UACA,KACA,MACoB;AACpB,MAAI,UAAU;AACZ,WAAO;AAAA,EACT;AACA,QAAM,aAAa,KAAK,OAAO,UAAU,OAAO,YAAY;AAC5D,QAAM,QAAQ,IAAI,QAAQ,UAAU;AACpC,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,CAAC,GAAG,KAAK,KAAK;AAAA,EAC7B;AACA,SAAO,GAAG,KAAK,GAAG,KAAK,KAAK;AAC9B;AAEA,SAAS,QAAQ,KAA8B;AAC7C,MAAI,CAAC,IAAI,KAAK;AACZ,WAAO;AAAA,EACT;AACA,MAAI,IAAI,IAAI,WAAW,SAAS,KAAK,IAAI,IAAI,WAAW,UAAU,GAAG;AACnE,WAAO,IAAI;AAAA,EACb;AAEA,QAAM,OAAO,IAAI,QAAQ,MAAM;AAC/B,MAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,WAAO,IAAI;AAAA,EACb;AACA,QAAM,SAAS,IAAI,kBAAkB,4BAAY,UAAU;AAC3D,SAAO,GAAG,MAAM,MAAM,IAAI,GAAG,IAAI,GAAG;AACtC;AAMA,IAAM,uBAAuB,oBAAI,QAA+C;AAEhF,SAAS,mBAAmB,KAA4B;AACtD,MAAI,qBAAqB,IAAI,GAAG,GAAG;AACjC;AAAA,EACF;AACA,QAAM,SAAS;AACf,MAAI,OAAO,OAAO,QAAQ,YAAY;AACpC;AAAA,EACF;AAEA,QAAM,UAAgC,CAAC;AACvC,uBAAqB,IAAI,KAAK,OAAO;AAErC,QAAM,aAAa,OAAO,yBAAyB,KAAK,QAAQ;AAChE,MAAI,cAAc,CAAC,WAAW,cAAc;AAC1C,QAAI,WAAW,SAAS,OAAO,WAAW,UAAU,UAAU;AAC5D,cAAQ,KAAK,EAAE,GAAI,WAAW,MAA6B,CAAC;AAAA,IAC9D;AACA;AAAA,EACF;AAEA,MAAI,UACF,cAAc,WAAW,aACpB,WAAW,QACZ;AAEN,MAAI,WAAW,OAAO,YAAY,UAAU;AAC1C,YAAQ,KAAK,EAAE,GAAG,QAAQ,CAAC;AAAA,EAC7B;AAEA,SAAO,eAAe,KAAK,UAAU;AAAA,IACnC,cAAc;AAAA,IACd,YAAY,YAAY,cAAc;AAAA,IACtC,MAAM;AACJ,aAAO;AAAA,IACT;AAAA,IACA,IAAI,OAAO;AACT,gBAAU;AACV,UAAI,SAAS,OAAO,UAAU,UAAU;AACtC,gBAAQ,KAAK,EAAE,GAAI,MAA6B,CAAC;AAAA,MACnD;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,oBAAoB,KAA0C;AACrE,QAAM,SAAS;AAKf,QAAM,YAAY,wBAAwB,OAAO,OAAO,IAAI;AAC5D,QAAM,UAAU,OAAO,WAAW;AAClC,MAAI,CAAC,aAAa,CAAC,SAAS;AAC1B,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,qBAAqB,KAAK,OAAO,MAAM;AACtD,QAAM,kBAAkB,qBAAqB,SAAS,QAAQ,SAAS;AACvE,SAAO,iBAAiB,iBAAiB,SAAS;AACpD;AAEA,SAAS,wBAAwB,MAA6C;AAC5E,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,eAAW,SAAS,MAAM;AACxB,UAAI,OAAO,UAAU,UAAU;AAC7B,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,qBACP,KACA,UACoB;AACpB,QAAM,UAAU,qBAAqB,IAAI,GAAG;AAC5C,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,WAAO,YAAY,CAAC;AAAA,EACtB;AAEA,QAAM,SAA6B,CAAC;AACpC,aAAW,YAAY,SAAS;AAC9B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAI,EAAE,OAAO,SAAS;AACpB,eAAO,GAAG,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACA,MAAI,UAAU;AACZ,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAI,EAAE,OAAO,SAAS;AACpB,eAAO,GAAG,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,qBACP,SACA,QACA,WACQ;AACR,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,QAAM,UAAU,OAAO,QAAQ,MAAM;AACrC,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,IAAI,IAAI,YAAY,yBAAyB,SAAS,IAAI,CAAC,CAAC;AAC7E,QAAM,eAAe,QAClB,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,EACtC,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,EAAE,MAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,CAAC,IAAI,MAAM,EAAE,EACjF,OAAO,CAAC,UAAoD,CAAC,CAAC,MAAM,KAAK;AAE5E,MAAI,aAAa,WAAW,GAAG;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,eAAe,oBAAI,IAAoB;AAC7C,QAAM,WAAW,QAAQ,MAAM,GAAG;AAClC,QAAM,UAAU,SAAS,IAAI,CAAC,YAAY;AACxC,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AACA,eAAW,EAAE,MAAM,MAAM,KAAK,cAAc;AAC1C,UAAI,KAAK,IAAI,IAAI,GAAG;AAClB;AAAA,MACF;AACA,YAAM,eAAe,aAAa,IAAI,KAAK,KAAK,mBAAmB,KAAK;AACxE,mBAAa,IAAI,OAAO,YAAY;AACpC,UAAI,YAAY,SAAS,YAAY,cAAc;AACjD,aAAK,IAAI,IAAI;AACb,eAAO,IAAI,IAAI;AAAA,MACjB;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,QAAQ,KAAK,GAAG;AACzB;AAEA,SAAS,yBAAyB,MAAwB;AACxD,QAAM,QAAkB,CAAC;AACzB,QAAM,eAAe;AACrB,aAAW,SAAS,KAAK,SAAS,YAAY,GAAG;AAC/C,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,MAAM;AACR,YAAM,KAAK,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,SAAiB,WAA4B;AACrE,QAAM,OAAO,UAAU,mBAAmB,OAAO,IAAI;AACrD,QAAM,QAAQ,YAAY,mBAAmB,SAAS,IAAI;AAC1D,MAAI,CAAC,MAAM;AACT,WAAO,SAAS;AAAA,EAClB;AACA,MAAI,CAAC,SAAS,UAAU,KAAK;AAC3B,WAAO;AAAA,EACT;AACA,QAAM,cAAc,KAAK,SAAS,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI;AAC7D,SAAO,GAAG,WAAW,GAAG,KAAK;AAC/B;AAEA,SAAS,mBAAmB,MAAsB;AAChD,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,SAAO,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AAC/C;","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:
|
|
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(
|
|
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
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
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
|
-
|
|
376
|
-
|
|
425
|
+
const explicit = normalizeRequestIdCandidate(ctx.requestId);
|
|
426
|
+
if (explicit) {
|
|
427
|
+
res.setHeader(canonicalHeaderName(headerName), explicit);
|
|
428
|
+
return;
|
|
377
429
|
}
|
|
378
|
-
|
|
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":";AAAA,SAAS,yBAAyB;AAClC;AAAA,EACE,iBAAiB;AAAA,EACjB;AAAA,OAEK;AAEA,SAAS,cAAc,QAA2B;AACvD,QAAM,WAAW,gBAAgB,MAAM;AACvC,QAAM,WACJ,OAAO,UAAU,YACjB,IAAI,kBAAkB;AAAA,IACpB,KAAK,SAAS,SAAS;AAAA,IACvB,SAAS,SAAS,SAAS,WAAW,CAAC;AAAA,IACvC,eAAe,SAAS,SAAS;AAAA,EACnC,CAAC;AAEH,SAAO,kBAAkB,QAAQ,QAAQ;AAC3C;;;ACjBA,SAAS,iBAAiB;AAU1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAcA,SAAS,gBACd,SACA,MACA,SACiB;AACjB,SAAO,CAAC,KAAK,QAAQ;AACnB,UAAM,oBAAuC;AAAA,MAC3C,QAAQ,IAAI,UAAU;AAAA,MACtB,KAAK,QAAQ,GAAG;AAAA,MAChB,OAAO,SAAS;AAAA,MAChB,SAAS;AAAA,QACP,IAAI;AAAA,MACN;AAAA,MACA,WAAW,SAAS;AAAA,MACpB,eAAe,IAAI,QAAQ;AAAA,MAC3B,aAAa,KAAK,IAAI;AAAA,IACxB;AAEA,uBAAmB,GAAG;AAEtB,UAAM,MAAM,KAAK,aAAa,iBAAiB;AAC/C,wBAAoB,KAAK,GAAG;AAC5B,wBAAoB,KAAK,GAAG;AAE5B,QAAI,SAAS,WAAW;AACtB,0BAAoB,KAAK,QAAQ,SAAS;AAAA,IAC5C;AACA,QAAI,SAAS,OAAO;AAClB,sBAAgB,KAAK,QAAQ,KAAK;AAAA,IACpC;AACA,QAAI,SAAS,SAAS;AACpB,yBAAmB,KAAK,QAAQ,OAAO;AAAA,IACzC;AACA,QAAI,SAAS,WAAW;AACtB,2BAAqB,KAAK,QAAQ,SAAS;AAAA,IAC7C;AAEA,QAAI,SAAS,WAAW;AACtB,UAAI;AACF,gBAAQ,UAAU,GAAG;AAAA,MACvB,SAAS,KAAK;AACZ,qBAAa,KAAK,OAAO,QAAQ,QAAQ,KAAK,OAAO,UAAU,0BAA0B;AAAA,UACvF,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACxD,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,UAAU,SAAS,UACrB,EAAE,GAAG,KAAK,OAAO,SAAS,GAAG,QAAQ,QAAQ,IAC7C,KAAK,OAAO;AAEhB,UAAM,iBACJ,QAAQ,gBAAgB,SAAS,OAAO,gBAAgB,KAAK,QAAQ,YAAY;AACnF,UAAM,WAAW,IAAI;AAAA,MACnB,QAAQ,iBAAiB;AAAA,MACzB,QAAQ;AAAA,MACR,CAAC,aAAa;AACZ,gCAAwB,UAAU,KAAK,IAAI;AAAA,MAC7C;AAAA,IACF;AACA,aAAS,KAAK,GAAG;AAEjB,QAAI,WAAW;AACf,QAAI;AACJ,QAAI,gBAAgB;AAEpB,UAAM,SAAS,MAAM;AACnB,UAAI,UAAU;AACZ;AAAA,MACF;AACA,iBAAW;AACX,UAAI,CAAC,kBAAkB,OAAO;AAC5B,cAAM,QAAQ,oBAAoB,GAAG;AACrC,YAAI,OAAO;AACT,4BAAkB,QAAQ;AAAA,QAC5B;AAAA,MACF;AAEA,UAAI,kBAAkB,eAAe,MAAM;AACzC,0BAAkB,OAAO;AAAA,UACvB,eAAe,OAAO,MAAM;AAAA,UAC5B,eAAe,OAAO,WAAW;AAAA,UACjC,eAAe,OAAO,UAAU;AAAA,UAChC,QAAQ,gBAAgB,SAAS,SAAS;AAAA,QAC5C;AAAA,MACF;AAEA,YAAM,kBAAkB,SAAS,gBAAgB,IAAI,WAAW,CAAC;AACjE,YAAM,iBAAiB,SAAS,WAAW,KAAK,IAAI;AACpD,YAAM,aAAa,iBAAiB,CAAC,SAAS,iBAAiB,IAAI,MAAM;AACzE,YAAM,YAAY;AAAA,QAChB,cAAc;AAAA,QACd,kBAAkB;AAAA,QAClB;AAAA,MACF;AAEA,YAAM,eACJ,SAAS,aAAa,KAAK,CAAC,YACxB;AAAA,QACE,SAAS,KAAK;AAAA,QACd,SAAS,WAAW;AAAA,QACpB,SAAS,UAAU;AAAA,QACnB,QAAQ,iBAAiB,SAAS,SAAS;AAAA,MAC7C,IACA;AAEN,YAAM,qBAAyC;AAAA,QAC7C,YAAY,cAAc;AAAA,QAC1B,SAAS;AAAA,QACT,MAAM;AAAA,QACN,WAAW,KAAK,IAAI;AAAA,MACtB;AAEA,YAAM,MAAM,KAAK,WAAW,KAAK,oBAAoB,aAAa;AAElE,UAAI,iBAAiB,SAAS,WAAW,CAAC,eAAe;AACvD,wBAAgB;AAChB,YAAI;AACF,kBAAQ,QAAQ,KAAK,aAAa;AAAA,QACpC,SAAS,KAAK;AACZ,uBAAa,KAAK,OAAO,QAAQ,QAAQ,KAAK,OAAO,UAAU,wBAAwB;AAAA,YACrF,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,UACxD,CAAC;AAAA,QACH;AAAA,MACF;AAEA,UAAI,SAAS,YAAY;AACvB,YAAI;AACF,kBAAQ,WAAW,KAAK,GAAG;AAAA,QAC7B,SAAS,KAAK;AACZ;AAAA,YACE,KAAK,OAAO;AAAA,YACZ;AAAA,YACA,KAAK,OAAO;AAAA,YACZ;AAAA,YACA;AAAA,cACE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,YACxD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,UAAU,MAAM;AACzB,QAAI,KAAK,SAAS,MAAM;AAExB,QAAI;AACF,YAAM,SAAS,QAAQ,KAAK,GAAG;AAC/B,UAAI,UAAU,OAAQ,OAAyB,UAAU,YAAY;AACnE,aAAM,OAAyB,MAAM,CAAC,QAAQ;AAC5C,0BAAgB;AAChB,cAAI,SAAS,WAAW,CAAC,eAAe;AACtC,4BAAgB;AAChB,gBAAI;AACF,sBAAQ,QAAQ,KAAK,GAAG;AAAA,YAC1B,SAAS,UAAU;AACjB;AAAA,gBACE,KAAK,OAAO;AAAA,gBACZ;AAAA,gBACA,KAAK,OAAO;AAAA,gBACZ;AAAA,gBACA;AAAA,kBACE,OAAO,oBAAoB,QAAQ,SAAS,UAAU,OAAO,QAAQ;AAAA,gBACvE;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,SAAS,KAAK;AACZ,sBAAgB;AAChB,UAAI,SAAS,WAAW,CAAC,eAAe;AACtC,wBAAgB;AAChB,YAAI;AACF,kBAAQ,QAAQ,KAAK,GAAG;AAAA,QAC1B,SAAS,UAAU;AACjB,uBAAa,KAAK,OAAO,QAAQ,QAAQ,KAAK,OAAO,UAAU,wBAAwB;AAAA,YACrF,OAAO,oBAAoB,QAAQ,SAAS,UAAU,OAAO,QAAQ;AAAA,UACvE,CAAC;AAAA,QACH;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEO,SAAS,eAAe,KAA+C;AAC5E,SAAO,yBAAyB,GAAG;AACrC;AAQA,SAAS,gBAAgB,KAAsB,OAAsC;AACnF,MAAI,SAAS,GAAG;AACd,WAAO;AAAA,EACT;AACA,MAAI,CAAC,eAAe,GAAG,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,QAAM,UAA0B;AAAA,IAC9B,QAAQ,IAAI,cAAc,KAAK;AAAA,IAC/B,MAAM;AAAA,IACN,eAAe;AAAA,EACjB;AAEA,QAAM,eAAe,IAAI;AACzB,MAAI,OAAO,SAAS,KAAK,OAAgB,UAAoC;AAC3E,QAAI,SAAS,MAAM;AACjB,kBAAY,SAAS,OAAO,QAAQ;AAAA,IACtC;AACA,WAAO,aAAa,KAAK,KAAK,OAAc,QAAe;AAAA,EAC7D;AAEA,QAAM,eAAe,IAAI;AACzB,MAAI,OAAO,SAAS,KAAK,UAAkB,MAA0B;AACnE,QAAI,UAAU,UAAU,QAAQ,iBAAiB,KAAK,CAAC,KAAK,MAAM;AAChE,cAAQ,OAAO;AAAA,IACjB;AACA,QAAI,UAAU,SAAS,QAAQ,eAAe;AAC5C,cAAQ,OAAO;AAAA,IACjB;AACA,WAAO,aAAa,KAAK,KAAK,OAAO,GAAG,IAAI;AAAA,EAC9C;AAEA,QAAM,aAAa,IAAI;AACvB,MAAI,KAAK,SAAS,GAAG,OAAe,UAAyC;AAC3E,QAAI,UAAU,UAAU,UAAU,YAAY;AAC5C,cAAQ,gBAAgB;AAAA,IAC1B;AACA,WAAO,WAAW,KAAK,KAAK,OAAO,QAAQ;AAAA,EAC7C;AAEA,QAAM,eAAe,IAAI;AACzB,MAAI,OAAO,SAAS,KAAK,OAAe,UAAyC;AAC/E,QAAI,UAAU,UAAU,UAAU,YAAY;AAC5C,cAAQ,gBAAgB;AAAA,IAC1B;AACA,WAAO,aAAa,KAAK,KAAK,OAAO,QAAQ;AAAA,EAC/C;AAEA,QAAM,sBAAsB,IAAI;AAChC,MAAI,cAAc,SAAS,YAAY,OAAe,UAAyC;AAC7F,QAAI,UAAU,UAAU,UAAU,YAAY;AAC5C,cAAQ,gBAAgB;AAAA,IAC1B;AACA,WAAO,oBAAoB,KAAK,KAAK,OAAO,QAAQ;AAAA,EACtD;AAEA,QAAM,eAAe,IAAI;AACzB,MAAI,OAAO,SAAS,KAAK,aAAsB,SAA4B;AACzE,YAAQ,gBAAgB;AACxB,WAAO,aAAa,KAAK,KAAK,aAAoB,OAAc;AAAA,EAClE;AAEA,QAAM,eAAe,IAAI;AACzB,MAAI,OAAO,SAAS,KAAK,MAAoB;AAC3C,YAAQ,gBAAgB;AACxB,UAAM,QAAQ,aAAa,KAAK,KAAK,IAAW;AAChD,UAAM,kBAAmB,IACtB;AACH,UAAM,mBACJ,OAAO,IAAI,kBAAkB,cAAc,IAAI,cAAc,MAAM,IAAI;AACzE,QAAI,CAAC,oBAAoB,oBAAoB,QAAQ,SAAS,MAAM;AAClE,cAAQ,OAAO;AAAA,IACjB;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,KAA+B;AACrD,MAAI,IAAI,QAAQ,gBAAgB,KAAK,MAAM;AACzC,WAAO;AAAA,EACT;AACA,MAAI,IAAI,QAAQ,mBAAmB,KAAK,MAAM;AAC5C,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,YAAY,SAAyB,OAAgB,UAAiC;AAC7F,QAAM,QAAQ,QAAQ,OAAO,QAAQ;AACrC,MAAI,CAAC,OAAO;AACV;AAAA,EACF;AACA,UAAQ,OAAO,MAAM,KAAK;AAC5B;AAEA,SAAS,QAAQ,OAAgB,UAA8C;AAC7E,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,OAAO,KAAK,OAAO,QAAQ;AAAA,EACpC;AACA,MAAI,iBAAiB,YAAY;AAC/B,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,aAAa;AAChC,WAAO,IAAI,WAAW,KAAK;AAAA,EAC7B;AACA,SAAO;AACT;AAEA,IAAM,mBAAN,MAAuB;AAAA,EAQrB,YAAY,aAAsB,aAAqB,UAA0C;AAJjG,SAAQ,cAAc;AACtB,SAAQ,QAAQ;AAId,SAAK,SAAS,cAAc,IAAI,cAAc,WAAW,IAAI;AAC7D,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,OAAmB;AACjB,WAAO,KAAK,QAAQ,MAAM,KAAK,IAAI,WAAW;AAAA,EAChD;AAAA,EAEA,aAAqB;AACnB,WAAO,KAAK,QAAQ,WAAW,KAAK;AAAA,EACtC;AAAA,EAEA,eAAwB;AACtB,WAAO,CAAC,CAAC,KAAK,UAAU,KAAK,OAAO,WAAW,IAAI;AAAA,EACrD;AAAA,EAEA,eAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,mBAA4B;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,gBACE,gBACmC;AACnC,QAAI,KAAK,gBAAgB;AACvB,aAAO,4BAA4B,KAAK,cAAc;AAAA,IACxD;AACA,WAAO,4BAA4B,cAAc;AAAA,EACnD;AAAA,EAEA,aAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK,QAAQ,UAAU,KAAK;AAAA,EACrC;AAAA,EAEA,KAAK,KAA2B;AAC9B,UAAM,oBAAoB,IAAI;AAC9B,QAAI,aAAa,CAAC,eAAuB,SAAgB;AACvD,UAAI,CAAC,KAAK,aAAa;AACrB,aAAK,sBAAsB,KAAK,IAAI;AAAA,MACtC;AACA,WAAK,aAAa,KAAK,UAAU;AACjC,aAAQ,kBAA0B,KAAK,KAAK,YAAY,GAAG,IAAI;AAAA,IACjE;AAEA,UAAM,gBAAgB,IAAI;AAC1B,QAAI,SAAS,CAAC,OAAgB,UAA2B,OAAsC;AAC7F,WAAK,aAAa,KAAK,IAAI,cAAc,GAAG;AAC5C,WAAK,YAAY,OAAO,QAAQ;AAChC,aAAO,cAAc,KAAK,KAAK,OAAc,UAAiB,EAAS;AAAA,IACzE;AAEA,UAAM,cAAc,IAAI;AACxB,QAAI,OAAO,CAAC,OAAiB,UAA2B,OAAoB;AAC1E,WAAK,aAAa,KAAK,IAAI,cAAc,GAAG;AAC5C,UAAI,OAAO;AACT,aAAK,YAAY,OAAO,QAAQ;AAAA,MAClC;AACA,aAAO,YAAY,KAAK,KAAK,OAAc,UAAiB,EAAS;AAAA,IACvE;AAEA,QAAI,OAAO,IAAI,iBAAiB,YAAY;AAC1C,YAAM,gBAAgB,IAAI;AAC1B,UAAI,gBAAgB,MAAM;AACxB,aAAK,aAAa,KAAK,IAAI,cAAc,GAAG;AAC5C,eAAO,cAAc,KAAK,GAAG;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,aAAa,KAAqB,YAA0B;AAClE,QAAI,KAAK,aAAa;AACpB;AAAA,IACF;AACA,SAAK,WAAW,GAAG;AACnB,SAAK,cAAc;AACnB,SAAK,SAAS;AACd,SAAK,iBAAiB,EAAE,GAAG,IAAI,WAAW,EAAE;AAAA,EAI9C;AAAA,EAEQ,sBAAsB,KAAqB,MAAmB;AACpE,QAAI,KAAK,WAAW,GAAG;AACrB;AAAA,IACF;AACA,UAAM,aAAa,OAAO,KAAK,CAAC,MAAM,WAAW,KAAK,CAAC,IAAI,KAAK,CAAC;AACjE,QAAI,CAAC,YAAY;AACf;AAAA,IACF;AACA,QAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,UAAI,WAAW,WAAW,GAAG;AAC3B;AAAA,MACF;AACA,UAAI,OAAO,WAAW,CAAC,MAAM,UAAU;AACrC,iBAAS,IAAI,GAAG,IAAI,WAAW,SAAS,GAAG,KAAK,GAAG;AACjD,gBAAM,OAAO,WAAW,CAAC;AACzB,gBAAM,QAAQ,WAAW,IAAI,CAAC;AAC9B,cAAI,OAAO,SAAS,YAAY,UAAU,UAAa,UAAU,MAAM;AACrE,gBAAI,UAAU,MAAM,KAAY;AAAA,UAClC;AAAA,QACF;AACA;AAAA,MACF;AACA,iBAAW,SAAS,YAAY;AAC9B,YAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB;AAAA,QACF;AACA,cAAM,CAAC,MAAM,KAAK,IAAI;AACtB,YAAI,OAAO,SAAS,YAAY,UAAU,UAAa,UAAU,MAAM;AACrE,cAAI,UAAU,MAAM,KAAY;AAAA,QAClC;AAAA,MACF;AACA;AAAA,IACF;AACA,QAAI,OAAO,eAAe,UAAU;AAClC,iBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,UAAqC,GAAG;AACjF,YAAI,UAAU,UAAa,UAAU,MAAM;AACzC,cAAI,UAAU,MAAM,KAAY;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,YAAY,OAAgB,UAAiC;AACnE,UAAM,QAAQ,QAAQ,OAAO,QAAQ;AACrC,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AACA,SAAK,SAAS,MAAM;AACpB,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,MAAM,KAAK;AAAA,IACzB;AAAA,EACF;AACF;AAEA,SAAS,wBAAwB,KAAqB,KAAkB,MAAyB;AAC/F,QAAM,aAAa,KAAK,OAAO,UAAU;AACzC,QAAM,WAAW,oBAAoB,IAAI,UAAU,UAAU,CAAC;AAC9D,MAAI,UAAU;AACZ;AAAA,EACF;AAEA,QAAM,WAAW,4BAA4B,IAAI,SAAS;AAC1D,MAAI,UAAU;AACZ,QAAI,UAAU,oBAAoB,UAAU,GAAG,QAAQ;AACvD;AAAA,EACF;AAEA,QAAM,YAAY,kBAAkB;AACpC,MAAI,UAAU,oBAAoB,UAAU,GAAG,SAAS;AACxD,sBAAoB,KAAK,SAAS;AACpC;AAEA,SAAS,QAAQ,KAA8B;AAC7C,MAAI,CAAC,IAAI,KAAK;AACZ,WAAO;AAAA,EACT;AACA,MAAI,IAAI,IAAI,WAAW,SAAS,KAAK,IAAI,IAAI,WAAW,UAAU,GAAG;AACnE,WAAO,IAAI;AAAA,EACb;AAEA,QAAM,OAAO,IAAI,QAAQ,MAAM;AAC/B,MAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,WAAO,IAAI;AAAA,EACb;AACA,QAAM,SAAS,IAAI,kBAAkB,YAAY,UAAU;AAC3D,SAAO,GAAG,MAAM,MAAM,IAAI,GAAG,IAAI,GAAG;AACtC;AAEA,SAAS,oBAAoB,OAAoC;AAC/D,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,4BAA4B,MAAM,CAAC,CAAC;AAAA,EAC7C;AACA,SAAO,4BAA4B,GAAG,KAAK,EAAE;AAC/C;AAEA,SAAS,4BAA4B,OAA+C;AAClF,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,UAAU,UAAU;AAC7B;AAEA,SAAS,oBAAoB,YAA4B;AACvD,SAAO,WACJ,MAAM,GAAG,EACT,OAAO,OAAO,EACd,IAAI,CAAC,SAAU,OAAO,KAAK,CAAC,EAAG,YAAY,IAAI,KAAK,MAAM,CAAC,IAAI,IAAK,EACpE,KAAK,GAAG;AACb;AAMA,IAAM,uBAAuB,oBAAI,QAA+C;AAEhF,SAAS,mBAAmB,KAA4B;AACtD,MAAI,qBAAqB,IAAI,GAAG,GAAG;AACjC;AAAA,EACF;AACA,QAAM,SAAS;AACf,MAAI,OAAO,OAAO,QAAQ,YAAY;AACpC;AAAA,EACF;AAEA,QAAM,UAAgC,CAAC;AACvC,uBAAqB,IAAI,KAAK,OAAO;AAErC,QAAM,aAAa,OAAO,yBAAyB,KAAK,QAAQ;AAChE,MAAI,cAAc,CAAC,WAAW,cAAc;AAC1C,QAAI,WAAW,SAAS,OAAO,WAAW,UAAU,UAAU;AAC5D,cAAQ,KAAK,EAAE,GAAI,WAAW,MAA6B,CAAC;AAAA,IAC9D;AACA;AAAA,EACF;AAEA,MAAI,UACF,cAAc,WAAW,aACpB,WAAW,QACZ;AAEN,MAAI,WAAW,OAAO,YAAY,UAAU;AAC1C,YAAQ,KAAK,EAAE,GAAG,QAAQ,CAAC;AAAA,EAC7B;AAEA,SAAO,eAAe,KAAK,UAAU;AAAA,IACnC,cAAc;AAAA,IACd,YAAY,YAAY,cAAc;AAAA,IACtC,MAAM;AACJ,aAAO;AAAA,IACT;AAAA,IACA,IAAI,OAAO;AACT,gBAAU;AACV,UAAI,SAAS,OAAO,UAAU,UAAU;AACtC,gBAAQ,KAAK,EAAE,GAAI,MAA6B,CAAC;AAAA,MACnD;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,oBAAoB,KAA0C;AACrE,QAAM,SAAS;AAKf,QAAM,YAAY,wBAAwB,OAAO,OAAO,IAAI;AAC5D,QAAM,UAAU,OAAO,WAAW;AAClC,MAAI,CAAC,aAAa,CAAC,SAAS;AAC1B,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,qBAAqB,KAAK,OAAO,MAAM;AACtD,QAAM,kBAAkB,qBAAqB,SAAS,QAAQ,SAAS;AACvE,SAAO,iBAAiB,iBAAiB,SAAS;AACpD;AAEA,SAAS,wBAAwB,MAA6C;AAC5E,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,eAAW,SAAS,MAAM;AACxB,UAAI,OAAO,UAAU,UAAU;AAC7B,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,qBACP,KACA,UACoB;AACpB,QAAM,UAAU,qBAAqB,IAAI,GAAG;AAC5C,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,WAAO,YAAY,CAAC;AAAA,EACtB;AAEA,QAAM,SAA6B,CAAC;AACpC,aAAW,YAAY,SAAS;AAC9B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAI,EAAE,OAAO,SAAS;AACpB,eAAO,GAAG,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACA,MAAI,UAAU;AACZ,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAI,EAAE,OAAO,SAAS;AACpB,eAAO,GAAG,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,qBACP,SACA,QACA,WACQ;AACR,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,QAAM,UAAU,OAAO,QAAQ,MAAM;AACrC,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,IAAI,IAAI,YAAY,yBAAyB,SAAS,IAAI,CAAC,CAAC;AAC7E,QAAM,eAAe,QAClB,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,EACtC,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,EAAE,MAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,CAAC,IAAI,MAAM,EAAE,EACjF,OAAO,CAAC,UAAoD,CAAC,CAAC,MAAM,KAAK;AAE5E,MAAI,aAAa,WAAW,GAAG;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,eAAe,oBAAI,IAAoB;AAC7C,QAAM,WAAW,QAAQ,MAAM,GAAG;AAClC,QAAM,UAAU,SAAS,IAAI,CAAC,YAAY;AACxC,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AACA,eAAW,EAAE,MAAM,MAAM,KAAK,cAAc;AAC1C,UAAI,KAAK,IAAI,IAAI,GAAG;AAClB;AAAA,MACF;AACA,YAAM,eAAe,aAAa,IAAI,KAAK,KAAK,mBAAmB,KAAK;AACxE,mBAAa,IAAI,OAAO,YAAY;AACpC,UAAI,YAAY,SAAS,YAAY,cAAc;AACjD,aAAK,IAAI,IAAI;AACb,eAAO,IAAI,IAAI;AAAA,MACjB;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,QAAQ,KAAK,GAAG;AACzB;AAEA,SAAS,yBAAyB,MAAwB;AACxD,QAAM,QAAkB,CAAC;AACzB,QAAM,eAAe;AACrB,aAAW,SAAS,KAAK,SAAS,YAAY,GAAG;AAC/C,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,MAAM;AACR,YAAM,KAAK,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,SAAiB,WAA4B;AACrE,QAAM,OAAO,UAAU,mBAAmB,OAAO,IAAI;AACrD,QAAM,QAAQ,YAAY,mBAAmB,SAAS,IAAI;AAC1D,MAAI,CAAC,MAAM;AACT,WAAO,SAAS;AAAA,EAClB;AACA,MAAI,CAAC,SAAS,UAAU,KAAK;AAC3B,WAAO;AAAA,EACT;AACA,QAAM,cAAc,KAAK,SAAS,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI;AAC7D,SAAO,GAAG,WAAW,GAAG,KAAK;AAC/B;AAEA,SAAS,mBAAmB,MAAsB;AAChD,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,SAAO,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AAC/C;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stainlessdev/xray-node",
|
|
3
|
-
"version": "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.
|
|
23
|
+
"@stainlessdev/xray-core": "0.7.0-dev.588fa57"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@opentelemetry/api": "^1.9.0",
|