main repo

This commit is contained in:
Basilosaurusrex
2025-11-24 18:09:40 +01:00
parent b636ee5e70
commit f027651f9b
34146 changed files with 4436636 additions and 0 deletions

5
node_modules/@supabase/auth-js/src/AuthAdminApi.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import GoTrueAdminApi from './GoTrueAdminApi'
const AuthAdminApi = GoTrueAdminApi
export default AuthAdminApi

5
node_modules/@supabase/auth-js/src/AuthClient.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import GoTrueClient from './GoTrueClient'
const AuthClient = GoTrueClient
export default AuthClient

352
node_modules/@supabase/auth-js/src/GoTrueAdminApi.ts generated vendored Normal file
View File

@@ -0,0 +1,352 @@
import {
Fetch,
_generateLinkResponse,
_noResolveJsonResponse,
_request,
_userResponse,
} from './lib/fetch'
import { resolveFetch, validateUUID } from './lib/helpers'
import {
AdminUserAttributes,
GenerateLinkParams,
GenerateLinkResponse,
Pagination,
User,
UserResponse,
GoTrueAdminMFAApi,
AuthMFAAdminDeleteFactorParams,
AuthMFAAdminDeleteFactorResponse,
AuthMFAAdminListFactorsParams,
AuthMFAAdminListFactorsResponse,
PageParams,
SIGN_OUT_SCOPES,
SignOutScope,
} from './lib/types'
import { AuthError, isAuthError } from './lib/errors'
export default class GoTrueAdminApi {
/** Contains all MFA administration methods. */
mfa: GoTrueAdminMFAApi
protected url: string
protected headers: {
[key: string]: string
}
protected fetch: Fetch
constructor({
url = '',
headers = {},
fetch,
}: {
url: string
headers?: {
[key: string]: string
}
fetch?: Fetch
}) {
this.url = url
this.headers = headers
this.fetch = resolveFetch(fetch)
this.mfa = {
listFactors: this._listFactors.bind(this),
deleteFactor: this._deleteFactor.bind(this),
}
}
/**
* Removes a logged-in session.
* @param jwt A valid, logged-in JWT.
* @param scope The logout sope.
*/
async signOut(
jwt: string,
scope: SignOutScope = SIGN_OUT_SCOPES[0]
): Promise<{ data: null; error: AuthError | null }> {
if (SIGN_OUT_SCOPES.indexOf(scope) < 0) {
throw new Error(
`@supabase/auth-js: Parameter scope must be one of ${SIGN_OUT_SCOPES.join(', ')}`
)
}
try {
await _request(this.fetch, 'POST', `${this.url}/logout?scope=${scope}`, {
headers: this.headers,
jwt,
noResolveJson: true,
})
return { data: null, error: null }
} catch (error) {
if (isAuthError(error)) {
return { data: null, error }
}
throw error
}
}
/**
* Sends an invite link to an email address.
* @param email The email address of the user.
* @param options Additional options to be included when inviting.
*/
async inviteUserByEmail(
email: string,
options: {
/** A custom data object to store additional metadata about the user. This maps to the `auth.users.user_metadata` column. */
data?: object
/** The URL which will be appended to the email link sent to the user's email address. Once clicked the user will end up on this URL. */
redirectTo?: string
} = {}
): Promise<UserResponse> {
try {
return await _request(this.fetch, 'POST', `${this.url}/invite`, {
body: { email, data: options.data },
headers: this.headers,
redirectTo: options.redirectTo,
xform: _userResponse,
})
} catch (error) {
if (isAuthError(error)) {
return { data: { user: null }, error }
}
throw error
}
}
/**
* Generates email links and OTPs to be sent via a custom email provider.
* @param email The user's email.
* @param options.password User password. For signup only.
* @param options.data Optional user metadata. For signup only.
* @param options.redirectTo The redirect url which should be appended to the generated link
*/
async generateLink(params: GenerateLinkParams): Promise<GenerateLinkResponse> {
try {
const { options, ...rest } = params
const body: any = { ...rest, ...options }
if ('newEmail' in rest) {
// replace newEmail with new_email in request body
body.new_email = rest?.newEmail
delete body['newEmail']
}
return await _request(this.fetch, 'POST', `${this.url}/admin/generate_link`, {
body: body,
headers: this.headers,
xform: _generateLinkResponse,
redirectTo: options?.redirectTo,
})
} catch (error) {
if (isAuthError(error)) {
return {
data: {
properties: null,
user: null,
},
error,
}
}
throw error
}
}
// User Admin API
/**
* Creates a new user.
* This function should only be called on a server. Never expose your `service_role` key in the browser.
*/
async createUser(attributes: AdminUserAttributes): Promise<UserResponse> {
try {
return await _request(this.fetch, 'POST', `${this.url}/admin/users`, {
body: attributes,
headers: this.headers,
xform: _userResponse,
})
} catch (error) {
if (isAuthError(error)) {
return { data: { user: null }, error }
}
throw error
}
}
/**
* Get a list of users.
*
* This function should only be called on a server. Never expose your `service_role` key in the browser.
* @param params An object which supports `page` and `perPage` as numbers, to alter the paginated results.
*/
async listUsers(
params?: PageParams
): Promise<
| { data: { users: User[]; aud: string } & Pagination; error: null }
| { data: { users: [] }; error: AuthError }
> {
try {
const pagination: Pagination = { nextPage: null, lastPage: 0, total: 0 }
const response = await _request(this.fetch, 'GET', `${this.url}/admin/users`, {
headers: this.headers,
noResolveJson: true,
query: {
page: params?.page?.toString() ?? '',
per_page: params?.perPage?.toString() ?? '',
},
xform: _noResolveJsonResponse,
})
if (response.error) throw response.error
const users = await response.json()
const total = response.headers.get('x-total-count') ?? 0
const links = response.headers.get('link')?.split(',') ?? []
if (links.length > 0) {
links.forEach((link: string) => {
const page = parseInt(link.split(';')[0].split('=')[1].substring(0, 1))
const rel = JSON.parse(link.split(';')[1].split('=')[1])
pagination[`${rel}Page`] = page
})
pagination.total = parseInt(total)
}
return { data: { ...users, ...pagination }, error: null }
} catch (error) {
if (isAuthError(error)) {
return { data: { users: [] }, error }
}
throw error
}
}
/**
* Get user by id.
*
* @param uid The user's unique identifier
*
* This function should only be called on a server. Never expose your `service_role` key in the browser.
*/
async getUserById(uid: string): Promise<UserResponse> {
validateUUID(uid)
try {
return await _request(this.fetch, 'GET', `${this.url}/admin/users/${uid}`, {
headers: this.headers,
xform: _userResponse,
})
} catch (error) {
if (isAuthError(error)) {
return { data: { user: null }, error }
}
throw error
}
}
/**
* Updates the user data.
*
* @param attributes The data you want to update.
*
* This function should only be called on a server. Never expose your `service_role` key in the browser.
*/
async updateUserById(uid: string, attributes: AdminUserAttributes): Promise<UserResponse> {
validateUUID(uid)
try {
return await _request(this.fetch, 'PUT', `${this.url}/admin/users/${uid}`, {
body: attributes,
headers: this.headers,
xform: _userResponse,
})
} catch (error) {
if (isAuthError(error)) {
return { data: { user: null }, error }
}
throw error
}
}
/**
* Delete a user. Requires a `service_role` key.
*
* @param id The user id you want to remove.
* @param shouldSoftDelete If true, then the user will be soft-deleted from the auth schema. Soft deletion allows user identification from the hashed user ID but is not reversible.
* Defaults to false for backward compatibility.
*
* This function should only be called on a server. Never expose your `service_role` key in the browser.
*/
async deleteUser(id: string, shouldSoftDelete = false): Promise<UserResponse> {
validateUUID(id)
try {
return await _request(this.fetch, 'DELETE', `${this.url}/admin/users/${id}`, {
headers: this.headers,
body: {
should_soft_delete: shouldSoftDelete,
},
xform: _userResponse,
})
} catch (error) {
if (isAuthError(error)) {
return { data: { user: null }, error }
}
throw error
}
}
private async _listFactors(
params: AuthMFAAdminListFactorsParams
): Promise<AuthMFAAdminListFactorsResponse> {
validateUUID(params.userId)
try {
const { data, error } = await _request(
this.fetch,
'GET',
`${this.url}/admin/users/${params.userId}/factors`,
{
headers: this.headers,
xform: (factors: any) => {
return { data: { factors }, error: null }
},
}
)
return { data, error }
} catch (error) {
if (isAuthError(error)) {
return { data: null, error }
}
throw error
}
}
private async _deleteFactor(
params: AuthMFAAdminDeleteFactorParams
): Promise<AuthMFAAdminDeleteFactorResponse> {
validateUUID(params.userId)
validateUUID(params.id)
try {
const data = await _request(
this.fetch,
'DELETE',
`${this.url}/admin/users/${params.userId}/factors/${params.id}`,
{
headers: this.headers,
}
)
return { data, error: null }
} catch (error) {
if (isAuthError(error)) {
return { data: null, error }
}
throw error
}
}
}

