@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 +27 -0
- package/dist/index.js +278 -162
- package/package.json +2 -2
- package/src/index.ts +265 -153
- package/test/mongodb-esm-import-hook.test.js +207 -0
- package/test/mongodb-suppression-cleanup.test.js +72 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reproapp/node-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.32",
|
|
4
4
|
"description": "Repro Nest SDK",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"build": "tsc -p tsconfig.json",
|
|
13
13
|
"dev": "tsc -p tsconfig.json --watch --preserveWatchOutput",
|
|
14
14
|
"prepublishOnly": "npm run build",
|
|
15
|
-
"test": "npm run build && node test/unawaited.test.js && node test/integration-unawaited.js && node test/request-flush-timing.test.js && node test/request-capture-background.test.js && node test/init-auto-http-server.test.js && node test/client-performance-regression.test.js && node test/request-manifest-priority.test.js && node test/runtime-no-double-invoke.test.js && node test/express-trace-http-args.test.js && node test/trace-batch-size.test.js && node test/sdk-background-priority.test.js && node test/ingest-queue-retention.test.js && node test/ingest-high-priority-retention.test.js && node test/ingest-critical-retention.test.js && node test/ingest-critical-retry-retention.test.js && node test/ingest-timeout.test.js && node -r ./tracer/register test/promise-map.test.js && node test/disable-subtree.test.js && node test/circular-capture.test.js && node test/wrap-plugin-arrow-args.test.js && node test/wrap-plugin-super-call.test.js && node test/function-arg-identity.test.js && node test/privacy-runtime-policy.test.js && node test/runtime-privacy-materialization.test.js && node test/kafka-runtime-privacy-policy.test.js && node test/amqplib-integration.test.js && node test/mongodb-integration.test.js",
|
|
15
|
+
"test": "npm run build && node test/unawaited.test.js && node test/integration-unawaited.js && node test/request-flush-timing.test.js && node test/request-capture-background.test.js && node test/init-auto-http-server.test.js && node test/client-performance-regression.test.js && node test/request-manifest-priority.test.js && node test/runtime-no-double-invoke.test.js && node test/express-trace-http-args.test.js && node test/trace-batch-size.test.js && node test/sdk-background-priority.test.js && node test/ingest-queue-retention.test.js && node test/ingest-high-priority-retention.test.js && node test/ingest-critical-retention.test.js && node test/ingest-critical-retry-retention.test.js && node test/ingest-timeout.test.js && node -r ./tracer/register test/promise-map.test.js && node test/disable-subtree.test.js && node test/circular-capture.test.js && node test/wrap-plugin-arrow-args.test.js && node test/wrap-plugin-super-call.test.js && node test/function-arg-identity.test.js && node test/privacy-runtime-policy.test.js && node test/runtime-privacy-materialization.test.js && node test/kafka-runtime-privacy-policy.test.js && node test/amqplib-integration.test.js && node test/mongodb-integration.test.js && node test/mongodb-esm-import-hook.test.js && node test/mongodb-suppression-cleanup.test.js",
|
|
16
16
|
"test:containers": "npm run build && node test/runtime-no-double-invoke.testcontainers.test.js && node test/wrap-plugin-super-call.testcontainers.test.js && node test/function-arg-identity.testcontainers.test.js"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { AsyncLocalStorage } from 'async_hooks';
|
|
|
5
5
|
import { randomUUID } from 'crypto';
|
|
6
6
|
import { createRequire } from 'module';
|
|
7
7
|
import { join } from 'path';
|
|
8
|
+
import { pathToFileURL } from 'url';
|
|
8
9
|
import {
|
|
9
10
|
configureIngestQueueDrain,
|
|
10
11
|
enqueueIngestEntries,
|
|
@@ -1162,6 +1163,7 @@ type NativeMongoSuppression = {
|
|
|
1162
1163
|
collection?: string | null;
|
|
1163
1164
|
ops?: Set<string>;
|
|
1164
1165
|
startedAt: number;
|
|
1166
|
+
ownerStore?: Ctx;
|
|
1165
1167
|
};
|
|
1166
1168
|
|
|
1167
1169
|
type RequestCaptureScopeState = {
|
|
@@ -1235,6 +1237,7 @@ function pushNativeMongoSuppression(collection: any, ops?: string[] | readonly s
|
|
|
1235
1237
|
collection: collection == null ? null : String(collection),
|
|
1236
1238
|
ops: normalizedOps.length ? new Set(normalizedOps) : undefined,
|
|
1237
1239
|
startedAt: Date.now(),
|
|
1240
|
+
ownerStore: store,
|
|
1238
1241
|
};
|
|
1239
1242
|
if (!Array.isArray(store.nativeMongoSuppressions)) {
|
|
1240
1243
|
store.nativeMongoSuppressions = [];
|
|
@@ -1245,12 +1248,22 @@ function pushNativeMongoSuppression(collection: any, ops?: string[] | readonly s
|
|
|
1245
1248
|
|
|
1246
1249
|
function popNativeMongoSuppression(token: NativeMongoSuppression | null | undefined): void {
|
|
1247
1250
|
if (!token) return;
|
|
1248
|
-
const store = als.getStore();
|
|
1251
|
+
const store = token.ownerStore ?? als.getStore();
|
|
1249
1252
|
const suppressions = store?.nativeMongoSuppressions;
|
|
1250
|
-
if (
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1253
|
+
if (Array.isArray(suppressions) && suppressions.length > 0) {
|
|
1254
|
+
const index = suppressions.indexOf(token);
|
|
1255
|
+
if (index >= 0) {
|
|
1256
|
+
suppressions.splice(index, 1);
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
token.ownerStore = undefined;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
function releaseNativeMongoSuppression(target: any): void {
|
|
1263
|
+
const token = target?.__repro_native_mongo_suppression;
|
|
1264
|
+
popNativeMongoSuppression(token);
|
|
1265
|
+
try { delete target.__repro_native_mongo_suppression; } catch {
|
|
1266
|
+
try { target.__repro_native_mongo_suppression = undefined; } catch {}
|
|
1254
1267
|
}
|
|
1255
1268
|
}
|
|
1256
1269
|
|
|
@@ -1260,8 +1273,12 @@ function isNativeMongoSuppressed(collection: any, op: string): boolean {
|
|
|
1260
1273
|
const normalizedCollection = collection == null ? null : String(collection);
|
|
1261
1274
|
const normalizedOp = normalizeNativeMongoSuppressionOp(op);
|
|
1262
1275
|
const now = Date.now();
|
|
1263
|
-
for (
|
|
1264
|
-
|
|
1276
|
+
for (let i = suppressions.length - 1; i >= 0; i -= 1) {
|
|
1277
|
+
const token = suppressions[i];
|
|
1278
|
+
if (!token || now - token.startedAt > 60000) {
|
|
1279
|
+
suppressions.splice(i, 1);
|
|
1280
|
+
continue;
|
|
1281
|
+
}
|
|
1265
1282
|
if (token.collection && normalizedCollection && token.collection !== normalizedCollection) continue;
|
|
1266
1283
|
if (token.ops && token.ops.size > 0 && !token.ops.has(normalizedOp)) continue;
|
|
1267
1284
|
return true;
|
|
@@ -5571,41 +5588,44 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5571
5588
|
});
|
|
5572
5589
|
|
|
5573
5590
|
schema.post('save', { document: true }, function () {
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
const meta = (this as any).__repro_meta || {};
|
|
5579
|
-
const before = null;
|
|
5580
|
-
const after = this;
|
|
5581
|
-
const collection = meta.collection || resolveCollectionOrWarn(this, 'doc');
|
|
5582
|
-
const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
|
|
5583
|
-
if (!shouldCaptureDbSpan(spanContext)) return;
|
|
5584
|
-
const modifiedPaths = Array.isArray(meta.modifiedPaths) ? meta.modifiedPaths : [];
|
|
5585
|
-
|
|
5586
|
-
const query = meta.wasNew
|
|
5587
|
-
? { op: 'insertOne', doc: after }
|
|
5588
|
-
: {
|
|
5589
|
-
filter: { _id: this._id },
|
|
5590
|
-
update: buildModifiedPathUpdate(this, modifiedPaths),
|
|
5591
|
-
options: { upsert: false },
|
|
5592
|
-
};
|
|
5591
|
+
try {
|
|
5592
|
+
const { sid, aid } = getCtx();
|
|
5593
|
+
if (!sid || !aid) return;
|
|
5594
|
+
if ((this as any).$isSubdocument) return;
|
|
5593
5595
|
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5596
|
+
const meta = (this as any).__repro_meta || {};
|
|
5597
|
+
const before = null;
|
|
5598
|
+
const after = this;
|
|
5599
|
+
const collection = meta.collection || resolveCollectionOrWarn(this, 'doc');
|
|
5600
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
|
|
5601
|
+
if (!shouldCaptureDbSpan(spanContext)) return;
|
|
5602
|
+
const modifiedPaths = Array.isArray(meta.modifiedPaths) ? meta.modifiedPaths : [];
|
|
5603
|
+
|
|
5604
|
+
const query = meta.wasNew
|
|
5605
|
+
? { op: 'insertOne', doc: after }
|
|
5606
|
+
: {
|
|
5607
|
+
filter: { _id: this._id },
|
|
5608
|
+
update: buildModifiedPathUpdate(this, modifiedPaths),
|
|
5609
|
+
options: { upsert: false },
|
|
5610
|
+
};
|
|
5611
|
+
|
|
5612
|
+
emitDbQuery(cfg, sid, aid ?? undefined, {
|
|
5613
|
+
collection,
|
|
5614
|
+
pk: { _id: (this as any)._id },
|
|
5615
|
+
before,
|
|
5616
|
+
after,
|
|
5617
|
+
op: meta.wasNew ? 'insert' : 'update',
|
|
5618
|
+
query,
|
|
5619
|
+
t: alignTimestamp(meta.t0 ?? Date.now()),
|
|
5620
|
+
spanContext,
|
|
5621
|
+
});
|
|
5622
|
+
} finally {
|
|
5623
|
+
releaseNativeMongoSuppression(this);
|
|
5624
|
+
}
|
|
5605
5625
|
});
|
|
5606
5626
|
|
|
5607
5627
|
schema.post('save', { document: true }, function (error: any, _doc: any, next: Function) {
|
|
5608
|
-
|
|
5628
|
+
releaseNativeMongoSuppression(this);
|
|
5609
5629
|
next(error);
|
|
5610
5630
|
});
|
|
5611
5631
|
|
|
@@ -5630,35 +5650,38 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5630
5650
|
});
|
|
5631
5651
|
|
|
5632
5652
|
schema.post<Query<any, any>>('findOneAndUpdate', function (res: any) {
|
|
5633
|
-
|
|
5634
|
-
|
|
5653
|
+
try {
|
|
5654
|
+
const { sid, aid } = getCtx();
|
|
5655
|
+
if (!sid || !aid) return;
|
|
5635
5656
|
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5657
|
+
const before = null;
|
|
5658
|
+
const after = res ?? null;
|
|
5659
|
+
const collection = (this as any).__repro_collection || resolveCollectionOrWarn(this, 'query');
|
|
5660
|
+
const spanContext = (this as any).__repro_spanContext || captureSpanContextFromTracer(this);
|
|
5661
|
+
if (!shouldCaptureDbSpan(spanContext)) return;
|
|
5662
|
+
const filter = (this as any).__repro_filter;
|
|
5663
|
+
const pk = after?._id ?? (filter && typeof filter === 'object' ? (filter as any)._id : undefined);
|
|
5643
5664
|
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5665
|
+
emitDbQuery(cfg, sid, aid ?? undefined, {
|
|
5666
|
+
collection,
|
|
5667
|
+
pk: { _id: pk },
|
|
5668
|
+
before,
|
|
5669
|
+
after,
|
|
5670
|
+
op: 'update',
|
|
5671
|
+
queryRaw: {
|
|
5672
|
+
filter,
|
|
5673
|
+
update: (this as any).__repro_update,
|
|
5674
|
+
},
|
|
5675
|
+
t: alignTimestamp((this as any).__repro_t0 ?? Date.now()),
|
|
5676
|
+
spanContext,
|
|
5677
|
+
});
|
|
5678
|
+
} finally {
|
|
5679
|
+
releaseNativeMongoSuppression(this);
|
|
5680
|
+
}
|
|
5658
5681
|
});
|
|
5659
5682
|
|
|
5660
5683
|
schema.post<Query<any, any>>('findOneAndUpdate', function (this: any, error: any, _res: any, next: Function) {
|
|
5661
|
-
|
|
5684
|
+
releaseNativeMongoSuppression(this);
|
|
5662
5685
|
next(error);
|
|
5663
5686
|
} as any);
|
|
5664
5687
|
|
|
@@ -5680,27 +5703,30 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5680
5703
|
});
|
|
5681
5704
|
|
|
5682
5705
|
schema.post<Query<any, any>>('deleteOne', { document: false, query: true }, function () {
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5706
|
+
try {
|
|
5707
|
+
const { sid, aid } = getCtx(); if (!sid || !aid) return;
|
|
5708
|
+
const before = null;
|
|
5709
|
+
const collection = (this as any).__repro_collection || resolveCollectionOrWarn(this, 'query');
|
|
5710
|
+
const filter = (this as any).__repro_filter ?? undefined;
|
|
5711
|
+
const spanContext = (this as any).__repro_spanContext || captureSpanContextFromTracer(this);
|
|
5712
|
+
if (!shouldCaptureDbSpan(spanContext)) return;
|
|
5713
|
+
emitDbQuery(cfg, sid, aid ?? undefined, {
|
|
5714
|
+
collection,
|
|
5715
|
+
pk: filter && typeof filter === 'object' && '_id' in filter ? { _id: (filter as any)._id } : undefined,
|
|
5716
|
+
before,
|
|
5717
|
+
after: null,
|
|
5718
|
+
op: 'delete',
|
|
5719
|
+
queryRaw: { filter },
|
|
5720
|
+
t: alignTimestamp((this as any).__repro_t0 ?? Date.now()),
|
|
5721
|
+
spanContext,
|
|
5722
|
+
});
|
|
5723
|
+
} finally {
|
|
5724
|
+
releaseNativeMongoSuppression(this);
|
|
5725
|
+
}
|
|
5700
5726
|
});
|
|
5701
5727
|
|
|
5702
5728
|
schema.post<Query<any, any>>('deleteOne', { document: false, query: true }, function (this: any, error: any, _res: any, next: Function) {
|
|
5703
|
-
|
|
5729
|
+
releaseNativeMongoSuppression(this);
|
|
5704
5730
|
next(error);
|
|
5705
5731
|
} as any);
|
|
5706
5732
|
|
|
@@ -5765,31 +5791,34 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5765
5791
|
});
|
|
5766
5792
|
|
|
5767
5793
|
schema.post(op as any, function (this: any, res: any) {
|
|
5768
|
-
|
|
5769
|
-
|
|
5794
|
+
try {
|
|
5795
|
+
const { sid, aid } = getCtx();
|
|
5796
|
+
if (!sid) return;
|
|
5770
5797
|
|
|
5771
|
-
|
|
5772
|
-
|
|
5798
|
+
const meta = (this as any).__repro_qmeta || { t0: Date.now(), collection: 'unknown', op };
|
|
5799
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
|
|
5773
5800
|
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5801
|
+
emitDbQuery(cfg, sid, aid, {
|
|
5802
|
+
collection: meta.collection,
|
|
5803
|
+
op,
|
|
5804
|
+
queryRaw: {
|
|
5805
|
+
filter: meta.rawFilter,
|
|
5806
|
+
update: meta.rawUpdate,
|
|
5807
|
+
projection: meta.rawProjection,
|
|
5808
|
+
options: meta.rawOptions,
|
|
5809
|
+
},
|
|
5810
|
+
resultMetaRaw: res,
|
|
5811
|
+
durMs: Date.now() - meta.t0,
|
|
5812
|
+
t: alignedNow(),
|
|
5813
|
+
spanContext,
|
|
5814
|
+
});
|
|
5815
|
+
} finally {
|
|
5816
|
+
releaseNativeMongoSuppression(this);
|
|
5817
|
+
}
|
|
5789
5818
|
});
|
|
5790
5819
|
|
|
5791
5820
|
schema.post(op as any, function (this: any, error: any, _res: any, next: Function) {
|
|
5792
|
-
|
|
5821
|
+
releaseNativeMongoSuppression(this);
|
|
5793
5822
|
next(error);
|
|
5794
5823
|
} as any);
|
|
5795
5824
|
}
|
|
@@ -5823,25 +5852,28 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5823
5852
|
} as any);
|
|
5824
5853
|
|
|
5825
5854
|
schema.post<any>('insertMany' as any, { document: false, query: false } as any, function (this: any, docs: any[]) {
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5855
|
+
try {
|
|
5856
|
+
const { sid, aid } = getCtx();
|
|
5857
|
+
if (!sid) return;
|
|
5858
|
+
const meta = (this as any).__repro_insert_meta || { t0: Date.now(), collection: 'unknown' };
|
|
5859
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
|
|
5860
|
+
|
|
5861
|
+
emitDbQuery(cfg, sid, aid ?? undefined, {
|
|
5862
|
+
collection: meta.collection,
|
|
5863
|
+
op: 'insertMany',
|
|
5864
|
+
queryRaw: { docs: meta.rawDocs ?? undefined },
|
|
5865
|
+
resultMetaRaw: docs,
|
|
5866
|
+
durMs: Date.now() - meta.t0,
|
|
5867
|
+
t: alignedNow(),
|
|
5868
|
+
spanContext,
|
|
5869
|
+
});
|
|
5870
|
+
} finally {
|
|
5871
|
+
releaseNativeMongoSuppression(this);
|
|
5872
|
+
}
|
|
5841
5873
|
} as any);
|
|
5842
5874
|
|
|
5843
5875
|
schema.post<any>('insertMany' as any, { document: false, query: false } as any, function (this: any, error: any, _res: any, next: Function) {
|
|
5844
|
-
|
|
5876
|
+
releaseNativeMongoSuppression(this);
|
|
5845
5877
|
next(error);
|
|
5846
5878
|
} as any);
|
|
5847
5879
|
|
|
@@ -5870,25 +5902,28 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5870
5902
|
} as any);
|
|
5871
5903
|
|
|
5872
5904
|
schema.post<any>('bulkWrite' as any, { document: false, query: false } as any, function (this: any, res: any) {
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5905
|
+
try {
|
|
5906
|
+
const { sid, aid } = getCtx();
|
|
5907
|
+
if (!sid) return;
|
|
5908
|
+
const meta = (this as any).__repro_bulk_meta || { t0: Date.now(), collection: 'unknown' };
|
|
5909
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
|
|
5910
|
+
|
|
5911
|
+
emitDbQuery(cfg, sid, aid, {
|
|
5912
|
+
collection: meta.collection,
|
|
5913
|
+
op: 'bulkWrite',
|
|
5914
|
+
queryRaw: { ops: meta.rawOps ?? undefined },
|
|
5915
|
+
resultMetaRaw: res,
|
|
5916
|
+
durMs: Date.now() - meta.t0,
|
|
5917
|
+
t: alignedNow(),
|
|
5918
|
+
spanContext,
|
|
5919
|
+
});
|
|
5920
|
+
} finally {
|
|
5921
|
+
releaseNativeMongoSuppression(this);
|
|
5922
|
+
}
|
|
5888
5923
|
} as any);
|
|
5889
5924
|
|
|
5890
5925
|
schema.post<any>('bulkWrite' as any, { document: false, query: false } as any, function (this: any, error: any, _res: any, next: Function) {
|
|
5891
|
-
|
|
5926
|
+
releaseNativeMongoSuppression(this);
|
|
5892
5927
|
next(error);
|
|
5893
5928
|
} as any);
|
|
5894
5929
|
|
|
@@ -5923,26 +5958,29 @@ export function reproMongoosePlugin(cfg: ReproMiddlewareConfig) {
|
|
|
5923
5958
|
});
|
|
5924
5959
|
|
|
5925
5960
|
schema.post('aggregate', function (this: any, res: any[]) {
|
|
5926
|
-
|
|
5927
|
-
|
|
5961
|
+
try {
|
|
5962
|
+
const { sid, aid } = getCtx();
|
|
5963
|
+
if (!sid) return;
|
|
5928
5964
|
|
|
5929
|
-
|
|
5930
|
-
|
|
5965
|
+
const meta = (this as any).__repro_aggmeta || { t0: Date.now(), collection: 'unknown' };
|
|
5966
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer(this);
|
|
5931
5967
|
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5968
|
+
emitDbQuery(cfg, sid, aid, {
|
|
5969
|
+
collection: meta.collection,
|
|
5970
|
+
op: 'aggregate',
|
|
5971
|
+
queryRaw: { pipeline: meta.rawPipeline },
|
|
5972
|
+
resultMetaRaw: res,
|
|
5973
|
+
durMs: Date.now() - meta.t0,
|
|
5974
|
+
t: alignedNow(),
|
|
5975
|
+
spanContext,
|
|
5976
|
+
});
|
|
5977
|
+
} finally {
|
|
5978
|
+
releaseNativeMongoSuppression(this);
|
|
5979
|
+
}
|
|
5942
5980
|
});
|
|
5943
5981
|
|
|
5944
5982
|
schema.post('aggregate', function (this: any, error: any, _res: any, next: Function) {
|
|
5945
|
-
|
|
5983
|
+
releaseNativeMongoSuppression(this);
|
|
5946
5984
|
next(error);
|
|
5947
5985
|
} as any);
|
|
5948
5986
|
};
|
|
@@ -8810,6 +8848,8 @@ export type MongoDbPatchConfig = ReproMiddlewareConfig & {
|
|
|
8810
8848
|
|
|
8811
8849
|
const mongoDbPatchConfigs: MongoDbPatchConfig[] = [];
|
|
8812
8850
|
let mongoDbRequireHookInstalled = false;
|
|
8851
|
+
let mongoDbImportHookInstalled = false;
|
|
8852
|
+
let mongoDbImportHookReady: Promise<void> | null = null;
|
|
8813
8853
|
|
|
8814
8854
|
const MONGODB_PROMISE_OPS = [
|
|
8815
8855
|
'insertOne',
|
|
@@ -8832,6 +8872,12 @@ const MONGODB_PROMISE_OPS = [
|
|
|
8832
8872
|
const MONGODB_CURSOR_OPS = ['find', 'aggregate'] as const;
|
|
8833
8873
|
const MONGODB_CURSOR_TERMINALS = ['toArray', 'next', 'forEach'] as const;
|
|
8834
8874
|
|
|
8875
|
+
function registerMongoDbPatchConfig(cfg: MongoDbPatchConfig): void {
|
|
8876
|
+
if (!mongoDbPatchConfigs.includes(cfg)) {
|
|
8877
|
+
mongoDbPatchConfigs.push(cfg);
|
|
8878
|
+
}
|
|
8879
|
+
}
|
|
8880
|
+
|
|
8835
8881
|
function resolveMongoDbRuntimeContext(cfg: MongoDbPatchConfig) {
|
|
8836
8882
|
const ctx = getCtx();
|
|
8837
8883
|
const fallback = cfg.resolveContext?.() ?? {};
|
|
@@ -8842,6 +8888,18 @@ function resolveMongoDbRuntimeContext(cfg: MongoDbPatchConfig) {
|
|
|
8842
8888
|
};
|
|
8843
8889
|
}
|
|
8844
8890
|
|
|
8891
|
+
function resolveMongoDbCaptureContext(): { cfg: MongoDbPatchConfig; sid: string; aid: string | null } | null {
|
|
8892
|
+
for (let i = mongoDbPatchConfigs.length - 1; i >= 0; i -= 1) {
|
|
8893
|
+
const cfg = mongoDbPatchConfigs[i];
|
|
8894
|
+
if (!cfg) continue;
|
|
8895
|
+
const { sid, aid } = resolveMongoDbRuntimeContext(cfg);
|
|
8896
|
+
if (sid) {
|
|
8897
|
+
return { cfg, sid, aid };
|
|
8898
|
+
}
|
|
8899
|
+
}
|
|
8900
|
+
return null;
|
|
8901
|
+
}
|
|
8902
|
+
|
|
8845
8903
|
function resolveMongoCollectionName(collection: any): string {
|
|
8846
8904
|
const candidates = [
|
|
8847
8905
|
collection?.collectionName,
|
|
@@ -9142,10 +9200,11 @@ function patchMongoCollectionMethod(proto: any, op: string, cursorOp: boolean, c
|
|
|
9142
9200
|
return original.apply(this, args);
|
|
9143
9201
|
}
|
|
9144
9202
|
|
|
9145
|
-
const
|
|
9146
|
-
if (!
|
|
9203
|
+
const captureContext = resolveMongoDbCaptureContext();
|
|
9204
|
+
if (!captureContext) {
|
|
9147
9205
|
return original.apply(this, args);
|
|
9148
9206
|
}
|
|
9207
|
+
const { cfg: activeCfg, sid, aid } = captureContext;
|
|
9149
9208
|
|
|
9150
9209
|
const spanContext = captureSpanContextFromTracer(this);
|
|
9151
9210
|
const t0 = Date.now();
|
|
@@ -9157,7 +9216,7 @@ function patchMongoCollectionMethod(proto: any, op: string, cursorOp: boolean, c
|
|
|
9157
9216
|
const emitSuccess = (result: any) => {
|
|
9158
9217
|
if (emitted) return;
|
|
9159
9218
|
emitted = true;
|
|
9160
|
-
emitDbQuery(
|
|
9219
|
+
emitDbQuery(activeCfg, sid, aid ?? undefined, {
|
|
9161
9220
|
type: 'mongo',
|
|
9162
9221
|
collection,
|
|
9163
9222
|
op,
|
|
@@ -9174,7 +9233,7 @@ function patchMongoCollectionMethod(proto: any, op: string, cursorOp: boolean, c
|
|
|
9174
9233
|
const emitFailure = (error: any) => {
|
|
9175
9234
|
if (emitted) return;
|
|
9176
9235
|
emitted = true;
|
|
9177
|
-
emitDbQuery(
|
|
9236
|
+
emitDbQuery(activeCfg, sid, aid ?? undefined, {
|
|
9178
9237
|
type: 'mongo',
|
|
9179
9238
|
collection,
|
|
9180
9239
|
op,
|
|
@@ -9199,7 +9258,7 @@ function patchMongoCollectionMethod(proto: any, op: string, cursorOp: boolean, c
|
|
|
9199
9258
|
const result = original.apply(this, actualArgs);
|
|
9200
9259
|
if (cursorOp) {
|
|
9201
9260
|
return patchMongoCursorInstance(result, {
|
|
9202
|
-
cfg,
|
|
9261
|
+
cfg: activeCfg,
|
|
9203
9262
|
sid,
|
|
9204
9263
|
aid,
|
|
9205
9264
|
collection,
|
|
@@ -9283,6 +9342,7 @@ function patchMongoClientPrototype(proto: any, cfg: MongoDbPatchConfig): void {
|
|
|
9283
9342
|
}
|
|
9284
9343
|
|
|
9285
9344
|
function patchMongoDbFromModuleExports(mongoModule: any, cfg: MongoDbPatchConfig): void {
|
|
9345
|
+
registerMongoDbPatchConfig(cfg);
|
|
9286
9346
|
if (!mongoModule) return;
|
|
9287
9347
|
const constructors = new Set<any>();
|
|
9288
9348
|
const addCtor = (candidate: any) => {
|
|
@@ -9343,9 +9403,50 @@ function installMongoDbRequireHook(): void {
|
|
|
9343
9403
|
} catch {}
|
|
9344
9404
|
}
|
|
9345
9405
|
|
|
9406
|
+
function installMongoDbImportHook(): Promise<void> {
|
|
9407
|
+
if (mongoDbImportHookInstalled) return mongoDbImportHookReady ?? Promise.resolve();
|
|
9408
|
+
mongoDbImportHookInstalled = true;
|
|
9409
|
+
|
|
9410
|
+
mongoDbImportHookReady = (async () => {
|
|
9411
|
+
try {
|
|
9412
|
+
const nodeModule = requireOptionalHostModule('node:module') ?? requireOptionalHostModule('module');
|
|
9413
|
+
if (typeof nodeModule?.register !== 'function') return;
|
|
9414
|
+
|
|
9415
|
+
const iitm = requireOptionalHostModule('import-in-the-middle');
|
|
9416
|
+
const Hook = iitm?.Hook ?? iitm;
|
|
9417
|
+
if (typeof Hook !== 'function') return;
|
|
9418
|
+
|
|
9419
|
+
let waitForAllMessagesAcknowledged: undefined | (() => Promise<void>);
|
|
9420
|
+
let registerOptions: any = { data: { include: ['mongodb'] } };
|
|
9421
|
+
if (typeof iitm?.createAddHookMessageChannel === 'function') {
|
|
9422
|
+
const channel = iitm.createAddHookMessageChannel();
|
|
9423
|
+
registerOptions = channel.registerOptions;
|
|
9424
|
+
waitForAllMessagesAcknowledged = channel.waitForAllMessagesAcknowledged;
|
|
9425
|
+
}
|
|
9426
|
+
|
|
9427
|
+
nodeModule.register('import-in-the-middle/hook.mjs', pathToFileURL(__filename), registerOptions);
|
|
9428
|
+
|
|
9429
|
+
// eslint-disable-next-line no-new
|
|
9430
|
+
new Hook(['mongodb'], (exports: any) => {
|
|
9431
|
+
for (const cfg of mongoDbPatchConfigs) {
|
|
9432
|
+
patchMongoDbFromModuleExports(exports, cfg);
|
|
9433
|
+
}
|
|
9434
|
+
return exports;
|
|
9435
|
+
});
|
|
9436
|
+
|
|
9437
|
+
if (waitForAllMessagesAcknowledged) {
|
|
9438
|
+
await waitForAllMessagesAcknowledged();
|
|
9439
|
+
}
|
|
9440
|
+
} catch {}
|
|
9441
|
+
})();
|
|
9442
|
+
|
|
9443
|
+
return mongoDbImportHookReady;
|
|
9444
|
+
}
|
|
9445
|
+
|
|
9346
9446
|
export function patchMongoDb(cfg: MongoDbPatchConfig): void {
|
|
9347
|
-
|
|
9447
|
+
registerMongoDbPatchConfig(cfg);
|
|
9348
9448
|
installMongoDbRequireHook();
|
|
9449
|
+
void installMongoDbImportHook();
|
|
9349
9450
|
|
|
9350
9451
|
const mongoModules = new Set<any>();
|
|
9351
9452
|
for (const loadedMongoModule of getLoadedModuleExportsByPackage('mongodb')) {
|
|
@@ -9867,6 +9968,7 @@ export async function initRepro(cfg: ReproInitConfig): Promise<void> {
|
|
|
9867
9968
|
patchAmqplib(integrationCfg);
|
|
9868
9969
|
patchRedis(integrationCfg);
|
|
9869
9970
|
patchMongoDb(integrationCfg);
|
|
9971
|
+
await installMongoDbImportHook();
|
|
9870
9972
|
patchSendgridMail(integrationCfg);
|
|
9871
9973
|
patchMongooseIntegration(reproAutoMiddlewareConfig);
|
|
9872
9974
|
|
|
@@ -9901,6 +10003,16 @@ export const __reproTestHooks = {
|
|
|
9901
10003
|
lastClientActivityAt = 0;
|
|
9902
10004
|
sdkBackgroundQuietUntil = 0;
|
|
9903
10005
|
},
|
|
10006
|
+
runWithRequestContextForTest<T>(ctx: Partial<Ctx>, fn: () => T): T {
|
|
10007
|
+
return als.run({
|
|
10008
|
+
...ctx,
|
|
10009
|
+
excludedSpanIds: ctx.excludedSpanIds ?? new Set<string>(),
|
|
10010
|
+
}, fn);
|
|
10011
|
+
},
|
|
10012
|
+
getNativeMongoSuppressionCountForTest(): number {
|
|
10013
|
+
const suppressions = getCtx().nativeMongoSuppressions;
|
|
10014
|
+
return Array.isArray(suppressions) ? suppressions.length : 0;
|
|
10015
|
+
},
|
|
9904
10016
|
getRuntimePrivacyPolicyForTest(cfg: ReproMiddlewareConfig): NormalizedRuntimePrivacyPolicy | null {
|
|
9905
10017
|
return getRuntimePrivacyState(cfg).policy;
|
|
9906
10018
|
},
|