@sentry/node 10.41.0-beta.0 → 10.42.0
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/build/cjs/integrations/tracing/postgresjs.js +13 -309
- package/build/cjs/integrations/tracing/postgresjs.js.map +1 -1
- package/build/esm/integrations/tracing/postgresjs.js +15 -311
- package/build/esm/integrations/tracing/postgresjs.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/types/integrations/tracing/postgresjs.d.ts +4 -32
- package/build/types/integrations/tracing/postgresjs.d.ts.map +1 -1
- package/build/types-ts3.8/integrations/tracing/postgresjs.d.ts +4 -32
- package/package.json +4 -4
|
@@ -7,7 +7,6 @@ const core = require('@sentry/core');
|
|
|
7
7
|
const nodeCore = require('@sentry/node-core');
|
|
8
8
|
const debugBuild = require('../../debug-build.js');
|
|
9
9
|
|
|
10
|
-
/* eslint-disable max-lines */
|
|
11
10
|
// Instrumentation for https://github.com/porsager/postgres
|
|
12
11
|
|
|
13
12
|
|
|
@@ -15,8 +14,6 @@ const INTEGRATION_NAME = 'PostgresJs';
|
|
|
15
14
|
const SUPPORTED_VERSIONS = ['>=3.0.0 <4'];
|
|
16
15
|
const SQL_OPERATION_REGEX = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i;
|
|
17
16
|
|
|
18
|
-
const CONNECTION_CONTEXT_SYMBOL = Symbol('sentryPostgresConnectionContext');
|
|
19
|
-
const INSTRUMENTED_MARKER = Symbol.for('sentry.instrumented.postgresjs');
|
|
20
17
|
// Marker to track if a query was created from an instrumented sql instance
|
|
21
18
|
// This prevents double-spanning when both wrapper and prototype patches are active
|
|
22
19
|
const QUERY_FROM_INSTRUMENTED_SQL = Symbol.for('sentry.query.from.instrumented.sql');
|
|
@@ -105,7 +102,12 @@ class PostgresJsInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
105
102
|
return sql;
|
|
106
103
|
}
|
|
107
104
|
|
|
108
|
-
|
|
105
|
+
// Delegate to the portable instrumentation from @sentry/core
|
|
106
|
+
const config = self.getConfig();
|
|
107
|
+
return core.instrumentPostgresJsSql(sql, {
|
|
108
|
+
requireParentSpan: config.requireParentSpan,
|
|
109
|
+
requestHook: config.requestHook,
|
|
110
|
+
});
|
|
109
111
|
};
|
|
110
112
|
|
|
111
113
|
Object.setPrototypeOf(WrappedPostgres, Original);
|
|
@@ -131,94 +133,14 @@ class PostgresJsInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
/**
|
|
134
|
-
*
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
original,
|
|
138
|
-
target,
|
|
139
|
-
proxiedSql,
|
|
140
|
-
) {
|
|
141
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
142
|
-
const self = this;
|
|
143
|
-
return function ( ...args) {
|
|
144
|
-
const query = Reflect.apply(original, target, args);
|
|
145
|
-
|
|
146
|
-
if (query && typeof query === 'object' && 'handle' in query) {
|
|
147
|
-
self._wrapSingleQueryHandle(query , proxiedSql);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return query;
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Wraps callback-based methods (begin, reserve) to recursively instrument Sql instances.
|
|
156
|
-
* Note: These methods can also be used as tagged templates, which we pass through unchanged.
|
|
157
|
-
*
|
|
158
|
-
* Savepoint is not wrapped to avoid complex nested transaction instrumentation issues.
|
|
159
|
-
* Queries within savepoint callbacks are still instrumented through the parent transaction's Sql instance.
|
|
160
|
-
*/
|
|
161
|
-
_wrapCallbackMethod(
|
|
162
|
-
original,
|
|
163
|
-
target,
|
|
164
|
-
parentSqlInstance,
|
|
165
|
-
) {
|
|
166
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
167
|
-
const self = this;
|
|
168
|
-
return function ( ...args) {
|
|
169
|
-
// Extract parent context to propagate to child instances
|
|
170
|
-
const parentContext = (parentSqlInstance )[CONNECTION_CONTEXT_SYMBOL]
|
|
171
|
-
|
|
172
|
-
;
|
|
173
|
-
|
|
174
|
-
// Check if this is a callback-based call by verifying the last argument is a function
|
|
175
|
-
const isCallbackBased = typeof args[args.length - 1] === 'function';
|
|
176
|
-
|
|
177
|
-
if (!isCallbackBased) {
|
|
178
|
-
// Not a callback-based call - could be tagged template or promise-based
|
|
179
|
-
const result = Reflect.apply(original, target, args);
|
|
180
|
-
// If result is a Promise (e.g., reserve() without callback), instrument the resolved Sql instance
|
|
181
|
-
if (result && typeof (result ).then === 'function') {
|
|
182
|
-
return (result ).then((sqlInstance) => {
|
|
183
|
-
return self._instrumentSqlInstance(sqlInstance, parentContext);
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
return result;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Callback-based call: wrap the callback to instrument the Sql instance
|
|
190
|
-
const callback = (args.length === 1 ? args[0] : args[1]) ;
|
|
191
|
-
const wrappedCallback = function (sqlInstance) {
|
|
192
|
-
const instrumentedSql = self._instrumentSqlInstance(sqlInstance, parentContext);
|
|
193
|
-
return callback(instrumentedSql);
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
const newArgs = args.length === 1 ? [wrappedCallback] : [args[0], wrappedCallback];
|
|
197
|
-
return Reflect.apply(original, target, newArgs);
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Sets connection context attributes on a span.
|
|
136
|
+
* Determines whether a span should be created based on the current context.
|
|
137
|
+
* If `requireParentSpan` is set to true in the configuration, a span will
|
|
138
|
+
* only be created if there is a parent span available.
|
|
203
139
|
*/
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (connectionContext.ATTR_DB_NAMESPACE) {
|
|
209
|
-
span.setAttribute(semanticConventions.ATTR_DB_NAMESPACE, connectionContext.ATTR_DB_NAMESPACE);
|
|
210
|
-
}
|
|
211
|
-
if (connectionContext.ATTR_SERVER_ADDRESS) {
|
|
212
|
-
span.setAttribute(semanticConventions.ATTR_SERVER_ADDRESS, connectionContext.ATTR_SERVER_ADDRESS);
|
|
213
|
-
}
|
|
214
|
-
if (connectionContext.ATTR_SERVER_PORT !== undefined) {
|
|
215
|
-
// Port is stored as string in PostgresConnectionContext for requestHook backwards compatibility,
|
|
216
|
-
// but OTEL semantic conventions expect port as a number for span attributes
|
|
217
|
-
const portNumber = parseInt(connectionContext.ATTR_SERVER_PORT, 10);
|
|
218
|
-
if (!isNaN(portNumber)) {
|
|
219
|
-
span.setAttribute(semanticConventions.ATTR_SERVER_PORT, portNumber);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
140
|
+
_shouldCreateSpans() {
|
|
141
|
+
const config = this.getConfig();
|
|
142
|
+
const hasParentSpan = api.trace.getSpan(api.context.active()) !== undefined;
|
|
143
|
+
return hasParentSpan || !config.requireParentSpan;
|
|
222
144
|
}
|
|
223
145
|
|
|
224
146
|
/**
|
|
@@ -236,224 +158,6 @@ class PostgresJsInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
236
158
|
}
|
|
237
159
|
}
|
|
238
160
|
|
|
239
|
-
/**
|
|
240
|
-
* Extracts and stores connection context from sql.options.
|
|
241
|
-
*/
|
|
242
|
-
_attachConnectionContext(sql, proxiedSql) {
|
|
243
|
-
const sqlInstance = sql ;
|
|
244
|
-
if (!sqlInstance.options || typeof sqlInstance.options !== 'object') {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const opts = sqlInstance.options;
|
|
249
|
-
// postgres.js stores parsed options with host and port as arrays
|
|
250
|
-
// The library defaults to 'localhost' and 5432 if not specified, but we're defensive here
|
|
251
|
-
const host = opts.host?.[0] || 'localhost';
|
|
252
|
-
const port = opts.port?.[0] || 5432;
|
|
253
|
-
|
|
254
|
-
const connectionContext = {
|
|
255
|
-
ATTR_DB_NAMESPACE: typeof opts.database === 'string' && opts.database !== '' ? opts.database : undefined,
|
|
256
|
-
ATTR_SERVER_ADDRESS: host,
|
|
257
|
-
ATTR_SERVER_PORT: String(port),
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
proxiedSql[CONNECTION_CONTEXT_SYMBOL] = connectionContext;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Instruments a sql instance by wrapping its query execution methods.
|
|
265
|
-
*/
|
|
266
|
-
_instrumentSqlInstance(sql, parentConnectionContext) {
|
|
267
|
-
// Check if already instrumented to prevent double-wrapping
|
|
268
|
-
// Using Symbol.for() ensures the marker survives proxying
|
|
269
|
-
if ((sql )[INSTRUMENTED_MARKER]) {
|
|
270
|
-
return sql;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
274
|
-
const self = this;
|
|
275
|
-
|
|
276
|
-
// Wrap the sql function to intercept query creation
|
|
277
|
-
const proxiedSql = new Proxy(sql , {
|
|
278
|
-
apply(target, thisArg, argumentsList) {
|
|
279
|
-
const query = Reflect.apply(target, thisArg, argumentsList);
|
|
280
|
-
|
|
281
|
-
if (query && typeof query === 'object' && 'handle' in query) {
|
|
282
|
-
self._wrapSingleQueryHandle(query , proxiedSql);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
return query;
|
|
286
|
-
},
|
|
287
|
-
get(target, prop) {
|
|
288
|
-
const original = (target )[prop];
|
|
289
|
-
|
|
290
|
-
if (typeof prop !== 'string' || typeof original !== 'function') {
|
|
291
|
-
return original;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Wrap methods that return PendingQuery objects (unsafe, file)
|
|
295
|
-
if (prop === 'unsafe' || prop === 'file') {
|
|
296
|
-
return self._wrapQueryMethod(original , target, proxiedSql);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Wrap begin and reserve (not savepoint to avoid duplicate spans)
|
|
300
|
-
if (prop === 'begin' || prop === 'reserve') {
|
|
301
|
-
return self._wrapCallbackMethod(original , target, proxiedSql);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return original;
|
|
305
|
-
},
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
// Use provided parent context if available, otherwise extract from sql.options
|
|
309
|
-
if (parentConnectionContext) {
|
|
310
|
-
(proxiedSql )[CONNECTION_CONTEXT_SYMBOL] = parentConnectionContext;
|
|
311
|
-
} else {
|
|
312
|
-
this._attachConnectionContext(sql, proxiedSql );
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// Mark both the original and proxy as instrumented to prevent double-wrapping
|
|
316
|
-
// The proxy might be passed to other methods, or the original
|
|
317
|
-
// might be accessed directly, so we need to mark both
|
|
318
|
-
(sql )[INSTRUMENTED_MARKER] = true;
|
|
319
|
-
(proxiedSql )[INSTRUMENTED_MARKER] = true;
|
|
320
|
-
|
|
321
|
-
return proxiedSql;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Wraps a single query's handle method to create spans.
|
|
326
|
-
*/
|
|
327
|
-
_wrapSingleQueryHandle(
|
|
328
|
-
query,
|
|
329
|
-
sqlInstance,
|
|
330
|
-
) {
|
|
331
|
-
// Prevent double wrapping - check if the handle itself is already wrapped
|
|
332
|
-
if ((query.handle )?.__sentryWrapped) {
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Mark this query as coming from an instrumented sql instance
|
|
337
|
-
// This prevents the Query.prototype fallback patch from double-spanning
|
|
338
|
-
(query )[QUERY_FROM_INSTRUMENTED_SQL] = true;
|
|
339
|
-
|
|
340
|
-
const originalHandle = query.handle ;
|
|
341
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
342
|
-
const self = this;
|
|
343
|
-
|
|
344
|
-
// IMPORTANT: We must replace the handle function directly, not use a Proxy,
|
|
345
|
-
// because Query.then() internally calls this.handle(), which would bypass a Proxy wrapper.
|
|
346
|
-
const wrappedHandle = async function ( ...args) {
|
|
347
|
-
if (!self._shouldCreateSpans()) {
|
|
348
|
-
return originalHandle.apply(this, args);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
const fullQuery = self._reconstructQuery(query.strings);
|
|
352
|
-
const sanitizedSqlQuery = self._sanitizeSqlQuery(fullQuery);
|
|
353
|
-
|
|
354
|
-
return core.startSpanManual(
|
|
355
|
-
{
|
|
356
|
-
name: sanitizedSqlQuery || 'postgresjs.query',
|
|
357
|
-
op: 'db',
|
|
358
|
-
},
|
|
359
|
-
(span) => {
|
|
360
|
-
nodeCore.addOriginToSpan(span, 'auto.db.postgresjs');
|
|
361
|
-
|
|
362
|
-
span.setAttributes({
|
|
363
|
-
[semanticConventions.ATTR_DB_SYSTEM_NAME]: 'postgres',
|
|
364
|
-
[semanticConventions.ATTR_DB_QUERY_TEXT]: sanitizedSqlQuery,
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
const connectionContext = sqlInstance
|
|
368
|
-
? ((sqlInstance )[CONNECTION_CONTEXT_SYMBOL]
|
|
369
|
-
|
|
370
|
-
)
|
|
371
|
-
: undefined;
|
|
372
|
-
|
|
373
|
-
self._setConnectionAttributes(span, connectionContext);
|
|
374
|
-
|
|
375
|
-
const config = self.getConfig();
|
|
376
|
-
const { requestHook } = config;
|
|
377
|
-
if (requestHook) {
|
|
378
|
-
instrumentation.safeExecuteInTheMiddle(
|
|
379
|
-
() => requestHook(span, sanitizedSqlQuery, connectionContext),
|
|
380
|
-
e => {
|
|
381
|
-
if (e) {
|
|
382
|
-
span.setAttribute('sentry.hook.error', 'requestHook failed');
|
|
383
|
-
debugBuild.DEBUG_BUILD && core.debug.error(`Error in requestHook for ${INTEGRATION_NAME} integration:`, e);
|
|
384
|
-
}
|
|
385
|
-
},
|
|
386
|
-
true,
|
|
387
|
-
);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const queryWithCallbacks = this
|
|
391
|
-
|
|
392
|
-
;
|
|
393
|
-
|
|
394
|
-
queryWithCallbacks.resolve = new Proxy(queryWithCallbacks.resolve , {
|
|
395
|
-
apply: (resolveTarget, resolveThisArg, resolveArgs) => {
|
|
396
|
-
try {
|
|
397
|
-
self._setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);
|
|
398
|
-
span.end();
|
|
399
|
-
} catch (e) {
|
|
400
|
-
debugBuild.DEBUG_BUILD && core.debug.error('Error ending span in resolve callback:', e);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);
|
|
404
|
-
},
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
queryWithCallbacks.reject = new Proxy(queryWithCallbacks.reject , {
|
|
408
|
-
apply: (rejectTarget, rejectThisArg, rejectArgs) => {
|
|
409
|
-
try {
|
|
410
|
-
span.setStatus({
|
|
411
|
-
code: core.SPAN_STATUS_ERROR,
|
|
412
|
-
message: rejectArgs?.[0]?.message || 'unknown_error',
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
span.setAttribute(semanticConventions.ATTR_DB_RESPONSE_STATUS_CODE, rejectArgs?.[0]?.code || 'unknown');
|
|
416
|
-
span.setAttribute(semanticConventions.ATTR_ERROR_TYPE, rejectArgs?.[0]?.name || 'unknown');
|
|
417
|
-
|
|
418
|
-
self._setOperationName(span, sanitizedSqlQuery);
|
|
419
|
-
span.end();
|
|
420
|
-
} catch (e) {
|
|
421
|
-
debugBuild.DEBUG_BUILD && core.debug.error('Error ending span in reject callback:', e);
|
|
422
|
-
}
|
|
423
|
-
return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);
|
|
424
|
-
},
|
|
425
|
-
});
|
|
426
|
-
|
|
427
|
-
// Handle synchronous errors that might occur before promise is created
|
|
428
|
-
try {
|
|
429
|
-
return originalHandle.apply(this, args);
|
|
430
|
-
} catch (e) {
|
|
431
|
-
span.setStatus({
|
|
432
|
-
code: core.SPAN_STATUS_ERROR,
|
|
433
|
-
message: e instanceof Error ? e.message : 'unknown_error',
|
|
434
|
-
});
|
|
435
|
-
span.end();
|
|
436
|
-
throw e;
|
|
437
|
-
}
|
|
438
|
-
},
|
|
439
|
-
);
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
(wrappedHandle ).__sentryWrapped = true;
|
|
443
|
-
query.handle = wrappedHandle;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* Determines whether a span should be created based on the current context.
|
|
448
|
-
* If `requireParentSpan` is set to true in the configuration, a span will
|
|
449
|
-
* only be created if there is a parent span available.
|
|
450
|
-
*/
|
|
451
|
-
_shouldCreateSpans() {
|
|
452
|
-
const config = this.getConfig();
|
|
453
|
-
const hasParentSpan = api.trace.getSpan(api.context.active()) !== undefined;
|
|
454
|
-
return hasParentSpan || !config.requireParentSpan;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
161
|
/**
|
|
458
162
|
* Reconstructs the full SQL query from template strings with PostgreSQL placeholders.
|
|
459
163
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgresjs.js","sources":["../../../../src/integrations/tracing/postgresjs.ts"],"sourcesContent":["/* eslint-disable max-lines */\n// Instrumentation for https://github.com/porsager/postgres\n\nimport { context, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport {\n ATTR_DB_NAMESPACE,\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_RESPONSE_STATUS_CODE,\n ATTR_DB_SYSTEM_NAME,\n ATTR_ERROR_TYPE,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n} from '@opentelemetry/semantic-conventions';\nimport type { IntegrationFn, Span } from '@sentry/core';\nimport {\n debug,\n defineIntegration,\n replaceExports,\n SDK_VERSION,\n SPAN_STATUS_ERROR,\n startSpanManual,\n} from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\nimport { DEBUG_BUILD } from '../../debug-build';\n\nconst INTEGRATION_NAME = 'PostgresJs';\nconst SUPPORTED_VERSIONS = ['>=3.0.0 <4'];\nconst SQL_OPERATION_REGEX = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i;\n\ntype PostgresConnectionContext = {\n ATTR_DB_NAMESPACE?: string; // Database name\n ATTR_SERVER_ADDRESS?: string; // Hostname or IP address of the database server\n ATTR_SERVER_PORT?: string; // Port number of the database server\n};\n\nconst CONNECTION_CONTEXT_SYMBOL = Symbol('sentryPostgresConnectionContext');\nconst INSTRUMENTED_MARKER = Symbol.for('sentry.instrumented.postgresjs');\n// Marker to track if a query was created from an instrumented sql instance\n// This prevents double-spanning when both wrapper and prototype patches are active\nconst QUERY_FROM_INSTRUMENTED_SQL = Symbol.for('sentry.query.from.instrumented.sql');\n\ntype PostgresJsInstrumentationConfig = InstrumentationConfig & {\n /**\n * Whether to require a parent span for the instrumentation.\n * If set to true, the instrumentation will only create spans if there is a parent span\n * available in the current scope.\n * @default true\n */\n requireParentSpan?: boolean;\n /**\n * Hook to modify the span before it is started.\n * This can be used to set additional attributes or modify the span in any way.\n */\n requestHook?: (span: Span, sanitizedSqlQuery: string, postgresConnectionContext?: PostgresConnectionContext) => void;\n};\n\nexport const instrumentPostgresJs = generateInstrumentOnce(\n INTEGRATION_NAME,\n (options?: PostgresJsInstrumentationConfig) =>\n new PostgresJsInstrumentation({\n requireParentSpan: options?.requireParentSpan ?? true,\n requestHook: options?.requestHook,\n }),\n);\n\n/**\n * Instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n * This instrumentation captures postgresjs queries and their attributes.\n *\n * Uses internal Sentry patching patterns to support both CommonJS and ESM environments.\n */\nexport class PostgresJsInstrumentation extends InstrumentationBase<PostgresJsInstrumentationConfig> {\n public constructor(config: PostgresJsInstrumentationConfig) {\n super('sentry-postgres-js', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by patching the postgres module.\n * Uses two complementary approaches:\n * 1. Main function wrapper: instruments sql instances created AFTER instrumentation is set up (CJS + ESM)\n * 2. Query.prototype patch: fallback for sql instances created BEFORE instrumentation (CJS only)\n */\n public init(): InstrumentationNodeModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n 'postgres',\n SUPPORTED_VERSIONS,\n exports => {\n try {\n return this._patchPostgres(exports);\n } catch (e) {\n DEBUG_BUILD && debug.error('Failed to patch postgres module:', e);\n return exports;\n }\n },\n exports => exports,\n );\n\n // Add fallback Query.prototype patching for pre-existing sql instances (CJS only)\n // This catches queries from sql instances created before Sentry was initialized\n ['src', 'cf/src', 'cjs/src'].forEach(path => {\n module.files.push(\n new InstrumentationNodeModuleFile(\n `postgres/${path}/query.js`,\n SUPPORTED_VERSIONS,\n this._patchQueryPrototype.bind(this),\n this._unpatchQueryPrototype.bind(this),\n ),\n );\n });\n\n return module;\n }\n\n /**\n * Patches the postgres module by wrapping the main export function.\n * This intercepts the creation of sql instances and instruments them.\n */\n private _patchPostgres(exports: { [key: string]: unknown }): { [key: string]: unknown } {\n // In CJS: exports is the function itself\n // In ESM: exports.default is the function\n const isFunction = typeof exports === 'function';\n const Original = isFunction ? exports : exports.default;\n\n if (typeof Original !== 'function') {\n DEBUG_BUILD && debug.warn('postgres module does not export a function. Skipping instrumentation.');\n return exports;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n const WrappedPostgres = function (this: unknown, ...args: unknown[]): unknown {\n const sql = Reflect.construct(Original as (...args: unknown[]) => unknown, args);\n\n // Validate that construction succeeded and returned a valid function object\n if (!sql || typeof sql !== 'function') {\n DEBUG_BUILD && debug.warn('postgres() did not return a valid instance');\n return sql;\n }\n\n return self._instrumentSqlInstance(sql);\n };\n\n Object.setPrototypeOf(WrappedPostgres, Original);\n Object.setPrototypeOf(WrappedPostgres.prototype, (Original as { prototype: object }).prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedPostgres, key, descriptor);\n }\n }\n }\n\n // For CJS: the exports object IS the function, so return the wrapped function\n // For ESM: replace the default export\n if (isFunction) {\n return WrappedPostgres as unknown as { [key: string]: unknown };\n } else {\n replaceExports(exports, 'default', WrappedPostgres);\n return exports;\n }\n }\n\n /**\n * Wraps query-returning methods (unsafe, file) to ensure their queries are instrumented.\n */\n private _wrapQueryMethod(\n original: (...args: unknown[]) => unknown,\n target: unknown,\n proxiedSql: unknown,\n ): (...args: unknown[]) => unknown {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n return function (this: unknown, ...args: unknown[]): unknown {\n const query = Reflect.apply(original, target, args);\n\n if (query && typeof query === 'object' && 'handle' in query) {\n self._wrapSingleQueryHandle(query as { handle: unknown; strings?: string[] }, proxiedSql);\n }\n\n return query;\n };\n }\n\n /**\n * Wraps callback-based methods (begin, reserve) to recursively instrument Sql instances.\n * Note: These methods can also be used as tagged templates, which we pass through unchanged.\n *\n * Savepoint is not wrapped to avoid complex nested transaction instrumentation issues.\n * Queries within savepoint callbacks are still instrumented through the parent transaction's Sql instance.\n */\n private _wrapCallbackMethod(\n original: (...args: unknown[]) => unknown,\n target: unknown,\n parentSqlInstance: unknown,\n ): (...args: unknown[]) => unknown {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n return function (this: unknown, ...args: unknown[]): unknown {\n // Extract parent context to propagate to child instances\n const parentContext = (parentSqlInstance as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] as\n | PostgresConnectionContext\n | undefined;\n\n // Check if this is a callback-based call by verifying the last argument is a function\n const isCallbackBased = typeof args[args.length - 1] === 'function';\n\n if (!isCallbackBased) {\n // Not a callback-based call - could be tagged template or promise-based\n const result = Reflect.apply(original, target, args);\n // If result is a Promise (e.g., reserve() without callback), instrument the resolved Sql instance\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((sqlInstance: unknown) => {\n return self._instrumentSqlInstance(sqlInstance, parentContext);\n });\n }\n return result;\n }\n\n // Callback-based call: wrap the callback to instrument the Sql instance\n const callback = (args.length === 1 ? args[0] : args[1]) as (sql: unknown) => unknown;\n const wrappedCallback = function (sqlInstance: unknown): unknown {\n const instrumentedSql = self._instrumentSqlInstance(sqlInstance, parentContext);\n return callback(instrumentedSql);\n };\n\n const newArgs = args.length === 1 ? [wrappedCallback] : [args[0], wrappedCallback];\n return Reflect.apply(original, target, newArgs);\n };\n }\n\n /**\n * Sets connection context attributes on a span.\n */\n private _setConnectionAttributes(span: Span, connectionContext: PostgresConnectionContext | undefined): void {\n if (!connectionContext) {\n return;\n }\n if (connectionContext.ATTR_DB_NAMESPACE) {\n span.setAttribute(ATTR_DB_NAMESPACE, connectionContext.ATTR_DB_NAMESPACE);\n }\n if (connectionContext.ATTR_SERVER_ADDRESS) {\n span.setAttribute(ATTR_SERVER_ADDRESS, connectionContext.ATTR_SERVER_ADDRESS);\n }\n if (connectionContext.ATTR_SERVER_PORT !== undefined) {\n // Port is stored as string in PostgresConnectionContext for requestHook backwards compatibility,\n // but OTEL semantic conventions expect port as a number for span attributes\n const portNumber = parseInt(connectionContext.ATTR_SERVER_PORT, 10);\n if (!isNaN(portNumber)) {\n span.setAttribute(ATTR_SERVER_PORT, portNumber);\n }\n }\n }\n\n /**\n * Extracts DB operation name from SQL query and sets it on the span.\n */\n private _setOperationName(span: Span, sanitizedQuery: string | undefined, command?: string): void {\n if (command) {\n span.setAttribute(ATTR_DB_OPERATION_NAME, command);\n return;\n }\n // Fallback: extract operation from the SQL query\n const operationMatch = sanitizedQuery?.match(SQL_OPERATION_REGEX);\n if (operationMatch?.[1]) {\n span.setAttribute(ATTR_DB_OPERATION_NAME, operationMatch[1].toUpperCase());\n }\n }\n\n /**\n * Extracts and stores connection context from sql.options.\n */\n private _attachConnectionContext(sql: unknown, proxiedSql: Record<symbol, unknown>): void {\n const sqlInstance = sql as { options?: { host?: string[]; port?: number[]; database?: string } };\n if (!sqlInstance.options || typeof sqlInstance.options !== 'object') {\n return;\n }\n\n const opts = sqlInstance.options;\n // postgres.js stores parsed options with host and port as arrays\n // The library defaults to 'localhost' and 5432 if not specified, but we're defensive here\n const host = opts.host?.[0] || 'localhost';\n const port = opts.port?.[0] || 5432;\n\n const connectionContext: PostgresConnectionContext = {\n ATTR_DB_NAMESPACE: typeof opts.database === 'string' && opts.database !== '' ? opts.database : undefined,\n ATTR_SERVER_ADDRESS: host,\n ATTR_SERVER_PORT: String(port),\n };\n\n proxiedSql[CONNECTION_CONTEXT_SYMBOL] = connectionContext;\n }\n\n /**\n * Instruments a sql instance by wrapping its query execution methods.\n */\n private _instrumentSqlInstance(sql: unknown, parentConnectionContext?: PostgresConnectionContext): unknown {\n // Check if already instrumented to prevent double-wrapping\n // Using Symbol.for() ensures the marker survives proxying\n if ((sql as Record<symbol, unknown>)[INSTRUMENTED_MARKER]) {\n return sql;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n // Wrap the sql function to intercept query creation\n const proxiedSql: unknown = new Proxy(sql as (...args: unknown[]) => unknown, {\n apply(target, thisArg, argumentsList: unknown[]) {\n const query = Reflect.apply(target, thisArg, argumentsList);\n\n if (query && typeof query === 'object' && 'handle' in query) {\n self._wrapSingleQueryHandle(query as { handle: unknown; strings?: string[] }, proxiedSql);\n }\n\n return query;\n },\n get(target, prop) {\n const original = (target as unknown as Record<string | symbol, unknown>)[prop];\n\n if (typeof prop !== 'string' || typeof original !== 'function') {\n return original;\n }\n\n // Wrap methods that return PendingQuery objects (unsafe, file)\n if (prop === 'unsafe' || prop === 'file') {\n return self._wrapQueryMethod(original as (...args: unknown[]) => unknown, target, proxiedSql);\n }\n\n // Wrap begin and reserve (not savepoint to avoid duplicate spans)\n if (prop === 'begin' || prop === 'reserve') {\n return self._wrapCallbackMethod(original as (...args: unknown[]) => unknown, target, proxiedSql);\n }\n\n return original;\n },\n });\n\n // Use provided parent context if available, otherwise extract from sql.options\n if (parentConnectionContext) {\n (proxiedSql as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] = parentConnectionContext;\n } else {\n this._attachConnectionContext(sql, proxiedSql as Record<symbol, unknown>);\n }\n\n // Mark both the original and proxy as instrumented to prevent double-wrapping\n // The proxy might be passed to other methods, or the original\n // might be accessed directly, so we need to mark both\n (sql as Record<symbol, unknown>)[INSTRUMENTED_MARKER] = true;\n (proxiedSql as Record<symbol, unknown>)[INSTRUMENTED_MARKER] = true;\n\n return proxiedSql;\n }\n\n /**\n * Wraps a single query's handle method to create spans.\n */\n private _wrapSingleQueryHandle(\n query: { handle: unknown; strings?: string[]; __sentryWrapped?: boolean },\n sqlInstance: unknown,\n ): void {\n // Prevent double wrapping - check if the handle itself is already wrapped\n if ((query.handle as { __sentryWrapped?: boolean })?.__sentryWrapped) {\n return;\n }\n\n // Mark this query as coming from an instrumented sql instance\n // This prevents the Query.prototype fallback patch from double-spanning\n (query as Record<symbol, unknown>)[QUERY_FROM_INSTRUMENTED_SQL] = true;\n\n const originalHandle = query.handle as (...args: unknown[]) => Promise<unknown>;\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n // IMPORTANT: We must replace the handle function directly, not use a Proxy,\n // because Query.then() internally calls this.handle(), which would bypass a Proxy wrapper.\n const wrappedHandle = async function (this: unknown, ...args: unknown[]): Promise<unknown> {\n if (!self._shouldCreateSpans()) {\n return originalHandle.apply(this, args);\n }\n\n const fullQuery = self._reconstructQuery(query.strings);\n const sanitizedSqlQuery = self._sanitizeSqlQuery(fullQuery);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n addOriginToSpan(span, 'auto.db.postgresjs');\n\n span.setAttributes({\n [ATTR_DB_SYSTEM_NAME]: 'postgres',\n [ATTR_DB_QUERY_TEXT]: sanitizedSqlQuery,\n });\n\n const connectionContext = sqlInstance\n ? ((sqlInstance as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] as\n | PostgresConnectionContext\n | undefined)\n : undefined;\n\n self._setConnectionAttributes(span, connectionContext);\n\n const config = self.getConfig();\n const { requestHook } = config;\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, sanitizedSqlQuery, connectionContext),\n e => {\n if (e) {\n span.setAttribute('sentry.hook.error', 'requestHook failed');\n DEBUG_BUILD && debug.error(`Error in requestHook for ${INTEGRATION_NAME} integration:`, e);\n }\n },\n true,\n );\n }\n\n const queryWithCallbacks = this as {\n resolve: unknown;\n reject: unknown;\n };\n\n queryWithCallbacks.resolve = new Proxy(queryWithCallbacks.resolve as (...args: unknown[]) => unknown, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n try {\n self._setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e);\n }\n\n return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n },\n });\n\n queryWithCallbacks.reject = new Proxy(queryWithCallbacks.reject as (...args: unknown[]) => unknown, {\n apply: (rejectTarget, rejectThisArg, rejectArgs: { message?: string; code?: string; name?: string }[]) => {\n try {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: rejectArgs?.[0]?.message || 'unknown_error',\n });\n\n span.setAttribute(ATTR_DB_RESPONSE_STATUS_CODE, rejectArgs?.[0]?.code || 'unknown');\n span.setAttribute(ATTR_ERROR_TYPE, rejectArgs?.[0]?.name || 'unknown');\n\n self._setOperationName(span, sanitizedSqlQuery);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in reject callback:', e);\n }\n return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n },\n });\n\n // Handle synchronous errors that might occur before promise is created\n try {\n return originalHandle.apply(this, args);\n } catch (e) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: e instanceof Error ? e.message : 'unknown_error',\n });\n span.end();\n throw e;\n }\n },\n );\n };\n\n (wrappedHandle as { __sentryWrapped?: boolean }).__sentryWrapped = true;\n query.handle = wrappedHandle;\n }\n\n /**\n * Determines whether a span should be created based on the current context.\n * If `requireParentSpan` is set to true in the configuration, a span will\n * only be created if there is a parent span available.\n */\n private _shouldCreateSpans(): boolean {\n const config = this.getConfig();\n const hasParentSpan = trace.getSpan(context.active()) !== undefined;\n return hasParentSpan || !config.requireParentSpan;\n }\n\n /**\n * Reconstructs the full SQL query from template strings with PostgreSQL placeholders.\n *\n * For sql`SELECT * FROM users WHERE id = ${123} AND name = ${'foo'}`:\n * strings = [\"SELECT * FROM users WHERE id = \", \" AND name = \", \"\"]\n * returns: \"SELECT * FROM users WHERE id = $1 AND name = $2\"\n */\n private _reconstructQuery(strings: string[] | undefined): string | undefined {\n if (!strings?.length) {\n return undefined;\n }\n if (strings.length === 1) {\n return strings[0] || undefined;\n }\n // Join template parts with PostgreSQL placeholders ($1, $2, etc.)\n return strings.reduce((acc, str, i) => (i === 0 ? str : `${acc}$${i}${str}`), '');\n }\n\n /**\n * Sanitize SQL query as per the OTEL semantic conventions\n * https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext\n *\n * PostgreSQL $n placeholders are preserved per OTEL spec - they're parameterized queries,\n * not sensitive literals. Only actual values (strings, numbers, booleans) are sanitized.\n */\n private _sanitizeSqlQuery(sqlQuery: string | undefined): string {\n if (!sqlQuery) {\n return 'Unknown SQL Query';\n }\n\n return (\n sqlQuery\n // Remove comments first (they may contain newlines and extra spaces)\n .replace(/--.*$/gm, '') // Single line comments (multiline mode)\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Multi-line comments\n .replace(/;\\s*$/, '') // Remove trailing semicolons\n // Collapse whitespace to a single space (after removing comments)\n .replace(/\\s+/g, ' ')\n .trim() // Remove extra spaces and trim\n // Sanitize hex/binary literals before string literals\n .replace(/\\bX'[0-9A-Fa-f]*'/gi, '?') // Hex string literals\n .replace(/\\bB'[01]*'/gi, '?') // Binary string literals\n // Sanitize string literals (handles escaped quotes)\n .replace(/'(?:[^']|'')*'/g, '?')\n // Sanitize hex numbers\n .replace(/\\b0x[0-9A-Fa-f]+/gi, '?')\n // Sanitize boolean literals\n .replace(/\\b(?:TRUE|FALSE)\\b/gi, '?')\n // Sanitize numeric literals (preserve $n placeholders via negative lookbehind)\n .replace(/-?\\b\\d+\\.?\\d*[eE][+-]?\\d+\\b/g, '?') // Scientific notation\n .replace(/-?\\b\\d+\\.\\d+\\b/g, '?') // Decimals\n .replace(/-?\\.\\d+\\b/g, '?') // Decimals starting with dot\n .replace(/(?<!\\$)-?\\b\\d+\\b/g, '?') // Integers (NOT $n placeholders)\n // Collapse IN clauses for cardinality (both ? and $n variants)\n .replace(/\\bIN\\b\\s*\\(\\s*\\?(?:\\s*,\\s*\\?)*\\s*\\)/gi, 'IN (?)')\n .replace(/\\bIN\\b\\s*\\(\\s*\\$\\d+(?:\\s*,\\s*\\$\\d+)*\\s*\\)/gi, 'IN ($?)')\n );\n }\n\n /**\n * Fallback patch for Query.prototype.handle to instrument queries from pre-existing sql instances.\n * This catches queries from sql instances created BEFORE Sentry was initialized (CJS only).\n *\n * Note: Queries from pre-existing instances won't have connection context (database, host, port)\n * because the sql instance wasn't created through our instrumented wrapper.\n */\n private _patchQueryPrototype(moduleExports: {\n Query: {\n prototype: {\n handle: ((...args: unknown[]) => Promise<unknown>) & {\n __sentry_original__?: (...args: unknown[]) => Promise<unknown>;\n };\n };\n };\n }): typeof moduleExports {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n const originalHandle = moduleExports.Query.prototype.handle;\n\n moduleExports.Query.prototype.handle = async function (\n this: {\n resolve: unknown;\n reject: unknown;\n strings?: string[];\n },\n ...args: unknown[]\n ): Promise<unknown> {\n // Skip if this query came from an instrumented sql instance (already handled by wrapper)\n if ((this as Record<symbol, unknown>)[QUERY_FROM_INSTRUMENTED_SQL]) {\n return originalHandle.apply(this, args);\n }\n\n // Skip if we shouldn't create spans\n if (!self._shouldCreateSpans()) {\n return originalHandle.apply(this, args);\n }\n\n const fullQuery = self._reconstructQuery(this.strings);\n const sanitizedSqlQuery = self._sanitizeSqlQuery(fullQuery);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n addOriginToSpan(span, 'auto.db.postgresjs');\n\n span.setAttributes({\n [ATTR_DB_SYSTEM_NAME]: 'postgres',\n [ATTR_DB_QUERY_TEXT]: sanitizedSqlQuery,\n });\n\n // Note: No connection context available for pre-existing instances\n // because the sql instance wasn't created through our instrumented wrapper\n\n const config = self.getConfig();\n const { requestHook } = config;\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, sanitizedSqlQuery, undefined),\n e => {\n if (e) {\n span.setAttribute('sentry.hook.error', 'requestHook failed');\n DEBUG_BUILD && debug.error(`Error in requestHook for ${INTEGRATION_NAME} integration:`, e);\n }\n },\n true,\n );\n }\n\n // Wrap resolve to end span on success\n const originalResolve = this.resolve;\n this.resolve = new Proxy(originalResolve as (...args: unknown[]) => unknown, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n try {\n self._setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e);\n }\n return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n },\n });\n\n // Wrap reject to end span on error\n const originalReject = this.reject;\n this.reject = new Proxy(originalReject as (...args: unknown[]) => unknown, {\n apply: (rejectTarget, rejectThisArg, rejectArgs: { message?: string; code?: string; name?: string }[]) => {\n try {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: rejectArgs?.[0]?.message || 'unknown_error',\n });\n span.setAttribute(ATTR_DB_RESPONSE_STATUS_CODE, rejectArgs?.[0]?.code || 'unknown');\n span.setAttribute(ATTR_ERROR_TYPE, rejectArgs?.[0]?.name || 'unknown');\n self._setOperationName(span, sanitizedSqlQuery);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in reject callback:', e);\n }\n return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n },\n });\n\n try {\n return originalHandle.apply(this, args);\n } catch (e) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: e instanceof Error ? e.message : 'unknown_error',\n });\n span.end();\n throw e;\n }\n },\n );\n };\n\n // Store original for unpatch - must be set on the NEW patched function\n moduleExports.Query.prototype.handle.__sentry_original__ = originalHandle;\n\n return moduleExports;\n }\n\n /**\n * Restores the original Query.prototype.handle method.\n */\n private _unpatchQueryPrototype(moduleExports: {\n Query: {\n prototype: {\n handle: ((...args: unknown[]) => Promise<unknown>) & {\n __sentry_original__?: (...args: unknown[]) => Promise<unknown>;\n };\n };\n };\n }): typeof moduleExports {\n if (moduleExports.Query.prototype.handle.__sentry_original__) {\n moduleExports.Query.prototype.handle = moduleExports.Query.prototype.handle.__sentry_original__;\n }\n return moduleExports;\n }\n}\n\nconst _postgresJsIntegration = ((options?: PostgresJsInstrumentationConfig) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPostgresJs(options);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n *\n * For more information, see the [`postgresIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/postgres/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.postgresJsIntegration()],\n * });\n * ```\n */\n\nexport const postgresJsIntegration = defineIntegration(_postgresJsIntegration);\n"],"names":["generateInstrumentOnce","InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","exports","DEBUG_BUILD","debug","InstrumentationNodeModuleFile","replaceExports","ATTR_DB_NAMESPACE","ATTR_SERVER_ADDRESS","ATTR_SERVER_PORT","ATTR_DB_OPERATION_NAME","startSpanManual","addOriginToSpan","ATTR_DB_SYSTEM_NAME","ATTR_DB_QUERY_TEXT","safeExecuteInTheMiddle","SPAN_STATUS_ERROR","ATTR_DB_RESPONSE_STATUS_CODE","ATTR_ERROR_TYPE","trace","context","defineIntegration"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"postgresjs.js","sources":["../../../../src/integrations/tracing/postgresjs.ts"],"sourcesContent":["// Instrumentation for https://github.com/porsager/postgres\n\nimport { context, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport {\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_RESPONSE_STATUS_CODE,\n ATTR_DB_SYSTEM_NAME,\n ATTR_ERROR_TYPE,\n} from '@opentelemetry/semantic-conventions';\nimport type { IntegrationFn, Span } from '@sentry/core';\nimport {\n debug,\n defineIntegration,\n instrumentPostgresJsSql,\n replaceExports,\n SDK_VERSION,\n SPAN_STATUS_ERROR,\n startSpanManual,\n} from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\nimport { DEBUG_BUILD } from '../../debug-build';\n\nconst INTEGRATION_NAME = 'PostgresJs';\nconst SUPPORTED_VERSIONS = ['>=3.0.0 <4'];\nconst SQL_OPERATION_REGEX = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i;\n\ntype PostgresConnectionContext = {\n ATTR_DB_NAMESPACE?: string; // Database name\n ATTR_SERVER_ADDRESS?: string; // Hostname or IP address of the database server\n ATTR_SERVER_PORT?: string; // Port number of the database server\n};\n\n// Marker to track if a query was created from an instrumented sql instance\n// This prevents double-spanning when both wrapper and prototype patches are active\nconst QUERY_FROM_INSTRUMENTED_SQL = Symbol.for('sentry.query.from.instrumented.sql');\n\ntype PostgresJsInstrumentationConfig = InstrumentationConfig & {\n /**\n * Whether to require a parent span for the instrumentation.\n * If set to true, the instrumentation will only create spans if there is a parent span\n * available in the current scope.\n * @default true\n */\n requireParentSpan?: boolean;\n /**\n * Hook to modify the span before it is started.\n * This can be used to set additional attributes or modify the span in any way.\n */\n requestHook?: (span: Span, sanitizedSqlQuery: string, postgresConnectionContext?: PostgresConnectionContext) => void;\n};\n\nexport const instrumentPostgresJs = generateInstrumentOnce(\n INTEGRATION_NAME,\n (options?: PostgresJsInstrumentationConfig) =>\n new PostgresJsInstrumentation({\n requireParentSpan: options?.requireParentSpan ?? true,\n requestHook: options?.requestHook,\n }),\n);\n\n/**\n * Instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n * This instrumentation captures postgresjs queries and their attributes.\n *\n * Uses internal Sentry patching patterns to support both CommonJS and ESM environments.\n */\nexport class PostgresJsInstrumentation extends InstrumentationBase<PostgresJsInstrumentationConfig> {\n public constructor(config: PostgresJsInstrumentationConfig) {\n super('sentry-postgres-js', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by patching the postgres module.\n * Uses two complementary approaches:\n * 1. Main function wrapper: instruments sql instances created AFTER instrumentation is set up (CJS + ESM)\n * 2. Query.prototype patch: fallback for sql instances created BEFORE instrumentation (CJS only)\n */\n public init(): InstrumentationNodeModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n 'postgres',\n SUPPORTED_VERSIONS,\n exports => {\n try {\n return this._patchPostgres(exports);\n } catch (e) {\n DEBUG_BUILD && debug.error('Failed to patch postgres module:', e);\n return exports;\n }\n },\n exports => exports,\n );\n\n // Add fallback Query.prototype patching for pre-existing sql instances (CJS only)\n // This catches queries from sql instances created before Sentry was initialized\n ['src', 'cf/src', 'cjs/src'].forEach(path => {\n module.files.push(\n new InstrumentationNodeModuleFile(\n `postgres/${path}/query.js`,\n SUPPORTED_VERSIONS,\n this._patchQueryPrototype.bind(this),\n this._unpatchQueryPrototype.bind(this),\n ),\n );\n });\n\n return module;\n }\n\n /**\n * Patches the postgres module by wrapping the main export function.\n * This intercepts the creation of sql instances and instruments them.\n */\n private _patchPostgres(exports: { [key: string]: unknown }): { [key: string]: unknown } {\n // In CJS: exports is the function itself\n // In ESM: exports.default is the function\n const isFunction = typeof exports === 'function';\n const Original = isFunction ? exports : exports.default;\n\n if (typeof Original !== 'function') {\n DEBUG_BUILD && debug.warn('postgres module does not export a function. Skipping instrumentation.');\n return exports;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n const WrappedPostgres = function (this: unknown, ...args: unknown[]): unknown {\n const sql = Reflect.construct(Original as (...args: unknown[]) => unknown, args);\n\n // Validate that construction succeeded and returned a valid function object\n if (!sql || typeof sql !== 'function') {\n DEBUG_BUILD && debug.warn('postgres() did not return a valid instance');\n return sql;\n }\n\n // Delegate to the portable instrumentation from @sentry/core\n const config = self.getConfig();\n return instrumentPostgresJsSql(sql, {\n requireParentSpan: config.requireParentSpan,\n requestHook: config.requestHook,\n });\n };\n\n Object.setPrototypeOf(WrappedPostgres, Original);\n Object.setPrototypeOf(WrappedPostgres.prototype, (Original as { prototype: object }).prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedPostgres, key, descriptor);\n }\n }\n }\n\n // For CJS: the exports object IS the function, so return the wrapped function\n // For ESM: replace the default export\n if (isFunction) {\n return WrappedPostgres as unknown as { [key: string]: unknown };\n } else {\n replaceExports(exports, 'default', WrappedPostgres);\n return exports;\n }\n }\n\n /**\n * Determines whether a span should be created based on the current context.\n * If `requireParentSpan` is set to true in the configuration, a span will\n * only be created if there is a parent span available.\n */\n private _shouldCreateSpans(): boolean {\n const config = this.getConfig();\n const hasParentSpan = trace.getSpan(context.active()) !== undefined;\n return hasParentSpan || !config.requireParentSpan;\n }\n\n /**\n * Extracts DB operation name from SQL query and sets it on the span.\n */\n private _setOperationName(span: Span, sanitizedQuery: string | undefined, command?: string): void {\n if (command) {\n span.setAttribute(ATTR_DB_OPERATION_NAME, command);\n return;\n }\n // Fallback: extract operation from the SQL query\n const operationMatch = sanitizedQuery?.match(SQL_OPERATION_REGEX);\n if (operationMatch?.[1]) {\n span.setAttribute(ATTR_DB_OPERATION_NAME, operationMatch[1].toUpperCase());\n }\n }\n\n /**\n * Reconstructs the full SQL query from template strings with PostgreSQL placeholders.\n *\n * For sql`SELECT * FROM users WHERE id = ${123} AND name = ${'foo'}`:\n * strings = [\"SELECT * FROM users WHERE id = \", \" AND name = \", \"\"]\n * returns: \"SELECT * FROM users WHERE id = $1 AND name = $2\"\n */\n private _reconstructQuery(strings: string[] | undefined): string | undefined {\n if (!strings?.length) {\n return undefined;\n }\n if (strings.length === 1) {\n return strings[0] || undefined;\n }\n // Join template parts with PostgreSQL placeholders ($1, $2, etc.)\n return strings.reduce((acc, str, i) => (i === 0 ? str : `${acc}$${i}${str}`), '');\n }\n\n /**\n * Sanitize SQL query as per the OTEL semantic conventions\n * https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext\n *\n * PostgreSQL $n placeholders are preserved per OTEL spec - they're parameterized queries,\n * not sensitive literals. Only actual values (strings, numbers, booleans) are sanitized.\n */\n private _sanitizeSqlQuery(sqlQuery: string | undefined): string {\n if (!sqlQuery) {\n return 'Unknown SQL Query';\n }\n\n return (\n sqlQuery\n // Remove comments first (they may contain newlines and extra spaces)\n .replace(/--.*$/gm, '') // Single line comments (multiline mode)\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Multi-line comments\n .replace(/;\\s*$/, '') // Remove trailing semicolons\n // Collapse whitespace to a single space (after removing comments)\n .replace(/\\s+/g, ' ')\n .trim() // Remove extra spaces and trim\n // Sanitize hex/binary literals before string literals\n .replace(/\\bX'[0-9A-Fa-f]*'/gi, '?') // Hex string literals\n .replace(/\\bB'[01]*'/gi, '?') // Binary string literals\n // Sanitize string literals (handles escaped quotes)\n .replace(/'(?:[^']|'')*'/g, '?')\n // Sanitize hex numbers\n .replace(/\\b0x[0-9A-Fa-f]+/gi, '?')\n // Sanitize boolean literals\n .replace(/\\b(?:TRUE|FALSE)\\b/gi, '?')\n // Sanitize numeric literals (preserve $n placeholders via negative lookbehind)\n .replace(/-?\\b\\d+\\.?\\d*[eE][+-]?\\d+\\b/g, '?') // Scientific notation\n .replace(/-?\\b\\d+\\.\\d+\\b/g, '?') // Decimals\n .replace(/-?\\.\\d+\\b/g, '?') // Decimals starting with dot\n .replace(/(?<!\\$)-?\\b\\d+\\b/g, '?') // Integers (NOT $n placeholders)\n // Collapse IN clauses for cardinality (both ? and $n variants)\n .replace(/\\bIN\\b\\s*\\(\\s*\\?(?:\\s*,\\s*\\?)*\\s*\\)/gi, 'IN (?)')\n .replace(/\\bIN\\b\\s*\\(\\s*\\$\\d+(?:\\s*,\\s*\\$\\d+)*\\s*\\)/gi, 'IN ($?)')\n );\n }\n\n /**\n * Fallback patch for Query.prototype.handle to instrument queries from pre-existing sql instances.\n * This catches queries from sql instances created BEFORE Sentry was initialized (CJS only).\n *\n * Note: Queries from pre-existing instances won't have connection context (database, host, port)\n * because the sql instance wasn't created through our instrumented wrapper.\n */\n private _patchQueryPrototype(moduleExports: {\n Query: {\n prototype: {\n handle: ((...args: unknown[]) => Promise<unknown>) & {\n __sentry_original__?: (...args: unknown[]) => Promise<unknown>;\n };\n };\n };\n }): typeof moduleExports {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n const originalHandle = moduleExports.Query.prototype.handle;\n\n moduleExports.Query.prototype.handle = async function (\n this: {\n resolve: unknown;\n reject: unknown;\n strings?: string[];\n },\n ...args: unknown[]\n ): Promise<unknown> {\n // Skip if this query came from an instrumented sql instance (already handled by wrapper)\n if ((this as Record<symbol, unknown>)[QUERY_FROM_INSTRUMENTED_SQL]) {\n return originalHandle.apply(this, args);\n }\n\n // Skip if we shouldn't create spans\n if (!self._shouldCreateSpans()) {\n return originalHandle.apply(this, args);\n }\n\n const fullQuery = self._reconstructQuery(this.strings);\n const sanitizedSqlQuery = self._sanitizeSqlQuery(fullQuery);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n addOriginToSpan(span, 'auto.db.postgresjs');\n\n span.setAttributes({\n [ATTR_DB_SYSTEM_NAME]: 'postgres',\n [ATTR_DB_QUERY_TEXT]: sanitizedSqlQuery,\n });\n\n // Note: No connection context available for pre-existing instances\n // because the sql instance wasn't created through our instrumented wrapper\n\n const config = self.getConfig();\n const { requestHook } = config;\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, sanitizedSqlQuery, undefined),\n e => {\n if (e) {\n span.setAttribute('sentry.hook.error', 'requestHook failed');\n DEBUG_BUILD && debug.error(`Error in requestHook for ${INTEGRATION_NAME} integration:`, e);\n }\n },\n true,\n );\n }\n\n // Wrap resolve to end span on success\n const originalResolve = this.resolve;\n this.resolve = new Proxy(originalResolve as (...args: unknown[]) => unknown, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n try {\n self._setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e);\n }\n return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n },\n });\n\n // Wrap reject to end span on error\n const originalReject = this.reject;\n this.reject = new Proxy(originalReject as (...args: unknown[]) => unknown, {\n apply: (rejectTarget, rejectThisArg, rejectArgs: { message?: string; code?: string; name?: string }[]) => {\n try {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: rejectArgs?.[0]?.message || 'unknown_error',\n });\n span.setAttribute(ATTR_DB_RESPONSE_STATUS_CODE, rejectArgs?.[0]?.code || 'unknown');\n span.setAttribute(ATTR_ERROR_TYPE, rejectArgs?.[0]?.name || 'unknown');\n self._setOperationName(span, sanitizedSqlQuery);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in reject callback:', e);\n }\n return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n },\n });\n\n try {\n return originalHandle.apply(this, args);\n } catch (e) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: e instanceof Error ? e.message : 'unknown_error',\n });\n span.end();\n throw e;\n }\n },\n );\n };\n\n // Store original for unpatch - must be set on the NEW patched function\n moduleExports.Query.prototype.handle.__sentry_original__ = originalHandle;\n\n return moduleExports;\n }\n\n /**\n * Restores the original Query.prototype.handle method.\n */\n private _unpatchQueryPrototype(moduleExports: {\n Query: {\n prototype: {\n handle: ((...args: unknown[]) => Promise<unknown>) & {\n __sentry_original__?: (...args: unknown[]) => Promise<unknown>;\n };\n };\n };\n }): typeof moduleExports {\n if (moduleExports.Query.prototype.handle.__sentry_original__) {\n moduleExports.Query.prototype.handle = moduleExports.Query.prototype.handle.__sentry_original__;\n }\n return moduleExports;\n }\n}\n\nconst _postgresJsIntegration = ((options?: PostgresJsInstrumentationConfig) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPostgresJs(options);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n *\n * For more information, see the [`postgresIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/postgres/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.postgresJsIntegration()],\n * });\n * ```\n */\n\nexport const postgresJsIntegration = defineIntegration(_postgresJsIntegration);\n"],"names":["generateInstrumentOnce","InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","exports","DEBUG_BUILD","debug","InstrumentationNodeModuleFile","instrumentPostgresJsSql","replaceExports","trace","context","ATTR_DB_OPERATION_NAME","startSpanManual","addOriginToSpan","ATTR_DB_SYSTEM_NAME","ATTR_DB_QUERY_TEXT","safeExecuteInTheMiddle","SPAN_STATUS_ERROR","ATTR_DB_RESPONSE_STATUS_CODE","ATTR_ERROR_TYPE","defineIntegration"],"mappings":"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"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { trace, context } from '@opentelemetry/api';
|
|
2
2
|
import { InstrumentationBase, InstrumentationNodeModuleDefinition, InstrumentationNodeModuleFile, safeExecuteInTheMiddle } from '@opentelemetry/instrumentation';
|
|
3
|
-
import {
|
|
4
|
-
import { SDK_VERSION, debug, replaceExports, startSpanManual, SPAN_STATUS_ERROR, defineIntegration } from '@sentry/core';
|
|
3
|
+
import { ATTR_DB_OPERATION_NAME, ATTR_DB_QUERY_TEXT, ATTR_DB_SYSTEM_NAME, ATTR_DB_RESPONSE_STATUS_CODE, ATTR_ERROR_TYPE } from '@opentelemetry/semantic-conventions';
|
|
4
|
+
import { SDK_VERSION, debug, replaceExports, startSpanManual, SPAN_STATUS_ERROR, defineIntegration, instrumentPostgresJsSql } from '@sentry/core';
|
|
5
5
|
import { generateInstrumentOnce, addOriginToSpan } from '@sentry/node-core';
|
|
6
6
|
import { DEBUG_BUILD } from '../../debug-build.js';
|
|
7
7
|
|
|
8
|
-
/* eslint-disable max-lines */
|
|
9
8
|
// Instrumentation for https://github.com/porsager/postgres
|
|
10
9
|
|
|
11
10
|
|
|
@@ -13,8 +12,6 @@ const INTEGRATION_NAME = 'PostgresJs';
|
|
|
13
12
|
const SUPPORTED_VERSIONS = ['>=3.0.0 <4'];
|
|
14
13
|
const SQL_OPERATION_REGEX = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i;
|
|
15
14
|
|
|
16
|
-
const CONNECTION_CONTEXT_SYMBOL = Symbol('sentryPostgresConnectionContext');
|
|
17
|
-
const INSTRUMENTED_MARKER = Symbol.for('sentry.instrumented.postgresjs');
|
|
18
15
|
// Marker to track if a query was created from an instrumented sql instance
|
|
19
16
|
// This prevents double-spanning when both wrapper and prototype patches are active
|
|
20
17
|
const QUERY_FROM_INSTRUMENTED_SQL = Symbol.for('sentry.query.from.instrumented.sql');
|
|
@@ -103,7 +100,12 @@ class PostgresJsInstrumentation extends InstrumentationBase {
|
|
|
103
100
|
return sql;
|
|
104
101
|
}
|
|
105
102
|
|
|
106
|
-
|
|
103
|
+
// Delegate to the portable instrumentation from @sentry/core
|
|
104
|
+
const config = self.getConfig();
|
|
105
|
+
return instrumentPostgresJsSql(sql, {
|
|
106
|
+
requireParentSpan: config.requireParentSpan,
|
|
107
|
+
requestHook: config.requestHook,
|
|
108
|
+
});
|
|
107
109
|
};
|
|
108
110
|
|
|
109
111
|
Object.setPrototypeOf(WrappedPostgres, Original);
|
|
@@ -129,94 +131,14 @@ class PostgresJsInstrumentation extends InstrumentationBase {
|
|
|
129
131
|
}
|
|
130
132
|
|
|
131
133
|
/**
|
|
132
|
-
*
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
original,
|
|
136
|
-
target,
|
|
137
|
-
proxiedSql,
|
|
138
|
-
) {
|
|
139
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
140
|
-
const self = this;
|
|
141
|
-
return function ( ...args) {
|
|
142
|
-
const query = Reflect.apply(original, target, args);
|
|
143
|
-
|
|
144
|
-
if (query && typeof query === 'object' && 'handle' in query) {
|
|
145
|
-
self._wrapSingleQueryHandle(query , proxiedSql);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return query;
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Wraps callback-based methods (begin, reserve) to recursively instrument Sql instances.
|
|
154
|
-
* Note: These methods can also be used as tagged templates, which we pass through unchanged.
|
|
155
|
-
*
|
|
156
|
-
* Savepoint is not wrapped to avoid complex nested transaction instrumentation issues.
|
|
157
|
-
* Queries within savepoint callbacks are still instrumented through the parent transaction's Sql instance.
|
|
158
|
-
*/
|
|
159
|
-
_wrapCallbackMethod(
|
|
160
|
-
original,
|
|
161
|
-
target,
|
|
162
|
-
parentSqlInstance,
|
|
163
|
-
) {
|
|
164
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
165
|
-
const self = this;
|
|
166
|
-
return function ( ...args) {
|
|
167
|
-
// Extract parent context to propagate to child instances
|
|
168
|
-
const parentContext = (parentSqlInstance )[CONNECTION_CONTEXT_SYMBOL]
|
|
169
|
-
|
|
170
|
-
;
|
|
171
|
-
|
|
172
|
-
// Check if this is a callback-based call by verifying the last argument is a function
|
|
173
|
-
const isCallbackBased = typeof args[args.length - 1] === 'function';
|
|
174
|
-
|
|
175
|
-
if (!isCallbackBased) {
|
|
176
|
-
// Not a callback-based call - could be tagged template or promise-based
|
|
177
|
-
const result = Reflect.apply(original, target, args);
|
|
178
|
-
// If result is a Promise (e.g., reserve() without callback), instrument the resolved Sql instance
|
|
179
|
-
if (result && typeof (result ).then === 'function') {
|
|
180
|
-
return (result ).then((sqlInstance) => {
|
|
181
|
-
return self._instrumentSqlInstance(sqlInstance, parentContext);
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
return result;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Callback-based call: wrap the callback to instrument the Sql instance
|
|
188
|
-
const callback = (args.length === 1 ? args[0] : args[1]) ;
|
|
189
|
-
const wrappedCallback = function (sqlInstance) {
|
|
190
|
-
const instrumentedSql = self._instrumentSqlInstance(sqlInstance, parentContext);
|
|
191
|
-
return callback(instrumentedSql);
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
const newArgs = args.length === 1 ? [wrappedCallback] : [args[0], wrappedCallback];
|
|
195
|
-
return Reflect.apply(original, target, newArgs);
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Sets connection context attributes on a span.
|
|
134
|
+
* Determines whether a span should be created based on the current context.
|
|
135
|
+
* If `requireParentSpan` is set to true in the configuration, a span will
|
|
136
|
+
* only be created if there is a parent span available.
|
|
201
137
|
*/
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
if (connectionContext.ATTR_DB_NAMESPACE) {
|
|
207
|
-
span.setAttribute(ATTR_DB_NAMESPACE, connectionContext.ATTR_DB_NAMESPACE);
|
|
208
|
-
}
|
|
209
|
-
if (connectionContext.ATTR_SERVER_ADDRESS) {
|
|
210
|
-
span.setAttribute(ATTR_SERVER_ADDRESS, connectionContext.ATTR_SERVER_ADDRESS);
|
|
211
|
-
}
|
|
212
|
-
if (connectionContext.ATTR_SERVER_PORT !== undefined) {
|
|
213
|
-
// Port is stored as string in PostgresConnectionContext for requestHook backwards compatibility,
|
|
214
|
-
// but OTEL semantic conventions expect port as a number for span attributes
|
|
215
|
-
const portNumber = parseInt(connectionContext.ATTR_SERVER_PORT, 10);
|
|
216
|
-
if (!isNaN(portNumber)) {
|
|
217
|
-
span.setAttribute(ATTR_SERVER_PORT, portNumber);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
138
|
+
_shouldCreateSpans() {
|
|
139
|
+
const config = this.getConfig();
|
|
140
|
+
const hasParentSpan = trace.getSpan(context.active()) !== undefined;
|
|
141
|
+
return hasParentSpan || !config.requireParentSpan;
|
|
220
142
|
}
|
|
221
143
|
|
|
222
144
|
/**
|
|
@@ -234,224 +156,6 @@ class PostgresJsInstrumentation extends InstrumentationBase {
|
|
|
234
156
|
}
|
|
235
157
|
}
|
|
236
158
|
|
|
237
|
-
/**
|
|
238
|
-
* Extracts and stores connection context from sql.options.
|
|
239
|
-
*/
|
|
240
|
-
_attachConnectionContext(sql, proxiedSql) {
|
|
241
|
-
const sqlInstance = sql ;
|
|
242
|
-
if (!sqlInstance.options || typeof sqlInstance.options !== 'object') {
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const opts = sqlInstance.options;
|
|
247
|
-
// postgres.js stores parsed options with host and port as arrays
|
|
248
|
-
// The library defaults to 'localhost' and 5432 if not specified, but we're defensive here
|
|
249
|
-
const host = opts.host?.[0] || 'localhost';
|
|
250
|
-
const port = opts.port?.[0] || 5432;
|
|
251
|
-
|
|
252
|
-
const connectionContext = {
|
|
253
|
-
ATTR_DB_NAMESPACE: typeof opts.database === 'string' && opts.database !== '' ? opts.database : undefined,
|
|
254
|
-
ATTR_SERVER_ADDRESS: host,
|
|
255
|
-
ATTR_SERVER_PORT: String(port),
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
proxiedSql[CONNECTION_CONTEXT_SYMBOL] = connectionContext;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Instruments a sql instance by wrapping its query execution methods.
|
|
263
|
-
*/
|
|
264
|
-
_instrumentSqlInstance(sql, parentConnectionContext) {
|
|
265
|
-
// Check if already instrumented to prevent double-wrapping
|
|
266
|
-
// Using Symbol.for() ensures the marker survives proxying
|
|
267
|
-
if ((sql )[INSTRUMENTED_MARKER]) {
|
|
268
|
-
return sql;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
272
|
-
const self = this;
|
|
273
|
-
|
|
274
|
-
// Wrap the sql function to intercept query creation
|
|
275
|
-
const proxiedSql = new Proxy(sql , {
|
|
276
|
-
apply(target, thisArg, argumentsList) {
|
|
277
|
-
const query = Reflect.apply(target, thisArg, argumentsList);
|
|
278
|
-
|
|
279
|
-
if (query && typeof query === 'object' && 'handle' in query) {
|
|
280
|
-
self._wrapSingleQueryHandle(query , proxiedSql);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return query;
|
|
284
|
-
},
|
|
285
|
-
get(target, prop) {
|
|
286
|
-
const original = (target )[prop];
|
|
287
|
-
|
|
288
|
-
if (typeof prop !== 'string' || typeof original !== 'function') {
|
|
289
|
-
return original;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// Wrap methods that return PendingQuery objects (unsafe, file)
|
|
293
|
-
if (prop === 'unsafe' || prop === 'file') {
|
|
294
|
-
return self._wrapQueryMethod(original , target, proxiedSql);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Wrap begin and reserve (not savepoint to avoid duplicate spans)
|
|
298
|
-
if (prop === 'begin' || prop === 'reserve') {
|
|
299
|
-
return self._wrapCallbackMethod(original , target, proxiedSql);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
return original;
|
|
303
|
-
},
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
// Use provided parent context if available, otherwise extract from sql.options
|
|
307
|
-
if (parentConnectionContext) {
|
|
308
|
-
(proxiedSql )[CONNECTION_CONTEXT_SYMBOL] = parentConnectionContext;
|
|
309
|
-
} else {
|
|
310
|
-
this._attachConnectionContext(sql, proxiedSql );
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Mark both the original and proxy as instrumented to prevent double-wrapping
|
|
314
|
-
// The proxy might be passed to other methods, or the original
|
|
315
|
-
// might be accessed directly, so we need to mark both
|
|
316
|
-
(sql )[INSTRUMENTED_MARKER] = true;
|
|
317
|
-
(proxiedSql )[INSTRUMENTED_MARKER] = true;
|
|
318
|
-
|
|
319
|
-
return proxiedSql;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Wraps a single query's handle method to create spans.
|
|
324
|
-
*/
|
|
325
|
-
_wrapSingleQueryHandle(
|
|
326
|
-
query,
|
|
327
|
-
sqlInstance,
|
|
328
|
-
) {
|
|
329
|
-
// Prevent double wrapping - check if the handle itself is already wrapped
|
|
330
|
-
if ((query.handle )?.__sentryWrapped) {
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// Mark this query as coming from an instrumented sql instance
|
|
335
|
-
// This prevents the Query.prototype fallback patch from double-spanning
|
|
336
|
-
(query )[QUERY_FROM_INSTRUMENTED_SQL] = true;
|
|
337
|
-
|
|
338
|
-
const originalHandle = query.handle ;
|
|
339
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
340
|
-
const self = this;
|
|
341
|
-
|
|
342
|
-
// IMPORTANT: We must replace the handle function directly, not use a Proxy,
|
|
343
|
-
// because Query.then() internally calls this.handle(), which would bypass a Proxy wrapper.
|
|
344
|
-
const wrappedHandle = async function ( ...args) {
|
|
345
|
-
if (!self._shouldCreateSpans()) {
|
|
346
|
-
return originalHandle.apply(this, args);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
const fullQuery = self._reconstructQuery(query.strings);
|
|
350
|
-
const sanitizedSqlQuery = self._sanitizeSqlQuery(fullQuery);
|
|
351
|
-
|
|
352
|
-
return startSpanManual(
|
|
353
|
-
{
|
|
354
|
-
name: sanitizedSqlQuery || 'postgresjs.query',
|
|
355
|
-
op: 'db',
|
|
356
|
-
},
|
|
357
|
-
(span) => {
|
|
358
|
-
addOriginToSpan(span, 'auto.db.postgresjs');
|
|
359
|
-
|
|
360
|
-
span.setAttributes({
|
|
361
|
-
[ATTR_DB_SYSTEM_NAME]: 'postgres',
|
|
362
|
-
[ATTR_DB_QUERY_TEXT]: sanitizedSqlQuery,
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
const connectionContext = sqlInstance
|
|
366
|
-
? ((sqlInstance )[CONNECTION_CONTEXT_SYMBOL]
|
|
367
|
-
|
|
368
|
-
)
|
|
369
|
-
: undefined;
|
|
370
|
-
|
|
371
|
-
self._setConnectionAttributes(span, connectionContext);
|
|
372
|
-
|
|
373
|
-
const config = self.getConfig();
|
|
374
|
-
const { requestHook } = config;
|
|
375
|
-
if (requestHook) {
|
|
376
|
-
safeExecuteInTheMiddle(
|
|
377
|
-
() => requestHook(span, sanitizedSqlQuery, connectionContext),
|
|
378
|
-
e => {
|
|
379
|
-
if (e) {
|
|
380
|
-
span.setAttribute('sentry.hook.error', 'requestHook failed');
|
|
381
|
-
DEBUG_BUILD && debug.error(`Error in requestHook for ${INTEGRATION_NAME} integration:`, e);
|
|
382
|
-
}
|
|
383
|
-
},
|
|
384
|
-
true,
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
const queryWithCallbacks = this
|
|
389
|
-
|
|
390
|
-
;
|
|
391
|
-
|
|
392
|
-
queryWithCallbacks.resolve = new Proxy(queryWithCallbacks.resolve , {
|
|
393
|
-
apply: (resolveTarget, resolveThisArg, resolveArgs) => {
|
|
394
|
-
try {
|
|
395
|
-
self._setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);
|
|
396
|
-
span.end();
|
|
397
|
-
} catch (e) {
|
|
398
|
-
DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);
|
|
402
|
-
},
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
queryWithCallbacks.reject = new Proxy(queryWithCallbacks.reject , {
|
|
406
|
-
apply: (rejectTarget, rejectThisArg, rejectArgs) => {
|
|
407
|
-
try {
|
|
408
|
-
span.setStatus({
|
|
409
|
-
code: SPAN_STATUS_ERROR,
|
|
410
|
-
message: rejectArgs?.[0]?.message || 'unknown_error',
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
span.setAttribute(ATTR_DB_RESPONSE_STATUS_CODE, rejectArgs?.[0]?.code || 'unknown');
|
|
414
|
-
span.setAttribute(ATTR_ERROR_TYPE, rejectArgs?.[0]?.name || 'unknown');
|
|
415
|
-
|
|
416
|
-
self._setOperationName(span, sanitizedSqlQuery);
|
|
417
|
-
span.end();
|
|
418
|
-
} catch (e) {
|
|
419
|
-
DEBUG_BUILD && debug.error('Error ending span in reject callback:', e);
|
|
420
|
-
}
|
|
421
|
-
return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);
|
|
422
|
-
},
|
|
423
|
-
});
|
|
424
|
-
|
|
425
|
-
// Handle synchronous errors that might occur before promise is created
|
|
426
|
-
try {
|
|
427
|
-
return originalHandle.apply(this, args);
|
|
428
|
-
} catch (e) {
|
|
429
|
-
span.setStatus({
|
|
430
|
-
code: SPAN_STATUS_ERROR,
|
|
431
|
-
message: e instanceof Error ? e.message : 'unknown_error',
|
|
432
|
-
});
|
|
433
|
-
span.end();
|
|
434
|
-
throw e;
|
|
435
|
-
}
|
|
436
|
-
},
|
|
437
|
-
);
|
|
438
|
-
};
|
|
439
|
-
|
|
440
|
-
(wrappedHandle ).__sentryWrapped = true;
|
|
441
|
-
query.handle = wrappedHandle;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
/**
|
|
445
|
-
* Determines whether a span should be created based on the current context.
|
|
446
|
-
* If `requireParentSpan` is set to true in the configuration, a span will
|
|
447
|
-
* only be created if there is a parent span available.
|
|
448
|
-
*/
|
|
449
|
-
_shouldCreateSpans() {
|
|
450
|
-
const config = this.getConfig();
|
|
451
|
-
const hasParentSpan = trace.getSpan(context.active()) !== undefined;
|
|
452
|
-
return hasParentSpan || !config.requireParentSpan;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
159
|
/**
|
|
456
160
|
* Reconstructs the full SQL query from template strings with PostgreSQL placeholders.
|
|
457
161
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgresjs.js","sources":["../../../../src/integrations/tracing/postgresjs.ts"],"sourcesContent":["/* eslint-disable max-lines */\n// Instrumentation for https://github.com/porsager/postgres\n\nimport { context, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport {\n ATTR_DB_NAMESPACE,\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_RESPONSE_STATUS_CODE,\n ATTR_DB_SYSTEM_NAME,\n ATTR_ERROR_TYPE,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n} from '@opentelemetry/semantic-conventions';\nimport type { IntegrationFn, Span } from '@sentry/core';\nimport {\n debug,\n defineIntegration,\n replaceExports,\n SDK_VERSION,\n SPAN_STATUS_ERROR,\n startSpanManual,\n} from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\nimport { DEBUG_BUILD } from '../../debug-build';\n\nconst INTEGRATION_NAME = 'PostgresJs';\nconst SUPPORTED_VERSIONS = ['>=3.0.0 <4'];\nconst SQL_OPERATION_REGEX = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i;\n\ntype PostgresConnectionContext = {\n ATTR_DB_NAMESPACE?: string; // Database name\n ATTR_SERVER_ADDRESS?: string; // Hostname or IP address of the database server\n ATTR_SERVER_PORT?: string; // Port number of the database server\n};\n\nconst CONNECTION_CONTEXT_SYMBOL = Symbol('sentryPostgresConnectionContext');\nconst INSTRUMENTED_MARKER = Symbol.for('sentry.instrumented.postgresjs');\n// Marker to track if a query was created from an instrumented sql instance\n// This prevents double-spanning when both wrapper and prototype patches are active\nconst QUERY_FROM_INSTRUMENTED_SQL = Symbol.for('sentry.query.from.instrumented.sql');\n\ntype PostgresJsInstrumentationConfig = InstrumentationConfig & {\n /**\n * Whether to require a parent span for the instrumentation.\n * If set to true, the instrumentation will only create spans if there is a parent span\n * available in the current scope.\n * @default true\n */\n requireParentSpan?: boolean;\n /**\n * Hook to modify the span before it is started.\n * This can be used to set additional attributes or modify the span in any way.\n */\n requestHook?: (span: Span, sanitizedSqlQuery: string, postgresConnectionContext?: PostgresConnectionContext) => void;\n};\n\nexport const instrumentPostgresJs = generateInstrumentOnce(\n INTEGRATION_NAME,\n (options?: PostgresJsInstrumentationConfig) =>\n new PostgresJsInstrumentation({\n requireParentSpan: options?.requireParentSpan ?? true,\n requestHook: options?.requestHook,\n }),\n);\n\n/**\n * Instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n * This instrumentation captures postgresjs queries and their attributes.\n *\n * Uses internal Sentry patching patterns to support both CommonJS and ESM environments.\n */\nexport class PostgresJsInstrumentation extends InstrumentationBase<PostgresJsInstrumentationConfig> {\n public constructor(config: PostgresJsInstrumentationConfig) {\n super('sentry-postgres-js', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by patching the postgres module.\n * Uses two complementary approaches:\n * 1. Main function wrapper: instruments sql instances created AFTER instrumentation is set up (CJS + ESM)\n * 2. Query.prototype patch: fallback for sql instances created BEFORE instrumentation (CJS only)\n */\n public init(): InstrumentationNodeModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n 'postgres',\n SUPPORTED_VERSIONS,\n exports => {\n try {\n return this._patchPostgres(exports);\n } catch (e) {\n DEBUG_BUILD && debug.error('Failed to patch postgres module:', e);\n return exports;\n }\n },\n exports => exports,\n );\n\n // Add fallback Query.prototype patching for pre-existing sql instances (CJS only)\n // This catches queries from sql instances created before Sentry was initialized\n ['src', 'cf/src', 'cjs/src'].forEach(path => {\n module.files.push(\n new InstrumentationNodeModuleFile(\n `postgres/${path}/query.js`,\n SUPPORTED_VERSIONS,\n this._patchQueryPrototype.bind(this),\n this._unpatchQueryPrototype.bind(this),\n ),\n );\n });\n\n return module;\n }\n\n /**\n * Patches the postgres module by wrapping the main export function.\n * This intercepts the creation of sql instances and instruments them.\n */\n private _patchPostgres(exports: { [key: string]: unknown }): { [key: string]: unknown } {\n // In CJS: exports is the function itself\n // In ESM: exports.default is the function\n const isFunction = typeof exports === 'function';\n const Original = isFunction ? exports : exports.default;\n\n if (typeof Original !== 'function') {\n DEBUG_BUILD && debug.warn('postgres module does not export a function. Skipping instrumentation.');\n return exports;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n const WrappedPostgres = function (this: unknown, ...args: unknown[]): unknown {\n const sql = Reflect.construct(Original as (...args: unknown[]) => unknown, args);\n\n // Validate that construction succeeded and returned a valid function object\n if (!sql || typeof sql !== 'function') {\n DEBUG_BUILD && debug.warn('postgres() did not return a valid instance');\n return sql;\n }\n\n return self._instrumentSqlInstance(sql);\n };\n\n Object.setPrototypeOf(WrappedPostgres, Original);\n Object.setPrototypeOf(WrappedPostgres.prototype, (Original as { prototype: object }).prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedPostgres, key, descriptor);\n }\n }\n }\n\n // For CJS: the exports object IS the function, so return the wrapped function\n // For ESM: replace the default export\n if (isFunction) {\n return WrappedPostgres as unknown as { [key: string]: unknown };\n } else {\n replaceExports(exports, 'default', WrappedPostgres);\n return exports;\n }\n }\n\n /**\n * Wraps query-returning methods (unsafe, file) to ensure their queries are instrumented.\n */\n private _wrapQueryMethod(\n original: (...args: unknown[]) => unknown,\n target: unknown,\n proxiedSql: unknown,\n ): (...args: unknown[]) => unknown {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n return function (this: unknown, ...args: unknown[]): unknown {\n const query = Reflect.apply(original, target, args);\n\n if (query && typeof query === 'object' && 'handle' in query) {\n self._wrapSingleQueryHandle(query as { handle: unknown; strings?: string[] }, proxiedSql);\n }\n\n return query;\n };\n }\n\n /**\n * Wraps callback-based methods (begin, reserve) to recursively instrument Sql instances.\n * Note: These methods can also be used as tagged templates, which we pass through unchanged.\n *\n * Savepoint is not wrapped to avoid complex nested transaction instrumentation issues.\n * Queries within savepoint callbacks are still instrumented through the parent transaction's Sql instance.\n */\n private _wrapCallbackMethod(\n original: (...args: unknown[]) => unknown,\n target: unknown,\n parentSqlInstance: unknown,\n ): (...args: unknown[]) => unknown {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n return function (this: unknown, ...args: unknown[]): unknown {\n // Extract parent context to propagate to child instances\n const parentContext = (parentSqlInstance as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] as\n | PostgresConnectionContext\n | undefined;\n\n // Check if this is a callback-based call by verifying the last argument is a function\n const isCallbackBased = typeof args[args.length - 1] === 'function';\n\n if (!isCallbackBased) {\n // Not a callback-based call - could be tagged template or promise-based\n const result = Reflect.apply(original, target, args);\n // If result is a Promise (e.g., reserve() without callback), instrument the resolved Sql instance\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((sqlInstance: unknown) => {\n return self._instrumentSqlInstance(sqlInstance, parentContext);\n });\n }\n return result;\n }\n\n // Callback-based call: wrap the callback to instrument the Sql instance\n const callback = (args.length === 1 ? args[0] : args[1]) as (sql: unknown) => unknown;\n const wrappedCallback = function (sqlInstance: unknown): unknown {\n const instrumentedSql = self._instrumentSqlInstance(sqlInstance, parentContext);\n return callback(instrumentedSql);\n };\n\n const newArgs = args.length === 1 ? [wrappedCallback] : [args[0], wrappedCallback];\n return Reflect.apply(original, target, newArgs);\n };\n }\n\n /**\n * Sets connection context attributes on a span.\n */\n private _setConnectionAttributes(span: Span, connectionContext: PostgresConnectionContext | undefined): void {\n if (!connectionContext) {\n return;\n }\n if (connectionContext.ATTR_DB_NAMESPACE) {\n span.setAttribute(ATTR_DB_NAMESPACE, connectionContext.ATTR_DB_NAMESPACE);\n }\n if (connectionContext.ATTR_SERVER_ADDRESS) {\n span.setAttribute(ATTR_SERVER_ADDRESS, connectionContext.ATTR_SERVER_ADDRESS);\n }\n if (connectionContext.ATTR_SERVER_PORT !== undefined) {\n // Port is stored as string in PostgresConnectionContext for requestHook backwards compatibility,\n // but OTEL semantic conventions expect port as a number for span attributes\n const portNumber = parseInt(connectionContext.ATTR_SERVER_PORT, 10);\n if (!isNaN(portNumber)) {\n span.setAttribute(ATTR_SERVER_PORT, portNumber);\n }\n }\n }\n\n /**\n * Extracts DB operation name from SQL query and sets it on the span.\n */\n private _setOperationName(span: Span, sanitizedQuery: string | undefined, command?: string): void {\n if (command) {\n span.setAttribute(ATTR_DB_OPERATION_NAME, command);\n return;\n }\n // Fallback: extract operation from the SQL query\n const operationMatch = sanitizedQuery?.match(SQL_OPERATION_REGEX);\n if (operationMatch?.[1]) {\n span.setAttribute(ATTR_DB_OPERATION_NAME, operationMatch[1].toUpperCase());\n }\n }\n\n /**\n * Extracts and stores connection context from sql.options.\n */\n private _attachConnectionContext(sql: unknown, proxiedSql: Record<symbol, unknown>): void {\n const sqlInstance = sql as { options?: { host?: string[]; port?: number[]; database?: string } };\n if (!sqlInstance.options || typeof sqlInstance.options !== 'object') {\n return;\n }\n\n const opts = sqlInstance.options;\n // postgres.js stores parsed options with host and port as arrays\n // The library defaults to 'localhost' and 5432 if not specified, but we're defensive here\n const host = opts.host?.[0] || 'localhost';\n const port = opts.port?.[0] || 5432;\n\n const connectionContext: PostgresConnectionContext = {\n ATTR_DB_NAMESPACE: typeof opts.database === 'string' && opts.database !== '' ? opts.database : undefined,\n ATTR_SERVER_ADDRESS: host,\n ATTR_SERVER_PORT: String(port),\n };\n\n proxiedSql[CONNECTION_CONTEXT_SYMBOL] = connectionContext;\n }\n\n /**\n * Instruments a sql instance by wrapping its query execution methods.\n */\n private _instrumentSqlInstance(sql: unknown, parentConnectionContext?: PostgresConnectionContext): unknown {\n // Check if already instrumented to prevent double-wrapping\n // Using Symbol.for() ensures the marker survives proxying\n if ((sql as Record<symbol, unknown>)[INSTRUMENTED_MARKER]) {\n return sql;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n // Wrap the sql function to intercept query creation\n const proxiedSql: unknown = new Proxy(sql as (...args: unknown[]) => unknown, {\n apply(target, thisArg, argumentsList: unknown[]) {\n const query = Reflect.apply(target, thisArg, argumentsList);\n\n if (query && typeof query === 'object' && 'handle' in query) {\n self._wrapSingleQueryHandle(query as { handle: unknown; strings?: string[] }, proxiedSql);\n }\n\n return query;\n },\n get(target, prop) {\n const original = (target as unknown as Record<string | symbol, unknown>)[prop];\n\n if (typeof prop !== 'string' || typeof original !== 'function') {\n return original;\n }\n\n // Wrap methods that return PendingQuery objects (unsafe, file)\n if (prop === 'unsafe' || prop === 'file') {\n return self._wrapQueryMethod(original as (...args: unknown[]) => unknown, target, proxiedSql);\n }\n\n // Wrap begin and reserve (not savepoint to avoid duplicate spans)\n if (prop === 'begin' || prop === 'reserve') {\n return self._wrapCallbackMethod(original as (...args: unknown[]) => unknown, target, proxiedSql);\n }\n\n return original;\n },\n });\n\n // Use provided parent context if available, otherwise extract from sql.options\n if (parentConnectionContext) {\n (proxiedSql as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] = parentConnectionContext;\n } else {\n this._attachConnectionContext(sql, proxiedSql as Record<symbol, unknown>);\n }\n\n // Mark both the original and proxy as instrumented to prevent double-wrapping\n // The proxy might be passed to other methods, or the original\n // might be accessed directly, so we need to mark both\n (sql as Record<symbol, unknown>)[INSTRUMENTED_MARKER] = true;\n (proxiedSql as Record<symbol, unknown>)[INSTRUMENTED_MARKER] = true;\n\n return proxiedSql;\n }\n\n /**\n * Wraps a single query's handle method to create spans.\n */\n private _wrapSingleQueryHandle(\n query: { handle: unknown; strings?: string[]; __sentryWrapped?: boolean },\n sqlInstance: unknown,\n ): void {\n // Prevent double wrapping - check if the handle itself is already wrapped\n if ((query.handle as { __sentryWrapped?: boolean })?.__sentryWrapped) {\n return;\n }\n\n // Mark this query as coming from an instrumented sql instance\n // This prevents the Query.prototype fallback patch from double-spanning\n (query as Record<symbol, unknown>)[QUERY_FROM_INSTRUMENTED_SQL] = true;\n\n const originalHandle = query.handle as (...args: unknown[]) => Promise<unknown>;\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n // IMPORTANT: We must replace the handle function directly, not use a Proxy,\n // because Query.then() internally calls this.handle(), which would bypass a Proxy wrapper.\n const wrappedHandle = async function (this: unknown, ...args: unknown[]): Promise<unknown> {\n if (!self._shouldCreateSpans()) {\n return originalHandle.apply(this, args);\n }\n\n const fullQuery = self._reconstructQuery(query.strings);\n const sanitizedSqlQuery = self._sanitizeSqlQuery(fullQuery);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n addOriginToSpan(span, 'auto.db.postgresjs');\n\n span.setAttributes({\n [ATTR_DB_SYSTEM_NAME]: 'postgres',\n [ATTR_DB_QUERY_TEXT]: sanitizedSqlQuery,\n });\n\n const connectionContext = sqlInstance\n ? ((sqlInstance as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] as\n | PostgresConnectionContext\n | undefined)\n : undefined;\n\n self._setConnectionAttributes(span, connectionContext);\n\n const config = self.getConfig();\n const { requestHook } = config;\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, sanitizedSqlQuery, connectionContext),\n e => {\n if (e) {\n span.setAttribute('sentry.hook.error', 'requestHook failed');\n DEBUG_BUILD && debug.error(`Error in requestHook for ${INTEGRATION_NAME} integration:`, e);\n }\n },\n true,\n );\n }\n\n const queryWithCallbacks = this as {\n resolve: unknown;\n reject: unknown;\n };\n\n queryWithCallbacks.resolve = new Proxy(queryWithCallbacks.resolve as (...args: unknown[]) => unknown, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n try {\n self._setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e);\n }\n\n return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n },\n });\n\n queryWithCallbacks.reject = new Proxy(queryWithCallbacks.reject as (...args: unknown[]) => unknown, {\n apply: (rejectTarget, rejectThisArg, rejectArgs: { message?: string; code?: string; name?: string }[]) => {\n try {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: rejectArgs?.[0]?.message || 'unknown_error',\n });\n\n span.setAttribute(ATTR_DB_RESPONSE_STATUS_CODE, rejectArgs?.[0]?.code || 'unknown');\n span.setAttribute(ATTR_ERROR_TYPE, rejectArgs?.[0]?.name || 'unknown');\n\n self._setOperationName(span, sanitizedSqlQuery);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in reject callback:', e);\n }\n return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n },\n });\n\n // Handle synchronous errors that might occur before promise is created\n try {\n return originalHandle.apply(this, args);\n } catch (e) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: e instanceof Error ? e.message : 'unknown_error',\n });\n span.end();\n throw e;\n }\n },\n );\n };\n\n (wrappedHandle as { __sentryWrapped?: boolean }).__sentryWrapped = true;\n query.handle = wrappedHandle;\n }\n\n /**\n * Determines whether a span should be created based on the current context.\n * If `requireParentSpan` is set to true in the configuration, a span will\n * only be created if there is a parent span available.\n */\n private _shouldCreateSpans(): boolean {\n const config = this.getConfig();\n const hasParentSpan = trace.getSpan(context.active()) !== undefined;\n return hasParentSpan || !config.requireParentSpan;\n }\n\n /**\n * Reconstructs the full SQL query from template strings with PostgreSQL placeholders.\n *\n * For sql`SELECT * FROM users WHERE id = ${123} AND name = ${'foo'}`:\n * strings = [\"SELECT * FROM users WHERE id = \", \" AND name = \", \"\"]\n * returns: \"SELECT * FROM users WHERE id = $1 AND name = $2\"\n */\n private _reconstructQuery(strings: string[] | undefined): string | undefined {\n if (!strings?.length) {\n return undefined;\n }\n if (strings.length === 1) {\n return strings[0] || undefined;\n }\n // Join template parts with PostgreSQL placeholders ($1, $2, etc.)\n return strings.reduce((acc, str, i) => (i === 0 ? str : `${acc}$${i}${str}`), '');\n }\n\n /**\n * Sanitize SQL query as per the OTEL semantic conventions\n * https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext\n *\n * PostgreSQL $n placeholders are preserved per OTEL spec - they're parameterized queries,\n * not sensitive literals. Only actual values (strings, numbers, booleans) are sanitized.\n */\n private _sanitizeSqlQuery(sqlQuery: string | undefined): string {\n if (!sqlQuery) {\n return 'Unknown SQL Query';\n }\n\n return (\n sqlQuery\n // Remove comments first (they may contain newlines and extra spaces)\n .replace(/--.*$/gm, '') // Single line comments (multiline mode)\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Multi-line comments\n .replace(/;\\s*$/, '') // Remove trailing semicolons\n // Collapse whitespace to a single space (after removing comments)\n .replace(/\\s+/g, ' ')\n .trim() // Remove extra spaces and trim\n // Sanitize hex/binary literals before string literals\n .replace(/\\bX'[0-9A-Fa-f]*'/gi, '?') // Hex string literals\n .replace(/\\bB'[01]*'/gi, '?') // Binary string literals\n // Sanitize string literals (handles escaped quotes)\n .replace(/'(?:[^']|'')*'/g, '?')\n // Sanitize hex numbers\n .replace(/\\b0x[0-9A-Fa-f]+/gi, '?')\n // Sanitize boolean literals\n .replace(/\\b(?:TRUE|FALSE)\\b/gi, '?')\n // Sanitize numeric literals (preserve $n placeholders via negative lookbehind)\n .replace(/-?\\b\\d+\\.?\\d*[eE][+-]?\\d+\\b/g, '?') // Scientific notation\n .replace(/-?\\b\\d+\\.\\d+\\b/g, '?') // Decimals\n .replace(/-?\\.\\d+\\b/g, '?') // Decimals starting with dot\n .replace(/(?<!\\$)-?\\b\\d+\\b/g, '?') // Integers (NOT $n placeholders)\n // Collapse IN clauses for cardinality (both ? and $n variants)\n .replace(/\\bIN\\b\\s*\\(\\s*\\?(?:\\s*,\\s*\\?)*\\s*\\)/gi, 'IN (?)')\n .replace(/\\bIN\\b\\s*\\(\\s*\\$\\d+(?:\\s*,\\s*\\$\\d+)*\\s*\\)/gi, 'IN ($?)')\n );\n }\n\n /**\n * Fallback patch for Query.prototype.handle to instrument queries from pre-existing sql instances.\n * This catches queries from sql instances created BEFORE Sentry was initialized (CJS only).\n *\n * Note: Queries from pre-existing instances won't have connection context (database, host, port)\n * because the sql instance wasn't created through our instrumented wrapper.\n */\n private _patchQueryPrototype(moduleExports: {\n Query: {\n prototype: {\n handle: ((...args: unknown[]) => Promise<unknown>) & {\n __sentry_original__?: (...args: unknown[]) => Promise<unknown>;\n };\n };\n };\n }): typeof moduleExports {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n const originalHandle = moduleExports.Query.prototype.handle;\n\n moduleExports.Query.prototype.handle = async function (\n this: {\n resolve: unknown;\n reject: unknown;\n strings?: string[];\n },\n ...args: unknown[]\n ): Promise<unknown> {\n // Skip if this query came from an instrumented sql instance (already handled by wrapper)\n if ((this as Record<symbol, unknown>)[QUERY_FROM_INSTRUMENTED_SQL]) {\n return originalHandle.apply(this, args);\n }\n\n // Skip if we shouldn't create spans\n if (!self._shouldCreateSpans()) {\n return originalHandle.apply(this, args);\n }\n\n const fullQuery = self._reconstructQuery(this.strings);\n const sanitizedSqlQuery = self._sanitizeSqlQuery(fullQuery);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n addOriginToSpan(span, 'auto.db.postgresjs');\n\n span.setAttributes({\n [ATTR_DB_SYSTEM_NAME]: 'postgres',\n [ATTR_DB_QUERY_TEXT]: sanitizedSqlQuery,\n });\n\n // Note: No connection context available for pre-existing instances\n // because the sql instance wasn't created through our instrumented wrapper\n\n const config = self.getConfig();\n const { requestHook } = config;\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, sanitizedSqlQuery, undefined),\n e => {\n if (e) {\n span.setAttribute('sentry.hook.error', 'requestHook failed');\n DEBUG_BUILD && debug.error(`Error in requestHook for ${INTEGRATION_NAME} integration:`, e);\n }\n },\n true,\n );\n }\n\n // Wrap resolve to end span on success\n const originalResolve = this.resolve;\n this.resolve = new Proxy(originalResolve as (...args: unknown[]) => unknown, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n try {\n self._setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e);\n }\n return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n },\n });\n\n // Wrap reject to end span on error\n const originalReject = this.reject;\n this.reject = new Proxy(originalReject as (...args: unknown[]) => unknown, {\n apply: (rejectTarget, rejectThisArg, rejectArgs: { message?: string; code?: string; name?: string }[]) => {\n try {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: rejectArgs?.[0]?.message || 'unknown_error',\n });\n span.setAttribute(ATTR_DB_RESPONSE_STATUS_CODE, rejectArgs?.[0]?.code || 'unknown');\n span.setAttribute(ATTR_ERROR_TYPE, rejectArgs?.[0]?.name || 'unknown');\n self._setOperationName(span, sanitizedSqlQuery);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in reject callback:', e);\n }\n return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n },\n });\n\n try {\n return originalHandle.apply(this, args);\n } catch (e) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: e instanceof Error ? e.message : 'unknown_error',\n });\n span.end();\n throw e;\n }\n },\n );\n };\n\n // Store original for unpatch - must be set on the NEW patched function\n moduleExports.Query.prototype.handle.__sentry_original__ = originalHandle;\n\n return moduleExports;\n }\n\n /**\n * Restores the original Query.prototype.handle method.\n */\n private _unpatchQueryPrototype(moduleExports: {\n Query: {\n prototype: {\n handle: ((...args: unknown[]) => Promise<unknown>) & {\n __sentry_original__?: (...args: unknown[]) => Promise<unknown>;\n };\n };\n };\n }): typeof moduleExports {\n if (moduleExports.Query.prototype.handle.__sentry_original__) {\n moduleExports.Query.prototype.handle = moduleExports.Query.prototype.handle.__sentry_original__;\n }\n return moduleExports;\n }\n}\n\nconst _postgresJsIntegration = ((options?: PostgresJsInstrumentationConfig) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPostgresJs(options);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n *\n * For more information, see the [`postgresIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/postgres/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.postgresJsIntegration()],\n * });\n * ```\n */\n\nexport const postgresJsIntegration = defineIntegration(_postgresJsIntegration);\n"],"names":["exports"],"mappings":";;;;;;;AAAA;AACA;;;AAgCA,MAAM,gBAAA,GAAmB,YAAY;AACrC,MAAM,kBAAA,GAAqB,CAAC,YAAY,CAAC;AACzC,MAAM,mBAAA,GAAsB,mDAAmD;;AAQ/E,MAAM,yBAAA,GAA4B,MAAM,CAAC,iCAAiC,CAAC;AAC3E,MAAM,sBAAsB,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC;AACxE;AACA;AACA,MAAM,8BAA8B,MAAM,CAAC,GAAG,CAAC,oCAAoC,CAAC;;AAiB7E,MAAM,oBAAA,GAAuB,sBAAsB;AAC1D,EAAE,gBAAgB;AAClB,EAAE,CAAC,OAAO;AACV,IAAI,IAAI,yBAAyB,CAAC;AAClC,MAAM,iBAAiB,EAAE,OAAO,EAAE,iBAAA,IAAqB,IAAI;AAC3D,MAAM,WAAW,EAAE,OAAO,EAAE,WAAW;AACvC,KAAK,CAAC;AACN;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,yBAAA,SAAkC,mBAAmB,CAAkC;AACpG,GAAS,WAAW,CAAC,MAAM,EAAmC;AAC9D,IAAI,KAAK,CAAC,oBAAoB,EAAE,WAAW,EAAE,MAAM,CAAC;AACpD,EAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA,GAAS,IAAI,GAAwC;AACrD,IAAI,MAAM,MAAA,GAAS,IAAI,mCAAmC;AAC1D,MAAM,UAAU;AAChB,MAAM,kBAAkB;AACxB,MAAMA,aAAW;AACjB,QAAQ,IAAI;AACZ,UAAU,OAAO,IAAI,CAAC,cAAc,CAACA,SAAO,CAAC;AAC7C,QAAQ,CAAA,CAAE,OAAO,CAAC,EAAE;AACpB,UAAU,WAAA,IAAe,KAAK,CAAC,KAAK,CAAC,kCAAkC,EAAE,CAAC,CAAC;AAC3E,UAAU,OAAOA,SAAO;AACxB,QAAQ;AACR,MAAM,CAAC;AACP,MAAMA,SAAA,IAAWA,SAAO;AACxB,KAAK;;AAEL;AACA;AACA,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,IAAA,IAAQ;AACjD,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI;AACvB,QAAQ,IAAI,6BAA6B;AACzC,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC;AACrC,UAAU,kBAAkB;AAC5B,UAAU,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;AAC9C,UAAU,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC;AAChD,SAAS;AACT,OAAO;AACP,IAAI,CAAC,CAAC;;AAEN,IAAI,OAAO,MAAM;AACjB,EAAE;;AAEF;AACA;AACA;AACA;AACA,GAAU,cAAc,CAACA,SAAO,EAA0D;AAC1F;AACA;AACA,IAAI,MAAM,UAAA,GAAa,OAAOA,SAAA,KAAY,UAAU;AACpD,IAAI,MAAM,WAAW,UAAA,GAAaA,SAAA,GAAUA,SAAO,CAAC,OAAO;;AAE3D,IAAI,IAAI,OAAO,QAAA,KAAa,UAAU,EAAE;AACxC,MAAM,eAAe,KAAK,CAAC,IAAI,CAAC,uEAAuE,CAAC;AACxG,MAAM,OAAOA,SAAO;AACpB,IAAI;;AAEJ;AACA,IAAI,MAAM,IAAA,GAAO,IAAI;;AAErB,IAAI,MAAM,kBAAkB,WAAyB,GAAG,IAAI,EAAsB;AAClF,MAAM,MAAM,GAAA,GAAM,OAAO,CAAC,SAAS,CAAC,QAAA,GAA6C,IAAI,CAAC;;AAEtF;AACA,MAAM,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,UAAU,EAAE;AAC7C,QAAQ,eAAe,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC;AAC/E,QAAQ,OAAO,GAAG;AAClB,MAAM;;AAEN,MAAM,OAAO,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC;AAC7C,IAAI,CAAC;;AAEL,IAAI,MAAM,CAAC,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC;AACpD,IAAI,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC,QAAA,GAAmC,SAAS,CAAC;;AAEnG,IAAI,KAAK,MAAM,GAAA,IAAO,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE;AAC5D,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC1D,QAAQ,MAAM,UAAA,GAAa,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,GAAG,CAAC;AACzE,QAAQ,IAAI,UAAU,EAAE;AACxB,UAAU,MAAM,CAAC,cAAc,CAAC,eAAe,EAAE,GAAG,EAAE,UAAU,CAAC;AACjE,QAAQ;AACR,MAAM;AACN,IAAI;;AAEJ;AACA;AACA,IAAI,IAAI,UAAU,EAAE;AACpB,MAAM,OAAO,eAAA;AACb,IAAI,OAAO;AACX,MAAM,cAAc,CAACA,SAAO,EAAE,SAAS,EAAE,eAAe,CAAC;AACzD,MAAM,OAAOA,SAAO;AACpB,IAAI;AACJ,EAAE;;AAEF;AACA;AACA;AACA,GAAU,gBAAgB;AAC1B,IAAI,QAAQ;AACZ,IAAI,MAAM;AACV,IAAI,UAAU;AACd,IAAqC;AACrC;AACA,IAAI,MAAM,IAAA,GAAO,IAAI;AACrB,IAAI,OAAO,WAAyB,GAAG,IAAI,EAAsB;AACjE,MAAM,MAAM,KAAA,GAAQ,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;;AAEzD,MAAM,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,QAAA,IAAY,KAAK,EAAE;AACnE,QAAQ,IAAI,CAAC,sBAAsB,CAAC,KAAA,GAAkD,UAAU,CAAC;AACjG,MAAM;;AAEN,MAAM,OAAO,KAAK;AAClB,IAAI,CAAC;AACL,EAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAU,mBAAmB;AAC7B,IAAI,QAAQ;AACZ,IAAI,MAAM;AACV,IAAI,iBAAiB;AACrB,IAAqC;AACrC;AACA,IAAI,MAAM,IAAA,GAAO,IAAI;AACrB,IAAI,OAAO,WAAyB,GAAG,IAAI,EAAsB;AACjE;AACA,MAAM,MAAM,gBAAgB,CAAC,oBAA8C,yBAAyB;;AAE5F;;AAER;AACA,MAAM,MAAM,eAAA,GAAkB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAA,GAAS,CAAC,CAAA,KAAM,UAAU;;AAEzE,MAAM,IAAI,CAAC,eAAe,EAAE;AAC5B;AACA,QAAQ,MAAM,MAAA,GAAS,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;AAC5D;AACA,QAAQ,IAAI,MAAA,IAAU,OAAO,CAAC,MAAA,GAA4B,IAAA,KAAS,UAAU,EAAE;AAC/E,UAAU,OAAO,CAAC,MAAA,GAA4B,IAAI,CAAC,CAAC,WAAW,KAAc;AAC7E,YAAY,OAAO,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,aAAa,CAAC;AAC1E,UAAU,CAAC,CAAC;AACZ,QAAQ;AACR,QAAQ,OAAO,MAAM;AACrB,MAAM;;AAEN;AACA,MAAM,MAAM,QAAA,IAAY,IAAI,CAAC,WAAW,CAAA,GAAI,IAAI,CAAC,CAAC,CAAA,GAAI,IAAI,CAAC,CAAC,CAAC,CAAA;AAC7D,MAAM,MAAM,eAAA,GAAkB,UAAU,WAAW,EAAoB;AACvE,QAAQ,MAAM,eAAA,GAAkB,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,aAAa,CAAC;AACvF,QAAQ,OAAO,QAAQ,CAAC,eAAe,CAAC;AACxC,MAAM,CAAC;;AAEP,MAAM,MAAM,UAAU,IAAI,CAAC,MAAA,KAAW,IAAI,CAAC,eAAe,CAAA,GAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC;AACxF,MAAM,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC;AACrD,IAAI,CAAC;AACL,EAAE;;AAEF;AACA;AACA;AACA,GAAU,wBAAwB,CAAC,IAAI,EAAQ,iBAAiB,EAA+C;AAC/G,IAAI,IAAI,CAAC,iBAAiB,EAAE;AAC5B,MAAM;AACN,IAAI;AACJ,IAAI,IAAI,iBAAiB,CAAC,iBAAiB,EAAE;AAC7C,MAAM,IAAI,CAAC,YAAY,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,iBAAiB,CAAC;AAC/E,IAAI;AACJ,IAAI,IAAI,iBAAiB,CAAC,mBAAmB,EAAE;AAC/C,MAAM,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,mBAAmB,CAAC;AACnF,IAAI;AACJ,IAAI,IAAI,iBAAiB,CAAC,gBAAA,KAAqB,SAAS,EAAE;AAC1D;AACA;AACA,MAAM,MAAM,UAAA,GAAa,QAAQ,CAAC,iBAAiB,CAAC,gBAAgB,EAAE,EAAE,CAAC;AACzE,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE;AAC9B,QAAQ,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,UAAU,CAAC;AACvD,MAAM;AACN,IAAI;AACJ,EAAE;;AAEF;AACA;AACA;AACA,GAAU,iBAAiB,CAAC,IAAI,EAAQ,cAAc,EAAsB,OAAO,EAAiB;AACpG,IAAI,IAAI,OAAO,EAAE;AACjB,MAAM,IAAI,CAAC,YAAY,CAAC,sBAAsB,EAAE,OAAO,CAAC;AACxD,MAAM;AACN,IAAI;AACJ;AACA,IAAI,MAAM,iBAAiB,cAAc,EAAE,KAAK,CAAC,mBAAmB,CAAC;AACrE,IAAI,IAAI,cAAc,GAAG,CAAC,CAAC,EAAE;AAC7B,MAAM,IAAI,CAAC,YAAY,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AAChF,IAAI;AACJ,EAAE;;AAEF;AACA;AACA;AACA,GAAU,wBAAwB,CAAC,GAAG,EAAW,UAAU,EAAiC;AAC5F,IAAI,MAAM,WAAA,GAAc,GAAA;AACxB,IAAI,IAAI,CAAC,WAAW,CAAC,OAAA,IAAW,OAAO,WAAW,CAAC,OAAA,KAAY,QAAQ,EAAE;AACzE,MAAM;AACN,IAAI;;AAEJ,IAAI,MAAM,IAAA,GAAO,WAAW,CAAC,OAAO;AACpC;AACA;AACA,IAAI,MAAM,IAAA,GAAO,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA,IAAK,WAAW;AAC9C,IAAI,MAAM,IAAA,GAAO,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA,IAAK,IAAI;;AAEvC,IAAI,MAAM,iBAAiB,GAA8B;AACzD,MAAM,iBAAiB,EAAE,OAAO,IAAI,CAAC,QAAA,KAAa,QAAA,IAAY,IAAI,CAAC,QAAA,KAAa,EAAA,GAAK,IAAI,CAAC,QAAA,GAAW,SAAS;AAC9G,MAAM,mBAAmB,EAAE,IAAI;AAC/B,MAAM,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC;AACpC,KAAK;;AAEL,IAAI,UAAU,CAAC,yBAAyB,CAAA,GAAI,iBAAiB;AAC7D,EAAE;;AAEF;AACA;AACA;AACA,GAAU,sBAAsB,CAAC,GAAG,EAAW,uBAAuB,EAAuC;AAC7G;AACA;AACA,IAAI,IAAI,CAAC,GAAA,GAAgC,mBAAmB,CAAC,EAAE;AAC/D,MAAM,OAAO,GAAG;AAChB,IAAI;;AAEJ;AACA,IAAI,MAAM,IAAA,GAAO,IAAI;;AAErB;AACA,IAAI,MAAM,UAAU,GAAY,IAAI,KAAK,CAAC,MAAwC;AAClF,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAa;AACvD,QAAQ,MAAM,KAAA,GAAQ,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC;;AAEnE,QAAQ,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,QAAA,IAAY,KAAK,EAAE;AACrE,UAAU,IAAI,CAAC,sBAAsB,CAAC,KAAA,GAAkD,UAAU,CAAC;AACnG,QAAQ;;AAER,QAAQ,OAAO,KAAK;AACpB,MAAM,CAAC;AACP,MAAM,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE;AACxB,QAAQ,MAAM,WAAW,CAAC,SAAuD,IAAI,CAAC;;AAEtF,QAAQ,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,OAAO,QAAA,KAAa,UAAU,EAAE;AACxE,UAAU,OAAO,QAAQ;AACzB,QAAQ;;AAER;AACA,QAAQ,IAAI,IAAA,KAAS,YAAY,IAAA,KAAS,MAAM,EAAE;AAClD,UAAU,OAAO,IAAI,CAAC,gBAAgB,CAAC,WAA6C,MAAM,EAAE,UAAU,CAAC;AACvG,QAAQ;;AAER;AACA,QAAQ,IAAI,IAAA,KAAS,WAAW,IAAA,KAAS,SAAS,EAAE;AACpD,UAAU,OAAO,IAAI,CAAC,mBAAmB,CAAC,WAA6C,MAAM,EAAE,UAAU,CAAC;AAC1G,QAAQ;;AAER,QAAQ,OAAO,QAAQ;AACvB,MAAM,CAAC;AACP,KAAK,CAAC;;AAEN;AACA,IAAI,IAAI,uBAAuB,EAAE;AACjC,MAAM,CAAC,UAAA,GAAuC,yBAAyB,CAAA,GAAI,uBAAuB;AAClG,IAAI,OAAO;AACX,MAAM,IAAI,CAAC,wBAAwB,CAAC,GAAG,EAAE,YAAsC;AAC/E,IAAI;;AAEJ;AACA;AACA;AACA,IAAI,CAAC,GAAA,GAAgC,mBAAmB,CAAA,GAAI,IAAI;AAChE,IAAI,CAAC,UAAA,GAAuC,mBAAmB,CAAA,GAAI,IAAI;;AAEvE,IAAI,OAAO,UAAU;AACrB,EAAE;;AAEF;AACA;AACA;AACA,GAAU,sBAAsB;AAChC,IAAI,KAAK;AACT,IAAI,WAAW;AACf,IAAU;AACV;AACA,IAAI,IAAI,CAAC,KAAK,CAAC,MAAA,IAA0C,eAAe,EAAE;AAC1E,MAAM;AACN,IAAI;;AAEJ;AACA;AACA,IAAI,CAAC,KAAA,GAAkC,2BAA2B,CAAA,GAAI,IAAI;;AAE1E,IAAI,MAAM,cAAA,GAAiB,KAAK,CAAC,MAAA;AACjC;AACA,IAAI,MAAM,IAAA,GAAO,IAAI;;AAErB;AACA;AACA,IAAI,MAAM,aAAA,GAAgB,iBAA+B,GAAG,IAAI,EAA+B;AAC/F,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE;AACtC,QAAQ,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;AAC/C,MAAM;;AAEN,MAAM,MAAM,SAAA,GAAY,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC;AAC7D,MAAM,MAAM,oBAAoB,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC;;AAEjE,MAAM,OAAO,eAAe;AAC5B,QAAQ;AACR,UAAU,IAAI,EAAE,iBAAA,IAAqB,kBAAkB;AACvD,UAAU,EAAE,EAAE,IAAI;AAClB,SAAS;AACT,QAAQ,CAAC,IAAI,KAAW;AACxB,UAAU,eAAe,CAAC,IAAI,EAAE,oBAAoB,CAAC;;AAErD,UAAU,IAAI,CAAC,aAAa,CAAC;AAC7B,YAAY,CAAC,mBAAmB,GAAG,UAAU;AAC7C,YAAY,CAAC,kBAAkB,GAAG,iBAAiB;AACnD,WAAW,CAAC;;AAEZ,UAAU,MAAM,oBAAoB;AACpC,eAAe,CAAC,cAAwC,yBAAyB;;AAEjE;AAChB,cAAc,SAAS;;AAEvB,UAAU,IAAI,CAAC,wBAAwB,CAAC,IAAI,EAAE,iBAAiB,CAAC;;AAEhE,UAAU,MAAM,MAAA,GAAS,IAAI,CAAC,SAAS,EAAE;AACzC,UAAU,MAAM,EAAE,WAAA,EAAY,GAAI,MAAM;AACxC,UAAU,IAAI,WAAW,EAAE;AAC3B,YAAY,sBAAsB;AAClC,cAAc,MAAM,WAAW,CAAC,IAAI,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;AAC3E,cAAc,KAAK;AACnB,gBAAgB,IAAI,CAAC,EAAE;AACvB,kBAAkB,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;AAC9E,kBAAkB,WAAA,IAAe,KAAK,CAAC,KAAK,CAAC,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;AAC5G,gBAAgB;AAChB,cAAc,CAAC;AACf,cAAc,IAAI;AAClB,aAAa;AACb,UAAU;;AAEV,UAAU,MAAM,kBAAA,GAAqB;;AAG3B;;AAEV,UAAU,kBAAkB,CAAC,OAAA,GAAU,IAAI,KAAK,CAAC,kBAAkB,CAAC,OAAA,GAA4C;AAChH,YAAY,KAAK,EAAE,CAAC,aAAa,EAAE,cAAc,EAAE,WAAW,KAA6B;AAC3F,cAAc,IAAI;AAClB,gBAAgB,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,EAAE,WAAW,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC;AAC1F,gBAAgB,IAAI,CAAC,GAAG,EAAE;AAC1B,cAAc,CAAA,CAAE,OAAO,CAAC,EAAE;AAC1B,gBAAgB,WAAA,IAAe,KAAK,CAAC,KAAK,CAAC,wCAAwC,EAAE,CAAC,CAAC;AACvF,cAAc;;AAEd,cAAc,OAAO,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,cAAc,EAAE,WAAW,CAAC;AAC9E,YAAY,CAAC;AACb,WAAW,CAAC;;AAEZ,UAAU,kBAAkB,CAAC,MAAA,GAAS,IAAI,KAAK,CAAC,kBAAkB,CAAC,MAAA,GAA2C;AAC9G,YAAY,KAAK,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,UAAU,KAA2D;AACtH,cAAc,IAAI;AAClB,gBAAgB,IAAI,CAAC,SAAS,CAAC;AAC/B,kBAAkB,IAAI,EAAE,iBAAiB;AACzC,kBAAkB,OAAO,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,OAAA,IAAW,eAAe;AACtE,iBAAiB,CAAC;;AAElB,gBAAgB,IAAI,CAAC,YAAY,CAAC,4BAA4B,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,IAAA,IAAQ,SAAS,CAAC;AACnG,gBAAgB,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,IAAA,IAAQ,SAAS,CAAC;;AAEtF,gBAAgB,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,CAAC;AAC/D,gBAAgB,IAAI,CAAC,GAAG,EAAE;AAC1B,cAAc,CAAA,CAAE,OAAO,CAAC,EAAE;AAC1B,gBAAgB,WAAA,IAAe,KAAK,CAAC,KAAK,CAAC,uCAAuC,EAAE,CAAC,CAAC;AACtF,cAAc;AACd,cAAc,OAAO,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,aAAa,EAAE,UAAU,CAAC;AAC3E,YAAY,CAAC;AACb,WAAW,CAAC;;AAEZ;AACA,UAAU,IAAI;AACd,YAAY,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;AACnD,UAAU,CAAA,CAAE,OAAO,CAAC,EAAE;AACtB,YAAY,IAAI,CAAC,SAAS,CAAC;AAC3B,cAAc,IAAI,EAAE,iBAAiB;AACrC,cAAc,OAAO,EAAE,CAAA,YAAa,KAAA,GAAQ,CAAC,CAAC,OAAA,GAAU,eAAe;AACvE,aAAa,CAAC;AACd,YAAY,IAAI,CAAC,GAAG,EAAE;AACtB,YAAY,MAAM,CAAC;AACnB,UAAU;AACV,QAAQ,CAAC;AACT,OAAO;AACP,IAAI,CAAC;;AAEL,IAAI,CAAC,aAAA,GAAgD,eAAA,GAAkB,IAAI;AAC3E,IAAI,KAAK,CAAC,MAAA,GAAS,aAAa;AAChC,EAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,GAAU,kBAAkB,GAAY;AACxC,IAAI,MAAM,MAAA,GAAS,IAAI,CAAC,SAAS,EAAE;AACnC,IAAI,MAAM,aAAA,GAAgB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAA,KAAM,SAAS;AACvE,IAAI,OAAO,aAAA,IAAiB,CAAC,MAAM,CAAC,iBAAiB;AACrD,EAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAU,iBAAiB,CAAC,OAAO,EAA4C;AAC/E,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE;AAC1B,MAAM,OAAO,SAAS;AACtB,IAAI;AACJ,IAAI,IAAI,OAAO,CAAC,MAAA,KAAW,CAAC,EAAE;AAC9B,MAAM,OAAO,OAAO,CAAC,CAAC,CAAA,IAAK,SAAS;AACpC,IAAI;AACJ;AACA,IAAI,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAA,KAAM,IAAI,GAAA,GAAM,CAAC,EAAA,GAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,GAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAA,iBAAA,CAAA,QAAA,EAAA;AACA,IAAA,IAAA,CAAA,QAAA,EAAA;AACA,MAAA,OAAA,mBAAA;AACA,IAAA;;AAEA,IAAA;AACA,MAAA;AACA;AACA,SAAA,OAAA,CAAA,SAAA,EAAA,EAAA,CAAA;AACA,SAAA,OAAA,CAAA,mBAAA,EAAA,EAAA,CAAA;AACA,SAAA,OAAA,CAAA,OAAA,EAAA,EAAA,CAAA;AACA;AACA,SAAA,OAAA,CAAA,MAAA,EAAA,GAAA;AACA,SAAA,IAAA,EAAA;AACA;AACA,SAAA,OAAA,CAAA,qBAAA,EAAA,GAAA,CAAA;AACA,SAAA,OAAA,CAAA,cAAA,EAAA,GAAA,CAAA;AACA;AACA,SAAA,OAAA,CAAA,iBAAA,EAAA,GAAA;AACA;AACA,SAAA,OAAA,CAAA,oBAAA,EAAA,GAAA;AACA;AACA,SAAA,OAAA,CAAA,sBAAA,EAAA,GAAA;AACA;AACA,SAAA,OAAA,CAAA,8BAAA,EAAA,GAAA,CAAA;AACA,SAAA,OAAA,CAAA,iBAAA,EAAA,GAAA,CAAA;AACA,SAAA,OAAA,CAAA,YAAA,EAAA,GAAA,CAAA;AACA,SAAA,OAAA,CAAA,mBAAA,EAAA,GAAA,CAAA;AACA;AACA,SAAA,OAAA,CAAA,uCAAA,EAAA,QAAA;AACA,SAAA,OAAA,CAAA,6CAAA,EAAA,SAAA;AACA;AACA,EAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAA,oBAAA,CAAA;;AAQA,EAAA;AACA;AACA,IAAA,MAAA,IAAA,GAAA,IAAA;AACA,IAAA,MAAA,cAAA,GAAA,aAAA,CAAA,KAAA,CAAA,SAAA,CAAA,MAAA;;AAEA,IAAA,aAAA,CAAA,KAAA,CAAA,SAAA,CAAA,MAAA,GAAA;;AAMA,MAAA,GAAA;AACA,MAAA;AACA;AACA,MAAA,IAAA,CAAA,IAAA,GAAA,2BAAA,CAAA,EAAA;AACA,QAAA,OAAA,cAAA,CAAA,KAAA,CAAA,IAAA,EAAA,IAAA,CAAA;AACA,MAAA;;AAEA;AACA,MAAA,IAAA,CAAA,IAAA,CAAA,kBAAA,EAAA,EAAA;AACA,QAAA,OAAA,cAAA,CAAA,KAAA,CAAA,IAAA,EAAA,IAAA,CAAA;AACA,MAAA;;AAEA,MAAA,MAAA,SAAA,GAAA,IAAA,CAAA,iBAAA,CAAA,IAAA,CAAA,OAAA,CAAA;AACA,MAAA,MAAA,iBAAA,GAAA,IAAA,CAAA,iBAAA,CAAA,SAAA,CAAA;;AAEA,MAAA,OAAA,eAAA;AACA,QAAA;AACA,UAAA,IAAA,EAAA,iBAAA,IAAA,kBAAA;AACA,UAAA,EAAA,EAAA,IAAA;AACA,SAAA;AACA,QAAA,CAAA,IAAA,KAAA;AACA,UAAA,eAAA,CAAA,IAAA,EAAA,oBAAA,CAAA;;AAEA,UAAA,IAAA,CAAA,aAAA,CAAA;AACA,YAAA,CAAA,mBAAA,GAAA,UAAA;AACA,YAAA,CAAA,kBAAA,GAAA,iBAAA;AACA,WAAA,CAAA;;AAEA;AACA;;AAEA,UAAA,MAAA,MAAA,GAAA,IAAA,CAAA,SAAA,EAAA;AACA,UAAA,MAAA,EAAA,WAAA,EAAA,GAAA,MAAA;AACA,UAAA,IAAA,WAAA,EAAA;AACA,YAAA,sBAAA;AACA,cAAA,MAAA,WAAA,CAAA,IAAA,EAAA,iBAAA,EAAA,SAAA,CAAA;AACA,cAAA,CAAA,IAAA;AACA,gBAAA,IAAA,CAAA,EAAA;AACA,kBAAA,IAAA,CAAA,YAAA,CAAA,mBAAA,EAAA,oBAAA,CAAA;AACA,kBAAA,WAAA,IAAA,KAAA,CAAA,KAAA,CAAA,CAAA,yBAAA,EAAA,gBAAA,CAAA,aAAA,CAAA,EAAA,CAAA,CAAA;AACA,gBAAA;AACA,cAAA,CAAA;AACA,cAAA,IAAA;AACA,aAAA;AACA,UAAA;;AAEA;AACA,UAAA,MAAA,eAAA,GAAA,IAAA,CAAA,OAAA;AACA,UAAA,IAAA,CAAA,OAAA,GAAA,IAAA,KAAA,CAAA,eAAA,GAAA;AACA,YAAA,KAAA,EAAA,CAAA,aAAA,EAAA,cAAA,EAAA,WAAA,KAAA;AACA,cAAA,IAAA;AACA,gBAAA,IAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,iBAAA,EAAA,WAAA,GAAA,CAAA,CAAA,EAAA,OAAA,CAAA;AACA,gBAAA,IAAA,CAAA,GAAA,EAAA;AACA,cAAA,CAAA,CAAA,OAAA,CAAA,EAAA;AACA,gBAAA,WAAA,IAAA,KAAA,CAAA,KAAA,CAAA,wCAAA,EAAA,CAAA,CAAA;AACA,cAAA;AACA,cAAA,OAAA,OAAA,CAAA,KAAA,CAAA,aAAA,EAAA,cAAA,EAAA,WAAA,CAAA;AACA,YAAA,CAAA;AACA,WAAA,CAAA;;AAEA;AACA,UAAA,MAAA,cAAA,GAAA,IAAA,CAAA,MAAA;AACA,UAAA,IAAA,CAAA,MAAA,GAAA,IAAA,KAAA,CAAA,cAAA,GAAA;AACA,YAAA,KAAA,EAAA,CAAA,YAAA,EAAA,aAAA,EAAA,UAAA,KAAA;AACA,cAAA,IAAA;AACA,gBAAA,IAAA,CAAA,SAAA,CAAA;AACA,kBAAA,IAAA,EAAA,iBAAA;AACA,kBAAA,OAAA,EAAA,UAAA,GAAA,CAAA,CAAA,EAAA,OAAA,IAAA,eAAA;AACA,iBAAA,CAAA;AACA,gBAAA,IAAA,CAAA,YAAA,CAAA,4BAAA,EAAA,UAAA,GAAA,CAAA,CAAA,EAAA,IAAA,IAAA,SAAA,CAAA;AACA,gBAAA,IAAA,CAAA,YAAA,CAAA,eAAA,EAAA,UAAA,GAAA,CAAA,CAAA,EAAA,IAAA,IAAA,SAAA,CAAA;AACA,gBAAA,IAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,iBAAA,CAAA;AACA,gBAAA,IAAA,CAAA,GAAA,EAAA;AACA,cAAA,CAAA,CAAA,OAAA,CAAA,EAAA;AACA,gBAAA,WAAA,IAAA,KAAA,CAAA,KAAA,CAAA,uCAAA,EAAA,CAAA,CAAA;AACA,cAAA;AACA,cAAA,OAAA,OAAA,CAAA,KAAA,CAAA,YAAA,EAAA,aAAA,EAAA,UAAA,CAAA;AACA,YAAA,CAAA;AACA,WAAA,CAAA;;AAEA,UAAA,IAAA;AACA,YAAA,OAAA,cAAA,CAAA,KAAA,CAAA,IAAA,EAAA,IAAA,CAAA;AACA,UAAA,CAAA,CAAA,OAAA,CAAA,EAAA;AACA,YAAA,IAAA,CAAA,SAAA,CAAA;AACA,cAAA,IAAA,EAAA,iBAAA;AACA,cAAA,OAAA,EAAA,CAAA,YAAA,KAAA,GAAA,CAAA,CAAA,OAAA,GAAA,eAAA;AACA,aAAA,CAAA;AACA,YAAA,IAAA,CAAA,GAAA,EAAA;AACA,YAAA,MAAA,CAAA;AACA,UAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA;;AAEA;AACA,IAAA,aAAA,CAAA,KAAA,CAAA,SAAA,CAAA,MAAA,CAAA,mBAAA,GAAA,cAAA;;AAEA,IAAA,OAAA,aAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA,GAAA,sBAAA,CAAA;;AAQA,EAAA;AACA,IAAA,IAAA,aAAA,CAAA,KAAA,CAAA,SAAA,CAAA,MAAA,CAAA,mBAAA,EAAA;AACA,MAAA,aAAA,CAAA,KAAA,CAAA,SAAA,CAAA,MAAA,GAAA,aAAA,CAAA,KAAA,CAAA,SAAA,CAAA,MAAA,CAAA,mBAAA;AACA,IAAA;AACA,IAAA,OAAA,aAAA;AACA,EAAA;AACA;;AAEA,MAAA,sBAAA,IAAA,CAAA,OAAA,KAAA;AACA,EAAA,OAAA;AACA,IAAA,IAAA,EAAA,gBAAA;AACA,IAAA,SAAA,GAAA;AACA,MAAA,oBAAA,CAAA,OAAA,CAAA;AACA,IAAA,CAAA;AACA,GAAA;AACA,CAAA,CAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAA,qBAAA,GAAA,iBAAA,CAAA,sBAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"postgresjs.js","sources":["../../../../src/integrations/tracing/postgresjs.ts"],"sourcesContent":["// Instrumentation for https://github.com/porsager/postgres\n\nimport { context, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport {\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_RESPONSE_STATUS_CODE,\n ATTR_DB_SYSTEM_NAME,\n ATTR_ERROR_TYPE,\n} from '@opentelemetry/semantic-conventions';\nimport type { IntegrationFn, Span } from '@sentry/core';\nimport {\n debug,\n defineIntegration,\n instrumentPostgresJsSql,\n replaceExports,\n SDK_VERSION,\n SPAN_STATUS_ERROR,\n startSpanManual,\n} from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\nimport { DEBUG_BUILD } from '../../debug-build';\n\nconst INTEGRATION_NAME = 'PostgresJs';\nconst SUPPORTED_VERSIONS = ['>=3.0.0 <4'];\nconst SQL_OPERATION_REGEX = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i;\n\ntype PostgresConnectionContext = {\n ATTR_DB_NAMESPACE?: string; // Database name\n ATTR_SERVER_ADDRESS?: string; // Hostname or IP address of the database server\n ATTR_SERVER_PORT?: string; // Port number of the database server\n};\n\n// Marker to track if a query was created from an instrumented sql instance\n// This prevents double-spanning when both wrapper and prototype patches are active\nconst QUERY_FROM_INSTRUMENTED_SQL = Symbol.for('sentry.query.from.instrumented.sql');\n\ntype PostgresJsInstrumentationConfig = InstrumentationConfig & {\n /**\n * Whether to require a parent span for the instrumentation.\n * If set to true, the instrumentation will only create spans if there is a parent span\n * available in the current scope.\n * @default true\n */\n requireParentSpan?: boolean;\n /**\n * Hook to modify the span before it is started.\n * This can be used to set additional attributes or modify the span in any way.\n */\n requestHook?: (span: Span, sanitizedSqlQuery: string, postgresConnectionContext?: PostgresConnectionContext) => void;\n};\n\nexport const instrumentPostgresJs = generateInstrumentOnce(\n INTEGRATION_NAME,\n (options?: PostgresJsInstrumentationConfig) =>\n new PostgresJsInstrumentation({\n requireParentSpan: options?.requireParentSpan ?? true,\n requestHook: options?.requestHook,\n }),\n);\n\n/**\n * Instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n * This instrumentation captures postgresjs queries and their attributes.\n *\n * Uses internal Sentry patching patterns to support both CommonJS and ESM environments.\n */\nexport class PostgresJsInstrumentation extends InstrumentationBase<PostgresJsInstrumentationConfig> {\n public constructor(config: PostgresJsInstrumentationConfig) {\n super('sentry-postgres-js', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by patching the postgres module.\n * Uses two complementary approaches:\n * 1. Main function wrapper: instruments sql instances created AFTER instrumentation is set up (CJS + ESM)\n * 2. Query.prototype patch: fallback for sql instances created BEFORE instrumentation (CJS only)\n */\n public init(): InstrumentationNodeModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition(\n 'postgres',\n SUPPORTED_VERSIONS,\n exports => {\n try {\n return this._patchPostgres(exports);\n } catch (e) {\n DEBUG_BUILD && debug.error('Failed to patch postgres module:', e);\n return exports;\n }\n },\n exports => exports,\n );\n\n // Add fallback Query.prototype patching for pre-existing sql instances (CJS only)\n // This catches queries from sql instances created before Sentry was initialized\n ['src', 'cf/src', 'cjs/src'].forEach(path => {\n module.files.push(\n new InstrumentationNodeModuleFile(\n `postgres/${path}/query.js`,\n SUPPORTED_VERSIONS,\n this._patchQueryPrototype.bind(this),\n this._unpatchQueryPrototype.bind(this),\n ),\n );\n });\n\n return module;\n }\n\n /**\n * Patches the postgres module by wrapping the main export function.\n * This intercepts the creation of sql instances and instruments them.\n */\n private _patchPostgres(exports: { [key: string]: unknown }): { [key: string]: unknown } {\n // In CJS: exports is the function itself\n // In ESM: exports.default is the function\n const isFunction = typeof exports === 'function';\n const Original = isFunction ? exports : exports.default;\n\n if (typeof Original !== 'function') {\n DEBUG_BUILD && debug.warn('postgres module does not export a function. Skipping instrumentation.');\n return exports;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n\n const WrappedPostgres = function (this: unknown, ...args: unknown[]): unknown {\n const sql = Reflect.construct(Original as (...args: unknown[]) => unknown, args);\n\n // Validate that construction succeeded and returned a valid function object\n if (!sql || typeof sql !== 'function') {\n DEBUG_BUILD && debug.warn('postgres() did not return a valid instance');\n return sql;\n }\n\n // Delegate to the portable instrumentation from @sentry/core\n const config = self.getConfig();\n return instrumentPostgresJsSql(sql, {\n requireParentSpan: config.requireParentSpan,\n requestHook: config.requestHook,\n });\n };\n\n Object.setPrototypeOf(WrappedPostgres, Original);\n Object.setPrototypeOf(WrappedPostgres.prototype, (Original as { prototype: object }).prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedPostgres, key, descriptor);\n }\n }\n }\n\n // For CJS: the exports object IS the function, so return the wrapped function\n // For ESM: replace the default export\n if (isFunction) {\n return WrappedPostgres as unknown as { [key: string]: unknown };\n } else {\n replaceExports(exports, 'default', WrappedPostgres);\n return exports;\n }\n }\n\n /**\n * Determines whether a span should be created based on the current context.\n * If `requireParentSpan` is set to true in the configuration, a span will\n * only be created if there is a parent span available.\n */\n private _shouldCreateSpans(): boolean {\n const config = this.getConfig();\n const hasParentSpan = trace.getSpan(context.active()) !== undefined;\n return hasParentSpan || !config.requireParentSpan;\n }\n\n /**\n * Extracts DB operation name from SQL query and sets it on the span.\n */\n private _setOperationName(span: Span, sanitizedQuery: string | undefined, command?: string): void {\n if (command) {\n span.setAttribute(ATTR_DB_OPERATION_NAME, command);\n return;\n }\n // Fallback: extract operation from the SQL query\n const operationMatch = sanitizedQuery?.match(SQL_OPERATION_REGEX);\n if (operationMatch?.[1]) {\n span.setAttribute(ATTR_DB_OPERATION_NAME, operationMatch[1].toUpperCase());\n }\n }\n\n /**\n * Reconstructs the full SQL query from template strings with PostgreSQL placeholders.\n *\n * For sql`SELECT * FROM users WHERE id = ${123} AND name = ${'foo'}`:\n * strings = [\"SELECT * FROM users WHERE id = \", \" AND name = \", \"\"]\n * returns: \"SELECT * FROM users WHERE id = $1 AND name = $2\"\n */\n private _reconstructQuery(strings: string[] | undefined): string | undefined {\n if (!strings?.length) {\n return undefined;\n }\n if (strings.length === 1) {\n return strings[0] || undefined;\n }\n // Join template parts with PostgreSQL placeholders ($1, $2, etc.)\n return strings.reduce((acc, str, i) => (i === 0 ? str : `${acc}$${i}${str}`), '');\n }\n\n /**\n * Sanitize SQL query as per the OTEL semantic conventions\n * https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext\n *\n * PostgreSQL $n placeholders are preserved per OTEL spec - they're parameterized queries,\n * not sensitive literals. Only actual values (strings, numbers, booleans) are sanitized.\n */\n private _sanitizeSqlQuery(sqlQuery: string | undefined): string {\n if (!sqlQuery) {\n return 'Unknown SQL Query';\n }\n\n return (\n sqlQuery\n // Remove comments first (they may contain newlines and extra spaces)\n .replace(/--.*$/gm, '') // Single line comments (multiline mode)\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Multi-line comments\n .replace(/;\\s*$/, '') // Remove trailing semicolons\n // Collapse whitespace to a single space (after removing comments)\n .replace(/\\s+/g, ' ')\n .trim() // Remove extra spaces and trim\n // Sanitize hex/binary literals before string literals\n .replace(/\\bX'[0-9A-Fa-f]*'/gi, '?') // Hex string literals\n .replace(/\\bB'[01]*'/gi, '?') // Binary string literals\n // Sanitize string literals (handles escaped quotes)\n .replace(/'(?:[^']|'')*'/g, '?')\n // Sanitize hex numbers\n .replace(/\\b0x[0-9A-Fa-f]+/gi, '?')\n // Sanitize boolean literals\n .replace(/\\b(?:TRUE|FALSE)\\b/gi, '?')\n // Sanitize numeric literals (preserve $n placeholders via negative lookbehind)\n .replace(/-?\\b\\d+\\.?\\d*[eE][+-]?\\d+\\b/g, '?') // Scientific notation\n .replace(/-?\\b\\d+\\.\\d+\\b/g, '?') // Decimals\n .replace(/-?\\.\\d+\\b/g, '?') // Decimals starting with dot\n .replace(/(?<!\\$)-?\\b\\d+\\b/g, '?') // Integers (NOT $n placeholders)\n // Collapse IN clauses for cardinality (both ? and $n variants)\n .replace(/\\bIN\\b\\s*\\(\\s*\\?(?:\\s*,\\s*\\?)*\\s*\\)/gi, 'IN (?)')\n .replace(/\\bIN\\b\\s*\\(\\s*\\$\\d+(?:\\s*,\\s*\\$\\d+)*\\s*\\)/gi, 'IN ($?)')\n );\n }\n\n /**\n * Fallback patch for Query.prototype.handle to instrument queries from pre-existing sql instances.\n * This catches queries from sql instances created BEFORE Sentry was initialized (CJS only).\n *\n * Note: Queries from pre-existing instances won't have connection context (database, host, port)\n * because the sql instance wasn't created through our instrumented wrapper.\n */\n private _patchQueryPrototype(moduleExports: {\n Query: {\n prototype: {\n handle: ((...args: unknown[]) => Promise<unknown>) & {\n __sentry_original__?: (...args: unknown[]) => Promise<unknown>;\n };\n };\n };\n }): typeof moduleExports {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n const originalHandle = moduleExports.Query.prototype.handle;\n\n moduleExports.Query.prototype.handle = async function (\n this: {\n resolve: unknown;\n reject: unknown;\n strings?: string[];\n },\n ...args: unknown[]\n ): Promise<unknown> {\n // Skip if this query came from an instrumented sql instance (already handled by wrapper)\n if ((this as Record<symbol, unknown>)[QUERY_FROM_INSTRUMENTED_SQL]) {\n return originalHandle.apply(this, args);\n }\n\n // Skip if we shouldn't create spans\n if (!self._shouldCreateSpans()) {\n return originalHandle.apply(this, args);\n }\n\n const fullQuery = self._reconstructQuery(this.strings);\n const sanitizedSqlQuery = self._sanitizeSqlQuery(fullQuery);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n addOriginToSpan(span, 'auto.db.postgresjs');\n\n span.setAttributes({\n [ATTR_DB_SYSTEM_NAME]: 'postgres',\n [ATTR_DB_QUERY_TEXT]: sanitizedSqlQuery,\n });\n\n // Note: No connection context available for pre-existing instances\n // because the sql instance wasn't created through our instrumented wrapper\n\n const config = self.getConfig();\n const { requestHook } = config;\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, sanitizedSqlQuery, undefined),\n e => {\n if (e) {\n span.setAttribute('sentry.hook.error', 'requestHook failed');\n DEBUG_BUILD && debug.error(`Error in requestHook for ${INTEGRATION_NAME} integration:`, e);\n }\n },\n true,\n );\n }\n\n // Wrap resolve to end span on success\n const originalResolve = this.resolve;\n this.resolve = new Proxy(originalResolve as (...args: unknown[]) => unknown, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n try {\n self._setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e);\n }\n return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n },\n });\n\n // Wrap reject to end span on error\n const originalReject = this.reject;\n this.reject = new Proxy(originalReject as (...args: unknown[]) => unknown, {\n apply: (rejectTarget, rejectThisArg, rejectArgs: { message?: string; code?: string; name?: string }[]) => {\n try {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: rejectArgs?.[0]?.message || 'unknown_error',\n });\n span.setAttribute(ATTR_DB_RESPONSE_STATUS_CODE, rejectArgs?.[0]?.code || 'unknown');\n span.setAttribute(ATTR_ERROR_TYPE, rejectArgs?.[0]?.name || 'unknown');\n self._setOperationName(span, sanitizedSqlQuery);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in reject callback:', e);\n }\n return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n },\n });\n\n try {\n return originalHandle.apply(this, args);\n } catch (e) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: e instanceof Error ? e.message : 'unknown_error',\n });\n span.end();\n throw e;\n }\n },\n );\n };\n\n // Store original for unpatch - must be set on the NEW patched function\n moduleExports.Query.prototype.handle.__sentry_original__ = originalHandle;\n\n return moduleExports;\n }\n\n /**\n * Restores the original Query.prototype.handle method.\n */\n private _unpatchQueryPrototype(moduleExports: {\n Query: {\n prototype: {\n handle: ((...args: unknown[]) => Promise<unknown>) & {\n __sentry_original__?: (...args: unknown[]) => Promise<unknown>;\n };\n };\n };\n }): typeof moduleExports {\n if (moduleExports.Query.prototype.handle.__sentry_original__) {\n moduleExports.Query.prototype.handle = moduleExports.Query.prototype.handle.__sentry_original__;\n }\n return moduleExports;\n }\n}\n\nconst _postgresJsIntegration = ((options?: PostgresJsInstrumentationConfig) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPostgresJs(options);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n *\n * For more information, see the [`postgresIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/postgres/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.postgresJsIntegration()],\n * });\n * ```\n */\n\nexport const postgresJsIntegration = defineIntegration(_postgresJsIntegration);\n"],"names":["exports"],"mappings":"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"}
|
package/build/esm/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"module","version":"10.
|
|
1
|
+
{"type":"module","version":"10.42.0","sideEffects":false}
|
|
@@ -43,44 +43,16 @@ export declare class PostgresJsInstrumentation extends InstrumentationBase<Postg
|
|
|
43
43
|
* This intercepts the creation of sql instances and instruments them.
|
|
44
44
|
*/
|
|
45
45
|
private _patchPostgres;
|
|
46
|
-
/**
|
|
47
|
-
* Wraps query-returning methods (unsafe, file) to ensure their queries are instrumented.
|
|
48
|
-
*/
|
|
49
|
-
private _wrapQueryMethod;
|
|
50
|
-
/**
|
|
51
|
-
* Wraps callback-based methods (begin, reserve) to recursively instrument Sql instances.
|
|
52
|
-
* Note: These methods can also be used as tagged templates, which we pass through unchanged.
|
|
53
|
-
*
|
|
54
|
-
* Savepoint is not wrapped to avoid complex nested transaction instrumentation issues.
|
|
55
|
-
* Queries within savepoint callbacks are still instrumented through the parent transaction's Sql instance.
|
|
56
|
-
*/
|
|
57
|
-
private _wrapCallbackMethod;
|
|
58
|
-
/**
|
|
59
|
-
* Sets connection context attributes on a span.
|
|
60
|
-
*/
|
|
61
|
-
private _setConnectionAttributes;
|
|
62
|
-
/**
|
|
63
|
-
* Extracts DB operation name from SQL query and sets it on the span.
|
|
64
|
-
*/
|
|
65
|
-
private _setOperationName;
|
|
66
|
-
/**
|
|
67
|
-
* Extracts and stores connection context from sql.options.
|
|
68
|
-
*/
|
|
69
|
-
private _attachConnectionContext;
|
|
70
|
-
/**
|
|
71
|
-
* Instruments a sql instance by wrapping its query execution methods.
|
|
72
|
-
*/
|
|
73
|
-
private _instrumentSqlInstance;
|
|
74
|
-
/**
|
|
75
|
-
* Wraps a single query's handle method to create spans.
|
|
76
|
-
*/
|
|
77
|
-
private _wrapSingleQueryHandle;
|
|
78
46
|
/**
|
|
79
47
|
* Determines whether a span should be created based on the current context.
|
|
80
48
|
* If `requireParentSpan` is set to true in the configuration, a span will
|
|
81
49
|
* only be created if there is a parent span available.
|
|
82
50
|
*/
|
|
83
51
|
private _shouldCreateSpans;
|
|
52
|
+
/**
|
|
53
|
+
* Extracts DB operation name from SQL query and sets it on the span.
|
|
54
|
+
*/
|
|
55
|
+
private _setOperationName;
|
|
84
56
|
/**
|
|
85
57
|
* Reconstructs the full SQL query from template strings with PostgreSQL placeholders.
|
|
86
58
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgresjs.d.ts","sourceRoot":"","sources":["../../../../src/integrations/tracing/postgresjs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"postgresjs.d.ts","sourceRoot":"","sources":["../../../../src/integrations/tracing/postgresjs.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EACL,mBAAmB,EACnB,mCAAmC,EAGpC,MAAM,gCAAgC,CAAC;AAQxC,OAAO,KAAK,EAAiB,IAAI,EAAE,MAAM,cAAc,CAAC;AAiBxD,KAAK,yBAAyB,GAAG;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAMF,KAAK,+BAA+B,GAAG,qBAAqB,GAAG;IAC7D;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,yBAAyB,CAAC,EAAE,yBAAyB,KAAK,IAAI,CAAC;CACtH,CAAC;AAEF,eAAO,MAAM,oBAAoB;;CAOhC,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,yBAA0B,SAAQ,mBAAmB,CAAC,+BAA+B,CAAC;gBAC9E,MAAM,EAAE,+BAA+B;IAI1D;;;;;OAKG;IACI,IAAI,IAAI,mCAAmC;IA+BlD;;;OAGG;IACH,OAAO,CAAC,cAAc;IAqDtB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAkCzB;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAuH5B;;OAEG;IACH,OAAO,CAAC,sBAAsB;CAc/B;AAWD;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,qBAAqB,+FAA4C,CAAC"}
|
|
@@ -43,44 +43,16 @@ export declare class PostgresJsInstrumentation extends InstrumentationBase<Postg
|
|
|
43
43
|
* This intercepts the creation of sql instances and instruments them.
|
|
44
44
|
*/
|
|
45
45
|
private _patchPostgres;
|
|
46
|
-
/**
|
|
47
|
-
* Wraps query-returning methods (unsafe, file) to ensure their queries are instrumented.
|
|
48
|
-
*/
|
|
49
|
-
private _wrapQueryMethod;
|
|
50
|
-
/**
|
|
51
|
-
* Wraps callback-based methods (begin, reserve) to recursively instrument Sql instances.
|
|
52
|
-
* Note: These methods can also be used as tagged templates, which we pass through unchanged.
|
|
53
|
-
*
|
|
54
|
-
* Savepoint is not wrapped to avoid complex nested transaction instrumentation issues.
|
|
55
|
-
* Queries within savepoint callbacks are still instrumented through the parent transaction's Sql instance.
|
|
56
|
-
*/
|
|
57
|
-
private _wrapCallbackMethod;
|
|
58
|
-
/**
|
|
59
|
-
* Sets connection context attributes on a span.
|
|
60
|
-
*/
|
|
61
|
-
private _setConnectionAttributes;
|
|
62
|
-
/**
|
|
63
|
-
* Extracts DB operation name from SQL query and sets it on the span.
|
|
64
|
-
*/
|
|
65
|
-
private _setOperationName;
|
|
66
|
-
/**
|
|
67
|
-
* Extracts and stores connection context from sql.options.
|
|
68
|
-
*/
|
|
69
|
-
private _attachConnectionContext;
|
|
70
|
-
/**
|
|
71
|
-
* Instruments a sql instance by wrapping its query execution methods.
|
|
72
|
-
*/
|
|
73
|
-
private _instrumentSqlInstance;
|
|
74
|
-
/**
|
|
75
|
-
* Wraps a single query's handle method to create spans.
|
|
76
|
-
*/
|
|
77
|
-
private _wrapSingleQueryHandle;
|
|
78
46
|
/**
|
|
79
47
|
* Determines whether a span should be created based on the current context.
|
|
80
48
|
* If `requireParentSpan` is set to true in the configuration, a span will
|
|
81
49
|
* only be created if there is a parent span available.
|
|
82
50
|
*/
|
|
83
51
|
private _shouldCreateSpans;
|
|
52
|
+
/**
|
|
53
|
+
* Extracts DB operation name from SQL query and sets it on the span.
|
|
54
|
+
*/
|
|
55
|
+
private _setOperationName;
|
|
84
56
|
/**
|
|
85
57
|
* Reconstructs the full SQL query from template strings with PostgreSQL placeholders.
|
|
86
58
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/node",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.42.0",
|
|
4
4
|
"description": "Sentry Node SDK using OpenTelemetry for performance instrumentation",
|
|
5
5
|
"repository": "git://github.com/getsentry/sentry-javascript.git",
|
|
6
6
|
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node",
|
|
@@ -96,9 +96,9 @@
|
|
|
96
96
|
"@opentelemetry/semantic-conventions": "^1.39.0",
|
|
97
97
|
"@prisma/instrumentation": "7.2.0",
|
|
98
98
|
"@fastify/otel": "0.16.0",
|
|
99
|
-
"@sentry/core": "10.
|
|
100
|
-
"@sentry/node-core": "10.
|
|
101
|
-
"@sentry/opentelemetry": "10.
|
|
99
|
+
"@sentry/core": "10.42.0",
|
|
100
|
+
"@sentry/node-core": "10.42.0",
|
|
101
|
+
"@sentry/opentelemetry": "10.42.0",
|
|
102
102
|
"import-in-the-middle": "^2.0.6"
|
|
103
103
|
},
|
|
104
104
|
"devDependencies": {
|