@depup/supabase__auth-js 2.103.0-depup.0 → 2.110.8-depup.0

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.
Files changed (106) hide show
  1. package/AGENTS.md +11 -0
  2. package/README.md +2 -2
  3. package/changes.json +1 -1
  4. package/dist/main/GoTrueAdminApi.d.ts +45 -8
  5. package/dist/main/GoTrueAdminApi.d.ts.map +1 -1
  6. package/dist/main/GoTrueAdminApi.js +67 -7
  7. package/dist/main/GoTrueAdminApi.js.map +1 -1
  8. package/dist/main/GoTrueClient.d.ts +239 -42
  9. package/dist/main/GoTrueClient.d.ts.map +1 -1
  10. package/dist/main/GoTrueClient.js +946 -164
  11. package/dist/main/GoTrueClient.js.map +1 -1
  12. package/dist/main/lib/constants.d.ts +8 -0
  13. package/dist/main/lib/constants.d.ts.map +1 -1
  14. package/dist/main/lib/constants.js +9 -1
  15. package/dist/main/lib/constants.js.map +1 -1
  16. package/dist/main/lib/errors.d.ts +42 -3
  17. package/dist/main/lib/errors.d.ts.map +1 -1
  18. package/dist/main/lib/errors.js +44 -13
  19. package/dist/main/lib/errors.js.map +1 -1
  20. package/dist/main/lib/fetch.d.ts +28 -8
  21. package/dist/main/lib/fetch.d.ts.map +1 -1
  22. package/dist/main/lib/fetch.js +28 -6
  23. package/dist/main/lib/fetch.js.map +1 -1
  24. package/dist/main/lib/helpers.d.ts +4 -1
  25. package/dist/main/lib/helpers.d.ts.map +1 -1
  26. package/dist/main/lib/helpers.js +15 -4
  27. package/dist/main/lib/helpers.js.map +1 -1
  28. package/dist/main/lib/locks.d.ts +29 -35
  29. package/dist/main/lib/locks.d.ts.map +1 -1
  30. package/dist/main/lib/locks.js +37 -38
  31. package/dist/main/lib/locks.js.map +1 -1
  32. package/dist/main/lib/types.d.ts +305 -64
  33. package/dist/main/lib/types.d.ts.map +1 -1
  34. package/dist/main/lib/types.js.map +1 -1
  35. package/dist/main/lib/version.d.ts +1 -1
  36. package/dist/main/lib/version.js +1 -1
  37. package/dist/main/lib/webauthn.d.ts +8 -0
  38. package/dist/main/lib/webauthn.d.ts.map +1 -1
  39. package/dist/main/lib/webauthn.dom.d.ts +3 -3
  40. package/dist/main/lib/webauthn.dom.d.ts.map +1 -1
  41. package/dist/main/lib/webauthn.errors.d.ts +5 -0
  42. package/dist/main/lib/webauthn.errors.d.ts.map +1 -1
  43. package/dist/main/lib/webauthn.errors.js +7 -0
  44. package/dist/main/lib/webauthn.errors.js.map +1 -1
  45. package/dist/main/lib/webauthn.js +1 -0
  46. package/dist/main/lib/webauthn.js.map +1 -1
  47. package/dist/module/GoTrueAdminApi.d.ts +45 -8
  48. package/dist/module/GoTrueAdminApi.d.ts.map +1 -1
  49. package/dist/module/GoTrueAdminApi.js +68 -8
  50. package/dist/module/GoTrueAdminApi.js.map +1 -1
  51. package/dist/module/GoTrueClient.d.ts +239 -42
  52. package/dist/module/GoTrueClient.d.ts.map +1 -1
  53. package/dist/module/GoTrueClient.js +951 -169
  54. package/dist/module/GoTrueClient.js.map +1 -1
  55. package/dist/module/lib/constants.d.ts +8 -0
  56. package/dist/module/lib/constants.d.ts.map +1 -1
  57. package/dist/module/lib/constants.js +8 -0
  58. package/dist/module/lib/constants.js.map +1 -1
  59. package/dist/module/lib/errors.d.ts +42 -3
  60. package/dist/module/lib/errors.d.ts.map +1 -1
  61. package/dist/module/lib/errors.js +41 -12
  62. package/dist/module/lib/errors.js.map +1 -1
  63. package/dist/module/lib/fetch.d.ts +28 -8
  64. package/dist/module/lib/fetch.d.ts.map +1 -1
  65. package/dist/module/lib/fetch.js +28 -6
  66. package/dist/module/lib/fetch.js.map +1 -1
  67. package/dist/module/lib/helpers.d.ts +4 -1
  68. package/dist/module/lib/helpers.d.ts.map +1 -1
  69. package/dist/module/lib/helpers.js +14 -4
  70. package/dist/module/lib/helpers.js.map +1 -1
  71. package/dist/module/lib/locks.d.ts +29 -35
  72. package/dist/module/lib/locks.d.ts.map +1 -1
  73. package/dist/module/lib/locks.js +37 -38
  74. package/dist/module/lib/locks.js.map +1 -1
  75. package/dist/module/lib/types.d.ts +305 -64
  76. package/dist/module/lib/types.d.ts.map +1 -1
  77. package/dist/module/lib/types.js.map +1 -1
  78. package/dist/module/lib/version.d.ts +1 -1
  79. package/dist/module/lib/version.js +1 -1
  80. package/dist/module/lib/webauthn.d.ts +8 -0
  81. package/dist/module/lib/webauthn.d.ts.map +1 -1
  82. package/dist/module/lib/webauthn.dom.d.ts +3 -3
  83. package/dist/module/lib/webauthn.dom.d.ts.map +1 -1
  84. package/dist/module/lib/webauthn.errors.d.ts +5 -0
  85. package/dist/module/lib/webauthn.errors.d.ts.map +1 -1
  86. package/dist/module/lib/webauthn.errors.js +7 -0
  87. package/dist/module/lib/webauthn.errors.js.map +1 -1
  88. package/dist/module/lib/webauthn.js +1 -1
  89. package/dist/module/lib/webauthn.js.map +1 -1
  90. package/dist/tsconfig.module.tsbuildinfo +1 -1
  91. package/dist/tsconfig.tsbuildinfo +1 -1
  92. package/migrations/README.md +25 -0
  93. package/migrations/lockless-coordination.md +155 -0
  94. package/package.json +25 -12
  95. package/src/GoTrueAdminApi.ts +99 -7
  96. package/src/GoTrueClient.ts +1117 -181
  97. package/src/lib/constants.ts +9 -0
  98. package/src/lib/errors.ts +76 -9
  99. package/src/lib/fetch.ts +66 -24
  100. package/src/lib/helpers.ts +19 -6
  101. package/src/lib/locks.ts +44 -42
  102. package/src/lib/types.ts +374 -82
  103. package/src/lib/version.ts +1 -1
  104. package/src/lib/webauthn.dom.ts +3 -3
  105. package/src/lib/webauthn.errors.ts +12 -0
  106. package/src/lib/webauthn.ts +1 -1
