@dloizides/auth-web 1.18.3 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.20.0
4
+
5
+ `mapRegisterErrorCode` reads the typed `status` + body `errorCode` that `@dloizides/auth-client` 4.5.0
6
+ `BffRequestError` carries (duck-typed, so it needs no auth-client bump to compile). New codes:
7
+ `TenantNameTaken` (409 `TENANT_NAME_TAKEN`), `RateLimited` (429) and `AutoLoginFailed` (account created, sign-in
8
+ failed: tell the user to sign in, not to retry). `USER_EXISTS` maps to `EmailTaken`; 5xx to `Failed`. Consumers
9
+ with an exhaustive `Record<RegisterErrorCode, string>` must add the three new keys.
10
+
11
+ ## 1.19.0
12
+
13
+ **`<RegisterForm compact>` (AUTH-REG-1 "Compact register form").** Opt-in; the default seven-field form is unchanged.
14
+ Shows only "Your name", Email, Password and the tenant name. The name is split into firstName/lastName (one word
15
+ fills both, since Keycloak needs a last name), the username is derived from the whole email (lower-cased, chars
16
+ outside `[a-z0-9._-]` become `_`), and there is no confirm-password field. New optional `labels.fullName`.
17
+ `splitFullName` and `deriveUsernameFromEmail` are exported. `useRegisterForm({ compact })` for headless use.
18
+
3
19
  ## 1.18.3
4
20
 
5
21
  - `useLoginSubmit` has an in-flight ref guard, like `useRegisterForm`. A focused field stays read-only (not
package/dist/index.d.mts CHANGED
@@ -525,10 +525,19 @@ declare const enum RegisterErrorCode {
525
525
  PasswordMismatch = "passwordMismatch",
526
526
  /** The server reported `USERNAME_TAKEN`. */
527
527
  UsernameTaken = "usernameTaken",
528
- /** The server reported `EMAIL_TAKEN`. */
528
+ /** The server reported `EMAIL_TAKEN` or `USER_EXISTS` (409). */
529
529
  EmailTaken = "emailTaken",
530
530
  /** The server reported `REALM_REQUIRED` or `REALM_INVALID`. */
531
531
  RealmInvalid = "realmInvalid",
532
+ /** The server reported `TENANT_NAME_TAKEN` (409): the organisation / shop name is in use. */
533
+ TenantNameTaken = "tenantNameTaken",
534
+ /** The server rate-limited the request (HTTP 429). */
535
+ RateLimited = "rateLimited",
536
+ /**
537
+ * The account WAS created but the automatic sign-in failed (`AUTO_LOGIN_FAILED`).
538
+ * Tell the user to sign in; do not ask them to register again.
539
+ */
540
+ AutoLoginFailed = "autoLoginFailed",
532
541
  /** The server rejected the request with an unrecognised message. */
533
542
  ValidationFailed = "validationFailed",
534
543
  /** Generic failure: network error, empty message, or a filled honeypot (never revealed). */
@@ -592,6 +601,8 @@ interface RegisterFormLabels {
592
601
  /** `accessibilityLabel` for the submit button while the request runs. */
593
602
  submitting: string;
594
603
  fields: Record<RegisterInputField, RegisterFieldLabels>;
604
+ /** Copy for the single "Your name" input of the compact form. Defaults to English. */
605
+ fullName?: RegisterFieldLabels;
595
606
  }
596
607
  declare const DEFAULT_REGISTER_LABELS: RegisterFormLabels;
597
608
 
@@ -2472,9 +2483,15 @@ interface RegisterFormProps<TResult> {
2472
2483
  footer?: ReactNode;
2473
2484
  /** Prefix applied to every `testID`. */
2474
2485
  testIdPrefix?: string;
2486
+ /**
2487
+ * Opt-in compact form (AUTH-REG-1): only "Your name", Email, Password and the
2488
+ * tenant name. First/last name are split from the name (one word fills both),
2489
+ * the username is derived from the email, and there is no confirm-password field.
2490
+ */
2491
+ compact?: boolean;
2475
2492
  }
2476
2493
  /** Themeable registration form built on `useRegisterForm`. */
2477
- declare function RegisterForm<TResult>({ onSubmit, onSuccess, onError, onSubmitAttempt, passwordPolicy, labels: labelsProp, theme: themeProp, footer, testIdPrefix, }: Readonly<RegisterFormProps<TResult>>): ReactElement;
2494
+ declare function RegisterForm<TResult>({ onSubmit, onSuccess, onError, onSubmitAttempt, passwordPolicy, labels: labelsProp, theme: themeProp, footer, testIdPrefix, compact, }: Readonly<RegisterFormProps<TResult>>): ReactElement;
2478
2495
 
2479
2496
  /**
2480
2497
  * `testID` values for `<RegisterForm>`.
@@ -2511,6 +2528,11 @@ interface UseRegisterFormArgs<TResult> {
2511
2528
  * event). A press ignored because a submit is already in flight does not call it.
2512
2529
  */
2513
2530
  onSubmitAttempt?: () => void;
2531
+ /**
2532
+ * Compact mode (AUTH-REG-1): `firstName` holds the full name; last name, username
2533
+ * (from the email) and the password confirmation are derived before validation.
2534
+ */
2535
+ compact?: boolean;
2514
2536
  }
2515
2537
  interface UseRegisterFormResult<TResult> {
2516
2538
  state: RegisterFormValues;
@@ -2521,7 +2543,7 @@ interface UseRegisterFormResult<TResult> {
2521
2543
  error: RegisterErrorCode | null;
2522
2544
  }
2523
2545
  /** Headless registration form logic. */
2524
- declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAttempt, }: UseRegisterFormArgs<TResult>): UseRegisterFormResult<TResult>;
2546
+ declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAttempt, compact, }: UseRegisterFormArgs<TResult>): UseRegisterFormResult<TResult>;
2525
2547
 
