From f74a9fda218da545347017539335e2740084306e Mon Sep 17 00:00:00 2001 From: LekoArts Date: Tue, 26 Sep 2023 10:01:04 +0200 Subject: [PATCH 1/3] feat(clerk-react): Add versionSelector helper --- packages/react/src/globals.d.ts | 1 + .../utils/__tests__/versionSelector.test.ts | 39 +++++++++++++++++++ packages/react/src/utils/loadClerkJsScript.ts | 7 +--- packages/react/src/utils/versionSelector.ts | 29 ++++++++++++++ packages/react/tsup.config.ts | 3 +- 5 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 packages/react/src/utils/__tests__/versionSelector.test.ts create mode 100644 packages/react/src/utils/versionSelector.ts diff --git a/packages/react/src/globals.d.ts b/packages/react/src/globals.d.ts index 72b67abb156..35c17622984 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 00000000000..ff10fdf22d5 --- /dev/null +++ b/packages/react/src/utils/__tests__/versionSelector.test.ts @@ -0,0 +1,39 @@ +/* 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 staging/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 staging/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'); + + // @ts-ignore + global.PACKAGE_VERSION = '1.0.0-staging.0'; + // @ts-ignore + global.JS_PACKAGE_VERSION = '2.0.0-staging.0'; + + expect(versionSelector(undefined)).toEqual('2.0.0-staging.0'); + }); +}); diff --git a/packages/react/src/utils/loadClerkJsScript.ts b/packages/react/src/utils/loadClerkJsScript.ts index e93ceb90432..1ce63f52eb4 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 00000000000..f18687a3d63 --- /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 `@staging`/`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 === 'staging' || 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 e6e77964ef5..f07a865726d 100644 --- a/packages/react/tsup.config.ts +++ b/packages/react/tsup.config.ts @@ -2,7 +2,7 @@ import type { Options } from 'tsup'; import { defineConfig } from 'tsup'; import { runAfterLast } from '../../scripts/utils'; -// @ts-ignore +import { version as clerkJsVersion } from '../clerk-js/package.json'; import { name, version } from './package.json'; export default defineConfig(overrideOptions => { @@ -19,6 +19,7 @@ export default defineConfig(overrideOptions => { define: { PACKAGE_NAME: `"${name}"`, PACKAGE_VERSION: `"${version}"`, + JS_PACKAGE_VERSION: `"${clerkJsVersion}"`, __DEV__: `${isWatch}`, }, }; From 08fefece5a5a834c0d1f06fb650aafefb0a2c88c Mon Sep 17 00:00:00 2001 From: Lennart Date: Tue, 26 Sep 2023 10:11:05 +0200 Subject: [PATCH 2/3] Create neat-needles-poke.md --- .changeset/neat-needles-poke.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/neat-needles-poke.md diff --git a/.changeset/neat-needles-poke.md b/.changeset/neat-needles-poke.md new file mode 100644 index 00000000000..edff83d0f9c --- /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`. From 56614aaa7e2007b8089d0aae30140a81be5bc2c1 Mon Sep 17 00:00:00 2001 From: LekoArts Date: Thu, 28 Sep 2023 11:10:58 +0200 Subject: [PATCH 3/3] fix(clerk-react): Only care about snapshot --- .../react/src/utils/__tests__/versionSelector.test.ts | 11 ++--------- packages/react/src/utils/versionSelector.ts | 4 ++-- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/react/src/utils/__tests__/versionSelector.test.ts b/packages/react/src/utils/__tests__/versionSelector.test.ts index ff10fdf22d5..4ad8d33f862 100644 --- a/packages/react/src/utils/__tests__/versionSelector.test.ts +++ b/packages/react/src/utils/__tests__/versionSelector.test.ts @@ -13,7 +13,7 @@ describe('versionSelector', () => { expect(versionSelector(undefined)).toEqual('1'); }); - it('should use the prerelease tag when it is not staging/snapshot', () => { + it('should use the prerelease tag when it is not snapshot', () => { // @ts-ignore global.PACKAGE_VERSION = '1.0.0-next.0'; // @ts-ignore @@ -21,19 +21,12 @@ describe('versionSelector', () => { expect(versionSelector(undefined)).toEqual('next'); }); - it('should use the exact JS version if tag is staging/snapshot', () => { + 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'); - - // @ts-ignore - global.PACKAGE_VERSION = '1.0.0-staging.0'; - // @ts-ignore - global.JS_PACKAGE_VERSION = '2.0.0-staging.0'; - - expect(versionSelector(undefined)).toEqual('2.0.0-staging.0'); }); }); diff --git a/packages/react/src/utils/versionSelector.ts b/packages/react/src/utils/versionSelector.ts index f18687a3d63..742e5d47a21 100644 --- a/packages/react/src/utils/versionSelector.ts +++ b/packages/react/src/utils/versionSelector.ts @@ -1,7 +1,7 @@ /** * 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 `@staging`/`snapshot` prerelease for `@clerk/clerk-react` + * 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 @@ -14,7 +14,7 @@ export const versionSelector = (clerkJSVersion: string | undefined) => { const prereleaseTag = getPrereleaseTag(PACKAGE_VERSION); if (prereleaseTag) { - if (prereleaseTag === 'staging' || prereleaseTag === 'snapshot') { + if (prereleaseTag === 'snapshot') { return JS_PACKAGE_VERSION; }