@reproapp/node-sdk 0.0.30 → 0.0.32

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.d.ts CHANGED
@@ -262,6 +262,31 @@ export type ReproTracingInitOptions = TracerInitOpts & {
262
262
  export declare function initReproTracing(opts?: ReproTracingInitOptions): TracerApi | null;
263
263
  /** Optional helper if users want to check it. */
264
264
  export declare function isReproTracingEnabled(): boolean;
265
+ type Ctx = {
266
+ sid?: string;
267
+ aid?: string;
268
+ rid?: string;
269
+ clockSkewMs?: number;
270
+ excludedSpanIds?: Set<string>;
271
+ maskReq?: MaskRequestContext;
272
+ privacyTasks?: Set<Promise<void>>;
273
+ captureScope?: RequestCaptureScopeState;
274
+ nativeMongoSuppressions?: NativeMongoSuppression[];
275
+ };
276
+ type NativeMongoSuppression = {
277
+ collection?: string | null;
278
+ ops?: Set<string>;
279
+ startedAt: number;
280
+ ownerStore?: Ctx;
281
+ };
282
+ type RequestCaptureScopeState = {
283
+ requestRid: string;
284
+ transport: 'http' | 'kafka' | 'amqp' | 'background';
285
+ backendRequestCount: number;
286
+ traceBatchCount: number;
287
+ dbChangeCount: number;
288
+ emailEventCount: number;
289
+ };
265
290
  declare function sanitizeTraceValueForPrivacy(value: any): any;
266
291
  declare function sanitizeMaterializedTraceValue(value: any): any;
267
292
  export declare function __materializePendingTraceEventsForWorker(payload: TraceMaterializationWorkerPayload): Promise<PendingTraceEventRecord[]>;
@@ -382,6 +407,8 @@ export declare const __reproTestHooks: {
382
407
  }): void;
383
408
  drainSdkBackgroundQueueForTest(): Promise<void>;
384
409
  resetSdkBackgroundQueuesForTest(): void;
410
+ runWithRequestContextForTest<T>(ctx: Partial<Ctx>, fn: () => T): T;
411
+ getNativeMongoSuppressionCountForTest(): number;
385
412
  getRuntimePrivacyPolicyForTest(cfg: ReproMiddlewareConfig): NormalizedRuntimePrivacyPolicy | null;
386
413
  setRuntimePrivacyPolicyForTest(cfg: ReproMiddlewareConfig, policy: NormalizedRuntimePrivacyPolicy | null): void;
387
414
  recordKafkaTraceEventAsyncForTest: typeof recordKafkaTraceEventAsync;
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ const async_hooks_1 = require("async_hooks");
6
6
  const crypto_1 = require("crypto");
7
7
  const module_1 = require("module");
8
8
  const path_1 = require("path");
9
+ const url_1 = require("url");
9
10
  const client_1 = require("./ingest/client");
10
11
  const privacy_1 = require("./privacy");