2526
2548
  /**
2527
2549
  * Pure registration helpers: trimming, client-side validation and decoding of a
@@ -2535,6 +2557,30 @@ declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAt
2535
2557
  /** The default password rule: 8+ characters with a letter, a digit and a special character. */
2536
2558
  declare function isRegisterPasswordStrong(password: string): boolean;
2537
2559
 
2560
+ /**
2561
+ * Compact registration (AUTH-REG-1 "Compact register form"): the form shows only
2562
+ * "Your name", Email, Password (+ tenant name). Keycloak still needs a username,
2563
+ * a first name AND a last name, so they are derived here before validation.
2564
+ *
2565
+ * In compact mode the single "Your name" input is stored in `firstName`.
2566
+ */
2567
+
2568
+ interface SplitName {
2569
+ firstName: string;
2570
+ lastName: string;
2571
+ }
2572
+ /**
2573
+ * Split a full name on whitespace: the first word is the first name, the rest the
2574
+ * last name. A single word is used for both (Keycloak requires a last name).
2575
+ */
2576
+ declare function splitFullName(fullName: string): SplitName;
2577
+ /**
2578
+ * A username derived from the whole email (so two people with the same local part
2579
+ * on different domains never collide): lower-cased, every char outside
2580
+ * `[a-z0-9._-]` replaced by `_`. `Ada+shop@Example.com` becomes `ada_shop_example.com`.
2581
+ */
2582
+ declare function deriveUsernameFromEmail(email: string): string;
2583
+
2538
2584
  /**
2539
2585
  * `createBffAuthClient` — the one-line wiring of a same-origin `BffAuthClient`.
2540
2586
  *
@@ -2824,4 +2870,4 @@ interface UseChangePasswordResult {
2824
2870
  }
2825
2871
  declare function useChangePassword({ client, onChanged, }: UseChangePasswordArgs): UseChangePasswordResult;
2826
2872
 
2827
- export { type AccountSettingsChangePasswordConfig, type AccountSettingsDevicePinConfig, type AccountSettingsLabels, type AccountSettingsPasskeysConfig, type AccountSettingsPreferredMethodConfig, AccountSettingsScreen, type AccountSettingsScreenProps, AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type BffLogoutClient, CHANGE_PASSWORD_ENDPOINT, type ChangePasswordCapableClient, ChangePasswordCard, type ChangePasswordCardProps, ChangePasswordErrorKey, type ChangePasswordRequest, type ChangePasswordResult, type CreateBffAuthClientOptions, type CreateBffChangePasswordClientOptions, DEFAULT_ACCOUNT_SETTINGS_LABELS, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_REGISTER_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, type DemoCredentialsHintLabels, type DemoCredentialsHintProps, DemoCredentialsHintVariant, type DemoCredentialsHintWiring, type DemoCredentialsLoginFormProps, type DevicePinCapableClient, type DevicePinDisableCapableClient, type DevicePinEnrollCapableClient, DevicePinEnrollErrorKey, DevicePinEnrollForm, type DevicePinEnrollFormProps, type DevicePinEnrollLabels, type DevicePinEnrollResult, DevicePinErrorKey, DevicePinInput, type DevicePinInputProps, DevicePinLengthPicker, type DevicePinLengthPickerProps, DevicePinOffer, type DevicePinOfferProps, DevicePinSettingsCard, type DevicePinSettingsCardProps, type DevicePinSettingsLabels, type DevicePinUnlockCapableClient, type DevicePinUnlockLabels, type DevicePinUnlockResult, DevicePinUnlockScreen, type DevicePinUnlockScreenProps, type DevicePinUnlockedUser, ForgotPasswordFields, type ForgotPasswordFieldsLabels, type ForgotPasswordFieldsProps, ForgotPasswordForm, type ForgotPasswordFormLabels, type ForgotPasswordFormProps, type LoginConfigCapableClient, LoginForm, type LoginFormLabels, type LoginFormProps, OtpForm, type OtpFormLabels, type OtpFormProps, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, type PerformBffLogoutOptions, PinForm, type PinFormLabels, type PinFormProps, type PreferencesClientOptions, type PreferredMethodClient, PreferredMethodHint, type PreferredMethodHintLabels, type PreferredMethodHintProps, PreferredMethodSettingsCard, type PreferredMethodSettingsCardProps, type PreferredMethodSettingsLabels, PrefillIntent, RegisterErrorCode, type RegisterField, type RegisterFieldLabels, RegisterForm, type RegisterFormLabels, type RegisterFormProps, type RegisterFormValues, type RegisterInputField, type RegisterPasswordPolicy, type RegisterSubmitOutcome, type RegisterSubmitValues, RegisterTestIds, ResetPasswordError, ResetPasswordForm, type ResetPasswordFormLabels, type ResetPasswordFormProps, type RoleRoute, type RoleRouteTable, type UseBffAuthOptions, type UseBffAuthResult, type UseBffForgotPasswordOptions, type UseBffLoginConfigResult, type UseBffResetPasswordOptions, type UseChangePasswordArgs, type UseChangePasswordResult, type UseDemoCredentialsOptions, type UseDemoCredentialsResult, type UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePasskeyCeremonyOptions, type UsePasskeyCeremonyResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseRegisterFormArgs, type UseRegisterFormResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createBffChangePasswordClient, createPreferencesClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isRegisterPasswordStrong, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveAccountList, resolveDemoAccounts, resolveDemoCredentials, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useChangePassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useRegisterForm, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
2873
+ export { type AccountSettingsChangePasswordConfig, type AccountSettingsDevicePinConfig, type AccountSettingsLabels, type AccountSettingsPasskeysConfig, type AccountSettingsPreferredMethodConfig, AccountSettingsScreen, type AccountSettingsScreenProps, AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type BffLogoutClient, CHANGE_PASSWORD_ENDPOINT, type ChangePasswordCapableClient, ChangePasswordCard, type ChangePasswordCardProps, ChangePasswordErrorKey, type ChangePasswordRequest, type ChangePasswordResult, type CreateBffAuthClientOptions, type CreateBffChangePasswordClientOptions, DEFAULT_ACCOUNT_SETTINGS_LABELS, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_REGISTER_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, type DemoCredentialsHintLabels, type DemoCredentialsHintProps, DemoCredentialsHintVariant, type DemoCredentialsHintWiring, type DemoCredentialsLoginFormProps, type DevicePinCapableClient, type DevicePinDisableCapableClient, type DevicePinEnrollCapableClient, DevicePinEnrollErrorKey, DevicePinEnrollForm, type DevicePinEnrollFormProps, type DevicePinEnrollLabels, type DevicePinEnrollResult, DevicePinErrorKey, DevicePinInput, type DevicePinInputProps, DevicePinLengthPicker, type DevicePinLengthPickerProps, DevicePinOffer, type DevicePinOfferProps, DevicePinSettingsCard, type DevicePinSettingsCardProps, type DevicePinSettingsLabels, type DevicePinUnlockCapableClient, type DevicePinUnlockLabels, type DevicePinUnlockResult, DevicePinUnlockScreen, type DevicePinUnlockScreenProps, type DevicePinUnlockedUser, ForgotPasswordFields, type ForgotPasswordFieldsLabels, type ForgotPasswordFieldsProps, ForgotPasswordForm, type ForgotPasswordFormLabels, type ForgotPasswordFormProps, type LoginConfigCapableClient, LoginForm, type LoginFormLabels, type LoginFormProps, OtpForm, type OtpFormLabels, type OtpFormProps, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, type PerformBffLogoutOptions, PinForm, type PinFormLabels, type PinFormProps, type PreferencesClientOptions, type PreferredMethodClient, PreferredMethodHint, type PreferredMethodHintLabels, type PreferredMethodHintProps, PreferredMethodSettingsCard, type PreferredMethodSettingsCardProps, type PreferredMethodSettingsLabels, PrefillIntent, RegisterErrorCode, type RegisterField, type RegisterFieldLabels, RegisterForm, type RegisterFormLabels, type RegisterFormProps, type RegisterFormValues, type RegisterInputField, type RegisterPasswordPolicy, type RegisterSubmitOutcome, type RegisterSubmitValues, RegisterTestIds, ResetPasswordError, ResetPasswordForm, type ResetPasswordFormLabels, type ResetPasswordFormProps, type RoleRoute, type RoleRouteTable, type SplitName, type UseBffAuthOptions, type UseBffAuthResult, type UseBffForgotPasswordOptions, type UseBffLoginConfigResult, type UseBffResetPasswordOptions, type UseChangePasswordArgs, type UseChangePasswordResult, type UseDemoCredentialsOptions, type UseDemoCredentialsResult, type UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePasskeyCeremonyOptions, type UsePasskeyCeremonyResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseRegisterFormArgs, type UseRegisterFormResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createBffChangePasswordClient, createPreferencesClient, defaultAuthTheme, deriveUsernameFromEmail, isAllowedPinDigits, isPasswordValid, isRegisterPasswordStrong, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveAccountList, resolveDemoAccounts, resolveDemoCredentials, resolvePostLoginRoute, splitFullName, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useChangePassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useRegisterForm, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
package/dist/index.d.ts CHANGED
@@ -525,10 +525,19 @@ declare const enum RegisterErrorCode {
525
525
  PasswordMismatch = "passwordMismatch",
526
526
  /** The server reported `USERNAME_TAKEN`. */
