@symbiote-native/web-browser 3.0.1 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,14 +1,13 @@
1
1
  # @symbiote-native/web-browser
2
2
 
3
- A wrapper package for [SymbioteNative](../../README.md) that makes
4
- [`expo-web-browser`](https://github.com/expo/expo/tree/main/packages/expo-web-browser) — an in-app
5
- browser (`SFSafariViewController` on iOS, Chrome Custom Tabs on Android) plus the OAuth
6
- auth-session flow — usable from **every** adapter, React, Vue, Svelte, Solid, and Angular, not just
7
- React. Built the same way as [`@symbiote-native/secure-store`](../secure-store): an
8
- `expo-modules-core`-based wrapper (see the `symbiote-expo-native-module` project skill for the full
9
- mechanism — why `expo-modules-core` is depended on directly and never the `expo` meta-package, why
10
- the upstream JS is hand-ported into `core/` rather than imported, and how autolinking picks up the
11
- native module).
3
+ Open a link in an in-app browser (`SFSafariViewController` on iOS, Chrome Custom Tabs on Android),
4
+ or run an OAuth login in one and get the redirect back. One API for every
5
+ [SymbioteNative](../../README.md) adapter (React, Vue, Svelte, Solid and Angular).
6
+
7
+ It wraps [`expo-web-browser`](https://github.com/expo/expo/tree/main/packages/expo-web-browser)
8
+ the same way [`@symbiote-native/secure-store`](../secure-store) wraps its upstream:
9
+ `expo-modules-core` is a direct dependency, never the `expo` meta-package, and the upstream JS is
10
+ hand-ported into `core/`. The mechanics live in the `symbiote-expo-native-module` project skill.
12
11
 
13
12
  ## Install
14
13
 
@@ -24,35 +23,35 @@ npx @symbiote-native/cli new my-app --web-browser
24
23
  npx @symbiote-native/cli add --web-browser
25
24
  ```
26
25
 
27
- Either way: installs `@symbiote-native/web-browser` and wires the native autolinking automatically — see
26
+ Either way: installs `@symbiote-native/web-browser` and wires the native autolinking automatically - see
28
27
  [`@symbiote-native/cli`](../cli).
29
28
 
30
29
  <details>
31
- <summary>Manual install (no CLI — installing and wiring native autolinking by hand)</summary>
30
+ <summary>Manual install (no CLI - installing and wiring native autolinking by hand)</summary>
32
31
 
33
32
  ```bash
34
33
  npm install @symbiote-native/web-browser
35
34
  ```
36
35
 
37
- `expo-web-browser` and `expo-modules-core` come along as regular, pinned dependencies — never
36
+ `expo-web-browser` and `expo-modules-core` come along as regular, pinned dependencies - never
38
37
  install either yourself, and never add the `expo` meta-package to this project (it bundles its own
39
38
  Metro/Babel pipeline that conflicts with this project's own).
40
39
 
41
40
  ### Required one-time step: native autolinking wiring
42
41
 
43
42
  Unlike a plain RN native module, `expo-web-browser`'s native code is discovered by
44
- `expo-modules-autolinking` — this needs wiring into the native host app **once**, covering this
43
+ `expo-modules-autolinking` - this needs wiring into the native host app **once**, covering this
45
44
  package and every other `expo-modules-core` package with zero further changes:
46
45
 
47
46
  | Platform | Touches |
48
47
  | -------- | ------------------------------------------------------------------------------------- |
49
- | iOS | `ios/Podfile` — add `use_expo_modules!` |
50
- | iOS | `AppDelegate.swift` — Expo's runtime-bootstrap hook |
51
- | Android | `settings.gradle` / `app/build.gradle` — resolve and include the Expo Gradle projects |
52
- | Android | `MainApplication.kt` — Expo's bootstrap hook, plus a native-module name map |
48
+ | iOS | `ios/Podfile` - add `use_expo_modules!` |
49
+ | iOS | `AppDelegate.swift` - Expo's runtime-bootstrap hook |
50
+ | Android | `settings.gradle` / `app/build.gradle` - resolve and include the Expo Gradle projects |
51
+ | Android | `MainApplication.kt` - Expo's bootstrap hook, plus a native-module name map |
53
52
 
54
53
  Full mechanics live in the `symbiote-expo-native-module` skill. The per-package half of that table
55
- — the Gradle dependency and the module map entry — is generated by
54
+ (the Gradle dependency and the module map entry) is generated by
56
55
  [`@symbiote-native/expo-modules-link`](../expo-modules-link) from this package's `native-link.json`
57
56
  on every install. No `Info.plist` usage description is needed, and the `<queries>` entry Android
58
57
  needs to see the Custom Tabs service ships inside `expo-web-browser`'s own manifest and merges into
@@ -70,8 +69,8 @@ src/angular/ @symbiote-native/web-browser/angular
70
69
  ```
71
70
 
72
71
  `./react`, `./vue`, `./svelte`, and `./solid` are `exports`-map aliases straight onto
73
- `src/core/` — no physical per-framework file. Every export is a stateless free function; the one
74
- piece of live state — the Android auth-session polyfill's redirect subscription — belongs to a
72
+ `src/core/` - no physical per-framework file. Every export is a stateless free function; the one
73
+ piece of live state - the Android auth-session polyfill's redirect subscription - belongs to a
75
74
  single in-flight promise inside the core and never surfaces as something a caller subscribes to or
76
75
  tears down. So there is nothing for a hook, composable, or service to wrap, the same reason
77
76
  [`@symbiote-native/secure-store`](../secure-store) does the same. `./angular` stays a physical
@@ -87,7 +86,7 @@ import * as WebBrowser from '@symbiote-native/web-browser';
87
86
  await WebBrowser.openBrowserAsync('https://example.com');
88
87
  ```
89
88
 
90
- Every framework subpath re-exports the identical free functions — pick whichever import matches
89
+ Every framework subpath re-exports the identical free functions - pick whichever import matches
91
90
  the app's own adapter, or the bare package if you don't care:
92
91
 
93
92
  ```ts
@@ -98,7 +97,7 @@ import { openBrowserAsync } from '@symbiote-native/web-browser/solid';
98
97
  import { openBrowserAsync } from '@symbiote-native/web-browser/angular';
99
98
  ```
100
99
 
101
- These mirror the real canary demo screens —
100
+ These mirror the real canary demo screens -
102
101
  `examples/expo-react/screens/WebBrowserScreen.tsx`,
103
102
  `examples/expo-vue-sfc/screens/WebBrowserScreen.vue`,
104
103
  `examples/expo-vue-tsx/screens/WebBrowserScreen.tsx`,
@@ -127,7 +126,7 @@ if (result.type === 'success') {
127
126
  iOS uses `ASWebAuthenticationSession`, so the system asks the user whether the app may authenticate
128
127
  with that url, and the redirect URI registered with the authorization server has to use the app's
129
128
  own scheme (`myapp://`, not `https://`). Android has no equivalent, so it is polyfilled with a
130
- Custom Tab racing `Linking` against `AppState` — adding your own `Linking` listener for the same
129
+ Custom Tab racing `Linking` against `AppState` - adding your own `Linking` listener for the same
131
130
  redirect is unnecessary on both, and on iOS can have side effects.
132
131
 
133
132
  Warming the Custom Tabs service up before you need it, on Android:
@@ -144,13 +143,13 @@ await WebBrowser.coolDownAsync(servicePackage);
144
143
  | Export | Signature | Notes |
145
144
  | -------------------------------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
146
145
  | `openBrowserAsync` | `(url, options?) => Promise<IWebBrowserResult>` | Opens the in-app browser. |
147
- | `dismissBrowser` | `() => Promise<IWebBrowserDismissResult>` | iOS only — throws elsewhere, since a Custom Tab cannot be closed programmatically. |
146
+ | `dismissBrowser` | `() => Promise<IWebBrowserDismissResult>` | iOS only - throws elsewhere, since a Custom Tab cannot be closed programmatically. |
148
147
  | `openAuthSessionAsync` | `(url, redirectUrl?, options?) => Promise<IWebBrowserAuthSessionResult>` | Resolves `{ type: 'success', url }` on the redirect. |
149
148
  | `dismissAuthSession` | `() => void` | iOS only, for the same reason as `dismissBrowser`. |
150
149
  | `warmUpAsync` | `(browserPackage?) => Promise<IWebBrowserWarmUpResult>` | Android. Resolves `{}` elsewhere. |
151
150
  | `mayInitWithUrlAsync` | `(url, browserPackage?) => Promise<IWebBrowserMayInitWithUrlResult>` | Android. Resolves `{}` elsewhere. |
152
151
  | `coolDownAsync` | `(browserPackage?) => Promise<IWebBrowserCoolDownResult>` | Android. Resolves `{}` elsewhere. |
153
- | `getCustomTabsSupportingBrowsersAsync` | `() => Promise<IWebBrowserCustomTabsResults>` | Android. Throws on iOS — see the note below. |
152
+ | `getCustomTabsSupportingBrowsersAsync` | `() => Promise<IWebBrowserCustomTabsResults>` | Android. Throws on iOS - see the note below. |
154
153
  | `WebBrowserResultType` | `enum` | `CANCEL`, `DISMISS`, `OPENED`, `LOCKED`. |
155
154
  | `WebBrowserPresentationStyle` | `enum` | iOS modal presentation styles for `options.presentationStyle`. |
156
155
 
@@ -159,6 +158,12 @@ await WebBrowser.coolDownAsync(servicePackage);
159
158
  `useProxyActivity`; iOS's `controlsColor`, `dismissButtonStyle`, `readerMode`, `presentationStyle`.
160
159
  `IAuthSessionOpenOptions` adds iOS's `preferEphemeralSession` and `preferUniversalLinks`.
161
160
 
161
+ ## maybeCompleteAuthSession
162
+
163
+ Ported so shared code that calls it at module scope, as Expo apps do, keeps working. It closes the
164
+ web popup of an auth session, so on iOS and Android it returns
165
+ `{ type: 'failed', message: 'Not supported on this platform' }`.
166
+
162
167
  ## Not ported
163
168
 
164
169
  - **The `experimentalLauncherActivity` config plugin.** Upstream's
@@ -168,15 +173,14 @@ await WebBrowser.coolDownAsync(servicePackage);
168
173
  upstream and unnecessary for `openBrowserAsync`, `openAuthSessionAsync`, or anything else on this
169
174
  page, so this package does not reproduce it. An app that genuinely wants that workaround adds the
170
175
  activity by hand.
171
- - **`maybeCompleteAuthSession`.** Genuinely web-only: it closes the `window.open` popup the web
172
- implementation of `openAuthSessionAsync` created. On a native platform upstream's own version can
173
- only ever return `{ type: 'failed', message: 'Not supported on this platform' }`, so it is left
174
- out rather than shipped as a function that can never succeed.
175
- - **The web-only open options** `windowName` and `windowFeatures`, for the same reason —
176
+ - **The web-only open options** `windowName` and `windowFeatures`, for the same reason -
176
177
  SymbioteNative has no web target, so nothing could read them.
177
178
 
178
179
  ## Notes
179
180
 
181
+ - **Pick the call by purpose.** Use `openBrowserAsync` to show a page (a privacy policy, docs). Use
182
+ `openAuthSessionAsync` for login: since iOS 11 `SFSafariViewController` no longer shares cookies
183
+ with Safari, so the auth session is the one that sees the user's signed-in state.
180
184
  - **`getCustomTabsSupportingBrowsersAsync` throws on iOS rather than resolving empty.** iOS's
181
185
  native module registers its no-op stub as `getCustomTabsSupportingBrowsers`, without the `Async`
182
186
  suffix, so the availability check fires before the "not Android, return an empty result" branch
@@ -187,14 +191,30 @@ await WebBrowser.coolDownAsync(servicePackage);
187
191
  `controlsColor` go through `processColor`, so any React Native color format works.
188
192
  - **Only one auth session at a time.** Starting a second one while the first is open rejects.
189
193
 
194
+ ## Common questions
195
+
196
+ - **Login returns `cancel` though I signed in.** The redirect never reached the app: use your own
197
+ URL scheme (`myapp://`, not `https://`), register it in both native projects, and allow-list the
198
+ same URI at the provider. A mismatched Android intent filter makes every attempt look cancelled.
199
+ - **`openBrowserAsync` resolves at launch on Android.** Custom Tabs report no close; use
200
+ `openAuthSessionAsync` when you need to know the user returned.
201
+ - **`cancel` vs `dismiss`.** `cancel`: the user closed the browser or returned without a redirect.
202
+ `dismiss`: your code called `dismissBrowser`.
203
+ - **Sign-in with `openBrowserAsync`?** No; use `openAuthSessionAsync` (no shared Safari cookies).
204
+
205
+ Sources: [expo/expo#23781](https://github.com/expo/expo/issues/23781),
206
+ [expo/expo#6289](https://github.com/expo/expo/issues/6289),
207
+ [expo/expo#12044](https://github.com/expo/expo/issues/12044),
208
+ [expo/expo#6679](https://github.com/expo/expo/issues/6679).
209
+
190
210
  ## Test it
191
211
 
192
212
  ```bash
193
213
  pnpm vitest run packages/web-browser
194
214
  ```
195
215
 
196
- The core tests fake the native module in place of `requireNativeModule`'s runtime resolution —
197
- `ExpoWebBrowser` only exists on a device — and drive fake `AppState`/`Linking` event sources so the
216
+ The core tests fake the native module in place of `requireNativeModule`'s runtime resolution -
217
+ `ExpoWebBrowser` only exists on a device - and drive fake `AppState`/`Linking` event sources so the
198
218
  Android auth-session polyfill's race is exercised headlessly. The browser itself, the iOS
199
219
  `ASWebAuthenticationSession` consent prompt, and real deep-link delivery can only be verified on a
200
220
  device or simulator.
@@ -1,3 +1,3 @@
1
- export { getCustomTabsSupportingBrowsersAsync, warmUpAsync, mayInitWithUrlAsync, coolDownAsync, openBrowserAsync, dismissBrowser, openAuthSessionAsync, dismissAuthSession, } from './web-browser';
1
+ export { getCustomTabsSupportingBrowsersAsync, warmUpAsync, mayInitWithUrlAsync, coolDownAsync, openBrowserAsync, dismissBrowser, openAuthSessionAsync, dismissAuthSession, maybeCompleteAuthSession, } from './web-browser';
2
2
  export { WebBrowserResultType, WebBrowserPresentationStyle } from './types';
3
- export type { IAuthSessionOpenOptions, IRedirectEvent, IServiceActionResult, IWebBrowserAuthSessionResult, IWebBrowserCoolDownResult, IWebBrowserCustomTabsResults, IWebBrowserDismissResult, IWebBrowserMayInitWithUrlResult, IWebBrowserOpenOptions, IWebBrowserRedirectResult, IWebBrowserResult, IWebBrowserWarmUpResult, } from './types';
3
+ export type { IAuthSessionOpenOptions, IRedirectEvent, IServiceActionResult, IWebBrowserAuthSessionResult, IWebBrowserCompleteAuthSessionOptions, IWebBrowserCompleteAuthSessionResult, IWebBrowserCoolDownResult, IWebBrowserCustomTabsResults, IWebBrowserDismissResult, IWebBrowserMayInitWithUrlResult, IWebBrowserOpenOptions, IWebBrowserRedirectResult, IWebBrowserResult, IWebBrowserWarmUpResult, } from './types';
@@ -1,2 +1,2 @@
1
- export { getCustomTabsSupportingBrowsersAsync, warmUpAsync, mayInitWithUrlAsync, coolDownAsync, openBrowserAsync, dismissBrowser, openAuthSessionAsync, dismissAuthSession, } from './web-browser.js';
1
+ export { getCustomTabsSupportingBrowsersAsync, warmUpAsync, mayInitWithUrlAsync, coolDownAsync, openBrowserAsync, dismissBrowser, openAuthSessionAsync, dismissAuthSession, maybeCompleteAuthSession, } from './web-browser.js';
2
2
  export { WebBrowserResultType, WebBrowserPresentationStyle } from './types.js';
@@ -1,4 +1,4 @@
1
- import type { IProcessedOpenOptions, IWebBrowserAuthSessionResult, IWebBrowserCoolDownResult, IWebBrowserCustomTabsResults, IWebBrowserDismissResult, IWebBrowserMayInitWithUrlResult, IWebBrowserResult, IWebBrowserWarmUpResult } from './types';
1
+ import type { IProcessedOpenOptions, IWebBrowserCompleteAuthSessionOptions, IWebBrowserCompleteAuthSessionResult, IWebBrowserAuthSessionResult, IWebBrowserCoolDownResult, IWebBrowserCustomTabsResults, IWebBrowserDismissResult, IWebBrowserMayInitWithUrlResult, IWebBrowserResult, IWebBrowserWarmUpResult } from './types';
2
2
  export type INativeWebBrowserModule = {
3
3
  openBrowserAsync?(url: string, options: IProcessedOpenOptions): Promise<IWebBrowserResult>;
4
4
  dismissBrowser?(): Promise<IWebBrowserDismissResult>;
@@ -8,5 +8,6 @@ export type INativeWebBrowserModule = {
8
8
  coolDownAsync?(browserPackage?: string): Promise<IWebBrowserCoolDownResult>;
9
9
  mayInitWithUrlAsync?(url: string, browserPackage?: string): Promise<IWebBrowserMayInitWithUrlResult>;
10
10
  getCustomTabsSupportingBrowsersAsync?(): Promise<IWebBrowserCustomTabsResults>;
11
+ maybeCompleteAuthSession?(options: IWebBrowserCompleteAuthSessionOptions): IWebBrowserCompleteAuthSessionResult;
11
12
  };
12
13
  export declare const expoWebBrowser: INativeWebBrowserModule;
@@ -187,6 +187,14 @@ export type IWebBrowserRedirectResult = {
187
187
  export type IServiceActionResult = {
188
188
  servicePackage?: string;
189
189
  };
190
+ export type IWebBrowserCompleteAuthSessionOptions = {
191
+ /** Close the window without checking the redirect against the cached redirect URL */
192
+ skipRedirectCheck?: boolean;
193
+ };
194
+ export type IWebBrowserCompleteAuthSessionResult = {
195
+ type: 'success' | 'failed';
196
+ message: string;
197
+ };
190
198
  export type IWebBrowserAuthSessionResult = IWebBrowserRedirectResult | IWebBrowserResult;
191
199
  export type IWebBrowserMayInitWithUrlResult = IServiceActionResult;
192
200
  export type IWebBrowserWarmUpResult = IServiceActionResult;
@@ -1,4 +1,4 @@
1
- import { type IAuthSessionOpenOptions, type IWebBrowserAuthSessionResult, type IWebBrowserCoolDownResult, type IWebBrowserCustomTabsResults, type IWebBrowserDismissResult, type IWebBrowserMayInitWithUrlResult, type IWebBrowserOpenOptions, type IWebBrowserResult, type IWebBrowserWarmUpResult } from './types';
1
+ import { type IAuthSessionOpenOptions, type IWebBrowserAuthSessionResult, type IWebBrowserCompleteAuthSessionOptions, type IWebBrowserCompleteAuthSessionResult, type IWebBrowserCoolDownResult, type IWebBrowserCustomTabsResults, type IWebBrowserDismissResult, type IWebBrowserMayInitWithUrlResult, type IWebBrowserOpenOptions, type IWebBrowserResult, type IWebBrowserWarmUpResult } from './types';
2
2
  /**
3
3
  * The packages that support Custom Tabs, the Custom Tabs service, and the user's chosen and
4
4
  * preferred browser. Only as reliable as `PackageManager.getResolvingActivities` underneath — a
@@ -81,3 +81,5 @@ export declare function openAuthSessionAsync(url: string, redirectUrl?: string |
81
81
  * @platform ios
82
82
  */
83
83
  export declare function dismissAuthSession(): void;
84
+ /** @platform web */
85
+ export declare function maybeCompleteAuthSession(options?: IWebBrowserCompleteAuthSessionOptions): IWebBrowserCompleteAuthSessionResult;
@@ -1,8 +1,5 @@
1
- // Hand-ported from .vendors/expo/packages/expo-web-browser/src/WebBrowser.ts (sdk-57). Two
2
- // deliberate departures from upstream, both because SymbioteNative has no web target:
3
- // `maybeCompleteAuthSession` is not ported (it exists only to close a `window.open` popup; on a
4
- // native platform it can do nothing but return `{ type: 'failed' }`), and the web-only open
5
- // options are gone from IWebBrowserOpenOptions.
1
+ // Hand-ported from .vendors/expo/packages/expo-web-browser/src/WebBrowser.ts (sdk-57)
2
+ // The web-only open options are gone from IWebBrowserOpenOptions, SymbioteNative has no web target
6
3
  import { Platform, UnavailabilityError } from 'expo-modules-core';
7
4
  import { AppState, Linking, processColor } from 'react-native';
8
5
  import { expoWebBrowser } from './native-module.js';
@@ -161,6 +158,14 @@ export function dismissAuthSession() {
161
158
  }
162
159
  void expoWebBrowser.dismissBrowser();
163
160
  }
161
+ // Native has no popup to close, so it reports `failed` and shared code can call it at module scope
162
+ /** @platform web */
163
+ export function maybeCompleteAuthSession(options = {}) {
164
+ if (expoWebBrowser.maybeCompleteAuthSession) {
165
+ return expoWebBrowser.maybeCompleteAuthSession(options);
166
+ }
167
+ return { type: 'failed', message: 'Not supported on this platform' };
168
+ }
164
169
  function processOptions(options) {
165
170
  return {
166
171
  ...options,
@@ -1,3 +1,3 @@
1
- export { getCustomTabsSupportingBrowsersAsync, warmUpAsync, mayInitWithUrlAsync, coolDownAsync, openBrowserAsync, dismissBrowser, openAuthSessionAsync, dismissAuthSession, } from './web-browser';
1
+ export { getCustomTabsSupportingBrowsersAsync, warmUpAsync, mayInitWithUrlAsync, coolDownAsync, openBrowserAsync, dismissBrowser, openAuthSessionAsync, dismissAuthSession, maybeCompleteAuthSession, } from './web-browser';
2
2
  export { WebBrowserResultType, WebBrowserPresentationStyle } from './types';
3
- export type { IAuthSessionOpenOptions, IRedirectEvent, IServiceActionResult, IWebBrowserAuthSessionResult, IWebBrowserCoolDownResult, IWebBrowserCustomTabsResults, IWebBrowserDismissResult, IWebBrowserMayInitWithUrlResult, IWebBrowserOpenOptions, IWebBrowserRedirectResult, IWebBrowserResult, IWebBrowserWarmUpResult, } from './types';
3
+ export type { IAuthSessionOpenOptions, IRedirectEvent, IServiceActionResult, IWebBrowserAuthSessionResult, IWebBrowserCompleteAuthSessionOptions, IWebBrowserCompleteAuthSessionResult, IWebBrowserCoolDownResult, IWebBrowserCustomTabsResults, IWebBrowserDismissResult, IWebBrowserMayInitWithUrlResult, IWebBrowserOpenOptions, IWebBrowserRedirectResult, IWebBrowserResult, IWebBrowserWarmUpResult, } from './types';
@@ -1,3 +1,3 @@
1
- export { getCustomTabsSupportingBrowsersAsync, warmUpAsync, mayInitWithUrlAsync, coolDownAsync, openBrowserAsync, dismissBrowser, openAuthSessionAsync, dismissAuthSession, } from './web-browser';
1
+ export { getCustomTabsSupportingBrowsersAsync, warmUpAsync, mayInitWithUrlAsync, coolDownAsync, openBrowserAsync, dismissBrowser, openAuthSessionAsync, dismissAuthSession, maybeCompleteAuthSession, } from './web-browser';
2
2
  export { WebBrowserResultType, WebBrowserPresentationStyle } from './types';
3
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oCAAoC,EACpC,WAAW,EACX,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oCAAoC,EACpC,WAAW,EACX,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { IProcessedOpenOptions, IWebBrowserAuthSessionResult, IWebBrowserCoolDownResult, IWebBrowserCustomTabsResults, IWebBrowserDismissResult, IWebBrowserMayInitWithUrlResult, IWebBrowserResult, IWebBrowserWarmUpResult } from './types';
1
+ import type { IProcessedOpenOptions, IWebBrowserCompleteAuthSessionOptions, IWebBrowserCompleteAuthSessionResult, IWebBrowserAuthSessionResult, IWebBrowserCoolDownResult, IWebBrowserCustomTabsResults, IWebBrowserDismissResult, IWebBrowserMayInitWithUrlResult, IWebBrowserResult, IWebBrowserWarmUpResult } from './types';
2
2
  export type INativeWebBrowserModule = {
3
3
  openBrowserAsync?(url: string, options: IProcessedOpenOptions): Promise<IWebBrowserResult>;
4
4
  dismissBrowser?(): Promise<IWebBrowserDismissResult>;
@@ -8,5 +8,6 @@ export type INativeWebBrowserModule = {
8
8
  coolDownAsync?(browserPackage?: string): Promise<IWebBrowserCoolDownResult>;
9
9
  mayInitWithUrlAsync?(url: string, browserPackage?: string): Promise<IWebBrowserMayInitWithUrlResult>;
10
10
  getCustomTabsSupportingBrowsersAsync?(): Promise<IWebBrowserCustomTabsResults>;
11
+ maybeCompleteAuthSession?(options: IWebBrowserCompleteAuthSessionOptions): IWebBrowserCompleteAuthSessionResult;
11
12
  };
12
13
  export declare const expoWebBrowser: INativeWebBrowserModule;
@@ -1 +1 @@
1
- {"version":3,"file":"native-module.js","sourceRoot":"","sources":["../../src/core/native-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAYxD,MAAM,4BAA4B,GAAG,gBAAgB,CAAC;AA+BtD,MAAM,CAAC,MAAM,cAAc,GAAG,mBAAmB,CAC/C,4BAA4B,CAC7B,CAAC"}
1
+ {"version":3,"file":"native-module.js","sourceRoot":"","sources":["../../src/core/native-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAcxD,MAAM,4BAA4B,GAAG,gBAAgB,CAAC;AAmCtD,MAAM,CAAC,MAAM,cAAc,GAAG,mBAAmB,CAC/C,4BAA4B,CAC7B,CAAC"}
@@ -187,6 +187,14 @@ export type IWebBrowserRedirectResult = {
187
187
  export type IServiceActionResult = {
188
188
  servicePackage?: string;
189
189
  };
190
+ export type IWebBrowserCompleteAuthSessionOptions = {
191
+ /** Close the window without checking the redirect against the cached redirect URL */
192
+ skipRedirectCheck?: boolean;
193
+ };
194
+ export type IWebBrowserCompleteAuthSessionResult = {
195
+ type: 'success' | 'failed';
196
+ message: string;
197
+ };
190
198
  export type IWebBrowserAuthSessionResult = IWebBrowserRedirectResult | IWebBrowserResult;
191
199
  export type IWebBrowserMayInitWithUrlResult = IServiceActionResult;
192
200
  export type IWebBrowserWarmUpResult = IServiceActionResult;
@@ -1,4 +1,4 @@
1
- import { type IAuthSessionOpenOptions, type IWebBrowserAuthSessionResult, type IWebBrowserCoolDownResult, type IWebBrowserCustomTabsResults, type IWebBrowserDismissResult, type IWebBrowserMayInitWithUrlResult, type IWebBrowserOpenOptions, type IWebBrowserResult, type IWebBrowserWarmUpResult } from './types';
1
+ import { type IAuthSessionOpenOptions, type IWebBrowserAuthSessionResult, type IWebBrowserCompleteAuthSessionOptions, type IWebBrowserCompleteAuthSessionResult, type IWebBrowserCoolDownResult, type IWebBrowserCustomTabsResults, type IWebBrowserDismissResult, type IWebBrowserMayInitWithUrlResult, type IWebBrowserOpenOptions, type IWebBrowserResult, type IWebBrowserWarmUpResult } from './types';
2
2
  /**
3
3
  * The packages that support Custom Tabs, the Custom Tabs service, and the user's chosen and
4
4
  * preferred browser. Only as reliable as `PackageManager.getResolvingActivities` underneath — a
@@ -81,3 +81,5 @@ export declare function openAuthSessionAsync(url: string, redirectUrl?: string |
81
81
  * @platform ios
82
82
  */
83
83
  export declare function dismissAuthSession(): void;
84
+ /** @platform web */
85
+ export declare function maybeCompleteAuthSession(options?: IWebBrowserCompleteAuthSessionOptions): IWebBrowserCompleteAuthSessionResult;
@@ -1,8 +1,5 @@
1
- // Hand-ported from .vendors/expo/packages/expo-web-browser/src/WebBrowser.ts (sdk-57). Two
2
- // deliberate departures from upstream, both because SymbioteNative has no web target:
3
- // `maybeCompleteAuthSession` is not ported (it exists only to close a `window.open` popup; on a
4
- // native platform it can do nothing but return `{ type: 'failed' }`), and the web-only open
5
- // options are gone from IWebBrowserOpenOptions.
1
+ // Hand-ported from .vendors/expo/packages/expo-web-browser/src/WebBrowser.ts (sdk-57)
2
+ // The web-only open options are gone from IWebBrowserOpenOptions, SymbioteNative has no web target
6
3
  import { Platform, UnavailabilityError } from 'expo-modules-core';
7
4
  import { AppState, Linking, processColor } from 'react-native';
8
5
  import { expoWebBrowser } from './native-module';
@@ -161,6 +158,14 @@ export function dismissAuthSession() {
161
158
  }
162
159
  void expoWebBrowser.dismissBrowser();
163
160
  }
161
+ // Native has no popup to close, so it reports `failed` and shared code can call it at module scope
162
+ /** @platform web */
163
+ export function maybeCompleteAuthSession(options = {}) {
164
+ if (expoWebBrowser.maybeCompleteAuthSession) {
165
+ return expoWebBrowser.maybeCompleteAuthSession(options);
166
+ }
167
+ return { type: 'failed', message: 'Not supported on this platform' };
168
+ }
164
169
  function processOptions(options) {
165
170
  return {
166
171
  ...options,
@@ -1 +1 @@
1
- {"version":3,"file":"web-browser.js","sourceRoot":"","sources":["../../src/core/web-browser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"web-browser.js","sourceRoot":"","sources":["../../src/core/web-browser.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbiote-native/web-browser",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "expo-web-browser wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. In-app browser (SFSafariViewController / Android Custom Tabs) and the OAuth auth-session flow.",
5
5
  "keywords": [
6
6
  "react-native",
@@ -69,7 +69,7 @@
69
69
  },
70
70
  "dependencies": {
71
71
  "expo-web-browser": "57.0.2",
72
- "expo-modules-core": "57.0.5"
72
+ "expo-modules-core": "57.0.20"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@angular/core": ">=20",
@@ -79,12 +79,12 @@
79
79
  "solid-js": ">=1.9.0",
80
80
  "svelte": ">=5.56.0",
81
81
  "vue": ">=3.5.0",
82
- "@symbiote-native/angular": "^3.1.1",
83
- "@symbiote-native/engine": "^1.3.0",
84
- "@symbiote-native/react": "^3.0.3",
85
- "@symbiote-native/solid": "^3.0.3",
86
- "@symbiote-native/svelte": "^3.0.3",
87
- "@symbiote-native/vue": "^3.0.3"
82
+ "@symbiote-native/angular": "^3.2.0",
83
+ "@symbiote-native/solid": "^3.1.0",
84
+ "@symbiote-native/react": "^3.2.0",
85
+ "@symbiote-native/svelte": "^3.1.0",
86
+ "@symbiote-native/engine": "^1.5.0",
87
+ "@symbiote-native/vue": "^3.2.0"
88
88
  },
89
89
  "peerDependenciesMeta": {
90
90
  "@symbiote-native/angular": {
@@ -132,13 +132,13 @@
132
132
  "solid-js": "^1.9.14",
133
133
  "svelte": "^5.56.0",
134
134
  "typescript": "~6.0.0",
135
- "@symbiote-native/angular": "3.1.1",
136
- "@symbiote-native/engine": "1.3.0",
137
- "@symbiote-native/react": "3.0.3",
138
- "@symbiote-native/solid": "3.0.3",
139
- "@symbiote-native/svelte": "3.0.3",
140
- "@symbiote-native/test-utils": "0.4.3",
141
- "@symbiote-native/vue": "3.0.3"
135
+ "@symbiote-native/angular": "3.2.0",
136
+ "@symbiote-native/engine": "1.5.0",
137
+ "@symbiote-native/svelte": "3.1.0",
138
+ "@symbiote-native/solid": "3.1.0",
139
+ "@symbiote-native/react": "3.2.0",
140
+ "@symbiote-native/test-utils": "0.4.6",
141
+ "@symbiote-native/vue": "3.2.0"
142
142
  },
143
143
  "scripts": {
144
144
  "typecheck": "tsc --build",
package/src/core/index.ts CHANGED
@@ -7,6 +7,7 @@ export {
7
7
  dismissBrowser,
8
8
  openAuthSessionAsync,
9
9
  dismissAuthSession,
10
+ maybeCompleteAuthSession,
10
11
  } from './web-browser';
11
12
  export { WebBrowserResultType, WebBrowserPresentationStyle } from './types';
12
13
  export type {
@@ -14,6 +15,8 @@ export type {
14
15
  IRedirectEvent,
15
16
  IServiceActionResult,
16
17
  IWebBrowserAuthSessionResult,
18
+ IWebBrowserCompleteAuthSessionOptions,
19
+ IWebBrowserCompleteAuthSessionResult,
17
20
  IWebBrowserCoolDownResult,
18
21
  IWebBrowserCustomTabsResults,
19
22
  IWebBrowserDismissResult,
@@ -1,6 +1,8 @@
1
1
  import { requireNativeModule } from 'expo-modules-core';
2
2
  import type {
3
3
  IProcessedOpenOptions,
4
+ IWebBrowserCompleteAuthSessionOptions,
5
+ IWebBrowserCompleteAuthSessionResult,
4
6
  IWebBrowserAuthSessionResult,
5
7
  IWebBrowserCoolDownResult,
6
8
  IWebBrowserCustomTabsResults,
@@ -39,6 +41,10 @@ export type INativeWebBrowserModule = {
39
41
  browserPackage?: string,
40
42
  ): Promise<IWebBrowserMayInitWithUrlResult>;
41
43
  getCustomTabsSupportingBrowsersAsync?(): Promise<IWebBrowserCustomTabsResults>;
44
+ // Web only upstream, neither native platform registers it
45
+ maybeCompleteAuthSession?(
46
+ options: IWebBrowserCompleteAuthSessionOptions,
47
+ ): IWebBrowserCompleteAuthSessionResult;
42
48
  };
43
49
 
44
50
  export const expoWebBrowser = requireNativeModule<INativeWebBrowserModule>(
package/src/core/types.ts CHANGED
@@ -202,6 +202,16 @@ export type IServiceActionResult = {
202
202
  servicePackage?: string;
203
203
  };
204
204
 
205
+ export type IWebBrowserCompleteAuthSessionOptions = {
206
+ /** Close the window without checking the redirect against the cached redirect URL */
207
+ skipRedirectCheck?: boolean;
208
+ };
209
+
210
+ export type IWebBrowserCompleteAuthSessionResult = {
211
+ type: 'success' | 'failed';
212
+ message: string;
213
+ };
214
+
205
215
  export type IWebBrowserAuthSessionResult =
206
216
  IWebBrowserRedirectResult | IWebBrowserResult;
207
217
  export type IWebBrowserMayInitWithUrlResult = IServiceActionResult;
@@ -1,8 +1,5 @@
1
- // Hand-ported from .vendors/expo/packages/expo-web-browser/src/WebBrowser.ts (sdk-57). Two
2
- // deliberate departures from upstream, both because SymbioteNative has no web target:
3
- // `maybeCompleteAuthSession` is not ported (it exists only to close a `window.open` popup; on a
4
- // native platform it can do nothing but return `{ type: 'failed' }`), and the web-only open
5
- // options are gone from IWebBrowserOpenOptions.
1
+ // Hand-ported from .vendors/expo/packages/expo-web-browser/src/WebBrowser.ts (sdk-57)
2
+ // The web-only open options are gone from IWebBrowserOpenOptions, SymbioteNative has no web target
6
3
  import { Platform, UnavailabilityError } from 'expo-modules-core';
7
4
  import type { AppStateStatus, EmitterSubscription } from 'react-native';
8
5
  import { AppState, Linking, processColor } from 'react-native';
@@ -14,6 +11,8 @@ import {
14
11
  type IProcessedOpenOptions,
15
12
  type IRedirectEvent,
16
13
  type IWebBrowserAuthSessionResult,
14
+ type IWebBrowserCompleteAuthSessionOptions,
15
+ type IWebBrowserCompleteAuthSessionResult,
17
16
  type IWebBrowserCoolDownResult,
18
17
  type IWebBrowserCustomTabsResults,
19
18
  type IWebBrowserDismissResult,
@@ -209,6 +208,17 @@ export function dismissAuthSession(): void {
209
208
  void expoWebBrowser.dismissBrowser();
210
209
  }
211
210
 
211
+ // Native has no popup to close, so it reports `failed` and shared code can call it at module scope
212
+ /** @platform web */
213
+ export function maybeCompleteAuthSession(
214
+ options: IWebBrowserCompleteAuthSessionOptions = {},
215
+ ): IWebBrowserCompleteAuthSessionResult {
216
+ if (expoWebBrowser.maybeCompleteAuthSession) {
217
+ return expoWebBrowser.maybeCompleteAuthSession(options);
218
+ }
219
+ return { type: 'failed', message: 'Not supported on this platform' };
220
+ }
221
+
212
222
  function processOptions(
213
223
  options: IAuthSessionOpenOptions,
214
224
  ): IProcessedOpenOptions {