@use-tusk/drift-node-sdk 0.1.0 → 0.1.2
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/README.md +52 -3
- package/dist/index.cjs +125 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +124 -80
- package/dist/index.js.map +1 -1
- package/hook.mjs +11 -0
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@use-tusk/drift-node-sdk"><img src="https://img.shields.io/npm/v/@use-tusk/drift-node-sdk" alt="npm version"></a>
|
|
6
7
|
<a href="https://opensource.org/licenses/Apache-2.0"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License: Apache 2.0"></a>
|
|
7
|
-
<a href="https://github.com/Use-Tusk/
|
|
8
|
+
<a href="https://github.com/Use-Tusk/drift-node-sdk/commits/main/"><img src="https://img.shields.io/github/last-commit/Use-Tusk/drift-node-sdk" alt="GitHub last commit"></a>
|
|
8
9
|
</p>
|
|
9
10
|
|
|
10
11
|
The Node.js Tusk Drift SDK enables fast and deterministic API testing by capturing and replaying API calls made to/from your service. Automatically record real-world API calls, then replay them as tests using the [Tusk CLI](https://github.com/Use-Tusk/tusk-drift-cli) to find regressions. During replay, all outbound requests are intercepted with recorded data to ensure consistent behavior without side-effects.
|
|
@@ -57,6 +58,8 @@ Follow these steps in order to properly initialize the Tusk Drift SDK:
|
|
|
57
58
|
|
|
58
59
|
Create a separate file (e.g. `tdInit.ts`) to initialize the Tusk Drift SDK. This ensures the SDK is initialized as early as possible before any other modules are loaded.
|
|
59
60
|
|
|
61
|
+
#### For CommonJS Applications
|
|
62
|
+
|
|
60
63
|
```typescript
|
|
61
64
|
// tdInit.ts
|
|
62
65
|
import { TuskDrift } from "@use-tusk/drift-node-sdk";
|
|
@@ -71,6 +74,33 @@ TuskDrift.initialize({
|
|
|
71
74
|
export { TuskDrift };
|
|
72
75
|
```
|
|
73
76
|
|
|
77
|
+
#### For ESM Applications
|
|
78
|
+
|
|
79
|
+
ESM applications require additional setup to properly intercept module imports:
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// tdInit.ts
|
|
83
|
+
import { register } from 'node:module';
|
|
84
|
+
import { pathToFileURL } from 'node:url';
|
|
85
|
+
|
|
86
|
+
// Register the ESM loader
|
|
87
|
+
// This enables interception of ESM module imports
|
|
88
|
+
register('@use-tusk/drift-node-sdk/hook.mjs', pathToFileURL('./'));
|
|
89
|
+
|
|
90
|
+
import { TuskDrift } from "@use-tusk/drift-node-sdk";
|
|
91
|
+
|
|
92
|
+
// Initialize SDK immediately
|
|
93
|
+
TuskDrift.initialize({
|
|
94
|
+
apiKey: process.env.TUSK_DRIFT_API_KEY,
|
|
95
|
+
env: process.env.ENV,
|
|
96
|
+
logLevel: process.env.TUSK_DRIFT_LOG_LEVEL,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
export { TuskDrift };
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Why the ESM loader is needed**: ESM imports are statically analyzed and hoisted, meaning all imports are resolved before any code runs. The `register()` call sets up Node.js loader hooks that intercept module imports, allowing the SDK to instrument packages like `postgres`, `http`, etc. Without this, the SDK cannot patch ESM modules.
|
|
103
|
+
|
|
74
104
|
#### Configuration Options
|
|
75
105
|
|
|
76
106
|
<table>
|
|
@@ -106,7 +136,9 @@ export { TuskDrift };
|
|
|
106
136
|
|
|
107
137
|
### 2. Import SDK at Application Entry Point
|
|
108
138
|
|
|
109
|
-
|
|
139
|
+
#### For CommonJS Applications
|
|
140
|
+
|
|
141
|
+
In your main server file (e.g., `server.ts`, `index.ts`, `app.ts`), require the initialized SDK **at the very top**, before any other requires:
|
|
110
142
|
|
|
111
143
|
```typescript
|
|
112
144
|
// server.ts
|
|
@@ -117,7 +149,24 @@ import { TuskDrift } from "./tdInit"; // MUST be the first import
|
|
|
117
149
|
// Your application setup...
|
|
118
150
|
```
|
|
119
151
|
|
|
120
|
-
> **IMPORTANT**: Ensure NO require
|
|
152
|
+
> **IMPORTANT**: Ensure NO require calls are made before requiring the SDK initialization file. This guarantees proper instrumentation of all dependencies.
|
|
153
|
+
|
|
154
|
+
#### For ESM Applications
|
|
155
|
+
|
|
156
|
+
For ESM applications, you **cannot** control import order within your application code because all imports are hoisted. Instead, use the `--import` flag:
|
|
157
|
+
|
|
158
|
+
**Update your package.json scripts**:
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"scripts": {
|
|
163
|
+
"dev": "node --import ./dist/tdInit.js dist/server.js"
|
|
164
|
+
"dev:record": "TUSK_DRIFT_MODE=RECORD node --import ./dist/tdInit.js dist/server.js"
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Why `--import` is required for ESM**: In ESM, all `import` statements are hoisted and evaluated before any code runs, making it impossible to control import order within a file. The `--import` flag ensures the SDK initialization (including loader registration) happens in a separate phase before your application code loads, guaranteeing proper module interception.
|
|
121
170
|
|
|
122
171
|
### 3. Update Configuration File
|
|
123
172
|
|
package/dist/index.cjs
CHANGED
|
@@ -34,6 +34,8 @@ let semver = require("semver");
|
|
|
34
34
|
semver = __toESM(semver);
|
|
35
35
|
let require_in_the_middle = require("require-in-the-middle");
|
|
36
36
|
require_in_the_middle = __toESM(require_in_the_middle);
|
|
37
|
+
let import_in_the_middle = require("import-in-the-middle");
|
|
38
|
+
import_in_the_middle = __toESM(import_in_the_middle);
|
|
37
39
|
let __use_tusk_drift_schemas_google_protobuf_struct = require("@use-tusk/drift-schemas/google/protobuf/struct");
|
|
38
40
|
__use_tusk_drift_schemas_google_protobuf_struct = __toESM(__use_tusk_drift_schemas_google_protobuf_struct);
|
|
39
41
|
let __opentelemetry_api = require("@opentelemetry/api");
|
|
@@ -89,7 +91,7 @@ var TdInstrumentationAbstract = class {
|
|
|
89
91
|
|
|
90
92
|
//#endregion
|
|
91
93
|
//#region package.json
|
|
92
|
-
var version = "0.1.
|
|
94
|
+
var version = "0.1.2";
|
|
93
95
|
|
|
94
96
|
//#endregion
|
|
95
97
|
//#region src/version.ts
|
|
@@ -414,10 +416,11 @@ function sendUnpatchedDependencyAlert({ method, spanId, traceId, stackTrace }) {
|
|
|
414
416
|
|
|
415
417
|
//#endregion
|
|
416
418
|
//#region src/instrumentation/core/baseClasses/TdInstrumentationBase.ts
|
|
417
|
-
var TdInstrumentationBase = class extends TdInstrumentationAbstract {
|
|
419
|
+
var TdInstrumentationBase = class TdInstrumentationBase extends TdInstrumentationAbstract {
|
|
418
420
|
constructor(instrumentationName, config = {}) {
|
|
419
421
|
super(instrumentationName, config);
|
|
420
422
|
this._modules = [];
|
|
423
|
+
this._hooks = [];
|
|
421
424
|
this._enabled = false;
|
|
422
425
|
let modules = this.init();
|
|
423
426
|
if (modules && !Array.isArray(modules)) modules = [modules];
|
|
@@ -458,12 +461,35 @@ var TdInstrumentationBase = class extends TdInstrumentationAbstract {
|
|
|
458
461
|
const onRequire = (exports$1, name, baseDir) => {
|
|
459
462
|
return this._onRequire(module$1, exports$1, name, baseDir);
|
|
460
463
|
};
|
|
461
|
-
|
|
464
|
+
const hookFn = (exports$1, name, baseDir) => {
|
|
465
|
+
if (!baseDir && path.default.isAbsolute(name)) {
|
|
466
|
+
const parsedPath = path.default.parse(name);
|
|
467
|
+
name = parsedPath.name;
|
|
468
|
+
baseDir = parsedPath.dir;
|
|
469
|
+
}
|
|
470
|
+
return this._onRequire(module$1, exports$1, name, baseDir || void 0);
|
|
471
|
+
};
|
|
472
|
+
const cjsHook = new require_in_the_middle.Hook([module$1.name], { internals: true }, onRequire);
|
|
473
|
+
this._hooks.push(cjsHook);
|
|
474
|
+
const esmHook = new import_in_the_middle.Hook([module$1.name], { internals: false }, hookFn);
|
|
475
|
+
this._hooks.push(esmHook);
|
|
462
476
|
}
|
|
463
477
|
}
|
|
464
478
|
isEnabled() {
|
|
465
479
|
return this._enabled;
|
|
466
480
|
}
|
|
481
|
+
/**
|
|
482
|
+
* Mark a module as patched.
|
|
483
|
+
*/
|
|
484
|
+
markModuleAsPatched(moduleExports) {
|
|
485
|
+
TdInstrumentationBase._patchedModules.add(moduleExports);
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Check if a module has already been patched.
|
|
489
|
+
*/
|
|
490
|
+
isModulePatched(moduleExports) {
|
|
491
|
+
return TdInstrumentationBase._patchedModules.has(moduleExports);
|
|
492
|
+
}
|
|
467
493
|
_onRequire(module$1, exports$1, name, baseDir) {
|
|
468
494
|
if (!baseDir) {
|
|
469
495
|
if (typeof module$1.patch === "function") {
|
|
@@ -526,6 +552,7 @@ var TdInstrumentationBase = class extends TdInstrumentationAbstract {
|
|
|
526
552
|
}, exports$1);
|
|
527
553
|
}
|
|
528
554
|
};
|
|
555
|
+
TdInstrumentationBase._patchedModules = /* @__PURE__ */ new WeakSet();
|
|
529
556
|
|
|
530
557
|
//#endregion
|
|
531
558
|
//#region src/instrumentation/core/baseClasses/TdInstrumentationNodeModule.ts
|
|
@@ -1930,6 +1957,7 @@ function wrap(target, propertyName, wrapper) {
|
|
|
1930
1957
|
wrapped._original = original;
|
|
1931
1958
|
wrapped._propertyName = propertyName;
|
|
1932
1959
|
target[propertyName] = wrapped;
|
|
1960
|
+
return wrapped;
|
|
1933
1961
|
}
|
|
1934
1962
|
|
|
1935
1963
|
//#endregion
|
|
@@ -2212,18 +2240,25 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
2212
2240
|
_patchHttpModule(httpModule, protocol) {
|
|
2213
2241
|
const protocolUpper = protocol.toUpperCase();
|
|
2214
2242
|
logger.debug(`[HttpInstrumentation] Patching ${protocolUpper} module in ${this.mode} mode`);
|
|
2215
|
-
if (httpModule
|
|
2243
|
+
if (this.isModulePatched(httpModule)) {
|
|
2216
2244
|
logger.debug(`[HttpInstrumentation] ${protocolUpper} module already patched, skipping`);
|
|
2217
2245
|
return httpModule;
|
|
2218
2246
|
}
|
|
2219
|
-
|
|
2220
|
-
|
|
2247
|
+
if (httpModule[Symbol.toStringTag] === "Module") {
|
|
2248
|
+
if (httpModule.default) {
|
|
2249
|
+
this._wrap(httpModule.default, "request", this._getRequestPatchFn(protocol));
|
|
2250
|
+
this._wrap(httpModule.default, "get", this._getGetPatchFn(protocol));
|
|
2251
|
+
}
|
|
2252
|
+
} else {
|
|
2253
|
+
this._wrap(httpModule, "request", this._getRequestPatchFn(protocol));
|
|
2254
|
+
this._wrap(httpModule, "get", this._getGetPatchFn(protocol));
|
|
2255
|
+
}
|
|
2221
2256
|
const HttpServer = httpModule.Server;
|
|
2222
2257
|
if (HttpServer && HttpServer.prototype) {
|
|
2223
2258
|
this._wrap(HttpServer.prototype, "emit", this._getServerEmitPatchFn(protocol));
|
|
2224
2259
|
logger.debug(`[HttpInstrumentation] Wrapped Server.prototype.emit for ${protocolUpper}`);
|
|
2225
2260
|
}
|
|
2226
|
-
httpModule
|
|
2261
|
+
this.markModuleAsPatched(httpModule);
|
|
2227
2262
|
logger.debug(`[HttpInstrumentation] ${protocolUpper} module patching complete`);
|
|
2228
2263
|
return httpModule;
|
|
2229
2264
|
}
|
|
@@ -2568,7 +2603,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
2568
2603
|
}
|
|
2569
2604
|
});
|
|
2570
2605
|
}
|
|
2571
|
-
_captureClientRequestBody(req, spanInfo, inputValue, schemaMerges) {
|
|
2606
|
+
_captureClientRequestBody(req, spanInfo, inputValue, schemaMerges, onBodyCaptured) {
|
|
2572
2607
|
const requestBodyChunks = [];
|
|
2573
2608
|
let requestBodyCaptured = false;
|
|
2574
2609
|
const originalWrite = req.write?.bind(req);
|
|
@@ -2590,6 +2625,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
2590
2625
|
body: encodedBody,
|
|
2591
2626
|
bodySize: bodyBuffer.length
|
|
2592
2627
|
};
|
|
2628
|
+
if (onBodyCaptured) onBodyCaptured(updatedInputValue);
|
|
2593
2629
|
SpanUtils.addSpanAttributes(spanInfo.span, {
|
|
2594
2630
|
inputValue: updatedInputValue,
|
|
2595
2631
|
inputSchemaMerges: {
|
|
@@ -2611,7 +2647,10 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
2611
2647
|
}
|
|
2612
2648
|
_handleOutboundRequestInSpan(originalRequest, args, spanInfo, inputValue, schemaMerges) {
|
|
2613
2649
|
const req = originalRequest.apply(this, args);
|
|
2614
|
-
|
|
2650
|
+
let completeInputValue = inputValue;
|
|
2651
|
+
this._captureClientRequestBody(req, spanInfo, inputValue, schemaMerges, (updatedInputValue) => {
|
|
2652
|
+
completeInputValue = updatedInputValue;
|
|
2653
|
+
});
|
|
2615
2654
|
req.on("response", (res) => {
|
|
2616
2655
|
logger.debug(`[HttpInstrumentation] HTTP response received: ${res.statusCode} (${SpanUtils.getTraceInfo()})`);
|
|
2617
2656
|
const outputValue = {
|
|
@@ -2651,7 +2690,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
2651
2690
|
},
|
|
2652
2691
|
headers: { matchImportance: 0 }
|
|
2653
2692
|
},
|
|
2654
|
-
inputValue
|
|
2693
|
+
inputValue: completeInputValue
|
|
2655
2694
|
});
|
|
2656
2695
|
} catch (error) {
|
|
2657
2696
|
logger.error(`[HttpInstrumentation] Error processing response body:`, error);
|
|
@@ -2669,7 +2708,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
2669
2708
|
},
|
|
2670
2709
|
headers: { matchImportance: 0 }
|
|
2671
2710
|
},
|
|
2672
|
-
inputValue
|
|
2711
|
+
inputValue: completeInputValue
|
|
2673
2712
|
});
|
|
2674
2713
|
} catch (error) {
|
|
2675
2714
|
logger.error(`[HttpInstrumentation] Error adding output attributes to span:`, error);
|
|
@@ -2912,7 +2951,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
2912
2951
|
return fallback;
|
|
2913
2952
|
}
|
|
2914
2953
|
_wrap(target, propertyName, wrapper) {
|
|
2915
|
-
wrap(target, propertyName, wrapper);
|
|
2954
|
+
return wrap(target, propertyName, wrapper);
|
|
2916
2955
|
}
|
|
2917
2956
|
};
|
|
2918
2957
|
|
|
@@ -3307,7 +3346,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
3307
3346
|
}
|
|
3308
3347
|
_patchPgModule(pgModule) {
|
|
3309
3348
|
logger.debug(`[PgInstrumentation] Patching PG module in ${this.mode} mode`);
|
|
3310
|
-
if (pgModule
|
|
3349
|
+
if (this.isModulePatched(pgModule)) {
|
|
3311
3350
|
logger.debug(`[PgInstrumentation] PG module already patched, skipping`);
|
|
3312
3351
|
return pgModule;
|
|
3313
3352
|
}
|
|
@@ -3319,7 +3358,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
3319
3358
|
this._wrap(pgModule.Client.prototype, "connect", this._getConnectPatchFn("client"));
|
|
3320
3359
|
logger.debug(`[PgInstrumentation] Wrapped Client.prototype.connect`);
|
|
3321
3360
|
}
|
|
3322
|
-
pgModule
|
|
3361
|
+
this.markModuleAsPatched(pgModule);
|
|
3323
3362
|
logger.debug(`[PgInstrumentation] PG module patching complete`);
|
|
3324
3363
|
return pgModule;
|
|
3325
3364
|
}
|
|
@@ -3641,7 +3680,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
3641
3680
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
|
|
3642
3681
|
}
|
|
3643
3682
|
_patchPgPoolModule(pgPoolModule) {
|
|
3644
|
-
if (pgPoolModule
|
|
3683
|
+
if (this.isModulePatched(pgPoolModule)) {
|
|
3645
3684
|
logger.debug(`[PgInstrumentation] PG Pool module already patched, skipping`);
|
|
3646
3685
|
return pgPoolModule;
|
|
3647
3686
|
}
|
|
@@ -3653,7 +3692,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
3653
3692
|
this._wrap(pgPoolModule.prototype, "connect", this._getPoolConnectPatchFn());
|
|
3654
3693
|
logger.debug(`[PgInstrumentation] Wrapped Pool.prototype.connect`);
|
|
3655
3694
|
}
|
|
3656
|
-
pgPoolModule
|
|
3695
|
+
this.markModuleAsPatched(pgPoolModule);
|
|
3657
3696
|
logger.debug(`[PgInstrumentation] PG Pool module patching complete`);
|
|
3658
3697
|
return pgPoolModule;
|
|
3659
3698
|
}
|
|
@@ -3764,6 +3803,17 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
3764
3803
|
}
|
|
3765
3804
|
};
|
|
3766
3805
|
|
|
3806
|
+
//#endregion
|
|
3807
|
+
//#region src/instrumentation/libraries/postgres/types.ts
|
|
3808
|
+
function isPostgresOutputValueType(value) {
|
|
3809
|
+
return value !== null && value !== void 0 && typeof value === "object" && "_tdOriginalFormat" in value && Object.values(PostgresReturnType).includes(value._tdOriginalFormat);
|
|
3810
|
+
}
|
|
3811
|
+
let PostgresReturnType = /* @__PURE__ */ function(PostgresReturnType$1) {
|
|
3812
|
+
PostgresReturnType$1["ARRAY"] = "array";
|
|
3813
|
+
PostgresReturnType$1["OBJECT"] = "object";
|
|
3814
|
+
return PostgresReturnType$1;
|
|
3815
|
+
}({});
|
|
3816
|
+
|
|
3767
3817
|
//#endregion
|
|
3768
3818
|
//#region src/instrumentation/libraries/postgres/Instrumentation.ts
|
|
3769
3819
|
var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
@@ -3782,25 +3832,41 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
3782
3832
|
}
|
|
3783
3833
|
_patchPostgresModule(postgresModule) {
|
|
3784
3834
|
logger.debug(`[PostgresInstrumentation] Patching Postgres module in ${this.mode} mode`);
|
|
3785
|
-
if (postgresModule
|
|
3835
|
+
if (this.isModulePatched(postgresModule)) {
|
|
3786
3836
|
logger.debug(`[PostgresInstrumentation] Postgres module already patched, skipping`);
|
|
3787
3837
|
return postgresModule;
|
|
3788
3838
|
}
|
|
3789
|
-
|
|
3839
|
+
const self$1 = this;
|
|
3840
|
+
if (postgresModule[Symbol.toStringTag] === "Module") {
|
|
3841
|
+
logger.debug(`[PostgresInstrumentation] Wrapping ESM default export`);
|
|
3842
|
+
this._wrap(postgresModule, "default", (originalFunction) => {
|
|
3843
|
+
return function(...args) {
|
|
3844
|
+
return self$1._handlePostgresConnection(originalFunction, args);
|
|
3845
|
+
};
|
|
3846
|
+
});
|
|
3847
|
+
} else {
|
|
3848
|
+
logger.debug(`[PostgresInstrumentation] Module is a function (CJS style)`);
|
|
3790
3849
|
const originalFunction = postgresModule;
|
|
3791
|
-
const self$1 = this;
|
|
3792
3850
|
const wrappedFunction = function(...args) {
|
|
3851
|
+
logger.debug(`[PostgresInstrumentation] Wrapped postgres() (CJS) called with args:`, args);
|
|
3793
3852
|
return self$1._handlePostgresConnection(originalFunction, args);
|
|
3794
3853
|
};
|
|
3795
3854
|
Object.setPrototypeOf(wrappedFunction, Object.getPrototypeOf(originalFunction));
|
|
3796
3855
|
Object.defineProperty(wrappedFunction, "name", { value: originalFunction.name });
|
|
3856
|
+
for (const key in originalFunction) if (originalFunction.hasOwnProperty(key)) wrappedFunction[key] = originalFunction[key];
|
|
3857
|
+
Object.getOwnPropertyNames(originalFunction).forEach((key) => {
|
|
3858
|
+
if (key !== "prototype" && key !== "length" && key !== "name") {
|
|
3859
|
+
const descriptor = Object.getOwnPropertyDescriptor(originalFunction, key);
|
|
3860
|
+
if (descriptor) Object.defineProperty(wrappedFunction, key, descriptor);
|
|
3861
|
+
}
|
|
3862
|
+
});
|
|
3797
3863
|
postgresModule = wrappedFunction;
|
|
3798
3864
|
}
|
|
3799
3865
|
if (postgresModule.sql && typeof postgresModule.sql === "function") {
|
|
3800
3866
|
this._wrap(postgresModule, "sql", this._getSqlPatchFn());
|
|
3801
3867
|
logger.debug(`[PostgresInstrumentation] Wrapped sql function`);
|
|
3802
3868
|
}
|
|
3803
|
-
postgresModule
|
|
3869
|
+
this.markModuleAsPatched(postgresModule);
|
|
3804
3870
|
logger.debug(`[PostgresInstrumentation] Postgres module patching complete`);
|
|
3805
3871
|
return postgresModule;
|
|
3806
3872
|
}
|
|
@@ -4262,8 +4328,8 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
4262
4328
|
const isResultObject = processedResult && typeof processedResult === "object" && "rows" in processedResult;
|
|
4263
4329
|
const rows = isResultObject ? processedResult.rows || [] : processedResult || [];
|
|
4264
4330
|
return Object.assign(rows, {
|
|
4265
|
-
command: isResultObject ? processedResult.command :
|
|
4266
|
-
count: isResultObject ? processedResult.count :
|
|
4331
|
+
command: isResultObject ? processedResult.command : void 0,
|
|
4332
|
+
count: isResultObject ? processedResult.count : void 0
|
|
4267
4333
|
});
|
|
4268
4334
|
}
|
|
4269
4335
|
async handleReplayUnsafeQuery({ inputValue, spanInfo, submodule, name }) {
|
|
@@ -4314,8 +4380,8 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
4314
4380
|
return Object.values(row);
|
|
4315
4381
|
});
|
|
4316
4382
|
return Object.assign(valueArrays, {
|
|
4317
|
-
command: isResultObject ? result.command :
|
|
4318
|
-
count: isResultObject ? result.count :
|
|
4383
|
+
command: isResultObject ? result.command : void 0,
|
|
4384
|
+
count: isResultObject ? result.count : void 0
|
|
4319
4385
|
});
|
|
4320
4386
|
});
|
|
4321
4387
|
} });
|
|
@@ -4325,61 +4391,40 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
4325
4391
|
* based on common PostgreSQL data patterns.
|
|
4326
4392
|
*/
|
|
4327
4393
|
convertPostgresTypes(result) {
|
|
4328
|
-
if (!result)
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
const dateObj = new Date(value);
|
|
4340
|
-
if (!isNaN(dateObj.getTime())) convertedRow[fieldName] = dateObj;
|
|
4341
|
-
}
|
|
4342
|
-
}
|
|
4343
|
-
});
|
|
4344
|
-
return convertedRow;
|
|
4345
|
-
});
|
|
4346
|
-
return convertedResult;
|
|
4394
|
+
if (!isPostgresOutputValueType(result)) {
|
|
4395
|
+
logger.error(`[PostgresInstrumentation] output value is not of type PostgresOutputValueType: ${JSON.stringify(result)}`);
|
|
4396
|
+
return;
|
|
4397
|
+
}
|
|
4398
|
+
if (!result) return;
|
|
4399
|
+
const { _tdOriginalFormat: originalFormat,...convertedResult } = result;
|
|
4400
|
+
if (originalFormat === PostgresReturnType.OBJECT) return convertedResult;
|
|
4401
|
+
else if (originalFormat === PostgresReturnType.ARRAY) return convertedResult.rows || [];
|
|
4402
|
+
else {
|
|
4403
|
+
logger.error(`[PostgresInstrumentation] Invalid result format: ${JSON.stringify(result)}`);
|
|
4404
|
+
return;
|
|
4347
4405
|
}
|
|
4348
|
-
if (Array.isArray(result)) return result.map((row) => {
|
|
4349
|
-
if (typeof row !== "object" || row === null) return row;
|
|
4350
|
-
const convertedRow = { ...row };
|
|
4351
|
-
Object.keys(row).forEach((fieldName) => {
|
|
4352
|
-
const value = row[fieldName];
|
|
4353
|
-
if (value === null || value === void 0) return;
|
|
4354
|
-
if (typeof value === "string") {
|
|
4355
|
-
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
|
|
4356
|
-
const dateObj = new Date(value);
|
|
4357
|
-
if (!isNaN(dateObj.getTime())) convertedRow[fieldName] = dateObj;
|
|
4358
|
-
}
|
|
4359
|
-
}
|
|
4360
|
-
});
|
|
4361
|
-
return convertedRow;
|
|
4362
|
-
});
|
|
4363
|
-
return result;
|
|
4364
4406
|
}
|
|
4365
4407
|
_addOutputAttributesToSpan(spanInfo, result) {
|
|
4366
4408
|
if (!result) return;
|
|
4367
4409
|
let outputValue;
|
|
4368
|
-
if (Array.isArray(result))
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
}
|
|
4410
|
+
if (Array.isArray(result)) {
|
|
4411
|
+
logger.debug(`[PostgresInstrumentation] Adding output attributes to span for array result: ${JSON.stringify(result)}`);
|
|
4412
|
+
outputValue = {
|
|
4413
|
+
_tdOriginalFormat: PostgresReturnType.ARRAY,
|
|
4414
|
+
rows: result
|
|
4415
|
+
};
|
|
4416
|
+
} else if (typeof result === "object") {
|
|
4417
|
+
logger.debug(`[PostgresInstrumentation] Adding output attributes to span for object result: ${JSON.stringify(result)}`);
|
|
4418
|
+
outputValue = {
|
|
4419
|
+
_tdOriginalFormat: PostgresReturnType.OBJECT,
|
|
4420
|
+
count: result.count,
|
|
4421
|
+
rows: result.rows,
|
|
4422
|
+
command: result.command
|
|
4423
|
+
};
|
|
4424
|
+
} else {
|
|
4425
|
+
logger.error(`[PostgresInstrumentation] Invalid result format: ${JSON.stringify(result)}`);
|
|
4426
|
+
return;
|
|
4427
|
+
}
|
|
4383
4428
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
|
|
4384
4429
|
}
|
|
4385
4430
|
_wrap(target, propertyName, wrapper) {
|
|
@@ -4413,7 +4458,7 @@ var TcpInstrumentation = class extends TdInstrumentationBase {
|
|
|
4413
4458
|
}
|
|
4414
4459
|
_patchNetModule(netModule) {
|
|
4415
4460
|
logger.debug(`[TcpInstrumentation] Patching NET module in ${this.mode} mode`);
|
|
4416
|
-
if (netModule
|
|
4461
|
+
if (this.isModulePatched(netModule)) {
|
|
4417
4462
|
logger.debug(`[TcpInstrumentation] NET module already patched, skipping`);
|
|
4418
4463
|
return netModule;
|
|
4419
4464
|
}
|
|
@@ -4430,7 +4475,7 @@ var TcpInstrumentation = class extends TdInstrumentationBase {
|
|
|
4430
4475
|
netModule.Socket.prototype.write = function(...args) {
|
|
4431
4476
|
return self$1._handleTcpCall("write", originalWrite, args, this);
|
|
4432
4477
|
};
|
|
4433
|
-
netModule
|
|
4478
|
+
this.markModuleAsPatched(netModule);
|
|
4434
4479
|
return netModule;
|
|
4435
4480
|
}
|
|
4436
4481
|
_logUnpatchedDependency(methodName, currentSpanInfo, socketContext) {
|
|
@@ -4493,7 +4538,7 @@ var JsonwebtokenInstrumentation = class extends TdInstrumentationBase {
|
|
|
4493
4538
|
})];
|
|
4494
4539
|
}
|
|
4495
4540
|
_patchJsonwebtokenModule(jwtModule) {
|
|
4496
|
-
if (jwtModule
|
|
4541
|
+
if (this.isModulePatched(jwtModule)) {
|
|
4497
4542
|
logger.debug(`[JsonwebtokenInstrumentation] jsonwebtoken module already patched, skipping`);
|
|
4498
4543
|
return jwtModule;
|
|
4499
4544
|
}
|
|
@@ -4508,7 +4553,7 @@ var JsonwebtokenInstrumentation = class extends TdInstrumentationBase {
|
|
|
4508
4553
|
this._wrap(jwtModule, "sign", this._getSignPatchFn());
|
|
4509
4554
|
logger.debug(`[JsonwebtokenInstrumentation] Wrapped jwt.sign`);
|
|
4510
4555
|
}
|
|
4511
|
-
jwtModule
|
|
4556
|
+
this.markModuleAsPatched(jwtModule);
|
|
4512
4557
|
logger.debug(`[JsonwebtokenInstrumentation] jsonwebtoken module patching complete`);
|
|
4513
4558
|
return jwtModule;
|
|
4514
4559
|
}
|
|
@@ -4906,7 +4951,7 @@ var JwksRsaInstrumentation = class extends TdInstrumentationBase {
|
|
|
4906
4951
|
}
|
|
4907
4952
|
_patchJwksRsaModule(jwksModule) {
|
|
4908
4953
|
logger.debug(`[JwksRsaInstrumentation] Patching jwks-rsa module, current mode: ${this.tuskDrift.getMode()}`);
|
|
4909
|
-
if (jwksModule
|
|
4954
|
+
if (this.isModulePatched(jwksModule)) {
|
|
4910
4955
|
logger.debug(`[JwksRsaInstrumentation] jwks-rsa module already patched, skipping`);
|
|
4911
4956
|
return jwksModule;
|
|
4912
4957
|
}
|
|
@@ -4926,7 +4971,7 @@ var JwksRsaInstrumentation = class extends TdInstrumentationBase {
|
|
|
4926
4971
|
};
|
|
4927
4972
|
logger.debug(`[JwksRsaInstrumentation] Patched expressJwtSecret method`);
|
|
4928
4973
|
}
|
|
4929
|
-
jwksModule
|
|
4974
|
+
this.markModuleAsPatched(jwksModule);
|
|
4930
4975
|
logger.debug(`[JwksRsaInstrumentation] jwks-rsa module patching complete`);
|
|
4931
4976
|
return jwksModule;
|
|
4932
4977
|
}
|