527
527
  UsernameTaken = "usernameTaken",
528
- /** The server reported `EMAIL_TAKEN`. */
528
+ /** The server reported `EMAIL_TAKEN` or `USER_EXISTS` (409). */
529
529
  EmailTaken = "emailTaken",
530
530
  /** The server reported `REALM_REQUIRED` or `REALM_INVALID`. */
531
531
  RealmInvalid = "realmInvalid",
532
+ /** The server reported `TENANT_NAME_TAKEN` (409): the organisation / shop name is in use. */
533
+ TenantNameTaken = "tenantNameTaken",
534
+ /** The server rate-limited the request (HTTP 429). */
535
+ RateLimited = "rateLimited",
536
+ /**
537
+ * The account WAS created but the automatic sign-in failed (`AUTO_LOGIN_FAILED`).
538
+ * Tell the user to sign in; do not ask them to register again.
539
+ */
540
+ AutoLoginFailed = "autoLoginFailed",
532
541
  /** The server rejected the request with an unrecognised message. */
533
542
  ValidationFailed = "validationFailed",
534
543
  /** Generic failure: network error, empty message, or a filled honeypot (never revealed). */
@@ -592,6 +601,8 @@ interface RegisterFormLabels {
592
601
  /** `accessibilityLabel` for the submit button while the request runs. */
593
602
  submitting: string;
594
603
  fields: Record<RegisterInputField, RegisterFieldLabels>;
604
+ /** Copy for the single "Your name" input of the compact form. Defaults to English. */
605
+ fullName?: RegisterFieldLabels;
595
606
  }
