@stainlessdev/xray-node 0.5.1 → 0.6.0-branch.bg-fix-req-id-gen.e29953f
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/dist/index.cjs +42 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +44 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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();
|
|
@@ -361,6 +368,7 @@ var ResponseRecorder = class {
|
|
|
361
368
|
if (this.wroteHeader) {
|
|
362
369
|
return;
|
|
363
370
|
}
|
|
371
|
+
this.onHeader?.(res);
|
|
364
372
|
this.wroteHeader = true;
|
|
365
373
|
this.status = statusCode;
|
|
366
374
|
this.headerSnapshot = { ...res.getHeaders() };
|
|
@@ -376,19 +384,20 @@ var ResponseRecorder = class {
|
|
|
376
384
|
}
|
|
377
385
|
}
|
|
378
386
|
};
|
|
379
|
-
function
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const value = req.headers[headerName];
|
|
385
|
-
if (!value) {
|
|
386
|
-
return void 0;
|
|
387
|
+
function ensureResponseRequestId(res, ctx, xray) {
|
|
388
|
+
const headerName = xray.config.requestId.header;
|
|
389
|
+
const existing = headerValueFromNode(res.getHeader(headerName));
|
|
390
|
+
if (existing) {
|
|
391
|
+
return;
|
|
387
392
|
}
|
|
388
|
-
|
|
389
|
-
|
|
393
|
+
const explicit = normalizeRequestIdCandidate(ctx.requestId);
|
|
394
|
+
if (explicit) {
|
|
395
|
+
res.setHeader(canonicalHeaderName(headerName), explicit);
|
|
396
|
+
return;
|
|
390
397
|
}
|
|
391
|
-
|
|
398
|
+
const generated = (0, import_internal.uuidv7)();
|
|
399
|
+
res.setHeader(canonicalHeaderName(headerName), generated);
|
|
400
|
+
(0, import_internal.setContextRequestId)(ctx, generated);
|
|
392
401
|
}
|
|
393
402
|
function fullUrl(req) {
|
|
394
403
|
if (!req.url) {
|
|
@@ -404,6 +413,25 @@ function fullUrl(req) {
|
|
|
404
413
|
const scheme = req.socket instanceof import_node_tls.TLSSocket ? "https" : "http";
|
|
405
414
|
return `${scheme}://${host}${req.url}`;
|
|
406
415
|
}
|
|
416
|
+
function headerValueFromNode(value) {
|
|
417
|
+
if (value == null) {
|
|
418
|
+
return void 0;
|
|
419
|
+
}
|
|
420
|
+
if (Array.isArray(value)) {
|
|
421
|
+
return normalizeRequestIdCandidate(value[0]);
|
|
422
|
+
}
|
|
423
|
+
return normalizeRequestIdCandidate(`${value}`);
|
|
424
|
+
}
|
|
425
|
+
function normalizeRequestIdCandidate(value) {
|
|
426
|
+
if (!value) {
|
|
427
|
+
return void 0;
|
|
428
|
+
}
|
|
429
|
+
const trimmed = value.trim();
|
|
430
|
+
return trimmed ? trimmed : void 0;
|
|
431
|
+
}
|
|
432
|
+
function canonicalHeaderName(headerName) {
|
|
433
|
+
return headerName.split("-").filter(Boolean).map((part) => part ? part[0].toUpperCase() + part.slice(1) : part).join("-");
|
|
434
|
+
}
|
|
407
435
|
var expressParamsHistory = /* @__PURE__ */ new WeakMap();
|
|
408
436
|
function trackExpressParams(req) {
|
|
409
437
|
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":"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","names":["createCoreEmitter"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/emitter.ts","../src/adapter.ts"],"sourcesContent":["export { createEmitter } from './emitter';\nexport { wrapHttpHandler, getXrayContext } from './adapter';\nexport type { WrapOptions, NodeHttpHandler } from './adapter';\n","import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';\nimport {\n createEmitter as createCoreEmitter,\n normalizeConfig,\n type XrayRuntimeConfig,\n} from '@stainlessdev/xray-core';\n\nexport function createEmitter(config: XrayRuntimeConfig) {\n const resolved = normalizeConfig(config);\n const exporter =\n config.exporter?.instance ??\n new OTLPTraceExporter({\n url: resolved.exporter.endpointUrl,\n headers: resolved.exporter.headers ?? {},\n timeoutMillis: resolved.exporter.timeoutMs,\n });\n\n return createCoreEmitter(config, exporter);\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport { TLSSocket } from 'node:tls';\nimport type {\n CaptureConfig,\n NormalizedRequest,\n NormalizedResponse,\n RedactionConfig,\n RequestLog,\n XrayContext,\n XrayEmitter,\n} from '@stainlessdev/xray-core';\nimport {\n LimitedBuffer,\n bindContextToObject,\n getXrayContextFromObject,\n headerValuesFromNodeHeaders,\n isWebsocketUpgrade,\n logWithLevel,\n makeCapturedBody,\n setCaptureOverride,\n setContextRequestId,\n setContextRoute,\n setRedactionOverride,\n uuidv7,\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 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 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 = uuidv7();\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
|
+
uuidv7
|
|
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();
|
|
@@ -348,6 +356,7 @@ var ResponseRecorder = class {
|
|
|
348
356
|
if (this.wroteHeader) {
|
|
349
357
|
return;
|
|
350
358
|
}
|
|
359
|
+
this.onHeader?.(res);
|
|
351
360
|
this.wroteHeader = true;
|
|
352
361
|
this.status = statusCode;
|
|
353
362
|
this.headerSnapshot = { ...res.getHeaders() };
|
|
@@ -363,19 +372,20 @@ var ResponseRecorder = class {
|
|
|
363
372
|
}
|
|
364
373
|
}
|
|
365
374
|
};
|
|
366
|
-
function
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
const value = req.headers[headerName];
|
|
372
|
-
if (!value) {
|
|
373
|
-
return void 0;
|
|
375
|
+
function ensureResponseRequestId(res, ctx, xray) {
|
|
376
|
+
const headerName = xray.config.requestId.header;
|
|
377
|
+
const existing = headerValueFromNode(res.getHeader(headerName));
|
|
378
|
+
if (existing) {
|
|
379
|
+
return;
|
|
374
380
|
}
|
|
375
|
-
|
|
376
|
-
|
|
381
|
+
const explicit = normalizeRequestIdCandidate(ctx.requestId);
|
|
382
|
+
if (explicit) {
|
|
383
|
+
res.setHeader(canonicalHeaderName(headerName), explicit);
|
|
384
|
+
return;
|
|
377
385
|
}
|
|
378
|
-
|
|
386
|
+
const generated = uuidv7();
|
|
387
|
+
res.setHeader(canonicalHeaderName(headerName), generated);
|
|
388
|
+
setContextRequestId(ctx, generated);
|
|
379
389
|
}
|
|
380
390
|
function fullUrl(req) {
|
|
381
391
|
if (!req.url) {
|
|
@@ -391,6 +401,25 @@ function fullUrl(req) {
|
|
|
391
401
|
const scheme = req.socket instanceof TLSSocket ? "https" : "http";
|
|
392
402
|
return `${scheme}://${host}${req.url}`;
|
|
393
403
|
}
|
|
404
|
+
function headerValueFromNode(value) {
|
|
405
|
+
if (value == null) {
|
|
406
|
+
return void 0;
|
|
407
|
+
}
|
|
408
|
+
if (Array.isArray(value)) {
|
|
409
|
+
return normalizeRequestIdCandidate(value[0]);
|
|
410
|
+
}
|
|
411
|
+
return normalizeRequestIdCandidate(`${value}`);
|
|
412
|
+
}
|
|
413
|
+
function normalizeRequestIdCandidate(value) {
|
|
414
|
+
if (!value) {
|
|
415
|
+
return void 0;
|
|
416
|
+
}
|
|
417
|
+
const trimmed = value.trim();
|
|
418
|
+
return trimmed ? trimmed : void 0;
|
|
419
|
+
}
|
|
420
|
+
function canonicalHeaderName(headerName) {
|
|
421
|
+
return headerName.split("-").filter(Boolean).map((part) => part ? part[0].toUpperCase() + part.slice(1) : part).join("-");
|
|
422
|
+
}
|
|
394
423
|
var expressParamsHistory = /* @__PURE__ */ new WeakMap();
|
|
395
424
|
function trackExpressParams(req) {
|
|
396
425
|
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 uuidv7,\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 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 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 = uuidv7();\n res.setHeader(canonicalHeaderName(headerName), generated);\n setContextRequestId(ctx, generated);\n}\n\nfunction fullUrl(req: IncomingMessage): string {\n if (!req.url) {\n return '';\n }\n if (req.url.startsWith('http://') || req.url.startsWith('https://')) {\n return req.url;\n }\n\n const host = req.headers['host'];\n if (!host || typeof host !== 'string') {\n return req.url;\n }\n const scheme = req.socket instanceof TLSSocket ? 'https' : 'http';\n return `${scheme}://${host}${req.url}`;\n}\n\nfunction headerValueFromNode(value: unknown): string | undefined {\n if (value == null) {\n return undefined;\n }\n if (Array.isArray(value)) {\n return normalizeRequestIdCandidate(value[0]);\n }\n return normalizeRequestIdCandidate(`${value}`);\n}\n\nfunction normalizeRequestIdCandidate(value: string | undefined): string | undefined {\n if (!value) {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction canonicalHeaderName(headerName: string): string {\n return headerName\n .split('-')\n .filter(Boolean)\n .map((part) => (part ? part[0]!.toUpperCase() + part.slice(1) : part))\n .join('-');\n}\n\ntype ExpressRoutePath = string | string[] | RegExp;\n\ntype ExpressRouteParams = Record<string, string | string[]>;\n\nconst expressParamsHistory = new WeakMap<IncomingMessage, ExpressRouteParams[]>();\n\nfunction trackExpressParams(req: IncomingMessage): void {\n if (expressParamsHistory.has(req)) {\n return;\n }\n const anyReq = req as IncomingMessage & { app?: unknown };\n if (typeof anyReq.app !== 'function') {\n return;\n }\n\n const history: ExpressRouteParams[] = [];\n expressParamsHistory.set(req, history);\n\n const descriptor = Object.getOwnPropertyDescriptor(req, 'params');\n if (descriptor && !descriptor.configurable) {\n if (descriptor.value && typeof descriptor.value === 'object') {\n history.push({ ...(descriptor.value as ExpressRouteParams) });\n }\n return;\n }\n\n let current = (\n descriptor && 'value' in descriptor\n ? (descriptor.value as ExpressRouteParams | undefined)\n : undefined\n ) as ExpressRouteParams | undefined;\n if (current && typeof current === 'object') {\n history.push({ ...current });\n }\n\n Object.defineProperty(req, 'params', {\n configurable: true,\n enumerable: descriptor?.enumerable ?? true,\n get() {\n return current;\n },\n set(value) {\n current = value as ExpressRouteParams | undefined;\n if (value && typeof value === 'object') {\n history.push({ ...(value as ExpressRouteParams) });\n }\n },\n });\n}\n\nfunction resolveExpressRoute(req: IncomingMessage): string | undefined {\n const anyReq = req as IncomingMessage & {\n baseUrl?: string;\n params?: ExpressRouteParams;\n route?: { path?: ExpressRoutePath };\n };\n const routePath = extractExpressRoutePath(anyReq.route?.path);\n const baseUrl = anyReq.baseUrl ?? '';\n if (!routePath && !baseUrl) {\n return undefined;\n }\n\n const params = collectExpressParams(req, anyReq.params);\n const resolvedBaseUrl = replaceBaseUrlParams(baseUrl, params, routePath);\n return joinExpressRoute(resolvedBaseUrl, routePath);\n}\n\nfunction extractExpressRoutePath(path?: ExpressRoutePath): string | undefined {\n if (typeof path === 'string') {\n return path;\n }\n if (Array.isArray(path)) {\n for (const entry of path) {\n if (typeof entry === 'string') {\n return entry;\n }\n }\n }\n return undefined;\n}\n\nfunction collectExpressParams(\n req: IncomingMessage,\n fallback?: ExpressRouteParams,\n): ExpressRouteParams {\n const history = expressParamsHistory.get(req);\n if (!history || history.length === 0) {\n return fallback ?? {};\n }\n\n const merged: ExpressRouteParams = {};\n for (const snapshot of history) {\n for (const [key, value] of Object.entries(snapshot)) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n }\n if (fallback) {\n for (const [key, value] of Object.entries(fallback)) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n }\n return merged;\n}\n\nfunction replaceBaseUrlParams(\n baseUrl: string,\n params: ExpressRouteParams,\n routePath?: string,\n): string {\n if (!baseUrl) {\n return baseUrl;\n }\n const entries = Object.entries(params);\n if (entries.length === 0) {\n return baseUrl;\n }\n\n const excluded = new Set(routePath ? extractExpressParamNames(routePath) : []);\n const replacements = entries\n .filter(([name]) => !excluded.has(name))\n .map(([name, value]) => ({ name, value: Array.isArray(value) ? value[0] : value }))\n .filter((entry): entry is { name: string; value: string } => !!entry.value);\n\n if (replacements.length === 0) {\n return baseUrl;\n }\n\n const used = new Set<string>();\n const encodedCache = new Map<string, string>();\n const segments = baseUrl.split('/');\n const updated = segments.map((segment) => {\n if (!segment) {\n return segment;\n }\n for (const { name, value } of replacements) {\n if (used.has(name)) {\n continue;\n }\n const encodedValue = encodedCache.get(value) ?? encodeURIComponent(value);\n encodedCache.set(value, encodedValue);\n if (segment === value || segment === encodedValue) {\n used.add(name);\n return `:${name}`;\n }\n }\n return segment;\n });\n\n return updated.join('/');\n}\n\nfunction extractExpressParamNames(path: string): string[] {\n const names: string[] = [];\n const paramPattern = /:([A-Za-z0-9_]+)(?:\\([^)]*\\))?[?*+]?/g;\n for (const match of path.matchAll(paramPattern)) {\n const name = match[1];\n if (name) {\n names.push(name);\n }\n }\n return names;\n}\n\nfunction joinExpressRoute(baseUrl: string, routePath?: string): string {\n const base = baseUrl ? ensureLeadingSlash(baseUrl) : '';\n const route = routePath ? ensureLeadingSlash(routePath) : '';\n if (!base) {\n return route || '/';\n }\n if (!route || route === '/') {\n return base;\n }\n const trimmedBase = base.endsWith('/') ? base.slice(0, -1) : base;\n return `${trimmedBase}${route}`;\n}\n\nfunction ensureLeadingSlash(path: string): string {\n if (!path) {\n return '/';\n }\n return path.startsWith('/') ? path : `/${path}`;\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stainlessdev/xray-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0-branch.bg-fix-req-id-gen.e29953f",
|
|
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.6.0-branch.bg-fix-req-id-gen.e29953f"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@opentelemetry/api": "^1.9.0",
|