3130
node_modules/@supabase/auth-js/src/GoTrueClient.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

13
node_modules/@supabase/auth-js/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,13 @@
import GoTrueAdminApi from './GoTrueAdminApi'
import GoTrueClient from './GoTrueClient'
import AuthAdminApi from './AuthAdminApi'
import AuthClient from './AuthClient'
export { GoTrueAdminApi, GoTrueClient, AuthAdminApi, AuthClient }
export * from './lib/types'
export * from './lib/errors'
export {
navigatorLock,
NavigatorLockAcquireTimeoutError,
internals as lockInternals,
processLock,
} from './lib/locks'

306
node_modules/@supabase/auth-js/src/lib/base64url.ts generated vendored Normal file
View File

@@ -0,0 +1,306 @@
/**
* Avoid modifying this file. It's part of
* https://github.com/supabase-community/base64url-js. Submit all fixes on
* that repo!
*/
/**
* An array of characters that encode 6 bits into a Base64-URL alphabet
* character.
*/
const TO_BASE64URL = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'.split('')
/**
* An array of characters that can appear in a Base64-URL encoded string but
* should be ignored.
*/
const IGNORE_BASE64URL = ' \t\n\r='.split('')
/**
* An array of 128 numbers that map a Base64-URL character to 6 bits, or if -2
* used to skip the character, or if -1 used to error out.
*/
const FROM_BASE64URL = (() => {
const charMap: number[] = new Array(128)
for (let i = 0; i < charMap.length; i += 1) {
charMap[i] = -1
}
for (let i = 0; i < IGNORE_BASE64URL.length; i += 1) {
charMap[IGNORE_BASE64URL[i].charCodeAt(0)] = -2
}
for (let i = 0; i < TO_BASE64URL.length; i += 1) {
charMap[TO_BASE64URL[i].charCodeAt(0)] = i
}
return charMap
})()
/**
* Converts a byte to a Base64-URL string.
*
* @param byte The byte to convert, or null to flush at the end of the byte sequence.
* @param state The Base64 conversion state. Pass an initial value of `{ queue: 0, queuedBits: 0 }`.
* @param emit A function called with the next Base64 character when ready.
*/
export function byteToBase64URL(
byte: number | null,
state: { queue: number; queuedBits: number },
emit: (char: string) => void
) {
if (byte !== null) {
state.queue = (state.queue << 8) | byte
state.queuedBits += 8
while (state.queuedBits >= 6) {
const pos = (state.queue >> (state.queuedBits - 6)) & 63
emit(TO_BASE64URL[pos])
state.queuedBits -= 6
}
} else if (state.queuedBits > 0) {
state.queue = state.queue << (6 - state.queuedBits)
state.queuedBits = 6
while (state.queuedBits >= 6) {
const pos = (state.queue >> (state.queuedBits - 6)) & 63
emit(TO_BASE64URL[pos])
state.queuedBits -= 6
}
}
}
/**
* Converts a String char code (extracted using `string.charCodeAt(position)`) to a sequence of Base64-URL characters.
*
* @param charCode The char code of the JavaScript string.
* @param state The Base64 state. Pass an initial value of `{ queue: 0, queuedBits: 0 }`.
* @param emit A function called with the next byte.
*/
export function byteFromBase64URL(
charCode: number,
state: { queue: number; queuedBits: number },
emit: (byte: number) => void
) {
const bits = FROM_BASE64URL[charCode]
if (bits > -1) {
// valid Base64-URL character
state.queue = (state.queue << 6) | bits
state.queuedBits += 6
while (state.queuedBits >= 8) {
emit((state.queue >> (state.queuedBits - 8)) & 0xff)
state.queuedBits -= 8
}
} else if (bits === -2) {
// ignore spaces, tabs, newlines, =
return
} else {
throw new Error(`Invalid Base64-URL character "${String.fromCharCode(charCode)}"`)
}
}
/**
* Converts a JavaScript string (which may include any valid character) into a
* Base64-URL encoded string. The string is first encoded in UTF-8 which is
* then encoded as Base64-URL.
*
* @param str The string to convert.
*/
export function stringToBase64URL(str: string) {
const base64: string[] = []
const emitter = (char: string) => {
base64.push(char)
}
const state = { queue: 0, queuedBits: 0 }
stringToUTF8(str, (byte: number) => {
byteToBase64URL(byte, state, emitter)
})
byteToBase64URL(null, state, emitter)
return base64.join('')
}
/**
* Converts a Base64-URL encoded string into a JavaScript string. It is assumed
* that the underlying string has been encoded as UTF-8.
*
* @param str The Base64-URL encoded string.
*/
export function stringFromBase64URL(str: string) {
const conv: string[] = []
const utf8Emit = (codepoint: number) => {
conv.push(String.fromCodePoint(codepoint))
}
const utf8State = {
utf8seq: 0,
codepoint: 0,
}
const b64State = { queue: 0, queuedBits: 0 }
const byteEmit = (byte: number) => {
stringFromUTF8(byte, utf8State, utf8Emit)
}
for (let i = 0; i < str.length; i += 1) {
byteFromBase64URL(str.charCodeAt(i), b64State, byteEmit)
}
return conv.join('')
}
/**
* Converts a Unicode codepoint to a multi-byte UTF-8 sequence.
*
* @param codepoint The Unicode codepoint.
* @param emit Function which will be called for each UTF-8 byte that represents the codepoint.
*/
export function codepointToUTF8(codepoint: number, emit: (byte: number) => void) {
if (codepoint <= 0x7f) {
emit(codepoint)
return
} else if (codepoint <= 0x7ff) {
emit(0xc0 | (codepoint >> 6))
emit(0x80 | (codepoint & 0x3f))
return
} else if (codepoint <= 0xffff) {
emit(0xe0 | (codepoint >> 12))
emit(0x80 | ((codepoint >> 6) & 0x3f))
emit(0x80 | (codepoint & 0x3f))
return
} else if (codepoint <= 0x10ffff) {
emit(0xf0 | (codepoint >> 18))
emit(0x80 | ((codepoint >> 12) & 0x3f))
emit(0x80 | ((codepoint >> 6) & 0x3f))
emit(0x80 | (codepoint & 0x3f))
return
}
throw new Error(`Unrecognized Unicode codepoint: ${codepoint.toString(16)}`)
}
/**
* Converts a JavaScript string to a sequence of UTF-8 bytes.
*
* @param str The string to convert to UTF-8.
* @param emit Function which will be called for each UTF-8 byte of the string.
*/
export function stringToUTF8(str: string, emit: (byte: number) => void) {
for (let i = 0; i < str.length; i += 1) {
let codepoint = str.charCodeAt(i)
if (codepoint > 0xd7ff && codepoint <= 0xdbff) {
// most UTF-16 codepoints are Unicode codepoints, except values in this
// range where the next UTF-16 codepoint needs to be combined with the
// current one to get the Unicode codepoint
const highSurrogate = ((codepoint - 0xd800) * 0x400) & 0xffff
const lowSurrogate = (str.charCodeAt(i + 1) - 0xdc00) & 0xffff
codepoint = (lowSurrogate | highSurrogate) + 0x10000
i += 1
}
codepointToUTF8(codepoint, emit)
}
}
/**
* Converts a UTF-8 byte to a Unicode codepoint.
*
* @param byte The UTF-8 byte next in the sequence.
* @param state The shared state between consecutive UTF-8 bytes in the
* sequence, an object with the shape `{ utf8seq: 0, codepoint: 0 }`.
* @param emit Function which will be called for each codepoint.
*/
export function stringFromUTF8(
byte: number,
state: { utf8seq: number; codepoint: number },
emit: (codepoint: number) => void
) {
if (state.utf8seq === 0) {
if (byte <= 0x7f) {
emit(byte)
return
}
// count the number of 1 leading bits until you reach 0
for (let leadingBit = 1; leadingBit < 6; leadingBit += 1) {
if (((byte >> (7 - leadingBit)) & 1) === 0) {
state.utf8seq = leadingBit
break
}
}
if (state.utf8seq === 2) {
state.codepoint = byte & 31
} else if (state.utf8seq === 3) {
state.codepoint = byte & 15
} else if (state.utf8seq === 4) {
state.codepoint = byte & 7
} else {
throw new Error('Invalid UTF-8 sequence')
}
state.utf8seq -= 1
} else if (state.utf8seq > 0) {
if (byte <= 0x7f) {
throw new Error('Invalid UTF-8 sequence')
}
state.codepoint = (state.codepoint << 6) | (byte & 63)
state.utf8seq -= 1
if (state.utf8seq === 0) {
emit(state.codepoint)
}
}
}
/**
* Helper functions to convert different types of strings to Uint8Array
*/
export function base64UrlToUint8Array(str: string): Uint8Array {
const result: number[] = []
const state = { queue: 0, queuedBits: 0 }
const onByte = (byte: number) => {
result.push(byte)
}
for (let i = 0; i < str.length; i += 1) {
byteFromBase64URL(str.charCodeAt(i), state, onByte)
}
return new Uint8Array(result)
}
export function stringToUint8Array(str: string): Uint8Array {
const result: number[] = []
stringToUTF8(str, (byte: number) => result.push(byte))
return new Uint8Array(result)
}
export function bytesToBase64URL(bytes: Uint8Array) {
const result: string[] = []
const state = { queue: 0, queuedBits: 0 }
const onChar = (char: string) => {
result.push(char)
}
bytes.forEach((byte) => byteToBase64URL(byte, state, onChar))
// always call with `null` after processing all bytes
byteToBase64URL(null, state, onChar)
return result.join('')
}

