diff --git a/packages/vercel-edge/src/index.ts b/packages/vercel-edge/src/index.ts index abe436f67705..d1f92c146338 100644 --- a/packages/vercel-edge/src/index.ts +++ b/packages/vercel-edge/src/index.ts @@ -50,6 +50,7 @@ export { setAttribute, setAttributes, setUser, + setConversationId, getSpanStatusFromHttpCode, setHttpStatus, withScope, @@ -92,9 +93,11 @@ export { spanToJSON, spanToTraceHeader, spanToBaggageHeader, + updateSpanName, consoleLoggingIntegration, createConsolaReporter, featureFlagsIntegration, + growthbookIntegration, logger, metrics, withStaticSpan, @@ -114,6 +117,7 @@ export { createLangChainCallbackHandler, instrumentLangChainEmbeddings, instrumentStateGraph, + instrumentCreateReactAgent, } from '@sentry/server-utils/no-diagnostic-channels'; export { VercelEdgeClient } from './client'; @@ -121,3 +125,7 @@ export { getDefaultIntegrations, init } from './sdk'; export { winterCGFetchIntegration } from './integrations/wintercg-fetch'; export type { FetchIntegrationOptions } from '@sentry/core'; + +// vercelAIIntegration and prismaIntegration require diagnostics channels, unavailable on Vercel Edge. +// Cloudflare's httpServerIntegration is consumed by its request wrapper, which Vercel Edge does not use. +// The fetch-based spotlightIntegration lives in the Cloudflare package, not a shared entry point. diff --git a/packages/vercel-edge/test/exports.test.ts b/packages/vercel-edge/test/exports.test.ts new file mode 100644 index 000000000000..e80e485cf9fc --- /dev/null +++ b/packages/vercel-edge/test/exports.test.ts @@ -0,0 +1,48 @@ +import { SentrySpan } from '@sentry/core'; +import { afterEach, describe, expect, it } from 'vitest'; +import { + getIsolationScope, + growthbookIntegration, + instrumentCreateReactAgent, + setConversationId, + updateSpanName, +} from '../src'; + +afterEach(() => { + setConversationId(null); +}); + +describe('portable exports', () => { + it('sets the conversation context through the public entry point', () => { + setConversationId('edge-conversation'); + + expect(getIsolationScope().getScopeData().conversationId).toBe('edge-conversation'); + }); + + it('updates a span name through the public entry point', () => { + const span = new SentrySpan({ name: 'original' }); + updateSpanName(span, 'renamed'); + expect(span.getSpanJSON().name).toBe('renamed'); + span.end(); + }); + + it('creates the GrowthBook integration through the public entry point', () => { + class GrowthBook { + public isOn(): boolean { + return true; + } + public getFeatureValue(): unknown { + return false; + } + } + + expect(growthbookIntegration({ growthbookClass: GrowthBook }).name).toBe('GrowthBook'); + }); + + it('wraps a React agent factory and preserves its result', () => { + const graph = {}; + const createAgent = instrumentCreateReactAgent(() => graph); + + expect(createAgent()).toBe(graph); + }); +});