11
12
  /**
@@ -834,6 +835,7 @@ function pushNativeMongoSuppression(collection, ops) {
834
835
  collection: collection == null ? null : String(collection),
835
836
  ops: normalizedOps.length ? new Set(normalizedOps) : undefined,
836
837
  startedAt: Date.now(),
838
+ ownerStore: store,
837
839
  };
838
840
  if (!Array.isArray(store.nativeMongoSuppressions)) {
839
841
  store.nativeMongoSuppressions = [];
@@ -844,13 +846,27 @@ function pushNativeMongoSuppression(collection, ops) {
844
846
  function popNativeMongoSuppression(token) {
845
847
  if (!token)
846
848
  return;
847
- const store = als.getStore();
849
+ const store = token.ownerStore ?? als.getStore();
848
850
  const suppressions = store?.nativeMongoSuppressions;
849
- if (!Array.isArray(suppressions) || suppressions.length === 0)
850
- return;
851
- const index = suppressions.indexOf(token);
852
- if (index >= 0) {
853
- suppressions.splice(index, 1);
851
+ if (Array.isArray(suppressions) && suppressions.length > 0) {
852
+ const index = suppressions.indexOf(token);
853
+ if (index >= 0) {
854
+ suppressions.splice(index, 1);
855
+ }
856
+ }
857
+ token.ownerStore = undefined;
858
+ }
859
+ function releaseNativeMongoSuppression(target) {
860
+ const token = target?.__repro_native_mongo_suppression;
861
+ popNativeMongoSuppression(token);
862
+ try {
863
+ delete target.__repro_native_mongo_suppression;
864
+ }
865
+ catch {
866
+ try {
867
+ target.__repro_native_mongo_suppression = undefined;
868
+ }
869
+ catch { }
854
870
  }
855
871
  }
856
872
  function isNativeMongoSuppressed(collection, op) {
@@ -860,9 +876,12 @@ function isNativeMongoSuppressed(collection, op) {
860
876
  const normalizedCollection = collection == null ? null : String(collection);
861
877
  const normalizedOp = normalizeNativeMongoSuppressionOp(op);
862
878
  const now = Date.now();
863
- for (const token of suppressions) {
864
- if (!token || now - token.startedAt > 60000)
879
+ for (let i = suppressions.length - 1; i >= 0; i -= 1) {
880
+ const token = suppressions[i];
881
+ if (!token || now - token.startedAt > 60000) {
882
+ suppressions.splice(i, 1);
865
883
  continue;
884
+ }
866
885
  if (token.collection && normalizedCollection && token.collection !== normalizedCollection)
867
886
  continue;
868
887
  if (token.ops && token.ops.size > 0 && !token.ops.has(normalizedOp))
@@ -4633,40 +4652,44 @@ function reproMongoosePlugin(cfg) {
4633
4652
  next();
4634
4653
  });
4635
4654
  schema.post('save', { document: true }, function () {
4636
- const { sid, aid } = getCtx();
4637
- if (!sid || !aid)
4638
- return;
4639
- if (this.$isSubdocument)
4640
- return;
4641
- const meta = this.__repro_meta || {};
4642
- const before = null;
4643
- const after = this;
4644
- const collection = meta.collection || resolveCollectionOrWarn(this, 'doc');
4645
- const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
4646
- if (!shouldCaptureDbSpan(spanContext))
4647
- return;
4648
- const modifiedPaths = Array.isArray(meta.modifiedPaths) ? meta.modifiedPaths : [];
4649
- const query = meta.wasNew
4650
- ? { op: 'insertOne', doc: after }
4651
- : {
4652
- filter: { _id: this._id },
4653
- update: buildModifiedPathUpdate(this, modifiedPaths),
4654
- options: { upsert: false },
4655
- };
4656
- emitDbQuery(cfg, sid, aid ?? undefined, {
4657
- collection,
4658
- pk: { _id: this._id },
4659
- before,
4660
- after,
4661
- op: meta.wasNew ? 'insert' : 'update',
4662
- query,
4663
- t: alignTimestamp(meta.t0 ?? Date.now()),
4664
- spanContext,
4665
- });
4666
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4655
+ try {
4656
+ const { sid, aid } = getCtx();
4657
+ if (!sid || !aid)
4658
+ return;
4659
+ if (this.$isSubdocument)
4660
+ return;
4661
+ const meta = this.__repro_meta || {};
4662
+ const before = null;
4663
+ const after = this;
4664
+ const collection = meta.collection || resolveCollectionOrWarn(this, 'doc');
4665
+ const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
4666
+ if (!shouldCaptureDbSpan(spanContext))
4667
+ return;
4668
+ const modifiedPaths = Array.isArray(meta.modifiedPaths) ? meta.modifiedPaths : [];
4669
+ const query = meta.wasNew
4670
+ ? { op: 'insertOne', doc: after }
4671
+ : {
4672
+ filter: { _id: this._id },
4673
+ update: buildModifiedPathUpdate(this, modifiedPaths),
4674
+ options: { upsert: false },
4675
+ };
4676
+ emitDbQuery(cfg, sid, aid ?? undefined, {
4677
+ collection,
4678
+ pk: { _id: this._id },
4679
+ before,
4680
+ after,
4681
+ op: meta.wasNew ? 'insert' : 'update',
4682
+ query,
4683
+ t: alignTimestamp(meta.t0 ?? Date.now()),
4684
+ spanContext,
4685
+ });
4686
+ }
4687
+ finally {
4688
+ releaseNativeMongoSuppression(this);
4689
+ }
4667
4690
  });
4668
4691
  schema.post('save', { document: true }, function (error, _doc, next) {
4669
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4692
+ releaseNativeMongoSuppression(this);
4670
4693
  next(error);
4671
4694
  });
4672
4695
  // -------- findOneAndUpdate capture (unchanged) --------
@@ -4688,34 +4711,38 @@ function reproMongoosePlugin(cfg) {
4688
4711
  next();
4689
4712
  });
4690
4713
  schema.post('findOneAndUpdate', function (res) {
4691
- const { sid, aid } = getCtx();
4692
- if (!sid || !aid)
4693
- return;
4694
- const before = null;
4695
- const after = res ?? null;
4696
- const collection = this.__repro_collection || resolveCollectionOrWarn(this, 'query');
4697
- const spanContext = this.__repro_spanContext || captureSpanContextFromTracer(this);
4698
- if (!shouldCaptureDbSpan(spanContext))
4699
- return;
4700
- const filter = this.__repro_filter;
4701
- const pk = after?._id ?? (filter && typeof filter === 'object' ? filter._id : undefined);
4702
- emitDbQuery(cfg, sid, aid ?? undefined, {
4703
- collection,
4704
- pk: { _id: pk },
4705
- before,
4706
- after,
4707
- op: 'update',
4708
- queryRaw: {
4709
- filter,
4710
- update: this.__repro_update,
4711
- },
4712
- t: alignTimestamp(this.__repro_t0 ?? Date.now()),
4713
- spanContext,
4714
- });
4715
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4714
+ try {
4715
+ const { sid, aid } = getCtx();
4716
+ if (!sid || !aid)
4717
+ return;
4718
+ const before = null;
4719
+ const after = res ?? null;
4720
+ const collection = this.__repro_collection || resolveCollectionOrWarn(this, 'query');
4721
+ const spanContext = this.__repro_spanContext || captureSpanContextFromTracer(this);
4722
+ if (!shouldCaptureDbSpan(spanContext))
4723
+ return;
4724
+ const filter = this.__repro_filter;
4725
+ const pk = after?._id ?? (filter && typeof filter === 'object' ? filter._id : undefined);
4726
+ emitDbQuery(cfg, sid, aid ?? undefined, {
4727
+ collection,
4728
+ pk: { _id: pk },
4729
+ before,
4730
+ after,
4731
+ op: 'update',
4732
+ queryRaw: {
4733
+ filter,
4734
+ update: this.__repro_update,
4735
+ },
4736
+ t: alignTimestamp(this.__repro_t0 ?? Date.now()),
4737
+ spanContext,
4738
+ });
4739
+ }
4740
+ finally {
4741
+ releaseNativeMongoSuppression(this);
4742
+ }
4716
4743
  });
4717
4744
  schema.post('findOneAndUpdate', function (error, _res, next) {
4718
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4745
+ releaseNativeMongoSuppression(this);
4719
4746
  next(error);
4720
4747
  });
4721
4748
  // -------- deleteOne capture (unchanged) --------
@@ -4735,29 +4762,33 @@ function reproMongoosePlugin(cfg) {
4735
4762
  next();
4736
4763
  });
4737
4764
  schema.post('deleteOne', { document: false, query: true }, function () {
4738
- const { sid, aid } = getCtx();
4739
- if (!sid || !aid)
4740
- return;
4741
- const before = null;
4742
- const collection = this.__repro_collection || resolveCollectionOrWarn(this, 'query');
4743
- const filter = this.__repro_filter ?? undefined;
4744
- const spanContext = this.__repro_spanContext || captureSpanContextFromTracer(this);
4745
- if (!shouldCaptureDbSpan(spanContext))
4746
- return;
4747
- emitDbQuery(cfg, sid, aid ?? undefined, {
4748
- collection,
4749
- pk: filter && typeof filter === 'object' && '_id' in filter ? { _id: filter._id } : undefined,
4750
- before,
4751
- after: null,
4752
- op: 'delete',
4753
- queryRaw: { filter },
4754
- t: alignTimestamp(this.__repro_t0 ?? Date.now()),
4755
- spanContext,
4756
- });
4757
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4765
+ try {
4766
+ const { sid, aid } = getCtx();
4767
+ if (!sid || !aid)
4768
+ return;
4769
+ const before = null;
4770
+ const collection = this.__repro_collection || resolveCollectionOrWarn(this, 'query');
4771
+ const filter = this.__repro_filter ?? undefined;
4772
+ const spanContext = this.__repro_spanContext || captureSpanContextFromTracer(this);
4773
+ if (!shouldCaptureDbSpan(spanContext))
4774
+ return;
4775
+ emitDbQuery(cfg, sid, aid ?? undefined, {
4776
+ collection,
4777
+ pk: filter && typeof filter === 'object' && '_id' in filter ? { _id: filter._id } : undefined,
4778
+ before,
4779
+ after: null,
4780
+ op: 'delete',
4781
+ queryRaw: { filter },
4782
+ t: alignTimestamp(this.__repro_t0 ?? Date.now()),
4783
+ spanContext,
4784
+ });
4785
+ }
4786
+ finally {
4787
+ releaseNativeMongoSuppression(this);
4788
+ }
4758
4789
  });
4759
4790
  schema.post('deleteOne', { document: false, query: true }, function (error, _res, next) {
4760
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4791
+ releaseNativeMongoSuppression(this);
4761
4792
  next(error);
4762
4793
  });
4763
4794
  // -------- NON-intrusive generic query telemetry via schema hooks -------
@@ -4813,29 +4844,33 @@ function reproMongoosePlugin(cfg) {
4813
4844
  next();
4814
4845
  });
4815
4846
  schema.post(op, function (res) {
4816
- const { sid, aid } = getCtx();
4817
- if (!sid)
4818
- return;
4819
- const meta = this.__repro_qmeta || { t0: Date.now(), collection: 'unknown', op };
4820
- const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
4821
- emitDbQuery(cfg, sid, aid, {
4822
- collection: meta.collection,
4823
- op,
4824
- queryRaw: {
4825
- filter: meta.rawFilter,
4826
- update: meta.rawUpdate,
4827
- projection: meta.rawProjection,
4828
- options: meta.rawOptions,
4829
- },
4830
- resultMetaRaw: res,
4831
- durMs: Date.now() - meta.t0,
4832
- t: alignedNow(),
4833
- spanContext,
4834
- });
4835
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4847
+ try {
4848
+ const { sid, aid } = getCtx();
4849
+ if (!sid)
4850
+ return;
4851
+ const meta = this.__repro_qmeta || { t0: Date.now(), collection: 'unknown', op };
4852
+ const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
4853
+ emitDbQuery(cfg, sid, aid, {
4854
+ collection: meta.collection,
4855
+ op,
4856
+ queryRaw: {
4857
+ filter: meta.rawFilter,
4858
+ update: meta.rawUpdate,
4859
+ projection: meta.rawProjection,
4860
+ options: meta.rawOptions,
4861
+ },
4862
+ resultMetaRaw: res,
4863
+ durMs: Date.now() - meta.t0,
4864
+ t: alignedNow(),
4865
+ spanContext,
4866
+ });
4867
+ }
4868
+ finally {
4869
+ releaseNativeMongoSuppression(this);
4870
+ }
4836
4871
  });
4837
4872
  schema.post(op, function (error, _res, next) {
4838
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4873
+ releaseNativeMongoSuppression(this);
4839
4874
  next(error);
4840
4875
  });
4841
4876
  }
@@ -4864,24 +4899,28 @@ function reproMongoosePlugin(cfg) {
4864
4899
  next();
4865
4900
  });
4866
4901
  schema.post('insertMany', { document: false, query: false }, function (docs) {
4867
- const { sid, aid } = getCtx();
4868
- if (!sid)
4869
- return;
4870
- const meta = this.__repro_insert_meta || { t0: Date.now(), collection: 'unknown' };
4871
- const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
4872
- emitDbQuery(cfg, sid, aid ?? undefined, {
4873
- collection: meta.collection,
4874
- op: 'insertMany',
4875
- queryRaw: { docs: meta.rawDocs ?? undefined },
4876
- resultMetaRaw: docs,
4877
- durMs: Date.now() - meta.t0,
4878
- t: alignedNow(),
4879
- spanContext,
4880
- });
4881
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4902
+ try {
4903
+ const { sid, aid } = getCtx();
4904
+ if (!sid)
4905
+ return;
4906
+ const meta = this.__repro_insert_meta || { t0: Date.now(), collection: 'unknown' };
4907
+ const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
4908
+ emitDbQuery(cfg, sid, aid ?? undefined, {
4909
+ collection: meta.collection,
4910
+ op: 'insertMany',
4911
+ queryRaw: { docs: meta.rawDocs ?? undefined },
4912
+ resultMetaRaw: docs,
4913
+ durMs: Date.now() - meta.t0,
4914
+ t: alignedNow(),
4915
+ spanContext,
4916
+ });
4917
+ }
4918
+ finally {
4919
+ releaseNativeMongoSuppression(this);
4920
+ }
4882
4921
  });
4883
4922
  schema.post('insertMany', { document: false, query: false }, function (error, _res, next) {
4884
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4923
+ releaseNativeMongoSuppression(this);
4885
4924
  next(error);
4886
4925
  });
4887
4926
  schema.pre('bulkWrite', { document: false, query: false }, function (next, ops) {
@@ -4906,24 +4945,28 @@ function reproMongoosePlugin(cfg) {
4906
4945
  next();
4907
4946
  });
4908
4947
  schema.post('bulkWrite', { document: false, query: false }, function (res) {
4909
- const { sid, aid } = getCtx();
4910
- if (!sid)
4911
- return;
4912
- const meta = this.__repro_bulk_meta || { t0: Date.now(), collection: 'unknown' };
4913
- const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
4914
- emitDbQuery(cfg, sid, aid, {
4915
- collection: meta.collection,
4916
- op: 'bulkWrite',
4917
- queryRaw: { ops: meta.rawOps ?? undefined },
4918
- resultMetaRaw: res,
4919
- durMs: Date.now() - meta.t0,
4920
- t: alignedNow(),
4921
- spanContext,
4922
- });
4923
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4948
+ try {
4949
+ const { sid, aid } = getCtx();
4950
+ if (!sid)
4951
+ return;
4952
+ const meta = this.__repro_bulk_meta || { t0: Date.now(), collection: 'unknown' };
4953
+ const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
4954
+ emitDbQuery(cfg, sid, aid, {
4955
+ collection: meta.collection,
4956
+ op: 'bulkWrite',
4957
+ queryRaw: { ops: meta.rawOps ?? undefined },
4958
+ resultMetaRaw: res,
4959
+ durMs: Date.now() - meta.t0,
4960
+ t: alignedNow(),
4961
+ spanContext,
4962
+ });
4963
+ }
4964
+ finally {
4965
+ releaseNativeMongoSuppression(this);
4966
+ }
4924
4967
  });
4925
4968
  schema.post('bulkWrite', { document: false, query: false }, function (error, _res, next) {
4926
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4969
+ releaseNativeMongoSuppression(this);
4927
4970
  next(error);
4928
4971
  });
4929
4972
  // Aggregate middleware (non-intrusive)
@@ -4953,24 +4996,28 @@ function reproMongoosePlugin(cfg) {
4953
4996
  next();
4954
4997
  });
4955
4998
  schema.post('aggregate', function (res) {
4956
- const { sid, aid } = getCtx();
4957
- if (!sid)
4958
- return;
4959
- const meta = this.__repro_aggmeta || { t0: Date.now(), collection: 'unknown' };
4960
- const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
4961
- emitDbQuery(cfg, sid, aid, {
4962
- collection: meta.collection,
4963
- op: 'aggregate',
4964
- queryRaw: { pipeline: meta.rawPipeline },
4965
- resultMetaRaw: res,
4966
- durMs: Date.now() - meta.t0,
4967
- t: alignedNow(),
4968
- spanContext,
4969
- });
4970
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
4999
+ try {
5000
+ const { sid, aid } = getCtx();
5001
+ if (!sid)
5002
+ return;
5003
+ const meta = this.__repro_aggmeta || { t0: Date.now(), collection: 'unknown' };
5004
+ const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
5005
+ emitDbQuery(cfg, sid, aid, {
5006
+ collection: meta.collection,
5007
+ op: 'aggregate',
5008
+ queryRaw: { pipeline: meta.rawPipeline },
5009
+ resultMetaRaw: res,
5010
+ durMs: Date.now() - meta.t0,
5011
+ t: alignedNow(),
5012
+ spanContext,
5013
+ });
5014
+ }
5015
+ finally {
5016
+ releaseNativeMongoSuppression(this);
5017
+ }
4971
5018
  });
4972
5019
  schema.post('aggregate', function (error, _res, next) {
4973
- popNativeMongoSuppression(this.__repro_native_mongo_suppression);
5020
+ releaseNativeMongoSuppression(this);
4974
5021
  next(error);
4975
5022
  });
4976
5023
  };
@@ -7599,6 +7646,8 @@ function patchRedis(cfg) {
7599
7646
  exports.patchRedis = patchRedis;
7600
7647
  const mongoDbPatchConfigs = [];
7601
7648
  let mongoDbRequireHookInstalled = false;
7649
+ let mongoDbImportHookInstalled = false;
7650
+ let mongoDbImportHookReady = null;
7602
7651
  const MONGODB_PROMISE_OPS = [
7603
7652
  'insertOne',
7604
7653
  'insertMany',
@@ -7618,6 +7667,11 @@ const MONGODB_PROMISE_OPS = [
7618
7667
  ];
7619
7668
  const MONGODB_CURSOR_OPS = ['find', 'aggregate'];
7620
7669
  const MONGODB_CURSOR_TERMINALS = ['toArray', 'next', 'forEach'];
7670
+ function registerMongoDbPatchConfig(cfg) {
7671
+ if (!mongoDbPatchConfigs.includes(cfg)) {
7672
+ mongoDbPatchConfigs.push(cfg);
7673
+ }
7674
+ }
7621
7675
  function resolveMongoDbRuntimeContext(cfg) {
7622
7676
  const ctx = getCtx();
7623
7677
  const fallback = cfg.resolveContext?.() ?? {};
@@ -7627,6 +7681,18 @@ function resolveMongoDbRuntimeContext(cfg) {
7627
7681
  aid: ctx.aid ?? fallback.aid ?? null,
7628
7682
  };
7629
7683
  }
7684
+ function resolveMongoDbCaptureContext() {
7685
+ for (let i = mongoDbPatchConfigs.length - 1; i >= 0; i -= 1) {
7686
+ const cfg = mongoDbPatchConfigs[i];
7687
+ if (!cfg)
7688
+ continue;
7689
+ const { sid, aid } = resolveMongoDbRuntimeContext(cfg);
7690
+ if (sid) {
7691
+ return { cfg, sid, aid };
7692
+ }
7693
+ }
7694
+ return null;
7695
+ }
7630
7696
  function resolveMongoCollectionName(collection) {
7631
7697
  const candidates = [
7632
7698
  collection?.collectionName,
@@ -7911,10 +7977,11 @@ function patchMongoCollectionMethod(proto, op, cursorOp, cfg) {
7911
7977
  if (isNativeMongoSuppressed(collection, op)) {
7912
7978
  return original.apply(this, args);
7913
7979
  }
7914
- const { sid, aid } = resolveMongoDbRuntimeContext(cfg);
7915
- if (!sid) {
7980
+ const captureContext = resolveMongoDbCaptureContext();
7981
+ if (!captureContext) {
7916
7982
  return original.apply(this, args);
7917
7983
  }
7984
+ const { cfg: activeCfg, sid, aid } = captureContext;
7918
7985
  const spanContext = captureSpanContextFromTracer(this);
7919
7986
  const t0 = Date.now();
7920
7987
  const dbName = resolveMongoDbName(this);
@@ -7925,7 +7992,7 @@ function patchMongoCollectionMethod(proto, op, cursorOp, cfg) {
7925
7992
  if (emitted)
7926
7993
  return;
7927
7994
  emitted = true;
7928
- emitDbQuery(cfg, sid, aid ?? undefined, {
7995
+ emitDbQuery(activeCfg, sid, aid ?? undefined, {
7929
7996
  type: 'mongo',
7930
7997
  collection,
7931
7998
  op,
@@ -7943,7 +8010,7 @@ function patchMongoCollectionMethod(proto, op, cursorOp, cfg) {
7943
8010
  if (emitted)
7944
8011
  return;
7945
8012
  emitted = true;
7946
- emitDbQuery(cfg, sid, aid ?? undefined, {
8013
+ emitDbQuery(activeCfg, sid, aid ?? undefined, {
7947
8014
  type: 'mongo',
7948
8015
  collection,
7949
8016
  op,
@@ -7968,7 +8035,7 @@ function patchMongoCollectionMethod(proto, op, cursorOp, cfg) {
7968
8035
  const result = original.apply(this, actualArgs);
7969
8036
  if (cursorOp) {
7970
8037
  return patchMongoCursorInstance(result, {
7971
- cfg,
8038
+ cfg: activeCfg,
7972
8039
  sid,
7973
8040
  aid,
7974
8041
  collection,
@@ -8053,6 +8120,7 @@ function patchMongoClientPrototype(proto, cfg) {
8053
8120
  };
8054
8121
  }
8055
8122
  function patchMongoDbFromModuleExports(mongoModule, cfg) {
8123
+ registerMongoDbPatchConfig(cfg);
8056
8124
  if (!mongoModule)
8057
8125
  return;
8058
8126
  const constructors = new Set();
@@ -8108,9 +8176,46 @@ function installMongoDbRequireHook() {
8108
8176
  }
8109
8177
  catch { }
8110
8178
  }
8179
+ function installMongoDbImportHook() {
8180
+ if (mongoDbImportHookInstalled)
8181
+ return mongoDbImportHookReady ?? Promise.resolve();
8182
+ mongoDbImportHookInstalled = true;
8183
+ mongoDbImportHookReady = (async () => {
8184
+ try {
8185
+ const nodeModule = requireOptionalHostModule('node:module') ?? requireOptionalHostModule('module');
8186
+ if (typeof nodeModule?.register !== 'function')
8187
+ return;
8188
+ const iitm = requireOptionalHostModule('import-in-the-middle');
8189
+ const Hook = iitm?.Hook ?? iitm;
8190
+ if (typeof Hook !== 'function')
8191
+ return;
8192
+ let waitForAllMessagesAcknowledged;
8193
+ let registerOptions = { data: { include: ['mongodb'] } };
8194
+ if (typeof iitm?.createAddHookMessageChannel === 'function') {
8195
+ const channel = iitm.createAddHookMessageChannel();
8196
+ registerOptions = channel.registerOptions;
8197
+ waitForAllMessagesAcknowledged = channel.waitForAllMessagesAcknowledged;
8198
+ }
8199
+ nodeModule.register('import-in-the-middle/hook.mjs', (0, url_1.pathToFileURL)(__filename), registerOptions);
8200
+ // eslint-disable-next-line no-new
8201
+ new Hook(['mongodb'], (exports) => {
8202
+ for (const cfg of mongoDbPatchConfigs) {
8203
+ patchMongoDbFromModuleExports(exports, cfg);
8204
+ }
8205
+ return exports;
8206
+ });
8207
+ if (waitForAllMessagesAcknowledged) {
8208
+ await waitForAllMessagesAcknowledged();
8209
+ }
8210
+ }
8211
+ catch { }
8212
+ })();
8213
+ return mongoDbImportHookReady;
8214
+ }
8111
8215
  function patchMongoDb(cfg) {
8112
- mongoDbPatchConfigs.push(cfg);
8216
+ registerMongoDbPatchConfig(cfg);
8113
8217
  installMongoDbRequireHook();
8218
+ void installMongoDbImportHook();
8114
8219
  const mongoModules = new Set();
8115
8220
  for (const loadedMongoModule of getLoadedModuleExportsByPackage('mongodb')) {
8116
8221
  mongoModules.add(loadedMongoModule);
@@ -8628,6 +8733,7 @@ async function initRepro(cfg) {
8628
8733
  patchAmqplib(integrationCfg);
8629
8734
  patchRedis(integrationCfg);
8630
8735
  patchMongoDb(integrationCfg);
8736
+ await installMongoDbImportHook();
8631
8737
  patchSendgridMail(integrationCfg);
8632
8738
  patchMongooseIntegration(reproAutoMiddlewareConfig);
8633
8739
  await initializeRuntimePrivacyPolicyAtStartup(reproAutoMiddlewareConfig);
@@ -8661,6 +8767,16 @@ exports.__reproTestHooks = {
8661
8767
  lastClientActivityAt = 0;
8662
8768
  sdkBackgroundQuietUntil = 0;
8663
8769
  },
8770
+ runWithRequestContextForTest(ctx, fn) {
8771
+ return als.run({
8772
+ ...ctx,
8773
+ excludedSpanIds: ctx.excludedSpanIds ?? new Set(),
8774
+ }, fn);
8775
+ },
8776
+ getNativeMongoSuppressionCountForTest() {
8777
+ const suppressions = getCtx().nativeMongoSuppressions;
8778
+ return Array.isArray(suppressions) ? suppressions.length : 0;
8779
+ },
8664
8780
  getRuntimePrivacyPolicyForTest(cfg) {
8665
8781
  return getRuntimePrivacyState(cfg).policy;
8666
8782
  },