@use-tusk/drift-node-sdk 0.1.21 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -11139,13 +11139,23 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
11139
11139
  let requestOptions;
11140
11140
  if (typeof args[0] === "string") {
11141
11141
  const url = new URL(args[0]);
11142
+ const additionalOptions = typeof args[1] === "function" ? void 0 : args[1];
11142
11143
  requestOptions = {
11143
11144
  protocol: url.protocol,
11144
11145
  hostname: url.hostname,
11145
11146
  port: url.port ? parseInt(url.port) : void 0,
11146
11147
  path: url.pathname + url.search,
11147
- method: args[1]?.method || "GET",
11148
- headers: args[1]?.headers || {}
11148
+ method: additionalOptions?.method || "GET",
11149
+ headers: additionalOptions?.headers || {}
11150
+ };
11151
+ } else if (self._isURLObject(args[0])) {
11152
+ const url = args[0];
11153
+ const additionalOptions = typeof args[1] === "function" ? void 0 : args[1];
11154
+ requestOptions = {
11155
+ ...self._urlToRequestOptions(url),
11156
+ method: additionalOptions?.method || "GET",
11157
+ headers: additionalOptions?.headers || {},
11158
+ ...additionalOptions
11149
11159
  };
11150
11160
  } else requestOptions = args[0] || {};
11151
11161
  const method = requestOptions.method || "GET";
@@ -11235,12 +11245,21 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
11235
11245
  let requestOptions;
11236
11246
  if (typeof args[0] === "string") {
11237
11247
  const url = new URL(args[0]);
11248
+ const additionalOptions = typeof args[1] === "function" ? void 0 : args[1];
11238
11249
  requestOptions = {
11239
11250
  protocol: url.protocol,
11240
11251
  hostname: url.hostname,
11241
11252
  port: url.port ? parseInt(url.port) : void 0,
11242
11253
  path: url.pathname + url.search,
11243
- headers: args[1]?.headers || {}
11254
+ headers: additionalOptions?.headers || {}
11255
+ };
11256
+ } else if (self._isURLObject(args[0])) {
11257
+ const url = args[0];
11258
+ const additionalOptions = typeof args[1] === "function" ? void 0 : args[1];
11259
+ requestOptions = {
11260
+ ...self._urlToRequestOptions(url),
11261
+ headers: additionalOptions?.headers || {},
11262
+ ...additionalOptions
11244
11263
  };
11245
11264
  } else requestOptions = args[0] || {};
11246
11265
  const method = "GET";
@@ -11346,6 +11365,25 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
11346
11365
  };
11347
11366
  };
11348
11367
  }
11368
+ /**
11369
+ * Check if the input is a URL object (WHATWG URL API)
11370
+ * This is used to detect when a URL object is passed to http.get/request
11371
+ */
11372
+ _isURLObject(input) {
11373
+ return input instanceof URL || input && typeof input.href === "string" && typeof input.pathname === "string";
11374
+ }
11375
+ /**
11376
+ * Convert a URL object to RequestOptions
11377
+ * Similar to Node.js's internal urlToHttpOptions function
11378
+ */
11379
+ _urlToRequestOptions(url) {
11380
+ return {
11381
+ protocol: url.protocol,
11382
+ hostname: url.hostname,
11383
+ port: url.port ? parseInt(url.port) : void 0,
11384
+ path: url.pathname + (url.search || "")
11385
+ };
11386
+ }
11349
11387
  _normalizeProtocol(protocol, fallback) {
11350
11388
  if (!protocol) return fallback;
11351
11389
  const normalized = protocol.toLowerCase().replace(/:$/, "");
@@ -11723,6 +11761,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
11723
11761
  packageName,
11724
11762
  instrumentationName: self.INSTRUMENTATION_NAME,
11725
11763
  inputValue,
11764
+ inputSchemaMerges: { values: { matchImportance: 0 } },
11726
11765
  isPreAppStart: false
11727
11766
  }, (spanInfo) => {
11728
11767
  return self.handleReplayQuery(queryConfig, inputValue, spanInfo, stackTrace);
@@ -11742,6 +11781,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
11742
11781
  instrumentationName: self.INSTRUMENTATION_NAME,
11743
11782
  packageName,
11744
11783
  inputValue,
11784
+ inputSchemaMerges: { values: { matchImportance: 0 } },
11745
11785
  isPreAppStart
11746
11786
  }, (spanInfo) => {
11747
11787
  return self._handleRecordQueryInSpan(spanInfo, originalQuery, queryConfig, args, this);
@@ -11918,7 +11958,8 @@ var PgInstrumentation = class extends TdInstrumentationBase {
11918
11958
  kind: import_src$29.SpanKind.CLIENT,
11919
11959
  stackTrace
11920
11960
  },
11921
- tuskDrift: this.tuskDrift
11961
+ tuskDrift: this.tuskDrift,
11962
+ inputValueSchemaMerges: { values: { matchImportance: 0 } }
11922
11963
  });
