Skip to content

feat(js,ui): mount and render the directory sync setup flow - #9592

Open
kalafut wants to merge 8 commits into
jim/dir-sync-2-hooksfrom
jim/dir-sync-3-ui
Open

feat(js,ui): mount and render the directory sync setup flow#9592
kalafut wants to merge 8 commits into
jim/dir-sync-2-hooksfrom
jim/dir-sync-3-ui

Conversation

@kalafut

@kalafut kalafut commented Aug 27, 2026

Copy link
Copy Markdown

Description

Part 3 of 4 of the self-serve Directory Sync stack. Stacked on jim/dir-sync-2-hooks; the changeset rides the first PR and the stack will be squashed on merge.

  • @clerk/clerk-js: __internal_mountConfigureDirectorySync with guards mirroring ConfigureSSO's (orgs enabled, active org, self-serve directory sync feature).
  • @clerk/ui: ConfigureDirectorySync wizard over the organization's enterprise connection and directory (show-once token held in wizard session state, read-only attribute mapping from the directory, test step polls provisioned users), plus a Directory Sync section on the Security page. Google-provider connections are directed to the Dashboard.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

🤖 Generated with Claude Code

https://claude.ai/code/session_01U54pszNFtqsBNpQhXaGvaa

@vercel

vercel Bot commented Aug 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
clerk-js-sandbox Ready Ready Preview Sep 3, 2026 5:23pm UTC
swingset Ready Ready Preview Sep 3, 2026 5:23pm UTC

Request Review

@kalafut kalafut changed the title feat(self-serve-ds): mount and render ConfigureDirectorySync feat(js,ui): mount and render the directory sync setup flow Aug 27, 2026
@changeset-bot

changeset-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: cc51deb

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes changesets to release 23 packages
Name Type
@clerk/clerk-js Minor
@clerk/localizations Minor
@clerk/react Minor
@clerk/shared Minor
@clerk/ui Minor
@clerk/chrome-extension Patch
@clerk/electron Patch
@clerk/expo Patch
@clerk/nextjs Patch
@clerk/react-router Patch
@clerk/tanstack-react-start Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/headless Patch
@clerk/hono Patch
@clerk/msw Patch
@clerk/nuxt Patch
@clerk/testing Patch
@clerk/vue Patch
@clerk/swingset Patch

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Aug 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9592

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9592

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9592

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9592

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9592

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9592

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9592

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9592

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9592

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9592

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9592

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9592

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9592

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9592

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9592

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9592

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9592

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9592

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9592

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9592

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9592

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9592

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9592

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9592

commit: cc51deb

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-09-03T17:27:32.896Z

Summary

Metric Count
Packages analyzed 19
Packages with changes 2
🔴 Breaking changes 0
🟡 Non-breaking changes 4
🟢 Additions 7

🤖 This report was reviewed by claude-sonnet-4-6.


@clerk/clerk-js

Current version: 6.31.0
Recommended bump: MINOR → 6.32.0

Subpath .

🟢 Additions (2)

Added: Clerk.__internal_mountConfigureDirectorySync
+ __internal_mountConfigureDirectorySync: (node: HTMLDivElement, props?: ConfigureSSOProps) => void;

Added property Clerk.__internal_mountConfigureDirectorySync

Added: Clerk.__internal_unmountConfigureDirectorySync
+ __internal_unmountConfigureDirectorySync: (node: HTMLDivElement) => void;

Added property Clerk.__internal_unmountConfigureDirectorySync

Subpath ./no-rhc

🟢 Additions (2)

Added: Clerk.__internal_mountConfigureDirectorySync
+ __internal_mountConfigureDirectorySync: (node: HTMLDivElement, props?: ConfigureSSOProps) => void;

Added property Clerk.__internal_mountConfigureDirectorySync

Added: Clerk.__internal_unmountConfigureDirectorySync
+ __internal_unmountConfigureDirectorySync: (node: HTMLDivElement) => void;

Added property Clerk.__internal_unmountConfigureDirectorySync


@clerk/shared

Current version: 4.31.0
Recommended bump: MINOR → 4.32.0

Subpath ./internal/clerk-js/componentGuards

🟢 Additions (1)

Added: disabledSelfServeDirectorySyncFeature
+ disabledSelfServeDirectorySyncFeature: ComponentGuard

Added variable disabledSelfServeDirectorySyncFeature

Subpath ./internal/clerk-js/warnings

🟡 Non-breaking Changes (1)

Modified: warnings
// ... 7 unchanged lines elided ...
    cannotRenderSignInComponentWhenSessionExists: string;
    cannotRenderSignInComponentWhenTaskExists: string;
    cannotRenderComponentWhenUserDoesNotExist: string;
-   createCannotRenderComponentWhenOrgDoesNotExist: (componentName: "OrganizationProfile" | "InviteMembers" | "ConfigureSSO") => string;
+   createCannotRenderComponentWhenOrgDoesNotExist: (componentName: "OrganizationProfile" | "InviteMembers" | "ConfigureSSO" | "ConfigureDirectorySync") => string;
    createCannotRenderComponentWhenPermissionIsMissing: (componentName: "InviteMembers", permission: string) => string;