34
node_modules/@supabase/auth-js/src/lib/constants.ts generated vendored Normal file
View File

@@ -0,0 +1,34 @@
import { version } from './version'
/** Current session will be checked for refresh at this interval. */
export const AUTO_REFRESH_TICK_DURATION_MS = 30 * 1000
/**
* A token refresh will be attempted this many ticks before the current session expires. */
export const AUTO_REFRESH_TICK_THRESHOLD = 3
/*
* Earliest time before an access token expires that the session should be refreshed.
*/
export const EXPIRY_MARGIN_MS = AUTO_REFRESH_TICK_THRESHOLD * AUTO_REFRESH_TICK_DURATION_MS
export const GOTRUE_URL = 'http://localhost:9999'
export const STORAGE_KEY = 'supabase.auth.token'
export const AUDIENCE = ''
export const DEFAULT_HEADERS = { 'X-Client-Info': `gotrue-js/${version}` }
export const NETWORK_FAILURE = {
MAX_RETRIES: 10,
RETRY_INTERVAL: 2, // in deciseconds
}
export const API_VERSION_HEADER_NAME = 'X-Supabase-Api-Version'
export const API_VERSIONS = {
'2024-01-01': {
timestamp: Date.parse('2024-01-01T00:00:00.0Z'),
name: '2024-01-01',
},
}
export const BASE64URL_REGEX = /^([a-z0-9_-]{4})*($|[a-z0-9_-]{3}$|[a-z0-9_-]{2}$)$/i
export const JWKS_TTL = 10 * 60 * 1000 // 10 minutes

90
node_modules/@supabase/auth-js/src/lib/error-codes.ts generated vendored Normal file
View File

@@ -0,0 +1,90 @@
/**
* Known error codes. Note that the server may also return other error codes
* not included in this list (if the client library is older than the version
* on the server).
*/
export type ErrorCode =
| 'unexpected_failure'
| 'validation_failed'
| 'bad_json'
| 'email_exists'
| 'phone_exists'
| 'bad_jwt'
| 'not_admin'
| 'no_authorization'
| 'user_not_found'
| 'session_not_found'
| 'session_expired'
| 'refresh_token_not_found'
| 'refresh_token_already_used'
| 'flow_state_not_found'
| 'flow_state_expired'
| 'signup_disabled'
| 'user_banned'
| 'provider_email_needs_verification'
| 'invite_not_found'
| 'bad_oauth_state'
| 'bad_oauth_callback'
| 'oauth_provider_not_supported'
| 'unexpected_audience'
| 'single_identity_not_deletable'
| 'email_conflict_identity_not_deletable'
| 'identity_already_exists'
| 'email_provider_disabled'
| 'phone_provider_disabled'
| 'too_many_enrolled_mfa_factors'
| 'mfa_factor_name_conflict'
| 'mfa_factor_not_found'
| 'mfa_ip_address_mismatch'
| 'mfa_challenge_expired'
| 'mfa_verification_failed'
| 'mfa_verification_rejected'
| 'insufficient_aal'
| 'captcha_failed'
| 'saml_provider_disabled'
| 'manual_linking_disabled'
| 'sms_send_failed'
| 'email_not_confirmed'
| 'phone_not_confirmed'
| 'reauth_nonce_missing'
| 'saml_relay_state_not_found'
| 'saml_relay_state_expired'
| 'saml_idp_not_found'
| 'saml_assertion_no_user_id'
| 'saml_assertion_no_email'
| 'user_already_exists'
| 'sso_provider_not_found'
| 'saml_metadata_fetch_failed'
| 'saml_idp_already_exists'
| 'sso_domain_already_exists'
| 'saml_entity_id_mismatch'
| 'conflict'
| 'provider_disabled'
| 'user_sso_managed'
| 'reauthentication_needed'
| 'same_password'
| 'reauthentication_not_valid'
| 'otp_expired'
| 'otp_disabled'
| 'identity_not_found'
| 'weak_password'
| 'over_request_rate_limit'
| 'over_email_send_rate_limit'
| 'over_sms_send_rate_limit'
| 'bad_code_verifier'
| 'anonymous_provider_disabled'
| 'hook_timeout'
| 'hook_timeout_after_retry'
| 'hook_payload_over_size_limit'
| 'hook_payload_invalid_content_type'
| 'request_timeout'
| 'mfa_phone_enroll_not_enabled'
| 'mfa_phone_verify_not_enabled'
| 'mfa_totp_enroll_not_enabled'
| 'mfa_totp_verify_not_enabled'
| 'mfa_webauthn_enroll_not_enabled'
| 'mfa_webauthn_verify_not_enabled'
| 'mfa_verified_factor_exists'
| 'invalid_credentials'
| 'email_address_not_authorized'
| 'email_address_invalid'