11923
11964
  if (!mockData) {
11924
11965
  const queryText = queryConfig.text || inputValue.text || "UNKNOWN_QUERY";
@@ -12781,6 +12822,7 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
12781
12822
  packageName: "postgres",
12782
12823
  instrumentationName: self.INSTRUMENTATION_NAME,
12783
12824
  inputValue,
12825
+ inputSchemaMerges: { parameters: { matchImportance: 0 } },
12784
12826
  isPreAppStart
12785
12827
  }, (spanInfo) => {
12786
12828
  const wrappedOnFulfilled = (result) => {
@@ -12828,6 +12870,7 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
12828
12870
  packageName: "postgres",
12829
12871
  instrumentationName: self.INSTRUMENTATION_NAME,
12830
12872
  inputValue,
12873
+ inputSchemaMerges: { parameters: { matchImportance: 0 } },
12831
12874
  isPreAppStart: self.tuskDrift.isAppReady() ? false : true
12832
12875
  }, async (spanInfo) => {
12833
12876
  const mockedResult = await self._handleReplayQueryOperation({
@@ -13030,7 +13073,8 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
13030
13073
  kind: import_src$27.SpanKind.CLIENT,
13031
13074
  stackTrace
13032
13075
  },
13033
- tuskDrift: this.tuskDrift
13076
+ tuskDrift: this.tuskDrift,
13077
+ inputValueSchemaMerges: { parameters: { matchImportance: 0 } }
13034
13078
  });
13035
13079
  }
