From eba661bf544af01b5711589a57505fab0d1f710a Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Mon, 1 Dec 2025 10:21:35 -0800 Subject: [PATCH 1/2] fix(shared): Prevent React-specific code from leaking --- packages/shared/src/organization.ts | 27 ------------------- packages/shared/src/react/hooks/index.ts | 1 + .../hooks/useAttemptToEnableOrganizations.ts | 27 +++++++++++++++++++ .../src/react/hooks/useOrganization.tsx | 3 ++- .../src/react/hooks/useOrganizationList.tsx | 2 +- 5 files changed, 31 insertions(+), 29 deletions(-) create mode 100644 packages/shared/src/react/hooks/useAttemptToEnableOrganizations.ts diff --git a/packages/shared/src/organization.ts b/packages/shared/src/organization.ts index 36b1905acff..a30de2d1d15 100644 --- a/packages/shared/src/organization.ts +++ b/packages/shared/src/organization.ts @@ -1,6 +1,3 @@ -import { useEffect, useRef } from 'react'; - -import { useClerk } from './react'; import type { OrganizationMembershipResource } from './types'; /** @@ -18,27 +15,3 @@ export function getCurrentOrganizationMembership( organizationMembership => organizationMembership.organization.id === organizationId, ); } - -/** - * Attempts to enable the organizations environment setting for a given caller - * - * @internal - */ -export function useAttemptToEnableOrganizations(caller: 'useOrganization' | 'useOrganizationList') { - const clerk = useClerk(); - const hasAttempted = useRef(false); - - useEffect(() => { - // Guard to not run this effect twice on Clerk resource update - if (hasAttempted.current) { - return; - } - - hasAttempted.current = true; - // Optional chaining is important for `@clerk/clerk-react` usage with older clerk-js versions that don't have the method - clerk.__internal_attemptToEnableEnvironmentSetting?.({ - for: 'organizations', - caller, - }); - }, [clerk, caller]); -} diff --git a/packages/shared/src/react/hooks/index.ts b/packages/shared/src/react/hooks/index.ts index 8260af844ec..01739678aee 100644 --- a/packages/shared/src/react/hooks/index.ts +++ b/packages/shared/src/react/hooks/index.ts @@ -2,6 +2,7 @@ export { assertContextExists, createContextAndHook } from './createContextAndHoo export { useAPIKeys as __experimental_useAPIKeys } from './useAPIKeys'; export { useOrganization } from './useOrganization'; export { useOrganizationList } from './useOrganizationList'; +export { useAttemptToEnableOrganizations } from './useAttemptToEnableOrganizations'; export { useSafeLayoutEffect } from './useSafeLayoutEffect'; export { useSession } from './useSession'; export { useSessionList } from './useSessionList'; diff --git a/packages/shared/src/react/hooks/useAttemptToEnableOrganizations.ts b/packages/shared/src/react/hooks/useAttemptToEnableOrganizations.ts new file mode 100644 index 00000000000..68a178b90dd --- /dev/null +++ b/packages/shared/src/react/hooks/useAttemptToEnableOrganizations.ts @@ -0,0 +1,27 @@ +import { useEffect, useRef } from 'react'; + +import { useClerk } from './useClerk'; + +/** + * Attempts to enable the organizations environment setting for a given caller + * + * @internal + */ +export function useAttemptToEnableOrganizations(caller: 'useOrganization' | 'useOrganizationList') { + const clerk = useClerk(); + const hasAttempted = useRef(false); + + useEffect(() => { + // Guard to not run this effect twice on Clerk resource update + if (hasAttempted.current) { + return; + } + + hasAttempted.current = true; + // Optional chaining is important for `@clerk/clerk-react` usage with older clerk-js versions that don't have the method + clerk.__internal_attemptToEnableEnvironmentSetting?.({ + for: 'organizations', + caller, + }); + }, [clerk, caller]); +} diff --git a/packages/shared/src/react/hooks/useOrganization.tsx b/packages/shared/src/react/hooks/useOrganization.tsx index 28ee4b9bee8..595546fd79b 100644 --- a/packages/shared/src/react/hooks/useOrganization.tsx +++ b/packages/shared/src/react/hooks/useOrganization.tsx @@ -1,4 +1,4 @@ -import { getCurrentOrganizationMembership, useAttemptToEnableOrganizations } from '../../organization'; +import { getCurrentOrganizationMembership } from '../../organization'; import { eventMethodCalled } from '../../telemetry/events/method-called'; import type { GetDomainsParams, @@ -20,6 +20,7 @@ import { import { STABLE_KEYS } from '../stable-keys'; import type { PaginatedHookConfig, PaginatedResources, PaginatedResourcesWithDefault } from '../types'; import { createCacheKeys } from './createCacheKeys'; +import { useAttemptToEnableOrganizations } from './useAttemptToEnableOrganizations'; import { usePagesOrInfinite, useWithSafeValues } from './usePagesOrInfinite'; /** diff --git a/packages/shared/src/react/hooks/useOrganizationList.tsx b/packages/shared/src/react/hooks/useOrganizationList.tsx index a75f124307d..9fcfe1f6210 100644 --- a/packages/shared/src/react/hooks/useOrganizationList.tsx +++ b/packages/shared/src/react/hooks/useOrganizationList.tsx @@ -1,4 +1,3 @@ -import { useAttemptToEnableOrganizations } from '../../organization'; import { eventMethodCalled } from '../../telemetry/events/method-called'; import type { CreateOrganizationParams, @@ -15,6 +14,7 @@ import { useAssertWrappedByClerkProvider, useClerkInstanceContext, useUserContex import { STABLE_KEYS } from '../stable-keys'; import type { PaginatedHookConfig, PaginatedResources, PaginatedResourcesWithDefault } from '../types'; import { createCacheKeys } from './createCacheKeys'; +import { useAttemptToEnableOrganizations } from './useAttemptToEnableOrganizations'; import { usePagesOrInfinite, useWithSafeValues } from './usePagesOrInfinite'; /** From 2c0785cbae833d5ffb46c0f736c64e0f6f33a53e Mon Sep 17 00:00:00 2001 From: Robert Soriano Date: Mon, 1 Dec 2025 10:27:34 -0800 Subject: [PATCH 2/2] chore: add changeset --- .changeset/proud-ads-repeat.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/proud-ads-repeat.md diff --git a/.changeset/proud-ads-repeat.md b/.changeset/proud-ads-repeat.md new file mode 100644 index 00000000000..266fb29991a --- /dev/null +++ b/.changeset/proud-ads-repeat.md @@ -0,0 +1,5 @@ +--- +"@clerk/shared": patch +--- + +Moved helper to enable Organizations feature to React-specific shared path