@reproapp/node-sdk 0.0.23 → 0.0.25

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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.__reproTestHooks = exports.initRepro = exports.patchSendgridMail = exports.patchRedis = exports.patchKafkaJs = exports.reproMongoosePlugin = exports.reproMiddleware = exports.__materializePendingTraceEventsForWorker = exports.isReproTracingEnabled = exports.initReproTracing = exports.disableReproTraceLogs = exports.enableReproTraceLogs = exports.setReproTraceLogsEnabled = exports.setDisabledTraceFiles = exports.setDisabledFunctionTypes = exports.setDisabledFunctionTraces = void 0;
3
+ exports.__reproTestHooks = exports.initRepro = exports.patchSendgridMail = exports.patchRedis = exports.patchAmqplib = exports.patchKafkaJs = exports.reproMongoosePlugin = exports.reproMiddleware = exports.__materializePendingTraceEventsForWorker = exports.isReproTracingEnabled = exports.initReproTracing = exports.disableReproTraceLogs = exports.enableReproTraceLogs = exports.setReproTraceLogsEnabled = exports.setDisabledTraceFiles = exports.setDisabledFunctionTypes = exports.setDisabledFunctionTraces = void 0;
4
4
  const mongoose = require("mongoose");
5
5
  const async_hooks_1 = require("async_hooks");
6
6
  const crypto_1 = require("crypto");