13036
13080
  /**
@@ -13084,6 +13128,7 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
13084
13128
  packageName: "postgres",
13085
13129
  instrumentationName: self.INSTRUMENTATION_NAME,
13086
13130
  inputValue,
13131
+ inputSchemaMerges: { parameters: { matchImportance: 0 } },
13087
13132
  isPreAppStart
13088
13133
  }, (spanInfo) => {
13089
13134
  return self._executeAndRecordCursorCallback({
@@ -13142,6 +13187,7 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
13142
13187
  packageName: "postgres",
13143
13188
  instrumentationName: self.INSTRUMENTATION_NAME,
13144
13189
  inputValue,
13190
+ inputSchemaMerges: { parameters: { matchImportance: 0 } },
13145
13191
  isPreAppStart: self.tuskDrift.isAppReady() ? false : true
13146
13192
  }, async (spanInfo) => {
13147
13193
  try {
@@ -13343,6 +13389,7 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
13343
13389
  packageName: "postgres",
13344
13390
  instrumentationName: self.INSTRUMENTATION_NAME,
13345
13391
  inputValue,
13392
+ inputSchemaMerges: { parameters: { matchImportance: 0 } },
13346
13393
  isPreAppStart
13347
13394
  }, async (spanInfo) => {
13348
13395
  const allRows = [];
@@ -13397,6 +13444,7 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
13397
13444
  packageName: "postgres",
13398
13445
  instrumentationName: self.INSTRUMENTATION_NAME,
13399
13446
  inputValue,
13447
+ inputSchemaMerges: { parameters: { matchImportance: 0 } },
13400
13448
  isPreAppStart: self.tuskDrift.isAppReady() ? false : true
13401
13449
  }, async (spanInfo) => {
13402
13450
  try {
@@ -13451,6 +13499,7 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
13451
13499
  packageName: "postgres",
13452
13500
  instrumentationName: self.INSTRUMENTATION_NAME,
13453
13501
  inputValue,
13502
+ inputSchemaMerges: { parameters: { matchImportance: 0 } },
13454
13503
  isPreAppStart
13455
13504
  }, (spanInfo) => {
13456
13505
  const wrappedOnFulfilled = (result) => {
@@ -13498,6 +13547,7 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
13498
13547
  packageName: "postgres",
13499
13548
  instrumentationName: self.INSTRUMENTATION_NAME,
13500
13549
  inputValue,
13550
+ inputSchemaMerges: { parameters: { matchImportance: 0 } },
13501
13551
  isPreAppStart: self.tuskDrift.isAppReady() ? false : true
13502
13552
  }, async (spanInfo) => {
13503
13553
  const mockedResult = await self._handleReplayQueryOperation({
@@ -13897,7 +13947,8 @@ var TdMysqlQueryMock = class {
13897
13947
  kind: import_src$26.SpanKind.CLIENT,
13898
13948
  stackTrace
13899
13949
  },
13900
- tuskDrift: this.tuskDrift
13950
+ tuskDrift: this.tuskDrift,
13951
+ inputValueSchemaMerges: { values: { matchImportance: 0 } }
13901
13952
  });
13902
13953
  }
13903
13954
  };
@@ -14153,6 +14204,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
14153
14204
  packageName: "mysql",
14154
14205
  instrumentationName: self.INSTRUMENTATION_NAME,
14155
14206
  inputValue,
14207
+ inputSchemaMerges: { values: { matchImportance: 0 } },
14156
14208
  isPreAppStart: false
14157
14209
  }, (spanInfo) => {
14158
14210
  const queryEmitter = self.queryMock.handleReplayQuery({
@@ -14179,6 +14231,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
14179
14231
  packageName: "mysql",
14180
14232
  instrumentationName: self.INSTRUMENTATION_NAME,
14181
14233
  inputValue,
14234
+ inputSchemaMerges: { values: { matchImportance: 0 } },
14182
14235
  isPreAppStart
14183
14236
  }, (spanInfo) => {
14184
14237
  return self._handleRecordQuery(spanInfo, originalQuery, this, args, callback, isEventEmitterMode);
@@ -14626,6 +14679,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
14626
14679
  packageName: "mysql",
14627
14680
  instrumentationName: self.INSTRUMENTATION_NAME,
14628
14681
  inputValue,
14682
+ inputSchemaMerges: { values: { matchImportance: 0 } },
14629
14683
  isPreAppStart: false
14630
14684
  }, (spanInfo) => {
14631
14685
  const queryEmitter = self.queryMock.handleReplayQuery({
@@ -14652,6 +14706,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
14652
14706
  packageName: "mysql",
14653
14707
  instrumentationName: self.INSTRUMENTATION_NAME,
14654
14708
  inputValue,
14709
+ inputSchemaMerges: { values: { matchImportance: 0 } },
14655
14710
  isPreAppStart
14656
14711
  }, (spanInfo) => {
14657
14712
  return self._handleRecordQuery(spanInfo, originalQuery, connection, args, callback, isEventEmitterMode);
@@ -15113,6 +15168,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
15113
15168
  packageName: "mysql",
15114
15169
  instrumentationName: self.INSTRUMENTATION_NAME,
15115
15170
  inputValue,
15171
+ inputSchemaMerges: { values: { matchImportance: 0 } },
15116
15172
  isPreAppStart: false
15117
15173
  }, (spanInfo) => {
15118
15174
  return self._handleReplayStream(inputValue, spanInfo, stackTrace, queryInstance);
@@ -15130,6 +15186,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
15130
15186
  packageName: "mysql",
15131
15187
  instrumentationName: self.INSTRUMENTATION_NAME,
15132
15188
  inputValue,
15189
+ inputSchemaMerges: { values: { matchImportance: 0 } },
15133
15190
  isPreAppStart
15134
15191
  }, (spanInfo) => {
15135
15192
  return self._handleRecordStream(spanInfo, originalStream, queryInstance, streamOptions);
@@ -15341,6 +15398,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
15341
15398
  packageName: "mysql",
15342
15399
  instrumentationName: self.INSTRUMENTATION_NAME,
15343
15400
  inputValue,
15401
+ inputSchemaMerges: { values: { matchImportance: 0 } },
15344
15402
  isPreAppStart: false
15345
15403
  }, (spanInfo) => {
15346
15404
  const queryEmitter = self.queryMock.handleReplayQuery({
@@ -15536,6 +15594,27 @@ var TdMysql2ConnectionMock = class extends EventEmitter {
15536
15594
  }
15537
15595
  return Promise.resolve();
15538
15596
  }
15597
+ prepare(sql, callback) {
15598
+ const sqlStr = typeof sql === "string" ? sql : sql.sql;
15599
+ const self = this;
15600
+ const mockStatement = {
15601
+ query: sqlStr,
15602
+ id: 1,
15603
+ columns: [],
15604
+ parameters: [],
15605
+ execute: (...args) => {
15606
+ const values = Array.isArray(args[0]) ? args[0] : [];
15607
+ const execCallback = typeof args[args.length - 1] === "function" ? args[args.length - 1] : void 0;
15608
+ return self.mysql2Instrumentation.handleNoOpReplayQuery({
15609
+ sql: sqlStr,
15610
+ values,
15611
+ callback: execCallback
15612
+ });
15613
+ },
15614
+ close: () => {}
15615
+ };
15616
+ if (callback) process.nextTick(() => callback(null, mockStatement));
15617
+ }
15539
15618
  pause() {}
15540
15619
  resume() {}
15541
15620
  escape(value) {
@@ -15592,6 +15671,10 @@ var TdMysql2QueryMock = class {
15592
15671
  });
15593
15672
  }).then(onResolve, onReject);
15594
15673
  };
15674
+ const self = this;
15675
+ emitter.stream = function(streamOptions) {
15676
+ return self._createReplayStreamForQuery(emitter, streamOptions);
15677
+ };
15595
15678
  process.nextTick(() => {
15596
15679
  const callback = queryConfig.callback;
15597
15680
  if (callback) callback(null, [], []);
@@ -15618,6 +15701,10 @@ var TdMysql2QueryMock = class {
15618
15701
  });
15619
15702
  }).then(onResolve, onReject);
15620
15703
  };
15704
+ const self = this;
15705
+ emitter.stream = function(streamOptions) {
15706
+ return self._createReplayStreamForQuery(emitter, streamOptions);
15707
+ };
15621
15708
  (async () => {
15622
15709
  try {
15623
15710
  const mockData = await this._fetchMockData(inputValue, spanInfo, spanName, submoduleName, stackTrace);
@@ -15661,8 +15748,46 @@ var TdMysql2QueryMock = class {
15661
15748
  kind: import_src$24.SpanKind.CLIENT,
15662
15749
  stackTrace
15663
15750
  },
15664
- tuskDrift: this.tuskDrift
15751
+ tuskDrift: this.tuskDrift,
15752
+ inputValueSchemaMerges: { values: { matchImportance: 0 } }
15753
+ });
15754
+ }
15755
+ /**
15756
+ * Create a replay stream for query.stream() calls
15757
+ * This is called when user calls query.stream() on a query object
15758
+ */
15759
+ _createReplayStreamForQuery(queryEmitter, streamOptions) {
15760
+ logger.debug(`[Mysql2Instrumentation] Creating replay stream for query.stream()`);
15761
+ const readableStream = new Readable({
15762
+ objectMode: true,
15763
+ read() {}
15764
+ });
15765
+ queryEmitter.on("result", (row) => {
15766
+ readableStream.push(row);
15767
+ });
15768
+ queryEmitter.on("error", (err) => {
15769
+ readableStream.destroy(err);
15770
+ });
15771
+ queryEmitter.on("end", () => {
15772
+ readableStream.push(null);
15665
15773
  });
15774
+ return readableStream;
15775
+ }
15776
+ /**
15777
+ * Recursively restore Buffer objects from their JSON serialized form.
15778
+ * JSON.stringify converts Buffer to {"type":"Buffer","data":[...]}
15779
+ * This function converts them back to actual Buffer instances.
15780
+ */
15781
+ _restoreBuffers(obj) {
15782
+ if (obj === null || obj === void 0) return obj;
15783
+ if (typeof obj === "object" && obj.type === "Buffer" && Array.isArray(obj.data)) return Buffer.from(obj.data);
15784
+ if (Array.isArray(obj)) return obj.map((item) => this._restoreBuffers(item));
15785
+ if (typeof obj === "object") {
15786
+ const result = {};
15787
+ for (const key of Object.keys(obj)) result[key] = this._restoreBuffers(obj[key]);
15788
+ return result;
15789
+ }
15790
+ return obj;
15666
15791
  }
