@reproapp/node-sdk 0.0.26 → 0.0.27
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 +11 -0
- package/dist/index.js +588 -1
- package/dist/ingest/client.js +18 -3
- package/package.json +2 -2
- package/src/index.ts +654 -0
- package/src/ingest/client.ts +25 -3
- package/test/ingest-critical-retention.test.js +147 -0
- package/test/ingest-critical-retry-retention.test.js +57 -0
- package/test/ingest-high-priority-retention.test.js +75 -0
- package/test/mongodb-integration.test.js +332 -0
package/src/index.ts
CHANGED
|
@@ -1154,6 +1154,13 @@ type Ctx = {
|
|
|
1154
1154
|
maskReq?: MaskRequestContext;
|
|
1155
1155
|
privacyTasks?: Set<Promise<void>>;
|
|
1156
1156
|
captureScope?: RequestCaptureScopeState;
|
|
1157
|
+
nativeMongoSuppressions?: NativeMongoSuppression[];
|
|
1158
|
+
};
|
|
1159
|
+
|
|
1160
|
+
type NativeMongoSuppression = {
|
|
1161
|
+
collection?: string | null;
|
|
1162
|
+
ops?: Set<string>;
|
|
1163
|
+
startedAt: number;
|
|
1157
1164
|
};
|
|
1158
1165
|
|
|
1159
1166
|
type RequestCaptureScopeState = {
|
|
@@ -1213,6 +1220,54 @@ function buildRequestCaptureManifestPayload(
|
|
|
1213
1220
|
const als = new AsyncLocalStorage<Ctx>();
|
|
1214
1221
|
const getCtx = () => als.getStore() || {};
|
|
1215
1222
|
|
|
1223
|
+
function normalizeNativeMongoSuppressionOp(op: string | null | undefined): string {
|
|
1224
|
+
return String(op ?? '').trim();
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
function pushNativeMongoSuppression(collection: any, ops?: string[] | readonly string[]): NativeMongoSuppression | null {
|
|
1228
|
+
const store = als.getStore();
|
|
1229
|
+
if (!store) return null;
|
|
1230
|
+
const normalizedOps = Array.isArray(ops)
|
|
1231
|
+
? ops.map(normalizeNativeMongoSuppressionOp).filter(Boolean)
|
|
1232
|
+
: [];
|
|
1233
|
+
const token: NativeMongoSuppression = {
|
|
1234
|
+
collection: collection == null ? null : String(collection),
|
|
1235
|
+
ops: normalizedOps.length ? new Set(normalizedOps) : undefined,
|
|
1236
|
+
startedAt: Date.now(),
|
|
1237
|
+
};
|
|
1238
|
+
if (!Array.isArray(store.nativeMongoSuppressions)) {
|
|
1239
|
+
store.nativeMongoSuppressions = [];
|
|
1240
|
+
}
|
|
1241
|
+
store.nativeMongoSuppressions.push(token);
|
|
1242
|
+
return token;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
function popNativeMongoSuppression(token: NativeMongoSuppression | null | undefined): void {
|
|
1246
|
+
if (!token) return;
|
|
1247
|
+
const store = als.getStore();
|
|
1248
|
+
const suppressions = store?.nativeMongoSuppressions;
|
|
1249
|
+
if (!Array.isArray(suppressions) || suppressions.length === 0) return;
|
|
1250
|
+
const index = suppressions.indexOf(token);
|
|
1251
|
+
if (index >= 0) {
|
|
1252
|
+
suppressions.splice(index, 1);
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
function isNativeMongoSuppressed(collection: any, op: string): boolean {
|
|
1257
|
+
const suppressions = (getCtx() as Ctx).nativeMongoSuppressions;
|
|
1258
|
+
if (!Array.isArray(suppressions) || suppressions.length === 0) return false;
|
|
1259
|
+
const normalizedCollection = collection == null ? null : String(collection);
|
|
1260
|
+
const normalizedOp = normalizeNativeMongoSuppressionOp(op);
|
|
1261
|
+
const now = Date.now();
|
|
1262
|
+
for (const token of suppressions) {
|
|
1263
|
+
if (!token || now - token.startedAt > 60000) continue;
|
|
1264
|
+
if (token.collection && normalizedCollection && token.collection !== normalizedCollection) continue;
|
|
1265
|
+
if (token.ops && token.ops.size > 0 && !token.ops.has(normalizedOp)) continue;
|
|
1266
|
+
return true;
|
|
1267
|
+
}
|
|
1268
|
+
return false;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1216
1271
|
function currentClockSkewMs(): number {
|
|
1217
1272
|
const store = als.getStore();
|
|
1218
1273
|
const skew = store?.clockSkewMs;
|
|
@@ -5424,6 +5479,15 @@ export function reproMiddleware(cfg: ReproMiddlewareConfig) {
|
|
|
5424
5479
|
// - ONLY schema middleware (pre/post) for specific ops
|
|
5425
5480
|
// - keeps your existing doc-diff hooks
|
|
5426
5481
|
// ===================================================================
|
|
5482
|
+
function nativeMongoOpsForMongooseOp(op: string): string[] {
|
|
5483
|
+
if (op === 'findByIdAndUpdate') return ['findOneAndUpdate'];
|
|
5484
|
+
if (op === 'findByIdAndDelete' || op === 'findByIdAndRemove' || op === 'findOneAndRemove') {
|
|
5485
|
+
return ['findOneAndDelete'];
|
|
5486
|
+
}
|
|
5487
|
+
if (op === 'findByIdAndReplace') return ['findOneAndReplace'];
|
|
5488
|
+
return [op];
|
|
5489
|
+
}
|
|
5490
|
+
|
|
5427
5491
|
export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
5428
5492
|
return function (schema: Schema) {
|
|
5429
5493
|
// -------- pre/post save (unchanged) --------
|
|
@@ -5441,6 +5505,10 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5441
5505
|
? (this as any).modifiedPaths()
|
|
5442
5506
|
: [],
|
|
5443
5507
|
};
|
|
5508
|
+
(this as any).__repro_native_mongo_suppression = pushNativeMongoSuppression(
|
|
5509
|
+
(this as any).__repro_meta.collection,
|
|
5510
|
+
this.isNew ? ['insertOne'] : ['updateOne', 'replaceOne'],
|
|
5511
|
+
);
|
|
5444
5512
|
next();
|
|
5445
5513
|
});
|
|
5446
5514
|
|
|
@@ -5475,6 +5543,12 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5475
5543
|
t: alignTimestamp(meta.t0 ?? Date.now()),
|
|
5476
5544
|
spanContext,
|
|
5477
5545
|
});
|
|
5546
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5547
|
+
});
|
|
5548
|
+
|
|
5549
|
+
schema.post('save', { document: true }, function (error: any, _doc: any, next: Function) {
|
|
5550
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5551
|
+
next(error);
|
|
5478
5552
|
});
|
|
5479
5553
|
|
|
5480
5554
|
// -------- findOneAndUpdate capture (unchanged) --------
|
|
@@ -5489,6 +5563,10 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5489
5563
|
(this as any).__repro_spanContext = captureSpanContextFromTracer(this);
|
|
5490
5564
|
(this as any).__repro_filter = filter;
|
|
5491
5565
|
(this as any).__repro_update = this.getUpdate?.() ?? (this as any)._update ?? undefined;
|
|
5566
|
+
(this as any).__repro_native_mongo_suppression = pushNativeMongoSuppression(
|
|
5567
|
+
(this as any).__repro_collection,
|
|
5568
|
+
['findOneAndUpdate'],
|
|
5569
|
+
);
|
|
5492
5570
|
} catch {}
|
|
5493
5571
|
next();
|
|
5494
5572
|
});
|
|
@@ -5518,8 +5596,14 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5518
5596
|
t: alignTimestamp((this as any).__repro_t0 ?? Date.now()),
|
|
5519
5597
|
spanContext,
|
|
5520
5598
|
});
|
|
5599
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5521
5600
|
});
|
|
5522
5601
|
|
|
5602
|
+
schema.post<Query<any, any>>('findOneAndUpdate', function (this: any, error: any, _res: any, next: Function) {
|
|
5603
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5604
|
+
next(error);
|
|
5605
|
+
} as any);
|
|
5606
|
+
|
|
5523
5607
|
// -------- deleteOne capture (unchanged) --------
|
|
5524
5608
|
schema.pre<Query<any, any>>('deleteOne', { document: false, query: true }, function (next) {
|
|
5525
5609
|
const { sid, aid } = getCtx(); if (!sid || !aid) return next();
|
|
@@ -5529,6 +5613,10 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5529
5613
|
(this as any).__repro_collection = resolveCollectionOrWarn(this, 'query');
|
|
5530
5614
|
(this as any).__repro_filter = filter;
|
|
5531
5615
|
(this as any).__repro_spanContext = captureSpanContextFromTracer(this);
|
|
5616
|
+
(this as any).__repro_native_mongo_suppression = pushNativeMongoSuppression(
|
|
5617
|
+
(this as any).__repro_collection,
|
|
5618
|
+
['deleteOne'],
|
|
5619
|
+
);
|
|
5532
5620
|
} catch {}
|
|
5533
5621
|
next();
|
|
5534
5622
|
});
|
|
@@ -5550,8 +5638,14 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5550
5638
|
t: alignTimestamp((this as any).__repro_t0 ?? Date.now()),
|
|
5551
5639
|
spanContext,
|
|
5552
5640
|
});
|
|
5641
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5553
5642
|
});
|
|
5554
5643
|
|
|
5644
|
+
schema.post<Query<any, any>>('deleteOne', { document: false, query: true }, function (this: any, error: any, _res: any, next: Function) {
|
|
5645
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5646
|
+
next(error);
|
|
5647
|
+
} as any);
|
|
5648
|
+
|
|
5555
5649
|
// -------- NON-intrusive generic query telemetry via schema hooks -------
|
|
5556
5650
|
const READ_OPS = [
|
|
5557
5651
|
'find',
|
|
@@ -5593,6 +5687,10 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5593
5687
|
rawProjection,
|
|
5594
5688
|
rawOptions,
|
|
5595
5689
|
};
|
|
5690
|
+
(this as any).__repro_native_mongo_suppression = pushNativeMongoSuppression(
|
|
5691
|
+
(this as any).__repro_qmeta.collection,
|
|
5692
|
+
nativeMongoOpsForMongooseOp(op),
|
|
5693
|
+
);
|
|
5596
5694
|
} catch {
|
|
5597
5695
|
(this as any).__repro_qmeta = {
|
|
5598
5696
|
t0: Date.now(),
|
|
@@ -5600,6 +5698,10 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5600
5698
|
op,
|
|
5601
5699
|
spanContext: captureSpanContextFromTracer(this),
|
|
5602
5700
|
};
|
|
5701
|
+
(this as any).__repro_native_mongo_suppression = pushNativeMongoSuppression(
|
|
5702
|
+
'unknown',
|
|
5703
|
+
nativeMongoOpsForMongooseOp(op),
|
|
5704
|
+
);
|
|
5603
5705
|
}
|
|
5604
5706
|
next();
|
|
5605
5707
|
});
|
|
@@ -5625,7 +5727,13 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5625
5727
|
t: alignedNow(),
|
|
5626
5728
|
spanContext,
|
|
5627
5729
|
});
|
|
5730
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5628
5731
|
});
|
|
5732
|
+
|
|
5733
|
+
schema.post(op as any, function (this: any, error: any, _res: any, next: Function) {
|
|
5734
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5735
|
+
next(error);
|
|
5736
|
+
} as any);
|
|
5629
5737
|
}
|
|
5630
5738
|
|
|
5631
5739
|
READ_OPS.forEach(attachQueryHooks);
|
|
@@ -5641,12 +5749,17 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5641
5749
|
rawDocs,
|
|
5642
5750
|
spanContext: captureSpanContextFromTracer(this),
|
|
5643
5751
|
};
|
|
5752
|
+
(this as any).__repro_native_mongo_suppression = pushNativeMongoSuppression(
|
|
5753
|
+
(this as any).__repro_insert_meta.collection,
|
|
5754
|
+
['insertMany'],
|
|
5755
|
+
);
|
|
5644
5756
|
} catch {
|
|
5645
5757
|
(this as any).__repro_insert_meta = {
|
|
5646
5758
|
t0: Date.now(),
|
|
5647
5759
|
collection: 'unknown',
|
|
5648
5760
|
spanContext: captureSpanContextFromTracer(this),
|
|
5649
5761
|
};
|
|
5762
|
+
(this as any).__repro_native_mongo_suppression = pushNativeMongoSuppression('unknown', ['insertMany']);
|
|
5650
5763
|
}
|
|
5651
5764
|
next();
|
|
5652
5765
|
} as any);
|
|
@@ -5666,6 +5779,12 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5666
5779
|
t: alignedNow(),
|
|
5667
5780
|
spanContext,
|
|
5668
5781
|
});
|
|
5782
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5783
|
+
} as any);
|
|
5784
|
+
|
|
5785
|
+
schema.post<any>('insertMany' as any, { document: false, query: false } as any, function (this: any, error: any, _res: any, next: Function) {
|
|
5786
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5787
|
+
next(error);
|
|
5669
5788
|
} as any);
|
|
5670
5789
|
|
|
5671
5790
|
schema.pre<any>('bulkWrite' as any, { document: false, query: false } as any, function (this: any, next: Function, ops?: any[]) {
|
|
@@ -5677,12 +5796,17 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5677
5796
|
rawOps,
|
|
5678
5797
|
spanContext: captureSpanContextFromTracer(this),
|
|
5679
5798
|
};
|
|
5799
|
+
(this as any).__repro_native_mongo_suppression = pushNativeMongoSuppression(
|
|
5800
|
+
(this as any).__repro_bulk_meta.collection,
|
|
5801
|
+
['bulkWrite'],
|
|
5802
|
+
);
|
|
5680
5803
|
} catch {
|
|
5681
5804
|
(this as any).__repro_bulk_meta = {
|
|
5682
5805
|
t0: Date.now(),
|
|
5683
5806
|
collection: 'unknown',
|
|
5684
5807
|
spanContext: captureSpanContextFromTracer(this),
|
|
5685
5808
|
};
|
|
5809
|
+
(this as any).__repro_native_mongo_suppression = pushNativeMongoSuppression('unknown', ['bulkWrite']);
|
|
5686
5810
|
}
|
|
5687
5811
|
next();
|
|
5688
5812
|
} as any);
|
|
@@ -5702,6 +5826,12 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5702
5826
|
t: alignedNow(),
|
|
5703
5827
|
spanContext,
|
|
5704
5828
|
});
|
|
5829
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5830
|
+
} as any);
|
|
5831
|
+
|
|
5832
|
+
schema.post<any>('bulkWrite' as any, { document: false, query: false } as any, function (this: any, error: any, _res: any, next: Function) {
|
|
5833
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5834
|
+
next(error);
|
|
5705
5835
|
} as any);
|
|
5706
5836
|
|
|
5707
5837
|
// Aggregate middleware (non-intrusive)
|
|
@@ -5718,6 +5848,10 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5718
5848
|
spanContext: captureSpanContextFromTracer(this),
|
|
5719
5849
|
rawPipeline,
|
|
5720
5850
|
};
|
|
5851
|
+
(this as any).__repro_native_mongo_suppression = pushNativeMongoSuppression(
|
|
5852
|
+
(this as any).__repro_aggmeta.collection,
|
|
5853
|
+
['aggregate'],
|
|
5854
|
+
);
|
|
5721
5855
|
} catch {
|
|
5722
5856
|
(this as any).__repro_aggmeta = {
|
|
5723
5857
|
t0: Date.now(),
|
|
@@ -5725,6 +5859,7 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5725
5859
|
pipeline: undefined,
|
|
5726
5860
|
spanContext: captureSpanContextFromTracer(this),
|
|
5727
5861
|
};
|
|
5862
|
+
(this as any).__repro_native_mongo_suppression = pushNativeMongoSuppression('unknown', ['aggregate']);
|
|
5728
5863
|
}
|
|
5729
5864
|
next();
|
|
5730
5865
|
});
|
|
@@ -5745,7 +5880,13 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5745
5880
|
t: alignedNow(),
|
|
5746
5881
|
spanContext,
|
|
5747
5882
|
});
|
|
5883
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5748
5884
|
});
|
|
5885
|
+
|
|
5886
|
+
schema.post('aggregate', function (this: any, error: any, _res: any, next: Function) {
|
|
5887
|
+
popNativeMongoSuppression((this as any).__repro_native_mongo_suppression);
|
|
5888
|
+
next(error);
|
|
5889
|
+
} as any);
|
|
5749
5890
|
};
|
|
5750
5891
|
}
|
|
5751
5892
|
|
|
@@ -5771,9 +5912,23 @@ function summarizeQueryResult(op: string, res: any) {
|
|
|
5771
5912
|
return summary;
|
|
5772
5913
|
}
|
|
5773
5914
|
|
|
5915
|
+
if (op === 'insertOne') {
|
|
5916
|
+
const summary: Record<string, any> = {
|
|
5917
|
+
insertedId: res?.insertedId ?? undefined,
|
|
5918
|
+
acknowledged: res?.acknowledged ?? undefined,
|
|
5919
|
+
};
|
|
5920
|
+
if (typeof resultPreview !== 'undefined') summary.result = resultPreview;
|
|
5921
|
+
return summary;
|
|
5922
|
+
}
|
|
5923
|
+
|
|
5774
5924
|
if (op === 'insertMany') {
|
|
5775
5925
|
const summary: Record<string, any> = {};
|
|
5776
5926
|
if (Array.isArray(res)) summary.inserted = res.length;
|
|
5927
|
+
else {
|
|
5928
|
+
summary.inserted = res?.insertedCount ?? undefined;
|
|
5929
|
+
summary.insertedIds = res?.insertedIds ?? undefined;
|
|
5930
|
+
summary.acknowledged = res?.acknowledged ?? undefined;
|
|
5931
|
+
}
|
|
5777
5932
|
if (typeof resultPreview !== 'undefined') summary.result = resultPreview;
|
|
5778
5933
|
return summary;
|
|
5779
5934
|
}
|
|
@@ -8588,6 +8743,502 @@ export function patchRedis(cfg: RedisPatchConfig) {
|
|
|
8588
8743
|
}
|
|
8589
8744
|
}
|
|
8590
8745
|
|
|
8746
|
+
// ===================================================================
|
|
8747
|
+
// Native MongoDB driver integration
|
|
8748
|
+
// ===================================================================
|
|
8749
|
+
export type MongoDbPatchConfig = ReproMiddlewareConfig & {
|
|
8750
|
+
resolveContext?: () => { sid?: string; aid?: string } | undefined;
|
|
8751
|
+
};
|
|
8752
|
+
|
|
8753
|
+
const mongoDbPatchConfigs: MongoDbPatchConfig[] = [];
|
|
8754
|
+
let mongoDbRequireHookInstalled = false;
|
|
8755
|
+
|
|
8756
|
+
const MONGODB_PROMISE_OPS = [
|
|
8757
|
+
'insertOne',
|
|
8758
|
+
'insertMany',
|
|
8759
|
+
'updateOne',
|
|
8760
|
+
'updateMany',
|
|
8761
|
+
'replaceOne',
|
|
8762
|
+
'deleteOne',
|
|
8763
|
+
'deleteMany',
|
|
8764
|
+
'findOne',
|
|
8765
|
+
'countDocuments',
|
|
8766
|
+
'estimatedDocumentCount',
|
|
8767
|
+
'distinct',
|
|
8768
|
+
'bulkWrite',
|
|
8769
|
+
'findOneAndUpdate',
|
|
8770
|
+
'findOneAndDelete',
|
|
8771
|
+
'findOneAndReplace',
|
|
8772
|
+
] as const;
|
|
8773
|
+
|
|
8774
|
+
const MONGODB_CURSOR_OPS = ['find', 'aggregate'] as const;
|
|
8775
|
+
const MONGODB_CURSOR_TERMINALS = ['toArray', 'next', 'forEach'] as const;
|
|
8776
|
+
|
|
8777
|
+
function resolveMongoDbRuntimeContext(cfg: MongoDbPatchConfig) {
|
|
8778
|
+
const ctx = getCtx();
|
|
8779
|
+
const fallback = cfg.resolveContext?.() ?? {};
|
|
8780
|
+
return {
|
|
8781
|
+
ctx,
|
|
8782
|
+
sid: ctx.sid ?? fallback.sid ?? null,
|
|
8783
|
+
aid: ctx.aid ?? fallback.aid ?? null,
|
|
8784
|
+
};
|
|
8785
|
+
}
|
|
8786
|
+
|
|
8787
|
+
function resolveMongoCollectionName(collection: any): string {
|
|
8788
|
+
const candidates = [
|
|
8789
|
+
collection?.collectionName,
|
|
8790
|
+
collection?.namespace?.collection,
|
|
8791
|
+
collection?.s?.namespace?.collection,
|
|
8792
|
+
collection?.s?.namespace?.collectionName,
|
|
8793
|
+
];
|
|
8794
|
+
for (const candidate of candidates) {
|
|
8795
|
+
if (typeof candidate === 'string' && candidate.trim()) return candidate;
|
|
8796
|
+
}
|
|
8797
|
+
|
|
8798
|
+
const namespace =
|
|
8799
|
+
typeof collection?.namespace === 'string'
|
|
8800
|
+
? collection.namespace
|
|
8801
|
+
: typeof collection?.s?.namespace === 'string'
|
|
8802
|
+
? collection.s.namespace
|
|
8803
|
+
: typeof collection?.namespace?.toString === 'function'
|
|
8804
|
+
? collection.namespace.toString()
|
|
8805
|
+
: typeof collection?.s?.namespace?.toString === 'function'
|
|
8806
|
+
? collection.s.namespace.toString()
|
|
8807
|
+
: null;
|
|
8808
|
+
if (namespace && namespace.includes('.')) {
|
|
8809
|
+
return namespace.slice(namespace.indexOf('.') + 1) || namespace;
|
|
8810
|
+
}
|
|
8811
|
+
return namespace || 'unknown';
|
|
8812
|
+
}
|
|
8813
|
+
|
|
8814
|
+
function resolveMongoDbName(collection: any): string | undefined {
|
|
8815
|
+
const candidates = [
|
|
8816
|
+
collection?.dbName,
|
|
8817
|
+
collection?.db?.databaseName,
|
|
8818
|
+
collection?.s?.db?.databaseName,
|
|
8819
|
+
collection?.namespace?.db,
|
|
8820
|
+
collection?.s?.namespace?.db,
|
|
8821
|
+
];
|
|
8822
|
+
for (const candidate of candidates) {
|
|
8823
|
+
if (typeof candidate === 'string' && candidate.trim()) return candidate;
|
|
8824
|
+
}
|
|
8825
|
+
const namespace =
|
|
8826
|
+
typeof collection?.namespace === 'string'
|
|
8827
|
+
? collection.namespace
|
|
8828
|
+
: typeof collection?.s?.namespace === 'string'
|
|
8829
|
+
? collection.s.namespace
|
|
8830
|
+
: null;
|
|
8831
|
+
if (namespace && namespace.includes('.')) {
|
|
8832
|
+
return namespace.slice(0, namespace.indexOf('.')) || undefined;
|
|
8833
|
+
}
|
|
8834
|
+
return undefined;
|
|
8835
|
+
}
|
|
8836
|
+
|
|
8837
|
+
function summarizeMongoSession(session: any): any {
|
|
8838
|
+
if (!session || typeof session !== 'object') return session;
|
|
8839
|
+
let inTransaction: any = undefined;
|
|
8840
|
+
try {
|
|
8841
|
+
inTransaction = typeof session.inTransaction === 'function' ? session.inTransaction() : undefined;
|
|
8842
|
+
} catch {}
|
|
8843
|
+
return {
|
|
8844
|
+
__kind: 'mongodb_client_session',
|
|
8845
|
+
id: session.id ?? session.serverSession?.id ?? undefined,
|
|
8846
|
+
hasEnded: session.hasEnded ?? undefined,
|
|
8847
|
+
inTransaction,
|
|
8848
|
+
};
|
|
8849
|
+
}
|
|
8850
|
+
|
|
8851
|
+
function normalizeMongoDriverOptions(options: any): any {
|
|
8852
|
+
if (!options || typeof options !== 'object' || Array.isArray(options)) return options;
|
|
8853
|
+
const normalized: Record<string, any> = {};
|
|
8854
|
+
for (const key of Object.keys(options)) {
|
|
8855
|
+
normalized[key] = key === 'session'
|
|
8856
|
+
? summarizeMongoSession(options[key])
|
|
8857
|
+
: options[key];
|
|
8858
|
+
}
|
|
8859
|
+
return normalized;
|
|
8860
|
+
}
|
|
8861
|
+
|
|
8862
|
+
function summarizeMongoError(error: any): Record<string, any> {
|
|
8863
|
+
return {
|
|
8864
|
+
name: error?.name ?? undefined,
|
|
8865
|
+
message: error?.message ?? String(error),
|
|
8866
|
+
code: error?.code ?? undefined,
|
|
8867
|
+
codeName: error?.codeName ?? undefined,
|
|
8868
|
+
};
|
|
8869
|
+
}
|
|
8870
|
+
|
|
8871
|
+
function extractMongoPkFromFilter(filter: any): any {
|
|
8872
|
+
if (filter && typeof filter === 'object' && Object.prototype.hasOwnProperty.call(filter, '_id')) {
|
|
8873
|
+
return { _id: filter._id };
|
|
8874
|
+
}
|
|
8875
|
+
return undefined;
|
|
8876
|
+
}
|
|
8877
|
+
|
|
8878
|
+
function extractMongoPkFromDoc(doc: any, result?: any): any {
|
|
8879
|
+
const id = doc && typeof doc === 'object' ? doc._id : undefined;
|
|
8880
|
+
const insertedId = result?.insertedId;
|
|
8881
|
+
if (id !== undefined) return { _id: id };
|
|
8882
|
+
if (insertedId !== undefined) return { _id: insertedId };
|
|
8883
|
+
return undefined;
|
|
8884
|
+
}
|
|
8885
|
+
|
|
8886
|
+
function buildMongoQueryPayload(op: string, args: any[], dbName?: string): any {
|
|
8887
|
+
const withDriver = (payload: Record<string, any>) => ({
|
|
8888
|
+
driver: 'mongodb',
|
|
8889
|
+
db: dbName,
|
|
8890
|
+
...payload,
|
|
8891
|
+
});
|
|
8892
|
+
|
|
8893
|
+
if (op === 'insertOne') {
|
|
8894
|
+
return withDriver({ doc: args[0], options: normalizeMongoDriverOptions(args[1]) });
|
|
8895
|
+
}
|
|
8896
|
+
if (op === 'insertMany') {
|
|
8897
|
+
return withDriver({ docs: args[0], options: normalizeMongoDriverOptions(args[1]) });
|
|
8898
|
+
}
|
|
8899
|
+
if (op === 'updateOne' || op === 'updateMany') {
|
|
8900
|
+
return withDriver({ filter: args[0], update: args[1], options: normalizeMongoDriverOptions(args[2]) });
|
|
8901
|
+
}
|
|
8902
|
+
if (op === 'replaceOne') {
|
|
8903
|
+
return withDriver({ filter: args[0], replacement: args[1], options: normalizeMongoDriverOptions(args[2]) });
|
|
8904
|
+
}
|
|
8905
|
+
if (op === 'deleteOne' || op === 'deleteMany') {
|
|
8906
|
+
return withDriver({ filter: args[0], options: normalizeMongoDriverOptions(args[1]) });
|
|
8907
|
+
}
|
|
8908
|
+
if (op === 'findOne' || op === 'find' || op === 'countDocuments') {
|
|
8909
|
+
return withDriver({ filter: args[0], options: normalizeMongoDriverOptions(args[1]) });
|
|
8910
|
+
}
|
|
8911
|
+
if (op === 'estimatedDocumentCount') {
|
|
8912
|
+
return withDriver({ options: normalizeMongoDriverOptions(args[0]) });
|
|
8913
|
+
}
|
|
8914
|
+
if (op === 'distinct') {
|
|
8915
|
+
return withDriver({ key: args[0], filter: args[1], options: normalizeMongoDriverOptions(args[2]) });
|
|
8916
|
+
}
|
|
8917
|
+
if (op === 'bulkWrite') {
|
|
8918
|
+
return withDriver({ ops: args[0], options: normalizeMongoDriverOptions(args[1]) });
|
|
8919
|
+
}
|
|
8920
|
+
if (op === 'findOneAndUpdate') {
|
|
8921
|
+
return withDriver({ filter: args[0], update: args[1], options: normalizeMongoDriverOptions(args[2]) });
|
|
8922
|
+
}
|
|
8923
|
+
if (op === 'findOneAndReplace') {
|
|
8924
|
+
return withDriver({ filter: args[0], replacement: args[1], options: normalizeMongoDriverOptions(args[2]) });
|
|
8925
|
+
}
|
|
8926
|
+
if (op === 'findOneAndDelete') {
|
|
8927
|
+
return withDriver({ filter: args[0], options: normalizeMongoDriverOptions(args[1]) });
|
|
8928
|
+
}
|
|
8929
|
+
if (op === 'aggregate') {
|
|
8930
|
+
return withDriver({ pipeline: args[0], options: normalizeMongoDriverOptions(args[1]) });
|
|
8931
|
+
}
|
|
8932
|
+
return withDriver({ args });
|
|
8933
|
+
}
|
|
8934
|
+
|
|
8935
|
+
function buildMongoPk(op: string, args: any[], result?: any): any {
|
|
8936
|
+
if (op === 'insertOne') return extractMongoPkFromDoc(args[0], result);
|
|
8937
|
+
if (
|
|
8938
|
+
op === 'updateOne' ||
|
|
8939
|
+
op === 'replaceOne' ||
|
|
8940
|
+
op === 'deleteOne' ||
|
|
8941
|
+
op === 'findOne' ||
|
|
8942
|
+
op === 'findOneAndUpdate' ||
|
|
8943
|
+
op === 'findOneAndDelete' ||
|
|
8944
|
+
op === 'findOneAndReplace'
|
|
8945
|
+
) {
|
|
8946
|
+
return extractMongoPkFromFilter(args[0]);
|
|
8947
|
+
}
|
|
8948
|
+
return undefined;
|
|
8949
|
+
}
|
|
8950
|
+
|
|
8951
|
+
function buildMongoAfter(op: string, args: any[], result?: any): any {
|
|
8952
|
+
if (op === 'insertOne') return args[0] ?? null;
|
|
8953
|
+
if (op === 'insertMany') return args[0] ?? null;
|
|
8954
|
+
if (op === 'findOne' || op === 'findOneAndUpdate' || op === 'findOneAndDelete' || op === 'findOneAndReplace') {
|
|
8955
|
+
return result ?? null;
|
|
8956
|
+
}
|
|
8957
|
+
if (op === 'find' || op === 'aggregate') {
|
|
8958
|
+
return Array.isArray(result) ? result : null;
|
|
8959
|
+
}
|
|
8960
|
+
return null;
|
|
8961
|
+
}
|
|
8962
|
+
|
|
8963
|
+
function findMongoCallbackIndex(args: any[]): number {
|
|
8964
|
+
for (let i = args.length - 1; i >= 0; i -= 1) {
|
|
8965
|
+
if (typeof args[i] === 'function') return i;
|
|
8966
|
+
}
|
|
8967
|
+
return -1;
|
|
8968
|
+
}
|
|
8969
|
+
|
|
8970
|
+
function patchMongoCursorInstance(cursor: any, meta: {
|
|
8971
|
+
cfg: MongoDbPatchConfig;
|
|
8972
|
+
sid: string;
|
|
8973
|
+
aid: string | null;
|
|
8974
|
+
collection: string;
|
|
8975
|
+
dbName?: string;
|
|
8976
|
+
op: string;
|
|
8977
|
+
args: any[];
|
|
8978
|
+
spanContext: SpanContext | null;
|
|
8979
|
+
}): any {
|
|
8980
|
+
if (!cursor || typeof cursor !== 'object') return cursor;
|
|
8981
|
+
if (cursor.__repro_mongodb_cursor_patched) return cursor;
|
|
8982
|
+
try {
|
|
8983
|
+
Object.defineProperty(cursor, '__repro_mongodb_cursor_patched', {
|
|
8984
|
+
value: true,
|
|
8985
|
+
configurable: true,
|
|
8986
|
+
});
|
|
8987
|
+
} catch {
|
|
8988
|
+
return cursor;
|
|
8989
|
+
}
|
|
8990
|
+
|
|
8991
|
+
for (const methodName of MONGODB_CURSOR_TERMINALS) {
|
|
8992
|
+
const original = cursor[methodName];
|
|
8993
|
+
if (typeof original !== 'function') continue;
|
|
8994
|
+
|
|
8995
|
+
cursor[methodName] = function reproPatchedMongoCursorTerminal(this: any, ...callArgs: any[]) {
|
|
8996
|
+
const t0 = Date.now();
|
|
8997
|
+
let emitted = false;
|
|
8998
|
+
let forEachDocs: any[] | null = null;
|
|
8999
|
+
const emitSuccess = (value: any) => {
|
|
9000
|
+
if (emitted) return;
|
|
9001
|
+
emitted = true;
|
|
9002
|
+
const terminalQueryArgs = [...meta.args] as any[];
|
|
9003
|
+
const queryRaw = buildMongoQueryPayload(meta.op, terminalQueryArgs, meta.dbName);
|
|
9004
|
+
queryRaw.cursorMethod = methodName;
|
|
9005
|
+
emitDbQuery(meta.cfg, meta.sid, meta.aid ?? undefined, {
|
|
9006
|
+
type: 'mongo',
|
|
9007
|
+
collection: meta.collection,
|
|
9008
|
+
op: meta.op,
|
|
9009
|
+
pk: buildMongoPk(meta.op, meta.args, value),
|
|
9010
|
+
before: null,
|
|
9011
|
+
after: buildMongoAfter(meta.op, meta.args, forEachDocs ?? value),
|
|
9012
|
+
queryRaw,
|
|
9013
|
+
resultMetaRaw: forEachDocs ?? value,
|
|
9014
|
+
durMs: Date.now() - t0,
|
|
9015
|
+
t: alignedNow(),
|
|
9016
|
+
spanContext: meta.spanContext,
|
|
9017
|
+
});
|
|
9018
|
+
};
|
|
9019
|
+
const emitFailure = (error: any) => {
|
|
9020
|
+
if (emitted) return;
|
|
9021
|
+
emitted = true;
|
|
9022
|
+
const terminalQueryArgs = [...meta.args] as any[];
|
|
9023
|
+
const queryRaw = buildMongoQueryPayload(meta.op, terminalQueryArgs, meta.dbName);
|
|
9024
|
+
queryRaw.cursorMethod = methodName;
|
|
9025
|
+
emitDbQuery(meta.cfg, meta.sid, meta.aid ?? undefined, {
|
|
9026
|
+
type: 'mongo',
|
|
9027
|
+
collection: meta.collection,
|
|
9028
|
+
op: meta.op,
|
|
9029
|
+
queryRaw,
|
|
9030
|
+
error: summarizeMongoError(error),
|
|
9031
|
+
durMs: Date.now() - t0,
|
|
9032
|
+
t: alignedNow(),
|
|
9033
|
+
spanContext: meta.spanContext,
|
|
9034
|
+
});
|
|
9035
|
+
};
|
|
9036
|
+
|
|
9037
|
+
const actualArgs = [...callArgs];
|
|
9038
|
+
if (methodName === 'forEach' && typeof actualArgs[0] === 'function') {
|
|
9039
|
+
forEachDocs = [];
|
|
9040
|
+
const originalIterator = actualArgs[0];
|
|
9041
|
+
actualArgs[0] = function reproMongoForEachIterator(this: any, doc: any, ...rest: any[]) {
|
|
9042
|
+
forEachDocs?.push(doc);
|
|
9043
|
+
return originalIterator.call(this, doc, ...rest);
|
|
9044
|
+
};
|
|
9045
|
+
}
|
|
9046
|
+
|
|
9047
|
+
try {
|
|
9048
|
+
const value = original.apply(this, actualArgs);
|
|
9049
|
+
if (value && typeof value.then === 'function') {
|
|
9050
|
+
return value.then(
|
|
9051
|
+
(resolved: any) => {
|
|
9052
|
+
emitSuccess(resolved);
|
|
9053
|
+
return resolved;
|
|
9054
|
+
},
|
|
9055
|
+
(err: any) => {
|
|
9056
|
+
emitFailure(err);
|
|
9057
|
+
throw err;
|
|
9058
|
+
},
|
|
9059
|
+
);
|
|
9060
|
+
}
|
|
9061
|
+
emitSuccess(value);
|
|
9062
|
+
return value;
|
|
9063
|
+
} catch (err) {
|
|
9064
|
+
emitFailure(err);
|
|
9065
|
+
throw err;
|
|
9066
|
+
}
|
|
9067
|
+
};
|
|
9068
|
+
}
|
|
9069
|
+
|
|
9070
|
+
return cursor;
|
|
9071
|
+
}
|
|
9072
|
+
|
|
9073
|
+
function patchMongoCollectionMethod(proto: any, op: string, cursorOp: boolean, cfg: MongoDbPatchConfig): void {
|
|
9074
|
+
if (!proto) return;
|
|
9075
|
+
const marker = `__repro_mongodb_${op}_patched`;
|
|
9076
|
+
if (proto[marker]) return;
|
|
9077
|
+
const original = proto[op];
|
|
9078
|
+
if (typeof original !== 'function') return;
|
|
9079
|
+
proto[marker] = true;
|
|
9080
|
+
|
|
9081
|
+
proto[op] = function reproPatchedMongoCollectionMethod(this: any, ...args: any[]) {
|
|
9082
|
+
const collection = resolveMongoCollectionName(this);
|
|
9083
|
+
if (isNativeMongoSuppressed(collection, op)) {
|
|
9084
|
+
return original.apply(this, args);
|
|
9085
|
+
}
|
|
9086
|
+
|
|
9087
|
+
const { sid, aid } = resolveMongoDbRuntimeContext(cfg);
|
|
9088
|
+
if (!sid) {
|
|
9089
|
+
return original.apply(this, args);
|
|
9090
|
+
}
|
|
9091
|
+
|
|
9092
|
+
const spanContext = captureSpanContextFromTracer(this);
|
|
9093
|
+
const t0 = Date.now();
|
|
9094
|
+
const dbName = resolveMongoDbName(this);
|
|
9095
|
+
const callbackIndex = cursorOp ? -1 : findMongoCallbackIndex(args);
|
|
9096
|
+
const actualArgs = callbackIndex >= 0 ? [...args] : args;
|
|
9097
|
+
let emitted = false;
|
|
9098
|
+
|
|
9099
|
+
const emitSuccess = (result: any) => {
|
|
9100
|
+
if (emitted) return;
|
|
9101
|
+
emitted = true;
|
|
9102
|
+
emitDbQuery(cfg, sid, aid ?? undefined, {
|
|
9103
|
+
type: 'mongo',
|
|
9104
|
+
collection,
|
|
9105
|
+
op,
|
|
9106
|
+
pk: buildMongoPk(op, args, result),
|
|
9107
|
+
before: null,
|
|
9108
|
+
after: buildMongoAfter(op, args, result),
|
|
9109
|
+
queryRaw: buildMongoQueryPayload(op, args, dbName),
|
|
9110
|
+
resultMetaRaw: result,
|
|
9111
|
+
durMs: Date.now() - t0,
|
|
9112
|
+
t: alignedNow(),
|
|
9113
|
+
spanContext,
|
|
9114
|
+
});
|
|
9115
|
+
};
|
|
9116
|
+
const emitFailure = (error: any) => {
|
|
9117
|
+
if (emitted) return;
|
|
9118
|
+
emitted = true;
|
|
9119
|
+
emitDbQuery(cfg, sid, aid ?? undefined, {
|
|
9120
|
+
type: 'mongo',
|
|
9121
|
+
collection,
|
|
9122
|
+
op,
|
|
9123
|
+
queryRaw: buildMongoQueryPayload(op, args, dbName),
|
|
9124
|
+
error: summarizeMongoError(error),
|
|
9125
|
+
durMs: Date.now() - t0,
|
|
9126
|
+
t: alignedNow(),
|
|
9127
|
+
spanContext,
|
|
9128
|
+
});
|
|
9129
|
+
};
|
|
9130
|
+
|
|
9131
|
+
if (callbackIndex >= 0) {
|
|
9132
|
+
const originalCallback = args[callbackIndex];
|
|
9133
|
+
actualArgs[callbackIndex] = function reproMongoCallback(this: any, err: any, result: any, ...rest: any[]) {
|
|
9134
|
+
if (err) emitFailure(err);
|
|
9135
|
+
else emitSuccess(result);
|
|
9136
|
+
return originalCallback.call(this, err, result, ...rest);
|
|
9137
|
+
};
|
|
9138
|
+
}
|
|
9139
|
+
|
|
9140
|
+
try {
|
|
9141
|
+
const result = original.apply(this, actualArgs);
|
|
9142
|
+
if (cursorOp) {
|
|
9143
|
+
return patchMongoCursorInstance(result, {
|
|
9144
|
+
cfg,
|
|
9145
|
+
sid,
|
|
9146
|
+
aid,
|
|
9147
|
+
collection,
|
|
9148
|
+
dbName,
|
|
9149
|
+
op,
|
|
9150
|
+
args,
|
|
9151
|
+
spanContext,
|
|
9152
|
+
});
|
|
9153
|
+
}
|
|
9154
|
+
if (result && typeof result.then === 'function') {
|
|
9155
|
+
return result.then(
|
|
9156
|
+
(value: any) => {
|
|
9157
|
+
emitSuccess(value);
|
|
9158
|
+
return value;
|
|
9159
|
+
},
|
|
9160
|
+
(error: any) => {
|
|
9161
|
+
emitFailure(error);
|
|
9162
|
+
throw error;
|
|
9163
|
+
},
|
|
9164
|
+
);
|
|
9165
|
+
}
|
|
9166
|
+
if (callbackIndex < 0) {
|
|
9167
|
+
emitSuccess(result);
|
|
9168
|
+
}
|
|
9169
|
+
return result;
|
|
9170
|
+
} catch (error) {
|
|
9171
|
+
emitFailure(error);
|
|
9172
|
+
throw error;
|
|
9173
|
+
}
|
|
9174
|
+
};
|
|
9175
|
+
}
|
|
9176
|
+
|
|
9177
|
+
function patchMongoCollectionPrototype(proto: any, cfg: MongoDbPatchConfig): void {
|
|
9178
|
+
if (!proto) return;
|
|
9179
|
+
for (const op of MONGODB_PROMISE_OPS) {
|
|
9180
|
+
patchMongoCollectionMethod(proto, op, false, cfg);
|
|
9181
|
+
}
|
|
9182
|
+
for (const op of MONGODB_CURSOR_OPS) {
|
|
9183
|
+
patchMongoCollectionMethod(proto, op, true, cfg);
|
|
9184
|
+
}
|
|
9185
|
+
}
|
|
9186
|
+
|
|
9187
|
+
function patchMongoDbFromModuleExports(mongoModule: any, cfg: MongoDbPatchConfig): void {
|
|
9188
|
+
if (!mongoModule) return;
|
|
9189
|
+
const constructors = new Set<any>();
|
|
9190
|
+
const addCtor = (candidate: any) => {
|
|
9191
|
+
if (typeof candidate === 'function' && candidate.prototype) {
|
|
9192
|
+
constructors.add(candidate);
|
|
9193
|
+
}
|
|
9194
|
+
};
|
|
9195
|
+
|
|
9196
|
+
addCtor(mongoModule?.Collection);
|
|
9197
|
+
addCtor(mongoModule?.default?.Collection);
|
|
9198
|
+
|
|
9199
|
+
for (const ctor of constructors) {
|
|
9200
|
+
patchMongoCollectionPrototype(ctor.prototype, cfg);
|
|
9201
|
+
}
|
|
9202
|
+
}
|
|
9203
|
+
|
|
9204
|
+
function installMongoDbRequireHook(): void {
|
|
9205
|
+
if (mongoDbRequireHookInstalled) return;
|
|
9206
|
+
mongoDbRequireHookInstalled = true;
|
|
9207
|
+
|
|
9208
|
+
try {
|
|
9209
|
+
const rim = requireOptionalHostModule('require-in-the-middle');
|
|
9210
|
+
const Hook = rim?.Hook ?? rim;
|
|
9211
|
+
if (typeof Hook !== 'function') return;
|
|
9212
|
+
|
|
9213
|
+
// eslint-disable-next-line no-new
|
|
9214
|
+
new Hook(['mongodb'], (exports: any) => {
|
|
9215
|
+
for (const cfg of mongoDbPatchConfigs) {
|
|
9216
|
+
patchMongoDbFromModuleExports(exports, cfg);
|
|
9217
|
+
}
|
|
9218
|
+
return exports;
|
|
9219
|
+
});
|
|
9220
|
+
} catch {}
|
|
9221
|
+
}
|
|
9222
|
+
|
|
9223
|
+
export function patchMongoDb(cfg: MongoDbPatchConfig): void {
|
|
9224
|
+
mongoDbPatchConfigs.push(cfg);
|
|
9225
|
+
installMongoDbRequireHook();
|
|
9226
|
+
|
|
9227
|
+
const mongoModules = new Set<any>();
|
|
9228
|
+
const resolvedMongoModule = requireOptionalHostModule('mongodb');
|
|
9229
|
+
if (resolvedMongoModule) {
|
|
9230
|
+
mongoModules.add(resolvedMongoModule);
|
|
9231
|
+
}
|
|
9232
|
+
for (const loadedMongoModule of getLoadedModuleExportsByPackage('mongodb')) {
|
|
9233
|
+
mongoModules.add(loadedMongoModule);
|
|
9234
|
+
}
|
|
9235
|
+
if (!mongoModules.size) return;
|
|
9236
|
+
|
|
9237
|
+
for (const mongoModule of mongoModules) {
|
|
9238
|
+
patchMongoDbFromModuleExports(mongoModule, cfg);
|
|
9239
|
+
}
|
|
9240
|
+
}
|
|
9241
|
+
|
|
8591
9242
|
// ===================================================================
|
|
8592
9243
|
// Auto init helpers
|
|
8593
9244
|
// ===================================================================
|
|
@@ -9015,6 +9666,7 @@ export async function initRepro(cfg: ReproInitConfig): Promise<void> {
|
|
|
9015
9666
|
patchKafkaJs(integrationCfg);
|
|
9016
9667
|
patchAmqplib(integrationCfg);
|
|
9017
9668
|
patchRedis(integrationCfg);
|
|
9669
|
+
patchMongoDb(integrationCfg);
|
|
9018
9670
|
patchSendgridMail(integrationCfg);
|
|
9019
9671
|
patchMongooseIntegration(reproAutoMiddlewareConfig);
|
|
9020
9672
|
|
|
@@ -9066,6 +9718,8 @@ export const __reproTestHooks = {
|
|
|
9066
9718
|
patchAmqplibConnectionForTest: patchAmqplibConnection,
|
|
9067
9719
|
patchAmqplibChannelForTest: patchAmqplibChannel,
|
|
9068
9720
|
wrapAmqplibConsumeHandlerForTest: wrapAmqplibConsumeHandler,
|
|
9721
|
+
patchMongoDbModuleForTest: patchMongoDbFromModuleExports,
|
|
9722
|
+
patchMongoCollectionPrototypeForTest: patchMongoCollectionPrototype,
|
|
9069
9723
|
chunkTraceEventsForTransportForTest: chunkTraceEventsForTransport,
|
|
9070
9724
|
estimateTraceBatchSerializedBytesForTest: estimateTraceBatchSerializedBytes,
|
|
9071
9725
|
sanitizeTraceValueForPrivacyForTest: sanitizeTraceValueForPrivacy,
|