From 9a175783bf2a56a6b3c6602a23d618a1d4cc5e44 Mon Sep 17 00:00:00 2001 From: grootbro Date: Mon, 7 Sep 2026 17:03:12 +0700 Subject: [PATCH 1/2] fix(react-native): support Expo SDK 55 and harden user-agent init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Widen expo peer ranges past the old 5–7 / 14–18 caps, and resolve getWebViewUserAgentAsync through a namespace import so Metro/CJS interop cannot crash SDK construction when the helper is nested or missing. --- packages/sdks/react-native/index.ts | 23 +++++++++++++++++++++-- packages/sdks/react-native/package.json | 4 ++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/sdks/react-native/index.ts b/packages/sdks/react-native/index.ts index 9044c692f..8884ac726 100644 --- a/packages/sdks/react-native/index.ts +++ b/packages/sdks/react-native/index.ts @@ -5,13 +5,32 @@ import type { } from '@openpanel/sdk'; import { OpenPanel as OpenPanelBase } from '@openpanel/sdk'; import * as Application from 'expo-application'; -import Constants from 'expo-constants'; +import * as ExpoConstants from 'expo-constants'; import { AppState, Platform } from 'react-native'; export * from '@openpanel/sdk'; const QUEUE_STORAGE_KEY = '@openpanel/offline_queue'; +/** + * Metro/CJS interop can nest the real module under `.default` when this + * package is consumed as ESM. Prefer the same `import *` shape we already + * use for expo-application, and fall back if the helper is missing so init + * never crashes (e.g. Expo SDK 55+ with previously unmet peers). + */ +function getWebViewUserAgent(): Promise { + const mod = ExpoConstants as typeof ExpoConstants & { + default?: typeof ExpoConstants; + }; + const constants = (mod.default ?? mod) as { + getWebViewUserAgentAsync?: () => Promise; + }; + if (typeof constants.getWebViewUserAgentAsync !== 'function') { + return Promise.resolve(null); + } + return constants.getWebViewUserAgentAsync(); +} + interface StorageLike { getItem(key: string): Promise; setItem(key: string, value: string): Promise; @@ -59,7 +78,7 @@ export class OpenPanel extends OpenPanelBase { sdkVersion: process.env.REACT_NATIVE_VERSION!, }); - this.api.addHeader('User-Agent', Constants.getWebViewUserAgentAsync()); + this.api.addHeader('User-Agent', getWebViewUserAgent()); this.storage = options.storage; if (options.networkInfo) { diff --git a/packages/sdks/react-native/package.json b/packages/sdks/react-native/package.json index fcca7fa79..cd67201bc 100644 --- a/packages/sdks/react-native/package.json +++ b/packages/sdks/react-native/package.json @@ -20,8 +20,8 @@ "typescript": "catalog:" }, "peerDependencies": { - "expo-application": "5 - 7", - "expo-constants": "14 - 18", + "expo-application": ">=5", + "expo-constants": ">=14", "react-native": "*" } } From 5cd1e85239c118c329d54b3fe0512d556fc4112d Mon Sep 17 00:00:00 2001 From: grootbro Date: Mon, 7 Sep 2026 17:26:52 +0700 Subject: [PATCH 2/2] fix(react-native): bound Expo peer ranges through SDK 55 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep the previously validated 5–7 / 14–18 caps and add the Expo SDK-aligned majors 50–55 so Expo 55 is accepted without an open-ended >=. --- packages/sdks/react-native/package.json | 4 ++-- pnpm-lock.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/sdks/react-native/package.json b/packages/sdks/react-native/package.json index cd67201bc..258ba9d53 100644 --- a/packages/sdks/react-native/package.json +++ b/packages/sdks/react-native/package.json @@ -20,8 +20,8 @@ "typescript": "catalog:" }, "peerDependencies": { - "expo-application": ">=5", - "expo-constants": ">=14", + "expo-application": "5 - 7 || 50 - 55", + "expo-constants": "14 - 18 || 50 - 55", "react-native": "*" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a88b23d96..4119cc874 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1844,10 +1844,10 @@ importers: specifier: workspace:1.3.1-local version: link:../sdk expo-application: - specifier: 5 - 7 + specifier: 5 - 7 || 50 - 55 version: 5.3.1(expo@50.0.7(@babel/core@7.29.0(supports-color@10.2.0))(@react-native/babel-preset@0.73.21(@babel/core@7.29.0(supports-color@10.2.0))(@babel/preset-env@7.23.9(@babel/core@7.29.0(supports-color@10.2.0))(supports-color@10.2.0))(supports-color@10.2.0))(bluebird@3.7.2)(react-native@0.73.6(@babel/core@7.29.0(supports-color@10.2.0))(@babel/preset-env@7.23.9(@babel/core@7.29.0(supports-color@10.2.0))(supports-color@10.2.0))(react@18.2.0)(supports-color@10.2.0))(react@18.2.0)(supports-color@10.2.0)) expo-constants: - specifier: 14 - 18 + specifier: 14 - 18 || 50 - 55 version: 15.4.5(expo@50.0.7(@babel/core@7.29.0(supports-color@10.2.0))(@react-native/babel-preset@0.73.21(@babel/core@7.29.0(supports-color@10.2.0))(@babel/preset-env@7.23.9(@babel/core@7.29.0(supports-color@10.2.0))(supports-color@10.2.0))(supports-color@10.2.0))(bluebird@3.7.2)(react-native@0.73.6(@babel/core@7.29.0(supports-color@10.2.0))(@babel/preset-env@7.23.9(@babel/core@7.29.0(supports-color@10.2.0))(supports-color@10.2.0))(react@18.2.0)(supports-color@10.2.0))(react@18.2.0)(supports-color@10.2.0))(supports-color@10.2.0) react-native: specifier: '*'