15667
15792
  /**
15668
15793
  * Convert stored MySQL2 values back to appropriate JavaScript types
@@ -15672,12 +15797,17 @@ var TdMysql2QueryMock = class {
15672
15797
  rows: [],
15673
15798
  fields: []
15674
15799
  };
15675
- if (result.rows !== void 0 && result.fields !== void 0) return {
15676
- rows: result.rows,
15677
- fields: result.fields
15800
+ const restoredResult = this._restoreBuffers(result);
15801
+ if (restoredResult.rows !== void 0 && restoredResult.fields !== void 0) return {
15802
+ rows: restoredResult.rows,
15803
+ fields: restoredResult.fields
15804
+ };
15805
+ if (restoredResult.affectedRows !== void 0) return {
15806
+ rows: restoredResult,
15807
+ fields: []
15678
15808
  };
15679
15809
  return {
15680
- rows: result,
15810
+ rows: restoredResult,
15681
15811
  fields: []
15682
15812
  };
15683
15813
  }
@@ -15822,6 +15952,18 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
15822
15952
  logger.debug(`[Mysql2Instrumentation] Wrapped BaseConnection.prototype.end`);
15823
15953
  }
15824
15954
  }
15955
+ if (BaseConnectionClass.prototype && BaseConnectionClass.prototype.prepare) {
15956
+ if (!isWrapped$1(BaseConnectionClass.prototype.prepare)) {
15957
+ this._wrap(BaseConnectionClass.prototype, "prepare", this._getPreparePatchFn("connection"));
15958
+ logger.debug(`[Mysql2Instrumentation] Wrapped BaseConnection.prototype.prepare`);
15959
+ }
15960
+ }
15961
+ if (BaseConnectionClass.prototype && BaseConnectionClass.prototype.changeUser) {
15962
+ if (!isWrapped$1(BaseConnectionClass.prototype.changeUser)) {
15963
+ this._wrap(BaseConnectionClass.prototype, "changeUser", this._getChangeUserPatchFn("connection"));
15964
+ logger.debug(`[Mysql2Instrumentation] Wrapped BaseConnection.prototype.changeUser`);
15965
+ }
15966
+ }
15825
15967
  this.markModuleAsPatched(BaseConnectionClass);
15826
15968
  logger.debug(`[Mysql2Instrumentation] BaseConnection class patching complete`);
15827
15969
  return BaseConnectionClass;
@@ -15873,6 +16015,18 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
15873
16015
  logger.debug(`[Mysql2Instrumentation] Wrapped Connection.prototype.end`);
15874
16016
  }
15875
16017
  }
16018
+ if (ConnectionClass.prototype && ConnectionClass.prototype.prepare) {
16019
+ if (!isWrapped$1(ConnectionClass.prototype.prepare)) {
16020
+ this._wrap(ConnectionClass.prototype, "prepare", this._getPreparePatchFn("connection"));
16021
+ logger.debug(`[Mysql2Instrumentation] Wrapped Connection.prototype.prepare`);
16022
+ }
16023
+ }
16024
+ if (ConnectionClass.prototype && ConnectionClass.prototype.changeUser) {
16025
+ if (!isWrapped$1(ConnectionClass.prototype.changeUser)) {
16026
+ this._wrap(ConnectionClass.prototype, "changeUser", this._getChangeUserPatchFn("connection"));
16027
+ logger.debug(`[Mysql2Instrumentation] Wrapped Connection.prototype.changeUser`);
16028
+ }
16029
+ }
15876
16030
  }
15877
16031
  _patchPoolV2(PoolClass) {
15878
16032
  logger.debug(`[Mysql2Instrumentation] Patching Pool class (v2)`);
@@ -15966,6 +16120,7 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
15966
16120
  packageName: "mysql2",
15967
16121
  instrumentationName: self.INSTRUMENTATION_NAME,
15968
16122
  inputValue,
16123
+ inputSchemaMerges: { values: { matchImportance: 0 } },
15969
16124
  isPreAppStart: false
15970
16125
  }, (spanInfo) => {
15971
16126
  return self.handleReplayQuery(queryConfig, inputValue, spanInfo, "query", stackTrace);
@@ -15984,6 +16139,7 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
15984
16139
  instrumentationName: self.INSTRUMENTATION_NAME,
15985
16140
  packageName: "mysql2",
15986
16141
  inputValue,
16142
+ inputSchemaMerges: { values: { matchImportance: 0 } },
15987
16143
  isPreAppStart
15988
16144
  }, (spanInfo) => {
15989
16145
  return self._handleRecordQueryInSpan(spanInfo, originalQuery, queryConfig, args, this);
@@ -16031,6 +16187,7 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
16031
16187
  packageName: "mysql2",
16032
16188
  instrumentationName: self.INSTRUMENTATION_NAME,
16033
16189
  inputValue,
16190
+ inputSchemaMerges: { values: { matchImportance: 0 } },
16034
16191
  isPreAppStart: false
16035
16192
  }, (spanInfo) => {
16036
16193
  return self.handleReplayQuery(queryConfig, inputValue, spanInfo, "execute", stackTrace);
@@ -16049,6 +16206,7 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
16049
16206
  instrumentationName: self.INSTRUMENTATION_NAME,
16050
16207
  packageName: "mysql2",
16051
16208
  inputValue,
16209
+ inputSchemaMerges: { values: { matchImportance: 0 } },
16052
16210
  isPreAppStart
16053
16211
  }, (spanInfo) => {
16054
16212
  return self._handleRecordQueryInSpan(spanInfo, originalExecute, queryConfig, args, this);
@@ -16272,6 +16430,251 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
16272
16430
  };
16273
16431
  };
16274
16432
  }
16433
+ _getChangeUserPatchFn(clientType) {
16434
+ const self = this;
16435
+ return (originalChangeUser) => {
16436
+ return function changeUser(options, callback) {
16437
+ if (typeof options === "function") {
16438
+ callback = options;
16439
+ options = {};
16440
+ }
16441
+ const inputValue = { clientType };
16442
+ if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
16443
+ noOpRequestHandler: () => {
16444
+ if (callback) {
16445
+ process.nextTick(() => callback(null));
16446
+ return;
16447
+ }
16448
+ return Promise.resolve();
16449
+ },
16450
+ isServerRequest: false,
16451
+ replayModeHandler: () => {
16452
+ return SpanUtils.createAndExecuteSpan(self.mode, () => originalChangeUser.apply(this, [options, callback]), {
16453
+ name: `mysql2.${clientType}.changeUser`,
16454
+ kind: import_src$22.SpanKind.CLIENT,
16455
+ submodule: "changeUser",
16456
+ packageName: "mysql2",
16457
+ packageType: PackageType.MYSQL,
16458
+ instrumentationName: self.INSTRUMENTATION_NAME,
16459
+ inputValue,
16460
+ isPreAppStart: false
16461
+ }, (spanInfo) => {
16462
+ if (callback) {
16463
+ process.nextTick(() => callback(null));
16464
+ return;
16465
+ }
16466
+ return Promise.resolve();
16467
+ });
16468
+ }
16469
+ });
16470
+ else if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
16471
+ originalFunctionCall: () => originalChangeUser.apply(this, [options, callback]),
16472
+ recordModeHandler: ({ isPreAppStart }) => {
16473
+ return SpanUtils.createAndExecuteSpan(self.mode, () => originalChangeUser.apply(this, [options, callback]), {
16474
+ name: `mysql2.${clientType}.changeUser`,
16475
+ kind: import_src$22.SpanKind.CLIENT,
16476
+ submodule: "changeUser",
16477
+ packageName: "mysql2",
16478
+ packageType: PackageType.MYSQL,
16479
+ instrumentationName: self.INSTRUMENTATION_NAME,
16480
+ inputValue,
16481
+ isPreAppStart
16482
+ }, (spanInfo) => {
16483
+ return self._handleSimpleCallbackMethod(spanInfo, originalChangeUser.bind(this, options), callback, this);
16484
+ });
16485
+ },
16486
+ spanKind: import_src$22.SpanKind.CLIENT
16487
+ });
16488
+ else return originalChangeUser.apply(this, [options, callback]);
16489
+ };
16490
+ };
16491
+ }
16492
+ _getPreparePatchFn(clientType) {
16493
+ const self = this;
16494
+ return (originalPrepare) => {
16495
+ return function prepare(...args) {
16496
+ const firstArg = args[0];
16497
+ const sql = typeof firstArg === "string" ? firstArg : firstArg?.sql;
16498
+ const originalCallback = typeof args[args.length - 1] === "function" ? args[args.length - 1] : void 0;
16499
+ if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
16500
+ noOpRequestHandler: () => self._handleNoOpReplayPrepare(sql, originalCallback),
16501
+ isServerRequest: false,
16502
+ replayModeHandler: () => self._handleReplayPrepare(sql, originalCallback, clientType)
16503
+ });
16504
+ else if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
16505
+ originalFunctionCall: () => originalPrepare.apply(this, args),
16506
+ recordModeHandler: ({ isPreAppStart }) => self._handleRecordPrepare(originalPrepare, args, sql, originalCallback, this, clientType, isPreAppStart),
16507
+ spanKind: import_src$22.SpanKind.CLIENT
16508
+ });
16509
+ return originalPrepare.apply(this, args);
16510
+ };
16511
+ };
16512
+ }
16513
+ _handleRecordPrepare(originalPrepare, args, sql, originalCallback, context$6, clientType, isPreAppStart) {
16514
+ const self = this;
16515
+ return SpanUtils.createAndExecuteSpan(this.mode, () => originalPrepare.apply(context$6, args), {
16516
+ name: `mysql2.${clientType}.prepare`,
16517
+ kind: import_src$22.SpanKind.CLIENT,
16518
+ submodule: "prepare",
16519
+ packageType: PackageType.MYSQL,
16520
+ packageName: "mysql2",
16521
+ instrumentationName: this.INSTRUMENTATION_NAME,
16522
+ inputValue: {
16523
+ sql,
16524
+ clientType
16525
+ },
16526
+ isPreAppStart
16527
+ }, (spanInfo) => {
16528
+ const wrappedCallback = (err, statement) => {
16529
+ if (err) {
16530
+ logger.debug(`[Mysql2Instrumentation] MySQL2 prepare error: ${err.message} (${SpanUtils.getTraceInfo()})`);
16531
+ try {
16532
+ SpanUtils.endSpan(spanInfo.span, {
16533
+ code: import_src$22.SpanStatusCode.ERROR,
16534
+ message: err.message
16535
+ });
16536
+ } catch (error) {
16537
+ logger.error(`[Mysql2Instrumentation] error ending span:`, error);
16538
+ }
16539
+ } else {
16540
+ logger.debug(`[Mysql2Instrumentation] MySQL2 prepare completed successfully (${SpanUtils.getTraceInfo()})`);
16541
+ try {
16542
+ SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
16543
+ prepared: true,
16544
+ statementId: statement?.id
16545
+ } });
16546
+ SpanUtils.endSpan(spanInfo.span, { code: import_src$22.SpanStatusCode.OK });
16547
+ } catch (error) {
16548
+ logger.error(`[Mysql2Instrumentation] error processing prepare response:`, error);
16549
+ }
16550
+ if (statement && statement.execute) {
16551
+ const originalExecute = statement.execute.bind(statement);
16552
+ statement.execute = self._getPreparedStatementExecuteWrapper(originalExecute, sql, clientType);
16553
+ }
16554
+ }
16555
+ if (originalCallback) originalCallback(err, statement);
16556
+ };
16557
+ const newArgs = [...args];
16558
+ const callbackIndex = newArgs.findIndex((a) => typeof a === "function");
16559
+ if (callbackIndex >= 0) newArgs[callbackIndex] = wrappedCallback;
16560
+ else newArgs.push(wrappedCallback);
16561
+ return originalPrepare.apply(context$6, newArgs);
16562
+ });
16563
+ }
16564
+ _getPreparedStatementExecuteWrapper(originalExecute, sql, clientType) {
16565
+ const self = this;
16566
+ return function execute(...args) {
16567
+ let values = [];
16568
+ let callback;
16569
+ for (const arg of args) if (typeof arg === "function") callback = arg;
16570
+ else if (Array.isArray(arg)) values = arg;
16571
+ else if (arg !== void 0) values = [arg];
16572
+ const inputValue = {
16573
+ sql,
16574
+ values,
16575
+ clientType
16576
+ };
16577
+ const queryConfig = {
16578
+ sql,
16579
+ values,
16580
+ callback
16581
+ };
16582
+ const stackTrace = captureStackTrace(["Mysql2Instrumentation"]);
16583
+ if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
16584
+ noOpRequestHandler: () => self.queryMock.handleNoOpReplayQuery(queryConfig),
16585
+ isServerRequest: false,
16586
+ replayModeHandler: () => {
16587
+ const spanName = `mysql2.${clientType}.preparedExecute`;
16588
+ return SpanUtils.createAndExecuteSpan(self.mode, () => originalExecute(...args), {
16589
+ name: spanName,
16590
+ kind: import_src$22.SpanKind.CLIENT,
16591
+ submodule: "preparedExecute",
16592
+ packageType: PackageType.MYSQL,
16593
+ packageName: "mysql2",
16594
+ instrumentationName: self.INSTRUMENTATION_NAME,
16595
+ inputValue,
16596
+ inputSchemaMerges: { values: { matchImportance: 0 } },
16597
+ isPreAppStart: false
16598
+ }, (spanInfo) => {
16599
+ return self.handleReplayQuery(queryConfig, inputValue, spanInfo, "preparedExecute", stackTrace);
16600
+ });
16601
+ }
16602
+ });
16603
+ else if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
16604
+ originalFunctionCall: () => originalExecute(...args),
16605
+ recordModeHandler: ({ isPreAppStart }) => {
16606
+ const spanName = `mysql2.${clientType}.preparedExecute`;
16607
+ return SpanUtils.createAndExecuteSpan(self.mode, () => originalExecute(...args), {
16608
+ name: spanName,
16609
+ kind: import_src$22.SpanKind.CLIENT,
16610
+ submodule: "preparedExecute",
16611
+ packageType: PackageType.MYSQL,
16612
+ packageName: "mysql2",
16613
+ instrumentationName: self.INSTRUMENTATION_NAME,
16614
+ inputValue,
16615
+ inputSchemaMerges: { values: { matchImportance: 0 } },
16616
+ isPreAppStart
16617
+ }, (spanInfo) => {
16618
+ return self._handleRecordQueryInSpan(spanInfo, originalExecute, queryConfig, args, void 0);
16619
+ });
16620
+ },
16621
+ spanKind: import_src$22.SpanKind.CLIENT
16622
+ });
16623
+ return originalExecute(...args);
16624
+ };
16625
+ }
16626
+ _handleReplayPrepare(sql, originalCallback, clientType) {
16627
+ const self = this;
16628
+ return SpanUtils.createAndExecuteSpan(this.mode, () => {}, {
16629
+ name: `mysql2.${clientType}.prepare`,
16630
+ kind: import_src$22.SpanKind.CLIENT,
16631
+ submodule: "prepare",
16632
+ packageType: PackageType.MYSQL,
16633
+ packageName: "mysql2",
16634
+ instrumentationName: this.INSTRUMENTATION_NAME,
16635
+ inputValue: {
16636
+ sql,
16637
+ clientType
16638
+ },
16639
+ isPreAppStart: false
16640
+ }, (spanInfo) => {
16641
+ const mockStatement = {
16642
+ query: sql,
16643
+ id: 1,
16644
+ columns: [],
16645
+ parameters: [],
16646
+ execute: self._getPreparedStatementExecuteWrapper(() => {}, sql, clientType),
16647
+ close: () => {}
16648
+ };
16649
+ try {
16650
+ SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: { prepared: true } });
16651
+ SpanUtils.endSpan(spanInfo.span, { code: import_src$22.SpanStatusCode.OK });
16652
+ } catch (error) {
16653
+ logger.error(`[Mysql2Instrumentation] error ending prepare span:`, error);
16654
+ }
16655
+ if (originalCallback) process.nextTick(() => originalCallback(null, mockStatement));
16656
+ });
16657
+ }
16658
+ _handleNoOpReplayPrepare(sql, originalCallback) {
16659
+ const self = this;
16660
+ const mockStatement = {
16661
+ query: sql,
16662
+ id: 1,
16663
+ columns: [],
16664
+ parameters: [],
16665
+ execute: (...args) => {
16666
+ const values = Array.isArray(args[0]) ? args[0] : [];
16667
+ const callback = typeof args[args.length - 1] === "function" ? args[args.length - 1] : void 0;
16668
+ return self.queryMock.handleNoOpReplayQuery({
16669
+ sql,
16670
+ values,
16671
+ callback
16672
+ });
16673
+ },
16674
+ close: () => {}
16675
+ };
16676
+ if (originalCallback) process.nextTick(() => originalCallback(null, mockStatement));
16677
+ }
16275
16678
  _handleSimpleCallbackMethod(spanInfo, originalMethod, callback, context$6) {
16276
16679
  if (callback) {
16277
16680
  const wrappedCallback = (error) => {
@@ -16343,15 +16746,29 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
16343
16746
  else if (args.length > 1 && typeof args[1] !== "function") config.values = [args[1]];
16344
16747
  return config;
16345
16748
  }
16346
- if (typeof firstArg === "object" && firstArg.sql) return {
16347
- sql: firstArg.sql,
16348
- values: firstArg.values,
16349
- callback: firstArg.callback || (typeof args[1] === "function" ? args[1] : void 0)
16350
- };
16749
+ if (typeof firstArg === "object" && firstArg.sql) {
16750
+ let values = firstArg.values;
16751
+ let callback = firstArg.callback;
16752
+ if (typeof args[1] === "function") callback = args[1];
16753
+ else {
16754
+ if (args[1] !== void 0) values = Array.isArray(args[1]) ? args[1] : [args[1]];
16755
+ if (typeof args[2] === "function") callback = args[2];
16756
+ }
16757
+ return {
16758
+ sql: firstArg.sql,
16759
+ values,
16760
+ callback
16761
+ };
16762
+ }
16351
16763
  return null;
16352
16764
  }
16353
16765
  _handleRecordQueryInSpan(spanInfo, originalQuery, queryConfig, args, context$6) {
16354
- if (!!queryConfig.callback) {
16766
+ const hasCallback = !!queryConfig.callback;
16767
+ const invokeOriginal = (invokeArgs) => {
16768
+ return context$6 ? originalQuery.apply(context$6, invokeArgs) : originalQuery(...invokeArgs);
16769
+ };
16770
+ if (hasCallback) {
16771
+ const parentContext = import_src$22.context.active();
16355
16772
  const originalCallback = queryConfig.callback;
16356
16773
  const wrappedCallback = (error, results, fields) => {
16357
16774
  if (error) {
@@ -16373,7 +16790,7 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
16373
16790
  logger.error(`[Mysql2Instrumentation] error processing response:`, error$1);
16374
16791
  }
16375
16792
  }
16376
- return originalCallback(error, results, fields);
16793
+ return import_src$22.context.with(parentContext, () => originalCallback(error, results, fields));
16377
16794
  };
16378
16795
  try {
16379
16796
  const firstArg = args[0];
@@ -16388,9 +16805,9 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
16388
16805
  } catch (error) {
16389
16806
  logger.error(`[Mysql2Instrumentation] error replacing callback:`, error, args);
16390
16807
  }
16391
- return originalQuery.apply(context$6, args);
16808
+ return invokeOriginal(args);
16392
16809
  } else {
16393
- const result = originalQuery.apply(context$6, args);
16810
+ const result = invokeOriginal(args);
16394
16811
  if (result && typeof result.on === "function") {
16395
16812
  const streamResults = [];
16396
16813
  let streamFields = null;
@@ -16596,6 +17013,34 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
16596
17013
  if (event === "error" && !this._isConnectOrErrorEmitted) return this;
16597
17014
  return super.on(event, listener);
16598
17015
  }
17016
+ once(event, listener) {
17017
+ if (!this._connectEventMock) return super.once(event, listener);
17018
+ if (event === "connect" && !this._isConnectOrErrorEmitted) {
17019
+ this._connectEventMock.getReplayedConnectionEvent(inputValue).then(({ output }) => {
17020
+ if (output !== void 0) process.nextTick(() => {
17021
+ listener.call(this, output);
17022
+ this._isConnectOrErrorEmitted = true;
17023
+ });
17024
+ }).catch((err) => {
17025
+ logger.error(`[Mysql2Instrumentation] Error replaying connection event:`, err);
17026
+ });
17027
+ return this;
17028
+ }
17029
+ if (event === "error" && !this._isConnectOrErrorEmitted) return this;
17030
+ return super.once(event, listener);
17031
+ }
17032
+ connect(callback) {
17033
+ if (!callback) return;
17034
+ this._connectEventMock.getReplayedConnectionEvent(inputValue).then(({ output }) => {
17035
+ if (output !== void 0) process.nextTick(() => {
17036
+ this._isConnectOrErrorEmitted = true;
17037
+ callback(null);
17038
+ });
17039
+ }).catch((err) => {
17040
+ logger.error(`[Mysql2Instrumentation] Error replaying connection event in connect():`, err);
17041
+ process.nextTick(() => callback(err));
17042
+ });
17043
+ }
16599
17044
  }
16600
17045
  const mockConnection = new MockConnection(...args);
16601
17046
  mockConnection.addListener("error", (_err) => {});
@@ -16623,9 +17068,13 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
16623
17068
  fields: fields || []
16624
17069
  };
16625
17070
  else if (result.affectedRows !== void 0) outputValue = {
17071
+ fieldCount: result.fieldCount,
16626
17072
  affectedRows: result.affectedRows,
16627
17073
  insertId: result.insertId,
16628
- warningCount: result.warningCount
17074
+ info: result.info ?? "",
17075
+ serverStatus: result.serverStatus ?? 0,
17076
+ warningStatus: result.warningStatus ?? 0,
17077
+ changedRows: result.changedRows ?? 0
16629
17078
  };
16630
17079
  else outputValue = result;
16631
17080
  SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
@@ -18853,16 +19302,28 @@ var GrpcInstrumentation = class GrpcInstrumentation extends TdInstrumentationBas
18853
19302
  /**
18854
19303
  * Helper method to parse optional unary response arguments
18855
19304
  *
18856
- * Handles the following cases:
18857
- * 1. (metadata: Metadata, callback: Function) - no options
18858
- * 2. (metadata: Metadata, options: Object, callback: Function) - with options
19305
+ * Handles the following cases (matching grpc-node's checkOptionalUnaryResponseArguments):
19306
+ * 1. (callback: Function) - callback only, no metadata or options
19307
+ * 2. (metadata: Metadata, callback: Function) - metadata + callback, no options
19308
+ * 3. (options: Object, callback: Function) - options + callback, no metadata
19309
+ * 4. (metadata: Metadata, options: Object, callback: Function) - full signature
18859
19310
  */
