From a0b25671cdee39cd0c2fca832b8c378fd445ec39 Mon Sep 17 00:00:00 2001 From: Lennart Date: Fri, 29 Sep 2023 16:25:41 +0200 Subject: [PATCH] fix(clerk-react): Add `versionSelector` helper (#1780) * feat(clerk-react): Add versionSelector helper * Create neat-needles-poke.md * fix(clerk-react): Only care about snapshot --- .changeset/neat-needles-poke.md | 5 +++ packages/react/src/globals.d.ts | 1 + .../utils/__tests__/versionSelector.test.ts | 32 +++++++++++++++++++ packages/react/src/utils/loadClerkJsScript.ts | 7 ++-- packages/react/src/utils/versionSelector.ts | 29 +++++++++++++++++ packages/react/tsup.config.ts | 2 ++ 6 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 .changeset/neat-needles-poke.md create mode 100644 packages/react/src/utils/__tests__/versionSelector.test.ts create mode 100644 packages/react/src/utils/versionSelector.ts diff --git a/.changeset/neat-needles-poke.md b/.changeset/neat-needles-poke.md new file mode 100644 index 0000000000..edff83d0f9 --- /dev/null +++ b/.changeset/neat-needles-poke.md @@ -0,0 +1,5 @@ +--- +"@clerk/clerk-react": patch +--- + +Refactor our script loading logic to use a `versionSelector` helper function. No change in behavior should occur. This internal change allows versions tagged with `snapshot` and `staging` to use the exact corresponding NPM version of `@clerk/clerk-js`. diff --git a/packages/react/src/globals.d.ts b/packages/react/src/globals.d.ts index 72b67abb15..35c1762298 100644 --- a/packages/react/src/globals.d.ts +++ b/packages/react/src/globals.d.ts @@ -3,5 +3,6 @@ export {}; declare global { const PACKAGE_NAME: string; const PACKAGE_VERSION: string; + const JS_PACKAGE_VERSION: string; const __DEV__: boolean; } diff --git a/packages/react/src/utils/__tests__/versionSelector.test.ts b/packages/react/src/utils/__tests__/versionSelector.test.ts new file mode 100644 index 0000000000..4ad8d33f86 --- /dev/null +++ b/packages/react/src/utils/__tests__/versionSelector.test.ts @@ -0,0 +1,32 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +import { versionSelector } from '../versionSelector'; + +describe('versionSelector', () => { + it('should return the clerkJSVersion if it is provided', () => { + expect(versionSelector('1.0.0')).toEqual('1.0.0'); + }); + it('should use the major version if there is no prerelease tag', () => { + // @ts-ignore + global.PACKAGE_VERSION = '1.0.0'; + // @ts-ignore + global.JS_PACKAGE_VERSION = '2.0.0'; + + expect(versionSelector(undefined)).toEqual('1'); + }); + it('should use the prerelease tag when it is not snapshot', () => { + // @ts-ignore + global.PACKAGE_VERSION = '1.0.0-next.0'; + // @ts-ignore + global.JS_PACKAGE_VERSION = '2.0.0-next.0'; + + expect(versionSelector(undefined)).toEqual('next'); + }); + it('should use the exact JS version if tag is snapshot', () => { + // @ts-ignore + global.PACKAGE_VERSION = '1.0.0-snapshot.0'; + // @ts-ignore + global.JS_PACKAGE_VERSION = '2.0.0-snapshot.0'; + + expect(versionSelector(undefined)).toEqual('2.0.0-snapshot.0'); + }); +}); diff --git a/packages/react/src/utils/loadClerkJsScript.ts b/packages/react/src/utils/loadClerkJsScript.ts index e93ceb9043..1ce63f52eb 100644 --- a/packages/react/src/utils/loadClerkJsScript.ts +++ b/packages/react/src/utils/loadClerkJsScript.ts @@ -3,6 +3,7 @@ import { addClerkPrefix, isValidProxyUrl, loadScript, parsePublishableKey, proxy import type { IsomorphicClerkOptions } from '../types'; import { errorThrower } from './errorThrower'; import { isDevOrStagingUrl } from './isDevOrStageUrl'; +import { versionSelector } from './versionSelector'; const FAILED_TO_LOAD_ERROR = 'Clerk: Failed to load Clerk'; @@ -44,7 +45,7 @@ const clerkJsScriptUrl = (opts: LoadClerkJsScriptOptions) => { } const variant = clerkJSVariant ? `${clerkJSVariant.replace(/\.+$/, '')}.` : ''; - const version = clerkJSVersion || getPrereleaseTag(PACKAGE_VERSION) || getMajorVersion(PACKAGE_VERSION); + const version = versionSelector(clerkJSVersion); return `https://${scriptHost}/npm/@clerk/clerk-js@${version}/dist/clerk.${variant}browser.js`; }; @@ -64,7 +65,3 @@ const applyClerkJsScriptAttributes = (options: LoadClerkJsScriptOptions) => (scr script.setAttribute('data-clerk-domain', domain); } }; - -const getPrereleaseTag = (packageVersion: string) => packageVersion.match(/-(.*)\./)?.[1]; - -const getMajorVersion = (packageVersion: string) => packageVersion.split('.')[0]; diff --git a/packages/react/src/utils/versionSelector.ts b/packages/react/src/utils/versionSelector.ts new file mode 100644 index 0000000000..742e5d47a2 --- /dev/null +++ b/packages/react/src/utils/versionSelector.ts @@ -0,0 +1,29 @@ +/** + * This version selector is a bit complicated, so here is the flow: + * 1. Use the clerkJSVersion prop on the provider + * 2. Use the exact `@clerk/clerk-js` version if it is a `@snapshot` prerelease for `@clerk/clerk-react` + * 3. Use the prerelease tag of `@clerk/clerk-react` + * 4. Fallback to the major version of `@clerk/clerk-react` + * @param clerkJSVersion - The optional clerkJSVersion prop on the provider + * @returns The npm tag, version or major version to use + */ +export const versionSelector = (clerkJSVersion: string | undefined) => { + if (clerkJSVersion) { + return clerkJSVersion; + } + + const prereleaseTag = getPrereleaseTag(PACKAGE_VERSION); + if (prereleaseTag) { + if (prereleaseTag === 'snapshot') { + return JS_PACKAGE_VERSION; + } + + return prereleaseTag; + } + + return getMajorVersion(PACKAGE_VERSION); +}; + +// TODO: Replace these with "semver" package +const getPrereleaseTag = (packageVersion: string) => packageVersion.match(/-(.*)\./)?.[1]; +const getMajorVersion = (packageVersion: string) => packageVersion.split('.')[0]; diff --git a/packages/react/tsup.config.ts b/packages/react/tsup.config.ts index ecb256fd7c..93f9237b1a 100644 --- a/packages/react/tsup.config.ts +++ b/packages/react/tsup.config.ts @@ -2,6 +2,7 @@ import type { Options } from 'tsup'; import { defineConfig } from 'tsup'; import { runAfterLast } from '../../scripts/utils'; +import { version as clerkJsVersion } from '../clerk-js/package.json'; import { name, version } from './package.json'; export default defineConfig(overrideOptions => { @@ -18,6 +19,7 @@ export default defineConfig(overrideOptions => { define: { PACKAGE_NAME: `"${name}"`, PACKAGE_VERSION: `"${version}"`, + JS_PACKAGE_VERSION: `"${clerkJsVersion}"`, __DEV__: `${isWatch}`, }, };