Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions packages/deno/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type { DenoOptions } from './types';
export {
addEventProcessor,
addBreadcrumb,
addIntegration,
captureException,
captureEvent,
captureMessage,
Expand All @@ -52,6 +53,7 @@ export {
setAttribute,
setAttributes,
setUser,
setConversationId,
getSpanStatusFromHttpCode,
setHttpStatus,
withScope,
Expand All @@ -69,6 +71,8 @@ export {
startNewTrace,
bindScopeToEmitter,
suppressTracing,
withActiveSpan,
getSpanDescendants,
eventFiltersIntegration,
linkedErrorsIntegration,
functionToStringIntegration,
Expand All @@ -78,6 +82,7 @@ export {
dedupeIntegration,
extraErrorDataIntegration,
rewriteFramesIntegration,
moduleMetadataIntegration,
supabaseIntegration,
instrumentSupabaseClient,
zodErrorsIntegration,
Expand All @@ -94,7 +99,9 @@ export {
spanToTraceHeader,
spanToBaggageHeader,
updateSpanName,
createConsolaReporter,
featureFlagsIntegration,
growthbookIntegration,
metrics,
withStaticSpan,
// oxlint-disable-next-line typescript/no-deprecated
Expand All @@ -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';
Expand Down
23 changes: 19 additions & 4 deletions packages/deno/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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());

/**
Expand Down Expand Up @@ -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,
Expand Down
42 changes: 42 additions & 0 deletions packages/deno/test/exports.test.ts
Original file line number Diff line number Diff line change
@@ -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<string, unknown>)[name], 'function');
});
}

Deno.test('exports the FlueOptions type', () => {
const options: FlueOptions = {};
assertEquals(typeof options, 'object');
});
38 changes: 38 additions & 0 deletions packages/deno/test/sdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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']);
});
Loading