18860
19311
  parseUnaryCallArguments(MetadataConstructor, arg1, arg2, arg3) {
19312
+ if (typeof arg1 === "function") return {
19313
+ metadata: new MetadataConstructor(),
19314
+ options: {},
19315
+ callback: arg1
19316
+ };
18861
19317
  if (arg1 instanceof MetadataConstructor && typeof arg2 === "function") return {
18862
19318
  metadata: arg1,
18863
19319
  options: {},
18864
19320
  callback: arg2
18865
19321
  };
19322
+ if (!(arg1 instanceof MetadataConstructor) && typeof arg1 === "object" && arg1 !== null && typeof arg2 === "function") return {
19323
+ metadata: new MetadataConstructor(),
19324
+ options: arg1,
19325
+ callback: arg2
19326
+ };
18866
19327
  if (arg1 instanceof MetadataConstructor && arg2 instanceof Object && typeof arg3 === "function") return {
18867
19328
  metadata: arg1,
18868
19329
  options: arg2,
@@ -25804,15 +26265,13 @@ var TdSpanExporter = class {
25804
26265
  logger.debug("All adapters cleared");
25805
26266
  }
25806
26267
  /**
25807
- * Set the mode for determining which adapters to run
25808
- */
25809
- setMode(mode) {
25810
- this.mode = mode;
25811
- }
25812
- /**
25813
26268
  * Export spans using all configured adapters
25814
26269
  */
25815
26270
  export(spans, resultCallback) {
26271
+ if (this.mode !== TuskDriftMode.RECORD) {
26272
+ resultCallback({ code: import_src$5.ExportResultCode.SUCCESS });
26273
+ return;
26274
+ }
25816
26275
  logger.debug(`TdSpanExporter.export() called with ${spans.length} span(s)`);
25817
26276
  const traceBlockingManager = TraceBlockingManager.getInstance();
25818
26277
  const filteredSpansBasedOnLibraryName = spans.filter((span) => {
@@ -25851,21 +26310,16 @@ var TdSpanExporter = class {
25851
26310
  resultCallback({ code: import_src$5.ExportResultCode.SUCCESS });
25852
26311
  return;
25853
26312
  }
25854
- const activeAdapters = this.getActiveAdapters();
25855
- if (activeAdapters.length === 0) {
26313
+ if (this.adapters.length === 0) {
25856
26314
  logger.debug(`No active adapters for mode: ${this.mode}`);
25857
26315
  resultCallback({ code: import_src$5.ExportResultCode.SUCCESS });
25858
26316
  return;
25859
26317
  }
25860
- Promise.all(activeAdapters.map((adapter) => adapter.exportSpans(cleanSpans))).then(() => resultCallback({ code: import_src$5.ExportResultCode.SUCCESS })).catch((error) => resultCallback({
26318
+ Promise.all(this.adapters.map((adapter) => adapter.exportSpans(cleanSpans))).then(() => resultCallback({ code: import_src$5.ExportResultCode.SUCCESS })).catch((error) => resultCallback({
25861
26319
  code: import_src$5.ExportResultCode.FAILED,
25862
26320
  error
25863
26321
  }));
25864
26322
  }
25865
- getActiveAdapters() {
25866
- if (this.mode !== TuskDriftMode.RECORD) return this.adapters.filter((adapter) => adapter.name === "in-memory" || adapter.name === "callback");
25867
- return this.adapters;
25868
- }
25869
26323
  /**
25870
26324
  * Shutdown all adapters
25871
26325
  */
@@ -32996,7 +33450,7 @@ var require_src = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/sdk-
32996
33450
  //#endregion
32997
33451
  //#region package.json
32998
33452
  var import_src$1 = /* @__PURE__ */ __toESM(require_src(), 1);
32999
- var version = "0.1.21";
33453
+ var version = "0.1.22";
33000
33454
 
33001
33455
  //#endregion
33002
33456
  //#region src/version.ts