From 93f6bb27475b1ed8e170d04e2643743716c49eb1 Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Mon, 18 May 2026 07:31:26 +0200 Subject: [PATCH 1/8] ref(node): Vendor koa instrumentation Closes https://github.com/getsentry/sentry-javascript/issues/20153 Co-Authored-By: Claude Opus 4.6 (1M context) --- .oxlintrc.base.json | 6 + packages/node/package.json | 3 +- .../tracing/{koa.ts => koa/index.ts} | 6 +- .../koa/vendored/enums/AttributeNames.ts | 25 ++ .../tracing/koa/vendored/instrumentation.ts | 215 ++++++++++++++++++ .../tracing/koa/vendored/internal-types.ts | 53 +++++ .../tracing/koa/vendored/types.ts | 83 +++++++ .../tracing/koa/vendored/utils.ts | 71 ++++++ yarn.lock | 76 ++++++- 9 files changed, 524 insertions(+), 14 deletions(-) rename packages/node/src/integrations/tracing/{koa.ts => koa/index.ts} (94%) create mode 100644 packages/node/src/integrations/tracing/koa/vendored/enums/AttributeNames.ts create mode 100644 packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts create mode 100644 packages/node/src/integrations/tracing/koa/vendored/internal-types.ts create mode 100644 packages/node/src/integrations/tracing/koa/vendored/types.ts create mode 100644 packages/node/src/integrations/tracing/koa/vendored/utils.ts diff --git a/.oxlintrc.base.json b/.oxlintrc.base.json index da50021f4431..a7bad4dd0fab 100644 --- a/.oxlintrc.base.json +++ b/.oxlintrc.base.json @@ -140,6 +140,12 @@ "no-bitwise": "off" } }, + { + "files": ["**/integrations/tracing/koa/vendored/**/*.ts"], + "rules": { + "typescript/no-explicit-any": "off" + } + }, { "files": ["**/scenarios/**", "**/rollup-utils/**"], "rules": { diff --git a/packages/node/package.json b/packages/node/package.json index 5e74867a0a88..4e917df72b49 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -78,7 +78,6 @@ "@opentelemetry/instrumentation-http": "0.214.0", "@opentelemetry/instrumentation-kafkajs": "0.23.0", "@opentelemetry/instrumentation-knex": "0.58.0", - "@opentelemetry/instrumentation-koa": "0.62.0", "@opentelemetry/instrumentation-lru-memoizer": "0.58.0", "@opentelemetry/instrumentation-mongodb": "0.67.0", "@opentelemetry/instrumentation-mongoose": "0.60.0", @@ -96,6 +95,8 @@ "import-in-the-middle": "^3.0.0" }, "devDependencies": { + "@types/koa": "3.0.2", + "@types/koa__router": "12.0.5", "@types/node": "^18.19.1" }, "scripts": { diff --git a/packages/node/src/integrations/tracing/koa.ts b/packages/node/src/integrations/tracing/koa/index.ts similarity index 94% rename from packages/node/src/integrations/tracing/koa.ts rename to packages/node/src/integrations/tracing/koa/index.ts index 7125479e91e0..11d8e01bf669 100644 --- a/packages/node/src/integrations/tracing/koa.ts +++ b/packages/node/src/integrations/tracing/koa/index.ts @@ -1,5 +1,5 @@ -import type { KoaInstrumentationConfig, KoaLayerType } from '@opentelemetry/instrumentation-koa'; -import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa'; +import type { KoaInstrumentationConfig, KoaLayerType } from './vendored/types'; +import { KoaInstrumentation } from './vendored/instrumentation'; import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions'; import type { IntegrationFn } from '@sentry/core'; import { @@ -12,7 +12,7 @@ import { spanToJSON, } from '@sentry/core'; import { addOriginToSpan, ensureIsWrapped, generateInstrumentOnce } from '@sentry/node-core'; -import { DEBUG_BUILD } from '../../debug-build'; +import { DEBUG_BUILD } from '../../../debug-build'; interface KoaOptions { /** diff --git a/packages/node/src/integrations/tracing/koa/vendored/enums/AttributeNames.ts b/packages/node/src/integrations/tracing/koa/vendored/enums/AttributeNames.ts new file mode 100644 index 000000000000..28dd9a00fed2 --- /dev/null +++ b/packages/node/src/integrations/tracing/koa/vendored/enums/AttributeNames.ts @@ -0,0 +1,25 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE from the Sentry authors: + * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-koa + * - Upstream version: @opentelemetry/instrumentation-koa@0.66.0 + */ +/* eslint-disable */ + +export enum AttributeNames { + KOA_TYPE = 'koa.type', + KOA_NAME = 'koa.name', +} diff --git a/packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts b/packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts new file mode 100644 index 000000000000..2987a94abd41 --- /dev/null +++ b/packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts @@ -0,0 +1,215 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE from the Sentry authors: + * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-koa + * - Upstream version: @opentelemetry/instrumentation-koa@0.66.0 + * - Minor TypeScript strictness adjustments for this repository's compiler settings + */ +/* eslint-disable */ + +import * as api from '@opentelemetry/api'; +import { + isWrapped, + InstrumentationBase, + InstrumentationNodeModuleDefinition, + safeExecuteInTheMiddle, +} from '@opentelemetry/instrumentation'; + +import type * as koa from 'koa'; +import { KoaLayerType, KoaInstrumentationConfig } from './types'; +import { SDK_VERSION } from '@sentry/core'; +import { getMiddlewareMetadata, isLayerIgnored } from './utils'; +import { getRPCMetadata, RPCType } from '@opentelemetry/core'; +import { + kLayerPatched, + KoaContext, + KoaMiddleware, + KoaPatchedMiddleware, +} from './internal-types'; + +const PACKAGE_NAME = '@sentry/instrumentation-koa'; + +/** Koa instrumentation for OpenTelemetry */ +export class KoaInstrumentation extends InstrumentationBase { + constructor(config: KoaInstrumentationConfig = {}) { + super(PACKAGE_NAME, SDK_VERSION, config); + } + + protected init() { + return new InstrumentationNodeModuleDefinition( + 'koa', + ['>=2.0.0 <4'], + (module: any) => { + const moduleExports: typeof koa = + module[Symbol.toStringTag] === 'Module' + ? module.default // ESM + : module; // CommonJS + if (moduleExports == null) { + return moduleExports; + } + if (isWrapped(moduleExports.prototype.use)) { + this._unwrap(moduleExports.prototype, 'use'); + } + this._wrap( + moduleExports.prototype, + 'use', + this._getKoaUsePatch.bind(this) + ); + return module; + }, + (module: any) => { + const moduleExports: typeof koa = + module[Symbol.toStringTag] === 'Module' + ? module.default // ESM + : module; // CommonJS + if (isWrapped(moduleExports.prototype.use)) { + this._unwrap(moduleExports.prototype, 'use'); + } + } + ); + } + + /** + * Patches the Koa.use function in order to instrument each original + * middleware layer which is introduced + * @param {KoaMiddleware} middleware - the original middleware function + */ + private _getKoaUsePatch(original: (middleware: KoaMiddleware) => koa) { + const plugin = this; + return function use(this: koa, middlewareFunction: KoaMiddleware) { + let patchedFunction: KoaMiddleware; + if (middlewareFunction.router) { + patchedFunction = plugin._patchRouterDispatch(middlewareFunction); + } else { + patchedFunction = plugin._patchLayer(middlewareFunction, false); + } + return original.apply(this, [patchedFunction]); + }; + } + + /** + * Patches the dispatch function used by @koa/router. This function + * goes through each routed middleware and adds instrumentation via a call + * to the @function _patchLayer function. + * @param {KoaMiddleware} dispatchLayer - the original dispatch function which dispatches + * routed middleware + */ + private _patchRouterDispatch(dispatchLayer: KoaMiddleware): KoaMiddleware { + api.diag.debug('Patching @koa/router dispatch'); + + const router = dispatchLayer.router; + + const routesStack = router?.stack ?? []; + for (const pathLayer of routesStack) { + const path = pathLayer.path; + // Type cast needed: router.stack comes from @types/koa@2.x but we use @types/koa@3.x + // See internal-types.ts for full explanation + const pathStack = pathLayer.stack as any; + for (let j = 0; j < pathStack.length; j++) { + const routedMiddleware: KoaMiddleware = pathStack[j]; + pathStack[j] = this._patchLayer(routedMiddleware, true, path); + } + } + + return dispatchLayer; + } + + /** + * Patches each individual @param middlewareLayer function in order to create the + * span and propagate context. It does not create spans when there is no parent span. + * @param {KoaMiddleware} middlewareLayer - the original middleware function. + * @param {boolean} isRouter - tracks whether the original middleware function + * was dispatched by the router originally + * @param {string?} layerPath - if present, provides additional data from the + * router about the routed path which the middleware is attached to + */ + private _patchLayer( + middlewareLayer: KoaPatchedMiddleware, + isRouter: boolean, + layerPath?: string | RegExp + ): KoaMiddleware { + const layerType = isRouter ? KoaLayerType.ROUTER : KoaLayerType.MIDDLEWARE; + // Skip patching layer if its ignored in the config + if ( + middlewareLayer[kLayerPatched] === true || + isLayerIgnored(layerType, this.getConfig()) + ) + return middlewareLayer; + + if ( + middlewareLayer.constructor.name === 'GeneratorFunction' || + middlewareLayer.constructor.name === 'AsyncGeneratorFunction' + ) { + api.diag.debug('ignoring generator-based Koa middleware layer'); + return middlewareLayer; + } + + middlewareLayer[kLayerPatched] = true; + + api.diag.debug('patching Koa middleware layer'); + return async (context: KoaContext, next: koa.Next) => { + const parent = api.trace.getSpan(api.context.active()); + if (parent === undefined) { + return middlewareLayer(context, next); + } + const metadata = getMiddlewareMetadata( + context, + middlewareLayer, + isRouter, + layerPath + ); + const span = this.tracer.startSpan(metadata.name, { + attributes: metadata.attributes, + }); + + const rpcMetadata = getRPCMetadata(api.context.active()); + + if (rpcMetadata?.type === RPCType.HTTP && context._matchedRoute) { + rpcMetadata.route = context._matchedRoute.toString(); + } + + const { requestHook } = this.getConfig(); + if (requestHook) { + safeExecuteInTheMiddle( + () => + requestHook(span, { + context, + middlewareLayer, + layerType, + }), + e => { + if (e) { + api.diag.error('koa instrumentation: request hook failed', e); + } + }, + true + ); + } + + const newContext = api.trace.setSpan(api.context.active(), span); + return api.context.with(newContext, async () => { + try { + return await middlewareLayer(context, next); + } catch (err: any) { + span.recordException(err); + throw err; + } finally { + span.end(); + } + }); + }; + } +} diff --git a/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts new file mode 100644 index 000000000000..a04ddc3e4049 --- /dev/null +++ b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE from the Sentry authors: + * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-koa + * - Upstream version: @opentelemetry/instrumentation-koa@0.66.0 + */ +/* eslint-disable */ + +import type { Middleware, ParameterizedContext, DefaultState } from 'koa'; +import type * as Router from '@koa/router'; + +/** + * Type compatibility note: + * + * This package uses @types/koa@3.x, but @types/koa__router@12.x depends on + * @types/koa@2.x. This creates type conflicts when working with router middleware. + * At runtime, koa@3.x is used throughout, so all methods exist and work correctly. + * + * The type casts in instrumentation.ts are necessary to bridge this gap. + * + * TODO: Remove type casts when @types/koa__router@13+ with @types/koa@3.x support is available + */ + +export type KoaContext = ParameterizedContext< + DefaultState, + Router.RouterParamContext +>; +export type KoaMiddleware = Middleware & { + router?: Router; +}; + +/** + * This symbol is used to mark a Koa layer as being already instrumented + * since its possible to use a given layer multiple times (ex: middlewares) + */ +export const kLayerPatched: unique symbol = Symbol('koa-layer-patched'); + +export type KoaPatchedMiddleware = KoaMiddleware & { + [kLayerPatched]?: boolean; +}; diff --git a/packages/node/src/integrations/tracing/koa/vendored/types.ts b/packages/node/src/integrations/tracing/koa/vendored/types.ts new file mode 100644 index 000000000000..4d1d0e16ae18 --- /dev/null +++ b/packages/node/src/integrations/tracing/koa/vendored/types.ts @@ -0,0 +1,83 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE from the Sentry authors: + * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-koa + * - Upstream version: @opentelemetry/instrumentation-koa@0.66.0 + */ +/* eslint-disable */ + +import { Span } from '@opentelemetry/api'; +import { InstrumentationConfig } from '@opentelemetry/instrumentation'; + +export enum KoaLayerType { + ROUTER = 'router', + MIDDLEWARE = 'middleware', +} + +/** + * Information about the current Koa middleware layer + * The middleware layer type is any by default. + * One can install koa types packages `@types/koa` and `@types/koa__router` + * with compatible versions to the koa version used in the project + * to get more specific types for the middleware layer property. + * + * Example use in a custom attribute function: + * ```ts + * import type { Middleware, ParameterizedContext, DefaultState } from 'koa'; + * import type { RouterParamContext } from '@koa/router'; + * + * type KoaContext = ParameterizedContext; + * type KoaMiddleware = Middleware; + * + * const koaConfig: KoaInstrumentationConfig = { + * requestHook: (span: Span, info: KoaRequestInfo) => { + * // custom typescript code that can access the typed into.middlewareLayer and info.context + * } + * + */ +export type KoaRequestInfo = { + context: KoaContextType; + middlewareLayer: KoaMiddlewareType; + layerType: KoaLayerType; +}; + +/** + * Function that can be used to add custom attributes to the current span + * @param span - The Express middleware layer span. + * @param context - The current KoaContext. + */ +export interface KoaRequestCustomAttributeFunction< + KoaContextType = any, + KoaMiddlewareType = any, +> { + (span: Span, info: KoaRequestInfo): void; +} + +/** + * Options available for the Koa Instrumentation (see [documentation](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-Instrumentation-koa#koa-Instrumentation-options)) + */ +export interface KoaInstrumentationConfig< + KoaContextType = any, + KoaMiddlewareType = any, +> extends InstrumentationConfig { + /** Ignore specific layers based on their type */ + ignoreLayersType?: KoaLayerType[]; + /** Function for adding custom attributes to each middleware layer span */ + requestHook?: KoaRequestCustomAttributeFunction< + KoaContextType, + KoaMiddlewareType + >; +} diff --git a/packages/node/src/integrations/tracing/koa/vendored/utils.ts b/packages/node/src/integrations/tracing/koa/vendored/utils.ts new file mode 100644 index 000000000000..24741f008f5e --- /dev/null +++ b/packages/node/src/integrations/tracing/koa/vendored/utils.ts @@ -0,0 +1,71 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE from the Sentry authors: + * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-koa + * - Upstream version: @opentelemetry/instrumentation-koa@0.66.0 + */ +/* eslint-disable */ + +import { KoaLayerType, KoaInstrumentationConfig } from './types'; +import { KoaContext, KoaMiddleware } from './internal-types'; +import { AttributeNames } from './enums/AttributeNames'; +import { Attributes } from '@opentelemetry/api'; +import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions'; + +export const getMiddlewareMetadata = ( + context: KoaContext, + layer: KoaMiddleware, + isRouter: boolean, + layerPath?: string | RegExp +): { + attributes: Attributes; + name: string; +} => { + if (isRouter) { + return { + attributes: { + [AttributeNames.KOA_NAME]: layerPath?.toString(), + [AttributeNames.KOA_TYPE]: KoaLayerType.ROUTER, + [ATTR_HTTP_ROUTE]: layerPath?.toString(), + }, + name: context._matchedRouteName || `router - ${layerPath}`, + }; + } else { + return { + attributes: { + [AttributeNames.KOA_NAME]: layer.name ?? 'middleware', + [AttributeNames.KOA_TYPE]: KoaLayerType.MIDDLEWARE, + }, + name: `middleware - ${layer.name}`, + }; + } +}; + +/** + * Check whether the given request is ignored by configuration + * @param [list] List of ignore patterns + * @param [onException] callback for doing something when an exception has + * occurred + */ +export const isLayerIgnored = ( + type: KoaLayerType, + config?: KoaInstrumentationConfig +): boolean => { + return !!( + Array.isArray(config?.ignoreLayersType) && + config?.ignoreLayersType?.includes(type) + ); +}; diff --git a/yarn.lock b/yarn.lock index 08c5b05e7a86..f60aa8ef853a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6280,15 +6280,6 @@ "@opentelemetry/instrumentation" "^0.214.0" "@opentelemetry/semantic-conventions" "^1.33.1" -"@opentelemetry/instrumentation-koa@0.62.0": - version "0.62.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.62.0.tgz#65fdf96c1b1ffb382167cd3b7a244631afd0cc1f" - integrity sha512-uVip0VuGUQXZ+vFxkKxAUNq8qNl+VFlyHDh/U6IQ8COOEDfbEchdaHnpFrMYF3psZRUuoSIgb7xOeXj00RdwDA== - dependencies: - "@opentelemetry/core" "^2.0.0" - "@opentelemetry/instrumentation" "^0.214.0" - "@opentelemetry/semantic-conventions" "^1.36.0" - "@opentelemetry/instrumentation-lru-memoizer@0.58.0": version "0.58.0" resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.58.0.tgz#7c730a0cb963e8ac5f3d11023518050e5f124a6a" @@ -6443,7 +6434,7 @@ "@opentelemetry/resources" "2.6.1" "@opentelemetry/semantic-conventions" "^1.29.0" -"@opentelemetry/semantic-conventions@^1.27.0", "@opentelemetry/semantic-conventions@^1.28.0", "@opentelemetry/semantic-conventions@^1.29.0", "@opentelemetry/semantic-conventions@^1.30.0", "@opentelemetry/semantic-conventions@^1.33.0", "@opentelemetry/semantic-conventions@^1.33.1", "@opentelemetry/semantic-conventions@^1.34.0", "@opentelemetry/semantic-conventions@^1.36.0", "@opentelemetry/semantic-conventions@^1.40.0": +"@opentelemetry/semantic-conventions@^1.27.0", "@opentelemetry/semantic-conventions@^1.28.0", "@opentelemetry/semantic-conventions@^1.29.0", "@opentelemetry/semantic-conventions@^1.30.0", "@opentelemetry/semantic-conventions@^1.33.0", "@opentelemetry/semantic-conventions@^1.33.1", "@opentelemetry/semantic-conventions@^1.34.0", "@opentelemetry/semantic-conventions@^1.40.0": version "1.40.0" resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.40.0.tgz#10b2944ca559386590683392022a897eefd011d3" integrity sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw== @@ -9090,6 +9081,13 @@ dependencies: tslib "^2.4.0" +"@types/accepts@*": + version "1.3.7" + resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.7.tgz#3b98b1889d2b2386604c2bbbe62e4fb51e95b265" + integrity sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ== + dependencies: + "@types/node" "*" + "@types/amqplib@^0.10.5": version "0.10.5" resolved "https://registry.yarnpkg.com/@types/amqplib/-/amqplib-0.10.5.tgz#fd883eddfbd669702a727fa10007b27c4c1e6ec7" @@ -9206,6 +9204,11 @@ dependencies: "@types/node" "*" +"@types/content-disposition@*": + version "0.5.9" + resolved "https://registry.yarnpkg.com/@types/content-disposition/-/content-disposition-0.5.9.tgz#00ca14939432869de829a4ccf6fd380fa9181750" + integrity sha512-8uYXI3Gw35MhiVYhG3s295oihrxRyytcRHjSjqnqZVDDy/xcGBRny7+Xj1Wgfhv5QzRtN2hB2dVRBUX9XW3UcQ== + "@types/cookie@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" @@ -9216,6 +9219,16 @@ resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5" integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA== +"@types/cookies@*": + version "0.9.2" + resolved "https://registry.yarnpkg.com/@types/cookies/-/cookies-0.9.2.tgz#ccdf86d782f2dea34531dd32733a25be48177cd4" + integrity sha512-1AvkDdZM2dbyFybL4fxpuNCaWyv//0AwsuUk2DWeXyM1/5ZKm6W3z6mQi24RZ4l2ucY+bkSHzbDVpySqPGuV8A== + dependencies: + "@types/connect" "*" + "@types/express" "*" + "@types/keygrip" "*" + "@types/node" "*" + "@types/cors@^2.8.12": version "2.8.12" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" @@ -9551,11 +9564,21 @@ resolved "https://registry.yarnpkg.com/@types/htmlbars-inline-precompile/-/htmlbars-inline-precompile-1.0.1.tgz#de564513fabb165746aecd76369c87bd85e5bbb4" integrity sha512-sVD2e6QAAHW0Y6Btse+tTA9k9g0iKm87wjxRsgZRU5EwSooz80tenbV+fA+f2BI2g0G2CqxsS1rIlwQCtPRQow== +"@types/http-assert@*": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.6.tgz#b6b657c38a2350d21ce213139f33b03b2b5fa431" + integrity sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw== + "@types/http-errors@*": version "2.0.4" resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== +"@types/http-errors@^2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" + integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== + "@types/http-proxy@^1.17.8": version "1.17.14" resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec" @@ -9608,6 +9631,39 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= +"@types/keygrip@*": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.6.tgz#1749535181a2a9b02ac04a797550a8787345b740" + integrity sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ== + +"@types/koa-compose@*": + version "3.2.9" + resolved "https://registry.yarnpkg.com/@types/koa-compose/-/koa-compose-3.2.9.tgz#6efb945ee5573be0f4eddb728a2f6826f7a3f395" + integrity sha512-BroAZ9FTvPiCy0Pi8tjD1OfJ7bgU1gQf0eR6e1Vm+JJATy9eKOG3hQMFtMciMawiSOVnLMdmUOC46s7HBhSTsA== + dependencies: + "@types/koa" "*" + +"@types/koa@*", "@types/koa@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/koa/-/koa-3.0.2.tgz#e788aeb46bfadb5e043abfe3528b55bfd11fed12" + integrity sha512-7TRzVOBcH/q8CfPh9AmHBQ8TZtimT4Sn+rw8//hXveI6+F41z93W8a+0B0O8L7apKQv+vKBIEZSECiL0Oo1JFA== + dependencies: + "@types/accepts" "*" + "@types/content-disposition" "*" + "@types/cookies" "*" + "@types/http-assert" "*" + "@types/http-errors" "^2" + "@types/keygrip" "*" + "@types/koa-compose" "*" + "@types/node" "*" + +"@types/koa__router@12.0.5": + version "12.0.5" + resolved "https://registry.yarnpkg.com/@types/koa__router/-/koa__router-12.0.5.tgz#4eaab7cf650bea292ae02787d9e1e6b77a31f191" + integrity sha512-1HeLxuDn4n5it1yZYCSyOYXo++73zT0ffoviXnPxbwbxLbvDFEvWD9ZzpRiIpK4oKR0pi+K+Mk/ZjyROjW3HSw== + dependencies: + "@types/koa" "*" + "@types/long@^4.0.0": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" From 114123a6f7921e4603f44e512e7dce4323edd965 Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Mon, 18 May 2026 07:32:09 +0200 Subject: [PATCH 2/8] yarn fix --- .../tracing/koa/vendored/instrumentation.ts | 32 ++++--------------- .../tracing/koa/vendored/internal-types.ts | 5 +-- .../tracing/koa/vendored/types.ts | 15 ++------- .../tracing/koa/vendored/utils.ts | 12 ++----- 4 files changed, 14 insertions(+), 50 deletions(-) diff --git a/packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts b/packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts index 2987a94abd41..568a97949141 100644 --- a/packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts +++ b/packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts @@ -33,12 +33,7 @@ import { KoaLayerType, KoaInstrumentationConfig } from './types'; import { SDK_VERSION } from '@sentry/core'; import { getMiddlewareMetadata, isLayerIgnored } from './utils'; import { getRPCMetadata, RPCType } from '@opentelemetry/core'; -import { - kLayerPatched, - KoaContext, - KoaMiddleware, - KoaPatchedMiddleware, -} from './internal-types'; +import { kLayerPatched, KoaContext, KoaMiddleware, KoaPatchedMiddleware } from './internal-types'; const PACKAGE_NAME = '@sentry/instrumentation-koa'; @@ -63,11 +58,7 @@ export class KoaInstrumentation extends InstrumentationBase { @@ -78,7 +69,7 @@ export class KoaInstrumentation extends InstrumentationBase; +export type KoaContext = ParameterizedContext; export type KoaMiddleware = Middleware & { router?: Router; }; diff --git a/packages/node/src/integrations/tracing/koa/vendored/types.ts b/packages/node/src/integrations/tracing/koa/vendored/types.ts index 4d1d0e16ae18..54a79d68e252 100644 --- a/packages/node/src/integrations/tracing/koa/vendored/types.ts +++ b/packages/node/src/integrations/tracing/koa/vendored/types.ts @@ -59,25 +59,16 @@ export type KoaRequestInfo = { * @param span - The Express middleware layer span. * @param context - The current KoaContext. */ -export interface KoaRequestCustomAttributeFunction< - KoaContextType = any, - KoaMiddlewareType = any, -> { +export interface KoaRequestCustomAttributeFunction { (span: Span, info: KoaRequestInfo): void; } /** * Options available for the Koa Instrumentation (see [documentation](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-Instrumentation-koa#koa-Instrumentation-options)) */ -export interface KoaInstrumentationConfig< - KoaContextType = any, - KoaMiddlewareType = any, -> extends InstrumentationConfig { +export interface KoaInstrumentationConfig extends InstrumentationConfig { /** Ignore specific layers based on their type */ ignoreLayersType?: KoaLayerType[]; /** Function for adding custom attributes to each middleware layer span */ - requestHook?: KoaRequestCustomAttributeFunction< - KoaContextType, - KoaMiddlewareType - >; + requestHook?: KoaRequestCustomAttributeFunction; } diff --git a/packages/node/src/integrations/tracing/koa/vendored/utils.ts b/packages/node/src/integrations/tracing/koa/vendored/utils.ts index 24741f008f5e..2066afde33c5 100644 --- a/packages/node/src/integrations/tracing/koa/vendored/utils.ts +++ b/packages/node/src/integrations/tracing/koa/vendored/utils.ts @@ -29,7 +29,7 @@ export const getMiddlewareMetadata = ( context: KoaContext, layer: KoaMiddleware, isRouter: boolean, - layerPath?: string | RegExp + layerPath?: string | RegExp, ): { attributes: Attributes; name: string; @@ -60,12 +60,6 @@ export const getMiddlewareMetadata = ( * @param [onException] callback for doing something when an exception has * occurred */ -export const isLayerIgnored = ( - type: KoaLayerType, - config?: KoaInstrumentationConfig -): boolean => { - return !!( - Array.isArray(config?.ignoreLayersType) && - config?.ignoreLayersType?.includes(type) - ); +export const isLayerIgnored = (type: KoaLayerType, config?: KoaInstrumentationConfig): boolean => { + return !!(Array.isArray(config?.ignoreLayersType) && config?.ignoreLayersType?.includes(type)); }; From 96b134bb38c7195624e0f8d213c95aefe66c442f Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Mon, 18 May 2026 10:11:03 +0200 Subject: [PATCH 3/8] ref: Fix koa unit test imports and deduplicate lockfile Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/node/test/integrations/tracing/koa.test.ts | 4 ++-- yarn.lock | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/node/test/integrations/tracing/koa.test.ts b/packages/node/test/integrations/tracing/koa.test.ts index 74d10c344d95..4961b0c9b82c 100644 --- a/packages/node/test/integrations/tracing/koa.test.ts +++ b/packages/node/test/integrations/tracing/koa.test.ts @@ -1,9 +1,9 @@ -import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa'; +import { KoaInstrumentation } from '../../../src/integrations/tracing/koa/vendored/instrumentation'; import { INSTRUMENTED } from '@sentry/node-core'; import { beforeEach, describe, expect, it, type MockInstance, vi } from 'vitest'; import { instrumentKoa, koaIntegration } from '../../../src/integrations/tracing/koa'; -vi.mock('@opentelemetry/instrumentation-koa'); +vi.mock('../../../src/integrations/tracing/koa/vendored/instrumentation'); describe('Koa', () => { beforeEach(() => { diff --git a/yarn.lock b/yarn.lock index f60aa8ef853a..cca3781a85eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9569,12 +9569,7 @@ resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.6.tgz#b6b657c38a2350d21ce213139f33b03b2b5fa431" integrity sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw== -"@types/http-errors@*": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" - integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== - -"@types/http-errors@^2": +"@types/http-errors@*", "@types/http-errors@^2": version "2.0.5" resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== From 60761e8b610607a8d53b044b11d262191c56be0f Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Mon, 18 May 2026 15:22:41 +0200 Subject: [PATCH 4/8] ref: Inline koa types to avoid requiring @types/koa and @types/koa__router Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/node/package.json | 2 - .../tracing/koa/vendored/instrumentation.ts | 13 ++-- .../tracing/koa/vendored/internal-types.ts | 47 +++++++++----- yarn.lock | 62 +------------------ 4 files changed, 39 insertions(+), 85 deletions(-) diff --git a/packages/node/package.json b/packages/node/package.json index 544024621855..1ebae6422dff 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -92,8 +92,6 @@ "import-in-the-middle": "^3.0.0" }, "devDependencies": { - "@types/koa": "3.0.2", - "@types/koa__router": "12.0.5", "@types/node": "^18.19.1" }, "scripts": { diff --git a/packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts b/packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts index 568a97949141..6251e4d81947 100644 --- a/packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts +++ b/packages/node/src/integrations/tracing/koa/vendored/instrumentation.ts @@ -28,12 +28,11 @@ import { safeExecuteInTheMiddle, } from '@opentelemetry/instrumentation'; -import type * as koa from 'koa'; import { KoaLayerType, KoaInstrumentationConfig } from './types'; import { SDK_VERSION } from '@sentry/core'; import { getMiddlewareMetadata, isLayerIgnored } from './utils'; import { getRPCMetadata, RPCType } from '@opentelemetry/core'; -import { kLayerPatched, KoaContext, KoaMiddleware, KoaPatchedMiddleware } from './internal-types'; +import { Next, kLayerPatched, KoaContext, KoaMiddleware, KoaPatchedMiddleware } from './internal-types'; const PACKAGE_NAME = '@sentry/instrumentation-koa'; @@ -48,7 +47,7 @@ export class KoaInstrumentation extends InstrumentationBase=2.0.0 <4'], (module: any) => { - const moduleExports: typeof koa = + const moduleExports: any = module[Symbol.toStringTag] === 'Module' ? module.default // ESM : module; // CommonJS @@ -62,7 +61,7 @@ export class KoaInstrumentation extends InstrumentationBase { - const moduleExports: typeof koa = + const moduleExports: any = module[Symbol.toStringTag] === 'Module' ? module.default // ESM : module; // CommonJS @@ -78,9 +77,9 @@ export class KoaInstrumentation extends InstrumentationBase koa) { + private _getKoaUsePatch(original: (middleware: KoaMiddleware) => any) { const plugin = this; - return function use(this: koa, middlewareFunction: KoaMiddleware) { + return function use(this: any, middlewareFunction: KoaMiddleware) { let patchedFunction: KoaMiddleware; if (middlewareFunction.router) { patchedFunction = plugin._patchRouterDispatch(middlewareFunction); @@ -147,7 +146,7 @@ export class KoaInstrumentation extends InstrumentationBase { + return async (context: KoaContext, next: Next) => { const parent = api.trace.getSpan(api.context.active()); if (parent === undefined) { return middlewareLayer(context, next); diff --git a/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts index dd39a0788efe..6fc86ced3a99 100644 --- a/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts +++ b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts @@ -19,23 +19,40 @@ */ /* eslint-disable */ -import type { Middleware, ParameterizedContext, DefaultState } from 'koa'; -import type * as Router from '@koa/router'; +// Inlined from @types/koa (DefinitelyTyped) +// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa/index.d.ts +interface DefaultState {} -/** - * Type compatibility note: - * - * This package uses @types/koa@3.x, but @types/koa__router@12.x depends on - * @types/koa@2.x. This creates type conflicts when working with router middleware. - * At runtime, koa@3.x is used throughout, so all methods exist and work correctly. - * - * The type casts in instrumentation.ts are necessary to bridge this gap. - * - * TODO: Remove type casts when @types/koa__router@13+ with @types/koa@3.x support is available - */ +export type Next = () => Promise; + +// Inlined from @types/koa-compose (DefinitelyTyped) +// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa-compose/index.d.ts +type Middleware = (context: T, next: Next) => any; + +// Inlined from @types/koa. Simplified to only include fields accessed by this instrumentation +type ParameterizedContext<_StateT = DefaultState, ContextT = {}, _ResponseBodyT = unknown> = + { [key: string]: any } & ContextT; + +// Inlined from @types/koa__router (DefinitelyTyped) +// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa__router/index.d.ts +interface RouterParamContext { + params: Record; + router: Router; + _matchedRoute: string | RegExp | undefined; + _matchedRouteName: string | undefined; +} + +interface Layer { + path: string | RegExp; + stack: any[]; +} + +export interface Router { + stack: Layer[]; +} -export type KoaContext = ParameterizedContext; -export type KoaMiddleware = Middleware & { +export type KoaContext = ParameterizedContext; +export type KoaMiddleware = Middleware & { router?: Router; }; diff --git a/yarn.lock b/yarn.lock index 3a92be255500..67c2216b6eee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9036,13 +9036,6 @@ dependencies: tslib "^2.4.0" -"@types/accepts@*": - version "1.3.7" - resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.7.tgz#3b98b1889d2b2386604c2bbbe62e4fb51e95b265" - integrity sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ== - dependencies: - "@types/node" "*" - "@types/amqplib@^0.10.5": version "0.10.5" resolved "https://registry.yarnpkg.com/@types/amqplib/-/amqplib-0.10.5.tgz#fd883eddfbd669702a727fa10007b27c4c1e6ec7" @@ -9159,11 +9152,6 @@ dependencies: "@types/node" "*" -"@types/content-disposition@*": - version "0.5.9" - resolved "https://registry.yarnpkg.com/@types/content-disposition/-/content-disposition-0.5.9.tgz#00ca14939432869de829a4ccf6fd380fa9181750" - integrity sha512-8uYXI3Gw35MhiVYhG3s295oihrxRyytcRHjSjqnqZVDDy/xcGBRny7+Xj1Wgfhv5QzRtN2hB2dVRBUX9XW3UcQ== - "@types/cookie@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" @@ -9174,16 +9162,6 @@ resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5" integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA== -"@types/cookies@*": - version "0.9.2" - resolved "https://registry.yarnpkg.com/@types/cookies/-/cookies-0.9.2.tgz#ccdf86d782f2dea34531dd32733a25be48177cd4" - integrity sha512-1AvkDdZM2dbyFybL4fxpuNCaWyv//0AwsuUk2DWeXyM1/5ZKm6W3z6mQi24RZ4l2ucY+bkSHzbDVpySqPGuV8A== - dependencies: - "@types/connect" "*" - "@types/express" "*" - "@types/keygrip" "*" - "@types/node" "*" - "@types/cors@^2.8.12": version "2.8.12" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" @@ -9519,12 +9497,7 @@ resolved "https://registry.yarnpkg.com/@types/htmlbars-inline-precompile/-/htmlbars-inline-precompile-1.0.1.tgz#de564513fabb165746aecd76369c87bd85e5bbb4" integrity sha512-sVD2e6QAAHW0Y6Btse+tTA9k9g0iKm87wjxRsgZRU5EwSooz80tenbV+fA+f2BI2g0G2CqxsS1rIlwQCtPRQow== -"@types/http-assert@*": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.6.tgz#b6b657c38a2350d21ce213139f33b03b2b5fa431" - integrity sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw== - -"@types/http-errors@*", "@types/http-errors@^2": +"@types/http-errors@*": version "2.0.5" resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== @@ -9581,39 +9554,6 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= -"@types/keygrip@*": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.6.tgz#1749535181a2a9b02ac04a797550a8787345b740" - integrity sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ== - -"@types/koa-compose@*": - version "3.2.9" - resolved "https://registry.yarnpkg.com/@types/koa-compose/-/koa-compose-3.2.9.tgz#6efb945ee5573be0f4eddb728a2f6826f7a3f395" - integrity sha512-BroAZ9FTvPiCy0Pi8tjD1OfJ7bgU1gQf0eR6e1Vm+JJATy9eKOG3hQMFtMciMawiSOVnLMdmUOC46s7HBhSTsA== - dependencies: - "@types/koa" "*" - -"@types/koa@*", "@types/koa@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/koa/-/koa-3.0.2.tgz#e788aeb46bfadb5e043abfe3528b55bfd11fed12" - integrity sha512-7TRzVOBcH/q8CfPh9AmHBQ8TZtimT4Sn+rw8//hXveI6+F41z93W8a+0B0O8L7apKQv+vKBIEZSECiL0Oo1JFA== - dependencies: - "@types/accepts" "*" - "@types/content-disposition" "*" - "@types/cookies" "*" - "@types/http-assert" "*" - "@types/http-errors" "^2" - "@types/keygrip" "*" - "@types/koa-compose" "*" - "@types/node" "*" - -"@types/koa__router@12.0.5": - version "12.0.5" - resolved "https://registry.yarnpkg.com/@types/koa__router/-/koa__router-12.0.5.tgz#4eaab7cf650bea292ae02787d9e1e6b77a31f191" - integrity sha512-1HeLxuDn4n5it1yZYCSyOYXo++73zT0ffoviXnPxbwbxLbvDFEvWD9ZzpRiIpK4oKR0pi+K+Mk/ZjyROjW3HSw== - dependencies: - "@types/koa" "*" - "@types/long@^4.0.0": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" From 242ca18f89a255fd2612d20a80d786cf70a15df7 Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Mon, 18 May 2026 15:29:35 +0200 Subject: [PATCH 5/8] yarn fix --- .../src/integrations/tracing/koa/vendored/internal-types.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts index 6fc86ced3a99..5e87fb873e7f 100644 --- a/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts +++ b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts @@ -30,8 +30,9 @@ export type Next = () => Promise; type Middleware = (context: T, next: Next) => any; // Inlined from @types/koa. Simplified to only include fields accessed by this instrumentation -type ParameterizedContext<_StateT = DefaultState, ContextT = {}, _ResponseBodyT = unknown> = - { [key: string]: any } & ContextT; +type ParameterizedContext<_StateT = DefaultState, ContextT = {}, _ResponseBodyT = unknown> = { + [key: string]: any; +} & ContextT; // Inlined from @types/koa__router (DefinitelyTyped) // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa__router/index.d.ts From fd43bcf0a6466fd12ad0c59e6b5eea031f9bfae0 Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Mon, 18 May 2026 15:35:48 +0200 Subject: [PATCH 6/8] ref: Keep inlined koa types closer to originals with generic params Co-Authored-By: Claude Opus 4.6 (1M context) --- .../tracing/koa/vendored/internal-types.ts | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts index 5e87fb873e7f..88f6ea5762cc 100644 --- a/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts +++ b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts @@ -25,20 +25,24 @@ interface DefaultState {} export type Next = () => Promise; -// Inlined from @types/koa-compose (DefinitelyTyped) -// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa-compose/index.d.ts -type Middleware = (context: T, next: Next) => any; - -// Inlined from @types/koa. Simplified to only include fields accessed by this instrumentation +// Simplified from @types/koa — ParameterizedContext only includes fields accessed by this instrumentation. type ParameterizedContext<_StateT = DefaultState, ContextT = {}, _ResponseBodyT = unknown> = { [key: string]: any; } & ContextT; +// Inlined from @types/koa, which wraps compose.Middleware from @types/koa-compose. +// Original: Middleware = compose.Middleware> +// compose.Middleware = (context: T, next: Next) => any +type Middleware = ( + context: ParameterizedContext, + next: Next, +) => any; + // Inlined from @types/koa__router (DefinitelyTyped) // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa__router/index.d.ts -interface RouterParamContext { +interface RouterParamContext { params: Record; - router: Router; + router: Router; _matchedRoute: string | RegExp | undefined; _matchedRouteName: string | undefined; } @@ -48,12 +52,12 @@ interface Layer { stack: any[]; } -export interface Router { +export interface Router<_StateT = DefaultState, _ContextT = {}> { stack: Layer[]; } export type KoaContext = ParameterizedContext; -export type KoaMiddleware = Middleware & { +export type KoaMiddleware = Middleware & { router?: Router; }; From e4ce0b2be26c027a889f9932d09295684985f969 Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Mon, 18 May 2026 15:37:57 +0200 Subject: [PATCH 7/8] ref: Consolidate type comments into single block Co-Authored-By: Claude Opus 4.6 (1M context) --- .../tracing/koa/vendored/internal-types.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts index 88f6ea5762cc..51aa9db40426 100644 --- a/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts +++ b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts @@ -19,27 +19,23 @@ */ /* eslint-disable */ -// Inlined from @types/koa (DefinitelyTyped) -// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa/index.d.ts +// Types below are inlined from @types/koa, @types/koa-compose, and @types/koa__router +// to avoid requiring these packages as dependencies. +// ParameterizedContext is simplified to only include fields accessed by this instrumentation. + interface DefaultState {} export type Next = () => Promise; -// Simplified from @types/koa — ParameterizedContext only includes fields accessed by this instrumentation. type ParameterizedContext<_StateT = DefaultState, ContextT = {}, _ResponseBodyT = unknown> = { [key: string]: any; } & ContextT; -// Inlined from @types/koa, which wraps compose.Middleware from @types/koa-compose. -// Original: Middleware = compose.Middleware> -// compose.Middleware = (context: T, next: Next) => any type Middleware = ( context: ParameterizedContext, next: Next, ) => any; -// Inlined from @types/koa__router (DefinitelyTyped) -// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa__router/index.d.ts interface RouterParamContext { params: Record; router: Router; From 91d92cac7495ccf233f3d60dae01e2adf9b9282b Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Mon, 18 May 2026 15:39:01 +0200 Subject: [PATCH 8/8] ref: Move vendored types note into header comment Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/integrations/tracing/koa/vendored/internal-types.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts index 51aa9db40426..a2039dc009cb 100644 --- a/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts +++ b/packages/node/src/integrations/tracing/koa/vendored/internal-types.ts @@ -16,13 +16,10 @@ * NOTICE from the Sentry authors: * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-koa * - Upstream version: @opentelemetry/instrumentation-koa@0.66.0 + * - Some types vendored from @types/koa, @types/koa-compose, and @types/koa__router with simplifications */ /* eslint-disable */ -// Types below are inlined from @types/koa, @types/koa-compose, and @types/koa__router -// to avoid requiring these packages as dependencies. -// ParameterizedContext is simplified to only include fields accessed by this instrumentation. - interface DefaultState {} export type Next = () => Promise;