-   cannotRenderAnyOrganizationComponent: (componentName: "OrganizationProfile" | "InviteMembers" | "OrganizationSwitcher" | "OrganizationList" | "CreateOrganization" | "TaskChooseOrganization" | "ConfigureSSO") => string;
+   cannotRenderAnyOrganizationComponent: (componentName: "OrganizationProfile" | "InviteMembers" | "OrganizationSwitcher" | "OrganizationList" | "CreateOrganization" | "TaskChooseOrganization" | "ConfigureSSO" | "ConfigureDirectorySync") => string;
    cannotRenderAnyBillingComponent: (componentName: "PricingTable" | "Checkout" | "PlanDetails") => string;
    cannotOpenUserProfile: string;
    cannotOpenCheckout: string;
    cannotOpenSignInOrSignUp: string;
    cannotRenderAPIKeysComponent: string;
    cannotRenderAPIKeysComponentForOrgWhenUnauthorized: string;
    cannotRenderAPIKeysComponentForUserWhenDisabled: string;
    cannotRenderAPIKeysComponentForOrgWhenDisabled: string;
    cannotRenderOAuthConsentComponentWhenUserDoesNotExist: string;
    cannotRenderOAuthDeviceVerificationComponentWhenUserDoesNotExist: string;
    cannotRenderConfigureSSOComponentWhenUserDoesNotExist: string;
    cannotRenderConfigureSSOComponentWhenDisabled: string;
+   cannotRenderConfigureDirectorySyncComponentWhenDisabled: string;
    cannotRenderConfigureSSOComponentWhenEmailAddressDisabled: string;
  }

