diff --git a/.changeset/nasty-baboons-cheer.md b/.changeset/nasty-baboons-cheer.md new file mode 100644 index 00000000000..0e25f60044c --- /dev/null +++ b/.changeset/nasty-baboons-cheer.md @@ -0,0 +1,8 @@ +--- +"@clerk/astro": patch +"@clerk/shared": patch +"@clerk/clerk-react": patch +"@clerk/nextjs": patch +--- + +Introduce functions that can be reused across front-end SDKs diff --git a/packages/astro/src/internal/create-clerk-instance.ts b/packages/astro/src/internal/create-clerk-instance.ts index 8e449ceabc3..8d56018fa07 100644 --- a/packages/astro/src/internal/create-clerk-instance.ts +++ b/packages/astro/src/internal/create-clerk-instance.ts @@ -1,17 +1,19 @@ +import { loadClerkJsScript, setClerkJsLoadingErrorPackageName } from '@clerk/shared/loadClerkJsScript'; import type { ClerkOptions } from '@clerk/types'; import { $clerk, $csrState } from '../stores/internal'; -import type { AstroClerkIntegrationParams, AstroClerkUpdateOptions } from '../types'; +import type { AstroClerkCreateInstanceParams, AstroClerkUpdateOptions } from '../types'; import { invokeClerkAstroJSFunctions } from './invoke-clerk-astro-js-functions'; import { mountAllClerkAstroJSComponents } from './mount-clerk-astro-js-components'; import { runOnce } from './run-once'; -import { waitForClerkScript } from './utils/loadClerkJSScript'; let initOptions: ClerkOptions | undefined; // TODO-SHARED: copied from `clerk-js` export const CLERK_BEFORE_UNLOAD_EVENT = 'clerk:beforeunload'; +setClerkJsLoadingErrorPackageName(PACKAGE_NAME); + function windowNavigate(to: URL | string): void { const toURL = new URL(to, window.location.href); window.dispatchEvent(new CustomEvent(CLERK_BEFORE_UNLOAD_EVENT)); @@ -35,10 +37,10 @@ function createNavigationHandler( */ const createClerkInstance = runOnce(createClerkInstanceInternal); -async function createClerkInstanceInternal(options?: AstroClerkIntegrationParams) { +async function createClerkInstanceInternal(options?: AstroClerkCreateInstanceParams) { let clerkJSInstance = window.Clerk; if (!clerkJSInstance) { - await waitForClerkScript(); + await loadClerkJsScript(options); if (!window.Clerk) { throw new Error('Failed to download latest ClerkJS. Contact support@clerk.com.'); @@ -47,7 +49,6 @@ async function createClerkInstanceInternal(options?: AstroClerkIntegrationParams } if (!$clerk.get()) { - // @ts-ignore $clerk.set(clerkJSInstance); } @@ -57,8 +58,7 @@ async function createClerkInstanceInternal(options?: AstroClerkIntegrationParams routerReplace: createNavigationHandler(window.history.replaceState.bind(window.history)), }; - // TODO: Update Clerk type from @clerk/types to include this method - return (clerkJSInstance as any) + return clerkJSInstance .load(initOptions) .then(() => { $csrState.setKey('isLoaded', true); diff --git a/packages/astro/src/internal/utils/loadClerkJSScript.ts b/packages/astro/src/internal/utils/loadClerkJSScript.ts deleted file mode 100644 index 6d250441339..00000000000 --- a/packages/astro/src/internal/utils/loadClerkJSScript.ts +++ /dev/null @@ -1,17 +0,0 @@ -const FAILED_TO_FIND_CLERK_SCRIPT = 'Clerk: Failed find clerk-js script'; - -// TODO-SHARED: Something similar exists inside clerk-react -export const waitForClerkScript = () => { - return new Promise((resolve, reject) => { - const script = document.querySelector('script[data-clerk-script]'); - - if (!script) { - return reject(FAILED_TO_FIND_CLERK_SCRIPT); - } - - script.addEventListener('load', () => { - script.remove(); - resolve(script); - }); - }); -}; diff --git a/packages/astro/src/internal/utils/versionSelector.ts b/packages/astro/src/internal/utils/versionSelector.ts deleted file mode 100644 index 12b8d4c2fdd..00000000000 --- a/packages/astro/src/internal/utils/versionSelector.ts +++ /dev/null @@ -1,9 +0,0 @@ -const HARDCODED_LATEST_CLERK_JS_VERSION = '5'; - -export const versionSelector = (clerkJSVersion: string | undefined): string => { - if (clerkJSVersion) { - return clerkJSVersion; - } - - return HARDCODED_LATEST_CLERK_JS_VERSION; -}; diff --git a/packages/astro/src/server/build-clerk-hotload-script.ts b/packages/astro/src/server/build-clerk-hotload-script.ts index 4b0ed219383..d135dd3bcb2 100644 --- a/packages/astro/src/server/build-clerk-hotload-script.ts +++ b/packages/astro/src/server/build-clerk-hotload-script.ts @@ -1,43 +1,8 @@ -import { createDevOrStagingUrlCache, parsePublishableKey } from '@clerk/shared/keys'; -import { isValidProxyUrl, proxyUrlToAbsoluteURL } from '@clerk/shared/proxy'; -import { addClerkPrefix } from '@clerk/shared/url'; +import { clerkJsScriptUrl } from '@clerk/shared/loadClerkJsScript'; import type { APIContext } from 'astro'; -import { versionSelector } from '../internal/utils/versionSelector'; import { getSafeEnv } from './get-safe-env'; -const { isDevOrStagingUrl } = createDevOrStagingUrlCache(); - -type BuildClerkJsScriptOptions = { - proxyUrl: string; - domain: string; - clerkJSUrl?: string; - clerkJSVariant?: 'headless' | ''; - clerkJSVersion?: string; - publishableKey: string; -}; - -const clerkJsScriptUrl = (opts: BuildClerkJsScriptOptions) => { - const { clerkJSUrl, clerkJSVariant, clerkJSVersion, proxyUrl, domain, publishableKey } = opts; - - if (clerkJSUrl) { - return clerkJSUrl; - } - - let scriptHost = ''; - if (!!proxyUrl && isValidProxyUrl(proxyUrl)) { - scriptHost = proxyUrlToAbsoluteURL(proxyUrl).replace(/http(s)?:\/\//, ''); - } else if (domain && !isDevOrStagingUrl(parsePublishableKey(publishableKey)?.frontendApi || '')) { - scriptHost = addClerkPrefix(domain); - } else { - scriptHost = parsePublishableKey(publishableKey)?.frontendApi || ''; - } - - const variant = clerkJSVariant ? `${clerkJSVariant.replace(/\.+$/, '')}.` : ''; - const version = versionSelector(clerkJSVersion); - return `https://${scriptHost}/npm/@clerk/clerk-js@${version}/dist/clerk.${variant}browser.js`; -}; - function buildClerkHotloadScript(locals: APIContext['locals']) { const publishableKey = getSafeEnv(locals).pk!; const proxyUrl = getSafeEnv(locals).proxyUrl!; @@ -51,10 +16,10 @@ function buildClerkHotloadScript(locals: APIContext['locals']) { publishableKey, }); return ` -