@blinkdotnew/sdk 0.19.5 → 0.19.6

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.mts CHANGED
@@ -1054,37 +1054,18 @@ declare class BlinkAuth {
1054
1054
  signInWithEmail(email: string, password: string): Promise<BlinkUser>;
1055
1055
  /**
1056
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
- * ```
1067
1057
  */
1068
1058
  signInWithGoogle(options?: AuthOptions): Promise<BlinkUser>;
1069
1059
  /**
1070
1060
  * Sign in with GitHub (headless mode)
1071
- *
1072
- * **Universal OAuth** - Works on both Web and React Native!
1073
- * See signInWithGoogle() for setup instructions.
1074
1061
  */
1075
1062
  signInWithGitHub(options?: AuthOptions): Promise<BlinkUser>;
1076
1063
  /**
1077
1064
  * Sign in with Apple (headless mode)
1078
- *
1079
- * **Universal OAuth** - Works on both Web and React Native!
1080
- * See signInWithGoogle() for setup instructions.
1081
1065
  */
1082
1066
  signInWithApple(options?: AuthOptions): Promise<BlinkUser>;
1083
1067
  /**
1084
1068
  * Sign in with Microsoft (headless mode)
1085
- *
1086
- * **Universal OAuth** - Works on both Web and React Native!
1087
- * See signInWithGoogle() for setup instructions.
1088
1069
  */
1089
1070
  signInWithMicrosoft(options?: AuthOptions): Promise<BlinkUser>;
1090
1071
  /**
@@ -1170,36 +1151,56 @@ declare class BlinkAuth {
1170
1151
  authenticate: () => Promise<BlinkUser>;
1171
1152
  }>;
1172
1153
  /**
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
1154
+ * Sign in with Google using expo-web-browser (React Native convenience)
1155
+ */
1156
+ signInWithGoogleMobile(options?: Omit<AuthOptions, 'redirectUrl'>): Promise<{
1157
+ authUrl: string;
1158
+ authenticate: () => Promise<BlinkUser>;
1159
+ }>;
1160
+ /**
1161
+ * Sign in with GitHub using expo-web-browser (React Native convenience)
1176
1162
  */
1177
- private signInWithProviderUniversal;
1163
+ signInWithGitHubMobile(options?: Omit<AuthOptions, 'redirectUrl'>): Promise<{
1164
+ authUrl: string;
1165
+ authenticate: () => Promise<BlinkUser>;
1166
+ }>;
1167
+ /**
1168
+ * Sign in with Apple using expo-web-browser (React Native convenience)
1169
+ */
1170
+ signInWithAppleMobile(options?: Omit<AuthOptions, 'redirectUrl'>): Promise<{
1171
+ authUrl: string;
1172
+ authenticate: () => Promise<BlinkUser>;
1173
+ }>;
1174
+ /**
1175
+ * React Native OAuth flow using expo-web-browser (internal)
1176
+ * Automatically handles opening browser and extracting tokens from redirect
1177
+ */
1178
+ private signInWithProviderReactNative;
1178
1179
  /**
1179
1180
  * Generic provider sign-in method (headless mode)
1180
1181
  *
1181
- * **Universal OAuth** - Works seamlessly on both Web and React Native!
1182
+ * Supports both web (popup) and React Native (deep link) OAuth flows.
1182
1183
  *
1183
- * When `webBrowser` is configured in the client, this method automatically
1184
- * uses the session-based OAuth flow that works on ALL platforms.
1184
+ * **React Native Setup:**
1185
+ * 1. Configure deep linking in your app (app.json):
1186
+ * ```json
1187
+ * { "expo": { "scheme": "com.yourapp" } }
1188
+ * ```
1185
1189
  *
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
+ * 2. Add redirect URL in Blink Dashboard:
1191
+ * `com.yourapp://**`
1190
1192
  *
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
- * })
1193
+ * 3. Handle deep link callbacks:
1194
+ * ```typescript
1195
+ * import * as Linking from 'expo-linking'
1199
1196
  *
1200
- * // Now this works on ALL platforms - no platform checks needed!
1201
- * const user = await blink.auth.signInWithGoogle()
1202
- * ```
1197
+ * Linking.addEventListener('url', async ({ url }) => {
1198
+ * const { queryParams } = Linking.parse(url)
1199
+ * if (queryParams.access_token) {
1200
+ * await blink.auth.setSession(queryParams)
1201
+ * }
1202
+ * })
1203
+ * ```
1203
1204
  *
1204
1205
  * @param provider - OAuth provider (google, github, apple, etc.)
1205
1206
  * @param options - Optional redirect URL and metadata
package/dist/index.d.ts CHANGED
@@ -1054,37 +1054,18 @@ declare class BlinkAuth {
1054
1054
  signInWithEmail(email: string, password: string): Promise<BlinkUser>;
1055
1055
  /**
1056
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
- * ```
1067
1057
  */
1068
1058
  signInWithGoogle(options?: AuthOptions): Promise<BlinkUser>;
1069
1059
  /**
1070
1060
  * Sign in with GitHub (headless mode)
1071
- *
1072
- * **Universal OAuth** - Works on both Web and React Native!
1073
- * See signInWithGoogle() for setup instructions.
1074
1061
  */
1075
1062
  signInWithGitHub(options?: AuthOptions): Promise<BlinkUser>;
1076
1063
  /**
1077
1064
  * Sign in with Apple (headless mode)
1078
- *
1079
- * **Universal OAuth** - Works on both Web and React Native!
1080
- * See signInWithGoogle() for setup instructions.
1081
1065
  */
1082
1066
  signInWithApple(options?: AuthOptions): Promise<BlinkUser>;
1083
1067
  /**
1084
1068
  * Sign in with Microsoft (headless mode)
1085
- *
1086
- * **Universal OAuth** - Works on both Web and React Native!
1087
- * See signInWithGoogle() for setup instructions.
1088
1069
  */
1089
1070
  signInWithMicrosoft(options?: AuthOptions): Promise<BlinkUser>;
1090
1071
  /**
@@ -1170,36 +1151,56 @@ declare class BlinkAuth {
1170
1151
  authenticate: () => Promise<BlinkUser>;
1171
1152
  }>;
1172
1153
  /**
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
1154
+ * Sign in with Google using expo-web-browser (React Native convenience)
1155
+ */
1156
+ signInWithGoogleMobile(options?: Omit<AuthOptions, 'redirectUrl'>): Promise<{
1157
+ authUrl: string;
1158
+ authenticate: () => Promise<BlinkUser>;
1159
+ }>;
1160
+ /**
1161
+ * Sign in with GitHub using expo-web-browser (React Native convenience)
1176
1162
  */
1177
- private signInWithProviderUniversal;
1163
+ signInWithGitHubMobile(options?: Omit<AuthOptions, 'redirectUrl'>): Promise<{
1164
+ authUrl: string;
1165
+ authenticate: () => Promise<BlinkUser>;
1166
+ }>;
1167
+ /**
1168
+ * Sign in with Apple using expo-web-browser (React Native convenience)
1169
+ */
1170
+ signInWithAppleMobile(options?: Omit<AuthOptions, 'redirectUrl'>): Promise<{
1171
+ authUrl: string;
1172
+ authenticate: () => Promise<BlinkUser>;
1173
+ }>;
1174
+ /**
1175
+ * React Native OAuth flow using expo-web-browser (internal)
1176
+ * Automatically handles opening browser and extracting tokens from redirect
1177
+ */
1178
+ private signInWithProviderReactNative;
1178
1179
  /**
1179
1180
  * Generic provider sign-in method (headless mode)
1180
1181
  *
1181
- * **Universal OAuth** - Works seamlessly on both Web and React Native!
1182
+ * Supports both web (popup) and React Native (deep link) OAuth flows.
1182
1183
  *
1183
- * When `webBrowser` is configured in the client, this method automatically
1184
- * uses the session-based OAuth flow that works on ALL platforms.
1184
+ * **React Native Setup:**
1185
+ * 1. Configure deep linking in your app (app.json):
1186
+ * ```json
1187
+ * { "expo": { "scheme": "com.yourapp" } }
1188
+ * ```
1185
1189
  *
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
+ * 2. Add redirect URL in Blink Dashboard:
1191
+ * `com.yourapp://**`
1190
1192
  *
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
- * })
1193
+ * 3. Handle deep link callbacks:
1194
+ * ```typescript
1195
+ * import * as Linking from 'expo-linking'
1199
1196
  *
1200
- * // Now this works on ALL platforms - no platform checks needed!
1201
- * const user = await blink.auth.signInWithGoogle()
1202
- * ```
1197
+ * Linking.addEventListener('url', async ({ url }) => {
1198
+ * const { queryParams } = Linking.parse(url)
1199
+ * if (queryParams.access_token) {
1200
+ * await blink.auth.setSession(queryParams)
1201
+ * }
1202
+ * })
1203
+ * ```
1203
1204
  *
1204
1205
  * @param provider - OAuth provider (google, github, apple, etc.)
1205
1206
  * @param options - Optional redirect URL and metadata
package/dist/index.js CHANGED
@@ -1177,7 +1177,7 @@ var BlinkAuth = class {
1177
1177
  this.authConfig = {
1178
1178
  mode: "managed",
1179
1179
  // Default mode
1180
- authUrl: "http://localhost:3000",
1180
+ authUrl: "https://blink.new",
1181
1181
  coreUrl: "https://core.blink.new",
1182
1182
  detectSessionInUrl: true,
1183
1183
  // Default to true for web compatibility
@@ -1238,7 +1238,10 @@ var BlinkAuth = class {
1238
1238
  setupParentWindowListener() {
1239
1239
  if (!isWeb || !this.isIframe || !hasWindow()) return;
1240
1240
  window.addEventListener("message", (event) => {
1241
- if (event.origin !== "https://blink.new" && event.origin !== "http://localhost:3000" && event.origin !== "http://localhost:3001") {
1241
+ const origin = event.origin;
1242
+ const isTrustedOrigin = origin === "https://blink.new" || origin === "http://localhost:3000" || origin === "http://localhost:3001" || origin.endsWith(".sites.blink.new") || // Trust all preview URLs
1243
+ origin.endsWith(".preview-blink.com");
1244
+ if (!isTrustedOrigin) {
1242
1245
  return;
1243
1246
  }
1244
1247
  if (event.data?.type === "BLINK_AUTH_TOKENS") {
@@ -1614,16 +1617,6 @@ var BlinkAuth = class {
1614
1617
  }
1615
1618
  /**
1616
1619
  * Sign in with Google (headless mode)
1617
- *
1618
- * **Universal OAuth** - Works on both Web and React Native!
1619
- *
1620
- * On React Native, requires `webBrowser` to be configured in client:
1621
- * ```typescript
1622
- * const blink = createClient({
1623
- * auth: { mode: 'headless', webBrowser: WebBrowser }
1624
- * })
1625
- * await blink.auth.signInWithGoogle() // Works on both platforms!
1626
- * ```
1627
1620
  */
1628
1621
  async signInWithGoogle(options) {
1629
1622
  if (this.authConfig.mode !== "headless") {
@@ -1633,9 +1626,6 @@ var BlinkAuth = class {
1633
1626
  }
1634
1627
  /**
1635
1628
  * Sign in with GitHub (headless mode)
1636
- *
1637
- * **Universal OAuth** - Works on both Web and React Native!
1638
- * See signInWithGoogle() for setup instructions.
1639
1629
  */
1640
1630
  async signInWithGitHub(options) {
1641
1631
  if (this.authConfig.mode !== "headless") {
@@ -1645,9 +1635,6 @@ var BlinkAuth = class {
1645
1635
  }
1646
1636
  /**
1647
1637
  * Sign in with Apple (headless mode)
1648
- *
1649
- * **Universal OAuth** - Works on both Web and React Native!
1650
- * See signInWithGoogle() for setup instructions.
1651
1638
  */
1652
1639
  async signInWithApple(options) {
1653
1640
  if (this.authConfig.mode !== "headless") {
@@ -1657,9 +1644,6 @@ var BlinkAuth = class {
1657
1644
  }
1658
1645
  /**
1659
1646
  * Sign in with Microsoft (headless mode)
1660
- *
1661
- * **Universal OAuth** - Works on both Web and React Native!
1662
- * See signInWithGoogle() for setup instructions.
1663
1647
  */
1664
1648
  async signInWithMicrosoft(options) {
1665
1649
  if (this.authConfig.mode !== "headless") {
@@ -1821,65 +1805,58 @@ var BlinkAuth = class {
1821
1805
  };
1822
1806
  }
1823
1807
  /**
1824
- * Universal OAuth flow using session-based authentication (internal)
1825
- * Works on ALL platforms: Web, iOS, Android
1826
- * Uses expo-web-browser to open auth URL and polls for completion
1808
+ * Sign in with Google using expo-web-browser (React Native convenience)
1827
1809
  */
1828
- async signInWithProviderUniversal(provider, options) {
1829
- const webBrowser = this.authConfig.webBrowser;
1830
- if (!webBrowser) {
1831
- throw new BlinkAuthError(
1832
- "NETWORK_ERROR" /* NETWORK_ERROR */,
1833
- "webBrowser module is required for universal OAuth flow"
1834
- );
1835
- }
1836
- const { sessionId, authUrl } = await this.initiateMobileOAuth(provider, options);
1837
- console.log("\u{1F510} Opening OAuth browser for", provider);
1838
- const result = await webBrowser.openAuthSessionAsync(authUrl);
1839
- console.log("\u{1F510} Browser closed with result:", result.type);
1840
- try {
1841
- const user = await this.pollMobileOAuthSession(sessionId, {
1842
- maxAttempts: 60,
1843
- // 30 seconds (500ms intervals)
1844
- intervalMs: 500
1845
- });
1846
- console.log("\u2705 OAuth completed successfully");
1847
- return user;
1848
- } catch (pollError) {
1849
- if (result.type === "cancel" || result.type === "dismiss") {
1850
- throw new BlinkAuthError(
1851
- "POPUP_CANCELED" /* POPUP_CANCELED */,
1852
- "Authentication was canceled"
1853
- );
1854
- }
1855
- throw pollError;
1856
- }
1810
+ async signInWithGoogleMobile(options) {
1811
+ return this.signInWithProviderMobile("google", options);
1812
+ }
1813
+ /**
1814
+ * Sign in with GitHub using expo-web-browser (React Native convenience)
1815
+ */
1816
+ async signInWithGitHubMobile(options) {
1817
+ return this.signInWithProviderMobile("github", options);
1818
+ }
1819
+ /**
1820
+ * Sign in with Apple using expo-web-browser (React Native convenience)
1821
+ */
1822
+ async signInWithAppleMobile(options) {
1823
+ return this.signInWithProviderMobile("apple", options);
1824
+ }
1825
+ /**
1826
+ * React Native OAuth flow using expo-web-browser (internal)
1827
+ * Automatically handles opening browser and extracting tokens from redirect
1828
+ */
1829
+ async signInWithProviderReactNative(provider, options) {
1830
+ throw new BlinkAuthError(
1831
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1832
+ 'React Native OAuth detected!\n\nPlease use the mobile-specific methods:\n\nimport * as WebBrowser from "expo-web-browser";\n\nconst { authUrl, authenticate } = await blink.auth.signInWithGoogleMobile();\nawait WebBrowser.openAuthSessionAsync(authUrl);\nconst user = await authenticate();\n\nOr update your useAuth hook to handle this automatically.'
1833
+ );
1857
1834
  }
1858
1835
  /**
1859
1836
  * Generic provider sign-in method (headless mode)
1860
1837
  *
1861
- * **Universal OAuth** - Works seamlessly on both Web and React Native!
1838
+ * Supports both web (popup) and React Native (deep link) OAuth flows.
1862
1839
  *
1863
- * When `webBrowser` is configured in the client, this method automatically
1864
- * uses the session-based OAuth flow that works on ALL platforms.
1840
+ * **React Native Setup:**
1841
+ * 1. Configure deep linking in your app (app.json):
1842
+ * ```json
1843
+ * { "expo": { "scheme": "com.yourapp" } }
1844
+ * ```
1865
1845
  *
1866
- * **Universal Setup (configure once, works everywhere):**
1867
- * ```typescript
1868
- * import * as WebBrowser from 'expo-web-browser'
1869
- * import AsyncStorage from '@react-native-async-storage/async-storage'
1846
+ * 2. Add redirect URL in Blink Dashboard:
1847
+ * `com.yourapp://**`
1870
1848
  *
1871
- * const blink = createClient({
1872
- * projectId: 'your-project',
1873
- * auth: {
1874
- * mode: 'headless',
1875
- * webBrowser: WebBrowser // Pass the module here
1876
- * },
1877
- * storage: new AsyncStorageAdapter(AsyncStorage)
1878
- * })
1879
- *
1880
- * // Now this works on ALL platforms - no platform checks needed!
1881
- * const user = await blink.auth.signInWithGoogle()
1882
- * ```
1849
+ * 3. Handle deep link callbacks:
1850
+ * ```typescript
1851
+ * import * as Linking from 'expo-linking'
1852
+ *
1853
+ * Linking.addEventListener('url', async ({ url }) => {
1854
+ * const { queryParams } = Linking.parse(url)
1855
+ * if (queryParams.access_token) {
1856
+ * await blink.auth.setSession(queryParams)
1857
+ * }
1858
+ * })
1859
+ * ```
1883
1860
  *
1884
1861
  * @param provider - OAuth provider (google, github, apple, etc.)
1885
1862
  * @param options - Optional redirect URL and metadata
@@ -1889,18 +1866,12 @@ var BlinkAuth = class {
1889
1866
  if (this.authConfig.mode !== "headless") {
1890
1867
  throw new BlinkAuthError("INVALID_CREDENTIALS" /* INVALID_CREDENTIALS */, "signInWithProvider is only available in headless mode");
1891
1868
  }
1892
- if (this.authConfig.webBrowser) {
1893
- return this.signInWithProviderUniversal(provider, options);
1894
- }
1895
- if (isReactNative2()) {
1896
- throw new BlinkAuthError(
1897
- "NETWORK_ERROR" /* NETWORK_ERROR */,
1898
- 'React Native OAuth requires webBrowser in config!\n\nimport * as WebBrowser from "expo-web-browser";\n\nconst blink = createClient({\n projectId: "your-project",\n auth: {\n mode: "headless",\n webBrowser: WebBrowser\n }\n})\n\nawait blink.auth.signInWithGoogle() // Works on all platforms!'
1899
- );
1900
- }
1901
1869
  if (!hasWindow()) {
1902
1870
  throw new BlinkAuthError("NETWORK_ERROR" /* NETWORK_ERROR */, "signInWithProvider requires a browser environment");
1903
1871
  }
1872
+ if (isReactNative2()) {
1873
+ return this.signInWithProviderReactNative(provider, options);
1874
+ }
1904
1875
  return new Promise((resolve, reject) => {
1905
1876
  const state = this.generateState();
1906
1877
  try {
@@ -1935,6 +1906,7 @@ var BlinkAuth = class {
1935
1906
  } catch {
1936
1907
  }
1937
1908
  if (event.origin === "http://localhost:3000" || event.origin === "http://localhost:3001") allowed = true;
1909
+ if (event.origin.endsWith(".sites.blink.new") || event.origin.endsWith(".preview-blink.com")) allowed = true;
1938
1910
  if (!allowed) return;
1939
1911
  if (event.data?.type === "BLINK_AUTH_TOKENS") {
1940
1912
  const { access_token, refresh_token, token_type, expires_in, refresh_expires_in, projectId, state: returnedState } = event.data;
package/dist/index.mjs CHANGED
@@ -1175,7 +1175,7 @@ var BlinkAuth = class {
1175
1175
  this.authConfig = {
1176
1176
  mode: "managed",
1177
1177
  // Default mode
1178
- authUrl: "http://localhost:3000",
1178
+ authUrl: "https://blink.new",
1179
1179
  coreUrl: "https://core.blink.new",
1180
1180
  detectSessionInUrl: true,
1181
1181
  // Default to true for web compatibility
@@ -1236,7 +1236,10 @@ var BlinkAuth = class {
1236
1236
  setupParentWindowListener() {
1237
1237
  if (!isWeb || !this.isIframe || !hasWindow()) return;
1238
1238
  window.addEventListener("message", (event) => {
1239
- if (event.origin !== "https://blink.new" && event.origin !== "http://localhost:3000" && event.origin !== "http://localhost:3001") {
1239
+ const origin = event.origin;
1240
+ const isTrustedOrigin = origin === "https://blink.new" || origin === "http://localhost:3000" || origin === "http://localhost:3001" || origin.endsWith(".sites.blink.new") || // Trust all preview URLs
1241
+ origin.endsWith(".preview-blink.com");
1242
+ if (!isTrustedOrigin) {
1240
1243
  return;
1241
1244
  }
1242
1245
  if (event.data?.type === "BLINK_AUTH_TOKENS") {
@@ -1612,16 +1615,6 @@ var BlinkAuth = class {
1612
1615
  }
1613
1616
  /**
1614
1617
  * Sign in with Google (headless mode)
1615
- *
1616
- * **Universal OAuth** - Works on both Web and React Native!
1617
- *
1618
- * On React Native, requires `webBrowser` to be configured in client:
1619
- * ```typescript
1620
- * const blink = createClient({
1621
- * auth: { mode: 'headless', webBrowser: WebBrowser }
1622
- * })
1623
- * await blink.auth.signInWithGoogle() // Works on both platforms!
1624
- * ```
1625
1618
  */
1626
1619
  async signInWithGoogle(options) {
1627
1620
  if (this.authConfig.mode !== "headless") {
@@ -1631,9 +1624,6 @@ var BlinkAuth = class {
1631
1624
  }
1632
1625
  /**
1633
1626
  * Sign in with GitHub (headless mode)
1634
- *
1635
- * **Universal OAuth** - Works on both Web and React Native!
1636
- * See signInWithGoogle() for setup instructions.
1637
1627
  */
1638
1628
  async signInWithGitHub(options) {
1639
1629
  if (this.authConfig.mode !== "headless") {
@@ -1643,9 +1633,6 @@ var BlinkAuth = class {
1643
1633
  }
1644
1634
  /**
1645
1635
  * Sign in with Apple (headless mode)
1646
- *
1647
- * **Universal OAuth** - Works on both Web and React Native!
1648
- * See signInWithGoogle() for setup instructions.
1649
1636
  */
1650
1637
  async signInWithApple(options) {
1651
1638
  if (this.authConfig.mode !== "headless") {
@@ -1655,9 +1642,6 @@ var BlinkAuth = class {
1655
1642
  }
1656
1643
  /**
1657
1644
  * Sign in with Microsoft (headless mode)
1658
- *
1659
- * **Universal OAuth** - Works on both Web and React Native!
1660
- * See signInWithGoogle() for setup instructions.
1661
1645
  */
1662
1646
  async signInWithMicrosoft(options) {
1663
1647
  if (this.authConfig.mode !== "headless") {
@@ -1819,65 +1803,58 @@ var BlinkAuth = class {
1819
1803
  };
1820
1804
  }
1821
1805
  /**
1822
- * Universal OAuth flow using session-based authentication (internal)
1823
- * Works on ALL platforms: Web, iOS, Android
1824
- * Uses expo-web-browser to open auth URL and polls for completion
1806
+ * Sign in with Google using expo-web-browser (React Native convenience)
1825
1807
  */
1826
- async signInWithProviderUniversal(provider, options) {
1827
- const webBrowser = this.authConfig.webBrowser;
1828
- if (!webBrowser) {
1829
- throw new BlinkAuthError(
1830
- "NETWORK_ERROR" /* NETWORK_ERROR */,
1831
- "webBrowser module is required for universal OAuth flow"
1832
- );
1833
- }
1834
- const { sessionId, authUrl } = await this.initiateMobileOAuth(provider, options);
1835
- console.log("\u{1F510} Opening OAuth browser for", provider);
1836
- const result = await webBrowser.openAuthSessionAsync(authUrl);
1837
- console.log("\u{1F510} Browser closed with result:", result.type);
1838
- try {
1839
- const user = await this.pollMobileOAuthSession(sessionId, {
1840
- maxAttempts: 60,
1841
- // 30 seconds (500ms intervals)
1842
- intervalMs: 500
1843
- });
1844
- console.log("\u2705 OAuth completed successfully");
1845
- return user;
1846
- } catch (pollError) {
1847
- if (result.type === "cancel" || result.type === "dismiss") {
1848
- throw new BlinkAuthError(
1849
- "POPUP_CANCELED" /* POPUP_CANCELED */,
1850
- "Authentication was canceled"
1851
- );
1852
- }
1853
- throw pollError;
1854
- }
1808
+ async signInWithGoogleMobile(options) {
1809
+ return this.signInWithProviderMobile("google", options);
1810
+ }
1811
+ /**
1812
+ * Sign in with GitHub using expo-web-browser (React Native convenience)
1813
+ */
1814
+ async signInWithGitHubMobile(options) {
1815
+ return this.signInWithProviderMobile("github", options);
1816
+ }
1817
+ /**
1818
+ * Sign in with Apple using expo-web-browser (React Native convenience)
1819
+ */
1820
+ async signInWithAppleMobile(options) {
1821
+ return this.signInWithProviderMobile("apple", options);
1822
+ }
1823
+ /**
1824
+ * React Native OAuth flow using expo-web-browser (internal)
1825
+ * Automatically handles opening browser and extracting tokens from redirect
1826
+ */
1827
+ async signInWithProviderReactNative(provider, options) {
1828
+ throw new BlinkAuthError(
1829
+ "NETWORK_ERROR" /* NETWORK_ERROR */,
1830
+ 'React Native OAuth detected!\n\nPlease use the mobile-specific methods:\n\nimport * as WebBrowser from "expo-web-browser";\n\nconst { authUrl, authenticate } = await blink.auth.signInWithGoogleMobile();\nawait WebBrowser.openAuthSessionAsync(authUrl);\nconst user = await authenticate();\n\nOr update your useAuth hook to handle this automatically.'
1831
+ );
1855
1832
  }
1856
1833
  /**
1857
1834
  * Generic provider sign-in method (headless mode)
1858
1835
  *
1859
- * **Universal OAuth** - Works seamlessly on both Web and React Native!
1836
+ * Supports both web (popup) and React Native (deep link) OAuth flows.
1860
1837
  *
1861
- * When `webBrowser` is configured in the client, this method automatically
1862
- * uses the session-based OAuth flow that works on ALL platforms.
1838
+ * **React Native Setup:**
1839
+ * 1. Configure deep linking in your app (app.json):
1840
+ * ```json
1841
+ * { "expo": { "scheme": "com.yourapp" } }
1842
+ * ```
1863
1843
  *
1864
- * **Universal Setup (configure once, works everywhere):**
1865
- * ```typescript
1866
- * import * as WebBrowser from 'expo-web-browser'
1867
- * import AsyncStorage from '@react-native-async-storage/async-storage'
1844
+ * 2. Add redirect URL in Blink Dashboard:
1845
+ * `com.yourapp://**`
1868
1846
  *
1869
- * const blink = createClient({
1870
- * projectId: 'your-project',
1871
- * auth: {
1872
- * mode: 'headless',
1873
- * webBrowser: WebBrowser // Pass the module here
1874
- * },
1875
- * storage: new AsyncStorageAdapter(AsyncStorage)
1876
- * })
1877
- *
1878
- * // Now this works on ALL platforms - no platform checks needed!
1879
- * const user = await blink.auth.signInWithGoogle()
1880
- * ```
1847
+ * 3. Handle deep link callbacks:
1848
+ * ```typescript
1849
+ * import * as Linking from 'expo-linking'
1850
+ *
1851
+ * Linking.addEventListener('url', async ({ url }) => {
1852
+ * const { queryParams } = Linking.parse(url)
1853
+ * if (queryParams.access_token) {
1854
+ * await blink.auth.setSession(queryParams)
1855
+ * }
1856
+ * })
1857
+ * ```
1881
1858
  *
1882
1859
  * @param provider - OAuth provider (google, github, apple, etc.)
1883
1860
  * @param options - Optional redirect URL and metadata
@@ -1887,18 +1864,12 @@ var BlinkAuth = class {
1887
1864
  if (this.authConfig.mode !== "headless") {
1888
1865
  throw new BlinkAuthError("INVALID_CREDENTIALS" /* INVALID_CREDENTIALS */, "signInWithProvider is only available in headless mode");
1889
1866
  }
1890
- if (this.authConfig.webBrowser) {
1891
- return this.signInWithProviderUniversal(provider, options);
1892
- }
1893
- if (isReactNative2()) {
1894
- throw new BlinkAuthError(
1895
- "NETWORK_ERROR" /* NETWORK_ERROR */,
1896
- 'React Native OAuth requires webBrowser in config!\n\nimport * as WebBrowser from "expo-web-browser";\n\nconst blink = createClient({\n projectId: "your-project",\n auth: {\n mode: "headless",\n webBrowser: WebBrowser\n }\n})\n\nawait blink.auth.signInWithGoogle() // Works on all platforms!'
1897
- );
1898
- }
1899
1867
  if (!hasWindow()) {
1900
1868
  throw new BlinkAuthError("NETWORK_ERROR" /* NETWORK_ERROR */, "signInWithProvider requires a browser environment");
1901
1869
  }
1870
+ if (isReactNative2()) {
1871
+ return this.signInWithProviderReactNative(provider, options);
1872
+ }
1902
1873
  return new Promise((resolve, reject) => {
1903
1874
  const state = this.generateState();
1904
1875
  try {
@@ -1933,6 +1904,7 @@ var BlinkAuth = class {
1933
1904
  } catch {
1934
1905
  }
1935
1906
  if (event.origin === "http://localhost:3000" || event.origin === "http://localhost:3001") allowed = true;
1907
+ if (event.origin.endsWith(".sites.blink.new") || event.origin.endsWith(".preview-blink.com")) allowed = true;
1936
1908
  if (!allowed) return;
1937
1909
  if (event.data?.type === "BLINK_AUTH_TOKENS") {
1938
1910
  const { access_token, refresh_token, token_type, expires_in, refresh_expires_in, projectId, state: returnedState } = event.data;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blinkdotnew/sdk",
3
- "version": "0.19.5",
3
+ "version": "0.19.6",
4
4
  "description": "Blink TypeScript SDK for client-side applications - Zero-boilerplate CRUD + auth + AI + analytics + notifications for modern SaaS/AI apps",
5
5
  "keywords": [
6
6
  "blink",