@blinkdotnew/sdk 0.19.4 → 0.19.5

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/dist/index.d.ts CHANGED
@@ -82,6 +82,49 @@ interface BlinkClientConfig {
82
82
  }
83
83
  interface BlinkAuthConfig {
84
84
  mode?: 'managed' | 'headless';
85
+ /**
86
+ * Automatically detect and extract auth tokens from URL parameters
87
+ *
88
+ * - Web: Set to `true` (default) to handle OAuth redirects
89
+ * - React Native: Set to `false` to use deep links instead
90
+ *
91
+ * @default true
92
+ *
93
+ * @example
94
+ * // React Native - disable URL detection, use deep links
95
+ * {
96
+ * auth: {
97
+ * detectSessionInUrl: false,
98
+ * storage: AsyncStorageAdapter(AsyncStorage)
99
+ * }
100
+ * }
101
+ */
102
+ detectSessionInUrl?: boolean;
103
+ /**
104
+ * WebBrowser module for React Native OAuth (expo-web-browser)
105
+ *
106
+ * When provided, `signInWithGoogle()` and other OAuth methods will
107
+ * automatically use the mobile session-based flow on React Native,
108
+ * so you don't need platform-specific code.
109
+ *
110
+ * @example
111
+ * // React Native setup (configure once)
112
+ * import * as WebBrowser from 'expo-web-browser'
113
+ * import AsyncStorage from '@react-native-async-storage/async-storage'
114
+ *
115
+ * const blink = createClient({
116
+ * projectId: 'your-project',
117
+ * auth: {
118
+ * mode: 'headless',
119
+ * webBrowser: WebBrowser // Pass the module here
120
+ * },
121
+ * storage: new AsyncStorageAdapter(AsyncStorage)
122
+ * })
123
+ *
124
+ * // Now this works on both web and mobile!
125
+ * const user = await blink.auth.signInWithGoogle()
126
+ */
127
+ webBrowser?: WebBrowserModule;
85
128
  email?: {
86
129
  requireVerification?: boolean;
87
130
  allowSignUp?: boolean;
@@ -118,11 +161,7 @@ type AuthProvider = 'email' | 'google' | 'github' | 'apple' | 'microsoft' | 'twi
118
161
  interface AuthOptions {
119
162
  redirectUrl?: string;
120
163
  metadata?: Record<string, any>;
121
- /**
122
- * Force redirect flow instead of popup (useful for Safari or when popups are blocked)
123
- * When true, always uses redirect flow regardless of browser detection
124
- */
125
- forceRedirect?: boolean;
164
+ useMobileSession?: boolean;
126
165
  }
127
166
  interface SignUpData {
128
167
  email: string;
@@ -136,6 +175,22 @@ interface SignUpData {
136
175
  interface MagicLinkOptions {
137
176
  redirectUrl?: string;
138
177
  }
178
+ /**
179
+ * WebBrowser interface for React Native OAuth
180
+ * Compatible with expo-web-browser module
181
+ *
182
+ * Simply pass the expo-web-browser module directly:
183
+ * ```typescript
184
+ * import * as WebBrowser from 'expo-web-browser'
185
+ * const blink = createClient({ auth: { webBrowser: WebBrowser } })
186
+ * ```
187
+ */
188
+ interface WebBrowserModule {
189
+ openAuthSessionAsync(url: string, redirectUrl?: string, options?: unknown): Promise<{
190
+ type: string;
191
+ url?: string;
192
+ }>;
193
+ }
139
194
  interface BlinkUser {
140
195
  id: string;
141
196
  email: string;
@@ -999,28 +1054,156 @@ declare class BlinkAuth {
999
1054
  signInWithEmail(email: string, password: string): Promise<BlinkUser>;
1000
1055
  /**
1001
1056
  * Sign in with Google (headless mode)
1057
+ *
1058
+ * **Universal OAuth** - Works on both Web and React Native!
1059
+ *
1060
+ * On React Native, requires `webBrowser` to be configured in client:
1061
+ * ```typescript
1062
+ * const blink = createClient({
1063
+ * auth: { mode: 'headless', webBrowser: WebBrowser }
1064
+ * })
1065
+ * await blink.auth.signInWithGoogle() // Works on both platforms!
1066
+ * ```
1002
1067
  */
1003
1068
  signInWithGoogle(options?: AuthOptions): Promise<BlinkUser>;
1004
1069
  /**
1005
1070
  * Sign in with GitHub (headless mode)
1071
+ *
1072
+ * **Universal OAuth** - Works on both Web and React Native!
1073
+ * See signInWithGoogle() for setup instructions.
1006
1074
  */
1007
1075
  signInWithGitHub(options?: AuthOptions): Promise<BlinkUser>;
1008
1076
  /**
1009
1077
  * Sign in with Apple (headless mode)
1078
+ *
1079
+ * **Universal OAuth** - Works on both Web and React Native!
1080
+ * See signInWithGoogle() for setup instructions.
1010
1081
  */
1011
1082
  signInWithApple(options?: AuthOptions): Promise<BlinkUser>;
1012
1083
  /**
1013
1084
  * Sign in with Microsoft (headless mode)
1085
+ *
1086
+ * **Universal OAuth** - Works on both Web and React Native!
1087
+ * See signInWithGoogle() for setup instructions.
1014
1088
  */
1015
1089
  signInWithMicrosoft(options?: AuthOptions): Promise<BlinkUser>;
1016
1090
  /**
1017
- * Check if current browser is Safari (desktop, iPhone, iPad)
1018
- * Safari has strict popup blocking, so we must use redirect flow
1091
+ * Initiate OAuth for mobile without deep linking (expo-web-browser pattern)
1092
+ *
1093
+ * This method:
1094
+ * 1. Generates a unique session ID
1095
+ * 2. Returns OAuth URL with session parameter
1096
+ * 3. App opens URL in expo-web-browser
1097
+ * 4. App polls checkMobileOAuthSession() until complete
1098
+ *
1099
+ * @param provider - OAuth provider (google, github, apple, etc.)
1100
+ * @param options - Optional metadata
1101
+ * @returns Session ID and OAuth URL
1102
+ *
1103
+ * @example
1104
+ * // React Native with expo-web-browser
1105
+ * import * as WebBrowser from 'expo-web-browser';
1106
+ *
1107
+ * const { sessionId, authUrl } = await blink.auth.initiateMobileOAuth('google');
1108
+ *
1109
+ * // Open browser
1110
+ * await WebBrowser.openAuthSessionAsync(authUrl);
1111
+ *
1112
+ * // Poll for completion
1113
+ * const user = await blink.auth.pollMobileOAuthSession(sessionId);
1114
+ * console.log('Authenticated:', user.email);
1019
1115
  */
1020
- private isSafari;
1116
+ initiateMobileOAuth(provider: AuthProvider, options?: Omit<AuthOptions, 'redirectUrl'>): Promise<{
1117
+ sessionId: string;
1118
+ authUrl: string;
1119
+ }>;
1120
+ /**
1121
+ * Check mobile OAuth session status (single check)
1122
+ *
1123
+ * @param sessionId - Session ID from initiateMobileOAuth
1124
+ * @returns Tokens if session is complete, null if still pending
1125
+ */
1126
+ checkMobileOAuthSession(sessionId: string): Promise<AuthTokens | null>;
1127
+ /**
1128
+ * Poll mobile OAuth session until complete (convenience method)
1129
+ *
1130
+ * @param sessionId - Session ID from initiateMobileOAuth
1131
+ * @param options - Polling options
1132
+ * @returns Authenticated user
1133
+ *
1134
+ * @example
1135
+ * const { sessionId, authUrl } = await blink.auth.initiateMobileOAuth('google');
1136
+ * await WebBrowser.openAuthSessionAsync(authUrl);
1137
+ * const user = await blink.auth.pollMobileOAuthSession(sessionId, {
1138
+ * maxAttempts: 60,
1139
+ * intervalMs: 1000
1140
+ * });
1141
+ */
1142
+ pollMobileOAuthSession(sessionId: string, options?: {
1143
+ maxAttempts?: number;
1144
+ intervalMs?: number;
1145
+ }): Promise<BlinkUser>;
1146
+ /**
1147
+ * Sign in with OAuth provider using expo-web-browser (React Native)
1148
+ *
1149
+ * This is a convenience method that handles the entire flow:
1150
+ * 1. Initiates mobile OAuth session
1151
+ * 2. Returns auth URL to open in WebBrowser
1152
+ * 3. Provides polling function to call after browser opens
1153
+ *
1154
+ * @param provider - OAuth provider
1155
+ * @returns Object with authUrl and authenticate function
1156
+ *
1157
+ * @example
1158
+ * import * as WebBrowser from 'expo-web-browser';
1159
+ *
1160
+ * const { authUrl, authenticate } = await blink.auth.signInWithProviderMobile('google');
1161
+ *
1162
+ * // Open browser
1163
+ * await WebBrowser.openAuthSessionAsync(authUrl);
1164
+ *
1165
+ * // Wait for authentication
1166
+ * const user = await authenticate();
1167
+ */
1168
+ signInWithProviderMobile(provider: AuthProvider, options?: Omit<AuthOptions, 'redirectUrl'>): Promise<{
1169
+ authUrl: string;
1170
+ authenticate: () => Promise<BlinkUser>;
1171
+ }>;
1172
+ /**
1173
+ * Universal OAuth flow using session-based authentication (internal)
1174
+ * Works on ALL platforms: Web, iOS, Android
1175
+ * Uses expo-web-browser to open auth URL and polls for completion
1176
+ */
1177
+ private signInWithProviderUniversal;
1021
1178
  /**
1022
1179
  * Generic provider sign-in method (headless mode)
1023
- * Uses redirect flow for Safari, popup flow for other browsers
1180
+ *
1181
+ * **Universal OAuth** - Works seamlessly on both Web and React Native!
1182
+ *
1183
+ * When `webBrowser` is configured in the client, this method automatically
1184
+ * uses the session-based OAuth flow that works on ALL platforms.
1185
+ *
1186
+ * **Universal Setup (configure once, works everywhere):**
1187
+ * ```typescript
1188
+ * import * as WebBrowser from 'expo-web-browser'
1189
+ * import AsyncStorage from '@react-native-async-storage/async-storage'
1190
+ *
1191
+ * const blink = createClient({
1192
+ * projectId: 'your-project',
1193
+ * auth: {
1194
+ * mode: 'headless',
1195
+ * webBrowser: WebBrowser // Pass the module here
1196
+ * },
1197
+ * storage: new AsyncStorageAdapter(AsyncStorage)
1198
+ * })
1199
+ *
1200
+ * // Now this works on ALL platforms - no platform checks needed!
1201
+ * const user = await blink.auth.signInWithGoogle()
1202
+ * ```
1203
+ *
1204
+ * @param provider - OAuth provider (google, github, apple, etc.)
1205
+ * @param options - Optional redirect URL and metadata
1206
+ * @returns Promise that resolves with authenticated user
1024
1207
  */
1025
1208
  signInWithProvider(provider: AuthProvider, options?: AuthOptions): Promise<BlinkUser>;
1026
1209
  /**
@@ -1110,6 +1293,40 @@ declare class BlinkAuth {
1110
1293
  * Manually set tokens (for server-side usage)
1111
1294
  */
1112
1295
  setToken(jwt: string, persist?: boolean): Promise<void>;
1296
+ /**
1297
+ * Manually set auth session from tokens (React Native deep link OAuth)
1298
+ *
1299
+ * Use this method to set the user session after receiving tokens from a deep link callback.
1300
+ * This is the React Native equivalent of automatic URL token detection on web.
1301
+ *
1302
+ * @param tokens - Auth tokens received from deep link or OAuth callback
1303
+ * @param persist - Whether to persist tokens to storage (default: true)
1304
+ *
1305
+ * @example
1306
+ * // React Native: Handle deep link OAuth callback
1307
+ * import * as Linking from 'expo-linking'
1308
+ *
1309
+ * Linking.addEventListener('url', async ({ url }) => {
1310
+ * const { queryParams } = Linking.parse(url)
1311
+ *
1312
+ * if (queryParams.access_token) {
1313
+ * await blink.auth.setSession({
1314
+ * access_token: queryParams.access_token,
1315
+ * refresh_token: queryParams.refresh_token,
1316
+ * expires_in: parseInt(queryParams.expires_in) || 3600,
1317
+ * refresh_expires_in: parseInt(queryParams.refresh_expires_in)
1318
+ * })
1319
+ *
1320
+ * console.log('User authenticated:', blink.auth.currentUser())
1321
+ * }
1322
+ * })
1323
+ */
1324
+ setSession(tokens: {
1325
+ access_token: string;
1326
+ refresh_token?: string;
1327
+ expires_in?: number;
1328
+ refresh_expires_in?: number;
1329
+ }, persist?: boolean): Promise<BlinkUser>;
1113
1330
  /**
1114
1331
  * Refresh access token using refresh token
1115
1332
  */
@@ -1125,11 +1342,6 @@ declare class BlinkAuth {
1125
1342
  private setTokens;
1126
1343
  private clearTokens;
1127
1344
  private getStoredTokens;
1128
- /**
1129
- * Extract URL parameters from both search params and hash fragments
1130
- * Safari OAuth redirects often use hash fragments instead of query params
1131
- */
1132
- private extractUrlParams;
1133
1345
  private extractTokensFromUrl;
1134
1346
  private clearUrlTokens;
1135
1347
  private redirectToAuth;
@@ -1139,6 +1351,10 @@ declare class BlinkAuth {
1139
1351
  * Generate secure random state for OAuth flows
1140
1352
  */
1141
1353
  private generateState;
1354
+ /**
1355
+ * Generate unique session ID for mobile OAuth
1356
+ */
1357
+ private generateSessionId;
1142
1358
  /**
1143
1359
  * Extract magic link token from URL
1144
1360
  */
@@ -2080,4 +2296,4 @@ declare class BlinkRealtimeImpl implements BlinkRealtime {
2080
2296
  onPresence(channelName: string, callback: (users: PresenceUser[]) => void): () => void;
2081
2297
  }
2082
2298
 
2083
- export { type AnalyticsEvent, AsyncStorageAdapter, type AuthState, type AuthStateChangeCallback, type AuthTokens, type BlinkAI, BlinkAIImpl, type BlinkAnalytics, BlinkAnalyticsImpl, type BlinkClient, type BlinkClientConfig, type BlinkData, BlinkDataImpl, BlinkDatabase, type BlinkRealtime, BlinkRealtimeChannel, BlinkRealtimeError, BlinkRealtimeImpl, type BlinkStorage, BlinkStorageImpl, BlinkTable, type BlinkUser, type CreateOptions, type DataExtraction, type FileObject, type FilterCondition, type ImageGenerationRequest, type ImageGenerationResponse, type Message, NoOpStorageAdapter, type ObjectGenerationRequest, type ObjectGenerationResponse, type PresenceUser, type QueryOptions, type RealtimeChannel, type RealtimeGetMessagesOptions, type RealtimeMessage, type RealtimePublishOptions, type RealtimeSubscribeOptions, type SearchRequest, type SearchResponse, type SpeechGenerationRequest, type SpeechGenerationResponse, type StorageAdapter, type StorageUploadOptions, type StorageUploadResponse, type TableOperations, type TextGenerationRequest, type TextGenerationResponse, type TokenUsage, type TranscriptionRequest, type TranscriptionResponse, type UpdateOptions, type UpsertOptions, WebStorageAdapter, createClient, getDefaultStorageAdapter, isBrowser, isNode, isReactNative, isWeb, platform };
2299
+ export { type AnalyticsEvent, AsyncStorageAdapter, type AuthState, type AuthStateChangeCallback, type AuthTokens, type BlinkAI, BlinkAIImpl, type BlinkAnalytics, BlinkAnalyticsImpl, type BlinkClient, type BlinkClientConfig, type BlinkData, BlinkDataImpl, BlinkDatabase, type BlinkRealtime, BlinkRealtimeChannel, BlinkRealtimeError, BlinkRealtimeImpl, type BlinkStorage, BlinkStorageImpl, BlinkTable, type BlinkUser, type CreateOptions, type DataExtraction, type FileObject, type FilterCondition, type ImageGenerationRequest, type ImageGenerationResponse, type Message, NoOpStorageAdapter, type ObjectGenerationRequest, type ObjectGenerationResponse, type PresenceUser, type QueryOptions, type RealtimeChannel, type RealtimeGetMessagesOptions, type RealtimeMessage, type RealtimePublishOptions, type RealtimeSubscribeOptions, type SearchRequest, type SearchResponse, type SpeechGenerationRequest, type SpeechGenerationResponse, type StorageAdapter, type StorageUploadOptions, type StorageUploadResponse, type TableOperations, type TextGenerationRequest, type TextGenerationResponse, type TokenUsage, type TranscriptionRequest, type TranscriptionResponse, type UpdateOptions, type UpsertOptions, type WebBrowserModule, WebStorageAdapter, createClient, getDefaultStorageAdapter, isBrowser, isNode, isReactNative, isWeb, platform };