165
node_modules/@supabase/auth-js/src/lib/errors.ts generated vendored Normal file
View File

@@ -0,0 +1,165 @@
import { WeakPasswordReasons } from './types'
import { ErrorCode } from './error-codes'
export class AuthError extends Error {
/**
* Error code associated with the error. Most errors coming from
* HTTP responses will have a code, though some errors that occur
* before a response is received will not have one present. In that
* case {@link #status} will also be undefined.
*/
code: ErrorCode | (string & {}) | undefined
/** HTTP status code that caused the error. */
status: number | undefined
protected __isAuthError = true
constructor(message: string, status?: number, code?: string) {
super(message)
this.name = 'AuthError'
this.status = status
this.code = code
}
}
export function isAuthError(error: unknown): error is AuthError {
return typeof error === 'object' && error !== null && '__isAuthError' in error
}
export class AuthApiError extends AuthError {
status: number
constructor(message: string, status: number, code: string | undefined) {
super(message, status, code)
this.name = 'AuthApiError'
this.status = status
this.code = code
}
}
export function isAuthApiError(error: unknown): error is AuthApiError {
return isAuthError(error) && error.name === 'AuthApiError'
}
export class AuthUnknownError extends AuthError {
originalError: unknown
constructor(message: string, originalError: unknown) {
super(message)
this.name = 'AuthUnknownError'
this.originalError = originalError
}
}
export class CustomAuthError extends AuthError {
name: string
status: number
constructor(message: string, name: string, status: number, code: string | undefined) {
super(message, status, code)
this.name = name
this.status = status
}
}
export class AuthSessionMissingError extends CustomAuthError {
constructor() {
super('Auth session missing!', 'AuthSessionMissingError', 400, undefined)
}
}
export function isAuthSessionMissingError(error: any): error is AuthSessionMissingError {
return isAuthError(error) && error.name === 'AuthSessionMissingError'
}
export class AuthInvalidTokenResponseError extends CustomAuthError {
constructor() {
super('Auth session or user missing', 'AuthInvalidTokenResponseError', 500, undefined)
}
}
export class AuthInvalidCredentialsError extends CustomAuthError {
constructor(message: string) {
super(message, 'AuthInvalidCredentialsError', 400, undefined)
}
}
export class AuthImplicitGrantRedirectError extends CustomAuthError {
details: { error: string; code: string } | null = null
constructor(message: string, details: { error: string; code: string } | null = null) {
super(message, 'AuthImplicitGrantRedirectError', 500, undefined)
this.details = details
}
toJSON() {
return {
name: this.name,
message: this.message,
status: this.status,
details: this.details,
}
}
}
export function isAuthImplicitGrantRedirectError(
error: any
): error is AuthImplicitGrantRedirectError {
return isAuthError(error) && error.name === 'AuthImplicitGrantRedirectError'
}
export class AuthPKCEGrantCodeExchangeError extends CustomAuthError {
details: { error: string; code: string } | null = null
constructor(message: string, details: { error: string; code: string } | null = null) {
super(message, 'AuthPKCEGrantCodeExchangeError', 500, undefined)
this.details = details
}
toJSON() {
return {
name: this.name,
message: this.message,
status: this.status,
details: this.details,
}
}
}
export class AuthRetryableFetchError extends CustomAuthError {
constructor(message: string, status: number) {
super(message, 'AuthRetryableFetchError', status, undefined)
}
}
export function isAuthRetryableFetchError(error: unknown): error is AuthRetryableFetchError {
return isAuthError(error) && error.name === 'AuthRetryableFetchError'
}
/**
* This error is thrown on certain methods when the password used is deemed
* weak. Inspect the reasons to identify what password strength rules are
* inadequate.
*/
export class AuthWeakPasswordError extends CustomAuthError {
/**
* Reasons why the password is deemed weak.
*/
reasons: WeakPasswordReasons[]
constructor(message: string, status: number, reasons: string[]) {
super(message, 'AuthWeakPasswordError', status, 'weak_password')
this.reasons = reasons
}
}
export function isAuthWeakPasswordError(error: unknown): error is AuthWeakPasswordError {
return isAuthError(error) && error.name === 'AuthWeakPasswordError'
}
export class AuthInvalidJwtError extends CustomAuthError {
constructor(message: string) {
super(message, 'AuthInvalidJwtError', 400, 'invalid_jwt')
}
}

283
node_modules/@supabase/auth-js/src/lib/fetch.ts generated vendored Normal file
View File

@@ -0,0 +1,283 @@
import { API_VERSIONS, API_VERSION_HEADER_NAME } from './constants'
import { expiresAt, looksLikeFetchResponse, parseResponseAPIVersion } from './helpers'
import {
AuthResponse,
AuthResponsePassword,
SSOResponse,
GenerateLinkProperties,
GenerateLinkResponse,
User,
UserResponse,
} from './types'
import {
AuthApiError,
AuthRetryableFetchError,
AuthWeakPasswordError,
AuthUnknownError,
AuthSessionMissingError,
} from './errors'
export type Fetch = typeof fetch
export interface FetchOptions {
headers?: {
[key: string]: string
}
noResolveJson?: boolean
}
export interface FetchParameters {
signal?: AbortSignal
}
export type RequestMethodType = 'GET' | 'POST' | 'PUT' | 'DELETE'
const _getErrorMessage = (err: any): string =>
err.msg || err.message || err.error_description || err.error || JSON.stringify(err)
const NETWORK_ERROR_CODES = [502, 503, 504]
export async function handleError(error: unknown) {
if (!looksLikeFetchResponse(error)) {
throw new AuthRetryableFetchError(_getErrorMessage(error), 0)
}
if (NETWORK_ERROR_CODES.includes(error.status)) {
// status in 500...599 range - server had an error, request might be retryed.
throw new AuthRetryableFetchError(_getErrorMessage(error), error.status)
}
let data: any
try {
data = await error.json()
} catch (e: any) {
throw new AuthUnknownError(_getErrorMessage(e), e)
}
let errorCode: string | undefined = undefined
const responseAPIVersion = parseResponseAPIVersion(error)
if (
responseAPIVersion &&
responseAPIVersion.getTime() >= API_VERSIONS['2024-01-01'].timestamp &&
typeof data === 'object' &&
data &&
typeof data.code === 'string'
) {
errorCode = data.code
} else if (typeof data === 'object' && data && typeof data.error_code === 'string') {
errorCode = data.error_code
}
if (!errorCode) {
// Legacy support for weak password errors, when there were no error codes
if (
typeof data === 'object' &&
data &&
typeof data.weak_password === 'object' &&
data.weak_password &&
Array.isArray(data.weak_password.reasons) &&
data.weak_password.reasons.length &&
data.weak_password.reasons.reduce((a: boolean, i: any) => a && typeof i === 'string', true)
) {
throw new AuthWeakPasswordError(
_getErrorMessage(data),
error.status,
data.weak_password.reasons
)
}
} else if (errorCode === 'weak_password') {
throw new AuthWeakPasswordError(
_getErrorMessage(data),
error.status,
data.weak_password?.reasons || []
)
} else if (errorCode === 'session_not_found') {
// The `session_id` inside the JWT does not correspond to a row in the
// `sessions` table. This usually means the user has signed out, has been
// deleted, or their session has somehow been terminated.
throw new AuthSessionMissingError()
}
throw new AuthApiError(_getErrorMessage(data), error.status || 500, errorCode)
}
const _getRequestParams = (
method: RequestMethodType,
options?: FetchOptions,
parameters?: FetchParameters,
body?: object
) => {
const params: { [k: string]: any } = { method, headers: options?.headers || {} }
if (method === 'GET') {
return params
}
params.headers = { 'Content-Type': 'application/json;charset=UTF-8', ...options?.headers }
params.body = JSON.stringify(body)
return { ...params, ...parameters }
}
interface GotrueRequestOptions extends FetchOptions {
jwt?: string
redirectTo?: string
body?: object
query?: { [key: string]: string }
/**
* Function that transforms api response from gotrue into a desirable / standardised format
*/
xform?: (data: any) => any
}
export async function _request(
fetcher: Fetch,
method: RequestMethodType,
url: string,
options?: GotrueRequestOptions
) {
const headers = {
...options?.headers,
}
if (!headers[API_VERSION_HEADER_NAME]) {
headers[API_VERSION_HEADER_NAME] = API_VERSIONS['2024-01-01'].name
}
if (options?.jwt) {
headers['Authorization'] = `Bearer ${options.jwt}`
}
const qs = options?.query ?? {}
if (options?.redirectTo) {
qs['redirect_to'] = options.redirectTo
}
const queryString = Object.keys(qs).length ? '?' + new URLSearchParams(qs).toString() : ''
const data = await _handleRequest(
fetcher,
method,
url + queryString,
{
headers,
noResolveJson: options?.noResolveJson,
},
{},
options?.body
)
return options?.xform ? options?.xform(data) : { data: { ...data }, error: null }
}
async function _handleRequest(
fetcher: Fetch,
method: RequestMethodType,
url: string,
options?: FetchOptions,
parameters?: FetchParameters,
body?: object
): Promise<any> {
const requestParams = _getRequestParams(method, options, parameters, body)
let result: any
try {
result = await fetcher(url, {
...requestParams,
})
} catch (e) {
console.error(e)
// fetch failed, likely due to a network or CORS error
throw new AuthRetryableFetchError(_getErrorMessage(e), 0)
}
if (!result.ok) {
await handleError(result)
}
if (options?.noResolveJson) {
return result
}
try {
return await result.json()
} catch (e: any) {
await handleError(e)
}
}
export function _sessionResponse(data: any): AuthResponse {
let session = null
if (hasSession(data)) {
session = { ...data }
if (!data.expires_at) {
session.expires_at = expiresAt(data.expires_in)
}
}
const user: User = data.user ?? (data as User)
return { data: { session, user }, error: null }
}
export function _sessionResponsePassword(data: any): AuthResponsePassword {
const response = _sessionResponse(data) as AuthResponsePassword
if (
!response.error &&
data.weak_password &&
typeof data.weak_password === 'object' &&
Array.isArray(data.weak_password.reasons) &&
data.weak_password.reasons.length &&
data.weak_password.message &&
typeof data.weak_password.message === 'string' &&
data.weak_password.reasons.reduce((a: boolean, i: any) => a && typeof i === 'string', true)
) {
response.data.weak_password = data.weak_password
}
return response
}
export function _userResponse(data: any): UserResponse {
const user: User = data.user ?? (data as User)
return { data: { user }, error: null }
}
export function _ssoResponse(data: any): SSOResponse {
return { data, error: null }
}
export function _generateLinkResponse(data: any): GenerateLinkResponse {
const { action_link, email_otp, hashed_token, redirect_to, verification_type, ...rest } = data
const properties: GenerateLinkProperties = {
action_link,
email_otp,
hashed_token,
redirect_to,
verification_type,
}
const user: User = { ...rest }
return {
data: {
properties,
user,
},
error: null,
}
}
export function _noResolveJsonResponse(data: any): Response {
return data
}
/**
* hasSession checks if the response object contains a valid session
* @param data A response object
* @returns true if a session is in the response
*/
function hasSession(data: any): boolean {
return data.access_token && data.refresh_token && data.expires_in
}

415
node_modules/@supabase/auth-js/src/lib/helpers.ts generated vendored Normal file
View File