596
607
  declare const DEFAULT_REGISTER_LABELS: RegisterFormLabels;
597
608
 
@@ -2472,9 +2483,15 @@ interface RegisterFormProps<TResult> {
2472
2483
  footer?: ReactNode;
2473
2484
  /** Prefix applied to every `testID`. */
2474
2485
  testIdPrefix?: string;
2486
+ /**
2487
+ * Opt-in compact form (AUTH-REG-1): only "Your name", Email, Password and the
2488
+ * tenant name. First/last name are split from the name (one word fills both),
2489
+ * the username is derived from the email, and there is no confirm-password field.
2490
+ */
2491
+ compact?: boolean;
2475
2492
  }
2476
2493
  /** Themeable registration form built on `useRegisterForm`. */
2477
- declare function RegisterForm<TResult>({ onSubmit, onSuccess, onError, onSubmitAttempt, passwordPolicy, labels: labelsProp, theme: themeProp, footer, testIdPrefix, }: Readonly<RegisterFormProps<TResult>>): ReactElement;
2494
+ declare function RegisterForm<TResult>({ onSubmit, onSuccess, onError, onSubmitAttempt, passwordPolicy, labels: labelsProp, theme: themeProp, footer, testIdPrefix, compact, }: Readonly<RegisterFormProps<TResult>>): ReactElement;
2478
2495
 
2479
2496
  /**
2480
2497
  * `testID` values for `<RegisterForm>`.
@@ -2511,6 +2528,11 @@ interface UseRegisterFormArgs<TResult> {
2511
2528
  * event). A press ignored because a submit is already in flight does not call it.
2512
2529
  */
2513
2530
  onSubmitAttempt?: () => void;
2531
+ /**
2532
+ * Compact mode (AUTH-REG-1): `firstName` holds the full name; last name, username
2533
+ * (from the email) and the password confirmation are derived before validation.
2534
+ */
2535
+ compact?: boolean;
2514
2536
  }
2515
2537
  interface UseRegisterFormResult<TResult> {
2516
2538
  state: RegisterFormValues;
@@ -2521,7 +2543,7 @@ interface UseRegisterFormResult<TResult> {
2521
2543
  error: RegisterErrorCode | null;
2522
2544
  }
2523
2545
  /** Headless registration form logic. */
2524
- declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAttempt, }: UseRegisterFormArgs<TResult>): UseRegisterFormResult<TResult>;
2546
+ declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAttempt, compact, }: UseRegisterFormArgs<TResult>): UseRegisterFormResult<TResult>;
2525
2547
 
2526
2548
  /**
2527
2549
  * Pure registration helpers: trimming, client-side validation and decoding of a
@@ -2535,6 +2557,30 @@ declare function useRegisterForm<TResult>({ onSubmit, passwordPolicy, onSubmitAt
2535
2557
  /** The default password rule: 8+ characters with a letter, a digit and a special character. */
2536
2558
  declare function isRegisterPasswordStrong(password: string): boolean;
2537
2559
 
