diff --git a/packages/deno/src/index.ts b/packages/deno/src/index.ts index badb9ed5a8af..f55fe14de14f 100644 --- a/packages/deno/src/index.ts +++ b/packages/deno/src/index.ts @@ -26,6 +26,7 @@ export type { DenoOptions } from './types'; export { addEventProcessor, addBreadcrumb, + addIntegration, captureException, captureEvent, captureMessage, @@ -52,6 +53,7 @@ export { setAttribute, setAttributes, setUser, + setConversationId, getSpanStatusFromHttpCode, setHttpStatus, withScope, @@ -69,6 +71,8 @@ export { startNewTrace, bindScopeToEmitter, suppressTracing, + withActiveSpan, + getSpanDescendants, eventFiltersIntegration, linkedErrorsIntegration, functionToStringIntegration, @@ -78,6 +82,7 @@ export { dedupeIntegration, extraErrorDataIntegration, rewriteFramesIntegration, + moduleMetadataIntegration, supabaseIntegration, instrumentSupabaseClient, zodErrorsIntegration, @@ -94,7 +99,9 @@ export { spanToTraceHeader, spanToBaggageHeader, updateSpanName, + createConsolaReporter, featureFlagsIntegration, + growthbookIntegration, metrics, withStaticSpan, // oxlint-disable-next-line typescript/no-deprecated @@ -103,12 +110,30 @@ export { consoleLoggingIntegration, spanStreamingIntegration, } from '@sentry/core'; -export { wrapMcpServerWithSentry } from '@sentry/core/server'; -export { instrumentPostgresJsSql } from '@sentry/server-utils'; +export { trpcMiddleware, wrapMcpServerWithSentry } from '@sentry/core/server'; +export { + instrumentPostgresJsSql, + prismaIntegration, + instrumentOpenAiClient, + instrumentAnthropicAiClient, + instrumentGoogleGenAIClient, + instrumentMistralAiClient, + instrumentTypeSafeClient, + createLangChainCallbackHandler, + instrumentLangChainEmbeddings, + instrumentStateGraph, + instrumentCreateReactAgent, +} from '@sentry/server-utils'; +export type { FlueOptions } from '@sentry/server-utils'; export { DenoClient } from './client'; -export { getDefaultIntegrations, init } from './sdk'; +export { + getDefaultIntegrations, + getDefaultIntegrationsWithoutPerformance, + init, + initWithoutDefaultIntegrations, +} from './sdk'; export { denoServeIntegration } from './integrations/deno-serve'; export type { DenoServeIntegrationOptions } from './integrations/deno-serve'; export { fetchIntegration } from './integrations/fetch'; diff --git a/packages/deno/src/sdk.ts b/packages/deno/src/sdk.ts index 93869d8face1..8b277fb32453 100644 --- a/packages/deno/src/sdk.ts +++ b/packages/deno/src/sdk.ts @@ -29,8 +29,8 @@ import { setupOpenTelemetryTracer } from './opentelemetry/tracer'; import { makeFetchTransport } from './transports'; import type { DenoOptions } from './types'; -/** Get the default integrations for the Deno SDK. */ -export function getDefaultIntegrations(options: Options): Integration[] { +/** Get the default integrations for the Deno SDK, excluding performance integrations. */ +export function getDefaultIntegrationsWithoutPerformance(): Integration[] { // We return a copy of the defaultIntegrations here to avoid mutating this return [ // Common @@ -52,10 +52,14 @@ export function getDefaultIntegrations(options: Options): Integration[] { globalHandlersIntegration(), // server-utils integrations ...getErrorIntegrations(), - ...(hasSpansEnabled(options) ? getTracingIntegrations() : []), ]; } +/** Get the default integrations for the Deno SDK. */ +export function getDefaultIntegrations(options: Options): Integration[] { + return [...getDefaultIntegrationsWithoutPerformance(), ...(hasSpansEnabled(options) ? getTracingIntegrations() : [])]; +} + const defaultStackParser: StackParser = createStackParser(nodeStackLineParser()); /** @@ -103,10 +107,21 @@ const defaultStackParser: StackParser = createStackParser(nodeStackLineParser()) * @see {@link DenoOptions} for documentation on configuration options. */ export function init(options: DenoOptions = {}): Client { + return _init(options, getDefaultIntegrations); +} + +/** + * Initialize Sentry for Deno, without any integrations added by default. + */ +export function initWithoutDefaultIntegrations(options: DenoOptions = {}): Client { + return _init(options, () => []); +} + +function _init(options: DenoOptions, getDefaultIntegrationsImpl: (options: Options) => Integration[]): Client { // Computed into a local rather than written back onto `options`: the default set // depends on the tracing options, so caching it on the caller's object would pin the // result of the first `init` for any reused options object. - const defaultIntegrations = options.defaultIntegrations ?? getDefaultIntegrations(options); + const defaultIntegrations = options.defaultIntegrations ?? getDefaultIntegrationsImpl(options); const clientOptions: ServerRuntimeClientOptions = { ...options, diff --git a/packages/deno/test/exports.test.ts b/packages/deno/test/exports.test.ts new file mode 100644 index 000000000000..c1468653c566 --- /dev/null +++ b/packages/deno/test/exports.test.ts @@ -0,0 +1,42 @@ +import { assertEquals } from 'https://deno.land/std@0.212.0/assert/assert_equals.ts'; +import * as Sentry from '../build/esm/index.js'; +import type { FlueOptions } from '../build/esm/index.js'; + +// Exports that Cloudflare ships and that need no Node APIs. +const EXPECTED_FUNCTION_EXPORTS = [ + // @sentry/core + 'addIntegration', + 'withActiveSpan', + 'getSpanDescendants', + 'setConversationId', + 'createConsolaReporter', + 'growthbookIntegration', + 'moduleMetadataIntegration', + // @sentry/core/server + 'trpcMiddleware', + // @sentry/server-utils + 'prismaIntegration', + 'instrumentOpenAiClient', + 'instrumentAnthropicAiClient', + 'instrumentGoogleGenAIClient', + 'instrumentMistralAiClient', + 'instrumentTypeSafeClient', + 'createLangChainCallbackHandler', + 'instrumentLangChainEmbeddings', + 'instrumentStateGraph', + 'instrumentCreateReactAgent', + // ./sdk + 'initWithoutDefaultIntegrations', + 'getDefaultIntegrationsWithoutPerformance', +]; + +for (const name of EXPECTED_FUNCTION_EXPORTS) { + Deno.test(`exports ${name}`, () => { + assertEquals(typeof (Sentry as Record)[name], 'function'); + }); +} + +Deno.test('exports the FlueOptions type', () => { + const options: FlueOptions = {}; + assertEquals(typeof options, 'object'); +}); diff --git a/packages/deno/test/sdk.test.ts b/packages/deno/test/sdk.test.ts index 032442ece005..9eebad5e6482 100644 --- a/packages/deno/test/sdk.test.ts +++ b/packages/deno/test/sdk.test.ts @@ -3,7 +3,9 @@ import { assertArrayIncludes } from 'https://deno.land/std@0.212.0/assert/assert import { getCurrentScope, getDefaultIntegrations, + getDefaultIntegrationsWithoutPerformance, init as initSdk, + initWithoutDefaultIntegrations, spanStreamingIntegration, } from '../build/esm/index.js'; import type { DenoOptions } from '../build/esm/index.js'; @@ -82,3 +84,39 @@ Deno.test("init doesn't write the computed default integrations back onto the op const names = second.getOptions().integrations.map(i => i.name); assertArrayIncludes(names, ['Graphql']); }); + +Deno.test('initWithoutDefaultIntegrations sets up only the integrations the user passes', () => { + getCurrentScope().setClient(undefined); + const client = initWithoutDefaultIntegrations({ + tracesSampleRate: 1, + traceLifecycle: 'static', + integrations: [spanStreamingIntegration()], + }); + const names = client.getOptions().integrations.map(i => i.name); + assertEquals(names, ['SpanStreaming']); +}); + +Deno.test('initWithoutDefaultIntegrations keeps defaultIntegrations the user passes', () => { + getCurrentScope().setClient(undefined); + const client = initWithoutDefaultIntegrations({ + traceLifecycle: 'static', + defaultIntegrations: getDefaultIntegrationsWithoutPerformance(), + }); + const names = client.getOptions().integrations.map(i => i.name); + assertArrayIncludes(names, ['Breadcrumbs', 'DenoServe', 'Express']); +}); + +Deno.test('getDefaultIntegrationsWithoutPerformance leaves out the tracing set', () => { + const names = getDefaultIntegrationsWithoutPerformance().map(i => i.name); + assertArrayIncludes(names, ['Breadcrumbs', 'DenoServe', 'Express', 'Fastify']); + assert(!names.includes('Graphql')); + assert(!names.includes('Postgres')); + assert(!names.includes('OpenAI')); +}); + +Deno.test('getDefaultIntegrations is getDefaultIntegrationsWithoutPerformance plus the tracing set', () => { + const base = getDefaultIntegrationsWithoutPerformance().map(i => i.name); + const full = getDefaultIntegrations({ tracesSampleRate: 1 }).map(i => i.name); + assertEquals(full.slice(0, base.length), base); + assertArrayIncludes(full.slice(base.length), ['Graphql', 'Postgres', 'OpenAI']); +});