@@ -0,0 +1,415 @@
import { API_VERSION_HEADER_NAME, BASE64URL_REGEX } from './constants'
import { AuthInvalidJwtError } from './errors'
import { base64UrlToUint8Array, stringFromBase64URL } from './base64url'
import { JwtHeader, JwtPayload, SupportedStorage, User } from './types'
export function expiresAt(expiresIn: number) {
const timeNow = Math.round(Date.now() / 1000)
return timeNow + expiresIn
}
export function uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0,
v = c == 'x' ? r : (r & 0x3) | 0x8
return v.toString(16)
})
}
export const isBrowser = () => typeof window !== 'undefined' && typeof document !== 'undefined'
const localStorageWriteTests = {
tested: false,
writable: false,
}
/**
* Checks whether localStorage is supported on this browser.
*/
export const supportsLocalStorage = () => {
if (!isBrowser()) {
return false
}
try {
if (typeof globalThis.localStorage !== 'object') {
return false
}
} catch (e) {
// DOM exception when accessing `localStorage`
return false
}
if (localStorageWriteTests.tested) {
return localStorageWriteTests.writable
}
const randomKey = `lswt-${Math.random()}${Math.random()}`
try {
globalThis.localStorage.setItem(randomKey, randomKey)
globalThis.localStorage.removeItem(randomKey)
localStorageWriteTests.tested = true
localStorageWriteTests.writable = true
} catch (e) {
// localStorage can't be written to
// https://www.chromium.org/for-testers/bug-reporting-guidelines/uncaught-securityerror-failed-to-read-the-localstorage-property-from-window-access-is-denied-for-this-document
localStorageWriteTests.tested = true
localStorageWriteTests.writable = false
}
return localStorageWriteTests.writable
}
/**
* Extracts parameters encoded in the URL both in the query and fragment.
*/
export function parseParametersFromURL(href: string) {
const result: { [parameter: string]: string } = {}
const url = new URL(href)
if (url.hash && url.hash[0] === '#') {
try {
const hashSearchParams = new URLSearchParams(url.hash.substring(1))
hashSearchParams.forEach((value, key) => {
result[key] = value
})
} catch (e: any) {
// hash is not a query string
}
}
// search parameters take precedence over hash parameters
url.searchParams.forEach((value, key) => {
result[key] = value
})
return result
}
type Fetch = typeof fetch
export const resolveFetch = (customFetch?: Fetch): Fetch => {
let _fetch: Fetch
if (customFetch) {
_fetch = customFetch
} else if (typeof fetch === 'undefined') {
_fetch = (...args) =>
import('@supabase/node-fetch' as any).then(({ default: fetch }) => fetch(...args))
} else {
_fetch = fetch
}
return (...args) => _fetch(...args)
}
export const looksLikeFetchResponse = (maybeResponse: unknown): maybeResponse is Response => {
return (
typeof maybeResponse === 'object' &&
maybeResponse !== null &&
'status' in maybeResponse &&
'ok' in maybeResponse &&
'json' in maybeResponse &&
typeof (maybeResponse as any).json === 'function'
)
}
// Storage helpers
export const setItemAsync = async (
storage: SupportedStorage,
key: string,
data: any
): Promise<void> => {
await storage.setItem(key, JSON.stringify(data))
}
export const getItemAsync = async (storage: SupportedStorage, key: string): Promise<unknown> => {
const value = await storage.getItem(key)
if (!value) {
return null
}
try {
return JSON.parse(value)
} catch {
return value
}
}
export const removeItemAsync = async (storage: SupportedStorage, key: string): Promise<void> => {
await storage.removeItem(key)
}
/**
* A deferred represents some asynchronous work that is not yet finished, which
* may or may not culminate in a value.
* Taken from: https://github.com/mike-north/types/blob/master/src/async.ts
*/
export class Deferred<T = any> {
public static promiseConstructor: PromiseConstructor = Promise
public readonly promise!: PromiseLike<T>
public readonly resolve!: (value?: T | PromiseLike<T>) => void
public readonly reject!: (reason?: any) => any
public constructor() {
// eslint-disable-next-line @typescript-eslint/no-extra-semi
;(this as any).promise = new Deferred.promiseConstructor((res, rej) => {
// eslint-disable-next-line @typescript-eslint/no-extra-semi
;(this as any).resolve = res
// eslint-disable-next-line @typescript-eslint/no-extra-semi
;(this as any).reject = rej
})
}
}
export function decodeJWT(token: string): {
header: JwtHeader
payload: JwtPayload
signature: Uint8Array
raw: {
header: string
payload: string
}
} {
const parts = token.split('.')
if (parts.length !== 3) {
throw new AuthInvalidJwtError('Invalid JWT structure')
}
// Regex checks for base64url format
for (let i = 0; i < parts.length; i++) {
if (!BASE64URL_REGEX.test(parts[i] as string)) {
throw new AuthInvalidJwtError('JWT not in base64url format')
}
}
const data = {
// using base64url lib
header: JSON.parse(stringFromBase64URL(parts[0])),
payload: JSON.parse(stringFromBase64URL(parts[1])),
signature: base64UrlToUint8Array(parts[2]),
raw: {
header: parts[0],
payload: parts[1],
},
}
return data
}
/**
* Creates a promise that resolves to null after some time.
*/
export async function sleep(time: number): Promise<null> {
return await new Promise((accept) => {
setTimeout(() => accept(null), time)
})
}
/**
* Converts the provided async function into a retryable function. Each result
* or thrown error is sent to the isRetryable function which should return true
* if the function should run again.
*/
export function retryable<T>(
fn: (attempt: number) => Promise<T>,
isRetryable: (attempt: number, error: any | null, result?: T) => boolean
): Promise<T> {
const promise = new Promise<T>((accept, reject) => {
// eslint-disable-next-line @typescript-eslint/no-extra-semi
;(async () => {
for (let attempt = 0; attempt < Infinity; attempt++) {
try {
const result = await fn(attempt)
if (!isRetryable(attempt, null, result)) {
accept(result)
return
}
} catch (e: any) {
if (!isRetryable(attempt, e)) {
reject(e)
return
}
}
}
})()
})
return promise
}
function dec2hex(dec: number) {
return ('0' + dec.toString(16)).substr(-2)
}
// Functions below taken from: https://stackoverflow.com/questions/63309409/creating-a-code-verifier-and-challenge-for-pkce-auth-on-spotify-api-in-reactjs
export function generatePKCEVerifier() {
const verifierLength = 56
const array = new Uint32Array(verifierLength)
if (typeof crypto === 'undefined') {
const charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'
const charSetLen = charSet.length
let verifier = ''
for (let i = 0; i < verifierLength; i++) {
verifier += charSet.charAt(Math.floor(Math.random() * charSetLen))
}
return verifier
}
crypto.getRandomValues(array)
return Array.from(array, dec2hex).join('')
}
async function sha256(randomString: string) {
const encoder = new TextEncoder()
const encodedData = encoder.encode(randomString)
const hash = await crypto.subtle.digest('SHA-256', encodedData)
const bytes = new Uint8Array(hash)
return Array.from(bytes)
.map((c) => String.fromCharCode(c))
.join('')
}
export async function generatePKCEChallenge(verifier: string) {
const hasCryptoSupport =
typeof crypto !== 'undefined' &&
typeof crypto.subtle !== 'undefined' &&
typeof TextEncoder !== 'undefined'
if (!hasCryptoSupport) {
console.warn(
'WebCrypto API is not supported. Code challenge method will default to use plain instead of sha256.'
)
return verifier
}
const hashed = await sha256(verifier)
return btoa(hashed).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
}
export async function getCodeChallengeAndMethod(
storage: SupportedStorage,
storageKey: string,
isPasswordRecovery = false
) {
const codeVerifier = generatePKCEVerifier()
let storedCodeVerifier = codeVerifier
if (isPasswordRecovery) {
storedCodeVerifier += '/PASSWORD_RECOVERY'
}
await setItemAsync(storage, `${storageKey}-code-verifier`, storedCodeVerifier)
const codeChallenge = await generatePKCEChallenge(codeVerifier)
const codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256'
return [codeChallenge, codeChallengeMethod]
}
/** Parses the API version which is 2YYY-MM-DD. */
const API_VERSION_REGEX = /^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[0-1])$/i
export function parseResponseAPIVersion(response: Response) {
const apiVersion = response.headers.get(API_VERSION_HEADER_NAME)
if (!apiVersion) {
return null
}
if (!apiVersion.match(API_VERSION_REGEX)) {
return null
}
try {
const date = new Date(`${apiVersion}T00:00:00.0Z`)
return date
} catch (e: any) {
return null
}
}
export function validateExp(exp: number) {
if (!exp) {
throw new Error('Missing exp claim')
}
const timeNow = Math.floor(Date.now() / 1000)
if (exp <= timeNow) {
throw new Error('JWT has expired')
}
}
export function getAlgorithm(
alg: 'HS256' | 'RS256' | 'ES256'
): RsaHashedImportParams | EcKeyImportParams {
switch (alg) {
case 'RS256':
return {
name: 'RSASSA-PKCS1-v1_5',
hash: { name: 'SHA-256' },
}
case 'ES256':
return {
name: 'ECDSA',
namedCurve: 'P-256',
hash: { name: 'SHA-256' },
}
default:
throw new Error('Invalid alg claim')
}
}
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
export function validateUUID(str: string) {
if (!UUID_REGEX.test(str)) {
throw new Error('@supabase/auth-js: Expected parameter to be UUID but is not')
}
}
export function userNotAvailableProxy(): User {
const proxyTarget = {} as User
return new Proxy(proxyTarget, {
get: (target: any, prop: string) => {
if (prop === '__isUserNotAvailableProxy') {
return true
}
// Preventative check for common problematic symbols during cloning/inspection
// These symbols might be accessed by structuredClone or other internal mechanisms.
if (typeof prop === 'symbol') {
const sProp = (prop as symbol).toString()
if (
sProp === 'Symbol(Symbol.toPrimitive)' ||
sProp === 'Symbol(Symbol.toStringTag)' ||
sProp === 'Symbol(util.inspect.custom)'
) {
// Node.js util.inspect
return undefined
}
}
throw new Error(
`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Accessing the "${prop}" property of the session object is not supported. Please use getUser() instead.`
)
},
set: (_target: any, prop: string) => {
throw new Error(
`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Setting the "${prop}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`
)
},
deleteProperty: (_target: any, prop: string) => {
throw new Error(
`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Deleting the "${prop}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`
)
},
})
}
/**
* Deep clones a JSON-serializable object using JSON.parse(JSON.stringify(obj)).
* Note: Only works for JSON-safe data.
*/
export function deepClone<T>(obj: T): T {
return JSON.parse(JSON.stringify(obj))
}

