From 4725d22a642ec22d3c8f9414c8fb9b24f7513c1f Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 15 Jul 2025 15:07:40 +0200 Subject: [PATCH 1/3] feat: Avoid usage of `any` This makes the lint rule error, instead of warn, and gets rid of some more any usage. Some of that may technically be breaking because the types can be exposed, but this should be very unlikely to affect any users. --- packages/core/src/fetch.ts | 5 ++- packages/core/src/integrations/supabase.ts | 33 ++++++++++------- packages/core/src/profiling.ts | 1 + packages/core/src/types-hoist/breadcrumb.ts | 10 ++++-- packages/core/src/types-hoist/context.ts | 4 +-- packages/core/src/types-hoist/error.ts | 2 +- packages/core/src/types-hoist/event.ts | 2 +- .../core/src/types-hoist/feedback/config.ts | 5 +-- packages/core/src/types-hoist/instrument.ts | 4 +-- packages/core/src/types-hoist/integration.ts | 1 + packages/core/src/types-hoist/misc.ts | 2 +- packages/core/src/types-hoist/polymorphics.ts | 8 ++--- .../core/src/types-hoist/samplingcontext.ts | 2 +- packages/core/src/types-hoist/stackframe.ts | 4 +-- packages/core/src/types-hoist/user.ts | 2 +- packages/core/src/utils/aggregate-errors.ts | 11 +++--- packages/core/src/utils/eventbuilder.ts | 2 +- packages/core/src/utils/is.ts | 2 +- packages/eslint-config-sdk/src/base.js | 3 ++ packages/feedback/src/modal/integration.tsx | 7 ++-- packages/nextjs/src/config/types.ts | 3 +- packages/nextjs/src/edge/index.ts | 2 +- .../src/integrations/tracing/fastify/types.ts | 2 ++ .../tracing/fastify/v3/instrumentation.ts | 36 +++++++++++-------- .../integrations/tracing/fastify/v3/types.ts | 1 + .../integrations/tracing/fastify/v3/utils.ts | 2 +- .../src/integrations/tracing/postgresjs.ts | 19 ++++++---- packages/remix/src/utils/types.ts | 1 + packages/remix/src/vendor/instrumentation.ts | 1 + .../src/coreHandlers/handleBreadcrumbs.ts | 3 +- .../coreHandlers/handleNetworkBreadcrumbs.ts | 4 +-- packages/replay-internal/src/types/rrweb.ts | 2 ++ packages/vue/src/pinia.ts | 5 +-- 33 files changed, 117 insertions(+), 74 deletions(-) diff --git a/packages/core/src/fetch.ts b/packages/core/src/fetch.ts index 502e24711994..cea442b39262 100644 --- a/packages/core/src/fetch.ts +++ b/packages/core/src/fetch.ts @@ -66,9 +66,8 @@ export function instrumentFetchRequest( spans[span.spanContext().spanId] = span; if (shouldAttachHeaders(handlerData.fetchData.url)) { - const request: string | Request = handlerData.args[0]; - - const options: { [key: string]: unknown } = handlerData.args[1] || {}; + const request = handlerData.args[0] as string | Request; + const options = (handlerData.args[1] || {}) as Record; const headers = _addTracingHeadersToFetchRequest( request, diff --git a/packages/core/src/integrations/supabase.ts b/packages/core/src/integrations/supabase.ts index 360f31142652..97afab1d50a4 100644 --- a/packages/core/src/integrations/supabase.ts +++ b/packages/core/src/integrations/supabase.ts @@ -10,6 +10,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from ' import { setHttpStatus, SPAN_STATUS_ERROR, SPAN_STATUS_OK, startSpan } from '../tracing'; import type { IntegrationFn } from '../types-hoist/integration'; import { debug } from '../utils/debug-logger'; +import type { SpanAttributes } from '../types-hoist/span'; import { isPlainObject } from '../utils/is'; const AUTH_OPERATIONS_TO_INSTRUMENT = [ @@ -64,7 +65,8 @@ export const FILTER_MAPPINGS = { not: 'not', }; -export const DB_OPERATIONS_TO_INSTRUMENT = ['select', 'insert', 'upsert', 'update', 'delete']; +export const DB_OPERATIONS_TO_INSTRUMENT = ['select', 'insert', 'upsert', 'update', 'delete'] as const; +type DBOperation = (typeof DB_OPERATIONS_TO_INSTRUMENT)[number]; type AuthOperationFn = (...args: unknown[]) => Promise; type AuthOperationName = (typeof AUTH_OPERATIONS_TO_INSTRUMENT)[number]; @@ -86,7 +88,7 @@ export interface PostgRESTFilterBuilder { headers: Record; url: URL; schema: string; - body: any; + body: unknown; } export interface SupabaseResponse { @@ -122,7 +124,7 @@ export interface SupabaseClientConstructor { export interface PostgRESTProtoThenable { then: ( onfulfilled?: ((value: T) => T | PromiseLike) | null, - onrejected?: ((reason: any) => T | PromiseLike) | null, + onrejected?: ((reason: unknown) => T | PromiseLike) | null, ) => Promise; } @@ -152,7 +154,7 @@ function isInstrumented(fn: T): boolean | undefined { * @param headers - The request headers * @returns The database operation type ('select', 'insert', 'upsert', 'update', or 'delete') */ -export function extractOperation(method: string, headers: Record = {}): string { +export function extractOperation(method: string, headers: Record = {}): DBOperation | '' { switch (method) { case 'GET': { return 'select'; @@ -333,7 +335,7 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte const typedThis = thisArg as PostgRESTFilterBuilder; const operation = extractOperation(typedThis.method, typedThis.headers); - if (!operations.includes(operation)) { + if (!operations.includes(operation as DBOperation)) { return Reflect.apply(target, thisArg, argumentsList); } @@ -364,7 +366,7 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte ' ', )} from(${table})`; - const attributes: Record = { + const attributes: SpanAttributes = { 'db.table': table, 'db.schema': typedThis.schema, 'db.url': typedThis.url.origin, @@ -380,7 +382,11 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte } if (Object.keys(body).length) { - attributes['db.body'] = body; + try { + attributes['db.body'] = JSON.stringify(body); + } catch { + // could not stringify body + } } return startSpan( @@ -465,17 +471,19 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte markAsInstrumented((PostgRESTFilterBuilder.prototype as unknown as PostgRESTProtoThenable).then); } +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type BuilderPrototype = Record any>; + function instrumentPostgRESTQueryBuilder(PostgRESTQueryBuilder: new () => PostgRESTQueryBuilder): void { // We need to wrap _all_ operations despite them sharing the same `PostgRESTFilterBuilder` // constructor, as we don't know which method will be called first, and we don't want to miss any calls. for (const operation of DB_OPERATIONS_TO_INSTRUMENT) { - if (isInstrumented((PostgRESTQueryBuilder.prototype as Record)[operation])) { + if (isInstrumented((PostgRESTQueryBuilder.prototype as BuilderPrototype)[operation])) { continue; } - type PostgRESTOperation = keyof Pick; - (PostgRESTQueryBuilder.prototype as Record)[operation as PostgRESTOperation] = new Proxy( - (PostgRESTQueryBuilder.prototype as Record)[operation as PostgRESTOperation], + (PostgRESTQueryBuilder.prototype as BuilderPrototype)[operation] = new Proxy( + (PostgRESTQueryBuilder.prototype as BuilderPrototype)[operation], { apply(target, thisArg, argumentsList) { const rv = Reflect.apply(target, thisArg, argumentsList); @@ -490,7 +498,7 @@ function instrumentPostgRESTQueryBuilder(PostgRESTQueryBuilder: new () => PostgR }, ); - markAsInstrumented((PostgRESTQueryBuilder.prototype as Record)[operation]); + markAsInstrumented((PostgRESTQueryBuilder.prototype as BuilderPrototype)[operation]); } } @@ -517,6 +525,7 @@ const _supabaseIntegration = ((supabaseClient: unknown) => { }; }) satisfies IntegrationFn; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const supabaseIntegration = defineIntegration((options: { supabaseClient: any }) => { return _supabaseIntegration(options.supabaseClient); }) satisfies IntegrationFn; diff --git a/packages/core/src/profiling.ts b/packages/core/src/profiling.ts index 407c4a07c53c..5fb74b02816e 100644 --- a/packages/core/src/profiling.ts +++ b/packages/core/src/profiling.ts @@ -1,3 +1,4 @@ +import type { Client } from './client'; import { getClient } from './currentScopes'; import { DEBUG_BUILD } from './debug-build'; import type { Profiler, ProfilingIntegration } from './types-hoist/profiling'; diff --git a/packages/core/src/types-hoist/breadcrumb.ts b/packages/core/src/types-hoist/breadcrumb.ts index 1c5bef4bc49a..aa731d131264 100644 --- a/packages/core/src/types-hoist/breadcrumb.ts +++ b/packages/core/src/types-hoist/breadcrumb.ts @@ -52,7 +52,10 @@ export interface Breadcrumb { * * @summary Arbitrary data associated with this breadcrumb. */ - data?: { [key: string]: any }; + // Note: we cannot use Record here because it's not compatible with interface data types + // See: https://github.com/microsoft/TypeScript/issues/15300 + // eslint-disable-next-line @typescript-eslint/no-explicit-any + data?: Record; /** * The format is a numeric (integer or float) value representing @@ -70,6 +73,9 @@ export interface Breadcrumb { /** JSDoc */ export interface BreadcrumbHint { + // Note: we cannot use unknown here because it's not compatible with interface data types + // See: https://github.com/microsoft/TypeScript/issues/15300 + // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; } @@ -90,7 +96,7 @@ export interface XhrBreadcrumbData { } export interface FetchBreadcrumbHint { - input: any[]; + input: unknown[]; data?: unknown; response?: unknown; startTimestamp: number; diff --git a/packages/core/src/types-hoist/context.ts b/packages/core/src/types-hoist/context.ts index a3673f84a968..5c09373caada 100644 --- a/packages/core/src/types-hoist/context.ts +++ b/packages/core/src/types-hoist/context.ts @@ -1,7 +1,7 @@ import type { FeatureFlag } from '../utils/featureFlags'; import type { SpanLinkJSON } from './link'; import type { Primitive } from './misc'; -import type { SpanOrigin } from './span'; +import type { SpanAttributes, SpanOrigin } from './span'; export type Context = Record; @@ -99,7 +99,7 @@ export interface ResponseContext extends Record { } export interface TraceContext extends Record { - data?: { [key: string]: any }; + data?: SpanAttributes; op?: string; parent_span_id?: string; span_id: string; diff --git a/packages/core/src/types-hoist/error.ts b/packages/core/src/types-hoist/error.ts index d94becdbaf1f..df67cf898f41 100644 --- a/packages/core/src/types-hoist/error.ts +++ b/packages/core/src/types-hoist/error.ts @@ -2,5 +2,5 @@ * Just an Error object with arbitrary attributes attached to it. */ export interface ExtendedError extends Error { - [key: string]: any; + [key: string]: unknown; } diff --git a/packages/core/src/types-hoist/event.ts b/packages/core/src/types-hoist/event.ts index a042edad2cda..1452c15611f4 100644 --- a/packages/core/src/types-hoist/event.ts +++ b/packages/core/src/types-hoist/event.ts @@ -83,6 +83,6 @@ export interface EventHint { syntheticException?: Error | null; originalException?: unknown; attachments?: Attachment[]; - data?: any; + data?: unknown; integrations?: string[]; } diff --git a/packages/core/src/types-hoist/feedback/config.ts b/packages/core/src/types-hoist/feedback/config.ts index 49bc7231e9e2..8b6cdb7653e7 100644 --- a/packages/core/src/types-hoist/feedback/config.ts +++ b/packages/core/src/types-hoist/feedback/config.ts @@ -1,4 +1,5 @@ import type { Primitive } from '../misc'; +import type { User } from '../user'; import type { FeedbackFormData } from './form'; import type { FeedbackTheme } from './theme'; @@ -53,8 +54,8 @@ export interface FeedbackGeneralConfiguration { * The value of the email/name keys represent the properties of your user context. */ useSentryUser: { - email: string; - name: string; + email: keyof User; + name: keyof User; }; /** diff --git a/packages/core/src/types-hoist/instrument.ts b/packages/core/src/types-hoist/instrument.ts index b067f6618558..d3750eb970d8 100644 --- a/packages/core/src/types-hoist/instrument.ts +++ b/packages/core/src/types-hoist/instrument.ts @@ -47,7 +47,7 @@ interface SentryFetchData { } export interface HandlerDataFetch { - args: any[]; + args: unknown[]; fetchData: SentryFetchData; // This data is among other things dumped directly onto the fetch breadcrumb data startTimestamp: number; endTimestamp?: number; @@ -74,7 +74,7 @@ export interface HandlerDataDom { export interface HandlerDataConsole { level: ConsoleLevel; - args: any[]; + args: unknown[]; } export interface HandlerDataHistory { diff --git a/packages/core/src/types-hoist/integration.ts b/packages/core/src/types-hoist/integration.ts index cc9e4bc580ce..120cb1acc884 100644 --- a/packages/core/src/types-hoist/integration.ts +++ b/packages/core/src/types-hoist/integration.ts @@ -47,4 +47,5 @@ export interface Integration { * An integration in function form. * This is expected to return an integration. */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type IntegrationFn = (...rest: any[]) => IntegrationType; diff --git a/packages/core/src/types-hoist/misc.ts b/packages/core/src/types-hoist/misc.ts index af9ed8fc6bd7..162e49b4b67f 100644 --- a/packages/core/src/types-hoist/misc.ts +++ b/packages/core/src/types-hoist/misc.ts @@ -4,7 +4,7 @@ import type { QueryParams } from './request'; * Data extracted from an incoming request to a node server */ export interface ExtractedNodeRequestData { - [key: string]: any; + [key: string]: unknown; /** Specific headers from the request */ headers?: { [key: string]: string }; diff --git a/packages/core/src/types-hoist/polymorphics.ts b/packages/core/src/types-hoist/polymorphics.ts index 88abf7770b2c..8b3a3ca4f8bb 100644 --- a/packages/core/src/types-hoist/polymorphics.ts +++ b/packages/core/src/types-hoist/polymorphics.ts @@ -50,13 +50,13 @@ type NextjsRequest = NodeRequest & { [key: string]: string; }; query?: { - [key: string]: any; + [key: string]: unknown; }; }; type ExpressRequest = NodeRequest & { baseUrl?: string; - body?: string | { [key: string]: any }; + body?: string | { [key: string]: unknown }; host?: string; hostname?: string; ip?: string; @@ -70,10 +70,10 @@ type ExpressRequest = NodeRequest & { ]; }; query?: { - [key: string]: any; + [key: string]: unknown; }; user?: { - [key: string]: any; + [key: string]: unknown; }; _reconstructedRoute?: string; }; diff --git a/packages/core/src/types-hoist/samplingcontext.ts b/packages/core/src/types-hoist/samplingcontext.ts index b0a52862870c..20b4de8b5125 100644 --- a/packages/core/src/types-hoist/samplingcontext.ts +++ b/packages/core/src/types-hoist/samplingcontext.ts @@ -6,7 +6,7 @@ import type { SpanAttributes } from './span'; * Context data passed by the user when starting a transaction, to be used by the tracesSampler method. */ export interface CustomSamplingContext { - [key: string]: any; + [key: string]: unknown; } /** diff --git a/packages/core/src/types-hoist/stackframe.ts b/packages/core/src/types-hoist/stackframe.ts index 4f99f1ba3595..fb5f64ff131a 100644 --- a/packages/core/src/types-hoist/stackframe.ts +++ b/packages/core/src/types-hoist/stackframe.ts @@ -13,7 +13,7 @@ export interface StackFrame { in_app?: boolean; instruction_addr?: string; addr_mode?: string; - vars?: { [key: string]: any }; + vars?: { [key: string]: unknown }; debug_id?: string; - module_metadata?: any; + module_metadata?: unknown; } diff --git a/packages/core/src/types-hoist/user.ts b/packages/core/src/types-hoist/user.ts index 801fb66202b1..cb849acdab43 100644 --- a/packages/core/src/types-hoist/user.ts +++ b/packages/core/src/types-hoist/user.ts @@ -2,7 +2,7 @@ * An interface describing a user of an application or a handled request. */ export interface User { - [key: string]: any; + [key: string]: unknown; id?: string | number; ip_address?: string | null; email?: string; diff --git a/packages/core/src/utils/aggregate-errors.ts b/packages/core/src/utils/aggregate-errors.ts index f472e5b9968b..759e0446d2b1 100644 --- a/packages/core/src/utils/aggregate-errors.ts +++ b/packages/core/src/utils/aggregate-errors.ts @@ -55,16 +55,17 @@ function aggregateExceptionsFromError( let newExceptions = [...prevExceptions]; // Recursively call this function in order to walk down a chain of errors - if (isInstanceOf(error[key], Error)) { + const errorValue = error[key]; + if (isInstanceOf(errorValue, Error)) { applyExceptionGroupFieldsForParentException(exception, exceptionId); - const newException = exceptionFromErrorImplementation(parser, error[key]); + const newException = exceptionFromErrorImplementation(parser, errorValue); const newExceptionId = newExceptions.length; applyExceptionGroupFieldsForChildException(newException, key, newExceptionId, exceptionId); newExceptions = aggregateExceptionsFromError( exceptionFromErrorImplementation, parser, limit, - error[key], + errorValue as ExtendedError, key, [newException, ...newExceptions], newException, @@ -75,7 +76,7 @@ function aggregateExceptionsFromError( // This will create exception grouping for AggregateErrors // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError if (Array.isArray(error.errors)) { - error.errors.forEach((childError, i) => { + error.errors.forEach((childError: unknown, i) => { if (isInstanceOf(childError, Error)) { applyExceptionGroupFieldsForParentException(exception, exceptionId); const newException = exceptionFromErrorImplementation(parser, childError); @@ -85,7 +86,7 @@ function aggregateExceptionsFromError( exceptionFromErrorImplementation, parser, limit, - childError, + childError as ExtendedError, key, [newException, ...newExceptions], newException, diff --git a/packages/core/src/utils/eventbuilder.ts b/packages/core/src/utils/eventbuilder.ts index 24889187712f..51e6b2a76cc6 100644 --- a/packages/core/src/utils/eventbuilder.ts +++ b/packages/core/src/utils/eventbuilder.ts @@ -134,7 +134,7 @@ export function eventFromUnknownInput( exception: unknown, hint?: EventHint, ): Event { - const providedMechanism: Mechanism | undefined = hint?.data && (hint.data as { mechanism: Mechanism }).mechanism; + const providedMechanism = (hint?.data as { mechanism?: Mechanism })?.mechanism; const mechanism: Mechanism = providedMechanism || { handled: true, type: 'generic', diff --git a/packages/core/src/utils/is.ts b/packages/core/src/utils/is.ts index 9ec498983d4a..bd8760c4d971 100644 --- a/packages/core/src/utils/is.ts +++ b/packages/core/src/utils/is.ts @@ -179,7 +179,7 @@ export function isSyntheticEvent(wat: unknown): boolean { * @param base A constructor to be used in a check. * @returns A boolean representing the result. */ -export function isInstanceOf(wat: any, base: any): boolean { +export function isInstanceOf any>(wat: any, base: T): wat is InstanceType { try { return wat instanceof base; } catch { diff --git a/packages/eslint-config-sdk/src/base.js b/packages/eslint-config-sdk/src/base.js index 52334507ac8b..ca993e56dfb1 100644 --- a/packages/eslint-config-sdk/src/base.js +++ b/packages/eslint-config-sdk/src/base.js @@ -110,6 +110,9 @@ module.exports = { // We do not care about empty functions '@typescript-eslint/no-empty-function': 'off', + + // Disallow (instead of warn) for usage of any. + '@typescript-eslint/no-explicit-any': 'error', }, }, { diff --git a/packages/feedback/src/modal/integration.tsx b/packages/feedback/src/modal/integration.tsx index 5bdf4362509d..8ac49b35b88a 100644 --- a/packages/feedback/src/modal/integration.tsx +++ b/packages/feedback/src/modal/integration.tsx @@ -63,14 +63,17 @@ export const feedbackModalIntegration = ((): FeedbackModalIntegration => { const screenshotInput = screenshotIntegration?.createInput({ h, hooks, dialog, options }); const renderContent = (open: boolean): void => { + const defaultName = user?.[userKey.name]; + const defaultEmail = user?.[userKey.email]; + render( { renderContent(false); options.onFormClose?.(); diff --git a/packages/nextjs/src/config/types.ts b/packages/nextjs/src/config/types.ts index b29fbb6881af..a3b4013064a2 100644 --- a/packages/nextjs/src/config/types.ts +++ b/packages/nextjs/src/config/types.ts @@ -11,7 +11,8 @@ type NextRewrite = { }; interface WebpackPluginInstance { - [index: string]: any; + [index: string]: unknown; + // eslint-disable-next-line @typescript-eslint/no-explicit-any apply: (compiler: any) => void; } diff --git a/packages/nextjs/src/edge/index.ts b/packages/nextjs/src/edge/index.ts index 7982667f0c3f..f4bfb275cb1f 100644 --- a/packages/nextjs/src/edge/index.ts +++ b/packages/nextjs/src/edge/index.ts @@ -80,7 +80,7 @@ export function init(options: VercelEdgeOptions = {}): void { if ( event.type === 'transaction' && event.contexts?.trace?.data?.['next.span_type'] === 'Middleware.execute' && - event.contexts?.trace?.data?.['next.span_name'] + typeof event.contexts?.trace?.data?.['next.span_name'] === 'string' ) { if (event.transaction) { event.transaction = stripUrlQueryAndFragment(event.contexts.trace.data['next.span_name']); diff --git a/packages/node/src/integrations/tracing/fastify/types.ts b/packages/node/src/integrations/tracing/fastify/types.ts index e15c1c85324b..d88e36f6c702 100644 --- a/packages/node/src/integrations/tracing/fastify/types.ts +++ b/packages/node/src/integrations/tracing/fastify/types.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + export type HandlerOriginal = | ((request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction) => Promise) | ((request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction) => void); diff --git a/packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts b/packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts index 7b8035927a11..dd7acd7e3c0d 100644 --- a/packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts +++ b/packages/node/src/integrations/tracing/fastify/v3/instrumentation.ts @@ -96,11 +96,9 @@ export class FastifyInstrumentationV3 extends InstrumentationBase { + return function (this: unknown, ...args: unknown[]): Promise { if (!instrumentation.isEnabled()) { return original.apply(this, args); } @@ -175,10 +173,10 @@ export class FastifyInstrumentationV3 extends InstrumentationBase return function (original: FastifyInstance['addHook']): () => FastifyInstance { - return function wrappedAddHook(this: any, ...args: any) { + return function wrappedAddHook(this: { pluginName?: string }, ...args: unknown[]) { const name = args[0] as string; const handler = args[1] as HandlerOriginal; - const pluginName = this.pluginName; + const pluginName = this.pluginName || ANONYMOUS_NAME; if (!hooksNamesToWrap.has(name)) { return original.apply(this, args); } @@ -200,7 +198,7 @@ export class FastifyInstrumentationV3 extends InstrumentationBase FastifyInstance { const instrumentation = this; - function fastify(this: FastifyInstance, ...args: any) { + function fastify(this: FastifyInstance, ...args: unknown[]) { const app: FastifyInstance = moduleExports.fastify.apply(this, args); app.addHook('onRequest', instrumentation._hookOnRequest()); app.addHook('preHandler', instrumentation._hookPreHandler()); @@ -225,8 +223,8 @@ export class FastifyInstrumentationV3 extends InstrumentationBase FastifyReply): () => FastifyReply { - return function send(this: FastifyReply, ...args: any) { - const maybeError: any = args[0]; + return function send(this: FastifyReply, ...args: unknown[]) { + const maybeError = args[0]; if (!instrumentation.isEnabled()) { return original.apply(this, args); @@ -252,13 +250,21 @@ export class FastifyInstrumentationV3 extends InstrumentationBase=3.0.0 <4']; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type ResolveRejectFunction = (...args: any[]) => any; + type PostgresConnectionContext = { ATTR_DB_NAMESPACE?: string; // Database name ATTR_SERVER_ADDRESS?: string; // Hostname or IP address of the database server @@ -113,7 +116,7 @@ export class PostgresJsInstrumentation extends InstrumentationBase { const result = Reflect.apply(resolveTarget, resolveThisArg, resolveArgs); @@ -170,16 +173,17 @@ export class PostgresJsInstrumentation extends InstrumentationBase any; }; }; - }): any { + }): unknown { moduleExports.Query.prototype.handle = new Proxy(moduleExports.Query.prototype.handle, { apply: async ( handleTarget, handleThisArg: { - resolve: any; - reject: any; + resolve: ResolveRejectFunction; + reject: ResolveRejectFunction; strings?: string[]; }, handleArgs, @@ -253,7 +257,8 @@ export class PostgresJsInstrumentation extends InstrumentationBase any): unknown { return new Proxy(Connection, { apply: (connectionTarget, thisArg, connectionArgs: { database: string; host: string[]; port: number[] }[]) => { const databaseName = connectionArgs[0]?.database || ''; diff --git a/packages/remix/src/utils/types.ts b/packages/remix/src/utils/types.ts index 9634678a05ce..6eb526c176ff 100644 --- a/packages/remix/src/utils/types.ts +++ b/packages/remix/src/utils/types.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type SentryMetaArgs any> = Parameters[0] & { data: { sentryTrace: string; diff --git a/packages/remix/src/vendor/instrumentation.ts b/packages/remix/src/vendor/instrumentation.ts index 317a17da663d..8668161dcd2f 100644 --- a/packages/remix/src/vendor/instrumentation.ts +++ b/packages/remix/src/vendor/instrumentation.ts @@ -1,6 +1,7 @@ /* eslint-disable deprecation/deprecation */ /* eslint-disable max-lines */ /* eslint-disable jsdoc/require-jsdoc */ +/* eslint-disable @typescript-eslint/no-explicit-any */ // Vendored and modified from: // https://github.com/justindsmith/opentelemetry-instrumentations-js/blob/3b1e8c3e566e5cc3389e9c28cafce6a5ebb39600/packages/instrumentation-remix/src/instrumentation.ts diff --git a/packages/replay-internal/src/coreHandlers/handleBreadcrumbs.ts b/packages/replay-internal/src/coreHandlers/handleBreadcrumbs.ts index 8257ebdb1044..a47829c3f0db 100644 --- a/packages/replay-internal/src/coreHandlers/handleBreadcrumbs.ts +++ b/packages/replay-internal/src/coreHandlers/handleBreadcrumbs.ts @@ -33,9 +33,8 @@ function beforeAddBreadcrumb(replay: ReplayContainer, breadcrumb: Breadcrumb): v } /** Exported only for tests. */ -export function normalizeBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb | null { +export function normalizeBreadcrumb(breadcrumb: Required>): Breadcrumb | null { if ( - !isBreadcrumbWithCategory(breadcrumb) || [ // fetch & xhr are handled separately,in handleNetworkBreadcrumbs 'fetch', diff --git a/packages/replay-internal/src/coreHandlers/handleNetworkBreadcrumbs.ts b/packages/replay-internal/src/coreHandlers/handleNetworkBreadcrumbs.ts index 6a2e49bfa5b9..60be66ba2820 100644 --- a/packages/replay-internal/src/coreHandlers/handleNetworkBreadcrumbs.ts +++ b/packages/replay-internal/src/coreHandlers/handleNetworkBreadcrumbs.ts @@ -92,9 +92,9 @@ function _isFetchBreadcrumb(breadcrumb: Breadcrumb): breadcrumb is Breadcrumb & } function _isXhrHint(hint?: BreadcrumbHint): hint is XhrHint { - return hint?.xhr; + return !!hint?.xhr; } function _isFetchHint(hint?: BreadcrumbHint): hint is FetchHint { - return hint?.response; + return !!hint?.response; } diff --git a/packages/replay-internal/src/types/rrweb.ts b/packages/replay-internal/src/types/rrweb.ts index 33f5e1b3bf7f..0d9a2d6065d9 100644 --- a/packages/replay-internal/src/types/rrweb.ts +++ b/packages/replay-internal/src/types/rrweb.ts @@ -69,7 +69,9 @@ export interface CanvasManagerOptions { type: string; quality: number; }>; + // eslint-disable-next-line @typescript-eslint/no-explicit-any mutationCb: (p: any) => void; win: typeof globalThis & Window; + // eslint-disable-next-line @typescript-eslint/no-explicit-any mirror: any; } diff --git a/packages/vue/src/pinia.ts b/packages/vue/src/pinia.ts index f55be4d6602c..cb8796f4d75c 100644 --- a/packages/vue/src/pinia.ts +++ b/packages/vue/src/pinia.ts @@ -2,7 +2,7 @@ import { addBreadcrumb, addNonEnumerableProperty, getClient, getCurrentScope, ge import type { Ref } from 'vue'; // Inline Pinia types -type StateTree = Record; +type StateTree = Record; type PiniaPlugin = (context: { store: { $id: string; @@ -15,8 +15,9 @@ type PiniaPlugin = (context: { type SentryPiniaPluginOptions = { attachPiniaState: boolean; addBreadcrumbs: boolean; + // eslint-disable-next-line @typescript-eslint/no-explicit-any actionTransformer: (action: string) => any; - stateTransformer: (state: Record) => any; + stateTransformer: (state: Record) => Record; }; const DEFAULT_PINIA_PLUGIN_OPTIONS: SentryPiniaPluginOptions = { From b9cc0241184900203e59b7da15d77d99393cd593 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 16 Jul 2025 16:11:23 +0200 Subject: [PATCH 2/3] fix test --- .../test/unit/coreHandlers/handleBreadcrumbs.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/replay-internal/test/unit/coreHandlers/handleBreadcrumbs.test.ts b/packages/replay-internal/test/unit/coreHandlers/handleBreadcrumbs.test.ts index f820f5774b01..79595801f378 100644 --- a/packages/replay-internal/test/unit/coreHandlers/handleBreadcrumbs.test.ts +++ b/packages/replay-internal/test/unit/coreHandlers/handleBreadcrumbs.test.ts @@ -4,7 +4,7 @@ import { normalizeBreadcrumb, normalizeConsoleBreadcrumb } from '../../../src/co describe('Unit | coreHandlers | handleBreadcrumbs', () => { describe('normalizeBreadcrumb', () => { - it.each([undefined, 'ui.click', 'ui.scroll', 'fetch', 'xhr', 'sentry.event', 'sentry.transaction'])( + it.each(['ui.click', 'ui.scroll', 'fetch', 'xhr', 'sentry.event', 'sentry.transaction'])( 'returns null if breadcrumb has category=%j', category => { const actual = normalizeBreadcrumb({ category }); From 142d072b1361244392621ccc7bde78d6d8f4b25d Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 17 Jul 2025 10:26:03 +0200 Subject: [PATCH 3/3] fix linting --- packages/core/src/integrations/supabase.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/integrations/supabase.ts b/packages/core/src/integrations/supabase.ts index 97afab1d50a4..093cfc399c42 100644 --- a/packages/core/src/integrations/supabase.ts +++ b/packages/core/src/integrations/supabase.ts @@ -9,8 +9,8 @@ import { defineIntegration } from '../integration'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../semanticAttributes'; import { setHttpStatus, SPAN_STATUS_ERROR, SPAN_STATUS_OK, startSpan } from '../tracing'; import type { IntegrationFn } from '../types-hoist/integration'; -import { debug } from '../utils/debug-logger'; import type { SpanAttributes } from '../types-hoist/span'; +import { debug } from '../utils/debug-logger'; import { isPlainObject } from '../utils/is'; const AUTH_OPERATIONS_TO_INSTRUMENT = [