@@ -12,6 +12,15 @@ export const AUTO_REFRESH_TICK_THRESHOLD = 3
12
12
  */
13
13
  export const EXPIRY_MARGIN_MS = AUTO_REFRESH_TICK_THRESHOLD * AUTO_REFRESH_TICK_DURATION_MS
14
14
 
15
+ /**
16
+ * After a refresh fails, serial callers (including the next auto-refresh
17
+ * tick) within this window receive the cached failure instead of firing
18
+ * another /token request. Two ticks: each outage burns at most one /token
19
+ * call per cooldown window. Cleared on any successful refresh (locally or
20
+ * via BroadcastChannel from another tab) and on `_removeSession`.
21
+ */
22
+ export const REFRESH_FAILURE_COOLDOWN_MS = 2 * AUTO_REFRESH_TICK_DURATION_MS
23
+
15
24
  export const GOTRUE_URL = 'http://localhost:9999'
16
25
  export const STORAGE_KEY = 'supabase.auth.token'
17
26
  export const AUDIENCE = ''
package/src/lib/errors.ts CHANGED
@@ -16,7 +16,7 @@ export class AuthError extends Error {
16
16
  * Error code associated with the error. Most errors coming from
17
17
  * HTTP responses will have a code, though some errors that occur
18
18
  * before a response is received will not have one present. In that
19
- * case {@link #status} will also be undefined.
19
+ * case {@link AuthError.status} will also be undefined.
20
20
  */
21
21
  code: ErrorCode | (string & {}) | undefined
22
22
 
@@ -31,6 +31,20 @@ export class AuthError extends Error {
31
31
  this.status = status
32
32
  this.code = code
33
33
  }
34
+
35
+ toJSON(): {
36
+ name: string
37
+ message: string
38
+ status: number | undefined
39
+ code: ErrorCode | (string & {}) | undefined
40
+ } {
41
+ return {
42
+ name: this.name,
43
+ message: this.message,
44
+ status: this.status,
45
+ code: this.code,
46
+ }
47
+ }
34
48
  }
35
49
 
36
50
  export function isAuthError(error: unknown): error is AuthError {
@@ -179,11 +193,15 @@ export class AuthImplicitGrantRedirectError extends CustomAuthError {
179
193
  this.details = details
180
194
  }
181
195
 
182
- toJSON() {
196
+ toJSON(): {
197
+ name: string
198
+ message: string
199
+ status: number | undefined
200
+ code: ErrorCode | (string & {}) | undefined
201
+ details: { error: string; code: string } | null
202
+ } {
183
203
  return {
184
- name: this.name,
185
- message: this.message,
186
- status: this.status,
204
+ ...super.toJSON(),
187
205
  details: this.details,
188
206
  }
189
207
  }
@@ -213,11 +231,15 @@ export class AuthPKCEGrantCodeExchangeError extends CustomAuthError {
213
231
  this.details = details
214
232
  }
215
233
 
216
- toJSON() {
234
+ toJSON(): {
235
+ name: string
236
+ message: string
237
+ status: number | undefined
238
+ code: ErrorCode | (string & {}) | undefined
239
+ details: { error: string; code: string } | null
240
+ } {
217
241
  return {
218
- name: this.name,
219
- message: this.message,
220
- status: this.status,
242
+ ...super.toJSON(),
221
243
  details: this.details,
222
244
  }
223
245
  }
@@ -275,6 +297,38 @@ export function isAuthRetryableFetchError(error: unknown): error is AuthRetryabl
275
297
  return isAuthError(error) && error.name === 'AuthRetryableFetchError'
276
298
  }
277
299
 
300
+ /**
301
+ * Returned when the server rotated a refresh token successfully but the
302
+ * client chose not to persist the rotated tokens because the local session
303
+ * changed mid-flight. Usually means a concurrent `signOut` cleared storage
304
+ * between when the refresh started and when it came back.
305
+ *
306
+ * Set on the `error` field of the refresh result so callers can tell "we
307
+ * got rotated tokens but threw them away" apart from "the refresh failed."
308
+ * The rotated session on the server will be picked up on the next refresh
309
+ * via GoTrue's parent-of-active path.
310
+ *
311
+ * @example
312
+ * ```ts
313
+ * import { isAuthRefreshDiscardedError } from '@supabase/auth-js'
314
+ *
315
+ * if (isAuthRefreshDiscardedError(error)) {
316
+ * // Concurrent signOut/sign-in raced our refresh. Treat as a no-op.
317
+ * }
318
+ * ```
319
+ */
320
+ export class AuthRefreshDiscardedError extends CustomAuthError {
321
+ constructor(
322
+ message = 'Refresh result discarded: session state changed mid-flight (e.g., concurrent signOut)'
323
+ ) {
324
+ super(message, 'AuthRefreshDiscardedError', 409, undefined)
325
+ }
326
+ }
327
+
328
+ export function isAuthRefreshDiscardedError(error: unknown): error is AuthRefreshDiscardedError {
329
+ return isAuthError(error) && error.name === 'AuthRefreshDiscardedError'
330
+ }
331
+
278
332
  /**
279
333
  * This error is thrown on certain methods when the password used is deemed
280
334
  * weak. Inspect the reasons to identify what password strength rules are
@@ -301,6 +355,19 @@ export class AuthWeakPasswordError extends CustomAuthError {
301
355
 
302
356
  this.reasons = reasons
303
357
  }
358
+
359
+ toJSON(): {
360
+ name: string
361
+ message: string
362
+ status: number | undefined
363
+ code: ErrorCode | (string & {}) | undefined
364
+ reasons: WeakPasswordReasons[]
365
+ } {
366
+ return {
367
+ ...super.toJSON(),
368
+ reasons: this.reasons,
369
+ }
370
+ }
304
371
  }
305
372
 
306
373
  export function isAuthWeakPasswordError(error: unknown): error is AuthWeakPasswordError {
package/src/lib/fetch.ts CHANGED
@@ -3,11 +3,13 @@ import { expiresAt, looksLikeFetchResponse, parseResponseAPIVersion } from './he
3
3
  import {
4
4
  AuthResponse,
5
5
  AuthResponsePassword,
6
+ Session,
6
7
  SSOResponse,
7
8
  GenerateLinkProperties,
8
9
  GenerateLinkResponse,
9
10
  User,
10
11
  UserResponse,
12
+ WeakPassword,
11
13
  } from './types'
12
14
  import {
13
15
  AuthApiError,
@@ -19,6 +21,30 @@ import {
19
21
 
20
22
  export type Fetch = typeof fetch
21
23
 
24
+ /** Raw session data from GoTrue server response. */
25
+ interface GoTrueSessionData {
26
+ access_token?: string
27
+ refresh_token?: string
28
+ expires_in?: number
29
+ expires_at?: number
30
+ user?: User
31
+ [key: string]: any // server returns additional fields (token_type, provider_token, etc.) copied into Session
32
+ }
33
+
34
+ /** Raw session data that includes weak password info (password sign-in endpoints). */
35
+ interface GoTrueSessionPasswordData extends GoTrueSessionData {
36
+ weak_password?: WeakPassword
37
+ }
38
+
39
+ /** Raw user data — either `{ user: User }` or the User object itself. */
40
+ interface GoTrueUserData {
41
+ user?: User
42
+ [key: string]: any // data may BE the User directly (fallback path)
43
+ }
44
+
45
+ /** Raw generate-link data — link properties + User fields flattened into one object. */
46
+ type GoTrueGenerateLinkData = GenerateLinkProperties & Record<string, any>
47
+
22
48
  export interface FetchOptions {
23
49
  headers?: {
24
50
  [key: string]: string
@@ -30,12 +56,25 @@ export interface FetchParameters {
30
56
  signal?: AbortSignal
31
57
  }
32
58
 
33
- export type RequestMethodType = 'GET' | 'POST' | 'PUT' | 'DELETE'
59
+ export type RequestMethodType = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
34
60
 
35
- const _getErrorMessage = (err: any): string =>
36
- err.msg || err.message || err.error_description || err.error || JSON.stringify(err)
61
+ const _getErrorMessage = (err: unknown): string => {
62
+ if (typeof err === 'object' && err !== null) {
63
+ const e = err as Record<string, unknown>
64
+ if (typeof e.msg === 'string') return e.msg
65
+ if (typeof e.message === 'string') return e.message
66
+ if (typeof e.error_description === 'string') return e.error_description
67
+ if (typeof e.error === 'string') return e.error
68
+ }
69
+ return JSON.stringify(err)
70
+ }
37
71
 
38
- const NETWORK_ERROR_CODES = [502, 503, 504]
72
+ // 500, 501, 502, 503, 504: Standard server/gateway errors
73
+ // 520-529, 530: Cloudflare-specific error codes (web server down, connection timed out, etc.)
74
+ // These are infrastructure errors and should not cause session invalidation.
75
+ const NETWORK_ERROR_CODES = [
76
+ 500, 501, 502, 503, 504, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530,
77
+ ]
39
78
 
40
79
  export async function handleError(error: unknown) {
41
80
  if (!looksLikeFetchResponse(error)) {
@@ -50,7 +89,7 @@ export async function handleError(error: unknown) {
50
89
  let data: any
51
90
  try {
52
91
  data = await error.json()
53
- } catch (e: any) {
92
+ } catch (e) {
54
93
  throw new AuthUnknownError(_getErrorMessage(e), e)
55
94
  }
56
95
 
@@ -178,16 +217,17 @@ async function _handleRequest(
178
217
  ): Promise<any> {
179
218
  const requestParams = _getRequestParams(method, options, parameters, body)
180
219
 
181
- let result: any
220
+ let result: Response
182
221
 
183
222
  try {
184
223
  result = await fetcher(url, {
185
224
  ...requestParams,
186
225
  })
187
226
  } catch (e) {
188
- console.error(e)
189
-
190
- // fetch failed, likely due to a network or CORS error
227
+ // fetch failed (network / CORS / aborted request) — surfaced to the
228
+ // caller as a retryable error below. Deliberately not logged here: an
229
+ // aborted in-flight request (e.g. a superseded page navigation) is a
230
+ // transient condition, and logging the raw error pollutes the console.
191
231
  throw new AuthRetryableFetchError(_getErrorMessage(e), 0)
192
232
  }
193
233
 
@@ -201,26 +241,28 @@ async function _handleRequest(
201
241
 
202
242
  try {
203
243
  return await result.json()
204
- } catch (e: any) {
244
+ } catch (e) {
205
245
  await handleError(e)
206
246
  }
207
247
  }
208
248
 
209
- export function _sessionResponse(data: any): AuthResponse {
249
+ export function _sessionResponse(data: GoTrueSessionData): AuthResponse {
210
250
  let session = null
211
251
  if (hasSession(data)) {
212
- session = { ...data }
252
+ session = { ...data } as Session
213
253
 
214
254
  if (!data.expires_at) {
215
- session.expires_at = expiresAt(data.expires_in)
255
+ session.expires_at = expiresAt(data.expires_in!)
216
256
  }
217
257
  }
218
258
 
219
- const user: User = data.user ?? (data as User)
259
+ // Some /verify responses (e.g. secure email_change first-confirmation) return
260
+ // only `{ msg, code }` with no user and no session. Treat those as null user.
261
+ const user: User | null = data.user ?? (typeof data?.id === 'string' ? (data as User) : null)
220
262
  return { data: { session, user }, error: null }
221
263
  }
222
264
 
223
- export function _sessionResponsePassword(data: any): AuthResponsePassword {
265
+ export function _sessionResponsePassword(data: GoTrueSessionPasswordData): AuthResponsePassword {
224
266
  const response = _sessionResponse(data) as AuthResponsePassword
225
267
 
226
268
  if (
@@ -231,7 +273,7 @@ export function _sessionResponsePassword(data: any): AuthResponsePassword {
231
273
  data.weak_password.reasons.length &&
232
274
  data.weak_password.message &&
233
275
  typeof data.weak_password.message === 'string' &&
234
- data.weak_password.reasons.reduce((a: boolean, i: any) => a && typeof i === 'string', true)
276
+ data.weak_password.reasons.reduce((a: boolean, i: unknown) => a && typeof i === 'string', true)
235
277
  ) {
236
278
  response.data.weak_password = data.weak_password
237
279
  }
@@ -239,16 +281,16 @@ export function _sessionResponsePassword(data: any): AuthResponsePassword {
239
281
  return response
240
282
  }
241
283
 
242
- export function _userResponse(data: any): UserResponse {
284
+ export function _userResponse(data: GoTrueUserData): UserResponse {
243
285
  const user: User = data.user ?? (data as User)
244
286
  return { data: { user }, error: null }
245
287
  }
246
288
 
247
- export function _ssoResponse(data: any): SSOResponse {
248
- return { data, error: null }
289
+ export function _ssoResponse(data: Record<string, any>): SSOResponse {
290
+ return { data, error: null } as SSOResponse
249
291
  }
250
292
 
251
- export function _generateLinkResponse(data: any): GenerateLinkResponse {
293
+ export function _generateLinkResponse(data: GoTrueGenerateLinkData): GenerateLinkResponse {
252
294
  const { action_link, email_otp, hashed_token, redirect_to, verification_type, ...rest } = data
253
295
 
254
296
  const properties: GenerateLinkProperties = {
@@ -259,7 +301,7 @@ export function _generateLinkResponse(data: any): GenerateLinkResponse {
259
301
  verification_type,
260
302
  }
261
303
 
262
- const user: User = { ...rest }
304
+ const user = { ...rest } as User
263
305
  return {
264
306
  data: {
265
307
  properties,
@@ -269,7 +311,7 @@ export function _generateLinkResponse(data: any): GenerateLinkResponse {
269
311
  }
270
312
  }
271
313
 
272
- export function _noResolveJsonResponse(data: any): Response {
314
+ export function _noResolveJsonResponse(data: Response): Response {
273
315
  return data
274
316
  }
275
317
 
@@ -278,6 +320,6 @@ export function _noResolveJsonResponse(data: any): Response {
278
320
  * @param data A response object
279
321
  * @returns true if a session is in the response
280
322
  */
281
- function hasSession(data: any): boolean {
282
- return data.access_token && data.refresh_token && data.expires_in
323
+ function hasSession(data: GoTrueSessionData): boolean {
324
+ return !!data.access_token && !!data.refresh_token && !!data.expires_in
283
325
  }
@@ -87,7 +87,7 @@ export function parseParametersFromURL(href: string) {
87
87
  hashSearchParams.forEach((value, key) => {
88
88
  result[key] = value
89
89
  })
90
- } catch (e: any) {
90
+ } catch (_e) {
91
91
  // hash is not a query string
92
92
  }
93
93
  }
@@ -139,7 +139,12 @@ export const getItemAsync = async (storage: SupportedStorage, key: string): Prom
139
139
  try {
140
140
  return JSON.parse(value)
141
141
  } catch {
142
- return value
142
+ // Storage values are always written as JSON via setItemAsync. A non-JSON
143
+ // value means the entry is corrupted (e.g. mismatched chunked cookies in
144
+ // SSR contexts). Treat as absent so callers do not mutate or re-save the
145
+ // garbage, which would otherwise trigger a TypeError downstream and
146
+ // leak the raw value into error logs.
147
+ return null
143
148
  }
144
149
  }
145
150
 
@@ -235,7 +240,7 @@ export function retryable<T>(
235
240
  accept(result)
236
241
  return
237
242
  }
238
- } catch (e: any) {
243
+ } catch (e) {
239
244
  if (!isRetryable(attempt, e)) {
240
245
  reject(e)
241
246
  return
@@ -304,7 +309,7 @@ export async function getCodeChallengeAndMethod(
304
309
  const codeVerifier = generatePKCEVerifier()
305
310
  let storedCodeVerifier = codeVerifier
306
311
  if (isPasswordRecovery) {
307
- storedCodeVerifier += '/PASSWORD_RECOVERY'
312
+ storedCodeVerifier += '/recovery'
308
313
  }
309
314
  await setItemAsync(storage, `${storageKey}-code-verifier`, storedCodeVerifier)
310
315
  const codeChallenge = await generatePKCEChallenge(codeVerifier)
@@ -329,7 +334,7 @@ export function parseResponseAPIVersion(response: Response) {
329
334
  try {
330
335
  const date = new Date(`${apiVersion}T00:00:00.0Z`)
331
336
  return date
332
- } catch (e: any) {
337
+ } catch (_e) {
333
338
  return null
334
339
  }
335
340
  }
@@ -345,7 +350,7 @@ export function validateExp(exp: number) {
345
350
  }
346
351
 
347
352
  export function getAlgorithm(
348
- alg: 'HS256' | 'RS256' | 'ES256'
353
+ alg: 'HS256' | 'RS256' | 'ES256' | (string & {})
349
354
  ): RsaHashedImportParams | EcKeyImportParams {
350
355
  switch (alg) {
351
356
  case 'RS256':
@@ -372,6 +377,14 @@ export function validateUUID(str: string) {
372
377
  }
373
378
  }
374
379
 
380
+ export function assertPasskeyExperimentalEnabled(experimental: { passkey?: boolean }): void {
381
+ if (!experimental.passkey) {
382
+ throw new Error(
383
+ '@supabase/auth-js: the passkey API is experimental and disabled by default. Enable it by passing `auth: { experimental: { passkey: true } }` to createClient (or to the GoTrueClient constructor).'
384
+ )
385
+ }
386
+ }
387
+
375
388
  export function userNotAvailableProxy(): User {
376
389
  const proxyTarget = {} as User
377
390
 
package/src/lib/locks.ts CHANGED
@@ -1,6 +1,17 @@
1
+ /**
2
+ * Lock primitives retained for backwards-compatible imports. The auth client
3
+ * coordinates refreshes itself (deduping in-instance callers onto a shared
4
+ * in-flight promise) and lets the GoTrue server resolve cross-instance races,
5
+ * so it does not invoke any primitive from this module. The functions still
6
+ * work for direct callers that need a navigator.locks-backed or in-process
7
+ * exclusive lock of their own.
8
+ */
9
+
1
10
  import { supportsLocalStorage } from './helpers'
2
11
 
3
12
  /**
13
+ * @deprecated Debug flag for `navigatorLock` / `processLock`. The auth
14
+ * client ignores both, so this has no client-side effect.
4
15
  * @experimental
5
16
  */
6
17
  export const internals = {
@@ -18,18 +29,9 @@ export const internals = {
18
29
  /**
19
30
  * An error thrown when a lock cannot be acquired after some amount of time.
20
31
  *
21
- * Use the {@link #isAcquireTimeout} property instead of checking with `instanceof`.
22
- *
23
- * @example
24
- * ```ts
25
- * import { LockAcquireTimeoutError } from '@supabase/auth-js'
26
- *
27
- * class CustomLockError extends LockAcquireTimeoutError {
28
- * constructor() {
29
- * super('Lock timed out')
30
- * }
31
- * }
32
- * ```
32
+ * @deprecated The auth client doesn't acquire locks around auth operations,
33
+ * so this error never originates from `supabase.auth.*` calls. Direct callers
34
+ * of `navigatorLock` / `processLock` still receive it on acquire timeout.
33
35
  */
34
36
  export abstract class LockAcquireTimeoutError extends Error {
35
37
  public readonly isAcquireTimeout = true
@@ -40,25 +42,15 @@ export abstract class LockAcquireTimeoutError extends Error {
40
42
  }
41
43
 
42
44
  /**
43
- * Error thrown when the browser Navigator Lock API fails to acquire a lock.
44
- *
45
- * @example
46
- * ```ts
47
- * import { NavigatorLockAcquireTimeoutError } from '@supabase/auth-js'
48
- *
49
- * throw new NavigatorLockAcquireTimeoutError('Lock timed out')
50
- * ```
45
+ * @deprecated The auth client doesn't call `navigator.locks`, so this error
46
+ * never originates from `supabase.auth.*` calls. Direct callers of
47
+ * `navigatorLock` still receive it on acquire timeout.
51
48
  */
52
49
  export class NavigatorLockAcquireTimeoutError extends LockAcquireTimeoutError {}
53
50
  /**
54
- * Error thrown when the process-level lock helper cannot acquire a lock.
55
- *
56
- * @example
57
- * ```ts
58
- * import { ProcessLockAcquireTimeoutError } from '@supabase/auth-js'
59
- *
60
- * throw new ProcessLockAcquireTimeoutError('Lock timed out')
61
- * ```
51
+ * @deprecated The auth client doesn't run `processLock`, so this error
52
+ * never originates from `supabase.auth.*` calls. Direct callers of
53
+ * `processLock` still receive it on acquire timeout.
62
54
  */
63
55
  export class ProcessLockAcquireTimeoutError extends LockAcquireTimeoutError {}
64
56
 
@@ -86,12 +78,10 @@ export class ProcessLockAcquireTimeoutError extends LockAcquireTimeoutError {}
86
78
  * will time out after so many milliseconds. An error is
87
79
  * a timeout if it has `isAcquireTimeout` set to true.
88
80
  * @param fn The operation to run once the lock is acquired.
89
- * @example
90
- * ```ts
91
- * await navigatorLock('sync-user', 1000, async () => {
92
- * await refreshSession()
93
- * })
94
- * ```
81
+ *
82
+ * @deprecated The auth client coordinates refreshes itself and the server
83
+ * resolves concurrent refresh races, so passing `{ lock: navigatorLock }`
84
+ * to it has no effect. You can safely drop the import from your client setup.
95
85
  */
96
86
  export async function navigatorLock<R>(
97
87
  name: string,
@@ -176,7 +166,7 @@ export async function navigatorLock<R>(
176
166
  '@supabase/gotrue-js: Navigator LockManager state',
177
167
  JSON.stringify(result, null, ' ')
178
168
  )
179
- } catch (e: any) {
169
+ } catch (e) {
180
170
  console.warn(
181
171
  '@supabase/gotrue-js: Error when querying Navigator LockManager state',
182
172
  e
@@ -198,14 +188,21 @@ export async function navigatorLock<R>(
198
188
  }
199
189
  }
200
190
  )
201
- } catch (e: any) {
191
+ } catch (e) {
202
192
  // Always clear the acquire timeout once the request settles, so it cannot
203
193
  // fire later and incorrectly abort/log after a rejection.
204
194
  if (acquireTimeout > 0) {
205
195
  clearTimeout(acquireTimeoutTimer)
206
196
  }
207
197
 
208
- if (e?.name === 'AbortError' && acquireTimeout > 0) {
198
+ // DOMException does not extend Error in Node.js, so use structural check
199
+ if (
200
+ e !== null &&
201
+ typeof e === 'object' &&
202
+ 'name' in e &&
203
+ e.name === 'AbortError' &&
204
+ acquireTimeout > 0
205
+ ) {
209
206
  if (abortController.signal.aborted) {
210
207
  // OUR timeout fired — the lock is genuinely orphaned. Steal it.
211
208
  //
@@ -305,7 +302,7 @@ const PROCESS_LOCKS: { [name: string]: Promise<any> } = {}
305
302
  * Useful for environments like React Native or other non-browser
306
303
  * single-process (i.e. no concept of "tabs") environments.
307
304
  *
308
- * Use {@link #navigatorLock} in browser environments.
305
+ * Use {@link navigatorLock} in browser environments.
309
306
  *
310
307
  * @param name Name of the lock to be acquired.
311
308
  * @param acquireTimeout If negative, no timeout. If 0 an error is thrown if
@@ -313,6 +310,11 @@ const PROCESS_LOCKS: { [name: string]: Promise<any> } = {}
313
310
  * will time out after so many milliseconds. An error is
314
311
  * a timeout if it has `isAcquireTimeout` set to true.
315
312
  * @param fn The operation to run once the lock is acquired.
313
+ *
314
+ * @deprecated The auth client coordinates refreshes itself and the server
315
+ * resolves concurrent refresh races, so passing `{ lock: processLock }`
316
+ * to it has no effect. You can safely drop the import from your client setup.
317
+ *
316
318
  * @example
317
319
  * ```ts
318
320
  * await processLock('migrate', 5000, async () => {
@@ -370,14 +372,14 @@ export async function processLock<R>(
370
372
  if (timeoutId !== null) {
371
373
  clearTimeout(timeoutId)
372
374
  }
373
- } catch (e: any) {
375
+ } catch (e) {
374
376
  // Clear the timeout on error path as well
375
377
  if (timeoutId !== null) {
376
378
  clearTimeout(timeoutId)
377
379
  }
378
380
 
379
381
  // Re-throw timeout errors, ignore others
380
- if (e && e.isAcquireTimeout) {
382
+ if (e instanceof LockAcquireTimeoutError) {
381
383
  throw e
382
384
  }
383
385
  // Fall through to run fn() - previous operation finished with error
@@ -391,8 +393,8 @@ export async function processLock<R>(
391
393
  PROCESS_LOCKS[name] = (async () => {
392
394
  try {
393
395
  return await currentOperation
394
- } catch (e: any) {
395
- if (e && e.isAcquireTimeout) {
396
+ } catch (e) {
397
+ if (e instanceof LockAcquireTimeoutError) {
396
398
  // if the current operation timed out, it doesn't mean that the previous
397
399
  // operation finished, so we need continue waiting for it to finish
398
400
  try {