@clerk/shared 4.29.3-snapshot.v20260819182138 → 4.29.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{error-Br1l1pdF.mjs → error-DRCZN5DP.mjs} +13 -7
- package/dist/_chunks/error-DRCZN5DP.mjs.map +1 -0
- package/dist/_chunks/{error-BmCE2eHg.js → error-DiOD3e6d.js} +13 -7
- package/dist/_chunks/error-DiOD3e6d.js.map +1 -0
- package/dist/error.js +1 -1
- package/dist/error.mjs +1 -1
- package/dist/errors/errorThrower.d.mts +3 -3
- package/dist/errors/errorThrower.d.ts +3 -3
- package/dist/errors/errorThrower.js +12 -6
- package/dist/internal/clerk-js/passkeys.js +1 -1
- package/dist/internal/clerk-js/passkeys.mjs +1 -1
- package/dist/internal/clerk-js/protectCheck.js +1 -1
- package/dist/internal/clerk-js/protectCheck.mjs +1 -1
- package/dist/internal/clerk-js/web3.js +1 -1
- package/dist/internal/clerk-js/web3.mjs +1 -1
- package/dist/keys.js +4 -2
- package/dist/keys.js.map +1 -1
- package/dist/keys.mjs +4 -2
- package/dist/keys.mjs.map +1 -1
- package/dist/loadClerkJsScript.js +2 -2
- package/dist/loadClerkJsScript.js.map +1 -1
- package/dist/loadClerkJsScript.mjs +2 -2
- package/dist/loadClerkJsScript.mjs.map +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/index.mjs +1 -1
- package/dist/versionSelector.js +1 -1
- package/dist/versionSelector.js.map +1 -1
- package/dist/versionSelector.mjs +1 -1
- package/dist/versionSelector.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/_chunks/error-BmCE2eHg.js.map +0 -1
- package/dist/_chunks/error-Br1l1pdF.mjs.map +0 -1
|
@@ -218,21 +218,27 @@ var ClerkOfflineError = class ClerkOfflineError extends ClerkRuntimeError {
|
|
|
218
218
|
//#region src/errors/errorThrower.ts
|
|
219
219
|
const DefaultMessages = Object.freeze({
|
|
220
220
|
InvalidProxyUrlErrorMessage: `The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})`,
|
|
221
|
-
InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, run:
|
|
221
|
+
InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, in your terminal run:
|
|
222
222
|
|
|
223
223
|
npx clerk@latest init
|
|
224
224
|
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
It creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.
|
|
226
|
+
|
|
227
|
+
If you have a Clerk application, run \`npx clerk@latest env pull\` to write the keys (\`--instance prod\` for production keys). Or copy its Publishable key from https://dashboard.clerk.com/last-active?path=api-keys.`,
|
|
228
|
+
MissingPublishableKeyErrorMessage: `Missing publishableKey. To set up Clerk for this project, in your terminal run:
|
|
227
229
|
|
|
228
230
|
npx clerk@latest init
|
|
229
231
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
+
It creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.
|
|
233
|
+
|
|
234
|
+
If you have a Clerk application, run \`npx clerk@latest env pull\` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running \`npx clerk@latest deploy\`, or \`npx clerk@latest env pull --instance prod\` to use an existing one.`,
|
|
235
|
+
MissingSecretKeyErrorMessage: `Missing secretKey. To set up Clerk for this project, in your terminal run:
|
|
232
236
|
|
|
233
237
|
npx clerk@latest init
|
|
234
238
|
|
|
235
|
-
|
|
239
|
+
It creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.
|
|
240
|
+
|
|
241
|
+
If you have a Clerk application, run \`npx clerk@latest env pull\` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running \`npx clerk@latest deploy\`, or \`npx clerk@latest env pull --instance prod\` to use an existing one.`,
|
|
236
242
|
MissingClerkProvider: `{{source}} can only be used within the <ClerkProvider /> component. Learn more: https://clerk.com/docs/components/clerk-provider`
|
|
237
243
|
});
|
|
238
244
|
/**
|
|
@@ -473,4 +479,4 @@ function createClerkGlobalHookError(error) {
|
|
|
473
479
|
|
|
474
480
|
//#endregion
|
|
475
481
|
export { isClerkAPIResponseError as C, ClerkAPIError as D, parseErrors as E, isClerkAPIError as O, ClerkAPIResponseError as S, parseError as T, EmailLinkErrorCode as _, isEmailLinkError as a, ClerkOfflineError as b, isNetworkError as c, isReverificationCancelledError as d, isUnauthenticatedError as f, EmailLinkError as g, ClerkWebAuthnError as h, isCaptchaError as i, isPasswordCompromisedError as l, isUserLockedError as m, is429Error as n, isKnownError as o, isUnauthorizedError as p, is4xxError as r, isMetamaskError as s, createClerkGlobalHookError as t, isPasswordPwnedError as u, EmailLinkErrorCodeStatus as v, errorToJSON as w, MissingExpiredTokenError as x, buildErrorThrower as y };
|
|
476
|
-
//# sourceMappingURL=error-
|
|
482
|
+
//# sourceMappingURL=error-DRCZN5DP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-DRCZN5DP.mjs","names":[],"sources":["../../src/errors/clerkApiError.ts","../../src/errors/parseError.ts","../../src/errors/clerkApiResponseError.ts","../../src/errors/missingExpiredTokenError.ts","../../src/errors/clerkOfflineError.ts","../../src/errors/errorThrower.ts","../../src/errors/emailLinkError.ts","../../src/errors/webAuthNError.ts","../../src/errors/helpers.ts","../../src/errors/globalHookError.ts"],"sourcesContent":["import type { ClerkAPIError as ClerkAPIErrorInterface, ClerkAPIErrorJSON } from '../types';\nimport { createErrorTypeGuard } from './createErrorTypeGuard';\n\nexport type ClerkAPIErrorMeta = Record<string, unknown>;\n\n/**\n * This error contains the specific error message, code, and any additional metadata that was returned by the Clerk API.\n */\nexport class ClerkAPIError<Meta extends ClerkAPIErrorMeta = any> implements ClerkAPIErrorInterface {\n static kind = 'ClerkAPIError';\n readonly code: string;\n readonly message: string;\n readonly longMessage: string | undefined;\n readonly meta: Meta;\n\n constructor(json: ClerkAPIErrorJSON) {\n const parsedError = {\n code: json.code,\n message: json.message,\n longMessage: json.long_message,\n meta: {\n paramName: json.meta?.param_name,\n sessionId: json.meta?.session_id,\n emailAddresses: json.meta?.email_addresses,\n identifiers: json.meta?.identifiers,\n zxcvbn: json.meta?.zxcvbn,\n plan: json.meta?.plan,\n isPlanUpgradePossible: json.meta?.is_plan_upgrade_possible,\n seatsQuantityToAdd: json.meta?.seats_quantity_to_add,\n seatsQuantity: json.meta?.seats_quantity,\n } as unknown as Meta,\n };\n this.code = parsedError.code;\n this.message = parsedError.message;\n this.longMessage = parsedError.longMessage;\n this.meta = parsedError.meta;\n }\n}\n\n/**\n * Type guard to check if a value is a ClerkAPIError instance.\n */\nexport const isClerkAPIError = createErrorTypeGuard(ClerkAPIError);\n","import type { ClerkAPIError as ClerkAPIErrorInterface, ClerkAPIErrorJSON } from '../types';\nimport { ClerkAPIError } from './clerkApiError';\n\n/**\n * Parses an array of ClerkAPIErrorJSON objects into an array of ClerkAPIError objects.\n *\n * @internal\n */\nexport function parseErrors(data: ClerkAPIErrorJSON[] = []): ClerkAPIErrorInterface[] {\n return data.length > 0 ? data.map(e => new ClerkAPIError(e)) : [];\n}\n\n/**\n * Parses a ClerkAPIErrorJSON object into a ClerkAPIError object.\n *\n * @deprecated Use `ClerkAPIError` class instead\n *\n * @internal\n */\nexport function parseError(error: ClerkAPIErrorJSON): ClerkAPIErrorInterface {\n return new ClerkAPIError(error);\n}\n\n/**\n * Converts a ClerkAPIError object into a ClerkAPIErrorJSON object.\n *\n * @internal\n */\nexport function errorToJSON(error: ClerkAPIError | null): ClerkAPIErrorJSON {\n return {\n code: error?.code || '',\n message: error?.message || '',\n long_message: error?.longMessage,\n meta: {\n param_name: error?.meta?.paramName,\n session_id: error?.meta?.sessionId,\n email_addresses: error?.meta?.emailAddresses,\n identifiers: error?.meta?.identifiers,\n zxcvbn: error?.meta?.zxcvbn,\n plan: error?.meta?.plan,\n is_plan_upgrade_possible: error?.meta?.isPlanUpgradePossible,\n seats_quantity_to_add: error?.meta?.seatsQuantityToAdd,\n seats_quantity: error?.meta?.seatsQuantity,\n },\n };\n}\n","import type { ClerkAPIErrorJSON, ClerkAPIResponseError as ClerkAPIResponseErrorInterface } from '../types';\nimport { ClerkAPIError } from './clerkApiError';\nimport type { ClerkErrorParams } from './clerkError';\nimport { ClerkError } from './clerkError';\nimport { createErrorTypeGuard } from './createErrorTypeGuard';\n\ninterface ClerkAPIResponseOptions extends Omit<ClerkErrorParams, 'message' | 'code'> {\n data: ClerkAPIErrorJSON[];\n status: number;\n clerkTraceId?: string;\n retryAfter?: number;\n}\n\nexport class ClerkAPIResponseError extends ClerkError implements ClerkAPIResponseErrorInterface {\n static kind = 'ClerkAPIResponseError';\n status: number;\n clerkTraceId?: string;\n retryAfter?: number;\n errors: ClerkAPIError[];\n\n constructor(message: string, options: ClerkAPIResponseOptions) {\n const { data: errorsJson, status, clerkTraceId, retryAfter } = options;\n super({ ...options, message, code: 'api_response_error' });\n Object.setPrototypeOf(this, ClerkAPIResponseError.prototype);\n this.status = status;\n this.clerkTraceId = clerkTraceId;\n this.retryAfter = retryAfter;\n this.errors = (errorsJson || []).map(e => new ClerkAPIError(e));\n }\n\n public toString() {\n let message = `[${this.name}]\\nMessage:${this.message}\\nStatus:${this.status}\\nSerialized errors: ${this.errors.map(\n e => JSON.stringify(e),\n )}`;\n\n if (this.clerkTraceId) {\n message += `\\nClerk Trace ID: ${this.clerkTraceId}`;\n }\n\n return message;\n }\n\n // Override formatMessage to keep it unformatted for backward compatibility\n protected static override formatMessage(name: string, msg: string, _: string, __: string | undefined) {\n return msg;\n }\n}\n\n/**\n * Type guard to check if an error is a ClerkAPIResponseError.\n * Can be called as a standalone function or as a method on an error object.\n *\n * @example\n * // As a standalone function\n * if (isClerkAPIResponseError(error)) { ... }\n *\n * // As a method (when attached to error object)\n * if (error.isClerkAPIResponseError()) { ... }\n */\nexport const isClerkAPIResponseError = createErrorTypeGuard(ClerkAPIResponseError);\n","import { ClerkAPIResponseError, isClerkAPIResponseError } from './clerkApiResponseError';\n\n/**\n * Error class representing a missing expired token error from the API.\n * This error occurs when the server requires an expired token to mint a new session token.\n *\n * Use the static `is` method to check if a ClerkAPIResponseError matches this error type.\n *\n * @example\n * ```typescript\n * if (MissingExpiredTokenError.is(error)) {\n * // Handle the missing expired token error\n * }\n * ```\n */\nexport class MissingExpiredTokenError extends ClerkAPIResponseError {\n static kind = 'MissingExpiredTokenError';\n static readonly ERROR_CODE = 'missing_expired_token' as const;\n static readonly STATUS = 422 as const;\n\n /**\n * Type guard to check if an error is a MissingExpiredTokenError.\n * This checks the error's properties (status and error code) rather than instanceof,\n * allowing it to work with ClerkAPIResponseError instances thrown from the API layer.\n *\n * @example\n * ```typescript\n * try {\n * await someApiCall();\n * } catch (e) {\n * if (MissingExpiredTokenError.is(e)) {\n * // e is typed as ClerkAPIResponseError with the specific error properties\n * }\n * }\n * ```\n */\n static is(err: unknown): err is ClerkAPIResponseError {\n return (\n isClerkAPIResponseError(err) &&\n err.status === MissingExpiredTokenError.STATUS &&\n err.errors.length > 0 &&\n err.errors[0].code === MissingExpiredTokenError.ERROR_CODE\n );\n }\n}\n","import { ClerkRuntimeError, isClerkRuntimeError } from './clerkRuntimeError';\n\n/**\n * Error thrown when a network request fails due to the client being offline.\n *\n * This error is thrown instead of returning `null` to make it explicit that\n * the failure was due to network conditions, not authentication state.\n *\n * @example\n * ```typescript\n * try {\n * const token = await session.getToken();\n * } catch (error) {\n * if (ClerkOfflineError.is(error)) {\n * // Handle offline scenario\n * showOfflineScreen();\n * }\n * }\n * ```\n */\nexport class ClerkOfflineError extends ClerkRuntimeError {\n static kind = 'ClerkOfflineError';\n static readonly ERROR_CODE = 'clerk_offline' as const;\n\n constructor(message: string) {\n super(message, { code: ClerkOfflineError.ERROR_CODE });\n Object.setPrototypeOf(this, ClerkOfflineError.prototype);\n }\n\n /**\n * Type guard to check if an error is a ClerkOfflineError.\n * This checks both instanceof and the error code to support cross-bundle/cross-realm errors\n *\n * @example\n * ```typescript\n * try {\n * const token = await session.getToken();\n * } catch (error) {\n * if (ClerkOfflineError.is(error)) {\n * // error is typed as ClerkOfflineError\n * console.log('User is offline');\n * }\n * }\n * ```\n */\n static is(error: unknown): error is ClerkOfflineError {\n if (error === null || error === undefined) {\n return false;\n }\n return (\n error instanceof ClerkOfflineError || (isClerkRuntimeError(error) && error.code === ClerkOfflineError.ERROR_CODE)\n );\n }\n}\n","const DefaultMessages = Object.freeze({\n InvalidProxyUrlErrorMessage: `The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})`,\n InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run \\`npx clerk@latest env pull\\` to write the keys (\\`--instance prod\\` for production keys). Or copy its Publishable key from https://dashboard.clerk.com/last-active?path=api-keys.`,\n MissingPublishableKeyErrorMessage: `Missing publishableKey. To set up Clerk for this project, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run \\`npx clerk@latest env pull\\` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running \\`npx clerk@latest deploy\\`, or \\`npx clerk@latest env pull --instance prod\\` to use an existing one.`,\n MissingSecretKeyErrorMessage: `Missing secretKey. To set up Clerk for this project, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run \\`npx clerk@latest env pull\\` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running \\`npx clerk@latest deploy\\`, or \\`npx clerk@latest env pull --instance prod\\` to use an existing one.`,\n MissingClerkProvider: `{{source}} can only be used within the <ClerkProvider /> component. Learn more: https://clerk.com/docs/components/clerk-provider`,\n});\n\ntype MessageKeys = keyof typeof DefaultMessages;\n\ntype Messages = Record<MessageKeys, string>;\n\ntype CustomMessages = Partial<Messages>;\n\nexport type ErrorThrowerOptions = {\n packageName: string;\n customMessages?: CustomMessages;\n};\n\nexport interface ErrorThrower {\n setPackageName(options: ErrorThrowerOptions): ErrorThrower;\n\n setMessages(options: ErrorThrowerOptions): ErrorThrower;\n\n throwInvalidPublishableKeyError(params: { key?: string }): never;\n\n throwInvalidProxyUrl(params: { url?: string }): never;\n\n throwMissingPublishableKeyError(): never;\n\n throwMissingSecretKeyError(): never;\n\n throwMissingClerkProviderError(params: { source?: string }): never;\n\n throw(message: string): never;\n}\n\n/**\n * Builds an error thrower.\n *\n * @internal\n */\nexport function buildErrorThrower({ packageName, customMessages }: ErrorThrowerOptions): ErrorThrower {\n let pkg = packageName;\n\n /**\n * Builds a message from a raw message and replacements.\n *\n * @internal\n */\n function buildMessage(rawMessage: string, replacements?: Record<string, string | number>) {\n if (!replacements) {\n return `${pkg}: ${rawMessage}`;\n }\n\n let msg = rawMessage;\n const matches = rawMessage.matchAll(/{{([a-zA-Z0-9-_]+)}}/g);\n\n for (const match of matches) {\n const replacement = (replacements[match[1]] || '').toString();\n msg = msg.replace(`{{${match[1]}}}`, replacement);\n }\n\n return `${pkg}: ${msg}`;\n }\n\n const messages = {\n ...DefaultMessages,\n ...customMessages,\n };\n\n return {\n setPackageName({ packageName }: ErrorThrowerOptions): ErrorThrower {\n if (typeof packageName === 'string') {\n pkg = packageName;\n }\n return this;\n },\n\n setMessages({ customMessages }: ErrorThrowerOptions): ErrorThrower {\n Object.assign(messages, customMessages || {});\n return this;\n },\n\n throwInvalidPublishableKeyError(params: { key?: string }): never {\n throw new Error(buildMessage(messages.InvalidPublishableKeyErrorMessage, params));\n },\n\n throwInvalidProxyUrl(params: { url?: string }): never {\n throw new Error(buildMessage(messages.InvalidProxyUrlErrorMessage, params));\n },\n\n throwMissingPublishableKeyError(): never {\n throw new Error(buildMessage(messages.MissingPublishableKeyErrorMessage));\n },\n\n throwMissingSecretKeyError(): never {\n throw new Error(buildMessage(messages.MissingSecretKeyErrorMessage));\n },\n\n throwMissingClerkProviderError(params: { source?: string }): never {\n throw new Error(buildMessage(messages.MissingClerkProvider, params));\n },\n\n throw(message: string): never {\n throw new Error(buildMessage(message));\n },\n };\n}\n","export class EmailLinkError extends Error {\n code: string;\n\n constructor(code: string) {\n super(code);\n this.code = code;\n this.name = 'EmailLinkError' as const;\n Object.setPrototypeOf(this, EmailLinkError.prototype);\n }\n}\n\n/**\n * @deprecated Use `EmailLinkErrorCodeStatus` instead.\n *\n * @internal\n */\nexport const EmailLinkErrorCode = {\n Expired: 'expired',\n Failed: 'failed',\n ClientMismatch: 'client_mismatch',\n};\n\nexport const EmailLinkErrorCodeStatus = {\n Expired: 'expired',\n Failed: 'failed',\n ClientMismatch: 'client_mismatch',\n} as const;\n","import type { ClerkErrorParams } from './clerkError';\nimport { ClerkRuntimeError } from './clerkRuntimeError';\n\ntype ClerkWebAuthnErrorCode =\n // Generic\n | 'passkey_not_supported'\n | 'passkey_pa_not_supported'\n | 'passkey_invalid_rpID_or_domain'\n | 'passkey_already_exists'\n | 'passkey_operation_aborted'\n // Retrieval\n | 'passkey_retrieval_cancelled'\n | 'passkey_retrieval_failed'\n // Registration\n | 'passkey_registration_cancelled'\n | 'passkey_registration_failed';\n\ntype ClerkWebAuthnErrorOptions = Omit<ClerkErrorParams, 'message' | 'code'> & { code: ClerkWebAuthnErrorCode };\n\nexport class ClerkWebAuthnError extends ClerkRuntimeError {\n /**\n * A unique code identifying the error, can be used for localization.\n */\n code: ClerkWebAuthnErrorCode;\n\n constructor(message: string, options: ClerkWebAuthnErrorOptions) {\n super(message, options);\n this.code = options.code;\n }\n}\n","import type { ClerkAPIResponseError } from './clerkApiResponseError';\nimport { isClerkAPIResponseError } from './clerkApiResponseError';\nimport type { ClerkRuntimeError } from './clerkRuntimeError';\nimport { isClerkRuntimeError } from './clerkRuntimeError';\nimport type { EmailLinkError } from './emailLinkError';\nimport type { MetamaskError } from './metamaskError';\n\n/**\n * Checks if the provided error object is an unauthorized error.\n *\n * @internal\n *\n * @deprecated This is no longer used, and will be removed in the next major version.\n */\nexport function isUnauthorizedError(e: any): boolean {\n const status = e?.status;\n const code = e?.errors?.[0]?.code;\n return code === 'authentication_invalid' && status === 401;\n}\n\n/**\n * Checks if the provided error object is a captcha error.\n *\n * @internal\n */\nexport function isCaptchaError(e: ClerkAPIResponseError): boolean {\n return ['captcha_invalid', 'captcha_not_enabled', 'captcha_missing_token'].includes(e.errors[0].code);\n}\n\n/**\n * Checks if the provided error is a 4xx error.\n *\n * @internal\n */\nexport function is4xxError(e: any): boolean {\n const status = e?.status;\n return !!status && status >= 400 && status < 500;\n}\n\n/**\n * Checks if the provided error is a 429 (Too Many Requests) error.\n *\n * @internal\n */\nexport function is429Error(e: any): boolean {\n return e?.status === 429;\n}\n\nconst unauthenticated403ErrorCodes = new Set(['user_banned', 'user_deactivated']);\n\n/**\n * Checks if the provided error indicates the user's session is no longer valid\n * and should trigger the unauthenticated flow (e.g. sign-out / redirect to sign-in).\n *\n * Only matches explicit authentication failure status codes:\n * - 401: session is invalid or expired\n * - 422: invalid session state (e.g. missing_expired_token)\n * - 403: terminal user state (e.g. user_banned, user_deactivated)\n *\n * 404 is intentionally excluded despite being returned for \"session not found\",\n * because it's also returned for unrelated resources (org not found, JWT template\n * not found) and shares the same `resource_not_found` error code, making it\n * impossible to distinguish. Session-not-found 401s are already handled directly\n * by Base._fetch.\n *\n * @internal\n */\nexport function isUnauthenticatedError(e: any): boolean {\n const status = e?.status;\n const hasTerminalUserErrorCode =\n Array.isArray(e?.errors) && e.errors.some((error: any) => unauthenticated403ErrorCodes.has(error?.code));\n\n return status === 401 || status === 422 || (status === 403 && hasTerminalUserErrorCode);\n}\n\n/**\n * Checks if the provided error is a network error.\n *\n * @internal\n */\nexport function isNetworkError(e: any): boolean {\n // TODO: revise during error handling epic\n const message = (`${e.message}${e.name}` || '').toLowerCase().replace(/\\s+/g, '');\n return message.includes('networkerror');\n}\n\n/**\n * Checks if the provided error is either a ClerkAPIResponseError, a ClerkRuntimeError, or a MetamaskError.\n */\nexport function isKnownError(error: any): error is ClerkAPIResponseError | ClerkRuntimeError | MetamaskError {\n return isClerkAPIResponseError(error) || isMetamaskError(error) || isClerkRuntimeError(error);\n}\n\n/**\n * Checks if the provided error is a Clerk runtime error indicating a reverification was cancelled.\n */\nexport function isReverificationCancelledError(err: any) {\n return isClerkRuntimeError(err) && err.code === 'reverification_cancelled';\n}\n\n/**\n * Checks if the provided error is a Metamask error.\n */\nexport function isMetamaskError(err: any): err is MetamaskError {\n return 'code' in err && [4001, 32602, 32603].includes(err.code) && 'message' in err;\n}\n\n/**\n * Checks if the provided error is clerk api response error indicating a user is locked.\n */\nexport function isUserLockedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'user_locked';\n}\n\n/**\n * Checks if the provided error is a clerk api response error indicating a password was pwned.\n *\n * @internal\n */\nexport function isPasswordPwnedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'form_password_pwned';\n}\n\n/**\n * Checks if the provided error is a clerk api response error indicating a password was compromised.\n *\n * @internal\n */\nexport function isPasswordCompromisedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'form_password_compromised';\n}\n\n/**\n * Checks if the provided error is an EmailLinkError.\n */\nexport function isEmailLinkError(err: Error): err is EmailLinkError {\n return err.name === 'EmailLinkError';\n}\n","import { isClerkAPIResponseError } from './clerkApiResponseError';\nimport type { ClerkError } from './clerkError';\nimport { isClerkRuntimeError } from './clerkRuntimeError';\n\n/**\n * Creates a ClerkGlobalHookError object from a ClerkError instance.\n * It's a wrapper for all the different instances of Clerk errors that can\n * be returned when using Clerk hooks.\n */\nexport function createClerkGlobalHookError(error: ClerkError) {\n const predicates = {\n isClerkAPIResponseError,\n isClerkRuntimeError,\n } as const;\n\n for (const [name, fn] of Object.entries(predicates)) {\n Object.assign(error, { [name]: fn });\n }\n\n return error as ClerkError & typeof predicates;\n}\n\nexport type ClerkGlobalHookError = ReturnType<typeof createClerkGlobalHookError>;\n"],"mappings":"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"}
|
|
@@ -218,21 +218,27 @@ var ClerkOfflineError = class ClerkOfflineError extends require_clerkRuntimeErro
|
|
|
218
218
|
//#region src/errors/errorThrower.ts
|
|
219
219
|
const DefaultMessages = Object.freeze({
|
|
220
220
|
InvalidProxyUrlErrorMessage: `The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})`,
|
|
221
|
-
InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, run:
|
|
221
|
+
InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, in your terminal run:
|
|
222
222
|
|
|
223
223
|
npx clerk@latest init
|
|
224
224
|
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
It creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.
|
|
226
|
+
|
|
227
|
+
If you have a Clerk application, run \`npx clerk@latest env pull\` to write the keys (\`--instance prod\` for production keys). Or copy its Publishable key from https://dashboard.clerk.com/last-active?path=api-keys.`,
|
|
228
|
+
MissingPublishableKeyErrorMessage: `Missing publishableKey. To set up Clerk for this project, in your terminal run:
|
|
227
229
|
|
|
228
230
|
npx clerk@latest init
|
|
229
231
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
+
It creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.
|
|
233
|
+
|
|
234
|
+
If you have a Clerk application, run \`npx clerk@latest env pull\` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running \`npx clerk@latest deploy\`, or \`npx clerk@latest env pull --instance prod\` to use an existing one.`,
|
|
235
|
+
MissingSecretKeyErrorMessage: `Missing secretKey. To set up Clerk for this project, in your terminal run:
|
|
232
236
|
|
|
233
237
|
npx clerk@latest init
|
|
234
238
|
|
|
235
|
-
|
|
239
|
+
It creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.
|
|
240
|
+
|
|
241
|
+
If you have a Clerk application, run \`npx clerk@latest env pull\` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running \`npx clerk@latest deploy\`, or \`npx clerk@latest env pull --instance prod\` to use an existing one.`,
|
|
236
242
|
MissingClerkProvider: `{{source}} can only be used within the <ClerkProvider /> component. Learn more: https://clerk.com/docs/components/clerk-provider`
|
|
237
243
|
});
|
|
238
244
|
/**
|
|
@@ -640,4 +646,4 @@ Object.defineProperty(exports, 'parseErrors', {
|
|
|
640
646
|
return parseErrors;
|
|
641
647
|
}
|
|
642
648
|
});
|
|
643
|
-
//# sourceMappingURL=error-
|
|
649
|
+
//# sourceMappingURL=error-DiOD3e6d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-DiOD3e6d.js","names":["createErrorTypeGuard","ClerkError","createErrorTypeGuard","ClerkRuntimeError","isClerkRuntimeError","ClerkRuntimeError","isClerkRuntimeError"],"sources":["../../src/errors/clerkApiError.ts","../../src/errors/parseError.ts","../../src/errors/clerkApiResponseError.ts","../../src/errors/missingExpiredTokenError.ts","../../src/errors/clerkOfflineError.ts","../../src/errors/errorThrower.ts","../../src/errors/emailLinkError.ts","../../src/errors/webAuthNError.ts","../../src/errors/helpers.ts","../../src/errors/globalHookError.ts"],"sourcesContent":["import type { ClerkAPIError as ClerkAPIErrorInterface, ClerkAPIErrorJSON } from '../types';\nimport { createErrorTypeGuard } from './createErrorTypeGuard';\n\nexport type ClerkAPIErrorMeta = Record<string, unknown>;\n\n/**\n * This error contains the specific error message, code, and any additional metadata that was returned by the Clerk API.\n */\nexport class ClerkAPIError<Meta extends ClerkAPIErrorMeta = any> implements ClerkAPIErrorInterface {\n static kind = 'ClerkAPIError';\n readonly code: string;\n readonly message: string;\n readonly longMessage: string | undefined;\n readonly meta: Meta;\n\n constructor(json: ClerkAPIErrorJSON) {\n const parsedError = {\n code: json.code,\n message: json.message,\n longMessage: json.long_message,\n meta: {\n paramName: json.meta?.param_name,\n sessionId: json.meta?.session_id,\n emailAddresses: json.meta?.email_addresses,\n identifiers: json.meta?.identifiers,\n zxcvbn: json.meta?.zxcvbn,\n plan: json.meta?.plan,\n isPlanUpgradePossible: json.meta?.is_plan_upgrade_possible,\n seatsQuantityToAdd: json.meta?.seats_quantity_to_add,\n seatsQuantity: json.meta?.seats_quantity,\n } as unknown as Meta,\n };\n this.code = parsedError.code;\n this.message = parsedError.message;\n this.longMessage = parsedError.longMessage;\n this.meta = parsedError.meta;\n }\n}\n\n/**\n * Type guard to check if a value is a ClerkAPIError instance.\n */\nexport const isClerkAPIError = createErrorTypeGuard(ClerkAPIError);\n","import type { ClerkAPIError as ClerkAPIErrorInterface, ClerkAPIErrorJSON } from '../types';\nimport { ClerkAPIError } from './clerkApiError';\n\n/**\n * Parses an array of ClerkAPIErrorJSON objects into an array of ClerkAPIError objects.\n *\n * @internal\n */\nexport function parseErrors(data: ClerkAPIErrorJSON[] = []): ClerkAPIErrorInterface[] {\n return data.length > 0 ? data.map(e => new ClerkAPIError(e)) : [];\n}\n\n/**\n * Parses a ClerkAPIErrorJSON object into a ClerkAPIError object.\n *\n * @deprecated Use `ClerkAPIError` class instead\n *\n * @internal\n */\nexport function parseError(error: ClerkAPIErrorJSON): ClerkAPIErrorInterface {\n return new ClerkAPIError(error);\n}\n\n/**\n * Converts a ClerkAPIError object into a ClerkAPIErrorJSON object.\n *\n * @internal\n */\nexport function errorToJSON(error: ClerkAPIError | null): ClerkAPIErrorJSON {\n return {\n code: error?.code || '',\n message: error?.message || '',\n long_message: error?.longMessage,\n meta: {\n param_name: error?.meta?.paramName,\n session_id: error?.meta?.sessionId,\n email_addresses: error?.meta?.emailAddresses,\n identifiers: error?.meta?.identifiers,\n zxcvbn: error?.meta?.zxcvbn,\n plan: error?.meta?.plan,\n is_plan_upgrade_possible: error?.meta?.isPlanUpgradePossible,\n seats_quantity_to_add: error?.meta?.seatsQuantityToAdd,\n seats_quantity: error?.meta?.seatsQuantity,\n },\n };\n}\n","import type { ClerkAPIErrorJSON, ClerkAPIResponseError as ClerkAPIResponseErrorInterface } from '../types';\nimport { ClerkAPIError } from './clerkApiError';\nimport type { ClerkErrorParams } from './clerkError';\nimport { ClerkError } from './clerkError';\nimport { createErrorTypeGuard } from './createErrorTypeGuard';\n\ninterface ClerkAPIResponseOptions extends Omit<ClerkErrorParams, 'message' | 'code'> {\n data: ClerkAPIErrorJSON[];\n status: number;\n clerkTraceId?: string;\n retryAfter?: number;\n}\n\nexport class ClerkAPIResponseError extends ClerkError implements ClerkAPIResponseErrorInterface {\n static kind = 'ClerkAPIResponseError';\n status: number;\n clerkTraceId?: string;\n retryAfter?: number;\n errors: ClerkAPIError[];\n\n constructor(message: string, options: ClerkAPIResponseOptions) {\n const { data: errorsJson, status, clerkTraceId, retryAfter } = options;\n super({ ...options, message, code: 'api_response_error' });\n Object.setPrototypeOf(this, ClerkAPIResponseError.prototype);\n this.status = status;\n this.clerkTraceId = clerkTraceId;\n this.retryAfter = retryAfter;\n this.errors = (errorsJson || []).map(e => new ClerkAPIError(e));\n }\n\n public toString() {\n let message = `[${this.name}]\\nMessage:${this.message}\\nStatus:${this.status}\\nSerialized errors: ${this.errors.map(\n e => JSON.stringify(e),\n )}`;\n\n if (this.clerkTraceId) {\n message += `\\nClerk Trace ID: ${this.clerkTraceId}`;\n }\n\n return message;\n }\n\n // Override formatMessage to keep it unformatted for backward compatibility\n protected static override formatMessage(name: string, msg: string, _: string, __: string | undefined) {\n return msg;\n }\n}\n\n/**\n * Type guard to check if an error is a ClerkAPIResponseError.\n * Can be called as a standalone function or as a method on an error object.\n *\n * @example\n * // As a standalone function\n * if (isClerkAPIResponseError(error)) { ... }\n *\n * // As a method (when attached to error object)\n * if (error.isClerkAPIResponseError()) { ... }\n */\nexport const isClerkAPIResponseError = createErrorTypeGuard(ClerkAPIResponseError);\n","import { ClerkAPIResponseError, isClerkAPIResponseError } from './clerkApiResponseError';\n\n/**\n * Error class representing a missing expired token error from the API.\n * This error occurs when the server requires an expired token to mint a new session token.\n *\n * Use the static `is` method to check if a ClerkAPIResponseError matches this error type.\n *\n * @example\n * ```typescript\n * if (MissingExpiredTokenError.is(error)) {\n * // Handle the missing expired token error\n * }\n * ```\n */\nexport class MissingExpiredTokenError extends ClerkAPIResponseError {\n static kind = 'MissingExpiredTokenError';\n static readonly ERROR_CODE = 'missing_expired_token' as const;\n static readonly STATUS = 422 as const;\n\n /**\n * Type guard to check if an error is a MissingExpiredTokenError.\n * This checks the error's properties (status and error code) rather than instanceof,\n * allowing it to work with ClerkAPIResponseError instances thrown from the API layer.\n *\n * @example\n * ```typescript\n * try {\n * await someApiCall();\n * } catch (e) {\n * if (MissingExpiredTokenError.is(e)) {\n * // e is typed as ClerkAPIResponseError with the specific error properties\n * }\n * }\n * ```\n */\n static is(err: unknown): err is ClerkAPIResponseError {\n return (\n isClerkAPIResponseError(err) &&\n err.status === MissingExpiredTokenError.STATUS &&\n err.errors.length > 0 &&\n err.errors[0].code === MissingExpiredTokenError.ERROR_CODE\n );\n }\n}\n","import { ClerkRuntimeError, isClerkRuntimeError } from './clerkRuntimeError';\n\n/**\n * Error thrown when a network request fails due to the client being offline.\n *\n * This error is thrown instead of returning `null` to make it explicit that\n * the failure was due to network conditions, not authentication state.\n *\n * @example\n * ```typescript\n * try {\n * const token = await session.getToken();\n * } catch (error) {\n * if (ClerkOfflineError.is(error)) {\n * // Handle offline scenario\n * showOfflineScreen();\n * }\n * }\n * ```\n */\nexport class ClerkOfflineError extends ClerkRuntimeError {\n static kind = 'ClerkOfflineError';\n static readonly ERROR_CODE = 'clerk_offline' as const;\n\n constructor(message: string) {\n super(message, { code: ClerkOfflineError.ERROR_CODE });\n Object.setPrototypeOf(this, ClerkOfflineError.prototype);\n }\n\n /**\n * Type guard to check if an error is a ClerkOfflineError.\n * This checks both instanceof and the error code to support cross-bundle/cross-realm errors\n *\n * @example\n * ```typescript\n * try {\n * const token = await session.getToken();\n * } catch (error) {\n * if (ClerkOfflineError.is(error)) {\n * // error is typed as ClerkOfflineError\n * console.log('User is offline');\n * }\n * }\n * ```\n */\n static is(error: unknown): error is ClerkOfflineError {\n if (error === null || error === undefined) {\n return false;\n }\n return (\n error instanceof ClerkOfflineError || (isClerkRuntimeError(error) && error.code === ClerkOfflineError.ERROR_CODE)\n );\n }\n}\n","const DefaultMessages = Object.freeze({\n InvalidProxyUrlErrorMessage: `The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})`,\n InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run \\`npx clerk@latest env pull\\` to write the keys (\\`--instance prod\\` for production keys). Or copy its Publishable key from https://dashboard.clerk.com/last-active?path=api-keys.`,\n MissingPublishableKeyErrorMessage: `Missing publishableKey. To set up Clerk for this project, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run \\`npx clerk@latest env pull\\` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running \\`npx clerk@latest deploy\\`, or \\`npx clerk@latest env pull --instance prod\\` to use an existing one.`,\n MissingSecretKeyErrorMessage: `Missing secretKey. To set up Clerk for this project, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run \\`npx clerk@latest env pull\\` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running \\`npx clerk@latest deploy\\`, or \\`npx clerk@latest env pull --instance prod\\` to use an existing one.`,\n MissingClerkProvider: `{{source}} can only be used within the <ClerkProvider /> component. Learn more: https://clerk.com/docs/components/clerk-provider`,\n});\n\ntype MessageKeys = keyof typeof DefaultMessages;\n\ntype Messages = Record<MessageKeys, string>;\n\ntype CustomMessages = Partial<Messages>;\n\nexport type ErrorThrowerOptions = {\n packageName: string;\n customMessages?: CustomMessages;\n};\n\nexport interface ErrorThrower {\n setPackageName(options: ErrorThrowerOptions): ErrorThrower;\n\n setMessages(options: ErrorThrowerOptions): ErrorThrower;\n\n throwInvalidPublishableKeyError(params: { key?: string }): never;\n\n throwInvalidProxyUrl(params: { url?: string }): never;\n\n throwMissingPublishableKeyError(): never;\n\n throwMissingSecretKeyError(): never;\n\n throwMissingClerkProviderError(params: { source?: string }): never;\n\n throw(message: string): never;\n}\n\n/**\n * Builds an error thrower.\n *\n * @internal\n */\nexport function buildErrorThrower({ packageName, customMessages }: ErrorThrowerOptions): ErrorThrower {\n let pkg = packageName;\n\n /**\n * Builds a message from a raw message and replacements.\n *\n * @internal\n */\n function buildMessage(rawMessage: string, replacements?: Record<string, string | number>) {\n if (!replacements) {\n return `${pkg}: ${rawMessage}`;\n }\n\n let msg = rawMessage;\n const matches = rawMessage.matchAll(/{{([a-zA-Z0-9-_]+)}}/g);\n\n for (const match of matches) {\n const replacement = (replacements[match[1]] || '').toString();\n msg = msg.replace(`{{${match[1]}}}`, replacement);\n }\n\n return `${pkg}: ${msg}`;\n }\n\n const messages = {\n ...DefaultMessages,\n ...customMessages,\n };\n\n return {\n setPackageName({ packageName }: ErrorThrowerOptions): ErrorThrower {\n if (typeof packageName === 'string') {\n pkg = packageName;\n }\n return this;\n },\n\n setMessages({ customMessages }: ErrorThrowerOptions): ErrorThrower {\n Object.assign(messages, customMessages || {});\n return this;\n },\n\n throwInvalidPublishableKeyError(params: { key?: string }): never {\n throw new Error(buildMessage(messages.InvalidPublishableKeyErrorMessage, params));\n },\n\n throwInvalidProxyUrl(params: { url?: string }): never {\n throw new Error(buildMessage(messages.InvalidProxyUrlErrorMessage, params));\n },\n\n throwMissingPublishableKeyError(): never {\n throw new Error(buildMessage(messages.MissingPublishableKeyErrorMessage));\n },\n\n throwMissingSecretKeyError(): never {\n throw new Error(buildMessage(messages.MissingSecretKeyErrorMessage));\n },\n\n throwMissingClerkProviderError(params: { source?: string }): never {\n throw new Error(buildMessage(messages.MissingClerkProvider, params));\n },\n\n throw(message: string): never {\n throw new Error(buildMessage(message));\n },\n };\n}\n","export class EmailLinkError extends Error {\n code: string;\n\n constructor(code: string) {\n super(code);\n this.code = code;\n this.name = 'EmailLinkError' as const;\n Object.setPrototypeOf(this, EmailLinkError.prototype);\n }\n}\n\n/**\n * @deprecated Use `EmailLinkErrorCodeStatus` instead.\n *\n * @internal\n */\nexport const EmailLinkErrorCode = {\n Expired: 'expired',\n Failed: 'failed',\n ClientMismatch: 'client_mismatch',\n};\n\nexport const EmailLinkErrorCodeStatus = {\n Expired: 'expired',\n Failed: 'failed',\n ClientMismatch: 'client_mismatch',\n} as const;\n","import type { ClerkErrorParams } from './clerkError';\nimport { ClerkRuntimeError } from './clerkRuntimeError';\n\ntype ClerkWebAuthnErrorCode =\n // Generic\n | 'passkey_not_supported'\n | 'passkey_pa_not_supported'\n | 'passkey_invalid_rpID_or_domain'\n | 'passkey_already_exists'\n | 'passkey_operation_aborted'\n // Retrieval\n | 'passkey_retrieval_cancelled'\n | 'passkey_retrieval_failed'\n // Registration\n | 'passkey_registration_cancelled'\n | 'passkey_registration_failed';\n\ntype ClerkWebAuthnErrorOptions = Omit<ClerkErrorParams, 'message' | 'code'> & { code: ClerkWebAuthnErrorCode };\n\nexport class ClerkWebAuthnError extends ClerkRuntimeError {\n /**\n * A unique code identifying the error, can be used for localization.\n */\n code: ClerkWebAuthnErrorCode;\n\n constructor(message: string, options: ClerkWebAuthnErrorOptions) {\n super(message, options);\n this.code = options.code;\n }\n}\n","import type { ClerkAPIResponseError } from './clerkApiResponseError';\nimport { isClerkAPIResponseError } from './clerkApiResponseError';\nimport type { ClerkRuntimeError } from './clerkRuntimeError';\nimport { isClerkRuntimeError } from './clerkRuntimeError';\nimport type { EmailLinkError } from './emailLinkError';\nimport type { MetamaskError } from './metamaskError';\n\n/**\n * Checks if the provided error object is an unauthorized error.\n *\n * @internal\n *\n * @deprecated This is no longer used, and will be removed in the next major version.\n */\nexport function isUnauthorizedError(e: any): boolean {\n const status = e?.status;\n const code = e?.errors?.[0]?.code;\n return code === 'authentication_invalid' && status === 401;\n}\n\n/**\n * Checks if the provided error object is a captcha error.\n *\n * @internal\n */\nexport function isCaptchaError(e: ClerkAPIResponseError): boolean {\n return ['captcha_invalid', 'captcha_not_enabled', 'captcha_missing_token'].includes(e.errors[0].code);\n}\n\n/**\n * Checks if the provided error is a 4xx error.\n *\n * @internal\n */\nexport function is4xxError(e: any): boolean {\n const status = e?.status;\n return !!status && status >= 400 && status < 500;\n}\n\n/**\n * Checks if the provided error is a 429 (Too Many Requests) error.\n *\n * @internal\n */\nexport function is429Error(e: any): boolean {\n return e?.status === 429;\n}\n\nconst unauthenticated403ErrorCodes = new Set(['user_banned', 'user_deactivated']);\n\n/**\n * Checks if the provided error indicates the user's session is no longer valid\n * and should trigger the unauthenticated flow (e.g. sign-out / redirect to sign-in).\n *\n * Only matches explicit authentication failure status codes:\n * - 401: session is invalid or expired\n * - 422: invalid session state (e.g. missing_expired_token)\n * - 403: terminal user state (e.g. user_banned, user_deactivated)\n *\n * 404 is intentionally excluded despite being returned for \"session not found\",\n * because it's also returned for unrelated resources (org not found, JWT template\n * not found) and shares the same `resource_not_found` error code, making it\n * impossible to distinguish. Session-not-found 401s are already handled directly\n * by Base._fetch.\n *\n * @internal\n */\nexport function isUnauthenticatedError(e: any): boolean {\n const status = e?.status;\n const hasTerminalUserErrorCode =\n Array.isArray(e?.errors) && e.errors.some((error: any) => unauthenticated403ErrorCodes.has(error?.code));\n\n return status === 401 || status === 422 || (status === 403 && hasTerminalUserErrorCode);\n}\n\n/**\n * Checks if the provided error is a network error.\n *\n * @internal\n */\nexport function isNetworkError(e: any): boolean {\n // TODO: revise during error handling epic\n const message = (`${e.message}${e.name}` || '').toLowerCase().replace(/\\s+/g, '');\n return message.includes('networkerror');\n}\n\n/**\n * Checks if the provided error is either a ClerkAPIResponseError, a ClerkRuntimeError, or a MetamaskError.\n */\nexport function isKnownError(error: any): error is ClerkAPIResponseError | ClerkRuntimeError | MetamaskError {\n return isClerkAPIResponseError(error) || isMetamaskError(error) || isClerkRuntimeError(error);\n}\n\n/**\n * Checks if the provided error is a Clerk runtime error indicating a reverification was cancelled.\n */\nexport function isReverificationCancelledError(err: any) {\n return isClerkRuntimeError(err) && err.code === 'reverification_cancelled';\n}\n\n/**\n * Checks if the provided error is a Metamask error.\n */\nexport function isMetamaskError(err: any): err is MetamaskError {\n return 'code' in err && [4001, 32602, 32603].includes(err.code) && 'message' in err;\n}\n\n/**\n * Checks if the provided error is clerk api response error indicating a user is locked.\n */\nexport function isUserLockedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'user_locked';\n}\n\n/**\n * Checks if the provided error is a clerk api response error indicating a password was pwned.\n *\n * @internal\n */\nexport function isPasswordPwnedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'form_password_pwned';\n}\n\n/**\n * Checks if the provided error is a clerk api response error indicating a password was compromised.\n *\n * @internal\n */\nexport function isPasswordCompromisedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'form_password_compromised';\n}\n\n/**\n * Checks if the provided error is an EmailLinkError.\n */\nexport function isEmailLinkError(err: Error): err is EmailLinkError {\n return err.name === 'EmailLinkError';\n}\n","import { isClerkAPIResponseError } from './clerkApiResponseError';\nimport type { ClerkError } from './clerkError';\nimport { isClerkRuntimeError } from './clerkRuntimeError';\n\n/**\n * Creates a ClerkGlobalHookError object from a ClerkError instance.\n * It's a wrapper for all the different instances of Clerk errors that can\n * be returned when using Clerk hooks.\n */\nexport function createClerkGlobalHookError(error: ClerkError) {\n const predicates = {\n isClerkAPIResponseError,\n isClerkRuntimeError,\n } as const;\n\n for (const [name, fn] of Object.entries(predicates)) {\n Object.assign(error, { [name]: fn });\n }\n\n return error as ClerkError & typeof predicates;\n}\n\nexport type ClerkGlobalHookError = ReturnType<typeof createClerkGlobalHookError>;\n"],"mappings":";;;;;;AAQA,IAAa,gBAAb,MAAmG;CACjG,OAAO,OAAO;CACd,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CAET,YAAY,MAAyB;EACnC,MAAM,cAAc;GAClB,MAAM,KAAK;GACX,SAAS,KAAK;GACd,aAAa,KAAK;GAClB,MAAM;IACJ,WAAW,KAAK,MAAM;IACtB,WAAW,KAAK,MAAM;IACtB,gBAAgB,KAAK,MAAM;IAC3B,aAAa,KAAK,MAAM;IACxB,QAAQ,KAAK,MAAM;IACnB,MAAM,KAAK,MAAM;IACjB,uBAAuB,KAAK,MAAM;IAClC,oBAAoB,KAAK,MAAM;IAC/B,eAAe,KAAK,MAAM;GAC5B;EACF;EACA,KAAK,OAAO,YAAY;EACxB,KAAK,UAAU,YAAY;EAC3B,KAAK,cAAc,YAAY;EAC/B,KAAK,OAAO,YAAY;CAC1B;AACF;;;;AAKA,MAAa,kBAAkBA,+CAAqB,aAAa;;;;;;;;;AClCjE,SAAgB,YAAY,OAA4B,CAAC,GAA6B;CACpF,OAAO,KAAK,SAAS,IAAI,KAAK,KAAI,MAAK,IAAI,cAAc,CAAC,CAAC,IAAI,CAAC;AAClE;;;;;;;;AASA,SAAgB,WAAW,OAAkD;CAC3E,OAAO,IAAI,cAAc,KAAK;AAChC;;;;;;AAOA,SAAgB,YAAY,OAAgD;CAC1E,OAAO;EACL,MAAM,OAAO,QAAQ;EACrB,SAAS,OAAO,WAAW;EAC3B,cAAc,OAAO;EACrB,MAAM;GACJ,YAAY,OAAO,MAAM;GACzB,YAAY,OAAO,MAAM;GACzB,iBAAiB,OAAO,MAAM;GAC9B,aAAa,OAAO,MAAM;GAC1B,QAAQ,OAAO,MAAM;GACrB,MAAM,OAAO,MAAM;GACnB,0BAA0B,OAAO,MAAM;GACvC,uBAAuB,OAAO,MAAM;GACpC,gBAAgB,OAAO,MAAM;EAC/B;CACF;AACF;;;;AChCA,IAAa,wBAAb,MAAa,8BAA8BC,qCAAqD;CAC9F,OAAO,OAAO;CACd;CACA;CACA;CACA;CAEA,YAAY,SAAiB,SAAkC;EAC7D,MAAM,EAAE,MAAM,YAAY,QAAQ,cAAc,eAAe;EAC/D,MAAM;GAAE,GAAG;GAAS;GAAS,MAAM;EAAqB,CAAC;EACzD,OAAO,eAAe,MAAM,sBAAsB,SAAS;EAC3D,KAAK,SAAS;EACd,KAAK,eAAe;EACpB,KAAK,aAAa;EAClB,KAAK,UAAU,cAAc,CAAC,EAAC,CAAE,KAAI,MAAK,IAAI,cAAc,CAAC,CAAC;CAChE;CAEA,AAAO,WAAW;EAChB,IAAI,UAAU,IAAI,KAAK,KAAK,aAAa,KAAK,QAAQ,WAAW,KAAK,OAAO,uBAAuB,KAAK,OAAO,KAC9G,MAAK,KAAK,UAAU,CAAC,CACvB;EAEA,IAAI,KAAK,cACP,WAAW,qBAAqB,KAAK;EAGvC,OAAO;CACT;CAGA,OAA0B,cAAc,MAAc,KAAa,GAAW,IAAwB;EACpG,OAAO;CACT;AACF;;;;;;;;;;;;AAaA,MAAa,0BAA0BC,+CAAqB,qBAAqB;;;;;;;;;;;;;;;;;AC5CjF,IAAa,2BAAb,MAAa,iCAAiC,sBAAsB;CAClE,OAAO,OAAO;CACd,OAAgB,aAAa;CAC7B,OAAgB,SAAS;;;;;;;;;;;;;;;;;CAkBzB,OAAO,GAAG,KAA4C;EACpD,OACE,wBAAwB,GAAG,KAC3B,IAAI,WAAW,yBAAyB,UACxC,IAAI,OAAO,SAAS,KACpB,IAAI,OAAO,EAAE,CAAC,SAAS,yBAAyB;CAEpD;AACF;;;;;;;;;;;;;;;;;;;;;;ACxBA,IAAa,oBAAb,MAAa,0BAA0BC,4CAAkB;CACvD,OAAO,OAAO;CACd,OAAgB,aAAa;CAE7B,YAAY,SAAiB;EAC3B,MAAM,SAAS,EAAE,MAAM,kBAAkB,WAAW,CAAC;EACrD,OAAO,eAAe,MAAM,kBAAkB,SAAS;CACzD;;;;;;;;;;;;;;;;;CAkBA,OAAO,GAAG,OAA4C;EACpD,IAAI,UAAU,QAAQ,UAAU,QAC9B,OAAO;EAET,OACE,iBAAiB,qBAAsBC,8CAAoB,KAAK,KAAK,MAAM,SAAS,kBAAkB;CAE1G;AACF;;;;ACrDA,MAAM,kBAAkB,OAAO,OAAO;CACpC,6BAA6B;CAC7B,mCAAmC;;;;;;;CAOnC,mCAAmC;;;;;;;CAOnC,8BAA8B;;;;;;;CAO9B,sBAAsB;AACxB,CAAC;;;;;;AAoCD,SAAgB,kBAAkB,EAAE,aAAa,kBAAqD;CACpG,IAAI,MAAM;;;;;;CAOV,SAAS,aAAa,YAAoB,cAAgD;EACxF,IAAI,CAAC,cACH,OAAO,GAAG,IAAI,IAAI;EAGpB,IAAI,MAAM;EACV,MAAM,UAAU,WAAW,SAAS,uBAAuB;EAE3D,KAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,eAAe,aAAa,MAAM,OAAO,GAAE,CAAE,SAAS;GAC5D,MAAM,IAAI,QAAQ,KAAK,MAAM,GAAG,KAAK,WAAW;EAClD;EAEA,OAAO,GAAG,IAAI,IAAI;CACpB;CAEA,MAAM,WAAW;EACf,GAAG;EACH,GAAG;CACL;CAEA,OAAO;EACL,eAAe,EAAE,eAAkD;GACjE,IAAI,OAAO,gBAAgB,UACzB,MAAM;GAER,OAAO;EACT;EAEA,YAAY,EAAE,kBAAqD;GACjE,OAAO,OAAO,UAAU,kBAAkB,CAAC,CAAC;GAC5C,OAAO;EACT;EAEA,gCAAgC,QAAiC;GAC/D,MAAM,IAAI,MAAM,aAAa,SAAS,mCAAmC,MAAM,CAAC;EAClF;EAEA,qBAAqB,QAAiC;GACpD,MAAM,IAAI,MAAM,aAAa,SAAS,6BAA6B,MAAM,CAAC;EAC5E;EAEA,kCAAyC;GACvC,MAAM,IAAI,MAAM,aAAa,SAAS,iCAAiC,CAAC;EAC1E;EAEA,6BAAoC;GAClC,MAAM,IAAI,MAAM,aAAa,SAAS,4BAA4B,CAAC;EACrE;EAEA,+BAA+B,QAAoC;GACjE,MAAM,IAAI,MAAM,aAAa,SAAS,sBAAsB,MAAM,CAAC;EACrE;EAEA,MAAM,SAAwB;GAC5B,MAAM,IAAI,MAAM,aAAa,OAAO,CAAC;EACvC;CACF;AACF;;;;AC9HA,IAAa,iBAAb,MAAa,uBAAuB,MAAM;CACxC;CAEA,YAAY,MAAc;EACxB,MAAM,IAAI;EACV,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,OAAO,eAAe,MAAM,eAAe,SAAS;CACtD;AACF;;;;;;AAOA,MAAa,qBAAqB;CAChC,SAAS;CACT,QAAQ;CACR,gBAAgB;AAClB;AAEA,MAAa,2BAA2B;CACtC,SAAS;CACT,QAAQ;CACR,gBAAgB;AAClB;;;;ACPA,IAAa,qBAAb,cAAwCC,4CAAkB;;;;CAIxD;CAEA,YAAY,SAAiB,SAAoC;EAC/D,MAAM,SAAS,OAAO;EACtB,KAAK,OAAO,QAAQ;CACtB;AACF;;;;;;;;;;;ACfA,SAAgB,oBAAoB,GAAiB;CACnD,MAAM,SAAS,GAAG;CAElB,OADa,GAAG,SAAS,EAAE,EAAE,SACb,4BAA4B,WAAW;AACzD;;;;;;AAOA,SAAgB,eAAe,GAAmC;CAChE,OAAO;EAAC;EAAmB;EAAuB;CAAuB,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,IAAI;AACtG;;;;;;AAOA,SAAgB,WAAW,GAAiB;CAC1C,MAAM,SAAS,GAAG;CAClB,OAAO,CAAC,CAAC,UAAU,UAAU,OAAO,SAAS;AAC/C;;;;;;AAOA,SAAgB,WAAW,GAAiB;CAC1C,OAAO,GAAG,WAAW;AACvB;AAEA,MAAM,+BAA+B,IAAI,IAAI,CAAC,eAAe,kBAAkB,CAAC;;;;;;;;;;;;;;;;;;AAmBhF,SAAgB,uBAAuB,GAAiB;CACtD,MAAM,SAAS,GAAG;CAClB,MAAM,2BACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,EAAE,OAAO,MAAM,UAAe,6BAA6B,IAAI,OAAO,IAAI,CAAC;CAEzG,OAAO,WAAW,OAAO,WAAW,OAAQ,WAAW,OAAO;AAChE;;;;;;AAOA,SAAgB,eAAe,GAAiB;CAG9C,QADiB,GAAG,EAAE,UAAU,EAAE,UAAU,GAAE,CAAE,YAAY,CAAC,CAAC,QAAQ,QAAQ,EACjE,CAAC,CAAC,SAAS,cAAc;AACxC;;;;AAKA,SAAgB,aAAa,OAAgF;CAC3G,OAAO,wBAAwB,KAAK,KAAK,gBAAgB,KAAK,KAAKC,8CAAoB,KAAK;AAC9F;;;;AAKA,SAAgB,+BAA+B,KAAU;CACvD,OAAOA,8CAAoB,GAAG,KAAK,IAAI,SAAS;AAClD;;;;AAKA,SAAgB,gBAAgB,KAAgC;CAC9D,OAAO,UAAU,OAAO;EAAC;EAAM;EAAO;CAAK,CAAC,CAAC,SAAS,IAAI,IAAI,KAAK,aAAa;AAClF;;;;AAKA,SAAgB,kBAAkB,KAAU;CAC1C,OAAO,wBAAwB,GAAG,KAAK,IAAI,SAAS,EAAE,EAAE,SAAS;AACnE;;;;;;AAOA,SAAgB,qBAAqB,KAAU;CAC7C,OAAO,wBAAwB,GAAG,KAAK,IAAI,SAAS,EAAE,EAAE,SAAS;AACnE;;;;;;AAOA,SAAgB,2BAA2B,KAAU;CACnD,OAAO,wBAAwB,GAAG,KAAK,IAAI,SAAS,EAAE,EAAE,SAAS;AACnE;;;;AAKA,SAAgB,iBAAiB,KAAmC;CAClE,OAAO,IAAI,SAAS;AACtB;;;;;;;;;AChIA,SAAgB,2BAA2B,OAAmB;CAC5D,MAAM,aAAa;EACjB;EACA;CACF;CAEA,KAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,UAAU,GAChD,OAAO,OAAO,OAAO,GAAG,OAAO,GAAG,CAAC;CAGrC,OAAO;AACT"}
|
package/dist/error.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_clerkRuntimeError = require('./_chunks/clerkRuntimeError-CYZdTZ_x.js');
|
|
3
|
-
const require_error = require('./_chunks/error-
|
|
3
|
+
const require_error = require('./_chunks/error-DiOD3e6d.js');
|
|
4
4
|
|
|
5
5
|
exports.ClerkAPIError = require_error.ClerkAPIError;
|
|
6
6
|
exports.ClerkAPIResponseError = require_error.ClerkAPIResponseError;
|
package/dist/error.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { i as isClerkError, n as isClerkRuntimeError, r as ClerkError, t as ClerkRuntimeError } from "./_chunks/clerkRuntimeError-DlesLWqO.mjs";
|
|
2
|
-
import { C as isClerkAPIResponseError, D as ClerkAPIError, E as parseErrors, O as isClerkAPIError, S as ClerkAPIResponseError, T as parseError, _ as EmailLinkErrorCode, a as isEmailLinkError, b as ClerkOfflineError, c as isNetworkError, d as isReverificationCancelledError, f as isUnauthenticatedError, g as EmailLinkError, h as ClerkWebAuthnError, i as isCaptchaError, l as isPasswordCompromisedError, m as isUserLockedError, n as is429Error, o as isKnownError, p as isUnauthorizedError, r as is4xxError, s as isMetamaskError, t as createClerkGlobalHookError, u as isPasswordPwnedError, v as EmailLinkErrorCodeStatus, w as errorToJSON, x as MissingExpiredTokenError, y as buildErrorThrower } from "./_chunks/error-
|
|
2
|
+
import { C as isClerkAPIResponseError, D as ClerkAPIError, E as parseErrors, O as isClerkAPIError, S as ClerkAPIResponseError, T as parseError, _ as EmailLinkErrorCode, a as isEmailLinkError, b as ClerkOfflineError, c as isNetworkError, d as isReverificationCancelledError, f as isUnauthenticatedError, g as EmailLinkError, h as ClerkWebAuthnError, i as isCaptchaError, l as isPasswordCompromisedError, m as isUserLockedError, n as is429Error, o as isKnownError, p as isUnauthorizedError, r as is4xxError, s as isMetamaskError, t as createClerkGlobalHookError, u as isPasswordPwnedError, v as EmailLinkErrorCodeStatus, w as errorToJSON, x as MissingExpiredTokenError, y as buildErrorThrower } from "./_chunks/error-DRCZN5DP.mjs";
|
|
3
3
|
|
|
4
4
|
export { ClerkAPIError, ClerkAPIResponseError, ClerkError, ClerkOfflineError, ClerkRuntimeError, ClerkWebAuthnError, EmailLinkError, EmailLinkErrorCode, EmailLinkErrorCodeStatus, MissingExpiredTokenError, buildErrorThrower, createClerkGlobalHookError, errorToJSON, is429Error, is4xxError, isCaptchaError, isClerkAPIError, isClerkAPIResponseError, isClerkError, isClerkRuntimeError, isEmailLinkError, isKnownError, isMetamaskError, isNetworkError, isPasswordCompromisedError, isPasswordPwnedError, isReverificationCancelledError, isUnauthenticatedError, isUnauthorizedError, isUserLockedError, parseError, parseErrors };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
//#region src/errors/errorThrower.d.ts
|
|
2
2
|
declare const DefaultMessages: Readonly<{
|
|
3
3
|
InvalidProxyUrlErrorMessage: "The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})";
|
|
4
|
-
InvalidPublishableKeyErrorMessage: "The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, run:\n\n npx clerk@latest init\n\
|
|
5
|
-
MissingPublishableKeyErrorMessage: "Missing publishableKey. To set up Clerk for this project, run:\n\n npx clerk@latest init\n\
|
|
6
|
-
MissingSecretKeyErrorMessage: "Missing secretKey. To set up Clerk for this project, run:\n\n npx clerk@latest init\n\
|
|
4
|
+
InvalidPublishableKeyErrorMessage: "The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run `npx clerk@latest env pull` to write the keys (`--instance prod` for production keys). Or copy its Publishable key from https://dashboard.clerk.com/last-active?path=api-keys.";
|
|
5
|
+
MissingPublishableKeyErrorMessage: "Missing publishableKey. To set up Clerk for this project, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run `npx clerk@latest env pull` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running `npx clerk@latest deploy`, or `npx clerk@latest env pull --instance prod` to use an existing one.";
|
|
6
|
+
MissingSecretKeyErrorMessage: "Missing secretKey. To set up Clerk for this project, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run `npx clerk@latest env pull` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running `npx clerk@latest deploy`, or `npx clerk@latest env pull --instance prod` to use an existing one.";
|
|
7
7
|
MissingClerkProvider: "{{source}} can only be used within the <ClerkProvider /> component. Learn more: https://clerk.com/docs/components/clerk-provider";
|
|
8
8
|
}>;
|
|
9
9
|
type MessageKeys = keyof typeof DefaultMessages;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
//#region src/errors/errorThrower.d.ts
|
|
2
2
|
declare const DefaultMessages: Readonly<{
|
|
3
3
|
InvalidProxyUrlErrorMessage: "The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})";
|
|
4
|
-
InvalidPublishableKeyErrorMessage: "The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, run:\n\n npx clerk@latest init\n\
|
|
5
|
-
MissingPublishableKeyErrorMessage: "Missing publishableKey. To set up Clerk for this project, run:\n\n npx clerk@latest init\n\
|
|
6
|
-
MissingSecretKeyErrorMessage: "Missing secretKey. To set up Clerk for this project, run:\n\n npx clerk@latest init\n\
|
|
4
|
+
InvalidPublishableKeyErrorMessage: "The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run `npx clerk@latest env pull` to write the keys (`--instance prod` for production keys). Or copy its Publishable key from https://dashboard.clerk.com/last-active?path=api-keys.";
|
|
5
|
+
MissingPublishableKeyErrorMessage: "Missing publishableKey. To set up Clerk for this project, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run `npx clerk@latest env pull` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running `npx clerk@latest deploy`, or `npx clerk@latest env pull --instance prod` to use an existing one.";
|
|
6
|
+
MissingSecretKeyErrorMessage: "Missing secretKey. To set up Clerk for this project, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run `npx clerk@latest env pull` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running `npx clerk@latest deploy`, or `npx clerk@latest env pull --instance prod` to use an existing one.";
|
|
7
7
|
MissingClerkProvider: "{{source}} can only be used within the <ClerkProvider /> component. Learn more: https://clerk.com/docs/components/clerk-provider";
|
|
8
8
|
}>;
|
|
9
9
|
type MessageKeys = keyof typeof DefaultMessages;
|
|
@@ -2,21 +2,27 @@
|
|
|
2
2
|
//#region src/errors/errorThrower.ts
|
|
3
3
|
const DefaultMessages = Object.freeze({
|
|
4
4
|
InvalidProxyUrlErrorMessage: `The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})`,
|
|
5
|
-
InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, run:
|
|
5
|
+
InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, in your terminal run:
|
|
6
6
|
|
|
7
7
|
npx clerk@latest init
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
It creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.
|
|
10
|
+
|
|
11
|
+
If you have a Clerk application, run \`npx clerk@latest env pull\` to write the keys (\`--instance prod\` for production keys). Or copy its Publishable key from https://dashboard.clerk.com/last-active?path=api-keys.`,
|
|
12
|
+
MissingPublishableKeyErrorMessage: `Missing publishableKey. To set up Clerk for this project, in your terminal run:
|
|
11
13
|
|
|
12
14
|
npx clerk@latest init
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
It creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.
|
|
17
|
+
|
|
18
|
+
If you have a Clerk application, run \`npx clerk@latest env pull\` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running \`npx clerk@latest deploy\`, or \`npx clerk@latest env pull --instance prod\` to use an existing one.`,
|
|
19
|
+
MissingSecretKeyErrorMessage: `Missing secretKey. To set up Clerk for this project, in your terminal run:
|
|
16
20
|
|
|
17
21
|
npx clerk@latest init
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
It creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.
|
|
24
|
+
|
|
25
|
+
If you have a Clerk application, run \`npx clerk@latest env pull\` to write the keys. Or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploy a production instance by running \`npx clerk@latest deploy\`, or \`npx clerk@latest env pull --instance prod\` to use an existing one.`,
|
|
20
26
|
MissingClerkProvider: `{{source}} can only be used within the <ClerkProvider /> component. Learn more: https://clerk.com/docs/components/clerk-provider`
|
|
21
27
|
});
|
|
22
28
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_error = require('../../_chunks/error-
|
|
2
|
+
const require_error = require('../../_chunks/error-DiOD3e6d.js');
|
|
3
3
|
|
|
4
4
|
//#region src/internal/clerk-js/passkeys.ts
|
|
5
5
|
var Base64Converter = class {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_clerkRuntimeError = require('../../_chunks/clerkRuntimeError-CYZdTZ_x.js');
|
|
3
|
-
require('../../_chunks/error-
|
|
3
|
+
require('../../_chunks/error-DiOD3e6d.js');
|
|
4
4
|
|
|
5
5
|
//#region src/internal/clerk-js/protectCheck.ts
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_clerkRuntimeError = require('../../_chunks/clerkRuntimeError-CYZdTZ_x.js');
|
|
3
|
-
const require_error = require('../../_chunks/error-
|
|
3
|
+
const require_error = require('../../_chunks/error-DiOD3e6d.js');
|
|
4
4
|
const require_internal_clerk_js_hex = require('./hex.js');
|
|
5
5
|
const require_internal_clerk_js_injectedWeb3EthProviders = require('./injectedWeb3EthProviders.js');
|
|
6
6
|
const require_internal_clerk_js_injectedWeb3SolanaProviders = require('./injectedWeb3SolanaProviders.js');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as ClerkRuntimeError } from "../../_chunks/clerkRuntimeError-DlesLWqO.mjs";
|
|
2
|
-
import { y as buildErrorThrower } from "../../_chunks/error-
|
|
2
|
+
import { y as buildErrorThrower } from "../../_chunks/error-DRCZN5DP.mjs";
|
|
3
3
|
import { toHex } from "./hex.mjs";
|
|
4
4
|
import { getInjectedWeb3EthProviders } from "./injectedWeb3EthProviders.mjs";
|
|
5
5
|
import { getInjectedWeb3SolanaProviders } from "./injectedWeb3SolanaProviders.mjs";
|
package/dist/keys.js
CHANGED
|
@@ -65,11 +65,13 @@ function isValidDecodedPublishableKey(decoded) {
|
|
|
65
65
|
if (withoutTrailing.includes("$")) return false;
|
|
66
66
|
return withoutTrailing.includes(".");
|
|
67
67
|
}
|
|
68
|
-
const fatalKeyGuidance = `To create a Clerk application with valid keys, run:
|
|
68
|
+
const fatalKeyGuidance = `To create a Clerk application with valid keys, in your terminal run:
|
|
69
69
|
|
|
70
70
|
npx clerk@latest init
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
It creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.
|
|
73
|
+
|
|
74
|
+
If you have a Clerk application, run \`npx clerk@latest env pull\` to write the keys (\`--instance prod\` for production keys). Or copy them from https://dashboard.clerk.com/last-active?path=api-keys.`;
|
|
73
75
|
/**
|
|
74
76
|
* Parses and validates a publishable key, extracting the frontend API and instance type.
|
|
75
77
|
*
|
package/dist/keys.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.js","names":["LEGACY_DEV_INSTANCE_SUFFIXES","isomorphicBtoa","isomorphicAtob","DEV_OR_STAGING_SUFFIXES"],"sources":["../src/keys.ts"],"sourcesContent":["import { DEV_OR_STAGING_SUFFIXES, LEGACY_DEV_INSTANCE_SUFFIXES } from './constants';\nimport { isomorphicAtob } from './isomorphicAtob';\nimport { isomorphicBtoa } from './isomorphicBtoa';\nimport type { PublishableKey } from './types';\n\n/**\n * Configuration options for parsing publishable keys.\n */\ntype ParsePublishableKeyOptions = {\n /** Whether to throw an error if parsing fails */\n fatal?: boolean;\n /** Custom domain to use for satellite instances */\n domain?: string;\n /** Proxy URL to use instead of the decoded frontend API */\n proxyUrl?: string;\n /** Whether this is a satellite instance */\n isSatellite?: boolean;\n};\n\n/** Prefix used for production publishable keys */\nconst PUBLISHABLE_KEY_LIVE_PREFIX = 'pk_live_';\n\n/** Prefix used for development publishable keys */\nconst PUBLISHABLE_KEY_TEST_PREFIX = 'pk_test_';\n\n/**\n * Regular expression that matches development frontend API keys.\n * Matches patterns like: foo-bar-13.clerk.accounts.dev.\n */\nconst PUBLISHABLE_FRONTEND_API_DEV_REGEX = /^(([a-z]+)-){2}([0-9]{1,2})\\.clerk\\.accounts([a-z.]*)(dev|com)$/i;\n\n/**\n * Converts a frontend API URL into an unpadded base64-encoded publishable key.\n *\n * @param frontendApi - The frontend API URL (e.g., 'clerk.example.com').\n * @returns An unpadded base64-encoded publishable key with appropriate prefix (pk_live_ or pk_test_).\n */\nexport function buildPublishableKey(frontendApi: string): string {\n const isDevKey =\n PUBLISHABLE_FRONTEND_API_DEV_REGEX.test(frontendApi) ||\n (frontendApi.startsWith('clerk.') && LEGACY_DEV_INSTANCE_SUFFIXES.some(s => frontendApi.endsWith(s)));\n const keyPrefix = isDevKey ? PUBLISHABLE_KEY_TEST_PREFIX : PUBLISHABLE_KEY_LIVE_PREFIX;\n return `${keyPrefix}${isomorphicBtoa(`${frontendApi}$`).replace(/=+$/, '')}`;\n}\n\n/**\n * Derives a publishable key from the current hostname. Intended for multi-domain\n * setups (e.g. custom domains on top of a default domain) where the correct key\n * must be resolved per request.\n *\n * Pass the configured publishable key as `fallbackKey` so that development\n * instances (pk_test_) are returned as-is instead of being incorrectly derived\n * from the host (e.g. localhost).\n *\n * @example\n * // React (use window.location.hostname, not window.location.host, to avoid including the port)\n * <ClerkProvider publishableKey={publishableKeyFromHost(window.location.hostname, import.meta.env.VITE_CLERK_PUBLISHABLE_KEY)}>\n *\n * @example\n * // Express (inside clerkMiddleware callback)\n * // Validate req.hostname against a known allowlist before passing it in.\n * // When `trust proxy` is enabled, req.hostname reads from X-Forwarded-Host\n * // and can be spoofed if your proxy is not properly configured.\n * const ALLOWED_HOSTS = ['domain-a.com', 'domain-b.com'];\n * clerkMiddleware((req) => {\n * if (!ALLOWED_HOSTS.includes(req.hostname)) throw new Error('Unknown host');\n * return { publishableKey: publishableKeyFromHost(req.hostname, process.env.CLERK_PUBLISHABLE_KEY) };\n * })\n */\nexport function publishableKeyFromHost(host: string, fallbackKey?: string): string {\n if (fallbackKey && isDevelopmentFromPublishableKey(fallbackKey)) {\n return fallbackKey;\n }\n const hostname = host.toLowerCase().replace(/:\\d+$/, '');\n if (!hostname) {\n throw new Error('Host must not be empty.');\n }\n return buildPublishableKey(`clerk.${hostname}`);\n}\n\n/**\n * Validates that a decoded publishable key has the correct format.\n * The decoded value should be a frontend API followed by exactly one '$' at the end.\n *\n * @param decoded - The decoded publishable key string to validate.\n * @returns `true` if the decoded key has valid format, `false` otherwise.\n */\nfunction isValidDecodedPublishableKey(decoded: string): boolean {\n if (!decoded.endsWith('$')) {\n return false;\n }\n\n const withoutTrailing = decoded.slice(0, -1);\n if (withoutTrailing.includes('$')) {\n return false;\n }\n\n return withoutTrailing.includes('.');\n}\n\nconst fatalKeyGuidance = `To create a Clerk application with valid keys, run:\n\n npx clerk@latest init\n\nThe command is non-interactive and requires no Clerk account or login. If you already have a Clerk application, run \\`npx clerk@latest env pull\\` to write its keys to your env file (\\`--instance prod\\` for production keys), or copy them from https://dashboard.clerk.com/last-active?path=api-keys.`;\n\nexport function parsePublishableKey(\n key: string | undefined,\n options: ParsePublishableKeyOptions & { fatal: true },\n): PublishableKey;\nexport function parsePublishableKey(\n key: string | undefined,\n options?: ParsePublishableKeyOptions,\n): PublishableKey | null;\n/**\n * Parses and validates a publishable key, extracting the frontend API and instance type.\n *\n * @param key - The publishable key to parse.\n * @param options - Configuration options for parsing.\n * @param options.fatal\n * @param options.domain\n * @param options.proxyUrl\n * @param options.isSatellite\n * @returns Parsed publishable key object with instanceType and frontendApi, or null if invalid.\n *\n * @throws {Error} When options.fatal is true and key is missing or invalid.\n */\nexport function parsePublishableKey(\n key: string | undefined,\n options: { fatal?: boolean; domain?: string; proxyUrl?: string; isSatellite?: boolean } = {},\n): PublishableKey | null {\n key = key || '';\n\n if (!key || !isPublishableKey(key)) {\n if (options.fatal && !key) {\n throw new Error(`Publishable key is missing. ${fatalKeyGuidance}`);\n }\n if (options.fatal && !isPublishableKey(key)) {\n throw new Error(`Publishable key not valid (expected format: pk_test_... or pk_live_...). ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n const instanceType = key.startsWith(PUBLISHABLE_KEY_LIVE_PREFIX) ? 'production' : 'development';\n\n let decodedFrontendApi: string;\n try {\n decodedFrontendApi = isomorphicAtob(key.split('_')[2]);\n } catch {\n if (options.fatal) {\n throw new Error(`Publishable key not valid: Failed to decode key. ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n if (!isValidDecodedPublishableKey(decodedFrontendApi)) {\n if (options.fatal) {\n throw new Error(`Publishable key not valid: Decoded key has invalid format. ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n let frontendApi = decodedFrontendApi.slice(0, -1);\n\n if (options.proxyUrl) {\n frontendApi = options.proxyUrl;\n } else if (instanceType !== 'development' && options.domain && options.isSatellite) {\n frontendApi = `clerk.${options.domain}`;\n }\n\n return {\n instanceType,\n frontendApi,\n };\n}\n\n/**\n * Checks if the provided key is a valid publishable key.\n *\n * @param key - The key to be checked. Defaults to an empty string if not provided.\n * @returns `true` if 'key' is a valid publishable key, `false` otherwise.\n */\nexport function isPublishableKey(key: string = '') {\n try {\n const hasValidPrefix = key.startsWith(PUBLISHABLE_KEY_LIVE_PREFIX) || key.startsWith(PUBLISHABLE_KEY_TEST_PREFIX);\n\n if (!hasValidPrefix) {\n return false;\n }\n\n const parts = key.split('_');\n if (parts.length !== 3) {\n return false;\n }\n\n const encodedPart = parts[2];\n if (!encodedPart) {\n return false;\n }\n\n const decoded = isomorphicAtob(encodedPart);\n return isValidDecodedPublishableKey(decoded);\n } catch {\n return false;\n }\n}\n\n/**\n * Creates a memoized cache for checking if URLs are development or staging environments.\n * Uses a Map to cache results for better performance on repeated checks.\n *\n * @returns An object with an isDevOrStagingUrl method that checks if a URL is dev/staging.\n */\nexport function createDevOrStagingUrlCache() {\n const devOrStagingUrlCache = new Map<string, boolean>();\n\n return {\n /**\n * Checks if a URL is a development or staging environment.\n *\n * @param url - The URL to check (string or URL object).\n * @returns `true` if the URL is a development or staging environment, `false` otherwise.\n */\n isDevOrStagingUrl: (url: string | URL): boolean => {\n if (!url) {\n return false;\n }\n\n const hostname = typeof url === 'string' ? url : url.hostname;\n let res = devOrStagingUrlCache.get(hostname);\n if (res === undefined) {\n res = DEV_OR_STAGING_SUFFIXES.some(s => hostname.endsWith(s));\n devOrStagingUrlCache.set(hostname, res);\n }\n return res;\n },\n };\n}\n\n/**\n * Checks if a publishable key is for a development environment.\n * Supports both legacy format (test_) and new format (pk_test_).\n *\n * @param apiKey - The API key to check.\n * @returns `true` if the key is for development, `false` otherwise.\n */\nexport function isDevelopmentFromPublishableKey(apiKey: string): boolean {\n return apiKey.startsWith('test_') || apiKey.startsWith('pk_test_');\n}\n\n/**\n * Checks if a publishable key is for a production environment.\n * Supports both legacy format (live_) and new format (pk_live_).\n *\n * @param apiKey - The API key to check.\n * @returns `true` if the key is for production, `false` otherwise.\n */\nexport function isProductionFromPublishableKey(apiKey: string): boolean {\n return apiKey.startsWith('live_') || apiKey.startsWith('pk_live_');\n}\n\n/**\n * Checks if a secret key is for a development environment.\n * Supports both legacy format (test_) and new format (sk_test_).\n *\n * @param apiKey - The secret key to check.\n * @returns `true` if the key is for development, `false` otherwise.\n */\nexport function isDevelopmentFromSecretKey(apiKey: string): boolean {\n return apiKey.startsWith('test_') || apiKey.startsWith('sk_test_');\n}\n\n/**\n * Checks if a secret key is for a production environment.\n * Supports both legacy format (live_) and new format (sk_live_).\n *\n * @param apiKey - The secret key to check.\n * @returns `true` if the key is for production, `false` otherwise.\n */\nexport function isProductionFromSecretKey(apiKey: string): boolean {\n return apiKey.startsWith('live_') || apiKey.startsWith('sk_live_');\n}\n\n/**\n * Generates a unique cookie suffix based on the publishable key using SHA-1 hashing.\n * The suffix is base64-encoded and URL-safe (+ and / characters are replaced).\n *\n * @param publishableKey - The publishable key to generate suffix from.\n * @param subtle - The SubtleCrypto interface to use for hashing (defaults to globalThis.crypto.subtle).\n * @returns A promise that resolves to an 8-character URL-safe base64 string.\n */\nexport async function getCookieSuffix(\n publishableKey: string,\n subtle: SubtleCrypto = globalThis.crypto.subtle,\n): Promise<string> {\n const data = new TextEncoder().encode(publishableKey);\n const digest = await subtle.digest('sha-1', data);\n const stringDigest = String.fromCharCode(...new Uint8Array(digest));\n // Base 64 Encoding with URL and Filename Safe Alphabet: https://datatracker.ietf.org/doc/html/rfc4648#section-5\n return isomorphicBtoa(stringDigest).replace(/\\+/gi, '-').replace(/\\//gi, '_').substring(0, 8);\n}\n\n/**\n * Creates a suffixed cookie name by appending the cookie suffix to the base name.\n * Used to create unique cookie names based on the publishable key.\n *\n * @param cookieName - The base cookie name.\n * @param cookieSuffix - The suffix to append (typically generated by getCookieSuffix).\n * @returns The suffixed cookie name in format: `${cookieName}_${cookieSuffix}`.\n */\nexport const getSuffixedCookieName = (cookieName: string, cookieSuffix: string): string => {\n return `${cookieName}_${cookieSuffix}`;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"keys.js","names":["LEGACY_DEV_INSTANCE_SUFFIXES","isomorphicBtoa","isomorphicAtob","DEV_OR_STAGING_SUFFIXES"],"sources":["../src/keys.ts"],"sourcesContent":["import { DEV_OR_STAGING_SUFFIXES, LEGACY_DEV_INSTANCE_SUFFIXES } from './constants';\nimport { isomorphicAtob } from './isomorphicAtob';\nimport { isomorphicBtoa } from './isomorphicBtoa';\nimport type { PublishableKey } from './types';\n\n/**\n * Configuration options for parsing publishable keys.\n */\ntype ParsePublishableKeyOptions = {\n /** Whether to throw an error if parsing fails */\n fatal?: boolean;\n /** Custom domain to use for satellite instances */\n domain?: string;\n /** Proxy URL to use instead of the decoded frontend API */\n proxyUrl?: string;\n /** Whether this is a satellite instance */\n isSatellite?: boolean;\n};\n\n/** Prefix used for production publishable keys */\nconst PUBLISHABLE_KEY_LIVE_PREFIX = 'pk_live_';\n\n/** Prefix used for development publishable keys */\nconst PUBLISHABLE_KEY_TEST_PREFIX = 'pk_test_';\n\n/**\n * Regular expression that matches development frontend API keys.\n * Matches patterns like: foo-bar-13.clerk.accounts.dev.\n */\nconst PUBLISHABLE_FRONTEND_API_DEV_REGEX = /^(([a-z]+)-){2}([0-9]{1,2})\\.clerk\\.accounts([a-z.]*)(dev|com)$/i;\n\n/**\n * Converts a frontend API URL into an unpadded base64-encoded publishable key.\n *\n * @param frontendApi - The frontend API URL (e.g., 'clerk.example.com').\n * @returns An unpadded base64-encoded publishable key with appropriate prefix (pk_live_ or pk_test_).\n */\nexport function buildPublishableKey(frontendApi: string): string {\n const isDevKey =\n PUBLISHABLE_FRONTEND_API_DEV_REGEX.test(frontendApi) ||\n (frontendApi.startsWith('clerk.') && LEGACY_DEV_INSTANCE_SUFFIXES.some(s => frontendApi.endsWith(s)));\n const keyPrefix = isDevKey ? PUBLISHABLE_KEY_TEST_PREFIX : PUBLISHABLE_KEY_LIVE_PREFIX;\n return `${keyPrefix}${isomorphicBtoa(`${frontendApi}$`).replace(/=+$/, '')}`;\n}\n\n/**\n * Derives a publishable key from the current hostname. Intended for multi-domain\n * setups (e.g. custom domains on top of a default domain) where the correct key\n * must be resolved per request.\n *\n * Pass the configured publishable key as `fallbackKey` so that development\n * instances (pk_test_) are returned as-is instead of being incorrectly derived\n * from the host (e.g. localhost).\n *\n * @example\n * // React (use window.location.hostname, not window.location.host, to avoid including the port)\n * <ClerkProvider publishableKey={publishableKeyFromHost(window.location.hostname, import.meta.env.VITE_CLERK_PUBLISHABLE_KEY)}>\n *\n * @example\n * // Express (inside clerkMiddleware callback)\n * // Validate req.hostname against a known allowlist before passing it in.\n * // When `trust proxy` is enabled, req.hostname reads from X-Forwarded-Host\n * // and can be spoofed if your proxy is not properly configured.\n * const ALLOWED_HOSTS = ['domain-a.com', 'domain-b.com'];\n * clerkMiddleware((req) => {\n * if (!ALLOWED_HOSTS.includes(req.hostname)) throw new Error('Unknown host');\n * return { publishableKey: publishableKeyFromHost(req.hostname, process.env.CLERK_PUBLISHABLE_KEY) };\n * })\n */\nexport function publishableKeyFromHost(host: string, fallbackKey?: string): string {\n if (fallbackKey && isDevelopmentFromPublishableKey(fallbackKey)) {\n return fallbackKey;\n }\n const hostname = host.toLowerCase().replace(/:\\d+$/, '');\n if (!hostname) {\n throw new Error('Host must not be empty.');\n }\n return buildPublishableKey(`clerk.${hostname}`);\n}\n\n/**\n * Validates that a decoded publishable key has the correct format.\n * The decoded value should be a frontend API followed by exactly one '$' at the end.\n *\n * @param decoded - The decoded publishable key string to validate.\n * @returns `true` if the decoded key has valid format, `false` otherwise.\n */\nfunction isValidDecodedPublishableKey(decoded: string): boolean {\n if (!decoded.endsWith('$')) {\n return false;\n }\n\n const withoutTrailing = decoded.slice(0, -1);\n if (withoutTrailing.includes('$')) {\n return false;\n }\n\n return withoutTrailing.includes('.');\n}\n\nconst fatalKeyGuidance = `To create a Clerk application with valid keys, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run \\`npx clerk@latest env pull\\` to write the keys (\\`--instance prod\\` for production keys). Or copy them from https://dashboard.clerk.com/last-active?path=api-keys.`;\n\nexport function parsePublishableKey(\n key: string | undefined,\n options: ParsePublishableKeyOptions & { fatal: true },\n): PublishableKey;\nexport function parsePublishableKey(\n key: string | undefined,\n options?: ParsePublishableKeyOptions,\n): PublishableKey | null;\n/**\n * Parses and validates a publishable key, extracting the frontend API and instance type.\n *\n * @param key - The publishable key to parse.\n * @param options - Configuration options for parsing.\n * @param options.fatal\n * @param options.domain\n * @param options.proxyUrl\n * @param options.isSatellite\n * @returns Parsed publishable key object with instanceType and frontendApi, or null if invalid.\n *\n * @throws {Error} When options.fatal is true and key is missing or invalid.\n */\nexport function parsePublishableKey(\n key: string | undefined,\n options: { fatal?: boolean; domain?: string; proxyUrl?: string; isSatellite?: boolean } = {},\n): PublishableKey | null {\n key = key || '';\n\n if (!key || !isPublishableKey(key)) {\n if (options.fatal && !key) {\n throw new Error(`Publishable key is missing. ${fatalKeyGuidance}`);\n }\n if (options.fatal && !isPublishableKey(key)) {\n throw new Error(`Publishable key not valid (expected format: pk_test_... or pk_live_...). ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n const instanceType = key.startsWith(PUBLISHABLE_KEY_LIVE_PREFIX) ? 'production' : 'development';\n\n let decodedFrontendApi: string;\n try {\n decodedFrontendApi = isomorphicAtob(key.split('_')[2]);\n } catch {\n if (options.fatal) {\n throw new Error(`Publishable key not valid: Failed to decode key. ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n if (!isValidDecodedPublishableKey(decodedFrontendApi)) {\n if (options.fatal) {\n throw new Error(`Publishable key not valid: Decoded key has invalid format. ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n let frontendApi = decodedFrontendApi.slice(0, -1);\n\n if (options.proxyUrl) {\n frontendApi = options.proxyUrl;\n } else if (instanceType !== 'development' && options.domain && options.isSatellite) {\n frontendApi = `clerk.${options.domain}`;\n }\n\n return {\n instanceType,\n frontendApi,\n };\n}\n\n/**\n * Checks if the provided key is a valid publishable key.\n *\n * @param key - The key to be checked. Defaults to an empty string if not provided.\n * @returns `true` if 'key' is a valid publishable key, `false` otherwise.\n */\nexport function isPublishableKey(key: string = '') {\n try {\n const hasValidPrefix = key.startsWith(PUBLISHABLE_KEY_LIVE_PREFIX) || key.startsWith(PUBLISHABLE_KEY_TEST_PREFIX);\n\n if (!hasValidPrefix) {\n return false;\n }\n\n const parts = key.split('_');\n if (parts.length !== 3) {\n return false;\n }\n\n const encodedPart = parts[2];\n if (!encodedPart) {\n return false;\n }\n\n const decoded = isomorphicAtob(encodedPart);\n return isValidDecodedPublishableKey(decoded);\n } catch {\n return false;\n }\n}\n\n/**\n * Creates a memoized cache for checking if URLs are development or staging environments.\n * Uses a Map to cache results for better performance on repeated checks.\n *\n * @returns An object with an isDevOrStagingUrl method that checks if a URL is dev/staging.\n */\nexport function createDevOrStagingUrlCache() {\n const devOrStagingUrlCache = new Map<string, boolean>();\n\n return {\n /**\n * Checks if a URL is a development or staging environment.\n *\n * @param url - The URL to check (string or URL object).\n * @returns `true` if the URL is a development or staging environment, `false` otherwise.\n */\n isDevOrStagingUrl: (url: string | URL): boolean => {\n if (!url) {\n return false;\n }\n\n const hostname = typeof url === 'string' ? url : url.hostname;\n let res = devOrStagingUrlCache.get(hostname);\n if (res === undefined) {\n res = DEV_OR_STAGING_SUFFIXES.some(s => hostname.endsWith(s));\n devOrStagingUrlCache.set(hostname, res);\n }\n return res;\n },\n };\n}\n\n/**\n * Checks if a publishable key is for a development environment.\n * Supports both legacy format (test_) and new format (pk_test_).\n *\n * @param apiKey - The API key to check.\n * @returns `true` if the key is for development, `false` otherwise.\n */\nexport function isDevelopmentFromPublishableKey(apiKey: string): boolean {\n return apiKey.startsWith('test_') || apiKey.startsWith('pk_test_');\n}\n\n/**\n * Checks if a publishable key is for a production environment.\n * Supports both legacy format (live_) and new format (pk_live_).\n *\n * @param apiKey - The API key to check.\n * @returns `true` if the key is for production, `false` otherwise.\n */\nexport function isProductionFromPublishableKey(apiKey: string): boolean {\n return apiKey.startsWith('live_') || apiKey.startsWith('pk_live_');\n}\n\n/**\n * Checks if a secret key is for a development environment.\n * Supports both legacy format (test_) and new format (sk_test_).\n *\n * @param apiKey - The secret key to check.\n * @returns `true` if the key is for development, `false` otherwise.\n */\nexport function isDevelopmentFromSecretKey(apiKey: string): boolean {\n return apiKey.startsWith('test_') || apiKey.startsWith('sk_test_');\n}\n\n/**\n * Checks if a secret key is for a production environment.\n * Supports both legacy format (live_) and new format (sk_live_).\n *\n * @param apiKey - The secret key to check.\n * @returns `true` if the key is for production, `false` otherwise.\n */\nexport function isProductionFromSecretKey(apiKey: string): boolean {\n return apiKey.startsWith('live_') || apiKey.startsWith('sk_live_');\n}\n\n/**\n * Generates a unique cookie suffix based on the publishable key using SHA-1 hashing.\n * The suffix is base64-encoded and URL-safe (+ and / characters are replaced).\n *\n * @param publishableKey - The publishable key to generate suffix from.\n * @param subtle - The SubtleCrypto interface to use for hashing (defaults to globalThis.crypto.subtle).\n * @returns A promise that resolves to an 8-character URL-safe base64 string.\n */\nexport async function getCookieSuffix(\n publishableKey: string,\n subtle: SubtleCrypto = globalThis.crypto.subtle,\n): Promise<string> {\n const data = new TextEncoder().encode(publishableKey);\n const digest = await subtle.digest('sha-1', data);\n const stringDigest = String.fromCharCode(...new Uint8Array(digest));\n // Base 64 Encoding with URL and Filename Safe Alphabet: https://datatracker.ietf.org/doc/html/rfc4648#section-5\n return isomorphicBtoa(stringDigest).replace(/\\+/gi, '-').replace(/\\//gi, '_').substring(0, 8);\n}\n\n/**\n * Creates a suffixed cookie name by appending the cookie suffix to the base name.\n * Used to create unique cookie names based on the publishable key.\n *\n * @param cookieName - The base cookie name.\n * @param cookieSuffix - The suffix to append (typically generated by getCookieSuffix).\n * @returns The suffixed cookie name in format: `${cookieName}_${cookieSuffix}`.\n */\nexport const getSuffixedCookieName = (cookieName: string, cookieSuffix: string): string => {\n return `${cookieName}_${cookieSuffix}`;\n};\n"],"mappings":"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"}
|
package/dist/keys.mjs
CHANGED
|
@@ -64,11 +64,13 @@ function isValidDecodedPublishableKey(decoded) {
|
|
|
64
64
|
if (withoutTrailing.includes("$")) return false;
|
|
65
65
|
return withoutTrailing.includes(".");
|
|
66
66
|
}
|
|
67
|
-
const fatalKeyGuidance = `To create a Clerk application with valid keys, run:
|
|
67
|
+
const fatalKeyGuidance = `To create a Clerk application with valid keys, in your terminal run:
|
|
68
68
|
|
|
69
69
|
npx clerk@latest init
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
It creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.
|
|
72
|
+
|
|
73
|
+
If you have a Clerk application, run \`npx clerk@latest env pull\` to write the keys (\`--instance prod\` for production keys). Or copy them from https://dashboard.clerk.com/last-active?path=api-keys.`;
|
|
72
74
|
/**
|
|
73
75
|
* Parses and validates a publishable key, extracting the frontend API and instance type.
|
|
74
76
|
*
|
package/dist/keys.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.mjs","names":[],"sources":["../src/keys.ts"],"sourcesContent":["import { DEV_OR_STAGING_SUFFIXES, LEGACY_DEV_INSTANCE_SUFFIXES } from './constants';\nimport { isomorphicAtob } from './isomorphicAtob';\nimport { isomorphicBtoa } from './isomorphicBtoa';\nimport type { PublishableKey } from './types';\n\n/**\n * Configuration options for parsing publishable keys.\n */\ntype ParsePublishableKeyOptions = {\n /** Whether to throw an error if parsing fails */\n fatal?: boolean;\n /** Custom domain to use for satellite instances */\n domain?: string;\n /** Proxy URL to use instead of the decoded frontend API */\n proxyUrl?: string;\n /** Whether this is a satellite instance */\n isSatellite?: boolean;\n};\n\n/** Prefix used for production publishable keys */\nconst PUBLISHABLE_KEY_LIVE_PREFIX = 'pk_live_';\n\n/** Prefix used for development publishable keys */\nconst PUBLISHABLE_KEY_TEST_PREFIX = 'pk_test_';\n\n/**\n * Regular expression that matches development frontend API keys.\n * Matches patterns like: foo-bar-13.clerk.accounts.dev.\n */\nconst PUBLISHABLE_FRONTEND_API_DEV_REGEX = /^(([a-z]+)-){2}([0-9]{1,2})\\.clerk\\.accounts([a-z.]*)(dev|com)$/i;\n\n/**\n * Converts a frontend API URL into an unpadded base64-encoded publishable key.\n *\n * @param frontendApi - The frontend API URL (e.g., 'clerk.example.com').\n * @returns An unpadded base64-encoded publishable key with appropriate prefix (pk_live_ or pk_test_).\n */\nexport function buildPublishableKey(frontendApi: string): string {\n const isDevKey =\n PUBLISHABLE_FRONTEND_API_DEV_REGEX.test(frontendApi) ||\n (frontendApi.startsWith('clerk.') && LEGACY_DEV_INSTANCE_SUFFIXES.some(s => frontendApi.endsWith(s)));\n const keyPrefix = isDevKey ? PUBLISHABLE_KEY_TEST_PREFIX : PUBLISHABLE_KEY_LIVE_PREFIX;\n return `${keyPrefix}${isomorphicBtoa(`${frontendApi}$`).replace(/=+$/, '')}`;\n}\n\n/**\n * Derives a publishable key from the current hostname. Intended for multi-domain\n * setups (e.g. custom domains on top of a default domain) where the correct key\n * must be resolved per request.\n *\n * Pass the configured publishable key as `fallbackKey` so that development\n * instances (pk_test_) are returned as-is instead of being incorrectly derived\n * from the host (e.g. localhost).\n *\n * @example\n * // React (use window.location.hostname, not window.location.host, to avoid including the port)\n * <ClerkProvider publishableKey={publishableKeyFromHost(window.location.hostname, import.meta.env.VITE_CLERK_PUBLISHABLE_KEY)}>\n *\n * @example\n * // Express (inside clerkMiddleware callback)\n * // Validate req.hostname against a known allowlist before passing it in.\n * // When `trust proxy` is enabled, req.hostname reads from X-Forwarded-Host\n * // and can be spoofed if your proxy is not properly configured.\n * const ALLOWED_HOSTS = ['domain-a.com', 'domain-b.com'];\n * clerkMiddleware((req) => {\n * if (!ALLOWED_HOSTS.includes(req.hostname)) throw new Error('Unknown host');\n * return { publishableKey: publishableKeyFromHost(req.hostname, process.env.CLERK_PUBLISHABLE_KEY) };\n * })\n */\nexport function publishableKeyFromHost(host: string, fallbackKey?: string): string {\n if (fallbackKey && isDevelopmentFromPublishableKey(fallbackKey)) {\n return fallbackKey;\n }\n const hostname = host.toLowerCase().replace(/:\\d+$/, '');\n if (!hostname) {\n throw new Error('Host must not be empty.');\n }\n return buildPublishableKey(`clerk.${hostname}`);\n}\n\n/**\n * Validates that a decoded publishable key has the correct format.\n * The decoded value should be a frontend API followed by exactly one '$' at the end.\n *\n * @param decoded - The decoded publishable key string to validate.\n * @returns `true` if the decoded key has valid format, `false` otherwise.\n */\nfunction isValidDecodedPublishableKey(decoded: string): boolean {\n if (!decoded.endsWith('$')) {\n return false;\n }\n\n const withoutTrailing = decoded.slice(0, -1);\n if (withoutTrailing.includes('$')) {\n return false;\n }\n\n return withoutTrailing.includes('.');\n}\n\nconst fatalKeyGuidance = `To create a Clerk application with valid keys, run:\n\n npx clerk@latest init\n\nThe command is non-interactive and requires no Clerk account or login. If you already have a Clerk application, run \\`npx clerk@latest env pull\\` to write its keys to your env file (\\`--instance prod\\` for production keys), or copy them from https://dashboard.clerk.com/last-active?path=api-keys.`;\n\nexport function parsePublishableKey(\n key: string | undefined,\n options: ParsePublishableKeyOptions & { fatal: true },\n): PublishableKey;\nexport function parsePublishableKey(\n key: string | undefined,\n options?: ParsePublishableKeyOptions,\n): PublishableKey | null;\n/**\n * Parses and validates a publishable key, extracting the frontend API and instance type.\n *\n * @param key - The publishable key to parse.\n * @param options - Configuration options for parsing.\n * @param options.fatal\n * @param options.domain\n * @param options.proxyUrl\n * @param options.isSatellite\n * @returns Parsed publishable key object with instanceType and frontendApi, or null if invalid.\n *\n * @throws {Error} When options.fatal is true and key is missing or invalid.\n */\nexport function parsePublishableKey(\n key: string | undefined,\n options: { fatal?: boolean; domain?: string; proxyUrl?: string; isSatellite?: boolean } = {},\n): PublishableKey | null {\n key = key || '';\n\n if (!key || !isPublishableKey(key)) {\n if (options.fatal && !key) {\n throw new Error(`Publishable key is missing. ${fatalKeyGuidance}`);\n }\n if (options.fatal && !isPublishableKey(key)) {\n throw new Error(`Publishable key not valid (expected format: pk_test_... or pk_live_...). ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n const instanceType = key.startsWith(PUBLISHABLE_KEY_LIVE_PREFIX) ? 'production' : 'development';\n\n let decodedFrontendApi: string;\n try {\n decodedFrontendApi = isomorphicAtob(key.split('_')[2]);\n } catch {\n if (options.fatal) {\n throw new Error(`Publishable key not valid: Failed to decode key. ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n if (!isValidDecodedPublishableKey(decodedFrontendApi)) {\n if (options.fatal) {\n throw new Error(`Publishable key not valid: Decoded key has invalid format. ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n let frontendApi = decodedFrontendApi.slice(0, -1);\n\n if (options.proxyUrl) {\n frontendApi = options.proxyUrl;\n } else if (instanceType !== 'development' && options.domain && options.isSatellite) {\n frontendApi = `clerk.${options.domain}`;\n }\n\n return {\n instanceType,\n frontendApi,\n };\n}\n\n/**\n * Checks if the provided key is a valid publishable key.\n *\n * @param key - The key to be checked. Defaults to an empty string if not provided.\n * @returns `true` if 'key' is a valid publishable key, `false` otherwise.\n */\nexport function isPublishableKey(key: string = '') {\n try {\n const hasValidPrefix = key.startsWith(PUBLISHABLE_KEY_LIVE_PREFIX) || key.startsWith(PUBLISHABLE_KEY_TEST_PREFIX);\n\n if (!hasValidPrefix) {\n return false;\n }\n\n const parts = key.split('_');\n if (parts.length !== 3) {\n return false;\n }\n\n const encodedPart = parts[2];\n if (!encodedPart) {\n return false;\n }\n\n const decoded = isomorphicAtob(encodedPart);\n return isValidDecodedPublishableKey(decoded);\n } catch {\n return false;\n }\n}\n\n/**\n * Creates a memoized cache for checking if URLs are development or staging environments.\n * Uses a Map to cache results for better performance on repeated checks.\n *\n * @returns An object with an isDevOrStagingUrl method that checks if a URL is dev/staging.\n */\nexport function createDevOrStagingUrlCache() {\n const devOrStagingUrlCache = new Map<string, boolean>();\n\n return {\n /**\n * Checks if a URL is a development or staging environment.\n *\n * @param url - The URL to check (string or URL object).\n * @returns `true` if the URL is a development or staging environment, `false` otherwise.\n */\n isDevOrStagingUrl: (url: string | URL): boolean => {\n if (!url) {\n return false;\n }\n\n const hostname = typeof url === 'string' ? url : url.hostname;\n let res = devOrStagingUrlCache.get(hostname);\n if (res === undefined) {\n res = DEV_OR_STAGING_SUFFIXES.some(s => hostname.endsWith(s));\n devOrStagingUrlCache.set(hostname, res);\n }\n return res;\n },\n };\n}\n\n/**\n * Checks if a publishable key is for a development environment.\n * Supports both legacy format (test_) and new format (pk_test_).\n *\n * @param apiKey - The API key to check.\n * @returns `true` if the key is for development, `false` otherwise.\n */\nexport function isDevelopmentFromPublishableKey(apiKey: string): boolean {\n return apiKey.startsWith('test_') || apiKey.startsWith('pk_test_');\n}\n\n/**\n * Checks if a publishable key is for a production environment.\n * Supports both legacy format (live_) and new format (pk_live_).\n *\n * @param apiKey - The API key to check.\n * @returns `true` if the key is for production, `false` otherwise.\n */\nexport function isProductionFromPublishableKey(apiKey: string): boolean {\n return apiKey.startsWith('live_') || apiKey.startsWith('pk_live_');\n}\n\n/**\n * Checks if a secret key is for a development environment.\n * Supports both legacy format (test_) and new format (sk_test_).\n *\n * @param apiKey - The secret key to check.\n * @returns `true` if the key is for development, `false` otherwise.\n */\nexport function isDevelopmentFromSecretKey(apiKey: string): boolean {\n return apiKey.startsWith('test_') || apiKey.startsWith('sk_test_');\n}\n\n/**\n * Checks if a secret key is for a production environment.\n * Supports both legacy format (live_) and new format (sk_live_).\n *\n * @param apiKey - The secret key to check.\n * @returns `true` if the key is for production, `false` otherwise.\n */\nexport function isProductionFromSecretKey(apiKey: string): boolean {\n return apiKey.startsWith('live_') || apiKey.startsWith('sk_live_');\n}\n\n/**\n * Generates a unique cookie suffix based on the publishable key using SHA-1 hashing.\n * The suffix is base64-encoded and URL-safe (+ and / characters are replaced).\n *\n * @param publishableKey - The publishable key to generate suffix from.\n * @param subtle - The SubtleCrypto interface to use for hashing (defaults to globalThis.crypto.subtle).\n * @returns A promise that resolves to an 8-character URL-safe base64 string.\n */\nexport async function getCookieSuffix(\n publishableKey: string,\n subtle: SubtleCrypto = globalThis.crypto.subtle,\n): Promise<string> {\n const data = new TextEncoder().encode(publishableKey);\n const digest = await subtle.digest('sha-1', data);\n const stringDigest = String.fromCharCode(...new Uint8Array(digest));\n // Base 64 Encoding with URL and Filename Safe Alphabet: https://datatracker.ietf.org/doc/html/rfc4648#section-5\n return isomorphicBtoa(stringDigest).replace(/\\+/gi, '-').replace(/\\//gi, '_').substring(0, 8);\n}\n\n/**\n * Creates a suffixed cookie name by appending the cookie suffix to the base name.\n * Used to create unique cookie names based on the publishable key.\n *\n * @param cookieName - The base cookie name.\n * @param cookieSuffix - The suffix to append (typically generated by getCookieSuffix).\n * @returns The suffixed cookie name in format: `${cookieName}_${cookieSuffix}`.\n */\nexport const getSuffixedCookieName = (cookieName: string, cookieSuffix: string): string => {\n return `${cookieName}_${cookieSuffix}`;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"keys.mjs","names":[],"sources":["../src/keys.ts"],"sourcesContent":["import { DEV_OR_STAGING_SUFFIXES, LEGACY_DEV_INSTANCE_SUFFIXES } from './constants';\nimport { isomorphicAtob } from './isomorphicAtob';\nimport { isomorphicBtoa } from './isomorphicBtoa';\nimport type { PublishableKey } from './types';\n\n/**\n * Configuration options for parsing publishable keys.\n */\ntype ParsePublishableKeyOptions = {\n /** Whether to throw an error if parsing fails */\n fatal?: boolean;\n /** Custom domain to use for satellite instances */\n domain?: string;\n /** Proxy URL to use instead of the decoded frontend API */\n proxyUrl?: string;\n /** Whether this is a satellite instance */\n isSatellite?: boolean;\n};\n\n/** Prefix used for production publishable keys */\nconst PUBLISHABLE_KEY_LIVE_PREFIX = 'pk_live_';\n\n/** Prefix used for development publishable keys */\nconst PUBLISHABLE_KEY_TEST_PREFIX = 'pk_test_';\n\n/**\n * Regular expression that matches development frontend API keys.\n * Matches patterns like: foo-bar-13.clerk.accounts.dev.\n */\nconst PUBLISHABLE_FRONTEND_API_DEV_REGEX = /^(([a-z]+)-){2}([0-9]{1,2})\\.clerk\\.accounts([a-z.]*)(dev|com)$/i;\n\n/**\n * Converts a frontend API URL into an unpadded base64-encoded publishable key.\n *\n * @param frontendApi - The frontend API URL (e.g., 'clerk.example.com').\n * @returns An unpadded base64-encoded publishable key with appropriate prefix (pk_live_ or pk_test_).\n */\nexport function buildPublishableKey(frontendApi: string): string {\n const isDevKey =\n PUBLISHABLE_FRONTEND_API_DEV_REGEX.test(frontendApi) ||\n (frontendApi.startsWith('clerk.') && LEGACY_DEV_INSTANCE_SUFFIXES.some(s => frontendApi.endsWith(s)));\n const keyPrefix = isDevKey ? PUBLISHABLE_KEY_TEST_PREFIX : PUBLISHABLE_KEY_LIVE_PREFIX;\n return `${keyPrefix}${isomorphicBtoa(`${frontendApi}$`).replace(/=+$/, '')}`;\n}\n\n/**\n * Derives a publishable key from the current hostname. Intended for multi-domain\n * setups (e.g. custom domains on top of a default domain) where the correct key\n * must be resolved per request.\n *\n * Pass the configured publishable key as `fallbackKey` so that development\n * instances (pk_test_) are returned as-is instead of being incorrectly derived\n * from the host (e.g. localhost).\n *\n * @example\n * // React (use window.location.hostname, not window.location.host, to avoid including the port)\n * <ClerkProvider publishableKey={publishableKeyFromHost(window.location.hostname, import.meta.env.VITE_CLERK_PUBLISHABLE_KEY)}>\n *\n * @example\n * // Express (inside clerkMiddleware callback)\n * // Validate req.hostname against a known allowlist before passing it in.\n * // When `trust proxy` is enabled, req.hostname reads from X-Forwarded-Host\n * // and can be spoofed if your proxy is not properly configured.\n * const ALLOWED_HOSTS = ['domain-a.com', 'domain-b.com'];\n * clerkMiddleware((req) => {\n * if (!ALLOWED_HOSTS.includes(req.hostname)) throw new Error('Unknown host');\n * return { publishableKey: publishableKeyFromHost(req.hostname, process.env.CLERK_PUBLISHABLE_KEY) };\n * })\n */\nexport function publishableKeyFromHost(host: string, fallbackKey?: string): string {\n if (fallbackKey && isDevelopmentFromPublishableKey(fallbackKey)) {\n return fallbackKey;\n }\n const hostname = host.toLowerCase().replace(/:\\d+$/, '');\n if (!hostname) {\n throw new Error('Host must not be empty.');\n }\n return buildPublishableKey(`clerk.${hostname}`);\n}\n\n/**\n * Validates that a decoded publishable key has the correct format.\n * The decoded value should be a frontend API followed by exactly one '$' at the end.\n *\n * @param decoded - The decoded publishable key string to validate.\n * @returns `true` if the decoded key has valid format, `false` otherwise.\n */\nfunction isValidDecodedPublishableKey(decoded: string): boolean {\n if (!decoded.endsWith('$')) {\n return false;\n }\n\n const withoutTrailing = decoded.slice(0, -1);\n if (withoutTrailing.includes('$')) {\n return false;\n }\n\n return withoutTrailing.includes('.');\n}\n\nconst fatalKeyGuidance = `To create a Clerk application with valid keys, in your terminal run:\n\n npx clerk@latest init\n\nIt creates a Clerk application and writes keys to your .env file. Requires no Clerk account or login and the command is non-interactive.\n\nIf you have a Clerk application, run \\`npx clerk@latest env pull\\` to write the keys (\\`--instance prod\\` for production keys). Or copy them from https://dashboard.clerk.com/last-active?path=api-keys.`;\n\nexport function parsePublishableKey(\n key: string | undefined,\n options: ParsePublishableKeyOptions & { fatal: true },\n): PublishableKey;\nexport function parsePublishableKey(\n key: string | undefined,\n options?: ParsePublishableKeyOptions,\n): PublishableKey | null;\n/**\n * Parses and validates a publishable key, extracting the frontend API and instance type.\n *\n * @param key - The publishable key to parse.\n * @param options - Configuration options for parsing.\n * @param options.fatal\n * @param options.domain\n * @param options.proxyUrl\n * @param options.isSatellite\n * @returns Parsed publishable key object with instanceType and frontendApi, or null if invalid.\n *\n * @throws {Error} When options.fatal is true and key is missing or invalid.\n */\nexport function parsePublishableKey(\n key: string | undefined,\n options: { fatal?: boolean; domain?: string; proxyUrl?: string; isSatellite?: boolean } = {},\n): PublishableKey | null {\n key = key || '';\n\n if (!key || !isPublishableKey(key)) {\n if (options.fatal && !key) {\n throw new Error(`Publishable key is missing. ${fatalKeyGuidance}`);\n }\n if (options.fatal && !isPublishableKey(key)) {\n throw new Error(`Publishable key not valid (expected format: pk_test_... or pk_live_...). ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n const instanceType = key.startsWith(PUBLISHABLE_KEY_LIVE_PREFIX) ? 'production' : 'development';\n\n let decodedFrontendApi: string;\n try {\n decodedFrontendApi = isomorphicAtob(key.split('_')[2]);\n } catch {\n if (options.fatal) {\n throw new Error(`Publishable key not valid: Failed to decode key. ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n if (!isValidDecodedPublishableKey(decodedFrontendApi)) {\n if (options.fatal) {\n throw new Error(`Publishable key not valid: Decoded key has invalid format. ${fatalKeyGuidance}`);\n }\n return null;\n }\n\n let frontendApi = decodedFrontendApi.slice(0, -1);\n\n if (options.proxyUrl) {\n frontendApi = options.proxyUrl;\n } else if (instanceType !== 'development' && options.domain && options.isSatellite) {\n frontendApi = `clerk.${options.domain}`;\n }\n\n return {\n instanceType,\n frontendApi,\n };\n}\n\n/**\n * Checks if the provided key is a valid publishable key.\n *\n * @param key - The key to be checked. Defaults to an empty string if not provided.\n * @returns `true` if 'key' is a valid publishable key, `false` otherwise.\n */\nexport function isPublishableKey(key: string = '') {\n try {\n const hasValidPrefix = key.startsWith(PUBLISHABLE_KEY_LIVE_PREFIX) || key.startsWith(PUBLISHABLE_KEY_TEST_PREFIX);\n\n if (!hasValidPrefix) {\n return false;\n }\n\n const parts = key.split('_');\n if (parts.length !== 3) {\n return false;\n }\n\n const encodedPart = parts[2];\n if (!encodedPart) {\n return false;\n }\n\n const decoded = isomorphicAtob(encodedPart);\n return isValidDecodedPublishableKey(decoded);\n } catch {\n return false;\n }\n}\n\n/**\n * Creates a memoized cache for checking if URLs are development or staging environments.\n * Uses a Map to cache results for better performance on repeated checks.\n *\n * @returns An object with an isDevOrStagingUrl method that checks if a URL is dev/staging.\n */\nexport function createDevOrStagingUrlCache() {\n const devOrStagingUrlCache = new Map<string, boolean>();\n\n return {\n /**\n * Checks if a URL is a development or staging environment.\n *\n * @param url - The URL to check (string or URL object).\n * @returns `true` if the URL is a development or staging environment, `false` otherwise.\n */\n isDevOrStagingUrl: (url: string | URL): boolean => {\n if (!url) {\n return false;\n }\n\n const hostname = typeof url === 'string' ? url : url.hostname;\n let res = devOrStagingUrlCache.get(hostname);\n if (res === undefined) {\n res = DEV_OR_STAGING_SUFFIXES.some(s => hostname.endsWith(s));\n devOrStagingUrlCache.set(hostname, res);\n }\n return res;\n },\n };\n}\n\n/**\n * Checks if a publishable key is for a development environment.\n * Supports both legacy format (test_) and new format (pk_test_).\n *\n * @param apiKey - The API key to check.\n * @returns `true` if the key is for development, `false` otherwise.\n */\nexport function isDevelopmentFromPublishableKey(apiKey: string): boolean {\n return apiKey.startsWith('test_') || apiKey.startsWith('pk_test_');\n}\n\n/**\n * Checks if a publishable key is for a production environment.\n * Supports both legacy format (live_) and new format (pk_live_).\n *\n * @param apiKey - The API key to check.\n * @returns `true` if the key is for production, `false` otherwise.\n */\nexport function isProductionFromPublishableKey(apiKey: string): boolean {\n return apiKey.startsWith('live_') || apiKey.startsWith('pk_live_');\n}\n\n/**\n * Checks if a secret key is for a development environment.\n * Supports both legacy format (test_) and new format (sk_test_).\n *\n * @param apiKey - The secret key to check.\n * @returns `true` if the key is for development, `false` otherwise.\n */\nexport function isDevelopmentFromSecretKey(apiKey: string): boolean {\n return apiKey.startsWith('test_') || apiKey.startsWith('sk_test_');\n}\n\n/**\n * Checks if a secret key is for a production environment.\n * Supports both legacy format (live_) and new format (sk_live_).\n *\n * @param apiKey - The secret key to check.\n * @returns `true` if the key is for production, `false` otherwise.\n */\nexport function isProductionFromSecretKey(apiKey: string): boolean {\n return apiKey.startsWith('live_') || apiKey.startsWith('sk_live_');\n}\n\n/**\n * Generates a unique cookie suffix based on the publishable key using SHA-1 hashing.\n * The suffix is base64-encoded and URL-safe (+ and / characters are replaced).\n *\n * @param publishableKey - The publishable key to generate suffix from.\n * @param subtle - The SubtleCrypto interface to use for hashing (defaults to globalThis.crypto.subtle).\n * @returns A promise that resolves to an 8-character URL-safe base64 string.\n */\nexport async function getCookieSuffix(\n publishableKey: string,\n subtle: SubtleCrypto = globalThis.crypto.subtle,\n): Promise<string> {\n const data = new TextEncoder().encode(publishableKey);\n const digest = await subtle.digest('sha-1', data);\n const stringDigest = String.fromCharCode(...new Uint8Array(digest));\n // Base 64 Encoding with URL and Filename Safe Alphabet: https://datatracker.ietf.org/doc/html/rfc4648#section-5\n return isomorphicBtoa(stringDigest).replace(/\\+/gi, '-').replace(/\\//gi, '_').substring(0, 8);\n}\n\n/**\n * Creates a suffixed cookie name by appending the cookie suffix to the base name.\n * Used to create unique cookie names based on the publishable key.\n *\n * @param cookieName - The base cookie name.\n * @param cookieSuffix - The suffix to append (typically generated by getCookieSuffix).\n * @returns The suffixed cookie name in format: `${cookieName}_${cookieSuffix}`.\n */\nexport const getSuffixedCookieName = (cookieName: string, cookieSuffix: string): string => {\n return `${cookieName}_${cookieSuffix}`;\n};\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_keys = require('./keys.js');
|
|
3
3
|
const require_clerkRuntimeError = require('./_chunks/clerkRuntimeError-CYZdTZ_x.js');
|
|
4
|
-
const require_error = require('./_chunks/error-
|
|
4
|
+
const require_error = require('./_chunks/error-DiOD3e6d.js');
|
|
5
5
|
const require_loadScript = require('./loadScript.js');
|
|
6
6
|
const require_proxy = require('./proxy.js');
|
|
7
7
|
const require_url = require('./url.js');
|
|
@@ -140,7 +140,7 @@ const clerkJSScriptUrl = (opts) => {
|
|
|
140
140
|
const clerkUIScriptUrl = (opts) => {
|
|
141
141
|
const { __internal_clerkUIUrl, __internal_clerkUIVersion, proxyUrl, domain, publishableKey } = opts;
|
|
142
142
|
if (__internal_clerkUIUrl) return __internal_clerkUIUrl;
|
|
143
|
-
const version = require_versionSelector.versionSelector(__internal_clerkUIVersion, "1.30.
|
|
143
|
+
const version = require_versionSelector.versionSelector(__internal_clerkUIVersion, "1.30.6");
|
|
144
144
|
if (proxyUrl && require_proxy.isProxyUrlRelative(proxyUrl)) return buildRelativeProxyScriptUrl(proxyUrl, "ui", version, "ui.browser.js");
|
|
145
145
|
return `https://${buildScriptHost({
|
|
146
146
|
publishableKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadClerkJsScript.js","names":["createDevOrStagingUrlCache","buildErrorThrower","ClerkRuntimeError","versionSelector","isProxyUrlRelative","isValidProxyUrl","proxyUrlToAbsoluteURL","parsePublishableKey","addClerkPrefix"],"sources":["../src/loadClerkJsScript.ts"],"sourcesContent":["import { buildErrorThrower, ClerkRuntimeError } from './error';\nimport { createDevOrStagingUrlCache, parsePublishableKey } from './keys';\nimport { loadScript } from './loadScript';\nimport { isProxyUrlRelative, isValidProxyUrl, proxyUrlToAbsoluteURL } from './proxy';\nimport type { SDKMetadata } from './types';\nimport { addClerkPrefix } from './url';\nimport { versionSelector } from './versionSelector';\n\nconst { isDevOrStagingUrl } = createDevOrStagingUrlCache();\n\nconst errorThrower = buildErrorThrower({ packageName: '@clerk/shared' });\n\nexport type LoadClerkJSScriptOptions = {\n publishableKey: string;\n /** @internal */\n __internal_clerkJSUrl?: string;\n /** @internal */\n __internal_clerkJSVersion?: string;\n sdkMetadata?: SDKMetadata;\n proxyUrl?: string;\n domain?: string;\n nonce?: string;\n /**\n * Timeout in milliseconds to wait for clerk-js to load before considering it failed.\n *\n * @default 15000 (15 seconds)\n */\n scriptLoadTimeout?: number;\n};\n\n/**\n * @deprecated Use `LoadClerkJSScriptOptions` instead. This alias will be removed in a future major version.\n */\nexport type LoadClerkJsScriptOptions = LoadClerkJSScriptOptions;\n\nexport type LoadClerkUIScriptOptions = {\n publishableKey: string;\n /** @internal */\n __internal_clerkUIUrl?: string;\n /** @internal */\n __internal_clerkUIVersion?: string;\n proxyUrl?: string;\n domain?: string;\n nonce?: string;\n scriptLoadTimeout?: number;\n};\n\n/**\n * Validates that window.Clerk exists and is properly initialized.\n * This ensures we don't have false positives where the script loads but Clerk is malformed.\n *\n * @returns `true` if window.Clerk exists and has the expected structure with a load method.\n */\nfunction isClerkGlobalProperlyLoaded(prop: 'Clerk' | '__internal_ClerkUICtor'): boolean {\n if (typeof window === 'undefined' || !(window as any)[prop]) {\n return false;\n }\n\n // Basic validation that window.Clerk has the expected structure\n const val = (window as any)[prop];\n return !!val;\n}\nconst isClerkProperlyLoaded = () => isClerkGlobalProperlyLoaded('Clerk');\nconst isClerkUIProperlyLoaded = () => isClerkGlobalProperlyLoaded('__internal_ClerkUICtor');\n\n/**\n * Checks if an existing script has a request error using Performance API.\n *\n * @param scriptUrl - The URL of the script to check.\n * @returns True if the script has failed to load due to a network/HTTP error.\n */\nfunction hasScriptRequestError(scriptUrl: string): boolean {\n if (typeof window === 'undefined' || !window.performance) {\n return false;\n }\n\n const entries = performance.getEntriesByName(scriptUrl, 'resource') as PerformanceResourceTiming[];\n\n if (entries.length === 0) {\n return false;\n }\n\n const scriptEntry = entries[entries.length - 1];\n\n // transferSize === 0 with responseEnd === 0 indicates network failure\n // transferSize === 0 with responseEnd > 0 might be a 4xx/5xx error or blocked request\n if (scriptEntry.transferSize === 0 && scriptEntry.decodedBodySize === 0) {\n // If there was no response at all, it's definitely an error\n if (scriptEntry.responseEnd === 0) {\n return true;\n }\n // If we got a response but no content, likely an HTTP error (4xx/5xx)\n if (scriptEntry.responseEnd > 0 && scriptEntry.responseStart > 0) {\n return true;\n }\n\n if ('responseStatus' in scriptEntry) {\n const status = (scriptEntry as any).responseStatus;\n if (status >= 400) {\n return true;\n }\n if (scriptEntry.responseStatus === 0) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Hotloads the Clerk JS script with robust failure detection.\n *\n * Uses a timeout-based approach to ensure absolute certainty about load success/failure.\n * If the script fails to load within the timeout period, or loads but doesn't create\n * a proper Clerk instance, the promise rejects with an error.\n *\n * @param opts - The options used to build the Clerk JS script URL and load the script.\n * Must include a `publishableKey` if no existing script is found.\n * @returns Promise that resolves with null if Clerk loads successfully, or rejects with an error.\n *\n * @example\n * ```typescript\n * try {\n * await loadClerkJsScript({ publishableKey: 'pk_test_...' });\n * console.log('Clerk loaded successfully');\n * } catch (error) {\n * console.error('Failed to load Clerk:', error.message);\n * }\n * ```\n */\nexport const loadClerkJSScript = async (opts?: LoadClerkJSScriptOptions): Promise<HTMLScriptElement | null> => {\n const timeout = opts?.scriptLoadTimeout ?? 15000;\n const rejectWith = (error?: Error) =>\n new ClerkRuntimeError('Failed to load Clerk JS' + (error?.message ? `, ${error.message}` : ''), {\n code: 'failed_to_load_clerk_js',\n cause: error,\n });\n\n if (isClerkProperlyLoaded()) {\n return null;\n }\n\n if (!opts?.publishableKey) {\n errorThrower.throwMissingPublishableKeyError();\n return null;\n }\n\n const scriptUrl = clerkJSScriptUrl(opts);\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-clerk-js-script]');\n\n if (existingScript) {\n if (hasScriptRequestError(scriptUrl)) {\n existingScript.remove();\n } else {\n try {\n await waitForPredicateWithTimeout(timeout, isClerkProperlyLoaded, rejectWith(), existingScript);\n return null;\n } catch {\n existingScript.remove();\n }\n }\n }\n\n const loadPromise = waitForPredicateWithTimeout(timeout, isClerkProperlyLoaded, rejectWith());\n\n loadScript(scriptUrl, {\n async: true,\n crossOrigin: 'anonymous',\n nonce: opts.nonce,\n beforeLoad: applyAttributesToScript(buildClerkJSScriptAttributes(opts)),\n }).catch(error => {\n throw rejectWith(error);\n });\n\n return loadPromise;\n};\n\nexport const loadClerkUIScript = async (opts?: LoadClerkUIScriptOptions): Promise<HTMLScriptElement | null> => {\n const timeout = opts?.scriptLoadTimeout ?? 15000;\n const rejectWith = (error?: Error) =>\n new ClerkRuntimeError('Failed to load Clerk UI' + (error?.message ? `, ${error.message}` : ''), {\n code: 'failed_to_load_clerk_ui',\n cause: error,\n });\n\n if (isClerkUIProperlyLoaded()) {\n return null;\n }\n\n if (!opts?.publishableKey) {\n errorThrower.throwMissingPublishableKeyError();\n return null;\n }\n\n const scriptUrl = clerkUIScriptUrl(opts);\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-clerk-ui-script]');\n\n if (existingScript) {\n if (hasScriptRequestError(scriptUrl)) {\n existingScript.remove();\n } else {\n try {\n await waitForPredicateWithTimeout(timeout, isClerkUIProperlyLoaded, rejectWith(), existingScript);\n return null;\n } catch {\n existingScript.remove();\n }\n }\n }\n\n const loadPromise = waitForPredicateWithTimeout(timeout, isClerkUIProperlyLoaded, rejectWith());\n\n loadScript(scriptUrl, {\n async: true,\n crossOrigin: 'anonymous',\n nonce: opts.nonce,\n beforeLoad: applyAttributesToScript(buildClerkUIScriptAttributes(opts)),\n }).catch(error => {\n throw rejectWith(error);\n });\n\n return loadPromise;\n};\n\nexport const clerkJSScriptUrl = (opts: LoadClerkJSScriptOptions) => {\n const { __internal_clerkJSUrl, __internal_clerkJSVersion, proxyUrl, domain, publishableKey } = opts;\n\n if (__internal_clerkJSUrl) {\n return __internal_clerkJSUrl;\n }\n\n const version = versionSelector(__internal_clerkJSVersion);\n\n if (proxyUrl && isProxyUrlRelative(proxyUrl)) {\n return buildRelativeProxyScriptUrl(proxyUrl, 'clerk-js', version, 'clerk.browser.js');\n }\n\n const scriptHost = buildScriptHost({ publishableKey, proxyUrl, domain });\n return `https://${scriptHost}/npm/@clerk/clerk-js@${version}/dist/clerk.browser.js`;\n};\n\nexport const clerkUIScriptUrl = (opts: LoadClerkUIScriptOptions) => {\n const { __internal_clerkUIUrl, __internal_clerkUIVersion, proxyUrl, domain, publishableKey } = opts;\n\n if (__internal_clerkUIUrl) {\n return __internal_clerkUIUrl;\n }\n\n const version = versionSelector(__internal_clerkUIVersion, UI_PACKAGE_VERSION);\n\n if (proxyUrl && isProxyUrlRelative(proxyUrl)) {\n return buildRelativeProxyScriptUrl(proxyUrl, 'ui', version, 'ui.browser.js');\n }\n\n const scriptHost = buildScriptHost({ publishableKey, proxyUrl, domain });\n return `https://${scriptHost}/npm/@clerk/ui@${version}/dist/ui.browser.js`;\n};\n\nexport const buildClerkJSScriptAttributes = (options: LoadClerkJSScriptOptions) => {\n const obj: Record<string, string> = {};\n\n if (options.publishableKey) {\n obj['data-clerk-publishable-key'] = options.publishableKey;\n }\n\n if (options.proxyUrl) {\n obj['data-clerk-proxy-url'] = options.proxyUrl;\n }\n\n if (options.domain) {\n obj['data-clerk-domain'] = options.domain;\n }\n\n if (options.nonce) {\n obj.nonce = options.nonce;\n }\n\n return obj;\n};\n\nexport const buildClerkUIScriptAttributes = (options: LoadClerkUIScriptOptions) => {\n // TODO @nikos do we need this?\n return buildClerkJSScriptAttributes(options);\n};\n\nconst applyAttributesToScript = (attributes: Record<string, string>) => (script: HTMLScriptElement) => {\n for (const attribute in attributes) {\n script.setAttribute(attribute, attributes[attribute]);\n }\n};\n\nconst stripTrailingSlashes = (value: string) => {\n while (value.endsWith('/')) {\n value = value.slice(0, -1);\n }\n\n return value;\n};\n\nconst buildRelativeProxyScriptUrl = (proxyUrl: string, packageName: string, version: string, fileName: string) => {\n return `${stripTrailingSlashes(proxyUrl)}/npm/@clerk/${packageName}@${version}/dist/${fileName}`;\n};\n\nexport const buildScriptHost = (opts: { publishableKey: string; proxyUrl?: string; domain?: string }) => {\n const { proxyUrl, domain, publishableKey } = opts;\n\n if (!!proxyUrl && isValidProxyUrl(proxyUrl)) {\n const resolvedProxyUrl = proxyUrlToAbsoluteURL(proxyUrl);\n\n if (isProxyUrlRelative(resolvedProxyUrl)) {\n return parsePublishableKey(publishableKey)?.frontendApi || '';\n }\n\n return resolvedProxyUrl.replace(/http(s)?:\\/\\//, '');\n } else if (domain && !isDevOrStagingUrl(parsePublishableKey(publishableKey)?.frontendApi || '')) {\n return addClerkPrefix(domain);\n } else {\n return parsePublishableKey(publishableKey)?.frontendApi || '';\n }\n};\n\nfunction waitForPredicateWithTimeout(\n timeoutMs: number,\n predicate: () => boolean,\n rejectWith: Error,\n existingScript?: HTMLScriptElement,\n): Promise<HTMLScriptElement | null> {\n return new Promise((resolve, reject) => {\n let resolved = false;\n\n const cleanup = (timeoutId: ReturnType<typeof setTimeout>, pollInterval: ReturnType<typeof setInterval>) => {\n clearTimeout(timeoutId);\n clearInterval(pollInterval);\n };\n\n // Bail out early if the script fails to load, instead of waiting for the entire timeout\n existingScript?.addEventListener('error', () => {\n cleanup(timeoutId, pollInterval);\n reject(rejectWith);\n });\n\n const checkAndResolve = () => {\n if (resolved) {\n return;\n }\n\n if (predicate()) {\n resolved = true;\n cleanup(timeoutId, pollInterval);\n resolve(null);\n }\n };\n\n const handleTimeout = () => {\n if (resolved) {\n return;\n }\n\n resolved = true;\n cleanup(timeoutId, pollInterval);\n\n if (!predicate()) {\n reject(rejectWith);\n } else {\n resolve(null);\n }\n };\n\n const timeoutId = setTimeout(handleTimeout, timeoutMs);\n\n checkAndResolve();\n\n const pollInterval = setInterval(() => {\n if (resolved) {\n clearInterval(pollInterval);\n return;\n }\n checkAndResolve();\n }, 100);\n });\n}\n\nexport function setClerkJSLoadingErrorPackageName(packageName: string) {\n errorThrower.setPackageName({ packageName });\n}\n\n/**\n * @deprecated Use `loadClerkJSScript` instead. This alias will be removed in a future major version.\n */\nexport const loadClerkJsScript = loadClerkJSScript;\n\n/**\n * @deprecated Use `clerkJSScriptUrl` instead. This alias will be removed in a future major version.\n */\nexport const clerkJsScriptUrl = clerkJSScriptUrl;\n\n/**\n * @deprecated Use `buildClerkJSScriptAttributes` instead. This alias will be removed in a future major version.\n */\nexport const buildClerkJsScriptAttributes = buildClerkJSScriptAttributes;\n\n/**\n * @deprecated Use `setClerkJSLoadingErrorPackageName` instead. This alias will be removed in a future major version.\n */\nexport const setClerkJsLoadingErrorPackageName = setClerkJSLoadingErrorPackageName;\n"],"mappings":";;;;;;;;;;AAQA,MAAM,EAAE,sBAAsBA,wCAA2B;AAEzD,MAAM,eAAeC,gCAAkB,EAAE,aAAa,gBAAgB,CAAC;;;;;;;AA2CvE,SAAS,4BAA4B,MAAmD;CACtF,IAAI,OAAO,WAAW,eAAe,CAAE,OAAe,OACpD,OAAO;CAKT,OAAO,CAAC,CADK,OAAe;AAE9B;AACA,MAAM,8BAA8B,4BAA4B,OAAO;AACvE,MAAM,gCAAgC,4BAA4B,wBAAwB;;;;;;;AAQ1F,SAAS,sBAAsB,WAA4B;CACzD,IAAI,OAAO,WAAW,eAAe,CAAC,OAAO,aAC3C,OAAO;CAGT,MAAM,UAAU,YAAY,iBAAiB,WAAW,UAAU;CAElE,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,MAAM,cAAc,QAAQ,QAAQ,SAAS;CAI7C,IAAI,YAAY,iBAAiB,KAAK,YAAY,oBAAoB,GAAG;EAEvE,IAAI,YAAY,gBAAgB,GAC9B,OAAO;EAGT,IAAI,YAAY,cAAc,KAAK,YAAY,gBAAgB,GAC7D,OAAO;EAGT,IAAI,oBAAoB,aAAa;GAEnC,IADgB,YAAoB,kBACtB,KACZ,OAAO;GAET,IAAI,YAAY,mBAAmB,GACjC,OAAO;EAEX;CACF;CAEA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,oBAAoB,OAAO,SAAuE;CAC7G,MAAM,UAAU,MAAM,qBAAqB;CAC3C,MAAM,cAAc,UAClB,IAAIC,4CAAkB,6BAA6B,OAAO,UAAU,KAAK,MAAM,YAAY,KAAK;EAC9F,MAAM;EACN,OAAO;CACT,CAAC;CAEH,IAAI,sBAAsB,GACxB,OAAO;CAGT,IAAI,CAAC,MAAM,gBAAgB;EACzB,aAAa,gCAAgC;EAC7C,OAAO;CACT;CAEA,MAAM,YAAY,iBAAiB,IAAI;CACvC,MAAM,iBAAiB,SAAS,cAAiC,8BAA8B;CAE/F,IAAI,gBACF,IAAI,sBAAsB,SAAS,GACjC,eAAe,OAAO;MAEtB,IAAI;EACF,MAAM,4BAA4B,SAAS,uBAAuB,WAAW,GAAG,cAAc;EAC9F,OAAO;CACT,QAAQ;EACN,eAAe,OAAO;CACxB;CAIJ,MAAM,cAAc,4BAA4B,SAAS,uBAAuB,WAAW,CAAC;CAE5F,8BAAW,WAAW;EACpB,OAAO;EACP,aAAa;EACb,OAAO,KAAK;EACZ,YAAY,wBAAwB,6BAA6B,IAAI,CAAC;CACxE,CAAC,CAAC,CAAC,OAAM,UAAS;EAChB,MAAM,WAAW,KAAK;CACxB,CAAC;CAED,OAAO;AACT;AAEA,MAAa,oBAAoB,OAAO,SAAuE;CAC7G,MAAM,UAAU,MAAM,qBAAqB;CAC3C,MAAM,cAAc,UAClB,IAAIA,4CAAkB,6BAA6B,OAAO,UAAU,KAAK,MAAM,YAAY,KAAK;EAC9F,MAAM;EACN,OAAO;CACT,CAAC;CAEH,IAAI,wBAAwB,GAC1B,OAAO;CAGT,IAAI,CAAC,MAAM,gBAAgB;EACzB,aAAa,gCAAgC;EAC7C,OAAO;CACT;CAEA,MAAM,YAAY,iBAAiB,IAAI;CACvC,MAAM,iBAAiB,SAAS,cAAiC,8BAA8B;CAE/F,IAAI,gBACF,IAAI,sBAAsB,SAAS,GACjC,eAAe,OAAO;MAEtB,IAAI;EACF,MAAM,4BAA4B,SAAS,yBAAyB,WAAW,GAAG,cAAc;EAChG,OAAO;CACT,QAAQ;EACN,eAAe,OAAO;CACxB;CAIJ,MAAM,cAAc,4BAA4B,SAAS,yBAAyB,WAAW,CAAC;CAE9F,8BAAW,WAAW;EACpB,OAAO;EACP,aAAa;EACb,OAAO,KAAK;EACZ,YAAY,wBAAwB,6BAA6B,IAAI,CAAC;CACxE,CAAC,CAAC,CAAC,OAAM,UAAS;EAChB,MAAM,WAAW,KAAK;CACxB,CAAC;CAED,OAAO;AACT;AAEA,MAAa,oBAAoB,SAAmC;CAClE,MAAM,EAAE,uBAAuB,2BAA2B,UAAU,QAAQ,mBAAmB;CAE/F,IAAI,uBACF,OAAO;CAGT,MAAM,UAAUC,wCAAgB,yBAAyB;CAEzD,IAAI,YAAYC,iCAAmB,QAAQ,GACzC,OAAO,4BAA4B,UAAU,YAAY,SAAS,kBAAkB;CAItF,OAAO,WADY,gBAAgB;EAAE;EAAgB;EAAU;CAAO,CAC3C,EAAE,uBAAuB,QAAQ;AAC9D;AAEA,MAAa,oBAAoB,SAAmC;CAClE,MAAM,EAAE,uBAAuB,2BAA2B,UAAU,QAAQ,mBAAmB;CAE/F,IAAI,uBACF,OAAO;CAGT,MAAM,UAAUD,wCAAgB,4DAA6C;CAE7E,IAAI,YAAYC,iCAAmB,QAAQ,GACzC,OAAO,4BAA4B,UAAU,MAAM,SAAS,eAAe;CAI7E,OAAO,WADY,gBAAgB;EAAE;EAAgB;EAAU;CAAO,CAC3C,EAAE,iBAAiB,QAAQ;AACxD;AAEA,MAAa,gCAAgC,YAAsC;CACjF,MAAM,MAA8B,CAAC;CAErC,IAAI,QAAQ,gBACV,IAAI,gCAAgC,QAAQ;CAG9C,IAAI,QAAQ,UACV,IAAI,0BAA0B,QAAQ;CAGxC,IAAI,QAAQ,QACV,IAAI,uBAAuB,QAAQ;CAGrC,IAAI,QAAQ,OACV,IAAI,QAAQ,QAAQ;CAGtB,OAAO;AACT;AAEA,MAAa,gCAAgC,YAAsC;CAEjF,OAAO,6BAA6B,OAAO;AAC7C;AAEA,MAAM,2BAA2B,gBAAwC,WAA8B;CACrG,KAAK,MAAM,aAAa,YACtB,OAAO,aAAa,WAAW,WAAW,UAAU;AAExD;AAEA,MAAM,wBAAwB,UAAkB;CAC9C,OAAO,MAAM,SAAS,GAAG,GACvB,QAAQ,MAAM,MAAM,GAAG,EAAE;CAG3B,OAAO;AACT;AAEA,MAAM,+BAA+B,UAAkB,aAAqB,SAAiB,aAAqB;CAChH,OAAO,GAAG,qBAAqB,QAAQ,EAAE,cAAc,YAAY,GAAG,QAAQ,QAAQ;AACxF;AAEA,MAAa,mBAAmB,SAAyE;CACvG,MAAM,EAAE,UAAU,QAAQ,mBAAmB;CAE7C,IAAI,CAAC,CAAC,YAAYC,8BAAgB,QAAQ,GAAG;EAC3C,MAAM,mBAAmBC,oCAAsB,QAAQ;EAEvD,IAAIF,iCAAmB,gBAAgB,GACrC,OAAOG,iCAAoB,cAAc,CAAC,EAAE,eAAe;EAG7D,OAAO,iBAAiB,QAAQ,iBAAiB,EAAE;CACrD,OAAO,IAAI,UAAU,CAAC,kBAAkBA,iCAAoB,cAAc,CAAC,EAAE,eAAe,EAAE,GAC5F,OAAOC,2BAAe,MAAM;MAE5B,OAAOD,iCAAoB,cAAc,CAAC,EAAE,eAAe;AAE/D;AAEA,SAAS,4BACP,WACA,WACA,YACA,gBACmC;CACnC,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,IAAI,WAAW;EAEf,MAAM,WAAW,WAA0C,iBAAiD;GAC1G,aAAa,SAAS;GACtB,cAAc,YAAY;EAC5B;EAGA,gBAAgB,iBAAiB,eAAe;GAC9C,QAAQ,WAAW,YAAY;GAC/B,OAAO,UAAU;EACnB,CAAC;EAED,MAAM,wBAAwB;GAC5B,IAAI,UACF;GAGF,IAAI,UAAU,GAAG;IACf,WAAW;IACX,QAAQ,WAAW,YAAY;IAC/B,QAAQ,IAAI;GACd;EACF;EAEA,MAAM,sBAAsB;GAC1B,IAAI,UACF;GAGF,WAAW;GACX,QAAQ,WAAW,YAAY;GAE/B,IAAI,CAAC,UAAU,GACb,OAAO,UAAU;QAEjB,QAAQ,IAAI;EAEhB;EAEA,MAAM,YAAY,WAAW,eAAe,SAAS;EAErD,gBAAgB;EAEhB,MAAM,eAAe,kBAAkB;GACrC,IAAI,UAAU;IACZ,cAAc,YAAY;IAC1B;GACF;GACA,gBAAgB;EAClB,GAAG,GAAG;CACR,CAAC;AACH;AAEA,SAAgB,kCAAkC,aAAqB;CACrE,aAAa,eAAe,EAAE,YAAY,CAAC;AAC7C;;;;AAKA,MAAa,oBAAoB;;;;AAKjC,MAAa,mBAAmB;;;;AAKhC,MAAa,+BAA+B;;;;AAK5C,MAAa,oCAAoC"}
|
|
1
|
+
{"version":3,"file":"loadClerkJsScript.js","names":["createDevOrStagingUrlCache","buildErrorThrower","ClerkRuntimeError","versionSelector","isProxyUrlRelative","isValidProxyUrl","proxyUrlToAbsoluteURL","parsePublishableKey","addClerkPrefix"],"sources":["../src/loadClerkJsScript.ts"],"sourcesContent":["import { buildErrorThrower, ClerkRuntimeError } from './error';\nimport { createDevOrStagingUrlCache, parsePublishableKey } from './keys';\nimport { loadScript } from './loadScript';\nimport { isProxyUrlRelative, isValidProxyUrl, proxyUrlToAbsoluteURL } from './proxy';\nimport type { SDKMetadata } from './types';\nimport { addClerkPrefix } from './url';\nimport { versionSelector } from './versionSelector';\n\nconst { isDevOrStagingUrl } = createDevOrStagingUrlCache();\n\nconst errorThrower = buildErrorThrower({ packageName: '@clerk/shared' });\n\nexport type LoadClerkJSScriptOptions = {\n publishableKey: string;\n /** @internal */\n __internal_clerkJSUrl?: string;\n /** @internal */\n __internal_clerkJSVersion?: string;\n sdkMetadata?: SDKMetadata;\n proxyUrl?: string;\n domain?: string;\n nonce?: string;\n /**\n * Timeout in milliseconds to wait for clerk-js to load before considering it failed.\n *\n * @default 15000 (15 seconds)\n */\n scriptLoadTimeout?: number;\n};\n\n/**\n * @deprecated Use `LoadClerkJSScriptOptions` instead. This alias will be removed in a future major version.\n */\nexport type LoadClerkJsScriptOptions = LoadClerkJSScriptOptions;\n\nexport type LoadClerkUIScriptOptions = {\n publishableKey: string;\n /** @internal */\n __internal_clerkUIUrl?: string;\n /** @internal */\n __internal_clerkUIVersion?: string;\n proxyUrl?: string;\n domain?: string;\n nonce?: string;\n scriptLoadTimeout?: number;\n};\n\n/**\n * Validates that window.Clerk exists and is properly initialized.\n * This ensures we don't have false positives where the script loads but Clerk is malformed.\n *\n * @returns `true` if window.Clerk exists and has the expected structure with a load method.\n */\nfunction isClerkGlobalProperlyLoaded(prop: 'Clerk' | '__internal_ClerkUICtor'): boolean {\n if (typeof window === 'undefined' || !(window as any)[prop]) {\n return false;\n }\n\n // Basic validation that window.Clerk has the expected structure\n const val = (window as any)[prop];\n return !!val;\n}\nconst isClerkProperlyLoaded = () => isClerkGlobalProperlyLoaded('Clerk');\nconst isClerkUIProperlyLoaded = () => isClerkGlobalProperlyLoaded('__internal_ClerkUICtor');\n\n/**\n * Checks if an existing script has a request error using Performance API.\n *\n * @param scriptUrl - The URL of the script to check.\n * @returns True if the script has failed to load due to a network/HTTP error.\n */\nfunction hasScriptRequestError(scriptUrl: string): boolean {\n if (typeof window === 'undefined' || !window.performance) {\n return false;\n }\n\n const entries = performance.getEntriesByName(scriptUrl, 'resource') as PerformanceResourceTiming[];\n\n if (entries.length === 0) {\n return false;\n }\n\n const scriptEntry = entries[entries.length - 1];\n\n // transferSize === 0 with responseEnd === 0 indicates network failure\n // transferSize === 0 with responseEnd > 0 might be a 4xx/5xx error or blocked request\n if (scriptEntry.transferSize === 0 && scriptEntry.decodedBodySize === 0) {\n // If there was no response at all, it's definitely an error\n if (scriptEntry.responseEnd === 0) {\n return true;\n }\n // If we got a response but no content, likely an HTTP error (4xx/5xx)\n if (scriptEntry.responseEnd > 0 && scriptEntry.responseStart > 0) {\n return true;\n }\n\n if ('responseStatus' in scriptEntry) {\n const status = (scriptEntry as any).responseStatus;\n if (status >= 400) {\n return true;\n }\n if (scriptEntry.responseStatus === 0) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Hotloads the Clerk JS script with robust failure detection.\n *\n * Uses a timeout-based approach to ensure absolute certainty about load success/failure.\n * If the script fails to load within the timeout period, or loads but doesn't create\n * a proper Clerk instance, the promise rejects with an error.\n *\n * @param opts - The options used to build the Clerk JS script URL and load the script.\n * Must include a `publishableKey` if no existing script is found.\n * @returns Promise that resolves with null if Clerk loads successfully, or rejects with an error.\n *\n * @example\n * ```typescript\n * try {\n * await loadClerkJsScript({ publishableKey: 'pk_test_...' });\n * console.log('Clerk loaded successfully');\n * } catch (error) {\n * console.error('Failed to load Clerk:', error.message);\n * }\n * ```\n */\nexport const loadClerkJSScript = async (opts?: LoadClerkJSScriptOptions): Promise<HTMLScriptElement | null> => {\n const timeout = opts?.scriptLoadTimeout ?? 15000;\n const rejectWith = (error?: Error) =>\n new ClerkRuntimeError('Failed to load Clerk JS' + (error?.message ? `, ${error.message}` : ''), {\n code: 'failed_to_load_clerk_js',\n cause: error,\n });\n\n if (isClerkProperlyLoaded()) {\n return null;\n }\n\n if (!opts?.publishableKey) {\n errorThrower.throwMissingPublishableKeyError();\n return null;\n }\n\n const scriptUrl = clerkJSScriptUrl(opts);\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-clerk-js-script]');\n\n if (existingScript) {\n if (hasScriptRequestError(scriptUrl)) {\n existingScript.remove();\n } else {\n try {\n await waitForPredicateWithTimeout(timeout, isClerkProperlyLoaded, rejectWith(), existingScript);\n return null;\n } catch {\n existingScript.remove();\n }\n }\n }\n\n const loadPromise = waitForPredicateWithTimeout(timeout, isClerkProperlyLoaded, rejectWith());\n\n loadScript(scriptUrl, {\n async: true,\n crossOrigin: 'anonymous',\n nonce: opts.nonce,\n beforeLoad: applyAttributesToScript(buildClerkJSScriptAttributes(opts)),\n }).catch(error => {\n throw rejectWith(error);\n });\n\n return loadPromise;\n};\n\nexport const loadClerkUIScript = async (opts?: LoadClerkUIScriptOptions): Promise<HTMLScriptElement | null> => {\n const timeout = opts?.scriptLoadTimeout ?? 15000;\n const rejectWith = (error?: Error) =>\n new ClerkRuntimeError('Failed to load Clerk UI' + (error?.message ? `, ${error.message}` : ''), {\n code: 'failed_to_load_clerk_ui',\n cause: error,\n });\n\n if (isClerkUIProperlyLoaded()) {\n return null;\n }\n\n if (!opts?.publishableKey) {\n errorThrower.throwMissingPublishableKeyError();\n return null;\n }\n\n const scriptUrl = clerkUIScriptUrl(opts);\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-clerk-ui-script]');\n\n if (existingScript) {\n if (hasScriptRequestError(scriptUrl)) {\n existingScript.remove();\n } else {\n try {\n await waitForPredicateWithTimeout(timeout, isClerkUIProperlyLoaded, rejectWith(), existingScript);\n return null;\n } catch {\n existingScript.remove();\n }\n }\n }\n\n const loadPromise = waitForPredicateWithTimeout(timeout, isClerkUIProperlyLoaded, rejectWith());\n\n loadScript(scriptUrl, {\n async: true,\n crossOrigin: 'anonymous',\n nonce: opts.nonce,\n beforeLoad: applyAttributesToScript(buildClerkUIScriptAttributes(opts)),\n }).catch(error => {\n throw rejectWith(error);\n });\n\n return loadPromise;\n};\n\nexport const clerkJSScriptUrl = (opts: LoadClerkJSScriptOptions) => {\n const { __internal_clerkJSUrl, __internal_clerkJSVersion, proxyUrl, domain, publishableKey } = opts;\n\n if (__internal_clerkJSUrl) {\n return __internal_clerkJSUrl;\n }\n\n const version = versionSelector(__internal_clerkJSVersion);\n\n if (proxyUrl && isProxyUrlRelative(proxyUrl)) {\n return buildRelativeProxyScriptUrl(proxyUrl, 'clerk-js', version, 'clerk.browser.js');\n }\n\n const scriptHost = buildScriptHost({ publishableKey, proxyUrl, domain });\n return `https://${scriptHost}/npm/@clerk/clerk-js@${version}/dist/clerk.browser.js`;\n};\n\nexport const clerkUIScriptUrl = (opts: LoadClerkUIScriptOptions) => {\n const { __internal_clerkUIUrl, __internal_clerkUIVersion, proxyUrl, domain, publishableKey } = opts;\n\n if (__internal_clerkUIUrl) {\n return __internal_clerkUIUrl;\n }\n\n const version = versionSelector(__internal_clerkUIVersion, UI_PACKAGE_VERSION);\n\n if (proxyUrl && isProxyUrlRelative(proxyUrl)) {\n return buildRelativeProxyScriptUrl(proxyUrl, 'ui', version, 'ui.browser.js');\n }\n\n const scriptHost = buildScriptHost({ publishableKey, proxyUrl, domain });\n return `https://${scriptHost}/npm/@clerk/ui@${version}/dist/ui.browser.js`;\n};\n\nexport const buildClerkJSScriptAttributes = (options: LoadClerkJSScriptOptions) => {\n const obj: Record<string, string> = {};\n\n if (options.publishableKey) {\n obj['data-clerk-publishable-key'] = options.publishableKey;\n }\n\n if (options.proxyUrl) {\n obj['data-clerk-proxy-url'] = options.proxyUrl;\n }\n\n if (options.domain) {\n obj['data-clerk-domain'] = options.domain;\n }\n\n if (options.nonce) {\n obj.nonce = options.nonce;\n }\n\n return obj;\n};\n\nexport const buildClerkUIScriptAttributes = (options: LoadClerkUIScriptOptions) => {\n // TODO @nikos do we need this?\n return buildClerkJSScriptAttributes(options);\n};\n\nconst applyAttributesToScript = (attributes: Record<string, string>) => (script: HTMLScriptElement) => {\n for (const attribute in attributes) {\n script.setAttribute(attribute, attributes[attribute]);\n }\n};\n\nconst stripTrailingSlashes = (value: string) => {\n while (value.endsWith('/')) {\n value = value.slice(0, -1);\n }\n\n return value;\n};\n\nconst buildRelativeProxyScriptUrl = (proxyUrl: string, packageName: string, version: string, fileName: string) => {\n return `${stripTrailingSlashes(proxyUrl)}/npm/@clerk/${packageName}@${version}/dist/${fileName}`;\n};\n\nexport const buildScriptHost = (opts: { publishableKey: string; proxyUrl?: string; domain?: string }) => {\n const { proxyUrl, domain, publishableKey } = opts;\n\n if (!!proxyUrl && isValidProxyUrl(proxyUrl)) {\n const resolvedProxyUrl = proxyUrlToAbsoluteURL(proxyUrl);\n\n if (isProxyUrlRelative(resolvedProxyUrl)) {\n return parsePublishableKey(publishableKey)?.frontendApi || '';\n }\n\n return resolvedProxyUrl.replace(/http(s)?:\\/\\//, '');\n } else if (domain && !isDevOrStagingUrl(parsePublishableKey(publishableKey)?.frontendApi || '')) {\n return addClerkPrefix(domain);\n } else {\n return parsePublishableKey(publishableKey)?.frontendApi || '';\n }\n};\n\nfunction waitForPredicateWithTimeout(\n timeoutMs: number,\n predicate: () => boolean,\n rejectWith: Error,\n existingScript?: HTMLScriptElement,\n): Promise<HTMLScriptElement | null> {\n return new Promise((resolve, reject) => {\n let resolved = false;\n\n const cleanup = (timeoutId: ReturnType<typeof setTimeout>, pollInterval: ReturnType<typeof setInterval>) => {\n clearTimeout(timeoutId);\n clearInterval(pollInterval);\n };\n\n // Bail out early if the script fails to load, instead of waiting for the entire timeout\n existingScript?.addEventListener('error', () => {\n cleanup(timeoutId, pollInterval);\n reject(rejectWith);\n });\n\n const checkAndResolve = () => {\n if (resolved) {\n return;\n }\n\n if (predicate()) {\n resolved = true;\n cleanup(timeoutId, pollInterval);\n resolve(null);\n }\n };\n\n const handleTimeout = () => {\n if (resolved) {\n return;\n }\n\n resolved = true;\n cleanup(timeoutId, pollInterval);\n\n if (!predicate()) {\n reject(rejectWith);\n } else {\n resolve(null);\n }\n };\n\n const timeoutId = setTimeout(handleTimeout, timeoutMs);\n\n checkAndResolve();\n\n const pollInterval = setInterval(() => {\n if (resolved) {\n clearInterval(pollInterval);\n return;\n }\n checkAndResolve();\n }, 100);\n });\n}\n\nexport function setClerkJSLoadingErrorPackageName(packageName: string) {\n errorThrower.setPackageName({ packageName });\n}\n\n/**\n * @deprecated Use `loadClerkJSScript` instead. This alias will be removed in a future major version.\n */\nexport const loadClerkJsScript = loadClerkJSScript;\n\n/**\n * @deprecated Use `clerkJSScriptUrl` instead. This alias will be removed in a future major version.\n */\nexport const clerkJsScriptUrl = clerkJSScriptUrl;\n\n/**\n * @deprecated Use `buildClerkJSScriptAttributes` instead. This alias will be removed in a future major version.\n */\nexport const buildClerkJsScriptAttributes = buildClerkJSScriptAttributes;\n\n/**\n * @deprecated Use `setClerkJSLoadingErrorPackageName` instead. This alias will be removed in a future major version.\n */\nexport const setClerkJsLoadingErrorPackageName = setClerkJSLoadingErrorPackageName;\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createDevOrStagingUrlCache, parsePublishableKey } from "./keys.mjs";
|
|
2
2
|
import { t as ClerkRuntimeError } from "./_chunks/clerkRuntimeError-DlesLWqO.mjs";
|
|
3
|
-
import { y as buildErrorThrower } from "./_chunks/error-
|
|
3
|
+
import { y as buildErrorThrower } from "./_chunks/error-DRCZN5DP.mjs";
|
|
4
4
|
import { loadScript } from "./loadScript.mjs";
|
|
5
5
|
import { isProxyUrlRelative, isValidProxyUrl, proxyUrlToAbsoluteURL } from "./proxy.mjs";
|
|
6
6
|
import { addClerkPrefix } from "./url.mjs";
|
|
@@ -139,7 +139,7 @@ const clerkJSScriptUrl = (opts) => {
|
|
|
139
139
|
const clerkUIScriptUrl = (opts) => {
|
|
140
140
|
const { __internal_clerkUIUrl, __internal_clerkUIVersion, proxyUrl, domain, publishableKey } = opts;
|
|
141
141
|
if (__internal_clerkUIUrl) return __internal_clerkUIUrl;
|
|
142
|
-
const version = versionSelector(__internal_clerkUIVersion, "1.30.
|
|
142
|
+
const version = versionSelector(__internal_clerkUIVersion, "1.30.6");
|
|
143
143
|
if (proxyUrl && isProxyUrlRelative(proxyUrl)) return buildRelativeProxyScriptUrl(proxyUrl, "ui", version, "ui.browser.js");
|
|
144
144
|
return `https://${buildScriptHost({
|
|
145
145
|
publishableKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadClerkJsScript.mjs","names":[],"sources":["../src/loadClerkJsScript.ts"],"sourcesContent":["import { buildErrorThrower, ClerkRuntimeError } from './error';\nimport { createDevOrStagingUrlCache, parsePublishableKey } from './keys';\nimport { loadScript } from './loadScript';\nimport { isProxyUrlRelative, isValidProxyUrl, proxyUrlToAbsoluteURL } from './proxy';\nimport type { SDKMetadata } from './types';\nimport { addClerkPrefix } from './url';\nimport { versionSelector } from './versionSelector';\n\nconst { isDevOrStagingUrl } = createDevOrStagingUrlCache();\n\nconst errorThrower = buildErrorThrower({ packageName: '@clerk/shared' });\n\nexport type LoadClerkJSScriptOptions = {\n publishableKey: string;\n /** @internal */\n __internal_clerkJSUrl?: string;\n /** @internal */\n __internal_clerkJSVersion?: string;\n sdkMetadata?: SDKMetadata;\n proxyUrl?: string;\n domain?: string;\n nonce?: string;\n /**\n * Timeout in milliseconds to wait for clerk-js to load before considering it failed.\n *\n * @default 15000 (15 seconds)\n */\n scriptLoadTimeout?: number;\n};\n\n/**\n * @deprecated Use `LoadClerkJSScriptOptions` instead. This alias will be removed in a future major version.\n */\nexport type LoadClerkJsScriptOptions = LoadClerkJSScriptOptions;\n\nexport type LoadClerkUIScriptOptions = {\n publishableKey: string;\n /** @internal */\n __internal_clerkUIUrl?: string;\n /** @internal */\n __internal_clerkUIVersion?: string;\n proxyUrl?: string;\n domain?: string;\n nonce?: string;\n scriptLoadTimeout?: number;\n};\n\n/**\n * Validates that window.Clerk exists and is properly initialized.\n * This ensures we don't have false positives where the script loads but Clerk is malformed.\n *\n * @returns `true` if window.Clerk exists and has the expected structure with a load method.\n */\nfunction isClerkGlobalProperlyLoaded(prop: 'Clerk' | '__internal_ClerkUICtor'): boolean {\n if (typeof window === 'undefined' || !(window as any)[prop]) {\n return false;\n }\n\n // Basic validation that window.Clerk has the expected structure\n const val = (window as any)[prop];\n return !!val;\n}\nconst isClerkProperlyLoaded = () => isClerkGlobalProperlyLoaded('Clerk');\nconst isClerkUIProperlyLoaded = () => isClerkGlobalProperlyLoaded('__internal_ClerkUICtor');\n\n/**\n * Checks if an existing script has a request error using Performance API.\n *\n * @param scriptUrl - The URL of the script to check.\n * @returns True if the script has failed to load due to a network/HTTP error.\n */\nfunction hasScriptRequestError(scriptUrl: string): boolean {\n if (typeof window === 'undefined' || !window.performance) {\n return false;\n }\n\n const entries = performance.getEntriesByName(scriptUrl, 'resource') as PerformanceResourceTiming[];\n\n if (entries.length === 0) {\n return false;\n }\n\n const scriptEntry = entries[entries.length - 1];\n\n // transferSize === 0 with responseEnd === 0 indicates network failure\n // transferSize === 0 with responseEnd > 0 might be a 4xx/5xx error or blocked request\n if (scriptEntry.transferSize === 0 && scriptEntry.decodedBodySize === 0) {\n // If there was no response at all, it's definitely an error\n if (scriptEntry.responseEnd === 0) {\n return true;\n }\n // If we got a response but no content, likely an HTTP error (4xx/5xx)\n if (scriptEntry.responseEnd > 0 && scriptEntry.responseStart > 0) {\n return true;\n }\n\n if ('responseStatus' in scriptEntry) {\n const status = (scriptEntry as any).responseStatus;\n if (status >= 400) {\n return true;\n }\n if (scriptEntry.responseStatus === 0) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Hotloads the Clerk JS script with robust failure detection.\n *\n * Uses a timeout-based approach to ensure absolute certainty about load success/failure.\n * If the script fails to load within the timeout period, or loads but doesn't create\n * a proper Clerk instance, the promise rejects with an error.\n *\n * @param opts - The options used to build the Clerk JS script URL and load the script.\n * Must include a `publishableKey` if no existing script is found.\n * @returns Promise that resolves with null if Clerk loads successfully, or rejects with an error.\n *\n * @example\n * ```typescript\n * try {\n * await loadClerkJsScript({ publishableKey: 'pk_test_...' });\n * console.log('Clerk loaded successfully');\n * } catch (error) {\n * console.error('Failed to load Clerk:', error.message);\n * }\n * ```\n */\nexport const loadClerkJSScript = async (opts?: LoadClerkJSScriptOptions): Promise<HTMLScriptElement | null> => {\n const timeout = opts?.scriptLoadTimeout ?? 15000;\n const rejectWith = (error?: Error) =>\n new ClerkRuntimeError('Failed to load Clerk JS' + (error?.message ? `, ${error.message}` : ''), {\n code: 'failed_to_load_clerk_js',\n cause: error,\n });\n\n if (isClerkProperlyLoaded()) {\n return null;\n }\n\n if (!opts?.publishableKey) {\n errorThrower.throwMissingPublishableKeyError();\n return null;\n }\n\n const scriptUrl = clerkJSScriptUrl(opts);\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-clerk-js-script]');\n\n if (existingScript) {\n if (hasScriptRequestError(scriptUrl)) {\n existingScript.remove();\n } else {\n try {\n await waitForPredicateWithTimeout(timeout, isClerkProperlyLoaded, rejectWith(), existingScript);\n return null;\n } catch {\n existingScript.remove();\n }\n }\n }\n\n const loadPromise = waitForPredicateWithTimeout(timeout, isClerkProperlyLoaded, rejectWith());\n\n loadScript(scriptUrl, {\n async: true,\n crossOrigin: 'anonymous',\n nonce: opts.nonce,\n beforeLoad: applyAttributesToScript(buildClerkJSScriptAttributes(opts)),\n }).catch(error => {\n throw rejectWith(error);\n });\n\n return loadPromise;\n};\n\nexport const loadClerkUIScript = async (opts?: LoadClerkUIScriptOptions): Promise<HTMLScriptElement | null> => {\n const timeout = opts?.scriptLoadTimeout ?? 15000;\n const rejectWith = (error?: Error) =>\n new ClerkRuntimeError('Failed to load Clerk UI' + (error?.message ? `, ${error.message}` : ''), {\n code: 'failed_to_load_clerk_ui',\n cause: error,\n });\n\n if (isClerkUIProperlyLoaded()) {\n return null;\n }\n\n if (!opts?.publishableKey) {\n errorThrower.throwMissingPublishableKeyError();\n return null;\n }\n\n const scriptUrl = clerkUIScriptUrl(opts);\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-clerk-ui-script]');\n\n if (existingScript) {\n if (hasScriptRequestError(scriptUrl)) {\n existingScript.remove();\n } else {\n try {\n await waitForPredicateWithTimeout(timeout, isClerkUIProperlyLoaded, rejectWith(), existingScript);\n return null;\n } catch {\n existingScript.remove();\n }\n }\n }\n\n const loadPromise = waitForPredicateWithTimeout(timeout, isClerkUIProperlyLoaded, rejectWith());\n\n loadScript(scriptUrl, {\n async: true,\n crossOrigin: 'anonymous',\n nonce: opts.nonce,\n beforeLoad: applyAttributesToScript(buildClerkUIScriptAttributes(opts)),\n }).catch(error => {\n throw rejectWith(error);\n });\n\n return loadPromise;\n};\n\nexport const clerkJSScriptUrl = (opts: LoadClerkJSScriptOptions) => {\n const { __internal_clerkJSUrl, __internal_clerkJSVersion, proxyUrl, domain, publishableKey } = opts;\n\n if (__internal_clerkJSUrl) {\n return __internal_clerkJSUrl;\n }\n\n const version = versionSelector(__internal_clerkJSVersion);\n\n if (proxyUrl && isProxyUrlRelative(proxyUrl)) {\n return buildRelativeProxyScriptUrl(proxyUrl, 'clerk-js', version, 'clerk.browser.js');\n }\n\n const scriptHost = buildScriptHost({ publishableKey, proxyUrl, domain });\n return `https://${scriptHost}/npm/@clerk/clerk-js@${version}/dist/clerk.browser.js`;\n};\n\nexport const clerkUIScriptUrl = (opts: LoadClerkUIScriptOptions) => {\n const { __internal_clerkUIUrl, __internal_clerkUIVersion, proxyUrl, domain, publishableKey } = opts;\n\n if (__internal_clerkUIUrl) {\n return __internal_clerkUIUrl;\n }\n\n const version = versionSelector(__internal_clerkUIVersion, UI_PACKAGE_VERSION);\n\n if (proxyUrl && isProxyUrlRelative(proxyUrl)) {\n return buildRelativeProxyScriptUrl(proxyUrl, 'ui', version, 'ui.browser.js');\n }\n\n const scriptHost = buildScriptHost({ publishableKey, proxyUrl, domain });\n return `https://${scriptHost}/npm/@clerk/ui@${version}/dist/ui.browser.js`;\n};\n\nexport const buildClerkJSScriptAttributes = (options: LoadClerkJSScriptOptions) => {\n const obj: Record<string, string> = {};\n\n if (options.publishableKey) {\n obj['data-clerk-publishable-key'] = options.publishableKey;\n }\n\n if (options.proxyUrl) {\n obj['data-clerk-proxy-url'] = options.proxyUrl;\n }\n\n if (options.domain) {\n obj['data-clerk-domain'] = options.domain;\n }\n\n if (options.nonce) {\n obj.nonce = options.nonce;\n }\n\n return obj;\n};\n\nexport const buildClerkUIScriptAttributes = (options: LoadClerkUIScriptOptions) => {\n // TODO @nikos do we need this?\n return buildClerkJSScriptAttributes(options);\n};\n\nconst applyAttributesToScript = (attributes: Record<string, string>) => (script: HTMLScriptElement) => {\n for (const attribute in attributes) {\n script.setAttribute(attribute, attributes[attribute]);\n }\n};\n\nconst stripTrailingSlashes = (value: string) => {\n while (value.endsWith('/')) {\n value = value.slice(0, -1);\n }\n\n return value;\n};\n\nconst buildRelativeProxyScriptUrl = (proxyUrl: string, packageName: string, version: string, fileName: string) => {\n return `${stripTrailingSlashes(proxyUrl)}/npm/@clerk/${packageName}@${version}/dist/${fileName}`;\n};\n\nexport const buildScriptHost = (opts: { publishableKey: string; proxyUrl?: string; domain?: string }) => {\n const { proxyUrl, domain, publishableKey } = opts;\n\n if (!!proxyUrl && isValidProxyUrl(proxyUrl)) {\n const resolvedProxyUrl = proxyUrlToAbsoluteURL(proxyUrl);\n\n if (isProxyUrlRelative(resolvedProxyUrl)) {\n return parsePublishableKey(publishableKey)?.frontendApi || '';\n }\n\n return resolvedProxyUrl.replace(/http(s)?:\\/\\//, '');\n } else if (domain && !isDevOrStagingUrl(parsePublishableKey(publishableKey)?.frontendApi || '')) {\n return addClerkPrefix(domain);\n } else {\n return parsePublishableKey(publishableKey)?.frontendApi || '';\n }\n};\n\nfunction waitForPredicateWithTimeout(\n timeoutMs: number,\n predicate: () => boolean,\n rejectWith: Error,\n existingScript?: HTMLScriptElement,\n): Promise<HTMLScriptElement | null> {\n return new Promise((resolve, reject) => {\n let resolved = false;\n\n const cleanup = (timeoutId: ReturnType<typeof setTimeout>, pollInterval: ReturnType<typeof setInterval>) => {\n clearTimeout(timeoutId);\n clearInterval(pollInterval);\n };\n\n // Bail out early if the script fails to load, instead of waiting for the entire timeout\n existingScript?.addEventListener('error', () => {\n cleanup(timeoutId, pollInterval);\n reject(rejectWith);\n });\n\n const checkAndResolve = () => {\n if (resolved) {\n return;\n }\n\n if (predicate()) {\n resolved = true;\n cleanup(timeoutId, pollInterval);\n resolve(null);\n }\n };\n\n const handleTimeout = () => {\n if (resolved) {\n return;\n }\n\n resolved = true;\n cleanup(timeoutId, pollInterval);\n\n if (!predicate()) {\n reject(rejectWith);\n } else {\n resolve(null);\n }\n };\n\n const timeoutId = setTimeout(handleTimeout, timeoutMs);\n\n checkAndResolve();\n\n const pollInterval = setInterval(() => {\n if (resolved) {\n clearInterval(pollInterval);\n return;\n }\n checkAndResolve();\n }, 100);\n });\n}\n\nexport function setClerkJSLoadingErrorPackageName(packageName: string) {\n errorThrower.setPackageName({ packageName });\n}\n\n/**\n * @deprecated Use `loadClerkJSScript` instead. This alias will be removed in a future major version.\n */\nexport const loadClerkJsScript = loadClerkJSScript;\n\n/**\n * @deprecated Use `clerkJSScriptUrl` instead. This alias will be removed in a future major version.\n */\nexport const clerkJsScriptUrl = clerkJSScriptUrl;\n\n/**\n * @deprecated Use `buildClerkJSScriptAttributes` instead. This alias will be removed in a future major version.\n */\nexport const buildClerkJsScriptAttributes = buildClerkJSScriptAttributes;\n\n/**\n * @deprecated Use `setClerkJSLoadingErrorPackageName` instead. This alias will be removed in a future major version.\n */\nexport const setClerkJsLoadingErrorPackageName = setClerkJSLoadingErrorPackageName;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"loadClerkJsScript.mjs","names":[],"sources":["../src/loadClerkJsScript.ts"],"sourcesContent":["import { buildErrorThrower, ClerkRuntimeError } from './error';\nimport { createDevOrStagingUrlCache, parsePublishableKey } from './keys';\nimport { loadScript } from './loadScript';\nimport { isProxyUrlRelative, isValidProxyUrl, proxyUrlToAbsoluteURL } from './proxy';\nimport type { SDKMetadata } from './types';\nimport { addClerkPrefix } from './url';\nimport { versionSelector } from './versionSelector';\n\nconst { isDevOrStagingUrl } = createDevOrStagingUrlCache();\n\nconst errorThrower = buildErrorThrower({ packageName: '@clerk/shared' });\n\nexport type LoadClerkJSScriptOptions = {\n publishableKey: string;\n /** @internal */\n __internal_clerkJSUrl?: string;\n /** @internal */\n __internal_clerkJSVersion?: string;\n sdkMetadata?: SDKMetadata;\n proxyUrl?: string;\n domain?: string;\n nonce?: string;\n /**\n * Timeout in milliseconds to wait for clerk-js to load before considering it failed.\n *\n * @default 15000 (15 seconds)\n */\n scriptLoadTimeout?: number;\n};\n\n/**\n * @deprecated Use `LoadClerkJSScriptOptions` instead. This alias will be removed in a future major version.\n */\nexport type LoadClerkJsScriptOptions = LoadClerkJSScriptOptions;\n\nexport type LoadClerkUIScriptOptions = {\n publishableKey: string;\n /** @internal */\n __internal_clerkUIUrl?: string;\n /** @internal */\n __internal_clerkUIVersion?: string;\n proxyUrl?: string;\n domain?: string;\n nonce?: string;\n scriptLoadTimeout?: number;\n};\n\n/**\n * Validates that window.Clerk exists and is properly initialized.\n * This ensures we don't have false positives where the script loads but Clerk is malformed.\n *\n * @returns `true` if window.Clerk exists and has the expected structure with a load method.\n */\nfunction isClerkGlobalProperlyLoaded(prop: 'Clerk' | '__internal_ClerkUICtor'): boolean {\n if (typeof window === 'undefined' || !(window as any)[prop]) {\n return false;\n }\n\n // Basic validation that window.Clerk has the expected structure\n const val = (window as any)[prop];\n return !!val;\n}\nconst isClerkProperlyLoaded = () => isClerkGlobalProperlyLoaded('Clerk');\nconst isClerkUIProperlyLoaded = () => isClerkGlobalProperlyLoaded('__internal_ClerkUICtor');\n\n/**\n * Checks if an existing script has a request error using Performance API.\n *\n * @param scriptUrl - The URL of the script to check.\n * @returns True if the script has failed to load due to a network/HTTP error.\n */\nfunction hasScriptRequestError(scriptUrl: string): boolean {\n if (typeof window === 'undefined' || !window.performance) {\n return false;\n }\n\n const entries = performance.getEntriesByName(scriptUrl, 'resource') as PerformanceResourceTiming[];\n\n if (entries.length === 0) {\n return false;\n }\n\n const scriptEntry = entries[entries.length - 1];\n\n // transferSize === 0 with responseEnd === 0 indicates network failure\n // transferSize === 0 with responseEnd > 0 might be a 4xx/5xx error or blocked request\n if (scriptEntry.transferSize === 0 && scriptEntry.decodedBodySize === 0) {\n // If there was no response at all, it's definitely an error\n if (scriptEntry.responseEnd === 0) {\n return true;\n }\n // If we got a response but no content, likely an HTTP error (4xx/5xx)\n if (scriptEntry.responseEnd > 0 && scriptEntry.responseStart > 0) {\n return true;\n }\n\n if ('responseStatus' in scriptEntry) {\n const status = (scriptEntry as any).responseStatus;\n if (status >= 400) {\n return true;\n }\n if (scriptEntry.responseStatus === 0) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Hotloads the Clerk JS script with robust failure detection.\n *\n * Uses a timeout-based approach to ensure absolute certainty about load success/failure.\n * If the script fails to load within the timeout period, or loads but doesn't create\n * a proper Clerk instance, the promise rejects with an error.\n *\n * @param opts - The options used to build the Clerk JS script URL and load the script.\n * Must include a `publishableKey` if no existing script is found.\n * @returns Promise that resolves with null if Clerk loads successfully, or rejects with an error.\n *\n * @example\n * ```typescript\n * try {\n * await loadClerkJsScript({ publishableKey: 'pk_test_...' });\n * console.log('Clerk loaded successfully');\n * } catch (error) {\n * console.error('Failed to load Clerk:', error.message);\n * }\n * ```\n */\nexport const loadClerkJSScript = async (opts?: LoadClerkJSScriptOptions): Promise<HTMLScriptElement | null> => {\n const timeout = opts?.scriptLoadTimeout ?? 15000;\n const rejectWith = (error?: Error) =>\n new ClerkRuntimeError('Failed to load Clerk JS' + (error?.message ? `, ${error.message}` : ''), {\n code: 'failed_to_load_clerk_js',\n cause: error,\n });\n\n if (isClerkProperlyLoaded()) {\n return null;\n }\n\n if (!opts?.publishableKey) {\n errorThrower.throwMissingPublishableKeyError();\n return null;\n }\n\n const scriptUrl = clerkJSScriptUrl(opts);\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-clerk-js-script]');\n\n if (existingScript) {\n if (hasScriptRequestError(scriptUrl)) {\n existingScript.remove();\n } else {\n try {\n await waitForPredicateWithTimeout(timeout, isClerkProperlyLoaded, rejectWith(), existingScript);\n return null;\n } catch {\n existingScript.remove();\n }\n }\n }\n\n const loadPromise = waitForPredicateWithTimeout(timeout, isClerkProperlyLoaded, rejectWith());\n\n loadScript(scriptUrl, {\n async: true,\n crossOrigin: 'anonymous',\n nonce: opts.nonce,\n beforeLoad: applyAttributesToScript(buildClerkJSScriptAttributes(opts)),\n }).catch(error => {\n throw rejectWith(error);\n });\n\n return loadPromise;\n};\n\nexport const loadClerkUIScript = async (opts?: LoadClerkUIScriptOptions): Promise<HTMLScriptElement | null> => {\n const timeout = opts?.scriptLoadTimeout ?? 15000;\n const rejectWith = (error?: Error) =>\n new ClerkRuntimeError('Failed to load Clerk UI' + (error?.message ? `, ${error.message}` : ''), {\n code: 'failed_to_load_clerk_ui',\n cause: error,\n });\n\n if (isClerkUIProperlyLoaded()) {\n return null;\n }\n\n if (!opts?.publishableKey) {\n errorThrower.throwMissingPublishableKeyError();\n return null;\n }\n\n const scriptUrl = clerkUIScriptUrl(opts);\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-clerk-ui-script]');\n\n if (existingScript) {\n if (hasScriptRequestError(scriptUrl)) {\n existingScript.remove();\n } else {\n try {\n await waitForPredicateWithTimeout(timeout, isClerkUIProperlyLoaded, rejectWith(), existingScript);\n return null;\n } catch {\n existingScript.remove();\n }\n }\n }\n\n const loadPromise = waitForPredicateWithTimeout(timeout, isClerkUIProperlyLoaded, rejectWith());\n\n loadScript(scriptUrl, {\n async: true,\n crossOrigin: 'anonymous',\n nonce: opts.nonce,\n beforeLoad: applyAttributesToScript(buildClerkUIScriptAttributes(opts)),\n }).catch(error => {\n throw rejectWith(error);\n });\n\n return loadPromise;\n};\n\nexport const clerkJSScriptUrl = (opts: LoadClerkJSScriptOptions) => {\n const { __internal_clerkJSUrl, __internal_clerkJSVersion, proxyUrl, domain, publishableKey } = opts;\n\n if (__internal_clerkJSUrl) {\n return __internal_clerkJSUrl;\n }\n\n const version = versionSelector(__internal_clerkJSVersion);\n\n if (proxyUrl && isProxyUrlRelative(proxyUrl)) {\n return buildRelativeProxyScriptUrl(proxyUrl, 'clerk-js', version, 'clerk.browser.js');\n }\n\n const scriptHost = buildScriptHost({ publishableKey, proxyUrl, domain });\n return `https://${scriptHost}/npm/@clerk/clerk-js@${version}/dist/clerk.browser.js`;\n};\n\nexport const clerkUIScriptUrl = (opts: LoadClerkUIScriptOptions) => {\n const { __internal_clerkUIUrl, __internal_clerkUIVersion, proxyUrl, domain, publishableKey } = opts;\n\n if (__internal_clerkUIUrl) {\n return __internal_clerkUIUrl;\n }\n\n const version = versionSelector(__internal_clerkUIVersion, UI_PACKAGE_VERSION);\n\n if (proxyUrl && isProxyUrlRelative(proxyUrl)) {\n return buildRelativeProxyScriptUrl(proxyUrl, 'ui', version, 'ui.browser.js');\n }\n\n const scriptHost = buildScriptHost({ publishableKey, proxyUrl, domain });\n return `https://${scriptHost}/npm/@clerk/ui@${version}/dist/ui.browser.js`;\n};\n\nexport const buildClerkJSScriptAttributes = (options: LoadClerkJSScriptOptions) => {\n const obj: Record<string, string> = {};\n\n if (options.publishableKey) {\n obj['data-clerk-publishable-key'] = options.publishableKey;\n }\n\n if (options.proxyUrl) {\n obj['data-clerk-proxy-url'] = options.proxyUrl;\n }\n\n if (options.domain) {\n obj['data-clerk-domain'] = options.domain;\n }\n\n if (options.nonce) {\n obj.nonce = options.nonce;\n }\n\n return obj;\n};\n\nexport const buildClerkUIScriptAttributes = (options: LoadClerkUIScriptOptions) => {\n // TODO @nikos do we need this?\n return buildClerkJSScriptAttributes(options);\n};\n\nconst applyAttributesToScript = (attributes: Record<string, string>) => (script: HTMLScriptElement) => {\n for (const attribute in attributes) {\n script.setAttribute(attribute, attributes[attribute]);\n }\n};\n\nconst stripTrailingSlashes = (value: string) => {\n while (value.endsWith('/')) {\n value = value.slice(0, -1);\n }\n\n return value;\n};\n\nconst buildRelativeProxyScriptUrl = (proxyUrl: string, packageName: string, version: string, fileName: string) => {\n return `${stripTrailingSlashes(proxyUrl)}/npm/@clerk/${packageName}@${version}/dist/${fileName}`;\n};\n\nexport const buildScriptHost = (opts: { publishableKey: string; proxyUrl?: string; domain?: string }) => {\n const { proxyUrl, domain, publishableKey } = opts;\n\n if (!!proxyUrl && isValidProxyUrl(proxyUrl)) {\n const resolvedProxyUrl = proxyUrlToAbsoluteURL(proxyUrl);\n\n if (isProxyUrlRelative(resolvedProxyUrl)) {\n return parsePublishableKey(publishableKey)?.frontendApi || '';\n }\n\n return resolvedProxyUrl.replace(/http(s)?:\\/\\//, '');\n } else if (domain && !isDevOrStagingUrl(parsePublishableKey(publishableKey)?.frontendApi || '')) {\n return addClerkPrefix(domain);\n } else {\n return parsePublishableKey(publishableKey)?.frontendApi || '';\n }\n};\n\nfunction waitForPredicateWithTimeout(\n timeoutMs: number,\n predicate: () => boolean,\n rejectWith: Error,\n existingScript?: HTMLScriptElement,\n): Promise<HTMLScriptElement | null> {\n return new Promise((resolve, reject) => {\n let resolved = false;\n\n const cleanup = (timeoutId: ReturnType<typeof setTimeout>, pollInterval: ReturnType<typeof setInterval>) => {\n clearTimeout(timeoutId);\n clearInterval(pollInterval);\n };\n\n // Bail out early if the script fails to load, instead of waiting for the entire timeout\n existingScript?.addEventListener('error', () => {\n cleanup(timeoutId, pollInterval);\n reject(rejectWith);\n });\n\n const checkAndResolve = () => {\n if (resolved) {\n return;\n }\n\n if (predicate()) {\n resolved = true;\n cleanup(timeoutId, pollInterval);\n resolve(null);\n }\n };\n\n const handleTimeout = () => {\n if (resolved) {\n return;\n }\n\n resolved = true;\n cleanup(timeoutId, pollInterval);\n\n if (!predicate()) {\n reject(rejectWith);\n } else {\n resolve(null);\n }\n };\n\n const timeoutId = setTimeout(handleTimeout, timeoutMs);\n\n checkAndResolve();\n\n const pollInterval = setInterval(() => {\n if (resolved) {\n clearInterval(pollInterval);\n return;\n }\n checkAndResolve();\n }, 100);\n });\n}\n\nexport function setClerkJSLoadingErrorPackageName(packageName: string) {\n errorThrower.setPackageName({ packageName });\n}\n\n/**\n * @deprecated Use `loadClerkJSScript` instead. This alias will be removed in a future major version.\n */\nexport const loadClerkJsScript = loadClerkJSScript;\n\n/**\n * @deprecated Use `clerkJSScriptUrl` instead. This alias will be removed in a future major version.\n */\nexport const clerkJsScriptUrl = clerkJSScriptUrl;\n\n/**\n * @deprecated Use `buildClerkJSScriptAttributes` instead. This alias will be removed in a future major version.\n */\nexport const buildClerkJsScriptAttributes = buildClerkJSScriptAttributes;\n\n/**\n * @deprecated Use `setClerkJSLoadingErrorPackageName` instead. This alias will be removed in a future major version.\n */\nexport const setClerkJsLoadingErrorPackageName = setClerkJSLoadingErrorPackageName;\n"],"mappings":"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"}
|
package/dist/react/index.js
CHANGED
|
@@ -4,7 +4,7 @@ const require_authorization_errors = require('../authorization-errors.js');
|
|
|
4
4
|
const require_authorization = require('../authorization.js');
|
|
5
5
|
const require_deriveState = require('../deriveState.js');
|
|
6
6
|
const require_clerkRuntimeError = require('../_chunks/clerkRuntimeError-CYZdTZ_x.js');
|
|
7
|
-
const require_error = require('../_chunks/error-
|
|
7
|
+
const require_error = require('../_chunks/error-DiOD3e6d.js');
|
|
8
8
|
const require_logger = require('../logger.js');
|
|
9
9
|
const require_organization = require('../organization.js');
|
|
10
10
|
const require_telemetry = require('../_chunks/telemetry-DZp9OI1j.js');
|
package/dist/react/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { isReverificationHint, reverificationError } from "../authorization-erro
|
|
|
2
2
|
import { validateReverificationConfig } from "../authorization.mjs";
|
|
3
3
|
import { deriveFromSsrInitialState } from "../deriveState.mjs";
|
|
4
4
|
import { t as ClerkRuntimeError } from "../_chunks/clerkRuntimeError-DlesLWqO.mjs";
|
|
5
|
-
import { C as isClerkAPIResponseError } from "../_chunks/error-
|
|
5
|
+
import { C as isClerkAPIResponseError } from "../_chunks/error-DRCZN5DP.mjs";
|
|
6
6
|
import { logger } from "../logger.mjs";
|
|
7
7
|
import { getCurrentOrganizationMembership } from "../organization.mjs";
|
|
8
8
|
import { a as eventMethodCalled } from "../_chunks/telemetry-9C6N5ppw.mjs";
|
package/dist/versionSelector.js
CHANGED
|
@@ -12,7 +12,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
12
12
|
* @param packageVersion - The version of `@clerk/clerk-js` that will be used if an explicit version is not provided
|
|
13
13
|
* @returns The npm tag, version or major version to use
|
|
14
14
|
*/
|
|
15
|
-
const versionSelector = (clerkJSVersion, packageVersion = "6.29.3
|
|
15
|
+
const versionSelector = (clerkJSVersion, packageVersion = "6.29.3") => {
|
|
16
16
|
if (clerkJSVersion) return clerkJSVersion;
|
|
17
17
|
const prereleaseTag = getPrereleaseTag(packageVersion);
|
|
18
18
|
if (prereleaseTag) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"versionSelector.js","names":[],"sources":["../src/versionSelector.ts"],"sourcesContent":["/**\n * This version selector is a bit complicated, so here is the flow:\n * 1. Use the clerkJSVersion prop on the provider\n * 2. Use the exact `@clerk/clerk-js` version if it is a `@snapshot` prerelease\n * 3. Use the prerelease tag of `@clerk/clerk-js` or the packageVersion provided\n * 4. Fallback to the major version of `@clerk/clerk-js` or the packageVersion provided\n *\n * @param clerkJSVersion - The optional clerkJSVersion prop on the provider\n * @param packageVersion - The version of `@clerk/clerk-js` that will be used if an explicit version is not provided\n * @returns The npm tag, version or major version to use\n */\nexport const versionSelector = (clerkJSVersion: string | undefined, packageVersion = JS_PACKAGE_VERSION) => {\n if (clerkJSVersion) {\n return clerkJSVersion;\n }\n\n const prereleaseTag = getPrereleaseTag(packageVersion);\n if (prereleaseTag) {\n if (prereleaseTag === 'snapshot') {\n return packageVersion;\n }\n\n return prereleaseTag;\n }\n\n return getMajorVersion(packageVersion);\n};\n\nconst getPrereleaseTag = (packageVersion: string) =>\n packageVersion\n .trim()\n .replace(/^v/, '')\n .match(/-(.+?)(\\.|$)/)?.[1];\n\nexport const getMajorVersion = (packageVersion: string) => packageVersion.trim().replace(/^v/, '').split('.')[0];\n"],"mappings":";;;;;;;;;;;;;;AAWA,MAAa,mBAAmB,gBAAoC,
|
|
1
|
+
{"version":3,"file":"versionSelector.js","names":[],"sources":["../src/versionSelector.ts"],"sourcesContent":["/**\n * This version selector is a bit complicated, so here is the flow:\n * 1. Use the clerkJSVersion prop on the provider\n * 2. Use the exact `@clerk/clerk-js` version if it is a `@snapshot` prerelease\n * 3. Use the prerelease tag of `@clerk/clerk-js` or the packageVersion provided\n * 4. Fallback to the major version of `@clerk/clerk-js` or the packageVersion provided\n *\n * @param clerkJSVersion - The optional clerkJSVersion prop on the provider\n * @param packageVersion - The version of `@clerk/clerk-js` that will be used if an explicit version is not provided\n * @returns The npm tag, version or major version to use\n */\nexport const versionSelector = (clerkJSVersion: string | undefined, packageVersion = JS_PACKAGE_VERSION) => {\n if (clerkJSVersion) {\n return clerkJSVersion;\n }\n\n const prereleaseTag = getPrereleaseTag(packageVersion);\n if (prereleaseTag) {\n if (prereleaseTag === 'snapshot') {\n return packageVersion;\n }\n\n return prereleaseTag;\n }\n\n return getMajorVersion(packageVersion);\n};\n\nconst getPrereleaseTag = (packageVersion: string) =>\n packageVersion\n .trim()\n .replace(/^v/, '')\n .match(/-(.+?)(\\.|$)/)?.[1];\n\nexport const getMajorVersion = (packageVersion: string) => packageVersion.trim().replace(/^v/, '').split('.')[0];\n"],"mappings":";;;;;;;;;;;;;;AAWA,MAAa,mBAAmB,gBAAoC,8BAAwC;CAC1G,IAAI,gBACF,OAAO;CAGT,MAAM,gBAAgB,iBAAiB,cAAc;CACrD,IAAI,eAAe;EACjB,IAAI,kBAAkB,YACpB,OAAO;EAGT,OAAO;CACT;CAEA,OAAO,gBAAgB,cAAc;AACvC;AAEA,MAAM,oBAAoB,mBACxB,eACG,KAAK,CAAC,CACN,QAAQ,MAAM,EAAE,CAAC,CACjB,MAAM,cAAc,CAAC,GAAG;AAE7B,MAAa,mBAAmB,mBAA2B,eAAe,KAAK,CAAC,CAAC,QAAQ,MAAM,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC"}
|
package/dist/versionSelector.mjs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* @param packageVersion - The version of `@clerk/clerk-js` that will be used if an explicit version is not provided
|
|
11
11
|
* @returns The npm tag, version or major version to use
|
|
12
12
|
*/
|
|
13
|
-
const versionSelector = (clerkJSVersion, packageVersion = "6.29.3
|
|
13
|
+
const versionSelector = (clerkJSVersion, packageVersion = "6.29.3") => {
|
|
14
14
|
if (clerkJSVersion) return clerkJSVersion;
|
|
15
15
|
const prereleaseTag = getPrereleaseTag(packageVersion);
|
|
16
16
|
if (prereleaseTag) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"versionSelector.mjs","names":[],"sources":["../src/versionSelector.ts"],"sourcesContent":["/**\n * This version selector is a bit complicated, so here is the flow:\n * 1. Use the clerkJSVersion prop on the provider\n * 2. Use the exact `@clerk/clerk-js` version if it is a `@snapshot` prerelease\n * 3. Use the prerelease tag of `@clerk/clerk-js` or the packageVersion provided\n * 4. Fallback to the major version of `@clerk/clerk-js` or the packageVersion provided\n *\n * @param clerkJSVersion - The optional clerkJSVersion prop on the provider\n * @param packageVersion - The version of `@clerk/clerk-js` that will be used if an explicit version is not provided\n * @returns The npm tag, version or major version to use\n */\nexport const versionSelector = (clerkJSVersion: string | undefined, packageVersion = JS_PACKAGE_VERSION) => {\n if (clerkJSVersion) {\n return clerkJSVersion;\n }\n\n const prereleaseTag = getPrereleaseTag(packageVersion);\n if (prereleaseTag) {\n if (prereleaseTag === 'snapshot') {\n return packageVersion;\n }\n\n return prereleaseTag;\n }\n\n return getMajorVersion(packageVersion);\n};\n\nconst getPrereleaseTag = (packageVersion: string) =>\n packageVersion\n .trim()\n .replace(/^v/, '')\n .match(/-(.+?)(\\.|$)/)?.[1];\n\nexport const getMajorVersion = (packageVersion: string) => packageVersion.trim().replace(/^v/, '').split('.')[0];\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,mBAAmB,gBAAoC,
|
|
1
|
+
{"version":3,"file":"versionSelector.mjs","names":[],"sources":["../src/versionSelector.ts"],"sourcesContent":["/**\n * This version selector is a bit complicated, so here is the flow:\n * 1. Use the clerkJSVersion prop on the provider\n * 2. Use the exact `@clerk/clerk-js` version if it is a `@snapshot` prerelease\n * 3. Use the prerelease tag of `@clerk/clerk-js` or the packageVersion provided\n * 4. Fallback to the major version of `@clerk/clerk-js` or the packageVersion provided\n *\n * @param clerkJSVersion - The optional clerkJSVersion prop on the provider\n * @param packageVersion - The version of `@clerk/clerk-js` that will be used if an explicit version is not provided\n * @returns The npm tag, version or major version to use\n */\nexport const versionSelector = (clerkJSVersion: string | undefined, packageVersion = JS_PACKAGE_VERSION) => {\n if (clerkJSVersion) {\n return clerkJSVersion;\n }\n\n const prereleaseTag = getPrereleaseTag(packageVersion);\n if (prereleaseTag) {\n if (prereleaseTag === 'snapshot') {\n return packageVersion;\n }\n\n return prereleaseTag;\n }\n\n return getMajorVersion(packageVersion);\n};\n\nconst getPrereleaseTag = (packageVersion: string) =>\n packageVersion\n .trim()\n .replace(/^v/, '')\n .match(/-(.+?)(\\.|$)/)?.[1];\n\nexport const getMajorVersion = (packageVersion: string) => packageVersion.trim().replace(/^v/, '').split('.')[0];\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,mBAAmB,gBAAoC,8BAAwC;CAC1G,IAAI,gBACF,OAAO;CAGT,MAAM,gBAAgB,iBAAiB,cAAc;CACrD,IAAI,eAAe;EACjB,IAAI,kBAAkB,YACpB,OAAO;EAGT,OAAO;CACT;CAEA,OAAO,gBAAgB,cAAc;AACvC;AAEA,MAAM,oBAAoB,mBACxB,eACG,KAAK,CAAC,CACN,QAAQ,MAAM,EAAE,CAAC,CACjB,MAAM,cAAc,CAAC,GAAG;AAE7B,MAAa,mBAAmB,mBAA2B,eAAe,KAAK,CAAC,CAAC,QAAQ,MAAM,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"error-BmCE2eHg.js","names":["createErrorTypeGuard","ClerkError","createErrorTypeGuard","ClerkRuntimeError","isClerkRuntimeError","ClerkRuntimeError","isClerkRuntimeError"],"sources":["../../src/errors/clerkApiError.ts","../../src/errors/parseError.ts","../../src/errors/clerkApiResponseError.ts","../../src/errors/missingExpiredTokenError.ts","../../src/errors/clerkOfflineError.ts","../../src/errors/errorThrower.ts","../../src/errors/emailLinkError.ts","../../src/errors/webAuthNError.ts","../../src/errors/helpers.ts","../../src/errors/globalHookError.ts"],"sourcesContent":["import type { ClerkAPIError as ClerkAPIErrorInterface, ClerkAPIErrorJSON } from '../types';\nimport { createErrorTypeGuard } from './createErrorTypeGuard';\n\nexport type ClerkAPIErrorMeta = Record<string, unknown>;\n\n/**\n * This error contains the specific error message, code, and any additional metadata that was returned by the Clerk API.\n */\nexport class ClerkAPIError<Meta extends ClerkAPIErrorMeta = any> implements ClerkAPIErrorInterface {\n static kind = 'ClerkAPIError';\n readonly code: string;\n readonly message: string;\n readonly longMessage: string | undefined;\n readonly meta: Meta;\n\n constructor(json: ClerkAPIErrorJSON) {\n const parsedError = {\n code: json.code,\n message: json.message,\n longMessage: json.long_message,\n meta: {\n paramName: json.meta?.param_name,\n sessionId: json.meta?.session_id,\n emailAddresses: json.meta?.email_addresses,\n identifiers: json.meta?.identifiers,\n zxcvbn: json.meta?.zxcvbn,\n plan: json.meta?.plan,\n isPlanUpgradePossible: json.meta?.is_plan_upgrade_possible,\n seatsQuantityToAdd: json.meta?.seats_quantity_to_add,\n seatsQuantity: json.meta?.seats_quantity,\n } as unknown as Meta,\n };\n this.code = parsedError.code;\n this.message = parsedError.message;\n this.longMessage = parsedError.longMessage;\n this.meta = parsedError.meta;\n }\n}\n\n/**\n * Type guard to check if a value is a ClerkAPIError instance.\n */\nexport const isClerkAPIError = createErrorTypeGuard(ClerkAPIError);\n","import type { ClerkAPIError as ClerkAPIErrorInterface, ClerkAPIErrorJSON } from '../types';\nimport { ClerkAPIError } from './clerkApiError';\n\n/**\n * Parses an array of ClerkAPIErrorJSON objects into an array of ClerkAPIError objects.\n *\n * @internal\n */\nexport function parseErrors(data: ClerkAPIErrorJSON[] = []): ClerkAPIErrorInterface[] {\n return data.length > 0 ? data.map(e => new ClerkAPIError(e)) : [];\n}\n\n/**\n * Parses a ClerkAPIErrorJSON object into a ClerkAPIError object.\n *\n * @deprecated Use `ClerkAPIError` class instead\n *\n * @internal\n */\nexport function parseError(error: ClerkAPIErrorJSON): ClerkAPIErrorInterface {\n return new ClerkAPIError(error);\n}\n\n/**\n * Converts a ClerkAPIError object into a ClerkAPIErrorJSON object.\n *\n * @internal\n */\nexport function errorToJSON(error: ClerkAPIError | null): ClerkAPIErrorJSON {\n return {\n code: error?.code || '',\n message: error?.message || '',\n long_message: error?.longMessage,\n meta: {\n param_name: error?.meta?.paramName,\n session_id: error?.meta?.sessionId,\n email_addresses: error?.meta?.emailAddresses,\n identifiers: error?.meta?.identifiers,\n zxcvbn: error?.meta?.zxcvbn,\n plan: error?.meta?.plan,\n is_plan_upgrade_possible: error?.meta?.isPlanUpgradePossible,\n seats_quantity_to_add: error?.meta?.seatsQuantityToAdd,\n seats_quantity: error?.meta?.seatsQuantity,\n },\n };\n}\n","import type { ClerkAPIErrorJSON, ClerkAPIResponseError as ClerkAPIResponseErrorInterface } from '../types';\nimport { ClerkAPIError } from './clerkApiError';\nimport type { ClerkErrorParams } from './clerkError';\nimport { ClerkError } from './clerkError';\nimport { createErrorTypeGuard } from './createErrorTypeGuard';\n\ninterface ClerkAPIResponseOptions extends Omit<ClerkErrorParams, 'message' | 'code'> {\n data: ClerkAPIErrorJSON[];\n status: number;\n clerkTraceId?: string;\n retryAfter?: number;\n}\n\nexport class ClerkAPIResponseError extends ClerkError implements ClerkAPIResponseErrorInterface {\n static kind = 'ClerkAPIResponseError';\n status: number;\n clerkTraceId?: string;\n retryAfter?: number;\n errors: ClerkAPIError[];\n\n constructor(message: string, options: ClerkAPIResponseOptions) {\n const { data: errorsJson, status, clerkTraceId, retryAfter } = options;\n super({ ...options, message, code: 'api_response_error' });\n Object.setPrototypeOf(this, ClerkAPIResponseError.prototype);\n this.status = status;\n this.clerkTraceId = clerkTraceId;\n this.retryAfter = retryAfter;\n this.errors = (errorsJson || []).map(e => new ClerkAPIError(e));\n }\n\n public toString() {\n let message = `[${this.name}]\\nMessage:${this.message}\\nStatus:${this.status}\\nSerialized errors: ${this.errors.map(\n e => JSON.stringify(e),\n )}`;\n\n if (this.clerkTraceId) {\n message += `\\nClerk Trace ID: ${this.clerkTraceId}`;\n }\n\n return message;\n }\n\n // Override formatMessage to keep it unformatted for backward compatibility\n protected static override formatMessage(name: string, msg: string, _: string, __: string | undefined) {\n return msg;\n }\n}\n\n/**\n * Type guard to check if an error is a ClerkAPIResponseError.\n * Can be called as a standalone function or as a method on an error object.\n *\n * @example\n * // As a standalone function\n * if (isClerkAPIResponseError(error)) { ... }\n *\n * // As a method (when attached to error object)\n * if (error.isClerkAPIResponseError()) { ... }\n */\nexport const isClerkAPIResponseError = createErrorTypeGuard(ClerkAPIResponseError);\n","import { ClerkAPIResponseError, isClerkAPIResponseError } from './clerkApiResponseError';\n\n/**\n * Error class representing a missing expired token error from the API.\n * This error occurs when the server requires an expired token to mint a new session token.\n *\n * Use the static `is` method to check if a ClerkAPIResponseError matches this error type.\n *\n * @example\n * ```typescript\n * if (MissingExpiredTokenError.is(error)) {\n * // Handle the missing expired token error\n * }\n * ```\n */\nexport class MissingExpiredTokenError extends ClerkAPIResponseError {\n static kind = 'MissingExpiredTokenError';\n static readonly ERROR_CODE = 'missing_expired_token' as const;\n static readonly STATUS = 422 as const;\n\n /**\n * Type guard to check if an error is a MissingExpiredTokenError.\n * This checks the error's properties (status and error code) rather than instanceof,\n * allowing it to work with ClerkAPIResponseError instances thrown from the API layer.\n *\n * @example\n * ```typescript\n * try {\n * await someApiCall();\n * } catch (e) {\n * if (MissingExpiredTokenError.is(e)) {\n * // e is typed as ClerkAPIResponseError with the specific error properties\n * }\n * }\n * ```\n */\n static is(err: unknown): err is ClerkAPIResponseError {\n return (\n isClerkAPIResponseError(err) &&\n err.status === MissingExpiredTokenError.STATUS &&\n err.errors.length > 0 &&\n err.errors[0].code === MissingExpiredTokenError.ERROR_CODE\n );\n }\n}\n","import { ClerkRuntimeError, isClerkRuntimeError } from './clerkRuntimeError';\n\n/**\n * Error thrown when a network request fails due to the client being offline.\n *\n * This error is thrown instead of returning `null` to make it explicit that\n * the failure was due to network conditions, not authentication state.\n *\n * @example\n * ```typescript\n * try {\n * const token = await session.getToken();\n * } catch (error) {\n * if (ClerkOfflineError.is(error)) {\n * // Handle offline scenario\n * showOfflineScreen();\n * }\n * }\n * ```\n */\nexport class ClerkOfflineError extends ClerkRuntimeError {\n static kind = 'ClerkOfflineError';\n static readonly ERROR_CODE = 'clerk_offline' as const;\n\n constructor(message: string) {\n super(message, { code: ClerkOfflineError.ERROR_CODE });\n Object.setPrototypeOf(this, ClerkOfflineError.prototype);\n }\n\n /**\n * Type guard to check if an error is a ClerkOfflineError.\n * This checks both instanceof and the error code to support cross-bundle/cross-realm errors\n *\n * @example\n * ```typescript\n * try {\n * const token = await session.getToken();\n * } catch (error) {\n * if (ClerkOfflineError.is(error)) {\n * // error is typed as ClerkOfflineError\n * console.log('User is offline');\n * }\n * }\n * ```\n */\n static is(error: unknown): error is ClerkOfflineError {\n if (error === null || error === undefined) {\n return false;\n }\n return (\n error instanceof ClerkOfflineError || (isClerkRuntimeError(error) && error.code === ClerkOfflineError.ERROR_CODE)\n );\n }\n}\n","const DefaultMessages = Object.freeze({\n InvalidProxyUrlErrorMessage: `The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})`,\n InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, run:\n\n npx clerk@latest init\n\nThe command is non-interactive and requires no Clerk account or login. If you already have a Clerk application, run \\`npx clerk@latest env pull\\` to write its keys to your env file (\\`--instance prod\\` for production keys), or copy its Publishable key from https://dashboard.clerk.com/last-active?path=api-keys.`,\n MissingPublishableKeyErrorMessage: `Missing publishableKey. To set up Clerk for this project, run:\n\n npx clerk@latest init\n\nThe command is non-interactive and requires no Clerk account or login: it creates a Clerk application and writes the required keys to your env file. If you already have a Clerk application, run \\`npx clerk@latest env pull\\` to write its keys, or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploying to production? Run \\`npx clerk@latest deploy\\` to provision a production instance, or \\`npx clerk@latest env pull --instance prod\\` to use an existing one.`,\n MissingSecretKeyErrorMessage: `Missing secretKey. To set up Clerk for this project, run:\n\n npx clerk@latest init\n\nThe command is non-interactive and requires no Clerk account or login: it creates a Clerk application and writes the required keys to your env file. If you already have a Clerk application, run \\`npx clerk@latest env pull\\` to write its keys, or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploying to production? Run \\`npx clerk@latest deploy\\` to provision a production instance, or \\`npx clerk@latest env pull --instance prod\\` to use an existing one.`,\n MissingClerkProvider: `{{source}} can only be used within the <ClerkProvider /> component. Learn more: https://clerk.com/docs/components/clerk-provider`,\n});\n\ntype MessageKeys = keyof typeof DefaultMessages;\n\ntype Messages = Record<MessageKeys, string>;\n\ntype CustomMessages = Partial<Messages>;\n\nexport type ErrorThrowerOptions = {\n packageName: string;\n customMessages?: CustomMessages;\n};\n\nexport interface ErrorThrower {\n setPackageName(options: ErrorThrowerOptions): ErrorThrower;\n\n setMessages(options: ErrorThrowerOptions): ErrorThrower;\n\n throwInvalidPublishableKeyError(params: { key?: string }): never;\n\n throwInvalidProxyUrl(params: { url?: string }): never;\n\n throwMissingPublishableKeyError(): never;\n\n throwMissingSecretKeyError(): never;\n\n throwMissingClerkProviderError(params: { source?: string }): never;\n\n throw(message: string): never;\n}\n\n/**\n * Builds an error thrower.\n *\n * @internal\n */\nexport function buildErrorThrower({ packageName, customMessages }: ErrorThrowerOptions): ErrorThrower {\n let pkg = packageName;\n\n /**\n * Builds a message from a raw message and replacements.\n *\n * @internal\n */\n function buildMessage(rawMessage: string, replacements?: Record<string, string | number>) {\n if (!replacements) {\n return `${pkg}: ${rawMessage}`;\n }\n\n let msg = rawMessage;\n const matches = rawMessage.matchAll(/{{([a-zA-Z0-9-_]+)}}/g);\n\n for (const match of matches) {\n const replacement = (replacements[match[1]] || '').toString();\n msg = msg.replace(`{{${match[1]}}}`, replacement);\n }\n\n return `${pkg}: ${msg}`;\n }\n\n const messages = {\n ...DefaultMessages,\n ...customMessages,\n };\n\n return {\n setPackageName({ packageName }: ErrorThrowerOptions): ErrorThrower {\n if (typeof packageName === 'string') {\n pkg = packageName;\n }\n return this;\n },\n\n setMessages({ customMessages }: ErrorThrowerOptions): ErrorThrower {\n Object.assign(messages, customMessages || {});\n return this;\n },\n\n throwInvalidPublishableKeyError(params: { key?: string }): never {\n throw new Error(buildMessage(messages.InvalidPublishableKeyErrorMessage, params));\n },\n\n throwInvalidProxyUrl(params: { url?: string }): never {\n throw new Error(buildMessage(messages.InvalidProxyUrlErrorMessage, params));\n },\n\n throwMissingPublishableKeyError(): never {\n throw new Error(buildMessage(messages.MissingPublishableKeyErrorMessage));\n },\n\n throwMissingSecretKeyError(): never {\n throw new Error(buildMessage(messages.MissingSecretKeyErrorMessage));\n },\n\n throwMissingClerkProviderError(params: { source?: string }): never {\n throw new Error(buildMessage(messages.MissingClerkProvider, params));\n },\n\n throw(message: string): never {\n throw new Error(buildMessage(message));\n },\n };\n}\n","export class EmailLinkError extends Error {\n code: string;\n\n constructor(code: string) {\n super(code);\n this.code = code;\n this.name = 'EmailLinkError' as const;\n Object.setPrototypeOf(this, EmailLinkError.prototype);\n }\n}\n\n/**\n * @deprecated Use `EmailLinkErrorCodeStatus` instead.\n *\n * @internal\n */\nexport const EmailLinkErrorCode = {\n Expired: 'expired',\n Failed: 'failed',\n ClientMismatch: 'client_mismatch',\n};\n\nexport const EmailLinkErrorCodeStatus = {\n Expired: 'expired',\n Failed: 'failed',\n ClientMismatch: 'client_mismatch',\n} as const;\n","import type { ClerkErrorParams } from './clerkError';\nimport { ClerkRuntimeError } from './clerkRuntimeError';\n\ntype ClerkWebAuthnErrorCode =\n // Generic\n | 'passkey_not_supported'\n | 'passkey_pa_not_supported'\n | 'passkey_invalid_rpID_or_domain'\n | 'passkey_already_exists'\n | 'passkey_operation_aborted'\n // Retrieval\n | 'passkey_retrieval_cancelled'\n | 'passkey_retrieval_failed'\n // Registration\n | 'passkey_registration_cancelled'\n | 'passkey_registration_failed';\n\ntype ClerkWebAuthnErrorOptions = Omit<ClerkErrorParams, 'message' | 'code'> & { code: ClerkWebAuthnErrorCode };\n\nexport class ClerkWebAuthnError extends ClerkRuntimeError {\n /**\n * A unique code identifying the error, can be used for localization.\n */\n code: ClerkWebAuthnErrorCode;\n\n constructor(message: string, options: ClerkWebAuthnErrorOptions) {\n super(message, options);\n this.code = options.code;\n }\n}\n","import type { ClerkAPIResponseError } from './clerkApiResponseError';\nimport { isClerkAPIResponseError } from './clerkApiResponseError';\nimport type { ClerkRuntimeError } from './clerkRuntimeError';\nimport { isClerkRuntimeError } from './clerkRuntimeError';\nimport type { EmailLinkError } from './emailLinkError';\nimport type { MetamaskError } from './metamaskError';\n\n/**\n * Checks if the provided error object is an unauthorized error.\n *\n * @internal\n *\n * @deprecated This is no longer used, and will be removed in the next major version.\n */\nexport function isUnauthorizedError(e: any): boolean {\n const status = e?.status;\n const code = e?.errors?.[0]?.code;\n return code === 'authentication_invalid' && status === 401;\n}\n\n/**\n * Checks if the provided error object is a captcha error.\n *\n * @internal\n */\nexport function isCaptchaError(e: ClerkAPIResponseError): boolean {\n return ['captcha_invalid', 'captcha_not_enabled', 'captcha_missing_token'].includes(e.errors[0].code);\n}\n\n/**\n * Checks if the provided error is a 4xx error.\n *\n * @internal\n */\nexport function is4xxError(e: any): boolean {\n const status = e?.status;\n return !!status && status >= 400 && status < 500;\n}\n\n/**\n * Checks if the provided error is a 429 (Too Many Requests) error.\n *\n * @internal\n */\nexport function is429Error(e: any): boolean {\n return e?.status === 429;\n}\n\nconst unauthenticated403ErrorCodes = new Set(['user_banned', 'user_deactivated']);\n\n/**\n * Checks if the provided error indicates the user's session is no longer valid\n * and should trigger the unauthenticated flow (e.g. sign-out / redirect to sign-in).\n *\n * Only matches explicit authentication failure status codes:\n * - 401: session is invalid or expired\n * - 422: invalid session state (e.g. missing_expired_token)\n * - 403: terminal user state (e.g. user_banned, user_deactivated)\n *\n * 404 is intentionally excluded despite being returned for \"session not found\",\n * because it's also returned for unrelated resources (org not found, JWT template\n * not found) and shares the same `resource_not_found` error code, making it\n * impossible to distinguish. Session-not-found 401s are already handled directly\n * by Base._fetch.\n *\n * @internal\n */\nexport function isUnauthenticatedError(e: any): boolean {\n const status = e?.status;\n const hasTerminalUserErrorCode =\n Array.isArray(e?.errors) && e.errors.some((error: any) => unauthenticated403ErrorCodes.has(error?.code));\n\n return status === 401 || status === 422 || (status === 403 && hasTerminalUserErrorCode);\n}\n\n/**\n * Checks if the provided error is a network error.\n *\n * @internal\n */\nexport function isNetworkError(e: any): boolean {\n // TODO: revise during error handling epic\n const message = (`${e.message}${e.name}` || '').toLowerCase().replace(/\\s+/g, '');\n return message.includes('networkerror');\n}\n\n/**\n * Checks if the provided error is either a ClerkAPIResponseError, a ClerkRuntimeError, or a MetamaskError.\n */\nexport function isKnownError(error: any): error is ClerkAPIResponseError | ClerkRuntimeError | MetamaskError {\n return isClerkAPIResponseError(error) || isMetamaskError(error) || isClerkRuntimeError(error);\n}\n\n/**\n * Checks if the provided error is a Clerk runtime error indicating a reverification was cancelled.\n */\nexport function isReverificationCancelledError(err: any) {\n return isClerkRuntimeError(err) && err.code === 'reverification_cancelled';\n}\n\n/**\n * Checks if the provided error is a Metamask error.\n */\nexport function isMetamaskError(err: any): err is MetamaskError {\n return 'code' in err && [4001, 32602, 32603].includes(err.code) && 'message' in err;\n}\n\n/**\n * Checks if the provided error is clerk api response error indicating a user is locked.\n */\nexport function isUserLockedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'user_locked';\n}\n\n/**\n * Checks if the provided error is a clerk api response error indicating a password was pwned.\n *\n * @internal\n */\nexport function isPasswordPwnedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'form_password_pwned';\n}\n\n/**\n * Checks if the provided error is a clerk api response error indicating a password was compromised.\n *\n * @internal\n */\nexport function isPasswordCompromisedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'form_password_compromised';\n}\n\n/**\n * Checks if the provided error is an EmailLinkError.\n */\nexport function isEmailLinkError(err: Error): err is EmailLinkError {\n return err.name === 'EmailLinkError';\n}\n","import { isClerkAPIResponseError } from './clerkApiResponseError';\nimport type { ClerkError } from './clerkError';\nimport { isClerkRuntimeError } from './clerkRuntimeError';\n\n/**\n * Creates a ClerkGlobalHookError object from a ClerkError instance.\n * It's a wrapper for all the different instances of Clerk errors that can\n * be returned when using Clerk hooks.\n */\nexport function createClerkGlobalHookError(error: ClerkError) {\n const predicates = {\n isClerkAPIResponseError,\n isClerkRuntimeError,\n } as const;\n\n for (const [name, fn] of Object.entries(predicates)) {\n Object.assign(error, { [name]: fn });\n }\n\n return error as ClerkError & typeof predicates;\n}\n\nexport type ClerkGlobalHookError = ReturnType<typeof createClerkGlobalHookError>;\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"error-Br1l1pdF.mjs","names":[],"sources":["../../src/errors/clerkApiError.ts","../../src/errors/parseError.ts","../../src/errors/clerkApiResponseError.ts","../../src/errors/missingExpiredTokenError.ts","../../src/errors/clerkOfflineError.ts","../../src/errors/errorThrower.ts","../../src/errors/emailLinkError.ts","../../src/errors/webAuthNError.ts","../../src/errors/helpers.ts","../../src/errors/globalHookError.ts"],"sourcesContent":["import type { ClerkAPIError as ClerkAPIErrorInterface, ClerkAPIErrorJSON } from '../types';\nimport { createErrorTypeGuard } from './createErrorTypeGuard';\n\nexport type ClerkAPIErrorMeta = Record<string, unknown>;\n\n/**\n * This error contains the specific error message, code, and any additional metadata that was returned by the Clerk API.\n */\nexport class ClerkAPIError<Meta extends ClerkAPIErrorMeta = any> implements ClerkAPIErrorInterface {\n static kind = 'ClerkAPIError';\n readonly code: string;\n readonly message: string;\n readonly longMessage: string | undefined;\n readonly meta: Meta;\n\n constructor(json: ClerkAPIErrorJSON) {\n const parsedError = {\n code: json.code,\n message: json.message,\n longMessage: json.long_message,\n meta: {\n paramName: json.meta?.param_name,\n sessionId: json.meta?.session_id,\n emailAddresses: json.meta?.email_addresses,\n identifiers: json.meta?.identifiers,\n zxcvbn: json.meta?.zxcvbn,\n plan: json.meta?.plan,\n isPlanUpgradePossible: json.meta?.is_plan_upgrade_possible,\n seatsQuantityToAdd: json.meta?.seats_quantity_to_add,\n seatsQuantity: json.meta?.seats_quantity,\n } as unknown as Meta,\n };\n this.code = parsedError.code;\n this.message = parsedError.message;\n this.longMessage = parsedError.longMessage;\n this.meta = parsedError.meta;\n }\n}\n\n/**\n * Type guard to check if a value is a ClerkAPIError instance.\n */\nexport const isClerkAPIError = createErrorTypeGuard(ClerkAPIError);\n","import type { ClerkAPIError as ClerkAPIErrorInterface, ClerkAPIErrorJSON } from '../types';\nimport { ClerkAPIError } from './clerkApiError';\n\n/**\n * Parses an array of ClerkAPIErrorJSON objects into an array of ClerkAPIError objects.\n *\n * @internal\n */\nexport function parseErrors(data: ClerkAPIErrorJSON[] = []): ClerkAPIErrorInterface[] {\n return data.length > 0 ? data.map(e => new ClerkAPIError(e)) : [];\n}\n\n/**\n * Parses a ClerkAPIErrorJSON object into a ClerkAPIError object.\n *\n * @deprecated Use `ClerkAPIError` class instead\n *\n * @internal\n */\nexport function parseError(error: ClerkAPIErrorJSON): ClerkAPIErrorInterface {\n return new ClerkAPIError(error);\n}\n\n/**\n * Converts a ClerkAPIError object into a ClerkAPIErrorJSON object.\n *\n * @internal\n */\nexport function errorToJSON(error: ClerkAPIError | null): ClerkAPIErrorJSON {\n return {\n code: error?.code || '',\n message: error?.message || '',\n long_message: error?.longMessage,\n meta: {\n param_name: error?.meta?.paramName,\n session_id: error?.meta?.sessionId,\n email_addresses: error?.meta?.emailAddresses,\n identifiers: error?.meta?.identifiers,\n zxcvbn: error?.meta?.zxcvbn,\n plan: error?.meta?.plan,\n is_plan_upgrade_possible: error?.meta?.isPlanUpgradePossible,\n seats_quantity_to_add: error?.meta?.seatsQuantityToAdd,\n seats_quantity: error?.meta?.seatsQuantity,\n },\n };\n}\n","import type { ClerkAPIErrorJSON, ClerkAPIResponseError as ClerkAPIResponseErrorInterface } from '../types';\nimport { ClerkAPIError } from './clerkApiError';\nimport type { ClerkErrorParams } from './clerkError';\nimport { ClerkError } from './clerkError';\nimport { createErrorTypeGuard } from './createErrorTypeGuard';\n\ninterface ClerkAPIResponseOptions extends Omit<ClerkErrorParams, 'message' | 'code'> {\n data: ClerkAPIErrorJSON[];\n status: number;\n clerkTraceId?: string;\n retryAfter?: number;\n}\n\nexport class ClerkAPIResponseError extends ClerkError implements ClerkAPIResponseErrorInterface {\n static kind = 'ClerkAPIResponseError';\n status: number;\n clerkTraceId?: string;\n retryAfter?: number;\n errors: ClerkAPIError[];\n\n constructor(message: string, options: ClerkAPIResponseOptions) {\n const { data: errorsJson, status, clerkTraceId, retryAfter } = options;\n super({ ...options, message, code: 'api_response_error' });\n Object.setPrototypeOf(this, ClerkAPIResponseError.prototype);\n this.status = status;\n this.clerkTraceId = clerkTraceId;\n this.retryAfter = retryAfter;\n this.errors = (errorsJson || []).map(e => new ClerkAPIError(e));\n }\n\n public toString() {\n let message = `[${this.name}]\\nMessage:${this.message}\\nStatus:${this.status}\\nSerialized errors: ${this.errors.map(\n e => JSON.stringify(e),\n )}`;\n\n if (this.clerkTraceId) {\n message += `\\nClerk Trace ID: ${this.clerkTraceId}`;\n }\n\n return message;\n }\n\n // Override formatMessage to keep it unformatted for backward compatibility\n protected static override formatMessage(name: string, msg: string, _: string, __: string | undefined) {\n return msg;\n }\n}\n\n/**\n * Type guard to check if an error is a ClerkAPIResponseError.\n * Can be called as a standalone function or as a method on an error object.\n *\n * @example\n * // As a standalone function\n * if (isClerkAPIResponseError(error)) { ... }\n *\n * // As a method (when attached to error object)\n * if (error.isClerkAPIResponseError()) { ... }\n */\nexport const isClerkAPIResponseError = createErrorTypeGuard(ClerkAPIResponseError);\n","import { ClerkAPIResponseError, isClerkAPIResponseError } from './clerkApiResponseError';\n\n/**\n * Error class representing a missing expired token error from the API.\n * This error occurs when the server requires an expired token to mint a new session token.\n *\n * Use the static `is` method to check if a ClerkAPIResponseError matches this error type.\n *\n * @example\n * ```typescript\n * if (MissingExpiredTokenError.is(error)) {\n * // Handle the missing expired token error\n * }\n * ```\n */\nexport class MissingExpiredTokenError extends ClerkAPIResponseError {\n static kind = 'MissingExpiredTokenError';\n static readonly ERROR_CODE = 'missing_expired_token' as const;\n static readonly STATUS = 422 as const;\n\n /**\n * Type guard to check if an error is a MissingExpiredTokenError.\n * This checks the error's properties (status and error code) rather than instanceof,\n * allowing it to work with ClerkAPIResponseError instances thrown from the API layer.\n *\n * @example\n * ```typescript\n * try {\n * await someApiCall();\n * } catch (e) {\n * if (MissingExpiredTokenError.is(e)) {\n * // e is typed as ClerkAPIResponseError with the specific error properties\n * }\n * }\n * ```\n */\n static is(err: unknown): err is ClerkAPIResponseError {\n return (\n isClerkAPIResponseError(err) &&\n err.status === MissingExpiredTokenError.STATUS &&\n err.errors.length > 0 &&\n err.errors[0].code === MissingExpiredTokenError.ERROR_CODE\n );\n }\n}\n","import { ClerkRuntimeError, isClerkRuntimeError } from './clerkRuntimeError';\n\n/**\n * Error thrown when a network request fails due to the client being offline.\n *\n * This error is thrown instead of returning `null` to make it explicit that\n * the failure was due to network conditions, not authentication state.\n *\n * @example\n * ```typescript\n * try {\n * const token = await session.getToken();\n * } catch (error) {\n * if (ClerkOfflineError.is(error)) {\n * // Handle offline scenario\n * showOfflineScreen();\n * }\n * }\n * ```\n */\nexport class ClerkOfflineError extends ClerkRuntimeError {\n static kind = 'ClerkOfflineError';\n static readonly ERROR_CODE = 'clerk_offline' as const;\n\n constructor(message: string) {\n super(message, { code: ClerkOfflineError.ERROR_CODE });\n Object.setPrototypeOf(this, ClerkOfflineError.prototype);\n }\n\n /**\n * Type guard to check if an error is a ClerkOfflineError.\n * This checks both instanceof and the error code to support cross-bundle/cross-realm errors\n *\n * @example\n * ```typescript\n * try {\n * const token = await session.getToken();\n * } catch (error) {\n * if (ClerkOfflineError.is(error)) {\n * // error is typed as ClerkOfflineError\n * console.log('User is offline');\n * }\n * }\n * ```\n */\n static is(error: unknown): error is ClerkOfflineError {\n if (error === null || error === undefined) {\n return false;\n }\n return (\n error instanceof ClerkOfflineError || (isClerkRuntimeError(error) && error.code === ClerkOfflineError.ERROR_CODE)\n );\n }\n}\n","const DefaultMessages = Object.freeze({\n InvalidProxyUrlErrorMessage: `The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})`,\n InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid (key={{key}}, expected format: pk_test_... or pk_live_...). To create a Clerk application with valid keys, run:\n\n npx clerk@latest init\n\nThe command is non-interactive and requires no Clerk account or login. If you already have a Clerk application, run \\`npx clerk@latest env pull\\` to write its keys to your env file (\\`--instance prod\\` for production keys), or copy its Publishable key from https://dashboard.clerk.com/last-active?path=api-keys.`,\n MissingPublishableKeyErrorMessage: `Missing publishableKey. To set up Clerk for this project, run:\n\n npx clerk@latest init\n\nThe command is non-interactive and requires no Clerk account or login: it creates a Clerk application and writes the required keys to your env file. If you already have a Clerk application, run \\`npx clerk@latest env pull\\` to write its keys, or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploying to production? Run \\`npx clerk@latest deploy\\` to provision a production instance, or \\`npx clerk@latest env pull --instance prod\\` to use an existing one.`,\n MissingSecretKeyErrorMessage: `Missing secretKey. To set up Clerk for this project, run:\n\n npx clerk@latest init\n\nThe command is non-interactive and requires no Clerk account or login: it creates a Clerk application and writes the required keys to your env file. If you already have a Clerk application, run \\`npx clerk@latest env pull\\` to write its keys, or copy them from https://dashboard.clerk.com/last-active?path=api-keys. Deploying to production? Run \\`npx clerk@latest deploy\\` to provision a production instance, or \\`npx clerk@latest env pull --instance prod\\` to use an existing one.`,\n MissingClerkProvider: `{{source}} can only be used within the <ClerkProvider /> component. Learn more: https://clerk.com/docs/components/clerk-provider`,\n});\n\ntype MessageKeys = keyof typeof DefaultMessages;\n\ntype Messages = Record<MessageKeys, string>;\n\ntype CustomMessages = Partial<Messages>;\n\nexport type ErrorThrowerOptions = {\n packageName: string;\n customMessages?: CustomMessages;\n};\n\nexport interface ErrorThrower {\n setPackageName(options: ErrorThrowerOptions): ErrorThrower;\n\n setMessages(options: ErrorThrowerOptions): ErrorThrower;\n\n throwInvalidPublishableKeyError(params: { key?: string }): never;\n\n throwInvalidProxyUrl(params: { url?: string }): never;\n\n throwMissingPublishableKeyError(): never;\n\n throwMissingSecretKeyError(): never;\n\n throwMissingClerkProviderError(params: { source?: string }): never;\n\n throw(message: string): never;\n}\n\n/**\n * Builds an error thrower.\n *\n * @internal\n */\nexport function buildErrorThrower({ packageName, customMessages }: ErrorThrowerOptions): ErrorThrower {\n let pkg = packageName;\n\n /**\n * Builds a message from a raw message and replacements.\n *\n * @internal\n */\n function buildMessage(rawMessage: string, replacements?: Record<string, string | number>) {\n if (!replacements) {\n return `${pkg}: ${rawMessage}`;\n }\n\n let msg = rawMessage;\n const matches = rawMessage.matchAll(/{{([a-zA-Z0-9-_]+)}}/g);\n\n for (const match of matches) {\n const replacement = (replacements[match[1]] || '').toString();\n msg = msg.replace(`{{${match[1]}}}`, replacement);\n }\n\n return `${pkg}: ${msg}`;\n }\n\n const messages = {\n ...DefaultMessages,\n ...customMessages,\n };\n\n return {\n setPackageName({ packageName }: ErrorThrowerOptions): ErrorThrower {\n if (typeof packageName === 'string') {\n pkg = packageName;\n }\n return this;\n },\n\n setMessages({ customMessages }: ErrorThrowerOptions): ErrorThrower {\n Object.assign(messages, customMessages || {});\n return this;\n },\n\n throwInvalidPublishableKeyError(params: { key?: string }): never {\n throw new Error(buildMessage(messages.InvalidPublishableKeyErrorMessage, params));\n },\n\n throwInvalidProxyUrl(params: { url?: string }): never {\n throw new Error(buildMessage(messages.InvalidProxyUrlErrorMessage, params));\n },\n\n throwMissingPublishableKeyError(): never {\n throw new Error(buildMessage(messages.MissingPublishableKeyErrorMessage));\n },\n\n throwMissingSecretKeyError(): never {\n throw new Error(buildMessage(messages.MissingSecretKeyErrorMessage));\n },\n\n throwMissingClerkProviderError(params: { source?: string }): never {\n throw new Error(buildMessage(messages.MissingClerkProvider, params));\n },\n\n throw(message: string): never {\n throw new Error(buildMessage(message));\n },\n };\n}\n","export class EmailLinkError extends Error {\n code: string;\n\n constructor(code: string) {\n super(code);\n this.code = code;\n this.name = 'EmailLinkError' as const;\n Object.setPrototypeOf(this, EmailLinkError.prototype);\n }\n}\n\n/**\n * @deprecated Use `EmailLinkErrorCodeStatus` instead.\n *\n * @internal\n */\nexport const EmailLinkErrorCode = {\n Expired: 'expired',\n Failed: 'failed',\n ClientMismatch: 'client_mismatch',\n};\n\nexport const EmailLinkErrorCodeStatus = {\n Expired: 'expired',\n Failed: 'failed',\n ClientMismatch: 'client_mismatch',\n} as const;\n","import type { ClerkErrorParams } from './clerkError';\nimport { ClerkRuntimeError } from './clerkRuntimeError';\n\ntype ClerkWebAuthnErrorCode =\n // Generic\n | 'passkey_not_supported'\n | 'passkey_pa_not_supported'\n | 'passkey_invalid_rpID_or_domain'\n | 'passkey_already_exists'\n | 'passkey_operation_aborted'\n // Retrieval\n | 'passkey_retrieval_cancelled'\n | 'passkey_retrieval_failed'\n // Registration\n | 'passkey_registration_cancelled'\n | 'passkey_registration_failed';\n\ntype ClerkWebAuthnErrorOptions = Omit<ClerkErrorParams, 'message' | 'code'> & { code: ClerkWebAuthnErrorCode };\n\nexport class ClerkWebAuthnError extends ClerkRuntimeError {\n /**\n * A unique code identifying the error, can be used for localization.\n */\n code: ClerkWebAuthnErrorCode;\n\n constructor(message: string, options: ClerkWebAuthnErrorOptions) {\n super(message, options);\n this.code = options.code;\n }\n}\n","import type { ClerkAPIResponseError } from './clerkApiResponseError';\nimport { isClerkAPIResponseError } from './clerkApiResponseError';\nimport type { ClerkRuntimeError } from './clerkRuntimeError';\nimport { isClerkRuntimeError } from './clerkRuntimeError';\nimport type { EmailLinkError } from './emailLinkError';\nimport type { MetamaskError } from './metamaskError';\n\n/**\n * Checks if the provided error object is an unauthorized error.\n *\n * @internal\n *\n * @deprecated This is no longer used, and will be removed in the next major version.\n */\nexport function isUnauthorizedError(e: any): boolean {\n const status = e?.status;\n const code = e?.errors?.[0]?.code;\n return code === 'authentication_invalid' && status === 401;\n}\n\n/**\n * Checks if the provided error object is a captcha error.\n *\n * @internal\n */\nexport function isCaptchaError(e: ClerkAPIResponseError): boolean {\n return ['captcha_invalid', 'captcha_not_enabled', 'captcha_missing_token'].includes(e.errors[0].code);\n}\n\n/**\n * Checks if the provided error is a 4xx error.\n *\n * @internal\n */\nexport function is4xxError(e: any): boolean {\n const status = e?.status;\n return !!status && status >= 400 && status < 500;\n}\n\n/**\n * Checks if the provided error is a 429 (Too Many Requests) error.\n *\n * @internal\n */\nexport function is429Error(e: any): boolean {\n return e?.status === 429;\n}\n\nconst unauthenticated403ErrorCodes = new Set(['user_banned', 'user_deactivated']);\n\n/**\n * Checks if the provided error indicates the user's session is no longer valid\n * and should trigger the unauthenticated flow (e.g. sign-out / redirect to sign-in).\n *\n * Only matches explicit authentication failure status codes:\n * - 401: session is invalid or expired\n * - 422: invalid session state (e.g. missing_expired_token)\n * - 403: terminal user state (e.g. user_banned, user_deactivated)\n *\n * 404 is intentionally excluded despite being returned for \"session not found\",\n * because it's also returned for unrelated resources (org not found, JWT template\n * not found) and shares the same `resource_not_found` error code, making it\n * impossible to distinguish. Session-not-found 401s are already handled directly\n * by Base._fetch.\n *\n * @internal\n */\nexport function isUnauthenticatedError(e: any): boolean {\n const status = e?.status;\n const hasTerminalUserErrorCode =\n Array.isArray(e?.errors) && e.errors.some((error: any) => unauthenticated403ErrorCodes.has(error?.code));\n\n return status === 401 || status === 422 || (status === 403 && hasTerminalUserErrorCode);\n}\n\n/**\n * Checks if the provided error is a network error.\n *\n * @internal\n */\nexport function isNetworkError(e: any): boolean {\n // TODO: revise during error handling epic\n const message = (`${e.message}${e.name}` || '').toLowerCase().replace(/\\s+/g, '');\n return message.includes('networkerror');\n}\n\n/**\n * Checks if the provided error is either a ClerkAPIResponseError, a ClerkRuntimeError, or a MetamaskError.\n */\nexport function isKnownError(error: any): error is ClerkAPIResponseError | ClerkRuntimeError | MetamaskError {\n return isClerkAPIResponseError(error) || isMetamaskError(error) || isClerkRuntimeError(error);\n}\n\n/**\n * Checks if the provided error is a Clerk runtime error indicating a reverification was cancelled.\n */\nexport function isReverificationCancelledError(err: any) {\n return isClerkRuntimeError(err) && err.code === 'reverification_cancelled';\n}\n\n/**\n * Checks if the provided error is a Metamask error.\n */\nexport function isMetamaskError(err: any): err is MetamaskError {\n return 'code' in err && [4001, 32602, 32603].includes(err.code) && 'message' in err;\n}\n\n/**\n * Checks if the provided error is clerk api response error indicating a user is locked.\n */\nexport function isUserLockedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'user_locked';\n}\n\n/**\n * Checks if the provided error is a clerk api response error indicating a password was pwned.\n *\n * @internal\n */\nexport function isPasswordPwnedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'form_password_pwned';\n}\n\n/**\n * Checks if the provided error is a clerk api response error indicating a password was compromised.\n *\n * @internal\n */\nexport function isPasswordCompromisedError(err: any) {\n return isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'form_password_compromised';\n}\n\n/**\n * Checks if the provided error is an EmailLinkError.\n */\nexport function isEmailLinkError(err: Error): err is EmailLinkError {\n return err.name === 'EmailLinkError';\n}\n","import { isClerkAPIResponseError } from './clerkApiResponseError';\nimport type { ClerkError } from './clerkError';\nimport { isClerkRuntimeError } from './clerkRuntimeError';\n\n/**\n * Creates a ClerkGlobalHookError object from a ClerkError instance.\n * It's a wrapper for all the different instances of Clerk errors that can\n * be returned when using Clerk hooks.\n */\nexport function createClerkGlobalHookError(error: ClerkError) {\n const predicates = {\n isClerkAPIResponseError,\n isClerkRuntimeError,\n } as const;\n\n for (const [name, fn] of Object.entries(predicates)) {\n Object.assign(error, { [name]: fn });\n }\n\n return error as ClerkError & typeof predicates;\n}\n\nexport type ClerkGlobalHookError = ReturnType<typeof createClerkGlobalHookError>;\n"],"mappings":"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"}
|