View File

@@ -0,0 +1,21 @@
import { SupportedStorage } from './types'
/**
* Returns a localStorage-like object that stores the key-value pairs in
* memory.
*/
export function memoryLocalStorageAdapter(store: { [key: string]: string } = {}): SupportedStorage {
return {
getItem: (key) => {
return store[key] || null
},
setItem: (key, value) => {
store[key] = value
},
removeItem: (key) => {
delete store[key]
},
}
}

225
node_modules/@supabase/auth-js/src/lib/locks.ts generated vendored Normal file
View File

@@ -0,0 +1,225 @@
import { supportsLocalStorage } from './helpers'
/**
* @experimental
*/
export const internals = {
/**
* @experimental
*/
debug: !!(
globalThis &&
supportsLocalStorage() &&
globalThis.localStorage &&
globalThis.localStorage.getItem('supabase.gotrue-js.locks.debug') === 'true'
),
}
/**
* An error thrown when a lock cannot be acquired after some amount of time.
*
* Use the {@link #isAcquireTimeout} property instead of checking with `instanceof`.
*/
export abstract class LockAcquireTimeoutError extends Error {
public readonly isAcquireTimeout = true
constructor(message: string) {
super(message)
}
}
export class NavigatorLockAcquireTimeoutError extends LockAcquireTimeoutError {}
export class ProcessLockAcquireTimeoutError extends LockAcquireTimeoutError {}
/**
* Implements a global exclusive lock using the Navigator LockManager API. It
* is available on all browsers released after 2022-03-15 with Safari being the
* last one to release support. If the API is not available, this function will
* throw. Make sure you check availablility before configuring {@link
* GoTrueClient}.
*
* You can turn on debugging by setting the `supabase.gotrue-js.locks.debug`
* local storage item to `true`.
*
* Internals:
*
* Since the LockManager API does not preserve stack traces for the async
* function passed in the `request` method, a trick is used where acquiring the
* lock releases a previously started promise to run the operation in the `fn`
* function. The lock waits for that promise to finish (with or without error),
* while the function will finally wait for the result anyway.
*
* @param name Name of the lock to be acquired.
* @param acquireTimeout If negative, no timeout. If 0 an error is thrown if
* the lock can't be acquired without waiting. If positive, the lock acquire
* will time out after so many milliseconds. An error is
* a timeout if it has `isAcquireTimeout` set to true.
* @param fn The operation to run once the lock is acquired.
*/
export async function navigatorLock<R>(
name: string,
acquireTimeout: number,
fn: () => Promise<R>
): Promise<R> {
if (internals.debug) {
console.log('@supabase/gotrue-js: navigatorLock: acquire lock', name, acquireTimeout)
}
const abortController = new globalThis.AbortController()
if (acquireTimeout > 0) {
setTimeout(() => {
abortController.abort()
if (internals.debug) {
console.log('@supabase/gotrue-js: navigatorLock acquire timed out', name)
}
}, acquireTimeout)
}
// MDN article: https://developer.mozilla.org/en-US/docs/Web/API/LockManager/request
// Wrapping navigator.locks.request() with a plain Promise is done as some
// libraries like zone.js patch the Promise object to track the execution
// context. However, it appears that most browsers use an internal promise
// implementation when using the navigator.locks.request() API causing them
// to lose context and emit confusing log messages or break certain features.
// This wrapping is believed to help zone.js track the execution context
// better.
return await Promise.resolve().then(() =>
globalThis.navigator.locks.request(
name,
acquireTimeout === 0
? {
mode: 'exclusive',
ifAvailable: true,
}
: {
mode: 'exclusive',
signal: abortController.signal,
},
async (lock) => {
if (lock) {
if (internals.debug) {
console.log('@supabase/gotrue-js: navigatorLock: acquired', name, lock.name)
}
try {
return await fn()
} finally {
if (internals.debug) {
console.log('@supabase/gotrue-js: navigatorLock: released', name, lock.name)
}
}
} else {
if (acquireTimeout === 0) {
if (internals.debug) {
console.log('@supabase/gotrue-js: navigatorLock: not immediately available', name)
}
throw new NavigatorLockAcquireTimeoutError(
`Acquiring an exclusive Navigator LockManager lock "${name}" immediately failed`
)
} else {
if (internals.debug) {
try {
const result = await globalThis.navigator.locks.query()
console.log(
'@supabase/gotrue-js: Navigator LockManager state',
JSON.stringify(result, null, ' ')
)
} catch (e: any) {
console.warn(
'@supabase/gotrue-js: Error when querying Navigator LockManager state',
e
)
}
}
// Browser is not following the Navigator LockManager spec, it
// returned a null lock when we didn't use ifAvailable. So we can
// pretend the lock is acquired in the name of backward compatibility
// and user experience and just run the function.
console.warn(
'@supabase/gotrue-js: Navigator LockManager returned a null lock when using #request without ifAvailable set to true, it appears this browser is not following the LockManager spec https://developer.mozilla.org/en-US/docs/Web/API/LockManager/request'
)
return await fn()
}
}
}
)
)
}
const PROCESS_LOCKS: { [name: string]: Promise<any> } = {}
/**
* Implements a global exclusive lock that works only in the current process.
* Useful for environments like React Native or other non-browser
* single-process (i.e. no concept of "tabs") environments.
*
* Use {@link #navigatorLock} in browser environments.
*
* @param name Name of the lock to be acquired.
* @param acquireTimeout If negative, no timeout. If 0 an error is thrown if
* the lock can't be acquired without waiting. If positive, the lock acquire
* will time out after so many milliseconds. An error is
* a timeout if it has `isAcquireTimeout` set to true.
* @param fn The operation to run once the lock is acquired.
*/
export async function processLock<R>(
name: string,
acquireTimeout: number,
fn: () => Promise<R>
): Promise<R> {
const previousOperation = PROCESS_LOCKS[name] ?? Promise.resolve()
const currentOperation = Promise.race(
[
previousOperation.catch(() => {
// ignore error of previous operation that we're waiting to finish
return null
}),
acquireTimeout >= 0
? new Promise((_, reject) => {
setTimeout(() => {
reject(
new ProcessLockAcquireTimeoutError(
`Acquring process lock with name "${name}" timed out`
)
)
}, acquireTimeout)
})
: null,
].filter((x) => x)
)
.catch((e: any) => {
if (e && e.isAcquireTimeout) {
throw e
}
return null
})
.then(async () => {
// previous operations finished and we didn't get a race on the acquire
// timeout, so the current operation can finally start
return await fn()
})
PROCESS_LOCKS[name] = currentOperation.catch(async (e: any) => {
if (e && e.isAcquireTimeout) {
// if the current operation timed out, it doesn't mean that the previous
// operation finished, so we need contnue waiting for it to finish
await previousOperation
return null
}
throw e
})
// finally wait for the current operation to finish successfully, with an
// error or with an acquire timeout error
return await currentOperation
}

23
node_modules/@supabase/auth-js/src/lib/polyfills.ts generated vendored Normal file
View File

@@ -0,0 +1,23 @@
/**
* https://mathiasbynens.be/notes/globalthis
*/
export function polyfillGlobalThis() {
if (typeof globalThis === 'object') return
try {
Object.defineProperty(Object.prototype, '__magic__', {
get: function () {
return this
},
configurable: true,
})
// @ts-expect-error 'Allow access to magic'
__magic__.globalThis = __magic__
// @ts-expect-error 'Allow access to magic'
delete Object.prototype.__magic__
} catch (e) {
if (typeof self !== 'undefined') {
// @ts-expect-error 'Allow access to globals'
self.globalThis = self
}
}
}

186
node_modules/@supabase/auth-js/src/lib/solana.ts generated vendored Normal file
View File

@@ -0,0 +1,186 @@
// types copied over from @solana/wallet-standard-features and @wallet-standard/base so this library doesn't depend on them
/**
* A namespaced identifier in the format `${namespace}:${reference}`.
*
* Used by {@link IdentifierArray} and {@link IdentifierRecord}.
*
* @group Identifier
*/
export type IdentifierString = `${string}:${string}`
/**
* A read-only array of namespaced identifiers in the format `${namespace}:${reference}`.
*
* Used by {@link Wallet.chains | Wallet::chains}, {@link WalletAccount.chains | WalletAccount::chains}, and
* {@link WalletAccount.features | WalletAccount::features}.
*
* @group Identifier
*/
export type IdentifierArray = readonly IdentifierString[]
/**
* Version of the Wallet Standard implemented by a {@link Wallet}.
*
* Used by {@link Wallet.version | Wallet::version}.
*
* Note that this is _NOT_ a version of the Wallet, but a version of the Wallet Standard itself that the Wallet
* supports.
*
* This may be used by the app to determine compatibility and feature detect.
*
* @group Wallet
*/
export type WalletVersion = '1.0.0'
/**
* A data URI containing a base64-encoded SVG, WebP, PNG, or GIF image.
*
* Used by {@link Wallet.icon | Wallet::icon} and {@link WalletAccount.icon | WalletAccount::icon}.
*
* @group Wallet
*/
export type WalletIcon = `data:image/${'svg+xml' | 'webp' | 'png' | 'gif'};base64,${string}`
/**
* Interface of a **WalletAccount**, also referred to as an **Account**.
*
* An account is a _read-only data object_ that is provided from the Wallet to the app, authorizing the app to use it.
*
* The app can use an account to display and query information from a chain.
*
* The app can also act using an account by passing it to {@link Wallet.features | features} of the Wallet.
*
* Wallets may use or extend {@link "@wallet-standard/wallet".ReadonlyWalletAccount} which implements this interface.
*
* @group Wallet
*/
export interface WalletAccount {
/** Address of the account, corresponding with a public key. */
readonly address: string
/** Public key of the account, corresponding with a secret key to use. */
readonly publicKey: Uint8Array
/**
* Chains supported by the account.
*
* This must be a subset of the {@link Wallet.chains | chains} of the Wallet.
*/
readonly chains: IdentifierArray
/**
* Feature names supported by the account.
*
* This must be a subset of the names of {@link Wallet.features | features} of the Wallet.
*/
readonly features: IdentifierArray
/** Optional user-friendly descriptive label or name for the account. This may be displayed by the app. */
readonly label?: string
/** Optional user-friendly icon for the account. This may be displayed by the app. */
readonly icon?: WalletIcon
}
/** Input for signing in. */
export interface SolanaSignInInput {
/**
* Optional EIP-4361 Domain.
* If not provided, the wallet must determine the Domain to include in the message.
*/
readonly domain?: string
/**
* Optional EIP-4361 Address.
* If not provided, the wallet must determine the Address to include in the message.
*/
readonly address?: string
/**
* Optional EIP-4361 Statement.
* If not provided, the wallet must not include Statement in the message.
*/
readonly statement?: string
/**
* Optional EIP-4361 URI.
* If not provided, the wallet must not include URI in the message.
*/
readonly uri?: string
/**
* Optional EIP-4361 Version.
* If not provided, the wallet must not include Version in the message.
*/
readonly version?: string
/**
* Optional EIP-4361 Chain ID.
* If not provided, the wallet must not include Chain ID in the message.
*/
readonly chainId?: string
/**
* Optional EIP-4361 Nonce.
* If not provided, the wallet must not include Nonce in the message.
*/
readonly nonce?: string
/**
* Optional EIP-4361 Issued At.
* If not provided, the wallet must not include Issued At in the message.
*/
readonly issuedAt?: string
/**
* Optional EIP-4361 Expiration Time.
* If not provided, the wallet must not include Expiration Time in the message.
*/
readonly expirationTime?: string
/**
* Optional EIP-4361 Not Before.
* If not provided, the wallet must not include Not Before in the message.
*/
readonly notBefore?: string
/**
* Optional EIP-4361 Request ID.
* If not provided, the wallet must not include Request ID in the message.
*/
readonly requestId?: string
/**
* Optional EIP-4361 Resources.
* If not provided, the wallet must not include Resources in the message.
*/
readonly resources?: readonly string[]
}
/** Output of signing in. */
export interface SolanaSignInOutput {
/**
* Account that was signed in.
* The address of the account may be different from the provided input Address.
*/
readonly account: WalletAccount
/**
* Message bytes that were signed.
* The wallet may prefix or otherwise modify the message before signing it.
*/
readonly signedMessage: Uint8Array
/**
* Message signature produced.
* If the signature type is provided, the signature must be Ed25519.
*/
readonly signature: Uint8Array
/**
* Optional type of the message signature produced.
* If not provided, the signature must be Ed25519.
*/
readonly signatureType?: 'ed25519'
}

1297
node_modules/@supabase/auth-js/src/lib/types.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/@supabase/auth-js/src/lib/version.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export const version = '2.71.1'