2560
+ /**
2561
+ * Compact registration (AUTH-REG-1 "Compact register form"): the form shows only
2562
+ * "Your name", Email, Password (+ tenant name). Keycloak still needs a username,
2563
+ * a first name AND a last name, so they are derived here before validation.
2564
+ *
2565
+ * In compact mode the single "Your name" input is stored in `firstName`.
2566
+ */
2567
+
2568
+ interface SplitName {
2569
+ firstName: string;
2570
+ lastName: string;
2571
+ }
2572
+ /**
2573
+ * Split a full name on whitespace: the first word is the first name, the rest the
2574
+ * last name. A single word is used for both (Keycloak requires a last name).
2575
+ */
2576
+ declare function splitFullName(fullName: string): SplitName;
2577
+ /**
2578
+ * A username derived from the whole email (so two people with the same local part
2579
+ * on different domains never collide): lower-cased, every char outside
2580
+ * `[a-z0-9._-]` replaced by `_`. `Ada+shop@Example.com` becomes `ada_shop_example.com`.
2581
+ */
2582
+ declare function deriveUsernameFromEmail(email: string): string;
2583
+
2538
2584
  /**
2539
2585
  * `createBffAuthClient` — the one-line wiring of a same-origin `BffAuthClient`.
2540
2586
  *
@@ -2824,4 +2870,4 @@ interface UseChangePasswordResult {
2824
2870
  }
2825
2871
  declare function useChangePassword({ client, onChanged, }: UseChangePasswordArgs): UseChangePasswordResult;
2826
2872
 
2827
- export { type AccountSettingsChangePasswordConfig, type AccountSettingsDevicePinConfig, type AccountSettingsLabels, type AccountSettingsPasskeysConfig, type AccountSettingsPreferredMethodConfig, AccountSettingsScreen, type AccountSettingsScreenProps, AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type BffLogoutClient, CHANGE_PASSWORD_ENDPOINT, type ChangePasswordCapableClient, ChangePasswordCard, type ChangePasswordCardProps, ChangePasswordErrorKey, type ChangePasswordRequest, type ChangePasswordResult, type CreateBffAuthClientOptions, type CreateBffChangePasswordClientOptions, DEFAULT_ACCOUNT_SETTINGS_LABELS, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_REGISTER_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, type DemoCredentialsHintLabels, type DemoCredentialsHintProps, DemoCredentialsHintVariant, type DemoCredentialsHintWiring, type DemoCredentialsLoginFormProps, type DevicePinCapableClient, type DevicePinDisableCapableClient, type DevicePinEnrollCapableClient, DevicePinEnrollErrorKey, DevicePinEnrollForm, type DevicePinEnrollFormProps, type DevicePinEnrollLabels, type DevicePinEnrollResult, DevicePinErrorKey, DevicePinInput, type DevicePinInputProps, DevicePinLengthPicker, type DevicePinLengthPickerProps, DevicePinOffer, type DevicePinOfferProps, DevicePinSettingsCard, type DevicePinSettingsCardProps, type DevicePinSettingsLabels, type DevicePinUnlockCapableClient, type DevicePinUnlockLabels, type DevicePinUnlockResult, DevicePinUnlockScreen, type DevicePinUnlockScreenProps, type DevicePinUnlockedUser, ForgotPasswordFields, type ForgotPasswordFieldsLabels, type ForgotPasswordFieldsProps, ForgotPasswordForm, type ForgotPasswordFormLabels, type ForgotPasswordFormProps, type LoginConfigCapableClient, LoginForm, type LoginFormLabels, type LoginFormProps, OtpForm, type OtpFormLabels, type OtpFormProps, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, type PerformBffLogoutOptions, PinForm, type PinFormLabels, type PinFormProps, type PreferencesClientOptions, type PreferredMethodClient, PreferredMethodHint, type PreferredMethodHintLabels, type PreferredMethodHintProps, PreferredMethodSettingsCard, type PreferredMethodSettingsCardProps, type PreferredMethodSettingsLabels, PrefillIntent, RegisterErrorCode, type RegisterField, type RegisterFieldLabels, RegisterForm, type RegisterFormLabels, type RegisterFormProps, type RegisterFormValues, type RegisterInputField, type RegisterPasswordPolicy, type RegisterSubmitOutcome, type RegisterSubmitValues, RegisterTestIds, ResetPasswordError, ResetPasswordForm, type ResetPasswordFormLabels, type ResetPasswordFormProps, type RoleRoute, type RoleRouteTable, type UseBffAuthOptions, type UseBffAuthResult, type UseBffForgotPasswordOptions, type UseBffLoginConfigResult, type UseBffResetPasswordOptions, type UseChangePasswordArgs, type UseChangePasswordResult, type UseDemoCredentialsOptions, type UseDemoCredentialsResult, type UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePasskeyCeremonyOptions, type UsePasskeyCeremonyResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseRegisterFormArgs, type UseRegisterFormResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createBffChangePasswordClient, createPreferencesClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isRegisterPasswordStrong, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveAccountList, resolveDemoAccounts, resolveDemoCredentials, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useChangePassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useRegisterForm, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
2873
+ export { type AccountSettingsChangePasswordConfig, type AccountSettingsDevicePinConfig, type AccountSettingsLabels, type AccountSettingsPasskeysConfig, type AccountSettingsPreferredMethodConfig, AccountSettingsScreen, type AccountSettingsScreenProps, AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type BffLogoutClient, CHANGE_PASSWORD_ENDPOINT, type ChangePasswordCapableClient, ChangePasswordCard, type ChangePasswordCardProps, ChangePasswordErrorKey, type ChangePasswordRequest, type ChangePasswordResult, type CreateBffAuthClientOptions, type CreateBffChangePasswordClientOptions, DEFAULT_ACCOUNT_SETTINGS_LABELS, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_REGISTER_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, type DemoCredentialsHintLabels, type DemoCredentialsHintProps, DemoCredentialsHintVariant, type DemoCredentialsHintWiring, type DemoCredentialsLoginFormProps, type DevicePinCapableClient, type DevicePinDisableCapableClient, type DevicePinEnrollCapableClient, DevicePinEnrollErrorKey, DevicePinEnrollForm, type DevicePinEnrollFormProps, type DevicePinEnrollLabels, type DevicePinEnrollResult, DevicePinErrorKey, DevicePinInput, type DevicePinInputProps, DevicePinLengthPicker, type DevicePinLengthPickerProps, DevicePinOffer, type DevicePinOfferProps, DevicePinSettingsCard, type DevicePinSettingsCardProps, type DevicePinSettingsLabels, type DevicePinUnlockCapableClient, type DevicePinUnlockLabels, type DevicePinUnlockResult, DevicePinUnlockScreen, type DevicePinUnlockScreenProps, type DevicePinUnlockedUser, ForgotPasswordFields, type ForgotPasswordFieldsLabels, type ForgotPasswordFieldsProps, ForgotPasswordForm, type ForgotPasswordFormLabels, type ForgotPasswordFormProps, type LoginConfigCapableClient, LoginForm, type LoginFormLabels, type LoginFormProps, OtpForm, type OtpFormLabels, type OtpFormProps, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, type PerformBffLogoutOptions, PinForm, type PinFormLabels, type PinFormProps, type PreferencesClientOptions, type PreferredMethodClient, PreferredMethodHint, type PreferredMethodHintLabels, type PreferredMethodHintProps, PreferredMethodSettingsCard, type PreferredMethodSettingsCardProps, type PreferredMethodSettingsLabels, PrefillIntent, RegisterErrorCode, type RegisterField, type RegisterFieldLabels, RegisterForm, type RegisterFormLabels, type RegisterFormProps, type RegisterFormValues, type RegisterInputField, type RegisterPasswordPolicy, type RegisterSubmitOutcome, type RegisterSubmitValues, RegisterTestIds, ResetPasswordError, ResetPasswordForm, type ResetPasswordFormLabels, type ResetPasswordFormProps, type RoleRoute, type RoleRouteTable, type SplitName, type UseBffAuthOptions, type UseBffAuthResult, type UseBffForgotPasswordOptions, type UseBffLoginConfigResult, type UseBffResetPasswordOptions, type UseChangePasswordArgs, type UseChangePasswordResult, type UseDemoCredentialsOptions, type UseDemoCredentialsResult, type UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePasskeyCeremonyOptions, type UsePasskeyCeremonyResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseRegisterFormArgs, type UseRegisterFormResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createBffChangePasswordClient, createPreferencesClient, defaultAuthTheme, deriveUsernameFromEmail, isAllowedPinDigits, isPasswordValid, isRegisterPasswordStrong, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveAccountList, resolveDemoAccounts, resolveDemoCredentials, resolvePostLoginRoute, splitFullName, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useChangePassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useRegisterForm, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
package/dist/index.js CHANGED
@@ -342,6 +342,7 @@ var DEFAULT_REGISTER_LABELS = {
342
342
  submit: "Create account",
343
343
  submitHint: "Creates your account",
344
344
  submitting: "Creating account...",
345
+ fullName: field("Your name", "Enter your full name"),
345
346
  fields: {
346
347
  firstName: field("First name", "Enter your first name"),
347
348
  lastName: field("Last name", "Enter your last name"),
@@ -4101,6 +4102,18 @@ var FIELDS = [
4101
4102
  { key: "confirmPassword", testId: RegisterTestIds.confirmPasswordInput, secure: true },
4102
4103
  { key: "tenantName", testId: RegisterTestIds.tenantNameInput }
4103
4104
  ];
4105
+ var COMPACT_FIELDS = [
4106
+ { key: "firstName", testId: RegisterTestIds.firstNameInput, autoComplete: "name" },
4107
+ { key: "email", testId: RegisterTestIds.emailInput, autoComplete: "email", keyboardType: "email-address" },
4108
+ { key: "password", testId: RegisterTestIds.passwordInput, secure: true },
4109
+ { key: "tenantName", testId: RegisterTestIds.tenantNameInput }
4110
+ ];
4111
+ function copyFor(key, labels, compact) {
4112
+ if (compact && key === "firstName" && labels.fullName !== void 0) {
4113
+ return labels.fullName;
4114
+ }
4115
+ return labels.fields[key];
4116
+ }
4104
4117
  var OFF_SCREEN = -9999;
4105
4118
  var HONEYPOT_SIZE = 1;
4106
4119
  var HONEYPOT_PLACEHOLDER = "Website";
@@ -4122,11 +4135,12 @@ function RegisterFormFields({
4122
4135
  styles: styles3,
4123
4136
  onChange,
4124
4137
  onSubmitEditing,
4125
- testIdPrefix
4138
+ testIdPrefix,
4139
+ compact = false
4126
4140
  }) {
4127
4141
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4128
- FIELDS.map((config) => {
4129
- const copy = labels.fields[config.key];
4142
+ (compact ? COMPACT_FIELDS : FIELDS).map((config) => {
4143
+ const copy = copyFor(config.key, labels, compact);
4130
4144
  return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles3.fieldGroup, children: [
4131
4145
  /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.label, children: copy.label }),
4132
4146
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -4179,6 +4193,9 @@ var RegisterErrorCode = /* @__PURE__ */ ((RegisterErrorCode2) => {
4179
4193
  RegisterErrorCode2["UsernameTaken"] = "usernameTaken";
4180
4194
  RegisterErrorCode2["EmailTaken"] = "emailTaken";
4181
4195
  RegisterErrorCode2["RealmInvalid"] = "realmInvalid";
4196
+ RegisterErrorCode2["TenantNameTaken"] = "tenantNameTaken";
4197
+ RegisterErrorCode2["RateLimited"] = "rateLimited";
4198
+ RegisterErrorCode2["AutoLoginFailed"] = "autoLoginFailed";
4182
4199
  RegisterErrorCode2["ValidationFailed"] = "validationFailed";
4183
4200
  RegisterErrorCode2["Failed"] = "failed";
4184
4201
  RegisterErrorCode2["InFlight"] = "inFlight";
@@ -4270,6 +4287,41 @@ function validateRegisterValues(values, passwordPolicy) {
4270
4287
  }
4271
4288
  return null;
4272
4289
  }
4290
+ var HTTP_TOO_MANY_REQUESTS = 429;
4291
+ var HTTP_SERVER_ERROR_MIN = 500;
4292
+ var BODY_ERROR_CODES = {
4293
+ USER_EXISTS: "emailTaken" /* EmailTaken */,
4294
+ USERNAME_TAKEN: "usernameTaken" /* UsernameTaken */,
4295
+ EMAIL_TAKEN: "emailTaken" /* EmailTaken */,
4296
+ TENANT_NAME_TAKEN: "tenantNameTaken" /* TenantNameTaken */,
4297
+ AUTO_LOGIN_FAILED: "autoLoginFailed" /* AutoLoginFailed */,
4298
+ INVALID_REQUEST: "validationFailed" /* ValidationFailed */,
4299
+ REALM_REQUIRED: "realmInvalid" /* RealmInvalid */,
4300
+ REALM_INVALID: "realmInvalid" /* RealmInvalid */
4301
+ };
4302
+ function typedFailureOf(error) {
4303
+ if (typeof error !== "object" || error === null) {
4304
+ return null;
4305
+ }
4306
+ const { status, errorCode } = error;
4307
+ const hasStatus = typeof status === "number";
4308
+ const hasCode = typeof errorCode === "string";
4309
+ if (!hasStatus && !hasCode) {
4310
+ return null;
4311
+ }
4312
+ return { status: hasStatus ? status : null, errorCode: hasCode ? errorCode : null };
4313
+ }
4314
+ function mapTypedFailure(failure) {
4315
+ const byCode = failure.errorCode === null ? void 0 : BODY_ERROR_CODES[failure.errorCode];
4316
+ if (byCode !== void 0) {
4317
+ return byCode;
4318
+ }
4319
+ if (failure.status === HTTP_TOO_MANY_REQUESTS) {
4320
+ return "rateLimited" /* RateLimited */;
4321
+ }
4322
+ const isServerError = failure.status !== null && failure.status >= HTTP_SERVER_ERROR_MIN;
4323
+ return isServerError ? "failed" /* Failed */ : null;
4324
+ }
4273
4325
  function messageOf(error) {
4274
4326
  if (error instanceof Error) {
4275
4327
  return error.message;
@@ -4277,6 +4329,11 @@ function messageOf(error) {
4277
4329
  return typeof error === "string" ? error : "";
4278
4330
  }
4279
4331
  function mapRegisterErrorCode(error) {
4332
+ const failure = typedFailureOf(error);
4333
+ const typed = failure === null ? null : mapTypedFailure(failure);
4334
+ if (typed !== null) {
4335
+ return typed;
4336
+ }
4280
4337
  const message = messageOf(error);
4281
4338
  if (message === "") {
4282
4339
  return "failed" /* Failed */;
@@ -4285,6 +4342,29 @@ function mapRegisterErrorCode(error) {
4285
4342
  return match === void 0 ? "validationFailed" /* ValidationFailed */ : match[1];
4286
4343
  }
4287
4344
 
4345
+ // src/hooks/registerCompact.ts
4346
+ var WHITESPACE_RUN = /\s+/;
4347
+ var UNSAFE_USERNAME_CHARS = /[^a-z0-9._-]/g;
4348
+ var USERNAME_REPLACEMENT = "_";
4349
+ function splitFullName(fullName) {
4350
+ const words = fullName.trim().split(WHITESPACE_RUN).filter((word) => word !== "");
4351
+ const [first = "", ...rest] = words;
4352
+ return { firstName: first, lastName: rest.length > 0 ? rest.join(" ") : first };
4353
+ }
4354
+ function deriveUsernameFromEmail(email) {
4355
+ return email.trim().toLowerCase().replace(UNSAFE_USERNAME_CHARS, USERNAME_REPLACEMENT);
4356
+ }
4357
+ function expandCompactRegisterValues(values) {
4358
+ const { firstName, lastName } = splitFullName(values.firstName);
4359
+ return {
4360
+ ...values,
4361
+ firstName,
4362
+ lastName,
4363
+ username: deriveUsernameFromEmail(values.email),
4364
+ confirmPassword: values.password
4365
+ };
4366
+ }
4367
+
4288
4368
  // src/hooks/useRegisterForm.ts
4289
4369
  var EMPTY_VALUES = {
4290
4370
  firstName: "",
@@ -4310,7 +4390,8 @@ function toSubmitValues(values) {
4310
4390
  function useRegisterForm({
4311
4391
  onSubmit,
4312
4392
  passwordPolicy = isRegisterPasswordStrong,
4313
- onSubmitAttempt
4393
+ onSubmitAttempt,
4394
+ compact = false
4314
4395
  }) {
4315
4396
  const [state, setState] = react.useState(EMPTY_VALUES);
4316
4397
  const [isSubmitting, setIsSubmitting] = react.useState(false);
@@ -4324,7 +4405,8 @@ function useRegisterForm({
4324
4405
  return { ok: false, error: "inFlight" /* InFlight */ };
4325
4406
  }
4326
4407
  onSubmitAttempt?.();
4327
- const trimmed = trimRegisterValues(state);
4408
+ const trimmedRaw = trimRegisterValues(state);
4409
+ const trimmed = compact ? expandCompactRegisterValues(trimmedRaw) : trimmedRaw;
4328
4410
  const refusal = trimmed.website === "" ? validateRegisterValues(trimmed, passwordPolicy) : "failed" /* Failed */;
4329
4411
  if (refusal !== null) {
4330
4412
  setError(refusal);
@@ -4344,7 +4426,7 @@ function useRegisterForm({
4344
4426
  inFlight.current = false;
4345
4427
  setIsSubmitting(false);
4346
4428
  }
4347
- }, [onSubmit, onSubmitAttempt, passwordPolicy, state]);
4429
+ }, [compact, onSubmit, onSubmitAttempt, passwordPolicy, state]);
4348
4430
  return { state, setField, submit, isSubmitting, error };
4349
4431
  }
4350
4432
  function RegisterForm({
@@ -4356,7 +4438,8 @@ function RegisterForm({
4356
4438
  labels: labelsProp,
4357
4439
  theme: themeProp,
4358
4440
  footer,
4359
- testIdPrefix
4441
+ testIdPrefix,
4442
+ compact = false
4360
4443
  }) {
4361
4444
  const theme = useAuthTheme(themeProp);
4362
4445
  const styles3 = useAuthStyles(theme);
@@ -4367,7 +4450,8 @@ function RegisterForm({
4367
4450
  const { state, setField, submit, isSubmitting } = useRegisterForm({
4368
4451
  onSubmit,
4369
4452
  onSubmitAttempt,
4370
- passwordPolicy
4453
+ passwordPolicy,
4454
+ compact
4371
4455
  });
4372
4456
  const handlePress = react.useCallback(async () => {
4373
4457
  routeRegisterOutcome(await submit(), { onSuccess, onError });
@@ -4379,6 +4463,7 @@ function RegisterForm({
4379
4463
  /* @__PURE__ */ jsxRuntime.jsx(
4380
4464
  RegisterFormFields,
4381
4465
  {
4466
+ compact,
4382
4467
  disabled: isSubmitting,
4383
4468
  labels,
4384
4469
  styles: styles3,
@@ -4613,6 +4698,7 @@ exports.createBffAuthClient = createBffAuthClient;
4613
4698
  exports.createBffChangePasswordClient = createBffChangePasswordClient;
4614
4699
  exports.createPreferencesClient = createPreferencesClient;
4615
4700
  exports.defaultAuthTheme = defaultAuthTheme;
4701
+ exports.deriveUsernameFromEmail = deriveUsernameFromEmail;
4616
4702
  exports.isAllowedPinDigits = isAllowedPinDigits;
4617
4703
  exports.isPasswordValid = isPasswordValid;
4618
4704
  exports.isRegisterPasswordStrong = isRegisterPasswordStrong;
@@ -4626,6 +4712,7 @@ exports.resolveAccountList = resolveAccountList;
4626
4712
  exports.resolveDemoAccounts = resolveDemoAccounts;
4627
4713
  exports.resolveDemoCredentials = resolveDemoCredentials;
4628
4714
  exports.resolvePostLoginRoute = resolvePostLoginRoute;
4715
+ exports.splitFullName = splitFullName;
4629
4716
  exports.startPasskeyLogin = startPasskeyLogin;
4630
4717
  exports.startPasskeyRegistration = startPasskeyRegistration;
4631
4718
  exports.syncPreferredMethodFromServer = syncPreferredMethodFromServer;