Static analyzer: Breaking change in variable warnings: Type changed: {proxyUrlAsFunctionNotSupported:string;domainAsFunctionNotSupported:string;cannotRenderComponentWhenSessionExists:strin…{proxyUrlAsFunctionNotSupported:string;domainAsFunctionNotSupported:string;cannotRenderComponentWhenSessionExists:strin…

🤖 AI review (reclassified as non-breaking) (90%): The only differences are: (1) adding "ConfigureDirectorySync" to the union parameter types of createCannotRenderComponentWhenOrgDoesNotExist and cannotRenderAnyOrganizationComponent (widening a function input union is non-breaking for callers — existing string literals still satisfy the wider union), and (2) adding a new string property cannotRenderConfigureDirectorySyncComponentWhenDisabled to the object (adding a new property to an output/read-only value object is non-breaking for consumers who only read known properties). No existing properties were removed or narrowed.

Subpath ./types

🟡 Non-breaking Changes (3)

Modified: __internal_AttemptToEnableEnvironmentSettingParams
  type __internal_AttemptToEnableEnvironmentSettingParams = {
    for: 'organizations';
-   caller: 'OrganizationSwitcher' | 'OrganizationProfile' | 'InviteMembers' | 'OrganizationList' | 'CreateOrganization' | 'TaskChooseOrganization' | 'ConfigureSSO' | 'useOrganizationList' | 'useOrganization';
+   caller: 'OrganizationSwitcher' | 'OrganizationProfile' | 'InviteMembers' | 'OrganizationList' | 'CreateOrganization' | 'TaskChooseOrganization' | 'ConfigureSSO' | 'ConfigureDirectorySync' | 'useOrganizationList' | 'useOrganization';
    onClose?: () => void;
  };

Static analyzer: Breaking change in type alias __internal_AttemptToEnableEnvironmentSettingParams: Type changed: {for:'organizations';caller:'ConfigureSSO'|'CreateOrganization'|'InviteMembers'|'OrganizationList'|'OrganizationProfile…{for:'organizations';caller:'ConfigureDirectorySync'|'ConfigureSSO'|'CreateOrganization'|'InviteMembers'|'OrganizationL…

🤖 AI review (reclassified as non-breaking) (90%): The caller union in __internal_AttemptToEnableEnvironmentSettingParams was widened by adding 'ConfigureDirectorySync'; this type is used as a function parameter (input position), so widening an input union is non-breaking for callers who pass one of the existing values.

Modified: __internal_LocalizationResource
// ... 1108 unchanged lines elided ...
          tooltip__noRole: LocalizationValue;
          tooltipLabel: LocalizationValue;
        };
+       directorySyncSection: {
+         title: LocalizationValue;
+         badge__unconfigured: LocalizationValue;
+         badge__ssoRequired: LocalizationValue;
+         badge__active: LocalizationValue;
+         badge__inactive: LocalizationValue;
+         description: LocalizationValue;
+         primaryButton__startConfiguration: LocalizationValue;
+         menuAction__edit: LocalizationValue;
+         menuAction__activate: LocalizationValue;
+         menuAction__deactivate: LocalizationValue;
+         menuAction__remove: LocalizationValue;
+         removeDialog: {
+           title: LocalizationValue;
+           subtitle: LocalizationValue;
+           confirmButton: LocalizationValue;
+         };
+       };
      };
      membersPage: {
        detailsTitle__emptyRow: LocalizationValue;
// ... 1004 unchanged lines elided ...

Static analyzer: Breaking change in type alias __internal_LocalizationResource: Type changed: {locale:string;maintenanceMode:import("@clerk/shared").LocalizationValue;roles:{[r:string]:import("@clerk/shared").Loca…{locale:string;maintenanceMode:import("@clerk/shared").LocalizationValue;roles:{[r:string]:import("@clerk/shared").Loca…

🤖 AI review (reclassified as non-breaking) (80%): __internal_LocalizationResource is used as the base of LocalizationResource via DeepPartial<DeepLocalizationWithoutObjects<...>>, making all fields optional in the output/consumer-facing type; adding new keys to the resource is non-breaking because no consumer is required to supply or conform to the new fields.

Modified: ProfileSectionId
- type ProfileSectionId = 'profile' | 'username' | 'emailAddresses' | 'phoneNumbers' | 'connectedAccounts' | 'enterpriseAccounts' | 'web3Wallets' | 'password' | 'passkeys' | 'mfa' | 'danger' | 'activeDevices' | 'organizationProfile' | 'organizationDanger' | 'organizationDomains' | 'manageVerifiedDomains' | 'subscriptionsList' | 'paymentMethods' | 'sso' | 'ssoStatus' | 'enableSso' | 'ssoDomain' | 'ssoConfiguration' | 'configureAgain' | 'resetSso' | 'testSsoUrl' | 'testResults' | 'accountCredits';
+ type ProfileSectionId = 'profile' | 'username' | 'emailAddresses' | 'phoneNumbers' | 'connectedAccounts' | 'enterpriseAccounts' | 'web3Wallets' | 'password' | 'passkeys' | 'mfa' | 'danger' | 'activeDevices' | 'organizationProfile' | 'organizationDanger' | 'organizationDomains' | 'manageVerifiedDomains' | 'subscriptionsList' | 'paymentMethods' | 'sso' | 'directorySync' | 'ssoStatus' | 'enableSso' | 'ssoDomain' | 'ssoConfiguration' | 'configureAgain' | 'resetSso' | 'testSsoUrl' | 'testResults' | 'accountCredits';

Static analyzer: Breaking change in type alias ProfileSectionId: Type changed: 'accountCredits'|'activeDevices'|'configureAgain'|'connectedAccounts'|'danger'|'emailAddresses'|'enableSso'|'enterprise…'accountCredits'|'activeDevices'|'configureAgain'|'connectedAccounts'|'danger'|'directorySync'|'emailAddresses'|'enable…

🤖 AI review (reclassified as non-breaking) (85%): ProfileSectionId is used as part of MenuId (a union), and adding 'directorySync' only widens the union; consumers who read or match against MenuId/ProfileSectionId values are unaffected by the addition of a new variant they did not previously handle as an exhaustive switch.

🟢 Additions (2)

Added: Clerk.__internal_mountConfigureDirectorySync
+ __internal_mountConfigureDirectorySync: (targetNode: HTMLDivElement, props?: ConfigureSSOProps) => void;

Added property Clerk.__internal_mountConfigureDirectorySync

Added: Clerk.__internal_unmountConfigureDirectorySync
+ __internal_unmountConfigureDirectorySync: (targetNode: HTMLDivElement) => void;

Added property Clerk.__internal_unmountConfigureDirectorySync


Report generated by Break Check

Last ran on cc51deb.

kalafut and others added 7 commits September 3, 2026 08:35
- @clerk/clerk-js: __internal_mountConfigureDirectorySync with guards
  mirroring ConfigureSSO's (orgs enabled, active org, self-serve
  directory sync feature).
- @clerk/ui: ConfigureDirectorySync wizard over the organization's
  enterprise connection and directory (show-once token held in wizard
  session state, read-only attribute mapping from the directory, test step
  polls provisioned users), plus a Directory Sync section on the Security
  page. Google-provider connections are directed to the Dashboard.
1. Mock directory.update()/delete() on the resource instead of the removed organization.updateDirectorySync/deleteDirectorySync; also mock getDomains so a retry loop can't wedge the page's loading gate.
2. Security section + wizard:show spinner while loading and an error alert on failure instead of falsely rendering "unconfigured"; wizard shows the skeleton while loading.
3. Standalone mount:wrapped in the shared ConfigureSSOProtect permission gate.
4. Clerk API surface:added __internal_(un)mountConfigureDirectorySync to the shared Clerk interface and IsomorphicClerk, so framework SDKs can reach the mount; added @clerk/react to the changeset.
5. Activate step:"Done"/"Skip for now" render only when the host supplies onExit (they were no-ops standalone).
6. Navbar:DirectorySyncNavbar is now a thin wrapper over ConfigureSSONavbar (with a new title prop), restoring mobile behavior.
7. TestSyncStep:|| instead of ?? so an empty display name falls through.
8. Bundle limits: bumped via bundlewatch:fix (554KB / 81KB).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant