From 618f6630991b4a2945a999e0aec3db6cfe7ac292 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Fri, 27 Feb 2026 14:48:46 +0100 Subject: [PATCH 1/2] test(metro): Add type tests for SentryExpoConfigOptions.getDefaultConfig Adds type compatibility tests validating the fix from #5246: - New format: a function with the flexible `Record` signature (Expo SDK 54 style, accommodating diverged Metro types) - Old format: the classic wrapping pattern where users call `expo/metro-config`'s getDefaultConfig and return a modified config Follows up on the type-test suggestion in https://github.com/getsentry/sentry-react-native/pull/5246#issuecomment-3384725753 Co-Authored-By: Claude Sonnet 4.6 --- packages/core/test/tools/metroconfig.test.ts | 43 ++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/packages/core/test/tools/metroconfig.test.ts b/packages/core/test/tools/metroconfig.test.ts index 2d2addeb11..8b3b0a78a2 100644 --- a/packages/core/test/tools/metroconfig.test.ts +++ b/packages/core/test/tools/metroconfig.test.ts @@ -7,6 +7,7 @@ import { withSentryFramesCollapsed, withSentryResolver, } from '../../src/js/tools/metroconfig'; +import type { SentryExpoConfigOptions } from '../../src/js/tools/metroconfig'; import { SENTRY_BABEL_TRANSFORMER_OPTIONS, SENTRY_DEFAULT_BABEL_TRANSFORMER_PATH, @@ -31,6 +32,48 @@ describe('metroconfig', () => { acceptsExpoDefaultConfigFactory(getSentryExpoConfig); }); + describe('SentryExpoConfigOptions.getDefaultConfig type compatibility', () => { + const checkCompatibility = (_options: SentryExpoConfigOptions): void => { + expect(true).toBe(true); + }; + + test('accepts a getDefaultConfig with the new flexible Record signature (Expo SDK 54 format)', () => { + // Expo SDK 54 Metro type definitions diverged from the metro package. + // The fix allows passing a getDefaultConfig with flexible types rather than + // the exact MetroConfig return type, accommodating different Metro versions. + const newFormatGetDefaultConfig = ( + _projectRoot: string, + _options?: Record, + ): Record => ({}); + + checkCompatibility({ getDefaultConfig: newFormatGetDefaultConfig }); + }); + + test('accepts a getDefaultConfig wrapping expo/metro-config (old usage pattern)', () => { + // Old usage pattern: users wrapping expo/metro-config's getDefaultConfig to + // add custom transformer or resolver config (e.g. react-native-svg-transformer). + // Record options are compatible with DefaultConfigOptions, + // and the spread object return type is compatible with Record. + const expoGetDefaultConfigMock: typeof getDefaultConfig = jest.fn().mockReturnValue({}); + + const oldPatternGetDefaultConfig = ( + projectRoot: string, + options?: Record, + ) => { + // Record is compatible with DefaultConfigOptions (all optional fields) + const config = expoGetDefaultConfigMock(projectRoot, options as Parameters[1]); + return { + ...config, + transformer: { + ...config.transformer, + }, + }; + }; + + checkCompatibility({ getDefaultConfig: oldPatternGetDefaultConfig }); + }); + }); + describe('withSentryFramesCollapsed', () => { test('adds customizeFrames if undefined ', () => { const config = withSentryFramesCollapsed({}); From 92cacda5cac4dd503ddf619472219527fba697f6 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Fri, 27 Feb 2026 15:07:53 +0100 Subject: [PATCH 2/2] Fix lint issue --- packages/core/test/tools/metroconfig.test.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/core/test/tools/metroconfig.test.ts b/packages/core/test/tools/metroconfig.test.ts index 8b3b0a78a2..18177fb71e 100644 --- a/packages/core/test/tools/metroconfig.test.ts +++ b/packages/core/test/tools/metroconfig.test.ts @@ -1,13 +1,13 @@ import type { getDefaultConfig } from 'expo/metro-config'; import type { MetroConfig } from 'metro'; import * as process from 'process'; +import type { SentryExpoConfigOptions } from '../../src/js/tools/metroconfig'; import { getSentryExpoConfig, withSentryBabelTransformer, withSentryFramesCollapsed, withSentryResolver, } from '../../src/js/tools/metroconfig'; -import type { SentryExpoConfigOptions } from '../../src/js/tools/metroconfig'; import { SENTRY_BABEL_TRANSFORMER_OPTIONS, SENTRY_DEFAULT_BABEL_TRANSFORMER_PATH, @@ -56,10 +56,7 @@ describe('metroconfig', () => { // and the spread object return type is compatible with Record. const expoGetDefaultConfigMock: typeof getDefaultConfig = jest.fn().mockReturnValue({}); - const oldPatternGetDefaultConfig = ( - projectRoot: string, - options?: Record, - ) => { + const oldPatternGetDefaultConfig = (projectRoot: string, options?: Record) => { // Record is compatible with DefaultConfigOptions (all optional fields) const config = expoGetDefaultConfigMock(projectRoot, options as Parameters[1]); return {