From 77f729160d972719932db16fe6f6923437947762 Mon Sep 17 00:00:00 2001 From: Dimitris Klouvas Date: Wed, 29 Nov 2023 00:30:17 +0200 Subject: [PATCH 1/6] chore(types): Use `Without` generic to resolve issues with `Omit` and complex types --- packages/react/src/types.ts | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/packages/react/src/types.ts b/packages/react/src/types.ts index 68b31e3ca0..d88e9fe0f3 100644 --- a/packages/react/src/types.ts +++ b/packages/react/src/types.ts @@ -11,6 +11,7 @@ import type { SignInRedirectOptions, SignUpRedirectOptions, UserResource, + Without, } from '@clerk/types'; import type React from 'react'; @@ -23,7 +24,7 @@ declare global { } } -export type IsomorphicClerkOptions = Omit & { +export type IsomorphicClerkOptions = Without & { Clerk?: ClerkProp; clerkJSUrl?: string; clerkJSVariant?: 'headless' | ''; @@ -37,19 +38,10 @@ export type ClerkProviderProps = IsomorphicClerkOptions & { initialState?: InitialState; }; -// TODO(@dimkl): replacing it with the following make nextjs type tests fail -// `Exclude & { publishableKey?: string }` -// find another way to reduce the duplication. -export type ClerkProviderOptionsWrapper = Omit & { - Clerk?: ClerkProp; - clerkJSUrl?: string; - clerkJSVariant?: 'headless' | ''; - clerkJSVersion?: string; - sdkMetadata?: SDKMetadata; +export type ClerkProviderOptionsWrapper = Without & { publishableKey?: string; -} & MultiDomainAndOrProxy & { - children: React.ReactNode; - }; + children: React.ReactNode; +}; export interface BrowserClerkConstructor { new (publishableKey: string, options?: DomainOrProxyUrl): BrowserClerk; @@ -75,7 +67,7 @@ export interface MountProps { } export interface HeadlessBrowserClerk extends Clerk { - load: (opts?: Omit) => Promise; + load: (opts?: Without) => Promise; updateClient: (client: ClientResource) => void; } From 638e388f8af9aebd0f5c118c6650a0b5a577a9e4 Mon Sep 17 00:00:00 2001 From: Dimitris Klouvas Date: Wed, 29 Nov 2023 00:32:44 +0200 Subject: [PATCH 2/6] chore(types): Make `routerPush` and `routerReplace` options both required or both optional In order to use unions we converted the `ClerkOptions` interface to type to compose the union for mutual required or optional for `routerPush` and `routerReplace` options. --- .../contexts/__tests__/ClerkProvider.test.tsx | 19 ++++++++++++ packages/types/src/clerk.retheme.ts | 22 ++++++++++++-- packages/types/src/clerk.ts | 29 +++++++++++++------ 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx b/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx index bd1814ee79..5b1662c8b0 100644 --- a/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx +++ b/packages/react/src/contexts/__tests__/ClerkProvider.test.tsx @@ -224,4 +224,23 @@ describe('ClerkProvider', () => { expectTypeOf({ publishableKey: 'test' }).not.toMatchTypeOf(); }); }); + + describe('navigation options', () => { + it('expects both routerPush & routerReplace to pass', () => { + expectTypeOf({ + publishableKey: 'test', + children: '', + routerPush: () => {}, + routerReplace: () => {}, + }).toMatchTypeOf(); + }); + + it('errors if one of routerPush / routerReplace is passed', () => { + expectTypeOf({ + publishableKey: 'test', + children: '', + routerPush: () => {}, + }).not.toMatchTypeOf(); + }); + }); }); diff --git a/packages/types/src/clerk.retheme.ts b/packages/types/src/clerk.retheme.ts index ee0b376398..691c180722 100644 --- a/packages/types/src/clerk.retheme.ts +++ b/packages/types/src/clerk.retheme.ts @@ -495,7 +495,25 @@ export type CustomNavigation = (to: string, options?: NavigateOptions) => Promis export type ClerkThemeOptions = DeepSnakeToCamel>; -export interface ClerkOptions { +/** + * Navigation options used to replace or push history changes. + * Both `routerPush` & `routerReplace` OR none options should be passed. + */ +type ClerkOptionsNavigationFn = + | { + routerPush?: never; + routerReplace?: never; + } + | { + routerPush: (to: string) => Promise | unknown; + routerReplace: (to: string) => Promise | unknown; + }; + +type ClerkOptionsNavigation = ClerkOptionsNavigationFn & { + routerDebug?: boolean; +}; + +export type ClerkOptions = ClerkOptionsNavigation & { appearance?: Appearance; localization?: LocalizationResource; /** @@ -535,7 +553,7 @@ export interface ClerkOptions { }; sdkMetadata?: SDKMetadata; -} +}; export interface NavigateOptions { replace?: boolean; diff --git a/packages/types/src/clerk.ts b/packages/types/src/clerk.ts index 1bf9181372..fca95e92fd 100644 --- a/packages/types/src/clerk.ts +++ b/packages/types/src/clerk.ts @@ -495,16 +495,27 @@ export type CustomNavigation = (to: string, options?: NavigateOptions) => Promis export type ClerkThemeOptions = DeepSnakeToCamel>; -export interface ClerkOptions { - appearance?: Appearance; - localization?: LocalizationResource; - /** - * Navigation - */ - routerPush?: (to: string) => Promise | unknown; - routerReplace?: (to: string) => Promise | unknown; +/** + * Navigation options used to replace or push history changes. + * Both `routerPush` & `routerReplace` OR none options should be passed. + */ +type ClerkOptionsNavigationFn = + | { + routerPush?: never; + routerReplace?: never; + } + | { + routerPush: (to: string) => Promise | unknown; + routerReplace: (to: string) => Promise | unknown; + }; + +type ClerkOptionsNavigation = ClerkOptionsNavigationFn & { routerDebug?: boolean; +}; +export type ClerkOptions = ClerkOptionsNavigation & { + appearance?: Appearance; + localization?: LocalizationResource; polling?: boolean; selectInitialSession?: (client: ClientResource) => ActiveSessionResource | null; /** Controls if ClerkJS will load with the standard browser setup using Clerk cookies */ @@ -536,7 +547,7 @@ export interface ClerkOptions { }; sdkMetadata?: SDKMetadata; -} +}; export interface NavigateOptions { replace?: boolean; From 63f0310365dcf8071580b652edb3586f05aa4f03 Mon Sep 17 00:00:00 2001 From: Dimitris Klouvas Date: Wed, 29 Nov 2023 00:47:59 +0200 Subject: [PATCH 3/6] chore(repo): Ignore test runner files and CHANGELOG.md from formatting Fixed the 3 slowed formatted files (filename ignored -> ms saved): - packages/backend/tests/cloudflare-miniflare/worker.js -> 1582ms - packages/backend/tests/edge-runtime/bundle.js -> 1477ms - packages/clerk-js/CHANGELOG.md -> 177ms --- .prettierignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.prettierignore b/.prettierignore index 1b91423549..b52b1aa940 100644 --- a/.prettierignore +++ b/.prettierignore @@ -15,4 +15,6 @@ dist examples node_modules package-lock.json -playground \ No newline at end of file +playground +packages/backend/tests/**/*.js +/**/CHANGELOG.md \ No newline at end of file From 69b3cff9926df4b53e3a53d330890de6f6dd46ab Mon Sep 17 00:00:00 2001 From: Dimitris Klouvas Date: Wed, 29 Nov 2023 00:53:11 +0200 Subject: [PATCH 4/6] chore(repo): Add changeset --- .changeset/tiny-forks-sit.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/tiny-forks-sit.md diff --git a/.changeset/tiny-forks-sit.md b/.changeset/tiny-forks-sit.md new file mode 100644 index 0000000000..5a7c9dbcc4 --- /dev/null +++ b/.changeset/tiny-forks-sit.md @@ -0,0 +1,8 @@ +--- +'@clerk/clerk-react': minor +'@clerk/types': minor +--- + +Update `` `routerPush` and `routerReplace` options to be both required or both missing. +Also used internally the `Without` generic instead of `Omit` to resolve issues with complex types and +partially making a type property optional. From fb6e3218934b85e3ecdf649bc0d07a3549609c17 Mon Sep 17 00:00:00 2001 From: Dimitris Klouvas Date: Wed, 29 Nov 2023 15:23:13 +0200 Subject: [PATCH 5/6] chore(repo): Update ui-retheme-changes-reminder to notify for files with retheme variant --- .github/workflows/ui-retheme-changes-reminder.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ui-retheme-changes-reminder.yml b/.github/workflows/ui-retheme-changes-reminder.yml index 0414f1056d..c78d12f76e 100644 --- a/.github/workflows/ui-retheme-changes-reminder.yml +++ b/.github/workflows/ui-retheme-changes-reminder.yml @@ -6,7 +6,13 @@ on: - main paths: - 'packages/clerk-js/src/ui/**' - + # files with matching `*.retheme.ts` retheme variant + - 'packages/localizations/src/en-US.ts' + - 'packages/localizations/src/index.ts' + - 'packages/types/src/appearance.ts' + - 'packages/types/src/clerk.ts' + - 'packages/types/src/index.ts' + - 'packages/types/src/localization.ts' jobs: check-changes: runs-on: ubuntu-latest From 495c3eb8a01e21ae8a6159be56e77395599b5cc2 Mon Sep 17 00:00:00 2001 From: Dimitris Klouvas Date: Wed, 29 Nov 2023 15:32:06 +0200 Subject: [PATCH 6/6] Update .changeset/tiny-forks-sit.md Co-authored-by: Lennart --- .changeset/tiny-forks-sit.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.changeset/tiny-forks-sit.md b/.changeset/tiny-forks-sit.md index 5a7c9dbcc4..bd2899152d 100644 --- a/.changeset/tiny-forks-sit.md +++ b/.changeset/tiny-forks-sit.md @@ -3,6 +3,4 @@ '@clerk/types': minor --- -Update `` `routerPush` and `routerReplace` options to be both required or both missing. -Also used internally the `Without` generic instead of `Omit` to resolve issues with complex types and -partially making a type property optional. +Update the TypeScript types of ``. If you use the `routerPush` prop you're now required to also provide the `routerReplace` prop (or other way around). You can also not provide them at all since both props are optional.