@@ -1525,9 +1525,10 @@ function resolveCollectionOrWarn(source, type) {
1525
1525
  function post(cfg, sessionId, body, options) {
1526
1526
  try {
1527
1527
  const entries = Array.isArray(body?.entries) ? body.entries : [];
1528
- (0, client_1.enqueueIngestEntries)(cfg, sessionId, entries, options);
1528
+ return (0, client_1.enqueueIngestEntries)(cfg, sessionId, entries, options);
1529
1529
  }
1530
1530
  catch { /* swallow in SDK */ }
1531
+ return false;
1531
1532
  }
1532
1533
  function toIngestConfig(cfg) {
1533
1534
  return {
@@ -4918,9 +4919,6 @@ function emitDbQuery(cfg, sid, aid, payload) {
4918
4919
  const spanContext = payload?.spanContext ?? captureSpanContextFromTracer();
4919
4920
  if (!shouldCaptureDbSpan(spanContext))
4920
4921
  return;
4921
- if (ctx.captureScope) {
4922
- ctx.captureScope.dbChangeCount += 1;
4923
- }
4924
4922
  const runCtx = {
4925
4923
  sid: ctx.sid,
4926
4924
  aid: ctx.aid,
@@ -5039,7 +5037,7 @@ async function emitDbQueryAsync(cfg, sid, aid, payload) {
5039
5037
  resultMetaMaterialization: resultMetaMaterialization.skipped,
5040
5038
  errorMaterialization: errorMaterialization.skipped,
5041
5039
  }, spanContext);
5042
- post(cfg, sid, {
5040
+ const enqueued = post(cfg, sid, {
5043
5041
  entries: [{
5044
5042
  actionId: aid ?? null,
5045
5043
  requestRid: ctx.rid ?? null,
@@ -5048,6 +5046,9 @@ async function emitDbQueryAsync(cfg, sid, aid, payload) {
5048
5046
  t: payload.t,
5049
5047
  }]
5050
5048
  });
5049
+ if (enqueued && ctx.captureScope) {
5050
+ ctx.captureScope.dbChangeCount += 1;
5051
+ }
5051
5052
  }
5052
5053
  function buildMinimalUpdate(before, after) {
5053
5054
  const set = {};
@@ -6324,6 +6325,780 @@ function patchKafkaJs(cfg) {
6324
6325
  }
6325
6326
  }
6326
6327
  exports.patchKafkaJs = patchKafkaJs;
6328
+ function decodeAmqpHeaderValue(value) {
6329
+ if (value === null || value === undefined)
6330
+ return null;
6331
+ if (typeof value === 'string') {
6332
+ const trimmed = value.trim();
6333
+ return trimmed.length ? trimmed : null;
6334
+ }
6335
+ if (Buffer.isBuffer(value)) {
6336
+ const decoded = value.toString('utf8').trim();
6337
+ return decoded.length ? decoded : null;
6338
+ }
6339
+ if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {
6340
+ return String(value);
6341
+ }
6342
+ return null;
6343
+ }
6344
+ function readAmqpHeader(headers, key) {
6345
+ if (!headers || typeof headers !== 'object')
6346
+ return null;
6347
+ const direct = decodeAmqpHeaderValue(headers[key]);
6348
+ if (direct)
6349
+ return direct;
6350
+ const normalized = key.toLowerCase();
6351
+ for (const [entryKey, entryValue] of Object.entries(headers)) {
6352
+ if (entryKey.toLowerCase() !== normalized)
6353
+ continue;
6354
+ return decodeAmqpHeaderValue(entryValue);
6355
+ }
6356
+ return null;
6357
+ }
6358
+ function cloneAmqpHeaders(headers) {
6359
+ if (!headers || typeof headers !== 'object' || Buffer.isBuffer(headers))
6360
+ return {};
6361
+ const out = {};
6362
+ for (const [key, value] of Object.entries(headers)) {
6363
+ out[key] = value;
6364
+ }
6365
+ return out;
6366
+ }
6367
+ function withAmqpPropagationHeaders(headers, values) {
6368
+ const out = cloneAmqpHeaders(headers);
6369
+ for (const [key, value] of Object.entries(values)) {
6370
+ if (value === null || value === undefined)
6371
+ continue;
6372
+ const str = String(value).trim();
6373
+ if (!str.length)
6374
+ continue;
6375
+ out[key] = str;
6376
+ }
6377
+ return out;
6378
+ }
6379
+ function normalizeAmqpHeadersForPayload(headers) {
6380
+ const out = {};
6381
+ if (!headers || typeof headers !== 'object' || Buffer.isBuffer(headers))
6382
+ return out;
6383
+ for (const [key, value] of Object.entries(headers)) {
6384
+ const decoded = decodeAmqpHeaderValue(value);
6385
+ if (decoded !== null) {
6386
+ out[key] = decoded;
6387
+ }
6388
+ else {
6389
+ const sanitized = sanitizeResultForMeta(value);
6390
+ if (sanitized !== undefined)
6391
+ out[key] = sanitized;
6392
+ }
6393
+ }
6394
+ return out;
6395
+ }
6396
+ function hasAmqpPropagationValues(values) {
6397
+ return Object.values(values).some((value) => {
6398
+ if (value === null || value === undefined)
6399
+ return false;
6400
+ return String(value).trim().length > 0;
6401
+ });
6402
+ }
6403
+ function isAmqpOptionsObject(value) {
6404
+ return Boolean(value && typeof value === 'object' && !Buffer.isBuffer(value) && typeof value !== 'function');
6405
+ }
6406
+ function withAmqpPropagationOptions(options, values) {
6407
+ const base = isAmqpOptionsObject(options) ? { ...options } : {};
6408
+ return {
6409
+ ...base,
6410
+ headers: withAmqpPropagationHeaders(base.headers, values),
6411
+ };
6412
+ }
6413
+ function amqpContentSize(content) {
6414
+ if (content === null || content === undefined)
6415
+ return null;
6416
+ if (typeof content === 'string')
6417
+ return Buffer.byteLength(content, 'utf8');
6418
+ if (Buffer.isBuffer(content))
6419
+ return content.length;
6420
+ if (content instanceof Uint8Array)
6421
+ return content.byteLength;
6422
+ return null;
6423
+ }
6424
+ function decodeAmqpContent(content) {
6425
+ if (content === null || content === undefined)
6426
+ return null;
6427
+ if (typeof content === 'string')
6428
+ return content;
6429
+ if (Buffer.isBuffer(content))
6430
+ return content.toString('utf8');
6431
+ if (content instanceof Uint8Array)
6432
+ return Buffer.from(content).toString('utf8');
6433
+ if (typeof content === 'number' || typeof content === 'boolean')
6434
+ return content;
6435
+ return sanitizeResultForMeta(content);
6436
+ }
6437
+ function contentTypeLooksJson(contentType) {
6438
+ return typeof contentType === 'string' && /\bjson\b/i.test(contentType);
6439
+ }
6440
+ function parseAmqpJsonString(value, contentType) {
6441
+ const trimmed = value.trim();
6442
+ if (!trimmed)
6443
+ return { parsed: false, value };
6444
+ if (!contentTypeLooksJson(contentType) && !'{['.includes(trimmed[0])) {
6445
+ return { parsed: false, value };
6446
+ }
6447
+ try {
6448
+ return { parsed: true, value: JSON.parse(value) };
6449
+ }
6450
+ catch {
6451
+ return { parsed: false, value };
6452
+ }
6453
+ }
6454
+ function decodeAmqpMessageContent(content, propertiesOrOptions) {
6455
+ const decoded = decodeAmqpContent(content);
6456
+ if (typeof decoded !== 'string') {
6457
+ return {
6458
+ value: decoded,
6459
+ valueEncoding: decoded === null ? null : typeof decoded,
6460
+ };
6461
+ }
6462
+ const parsed = parseAmqpJsonString(decoded, propertiesOrOptions?.contentType);
6463
+ if (parsed.parsed) {
6464
+ return {
6465
+ value: parsed.value,
6466
+ rawValue: decoded,
6467
+ valueEncoding: 'json',
6468
+ };
6469
+ }
6470
+ return {
6471
+ value: decoded,
6472
+ valueEncoding: Buffer.isBuffer(content) || content instanceof Uint8Array ? 'utf8' : 'string',
6473
+ };
6474
+ }
6475
+ function buildAmqpMessagePayload(content, propertiesOrOptions) {
6476
+ const decoded = decodeAmqpMessageContent(content, propertiesOrOptions);
6477
+ const payload = {
6478
+ value: decoded.value,
6479
+ valueEncoding: decoded.valueEncoding,
6480
+ valueBytes: amqpContentSize(content),
6481
+ headers: normalizeAmqpHeadersForPayload(propertiesOrOptions?.headers),
6482
+ };
6483
+ if (decoded.rawValue !== undefined) {
6484
+ payload.rawValue = decoded.rawValue;
6485
+ }
6486
+ if (propertiesOrOptions?.contentType !== undefined) {
6487
+ payload.contentType = propertiesOrOptions.contentType;
6488
+ }
6489
+ if (propertiesOrOptions?.contentEncoding !== undefined) {
6490
+ payload.contentEncoding = propertiesOrOptions.contentEncoding;
6491
+ }
6492
+ if (propertiesOrOptions?.messageId !== undefined) {
6493
+ payload.messageId = propertiesOrOptions.messageId;
6494
+ }
6495
+ if (propertiesOrOptions?.correlationId !== undefined) {
6496
+ payload.correlationId = propertiesOrOptions.correlationId;
6497
+ }
6498
+ if (propertiesOrOptions?.replyTo !== undefined) {
6499
+ payload.replyTo = propertiesOrOptions.replyTo;
6500
+ }
6501
+ if (propertiesOrOptions?.type !== undefined) {
6502
+ payload.type = propertiesOrOptions.type;
6503
+ }
6504
+ return payload;
6505
+ }
6506
+ function buildAmqpMessagePropertiesPayload(properties) {
6507
+ if (!properties || typeof properties !== 'object')
6508
+ return {};
6509
+ const payload = {};
6510
+ const copyKeys = [
6511
+ 'contentType',
6512
+ 'contentEncoding',
6513
+ 'deliveryMode',
6514
+ 'priority',
6515
+ 'correlationId',
6516
+ 'replyTo',
6517
+ 'expiration',
6518
+ 'messageId',
6519
+ 'timestamp',
6520
+ 'type',
6521
+ 'userId',
6522
+ 'appId',
6523
+ 'clusterId',
6524
+ ];
6525
+ for (const key of copyKeys) {
6526
+ if (properties[key] !== undefined)
6527
+ payload[key] = sanitizeResultForMeta(properties[key]);
6528
+ }
6529
+ payload.headers = normalizeAmqpHeadersForPayload(properties.headers);
6530
+ return payload;
6531
+ }
6532
+ function sanitizeAmqpQueue(queue) {
6533
+ const value = typeof queue === 'string' ? queue.trim() : '';
6534
+ return value.length ? value : 'unknown-queue';
6535
+ }
6536
+ function sanitizeAmqpExchange(exchange) {
6537
+ if (exchange === undefined || exchange === null)
6538
+ return '';
6539
+ const value = typeof exchange === 'string' ? exchange.trim() : String(exchange).trim();
6540
+ return value;
6541
+ }
6542
+ function sanitizeAmqpRoutingKey(routingKey) {
6543
+ const value = typeof routingKey === 'string' ? routingKey.trim() : '';
6544
+ return value.length ? value : 'unknown-routing-key';
6545
+ }
6546
+ function summarizeAmqpError(error) {
6547
+ const message = typeof error?.message === 'string'
6548
+ ? error.message
6549
+ : error === null || error === undefined
6550
+ ? 'Unknown AMQP error'
6551
+ : String(error);
6552
+ return {
6553
+ name: typeof error?.name === 'string' ? error.name : undefined,
6554
+ message,
6555
+ code: error?.code ?? undefined,
6556
+ };
6557
+ }
6558
+ function resolveAmqpContext(cfg, headers) {
6559
+ const ctx = getCtx();
6560
+ const fallback = cfg.resolveContext?.() ?? {};
6561
+ const tracerSpan = captureSpanContextFromTracer();
6562
+ const sid = readAmqpHeader(headers, KAFKA_HEADER_SESSION_ID) ?? ctx.sid ?? fallback.sid ?? null;
6563
+ const aid = readAmqpHeader(headers, KAFKA_HEADER_ACTION_ID) ?? ctx.aid ?? fallback.aid ?? null;
6564
+ const traceId = readAmqpHeader(headers, KAFKA_HEADER_TRACE_ID) ??
6565
+ tracerSpan?.traceId ??
6566
+ __TRACER__?.getCurrentTraceId?.() ??
6567
+ null;
6568
+ const parentSpanId = readAmqpHeader(headers, KAFKA_HEADER_SPAN_ID) ??
6569
+ readAmqpHeader(headers, KAFKA_HEADER_PARENT_SPAN_ID) ??
6570
+ null;
6571
+ const requestRid = readAmqpHeader(headers, KAFKA_HEADER_REQUEST_ID);
6572
+ return { sid, aid, traceId, parentSpanId, requestRid };
6573
+ }
6574
+ function withOptionalTraceContextSync(traceId, fn) {
6575
+ const tracerWithTrace = __TRACER__?.withTrace;
6576
+ if (traceId && typeof tracerWithTrace === 'function') {
6577
+ let invoked = false;
6578
+ try {
6579
+ return tracerWithTrace(traceId, () => {
6580
+ invoked = true;
6581
+ return fn();
6582
+ });
6583
+ }
6584
+ catch (error) {
6585
+ if (invoked)
6586
+ throw error;
6587
+ return fn();
6588
+ }
6589
+ }
6590
+ return fn();
6591
+ }
6592
+ function buildAmqpTraceEntries(actionId, requestRid, events) {
6593
+ return buildKafkaTraceEntries(actionId, requestRid, events);
6594
+ }
6595
+ function scheduleAmqpTraceFlush(cfg, amqpCtx, actionId, requestRid, rawTraceEvents, maskReq, captureScope) {
6596
+ const sid = amqpCtx.sid;
6597
+ if (!sid)
6598
+ return;
6599
+ const rawEvents = rawTraceEvents.slice();
6600
+ scheduleSdkBackgroundWork(async () => {
6601
+ await als.run(amqpCtx, async () => {
6602
+ await drainPrivacyTasks(amqpCtx);
6603
+ const pendingEvents = [];
6604
+ for (const rawTraceEvent of rawEvents) {
6605
+ const evt = buildPendingKafkaTraceEvent(rawTraceEvent);
6606
+ if (evt)
6607
+ pendingEvents.push(evt);
6608
+ }
6609
+ let entries = [];
6610
+ if (pendingEvents.length) {
6611
+ const masking = normalizeMaskingConfig(cfg.masking);
6612
+ const preparedEvents = preparePendingTraceEventsForFlush(pendingEvents);
6613
+ const materializedEvents = await materializePendingTraceEventsAsync(preparedEvents, {
6614
+ cfg,
6615
+ maskReq,
6616
+ masking,
6617
+ resolvePrivacy: () => getRuntimePrivacyState(cfg).policy ?? null,
6618
+ });
6619
+ entries = buildAmqpTraceEntries(actionId, requestRid, materializedEvents);
6620
+ captureScope.traceBatchCount = entries.length;
6621
+ if (entries.length) {
6622
+ post(cfg, sid, { entries });
6623
+ }
6624
+ }
6625
+ else {
6626
+ captureScope.traceBatchCount = 0;
6627
+ }
6628
+ post(cfg, sid, {
6629
+ entries: [{
6630
+ actionId: actionId ?? null,
6631
+ requestRid,
6632
+ requestCaptureManifest: buildRequestCaptureManifestPayload(captureScope, entries.length),
6633
+ t: alignedNow(),
6634
+ }],
6635
+ });
6636
+ });
6637
+ }, { priority: 'high' });
6638
+ }
6639
+ function setAmqpPublishOptionsArg(args, optionsIndex, nextOptions, callbackIndex, wrappedCallback) {
6640
+ const nextArgs = args.slice();
6641
+ while (nextArgs.length <= optionsIndex) {
6642
+ nextArgs.push(undefined);
6643
+ }
6644
+ nextArgs[optionsIndex] = nextOptions;
6645
+ if (callbackIndex >= 0 && wrappedCallback) {
6646
+ if (callbackIndex === optionsIndex) {
6647
+ nextArgs[optionsIndex + 1] = wrappedCallback;
6648
+ }
6649
+ else {
6650
+ nextArgs[callbackIndex] = wrappedCallback;
6651
+ }
6652
+ }
6653
+ return nextArgs;
6654
+ }
6655
+ function scheduleAmqpPublishCapture(params) {
6656
+ if (!params.sid)
6657
+ return;
6658
+ const maskReq = {
6659
+ method: params.method,
6660
+ path: params.path,
6661
+ key: params.key,
6662
+ };
6663
+ const messagePayload = buildAmqpMessagePayload(params.content, params.options);
6664
+ const body = {
6665
+ transport: 'amqp',
6666
+ exchange: params.exchange,
6667
+ routingKey: params.routingKey,
6668
+ queue: params.queue,
6669
+ messageBytes: amqpContentSize(params.content),
6670
+ message: messagePayload,
6671
+ value: cloneKafkaTelemetryValue(messagePayload.value),
6672
+ rawValue: messagePayload.rawValue,
6673
+ valueEncoding: messagePayload.valueEncoding,
6674
+ valueBytes: messagePayload.valueBytes,
6675
+ properties: buildAmqpMessagePropertiesPayload(params.options),
6676
+ traceId: params.span?.traceId ?? null,
6677
+ spanId: params.span?.spanId ?? null,
6678
+ parentSpanId: params.span?.parentSpanId ?? null,
6679
+ };
6680
+ scheduleSdkBackgroundWork(async () => {
6681
+ const bodyMaterialization = await materializeKafkaRequestBody(params.cfg, maskReq, body);
6682
+ const requestPayload = {
6683
+ rid: params.publishRid,
6684
+ method: params.method,
6685
+ url: params.path,
6686
+ path: params.path,
6687
+ status: params.status,
6688
+ durMs: Date.now() - params.t0,
6689
+ key: params.key,
6690
+ headers: {
6691
+ transport: 'amqp',
6692
+ exchange: params.exchange,
6693
+ routingKey: params.routingKey,
6694
+ queue: params.queue,
6695
+ messageBytes: amqpContentSize(params.content),
6696
+ backpressure: params.result === false ? true : undefined,
6697
+ },
6698
+ body: bodyMaterialization.value,
6699
+ bodyMaterialization: bodyMaterialization.skipped,
6700
+ respBody: params.status >= 400
6701
+ ? { error: summarizeAmqpError(params.error) }
6702
+ : { accepted: params.result !== false, backpressure: params.result === false ? true : undefined },
6703
+ };
6704
+ post(params.cfg, params.sid, {
6705
+ entries: [{
6706
+ actionId: params.aid ?? null,
6707
+ request: requestPayload,
6708
+ t: alignedNow(),
6709
+ }],
6710
+ });
6711
+ params.captureScope.backendRequestCount += 1;
6712
+ post(params.cfg, params.sid, {
6713
+ entries: [{
6714
+ actionId: params.aid ?? null,
6715
+ requestRid: params.publishRid,
6716
+ requestCaptureManifest: buildRequestCaptureManifestPayload(params.captureScope, 0),
6717
+ t: alignedNow(),
6718
+ }],
6719
+ });
6720
+ }, { priority: 'high' });
6721
+ }
6722
+ function patchAmqplibPublishMethod(channel, cfg, methodName) {
6723
+ const orig = channel?.[methodName];
6724
+ if (typeof orig !== 'function' || orig.__repro_amqplib_patched)
6725
+ return;
6726
+ const optionsIndex = methodName === 'publish' ? 3 : 2;
6727
+ const method = methodName === 'publish' ? 'AMQP_PUBLISH' : 'AMQP_SEND_TO_QUEUE';
6728
+ const wrapped = function reproPatchedAmqplibPublish(...args) {
6729
+ const ctx = getCtx();
6730
+ const fallback = cfg.resolveContext?.() ?? {};
6731
+ const sid = ctx.sid ?? fallback.sid ?? null;
6732
+ const aid = ctx.aid ?? fallback.aid ?? null;
6733
+ const span = captureSpanContextFromTracer();
6734
+ const publishRid = nextRequestId(alignedNow());
6735
+ const propagationValues = {
6736
+ [KAFKA_HEADER_TRACE_ID]: span?.traceId ?? null,
6737
+ [KAFKA_HEADER_SPAN_ID]: span?.spanId === null || span?.spanId === undefined ? null : String(span.spanId),
6738
+ [KAFKA_HEADER_PARENT_SPAN_ID]: span?.parentSpanId === null || span?.parentSpanId === undefined ? null : String(span.parentSpanId),
6739
+ [KAFKA_HEADER_REQUEST_ID]: publishRid,
6740
+ [KAFKA_HEADER_SESSION_ID]: sid,
6741
+ [KAFKA_HEADER_ACTION_ID]: aid,
6742
+ };
6743
+ const shouldPropagate = hasAmqpPropagationValues(propagationValues);
6744
+ const callbackIndex = args.length > 0 && typeof args[args.length - 1] === 'function'
6745
+ ? args.length - 1
6746
+ : -1;
6747
+ const originalOptions = callbackIndex === optionsIndex ? undefined : args[optionsIndex];
6748
+ const nextOptions = shouldPropagate
6749
+ ? withAmqpPropagationOptions(originalOptions, propagationValues)
6750
+ : originalOptions;
6751
+ const exchange = methodName === 'publish' ? sanitizeAmqpExchange(args[0]) : '';
6752
+ const routingKey = methodName === 'publish' ? sanitizeAmqpRoutingKey(args[1]) : undefined;
6753
+ const queue = methodName === 'sendToQueue' ? sanitizeAmqpQueue(args[0]) : undefined;
6754
+ const path = methodName === 'publish'
6755
+ ? `amqp://${exchange || 'default'}/${routingKey}`
6756
+ : `amqp://queue/${queue}`;
6757
+ const key = `${method} ${methodName === 'publish' ? `${exchange || 'default'}/${routingKey}` : queue}`;
6758
+ const content = methodName === 'publish' ? args[2] : args[1];
6759
+ const captureScope = createRequestCaptureScope(publishRid, 'amqp');
6760
+ const t0 = Date.now();
6761
+ let finished = false;
6762
+ const finish = (status, error, result) => {
6763
+ if (finished)
6764
+ return;
6765
+ finished = true;
6766
+ scheduleAmqpPublishCapture({
6767
+ cfg,
6768
+ sid,
6769
+ aid,
6770
+ publishRid,
6771
+ captureScope,
6772
+ method,
6773
+ path,
6774
+ key,
6775
+ exchange,
6776
+ routingKey,
6777
+ queue,
6778
+ content,
6779
+ options: nextOptions,
6780
+ span,
6781
+ t0,
6782
+ status,
6783
+ error,
6784
+ result,
6785
+ });
6786
+ };
6787
+ const originalCallback = callbackIndex >= 0 ? args[callbackIndex] : null;
6788
+ const wrappedCallback = typeof originalCallback === 'function'
6789
+ ? function reproAmqplibPublishCallback(...callbackArgs) {
6790
+ const error = callbackArgs[0];
6791
+ finish(error ? 500 : 200, error, callbackArgs[1]);
6792
+ return originalCallback.apply(this, callbackArgs);
6793
+ }
6794
+ : undefined;
6795
+ const nextArgs = shouldPropagate
6796
+ ? setAmqpPublishOptionsArg(args, optionsIndex, nextOptions, callbackIndex, wrappedCallback)
6797
+ : (wrappedCallback
6798
+ ? setAmqpPublishOptionsArg(args, optionsIndex, nextOptions, callbackIndex, wrappedCallback)
6799
+ : args);
6800
+ try {
6801
+ const result = orig.apply(this, nextArgs);
6802
+ if (!wrappedCallback) {
6803
+ finish(200, undefined, result);
6804
+ }
6805
+ return result;
6806
+ }
6807
+ catch (error) {
6808
+ finish(500, error);
6809
+ throw error;
6810
+ }
6811
+ };
6812
+ wrapped.__repro_amqplib_patched = true;
6813
+ channel[methodName] = wrapped;
6814
+ }
6815
+ function wrapAmqplibConsumeHandler(onMessage, cfg, queue) {
6816
+ return function reproAmqplibConsumeMessage(message) {
6817
+ if (message === null || message === undefined) {
6818
+ return onMessage.call(this, message);
6819
+ }
6820
+ const queueName = sanitizeAmqpQueue(queue);
6821
+ const properties = message?.properties ?? {};
6822
+ const headers = properties?.headers;
6823
+ const runtime = resolveAmqpContext(cfg, headers);
6824
+ const sid = runtime.sid;
6825
+ const aid = runtime.aid;
6826
+ const deliveryTag = message?.fields?.deliveryTag ?? alignedNow();
6827
+ const consumeRid = nextRequestId(`${queueName}-${deliveryTag}`);
6828
+ const traceId = consumeRid;
6829
+ const captureScope = createRequestCaptureScope(consumeRid, 'amqp');
6830
+ const rawTraceEvents = [];
6831
+ const maskReq = {
6832
+ method: 'AMQP_CONSUME',
6833
+ path: `amqp://queue/${queueName}`,
6834
+ key: `AMQP_CONSUME ${queueName}`,
6835
+ };
6836
+ const amqpCtx = {
6837
+ sid: sid ?? undefined,
6838
+ aid: aid ?? undefined,
6839
+ rid: consumeRid,
6840
+ clockSkewMs: 0,
6841
+ excludedSpanIds: new Set(),
6842
+ maskReq,
6843
+ privacyTasks: new Set(),
6844
+ captureScope,
6845
+ };
6846
+ let unsubscribe;
6847
+ const subscribeTrace = () => {
6848
+ if (!__TRACER__?.tracer?.on)
6849
+ return;
6850
+ try {
6851
+ unsubscribe = __TRACER__.tracer.on((event) => {
6852
+ if (!event || event.traceId !== traceId)
6853
+ return;
6854
+ rawTraceEvents.push(event);
6855
+ });
6856
+ }
6857
+ catch { }
6858
+ };
6859
+ const unsubscribeTrace = () => {
6860
+ try {
6861
+ unsubscribe && unsubscribe();
6862
+ }
6863
+ catch { }
6864
+ unsubscribe = undefined;
6865
+ };
6866
+ const invoke = () => {
6867
+ subscribeTrace();
6868
+ try {
6869
+ const result = onMessage.call(this, message);
6870
+ if (result && typeof result.then === 'function') {
6871
+ return result.finally(() => {
6872
+ unsubscribeTrace();
6873
+ });
6874
+ }
6875
+ unsubscribeTrace();
6876
+ return result;
6877
+ }
6878
+ catch (error) {
6879
+ unsubscribeTrace();
6880
+ throw error;
6881
+ }
6882
+ };
6883
+ const runInAls = () => {
6884
+ if (!sid && !aid)
6885
+ return invoke();
6886
+ return als.run(amqpCtx, () => invoke());
6887
+ };
6888
+ const t0 = Date.now();
6889
+ let finished = false;
6890
+ const finish = (threw, error) => {
6891
+ if (finished)
6892
+ return;
6893
+ finished = true;
6894
+ if (!sid)
6895
+ return;
6896
+ const fields = message?.fields ?? {};
6897
+ const messagePayload = buildAmqpMessagePayload(message?.content, properties);
6898
+ const body = {
6899
+ transport: 'amqp',
6900
+ queue: queueName,
6901
+ exchange: sanitizeAmqpExchange(fields.exchange),
6902
+ routingKey: sanitizeAmqpRoutingKey(fields.routingKey),
6903
+ deliveryTag: fields.deliveryTag ?? null,
6904
+ redelivered: fields.redelivered ?? null,
6905
+ consumerTag: fields.consumerTag ?? null,
6906
+ parentRequestRid: runtime.requestRid,
6907
+ parentTraceId: runtime.traceId,
6908
+ parentSpanId: runtime.parentSpanId,
6909
+ messageBytes: amqpContentSize(message?.content),
6910
+ message: messagePayload,
6911
+ value: cloneKafkaTelemetryValue(messagePayload.value),
6912
+ rawValue: messagePayload.rawValue,
6913
+ valueEncoding: messagePayload.valueEncoding,
6914
+ valueBytes: messagePayload.valueBytes,
6915
+ properties: buildAmqpMessagePropertiesPayload(properties),
6916
+ };
6917
+ scheduleSdkBackgroundWork(async () => {
6918
+ const bodyMaterialization = await materializeKafkaRequestBody(cfg, maskReq, body);
6919
+ const requestPayload = {
6920
+ rid: consumeRid,
6921
+ method: 'AMQP_CONSUME',
6922
+ url: `amqp://queue/${queueName}`,
6923
+ path: `amqp://queue/${queueName}`,
6924
+ status: threw ? 500 : 200,
6925
+ durMs: Date.now() - t0,
6926
+ key: `AMQP_CONSUME ${queueName}`,
6927
+ headers: normalizeAmqpHeadersForPayload(headers),
6928
+ body: bodyMaterialization.value,
6929
+ bodyMaterialization: bodyMaterialization.skipped,
6930
+ respBody: threw ? { error: summarizeAmqpError(error) } : undefined,
6931
+ };
6932
+ post(cfg, sid, {
6933
+ entries: [{
6934
+ actionId: aid ?? null,
6935
+ request: requestPayload,
6936
+ t: alignedNow(),
6937
+ }],
6938
+ });
6939
+ captureScope.backendRequestCount += 1;
6940
+ scheduleAmqpTraceFlush(cfg, amqpCtx, aid, consumeRid, rawTraceEvents, maskReq, captureScope);
6941
+ }, { priority: 'high' });
6942
+ };
6943
+ try {
6944
+ const result = withOptionalTraceContextSync(traceId, runInAls);
6945
+ if (result && typeof result.then === 'function') {
6946
+ return result.then((value) => {
6947
+ finish(false);
6948
+ return value;
6949
+ }, (error) => {
6950
+ finish(true, error);
6951
+ throw error;
6952
+ });
6953
+ }
6954
+ finish(false);
6955
+ return result;
6956
+ }
6957
+ catch (error) {
6958
+ finish(true, error);
6959
+ throw error;
6960
+ }
6961
+ };
6962
+ }
6963
+ function patchAmqplibChannel(channel, cfg) {
6964
+ if (!channel || channel.__repro_amqplib_channel_patched)
6965
+ return;
6966
+ channel.__repro_amqplib_channel_patched = true;
6967
+ patchAmqplibPublishMethod(channel, cfg, 'publish');
6968
+ patchAmqplibPublishMethod(channel, cfg, 'sendToQueue');
6969
+ const origConsume = channel.consume;
6970
+ if (typeof origConsume === 'function' && !origConsume.__repro_amqplib_patched) {
6971
+ const wrapped = function reproPatchedAmqplibConsume(queue, onMessage, ...rest) {
6972
+ if (typeof onMessage !== 'function') {
6973
+ return origConsume.call(this, queue, onMessage, ...rest);
6974
+ }
6975
+ return origConsume.call(this, queue, wrapAmqplibConsumeHandler(onMessage, cfg, queue), ...rest);
6976
+ };
6977
+ wrapped.__repro_amqplib_patched = true;
6978
+ channel.consume = wrapped;
6979
+ }
6980
+ }
6981
+ function wrapAmqplibChannelFactory(connection, cfg, methodName) {
6982
+ const orig = connection?.[methodName];
6983
+ if (typeof orig !== 'function' || orig.__repro_amqplib_patched)
6984
+ return;
6985
+ const wrapped = function reproPatchedAmqplibCreateChannel(...args) {
6986
+ const callbackIndex = args.length > 0 && typeof args[args.length - 1] === 'function'
6987
+ ? args.length - 1
6988
+ : -1;
6989
+ const nextArgs = args.slice();
6990
+ if (callbackIndex >= 0) {
6991
+ const originalCallback = args[callbackIndex];
6992
+ nextArgs[callbackIndex] = function reproAmqplibCreateChannelCallback(error, channel, ...rest) {
6993
+ if (channel)
6994
+ patchAmqplibChannel(channel, cfg);
6995
+ return originalCallback.call(this, error, channel, ...rest);
6996
+ };
6997
+ }
6998
+ const result = orig.apply(this, nextArgs);
6999
+ if (result && typeof result.then === 'function') {
7000
+ return result.then((channel) => {
7001
+ patchAmqplibChannel(channel, cfg);
7002
+ return channel;
7003
+ });
7004
+ }
7005
+ if (result)
7006
+ patchAmqplibChannel(result, cfg);
7007
+ return result;
7008
+ };
7009
+ wrapped.__repro_amqplib_patched = true;
7010
+ connection[methodName] = wrapped;
7011
+ }
7012
+ function patchAmqplibConnection(connection, cfg) {
7013
+ if (!connection || connection.__repro_amqplib_connection_patched)
7014
+ return;
7015
+ connection.__repro_amqplib_connection_patched = true;
7016
+ wrapAmqplibChannelFactory(connection, cfg, 'createChannel');
7017
+ wrapAmqplibChannelFactory(connection, cfg, 'createConfirmChannel');
7018
+ }
7019
+ function patchAmqplibModule(amqpModule, cfg) {
7020
+ if (!amqpModule || typeof amqpModule !== 'object')
7021
+ return;
7022
+ const targets = new Set([amqpModule]);
7023
+ if (amqpModule.default && typeof amqpModule.default === 'object') {
7024
+ targets.add(amqpModule.default);
7025
+ }
7026
+ for (const target of targets) {
7027
+ if (!target || target.__repro_amqplib_module_patched)
7028
+ continue;
7029
+ const origConnect = target.connect;
7030
+ if (typeof origConnect !== 'function')
7031
+ continue;
7032
+ target.__repro_amqplib_module_patched = true;
7033
+ target.connect = function reproPatchedAmqplibConnect(...args) {
7034
+ const callbackIndex = args.length > 0 && typeof args[args.length - 1] === 'function'
7035
+ ? args.length - 1
7036
+ : -1;
7037
+ const nextArgs = args.slice();
7038
+ if (callbackIndex >= 0) {
7039
+ const originalCallback = args[callbackIndex];
7040
+ nextArgs[callbackIndex] = function reproAmqplibConnectCallback(error, connection, ...rest) {
7041
+ if (connection)
7042
+ patchAmqplibConnection(connection, cfg);
7043
+ return originalCallback.call(this, error, connection, ...rest);
7044
+ };
7045
+ }
7046
+ const result = origConnect.apply(this, nextArgs);
7047
+ if (result && typeof result.then === 'function') {
7048
+ return result.then((connection) => {
7049
+ patchAmqplibConnection(connection, cfg);
7050
+ return connection;
7051
+ });
7052
+ }
7053
+ if (result)
7054
+ patchAmqplibConnection(result, cfg);
7055
+ return result;
7056
+ };
7057
+ }
7058
+ }
7059
+ const amqplibPatchConfigs = [];
7060
+ let amqplibRequireHookInstalled = false;
7061
+ function installAmqplibRequireHook() {
7062
+ if (amqplibRequireHookInstalled)
7063
+ return;
7064
+ amqplibRequireHookInstalled = true;
7065
+ try {
7066
+ const rim = requireOptionalHostModule('require-in-the-middle');
7067
+ const Hook = rim?.Hook ?? rim;
7068
+ if (typeof Hook !== 'function')
7069
+ return;
7070
+ // eslint-disable-next-line no-new
7071
+ new Hook(['amqplib', 'amqplib/callback_api'], (exports) => {
7072
+ for (const cfg of amqplibPatchConfigs) {
7073
+ patchAmqplibModule(exports, cfg);
7074
+ }
7075
+ return exports;
7076
+ });
7077
+ }
7078
+ catch { }
7079
+ }
7080
+ function patchAmqplib(cfg) {
7081
+ amqplibPatchConfigs.push(cfg);
7082
+ installAmqplibRequireHook();
7083
+ const amqpModules = new Set();
7084
+ const resolvedAmqpModule = requireOptionalHostModule('amqplib');
7085
+ if (resolvedAmqpModule) {
7086
+ amqpModules.add(resolvedAmqpModule);
7087
+ }
7088
+ const resolvedAmqpCallbackModule = requireOptionalHostModule('amqplib/callback_api');
7089
+ if (resolvedAmqpCallbackModule) {
7090
+ amqpModules.add(resolvedAmqpCallbackModule);
7091
+ }
7092
+ for (const loadedAmqpModule of getLoadedModuleExportsByPackage('amqplib')) {
7093
+ amqpModules.add(loadedAmqpModule);
7094
+ }
7095
+ if (!amqpModules.size)
7096
+ return;
7097
+ for (const amqpModule of amqpModules) {
7098
+ patchAmqplibModule(amqpModule, cfg);
7099
+ }
7100
+ }
7101
+ exports.patchAmqplib = patchAmqplib;
6327
7102
  const redisPatchConfigs = [];
6328
7103
  let redisRequireHookInstalled = false;
6329
7104
  const REDIS_KEYLESS_COMMANDS = new Set([
@@ -7037,6 +7812,7 @@ async function initRepro(cfg) {
7037
7812
  skipUrls: [resolveIngestUrl(ingestCfg)],
7038
7813
  });
7039
7814
  patchKafkaJs(integrationCfg);
7815
+ patchAmqplib(integrationCfg);
7040
7816
  patchRedis(integrationCfg);
7041
7817
  patchSendgridMail(integrationCfg);
7042
7818
  patchMongooseIntegration(reproAutoMiddlewareConfig);
@@ -7081,6 +7857,10 @@ exports.__reproTestHooks = {
7081
7857
  materializeInlinePrivacyValueAsyncForTest: materializeInlinePrivacyValueAsync,
7082
7858
  patchKafkaProducerInstanceForTest: patchKafkaProducerInstance,
7083
7859
  wrapKafkaEachMessageHandlerForTest: wrapKafkaEachMessageHandler,
7860
+ patchAmqplibModuleForTest: patchAmqplibModule,
7861
+ patchAmqplibConnectionForTest: patchAmqplibConnection,
7862
+ patchAmqplibChannelForTest: patchAmqplibChannel,
7863
+ wrapAmqplibConsumeHandlerForTest: wrapAmqplibConsumeHandler,
7084
7864
  chunkTraceEventsForTransportForTest: chunkTraceEventsForTransport,
7085
7865
  estimateTraceBatchSerializedBytesForTest: estimateTraceBatchSerializedBytes,
7086
7866
  sanitizeTraceValueForPrivacyForTest: sanitizeTraceValueForPrivacy,