@justanalyticsapp/node 0.2.1 → 0.3.1

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.
Files changed (40) hide show
  1. package/dist/client.d.ts +23 -1
  2. package/dist/client.js +139 -1
  3. package/dist/client.js.map +1 -1
  4. package/dist/integrations/axios-integration.d.ts +53 -0
  5. package/dist/integrations/axios-integration.js +217 -0
  6. package/dist/integrations/axios-integration.js.map +1 -0
  7. package/dist/integrations/drizzle.d.ts +54 -0
  8. package/dist/integrations/drizzle.js +236 -0
  9. package/dist/integrations/drizzle.js.map +1 -0
  10. package/dist/integrations/http.d.ts +3 -1
  11. package/dist/integrations/http.js +12 -1
  12. package/dist/integrations/http.js.map +1 -1
  13. package/dist/integrations/mongodb.d.ts +50 -0
  14. package/dist/integrations/mongodb.js +256 -0
  15. package/dist/integrations/mongodb.js.map +1 -0
  16. package/dist/integrations/mysql.d.ts +56 -0
  17. package/dist/integrations/mysql.js +298 -0
  18. package/dist/integrations/mysql.js.map +1 -0
  19. package/dist/integrations/next.d.ts +41 -0
  20. package/dist/integrations/next.js +204 -0
  21. package/dist/integrations/next.js.map +1 -1
  22. package/dist/integrations/pg.d.ts +31 -3
  23. package/dist/integrations/pg.js +100 -29
  24. package/dist/integrations/pg.js.map +1 -1
  25. package/dist/integrations/postgres-js.d.ts +57 -0
  26. package/dist/integrations/postgres-js.js +306 -0
  27. package/dist/integrations/postgres-js.js.map +1 -0
  28. package/dist/integrations/prisma.d.ts +54 -0
  29. package/dist/integrations/prisma.js +182 -0
  30. package/dist/integrations/prisma.js.map +1 -0
  31. package/dist/integrations/redis.d.ts +6 -0
  32. package/dist/integrations/redis.js +21 -35
  33. package/dist/integrations/redis.js.map +1 -1
  34. package/dist/integrations/upstash-redis.d.ts +43 -0
  35. package/dist/integrations/upstash-redis.js +166 -0
  36. package/dist/integrations/upstash-redis.js.map +1 -0
  37. package/dist/utils/safe-require.d.ts +22 -0
  38. package/dist/utils/safe-require.js +36 -0
  39. package/dist/utils/safe-require.js.map +1 -0
  40. package/package.json +1 -1
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ /**
3
+ * @file packages/node-sdk/src/integrations/mongodb.ts
4
+ * @description MongoDB auto-instrumentation integration for the JustAnalytics Node.js SDK.
5
+ *
6
+ * Monkey-patches `mongodb` Collection.prototype methods to automatically create
7
+ * `db.query` spans for all MongoDB operations. This also covers Mongoose since
8
+ * it uses the `mongodb` driver internally.
9
+ *
10
+ * Follows the same monkey-patching pattern as pg.ts and redis.ts:
11
+ * - Integration class with `enable()`/`disable()` lifecycle methods
12
+ * - Original function preservation for clean teardown
13
+ * - Fail-open design: if instrumentation code fails, the original operation executes normally
14
+ *
15
+ * SECURITY: Query filter objects are JSON-stringified with values replaced by '?'
16
+ * to prevent leaking sensitive data into span attributes.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.MongodbIntegration = void 0;
20
+ exports.sanitizeMongoFilter = sanitizeMongoFilter;
21
+ const span_1 = require("../span");
22
+ const context_1 = require("../context");
23
+ const id_1 = require("../utils/id");
24
+ const safe_require_1 = require("../utils/safe-require");
25
+ /** MongoDB Collection methods to instrument */
26
+ const COLLECTION_METHODS = [
27
+ 'find',
28
+ 'findOne',
29
+ 'insertOne',
30
+ 'insertMany',
31
+ 'updateOne',
32
+ 'updateMany',
33
+ 'deleteOne',
34
+ 'deleteMany',
35
+ 'aggregate',
36
+ 'countDocuments',
37
+ 'distinct',
38
+ 'findOneAndUpdate',
39
+ 'findOneAndDelete',
40
+ 'findOneAndReplace',
41
+ 'bulkWrite',
42
+ ];
43
+ /**
44
+ * Sanitize a MongoDB filter/query object by replacing all values with '?'.
45
+ * Only preserves top-level keys and operator keys (starting with '$').
46
+ */
47
+ function sanitizeMongoFilter(filter, maxLength = 1024) {
48
+ try {
49
+ if (!filter || typeof filter !== 'object') {
50
+ return filter === undefined ? '{}' : '?';
51
+ }
52
+ const sanitized = sanitizeObject(filter, 3);
53
+ const result = JSON.stringify(sanitized);
54
+ if (result.length > maxLength) {
55
+ return result.substring(0, maxLength - 3) + '...';
56
+ }
57
+ return result;
58
+ }
59
+ catch {
60
+ return '{}';
61
+ }
62
+ }
63
+ function sanitizeObject(obj, maxDepth) {
64
+ if (maxDepth <= 0)
65
+ return '?';
66
+ if (Array.isArray(obj)) {
67
+ return obj.length > 0 ? ['?'] : [];
68
+ }
69
+ const result = {};
70
+ for (const key of Object.keys(obj)) {
71
+ const value = obj[key];
72
+ if (key.startsWith('$') && typeof value === 'object' && value !== null) {
73
+ // Preserve MongoDB operator structure
74
+ result[key] = sanitizeObject(value, maxDepth - 1);
75
+ }
76
+ else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
77
+ result[key] = sanitizeObject(value, maxDepth - 1);
78
+ }
79
+ else {
80
+ result[key] = '?';
81
+ }
82
+ }
83
+ return result;
84
+ }
85
+ /**
86
+ * MongodbIntegration monkey-patches mongodb Collection.prototype methods
87
+ * to auto-create db.query spans for all MongoDB operations.
88
+ */
89
+ class MongodbIntegration {
90
+ constructor(serviceName, options, onSpanEnd) {
91
+ this._enabled = false;
92
+ this._instrumentedDriver = null;
93
+ // Store original Collection methods for restoration
94
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
+ this._collectionProto = null;
96
+ this._originals = new Map();
97
+ this._serviceName = serviceName;
98
+ this._onSpanEnd = onSpanEnd;
99
+ const opts = options || {};
100
+ this._options = {
101
+ enabled: opts.enabled !== false,
102
+ maxStatementLength: opts.maxStatementLength ?? 1024,
103
+ };
104
+ }
105
+ get instrumentedDriver() {
106
+ return this._instrumentedDriver;
107
+ }
108
+ enable() {
109
+ if (this._enabled)
110
+ return;
111
+ if (!this._options.enabled)
112
+ return;
113
+ try {
114
+ const mongodb = (0, safe_require_1.safeRequire)('mongodb');
115
+ if (!mongodb)
116
+ return;
117
+ const Collection = mongodb.Collection;
118
+ if (!Collection || !Collection.prototype) {
119
+ return;
120
+ }
121
+ this._collectionProto = Collection.prototype;
122
+ for (const method of COLLECTION_METHODS) {
123
+ const original = Collection.prototype[method];
124
+ if (typeof original !== 'function')
125
+ continue;
126
+ this._originals.set(method, original);
127
+ Collection.prototype[method] = this._wrapMethod(original, method);
128
+ }
129
+ this._instrumentedDriver = 'mongodb';
130
+ this._enabled = true;
131
+ }
132
+ catch {
133
+ this._restoreOriginals();
134
+ }
135
+ }
136
+ disable() {
137
+ if (!this._enabled)
138
+ return;
139
+ this._restoreOriginals();
140
+ this._instrumentedDriver = null;
141
+ this._enabled = false;
142
+ }
143
+ _wrapMethod(original, method) {
144
+ const integration = this;
145
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
146
+ return function patchedMethod(...args) {
147
+ try {
148
+ const parentSpan = (0, context_1.getActiveSpan)();
149
+ const traceId = parentSpan?.traceId ?? (0, id_1.generateTraceId)();
150
+ const parentSpanId = parentSpan?.id ?? null;
151
+ // Get collection name and database name from the Collection instance
152
+ const collectionName = this.collectionName || this.s?.namespace?.collection || 'unknown';
153
+ const dbName = this.dbName || this.s?.namespace?.db || this.s?.db?.databaseName || undefined;
154
+ const operationName = `db.query ${method}`;
155
+ // Sanitize the first argument (usually the filter/document)
156
+ const filterStr = args.length > 0
157
+ ? sanitizeMongoFilter(args[0], integration._options.maxStatementLength)
158
+ : '{}';
159
+ const statement = `${method} ${collectionName} ${filterStr}`;
160
+ const truncatedStatement = statement.length > integration._options.maxStatementLength
161
+ ? statement.substring(0, integration._options.maxStatementLength - 3) + '...'
162
+ : statement;
163
+ const attributes = {
164
+ 'db.system': 'mongodb',
165
+ 'db.operation': method,
166
+ 'db.mongodb.collection': collectionName,
167
+ 'db.statement': truncatedStatement,
168
+ };
169
+ if (dbName)
170
+ attributes['db.name'] = dbName;
171
+ const span = new span_1.Span({
172
+ operationName,
173
+ serviceName: integration._serviceName,
174
+ kind: 'client',
175
+ traceId,
176
+ parentSpanId,
177
+ attributes,
178
+ });
179
+ try {
180
+ const result = original.apply(this, args);
181
+ // MongoDB methods return promises (or cursors with toArray)
182
+ if (result && typeof result.then === 'function') {
183
+ return result.then((value) => {
184
+ span.end();
185
+ integration._onSpanEnd(span);
186
+ return value;
187
+ }, (error) => {
188
+ span.setStatus('error', error instanceof Error ? error.message : String(error));
189
+ span.end();
190
+ integration._onSpanEnd(span);
191
+ throw error;
192
+ });
193
+ }
194
+ // For methods that return cursors (e.g., find, aggregate), we
195
+ // instrument the cursor's toArray/next if possible, or just end span now
196
+ if (result && typeof result === 'object' && 'toArray' in result) {
197
+ // It's a cursor -- wrap toArray to capture full duration
198
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
199
+ const cursor = result;
200
+ const originalToArray = cursor.toArray;
201
+ if (typeof originalToArray === 'function') {
202
+ cursor.toArray = function patchedToArray(...toArrayArgs) {
203
+ const toArrayResult = originalToArray.apply(cursor, toArrayArgs);
204
+ if (toArrayResult && typeof toArrayResult.then === 'function') {
205
+ return toArrayResult.then((value) => {
206
+ span.end();
207
+ integration._onSpanEnd(span);
208
+ return value;
209
+ }, (error) => {
210
+ span.setStatus('error', error instanceof Error ? error.message : String(error));
211
+ span.end();
212
+ integration._onSpanEnd(span);
213
+ throw error;
214
+ });
215
+ }
216
+ span.end();
217
+ integration._onSpanEnd(span);
218
+ return toArrayResult;
219
+ };
220
+ }
221
+ else {
222
+ // No toArray -- end span immediately
223
+ span.end();
224
+ integration._onSpanEnd(span);
225
+ }
226
+ return result;
227
+ }
228
+ // Sync result (unlikely for MongoDB)
229
+ span.end();
230
+ integration._onSpanEnd(span);
231
+ return result;
232
+ }
233
+ catch (error) {
234
+ span.setStatus('error', error instanceof Error ? error.message : String(error));
235
+ span.end();
236
+ integration._onSpanEnd(span);
237
+ throw error;
238
+ }
239
+ }
240
+ catch {
241
+ return original.apply(this, args);
242
+ }
243
+ };
244
+ }
245
+ _restoreOriginals() {
246
+ if (this._collectionProto) {
247
+ for (const [method, original] of this._originals) {
248
+ this._collectionProto[method] = original;
249
+ }
250
+ this._originals.clear();
251
+ this._collectionProto = null;
252
+ }
253
+ }
254
+ }
255
+ exports.MongodbIntegration = MongodbIntegration;
256
+ //# sourceMappingURL=mongodb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongodb.js","sourceRoot":"","sources":["../../src/integrations/mongodb.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @file packages/node-sdk/src/integrations/mysql.ts
3
+ * @description MySQL auto-instrumentation integration for the JustAnalytics Node.js SDK.
4
+ *
5
+ * Monkey-patches `mysql2` (Connection.prototype.query and .execute) and/or
6
+ * legacy `mysql` (Connection.prototype.query) to automatically create `db.query`
7
+ * spans for all MySQL operations.
8
+ *
9
+ * Follows the same monkey-patching pattern as pg.ts:
10
+ * - Integration class with `enable()`/`disable()` lifecycle methods
11
+ * - Original function preservation for clean teardown
12
+ * - Integration with AsyncLocalStorage context for automatic parent-child span relationships
13
+ * - Fail-open design: if instrumentation code fails, the original query executes normally
14
+ *
15
+ * SQL sanitization reuses the same utilities from pg.ts.
16
+ */
17
+ import { Span } from '../span';
18
+ /**
19
+ * Configuration for the MySQL auto-instrumentation integration.
20
+ */
21
+ export interface MysqlIntegrationOptions {
22
+ /** Enable/disable the integration (default: true) */
23
+ enabled?: boolean;
24
+ /** Maximum character length for the db.statement attribute (default: 2048) */
25
+ maxQueryLength?: number;
26
+ }
27
+ /**
28
+ * MysqlIntegration monkey-patches mysql2 and/or mysql to auto-create
29
+ * db.query spans for all MySQL operations.
30
+ */
31
+ export declare class MysqlIntegration {
32
+ private _enabled;
33
+ private _options;
34
+ private _serviceName;
35
+ private _onSpanEnd;
36
+ /** Which driver was instrumented */
37
+ private _instrumentedDriver;
38
+ private _mysql2ConnectionProto;
39
+ private _originalMysql2Query;
40
+ private _originalMysql2Execute;
41
+ private _mysqlConnectionProto;
42
+ private _originalMysqlQuery;
43
+ constructor(serviceName: string, options: MysqlIntegrationOptions | undefined, onSpanEnd: (span: Span) => void);
44
+ get instrumentedDriver(): string | null;
45
+ enable(): void;
46
+ disable(): void;
47
+ private _tryPatchMysql2;
48
+ private _tryPatchMysql;
49
+ /**
50
+ * Wrap a mysql/mysql2 query or execute method to create db.query spans.
51
+ */
52
+ private _wrapQuery;
53
+ private _restoreMysql2;
54
+ private _restoreMysql;
55
+ private _restoreOriginals;
56
+ }
@@ -0,0 +1,298 @@
1
+ "use strict";
2
+ /**
3
+ * @file packages/node-sdk/src/integrations/mysql.ts
4
+ * @description MySQL auto-instrumentation integration for the JustAnalytics Node.js SDK.
5
+ *
6
+ * Monkey-patches `mysql2` (Connection.prototype.query and .execute) and/or
7
+ * legacy `mysql` (Connection.prototype.query) to automatically create `db.query`
8
+ * spans for all MySQL operations.
9
+ *
10
+ * Follows the same monkey-patching pattern as pg.ts:
11
+ * - Integration class with `enable()`/`disable()` lifecycle methods
12
+ * - Original function preservation for clean teardown
13
+ * - Integration with AsyncLocalStorage context for automatic parent-child span relationships
14
+ * - Fail-open design: if instrumentation code fails, the original query executes normally
15
+ *
16
+ * SQL sanitization reuses the same utilities from pg.ts.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.MysqlIntegration = void 0;
20
+ const span_1 = require("../span");
21
+ const context_1 = require("../context");
22
+ const id_1 = require("../utils/id");
23
+ const pg_1 = require("./pg");
24
+ const safe_require_1 = require("../utils/safe-require");
25
+ /**
26
+ * Normalize mysql/mysql2 query arguments into a consistent shape.
27
+ *
28
+ * Both drivers support:
29
+ * - query(sql, callback)
30
+ * - query(sql, values, callback)
31
+ * - query(sql) -- promise (mysql2 only)
32
+ * - query(sql, values) -- promise (mysql2 only)
33
+ * - query({ sql: string, ... })
34
+ */
35
+ function normalizeMysqlArgs(args) {
36
+ let text = '';
37
+ let callback = null;
38
+ if (typeof args[0] === 'string') {
39
+ text = args[0];
40
+ }
41
+ else if (typeof args[0] === 'object' && args[0] !== null && 'sql' in args[0]) {
42
+ text = args[0].sql;
43
+ }
44
+ // Find callback (last function argument)
45
+ for (let i = args.length - 1; i >= 1; i--) {
46
+ if (typeof args[i] === 'function') {
47
+ callback = args[i];
48
+ break;
49
+ }
50
+ }
51
+ // Also check first arg callback style: query(callback) is unusual but defensive
52
+ if (!callback && args.length === 1 && typeof args[0] === 'function') {
53
+ // Not a query call we can instrument
54
+ text = '';
55
+ }
56
+ return { text, callback };
57
+ }
58
+ /**
59
+ * MysqlIntegration monkey-patches mysql2 and/or mysql to auto-create
60
+ * db.query spans for all MySQL operations.
61
+ */
62
+ class MysqlIntegration {
63
+ constructor(serviceName, options, onSpanEnd) {
64
+ this._enabled = false;
65
+ /** Which driver was instrumented */
66
+ this._instrumentedDriver = null;
67
+ // mysql2 originals
68
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ this._mysql2ConnectionProto = null;
70
+ this._originalMysql2Query = null;
71
+ this._originalMysql2Execute = null;
72
+ // legacy mysql originals
73
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
+ this._mysqlConnectionProto = null;
75
+ this._originalMysqlQuery = null;
76
+ this._serviceName = serviceName;
77
+ this._onSpanEnd = onSpanEnd;
78
+ const opts = options || {};
79
+ this._options = {
80
+ enabled: opts.enabled !== false,
81
+ maxQueryLength: opts.maxQueryLength ?? 2048,
82
+ };
83
+ }
84
+ get instrumentedDriver() {
85
+ return this._instrumentedDriver;
86
+ }
87
+ enable() {
88
+ if (this._enabled)
89
+ return;
90
+ if (!this._options.enabled)
91
+ return;
92
+ const drivers = [];
93
+ // Try mysql2 first (most popular)
94
+ if (this._tryPatchMysql2()) {
95
+ drivers.push('mysql2');
96
+ }
97
+ // Try legacy mysql
98
+ if (this._tryPatchMysql()) {
99
+ drivers.push('mysql');
100
+ }
101
+ if (drivers.length === 0)
102
+ return;
103
+ this._instrumentedDriver = drivers.join(', ');
104
+ this._enabled = true;
105
+ }
106
+ disable() {
107
+ if (!this._enabled)
108
+ return;
109
+ this._restoreOriginals();
110
+ this._instrumentedDriver = null;
111
+ this._enabled = false;
112
+ }
113
+ _tryPatchMysql2() {
114
+ try {
115
+ const mysql2 = (0, safe_require_1.safeRequire)('mysql2');
116
+ if (!mysql2)
117
+ return false;
118
+ // mysql2 exposes Connection via the module
119
+ const Connection = mysql2.Connection;
120
+ if (!Connection || !Connection.prototype) {
121
+ return false;
122
+ }
123
+ this._mysql2ConnectionProto = Connection.prototype;
124
+ // Patch query
125
+ if (typeof Connection.prototype.query === 'function') {
126
+ this._originalMysql2Query = Connection.prototype.query;
127
+ Connection.prototype.query = this._wrapQuery(this._originalMysql2Query, 'mysql2');
128
+ }
129
+ // Patch execute (prepared statements)
130
+ if (typeof Connection.prototype.execute === 'function') {
131
+ this._originalMysql2Execute = Connection.prototype.execute;
132
+ Connection.prototype.execute = this._wrapQuery(this._originalMysql2Execute, 'mysql2');
133
+ }
134
+ return true;
135
+ }
136
+ catch {
137
+ this._restoreMysql2();
138
+ return false;
139
+ }
140
+ }
141
+ _tryPatchMysql() {
142
+ try {
143
+ const mysql = (0, safe_require_1.safeRequire)('mysql');
144
+ if (!mysql)
145
+ return false;
146
+ // Legacy mysql creates connections via createConnection/createPool
147
+ // The Connection prototype is internal; try to access it
148
+ const tempConn = mysql.createConnection ? mysql.createConnection({ host: '__probe__' }) : null;
149
+ if (tempConn && tempConn.constructor && tempConn.constructor.prototype) {
150
+ const proto = tempConn.constructor.prototype;
151
+ if (typeof proto.query === 'function') {
152
+ this._mysqlConnectionProto = proto;
153
+ this._originalMysqlQuery = proto.query;
154
+ proto.query = this._wrapQuery(this._originalMysqlQuery, 'mysql');
155
+ // Destroy the probe connection (it was never connected)
156
+ try {
157
+ tempConn.destroy();
158
+ }
159
+ catch { /* ignore */ }
160
+ return true;
161
+ }
162
+ try {
163
+ tempConn.destroy();
164
+ }
165
+ catch { /* ignore */ }
166
+ }
167
+ return false;
168
+ }
169
+ catch {
170
+ this._restoreMysql();
171
+ return false;
172
+ }
173
+ }
174
+ /**
175
+ * Wrap a mysql/mysql2 query or execute method to create db.query spans.
176
+ */
177
+ _wrapQuery(original, driver) {
178
+ const integration = this;
179
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
180
+ return function patchedQuery(...args) {
181
+ try {
182
+ const { text, callback } = normalizeMysqlArgs(args);
183
+ if (!text) {
184
+ return original.apply(this, args);
185
+ }
186
+ const parentSpan = (0, context_1.getActiveSpan)();
187
+ const traceId = parentSpan?.traceId ?? (0, id_1.generateTraceId)();
188
+ const parentSpanId = parentSpan?.id ?? null;
189
+ const operation = (0, pg_1.extractSqlOperation)(text);
190
+ const table = (0, pg_1.extractTableName)(text);
191
+ const sanitizedSql = (0, pg_1.sanitizeSql)(text, integration._options.maxQueryLength);
192
+ const operationName = operation !== 'UNKNOWN' ? `db.query ${operation}` : 'db.query';
193
+ const attributes = {
194
+ 'db.system': 'mysql',
195
+ 'db.statement': sanitizedSql,
196
+ 'db.driver': driver,
197
+ };
198
+ if (operation !== 'UNKNOWN')
199
+ attributes['db.operation'] = operation;
200
+ if (table)
201
+ attributes['db.sql.table'] = table;
202
+ // Extract connection info
203
+ const config = this.config || this.connectionConfig || {};
204
+ if (config.database)
205
+ attributes['db.name'] = config.database;
206
+ if (config.user)
207
+ attributes['db.user'] = config.user;
208
+ if (config.host) {
209
+ const host = config.host || 'localhost';
210
+ const port = config.port || 3306;
211
+ attributes['db.connection_string'] = `mysql://${config.user || ''}:***@${host}:${port}/${config.database || ''}`;
212
+ }
213
+ const span = new span_1.Span({
214
+ operationName,
215
+ serviceName: integration._serviceName,
216
+ kind: 'client',
217
+ traceId,
218
+ parentSpanId,
219
+ attributes,
220
+ });
221
+ if (callback) {
222
+ // Callback-style: wrap callback to end span
223
+ const wrappedArgs = [...args];
224
+ const cbIndex = wrappedArgs.findIndex((a) => typeof a === 'function');
225
+ if (cbIndex !== -1) {
226
+ const originalCb = wrappedArgs[cbIndex];
227
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
228
+ wrappedArgs[cbIndex] = function wrappedCallback(err, ...rest) {
229
+ if (err) {
230
+ span.setStatus('error', err instanceof Error ? err.message : String(err));
231
+ }
232
+ span.end();
233
+ integration._onSpanEnd(span);
234
+ return originalCb.call(this, err, ...rest);
235
+ };
236
+ }
237
+ return original.apply(this, wrappedArgs);
238
+ }
239
+ else {
240
+ // Promise-style (mysql2 supports this)
241
+ try {
242
+ const result = original.apply(this, args);
243
+ if (result && typeof result.then === 'function') {
244
+ return result.then((value) => {
245
+ span.end();
246
+ integration._onSpanEnd(span);
247
+ return value;
248
+ }, (error) => {
249
+ span.setStatus('error', error instanceof Error ? error.message : String(error));
250
+ span.end();
251
+ integration._onSpanEnd(span);
252
+ throw error;
253
+ });
254
+ }
255
+ span.end();
256
+ integration._onSpanEnd(span);
257
+ return result;
258
+ }
259
+ catch (error) {
260
+ span.setStatus('error', error instanceof Error ? error.message : String(error));
261
+ span.end();
262
+ integration._onSpanEnd(span);
263
+ throw error;
264
+ }
265
+ }
266
+ }
267
+ catch {
268
+ return original.apply(this, args);
269
+ }
270
+ };
271
+ }
272
+ _restoreMysql2() {
273
+ if (this._mysql2ConnectionProto) {
274
+ if (this._originalMysql2Query) {
275
+ this._mysql2ConnectionProto.query = this._originalMysql2Query;
276
+ this._originalMysql2Query = null;
277
+ }
278
+ if (this._originalMysql2Execute) {
279
+ this._mysql2ConnectionProto.execute = this._originalMysql2Execute;
280
+ this._originalMysql2Execute = null;
281
+ }
282
+ this._mysql2ConnectionProto = null;
283
+ }
284
+ }
285
+ _restoreMysql() {
286
+ if (this._mysqlConnectionProto && this._originalMysqlQuery) {
287
+ this._mysqlConnectionProto.query = this._originalMysqlQuery;
288
+ this._originalMysqlQuery = null;
289
+ this._mysqlConnectionProto = null;
290
+ }
291
+ }
292
+ _restoreOriginals() {
293
+ this._restoreMysql2();
294
+ this._restoreMysql();
295
+ }
296
+ }
297
+ exports.MysqlIntegration = MysqlIntegration;
298
+ //# sourceMappingURL=mysql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mysql.js","sourceRoot":"","sources":["../../src/integrations/mysql.ts"],"names":[],"mappings":"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"}